Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 } |
LEFT | RIGHT |