Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: lib/appIntegration.js

Issue 8433028: added hook function to appIntegration to handle function-overwrites from other extensions (Closed)
Left Patch Set: Created Sept. 25, 2012, 4:30 p.m.
Right Patch Set: added missing statement Created Sept. 28, 2012, 9:52 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « chrome/content/tests/tests/suffixTreeManipulation.js ('k') | lib/hooks.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* This Source Code Form is subject to the terms of the Mozilla Public 1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 function hook(obj, name, func) 5 let {hook} = require("hooks");
Wladimir Palant 2012/09/26 09:27:50 Any reason why you've put it here? I expected it t
6 let functionHooks = new WeakMap();
7
8 exports.removeFromWindow = function(window)
6 { 9 {
7 var orig = obj[name]; 10 if (functionHooks.has(window))
8 var origGet = obj.__lookupGetter__(name); 11 {
9 var origSet = obj.__lookupSetter__(name); 12 let unhook = functionHooks.get(window);
10 var dumbOverrideAttempt = false; 13 unhook();
Wladimir Palant 2012/09/26 09:27:50 You should use let instead of var in Firefox code
11 14 functionHooks.delete(window);
12 var newFunc = function() 15 }
13 { 16 };
14 try 17
15 {
16 func.apply(this, arguments);
17 }
18 catch(e)
19 {
20 Cu.reportError(e);
21 }
22 orig.apply(this, arguments);
23 }
24 newFunc.toString = function()
25 {
26 dumbOverrideAttempt = true;
27 return orig.toString();
28 }
29
30 obj.__defineGetter__(name, function()
31 {
32 dumbOverrideAttempt = false;
33 return newFunc;
34 }
35 );
36
37 obj.__defineSetter__(name, function(value)
38 {
39 if (dumbOverrideAttempt)
40 {
41 orig = value;
42 }
43 else
44 {
45 delete obj[name];
46 obj[name] = value;
47 }
48 }
49 );
50
51 return function() {
52 delete obj[name];
53 obj[name] = orig;
54 if (origGet) {
55 obj.__defineGetter__(name, origGet);
56 }
57 if (origSet) {
58 obj.__defineSetter__(name, origSet);
59 }
60 }
Wladimir Palant 2012/09/26 09:27:50 Inconsistent style here (brackets) - plus there is
61 }
62
63 let wm = new WeakMap();
64 let {Prefs} = require("prefs");
Wladimir Palant 2012/09/26 09:27:50 I would be very worried if our generic app-support
65 let {application} = require("info"); 18 let {application} = require("info");
66 switch (application) 19 switch (application)
67 { 20 {
68 case "firefox": 21 case "firefox":
69 { 22 {
70 // Firefox 23 // Firefox
71 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser"; 24 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser";
72 25
73 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null; 26 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null;
74 27
75 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null; 28 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null;
76 29
77 exports.applyToWindow = function(window, corrector) 30 exports.applyToWindow = function(window, corrector)
78 { 31 {
79 let urlbar = exports.getURLBar(window); 32 let urlbar = exports.getURLBar(window);
80 if (urlbar && urlbar.handleCommand && !("urlfixerOldHandler" in urlbar.han dleCommand)) 33 if (urlbar && urlbar.handleCommand && !functionHooks.has(window))
81 { 34 {
82 // Handle new URLs being entered 35 // Handle new URLs being entered
83 let hooks = []; 36 let unhook = hook(urlbar, "handleCommand", function()
Wladimir Palant 2012/09/26 09:27:50 From the look of it, we never hook more than one f
84 if (wm.get(window)) 37 {
Wladimir Palant 2012/09/26 09:27:50 The window should definitely be unknown here - if
85 { 38 let correction = corrector(window, urlbar.value);
86 hooks = wm.get(window); 39 if (correction)
87 } 40 urlbar.value = correction;
88 hooks.push(hook(urlbar, "handleCommand", function() 41 });
89 { 42 functionHooks.set(window, unhook);
90 try 43 }
91 { 44 };
92 let correction = corrector(window, urlbar.value); 45
93 if (correction)
94 urlbar.value = correction;
95 }
96 catch(e)
97 {
98 Cu.reportError(e);
99 }
Wladimir Palant 2012/09/26 09:27:50 The try..catch block here is no longer necessary -
100 }
101 ));
102 wm.set(window, hooks);
103 }
104 };
105
106 exports.removeFromWindow = function(window)
107 {
108 let urlbar = exports.getURLBar(window);
109 if (urlbar && urlbar.handleCommand && wm.has(window))
110 {
111 let hooks = wm.get(window);
112 for (let i = 0, len = hooks.length; i < len; i++)
113 {
114 hooks[i]();
115 }
116 wm.delete(window);
117 }
118 };
119
120 exports.openInfobar = function(window, id, message, buttons, persistence) 46 exports.openInfobar = function(window, id, message, buttons, persistence)
121 { 47 {
122 let browser = exports.getBrowser(window); 48 let browser = exports.getBrowser(window);
123 let infobar = browser.getNotificationBox(); 49 let infobar = browser.getNotificationBox();
124 let notif = infobar.getNotificationWithValue(id); 50 let notif = infobar.getNotificationWithValue(id);
125 51
126 if (notif) 52 if (notif)
127 { 53 {
128 infobar.removeNotification(notif); 54 infobar.removeNotification(notif);
129 } 55 }
130 56
131 notif = infobar.appendNotification( 57 notif = infobar.appendNotification(
132 message, 58 message,
133 id, 59 id,
134 require("info").addonRoot + "icon64.png", 60 require("info").addonRoot + "icon64.png",
135 infobar.PRIORITY_INFO_HIGH, 61 infobar.PRIORITY_INFO_HIGH,
136 buttons 62 buttons
137 ); 63 );
138 notif.persistence = persistence; 64 notif.persistence = persistence;
139 }; 65 };
140 66
141 exports.loadURI = function(uri) 67 exports.loadURI = function(window, uri)
142 { 68 {
143 exports.getBrowser(Services.wm.getMostRecentWindow("navigator:browser")).l oadURI(uri); 69 exports.getBrowser(window).loadURI(uri);
144 }; 70 };
145 71
146 break; 72 break;
147 } 73 }
148 case "seamonkey": 74 case "seamonkey":
149 { 75 {
76 let eventListeners = new WeakMap();
77
150 // SeaMonkey 78 // SeaMonkey
151 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser"; 79 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser";
152 80
153 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null; 81 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null;
154 82
155 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null; 83 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null;
156 84
157 exports.applyToWindow = function(window, corrector) 85 exports.applyToWindow = function(window, corrector)
158 { 86 {
159 let urlbar = exports.getURLBar(window); 87 let urlbar = exports.getURLBar(window);
160 if (urlbar && urlbar.handleCommand && !("urlfixerOldHandler" in urlbar.han dleCommand)) 88 let goButton = window.document.getElementById("go-button-container");
Wladimir Palant 2012/09/26 09:27:50 Replacing SeaMonkey code by Firefox-specific code
161 { 89
162 // Handle new URLs being entered 90 if (urlbar && urlbar._fireEvent && !functionHooks.has(window))
163 let hooks = []; 91 {
164 if (wm.get(window)) 92 function correctURL()
165 { 93 {
166 hooks = wm.get(window); 94 let correction = corrector(window, urlbar.value);
167 } 95 if (correction)
168 hooks.push(hook(urlbar, "handleCommand", function() 96 urlbar.value = correction;
97 }
98
99 let unhook = hook(urlbar, "_fireEvent", function(eventType)
100 {
101 if (eventType == "textentered")
169 { 102 {
170 try 103 correctURL();
171 {
172 let correction = corrector(window, urlbar.value);
173 if (correction)
174 urlbar.value = correction;
175 }
176 catch(e)
177 {
178 Cu.reportError(e);
179 }
180 oldHandler.apply(this, arguments);
181 } 104 }
182 )); 105 });
183 wm.set(window, hooks); 106 functionHooks.set(window, unhook);
184 } 107
185 }; 108 if (goButton)
186 109 {
Wladimir Palant 2012/09/26 09:27:50 I suggest the following setting for the Sublime Te
110 goButton.addEventListener("command", correctURL, true);
111 eventListeners.set(window, {
112 "listener": correctURL,
113 "element": goButton
114 });
115 }
116 }
117 };
118
119 let basicRemove = exports.removeFromWindow;
187 exports.removeFromWindow = function(window) 120 exports.removeFromWindow = function(window)
188 { 121 {
189 let urlbar = exports.getURLBar(window); 122 basicRemove(window);
190 if (urlbar && urlbar.handleCommand && wm.has(window)) 123
191 { 124 if (eventListeners.has(window))
192 let hooks = wm.get(window); 125 {
193 for (let i = 0, len = hooks.length; i < len; i++) 126 let eventListener = eventListeners.get(window);
194 { 127 eventListener.element.removeEventListener("command", eventListener.liste ner, true);
195 hooks[i](); 128 eventListeners.delete(window);
196 } 129 }
197 wm.delete(window); 130 };
198 } 131
199 };
200
201 exports.openInfobar = function(window, id, message, buttons, persistence) 132 exports.openInfobar = function(window, id, message, buttons, persistence)
202 { 133 {
203 let browser = exports.getBrowser(window); 134 let browser = exports.getBrowser(window);
204 let infobar = browser.getNotificationBox(); 135 let infobar = browser.getNotificationBox();
205 let notif = infobar.getNotificationWithValue(id); 136 let notif = infobar.getNotificationWithValue(id);
206 137
207 if (notif) 138 if (notif)
208 { 139 {
209 infobar.removeNotification(notif); 140 infobar.removeNotification(notif);
210 } 141 }
211 142
212 notif = infobar.appendNotification( 143 notif = infobar.appendNotification(
213 message, 144 message,
214 id, 145 id,
215 require("info").addonRoot + "icon64.png", 146 require("info").addonRoot + "icon64.png",
216 infobar.PRIORITY_INFO_HIGH, 147 infobar.PRIORITY_INFO_HIGH,
217 buttons 148 buttons
218 ); 149 );
219 notif.persistence = persistence; 150 notif.persistence = persistence;
220 }; 151 };
221 152
222 exports.loadURI = function(uri) 153 exports.loadURI = function(window, uri)
223 { 154 {
224 exports.getBrowser(Services.wm.getMostRecentWindow("navigator:browser")).l oadURI(uri); 155 exports.getBrowser(window).loadURI(uri);
225 }; 156 };
226 157
227 break; 158 break;
228 } 159 }
229 case "fennec": 160 case "fennec":
230 { 161 {
231 // XUL Fennec 162 // XUL Fennec
232 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser"; 163 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser";
233 164
234 exports.getURLBar = function(window) null; 165 exports.getURLBar = function(window) null;
235 166
236 exports.getBrowser = function(window) null; 167 exports.getBrowser = function(window) null;
237 168
238 exports.applyToWindow = function(window, corrector) 169 exports.applyToWindow = function(window, corrector)
239 { 170 {
240 if ("BrowserUI" in window && window.BrowserUI.goToURI && !("urlfixerOldHan dler" in window.BrowserUI.goToURI)) 171 if ("BrowserUI" in window && window.BrowserUI.goToURI && !functionHooks.ha s(window))
241 { 172 {
242 // Handle new URLs being entered 173 // Handle new URLs being entered
243 let oldHandler = window.BrowserUI.goToURI; 174 let unhook = hook(window.BrowserUI, "goToURI", function(url)
244 window.BrowserUI.goToURI = function(url)
245 { 175 {
246 url = url || this._edit.value; 176 url = url || this._edit.value;
247 try 177
248 { 178 let correction = corrector(window, url);
249 let correction = corrector(window, url); 179 if (correction)
250 if (correction) 180 url = correction;
251 url = correction; 181
252 } 182 return [url];
253 catch(e) 183 });
254 { 184 functionHooks.set(window, unhook);
255 Cu.reportError(e); 185 }
256 } 186 };
257 oldHandler.call(this, url); 187
258 } 188 exports.openInfobar = function(window, id, message, buttons, persistence)
259 window.BrowserUI.goToURI.urlfixerOldHandler = oldHandler; 189 {
260 window.BrowserUI.goToURI.toString = doNotRecompile; 190 if ("getNotificationBox" in window)
261 } 191 {
262 }; 192 let infobar = window.getNotificationBox();
263 193 let notification = infobar.getNotificationWithValue(id);
264 exports.removeFromWindow = function(window) 194
265 { 195 if (notification)
266 if ("BrowserUI" in window && window.BrowserUI.goToURI && "urlfixerOldHandl er" in window.BrowserUI.goToURI) 196 {
267 window.BrowserUI.goToURI = window.BrowserUI.goToURI.urlfixerOldHandler; 197 infobar.removeNotification(notification);
268 }; 198 }
269 199
270 exports.openInfobar = function() 200 notification = infobar.appendNotification(
271 { 201 message,
272 // TODO: Implement infobar 202 id,
273 }; 203 require("info").addonRoot + "icon64.png",
274 204 infobar.PRIORITY_INFO_HIGH,
275 exports.loadURI = function(window, uri) 205 buttons
276 { 206 );
277 // TODO: Implement infobar 207 notification.persistence = persistence;
208 }
209 };
210
211 exports.loadURI = function(window, uri)
212 {
213 if ("BrowserUI" in window && "goToURI" in window.BrowserUI)
214 {
215 window.BrowserUI.goToURI(uri);
216 }
278 }; 217 };
279 218
280 break; 219 break;
281 } 220 }
282 case "fennec2": 221 case "fennec2":
283 { 222 {
284 // Native Fennec 223 // Native Fennec
285 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser"; 224 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser";
286 225
287 exports.getURLBar = function(window) null; 226 exports.getURLBar = function(window) null;
288 227
289 exports.getBrowser = function(window) null; 228 exports.getBrowser = function(window) null;
290 229
291 exports.applyToWindow = function(window, corrector) 230 exports.applyToWindow = function(window, corrector)
292 { 231 {
293 if ("BrowserApp" in window && window.BrowserApp.observe && !("urlfixerOldH andler" in window.BrowserApp.observe)) 232 if ("BrowserApp" in window && window.BrowserApp.observe && !functionHooks. has(window))
294 { 233 {
295 let oldHandler = window.BrowserApp.observe; 234 let innerUnhook = null;
296 let oldFunc = null; 235 function cleanup()
297 let handler = function() 236 {
298 { 237 if (innerUnhook)
299 let params = Array.prototype.slice.apply(arguments); 238 innerUnhook();
300 try 239
301 { 240 innerUnhook = null;
302 let correction = corrector(window, params[0]); 241 }
303 if (correction) 242
304 params[0] = correction; 243 let unhook = hook(window.BrowserApp, "observe", function(subject, topic, data)
305 }
306 catch(e)
307 {
308 Cu.reportError(e);
309 }
310 return oldFunc.apply(this, params);
311 };
312
313 window.BrowserApp.observe = function(subject, topic, data)
314 { 244 {
315 // Huge hack: we replace addTab/loadURI when the observer is 245 // Huge hack: we replace addTab/loadURI when the observer is
316 // triggered. This seems to be the only way to know that the calls 246 // triggered. This seems to be the only way to know that the calls
317 // originate from user input. 247 // originate from user input.
318 let method = null; 248 let method = null;
319 if (topic == "Tab:Add") 249 if (topic == "Tab:Add")
320 method = "addTab"; 250 method = "addTab";
321 else if (topic == "Tab:Load") 251 else if (topic == "Tab:Load")
322 method = "loadURI"; 252 method = "loadURI";
323 253
324 if (method) 254 if (method)
325 { 255 {
326 oldFunc = this[method]; 256 innerUnhook = hook(this, method, function()
327 this[method] = handler; 257 {
258 let params = Array.prototype.slice.apply(arguments);
259 let correction = corrector(window, params[0]);
260 if (correction)
261 params[0] = correction;
262 return params;
263 });
328 } 264 }
329 265 }, cleanup);
330 try 266 functionHooks.set(window, unhook);
331 { 267 }
332 oldHandler.apply(this, arguments); 268 };
333 } 269
334 finally
335 {
336 if (method)
337 this[method] = oldFunc;
338 }
339 };
340 window.BrowserApp.observe.urlfixerOldHandler = oldHandler;
341 window.BrowserApp.observe.toString = doNotRecompile;
342 }
343 };
344
345 exports.removeFromWindow = function(window)
346 {
347 if ("BrowserApp" in window && window.BrowserApp.observe && "urlfixerOldHan dler" in window.BrowserApp.observe)
348 window.BrowserApp.observe = window.BrowserApp.observe.urlfixerOldHandler ;
349 };
350
351 exports.openInfobar = function(window, id, message, buttons, persistence) 270 exports.openInfobar = function(window, id, message, buttons, persistence)
352 { 271 {
353 if ("BrowserApp" in window && "selectedTab" in window.BrowserApp) 272 if ("BrowserApp" in window && "selectedTab" in window.BrowserApp)
354 { 273 {
355 window.NativeWindow.doorhanger.show(message, id, buttons, window.Browser App.selectedTab.id, 274 window.NativeWindow.doorhanger.show(message, id, buttons, window.Browser App.selectedTab.id,
356 { 275 {
357 persistence: persistence 276 persistence: persistence
358 } 277 }
359 ); 278 );
360 } 279 }
361 }; 280 };
362 281
363 exports.loadURI = function(uri) 282 exports.loadURI = function(window, uri)
364 { 283 {
365 let window = Services.wm.getMostRecentWindow("navigator:browser");
366 if ("BrowserApp" in window && "loadURI" in window.BrowserApp) 284 if ("BrowserApp" in window && "loadURI" in window.BrowserApp)
367 window.BrowserApp.loadURI(uri); 285 window.BrowserApp.loadURI(uri);
368 }; 286 };
369 287
370 break; 288 break;
371 } 289 }
372 default: 290 default:
373 { 291 {
374 exports.isKnownWindow = function(window) false; 292 exports.isKnownWindow = function(window) false;
375 break; 293 break;
376 } 294 }
377 } 295 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld