Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | /** |
michael@0 | 6 | * Allows registering a mock XPCOM component, that temporarily replaces the |
michael@0 | 7 | * original one when an object implementing a given ContractID is requested |
michael@0 | 8 | * using createInstance. |
michael@0 | 9 | * |
michael@0 | 10 | * @param aContractID |
michael@0 | 11 | * The ContractID of the component to replace, for example |
michael@0 | 12 | * "@mozilla.org/filepicker;1". |
michael@0 | 13 | * |
michael@0 | 14 | * @param aReplacementCtor |
michael@0 | 15 | * The constructor function for the JavaScript object that will be |
michael@0 | 16 | * created every time createInstance is called. This object must |
michael@0 | 17 | * implement QueryInterface and provide the XPCOM interfaces required by |
michael@0 | 18 | * the specified ContractID (for example |
michael@0 | 19 | * Components.interfaces.nsIFilePicker). |
michael@0 | 20 | */ |
michael@0 | 21 | |
michael@0 | 22 | function MockObjectRegisterer(aContractID, aReplacementCtor) { |
michael@0 | 23 | this._contractID = aContractID; |
michael@0 | 24 | this._replacementCtor = aReplacementCtor; |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | MockObjectRegisterer.prototype = { |
michael@0 | 28 | /** |
michael@0 | 29 | * Replaces the current factory with one that returns a new mock object. |
michael@0 | 30 | * |
michael@0 | 31 | * After register() has been called, it is mandatory to call unregister() to |
michael@0 | 32 | * restore the original component. Usually, you should use a try-catch block |
michael@0 | 33 | * to ensure that unregister() is called. |
michael@0 | 34 | */ |
michael@0 | 35 | register: function MOR_register() { |
michael@0 | 36 | if (this._originalFactory) |
michael@0 | 37 | throw new Exception("Invalid object state when calling register()"); |
michael@0 | 38 | |
michael@0 | 39 | // Define a factory that creates a new object using the given constructor. |
michael@0 | 40 | var providedConstructor = this._replacementCtor; |
michael@0 | 41 | this._mockFactory = { |
michael@0 | 42 | createInstance: function MF_createInstance(aOuter, aIid) { |
michael@0 | 43 | if (aOuter != null) |
michael@0 | 44 | throw SpecialPowers.Cr.NS_ERROR_NO_AGGREGATION; |
michael@0 | 45 | return new providedConstructor().QueryInterface(aIid); |
michael@0 | 46 | } |
michael@0 | 47 | }; |
michael@0 | 48 | |
michael@0 | 49 | var retVal = SpecialPowers.swapFactoryRegistration(this._cid, this._contractID, this._mockFactory, this._originalFactory); |
michael@0 | 50 | if ('error' in retVal) { |
michael@0 | 51 | throw new Exception("ERROR: " + retVal.error); |
michael@0 | 52 | } else { |
michael@0 | 53 | this._cid = retVal.cid; |
michael@0 | 54 | this._originalFactory = retVal.originalFactory; |
michael@0 | 55 | } |
michael@0 | 56 | }, |
michael@0 | 57 | |
michael@0 | 58 | /** |
michael@0 | 59 | * Restores the original factory. |
michael@0 | 60 | */ |
michael@0 | 61 | unregister: function MOR_unregister() { |
michael@0 | 62 | if (!this._originalFactory) |
michael@0 | 63 | throw new Exception("Invalid object state when calling unregister()"); |
michael@0 | 64 | |
michael@0 | 65 | // Free references to the mock factory. |
michael@0 | 66 | SpecialPowers.swapFactoryRegistration(this._cid, this._contractID, this._mockFactory, this._originalFactory); |
michael@0 | 67 | |
michael@0 | 68 | // Allow registering a mock factory again later. |
michael@0 | 69 | this._cid = null; |
michael@0 | 70 | this._originalFactory = null; |
michael@0 | 71 | this._mockFactory = null; |
michael@0 | 72 | }, |
michael@0 | 73 | |
michael@0 | 74 | // --- Private methods and properties --- |
michael@0 | 75 | |
michael@0 | 76 | /** |
michael@0 | 77 | * The factory of the component being replaced. |
michael@0 | 78 | */ |
michael@0 | 79 | _originalFactory: null, |
michael@0 | 80 | |
michael@0 | 81 | /** |
michael@0 | 82 | * The CID under which the mock contractID was registered. |
michael@0 | 83 | */ |
michael@0 | 84 | _cid: null, |
michael@0 | 85 | |
michael@0 | 86 | /** |
michael@0 | 87 | * The nsIFactory that was automatically generated by this object. |
michael@0 | 88 | */ |
michael@0 | 89 | _mockFactory: null |
michael@0 | 90 | } |