Changeset 330

User picture

Author: Gustavo Carreno

(2011/01/01 04:57) Over 1 year ago

Forgot to copy code onto the new version.

Affected files

Updated trunk/chrome/content/stackoverflowbarNew.js Download diff

329330
5
	org.gcarreno = {};
5
	org.gcarreno = {};
6
}
6
}
7
7
8
if (typeof org.gcarreno.StackOverflowBar == 'undefined') {
8
org.gcarreno.jSapiens = {
9
	org.gcarreno.StackOverflowBar = {
9
	_mainURL: "http://api.stackoverflow.com/",
10
		searchHistory: Components.classes["@mozilla.org/satchel/form-history;1"]
10
	_apiVer: "1.0",
11
						.getService(Components.interfaces.nsIFormHistory2 || Components.interfaces.nsIFormHistory),
11
	_key: "[PLEASE CHANGE ME!]",
12
		oneTime: false,
12
	
13
		Strings: {
13
	_req: Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]  
14
			Constants: {
14
		  .createInstance(Components.interfaces.nsIXMLHttpRequest),
15
				Protocol: "http",
15
	
16
				Host: "stackoverflow.com",
16
	_console: Components.classes['@mozilla.org/consoleservice;1']
17
				Ask: "/questions/ask",
17
			  .getService(Components.interfaces.nsIConsoleService),
18
				Home: {
18
			  
19
					Active: "/?tab=active",
19
	init: function(){
20
					Featured: "/?tab=featured",
20
		this.Log('init()');
21
					Hot: "/?tab=hot",
21
		this.answers._parent = this;
22
					Week: "/?tab=week",
22
		this.questions._parent = this;
23
					Month: "/?tab=month"
23
		this.users._parent = this;
24
				},
24
		return 0;
25
				Questions: {
25
	},
26
					Newest: "/questions?sort=newest",
26
	API: {
27
					Featured: "/questions?sort=featured",
27
		User: "/users",
28
					Hot: "/questions?sort=hot",
28
		UserQuestions: "",
29
					Votes: "/questions?sort=votes",
29
		UserAnswers: "",
30
					Active: "/questions?sort=active"					
30
		UserFavorites: "",
31
				},
31
		UserReputation: "",
32
				UnAnswered: {
32
		UserRecent: "",
33
					MyTags: "/unanswered/tagged?tab=mytags",
33
		UserFlair: ""
34
					Newest: "/unanswered/tagged?tab=newest",
34
	},
35
					Votes: "/unanswered/tagged?tab=votes"
35
	
36
				},
36
	answers: {
37
				User: {
37
		_parent: null,
38
					Stats: "/users/%s?tab=stats#tab-top",
38
		find: function(answerList) {
39
					Activity: "/users/%s?tab=activity#tab-top",
39
			this._parent.Log('answers.find(' + answerList + ')');
40
					Reputation: "/users/%s?tab=reputationhistory#tab-top",
40
			var text = null;
41
					Favorites: "/users/%s?tab=favorites#tab-top",
41
			if (answerList != 0 || answerList != null) {
42
					Preferences: "/users/%s?tab=preferences#tab-top",
42
				var url = this._parent._mainURL + this._parent._apiVer + "/answers/" + answerList;
43
					Accounts: "/users/%s?tab=accounts#tab-top",
43
				if (text = this._parent.Get(url)){
44
					
44
					return this._parent.JSONDecode(text);
45
					Recent: "/users/recent/%s?tab=summary#tab-top",
46
					RecentRep: "/users/recent/%s?tab=reputation#tab-top",
47
					Responses: "/users/recent/%s?tab=responses#tab-top",
48
					Revisions: "/users/recent/%s?tab=revisions#tab-top",
49
					Badges: "/users/recent/%s?tab=badges#tab-top"
50
				}
45
				}
51
			},
52
			Buttons: {
53
				Search: "button_search",
54
				Ask: "button_ask",
55
				TabActive: "button_tab_active",
56
				TabFeatured: "button_tab_featured",
57
				TabHot: "button_tab_hot",
58
				TabWeek: "button_tab_week",
59
				TabMonth: "button_tab_month",
60
				Featured: "button_featured",
61
				New: "button_new",
62
				Hot: "button_hot",
63
				Votes: "button_votes",
64
				Active: "button_active",
65
				TabMyTags: "button_tab_mytags",
66
				TabNewest: "button_tab_newest",
67
				TabVotes: "button_tab_votes",
68
				UserStats: "button_user_stats",
69
				UserActivity: "button_user_actvity",
70
				UserReputation: "button_user_reputation",
71
				UserFavorites: "button_user_favorites",
72
				UserPreferences: "button_user_preferences",
73
				UserAccounts: "button_user_accounts",
74
				
75
				UserRecentSummary: "button_user_recent_summary",
76
				UserRecentReputation: "button_user_recent_reputation",
77
				UserRecentResponses: "button_user_recent_responses",
78
				UserRecentRevisions: "button_user_recent_revisions",
79
				UserRecentBadges: "button_user_recent_badges",
80
				ShowOptions: "button_show_options",
81
				ShowOverview: "button_show_overview",
82
				Test: "button_test"
83
			},
84
			Options: {
85
				SearchInTab: "search_in_tab",
86
				ButtonsInTab: "buttons_in_tab",
87
				UseAPI: "use_api",
88
				UserID: "user_id"
89
			}
46
			}
47
			return this._parent.JSONDecode("{[]}");
90
		},
48
		},
91
		Search: function (event, type) {
49
		comments: function(anserList) {
92
		    this.Utils.Log('Entering Search: ' + type);
50
			this._parent.Log('answers.comments(' + answerList + ')');
93
		    var URL = "";
51
			var text = null;
94
		    var isEmpty = false;
52
			if (answerList != 0 || answerList != null) {
95
			var searchTerms = this.Utils.TrimString(this.GetTerms());
53
				var url = this._parent._mainURL + this._parent._apiVer + "/answers/" + answerList + '/comments';
96
		    if (searchTerms.length == 0) {
54
				if (text = this._parent.Get(url)){
97
				isEmpty = true;
55
					return this._parent.JSONDecode(text);
98
			} else {
56
				}
99
				this.searchHistory.addEntry("SOB-SearchTerms-History", searchTerms);
100
				searchTerms = this.Utils.ConvertTermsToURI(searchTerms);
101
			}
57
			}
102
		
58
			return this._parent.JSONDecode("{[]}");
103
		    switch(type)
59
		}
104
		    {
60
	},
105
		        case "sob_search":
61
	
106
		            if(!isEmpty) {
62
	questions: {
107
		                URL = this.Strings.Constants.Protocol + "://" + 
63
		_parent: null,
108
		                      this.Strings.Constants.Host + "/search?q=" + 
64
		find: function(questionList) {
109
		                      searchTerms;
65
			this._parent.Log('questions.find(' + questionList + ')');
110
		            }
66
			var text = null;
111
		            break;
67
			if (questionList != 0 || questionList != null) {
112
		    }
68
				var url = this._parent._mainURL + this._parent._apiVer + "/questions/" + questionList;
113
		    if (!isEmpty) {
69
				if (text = this._parent.Get(url)){
114
				this.Utils.LoadURL(URL, this.Utils.GetOption(this.Strings.Options.SearchInTab, "bool"));
70
					return this._parent.JSONDecode(text);
71
				}
115
			}
72
			}
73
			return this._parent.JSONDecode("{[]}");
116
		},
74
		},
117
		SearchTermsTextEntered: function (param){
75
		answers: function(questionList) {
118
		    this.Utils.Log('Entering SearchTermsTextEntered');
76
			this._parent.Log('questions.answers(' + questionList + ')');
119
			this.Search(null, 'sob_search');
77
			var text = null;
78
			if (questionList != 0 || questionList != null) {
79
				var url = this._parent._mainURL + this._parent._apiVer + "/questions/" + questionList + '/answers';
80
				if (text = this._parent.Get(url)){
81
					return this._parent.JSONDecode(text);
82
				}
83
			}
84
			return this._parent.JSONDecode("{[]}");
85
		}
86
	},
87
	
88
	users: {
89
		_parent: null,
90
		find: function(userList){
91
			this._parent.Log('users.find(' + userList + ')');
92
			return this._parent.JSONDecode("{[]}");
120
		},
93
		},
121
		GetTerms: function () {
94
		answers: function(userList){
122
		    this.Utils.Log('Entering GetTerms');
95
			this._parent.Log('users.answers(' + userList + ')');
123
			var terms = document.getElementById("SOB-SearchTerms");
96
			return this._parent.JSONDecode("{[]}");
124
			return terms.value;
125
		},
97
		},
126
		SetTerms: function (newTerms) {
98
		timeline: function (userList){
127
		    this.Utils.Log('Entering SetTerms');
99
			this._parent.Log('users.timeline(' + userList + ')');
128
			var terms = document.getElementById("SOB-SearchTerms");
100
			var text = null;
129
			terms.value = newTerms;
101
			if (userList != 0 || userList != null) {
102
				var url = this._parent._mainURL + this._parent._apiVer + "/users/" + userList + '/timeline';
103
				if (text = this._parent.Get(url)){
104
					return this._parent.JSONDecode(text);
105
				}
106
			}
107
			return this._parent.JSONDecode("{[]}");
108
		}
109
	},
110
	
111
	Get: function(url){
112
		this.Log('Get: "' + url + '"');
113
		this._req.open('GET', url, false);
114
		this._req.send(null);
115
		
116
		if (this._req.status == 200) {
117
			return this._req.responseText;
118
		}
119
		return 0;
120
	},
121
	
122
	JSONDecode: function(json){
123
			var JSON = Components.classes["@mozilla.org/dom/json;1"]
124
						.createInstance(Components.interfaces.nsIJSON);
125
						
126
			return JSON.decode(json);
127
	},
128
	
129
	Log: function (aMessage) {
130
		this._console.logStringMessage('jSapiens: ' + aMessage);
131
	}
132
}
133
134
org.gcarreno.StackOverflowBar = {
135
	searchHistory: Components.classes["@mozilla.org/satchel/form-history;1"]
136
				   .getService(Components.interfaces.nsIFormHistory2 || Components.interfaces.nsIFormHistory),
137
	_first_run: null,
138
	JSON: null,
139
	Preferences: null,
140
	Strings: {
141
		Constants: {
142
			Protocol: "http",
143
			Host: "stackoverflow.com",
144
			Ask: "/questions/ask",
145
			Home: {
146
				Active: "/?tab=active",
147
				Featured: "/?tab=featured",
148
				Hot: "/?tab=hot",
149
				Week: "/?tab=week",
150
				Month: "/?tab=month"
151
			},
152
			Questions: {
153
				Newest: "/questions?sort=newest",
154
				Featured: "/questions?sort=featured",
155
				Hot: "/questions?sort=hot",
156
				Votes: "/questions?sort=votes",
157
				Active: "/questions?sort=active"					
158
			},
159
			UnAnswered: {
160
				MyTags: "/unanswered/tagged?tab=mytags",
161
				Newest: "/unanswered/tagged?tab=newest",
162
				Votes: "/unanswered/tagged?tab=votes"
163
			},
164
			User: {
165
				Stats: "/users/%s?tab=stats#tab-top",
166
				Activity: "/users/%s?tab=activity#tab-top",
167
				Reputation: "/users/%s?tab=reputationhistory#tab-top",
168
				Favorites: "/users/%s?tab=favorites#tab-top",
169
				Preferences: "/users/%s?tab=preferences#tab-top",
170
				Accounts: "/users/%s?tab=accounts#tab-top",
171
				
172
				Recent: "/users/recent/%s?tab=summary#tab-top",
173
				RecentRep: "/users/recent/%s?tab=reputation#tab-top",
174
				Responses: "/users/recent/%s?tab=responses#tab-top",
175
				Revisions: "/users/recent/%s?tab=revisions#tab-top",
176
				Badges: "/users/recent/%s?tab=badges#tab-top"
177
			}
130
		},
178
		},
131
		ButtonClick: function (buttonName) {
179
		Buttons: {
132
		    this.Utils.Log('Entering ButtonClick: ' + buttonName);
180
			Search: "button_search",
181
			Ask: "button_ask",
182
			TabActive: "button_tab_active",
183
			TabFeatured: "button_tab_featured",
184
			TabHot: "button_tab_hot",
185
			TabWeek: "button_tab_week",
186
			TabMonth: "button_tab_month",
187
			Featured: "button_featured",
188
			New: "button_new",
189
			Hot: "button_hot",
190
			Votes: "button_votes",
191
			Active: "button_active",
192
			TabMyTags: "button_tab_mytags",
193
			TabNewest: "button_tab_newest",
194
			TabVotes: "button_tab_votes",
195
			UserStats: "button_user_stats",
196
			UserActivity: "button_user_actvity",
197
			UserReputation: "button_user_reputation",
198
			UserFavorites: "button_user_favorites",
199
			UserPreferences: "button_user_preferences",
200
			UserAccounts: "button_user_accounts",
133
			
201
			
134
			const buttons = this.Strings.Buttons;
202
			UserRecentSummary: "button_user_recent_summary",
135
			const consts = this.Strings.Constants;
203
			UserRecentReputation: "button_user_recent_reputation",
136
			const homepage = consts.Home;
204
			UserRecentResponses: "button_user_recent_responses",
137
			const questions = consts.Questions;
205
			UserRecentRevisions: "button_user_recent_revisions",
138
			const unanswered = consts.UnAnswered;
206
			UserRecentBadges: "button_user_recent_badges",
139
			const user = consts.User;
207
			ShowOptions: "button_show_options",
140
			const opts = this.Strings.Options;
208
			ShowOverview: "button_show_overview"
141
			
142
			var loadURL = this.Utils.LoadURL;
143
			
144
			var inNewTab = this.Utils.GetOption(opts.ButtonsInTab, "bool");
145
			var userID = this.Utils.GetOption(opts.UserID, "string");
146
			
147
			switch (buttonName) {
148
				case buttons.Ask:
149
					loadURL(consts.Protocol + "://" +
150
					        consts.Host + consts.Ask, inNewTab);
151
					break;
152
				case buttons.TabActive:
153
					loadURL(consts.Protocol + "://" +
154
					        consts.Host + homepage.Active, inNewTab);
155
				    break;
156
				case buttons.TabFeatured:
157
					loadURL(consts.Protocol + "://" +
158
					        consts.Host + homepage.Featured, inNewTab);
159
				    break;
160
				case buttons.TabHot:
161
					loadURL(consts.Protocol + "://" +
162
					        consts.Host + homepage.Hot, inNewTab);
163
				    break;
164
				case buttons.TabWeek:
165
					loadURL(consts.Protocol + "://" +
166
					        consts.Host + homepage.Week, inNewTab);
167
				    break;
168
				case buttons.TabMonth:
169
					loadURL(consts.Protocol + "://" +
170
					        consts.Host + homepage.Month, inNewTab);
171
				    break;
172
				case buttons.New:
173
					loadURL(consts.Protocol + "://" +
174
					        consts.Host + questions.Newest, inNewTab);
175
					break;
176
				case buttons.Featured:
177
					loadURL(consts.Protocol + "://" +
178
					        consts.Host + questions.Featured, inNewTab);
179
				    break;
180
				case buttons.Hot:
181
					loadURL(consts.Protocol + "://" +
182
					        consts.Host + questions.Hot, inNewTab);
183
					break;
184
				case buttons.Votes:
185
					loadURL(consts.Protocol + "://" +
186
					        consts.Host + questions.Votes, inNewTab);
187
					break;
188
				case buttons.Active:
189
					loadURL(consts.Protocol + "://" +
190
					        consts.Host + questions.Active, inNewTab);
191
					break;
192
				case buttons.TabMyTags:
193
					loadURL(consts.Protocol + "://" +
194
					        consts.Host + unanswered.MyTags, inNewTab);
195
					break;
196
				case buttons.TabNewest:
197
					loadURL(consts.Protocol + "://" +
198
					        consts.Host + unanswered.Newest, inNewTab);
199
					break;
200
				case buttons.TabVotes:
201
					loadURL(consts.Protocol + "://" +
202
					        consts.Host + unanswered.Votes, inNewTab);
203
					break;
204
				case buttons.UserStats:
205
					loadURL(consts.Protocol + "://" +
206
					        consts.Host + this.Utils.sprintf(user.Stats, userID), inNewTab);
207
					break;
208
				case buttons.UserActivity:
209
					loadURL(consts.Protocol + "://" +
210
					        consts.Host + this.Utils.sprintf(user.Activity, userID), inNewTab);
211
					break;
212
				case buttons.UserReputation:
213
					loadURL(consts.Protocol + "://" +
214
					        consts.Host + this.Utils.sprintf(user.Reputation, userID), inNewTab);
215
					break;
216
				case buttons.UserFavorites:
217
					loadURL(consts.Protocol + "://" +
218
					        consts.Host + this.Utils.sprintf(user.Favorites, userID), inNewTab);
219
					break;
220
				case buttons.UserPreferences:
221
					loadURL(consts.Protocol + "://" +
222
					        consts.Host + this.Utils.sprintf(user.Preferences, userID), inNewTab);
223
					break;
224
				case buttons.UserAccounts:
225
					loadURL(consts.Protocol + "://" +
226
					        consts.Host + this.Utils.sprintf(user.Accounts, userID), inNewTab);
227
					break;
228
				case buttons.UserRecentSummary:
229
					loadURL(consts.Protocol + "://" +
230
					        consts.Host + this.Utils.sprintf(user.Recent, userID), inNewTab);
231
					break;
232
				case buttons.UserRecentReputation:
233
					loadURL(consts.Protocol + "://" +
234
					        consts.Host + this.Utils.sprintf(user.RecentRep, userID), inNewTab);
235
					break;
236
				case buttons.UserRecentResponses:
237
					loadURL(consts.Protocol + "://" +
238
					        consts.Host + this.Utils.sprintf(user.Responses, userID), inNewTab);
239
					break;
240
				case buttons.UserRecentRevisions:
241
					loadURL(consts.Protocol + "://" +
242
					        consts.Host + this.Utils.sprintf(user.Revisions, userID), inNewTab);
243
					break;
244
				case buttons.UserRecentBadges:
245
					loadURL(consts.Protocol + "://" +
246
					        consts.Host + this.Utils.sprintf(user.Badges, userID), inNewTab);
247
					break;
248
				case buttons.ShowOptions:
249
					this.Utils.ShowOptions();
250
					break;
251
				case buttons.ShowOverview:
252
					this.Utils.ShowOverview();
253
					break;
254
				case buttons.Test:
255
					this.Utils.Test();
256
					break;
257
			}
258
		},
209
		},
259
		PrepareContextSearch: function (event, search) {
210
		Options: {
260
		    this.Utils.Log('Entering PrepareContextSearch');
211
			SearchInTab: "search_in_tab",
261
			// ****************************************
212
			ButtonsInTab: "buttons_in_tab",
262
			// Step 1: Get the selected text
213
			UserID: "user_id"
263
			// ****************************************
214
		}
215
	},
216
	Search: function (event, type) {
217
		this.Utils.Log('Entering Search: ' + type);
218
		var URL = "";
219
		var isEmpty = false;
220
		var searchTerms = this.Utils.TrimString(this.GetTerms());
221
		if (searchTerms.length == 0) {
222
			isEmpty = true;
223
		} else {
224
			this.searchHistory.addEntry("SOB-SearchTerms-History", searchTerms);
225
			searchTerms = this.Utils.ConvertTermsToURI(searchTerms);
226
		}
227
	
228
		switch(type)
229
		{
230
			case "sob_search":
231
				if(!isEmpty) {
232
					URL = this.Strings.Constants.Protocol + "://" + 
233
						  this.Strings.Constants.Host + "/search?q=" + 
234
						  searchTerms;
235
				}
236
				break;
237
		}
238
		if (!isEmpty) {
239
			this.Utils.LoadURL(URL, this.Utils.GetOption(this.Strings.Options.SearchInTab, "bool"));
240
		}
241
	},
242
	SearchTermsTextEntered: function (param){
243
		this.Utils.Log('Entering SearchTermsTextEntered');
244
		this.Search(null, 'sob_search');
245
	},
246
	GetTerms: function () {
247
		this.Utils.Log('Entering GetTerms');
248
		var terms = document.getElementById("SOB-SearchTerms");
249
		return terms.value;
250
	},
251
	SetTerms: function (newTerms) {
252
		this.Utils.Log('Entering SetTerms');
253
		var terms = document.getElementById("SOB-SearchTerms");
254
		terms.value = newTerms;
255
	},
256
	ButtonClick: function (buttonName) {
257
		this.Utils.Log('Entering ButtonClick: ' + buttonName);
264
		
258
		
265
			var node = document.popupNode;
259
		const buttons = this.Strings.Buttons;
266
			var selection = "";
260
		const consts = this.Strings.Constants;
267
			var nodeLocalName = node.localName.toLowerCase();
261
		const homepage = consts.Home;
262
		const questions = consts.Questions;
263
		const unanswered = consts.UnAnswered;
264
		const user = consts.User;
265
		const opts = this.Strings.Options;
268
		
266
		
269
			if((nodeLocalName == "textarea") || (nodeLocalName == "input" && node.type == "text"))
267
		var loadURL = this.Utils.LoadURL;
270
				selection = node.value.substring(node.selectionStart, node.selectionEnd);
271
			else
272
			{
273
				var focusedWindow = document.commandDispatcher.focusedWindow;
274
		        selection = focusedWindow.getSelection().toString();
275
			}
276
		
268
		
277
			// Limit the selection length
269
		var inNewTab = this.Utils.GetOption(opts.ButtonsInTab, "bool");
278
			if(selection.length >= 150)
270
		var userID = this.Utils.GetOption(opts.UserID, "string");
279
				selection = selection.substring(0, 149);
280
		
271
		
281
			// ****************************************
272
		switch (buttonName) {
282
			// Step 2: Clean up the selected text
273
			case buttons.Ask:
283
			// ****************************************
274
				loadURL(consts.Protocol + "://" +
275
						consts.Host + consts.Ask, inNewTab);
276
				break;
277
			case buttons.TabActive:
278
				loadURL(consts.Protocol + "://" +
279
						consts.Host + homepage.Active, inNewTab);
280
				break;
281
			case buttons.TabFeatured:
282
				loadURL(consts.Protocol + "://" +
283
						consts.Host + homepage.Featured, inNewTab);
284
				break;
285
			case buttons.TabHot:
286
				loadURL(consts.Protocol + "://" +
287
						consts.Host + homepage.Hot, inNewTab);
288
				break;
289
			case buttons.TabWeek:
290
				loadURL(consts.Protocol + "://" +
291
						consts.Host + homepage.Week, inNewTab);
292
				break;
293
			case buttons.TabMonth:
294
				loadURL(consts.Protocol + "://" +
295
						consts.Host + homepage.Month, inNewTab);
296
				break;
297
			case buttons.New:
298
				loadURL(consts.Protocol + "://" +
299
						consts.Host + questions.Newest, inNewTab);
300
				break;
301
			case buttons.Featured:
302
				loadURL(consts.Protocol + "://" +
303
						consts.Host + questions.Featured, inNewTab);
304
				break;
305
			case buttons.Hot:
306
				loadURL(consts.Protocol + "://" +
307
						consts.Host + questions.Hot, inNewTab);
308
				break;
309
			case buttons.Votes:
310
				loadURL(consts.Protocol + "://" +
311
						consts.Host + questions.Votes, inNewTab);
312
				break;
313
			case buttons.Active:
314
				loadURL(consts.Protocol + "://" +
315
						consts.Host + questions.Active, inNewTab);
316
				break;
317
			case buttons.TabMyTags:
318
				loadURL(consts.Protocol + "://" +
319
						consts.Host + unanswered.MyTags, inNewTab);
320
				break;
321
			case buttons.TabNewest:
322
				loadURL(consts.Protocol + "://" +
323
						consts.Host + unanswered.Newest, inNewTab);
324
				break;
325
			case buttons.TabVotes:
326
				loadURL(consts.Protocol + "://" +
327
						consts.Host + unanswered.Votes, inNewTab);
328
				break;
329
			case buttons.UserStats:
330
				loadURL(consts.Protocol + "://" +
331
						consts.Host + this.Utils.sprintf(user.Stats, userID), inNewTab);
332
				break;
333
			case buttons.UserActivity:
334
				loadURL(consts.Protocol + "://" +
335
						consts.Host + this.Utils.sprintf(user.Activity, userID), inNewTab);
336
				break;
337
			case buttons.UserReputation:
338
				loadURL(consts.Protocol + "://" +
339
						consts.Host + this.Utils.sprintf(user.Reputation, userID), inNewTab);
340
				break;
341
			case buttons.UserFavorites:
342
				loadURL(consts.Protocol + "://" +
343
						consts.Host + this.Utils.sprintf(user.Favorites, userID), inNewTab);
344
				break;
345
			case buttons.UserPreferences:
346
				loadURL(consts.Protocol + "://" +
347
						consts.Host + this.Utils.sprintf(user.Preferences, userID), inNewTab);
348
				break;
349
			case buttons.UserAccounts:
350
				loadURL(consts.Protocol + "://" +
351
						consts.Host + this.Utils.sprintf(user.Accounts, userID), inNewTab);
352
				break;
353
			case buttons.UserRecentSummary:
354
				loadURL(consts.Protocol + "://" +
355
						consts.Host + this.Utils.sprintf(user.Recent, userID), inNewTab);
356
				break;
357
			case buttons.UserRecentReputation:
358
				loadURL(consts.Protocol + "://" +
359
						consts.Host + this.Utils.sprintf(user.RecentRep, userID), inNewTab);
360
				break;
361
			case buttons.UserRecentResponses:
362
				loadURL(consts.Protocol + "://" +
363
						consts.Host + this.Utils.sprintf(user.Responses, userID), inNewTab);
364
				break;
365
			case buttons.UserRecentRevisions:
366
				loadURL(consts.Protocol + "://" +
367
						consts.Host + this.Utils.sprintf(user.Revisions, userID), inNewTab);
368
				break;
369
			case buttons.UserRecentBadges:
370
				loadURL(consts.Protocol + "://" +
371
						consts.Host + this.Utils.sprintf(user.Badges, userID), inNewTab);
372
				break;
373
			case buttons.ShowOptions:
374
				this.Utils.ShowOptions();
375
				break;
376
			case buttons.ShowOverview:
377
				this.Utils.ShowOverview();
378
				break;
379
		}
380
	},
381
	PrepareContextSearch: function (event, search) {
382
		this.Utils.Log('Entering PrepareContextSearch');
383
		// ****************************************
384
		// Step 1: Get the selected text
385
		// ****************************************
386
	
387
		var node = document.popupNode;
388
		var selection = "";
389
		var nodeLocalName = node.localName.toLowerCase();
390
	
391
		if((nodeLocalName == "textarea") || (nodeLocalName == "input" && node.type == "text"))
392
			selection = node.value.substring(node.selectionStart, node.selectionEnd);
393
		else
394
		{
395
			var focusedWindow = document.commandDispatcher.focusedWindow;
396
			selection = focusedWindow.getSelection().toString();
397
		}
398
	
399
		// Limit the selection length
400
		if(selection.length >= 150)
401
			selection = selection.substring(0, 149);
402
	
403
		// ****************************************
404
		// Step 2: Clean up the selected text
405
		// ****************************************
406
	
407
		selection = this.Utils.TrimString(selection); // Clean up whitespace
284
		
408
		
285
			selection = this.Utils.TrimString(selection); // Clean up whitespace
409
		var selArray = selection.split(" ");
286
			
410
		for(var i=0; i<selArray.length; i++)
287
			var selArray = selection.split(" ");
411
		{
288
			for(var i=0; i<selArray.length; i++)
412
			selArray[i] = selArray[i].replace(/^(\&|\(|\)|\[|\]|\{|\}|\"|,|\.|!|\?|'|:|;)+/, "");
289
			{
413
			selArray[i] = selArray[i].replace(/(\&|\(|\)|\[|\]|\{|\}|\"|,|\.|!|\?|'|:|;)+$/, "");
290
		        selArray[i] = selArray[i].replace(/^(\&|\(|\)|\[|\]|\{|\}|\"|,|\.|!|\?|'|:|;)+/, "");
414
		}
291
		        selArray[i] = selArray[i].replace(/(\&|\(|\)|\[|\]|\{|\}|\"|,|\.|!|\?|'|:|;)+$/, "");
415
	
292
			}
416
		selection = selArray.join(" ");
417
	
418
		// ****************************************
419
		// Step 3: Update the search box
420
		// ****************************************
421
	
422
		this.SetTerms(selection);
423
	
424
		// ****************************************
425
		// Step 4: Perform the search
426
		// ****************************************
427
	
428
		this.Search(event, search);
429
	},
430
	UpdateContextMenuVisibility: function () {
431
		this.Utils.Log('Entering UpdateContextMenuVisibility');
432
		//Todo
433
	},
434
	UpdateContextMenu: function () {
435
		this.Utils.Log('Entering UpdateContextMenu');
436
		var contextMenu = document.getElementById('SOB-Context');
437
		var node = document.popupNode;
438
		var selection = "";
439
		var nodeLocalName = node.localName.toLowerCase();
440
		if((nodeLocalName == "textarea") || (nodeLocalName == "input" && node.type == "text"))
441
			selection = node.value.substring(node.selectionStart, node.selectionEnd);
442
		else
443
		{
444
			var focusedWindow = document.commandDispatcher.focusedWindow;
445
			selection = focusedWindow.getSelection().toString();
446
		}
447
		this.Utils.Log('Selection: ' + selection);
448
		if (selection.length == 0) {
449
			contextMenu.setAttribute('disabled', 'true');
450
		} else {
451
			contextMenu.setAttribute('disabled', 'false');
452
		}
453
		return true;
454
	},
455
	ProgressListener: function () {
456
		this.Utils.Log('Entering ProgressListener');
457
		//Todo
458
	},
459
	Init: function() {
460
		this.Utils.Log('Entering Init');
293
		
461
		
294
			selection = selArray.join(" ");
462
		this.Utils.Log('Importing Preferences.jsm');
463
		try {
464
			Components.utils.import("resource://stackoverflowbar/Preferences.jsm", org.gcarreno.StackOverflowBar);
465
			this.Utils.Log("Module Preferences imported");
466
		} catch(e) {
467
			this.Utils.Log("Error: " + e.message);
468
		}
469
470
		org.gcarreno.jSapiens.init();
471
		this.Database.init();
472
		this.Overview.init();
473
		this.Timeline.my_turn();
295
		
474
		
296
			// ****************************************
475
		var mainItem = document.getElementById("SOB-Main-Item");
297
			// Step 3: Update the search box
476
		// Only initialize if the main toolbar item is present
298
			// ****************************************
477
		if(mainItem)
478
		{
479
			this._first_run = this.Utils.GetOption('first_run', 'bool');
480
			if (this._first_run) {
481
				this.Utils.Log('First run');
482
				this.Utils.SetOption('first_run', 'bool', false);
483
				this.Database.CreateDB()
484
			}
485
			this.UpdateContextMenuVisibility(); // Todo
486
		}
487
	},
488
	Finalise: function () {
489
		this.Utils.Log('Entering Finalise');
490
		//if (typeof window.getBrowser != 'undefined') {
491
		//	window.getBrowser().removeProgressListener(this.ProgressListener);
492
		//}
493
	},
494
	Database: {
495
		_sobU: null,
496
		_file: "sob-database.db",
497
		_dirS: Components.classes["@mozilla.org/file/directory_service;1"]
498
				.getService(Components.interfaces.nsIProperties),
499
		_dir: null,
299
		
500
		
300
			this.SetTerms(selection);
501
		_storage: Components.classes["@mozilla.org/storage/service;1"]
502
				.getService(Components.interfaces.mozIStorageService),
503
				  
504
		_console: Components.classes['@mozilla.org/consoleservice;1']
505
				.getService(Components.interfaces.nsIConsoleService),
506
				
507
		_dbConn: null,
301
		
508
		
302
			// ****************************************
509
		init: function() {
303
			// Step 4: Perform the search
510
			this.Log('Entering init');
304
			// ****************************************
511
			try {
512
				this.Log('File: ' + this._file);
513
				this._dir = this._dirS.get("ProfD", Components.interfaces.nsIFile);
514
				this._dir.append("StackOverflowBar");
515
			} catch(e) {
516
				this.Log('Error: ' +e.message);
517
			}
518
			if (!this._dir.exists() || !this._dir.isDirectory) {
519
				this.Log('Folder does not exist, creating');
520
				this._dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0774);
521
			}
522
			try {
523
				this._dir.append(this._file);
524
			} catch(e) {
525
				this.Log('Error: ' +e.message);
526
			}
527
			if (!this._dir.exists()) {
528
				this.Log('File missing, will create on DB Connect');
529
			}
530
			try {
531
				this._dbConn =this._storage.openDatabase(this._dir);
532
			} catch(e) {
533
				this.Log('Error: ' +e.message);
534
			}
535
		},
305
		
536
		
306
			this.Search(event, search);
537
		CreateDB: function() {
538
			this.Log('Creating Database');
539
			this._dbConn.executeSimpleSQL("CREATE TABLE timeline (date INTEGER, type STRING)");
307
		},
540
		},
308
		UpdateContextMenuVisibility: function () {
541
	
309
		    this.Utils.Log('Entering UpdateContextMenuVisibility');
542
		Log: function (aMessage) {
310
			//Todo
543
			this._console.logStringMessage('StackOverflowBar.Database: ' + aMessage);
544
		}
545
	},
546
	Timeline: {
547
		_console: Components.classes['@mozilla.org/consoleservice;1']
548
				.getService(Components.interfaces.nsIConsoleService),
549
		Log: function(aMessage) {
550
			this._console.logStringMessage('StackOverflowBar.Timeline: ' + aMessage);
311
		},
551
		},
312
		UpdateContextMenu: function () {
552
		my_turn: function() {
313
		    this.Utils.Log('Entering UpdateContextMenu');
553
			return;
314
			var contextMenu = document.getElementById('SOB-Context');
554
			var timeout = org.gcarreno.StackOverflowBar.Utils.GetOption('timeout');
315
			var node = document.popupNode;
555
			window.setTimeout(function() {
316
			var selection = "";
556
				org.gcarreno.StackOverflowBar.Timeline.my_turn();
317
			var nodeLocalName = node.localName.toLowerCase();
557
			}, timeout * 60 * 1000);
318
			if((nodeLocalName == "textarea") || (nodeLocalName == "input" && node.type == "text"))
558
		}
319
				selection = node.value.substring(node.selectionStart, node.selectionEnd);
559
	},
320
			else
560
	Overview : {
321
			{
561
		_sob: null,
322
				var focusedWindow = document.commandDispatcher.focusedWindow;
562
		_sobU: null,
323
		        selection = focusedWindow.getSelection().toString();
563
		_sobD: null,
564
		_jSapiens: null,
565
		_console: Components.classes['@mozilla.org/consoleservice;1']
566
				.getService(Components.interfaces.nsIConsoleService),
567
		
568
		init: function(){
569
			this.Log('init');
570
			if (typeof org.gcarreno.StackOverflowBar != 'undefined') {
571
				this.Log('Can reach SOB');
572
				this._sob = org.gcarreno.StackOverflowBar;
324
			}
573
			}
325
			this.Utils.Log('Selection: ' + selection);
574
			if (typeof org.gcarreno.StackOverflowBar.Database != 'undefined') {
326
			if (selection.length == 0) {
575
				this.Log('Can reach SOB.D');
327
				contextMenu.setAttribute('disabled', 'true');
576
				this._sobD = org.gcarreno.StackOverflowBar.Database;
328
			} else {
329
				contextMenu.setAttribute('disabled', 'false');
330
			}
577
			}
331
			return true;
578
			if (typeof org.gcarreno.StackOverflowBar.Utils != 'undefined') {
579
				this.Log('Can reach SOB.U');
580
				this._sobU = org.gcarreno.StackOverflowBar.Utils;
581
			}
582
			if (typeof org.gcarreno.jSapiens != 'undefined') {
583
				this.Log('Can reach jSapiens');
584
				this._jSapiens = org.gcarreno.jSapiens;
585
			}
332
		},
586
		},
333
		ProgressListener: function () {
587
		
334
		    this.Utils.Log('Entering ProgressListener');
588
		refresh: function () {
335
			//Todo
589
			var contents = document.getElementById('SOB-overview-contents');
336
		},
590
			
337
		Init: function() {
591
			var api_answer = this._jSapiens.users.timeline(this._sobU.GetOption('user_id'));
338
		    this.Utils.Log('Entering Init');
592
			var b_value = '';
339
			var mainItem = document.getElementById("SOB-Main-Item");
593
			
340
			// Only initialize if the main toolbar item is present
594
			b_value += 'User Timeline:\n';
341
			if(mainItem)
595
			b_value += '\tTotal: ' + api_answer.total + '\n';
342
			{
596
			
343
				if (this.oneTime == false) {
597
			if (api_answer.total > 0) {
344
					this.oneTime = true;
598
				for (var x = 0; x < api_answer.user_timelines.length; x++) {
345
					//window.getBrowser().addProgressListener(this.ProgressListener, Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
599
					b_value += '\t\tUser: ' + api_answer.user_timelines[x].user_id + '\n';
346
					this.UpdateContextMenuVisibility(); // Todo
600
					b_value += '\t\t\ttype: ' + api_answer.user_timelines[x].timeline_type + '\n';
601
					switch (api_answer.user_timelines[x].timeline_type) {
602
						case "comment":
603
							b_value += '\t\t\taction: ' + api_answer.user_timelines[x].action + '\n';
604
							b_value += '\t\t\tdescription: ' + api_answer.user_timelines[x].description + '\n';
605
							b_value += '\t\t\tdetail: ' + api_answer.user_timelines[x].detail + '\n';
606
							break;
607
						case "revision":
608
							b_value += '\t\t\taction: ' + api_answer.user_timelines[x].action + '\n';
609
							b_value += '\t\t\tdescription: ' + api_answer.user_timelines[x].description + '\n';
610
							b_value += '\t\t\tdetail: ' + api_answer.user_timelines[x].detail + '\n';
611
							break;
612
						case "badge":
613
							b_value += '\t\t\taction: ' + api_answer.user_timelines[x].action + '\n';
614
							b_value += '\t\t\tdescription: ' + api_answer.user_timelines[x].description + '\n';
615
							b_value += '\t\t\tdetail: ' + api_answer.user_timelines[x].detail + '\n';
616
							break;
617
						case "accepted":
618
							b_value += '\t\t\taction: ' + api_answer.user_timelines[x].action + '\n';
619
							b_value += '\t\t\tdescription: ' + api_answer.user_timelines[x].description + '\n';
620
							break;
621
						case "askoranswered":
622
							b_value += '\t\t\taction: ' + api_answer.user_timelines[x].action + '\n';
623
							b_value += '\t\t\tdescription: ' + api_answer.user_timelines[x].description + '\n';
624
							break;
625
					}
626
					var creation_date = new Date(api_answer.user_timelines[x].creation_date * 1000);
627
					b_value += '\t\t\tDate: ' + creation_date + '\n';
628
					//b_value += '\t\t\tviews: ' + api_answer.user_timelines[x].view_count + '\n';
347
				}
629
				}
348
			}
630
			}
631
			
632
			contents.value = b_value;
349
		},
633
		},
350
		Finalise: function () {
634
		
351
		    this.Utils.Log('Entering Finalise');
635
		Log: function (aMessage) {
352
			//if (typeof window.getBrowser != 'undefined') {
636
			this._console.logStringMessage('StackOverflowBar.Overview: ' + aMessage);
353
			//	window.getBrowser().removeProgressListener(this.ProgressListener);
637
		}
354
			//}
638
	},
639
	Utils: {
640
		consoleService: Components.classes['@mozilla.org/consoleservice;1']
641
						.getService(Components.interfaces.nsIConsoleService),
642
		prefService: Components.classes["@mozilla.org/preferences-service;1"]
643
						.getService(Components.interfaces.nsIPrefService),
644
						
645
		_sob_prefs: null,
646
		
647
		Log: function (aMessage) {
648
			this.consoleService.logStringMessage('StackOverflowBar: ' + aMessage);
355
		},
649
		},
356
		Utils: {
650
		GetOption: function(optName, optType) {
357
			consoleService: Components.classes['@mozilla.org/consoleservice;1']
651
			if (this._sob_prefs == null) {
358
							.getService(Components.interfaces.nsIConsoleService),
652
				this._sob_prefs = new org.gcarreno.StackOverflowBar.Preferences("extensions.stackoverflowbar.");
359
			prefService: Components.classes["@mozilla.org/preferences-service;1"]
653
			}
360
							.getService(Components.interfaces.nsIPrefService),
654
			var result = this._sob_prefs.get(optName);
361
			Log: function (aMessage) {
655
			
362
				this.consoleService.logStringMessage('StackOverflowBar: ' + aMessage);
656
			this.Log('Prefs get: ' + optName + ': '+ result);
363
			},
657
364
			GetOption: function(optName, optType) {
658
			return result;
365
				const branch = this.prefService.getBranch("extensions.stackoverflowbar.");
659
		},
660
		SetOption: function(optName, optType, optValue) {
661
			if (this._sob_prefs == null) {
662
				this._sob_prefs = new org.gcarreno.StackOverflowBar.Preferences("extensions.stackoverflowbar.");
663
			}
664
			this.Log('Prefs set: ' + optName + ': '+ optValue);
665
666
			this._sob_prefs.set(optName, optValue);
667
		},
668
		LoadOptions: function () {
669
			const options = org.gcarreno.StackOverflowBar.Strings.Options;
670
			
671
			document.getElementById("SOB-Opt-SearchInTab").checked = 
672
				this.GetOption(options.SearchInTab, "bool");
673
			document.getElementById("SOB-Opt-ButtonsInTab").checked = 
674
				this.GetOption(options.ButtonsInTab, "bool");
366
				
675
				
367
				var result = null;
676
			//document.getElementById("SOB-Opt-UseAPI").checked =
677
			//    this.GetOption(options.UseAPI, "bool");
368
				
678
				
369
				switch (optType) {
679
			document.getElementById("SOB-Opt-UserID").value =
370
					case "bool":
680
				this.GetOption(options.UserID, "string");
371
					    try {
681
		},
372
					    	result = branch.getBoolPref(optName); 
682
		SaveOptions: function () {
373
					    } catch (e) {
683
			const options = org.gcarreno.StackOverflowBar.Strings.Options;
374
					    	result = false;
375
					    }
376
						break;
377
					case "string":
378
						try {
379
							result = branch.getCharPref(optName); 
380
						} catch (e) {
381
							result = '';
382
						}
383
						break;
384
					case "int":
385
						try {
386
							result = branch.getIntPref(optName);
387
						} catch (e) {
388
							result = 0;
389
						}
390
						break;
391
				}
392
				return result;
393
			},
394
			SetOption: function(optName, optType, optValue) {
395
				const branch = this.prefService.getBranch("extensions.stackoverflowbar.");
396
				
397
				switch (optType) {
398
					case "bool":
399
						branch.setBoolPref(optName, optValue);
400
						break;
401
					case "string":
402
						branch.setCharPref(optName, optValue);
403
						break;
404
					case "int":
405
						branch.setIntPref(optName, optValue);
406
						break;
407
				}
408
			},
409
			LoadOptions: function () {
410
				const options = org.gcarreno.StackOverflowBar.Strings.Options;
411
				
412
				document.getElementById("SOB-Opt-SearchInTab").checked = 
413
					this.GetOption(options.SearchInTab, "bool");
414
				document.getElementById("SOB-Opt-ButtonsInTab").checked = 
415
					this.GetOption(options.ButtonsInTab, "bool");
416
					
417
				//document.getElementById("SOB-Opt-UseAPI").checked =
418
				//    this.GetOption(options.UseAPI, "bool");
419
				    
420
				document.getElementById("SOB-Opt-UserID").value =
421
					this.GetOption(options.UserID, "string");
422
			},
423
			SaveOptions: function () {
424
				const options = org.gcarreno.StackOverflowBar.Strings.Options;
425
684
426
				this.SetOption(options.SearchInTab, "bool", 
685
			this.SetOption(options.SearchInTab, "bool", 
427
					document.getElementById("SOB-Opt-SearchInTab").checked);
686
				document.getElementById("SOB-Opt-SearchInTab").checked);
428
				this.SetOption(options.ButtonsInTab, "bool",
687
			this.SetOption(options.ButtonsInTab, "bool",
429
					document.getElementById("SOB-Opt-ButtonsInTab").checked);
688
				document.getElementById("SOB-Opt-ButtonsInTab").checked);
430
					
431
				//this.SetOption(options.UseAPI, "bool",
432
				//    document.getElementById("SOB-Opt-UseAPI").checked);
433
				
689
				
434
				this.SetOption(options.UserID, "string",
690
			//this.SetOption(options.UseAPI, "bool",
435
					document.getElementById("SOB-Opt-UserID").value);
691
			//    document.getElementById("SOB-Opt-UseAPI").checked);
436
			},
692
			
437
			ShowOptions: function () {
693
			this.SetOption(options.UserID, "string",
438
				var flags = "chrome,centerscreen,modal";
694
				document.getElementById("SOB-Opt-UserID").value);
439
				window.openDialog("chrome://stackoverflowbar/content/options.xul", "Options", flags);
695
		},
440
			},
696
		ShowOptions: function () {
441
			ShowOverview: function () {
697
			var flags = "chrome,centerscreen,modal";
442
				var flags = "chrome,centerscreen,resizable";
698
			window.openDialog("chrome://stackoverflowbar/content/options.xul", "&sobar.options.title;", flags);
443
				window.openDialog("chrome://stackoverflowbar/content/overview.xul", "Overview", flags);
699
		},
444
			},
700
		ShowOverview: function () {
445
			LoadURL: function (aURL, inNewTab) {
701
			var flags = "chrome,centerscreen,resizable";
446
				if(inNewTab)
702
			window.openDialog("chrome://stackoverflowbar/content/overview.xul", "&sobar.overview.title;", flags);
447
				{
703
		},
448
			        var browser = window.getBrowser();
704
		LoadURL: function (aURL, inNewTab) {
449
			        var newTab = browser.addTab(aURL);
705
			if(inNewTab)
450
			        browser.selectedTab = newTab;
706
			{
707
				var browser = window.getBrowser();
708
				var newTab = browser.addTab(aURL);
709
				browser.selectedTab = newTab;
710
			}
711
			else
712
			{
713
				var content = window.content;
714
				content.document.location = aURL;
715
				content.focus();
716
			}
717
		},
718
		LoadHomepage: function (event) {
719
			const options = org.gcarreno.StackOverflowBar.Strings.Options;
720
			const consts = org.gcarreno.StackOverflowBar.Strings.Constants;
721
			
722
			var inNewTab = this.GetOption(options.ButtonsInTab, "bool");
723
			var URL = consts.Protocol + "://" + consts.Host;
724
			this.LoadURL(URL, inNewTab);
725
			event.stopPropagation();
726
		},
727
		LoadAboutURL: function (aWhere) {
728
			var url = "";
729
			switch(aWhere) {
730
				case 'home':
731
					url = 'http://guscarreno.blogspot.com/p/stack-overflow-bar.html'
732
					break;
733
				case 'support':
734
					url = 'http://www.assembla.com/spaces/StackOverflowBar'
735
					break;
736
			}
737
			
738
			var windowService = Components.classes["@mozilla.org/appshell/window-mediator;1"]
739
								.getService(Components.interfaces.nsIWindowMediator);
740
			var currentWindow = windowService.getMostRecentWindow("navigator:browser");
741
		
742
			if(currentWindow)
743
			{
744
				try {
745
					currentWindow.delayedOpenTab(url);
746
				} catch(e) {
747
					currentWindow.loadURI(url);
451
				}
748
				}
452
				else
749
			}
453
				{
750
			else
454
					var content = window.content;
751
				window.open(url);
455
					content.document.location = aURL;
752
		},
456
					content.focus();
753
		TrimString: function (string) {
754
			if (!string) {
755
				return "";
457
				}
756
				}
458
			},
757
			string = string.replace(/^\s+/, '');
459
			LoadHomepage: function (event) {
758
			string = string.replace(/\s+$/, '');
460
				const options = org.gcarreno.StackOverflowBar.Strings.Options;
759
			string = string.replace(/\s+/g, ' ');
461
				const consts = org.gcarreno.StackOverflowBar.Strings.Constants;
760
			return string;
462
				
761
		},
463
  			    var inNewTab = this.GetOption(options.ButtonsInTab, "bool");
762
		ConvertTermsToURI: function (terms) {
464
				var URL = consts.Protocol + "://" + consts.Host;
763
			var termArray = new Array();
465
				this.LoadURL(URL, inNewTab);
764
			termArray = terms.split(" ");
466
				event.stopPropagation();
765
			var result = "";
467
			},
766
			for (var i = 0; i < termArray.length; i++) {
468
			LoadAboutURL: function (aWhere) {
767
				if (i > 0) {
469
				var url = "";
768
					result += "+";
470
				switch(aWhere) {
471
					case 'home':
472
						url = 'http://gcarreno.org/stackoverflowbar/'
473
						break;
474
					case 'support':
475
						url = 'http://www.assembla.com/spaces/StackOverflowBar'
476
						break;
477
				}
769
				}
478
				
770
				result += encodeURIComponent(termArray[i]);
479
				var windowService = Components.classes["@mozilla.org/appshell/window-mediator;1"]
771
			}
480
									.getService(Components.interfaces.nsIWindowMediator);
772
			return result;
481
				var currentWindow = windowService.getMostRecentWindow("navigator:browser");
773
		},
482
			
774
		DoNothing: function () {},
483
				if(currentWindow)
484
				{
485
					try {
486
						currentWindow.delayedOpenTab(url);
487
					} catch(e) {
488
						currentWindow.loadURI(url);
489
					}
490
				}
491
				else
492
					window.open(url);
493
			},
494
			TrimString: function (string) {
495
			    if (!string) {
496
					return "";
497
					}
498
			    string = string.replace(/^\s+/, '');
499
			    string = string.replace(/\s+$/, '');
500
			    string = string.replace(/\s+/g, ' ');
501
			    return string;
502
			},
503
			ConvertTermsToURI: function (terms) {
504
			    var termArray = new Array();
505
			    termArray = terms.split(" ");
506
			    var result = "";
507
			    for (var i = 0; i < termArray.length; i++) {
508
					if (i > 0) {
509
						result += "+";
510
					}
511
			        result += encodeURIComponent(termArray[i]);
512
			    }
513
			    return result;
514
			},
515
			Test: function(){
516
				this.Log('Testing button');
517
				var box = document.getElementById('SOB-Test-Box');
518
				var strings = org.gcarreno.StackOverflowBar.Strings;
519
				
520
				var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]  
521
							.createInstance(Components.interfaces.nsIXMLHttpRequest);
522
				var url = this.sprintf(strings.Constants.Protocol + "://" +
523
									   strings.Constants.Host + 
524
									   strings.API.UserFlair,
525
									   this.GetOption(strings.Options.UserID, 'string'));
526
				box.value = '';
527
				this.Log('Req: ' + url);
528
				req.open('GET', url, false);
529
				req.send(null);
530
				
531
				if (req.status == 200) {
532
					var JSON = Components.classes["@mozilla.org/dom/json;1"]
533
								.createInstance(Components.interfaces.nsIJSON);
534
								
535
					var flair = JSON.decode(req.responseText);
536
					box.value = this.sprintf("Name: %s\nID: %s\n\n" + req.responseText, flair.displayName, flair.id);
537
				} else {
538
					box.value = 'Treta';
539
				}
540
			},
541
			DoNothing: function () {},
542
/**
775
/**
543
 * sprintf() for JavaScript v.0.4
776
* sprintf() for JavaScript v.0.4
544
 *
777
*
545
 * Copyright (c) 2007 Alexandru Marasteanu <http://alexei.417.ro/>
778
* Copyright (c) 2007 Alexandru Marasteanu <http://alexei.417.ro/>
546
 * Thanks to David Baird (unit test and patch).
779
* Thanks to David Baird (unit test and patch).
547
 *
780
*
548
 * This program is free software; you can redistribute it and/or modify it under
781
* This program is free software; you can redistribute it and/or modify it under
549
 * the terms of the GNU General Public License as published by the Free Software
782
* the terms of the GNU General Public License as published by the Free Software
550
 * Foundation; either version 2 of the License, or (at your option) any later
783
* Foundation; either version 2 of the License, or (at your option) any later
551
 * version.
784
* version.
552
 *
785
*
553
 * This program is distributed in the hope that it will be useful, but WITHOUT
786
* This program is distributed in the hope that it will be useful, but WITHOUT
554
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
787
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
555
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
788
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
556
 * details.
789
* details.
557
 *
790
*
558
 * You should have received a copy of the GNU General Public License along with
791
* You should have received a copy of the GNU General Public License along with
559
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
792
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
560
 * Place, Suite 330, Boston, MA 02111-1307 USA
793
* Place, Suite 330, Boston, MA 02111-1307 USA
561
 */
794
*/
562
			str_repeat: function (i, m) {
795
		str_repeat: function (i, m) {
563
				for (var o = []; m > 0; o[--m] = i); return(o.join('')); 
796
			for (var o = []; m > 0; o[--m] = i); return(o.join('')); 
564
			},
797
		},
565
			sprintf: function () {
798
		sprintf: function () {
566
				var i = 0, a, f = arguments[i++], o = [], m, p, c, x;
799
			var i = 0, a, f = arguments[i++], o = [], m, p, c, x;
567
				while (f) {
800
			while (f) {
568
				  if (m = /^[^\x25]+/.exec(f)) o.push(m[0]);
801
			  if (m = /^[^\x25]+/.exec(f)) o.push(m[0]);
569
				  else if (m = /^\x25{2}/.exec(f)) o.push('%');
802
			  else if (m = /^\x25{2}/.exec(f)) o.push('%');
570
				  else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
803
			  else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
571
				    if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw("Too few arguments.");
804
				if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw("Too few arguments.");
572
				    if (/[^s]/.test(m[7]) && (typeof(a) != 'number'))
805
				if (/[^s]/.test(m[7]) && (typeof(a) != 'number'))
573
				      throw("Expecting number but found " + typeof(a));
806
				  throw("Expecting number but found " + typeof(a));
574
				    switch (m[7]) {
807
				switch (m[7]) {
575
				      case 'b': a = a.toString(2); break;
808
				  case 'b': a = a.toString(2); break;
576
				      case 'c': a = String.fromCharCode(a); break;
809
				  case 'c': a = String.fromCharCode(a); break;
577
				      case 'd': a = parseInt(a); break;
810
				  case 'd': a = parseInt(a); break;
578
				      case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
811
				  case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
579
				      case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
812
				  case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
580
				      case 'o': a = a.toString(8); break;
813
				  case 'o': a = a.toString(8); break;
581
				      case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
814
				  case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
582
				      case 'u': a = Math.abs(a); break;
815
				  case 'u': a = Math.abs(a); break;
583
				      case 'x': a = a.toString(16); break;
816
				  case 'x': a = a.toString(16); break;
584
				      case 'X': a = a.toString(16).toUpperCase(); break;
817
				  case 'X': a = a.toString(16).toUpperCase(); break;
585
				    }
586
				    a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a);
587
				    c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
588
				    x = m[5] - String(a).length;
589
				    p = m[5] ? this.str_repeat(c, x) : '';
590
				    o.push(m[4] ? a + p : p + a);
591
				  }
592
				  else throw ("Huh ?!");
593
				  f = f.substring(m[0].length);
594
				}
818
				}
595
				return o.join('');
819
				a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a);
820
				c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
821
				x = m[5] - String(a).length;
822
				p = m[5] ? this.str_repeat(c, x) : '';
823
				o.push(m[4] ? a + p : p + a);
824
			  }
825
			  else throw ("Huh ?!");
826
			  f = f.substring(m[0].length);
596
			}
827
			}
828
			return o.join('');
597
		}
829
		}
598
	}
830
	}
599
}
831
}
600
832
601
window.addEventListener("load", function () { return org.gcarreno.StackOverflowBar.Init(); }, false);
833
window.addEventListener("load",   function () {return org.gcarreno.StackOverflowBar.Init(); }     , false);
602
window.addEventListener("unload", function () {return org.gcarreno.StackOverflowBar.Finalise(); } , false);
834
window.addEventListener("unload", function () {return org.gcarreno.StackOverflowBar.Finalise(); } , false);

Updated trunk/chrome/content/stackoverflowbarNew.xul Download diff

329330
1
<?xml version="1.0" encoding="ISO-8859-1" ?>
1
<?xml version="1.0" encoding="ISO-8859-1" ?>
2
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
2
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
3
<?xml-stylesheet href="chrome://stackoverflowbar/skin/stackoverflowbar.css"
3
<?xml-stylesheet href="chrome://stackoverflowbar/skin/stackoverflowbar.css" type="text/css"?>
4
                 type="text/css"?>
5
4
6
<?xul-overlay href="chrome://stackoverflowbar/content/toolbar.xul"?>
5
<?xul-overlay href="chrome://stackoverflowbar/content/toolbar.xul"?>
7
<?xul-overlay href="chrome://stackoverflowbar/content/contextmenu.xul"?>
6
<?xul-overlay href="chrome://stackoverflowbar/content/contextmenu.xul"?>
...
...
16
	
15
	
17
	<script type="application/x-javascript"
16
	<script type="application/x-javascript"
18
    		src="chrome://global/content/nsTransferable.js"/>
17
    		src="chrome://global/content/nsTransferable.js"/>
19
    
18
20
    <script type="application/x-javascript"
19
    <script type="application/x-javascript"
21
    		src="chrome://stackoverflowbar/content/stackoverflowbar.js" />
20
    		src="chrome://stackoverflowbar/content/stackoverflowbar.js" />
22
23
24
</overlay>
21
</overlay>

Updated trunk/chrome/locale/en-US/stackoverflowbar.dtd Download diff

329330
106
106
107
<!ENTITY sobar.options.tab.about "About">
107
<!ENTITY sobar.options.tab.about "About">
108
<!ENTITY sobar.options.label.about "About the StackOverflow Bar">
108
<!ENTITY sobar.options.label.about "About the StackOverflow Bar">
109
<!ENTITY sobar.options.about.text1 "StackOverflow Bar v0.2.0.329">
109
<!ENTITY sobar.options.about.text1 "StackOverflow Bar v0.3.0.330">
110
<!ENTITY sobar.options.about.text2 "Gustavo Carreno &lt;gcarreno@gcarreno.org&gt;">
110
<!ENTITY sobar.options.about.text2 "Gustavo Carreno &lt;gcarreno@gcarreno.org&gt;">
111
<!ENTITY sobar.options.about.text3 "Toolbar Site: ">
111
<!ENTITY sobar.options.about.text3 "Toolbar Site: ">
112
<!ENTITY sobar.options.about.text3.link "http://guscarreno.blogspot.com/p/stack-overflow-bar.html">
112
<!ENTITY sobar.options.about.text3.link "http://guscarreno.blogspot.com/p/stack-overflow-bar.html">

Updated trunk/chrome/locale/pt-PT/stackoverflowbar.dtd Download diff

329330
106
106
107
<!ENTITY sobar.options.tab.about "Sobre">
107
<!ENTITY sobar.options.tab.about "Sobre">
108
<!ENTITY sobar.options.label.about "Sobre a barra StackOverflow">
108
<!ENTITY sobar.options.label.about "Sobre a barra StackOverflow">
109
<!ENTITY sobar.options.about.text1 "Barra Stack Overflow v0.2.0.329">
109
<!ENTITY sobar.options.about.text1 "Barra Stack Overflow v0.3.0.330">
110
<!ENTITY sobar.options.about.text2 "Gustavo Carreno &lt;gcarreno@gcarreno.org&gt;">
110
<!ENTITY sobar.options.about.text2 "Gustavo Carreno &lt;gcarreno@gcarreno.org&gt;">
111
<!ENTITY sobar.options.about.text3 "Site da barra: ">
111
<!ENTITY sobar.options.about.text3 "Site da barra: ">
112
<!ENTITY sobar.options.about.text3.link "http://guscarreno.blogspot.com/p/stack-overflow-bar.html">
112
<!ENTITY sobar.options.about.text3.link "http://guscarreno.blogspot.com/p/stack-overflow-bar.html">

Updated trunk/install.rdf Download diff

329330
10
  <RDF:Description RDF:about="urn:mozilla:install-manifest"
10
  <RDF:Description RDF:about="urn:mozilla:install-manifest"
11
                   em:id="StackOverflowBar@gcarreno.org"
11
                   em:id="StackOverflowBar@gcarreno.org"
12
                   em:name="StackOverflow Bar"
12
                   em:name="StackOverflow Bar"
13
                   em:version="0.2.0.329"
13
                   em:version="0.3.0.330"
14
                   em:creator="Gustavo Carreno"
14
                   em:creator="Gustavo Carreno"
15
                   em:description="StackOverflow Bar"
15
                   em:description="StackOverflow Bar"
16
                   em:homepageURL="http://guscarreno.blogspot.com/p/stack-overflow-bar.html"
16
                   em:homepageURL="http://guscarreno.blogspot.com/p/stack-overflow-bar.html"