Bug 1617887 - remove Runner and other things from frame.jsm. r=darktrojan DONTBUILD
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Mon, 04 May 2020 13:57:17 +0300
changeset 39014 6e0dee99d40aa027e131e989bf99e2fef91d4725
parent 39013 ad8b33dcd11efd5c9914d9a85e97708f96767158
child 39015 003fb53e3b8868c171dba06e07de0850360e5762
push id401
push userclokep@gmail.com
push dateMon, 01 Jun 2020 20:41:59 +0000
reviewersdarktrojan
bugs1617887
Bug 1617887 - remove Runner and other things from frame.jsm. r=darktrojan DONTBUILD
mail/test/browser/shared-modules/WindowHelpers.jsm
mail/test/browser/shared-modules/controller.jsm
mail/test/browser/shared-modules/frame.jsm
mail/test/browser/shared-modules/moz.build
mail/test/browser/shared-modules/securable-module.jsm
--- a/mail/test/browser/shared-modules/WindowHelpers.jsm
+++ b/mail/test/browser/shared-modules/WindowHelpers.jsm
@@ -29,17 +29,16 @@ const EXPORTED_SYMBOLS = [
 ];
 
 var controller = ChromeUtils.import(
   "resource://testing-common/mozmill/controller.jsm"
 );
 var elib = ChromeUtils.import(
   "resource://testing-common/mozmill/elementslib.jsm"
 );
-var frame = ChromeUtils.import("resource://testing-common/mozmill/frame.jsm");
 var utils = ChromeUtils.import("resource://testing-common/mozmill/utils.jsm");
 
 var { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
 var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 /**
  * Timeout to use when waiting for the first window ever to load.  This is
@@ -332,18 +331,17 @@ var WindowWatcher = {
       augment_controller(troller, this.waitingForOpen);
 
       this._timer.cancel();
 
       let self = this;
       function startTest() {
         self.planForWindowClose(troller.window);
         try {
-          let runner = new frame.Runner();
-          runner.wrapper(self.subTestFunc, troller);
+          self.subTestFunc(troller);
         } finally {
           self.subTestFunc = null;
         }
 
         // if the test failed, make sure we force the window closed...
         // except I'm not sure how to easily figure that out...
         // so just close it no matter what.
         troller.window.close();
--- a/mail/test/browser/shared-modules/controller.jsm
+++ b/mail/test/browser/shared-modules/controller.jsm
@@ -51,16 +51,19 @@ var EventUtils = ChromeUtils.import(
 );
 
 var events = ChromeUtils.import("resource://testing-common/mozmill/events.jsm");
 var utils = ChromeUtils.import("resource://testing-common/mozmill/utils.jsm");
 var elementslib = ChromeUtils.import(
   "resource://testing-common/mozmill/elementslib.jsm"
 );
 var frame = ChromeUtils.import("resource://testing-common/mozmill/frame.jsm");
+frame.log = function(obj) {
+  frame.events.fireEvent("log", obj);
+};
 
 // The window map which is used to store information e.g. loaded state of each
 // open chrome and content window.
 var windowMap = {
   _windows: {},
 
   contains(aWindowId) {
     return aWindowId in this._windows;
--- a/mail/test/browser/shared-modules/frame.jsm
+++ b/mail/test/browser/shared-modules/frame.jsm
@@ -30,131 +30,17 @@
 // use your version of this file under the terms of the MPL, indicate your
 // decision by deleting the provisions above and replace them with the notice
 // and other provisions required by the GPL or the LGPL. If you do not delete
 // the provisions above, a recipient may use your version of this file under
 // the terms of any one of the MPL, the GPL or the LGPL.
 //
 // ***** END LICENSE BLOCK *****
 
-var EXPORTED_SYMBOLS = [
-  "loadFile",
-  "register_function",
-  "Collector",
-  "Runner",
-  "events",
-  "jsbridge",
-  "runTestDirectory",
-  "runTestFile",
-  "log",
-  "getThread",
-  "timers",
-  "persisted",
-  "registerModule",
-];
-
-var { HttpServer } = ChromeUtils.import(
-  "resource://testing-common/mozmill/httpd.jsm"
-);
-
-var os = ChromeUtils.import("resource://testing-common/mozmill/os.jsm");
-var utils = ChromeUtils.import("resource://testing-common/mozmill/utils.jsm");
-var securableModule = ChromeUtils.import(
-  "resource://testing-common/mozmill/securable-module.jsm"
-);
-var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-var elementslib = ChromeUtils.import(
-  "resource://testing-common/mozmill/elementslib.jsm"
-);
-
-var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
-
-var backstage = this;
-
-var registeredFunctions = {};
-
-var persisted = {};
-
-var thread;
-
-var arrayRemove = function(array, from, to) {
-  var rest = array.slice((to || from) + 1 || array.length);
-  array.length = from < 0 ? array.length + from : from;
-  return array.push.apply(array, rest);
-};
-
-var modules = undefined;
-
-var loadFile = function(path, collector) {
-  var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-  file.initWithPath(path);
-  var uri = Services.io.newFileURI(file).spec;
-
-  var module = new Cu.Sandbox(systemPrincipal, {
-    wantGlobalProperties: ["ChromeUtils"],
-  });
-  module.registeredFunctions = registeredFunctions;
-  module.collector = collector;
-
-  var mozmill = ChromeUtils.import(
-    "resource://testing-common/mozmill/mozmill.jsm"
-  );
-  module.mozmill = mozmill;
-  module.elementslib = elementslib;
-  module.persisted = persisted;
-  module.Cc = Cc;
-  module.Ci = Ci;
-  module.Cu = Cu;
-  module.require = function(mod) {
-    var loader = new securableModule.Loader({
-      rootPaths: [Services.io.newFileURI(file.parent).spec],
-      defaultPrincipal: "system",
-      globals: { mozmill, elementslib, persisted, Cc, Ci, Cu },
-    });
-    if (modules != undefined) {
-      loader.modules = modules;
-    }
-    var retval = loader.require(mod);
-    modules = loader.modules;
-    return retval;
-  };
-
-  if (collector != undefined) {
-    collector.current_file = file;
-    collector.current_path = path;
-  }
-  try {
-    Services.scriptloader.loadSubScript(uri, module, "UTF-8");
-  } catch (e) {
-    events.fail({ exception: e });
-
-    var obj = {
-      filename: path,
-      passed: 0,
-      failed: 1,
-      passes: [],
-      fails: [
-        {
-          exception: {
-            message: e.message || e.toString(),
-            fileName: e.filename || e.fileName,
-            lineNumber: e.lineNumber,
-          },
-        },
-      ],
-      name: "<TOP_LEVEL>",
-    };
-    events.fireEvent("endTest", obj);
-  }
-
-  module.__file__ = path;
-  module.__uri__ = uri;
-  return module;
-};
+const EXPORTED_SYMBOLS = ["events"];
 
 function stateChangeBase(possibilities, restrictions, target, cmeta, v) {
   if (possibilities) {
     if (!possibilities.includes(v)) {
       // TODO Error value not in this.poss
       return;
     }
   }
@@ -328,391 +214,18 @@ events.addListener = function(name, list
     this.listeners[name] = [listener];
   }
 };
 events.removeListener = function(listener) {
   for (var listenerIndex in this.listeners) {
     var e = this.listeners[listenerIndex];
     for (let i in e) {
       if (e[i] == listener) {
-        this.listeners[listenerIndex] = arrayRemove(e, i);
+        this.listeners[listenerIndex] = e.splice(i, 1);
       }
     }
   }
   for (let i in this.globalListeners) {
     if (this.globalListeners[i] == listener) {
-      this.globalListeners = arrayRemove(this.globalListeners, i);
-    }
-  }
-};
-
-var log = function(obj) {
-  events.fireEvent("log", obj);
-};
-
-var jsbridge;
-try {
-  jsbridge = ChromeUtils.import("chrome://jsbridge/content/modules/events.js");
-} catch (err) {
-  jsbridge = null;
-  Services.console.logStringMessage("jsbridge not available.");
-}
-
-if (jsbridge) {
-  events.addListener("", function(name, obj) {
-    jsbridge.fireEvent("mozmill." + name, obj);
-  });
-}
-
-function Collector() {
-  this.test_modules_by_filename = {};
-  this.test_modules_by_name = {};
-  this.requirements_run = {};
-  this.all_requirements = [];
-  this.loaded_directories = [];
-  this.testing = [];
-  this.httpd_started = false;
-  this.http_port = 43336;
-  // var logging = ChromeUtils.import("resource://testing-common/mozmill/logging.jsm");
-  // this.logger = new logging.Logger('Collector');
-}
-
-Collector.prototype.getModule = function(name) {
-  return this.test_modules_by_name[name];
-};
-
-Collector.prototype.getServer = function(port, basePath) {
-  if (basePath) {
-    var lp = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-    lp.initWithPath(basePath);
-  }
-
-  var srv = new HttpServer();
-  if (lp) {
-    srv.registerDirectory("/", lp);
-  }
-
-  srv.registerContentType("sjs", "sjs");
-  srv.identity.setPrimary("http", "localhost", port);
-  srv._port = port;
-
-  return srv;
-};
-
-Collector.prototype.startHttpd = function() {
-  while (this.httpd == undefined) {
-    try {
-      var http_server = this.getServer(this.http_port);
-      http_server.start(this.http_port);
-      this.httpd = http_server;
-    } catch (e) {
-      // Failure most likely due to port conflict
-      this.http_port++;
+      this.globalListeners = this.globalListeners.splice(i, 1);
     }
   }
 };
-
-Collector.prototype.stopHttpd = function() {
-  if (this.httpd) {
-    this.httpd.stop(function() {}); // Callback needed to pause execution until the server has been properly shutdown
-    this.httpd = null;
-  }
-};
-
-Collector.prototype.addHttpResource = function(directory, ns) {
-  if (!this.httpd) {
-    this.startHttpd();
-  }
-
-  if (!ns) {
-    ns = "/";
-  } else {
-    ns = "/" + ns + "/";
-  }
-
-  var lp = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-  lp.initWithPath(os.abspath(directory, this.current_file));
-  this.httpd.registerDirectory(ns, lp);
-
-  return "http://localhost:" + this.http_port + ns;
-};
-
-Collector.prototype.initTestModule = function(filename) {
-  var test_module = loadFile(filename, this);
-  test_module.__tests__ = [];
-  for (var i in test_module) {
-    if (test_module[i] == null) {
-      // do nothing
-    } else if (typeof test_module[i] == "function") {
-      if (i == "setupTest") {
-        test_module[i].__name__ = i;
-        test_module.__setupTest__ = test_module[i];
-      } else if (i == "setupModule") {
-        test_module[i].__name__ = i;
-        test_module.__setupModule__ = test_module[i];
-      } else if (i == "teardownTest") {
-        test_module[i].__name__ = i;
-        test_module.__teardownTest__ = test_module[i];
-      } else if (i == "teardownModule") {
-        test_module[i].__name__ = i;
-        test_module.__teardownModule__ = test_module[i];
-      } else if (i.startsWith("test")) {
-        test_module[i].__name__ = i;
-        test_module.__tests__.push(test_module[i]);
-      }
-    } else if (
-      typeof test_module[i] == "object" &&
-      test_module[i]._mozmillasynctest
-    ) {
-      test_module[i].__name__ = i;
-      test_module.__tests__.push(test_module[i]);
-    }
-    if (i == "RELATIVE_ROOT") {
-      test_module.__root_path__ = os.abspath(
-        test_module[i],
-        os.getFileForPath(filename)
-      );
-    }
-    if (i == "MODULE_REQUIRES") {
-      test_module.__requirements__ = test_module[i];
-      this.all_requirements.push.apply(backstage, test_module[i]);
-    }
-    if (i == "MODULE_NAME") {
-      test_module.__module_name__ = test_module[i];
-      this.test_modules_by_name[test_module[i]] = test_module;
-    }
-  }
-
-  test_module.collector = this;
-  test_module.status = "loaded";
-  this.test_modules_by_filename[filename] = test_module;
-
-  return test_module;
-};
-
-Collector.prototype.initTestDirectory = function(directory) {
-  var r = this;
-  function recursiveModuleLoader(dfile) {
-    r.loaded_directories.push(directory);
-    var dfiles = os.listDirectory(dfile);
-    for (var i in dfiles) {
-      var f = dfiles[i];
-      if (
-        f.isDirectory() &&
-        !f.leafName.startsWith(".") &&
-        f.leafName.startsWith("test") &&
-        !r.loaded_directories.includes(f.path)
-      ) {
-        recursiveModuleLoader(os.getFileForPath(f.path));
-      } else if (
-        f.leafName.startsWith("test") &&
-        f.leafName.endsWith(".js") &&
-        !(f.path in r.test_modules_by_filename)
-      ) {
-        r.initTestModule(f.path);
-      }
-      r.testing.push(f.path);
-    }
-  }
-  recursiveModuleLoader(os.getFileForPath(directory));
-};
-
-// Observer which gets notified when the application quits
-function AppQuitObserver() {
-  this.register();
-}
-AppQuitObserver.prototype = {
-  observe(subject, topic, data) {
-    events.appQuit = true;
-  },
-  register() {
-    Services.obs.addObserver(this, "quit-application");
-  },
-  unregister() {
-    Services.obs.removeObserver(this, "quit-application");
-  },
-};
-
-function Runner(collector, invokedFromIDE) {
-  this.collector = collector;
-  this.invokedFromIDE = invokedFromIDE;
-  events.fireEvent("startRunner", true);
-}
-Runner.prototype.runTestDirectory = function(directory) {
-  this.collector.initTestDirectory(directory);
-
-  for (var i in this.collector.test_modules_by_filename) {
-    var test = this.collector.test_modules_by_filename[i];
-    if (test.status != "done") {
-      this.runTestModule(test);
-    }
-  }
-};
-Runner.prototype.runTestFile = function(filename) {
-  // if ( !arrays.inArray(this.test_modules_by_filename, directory) ) {
-  //   this.collector.initTestModule(directory);
-  // }
-  this.collector.initTestModule(filename);
-  this.runTestModule(this.collector.test_modules_by_filename[filename]);
-};
-Runner.prototype.end = function() {
-  try {
-    events.fireEvent("persist", persisted);
-  } catch (e) {
-    events.fireEvent("error", "persist serialization failed.");
-  }
-  this.collector.stopHttpd();
-  events.fireEvent("endRunner", true);
-};
-
-Runner.prototype.wrapper = function(func, arg) {
-  thread = Services.tm.currentThread;
-
-  try {
-    if (arg) {
-      func(arg);
-    } else if (func._mozmillasynctest) {
-      func.run();
-    } else {
-      func();
-    }
-    // If a shutdown was expected but the application hasn't quit, throw a failure
-    if (events.isUserShutdown()) {
-      utils.sleep(500); // Prevents race condition between mozrunner hard process kill and normal FFx shutdown
-      if (!events.appQuit) {
-        events.fail({
-          function: "Runner.wrapper",
-          message: "Shutdown expected but none detected before end of test",
-        });
-      }
-    }
-  } catch (e) {
-    if (func._mozmillasynctest) {
-      func = {
-        filename: events.currentModule.__file__,
-        name: func.__name__,
-      };
-    }
-    // Allow the exception if a user shutdown was expected
-    if (!events.isUserShutdown()) {
-      events.fail({ exception: e, test: func });
-      Cu.reportError(e);
-    }
-  }
-};
-
-Runner.prototype._runTestModule = function(module) {
-  if (module.__requirements__ != undefined) {
-    for (var req of module.__requirements__) {
-      module[req] = this.collector.getModule(req);
-    }
-  }
-
-  var attrs = [];
-  for (let i in module) {
-    attrs.push(i);
-  }
-
-  events.setModule(module);
-  var observer = new AppQuitObserver();
-  var setupModulePassed, setupTestPassed;
-
-  module.__status__ = "running";
-  if (module.__setupModule__) {
-    events.setState("setupModule");
-    events.setTest(module.__setupModule__);
-    this.wrapper(module.__setupModule__, module);
-    setupModulePassed =
-      events.currentTest.__fails__.length == 0 && !events.currentTest.skipped;
-    events.endTest(module.__setupModule__);
-  } else {
-    setupModulePassed = true;
-  }
-  if (setupModulePassed) {
-    for (let i in module.__tests__) {
-      events.appQuit = false;
-      let test = module.__tests__[i];
-
-      // TODO: introduce per-test timeout:
-      // https://bugzilla.mozilla.org/show_bug.cgi?id=574871
-
-      if (module.__setupTest__) {
-        events.setState("setupTest");
-        events.setTest(module.__setupTest__);
-        this.wrapper(module.__setupTest__, test);
-        setupTestPassed =
-          events.currentTest.__fails__.length == 0 &&
-          !events.currentTest.skipped;
-        events.endTest(module.__setupTest__);
-      } else {
-        setupTestPassed = true;
-      }
-      events.setState("test");
-      events.setTest(test, this.invokedFromIDE);
-      if (setupTestPassed) {
-        this.wrapper(test);
-      } else {
-        events.skip("setupTest failed.");
-      }
-      if (module.__teardownTest__) {
-        events.setState("teardownTest");
-        events.setTest(module.__teardownTest__);
-        this.wrapper(module.__teardownTest__, test);
-        events.endTest(module.__teardownTest__);
-      }
-      events.endTest(test);
-    }
-  } else {
-    for (let test of module.__tests__) {
-      events.setTest(test);
-      events.skip("setupModule failed.");
-      events.endTest(test);
-    }
-  }
-  if (module.__teardownModule__) {
-    events.setState("teardownModule");
-    events.setTest(module.__teardownModule__);
-    this.wrapper(module.__teardownModule__, module);
-    events.endTest(module.__teardownModule__);
-  }
-
-  observer.unregister();
-
-  module.__status__ = "done";
-};
-
-Runner.prototype.runTestModule = function(module) {
-  if (module.__requirements__ != undefined) {
-    if (!this.collector.loaded_directories.includes(module.__root_path__)) {
-      if (module.__root_path__ != undefined) {
-        this.collector.initTestDirectory(module.__root_path__);
-      }
-    }
-  }
-  this._runTestModule(module);
-};
-
-var runTestDirectory = function(dir, invokedFromIDE) {
-  var runner = new Runner(new Collector(), invokedFromIDE);
-  runner.runTestDirectory(dir);
-  runner.end();
-  return true;
-};
-var runTestFile = function(filename, invokedFromIDE) {
-  var runner = new Runner(new Collector(), invokedFromIDE);
-  runner.runTestFile(filename);
-  runner.end();
-  return true;
-};
-
-var getThread = function() {
-  return thread;
-};
-
-function registerModule(name, path) {
-  let protocolHandler = Services.io
-    .getProtocolHandler("resource")
-    .QueryInterface(Ci.nsIResProtocolHandler);
-
-  let modulesFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-  modulesFile.initWithPath(path);
-  protocolHandler.setSubstitution(name, Services.io.newFileURI(modulesFile));
-}
--- a/mail/test/browser/shared-modules/moz.build
+++ b/mail/test/browser/shared-modules/moz.build
@@ -27,13 +27,12 @@ TESTING_JS_MODULES.mozmill += [
     'NewMailAccountHelpers.jsm',
     'NNTPHelpers.jsm',
     'NotificationBoxHelpers.jsm',
     'os.jsm',
     'PrefTabHelpers.jsm',
     'PromptHelpers.jsm',
     'QuickFilterBarHelpers.jsm',
     'SearchWindowHelpers.jsm',
-    'securable-module.jsm',
     'SubscribeWindowHelpers.jsm',
     'utils.jsm',
     'WindowHelpers.jsm',
 ]
deleted file mode 100644
--- a/mail/test/browser/shared-modules/securable-module.jsm
+++ /dev/null
@@ -1,419 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Atul Varma <atul@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-(function(global) {
-  const { Services } = ChromeUtils.import(
-    "resource://gre/modules/Services.jsm"
-  );
-
-  var exports = {};
-
-  var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
-    Ci.nsIPrincipal
-  );
-
-  function resolvePrincipal(principal, defaultPrincipal) {
-    if (principal === undefined) {
-      return defaultPrincipal;
-    }
-    if (principal == "system") {
-      return systemPrincipal;
-    }
-    return principal;
-  }
-
-  // The base URI to we use when we're given relative URLs, if any.
-  var baseURI = null;
-  if (global.window) {
-    baseURI = Services.io.newURI(global.location.href);
-  }
-  exports.baseURI = baseURI;
-
-  // The "parent" chrome URI to use if we're loading code that
-  // needs chrome privileges but may not have a filename that
-  // matches any of SpiderMonkey's defined system filename prefixes.
-  // The latter is needed so that wrappers can be automatically
-  // made for the code. For more information on this, see
-  // bug 418356:
-  //
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=418356
-  var parentChromeURIString;
-  if (baseURI) {
-    // We're being loaded from a chrome-privileged document, so
-    // use its URL as the parent string.
-    parentChromeURIString = baseURI.spec;
-  } else {
-    // We're being loaded from a chrome-privileged JS module or
-    // SecurableModule, so use its filename (which may itself
-    // contain a reference to a parent).
-    parentChromeURIString = Components.stack.filename;
-  }
-
-  function maybeParentifyFilename(filename) {
-    var doParentifyFilename = true;
-    try {
-      // TODO: Ideally we should just make
-      // nsIChromeRegistry.wrappersEnabled() available from script
-      // and use it here. Until that's in the platform, though,
-      // we'll play it safe and parentify the filename unless
-      // we're absolutely certain things will be ok if we don't.
-      var filenameURI = Services.io.newURI(filename, null, baseURI);
-      if (
-        filenameURI.scheme == "chrome" &&
-        filenameURI.pathQueryRef.indexOf("/content/") == 0
-      ) {
-        // Content packages will always have wrappers made for them;
-        // if automatic wrappers have been disabled for the
-        // chrome package via a chrome manifest flag, then
-        // this still works too, to the extent that the
-        // content package is insecure anyways.
-        doParentifyFilename = false;
-      }
-    } catch (e) {}
-    if (doParentifyFilename) {
-      return parentChromeURIString + " -> " + filename;
-    }
-    return filename;
-  }
-
-  function getRootDir(urlStr) {
-    // TODO: This feels hacky, and like there will be edge cases.
-    return urlStr.slice(0, urlStr.lastIndexOf("/") + 1);
-  }
-
-  exports.SandboxFactory = function(defaultPrincipal) {
-    // Unless specified otherwise, use a principal with limited
-    // privileges.
-    this._defaultPrincipal = resolvePrincipal(
-      defaultPrincipal,
-      "http://www.mozilla.org"
-    );
-  };
-
-  exports.SandboxFactory.prototype = {
-    createSandbox(options) {
-      var principal = resolvePrincipal(
-        options.principal,
-        this._defaultPrincipal
-      );
-
-      return {
-        _sandbox: new Cu.Sandbox(principal, {
-          wantGlobalProperties: ["ChromeUtils"],
-        }),
-        _principal: principal,
-        get globalScope() {
-          return this._sandbox;
-        },
-        defineProperty(name, value) {
-          this._sandbox[name] = value;
-        },
-        getProperty(name) {
-          return this._sandbox[name];
-        },
-        evaluate(options) {
-          if (typeof options == "string") {
-            options = { contents: options };
-          }
-          options = { __proto__: options };
-          if (typeof options.contents != "string") {
-            throw new Error("Expected string for options.contents");
-          }
-          if (options.lineNo === undefined) {
-            options.lineNo = 1;
-          }
-          if (options.jsVersion === undefined) {
-            options.jsVersion = "1.8";
-          }
-          if (typeof options.filename != "string") {
-            options.filename = "<string>";
-          }
-
-          if (this._principal == systemPrincipal) {
-            options.filename = maybeParentifyFilename(options.filename);
-          }
-
-          return Cu.evalInSandbox(
-            options.contents,
-            this._sandbox,
-            options.jsVersion,
-            options.filename,
-            options.lineNo
-          );
-        },
-      };
-    },
-  };
-
-  exports.Loader = function(options) {
-    options = { __proto__: options };
-    if (options.fs === undefined) {
-      var rootPaths = options.rootPath || options.rootPaths;
-      if (rootPaths) {
-        if (rootPaths.constructor.name != "Array") {
-          rootPaths = [rootPaths];
-        }
-        var fses = rootPaths.map(path => new exports.LocalFileSystem(path));
-        options.fs = new exports.CompositeFileSystem(fses);
-      } else {
-        options.fs = new exports.LocalFileSystem();
-      }
-    }
-    if (options.sandboxFactory === undefined) {
-      options.sandboxFactory = new exports.SandboxFactory(
-        options.defaultPrincipal
-      );
-    }
-    if (options.modules === undefined) {
-      options.modules = {};
-    }
-    if (options.globals === undefined) {
-      options.globals = {};
-    }
-
-    this.fs = options.fs;
-    this.sandboxFactory = options.sandboxFactory;
-    this.sandboxes = {};
-    this.modules = options.modules;
-    this.globals = options.globals;
-  };
-
-  exports.Loader.prototype = {
-    _makeRequire(rootDir) {
-      var self = this;
-      return function(module) {
-        if (module == "chrome") {
-          var chrome = {
-            Cc,
-            Ci,
-            Cu,
-            Cr,
-            Cm: Components.manager,
-            components: Components,
-          };
-          return chrome;
-        }
-        var path = self.fs.resolveModule(rootDir, module);
-        if (!path) {
-          throw new Error('Module "' + module + '" not found');
-        }
-        if (!(path in self.modules)) {
-          var options = self.fs.getFile(path);
-          if (options.filename === undefined) {
-            options.filename = path;
-          }
-
-          var sandbox = self.sandboxFactory.createSandbox(options);
-          self.sandboxes[path] = sandbox;
-          for (let name in self.globals) {
-            sandbox.defineProperty(name, self.globals[name]);
-          }
-          sandbox.defineProperty("require", self._makeRequire(path));
-          sandbox.evaluate("var exports = {};");
-          let ES5 = self.modules.es5;
-          if (ES5) {
-            let { Object, Array, Function } = sandbox.globalScope;
-            ES5.init(Object, Array, Function);
-          }
-          self.modules[path] = sandbox.getProperty("exports");
-          sandbox.evaluate(options);
-        }
-        return self.modules[path];
-      };
-    },
-
-    // This is only really used by unit tests and other
-    // development-related facilities, allowing access to symbols
-    // defined in the global scope of a module.
-    findSandboxForModule(module) {
-      var path = this.fs.resolveModule(null, module);
-      if (!path) {
-        throw new Error('Module "' + module + '" not found');
-      }
-      if (!(path in this.sandboxes)) {
-        this.require(module);
-      }
-      if (!(path in this.sandboxes)) {
-        throw new Error("Internal error: path not in sandboxes: " + path);
-      }
-      return this.sandboxes[path];
-    },
-
-    require(module) {
-      return this._makeRequire(null)(module);
-    },
-
-    runScript(options, extraOutput) {
-      if (typeof options == "string") {
-        options = { contents: options };
-      }
-      options = { __proto__: options };
-      var sandbox = this.sandboxFactory.createSandbox(options);
-      if (extraOutput) {
-        extraOutput.sandbox = sandbox;
-      }
-      for (let name in this.globals) {
-        sandbox.defineProperty(name, this.globals[name]);
-      }
-      sandbox.defineProperty("require", this._makeRequire(null));
-      return sandbox.evaluate(options);
-    },
-  };
-
-  exports.CompositeFileSystem = function(fses) {
-    this.fses = fses;
-    this._pathMap = {};
-  };
-
-  exports.CompositeFileSystem.prototype = {
-    resolveModule(base, path) {
-      for (var i = 0; i < this.fses.length; i++) {
-        var fs = this.fses[i];
-        var absPath = fs.resolveModule(base, path);
-        if (absPath) {
-          this._pathMap[absPath] = fs;
-          return absPath;
-        }
-      }
-      return null;
-    },
-    getFile(path) {
-      return this._pathMap[path].getFile(path);
-    },
-  };
-
-  exports.LocalFileSystem = function(root) {
-    if (root === undefined) {
-      if (!baseURI) {
-        throw new Error("Need a root path for module filesystem");
-      }
-      root = baseURI;
-    }
-    if (typeof root == "string") {
-      root = Services.io.newURI(root, null, baseURI);
-    }
-    if (root instanceof Ci.nsIFile) {
-      root = Services.io.newFileURI(root);
-    }
-    if (!(root instanceof Ci.nsIURI)) {
-      throw new Error("Expected nsIFile, nsIURI, or string for root");
-    }
-
-    this.root = root.spec;
-    this._rootURI = root;
-    this._rootURIDir = getRootDir(root.spec);
-  };
-
-  exports.LocalFileSystem.prototype = {
-    resolveModule(base, path) {
-      path = path + ".js";
-
-      var baseURI;
-      if (!base) {
-        baseURI = this._rootURI;
-      } else {
-        baseURI = Services.io.newURI(base);
-      }
-      var newURI = Services.io.newURI(path, null, baseURI);
-      var channel = Services.io.newChannelFromURI(
-        newURI,
-        null,
-        Services.scriptSecurityManager.getSystemPrincipal(),
-        null,
-        Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-        Ci.nsIContentPolicy.TYPE_OTHER
-      );
-      try {
-        channel.open().close();
-      } catch (e) {
-        if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
-          throw e;
-        }
-        return null;
-      }
-      return newURI.spec;
-    },
-    getFile(path) {
-      var channel = Services.io.newChannel(
-        path,
-        null,
-        null,
-        null,
-        Services.scriptSecurityManager.getSystemPrincipal(),
-        null,
-        Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-        Ci.nsIContentPolicy.TYPE_OTHER
-      );
-      var iStream = channel.open();
-      var ciStream = Cc[
-        "@mozilla.org/intl/converter-input-stream;1"
-      ].createInstance(Ci.nsIConverterInputStream);
-      var bufLen = 0x8000;
-      ciStream.init(
-        iStream,
-        "UTF-8",
-        bufLen,
-        Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER
-      );
-      var chunk = {};
-      var data = "";
-      while (ciStream.readString(bufLen, chunk) > 0) {
-        data += chunk.value;
-      }
-      ciStream.close();
-      iStream.close();
-      return { contents: data };
-    },
-  };
-
-  if (global.window) {
-    // We're being loaded in a chrome window, or a web page with
-    // UniversalXPConnect privileges.
-    global.SecurableModule = exports;
-  } else if (global.exports) {
-    // We're being loaded in a SecurableModule.
-    for (let name in exports) {
-      global.exports[name] = exports[name];
-    }
-  } else {
-    // We're being loaded in a JS module.
-    global.EXPORTED_SYMBOLS = [];
-    for (let name in exports) {
-      global.EXPORTED_SYMBOLS.push(name);
-      global[name] = exports[name];
-    }
-  }
-})(this);