| Index: lib/hooks.js |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/lib/hooks.js |
| @@ -0,0 +1,75 @@ |
| +/* This Source Code Form is subject to the terms of the Mozilla Public |
| + * 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/. */ |
| + |
| +function hook(obj, name, func, cleanup) |
| +{ |
| + let orig = obj[name]; |
| + let origGet = obj.__lookupGetter__(name); |
| + let origSet = obj.__lookupSetter__(name); |
| + let dumbOverrideAttempt = false; |
| + |
| + let newFunc = function() |
| + { |
| + let params = arguments; |
| + try |
| + { |
| + let result = func.apply(this, params); |
| + if (typeof result == "object") |
| + params = result; |
| + } |
| + catch(e) |
| + { |
| + Cu.reportError(e); |
| + } |
| + |
| + try |
| + { |
| + return orig.apply(this, params); |
| + } |
| + finally |
| + { |
| + if (typeof cleanup == "function") |
| + cleanup(); |
| + } |
| + }; |
| + 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); |
| + } |
| + }; |
| +} |
| +exports.hook = hook; |