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); |
}; |