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

Unified 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.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/content/tests/qunit.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
};
« 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