[Pkg-javascript-commits] [pdf.js] 37/119: Remove SpecialPowers addon

David Prévot taffit at moszumanska.debian.org
Wed May 13 21:27:39 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository pdf.js.

commit 75d8f70d061c4bf532357c2eb51a16282f868390
Author: Tim van der Meij <timvandermeij at gmail.com>
Date:   Fri Apr 3 20:17:20 2015 +0200

    Remove SpecialPowers addon
---
 test/driver.js                                     |    8 +-
 .../special-powers at mozilla.org/chrome.manifest     |    5 -
 .../chrome/specialpowers/content/MozillaLogger.js  |  121 --
 .../content/SpecialPowersObserverAPI.js            |  413 -----
 .../chrome/specialpowers/content/specialpowers.js  |  134 --
 .../specialpowers/content/specialpowersAPI.js      | 1744 --------------------
 .../chrome/specialpowers/modules/Assert.jsm        |  442 -----
 .../specialpowers/modules/MockColorPicker.jsm      |  125 --
 .../specialpowers/modules/MockFilePicker.jsm       |  236 ---
 .../specialpowers/modules/MockPermissionPrompt.jsm |   97 --
 .../components/SpecialPowersObserver.js            |  178 --
 .../special-powers at mozilla.org/install.rdf         |   26 -
 test/unit/testreporter.js                          |    7 +-
 13 files changed, 3 insertions(+), 3533 deletions(-)

diff --git a/test/driver.js b/test/driver.js
index b45205d..e5a5b66 100644
--- a/test/driver.js
+++ b/test/driver.js
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* globals PDFJS, combineUrl, StatTimer, SpecialPowers, Promise */
+/* globals PDFJS, combineUrl, StatTimer, Promise */
 
 'use strict';
 
@@ -367,11 +367,7 @@ function quitApp() {
   document.body.innerHTML = 'Tests are finished. <h1>CLOSE ME!</h1>' +
                              document.body.innerHTML;
   sendQuitRequest(function () {
-    if (window.SpecialPowers) {
-      SpecialPowers.quit();
-    } else {
-      window.close();
-    }
+    window.close();
   });
 }
 
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome.manifest b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome.manifest
deleted file mode 100644
index cac9fd6..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome.manifest
+++ /dev/null
@@ -1,5 +0,0 @@
-category profile-after-change @mozilla.org/special-powers-observer;1 @mozilla.org/special-powers-observer;1
-component {59a52458-13e0-4d93-9d85-a637344f29a1} components/SpecialPowersObserver.js
-content specialpowers chrome/specialpowers/content/
-contract @mozilla.org/special-powers-observer;1 {59a52458-13e0-4d93-9d85-a637344f29a1}
-resource specialpowers chrome/specialpowers/modules/
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/MozillaLogger.js b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/MozillaLogger.js
deleted file mode 100644
index fdc6c9a..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/MozillaLogger.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * MozillaLogger, a base class logger that just logs to stdout.
- */
-
-function MozillaLogger(aPath) {
-}
-
-MozillaLogger.prototype = {
-
-  init : function(path) {},
-
-  getLogCallback : function() {
-    return function (msg) {
-      var data = msg.num + " " + msg.level + " " + msg.info.join(' ') + "\n";
-      dump(data);
-    }
-  },
-
-  log : function(msg) {
-    dump(msg);
-  },
-
-  close : function() {}
-};
-
-
-/**
- * SpecialPowersLogger, inherits from MozillaLogger and utilizes SpecialPowers.
- * intented to be used in content scripts to write to a file
- */
-function SpecialPowersLogger(aPath) {
-  // Call the base constructor
-  MozillaLogger.call(this);
-  this.prototype = new MozillaLogger(aPath);
-  this.init(aPath);
-}
-
-SpecialPowersLogger.prototype = {
-  init : function (path) {
-    SpecialPowers.setLogFile(path);
-  },
-
-  getLogCallback : function () {
-    return function (msg) {
-      var data = msg.num + " " + msg.level + " " + msg.info.join(' ') + "\n";
-      SpecialPowers.log(data);
-
-      if (data.indexOf("SimpleTest FINISH") >= 0) {
-        SpecialPowers.closeLogFile();
-      }
-    }
-  },
-
-  log : function (msg) {
-    SpecialPowers.log(msg);
-  },
-
-  close : function () {
-    SpecialPowers.closeLogFile();
-  }
-};
-
-
-/**
- * MozillaFileLogger, a log listener that can write to a local file.
- * intended to be run from chrome space
- */
-
-/** Init the file logger with the absolute path to the file.
-    It will create and append if the file already exists **/
-function MozillaFileLogger(aPath) {
-  // Call the base constructor
-  MozillaLogger.call(this);
-  this.prototype = new MozillaLogger(aPath);
-  this.init(aPath);
-}
-
-MozillaFileLogger.prototype = {
-
-  init : function (path) {
-    var PR_WRITE_ONLY   = 0x02; // Open for writing only.
-    var PR_CREATE_FILE  = 0x08;
-    var PR_APPEND       = 0x10;
-    this._file = Components.classes["@mozilla.org/file/local;1"].
-                            createInstance(Components.interfaces.nsILocalFile);
-    this._file.initWithPath(path);
-    this._foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
-                                     createInstance(Components.interfaces.nsIFileOutputStream);
-    this._foStream.init(this._file, PR_WRITE_ONLY | PR_CREATE_FILE | PR_APPEND,
-                                     0664, 0);
-  },
-
-  getLogCallback : function() {
-    return function (msg) {
-      var data = msg.num + " " + msg.level + " " + msg.info.join(' ') + "\n";
-      if (MozillaFileLogger._foStream)
-        this._foStream.write(data, data.length);
-
-      if (data.indexOf("SimpleTest FINISH") >= 0) {
-        MozillaFileLogger.close();
-      }
-    }
-  },
-
-  log : function(msg) {
-    if (this._foStream)
-      this._foStream.write(msg, msg.length);
-  },
-
-  close : function() {
-    if(this._foStream)
-      this._foStream.close();
-
-    this._foStream = null;
-    this._file = null;
-  }
-};
-
-this.MozillaLogger = MozillaLogger;
-this.SpecialPowersLogger = SpecialPowersLogger;
-this.MozillaFileLogger = MozillaFileLogger;
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/SpecialPowersObserverAPI.js b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/SpecialPowersObserverAPI.js
deleted file mode 100644
index 160b82e..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/SpecialPowersObserverAPI.js
+++ /dev/null
@@ -1,413 +0,0 @@
-/* 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/. */
-"use strict";
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-if (typeof(Ci) == 'undefined') {
-  var Ci = Components.interfaces;
-}
-
-if (typeof(Cc) == 'undefined') {
-  var Cc = Components.classes;
-}
-
-/**
- * Special Powers Exception - used to throw exceptions nicely
- **/
-function SpecialPowersException(aMsg) {
-  this.message = aMsg;
-  this.name = "SpecialPowersException";
-}
-
-SpecialPowersException.prototype.toString = function() {
-  return this.name + ': "' + this.message + '"';
-};
-
-this.SpecialPowersObserverAPI = function SpecialPowersObserverAPI() {
-  this._crashDumpDir = null;
-  this._processCrashObserversRegistered = false;
-  this._chromeScriptListeners = [];
-}
-
-function parseKeyValuePairs(text) {
-  var lines = text.split('\n');
-  var data = {};
-  for (let i = 0; i < lines.length; i++) {
-    if (lines[i] == '')
-      continue;
-
-    // can't just .split() because the value might contain = characters
-    let eq = lines[i].indexOf('=');
-    if (eq != -1) {
-      let [key, value] = [lines[i].substring(0, eq),
-                          lines[i].substring(eq + 1)];
-      if (key && value)
-        data[key] = value.replace(/\\n/g, "\n").replace(/\\\\/g, "\\");
-    }
-  }
-  return data;
-}
-
-function parseKeyValuePairsFromFile(file) {
-  var fstream = Cc["@mozilla.org/network/file-input-stream;1"].
-                createInstance(Ci.nsIFileInputStream);
-  fstream.init(file, -1, 0, 0);
-  var is = Cc["@mozilla.org/intl/converter-input-stream;1"].
-           createInstance(Ci.nsIConverterInputStream);
-  is.init(fstream, "UTF-8", 1024, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-  var str = {};
-  var contents = '';
-  while (is.readString(4096, str) != 0) {
-    contents += str.value;
-  }
-  is.close();
-  fstream.close();
-  return parseKeyValuePairs(contents);
-}
-
-SpecialPowersObserverAPI.prototype = {
-
-  _observe: function(aSubject, aTopic, aData) {
-    function addDumpIDToMessage(propertyName) {
-      var id = aSubject.getPropertyAsAString(propertyName);
-      if (id) {
-        message.dumpIDs.push({id: id, extension: "dmp"});
-        message.dumpIDs.push({id: id, extension: "extra"});
-      }
-    }
-
-    switch(aTopic) {
-      case "plugin-crashed":
-      case "ipc:content-shutdown":
-        var message = { type: "crash-observed", dumpIDs: [] };
-        aSubject = aSubject.QueryInterface(Ci.nsIPropertyBag2);
-        if (aTopic == "plugin-crashed") {
-          addDumpIDToMessage("pluginDumpID");
-          addDumpIDToMessage("browserDumpID");
-
-          let pluginID = aSubject.getPropertyAsAString("pluginDumpID");
-          let extra = this._getExtraData(pluginID);
-          if (extra && ("additional_minidumps" in extra)) {
-            let dumpNames = extra.additional_minidumps.split(',');
-            for (let name of dumpNames) {
-              message.dumpIDs.push({id: pluginID + "-" + name, extension: "dmp"});
-            }
-          }
-        } else { // ipc:content-shutdown
-          addDumpIDToMessage("dumpID");
-        }
-        this._sendAsyncMessage("SPProcessCrashService", message);
-        break;
-    }
-  },
-
-  _getCrashDumpDir: function() {
-    if (!this._crashDumpDir) {
-      this._crashDumpDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
-      this._crashDumpDir.append("minidumps");
-    }
-    return this._crashDumpDir;
-  },
-
-  _getExtraData: function(dumpId) {
-    let extraFile = this._getCrashDumpDir().clone();
-    extraFile.append(dumpId + ".extra");
-    if (!extraFile.exists()) {
-      return null;
-    }
-    return parseKeyValuePairsFromFile(extraFile);
-  },
-
-  _deleteCrashDumpFiles: function(aFilenames) {
-    var crashDumpDir = this._getCrashDumpDir();
-    if (!crashDumpDir.exists()) {
-      return false;
-    }
-
-    var success = aFilenames.length != 0;
-    aFilenames.forEach(function(crashFilename) {
-      var file = crashDumpDir.clone();
-      file.append(crashFilename);
-      if (file.exists()) {
-        file.remove(false);
-      } else {
-        success = false;
-      }
-    });
-    return success;
-  },
-
-  _findCrashDumpFiles: function(aToIgnore) {
-    var crashDumpDir = this._getCrashDumpDir();
-    var entries = crashDumpDir.exists() && crashDumpDir.directoryEntries;
-    if (!entries) {
-      return [];
-    }
-
-    var crashDumpFiles = [];
-    while (entries.hasMoreElements()) {
-      var file = entries.getNext().QueryInterface(Ci.nsIFile);
-      var path = String(file.path);
-      if (path.match(/\.(dmp|extra)$/) && !aToIgnore[path]) {
-        crashDumpFiles.push(path);
-      }
-    }
-    return crashDumpFiles.concat();
-  },
-
-  _getURI: function (url) {
-    return Services.io.newURI(url, null, null);
-  },
-
-  _readUrlAsString: function(aUrl) {
-    // Fetch script content as we can't use scriptloader's loadSubScript
-    // to evaluate http:// urls...
-    var scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"]
-                             .getService(Ci.nsIScriptableInputStream);
-    var channel = Services.io.newChannel(aUrl, null, null);
-    var input = channel.open();
-    scriptableStream.init(input);
-
-    var str;
-    var buffer = [];
-
-    while ((str = scriptableStream.read(4096))) {
-      buffer.push(str);
-    }
-
-    var output = buffer.join("");
-
-    scriptableStream.close();
-    input.close();
-
-    var status;
-    try {
-      channel.QueryInterface(Ci.nsIHttpChannel);
-      status = channel.responseStatus;
-    } catch(e) {
-      /* The channel is not a nsIHttpCHannel, but that's fine */
-      dump("-*- _readUrlAsString: Got an error while fetching " +
-           "chrome script '" + aUrl + "': (" + e.name + ") " + e.message + ". " +
-           "Ignoring.\n");
-    }
-
-    if (status == 404) {
-      throw new SpecialPowersException(
-        "Error while executing chrome script '" + aUrl + "':\n" +
-        "The script doesn't exists. Ensure you have registered it in " +
-        "'support-files' in your mochitest.ini.");
-    }
-
-    return output;
-  },
-
-  /**
-   * messageManager callback function
-   * This will get requests from our API in the window and process them in chrome for it
-   **/
-  _receiveMessageAPI: function(aMessage) {
-    // We explicitly return values in the below code so that this function
-    // doesn't trigger a flurry of warnings about "does not always return
-    // a value".
-    switch(aMessage.name) {
-      case "SPPrefService":
-        var prefs = Services.prefs;
-        var prefType = aMessage.json.prefType.toUpperCase();
-        var prefName = aMessage.json.prefName;
-        var prefValue = "prefValue" in aMessage.json ? aMessage.json.prefValue : null;
-
-        if (aMessage.json.op == "get") {
-          if (!prefName || !prefType)
-            throw new SpecialPowersException("Invalid parameters for get in SPPrefService");
-
-          // return null if the pref doesn't exist
-          if (prefs.getPrefType(prefName) == prefs.PREF_INVALID)
-            return null;
-        } else if (aMessage.json.op == "set") {
-          if (!prefName || !prefType  || prefValue === null)
-            throw new SpecialPowersException("Invalid parameters for set in SPPrefService");
-        } else if (aMessage.json.op == "clear") {
-          if (!prefName)
-            throw new SpecialPowersException("Invalid parameters for clear in SPPrefService");
-        } else {
-          throw new SpecialPowersException("Invalid operation for SPPrefService");
-        }
-
-        // Now we make the call
-        switch(prefType) {
-          case "BOOL":
-            if (aMessage.json.op == "get")
-              return(prefs.getBoolPref(prefName));
-            else
-              return(prefs.setBoolPref(prefName, prefValue));
-          case "INT":
-            if (aMessage.json.op == "get")
-              return(prefs.getIntPref(prefName));
-            else
-              return(prefs.setIntPref(prefName, prefValue));
-          case "CHAR":
-            if (aMessage.json.op == "get")
-              return(prefs.getCharPref(prefName));
-            else
-              return(prefs.setCharPref(prefName, prefValue));
-          case "COMPLEX":
-            if (aMessage.json.op == "get")
-              return(prefs.getComplexValue(prefName, prefValue[0]));
-            else
-              return(prefs.setComplexValue(prefName, prefValue[0], prefValue[1]));
-          case "":
-            if (aMessage.json.op == "clear") {
-              prefs.clearUserPref(prefName);
-              return undefined;
-            }
-        }
-        return undefined;	// See comment at the beginning of this function.
-
-      case "SPProcessCrashService":
-        switch (aMessage.json.op) {
-          case "register-observer":
-            this._addProcessCrashObservers();
-            break;
-          case "unregister-observer":
-            this._removeProcessCrashObservers();
-            break;
-          case "delete-crash-dump-files":
-            return this._deleteCrashDumpFiles(aMessage.json.filenames);
-          case "find-crash-dump-files":
-            return this._findCrashDumpFiles(aMessage.json.crashDumpFilesToIgnore);
-          default:
-            throw new SpecialPowersException("Invalid operation for SPProcessCrashService");
-        }
-        return undefined;	// See comment at the beginning of this function.
-
-      case "SPPermissionManager":
-        let msg = aMessage.json;
-
-        let secMan = Services.scriptSecurityManager;
-        let principal = secMan.getAppCodebasePrincipal(this._getURI(msg.url), msg.appId, msg.isInBrowserElement);
-
-        switch (msg.op) {
-          case "add":
-            Services.perms.addFromPrincipal(principal, msg.type, msg.permission);
-            break;
-          case "remove":
-            Services.perms.removeFromPrincipal(principal, msg.type);
-            break;
-          case "has":
-            let hasPerm = Services.perms.testPermissionFromPrincipal(principal, msg.type);
-            if (hasPerm == Ci.nsIPermissionManager.ALLOW_ACTION)
-              return true;
-            return false;
-            break;
-          case "test":
-            let testPerm = Services.perms.testPermissionFromPrincipal(principal, msg.type, msg.value);
-            if (testPerm == msg.value)  {
-              return true;
-            }
-            return false;
-            break;
-          default:
-            throw new SpecialPowersException("Invalid operation for " +
-                                             "SPPermissionManager");
-        }
-        return undefined;	// See comment at the beginning of this function.
-
-      case "SPWebAppService":
-        let Webapps = {};
-        Components.utils.import("resource://gre/modules/Webapps.jsm", Webapps);
-        switch (aMessage.json.op) {
-          case "set-launchable":
-            let val = Webapps.DOMApplicationRegistry.allAppsLaunchable;
-            Webapps.DOMApplicationRegistry.allAppsLaunchable = aMessage.json.launchable;
-            return val;
-          default:
-            throw new SpecialPowersException("Invalid operation for SPWebAppsService");
-        }
-        return undefined;	// See comment at the beginning of this function.
-
-      case "SPObserverService":
-        switch (aMessage.json.op) {
-          case "notify":
-            let topic = aMessage.json.observerTopic;
-            let data = aMessage.json.observerData
-            Services.obs.notifyObservers(null, topic, data);
-            break;
-          default:
-            throw new SpecialPowersException("Invalid operation for SPObserverervice");
-        }
-        return undefined;	// See comment at the beginning of this function.
-
-      case "SPLoadChromeScript":
-        var url = aMessage.json.url;
-        var id = aMessage.json.id;
-
-        var jsScript = this._readUrlAsString(url);
-
-        // Setup a chrome sandbox that has access to sendAsyncMessage
-        // and addMessageListener in order to communicate with
-        // the mochitest.
-        var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
-        var sb = Components.utils.Sandbox(systemPrincipal);
-        var mm = aMessage.target
-                         .QueryInterface(Ci.nsIFrameLoaderOwner)
-                         .frameLoader
-                         .messageManager;
-        sb.sendAsyncMessage = (name, message) => {
-          mm.sendAsyncMessage("SPChromeScriptMessage",
-                              { id: id, name: name, message: message });
-        };
-        sb.addMessageListener = (name, listener) => {
-          this._chromeScriptListeners.push({ id: id, name: name, listener: listener });
-        };
-
-        // Also expose assertion functions
-        let reporter = function (err, message, stack) {
-          // Pipe assertions back to parent process
-          mm.sendAsyncMessage("SPChromeScriptAssert",
-                              { id: id, url: url, err: err, message: message,
-                                stack: stack });
-        };
-        Object.defineProperty(sb, "assert", {
-          get: function () {
-            let scope = Components.utils.createObjectIn(sb);
-            Services.scriptloader.loadSubScript("resource://specialpowers/Assert.jsm",
-                                                scope);
-
-            let assert = new scope.Assert(reporter);
-            delete sb.assert;
-            return sb.assert = assert;
-          },
-          configurable: true
-        });
-
-        // Evaluate the chrome script
-        try {
-          Components.utils.evalInSandbox(jsScript, sb, "1.8", url, 1);
-        } catch(e) {
-          throw new SpecialPowersException("Error while executing chrome " +
-                                           "script '" + url + "':\n" + e + "\n" +
-                                           e.fileName + ":" + e.lineNumber);
-        }
-        return undefined;	// See comment at the beginning of this function.
-
-      case "SPChromeScriptMessage":
-        var id = aMessage.json.id;
-        var name = aMessage.json.name;
-        var message = aMessage.json.message;
-        this._chromeScriptListeners
-            .filter(o => (o.name == name && o.id == id))
-            .forEach(o => o.listener(message));
-        return undefined;	// See comment at the beginning of this function.
-
-      default:
-        throw new SpecialPowersException("Unrecognized Special Powers API");
-    }
-
-    // We throw an exception before reaching this explicit return because
-    // we should never be arriving here anyway.
-    throw new SpecialPowersException("Unreached code");
-    return undefined;
-  }
-};
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/specialpowers.js b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/specialpowers.js
deleted file mode 100644
index 31ff093..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/specialpowers.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* 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/. */
-/* This code is loaded in every child process that is started by mochitest in
- * order to be used as a replacement for UniversalXPConnect
- */
-
-function SpecialPowers(window) {
-  this.window = Components.utils.getWeakReference(window);
-  this._encounteredCrashDumpFiles = [];
-  this._unexpectedCrashDumpFiles = { };
-  this._crashDumpDir = null;
-  this.DOMWindowUtils = bindDOMWindowUtils(window);
-  Object.defineProperty(this, 'Components', {
-      configurable: true, enumerable: true, get: function() {
-          var win = this.window.get();
-          if (!win)
-              return null;
-          return getRawComponents(win);
-      }});
-  this._pongHandlers = [];
-  this._messageListener = this._messageReceived.bind(this);
-  addMessageListener("SPPingService", this._messageListener);
-}
-
-SpecialPowers.prototype = new SpecialPowersAPI();
-
-SpecialPowers.prototype.toString = function() { return "[SpecialPowers]"; };
-SpecialPowers.prototype.sanityCheck = function() { return "foo"; };
-
-// This gets filled in in the constructor.
-SpecialPowers.prototype.DOMWindowUtils = undefined;
-SpecialPowers.prototype.Components = undefined;
-
-SpecialPowers.prototype._sendSyncMessage = function(msgname, msg) {
-  return sendSyncMessage(msgname, msg);
-};
-
-SpecialPowers.prototype._sendAsyncMessage = function(msgname, msg) {
-  sendAsyncMessage(msgname, msg);
-};
-
-SpecialPowers.prototype._addMessageListener = function(msgname, listener) {
-  addMessageListener(msgname, listener);
-};
-
-SpecialPowers.prototype._removeMessageListener = function(msgname, listener) {
-  removeMessageListener(msgname, listener);
-};
-
-SpecialPowers.prototype.registerProcessCrashObservers = function() {
-  addMessageListener("SPProcessCrashService", this._messageListener);
-  sendSyncMessage("SPProcessCrashService", { op: "register-observer" });
-};
-
-SpecialPowers.prototype.unregisterProcessCrashObservers = function() {
-  addMessageListener("SPProcessCrashService", this._messageListener);
-  sendSyncMessage("SPProcessCrashService", { op: "unregister-observer" });
-};
-
-SpecialPowers.prototype._messageReceived = function(aMessage) {
-  switch (aMessage.name) {
-    case "SPProcessCrashService":
-      if (aMessage.json.type == "crash-observed") {
-        for (let e of aMessage.json.dumpIDs) {
-          this._encounteredCrashDumpFiles.push(e.id + "." + e.extension);
-        }
-      }
-      break;
-
-    case "SPPingService":
-      if (aMessage.json.op == "pong") {
-        var handler = this._pongHandlers.shift();
-        if (handler) {
-          handler();
-        }
-      }
-      break;
-  }
-  return true;
-};
-
-SpecialPowers.prototype.quit = function() {
-  sendAsyncMessage("SpecialPowers.Quit", {});
-};
-
-SpecialPowers.prototype.executeAfterFlushingMessageQueue = function(aCallback) {
-  this._pongHandlers.push(aCallback);
-  sendAsyncMessage("SPPingService", { op: "ping" });
-};
-
-// Expose everything but internal APIs (starting with underscores) to
-// web content.  We cannot use Object.keys to view SpecialPowers.prototype since
-// we are using the functions from SpecialPowersAPI.prototype
-SpecialPowers.prototype.__exposedProps__ = {};
-for (var i in SpecialPowers.prototype) {
-  if (i.charAt(0) != "_")
-    SpecialPowers.prototype.__exposedProps__[i] = "r";
-}
-
-// Attach our API to the window.
-function attachSpecialPowersToWindow(aWindow) {
-  try {
-    if ((aWindow !== null) &&
-        (aWindow !== undefined) &&
-        (aWindow.wrappedJSObject) &&
-        !(aWindow.wrappedJSObject.SpecialPowers)) {
-      aWindow.wrappedJSObject.SpecialPowers = new SpecialPowers(aWindow);
-    }
-  } catch(ex) {
-    dump("TEST-INFO | specialpowers.js |  Failed to attach specialpowers to window exception: " + ex + "\n");
-  }
-}
-
-// This is a frame script, so it may be running in a content process.
-// In any event, it is targeted at a specific "tab", so we listen for
-// the DOMWindowCreated event to be notified about content windows
-// being created in this context.
-
-function SpecialPowersManager() {
-  addEventListener("DOMWindowCreated", this, false);
-}
-
-SpecialPowersManager.prototype = {
-  handleEvent: function handleEvent(aEvent) {
-    var window = aEvent.target.defaultView;
-    attachSpecialPowersToWindow(window);
-  }
-};
-
-var specialpowersmanager = new SpecialPowersManager();
-
-this.SpecialPowers = SpecialPowers;
-this.attachSpecialPowersToWindow = attachSpecialPowersToWindow;
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/specialpowersAPI.js b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/specialpowersAPI.js
deleted file mode 100644
index 7c1344d..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/content/specialpowersAPI.js
+++ /dev/null
@@ -1,1744 +0,0 @@
-/* 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/. */
-/* This code is loaded in every child process that is started by mochitest in
- * order to be used as a replacement for UniversalXPConnect
- */
-
-var Ci = Components.interfaces;
-var Cc = Components.classes;
-var Cu = Components.utils;
-
-Cu.import("resource://specialpowers/MockFilePicker.jsm");
-Cu.import("resource://specialpowers/MockColorPicker.jsm");
-Cu.import("resource://specialpowers/MockPermissionPrompt.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function SpecialPowersAPI() {
-  this._consoleListeners = [];
-  this._encounteredCrashDumpFiles = [];
-  this._unexpectedCrashDumpFiles = { };
-  this._crashDumpDir = null;
-  this._mfl = null;
-  this._prefEnvUndoStack = [];
-  this._pendingPrefs = [];
-  this._applyingPrefs = false;
-  this._permissionsUndoStack = [];
-  this._pendingPermissions = [];
-  this._applyingPermissions = false;
-  this._fm = null;
-  this._cb = null;
-}
-
-function bindDOMWindowUtils(aWindow) {
-  if (!aWindow)
-    return
-
-   var util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                     .getInterface(Ci.nsIDOMWindowUtils);
-   return wrapPrivileged(util);
-}
-
-function getRawComponents(aWindow) {
-  // If we're running in automation that supports enablePrivilege, then we also
-  // provided access to the privileged Components.
-  try {
-    let win = Cu.waiveXrays(aWindow);
-    if (typeof win.netscape.security.PrivilegeManager == 'object')
-      Cu.forcePrivilegedComponentsForScope(aWindow);
-  } catch (e) {}
-  return Cu.getComponentsForScope(aWindow);
-}
-
-function isWrappable(x) {
-  if (typeof x === "object")
-    return x !== null;
-  return typeof x === "function";
-};
-
-function isWrapper(x) {
-  return isWrappable(x) && (typeof x.SpecialPowers_wrappedObject !== "undefined");
-};
-
-function unwrapIfWrapped(x) {
-  return isWrapper(x) ? unwrapPrivileged(x) : x;
-};
-
-function wrapIfUnwrapped(x) {
-  return isWrapper(x) ? x : wrapPrivileged(x);
-}
-
-function isXrayWrapper(x) {
-  return Cu.isXrayWrapper(x);
-}
-
-function callGetOwnPropertyDescriptor(obj, name) {
-  // Quickstubbed getters and setters are propertyOps, and don't get reified
-  // until someone calls __lookupGetter__ or __lookupSetter__ on them (note
-  // that there are special version of those functions for quickstubs, so
-  // apply()ing Object.prototype.__lookupGetter__ isn't good enough). Try to
-  // trigger reification before calling Object.getOwnPropertyDescriptor.
-  //
-  // See bug 764315.
-  try {
-    obj.__lookupGetter__(name);
-    obj.__lookupSetter__(name);
-  } catch(e) { }
-  return Object.getOwnPropertyDescriptor(obj, name);
-}
-
-// We can't call apply() directy on Xray-wrapped functions, so we have to be
-// clever.
-function doApply(fun, invocant, args) {
-  return Function.prototype.apply.call(fun, invocant, args);
-}
-
-function wrapPrivileged(obj) {
-
-  // Primitives pass straight through.
-  if (!isWrappable(obj))
-    return obj;
-
-  // No double wrapping.
-  if (isWrapper(obj))
-    throw "Trying to double-wrap object!";
-
-  // Make our core wrapper object.
-  var handler = new SpecialPowersHandler(obj);
-
-  // If the object is callable, make a function proxy.
-  if (typeof obj === "function") {
-    var callTrap = function() {
-      // The invocant and arguments may or may not be wrappers. Unwrap them if necessary.
-      var invocant = unwrapIfWrapped(this);
-      var unwrappedArgs = Array.prototype.slice.call(arguments).map(unwrapIfWrapped);
-
-      try {
-        return wrapPrivileged(doApply(obj, invocant, unwrappedArgs));
-      } catch (e) {
-        // Wrap exceptions and re-throw them.
-        throw wrapIfUnwrapped(e);
-      }
-    };
-    var constructTrap = function() {
-      // The arguments may or may not be wrappers. Unwrap them if necessary.
-      var unwrappedArgs = Array.prototype.slice.call(arguments).map(unwrapIfWrapped);
-
-      // We want to invoke "obj" as a constructor, but using unwrappedArgs as
-      // the arguments.  Make sure to wrap and re-throw exceptions!
-      try {
-        return wrapPrivileged(new obj(...unwrappedArgs));
-      } catch (e) {
-        throw wrapIfUnwrapped(e);
-      }
-    };
-
-    return Proxy.createFunction(handler, callTrap, constructTrap);
-  }
-
-  // Otherwise, just make a regular object proxy.
-  return Proxy.create(handler);
-};
-
-function unwrapPrivileged(x) {
-
-  // We don't wrap primitives, so sometimes we have a primitive where we'd
-  // expect to have a wrapper. The proxy pretends to be the type that it's
-  // emulating, so we can just as easily check isWrappable() on a proxy as
-  // we can on an unwrapped object.
-  if (!isWrappable(x))
-    return x;
-
-  // If we have a wrappable type, make sure it's wrapped.
-  if (!isWrapper(x))
-    throw "Trying to unwrap a non-wrapped object!";
-
-  // Unwrap.
-  return x.SpecialPowers_wrappedObject;
-};
-
-function crawlProtoChain(obj, fn) {
-  var rv = fn(obj);
-  if (rv !== undefined)
-    return rv;
-  if (Object.getPrototypeOf(obj))
-    return crawlProtoChain(Object.getPrototypeOf(obj), fn);
-};
-
-/*
- * We want to waive the __exposedProps__ security check for SpecialPowers-wrapped
- * objects. We do this by creating a proxy singleton that just always returns 'rw'
- * for any property name.
- */
-function ExposedPropsWaiverHandler() {
-  // NB: XPConnect denies access if the relevant member of __exposedProps__ is not
-  // enumerable.
-  var _permit = { value: 'rw', writable: false, configurable: false, enumerable: true };
-  return {
-    getOwnPropertyDescriptor: function(name) { return _permit; },
-    getPropertyDescriptor: function(name) { return _permit; },
-    getOwnPropertyNames: function() { throw Error("Can't enumerate ExposedPropsWaiver"); },
-    getPropertyNames: function() { throw Error("Can't enumerate ExposedPropsWaiver"); },
-    enumerate: function() { throw Error("Can't enumerate ExposedPropsWaiver"); },
-    defineProperty: function(name) { throw Error("Can't define props on ExposedPropsWaiver"); },
-    delete: function(name) { throw Error("Can't delete props from ExposedPropsWaiver"); }
-  };
-};
-ExposedPropsWaiver = Proxy.create(ExposedPropsWaiverHandler());
-
-function SpecialPowersHandler(obj) {
-  this.wrappedObject = obj;
-};
-
-// Allow us to transitively maintain the membrane by wrapping descriptors
-// we return.
-SpecialPowersHandler.prototype.doGetPropertyDescriptor = function(name, own) {
-
-  // Handle our special API.
-  if (name == "SpecialPowers_wrappedObject")
-    return { value: this.wrappedObject, writeable: false, configurable: false, enumerable: false };
-
-  // Handle __exposedProps__.
-  if (name == "__exposedProps__")
-    return { value: ExposedPropsWaiver, writable: false, configurable: false, enumerable: false };
-
-  // In general, we want Xray wrappers for content DOM objects, because waiving
-  // Xray gives us Xray waiver wrappers that clamp the principal when we cross
-  // compartment boundaries. However, Xray adds some gunk to toString(), which
-  // has the potential to confuse consumers that aren't expecting Xray wrappers.
-  // Since toString() is a non-privileged method that returns only strings, we
-  // can just waive Xray for that case.
-  var obj = name == 'toString' ? XPCNativeWrapper.unwrap(this.wrappedObject)
-                               : this.wrappedObject;
-
-  //
-  // Call through to the wrapped object.
-  //
-  // Note that we have several cases here, each of which requires special handling.
-  //
-  var desc;
-
-  // Case 1: Own Properties.
-  //
-  // This one is easy, thanks to Object.getOwnPropertyDescriptor().
-  if (own)
-    desc = callGetOwnPropertyDescriptor(obj, name);
-
-  // Case 2: Not own, not Xray-wrapped.
-  //
-  // Here, we can just crawl the prototype chain, calling
-  // Object.getOwnPropertyDescriptor until we find what we want.
-  //
-  // NB: Make sure to check this.wrappedObject here, rather than obj, because
-  // we may have waived Xray on obj above.
-  else if (!isXrayWrapper(this.wrappedObject))
-    desc = crawlProtoChain(obj, function(o) {return callGetOwnPropertyDescriptor(o, name);});
-
-  // Case 3: Not own, Xray-wrapped.
-  //
-  // This one is harder, because we Xray wrappers are flattened and don't have
-  // a prototype. Xray wrappers are proxies themselves, so we'd love to just call
-  // through to XrayWrapper<Base>::getPropertyDescriptor(). Unfortunately though,
-  // we don't have any way to do that. :-(
-  //
-  // So we first try with a call to getOwnPropertyDescriptor(). If that fails,
-  // we make up a descriptor, using some assumptions about what kinds of things
-  // tend to live on the prototypes of Xray-wrapped objects.
-  else {
-    desc = Object.getOwnPropertyDescriptor(obj, name);
-    if (!desc) {
-      var getter = Object.prototype.__lookupGetter__.call(obj, name);
-      var setter = Object.prototype.__lookupSetter__.call(obj, name);
-      if (getter || setter)
-        desc = {get: getter, set: setter, configurable: true, enumerable: true};
-      else if (name in obj)
-        desc = {value: obj[name], writable: false, configurable: true, enumerable: true};
-    }
-  }
-
-  // Bail if we've got nothing.
-  if (typeof desc === 'undefined')
-    return undefined;
-
-  // When accessors are implemented as JSPropertyOps rather than JSNatives (ie,
-  // QuickStubs), the js engine does the wrong thing and treats it as a value
-  // descriptor rather than an accessor descriptor. Jorendorff suggested this
-  // little hack to work around it. See bug 520882.
-  if (desc && 'value' in desc && desc.value === undefined)
-    desc.value = obj[name];
-
-  // A trapping proxy's properties must always be configurable, but sometimes
-  // this we get non-configurable properties from Object.getOwnPropertyDescriptor().
-  // Tell a white lie.
-  desc.configurable = true;
-
-  // Transitively maintain the wrapper membrane.
-  function wrapIfExists(key) { if (key in desc) desc[key] = wrapPrivileged(desc[key]); };
-  wrapIfExists('value');
-  wrapIfExists('get');
-  wrapIfExists('set');
-
-  return desc;
-};
-
-SpecialPowersHandler.prototype.getOwnPropertyDescriptor = function(name) {
-  return this.doGetPropertyDescriptor(name, true);
-};
-
-SpecialPowersHandler.prototype.getPropertyDescriptor = function(name) {
-  return this.doGetPropertyDescriptor(name, false);
-};
-
-function doGetOwnPropertyNames(obj, props) {
-
-  // Insert our special API. It's not enumerable, but getPropertyNames()
-  // includes non-enumerable properties.
-  var specialAPI = 'SpecialPowers_wrappedObject';
-  if (props.indexOf(specialAPI) == -1)
-    props.push(specialAPI);
-
-  // Do the normal thing.
-  var flt = function(a) { return props.indexOf(a) == -1; };
-  props = props.concat(Object.getOwnPropertyNames(obj).filter(flt));
-
-  // If we've got an Xray wrapper, include the expandos as well.
-  if ('wrappedJSObject' in obj)
-    props = props.concat(Object.getOwnPropertyNames(obj.wrappedJSObject)
-                         .filter(flt));
-
-  return props;
-}
-
-SpecialPowersHandler.prototype.getOwnPropertyNames = function() {
-  return doGetOwnPropertyNames(this.wrappedObject, []);
-};
-
-SpecialPowersHandler.prototype.getPropertyNames = function() {
-
-  // Manually walk the prototype chain, making sure to add only property names
-  // that haven't been overridden.
-  //
-  // There's some trickiness here with Xray wrappers. Xray wrappers don't have
-  // a prototype, so we need to unwrap them if we want to get all of the names
-  // with Object.getOwnPropertyNames(). But we don't really want to unwrap the
-  // base object, because that will include expandos that are inaccessible via
-  // our implementation of get{,Own}PropertyDescriptor(). So we unwrap just
-  // before accessing the prototype. This ensures that we get Xray vision on
-  // the base object, and no Xray vision for the rest of the way up.
-  var obj = this.wrappedObject;
-  var props = [];
-  while (obj) {
-    props = doGetOwnPropertyNames(obj, props);
-    obj = Object.getPrototypeOf(XPCNativeWrapper.unwrap(obj));
-  }
-  return props;
-};
-
-SpecialPowersHandler.prototype.defineProperty = function(name, desc) {
-  return Object.defineProperty(this.wrappedObject, name, desc);
-};
-
-SpecialPowersHandler.prototype.delete = function(name) {
-  return delete this.wrappedObject[name];
-};
-
-SpecialPowersHandler.prototype.fix = function() { return undefined; /* Throws a TypeError. */ };
-
-// Per the ES5 spec this is a derived trap, but it's fundamental in spidermonkey
-// for some reason. See bug 665198.
-SpecialPowersHandler.prototype.enumerate = function() {
-  var t = this;
-  var filt = function(name) { return t.getPropertyDescriptor(name).enumerable; };
-  return this.getPropertyNames().filter(filt);
-};
-
-// SPConsoleListener reflects nsIConsoleMessage objects into JS in a
-// tidy, XPCOM-hiding way.  Messages that are nsIScriptError objects
-// have their properties exposed in detail.  It also auto-unregisters
-// itself when it receives a "sentinel" message.
-function SPConsoleListener(callback) {
-  this.callback = callback;
-}
-
-SPConsoleListener.prototype = {
-  observe: function(msg) {
-    let m = { message: msg.message,
-              errorMessage: null,
-              sourceName: null,
-              sourceLine: null,
-              lineNumber: null,
-              columnNumber: null,
-              category: null,
-              windowID: null,
-              isScriptError: false,
-              isWarning: false,
-              isException: false,
-              isStrict: false };
-    if (msg instanceof Ci.nsIScriptError) {
-      m.errorMessage  = msg.errorMessage;
-      m.sourceName    = msg.sourceName;
-      m.sourceLine    = msg.sourceLine;
-      m.lineNumber    = msg.lineNumber;
-      m.columnNumber  = msg.columnNumber;
-      m.category      = msg.category;
-      m.windowID      = msg.outerWindowID;
-      m.isScriptError = true;
-      m.isWarning     = ((msg.flags & Ci.nsIScriptError.warningFlag) === 1);
-      m.isException   = ((msg.flags & Ci.nsIScriptError.exceptionFlag) === 1);
-      m.isStrict      = ((msg.flags & Ci.nsIScriptError.strictFlag) === 1);
-    }
-
-    // expose all props of 'm' as read-only
-    let expose = {};
-    for (let prop in m)
-      expose[prop] = 'r';
-    m.__exposedProps__ = expose;
-    Object.freeze(m);
-
-    this.callback.call(undefined, m);
-
-    if (!m.isScriptError && m.message === "SENTINEL")
-      Services.console.unregisterListener(this);
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener])
-};
-
-function wrapCallback(cb) {
-  return function SpecialPowersCallbackWrapper() {
-    args = Array.prototype.map.call(arguments, wrapIfUnwrapped);
-    return cb.apply(this, args);
-  }
-}
-
-function wrapCallbackObject(obj) {
-  wrapper = { __exposedProps__: ExposedPropsWaiver };
-  for (var i in obj) {
-    if (typeof obj[i] == 'function')
-      wrapper[i] = wrapCallback(obj[i]);
-    else
-      wrapper[i] = obj[i];
-  }
-  return wrapper;
-}
-
-SpecialPowersAPI.prototype = {
-
-  /*
-   * Privileged object wrapping API
-   *
-   * Usage:
-   *   var wrapper = SpecialPowers.wrap(obj);
-   *   wrapper.privilegedMethod(); wrapper.privilegedProperty;
-   *   obj === SpecialPowers.unwrap(wrapper);
-   *
-   * These functions provide transparent access to privileged objects using
-   * various pieces of deep SpiderMagic. Conceptually, a wrapper is just an
-   * object containing a reference to the underlying object, where all method
-   * calls and property accesses are transparently performed with the System
-   * Principal. Moreover, objects obtained from the wrapper (including properties
-   * and method return values) are wrapped automatically. Thus, after a single
-   * call to SpecialPowers.wrap(), the wrapper layer is transitively maintained.
-   *
-   * Known Issues:
-   *
-   *  - The wrapping function does not preserve identity, so
-   *    SpecialPowers.wrap(foo) !== SpecialPowers.wrap(foo). See bug 718543.
-   *
-   *  - The wrapper cannot see expando properties on unprivileged DOM objects.
-   *    That is to say, the wrapper uses Xray delegation.
-   *
-   *  - The wrapper sometimes guesses certain ES5 attributes for returned
-   *    properties. This is explained in a comment in the wrapper code above,
-   *    and shouldn't be a problem.
-   */
-  wrap: wrapIfUnwrapped,
-  unwrap: unwrapIfWrapped,
-  isWrapper: isWrapper,
-
-  /*
-   * When content needs to pass a callback or a callback object to an API
-   * accessed over SpecialPowers, that API may sometimes receive arguments for
-   * whom it is forbidden to create a wrapper in content scopes. As such, we
-   * need a layer to wrap the values in SpecialPowers wrappers before they ever
-   * reach content.
-   */
-  wrapCallback: wrapCallback,
-  wrapCallbackObject: wrapCallbackObject,
-
-  /*
-   * Create blank privileged objects to use as out-params for privileged functions.
-   */
-  createBlankObject: function () {
-    var obj = new Object;
-    obj.__exposedProps__ = ExposedPropsWaiver;
-    return obj;
-  },
-
-  /*
-   * Because SpecialPowers wrappers don't preserve identity, comparing with ==
-   * can be hazardous. Sometimes we can just unwrap to compare, but sometimes
-   * wrapping the underlying object into a content scope is forbidden. This
-   * function strips any wrappers if they exist and compare the underlying
-   * values.
-   */
-  compare: function(a, b) {
-    return unwrapIfWrapped(a) === unwrapIfWrapped(b);
-  },
-
-  get MockFilePicker() {
-    return MockFilePicker
-  },
-
-  get MockColorPicker() {
-    return MockColorPicker
-  },
-
-  get MockPermissionPrompt() {
-    return MockPermissionPrompt
-  },
-
-  loadChromeScript: function (url) {
-    // Create a unique id for this chrome script
-    let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
-                          .getService(Ci.nsIUUIDGenerator);
-    let id = uuidGenerator.generateUUID().toString();
-
-    // Tells chrome code to evaluate this chrome script
-    this._sendSyncMessage("SPLoadChromeScript",
-                          { url: url, id: id });
-
-    // Returns a MessageManager like API in order to be
-    // able to communicate with this chrome script
-    let listeners = [];
-    let chromeScript = {
-      addMessageListener: (name, listener) => {
-        listeners.push({ name: name, listener: listener });
-      },
-
-      removeMessageListener: (name, listener) => {
-        listeners = listeners.filter(
-          o => (o.name != name || o.listener != listener)
-        );
-      },
-
-      sendAsyncMessage: (name, message) => {
-        this._sendSyncMessage("SPChromeScriptMessage",
-                              { id: id, name: name, message: message });
-      },
-
-      destroy: () => {
-        listeners = [];
-        this._removeMessageListener("SPChromeScriptMessage", chromeScript);
-        this._removeMessageListener("SPChromeScriptAssert", chromeScript);
-      },
-
-      receiveMessage: (aMessage) => {
-        let messageId = aMessage.json.id;
-        let name = aMessage.json.name;
-        let message = aMessage.json.message;
-        // Ignore message from other chrome script
-        if (messageId != id)
-          return;
-
-        if (aMessage.name == "SPChromeScriptMessage") {
-          listeners.filter(o => (o.name == name))
-                   .forEach(o => o.listener(this.wrap(message)));
-        } else if (aMessage.name == "SPChromeScriptAssert") {
-          assert(aMessage.json);
-        }
-      }
-    };
-    this._addMessageListener("SPChromeScriptMessage", chromeScript);
-    this._addMessageListener("SPChromeScriptAssert", chromeScript);
-
-    let assert = json => {
-      // An assertion has been done in a mochitest chrome script
-      let {url, err, message, stack} = json;
-
-      // Try to fetch a test runner from the mochitest
-      // in order to properly log these assertions and notify
-      // all usefull log observers
-      let window = this.window.get();
-      let parentRunner, repr = function (o) o;
-      if (window) {
-        window = window.wrappedJSObject;
-        parentRunner = window.TestRunner;
-        if (window.repr) {
-          repr = window.repr;
-        }
-      }
-
-      // Craft a mochitest-like report string
-      var resultString = err ? "TEST-UNEXPECTED-FAIL" : "TEST-PASS";
-      var diagnostic =
-        message ? message :
-                  ("assertion @ " + stack.filename + ":" + stack.lineNumber);
-      if (err) {
-        diagnostic +=
-          " - got " + repr(err.actual) +
-          ", expected " + repr(err.expected) +
-          " (operator " + err.operator + ")";
-      }
-      var msg = [resultString, url, diagnostic].join(" | ");
-      if (parentRunner) {
-        if (err) {
-          parentRunner.addFailedTest(url);
-          parentRunner.error(msg);
-        } else {
-          parentRunner.log(msg);
-        }
-      } else {
-        // When we are running only a single mochitest, there is no test runner
-        dump(msg + "\n");
-      }
-    };
-
-    return this.wrap(chromeScript);
-  },
-
-  get Services() {
-    return wrapPrivileged(Services);
-  },
-
-  /*
-   * In general, any Components object created for unprivileged scopes is
-   * neutered (it implements nsIXPCComponentsBase, but not nsIXPCComponents).
-   * We override this in certain legacy automation configurations (see the
-   * implementation of getRawComponents() above), but don't want to support
-   * it in cases where it isn't already required.
-   *
-   * In scopes with neutered Components, we don't have a natural referent for
-   * things like SpecialPowers.Cc. So in those cases, we fall back to the
-   * Components object from the SpecialPowers scope. This doesn't quite behave
-   * the same way (in particular, SpecialPowers.Cc[foo].createInstance() will
-   * create an instance in the SpecialPowers scope), but SpecialPowers wrapping
-   * is already a YMMV / Whatever-It-Takes-To-Get-TBPL-Green sort of thing.
-   *
-   * It probably wouldn't be too much work to just make SpecialPowers.Components
-   * unconditionally point to the Components object in the SpecialPowers scope.
-   * Try will tell what needs to be fixed up.
-   */
-  getFullComponents: function() {
-    return typeof this.Components.classes == 'object' ? this.Components
-                                                      : Components;
-  },
-
-  /*
-   * Convenient shortcuts to the standard Components abbreviations. Note that
-   * we don't SpecialPowers-wrap Components.interfaces, because it's available
-   * to untrusted content, and wrapping it confuses QI and identity checks.
-   */
-  get Cc() { return wrapPrivileged(this.getFullComponents()).classes; },
-  get Ci() { return this.Components.interfaces; },
-  get Cu() { return wrapPrivileged(this.getFullComponents()).utils; },
-  get Cr() { return wrapPrivileged(this.Components).results; },
-
-  /*
-   * SpecialPowers.getRawComponents() allows content to get a reference to a
-   * naked (and, in certain automation configurations, privileged) Components
-   * object for its scope.
-   *
-   * SpecialPowers.getRawComponents(window) is defined as the global property
-   * window.SpecialPowers.Components for convenience.
-   */
-  getRawComponents: getRawComponents,
-
-  getDOMWindowUtils: function(aWindow) {
-    if (aWindow == this.window.get() && this.DOMWindowUtils != null)
-      return this.DOMWindowUtils;
-
-    return bindDOMWindowUtils(aWindow);
-  },
-
-  removeExpectedCrashDumpFiles: function(aExpectingProcessCrash) {
-    var success = true;
-    if (aExpectingProcessCrash) {
-      var message = {
-        op: "delete-crash-dump-files",
-        filenames: this._encounteredCrashDumpFiles
-      };
-      if (!this._sendSyncMessage("SPProcessCrashService", message)[0]) {
-        success = false;
-      }
-    }
-    this._encounteredCrashDumpFiles.length = 0;
-    return success;
-  },
-
-  findUnexpectedCrashDumpFiles: function() {
-    var self = this;
-    var message = {
-      op: "find-crash-dump-files",
-      crashDumpFilesToIgnore: this._unexpectedCrashDumpFiles
-    };
-    var crashDumpFiles = this._sendSyncMessage("SPProcessCrashService", message)[0];
-    crashDumpFiles.forEach(function(aFilename) {
-      self._unexpectedCrashDumpFiles[aFilename] = true;
-    });
-    return crashDumpFiles;
-  },
-
-  _delayCallbackTwice: function(callback) {
-    function delayedCallback() {
-      function delayAgain() {
-	content.window.setTimeout(callback, 0);
-      }
-      content.window.setTimeout(delayAgain, 0);
-    }
-    return delayedCallback;
-  },
-
-  /* apply permissions to the system and when the test case is finished (SimpleTest.finish())
-     we will revert the permission back to the original.
-
-     inPermissions is an array of objects where each object has a type, action, context, ex:
-     [{'type': 'SystemXHR', 'allow': 1, 'context': document},
-      {'type': 'SystemXHR', 'allow': Ci.nsIPermissionManager.PROMPT_ACTION, 'context': document}]
-
-     Allow can be a boolean value of true/false or ALLOW_ACTION/DENY_ACTION/PROMPT_ACTION/UNKNOWN_ACTION
-  */
-  pushPermissions: function(inPermissions, callback) {
-    var pendingPermissions = [];
-    var cleanupPermissions = [];
-
-    for (var p in inPermissions) {
-        var permission = inPermissions[p];
-        var originalValue = Ci.nsIPermissionManager.UNKNOWN_ACTION;
-        if (this.testPermission(permission.type, Ci.nsIPermissionManager.ALLOW_ACTION, permission.context)) {
-          originalValue = Ci.nsIPermissionManager.ALLOW_ACTION;
-        } else if (this.testPermission(permission.type, Ci.nsIPermissionManager.DENY_ACTION, permission.context)) {
-          originalValue = Ci.nsIPermissionManager.DENY_ACTION;
-        } else if (this.testPermission(permission.type, Ci.nsIPermissionManager.PROMPT_ACTION, permission.context)) {
-          originalValue = Ci.nsIPermissionManager.PROMPT_ACTION;
-        } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_SESSION, permission.context)) {
-          originalValue = Ci.nsICookiePermission.ACCESS_SESSION;
-        } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY, permission.context)) {
-          originalValue = Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY;
-        } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY, permission.context)) {
-          originalValue = Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY;
-        }
-
-        let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(permission.context);
-
-        let perm;
-        if (typeof permission.allow !== 'boolean') {
-          perm = permission.allow;
-        } else {
-          perm = permission.allow ? Ci.nsIPermissionManager.ALLOW_ACTION
-                             : Ci.nsIPermissionManager.DENY_ACTION;
-        }
-
-        if (permission.remove == true)
-          perm = Ci.nsIPermissionManager.UNKNOWN_ACTION;
-
-        if (originalValue == perm) {
-          continue;
-        }
-
-        var todo = {'op': 'add', 'type': permission.type, 'permission': perm, 'value': perm, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement};
-        if (permission.remove == true)
-          todo.op = 'remove';
-
-        pendingPermissions.push(todo);
-
-        /* Push original permissions value or clear into cleanup array */
-        var cleanupTodo = {'op': 'add', 'type': permission.type, 'permission': perm, 'value': perm, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement};
-        if (originalValue == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
-          cleanupTodo.op = 'remove';
-        } else {
-          cleanupTodo.value = originalValue;
-          cleanupTodo.permission = originalValue;
-        }
-        cleanupPermissions.push(cleanupTodo);
-    }
-
-    if (pendingPermissions.length > 0) {
-      // The callback needs to be delayed twice. One delay is because the pref
-      // service doesn't guarantee the order it calls its observers in, so it
-      // may notify the observer holding the callback before the other
-      // observers have been notified and given a chance to make the changes
-      // that the callback checks for. The second delay is because pref
-      // observers often defer making their changes by posting an event to the
-      // event loop.
-      this._permissionsUndoStack.push(cleanupPermissions);
-      this._pendingPermissions.push([pendingPermissions,
-				     this._delayCallbackTwice(callback)]);
-      this._applyPermissions();
-    } else {
-      content.window.setTimeout(callback, 0);
-    }
-  },
-
-  popPermissions: function(callback) {
-    if (this._permissionsUndoStack.length > 0) {
-      // See pushPermissions comment regarding delay.
-      let cb = callback ? this._delayCallbackTwice(callback) : null;
-      /* Each pop from the stack will yield an object {op/type/permission/value/url/appid/isInBrowserElement} or null */
-      this._pendingPermissions.push([this._permissionsUndoStack.pop(), cb]);
-      this._applyPermissions();
-    } else {
-      content.window.setTimeout(callback, 0);
-    }
-  },
-
-  flushPermissions: function(callback) {
-    while (this._permissionsUndoStack.length > 1)
-      this.popPermissions(null);
-
-    this.popPermissions(callback);
-  },
-
-
-  _permissionObserver: {
-    _lastPermission: {},
-    _callBack: null,
-    _nextCallback: null,
-
-    observe: function (aSubject, aTopic, aData)
-    {
-      if (aTopic == "perm-changed") {
-        var permission = aSubject.QueryInterface(Ci.nsIPermission);
-        if (permission.type == this._lastPermission.type) {
-          var os = Components.classes["@mozilla.org/observer-service;1"]
-                             .getService(Components.interfaces.nsIObserverService);
-          os.removeObserver(this, "perm-changed");
-          content.window.setTimeout(this._callback, 0);
-          content.window.setTimeout(this._nextCallback, 0);
-        }
-      }
-    }
-  },
-
-  /*
-    Iterate through one atomic set of permissions actions and perform allow/deny as appropriate.
-    All actions performed must modify the relevant permission.
-  */
-  _applyPermissions: function() {
-    if (this._applyingPermissions || this._pendingPermissions.length <= 0) {
-      return;
-    }
-
-    /* Set lock and get prefs from the _pendingPrefs queue */
-    this._applyingPermissions = true;
-    var transaction = this._pendingPermissions.shift();
-    var pendingActions = transaction[0];
-    var callback = transaction[1];
-    var lastPermission = pendingActions[pendingActions.length-1];
-
-    var self = this;
-    var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-    this._permissionObserver._lastPermission = lastPermission;
-    this._permissionObserver._callback = callback;
-    this._permissionObserver._nextCallback = function () {
-        self._applyingPermissions = false;
-        // Now apply any permissions that may have been queued while we were applying
-        self._applyPermissions();
-    }
-
-    os.addObserver(this._permissionObserver, "perm-changed", false);
-
-    for (var idx in pendingActions) {
-      var perm = pendingActions[idx];
-      this._sendSyncMessage('SPPermissionManager', perm)[0];
-    }
-  },
-
-  /*
-   * Take in a list of pref changes to make, and invoke |callback| once those
-   * changes have taken effect.  When the test finishes, these changes are
-   * reverted.
-   *
-   * |inPrefs| must be an object with up to two properties: "set" and "clear".
-   * pushPrefEnv will set prefs as indicated in |inPrefs.set| and will unset
-   * the prefs indicated in |inPrefs.clear|.
-   *
-   * For example, you might pass |inPrefs| as:
-   *
-   *  inPrefs = {'set': [['foo.bar', 2], ['magic.pref', 'baz']],
-   *             'clear': [['clear.this'], ['also.this']] };
-   *
-   * Notice that |set| and |clear| are both an array of arrays.  In |set|, each
-   * of the inner arrays must have the form [pref_name, value] or [pref_name,
-   * value, iid].  (The latter form is used for prefs with "complex" values.)
-   *
-   * In |clear|, each inner array should have the form [pref_name].
-   *
-   * If you set the same pref more than once (or both set and clear a pref),
-   * the behavior of this method is undefined.
-   *
-   * (Implementation note: _prefEnvUndoStack is a stack of values to revert to,
-   * not values which have been set!)
-   *
-   * TODO: complex values for original cleanup?
-   *
-   */
-  pushPrefEnv: function(inPrefs, callback) {
-    var prefs = Components.classes["@mozilla.org/preferences-service;1"].
-                           getService(Components.interfaces.nsIPrefBranch);
-
-    var pref_string = [];
-    pref_string[prefs.PREF_INT] = "INT";
-    pref_string[prefs.PREF_BOOL] = "BOOL";
-    pref_string[prefs.PREF_STRING] = "CHAR";
-
-    var pendingActions = [];
-    var cleanupActions = [];
-
-    for (var action in inPrefs) { /* set|clear */
-      for (var idx in inPrefs[action]) {
-        var aPref = inPrefs[action][idx];
-        var prefName = aPref[0];
-        var prefValue = null;
-        var prefIid = null;
-        var prefType = prefs.PREF_INVALID;
-        var originalValue = null;
-
-        if (aPref.length == 3) {
-          prefValue = aPref[1];
-          prefIid = aPref[2];
-        } else if (aPref.length == 2) {
-          prefValue = aPref[1];
-        }
-
-        /* If pref is not found or invalid it doesn't exist. */
-        if (prefs.getPrefType(prefName) != prefs.PREF_INVALID) {
-          prefType = pref_string[prefs.getPrefType(prefName)];
-          if ((prefs.prefHasUserValue(prefName) && action == 'clear') ||
-              (action == 'set'))
-            originalValue = this._getPref(prefName, prefType);
-        } else if (action == 'set') {
-          /* prefName doesn't exist, so 'clear' is pointless */
-          if (aPref.length == 3) {
-            prefType = "COMPLEX";
-          } else if (aPref.length == 2) {
-            if (typeof(prefValue) == "boolean")
-              prefType = "BOOL";
-            else if (typeof(prefValue) == "number")
-              prefType = "INT";
-            else if (typeof(prefValue) == "string")
-              prefType = "CHAR";
-          }
-        }
-
-        /* PREF_INVALID: A non existing pref which we are clearing or invalid values for a set */
-        if (prefType == prefs.PREF_INVALID)
-          continue;
-
-        /* We are not going to set a pref if the value is the same */
-        if (originalValue == prefValue)
-          continue;
-
-        pendingActions.push({'action': action, 'type': prefType, 'name': prefName, 'value': prefValue, 'Iid': prefIid});
-
-        /* Push original preference value or clear into cleanup array */
-        var cleanupTodo = {'action': action, 'type': prefType, 'name': prefName, 'value': originalValue, 'Iid': prefIid};
-        if (originalValue == null) {
-          cleanupTodo.action = 'clear';
-        } else {
-          cleanupTodo.action = 'set';
-        }
-        cleanupActions.push(cleanupTodo);
-      }
-    }
-
-    if (pendingActions.length > 0) {
-      // The callback needs to be delayed twice. One delay is because the pref
-      // service doesn't guarantee the order it calls its observers in, so it
-      // may notify the observer holding the callback before the other
-      // observers have been notified and given a chance to make the changes
-      // that the callback checks for. The second delay is because pref
-      // observers often defer making their changes by posting an event to the
-      // event loop.
-      this._prefEnvUndoStack.push(cleanupActions);
-      this._pendingPrefs.push([pendingActions,
-			       this._delayCallbackTwice(callback)]);
-      this._applyPrefs();
-    } else {
-      content.window.setTimeout(callback, 0);
-    }
-  },
-
-  popPrefEnv: function(callback) {
-    if (this._prefEnvUndoStack.length > 0) {
-      // See pushPrefEnv comment regarding delay.
-      let cb = callback ? this._delayCallbackTwice(callback) : null;
-      /* Each pop will have a valid block of preferences */
-      this._pendingPrefs.push([this._prefEnvUndoStack.pop(), cb]);
-      this._applyPrefs();
-    } else {
-      content.window.setTimeout(callback, 0);
-    }
-  },
-
-  flushPrefEnv: function(callback) {
-    while (this._prefEnvUndoStack.length > 1)
-      this.popPrefEnv(null);
-
-    this.popPrefEnv(callback);
-  },
-
-  /*
-    Iterate through one atomic set of pref actions and perform sets/clears as appropriate.
-    All actions performed must modify the relevant pref.
-  */
-  _applyPrefs: function() {
-    if (this._applyingPrefs || this._pendingPrefs.length <= 0) {
-      return;
-    }
-
-    /* Set lock and get prefs from the _pendingPrefs queue */
-    this._applyingPrefs = true;
-    var transaction = this._pendingPrefs.shift();
-    var pendingActions = transaction[0];
-    var callback = transaction[1];
-
-    var lastPref = pendingActions[pendingActions.length-1];
-
-    var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
-    var self = this;
-    pb.addObserver(lastPref.name, function prefObs(subject, topic, data) {
-      pb.removeObserver(lastPref.name, prefObs);
-
-      content.window.setTimeout(callback, 0);
-      content.window.setTimeout(function () {
-        self._applyingPrefs = false;
-        // Now apply any prefs that may have been queued while we were applying
-        self._applyPrefs();
-      }, 0);
-    }, false);
-
-    for (var idx in pendingActions) {
-      var pref = pendingActions[idx];
-      if (pref.action == 'set') {
-        this._setPref(pref.name, pref.type, pref.value, pref.Iid);
-      } else if (pref.action == 'clear') {
-        this.clearUserPref(pref.name);
-      }
-    }
-  },
-
-  // Disables the app install prompt for the duration of this test. There is
-  // no need to re-enable the prompt at the end of the test.
-  //
-  // The provided callback is invoked once the prompt is disabled.
-  autoConfirmAppInstall: function(cb) {
-    this.pushPrefEnv({set: [['dom.mozApps.auto_confirm_install', true]]}, cb);
-  },
-
-  // Allow tests to disable the per platform app validity checks so we can
-  // test higher level WebApp functionality without full platform support.
-  setAllAppsLaunchable: function(launchable) {
-    var message = {
-      op: "set-launchable",
-      launchable: launchable
-    };
-    return this._sendSyncMessage("SPWebAppService", message);
-  },
-
-  _proxiedObservers: {
-    "specialpowers-http-notify-request": function(aMessage) {
-      let uri = aMessage.json.uri;
-      Services.obs.notifyObservers(null, "specialpowers-http-notify-request", uri);
-    },
-  },
-
-  _addObserverProxy: function(notification) {
-    if (notification in this._proxiedObservers) {
-      this._addMessageListener(notification, this._proxiedObservers[notification]);
-    }
-  },
-
-  _removeObserverProxy: function(notification) {
-    if (notification in this._proxiedObservers) {
-      this._removeMessageListener(notification, this._proxiedObservers[notification]);
-    }
-  },
-
-  addObserver: function(obs, notification, weak) {
-    this._addObserverProxy(notification);
-    if (typeof obs == 'object' && obs.observe.name != 'SpecialPowersCallbackWrapper')
-      obs.observe = wrapCallback(obs.observe);
-    var obsvc = Cc['@mozilla.org/observer-service;1']
-                   .getService(Ci.nsIObserverService);
-    obsvc.addObserver(obs, notification, weak);
-  },
-  removeObserver: function(obs, notification) {
-    this._removeObserverProxy(notification);
-    var obsvc = Cc['@mozilla.org/observer-service;1']
-                   .getService(Ci.nsIObserverService);
-    obsvc.removeObserver(obs, notification);
-  },
-  notifyObservers: function(subject, topic, data) {
-    var obsvc = Cc['@mozilla.org/observer-service;1']
-                   .getService(Ci.nsIObserverService);
-    obsvc.notifyObservers(subject, topic, data);
-  },
-
-  can_QI: function(obj) {
-    return obj.QueryInterface !== undefined;
-  },
-  do_QueryInterface: function(obj, iface) {
-    return obj.QueryInterface(Ci[iface]);
-  },
-
-  call_Instanceof: function (obj1, obj2) {
-     obj1=unwrapIfWrapped(obj1);
-     obj2=unwrapIfWrapped(obj2);
-     return obj1 instanceof obj2;
-  },
-
-  // Returns a privileged getter from an object. GetOwnPropertyDescriptor does
-  // not work here because xray wrappers don't properly implement it.
-  //
-  // This terribleness is used by content/base/test/test_object.html because
-  // <object> and <embed> tags will spawn plugins if their prototype is touched,
-  // so we need to get and cache the getter of |hasRunningPlugin| if we want to
-  // call it without paradoxically spawning the plugin.
-  do_lookupGetter: function(obj, name) {
-    return Object.prototype.__lookupGetter__.call(obj, name);
-  },
-
-  // Mimic the get*Pref API
-  getBoolPref: function(aPrefName) {
-    return (this._getPref(aPrefName, 'BOOL'));
-  },
-  getIntPref: function(aPrefName) {
-    return (this._getPref(aPrefName, 'INT'));
-  },
-  getCharPref: function(aPrefName) {
-    return (this._getPref(aPrefName, 'CHAR'));
-  },
-  getComplexValue: function(aPrefName, aIid) {
-    return (this._getPref(aPrefName, 'COMPLEX', aIid));
-  },
-
-  // Mimic the set*Pref API
-  setBoolPref: function(aPrefName, aValue) {
-    return (this._setPref(aPrefName, 'BOOL', aValue));
-  },
-  setIntPref: function(aPrefName, aValue) {
-    return (this._setPref(aPrefName, 'INT', aValue));
-  },
-  setCharPref: function(aPrefName, aValue) {
-    return (this._setPref(aPrefName, 'CHAR', aValue));
-  },
-  setComplexValue: function(aPrefName, aIid, aValue) {
-    return (this._setPref(aPrefName, 'COMPLEX', aValue, aIid));
-  },
-
-  // Mimic the clearUserPref API
-  clearUserPref: function(aPrefName) {
-    var msg = {'op':'clear', 'prefName': aPrefName, 'prefType': ""};
-    this._sendSyncMessage('SPPrefService', msg);
-  },
-
-  // Private pref functions to communicate to chrome
-  _getPref: function(aPrefName, aPrefType, aIid) {
-    var msg = {};
-    if (aIid) {
-      // Overloading prefValue to handle complex prefs
-      msg = {'op':'get', 'prefName': aPrefName, 'prefType':aPrefType, 'prefValue':[aIid]};
-    } else {
-      msg = {'op':'get', 'prefName': aPrefName,'prefType': aPrefType};
-    }
-    var val = this._sendSyncMessage('SPPrefService', msg);
-
-    if (val == null || val[0] == null)
-      throw "Error getting pref";
-    return val[0];
-  },
-  _setPref: function(aPrefName, aPrefType, aValue, aIid) {
-    var msg = {};
-    if (aIid) {
-      msg = {'op':'set','prefName':aPrefName, 'prefType': aPrefType, 'prefValue': [aIid,aValue]};
-    } else {
-      msg = {'op':'set', 'prefName': aPrefName, 'prefType': aPrefType, 'prefValue': aValue};
-    }
-    return(this._sendSyncMessage('SPPrefService', msg)[0]);
-  },
-
-  _getDocShell: function(window) {
-    return window.QueryInterface(Ci.nsIInterfaceRequestor)
-                 .getInterface(Ci.nsIWebNavigation)
-                 .QueryInterface(Ci.nsIDocShell);
-  },
-  _getMUDV: function(window) {
-    return this._getDocShell(window).contentViewer
-               .QueryInterface(Ci.nsIMarkupDocumentViewer);
-  },
-  //XXX: these APIs really ought to be removed, they're not e10s-safe.
-  // (also they're pretty Firefox-specific)
-  _getTopChromeWindow: function(window) {
-    return window.QueryInterface(Ci.nsIInterfaceRequestor)
-                 .getInterface(Ci.nsIWebNavigation)
-                 .QueryInterface(Ci.nsIDocShellTreeItem)
-                 .rootTreeItem
-                 .QueryInterface(Ci.nsIInterfaceRequestor)
-                 .getInterface(Ci.nsIDOMWindow)
-                 .QueryInterface(Ci.nsIDOMChromeWindow);
-  },
-  _getAutoCompletePopup: function(window) {
-    return this._getTopChromeWindow(window).document
-                                           .getElementById("PopupAutoComplete");
-  },
-  addAutoCompletePopupEventListener: function(window, eventname, listener) {
-    this._getAutoCompletePopup(window).addEventListener(eventname,
-                                                        listener,
-                                                        false);
-  },
-  removeAutoCompletePopupEventListener: function(window, eventname, listener) {
-    this._getAutoCompletePopup(window).removeEventListener(eventname,
-                                                           listener,
-                                                           false);
-  },
-  get formHistory() {
-    let tmp = {};
-    Cu.import("resource://gre/modules/FormHistory.jsm", tmp);
-    return wrapPrivileged(tmp.FormHistory);
-  },
-  getFormFillController: function(window) {
-    return Components.classes["@mozilla.org/satchel/form-fill-controller;1"]
-                     .getService(Components.interfaces.nsIFormFillController);
-  },
-  attachFormFillControllerTo: function(window) {
-    this.getFormFillController()
-        .attachToBrowser(this._getDocShell(window),
-                         this._getAutoCompletePopup(window));
-  },
-  detachFormFillControllerFrom: function(window) {
-    this.getFormFillController().detachFromBrowser(this._getDocShell(window));
-  },
-  isBackButtonEnabled: function(window) {
-    return !this._getTopChromeWindow(window).document
-                                      .getElementById("Browser:Back")
-                                      .hasAttribute("disabled");
-  },
-  //XXX end of problematic APIs
-
-  addChromeEventListener: function(type, listener, capture, allowUntrusted) {
-    addEventListener(type, listener, capture, allowUntrusted);
-  },
-  removeChromeEventListener: function(type, listener, capture) {
-    removeEventListener(type, listener, capture);
-  },
-
-  // Note: each call to registerConsoleListener MUST be paired with a
-  // call to postConsoleSentinel; when the callback receives the
-  // sentinel it will unregister itself (_after_ calling the
-  // callback).  SimpleTest.expectConsoleMessages does this for you.
-  // If you register more than one console listener, a call to
-  // postConsoleSentinel will zap all of them.
-  registerConsoleListener: function(callback) {
-    let listener = new SPConsoleListener(callback);
-    Services.console.registerListener(listener);
-  },
-  postConsoleSentinel: function() {
-    Services.console.logStringMessage("SENTINEL");
-  },
-  resetConsole: function() {
-    Services.console.reset();
-  },
-
-  getMaxLineBoxWidth: function(window) {
-    return this._getMUDV(window).maxLineBoxWidth;
-  },
-
-  setMaxLineBoxWidth: function(window, width) {
-    this._getMUDV(window).changeMaxLineBoxWidth(width);
-  },
-
-  getFullZoom: function(window) {
-    return this._getMUDV(window).fullZoom;
-  },
-  setFullZoom: function(window, zoom) {
-    this._getMUDV(window).fullZoom = zoom;
-  },
-  getTextZoom: function(window) {
-    return this._getMUDV(window).textZoom;
-  },
-  setTextZoom: function(window, zoom) {
-    this._getMUDV(window).textZoom = zoom;
-  },
-
-  emulateMedium: function(window, mediaType) {
-    this._getMUDV(window).emulateMedium(mediaType);
-  },
-  stopEmulatingMedium: function(window) {
-    this._getMUDV(window).stopEmulatingMedium();
-  },
-
-  snapshotWindowWithOptions: function (win, rect, bgcolor, options) {
-    var el = this.window.get().document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
-    if (rect === undefined) {
-      rect = { top: win.scrollY, left: win.scrollX,
-               width: win.innerWidth, height: win.innerHeight };
-    }
-    if (bgcolor === undefined) {
-      bgcolor = "rgb(255,255,255)";
-    }
-    if (options === undefined) {
-      options = { };
-    }
-
-    el.width = rect.width;
-    el.height = rect.height;
-    var ctx = el.getContext("2d");
-    var flags = 0;
-
-    for (var option in options) {
-      flags |= options[option] && ctx[option];
-    }
-
-    ctx.drawWindow(win,
-                   rect.left, rect.top, rect.width, rect.height,
-                   bgcolor,
-                   flags);
-    return el;
-  },
-
-  snapshotWindow: function (win, withCaret, rect, bgcolor) {
-    return this.snapshotWindowWithOptions(win, rect, bgcolor,
-                                          { DRAWWINDOW_DRAW_CARET: withCaret });
-  },
-
-  snapshotRect: function (win, rect, bgcolor) {
-    return this.snapshotWindowWithOptions(win, rect, bgcolor);
-  },
-
-  gc: function() {
-    this.DOMWindowUtils.garbageCollect();
-  },
-
-  forceGC: function() {
-    Cu.forceGC();
-  },
-
-  forceCC: function() {
-    Cu.forceCC();
-  },
-
-  // Due to various dependencies between JS objects and C++ objects, an ordinary
-  // forceGC doesn't necessarily clear all unused objects, thus the GC and CC
-  // needs to run several times and when no other JS is running.
-  // The current number of iterations has been determined according to massive
-  // cross platform testing.
-  exactGC: function(win, callback) {
-    var self = this;
-    let count = 0;
-
-    function doPreciseGCandCC() {
-      function scheduledGCCallback() {
-        self.getDOMWindowUtils(win).cycleCollect();
-
-        if (++count < 2) {
-          doPreciseGCandCC();
-        } else {
-          callback();
-        }
-      }
-
-      Cu.schedulePreciseGC(scheduledGCCallback);
-    }
-
-    doPreciseGCandCC();
-  },
-
-  setGCZeal: function(zeal) {
-    Cu.setGCZeal(zeal);
-  },
-
-  isMainProcess: function() {
-    try {
-      return Cc["@mozilla.org/xre/app-info;1"].
-               getService(Ci.nsIXULRuntime).
-               processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-    } catch (e) { }
-    return true;
-  },
-
-  _xpcomabi: null,
-
-  get XPCOMABI() {
-    if (this._xpcomabi != null)
-      return this._xpcomabi;
-
-    var xulRuntime = Cc["@mozilla.org/xre/app-info;1"]
-                        .getService(Components.interfaces.nsIXULAppInfo)
-                        .QueryInterface(Components.interfaces.nsIXULRuntime);
-
-    this._xpcomabi = xulRuntime.XPCOMABI;
-    return this._xpcomabi;
-  },
-
-  // The optional aWin parameter allows the caller to specify a given window in
-  // whose scope the runnable should be dispatched. If aFun throws, the
-  // exception will be reported to aWin.
-  executeSoon: function(aFun, aWin) {
-    // Create the runnable in the scope of aWin to avoid running into COWs.
-    var runnable = {};
-    if (aWin)
-        runnable = Cu.createObjectIn(aWin);
-    runnable.run = aFun;
-    Cu.dispatch(runnable, aWin);
-  },
-
-  _os: null,
-
-  get OS() {
-    if (this._os != null)
-      return this._os;
-
-    var xulRuntime = Cc["@mozilla.org/xre/app-info;1"]
-                        .getService(Components.interfaces.nsIXULAppInfo)
-                        .QueryInterface(Components.interfaces.nsIXULRuntime);
-
-    this._os = xulRuntime.OS;
-    return this._os;
-  },
-
-  addSystemEventListener: function(target, type, listener, useCapture) {
-    Cc["@mozilla.org/eventlistenerservice;1"].
-      getService(Ci.nsIEventListenerService).
-      addSystemEventListener(target, type, listener, useCapture);
-  },
-  removeSystemEventListener: function(target, type, listener, useCapture) {
-    Cc["@mozilla.org/eventlistenerservice;1"].
-      getService(Ci.nsIEventListenerService).
-      removeSystemEventListener(target, type, listener, useCapture);
-  },
-
-  getDOMRequestService: function() {
-    var serv = Cc["@mozilla.org/dom/dom-request-service;1"].
-      getService(Ci.nsIDOMRequestService);
-    var res = { __exposedProps__: {} };
-    var props = ["createRequest", "createCursor", "fireError", "fireSuccess",
-                 "fireDone", "fireDetailedError"];
-    for (i in props) {
-      let prop = props[i];
-      res[prop] = function() { return serv[prop].apply(serv, arguments) };
-      res.__exposedProps__[prop] = "r";
-    }
-    return res;
-  },
-
-  setLogFile: function(path) {
-    this._mfl = new MozillaFileLogger(path);
-  },
-
-  log: function(data) {
-    this._mfl.log(data);
-  },
-
-  closeLogFile: function() {
-    this._mfl.close();
-  },
-
-  addCategoryEntry: function(category, entry, value, persists, replace) {
-    Components.classes["@mozilla.org/categorymanager;1"].
-      getService(Components.interfaces.nsICategoryManager).
-      addCategoryEntry(category, entry, value, persists, replace);
-  },
-
-  deleteCategoryEntry: function(category, entry, persists) {
-    Components.classes["@mozilla.org/categorymanager;1"].
-      getService(Components.interfaces.nsICategoryManager).
-      deleteCategoryEntry(category, entry, persists);
-  },
-
-  copyString: function(str, doc) {
-    Components.classes["@mozilla.org/widget/clipboardhelper;1"].
-      getService(Components.interfaces.nsIClipboardHelper).
-      copyString(str, doc);
-  },
-
-  openDialog: function(win, args) {
-    return win.openDialog.apply(win, args);
-  },
-
-  // :jdm gets credit for this.  ex: getPrivilegedProps(window, 'location.href');
-  getPrivilegedProps: function(obj, props) {
-    var parts = props.split('.');
-
-    for (var i = 0; i < parts.length; i++) {
-      var p = parts[i];
-      if (obj[p]) {
-        obj = obj[p];
-      } else {
-        return null;
-      }
-    }
-    return obj;
-  },
-
-  get focusManager() {
-    if (this._fm != null)
-      return this._fm;
-
-    this._fm = Components.classes["@mozilla.org/focus-manager;1"].
-                        getService(Components.interfaces.nsIFocusManager);
-
-    return this._fm;
-  },
-
-  getFocusedElementForWindow: function(targetWindow, aDeep, childTargetWindow) {
-    return this.focusManager.getFocusedElementForWindow(targetWindow, aDeep, childTargetWindow);
-  },
-
-  activeWindow: function() {
-    return this.focusManager.activeWindow;
-  },
-
-  focusedWindow: function() {
-    return this.focusManager.focusedWindow;
-  },
-
-  focus: function(aWindow) {
-    // This is called inside TestRunner._makeIframe without aWindow, because of assertions in oop mochitests
-    // With aWindow, it is called in SimpleTest.waitForFocus to allow popup window opener focus switching
-    if (aWindow)
-      aWindow.focus();
-    sendAsyncMessage("SpecialPowers.Focus", {});
-  },
-
-  getClipboardData: function(flavor, whichClipboard) {
-    if (this._cb == null)
-      this._cb = Components.classes["@mozilla.org/widget/clipboard;1"].
-                            getService(Components.interfaces.nsIClipboard);
-    if (whichClipboard === undefined)
-      whichClipboard = this._cb.kGlobalClipboard;
-
-    var xferable = Components.classes["@mozilla.org/widget/transferable;1"].
-                   createInstance(Components.interfaces.nsITransferable);
-    xferable.init(this._getDocShell(content.window)
-                      .QueryInterface(Components.interfaces.nsILoadContext));
-    xferable.addDataFlavor(flavor);
-    this._cb.getData(xferable, whichClipboard);
-    var data = {};
-    try {
-      xferable.getTransferData(flavor, data, {});
-    } catch (e) {}
-    data = data.value || null;
-    if (data == null)
-      return "";
-
-    return data.QueryInterface(Components.interfaces.nsISupportsString).data;
-  },
-
-  clipboardCopyString: function(preExpectedVal, doc) {
-    var cbHelperSvc = Components.classes["@mozilla.org/widget/clipboardhelper;1"].
-                      getService(Components.interfaces.nsIClipboardHelper);
-    cbHelperSvc.copyString(preExpectedVal, doc);
-  },
-
-  supportsSelectionClipboard: function() {
-    if (this._cb == null) {
-      this._cb = Components.classes["@mozilla.org/widget/clipboard;1"].
-                            getService(Components.interfaces.nsIClipboard);
-    }
-    return this._cb.supportsSelectionClipboard();
-  },
-
-  swapFactoryRegistration: function(cid, contractID, newFactory, oldFactory) {
-    var componentRegistrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-
-    var unregisterFactory = newFactory;
-    var registerFactory = oldFactory;
-
-    if (cid == null) {
-      if (contractID != null) {
-        cid = componentRegistrar.contractIDToCID(contractID);
-        oldFactory = Components.manager.getClassObject(Components.classes[contractID],
-                                                            Components.interfaces.nsIFactory);
-      } else {
-        return {'error': "trying to register a new contract ID: Missing contractID"};
-      }
-
-      unregisterFactory = oldFactory;
-      registerFactory = newFactory;
-    }
-    componentRegistrar.unregisterFactory(cid,
-                                         unregisterFactory);
-
-    // Restore the original factory.
-    componentRegistrar.registerFactory(cid,
-                                       "",
-                                       contractID,
-                                       registerFactory);
-    return {'cid':cid, 'originalFactory':oldFactory};
-  },
-
-  _getElement: function(aWindow, id) {
-    return ((typeof(id) == "string") ?
-        aWindow.document.getElementById(id) : id);
-  },
-
-  dispatchEvent: function(aWindow, target, event) {
-    var el = this._getElement(aWindow, target);
-    return el.dispatchEvent(event);
-  },
-
-  get isDebugBuild() {
-    delete this.isDebugBuild;
-    var debug = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2);
-    return this.isDebugBuild = debug.isDebugBuild;
-  },
-  assertionCount: function() {
-    var debugsvc = Cc['@mozilla.org/xpcom/debug;1'].getService(Ci.nsIDebug2);
-    return debugsvc.assertionCount;
-  },
-
-  /**
-   * Get the message manager associated with an <iframe mozbrowser>.
-   */
-  getBrowserFrameMessageManager: function(aFrameElement) {
-    return this.wrap(aFrameElement.QueryInterface(Ci.nsIFrameLoaderOwner)
-                                  .frameLoader
-                                  .messageManager);
-  },
-
-  setFullscreenAllowed: function(document) {
-    var pm = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
-    pm.addFromPrincipal(document.nodePrincipal, "fullscreen", Ci.nsIPermissionManager.ALLOW_ACTION);
-    var obsvc = Cc['@mozilla.org/observer-service;1']
-                   .getService(Ci.nsIObserverService);
-    obsvc.notifyObservers(document, "fullscreen-approved", null);
-  },
-
-  removeFullscreenAllowed: function(document) {
-    var pm = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
-    pm.removeFromPrincipal(document.nodePrincipal, "fullscreen");
-  },
-
-  _getInfoFromPermissionArg: function(arg) {
-    let url = "";
-    let appId = Ci.nsIScriptSecurityManager.NO_APP_ID;
-    let isInBrowserElement = false;
-
-    if (typeof(arg) == "string") {
-      // It's an URL.
-      url = Cc["@mozilla.org/network/io-service;1"]
-              .getService(Ci.nsIIOService)
-              .newURI(arg, null, null)
-              .spec;
-    } else if (arg.manifestURL) {
-      // It's a thing representing an app.
-      let appsSvc = Cc["@mozilla.org/AppsService;1"]
-                      .getService(Ci.nsIAppsService)
-      let app = appsSvc.getAppByManifestURL(arg.manifestURL);
-
-      if (!app) {
-        throw "No app for this manifest!";
-      }
-
-      appId = appsSvc.getAppLocalIdByManifestURL(arg.manifestURL);
-      url = app.origin;
-      isInBrowserElement = arg.isInBrowserElement || false;
-    } else if (arg.nodePrincipal) {
-      // It's a document.
-      url = arg.nodePrincipal.URI.spec;
-      appId = arg.nodePrincipal.appId;
-      isInBrowserElement = arg.nodePrincipal.isInBrowserElement;
-    } else {
-      url = arg.url;
-      appId = arg.appId;
-      isInBrowserElement = arg.isInBrowserElement;
-    }
-
-    return [ url, appId, isInBrowserElement ];
-  },
-
-  addPermission: function(type, allow, arg) {
-    let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg);
-
-    let permission;
-    if (typeof allow !== 'boolean') {
-      permission = allow;
-    } else {
-      permission = allow ? Ci.nsIPermissionManager.ALLOW_ACTION
-                         : Ci.nsIPermissionManager.DENY_ACTION;
-    }
-
-    var msg = {
-      'op': 'add',
-      'type': type,
-      'permission': permission,
-      'url': url,
-      'appId': appId,
-      'isInBrowserElement': isInBrowserElement
-    };
-
-    this._sendSyncMessage('SPPermissionManager', msg);
-  },
-
-  removePermission: function(type, arg) {
-    let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg);
-
-    var msg = {
-      'op': 'remove',
-      'type': type,
-      'url': url,
-      'appId': appId,
-      'isInBrowserElement': isInBrowserElement
-    };
-
-    this._sendSyncMessage('SPPermissionManager', msg);
-  },
-
-  hasPermission: function (type, arg) {
-   let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg);
-
-    var msg = {
-      'op': 'has',
-      'type': type,
-      'url': url,
-      'appId': appId,
-      'isInBrowserElement': isInBrowserElement
-    };
-
-    return this._sendSyncMessage('SPPermissionManager', msg)[0];
-  },
-  testPermission: function (type, value, arg) {
-   let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg);
-
-    var msg = {
-      'op': 'test',
-      'type': type,
-      'value': value,
-      'url': url,
-      'appId': appId,
-      'isInBrowserElement': isInBrowserElement
-    };
-    return this._sendSyncMessage('SPPermissionManager', msg)[0];
-  },
-
-  getMozFullPath: function(file) {
-    return file.mozFullPath;
-  },
-
-  isWindowPrivate: function(win) {
-    return PrivateBrowsingUtils.isWindowPrivate(win);
-  },
-
-  notifyObserversInParentProcess: function(subject, topic, data) {
-    if (subject) {
-      throw new Error("Can't send subject to another process!");
-    }
-    if (this.isMainProcess()) {
-      this.notifyObservers(subject, topic, data);
-      return;
-    }
-    var msg = {
-      'op': 'notify',
-      'observerTopic': topic,
-      'observerData': data
-    };
-    this._sendSyncMessage('SPObserverService', msg);
-  },
-};
-
-this.SpecialPowersAPI = SpecialPowersAPI;
-this.bindDOMWindowUtils = bindDOMWindowUtils;
-this.getRawComponents = getRawComponents;
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/Assert.jsm b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/Assert.jsm
deleted file mode 100644
index 7752f16..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/Assert.jsm
+++ /dev/null
@@ -1,442 +0,0 @@
-/* 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/. */
-
-// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
-// When you see a javadoc comment that contains a number, it's a reference to a
-// specific section of the CommonJS spec.
-//
-// Originally from narwhal.js (http://narwhaljs.org)
-// Copyright (c) 2009 Thomas Robinson <280north.com>
-// MIT license: http://opensource.org/licenses/MIT
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = [
-  "Assert"
-];
-
-/**
- * 1. The assert module provides functions that throw AssertionError's when
- * particular conditions are not met.
- *
- * To use the module you'll need to instantiate it first, which allows consumers
- * to override certain behavior on the newly obtained instance. For examples,
- * see the javadoc comments for the `report` member function.
- */
-let Assert = this.Assert = function(reporterFunc) {
-  if (reporterFunc)
-    this.setReporter(reporterFunc);
-};
-
-function instanceOf(object, type) {
-  return Object.prototype.toString.call(object) == "[object " + type + "]";
-}
-
-function replacer(key, value) {
-  if (value === undefined) {
-    return "" + value;
-  }
-  if (typeof value === "number" && (isNaN(value) || !isFinite(value))) {
-    return value.toString();
-  }
-  if (typeof value === "function" || instanceOf(value, "RegExp")) {
-    return value.toString();
-  }
-  return value;
-}
-
-const kTruncateLength = 128;
-
-function truncate(text, newLength = kTruncateLength) {
-  if (typeof text == "string") {
-    return text.length < newLength ? text : text.slice(0, newLength);
-  } else {
-    return text;
-  }
-}
-
-function getMessage(error, prefix = "") {
-  let actual, expected;
-  // Wrap calls to JSON.stringify in try...catch blocks, as they may throw. If
-  // so, fall back to toString().
-  try {
-    actual = JSON.stringify(error.actual, replacer);
-  } catch (ex) {
-    actual = Object.prototype.toString.call(error.actual);
-  }
-  try {
-    expected = JSON.stringify(error.expected, replacer);
-  } catch (ex) {
-    expected = Object.prototype.toString.call(error.expected);
-  }
-  let message = prefix;
-  if (error.operator) {
-    message += (prefix ? " - " : "") + truncate(actual) + " " + error.operator +
-               " " + truncate(expected);
-  }
-  return message;
-}
-
-/**
- * 2. The AssertionError is defined in assert.
- *
- * Example:
- * new assert.AssertionError({
- *   message: message,
- *   actual: actual,
- *   expected: expected,
- *   operator: operator
- * });
- *
- * At present only the four keys mentioned above are used and
- * understood by the spec. Implementations or sub modules can pass
- * other keys to the AssertionError's constructor - they will be
- * ignored.
- */
-Assert.AssertionError = function(options) {
-  this.name = "AssertionError";
-  this.actual = options.actual;
-  this.expected = options.expected;
-  this.operator = options.operator;
-  this.message = getMessage(this, options.message);
-  // The part of the stack that comes from this module is not interesting.
-  let stack = Components.stack;
-  do {
-    stack = stack.caller;
-  } while(stack.filename && stack.filename.contains("Assert.jsm"))
-  this.stack = stack;
-};
-
-// assert.AssertionError instanceof Error
-Assert.AssertionError.prototype = Object.create(Error.prototype, {
-  constructor: {
-    value: Assert.AssertionError,
-    enumerable: false,
-    writable: true,
-    configurable: true
-  }
-});
-
-let proto = Assert.prototype;
-
-proto._reporter = null;
-/**
- * Set a custom assertion report handler function. Arguments passed in to this
- * function are:
- * err (AssertionError|null) An error object when the assertion failed or null
- *                           when it passed
- * message (string) Message describing the assertion
- * stack (stack) Stack trace of the assertion function
- *
- * Example:
- * ```js
- * Assert.setReporter(function customReporter(err, message, stack) {
- *   if (err) {
- *     do_report_result(false, err.message, err.stack);
- *   } else {
- *     do_report_result(true, message, stack);
- *   }
- * });
- * ```
- *
- * @param reporterFunc
- *        (function) Report handler function
- */
-proto.setReporter = function(reporterFunc) {
-  this._reporter = reporterFunc;
-};
-
-/**
- * 3. All of the following functions must throw an AssertionError when a
- * corresponding condition is not met, with a message that may be undefined if
- * not provided.  All assertion methods provide both the actual and expected
- * values to the assertion error for display purposes.
- *
- * This report method only throws errors on assertion failures, as per spec,
- * but consumers of this module (think: xpcshell-test, mochitest) may want to
- * override this default implementation.
- *
- * Example:
- * ```js
- * // The following will report an assertion failure.
- * this.report(1 != 2, 1, 2, "testing JS number math!", "==");
- * ```
- *
- * @param failed
- *        (boolean) Indicates if the assertion failed or not
- * @param actual
- *        (mixed) The result of evaluating the assertion
- * @param expected (optional)
- *        (mixed) Expected result from the test author
- * @param message (optional)
- *        (string) Short explanation of the expected result
- * @param operator (optional)
- *        (string) Operation qualifier used by the assertion method (ex: '==')
- */
-proto.report = function(failed, actual, expected, message, operator) {
-  let err = new Assert.AssertionError({
-    message: message,
-    actual: actual,
-    expected: expected,
-    operator: operator
-  });
-  if (!this._reporter) {
-    // If no custom reporter is set, throw the error.
-    if (failed) {
-      throw err;
-    }
-  } else {
-    this._reporter(failed ? err : null, message, err.stack);
-  }
-};
-
-/**
- * 4. Pure assertion tests whether a value is truthy, as determined by !!guard.
- * assert.ok(guard, message_opt);
- * This statement is equivalent to assert.equal(true, !!guard, message_opt);.
- * To test strictly for the value true, use assert.strictEqual(true, guard,
- * message_opt);.
- *
- * @param value
- *        (mixed) Test subject to be evaluated as truthy
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.ok = function(value, message) {
-  this.report(!value, value, true, message, "==");
-};
-
-/**
- * 5. The equality assertion tests shallow, coercive equality with ==.
- * assert.equal(actual, expected, message_opt);
- *
- * @param actual
- *        (mixed) Test subject to be evaluated as equivalent to `expected`
- * @param expected
- *        (mixed) Test reference to evaluate against `actual`
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.equal = function equal(actual, expected, message) {
-  this.report(actual != expected, actual, expected, message, "==");
-};
-
-/**
- * 6. The non-equality assertion tests for whether two objects are not equal
- * with != assert.notEqual(actual, expected, message_opt);
- *
- * @param actual
- *        (mixed) Test subject to be evaluated as NOT equivalent to `expected`
- * @param expected
- *        (mixed) Test reference to evaluate against `actual`
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.notEqual = function notEqual(actual, expected, message) {
-  this.report(actual == expected, actual, expected, message, "!=");
-};
-
-/**
- * 7. The equivalence assertion tests a deep equality relation.
- * assert.deepEqual(actual, expected, message_opt);
- *
- * We check using the most exact approximation of equality between two objects
- * to keep the chance of false positives to a minimum.
- * `JSON.stringify` is not designed to be used for this purpose; objects may
- * have ambiguous `toJSON()` implementations that would influence the test.
- *
- * @param actual
- *        (mixed) Test subject to be evaluated as equivalent to `expected`, including nested properties
- * @param expected
- *        (mixed) Test reference to evaluate against `actual`
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.deepEqual = function deepEqual(actual, expected, message) {
-  this.report(!_deepEqual(actual, expected), actual, expected, message, "deepEqual");
-};
-
-function _deepEqual(actual, expected) {
-  // 7.1. All identical values are equivalent, as determined by ===.
-  if (actual === expected) {
-    return true;
-  // 7.2. If the expected value is a Date object, the actual value is
-  // equivalent if it is also a Date object that refers to the same time.
-  } else if (instanceOf(actual, "Date") && instanceOf(expected, "Date")) {
-    return actual.getTime() === expected.getTime();
-  // 7.3 If the expected value is a RegExp object, the actual value is
-  // equivalent if it is also a RegExp object with the same source and
-  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
-  } else if (instanceOf(actual, "RegExp") && instanceOf(expected, "RegExp")) {
-    return actual.source === expected.source &&
-           actual.global === expected.global &&
-           actual.multiline === expected.multiline &&
-           actual.lastIndex === expected.lastIndex &&
-           actual.ignoreCase === expected.ignoreCase;
-  // 7.4. Other pairs that do not both pass typeof value == "object",
-  // equivalence is determined by ==.
-  } else if (typeof actual != "object" && typeof expected != "object") {
-    return actual == expected;
-  // 7.5 For all other Object pairs, including Array objects, equivalence is
-  // determined by having the same number of owned properties (as verified
-  // with Object.prototype.hasOwnProperty.call), the same set of keys
-  // (although not necessarily the same order), equivalent values for every
-  // corresponding key, and an identical 'prototype' property. Note: this
-  // accounts for both named and indexed properties on Arrays.
-  } else {
-    return objEquiv(actual, expected);
-  }
-}
-
-function isUndefinedOrNull(value) {
-  return value === null || value === undefined;
-}
-
-function isArguments(object) {
-  return instanceOf(object, "Arguments");
-}
-
-function objEquiv(a, b) {
-  if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) {
-    return false;
-  }
-  // An identical 'prototype' property.
-  if (a.prototype !== b.prototype) {
-    return false;
-  }
-  // Object.keys may be broken through screwy arguments passing. Converting to
-  // an array solves the problem.
-  if (isArguments(a)) {
-    if (!isArguments(b)) {
-      return false;
-    }
-    a = pSlice.call(a);
-    b = pSlice.call(b);
-    return _deepEqual(a, b);
-  }
-  let ka, kb, key, i;
-  try {
-    ka = Object.keys(a);
-    kb = Object.keys(b);
-  } catch (e) {
-    // Happens when one is a string literal and the other isn't
-    return false;
-  }
-  // Having the same number of owned properties (keys incorporates
-  // hasOwnProperty)
-  if (ka.length != kb.length)
-    return false;
-  // The same set of keys (although not necessarily the same order),
-  ka.sort();
-  kb.sort();
-  // Equivalent values for every corresponding key, and possibly expensive deep
-  // test
-  for (i = ka.length - 1; i >= 0; i--) {
-    key = ka[i];
-    if (!_deepEqual(a[key], b[key])) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/**
- * 8. The non-equivalence assertion tests for any deep inequality.
- * assert.notDeepEqual(actual, expected, message_opt);
- *
- * @param actual
- *        (mixed) Test subject to be evaluated as NOT equivalent to `expected`, including nested properties
- * @param expected
- *        (mixed) Test reference to evaluate against `actual`
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.notDeepEqual = function notDeepEqual(actual, expected, message) {
-  this.report(_deepEqual(actual, expected), actual, expected, message, "notDeepEqual");
-};
-
-/**
- * 9. The strict equality assertion tests strict equality, as determined by ===.
- * assert.strictEqual(actual, expected, message_opt);
- *
- * @param actual
- *        (mixed) Test subject to be evaluated as strictly equivalent to `expected`
- * @param expected
- *        (mixed) Test reference to evaluate against `actual`
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.strictEqual = function strictEqual(actual, expected, message) {
-  this.report(actual !== expected, actual, expected, message, "===");
-};
-
-/**
- * 10. The strict non-equality assertion tests for strict inequality, as
- * determined by !==.  assert.notStrictEqual(actual, expected, message_opt);
- *
- * @param actual
- *        (mixed) Test subject to be evaluated as NOT strictly equivalent to `expected`
- * @param expected
- *        (mixed) Test reference to evaluate against `actual`
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.notStrictEqual = function notStrictEqual(actual, expected, message) {
-  this.report(actual === expected, actual, expected, message, "!==");
-};
-
-function expectedException(actual, expected) {
-  if (!actual || !expected) {
-    return false;
-  }
-
-  if (instanceOf(expected, "RegExp")) {
-    return expected.test(actual);
-  } else if (actual instanceof expected) {
-    return true;
-  } else if (expected.call({}, actual) === true) {
-    return true;
-  }
-
-  return false;
-}
-
-/**
- * 11. Expected to throw an error:
- * assert.throws(block, Error_opt, message_opt);
- *
- * @param block
- *        (function) Function block to evaluate and catch eventual thrown errors
- * @param expected (optional)
- *        (mixed) Test reference to evaluate against the thrown result from `block`
- * @param message (optional)
- *        (string) Short explanation of the expected result
- */
-proto.throws = function(block, expected, message) {
-  let actual;
-
-  if (typeof expected === "string") {
-    message = expected;
-    expected = null;
-  }
-
-  try {
-    block();
-  } catch (e) {
-    actual = e;
-  }
-
-  message = (expected && expected.name ? " (" + expected.name + ")." : ".") +
-            (message ? " " + message : ".");
-
-  if (!actual) {
-    this.report(true, actual, expected, "Missing expected exception" + message);
-  }
-
-  if ((actual && expected && !expectedException(actual, expected))) {
-    throw actual;
-  }
-
-  this.report(false, expected, expected, message);
-};
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockColorPicker.jsm b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockColorPicker.jsm
deleted file mode 100644
index ab9f00b..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockColorPicker.jsm
+++ /dev/null
@@ -1,125 +0,0 @@
-/* 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/. */
-
-this.EXPORTED_SYMBOLS = ["MockColorPicker"];
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cm = Components.manager;
-const Cu = Components.utils;
-
-const CONTRACT_ID = "@mozilla.org/colorpicker;1";
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-var oldClassID = "", oldFactory = null;
-var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
-var newFactory = function (window) {
-  return {
-    createInstance: function(aOuter, aIID) {
-      if (aOuter)
-        throw Components.results.NS_ERROR_NO_AGGREGATION;
-      return new MockColorPickerInstance(window).QueryInterface(aIID);
-    },
-    lockFactory: function(aLock) {
-      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
-  };
-}
-
-this.MockColorPicker = {
-  init: function(window) {
-    this.reset();
-    this.factory = newFactory(window);
-    if (!registrar.isCIDRegistered(newClassID)) {
-      try {
-        oldClassID = registrar.contractIDToCID(CONTRACT_ID);
-        oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
-      } catch(ex) {
-        oldClassID = "";
-        oldFactory = null;
-        dump("TEST-INFO | can't get colorpicker registered component, " +
-             "assuming there is none");
-      }
-      if (oldClassID != "" && oldFactory != null) {
-        registrar.unregisterFactory(oldClassID, oldFactory);
-      }
-      registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
-    }
-  },
-
-  reset: function() {
-    this.returnColor = "";
-    this.showCallback = null;
-    this.shown = false;
-    this.showing = false;
-  },
-
-  cleanup: function() {
-    var previousFactory = this.factory;
-    this.reset();
-    this.factory = null;
-
-    registrar.unregisterFactory(newClassID, previousFactory);
-    if (oldClassID != "" && oldFactory != null) {
-      registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
-    }
-  }
-};
-
-function MockColorPickerInstance(window) {
-  this.window = window;
-};
-MockColorPickerInstance.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIColorPicker]),
-  init: function(aParent, aTitle, aInitialColor) {
-    this.parent = aParent;
-    this.initialColor = aInitialColor;
-  },
-  initialColor: "",
-  parent: null,
-  open: function(aColorPickerShownCallback) {
-    MockColorPicker.showing = true;
-    MockColorPicker.shown = true;
-
-    this.window.setTimeout(function() {
-      let result = "";
-      try {
-        if (typeof MockColorPicker.showCallback == "function") {
-          var updateCb = function(color) {
-            result = color;
-            aColorPickerShownCallback.update(color);
-          };
-          let returnColor = MockColorPicker.showCallback(this, updateCb);
-          if (typeof returnColor === "string") {
-            result = returnColor;
-          }
-        } else if (typeof MockColorPicker.returnColor === "string") {
-          result = MockColorPicker.returnColor;
-        }
-      } catch(ex) {
-        dump("TEST-UNEXPECTED-FAIL | Exception in MockColorPicker.jsm open() " +
-             "method: " + ex + "\n");
-      }
-      if (aColorPickerShownCallback) {
-        aColorPickerShownCallback.done(result);
-      }
-    }.bind(this), 0);
-  }
-};
-
-// Expose everything to content. We call reset() here so that all of the
-// relevant lazy expandos get added.
-MockColorPicker.reset();
-function exposeAll(obj) {
-  var props = {};
-  for (var prop in obj)
-    props[prop] = 'rw';
-  obj.__exposedProps__ = props;
-}
-exposeAll(MockColorPicker);
-exposeAll(MockColorPickerInstance.prototype);
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockFilePicker.jsm b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockFilePicker.jsm
deleted file mode 100644
index f7b130e..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockFilePicker.jsm
+++ /dev/null
@@ -1,236 +0,0 @@
-/* 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/. */
-
-this.EXPORTED_SYMBOLS = ["MockFilePicker"];
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cm = Components.manager;
-const Cu = Components.utils;
-
-const CONTRACT_ID = "@mozilla.org/filepicker;1";
-
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-var oldClassID, oldFactory;
-var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
-var newFactory = function (window) {
-  return {
-    createInstance: function(aOuter, aIID) {
-      if (aOuter)
-        throw Components.results.NS_ERROR_NO_AGGREGATION;
-      return new MockFilePickerInstance(window).QueryInterface(aIID);
-    },
-    lockFactory: function(aLock) {
-      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
-  };
-}
-
-this.MockFilePicker = {
-  returnOK: Ci.nsIFilePicker.returnOK,
-  returnCancel: Ci.nsIFilePicker.returnCancel,
-  returnReplace: Ci.nsIFilePicker.returnReplace,
-
-  filterAll: Ci.nsIFilePicker.filterAll,
-  filterHTML: Ci.nsIFilePicker.filterHTML,
-  filterText: Ci.nsIFilePicker.filterText,
-  filterImages: Ci.nsIFilePicker.filterImages,
-  filterXML: Ci.nsIFilePicker.filterXML,
-  filterXUL: Ci.nsIFilePicker.filterXUL,
-  filterApps: Ci.nsIFilePicker.filterApps,
-  filterAllowURLs: Ci.nsIFilePicker.filterAllowURLs,
-  filterAudio: Ci.nsIFilePicker.filterAudio,
-  filterVideo: Ci.nsIFilePicker.filterVideo,
-
-  window: null,
-
-  init: function(window) {
-    this.window = window;
-
-    this.reset();
-    this.factory = newFactory(window);
-    if (!registrar.isCIDRegistered(newClassID)) {
-      oldClassID = registrar.contractIDToCID(CONTRACT_ID);
-      oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
-      registrar.unregisterFactory(oldClassID, oldFactory);
-      registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
-    }
-  },
-
-  reset: function() {
-    this.appendFilterCallback = null;
-    this.appendFiltersCallback = null;
-    this.displayDirectory = null;
-    this.filterIndex = 0;
-    this.mode = null;
-    this.returnFiles = [];
-    this.returnValue = null;
-    this.showCallback = null;
-    this.shown = false;
-    this.showing = false;
-  },
-
-  cleanup: function() {
-    var previousFactory = this.factory;
-    this.reset();
-    this.factory = null;
-    if (oldFactory) {
-      registrar.unregisterFactory(newClassID, previousFactory);
-      registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
-    }
-  },
-
-  useAnyFile: function() {
-    var file = FileUtils.getDir("TmpD", [], false);
-    file.append("testfile");
-    file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
-    this.returnFiles = [file];
-  },
-
-  useBlobFile: function() {
-    var blob = new this.window.Blob([]);
-    var file = new this.window.File(blob, { name: 'helloworld.txt', type: 'plain/text' });
-    this.returnFiles = [file];
-  },
-
-  isNsIFile: function(aFile) {
-    let ret = false;
-    try {
-      if (aFile.QueryInterface(Ci.nsIFile))
-        ret = true;
-    } catch(e) {}
-
-    return ret;
-  }
-};
-
-function MockFilePickerInstance(window) {
-  this.window = window;
-};
-MockFilePickerInstance.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
-  init: function(aParent, aTitle, aMode) {
-    MockFilePicker.mode = aMode;
-    this.filterIndex = MockFilePicker.filterIndex;
-    this.parent = aParent;
-  },
-  appendFilter: function(aTitle, aFilter) {
-    if (typeof MockFilePicker.appendFilterCallback == "function")
-      MockFilePicker.appendFilterCallback(this, aTitle, aFilter);
-  },
-  appendFilters: function(aFilterMask) {
-    if (typeof MockFilePicker.appendFiltersCallback == "function")
-      MockFilePicker.appendFiltersCallback(this, aFilterMask);
-  },
-  defaultString: "",
-  defaultExtension: "",
-  parent: null,
-  filterIndex: 0,
-  displayDirectory: null,
-  get file() {
-    if (MockFilePicker.returnFiles.length >= 1 &&
-        // window.File does not implement nsIFile
-        MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
-      return MockFilePicker.returnFiles[0];
-    }
-
-    return null;
-  },
-  get domfile()  {
-    if (MockFilePicker.returnFiles.length >= 1) {
-      // window.File does not implement nsIFile
-      if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
-        return MockFilePicker.returnFiles[0];
-      }
-
-      let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
-                             .getInterface(Ci.nsIDOMWindowUtils);
-      return utils.wrapDOMFile(MockFilePicker.returnFiles[0]);
-    }
-    return null;
-  },
-  get fileURL() {
-    if (MockFilePicker.returnFiles.length >= 1 &&
-        // window.File does not implement nsIFile
-        MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
-      return Services.io.newFileURI(MockFilePicker.returnFiles[0]);
-    }
-
-    return null;
-  },
-  get files() {
-    return {
-      index: 0,
-      QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
-      hasMoreElements: function() {
-        return this.index < MockFilePicker.returnFiles.length;
-      },
-      getNext: function() {
-        // window.File does not implement nsIFile
-        if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
-          return null;
-        }
-        return MockFilePicker.returnFiles[this.index++];
-      }
-    };
-  },
-  get domfiles()  {
-    let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
-                           .getInterface(Ci.nsIDOMWindowUtils);
-    return {
-      index: 0,
-      QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
-      hasMoreElements: function() {
-        return this.index < MockFilePicker.returnFiles.length;
-      },
-      getNext: function() {
-        // window.File does not implement nsIFile
-        if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
-          return MockFilePicker.returnFiles[this.index++];
-        }
-        return utils.wrapDOMFile(MockFilePicker.returnFiles[this.index++]);
-      }
-    };
-  },
-  show: function() {
-    MockFilePicker.displayDirectory = this.displayDirectory;
-    MockFilePicker.shown = true;
-    if (typeof MockFilePicker.showCallback == "function") {
-      var returnValue = MockFilePicker.showCallback(this);
-      if (typeof returnValue != "undefined")
-        return returnValue;
-    }
-    return MockFilePicker.returnValue;
-  },
-  open: function(aFilePickerShownCallback) {
-    MockFilePicker.showing = true;
-    this.window.setTimeout(function() {
-      let result = Components.interfaces.nsIFilePicker.returnCancel;
-      try {
-        result = this.show();
-      } catch(ex) {
-      }
-      if (aFilePickerShownCallback) {
-        aFilePickerShownCallback.done(result);
-      }
-    }.bind(this), 0);
-  }
-};
-
-// Expose everything to content. We call reset() here so that all of the relevant
-// lazy expandos get added.
-MockFilePicker.reset();
-function exposeAll(obj) {
-  var props = {};
-  for (var prop in obj)
-    props[prop] = 'rw';
-  obj.__exposedProps__ = props;
-}
-exposeAll(MockFilePicker);
-exposeAll(MockFilePickerInstance.prototype);
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockPermissionPrompt.jsm b/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockPermissionPrompt.jsm
deleted file mode 100644
index cb2b1e9..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/chrome/specialpowers/modules/MockPermissionPrompt.jsm
+++ /dev/null
@@ -1,97 +0,0 @@
-/* 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/. */
-
-this.EXPORTED_SYMBOLS = ["MockPermissionPrompt"];
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cm = Components.manager;
-const Cu = Components.utils;
-
-const CONTRACT_ID = "@mozilla.org/content-permission/prompt;1";
-
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-var oldClassID, oldFactory;
-var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
-var newFactory = {
-  createInstance: function(aOuter, aIID) {
-    if (aOuter)
-      throw Components.results.NS_ERROR_NO_AGGREGATION;
-    return new MockPermissionPromptInstance().QueryInterface(aIID);
-  },
-  lockFactory: function(aLock) {
-    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
-};
-
-this.MockPermissionPrompt = {
-  init: function() {
-    this.reset();
-    if (!registrar.isCIDRegistered(newClassID)) {
-      try {
-        oldClassID = registrar.contractIDToCID(CONTRACT_ID);
-        oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
-      } catch (ex) {
-        oldClassID = "";
-        oldFactory = null;
-        dump("TEST-INFO | can't get permission prompt registered component, " +
-            "assuming there is none");
-      }
-      if (oldFactory) {
-        registrar.unregisterFactory(oldClassID, oldFactory);
-      }
-      registrar.registerFactory(newClassID, "", CONTRACT_ID, newFactory);
-    }
-  },
-
-  reset: function() {
-  },
-
-  cleanup: function() {
-    this.reset();
-    if (oldFactory) {
-      registrar.unregisterFactory(newClassID, newFactory);
-      registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
-    }
-  },
-};
-
-function MockPermissionPromptInstance() { };
-MockPermissionPromptInstance.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
-
-  promptResult: Ci.nsIPermissionManager.UNKNOWN_ACTION,
-
-  prompt: function(request) {
-
-    let perms = request.types.QueryInterface(Ci.nsIArray);
-    for (let idx = 0; idx < perms.length; idx++) {
-      let perm = perms.queryElementAt(idx, Ci.nsIContentPermissionType);
-      if (Services.perms.testExactPermissionFromPrincipal(
-           request.principal, perm.type) != Ci.nsIPermissionManager.ALLOW_ACTION) {
-        request.cancel();
-        return;
-      }
-    }
-
-    request.allow();
-  }
-};
-
-// Expose everything to content. We call reset() here so that all of the relevant
-// lazy expandos get added.
-MockPermissionPrompt.reset();
-function exposeAll(obj) {
-  var props = {};
-  for (var prop in obj)
-    props[prop] = 'rw';
-  obj.__exposedProps__ = props;
-}
-exposeAll(MockPermissionPrompt);
-exposeAll(MockPermissionPromptInstance.prototype);
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/components/SpecialPowersObserver.js b/test/resources/firefox/extensions/special-powers at mozilla.org/components/SpecialPowersObserver.js
deleted file mode 100644
index 7adc637..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/components/SpecialPowersObserver.js
+++ /dev/null
@@ -1,178 +0,0 @@
-/* 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/. */
-
-// Based on:
-// https://bugzilla.mozilla.org/show_bug.cgi?id=549539
-// https://bug549539.bugzilla.mozilla.org/attachment.cgi?id=429661
-// https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_1.9.3
-// http://mxr.mozilla.org/mozilla-central/source/toolkit/components/console/hudservice/HUDService.jsm#3240
-// https://developer.mozilla.org/en/how_to_build_an_xpcom_component_in_javascript
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-const CHILD_SCRIPT = "chrome://specialpowers/content/specialpowers.js"
-const CHILD_SCRIPT_API = "chrome://specialpowers/content/specialpowersAPI.js"
-const CHILD_LOGGER_SCRIPT = "chrome://specialpowers/content/MozillaLogger.js"
-
-
-// Glue to add in the observer API to this object.  This allows us to share code with chrome tests
-var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
-                       .getService(Components.interfaces.mozIJSSubScriptLoader);
-loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js");
-
-/* XPCOM gunk */
-this.SpecialPowersObserver = function SpecialPowersObserver() {
-  this._isFrameScriptLoaded = false;
-  this._mmIsGlobal = true;
-  this._messageManager = Cc["@mozilla.org/globalmessagemanager;1"].
-                         getService(Ci.nsIMessageBroadcaster);
-}
-
-
-SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
-
-  SpecialPowersObserver.prototype.classDescription = "Special powers Observer for use in testing.";
-  SpecialPowersObserver.prototype.classID = Components.ID("{59a52458-13e0-4d93-9d85-a637344f29a1}");
-  SpecialPowersObserver.prototype.contractID = "@mozilla.org/special-powers-observer;1";
-  SpecialPowersObserver.prototype.QueryInterface = XPCOMUtils.generateQI([Components.interfaces.nsIObserver]);
-  SpecialPowersObserver.prototype._xpcom_categories = [{category: "profile-after-change", service: true }];
-
-  SpecialPowersObserver.prototype.observe = function(aSubject, aTopic, aData)
-  {
-    switch (aTopic) {
-      case "profile-after-change":
-        this.init();
-        break;
-
-      case "chrome-document-global-created":
-        if (!this._isFrameScriptLoaded) {
-          // Register for any messages our API needs us to handle
-          this._messageManager.addMessageListener("SPPrefService", this);
-          this._messageManager.addMessageListener("SPProcessCrashService", this);
-          this._messageManager.addMessageListener("SPPingService", this);
-          this._messageManager.addMessageListener("SpecialPowers.Quit", this);
-          this._messageManager.addMessageListener("SpecialPowers.Focus", this);
-          this._messageManager.addMessageListener("SPPermissionManager", this);
-          this._messageManager.addMessageListener("SPWebAppService", this);
-          this._messageManager.addMessageListener("SPObserverService", this);
-          this._messageManager.addMessageListener("SPLoadChromeScript", this);
-          this._messageManager.addMessageListener("SPChromeScriptMessage", this);
-
-          this._messageManager.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
-          this._messageManager.loadFrameScript(CHILD_SCRIPT_API, true);
-          this._messageManager.loadFrameScript(CHILD_SCRIPT, true);
-          this._isFrameScriptLoaded = true;
-        }
-        break;
-
-      case "http-on-modify-request":
-        if (aSubject instanceof Ci.nsIChannel) {
-          let uri = aSubject.URI.spec;
-          this._sendAsyncMessage("specialpowers-http-notify-request", { uri: uri });
-        }
-        break;
-
-      case "xpcom-shutdown":
-        this.uninit();
-        break;
-
-      default:
-        this._observe(aSubject, aTopic, aData);
-        break;
-    }
-  };
-
-  SpecialPowersObserver.prototype._sendAsyncMessage = function(msgname, msg)
-  {
-    if (this._mmIsGlobal) {
-      this._messageManager.broadcastAsyncMessage(msgname, msg);
-    }
-    else {
-      this._messageManager.sendAsyncMessage(msgname, msg);
-    }
-  };
-
-  SpecialPowersObserver.prototype._receiveMessage = function(aMessage) {
-    return this._receiveMessageAPI(aMessage);
-  };
-
-  SpecialPowersObserver.prototype.init = function(messageManager)
-  {
-    var obs = Services.obs;
-    obs.addObserver(this, "xpcom-shutdown", false);
-    obs.addObserver(this, "chrome-document-global-created", false);
-    obs.addObserver(this, "http-on-modify-request", false);
-
-    if (messageManager) {
-      this._messageManager = messageManager;
-      this._mmIsGlobal = false;
-    }
-  };
-
-  SpecialPowersObserver.prototype.uninit = function()
-  {
-    var obs = Services.obs;
-    obs.removeObserver(this, "chrome-document-global-created");
-    obs.removeObserver(this, "http-on-modify-request");
-    this._removeProcessCrashObservers();
-  };
-
-  SpecialPowersObserver.prototype._addProcessCrashObservers = function() {
-    if (this._processCrashObserversRegistered) {
-      return;
-    }
-
-    var obs = Components.classes["@mozilla.org/observer-service;1"]
-                        .getService(Components.interfaces.nsIObserverService);
-
-    obs.addObserver(this, "plugin-crashed", false);
-    obs.addObserver(this, "ipc:content-shutdown", false);
-    this._processCrashObserversRegistered = true;
-  };
-
-  SpecialPowersObserver.prototype._removeProcessCrashObservers = function() {
-    if (!this._processCrashObserversRegistered) {
-      return;
-    }
-
-    var obs = Components.classes["@mozilla.org/observer-service;1"]
-                        .getService(Components.interfaces.nsIObserverService);
-
-    obs.removeObserver(this, "plugin-crashed");
-    obs.removeObserver(this, "ipc:content-shutdown");
-    this._processCrashObserversRegistered = false;
-  };
-
-  /**
-   * messageManager callback function
-   * This will get requests from our API in the window and process them in chrome for it
-   **/
-  SpecialPowersObserver.prototype.receiveMessage = function(aMessage) {
-    switch(aMessage.name) {
-      case "SPPingService":
-        if (aMessage.json.op == "ping") {
-          aMessage.target
-                  .QueryInterface(Ci.nsIFrameLoaderOwner)
-                  .frameLoader
-                  .messageManager
-                  .sendAsyncMessage("SPPingService", { op: "pong" });
-        }
-        break;
-      case "SpecialPowers.Quit":
-        let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
-        appStartup.quit(Ci.nsIAppStartup.eForceQuit);
-        break;
-      case "SpecialPowers.Focus":
-        aMessage.target.focus();
-        break;
-      default:
-        return this._receiveMessage(aMessage);
-    }
-  };
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SpecialPowersObserver]);
diff --git a/test/resources/firefox/extensions/special-powers at mozilla.org/install.rdf b/test/resources/firefox/extensions/special-powers at mozilla.org/install.rdf
deleted file mode 100644
index c97318d..0000000
--- a/test/resources/firefox/extensions/special-powers at mozilla.org/install.rdf
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>special-powers at mozilla.org</em:id>
-    <em:version>2010.07.23</em:version>
-    <em:type>2</em:type>
-
-    <!-- Target Application this extension can install into,
-         with minimum and maximum supported versions. -->
-    <em:targetApplication>
-      <Description>
-        <em:id>toolkit at mozilla.org</em:id>
-       <em:minVersion>3.0</em:minVersion>
-       <em:maxVersion>13.0a1</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:name>Special Powers</em:name>
-    <em:description>Special powers for use in testing.</em:description>
-    <em:creator>Mozilla</em:creator>
-  </Description>
-</RDF>
diff --git a/test/unit/testreporter.js b/test/unit/testreporter.js
index d338d81..e596712 100644
--- a/test/unit/testreporter.js
+++ b/test/unit/testreporter.js
@@ -1,6 +1,5 @@
 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* globals SpecialPowers */
 
 'use strict';
 
@@ -42,11 +41,7 @@ var TestReporter = function(browser, appPath) {
   }
 
   function sendQuitRequest() {
-    send('/tellMeToQuit?path=' + escape(appPath), {}, function () {
-      if (window.SpecialPowers) {
-        SpecialPowers.quit();
-      }
-    });
+    send('/tellMeToQuit?path=' + escape(appPath), {});
   }
 
   this.now = function() {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git



More information about the Pkg-javascript-commits mailing list