Changeset 77

User picture

Author: frojo56

(2009/03/02 15:20) Almost 3 years ago

Encapsulated all code in twitter_fantastico anonymous function

Affected files

Updated twitter_fantastico.user.js Download diff

7677
43
//ADDED: Character counter near textareas
43
//ADDED: Character counter near textareas
44
//ADDED: Highlight replies to you (yellow?)
44
//ADDED: Highlight replies to you (yellow?)
45
//ADDED: Highlight own tweets (green)
45
//ADDED: Highlight own tweets (green)
46
twitter_fantastico = function(){
47
	var j=jQuery.noConflict();
48
	var last_read_tweet_id;
49
	var tweets_on_page;
50
	var current_username = (j.trim(j("p#me_name").html())).length != 0 ? j.trim(j("p#me_name").html()) : j("#navigation
#profile_link").attr("href").replace(/https?:\/\/(?:www\.)?twitter\.com\/([\w\d]+)$/,"$1");
51
	var debug=true;
52
	var onNonProcessingPage = false;
53
	var onTwitterFriendFeed = false;
54
	var onTwitterIndividualTweet = false;
55
	var onTwitterUsersProfile = false;
56
	var onOwnProfilePage = false;
57
	var pageNumber=1;
58
	var loading=false;
59
	var lastPage=false;
60
	var useJQXHR=true;
61
	var current_script_length = 28734;
62
	var loaded_tweets = new Array();
46
63
47
var j=jQuery.noConflict();
64
	if (typeof GM_xmlhttpRequest == "function") 
48
var last_read_tweet_id;
49
var tweets_on_page;
50
var current_username = (j.trim(j("p#me_name").html())).length != 0 ? j.trim(j("p#me_name").html()) : j("#navigation #profile_link").attr("href").replace(/https?:\/\/(?:www\.)?twitter\.com\/([\w\d]+)$/,"$1");
51
var debug=true;
52
var onNonProcessingPage = false;
53
var onTwitterFriendFeed = false;
54
var onTwitterIndividualTweet = false;
55
var onTwitterUsersProfile = false;
56
var onOwnProfilePage = false;
57
var pageNumber=1;
58
var loading=false;
59
var lastPage=false;
60
var useJQXHR=true;
61
var current_script_length = 28734;
62
var loaded_tweets = new Array();
63
64
if (typeof GM_xmlhttpRequest == "function") 
65
{
66
  var xhr = GM_xmlhttpRequest;
67
} 
68
else 
69
{
70
	var xhr = function(params) 
71
	{
65
	{
72
    	var req = new XMLHttpRequest();
66
	  var xhr = GM_xmlhttpRequest;
67
	} 
68
	else 
69
	{
70
		var xhr = function(params) 
71
		{
72
	    	var req = new XMLHttpRequest();
73
73
74
    	req.onreadystatechange = function() {
74
	    	req.onreadystatechange = function() {
75
  			if (req.readyState == 4) {
75
	  			if (req.readyState == 4) {
76
		        if (req.status >= 200 && req.status < 400) 
76
			        if (req.status >= 200 && req.status < 400) 
77
					if (params.onload) 
77
						if (params.onload) 
78
						params.onload(req);
78
							params.onload(req);
79
		        else if (params.onerror) 
79
			        else if (params.onerror) 
80
					params.onerror(req);
80
						params.onerror(req);
81
			}
81
				}
82
	    }
82
		    }
83
83
84
    	if (params.headers) 
84
	    	if (params.headers) 
85
			for (name in params.headers);
85
				for (name in params.headers);
86
      	req.setRequestHeader(name, params.headers[name]);
86
	      	req.setRequestHeader(name, params.headers[name]);
87
87
88
	    req.open(params.method, params.url, true);
88
		    req.open(params.method, params.url, true);
89
	    req.send(params.data);
89
		    req.send(params.data);
90
		}
90
	}
91
	}
91
}
92
92
93
j(document).ready(function(){	
93
	j(document).ready(function(){	
94
	//Don't try to get data when user is on twitter's homepage, and not logged in yet.
94
		//Don't try to get data when user is on twitter's homepage, and not logged in yet.
95
	log("Document ready. Determining what page the user is on.");
95
		log("Document ready. Determining what page the user is on.");
96
	log("Current Username: " + current_username);
96
		log("Current Username: " + current_username);
97
97
98
	determine_what_page_user_is_on();
98
		determine_what_page_user_is_on();
99
	j('head').append("<style type='text/css'>"+page_css()+"</style>");
99
		j('head').append("<style type='text/css'>"+page_css()+"</style>");
100
	//add_bottom_actionbar();
100
		//add_bottom_actionbar();
101
	log("Loading page data");
101
		log("Loading page data");
102
	//load_page(false,useJQXHR);
102
		//load_page(false,useJQXHR);
103
	load_page(useJQXHR,false);
103
		load_page(useJQXHR,false);
104
	modify_tweets(loaded_tweets[pageNumber-1],false)
104
		modify_tweets(loaded_tweets[pageNumber-1],false)
105
	log("Attaching scroll event handler");
105
		log("Attaching scroll event handler");
106
	//apply scroll event handler
106
		//apply scroll event handler
107
	j(window).scroll(function(e){
107
		j(window).scroll(function(e){
108
		//window.pageYOffset
108
			//window.pageYOffset
109
		//window.innerHeight
109
			//window.innerHeight
110
		//log("Y: "+window.pageYOffset+" WindowHeight: "+window.innerHeight);
110
			//log("Y: "+window.pageYOffset+" WindowHeight: "+window.innerHeight);
111
		lastTweetTop = j("#timeline .status:last").offset().top;
111
			lastTweetTop = j("#timeline .status:last").offset().top;
112
		currentScrollPosition = window.pageYOffset + window.innerHeight;
112
			currentScrollPosition = window.pageYOffset + window.innerHeight;
113
		//log("Loading: "+loading+" LastPage: "+lastPage+" currentScrollPosition >= lastTweetTop - 20:" + (currentScrollPosition
>= lastTweetTop - 20));
113
			//log("Loading: "+loading+" LastPage: "+lastPage+" currentScrollPosition >= lastTweetTop - 20:" + (currentScrollPosition >= lastTweetTop - 20));
114
		if( !loading && !lastPage && currentScrollPosition >= lastTweetTop - window.innerHeight/3)
114
			if( !loading && !lastPage && currentScrollPosition >= lastTweetTop - window.innerHeight/3)
115
		{
115
			{
116
			pageNumber++;
116
				pageNumber++;
117
			log("Grabbing more tweets from page "+pageNumber);
117
				log("Grabbing more tweets from page "+pageNumber);
118
			load_page(useJQXHR,false);
118
				load_page(useJQXHR,false);
119
			modify_tweets(loaded_tweets[pageNumber-1],true);
119
				modify_tweets(loaded_tweets[pageNumber-1],true);
120
		}
120
			}
121
		});
122
		j("table.get-started-steps").hide();
123
		//Add counters to each text box
124
		add_counter_to_textareas();
125
		add_update_notification();
121
	});
126
	});
122
	j("table.get-started-steps").hide();
123
	//Add counters to each text box
124
	add_counter_to_textareas();
125
	add_update_notification();
126
});
127
127
128
function load_page(useJqueryAjax,is_async)
128
	function load_page(useJqueryAjax,is_async)
129
{
130
	loading=true;
131
	reHttp = /https?/;
132
	protocol = /https?/.exec(location.href)[0];
133
	if(!onNonProcessingPage &&  onTwitterFriendFeed)
134
	{
129
	{
135
		log("On friend feed");
130
		loading=true;
136
		log("Page Number: " + pageNumber);
131
		reHttp = /https?/;
137
		friends_timeline_url = protocol+"://twitter.com/statuses/friends_timeline.json";
132
		protocol = /https?/.exec(location.href)[0];
138
		if(useJqueryAjax)
133
		if(!onNonProcessingPage &&  onTwitterFriendFeed)
139
		{
134
		{
140
			log("Loading json page data");
135
			log("On friend feed");
136
			log("Page Number: " + pageNumber);
137
			friends_timeline_url = protocol+"://twitter.com/statuses/friends_timeline.json";
138
			if(useJqueryAjax)
139
			{
140
				log("Loading json page data via jquery");
141
				j.ajax({
142
					url:friends_timeline_url,
143
					type: "GET",
144
					data: {page:pageNumber},
145
					dataType: "json",
146
					async:is_async,
147
					beforeSend:function(xmlhr){
148
						//xmlhr.setRequestHeader("Cookie",getCookieSession());
149
					},
150
					success:function(data){
151
						if(data == null || data.length == 0)
152
						{	
153
							log("Data is null from "+friends_timeline_url+", or data.length was 0.");
154
							lastPage=true;
155
							pageNumber--;
156
							return;
157
						}
158
						loaded_tweets[pageNumber-1] = data;
159
						log('Successfully loaded ' + data.length + ' tweets.' )
160
						//modify_tweets(tweets_on_page,appendTweets);
161
						loading=false;
162
					},
163
					error:function(xmlhttp,errortype,errorobj){
164
						log('Error loading tweets on page load.')
165
					}
166
				});
167
			}
168
			else
169
			{
170
				log("Loading json page data via xhr");
171
				xhr({
172
					url:friends_timeline_url+"?page="+pageNumber,
173
					method:"GET",
174
					onload:function(req){
175
						newTweets = eval(req.responseText);
176
						if(newTweets == null || newTweets.length == 0 )
177
						{
178
							log("Data is null from "+friends_timeline_url+", or data.length was 0.");
179
							lastPage=true;
180
							pageNumber--;
181
							return;
182
						}
183
						log('Successfully loaded ' + newTweets.length + ' tweets.' );
184
						tweets_on_page = newTweets;
185
						loaded_tweets[pageNumber-1] = data;
186
						//modify_tweets(tweets_on_page,appendTweets);
187
						loading=false;
188
					}
189
				});
190
			}		
191
		}
192
		else if(!onNonProcessingPage && onTwitterIndividualTweet)
193
		{
194
			statusid = reUrlSplitUp[3];
195
			log("On indidivual page("+statusid+")");
196
			log("Page Number: " + pageNumber);
141
			j.ajax({
197
			j.ajax({
142
				url:friends_timeline_url,
198
				url:protocol+"://twitter.com/statuses/show/"+statusid+".json",
199
				type:"GET",
200
				data:{id:statusid},
201
				dataType:"json",
202
				async:false,
203
				success:function(data){
204
					//add to array, don't just apply single tweet
205
					loaded_tweets[pageNumber-1] = new Array();
206
					loaded_tweets[pageNumber-1].push(data);
207
					//loaded_tweets[pageNumber-1] = data;
208
					log("Loaded "+loaded_tweets[pageNumber-1].length+" tweet(s)");
209
					loading=false;
210
				}
211
			});
212
		}
213
		else if(onTwitterUsersProfile)
214
		{
215
			log("On user's profile");
216
			log("Page number: "+pageNumber);
217
			j.ajax({
218
				url:protocol+"://twitter.com/statuses/user_timeline/"+reUrlSplitUp[1]+".json",
143
				type: "GET",
219
				type: "GET",
144
				data: {page:pageNumber},
220
				data: {page:pageNumber},
145
				dataType: "json",
221
				dataType: "json",
146
				async:is_async,
222
				async:is_async,
147
				beforeSend:function(xmlhr){
148
					//xmlhr.setRequestHeader("Cookie",getCookieSession());
149
				},
150
				success:function(data){
223
				success:function(data){
151
					if(data == null || data.length == 0)
224
					if(data == null || data.length == 0)
152
					{	
225
					{	
...
...
164
				}
237
				}
165
			});
238
			});
166
		}
239
		}
167
		else
240
	}
241
	function modify_tweets(tweets,appendTweets)
242
	{
243
		log("Modifying " + tweets.length + " tweet(s)");
244
		if(tweets != null)
168
		{
245
		{
169
			xhr({
246
			for(i=0;i<tweets.length;i++)
170
				url:friends_timeline_url+"?page="+pageNumber,
247
			{
171
				method:"GET",
248
				jq_tweet = j("#timeline #status_"+tweets[i].id);
172
				onload:function(req){
249
				if(jq_tweet.length == 0)
173
					newTweets = eval(req.responseText);
250
					jq_tweet = j("#permalink");
174
					if(newTweets == null || newTweets.length == 0 )
251
				if(appendTweets)
252
				{
253
					new_jq_tweet = convert_json_tweet_to_html_tweet(tweets[i]);//.appendTo("#timeline");
254
					add_retweet_button(new_jq_tweet,tweets[i]);
255
					modify_reply_button(new_jq_tweet,tweets[i]);				
256
					if(tweets[i].user.screen_name == current_username)
175
					{
257
					{
176
						lastPage=true;
258
						new_jq_tweet.find("span.actions div").append("<a class='delete' title='delete this update' href='#delete'></a>");
177
						pageNumber--;
259
						modify_delete_button(new_jq_tweet,tweets[i]);
178
						return;
179
					}
260
					}
180
					log('Successfully loaded ' + newTweets.length + ' tweets.' );
261
					find_reply_to_me_in_tweet_and_set_to_me_class(new_jq_tweet);
181
					tweets_on_page = newTweets;
262
					if(j("#timeline").length>0)
182
					loaded_tweets[pageNumber-1] = data;
263
						new_jq_tweet.appendTo("#timeline");
183
					//modify_tweets(tweets_on_page,appendTweets);
264
					else
184
					loading=false;
265
						new_jq_tweet.appendTo("#wrapper");
266
					add_twitpic_preview(new_jq_tweet,tweets[i]);
185
				}
267
				}
186
			});
268
				else
187
		}		
269
				{
188
	}
270
					//oldEntryContent = j("#timeline #status_"+tweets[i].id+" .status-body .entry-content").html();
189
	else if(!onNonProcessingPage && onTwitterIndividualTweet)
271
					oldEntryContent = jq_tweet.find(".status-body .entry-content").html();
190
	{
272
					newEntryContent = link_up_status_text(oldEntryContent,false,false,true);
191
		statusid = reUrlSplitUp[3];
273
					//j("#timeline #status_"+tweets[i].id+" .status-body .entry-content").html(newEntryContent);
192
		log("On indidivual page("+statusid+")");
274
					jq_tweet.find(".status-body .entry-content").html(newEntryContent);
193
		log("Page Number: " + pageNumber);
275
					modify_reply_button(jq_tweet,tweets[i]);
194
		j.ajax({
276
					add_retweet_button(jq_tweet,tweets[i]);
195
			url:protocol+"://twitter.com/statuses/show/"+statusid+".json",
277
					modify_delete_button(jq_tweet,tweets[i]);
196
			type:"GET",
278
					add_twitpic_preview(jq_tweet,tweets[i]);
197
			data:{id:statusid},
279
					find_reply_to_me_in_tweet_and_set_to_me_class(jq_tweet);
198
			dataType:"json",
199
			async:false,
200
			success:function(data){
201
				//add to array, don't just apply single tweet
202
				loaded_tweets[pageNumber-1] = new Array();
203
				loaded_tweets[pageNumber-1].push(data);
204
				//loaded_tweets[pageNumber-1] = data;
205
				log("Loaded "+loaded_tweets[pageNumber-1].length+" tweet(s)");
206
				loading=false;
207
			}
208
		});
209
	}
210
	else if(onTwitterUsersProfile)
211
	{
212
		log("On user's profile");
213
		log("Page number: "+pageNumber);
214
		j.ajax({
215
			url:protocol+"://twitter.com/statuses/user_timeline/"+reUrlSplitUp[1]+".json",
216
			type: "GET",
217
			data: {page:pageNumber},
218
			dataType: "json",
219
			async:is_async,
220
			success:function(data){
221
				if(data == null || data.length == 0)
222
				{	
223
					lastPage=true;
224
					pageNumber--;
225
					return;
226
				}
280
				}
227
				loaded_tweets[pageNumber-1] = data;
281
228
				log('Successfully loaded ' + data.length + ' tweets.' )
229
				//modify_tweets(tweets_on_page,appendTweets);
230
				loading=false;
231
			},
232
			error:function(xmlhttp,errortype,errorobj){
233
				log('Error loading tweets on page load.')
234
			}
282
			}
235
		});
283
		}
284
		//log("Done modifying tweets.");
236
	}
285
	}
237
}
286
238
function modify_tweets(tweets,appendTweets)
287
	function add_retweet_button(tweet,json_tweet)
239
{
240
	log("Modifying " + tweets.length + " tweet(s)");
241
	if(tweets != null)
242
	{
288
	{
243
		for(i=0;i<tweets.length;i++)
289
		if(json_tweet.user.screen_name != current_username)
244
		{
290
		{
245
			jq_tweet = j("#timeline #status_"+tweets[i].id);
291
			tweet.find("a.retweet-link").remove();
246
			if(jq_tweet.length == 0)
292
			//log("Adding retweet button for "+ json_tweet.id);
247
				jq_tweet = j("#permalink");
293
			//log("Adding retweet button for " + json_tweet.id);
248
			if(appendTweets)
294
			if(tweet.find(".actions div").length==0)
249
			{
295
				jq_retweet_link = j("<a class='retweet-link' href='#retweet'>RT</a>").appendTo(tweet.find(".actions"));
250
				new_jq_tweet = convert_json_tweet_to_html_tweet(tweets[i]);//.appendTo("#timeline");
251
				add_retweet_button(new_jq_tweet,tweets[i]);
252
				modify_reply_button(new_jq_tweet,tweets[i]);				
253
				if(tweets[i].user.screen_name == current_username)
254
				{
255
					new_jq_tweet.find("span.actions div").append("<a class='delete' title='delete this update' href='#delete'></a>");
256
					modify_delete_button(new_jq_tweet,tweets[i]);
257
				}
258
				find_reply_to_me_in_tweet_and_set_to_me_class(new_jq_tweet);
259
				if(j("#timeline").length>0)
260
					new_jq_tweet.appendTo("#timeline");
261
				else
262
					new_jq_tweet.appendTo("#wrapper");
263
				add_twitpic_preview(new_jq_tweet,tweets[i]);
264
			}
265
			else
296
			else
266
			{
297
				jq_retweet_link = j("<a class='retweet-link' href='#retweet'>RT</a>").appendTo(tweet.find(".actions div"));
267
				//oldEntryContent = j("#timeline #status_"+tweets[i].id+" .status-body .entry-content").html();
298
268
				oldEntryContent = jq_tweet.find(".status-body .entry-content").html();
299
			jq_retweet_link.data('json_tweet',json_tweet);
269
				newEntryContent = link_up_status_text(oldEntryContent,false,false,true);
300
			jq_retweet_link.click(function(){
270
				//j("#timeline #status_"+tweets[i].id+" .status-body .entry-content").html(newEntryContent);
301
				show_embedded_retweet(j(this).data('json_tweet'));
271
				jq_tweet.find(".status-body .entry-content").html(newEntryContent);
302
				return false;
272
				modify_reply_button(jq_tweet,tweets[i]);
303
			});
273
				add_retweet_button(jq_tweet,tweets[i]);
304
			//log("Done adding retweet");
274
				modify_delete_button(jq_tweet,tweets[i]);
275
				add_twitpic_preview(jq_tweet,tweets[i]);
276
				find_reply_to_me_in_tweet_and_set_to_me_class(jq_tweet);
277
			}
278
			
279
		}
305
		}
306
280
	}
307
	}
281
	//log("Done modifying tweets.");
308
	function show_embedded_retweet(json_tweet)
282
}
309
	{
310
		if(j("li#status_"+json_tweet.id).length>0)
311
			jq_tweet = j("li#status_"+json_tweet.id);
312
		else
313
			jq_tweet = j("#permalink");
283
314
284
function add_retweet_button(tweet,json_tweet)
315
		if( jq_tweet.find(".status-body .embedded-retweet").length==0)
285
{
316
		{
286
	if(json_tweet.user.screen_name != current_username)
317
			jq_embedded_retweet = j("<div id='retweet_"+json_tweet.id+ "' class='embedded-retweet'><span class='counter'>140</span><br/><textarea  class='retweet-text'></textarea><br/><a class='retweet-submit' href='#'>Retweet this</a><a class='retweet-cancel' href='#'>Cancel</a></div>");
318
319
			jq_embedded_retweet.appendTo(jq_tweet.find(".status-body")).effect('scale',{from:{height:0},percent:100,direction:'vertical',scale:'box'},300);
320
			jq_textarea = jq_embedded_retweet.find("textarea.retweet-text");
321
			//jq_textarea.focus(function(){
322
			//	counter_span = j(this).parent().find("span.counter");
323
			//	counter_span.html(140-parseInt(j(this).val().length));
324
			//});
325
			counter_span = jq_textarea.parent().find("span.counter");
326
			counter_span.html(140-parseInt(jq_textarea.val().length));
327
328
			jq_textarea.val("RT @" + json_tweet.user.screen_name + " " + json_tweet.text);
329
			jq_retweet_link = jq_embedded_retweet.find("a.retweet-submit");
330
			jq_retweet_link.data('json_tweet',json_tweet);
331
			jq_retweet_link.data('jq_textarea',jq_textarea);
332
			jq_cancel_retweet_link = jq_embedded_retweet.find("a.retweet-cancel");
333
			jq_cancel_retweet_link.data('json_tweet',json_tweet);
334
			jq_cancel_retweet_link.data('jq_textarea',jq_textarea);
335
336
			jq_retweet_link.click(function(){
337
				jtweet = j(this).data('json_tweet');
338
				jq_ta = j(this).data('jq_textarea');
339
				j.ajax({
340
					url:'http://twitter.com/statuses/update.json',
341
					type: 'POST',
342
					dataType: 'json',
343
					data:{status:jq_ta.val(),in_reply_to_status_id:jtweet.id},
344
					success:function(data){
345
						jq_ta.parent().remove();
346
						convert_json_tweet_to_html_tweet(data).prependTo("#timeline").show("highlight",{},1000);
347
					}
348
				});
349
				return false;
350
			});
351
352
			jq_cancel_retweet_link.click(function(){
353
				jtweet = j(this).data('json_tweet');
354
				jq_ta = j(this).data('jq_textarea');
355
				jq_ta.parent().effect('scale',{percent:0,direction:'vertical',scale:'box'},300,function(){j(this).remove();});
356
357
				//jq_ta.parent().remove();
358
				return false;
359
			});
360
		}
361
362
	}
363
	function modify_reply_button(tweet,json_tweet)
287
	{
364
	{
288
		tweet.find("a.retweet-link").remove();
365
		//log("Modifying reply button for " + json_tweet.id);
289
		//log("Adding retweet button for "+ json_tweet.id);
366
		tweet.find(".actions .repl").remove();
290
		//log("Adding retweet button for " + json_tweet.id);
367
		tweet.find(".actions .reply").remove();
291
		if(tweet.find(".actions div").length==0)
368
		tweet.find(".actions .reply2").remove();
292
			jq_retweet_link = j("<a class='retweet-link' href='#retweet'>RT</a>").appendTo(tweet.find(".actions"));
369
		if(tweet.find(".actions div").length>0)
370
			jq_reply_link = j("<a class='reply2' href='#reply'></a>").appendTo(tweet.find(".actions div"));
293
		else
371
		else
294
			jq_retweet_link = j("<a class='retweet-link' href='#retweet'>RT</a>").appendTo(tweet.find(".actions div"));
372
			jq_reply_link = j("<a class='reply2' href='#reply'></a>").appendTo(tweet.find(".actions"));
295
373
		jq_reply_link.css({"height":"16px","background-image":"url(http://static.twitter.com/images/icon_reply.gif)"});
296
		jq_retweet_link.data('json_tweet',json_tweet);
374
		jq_reply_link.data('json_tweet',json_tweet);
297
		jq_retweet_link.click(function(){
375
		if(json_tweet.user.screen_name == current_username)
298
			show_embedded_retweet(j(this).data('json_tweet'));
376
		{
377
			log("Removing reply button, as this is the current user's tweet.");
378
			tweet.find(".reply").remove();
379
			tweet.find(".repl").remove();
380
			tweet.find(".reply2").remove();
299
			return false;
381
			return false;
382
		}
383
		//log("Adding reply click-event for: "+jq_reply_link.parent().parent().parent().attr("id"));
384
		jq_reply_link.click(function(){
385
			show_embedded_reply(j(this).data('json_tweet'));
386
			return false;
300
		});
387
		});
301
		//log("Done adding retweet");
388
		//log("Done modifying reply");
302
	}
389
	}
303
	
390
	function show_embedded_reply(json_tweet)
304
}
305
function show_embedded_retweet(json_tweet)
306
{
307
	if(j("li#status_"+json_tweet.id).length>0)
308
		jq_tweet = j("li#status_"+json_tweet.id);
309
	else
310
		jq_tweet = j("#permalink");
311
	
312
	if( jq_tweet.find(".status-body .embedded-retweet").length==0)
313
	{
391
	{
314
		jq_embedded_retweet = j("<div id='retweet_"+json_tweet.id+ "' class='embedded-retweet'><span class='counter'>140</span><br/><textarea  class='retweet-text'></textarea><br/><a class='retweet-submit' href='#'>Retweet this</a><a class='retweet-cancel' href='#'>Cancel</a></div>");
392
		if(j("#status_"+json_tweet.id).length>0)
393
			jq_tweet = j("#status_"+json_tweet.id);
394
		else
395
			jq_tweet = j("#permalink");
396
		if(jq_tweet.find(".status-body .embedded-reply").length==0)
397
		{
398
			jq_embedded_reply = j("<div id='reply_"+json_tweet.id+"' class='embedded-reply'><span class='counter'>140</span><br/><textarea class='reply-text'>@"+json_tweet.user.screen_name+"</textarea><br/><a class='reply-submit' href='#'>Reply</a><a class='reply-cancel' href='#'>Cancel</a></div>");
399
			jq_embedded_reply.appendTo(jq_tweet.find(".status-body")).effect('scale',{from:{height:0},percent:100,scale:'box',direction:'vertical'},300);
400
			jq_textarea = jq_embedded_reply.find("textarea.reply-text");
401
			//jq_textarea.focus(function(){
402
			//	counter_span = j(this).parent().find("span.counter");
403
			//	counter_span.html(140-parseInt(j(this).val().length));
404
			//});
405
			//jq_textarea.focus();
406
			counter_span = jq_textarea.parent().find("span.counter");
407
			counter_span.html(140-parseInt(jq_textarea.val().length));
408
			jq_reply_link = jq_embedded_reply.find("a.reply-submit");
409
			jq_reply_link.data('json_tweet',json_tweet);
410
			jq_reply_link.data('jq_textarea',jq_textarea);
315
411
316
		jq_embedded_retweet.appendTo(jq_tweet.find(".status-body")).effect('scale',{from:{height:0},percent:100,direction:'vertical',scale:'box'},300);
412
			jq_reply_cancel_link = jq_embedded_reply.find("a.reply-cancel");
317
		jq_textarea = jq_embedded_retweet.find("textarea.retweet-text");
413
			jq_reply_cancel_link.data('json_tweet',json_tweet);
318
		//jq_textarea.focus(function(){
414
			jq_reply_cancel_link.data('jq_textarea',jq_textarea);		
319
		//	counter_span = j(this).parent().find("span.counter");
415
320
		//	counter_span.html(140-parseInt(j(this).val().length));
416
			jq_reply_link.click(function(){
321
		//});
417
				jtweet = j(this).data('json_tweet');
322
		counter_span = jq_textarea.parent().find("span.counter");
418
				jq_ta = j(this).data('jq_textarea');
323
		counter_span.html(140-parseInt(jq_textarea.val().length));
419
				log("Replying to @"+jtweet.user.screen_name+"("+jtweet.id+") with: "+jtweet.text)
324
		
420
				j.ajax({
325
		jq_textarea.val("RT @" + json_tweet.user.screen_name + " " + json_tweet.text);
421
					url:'http://twitter.com/statuses/update.json',
326
		jq_retweet_link = jq_embedded_retweet.find("a.retweet-submit");
422
					type:'POST',
327
		jq_retweet_link.data('json_tweet',json_tweet);
423
					dataType:'json',
328
		jq_retweet_link.data('jq_textarea',jq_textarea);
424
					data:{status:jq_ta.val(),in_reply_to_status_id:jtweet.id},
329
		jq_cancel_retweet_link = jq_embedded_retweet.find("a.retweet-cancel");
425
					success:function(data){
330
		jq_cancel_retweet_link.data('json_tweet',json_tweet);
426
						jq_ta.parent().remove();
331
		jq_cancel_retweet_link.data('jq_textarea',jq_textarea);
427
						convert_json_tweet_to_html_tweet(data).prependTo("ol#timeline").show("highlight",{},1000);
332
		
428
					}
333
		jq_retweet_link.click(function(){
429
				});
334
			jtweet = j(this).data('json_tweet');
430
				return false;
335
			jq_ta = j(this).data('jq_textarea');
336
			j.ajax({
337
				url:'http://twitter.com/statuses/update.json',
338
				type: 'POST',
339
				dataType: 'json',
340
				data:{status:jq_ta.val(),in_reply_to_status_id:jtweet.id},
341
				success:function(data){
342
					jq_ta.parent().remove();
343
					convert_json_tweet_to_html_tweet(data).prependTo("#timeline").show("highlight",{},1000);
344
				}
345
			});
431
			});
346
			return false;
432
347
		});
433
			jq_reply_cancel_link.click(function(){
348
		
434
				jtweet = j(this).data('json_tweet');
349
		jq_cancel_retweet_link.click(function(){
435
				jq_ta = j(this).data('jq_textarea');
350
			jtweet = j(this).data('json_tweet');
436
				jq_ta.parent().effect('scale',{percent:0,direction:'vertical',scale:'box'},300,function(){j(this).remove();});
351
			jq_ta = j(this).data('jq_textarea');
437
				//jq_ta.parent().remove();
352
			jq_ta.parent().effect('scale',{percent:0,direction:'vertical',scale:'box'},300,function(){j(this).remove();});
438
				return false;
353
			
439
			});
354
			//jq_ta.parent().remove();
440
		}	
355
			return false;
356
		});
357
	}
441
	}
358
	
442
	function add_twitpic_preview(tweet,json_tweet)
359
}
360
function modify_reply_button(tweet,json_tweet)
361
{
362
	//log("Modifying reply button for " + json_tweet.id);
363
	tweet.find(".actions .repl").remove();
364
	tweet.find(".actions .reply").remove();
365
	tweet.find(".actions .reply2").remove();
366
	if(tweet.find(".actions div").length>0)
367
		jq_reply_link = j("<a class='reply2' href='#reply'></a>").appendTo(tweet.find(".actions div"));
368
	else
369
		jq_reply_link = j("<a class='reply2' href='#reply'></a>").appendTo(tweet.find(".actions"));
370
	jq_reply_link.css({"height":"16px","background-image":"url(http://static.twitter.com/images/icon_reply.gif)"});
371
	jq_reply_link.data('json_tweet',json_tweet);
372
	if(json_tweet.user.screen_name == current_username)
373
	{
443
	{
374
		log("Removing reply button, as this is the current user's tweet.");
444
		tweet.find("a[href^='http://twitpic.com']").each(function(){
375
		tweet.find(".reply").remove();
445
			href = j(this).attr('href');
376
		tweet.find(".repl").remove();
446
			html = "<div class='twitpic-preview'><a href='"+href+"'><img src='"+href+"-thumb'/></a></div>";
377
		tweet.find(".reply2").remove();
447
			j(this).parent().append(html);
378
		return false;
448
		})
379
	}
449
	}
380
	//log("Adding reply click-event for: "+jq_reply_link.parent().parent().parent().attr("id"));
381
	jq_reply_link.click(function(){
382
		show_embedded_reply(j(this).data('json_tweet'));
383
		return false;
384
	});
385
	//log("Done modifying reply");
386
}
387
function show_embedded_reply(json_tweet)
388
{
389
	if(j("#status_"+json_tweet.id).length>0)
390
		jq_tweet = j("#status_"+json_tweet.id);
391
	else
392
		jq_tweet = j("#permalink");
393
	if(jq_tweet.find(".status-body .embedded-reply").length==0)
394
	{
395
		jq_embedded_reply = j("<div id='reply_"+json_tweet.id+"' class='embedded-reply'><span class='counter'>140</span><br/><textarea class='reply-text'>@"+json_tweet.user.screen_name+"</textarea><br/><a class='reply-submit' href='#'>Reply</a><a class='reply-cancel' href='#'>Cancel</a></div>");
396
		jq_embedded_reply.appendTo(jq_tweet.find(".status-body")).effect('scale',{from:{height:0},percent:100,scale:'box',direction:'vertical'},300);
397
		jq_textarea = jq_embedded_reply.find("textarea.reply-text");
398
		//jq_textarea.focus(function(){
399
		//	counter_span = j(this).parent().find("span.counter");
400
		//	counter_span.html(140-parseInt(j(this).val().length));
401
		//});
402
		//jq_textarea.focus();
403
		counter_span = jq_textarea.parent().find("span.counter");
404
		counter_span.html(140-parseInt(jq_textarea.val().length));
405
		jq_reply_link = jq_embedded_reply.find("a.reply-submit");
406
		jq_reply_link.data('json_tweet',json_tweet);
407
		jq_reply_link.data('jq_textarea',jq_textarea);
408
		
409
		jq_reply_cancel_link = jq_embedded_reply.find("a.reply-cancel");
410
		jq_reply_cancel_link.data('json_tweet',json_tweet);
411
		jq_reply_cancel_link.data('jq_textarea',jq_textarea);		
412
		
413
		jq_reply_link.click(function(){
414
			jtweet = j(this).data('json_tweet');
415
			jq_ta = j(this).data('jq_textarea');
416
			log("Replying to @"+jtweet.user.screen_name+"("+jtweet.id+") with: "+jtweet.text)
417
			j.ajax({
418
				url:'http://twitter.com/statuses/update.json',
419
				type:'POST',
420
				dataType:'json',
421
				data:{status:jq_ta.val(),in_reply_to_status_id:jtweet.id},
422
				success:function(data){
423
					jq_ta.parent().remove();
424
					convert_json_tweet_to_html_tweet(data).prependTo("ol#timeline").show("highlight",{},1000);
425
				}
426
			});
427
			return false;
428
		});
429
		
430
		jq_reply_cancel_link.click(function(){
431
			jtweet = j(this).data('json_tweet');
432
			jq_ta = j(this).data('jq_textarea');
433
			jq_ta.parent().effect('scale',{percent:0,direction:'vertical',scale:'box'},300,function(){j(this).remove();});
434
			//jq_ta.parent().remove();
435
			return false;
436
		});
437
	}	
438
}
439
function add_twitpic_preview(tweet,json_tweet)
440
{
441
	tweet.find("a[href^='http://twitpic.com']").each(function(){
442
		href = j(this).attr('href');
443
		html = "<div class='twitpic-preview'><a href='"+href+"'><img src='"+href+"-thumb'/></a></div>";
444
		j(this).parent().append(html);
445
	})
446
}
447
450
448
function modify_delete_button(tweet,json_tweet)
451
	function modify_delete_button(tweet,json_tweet)
449
{
450
	if(current_username == json_tweet.user.screen_name)
451
	{
452
	{
452
		//log("current_username==json_tweet.user.screen_name: "+current_username+" == "+json_tweet.user.screen_name);
453
		if(current_username == json_tweet.user.screen_name)
453
		//http://twitter.com/statuses/destroy/id.json
454
		{
454
		//What's going on here:
455
			//log("current_username==json_tweet.user.screen_name: "+current_username+" == "+json_tweet.user.screen_name);
455
			//I'm finding and removing Twitter's existing delete button, so as to create a new delete button that does not
456
			//http://twitter.com/statuses/destroy/id.json
456
			//use a javascript prompt. Multiple attemps to just "unbind" Twitter's delete button failed. So I had to resort
457
			//What's going on here:
457
			//to hack-ish methods (see below). It works for now.
458
				//I'm finding and removing Twitter's existing delete button, so as to create a new delete button that does not
458
		tweet.find("a.del").remove();
459
				//use a javascript prompt. Multiple attemps to just "unbind" Twitter's delete button failed. So I had to resort
459
		tweet.find("a.delete").remove();
460
				//to hack-ish methods (see below). It works for now.
460
		newDeleteExists = tweet.find("a.delete").length>0;
461
			tweet.find("a.del").remove();
461
		jq_delete_css = {"height":"16px", "background-image":"url(http://static.twitter.com/images/icon_trash.gif)"};
462
			tweet.find("a.delete").remove();
462
		jq_delete = j("<a href='#delete' class='delete'></a>").appendTo(tweet.find(".actions div"));
463
			newDeleteExists = tweet.find("a.delete").length>0;
463
		jq_delete.css(jq_delete_css);
464
			jq_delete_css = {"height":"16px", "background-image":"url(http://static.twitter.com/images/icon_trash.gif)"};
464
		jq_delete.attr('href','#delete');
465
			jq_delete = j("<a href='#delete' class='delete'></a>").appendTo(tweet.find(".actions div"));
465
		jq_delete.data('json_tweet',json_tweet);
466
			jq_delete.css(jq_delete_css);
466
		jq_delete.click(function(){
467
			jq_delete.attr('href','#delete');
467
			j.ajax({
468
			jq_delete.data('json_tweet',json_tweet);
468
				url:"http://twitter.com/statuses/destroy/"+j(this).data('json_tweet').id+".json",
469
			jq_delete.click(function(){
469
				type: "DELETE",
470
				j.ajax({
470
				dataType: "json",
471
					url:"http://twitter.com/statuses/destroy/"+j(this).data('json_tweet').id+".json",
471
				data:{id:j(this).data('json_tweet').id},
472
					type: "DELETE",
473
					dataType: "json",
474
					data:{id:j(this).data('json_tweet').id},
475
				});
476
				tweet.effect('highlight',{color:'#f00'},800,function(){j(this).remove();})
477
				return false;
472
			});
478
			});
473
			tweet.effect('highlight',{color:'#f00'},800,function(){j(this).remove();})
479
		}	
474
			return false;
480
	}
475
		});
481
	function convert_json_tweet_to_html_tweet(json_tweet)
476
	}	
477
}
478
function convert_json_tweet_to_html_tweet(json_tweet)
479
{
480
	jq_tweet_li = j("a.repl").eq(0).parent().parent().parent().clone();
481
	if(jq_tweet_li.length == 0)
482
		jq_tweet_li = j("a.reply").eq(0).parent().parent().parent().clone();
483
	if(jq_tweet_li.length == 0)
484
		jq_tweet_li = j("a.reply2").eq(0).parent().parent().parent().clone();
485
	jq_tweet_li.children(".actions a.reply").attr("class","repl");
486
	jq_tweet_li.children(".actions a.reply2").attr("class","repl");
487
	jq_tweet_li.children(".actions .retweet-link").remove();
488
	jq_tweet_li.find("a:contains('in reply to')").remove();
489
	//log("Using "+jq_tweet_li.attr("id")+" as a template for copy.");
490
	jq_tweet_li.attr("id","status_"+json_tweet.id);
491
	jq_tweet_li.attr("class","hentry status u-"+json_tweet.user.screen_name+(current_username==json_tweet.user.screen_name?" mine":""));
492
	jq_tweet_li.find("span.author a.url").attr("href","http://twitter.com/"+json_tweet.user.screen_name);
493
	jq_tweet_li.find("span.author a.url img.photo").attr("src",json_tweet.user.profile_image_url);
494
	jq_tweet_li.find("span.author a.url img.photo").attr("alt",json_tweet.user.name);
495
	jq_tweet_li.find("span.status-body strong:first a").html(json_tweet.user.screen_name);
496
	jq_tweet_li.find("span.status-body strong:first a").attr('title',json_tweet.user.name);
497
	jq_tweet_li.find("span.status-body strong:first a").attr("href","http://twitter.com/"+json_tweet.user.screen_name);
498
	
499
	jq_tweet_li.find("span.status-body span.entry-content").html(link_up_status_text(json_tweet.text,true,true,true));
500
	jq_tweet_li.find("span.status-body span.entry-meta a.entry-date").attr("href","http://twitter.com/"+json_tweet.user.screen_name+"/status/"+json_tweet.id);
501
	jq_tweet_li.find("span.status-body span.entry-meta a.entry-date span.published").attr("title",format_time(json_tweet.created_at) + " ago"); 
502
	
503
	jq_tweet_li.find("span.status-body span.entry-meta a.entry-date span.published").html( format_time(json_tweet.created_at) + " ago"); 
504
	//jq_tweet_li.find("span.status-body span.entry-meta a.entry-date span.published").timeago();
505
	jq_tweet_li.find("span.status-body span.entry-meta a.entry-date + span").html("from " + json_tweet.source + "&nbsp;");
506
	
507
	jq_tweet_li.find("span.actions div a[id^=status_star]").unbind();
508
	jq_tweet_li.find("span.actions div a[id^=status_star]").attr("id","status_star_"+json_tweet.id);
509
	jq_tweet_li.find("span.actions div a[id^=status_star]").attr("class",(json_tweet.favorited?"fav":"non-fav"));
510
	jq_tweet_li.find("span.actions div a[id^=status_star]").attr("title",(json_tweet.favorited?"favorite this update":"un-favorite this tweet"));
511
	
512
	//log("Adding retweet button, via convert_json method.");
513
	
514
	
515
	jq_tweet_li.find("span.actions div a.retweet-link").unbind();
516
	
517
	jq_tweet_li.find("div.embedded-reply").remove();
518
	jq_tweet_li.find("div.embedded-retweet").remove();
519
	
520
	if(json_tweet.in_reply_to_status_id != null)
521
	{
482
	{
522
		jq_tweet_li.find("span.entry-meta").append("&nbsp;<a href='http://twitter.com/"+json_tweet.in_reply_to_screen_name+"/status/"+json_tweet.in_reply_to_status_id+"'>in reply to "+json_tweet.in_reply_to_screen_name+"</a>")
483
		jq_tweet_li = j("a.repl").eq(0).parent().parent().parent().clone();
484
		if(jq_tweet_li.length == 0)
485
			jq_tweet_li = j("a.reply").eq(0).parent().parent().parent().clone();
486
		if(jq_tweet_li.length == 0)
487
			jq_tweet_li = j("a.reply2").eq(0).parent().parent().parent().clone();
488
		jq_tweet_li.children(".actions a.reply").attr("class","repl");
489
		jq_tweet_li.children(".actions a.reply2").attr("class","repl");
490
		jq_tweet_li.children(".actions .retweet-link").remove();
491
		jq_tweet_li.find("a:contains('in reply to')").remove();
492
		//log("Using "+jq_tweet_li.attr("id")+" as a template for copy.");
493
		jq_tweet_li.attr("id","status_"+json_tweet.id);
494
		jq_tweet_li.attr("class","hentry status u-"+json_tweet.user.screen_name+(current_username==json_tweet.user.screen_name?" mine":""));
495
		jq_tweet_li.find("span.author a.url").attr("href","http://twitter.com/"+json_tweet.user.screen_name);
496
		jq_tweet_li.find("span.author a.url img.photo").attr("src",json_tweet.user.profile_image_url);
497
		jq_tweet_li.find("span.author a.url img.photo").attr("alt",json_tweet.user.name);
498
		jq_tweet_li.find("span.status-body strong:first a").html(json_tweet.user.screen_name);
499
		jq_tweet_li.find("span.status-body strong:first a").attr('title',json_tweet.user.name);
500
		jq_tweet_li.find("span.status-body strong:first a").attr("href","http://twitter.com/"+json_tweet.user.screen_name);
501
502
		jq_tweet_li.find("span.status-body span.entry-content").html(link_up_status_text(json_tweet.text,true,true,true));
503
		jq_tweet_li.find("span.status-body span.entry-meta a.entry-date").attr("href","http://twitter.com/"+json_tweet.user.screen_name+"/status/"+json_tweet.id);
504
		jq_tweet_li.find("span.status-body span.entry-meta a.entry-date span.published").attr("title",format_time(json_tweet.created_at) + " ago"); 
505
506
		jq_tweet_li.find("span.status-body span.entry-meta a.entry-date span.published").html( format_time(json_tweet.created_at) + " ago"); 
507
		//jq_tweet_li.find("span.status-body span.entry-meta a.entry-date span.published").timeago();
508
		jq_tweet_li.find("span.status-body span.entry-meta a.entry-date + span").html("from " + json_tweet.source + "&nbsp;");
509
510
		jq_tweet_li.find("span.actions div a[id^=status_star]").unbind();
511
		jq_tweet_li.find("span.actions div a[id^=status_star]").attr("id","status_star_"+json_tweet.id);
512
		jq_tweet_li.find("span.actions div a[id^=status_star]").attr("class",(json_tweet.favorited?"fav":"non-fav"));
513
		jq_tweet_li.find("span.actions div a[id^=status_star]").attr("title",(json_tweet.favorited?"favorite this update":"un-favorite this tweet"));
514
515
		//log("Adding retweet button, via convert_json method.");
516
517
518
		jq_tweet_li.find("span.actions div a.retweet-link").unbind();
519
520
		jq_tweet_li.find("div.embedded-reply").remove();
521
		jq_tweet_li.find("div.embedded-retweet").remove();
522
523
		if(json_tweet.in_reply_to_status_id != null)
524
		{
525
			jq_tweet_li.find("span.entry-meta").append("&nbsp;<a href='http://twitter.com/"+json_tweet.in_reply_to_screen_name+"/status/"+json_tweet.in_reply_to_status_id+"'>in reply to "+json_tweet.in_reply_to_screen_name+"</a>")
526
		}
527
		//find_reply_to_me_in_tweet_and_set_to_me_class(jq_tweet_li);
528
		return jq_tweet_li;
523
	}
529
	}
524
	//find_reply_to_me_in_tweet_and_set_to_me_class(jq_tweet_li);
530
	function determine_what_page_user_is_on()
525
	return jq_tweet_li;
526
}
527
function determine_what_page_user_is_on()
528
{
529
	reUrlSplitUp=/https?:\/\/(?:www\.)?twitter.com\/([\w\d]+)(?:\/(statuses)\/(\d+))?(?:\?page=(\d+))?/.exec(location.href);
530
	// 1: directory right after twitter.com (ie: home or carl_furrow, etc)
531
	// 2: the word "statuses" if in the url (what did I want to use this for?)
532
	// 3: the status id
533
	// 4: Page number
534
		
535
	if(reUrlSplitUp == null)
536
		onNonProcessingPage=true;
537
	else
538
	{
531
	{
539
		if(reUrlSplitUp[1]=="blocks" || reUrlSplitUp[1] == "account" || reUrlSplitUp[1] == "followers" || reUrlSplitUp[1] == "friends")
532
		reUrlSplitUp=/https?:\/\/(?:www\.)?twitter.com\/([\w\d]+)(?:\/(statuses)\/(\d+))?(?:\?page=(\d+))?/.exec(location.href);
540
		{
533
		// 1: directory right after twitter.com (ie: home or carl_furrow, etc)
534
		// 2: the word "statuses" if in the url (what did I want to use this for?)
535
		// 3: the status id
536
		// 4: Page number
537
538
		if(reUrlSplitUp == null)
541
			onNonProcessingPage=true;
539
			onNonProcessingPage=true;
542
			return;
540
		else
543
		}
544
			
545
		log("reUrlSplitUp[1]: "+reUrlSplitUp[1]+" reUrlSplitUp[2]: "+reUrlSplitUp[2]+" reUrlSplitUp[3]: "+reUrlSplitUp[3]+" reUrlSplitUp[4]: "+reUrlSplitUp[4]);
546
		if(reUrlSplitUp[1] != null && reUrlSplitUp[1] == "home")
547
			onTwitterFriendFeed=true;
548
		else if(reUrlSplitUp[1] != null && reUrlSplitUp[1] != "home")
549
		{
541
		{
550
			if(reUrlSplitUp[3] !=  null)
542
			if(reUrlSplitUp[1]=="blocks" || reUrlSplitUp[1] == "account" || reUrlSplitUp[1] == "followers" || reUrlSplitUp[1] == "friends")
551
				onTwitterIndividualTweet=true;
552
			else
553
			{
543
			{
554
				onTwitterUsersProfile=true;
544
				onNonProcessingPage=true;
555
				top_profile_link_name = /https?:\/\/twitter.com\/([\w\d]+)/.exec(j.trim(j("#navigation .top-nav #profile_link").attr("href")))[1];
545
				return;
556
				user_name = j.trim(j("#content .wrapper h2.thumb").text());
557
				log('(determine page)user_name:'+ user_name);
558
				log('(determine page)top_profile_link username: '+top_profile_link_name)
559
				if(top_profile_link_name == user_name)
560
					onOwnProfilePage=true;
561
			}
546
			}
562
547
548
			log("reUrlSplitUp[1]: "+reUrlSplitUp[1]+" reUrlSplitUp[2]: "+reUrlSplitUp[2]+" reUrlSplitUp[3]: "+reUrlSplitUp[3]+"
reUrlSplitUp[4]: "+reUrlSplitUp[4]);
549
			if(reUrlSplitUp[1] != null && reUrlSplitUp[1] == "home")
550
				onTwitterFriendFeed=true;
551
			else if(reUrlSplitUp[1] != null && reUrlSplitUp[1] != "home")
552
			{
553
				if(reUrlSplitUp[3] !=  null)
554
					onTwitterIndividualTweet=true;
555
				else
556
				{
557
					onTwitterUsersProfile=true;
558
					top_profile_link_name = /https?:\/\/twitter.com\/([\w\d]+)/.exec(j.trim(j("#navigation .top-nav #profile_link").attr("href")))[1];
559
					user_name = j.trim(j("#content .wrapper h2.thumb").text());
560
					log('(determine page)user_name:'+ user_name);
561
					log('(determine page)top_profile_link username: '+top_profile_link_name)
562
					if(top_profile_link_name == user_name)
563
						onOwnProfilePage=true;
564
				}
565
566
			}
567
			if(reUrlSplitUp[4] != null && reUrlSplitUp[4].length > 0)
568
				pageNumber = reUrlSplitUp[4];
569
		}	
570
		log("onNonProcessingPage: "+onNonProcessingPage+" onTwitterFriendFeed: "+onTwitterFriendFeed+"
onTwitterIndividualTweets:"+onTwitterIndividualTweet+" onTwitterUsersProfile: "+onTwitterUsersProfile);
571
	}
572
	function add_counter_to_textareas()
573
	{
574
		j("textarea.reply-text").live("keyup",function(e){
575
			counter_span = j(this).parent().find("span.counter");
576
			counter_span.html(140-parseInt(j(this).val().length));
577
		})
578
		j("textarea.retweet-text").live("keyup",function(e){
579
			counter_span = j(this).parent().find("span.counter");
580
			counter_span.html(140-parseInt(j(this).val().length));
581
		});
582
	}
583
	function link_up_status_text(statustext, linkUrls, linkReplies, linkHashes)
584
	{
585
		//log("Linking: "+text);
586
		newtext = statustext;
587
		if(newtext != null)
588
		{
589
			if(linkUrls)
590
				newtext = newtext.replace(/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:\/~\+#]*[\w\-\@?^=%&amp;\/~\+#])?/gi,"<a
href='$&'>$&</a>"); //from http://regexlib.com/REDetails.aspx?regexp_id=96
591
			if(linkReplies)
592
				newtext = newtext.replace(/@([^\s<]+)[\.,\?!]?/gi,"@<a href='http://twitter.com/$1'>$1</a>");
593
			if(linkHashes)
594
				newtext = newtext.replace(/#([^\s<]+)[\.,\?!]?/gi,"#<a href='http://hashtags.org/tag/$1'>$1</a>");	
563
		}
595
		}
564
		if(reUrlSplitUp[4] != null && reUrlSplitUp[4].length > 0)
596
		return newtext;
565
			pageNumber = reUrlSplitUp[4];
597
	}
566
	}	
598
	//helluva function name--bad practice on my part :)
567
	log("onNonProcessingPage: "+onNonProcessingPage+" onTwitterFriendFeed: "+onTwitterFriendFeed+" onTwitterIndividualTweets:"+onTwitterIndividualTweet+" onTwitterUsersProfile: "+onTwitterUsersProfile);
599
	function find_reply_to_me_in_tweet_and_set_to_me_class(jqTweet)
568
}
569
function add_counter_to_textareas()
570
{
571
	j("textarea.reply-text").live("keyup",function(e){
572
		counter_span = j(this).parent().find("span.counter");
573
		counter_span.html(140-parseInt(j(this).val().length));
574
	})
575
	j("textarea.retweet-text").live("keyup",function(e){
576
		counter_span = j(this).parent().find("span.counter");
577
		counter_span.html(140-parseInt(j(this).val().length));
578
	});
579
}
580
function link_up_status_text(statustext, linkUrls, linkReplies, linkHashes)
581
{
582
	//log("Linking: "+text);
583
	newtext = statustext;
584
	if(newtext != null)
585
	{
600
	{
586
		if(linkUrls)
601
		text = jqTweet.find(".status-body .entry-content").html();
587
			newtext = newtext.replace(/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:\/~\+#]*[\w\-\@?^=%&amp;\/~\+#])?/gi,"<a href='$&'>$&</a>"); //from http://regexlib.com/REDetails.aspx?regexp_id=96
602
		if(text != null)
588
		if(linkReplies)
603
			if(text.indexOf(current_username) != -1 && jqTweet.attr("class").indexOf("to_me") == -1)
589
			newtext = newtext.replace(/@([^\s<]+)[\.,\?!]?/gi,"@<a href='http://twitter.com/$1'>$1</a>");
604
				jqTweet.attr("class",jqTweet.attr("class")+" to_me");
590
		if(linkHashes)
591
			newtext = newtext.replace(/#([^\s<]+)[\.,\?!]?/gi,"#<a href='http://hashtags.org/tag/$1'>$1</a>");	
592
	}
605
	}
593
	return newtext;
606
	function add_bottom_actionbar()
594
}
607
	{
595
//helluva function name--bad practice on my part :)
608
		log('Adding bottom actionbar');
596
function find_reply_to_me_in_tweet_and_set_to_me_class(jqTweet)
609
		html="<div class='bottom-actionbar'></div>";
597
{
610
		j("body").append(html);
598
	text = jqTweet.find(".status-body .entry-content").html();
611
		log('Actionbar appended');
599
	if(text != null)
612
	}
600
		if(text.indexOf(current_username) != -1 && jqTweet.attr("class").indexOf("to_me") == -1)
613
	function add_update_notification()
601
			jqTweet.attr("class",jqTweet.attr("class")+" to_me");
614
	{
602
}
615
		//http://userscripts.org/scripts/source/41387.user.js
603
function add_bottom_actionbar()
616
		xhr({
604
{
617
			method:"HEAD",
605
	log('Adding bottom actionbar');
618
			url:"http://userscripts.org/scripts/source/41387.user.js",
606
	html="<div class='bottom-actionbar'></div>";
619
			headers: { 'Accept-Encoding': '' }, //Thanks Mislav
607
	j("body").append(html);
620
			onload:function(response){
608
	log('Actionbar appended');
621
				//log("Response from userscripts.org: "+response.responseHeaders);
609
}
622
				scriptLength = response.responseHeaders.match(/Content-Length: (\d+)/)[1];
610
function add_update_notification()
623
				log("Got script, length: "+scriptLength);
611
{
624
				if(current_script_length != scriptLength)
612
	//http://userscripts.org/scripts/source/41387.user.js
625
				{
613
	xhr({
626
					//show update link
614
		method:"HEAD",
627
					j("<div><a href='http://userscripts.org/scripts/show/41387'>*Update to Twitter Fantastico is available*</a></div>").prependTo("td#content .wrapper");
615
		url:"http://userscripts.org/scripts/source/41387.user.js",
628
				}
616
		headers: { 'Accept-Encoding': '' }, //Thanks Mislav
617
		onload:function(response){
618
			//log("Response from userscripts.org: "+response.responseHeaders);
619
			scriptLength = response.responseHeaders.match(/Content-Length: (\d+)/)[1];
620
			log("Got script, length: "+scriptLength);
621
			if(current_script_length != scriptLength)
622
			{
623
				//show update link
624
				j("<div><a href='http://userscripts.org/scripts/show/41387'>*Update to Twitter Fantastico is available*</a></div>").prependTo("td#content .wrapper");
625
			}
629
			}
630
		});		
631
	}
632
	function page_css()
633
	{
634
		css = "div.embedded-retweet textarea, div.embedded-reply textarea{width:95%;font-family:arial;font-size:95%;height:125px;} li.hentry{min-height:60px;}
span.counter{ float:right; font-weight:bold; position:relative; right:20px; color:#000;} a.retweet-link{text-indent:0px !important;} .twitpic-preview{}";
635
		mine_css = "ol.statuses li.mine:hover{background-color:#99CC99;} .mine{background-color:#CCFFCC;}li.mine .meta, li.mine .meta a{color:#666;}";
636
		to_me_css = "ol.statuses li.to_me:hover{background-color:#eecc44;} div.embedded-retweet a, div.embedded-reply a{margin:0 10px 0 0;} .to_me, .to_me
.entry-content{background-color:#FFDD99;background: #FFDD99 none repeat scroll 0 0 !important;}li.to_me .meta, li.to_me .meta a{color:#666;}";
637
		bottom_actionbar_css = ".bottom-actionbar{ position:fixed; background-color:#333; bottom:0; color:#fff; height:25px; padding:0 20px 0 20px; width:100%;
z-index:5; }";
638
		css += bottom_actionbar_css;
639
		if(onTwitterIndividualTweet)
640
		{
641
			return css;
626
		}
642
		}
627
	});		
643
		else
628
}
644
		{
629
function page_css()
645
			if(!onOwnProfilePage)
630
{
646
				return css+=mine_css + to_me_css;
631
	css = "div.embedded-retweet textarea, div.embedded-reply textarea{width:95%;font-family:arial;font-size:95%;height:125px;} li.hentry{min-height:60px;} span.counter{ float:right; font-weight:bold; position:relative; right:20px; color:#000;} a.retweet-link{text-indent:0px !important;} .twitpic-preview{}";
647
			else
632
	mine_css = "ol.statuses li.mine:hover{background-color:#99CC99;} .mine{background-color:#CCFFCC;}li.mine .meta, li.mine .meta a{color:#666;}";
648
				return css;
633
	to_me_css = "ol.statuses li.to_me:hover{background-color:#eecc44;} div.embedded-retweet a, div.embedded-reply a{margin:0 10px 0 0;} .to_me, .to_me .entry-content{background-color:#FFDD99;background: #FFDD99 none repeat scroll 0 0 !important;}li.to_me .meta, li.to_me .meta a{color:#666;}";
649
		}
634
	bottom_actionbar_css = ".bottom-actionbar{ position:fixed; background-color:#333; bottom:0; color:#fff; height:25px; padding:0 20px 0 20px; width:100%; z-index:5; }";
650
	}
635
	css += bottom_actionbar_css;
651
	function format_time(t)
636
	if(onTwitterIndividualTweet)
637
	{
652
	{
638
		return css;
653
		log("Time: "+t);
654
		return relativeTime(new Date(t));
639
	}
655
	}
640
	else
656
	function getCookieSession()
641
	{
657
	{
642
		if(!onOwnProfilePage)
658
		r = /_twitter_sess=([^\s;]+)/;
643
			return css+=mine_css + to_me_css;
659
		return r.exec(document.cookie.toString())[0];
644
		else
645
			return css;
646
	}
660
	}
647
}
661
	// stolen from twitter.com (hope you guys don't mind)
648
function format_time(t)
662
	function relativeTime(date, relativeTo) {
649
{
663
	  if (!relativeTo) relativeTo = new Date();
650
	log("Time: "+t);
664
	  var delta = (relativeTo.getTime() - date.getTime()) / 1000
651
	return relativeTime(new Date(t));
665
	  if (delta < 5) return 'less than 5 seconds'
652
}
666
	  else if (delta < 10)  return 'less than 10 seconds'
653
function getCookieSession()
667
	  else if (delta < 20)  return 'less than 20 seconds'
654
{
668
	  else if (delta < 60)  return 'less than a minute'
655
	r = /_twitter_sess=([^\s;]+)/;
669
	  else if (delta < 120) return 'about a minute'
656
	return r.exec(document.cookie.toString())[0];
670
	  else if (delta < (60*60))    return Math.round(delta / 60) + ' minutes'
657
}
671
	  else if (delta < (120*60))   return 'about an hour'
658
// stolen from twitter.com (hope you guys don't mind)
672
	  else if (delta < (24*60*60)) return 'about ' + Math.round(delta / 3600) + ' hours'
659
function relativeTime(date, relativeTo) {
673
	  else if (delta < (48*60*60)) return '1 day'
660
  if (!relativeTo) relativeTo = new Date();
674
	  else return Math.round(delta / 86400) + ' days'
661
  var delta = (relativeTo.getTime() - date.getTime()) / 1000
675
	}
662
  if (delta < 5) return 'less than 5 seconds'
676
	function log(msg)
663
  else if (delta < 10)  return 'less than 10 seconds'
677
	{
664
  else if (delta < 20)  return 'less than 20 seconds'
678
		if(debug)
665
  else if (delta < 60)  return 'less than a minute'
679
			GM_log(msg);
666
  else if (delta < 120) return 'about a minute'
680
	}	
667
  else if (delta < (60*60))    return Math.round(delta / 60) + ' minutes'
681
}();
668
  else if (delta < (120*60))   return 'about an hour'
669
  else if (delta < (24*60*60)) return 'about ' + Math.round(delta / 3600) + ' hours'
670
  else if (delta < (48*60*60)) return '1 day'
671
  else return Math.round(delta / 86400) + ' days'
672
}
673
function log(msg)
674
{
675
	if(debug)
676
		GM_log(msg);
677
}