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

Side by Side Diff: lib/appIntegration.js

Issue 8433028: added hook function to appIntegration to handle function-overwrites from other extensions (Closed)
Patch Set: Created Sept. 25, 2012, 4:30 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/content/tests/qunit.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // Extensions like Tab Mix Plus will try to recompile our handlers and fail 5 function hook(obj, name, func)
Wladimir Palant 2012/09/26 09:27:50 Any reason why you've put it here? I expected it t
6 // badly - they manage to replace our handler but the recompiled version
7 // won't work because the closure is missing its variables. We replace
8 // toString() function to prevent this kind of recompiling on earlier stages
9 // (produce a syntax error but still leave the source code viewable).
10 function doNotRecompile()
11 { 6 {
12 let result = Function.prototype.toString.apply(this); 7 var orig = obj[name];
13 return result + "\n$%&!/DO_NOT_RECOMPILE" 8 var origGet = obj.__lookupGetter__(name);
9 var origSet = obj.__lookupSetter__(name);
10 var dumbOverrideAttempt = false;
Wladimir Palant 2012/09/26 09:27:50 You should use let instead of var in Firefox code
11
12 var newFunc = function()
13 {
14 try
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
14 } 61 }
15 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
16 let {application} = require("info"); 65 let {application} = require("info");
17 switch (application) 66 switch (application)
18 { 67 {
19 case "firefox": 68 case "firefox":
20 { 69 {
21 // Firefox 70 // Firefox
22 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser"; 71 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser";
23 72
24 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null; 73 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null;
25 74
26 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null; 75 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null;
27 76
28 exports.applyToWindow = function(window, corrector) 77 exports.applyToWindow = function(window, corrector)
29 { 78 {
30 let urlbar = exports.getURLBar(window); 79 let urlbar = exports.getURLBar(window);
31 if (urlbar && urlbar.handleCommand && !("urlfixerOldHandler" in urlbar.han dleCommand)) 80 if (urlbar && urlbar.handleCommand && !("urlfixerOldHandler" in urlbar.han dleCommand))
32 { 81 {
33 // Handle new URLs being entered 82 // Handle new URLs being entered
34 let oldHandler = urlbar.handleCommand; 83 let hooks = [];
Wladimir Palant 2012/09/26 09:27:50 From the look of it, we never hook more than one f
35 urlbar.handleCommand = function() 84 if (wm.get(window))
Wladimir Palant 2012/09/26 09:27:50 The window should definitely be unknown here - if
36 { 85 {
37 try 86 hooks = wm.get(window);
87 }
88 hooks.push(hook(urlbar, "handleCommand", function()
38 { 89 {
39 let correction = corrector(window, urlbar.value); 90 try
40 if (correction) 91 {
41 urlbar.value = correction; 92 let correction = corrector(window, urlbar.value);
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 -
42 } 100 }
43 catch(e) 101 ));
44 { 102 wm.set(window, hooks);
45 if (e == Cr.NS_BINDING_ABORTED)
46 return;
47 else
48 Cu.reportError(e);
49 }
50 oldHandler.apply(this, arguments);
51 }
52 urlbar.handleCommand.urlfixerOldHandler = oldHandler;
53 urlbar.handleCommand.toString = doNotRecompile;
54 } 103 }
55 }; 104 };
56 105
57 exports.removeFromWindow = function(window) 106 exports.removeFromWindow = function(window)
58 { 107 {
59 let urlbar = exports.getURLBar(window); 108 let urlbar = exports.getURLBar(window);
60 if (urlbar && urlbar.handleCommand && "urlfixerOldHandler" in urlbar.handl eCommand) 109 if (urlbar && urlbar.handleCommand && wm.has(window))
61 urlbar.handleCommand = urlbar.handleCommand.urlfixerOldHandler; 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 }
62 }; 118 };
63 119
64 exports.openInfobar = function(window, id, message, buttons, persistence) 120 exports.openInfobar = function(window, id, message, buttons, persistence)
65 { 121 {
66 let browser = exports.getBrowser(window); 122 let browser = exports.getBrowser(window);
67 let infobar = browser.getNotificationBox(); 123 let infobar = browser.getNotificationBox();
68 let notif = infobar.getNotificationWithValue(id); 124 let notif = infobar.getNotificationWithValue(id);
69 125
70 if (notif) 126 if (notif)
71 { 127 {
(...skipping 22 matching lines...) Expand all
94 // SeaMonkey 150 // SeaMonkey
95 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser"; 151 exports.isKnownWindow = function(window) window.document.documentElement.get Attribute("windowtype") == "navigator:browser";
96 152
97 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null; 153 exports.getURLBar = function(window) "gURLBar" in window ? window.gURLBar : null;
98 154
99 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null; 155 exports.getBrowser = function(window) "gBrowser" in window ? window.gBrowser : null;
100 156
101 exports.applyToWindow = function(window, corrector) 157 exports.applyToWindow = function(window, corrector)
102 { 158 {
103 let urlbar = exports.getURLBar(window); 159 let urlbar = exports.getURLBar(window);
104 if (urlbar && window.handleURLBarCommand && !("urlfixerOldHandler" in wind ow.handleURLBarCommand)) 160 if (urlbar && urlbar.handleCommand && !("urlfixerOldHandler" in urlbar.han dleCommand))
Wladimir Palant 2012/09/26 09:27:50 Replacing SeaMonkey code by Firefox-specific code
105 { 161 {
106 // Handle new URLs being entered 162 // Handle new URLs being entered
107 let oldHandler = window.handleURLBarCommand; 163 let hooks = [];
108 window.handleURLBarCommand = function() 164 if (wm.get(window))
109 { 165 {
110 try 166 hooks = wm.get(window);
167 }
168 hooks.push(hook(urlbar, "handleCommand", function()
111 { 169 {
112 let correction = corrector(window, urlbar.value); 170 try
113 if (correction) 171 {
114 urlbar.value = correction; 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);
115 } 181 }
116 catch(e) 182 ));
117 { 183 wm.set(window, hooks);
118 if (e == Cr.NS_BINDING_ABORTED)
119 return;
120 else
121 Cu.reportError(e);
122 }
123 oldHandler.apply(this, arguments);
124 }
125 window.handleURLBarCommand.urlfixerOldHandler = oldHandler;
126 window.handleURLBarCommand.toString = doNotRecompile;
127 } 184 }
128 }; 185 };
129 186
Wladimir Palant 2012/09/26 09:27:50 I suggest the following setting for the Sublime Te
130 exports.removeFromWindow = function(window) 187 exports.removeFromWindow = function(window)
131 { 188 {
132 if (window.handleURLBarCommand && "urlfixerOldHandler" in window.handleURL BarCommand) 189 let urlbar = exports.getURLBar(window);
133 window.handleURLBarCommand = window.handleURLBarCommand.urlfixerOldHandl er; 190 if (urlbar && urlbar.handleCommand && wm.has(window))
191 {
192 let hooks = wm.get(window);
193 for (let i = 0, len = hooks.length; i < len; i++)
194 {
195 hooks[i]();
196 }
197 wm.delete(window);
198 }
134 }; 199 };
135 200
136 exports.openInfobar = function(window, id, message, buttons, persistence) 201 exports.openInfobar = function(window, id, message, buttons, persistence)
137 { 202 {
138 let browser = exports.getBrowser(window); 203 let browser = exports.getBrowser(window);
139 let infobar = browser.getNotificationBox(); 204 let infobar = browser.getNotificationBox();
140 let notif = infobar.getNotificationWithValue(id); 205 let notif = infobar.getNotificationWithValue(id);
141 206
142 if (notif) 207 if (notif)
143 { 208 {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 { 245 {
181 url = url || this._edit.value; 246 url = url || this._edit.value;
182 try 247 try
183 { 248 {
184 let correction = corrector(window, url); 249 let correction = corrector(window, url);
185 if (correction) 250 if (correction)
186 url = correction; 251 url = correction;
187 } 252 }
188 catch(e) 253 catch(e)
189 { 254 {
190 if (e == Cr.NS_BINDING_ABORTED) 255 Cu.reportError(e);
191 return;
192 else
193 Cu.reportError(e);
194 } 256 }
195 oldHandler.call(this, url); 257 oldHandler.call(this, url);
196 } 258 }
197 window.BrowserUI.goToURI.urlfixerOldHandler = oldHandler; 259 window.BrowserUI.goToURI.urlfixerOldHandler = oldHandler;
198 window.BrowserUI.goToURI.toString = doNotRecompile; 260 window.BrowserUI.goToURI.toString = doNotRecompile;
199 } 261 }
200 }; 262 };
201 263
202 exports.removeFromWindow = function(window) 264 exports.removeFromWindow = function(window)
203 { 265 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 { 298 {
237 let params = Array.prototype.slice.apply(arguments); 299 let params = Array.prototype.slice.apply(arguments);
238 try 300 try
239 { 301 {
240 let correction = corrector(window, params[0]); 302 let correction = corrector(window, params[0]);
241 if (correction) 303 if (correction)
242 params[0] = correction; 304 params[0] = correction;
243 } 305 }
244 catch(e) 306 catch(e)
245 { 307 {
246 if (e == Cr.NS_BINDING_ABORTED) 308 Cu.reportError(e);
247 return null;
248 else
249 Cu.reportError(e);
250 } 309 }
251 return oldFunc.apply(this, params); 310 return oldFunc.apply(this, params);
252 }; 311 };
253 312
254 window.BrowserApp.observe = function(subject, topic, data) 313 window.BrowserApp.observe = function(subject, topic, data)
255 { 314 {
256 // Huge hack: we replace addTab/loadURI when the observer is 315 // Huge hack: we replace addTab/loadURI when the observer is
257 // triggered. This seems to be the only way to know that the calls 316 // triggered. This seems to be the only way to know that the calls
258 // originate from user input. 317 // originate from user input.
259 let method = null; 318 let method = null;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 }; 368 };
310 369
311 break; 370 break;
312 } 371 }
313 default: 372 default:
314 { 373 {
315 exports.isKnownWindow = function(window) false; 374 exports.isKnownWindow = function(window) false;
316 break; 375 break;
317 } 376 }
318 } 377 }
OLDNEW
« no previous file with comments | « chrome/content/tests/qunit.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld