| Index: lib/appIntegration.js |
| =================================================================== |
| --- a/lib/appIntegration.js |
| +++ b/lib/appIntegration.js |
| @@ -2,17 +2,66 @@ |
| * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
| * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| -// Extensions like Tab Mix Plus will try to recompile our handlers and fail |
| -// badly - they manage to replace our handler but the recompiled version |
| -// won't work because the closure is missing its variables. We replace |
| -// toString() function to prevent this kind of recompiling on earlier stages |
| -// (produce a syntax error but still leave the source code viewable). |
| -function doNotRecompile() |
| +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
|
| { |
| - let result = Function.prototype.toString.apply(this); |
| - return result + "\n$%&!/DO_NOT_RECOMPILE" |
| + var orig = obj[name]; |
| + var origGet = obj.__lookupGetter__(name); |
| + var origSet = obj.__lookupSetter__(name); |
| + var dumbOverrideAttempt = false; |
|
Wladimir Palant
2012/09/26 09:27:50
You should use let instead of var in Firefox code
|
| + |
| + var newFunc = function() |
| + { |
| + try |
| + { |
| + func.apply(this, arguments); |
| + } |
| + catch(e) |
| + { |
| + Cu.reportError(e); |
| + } |
| + orig.apply(this, arguments); |
| + } |
| + newFunc.toString = function() |
| + { |
| + dumbOverrideAttempt = true; |
| + return orig.toString(); |
| + } |
| + |
| + obj.__defineGetter__(name, function() |
| + { |
| + dumbOverrideAttempt = false; |
| + return newFunc; |
| + } |
| + ); |
| + |
| + obj.__defineSetter__(name, function(value) |
| + { |
| + if (dumbOverrideAttempt) |
| + { |
| + orig = value; |
| + } |
| + else |
| + { |
| + delete obj[name]; |
| + obj[name] = value; |
| + } |
| + } |
| + ); |
| + |
| + return function() { |
| + delete obj[name]; |
| + obj[name] = orig; |
| + if (origGet) { |
| + obj.__defineGetter__(name, origGet); |
| + } |
| + if (origSet) { |
| + obj.__defineSetter__(name, origSet); |
| + } |
| + } |
|
Wladimir Palant
2012/09/26 09:27:50
Inconsistent style here (brackets) - plus there is
|
| } |
| +let wm = new WeakMap(); |
| +let {Prefs} = require("prefs"); |
|
Wladimir Palant
2012/09/26 09:27:50
I would be very worried if our generic app-support
|
| let {application} = require("info"); |
| switch (application) |
| { |
| @@ -31,34 +80,41 @@ |
| if (urlbar && urlbar.handleCommand && !("urlfixerOldHandler" in urlbar.handleCommand)) |
| { |
| // Handle new URLs being entered |
| - let oldHandler = urlbar.handleCommand; |
| - urlbar.handleCommand = function() |
| + let hooks = []; |
|
Wladimir Palant
2012/09/26 09:27:50
From the look of it, we never hook more than one f
|
| + if (wm.get(window)) |
|
Wladimir Palant
2012/09/26 09:27:50
The window should definitely be unknown here - if
|
| { |
| - try |
| + hooks = wm.get(window); |
| + } |
| + hooks.push(hook(urlbar, "handleCommand", function() |
| { |
| - let correction = corrector(window, urlbar.value); |
| - if (correction) |
| - urlbar.value = correction; |
| + try |
| + { |
| + let correction = corrector(window, urlbar.value); |
| + if (correction) |
| + urlbar.value = correction; |
| + } |
| + catch(e) |
| + { |
| + Cu.reportError(e); |
| + } |
|
Wladimir Palant
2012/09/26 09:27:50
The try..catch block here is no longer necessary -
|
| } |
| - catch(e) |
| - { |
| - if (e == Cr.NS_BINDING_ABORTED) |
| - return; |
| - else |
| - Cu.reportError(e); |
| - } |
| - oldHandler.apply(this, arguments); |
| - } |
| - urlbar.handleCommand.urlfixerOldHandler = oldHandler; |
| - urlbar.handleCommand.toString = doNotRecompile; |
| + )); |
| + wm.set(window, hooks); |
| } |
| }; |
| exports.removeFromWindow = function(window) |
| { |
| let urlbar = exports.getURLBar(window); |
| - if (urlbar && urlbar.handleCommand && "urlfixerOldHandler" in urlbar.handleCommand) |
| - urlbar.handleCommand = urlbar.handleCommand.urlfixerOldHandler; |
| + if (urlbar && urlbar.handleCommand && wm.has(window)) |
| + { |
| + let hooks = wm.get(window); |
| + for (let i = 0, len = hooks.length; i < len; i++) |
| + { |
| + hooks[i](); |
| + } |
| + wm.delete(window); |
| + } |
| }; |
| exports.openInfobar = function(window, id, message, buttons, persistence) |
| @@ -101,36 +157,45 @@ |
| exports.applyToWindow = function(window, corrector) |
| { |
| let urlbar = exports.getURLBar(window); |
| - if (urlbar && window.handleURLBarCommand && !("urlfixerOldHandler" in window.handleURLBarCommand)) |
| + if (urlbar && urlbar.handleCommand && !("urlfixerOldHandler" in urlbar.handleCommand)) |
|
Wladimir Palant
2012/09/26 09:27:50
Replacing SeaMonkey code by Firefox-specific code
|
| { |
| // Handle new URLs being entered |
| - let oldHandler = window.handleURLBarCommand; |
| - window.handleURLBarCommand = function() |
| + let hooks = []; |
| + if (wm.get(window)) |
| { |
| - try |
| + hooks = wm.get(window); |
| + } |
| + hooks.push(hook(urlbar, "handleCommand", function() |
| { |
| - let correction = corrector(window, urlbar.value); |
| - if (correction) |
| - urlbar.value = correction; |
| + try |
| + { |
| + let correction = corrector(window, urlbar.value); |
| + if (correction) |
| + urlbar.value = correction; |
| + } |
| + catch(e) |
| + { |
| + Cu.reportError(e); |
| + } |
| + oldHandler.apply(this, arguments); |
| } |
| - catch(e) |
| - { |
| - if (e == Cr.NS_BINDING_ABORTED) |
| - return; |
| - else |
| - Cu.reportError(e); |
| - } |
| - oldHandler.apply(this, arguments); |
| - } |
| - window.handleURLBarCommand.urlfixerOldHandler = oldHandler; |
| - window.handleURLBarCommand.toString = doNotRecompile; |
| + )); |
| + wm.set(window, hooks); |
| } |
| }; |
| - |
| + |
|
Wladimir Palant
2012/09/26 09:27:50
I suggest the following setting for the Sublime Te
|
| exports.removeFromWindow = function(window) |
| { |
| - if (window.handleURLBarCommand && "urlfixerOldHandler" in window.handleURLBarCommand) |
| - window.handleURLBarCommand = window.handleURLBarCommand.urlfixerOldHandler; |
| + let urlbar = exports.getURLBar(window); |
| + if (urlbar && urlbar.handleCommand && wm.has(window)) |
| + { |
| + let hooks = wm.get(window); |
| + for (let i = 0, len = hooks.length; i < len; i++) |
| + { |
| + hooks[i](); |
| + } |
| + wm.delete(window); |
| + } |
| }; |
| exports.openInfobar = function(window, id, message, buttons, persistence) |
| @@ -187,10 +252,7 @@ |
| } |
| catch(e) |
| { |
| - if (e == Cr.NS_BINDING_ABORTED) |
| - return; |
| - else |
| - Cu.reportError(e); |
| + Cu.reportError(e); |
| } |
| oldHandler.call(this, url); |
| } |
| @@ -243,10 +305,7 @@ |
| } |
| catch(e) |
| { |
| - if (e == Cr.NS_BINDING_ABORTED) |
| - return null; |
| - else |
| - Cu.reportError(e); |
| + Cu.reportError(e); |
| } |
| return oldFunc.apply(this, params); |
| }; |