Bug 1451519 Convert specialpowers to a webextension r=kmag
☠☠ backed out by a9fc2e123021 ☠ ☠
authorAndrew Swan <aswan@mozilla.com>
Wed, 27 Jun 2018 13:10:51 -0700
changeset 424460 722113b8204d8abfe8abfba74df5689ac1c31029
parent 424459 44ee5fe5de79521149789a1ed809e70ff9d27d23
child 424461 23b5f0e1a106a7bb9cbafe3391540ae1373edc65
push id65742
push useraswan@mozilla.com
push dateFri, 29 Jun 2018 18:05:24 +0000
treeherderautoland@722113b8204d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1451519
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1451519 Convert specialpowers to a webextension r=kmag This is a quick-and-dirty port. It might be nice to replace SpecialPowersObserver with the webextensions content script injection system at some point, but that isn't practical right now (since WE experiments cannot implement new APIs visible to content scripts). MozReview-Commit-ID: GinCu3VcbWK
dom/ipc/tests/test_bug1086684.html
js/xpconnect/loader/mozJSComponentLoader.cpp
testing/specialpowers/api.js
testing/specialpowers/bootstrap.js
testing/specialpowers/content/SpecialPowersObserver.jsm
testing/specialpowers/content/SpecialPowersObserverAPI.js
testing/specialpowers/content/specialpowers.js
testing/specialpowers/content/specialpowersAPI.js
testing/specialpowers/install.rdf
testing/specialpowers/jar.mn
testing/specialpowers/manifest.json
testing/specialpowers/moz.build
testing/specialpowers/schema.json
--- a/dom/ipc/tests/test_bug1086684.html
+++ b/dom/ipc/tests/test_bug1086684.html
@@ -16,17 +16,17 @@
 
     const childFrameURL =
       "http://mochi.test:8888/tests/dom/ipc/tests/file_bug1086684.html";
 
     function childFrameScript() {
       "use strict";
 
       let { MockFilePicker } =
-        ChromeUtils.import("chrome://specialpowers/content/MockFilePicker.jsm", {});
+        ChromeUtils.import("resource://specialpowers/MockFilePicker.jsm", {});
 
       function parentReady(message) {
         MockFilePicker.init(content);
         MockFilePicker.setFiles([message.data.file]);
         MockFilePicker.returnValue = MockFilePicker.returnOK;
 
         let input = content.document.getElementById("f");
         input.addEventListener("change", () => {
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -630,17 +630,17 @@ mozJSComponentLoader::ReuseGlobal(nsIURI
     if (spec.EqualsASCII("resource://gre/modules/jsdebugger.jsm")) {
         return false;
     }
 
     // Some SpecialPowers jsms call Cu.forcePermissiveCOWs(),
     // which sets a per-compartment flag that disables certain
     // security wrappers, so don't use the shared global for them
     // to avoid breaking tests.
-    if (FindInReadable(NS_LITERAL_CSTRING("chrome://specialpowers/"), spec)) {
+    if (FindInReadable(NS_LITERAL_CSTRING("resource://specialpowers/"), spec)) {
         return false;
     }
 
     return true;
 }
 
 JSObject*
 mozJSComponentLoader::GetSharedGlobal(JSContext* aCx)
rename from testing/specialpowers/bootstrap.js
rename to testing/specialpowers/api.js
--- a/testing/specialpowers/bootstrap.js
+++ b/testing/specialpowers/api.js
@@ -1,39 +1,30 @@
 /* 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/. */
 
+/* globals ExtensionAPI */
+
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-var spObserver;
-
-function startup(data, reason) {
-  let observer = {};
-  ChromeUtils.import("chrome://specialpowers/content/SpecialPowersObserver.jsm", observer);
+XPCOMUtils.defineLazyServiceGetter(this, "resProto",
+                                   "@mozilla.org/network/protocol;1?name=resource",
+                                   "nsISubstitutingProtocolHandler");
 
-  let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-  registrar.registerFactory(
-    observer.SpecialPowersObserver.prototype.classID,
-    "SpecialPowersObserver",
-    observer.SpecialPowersObserver.prototype.contractID,
-    observer.SpecialPowersObserverFactory
-  );
+this.specialpowers = class extends ExtensionAPI {
+  onStartup() {
+    let uri = Services.io.newURI("content/", null, this.extension.rootURI);
+    resProto.setSubstitutionWithFlags("specialpowers", uri,
+                                      resProto.ALLOW_CONTENT_ACCESS);
 
-  spObserver = new observer.SpecialPowersObserver();
-  spObserver.init();
-}
-
-function shutdown(data, reason) {
-  let observer = {};
-  ChromeUtils.import("chrome://specialpowers/content/SpecialPowersObserver.jsm", observer);
+    ChromeUtils.import("resource://specialpowers/SpecialPowersObserver.jsm");
+    this.observer = new SpecialPowersObserver();
+    this.observer.init();
+  }
 
-  let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-  registrar.unregisterFactory(
-    observer.SpecialPowersObserver.prototype.classID,
-    observer.SpecialPowersObserverFactory
-  );
-
-  spObserver.uninit();
-}
-
-function install(data, reason) {}
-function uninstall(data, reason) {}
+  onShutdown() {
+    this.observer.uninit();
+    this.observer = null;
+    resProto.setSubstitution("specialpowers", null);
+  }
+};
--- a/testing/specialpowers/content/SpecialPowersObserver.jsm
+++ b/testing/specialpowers/content/SpecialPowersObserver.jsm
@@ -6,42 +6,39 @@
 // 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
 // https://developer.mozilla.org/en/how_to_build_an_xpcom_component_in_javascript
 
 /* import-globals-from SpecialPowersObserverAPI.js */
 
-var EXPORTED_SYMBOLS = ["SpecialPowersObserver", "SpecialPowersObserverFactory"];
+var EXPORTED_SYMBOLS = ["SpecialPowersObserver"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 Cu.importGlobalProperties(["File"]);
 
-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";
+const CHILD_SCRIPT = "resource://specialpowers/specialpowers.js";
+const CHILD_SCRIPT_API = "resource://specialpowers/specialpowersAPI.js";
+const CHILD_LOGGER_SCRIPT = "resource://specialpowers/MozillaLogger.js";
 
 
 // Glue to add in the observer API to this object.  This allows us to share code with chrome tests
-Services.scriptloader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js");
+Services.scriptloader.loadSubScript("resource://specialpowers/SpecialPowersObserverAPI.js");
 
 /* XPCOM gunk */
 function SpecialPowersObserver() {
   this._isFrameScriptLoaded = false;
   this._messageManager = Services.mm;
 }
 
 
 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 = ChromeUtils.generateQI([Ci.nsIObserver]);
 
 SpecialPowersObserver.prototype.observe = function(aSubject, aTopic, aData) {
   switch (aTopic) {
     case "chrome-document-global-created":
       this._loadFrameScript();
       break;
 
@@ -284,17 +281,8 @@ SpecialPowersObserver.prototype.receiveM
         this._createdFiles = null;
       }
       break;
     default:
       return this._receiveMessage(aMessage);
   }
   return undefined;
 };
-
-var SpecialPowersObserverFactory = Object.freeze({
-  createInstance(outer, id) {
-    if (outer) { throw Cr.NS_ERROR_NO_AGGREGATION; }
-    return new SpecialPowersObserver();
-  },
-  loadFactory(lock) {},
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFactory])
-});
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -496,17 +496,17 @@ SpecialPowersObserverAPI.prototype = {
           // Pipe assertions back to parent process
           mm.sendAsyncMessage("SPChromeScriptAssert",
                               { id, name: scriptName, err, message,
                                 stack });
         };
         Object.defineProperty(sb, "assert", {
           get() {
             let scope = Cu.createObjectIn(sb);
-            Services.scriptloader.loadSubScript("chrome://specialpowers/content/Assert.jsm",
+            Services.scriptloader.loadSubScript("resource://specialpowers/Assert.jsm",
                                                 scope);
 
             let assert = new scope.Assert(reporter);
             delete sb.assert;
             return sb.assert = assert;
           },
           configurable: true
         });
--- a/testing/specialpowers/content/specialpowers.js
+++ b/testing/specialpowers/content/specialpowers.js
@@ -212,19 +212,19 @@ SpecialPowers.prototype.nestedFrameSetup
         });
       });
       mm.addMessageListener("SPPAddNestedMessageListener", function(msg) {
         self._addMessageListener(msg.json.name, function(aMsg) {
           mm.sendAsyncMessage(aMsg.name, aMsg.data);
           });
       });
 
-      mm.loadFrameScript("chrome://specialpowers/content/MozillaLogger.js", false);
-      mm.loadFrameScript("chrome://specialpowers/content/specialpowersAPI.js", false);
-      mm.loadFrameScript("chrome://specialpowers/content/specialpowers.js", false);
+      mm.loadFrameScript("resource://specialpowers/MozillaLogger.js", false);
+      mm.loadFrameScript("resource://specialpowers/specialpowersAPI.js", false);
+      mm.loadFrameScript("resource://specialpowers/specialpowers.js", false);
 
       let frameScript = "SpecialPowers.prototype.IsInNestedFrame=true;";
       mm.loadFrameScript("data:," + frameScript, false);
     }
   }, "remote-browser-shown");
 };
 
 SpecialPowers.prototype.isServiceWorkerRegistered = function() {
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -7,19 +7,19 @@
 
 "use strict";
 
 /* import-globals-from MozillaLogger.js */
 /* globals XPCNativeWrapper, content */
 
 var global = this;
 
-ChromeUtils.import("chrome://specialpowers/content/MockFilePicker.jsm");
-ChromeUtils.import("chrome://specialpowers/content/MockColorPicker.jsm");
-ChromeUtils.import("chrome://specialpowers/content/MockPermissionPrompt.jsm");
+ChromeUtils.import("resource://specialpowers/MockFilePicker.jsm");
+ChromeUtils.import("resource://specialpowers/MockColorPicker.jsm");
+ChromeUtils.import("resource://specialpowers/MockPermissionPrompt.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 ChromeUtils.import("resource://gre/modules/ServiceWorkerCleanUp.jsm");
 
 // We're loaded with "this" not set to the global in some cases, so we
deleted file mode 100644
--- a/testing/specialpowers/install.rdf
+++ /dev/null
@@ -1,28 +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@mozilla.org</em:id>
-    <em:version>2015.11.16</em:version>
-    <em:type>2</em:type>
-    <em:bootstrap>true</em:bootstrap>
-
-    <!-- Target Application this extension can install into, 
-         with minimum and maximum supported versions. -->
-    <em:targetApplication>
-      <Description>
-        <em:id>toolkit@mozilla.org</em:id>
-#expand        <em:minVersion>__MOZILLA_VERSION_U__</em:minVersion>
-               <!-- Set to * so toolkit/mozapps/update/chrome tests pass. -->
-               <em:maxVersion>*</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>
deleted file mode 100644
--- a/testing/specialpowers/jar.mn
+++ /dev/null
@@ -1,11 +0,0 @@
-specialpowers.jar:
-% content specialpowers %content/ contentaccessible=true
-  content/specialpowers.js (content/specialpowers.js)
-  content/specialpowersAPI.js (content/specialpowersAPI.js)
-  content/SpecialPowersObserverAPI.js (content/SpecialPowersObserverAPI.js)
-  content/SpecialPowersObserver.jsm (content/SpecialPowersObserver.jsm)
-  content/MozillaLogger.js (content/MozillaLogger.js)
-  content/MockFilePicker.jsm (content/MockFilePicker.jsm)
-  content/MockColorPicker.jsm (content/MockColorPicker.jsm)
-  content/MockPermissionPrompt.jsm (content/MockPermissionPrompt.jsm)
-  content/Assert.jsm (../modules/Assert.jsm)
new file mode 100644
--- /dev/null
+++ b/testing/specialpowers/manifest.json
@@ -0,0 +1,23 @@
+{
+  "manifest_version": 2,
+  "name": "Special Powers",
+  "version": "2018.06.27",
+
+  "applications": {
+    "gecko": {
+      "id": "special-powers@mozilla.org"
+    }
+  },
+  "permissions": [],
+
+  "experiment_apis": {
+    "specialpowers": {
+      "schema": "schema.json",
+      "parent": {
+        "scopes": ["addon_parent"],
+        "script": "api.js",
+        "events": ["startup"]
+      }
+    }
+  }
+}
--- a/testing/specialpowers/moz.build
+++ b/testing/specialpowers/moz.build
@@ -1,23 +1,31 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 XPI_NAME = 'specialpowers'
 
-JAR_MANIFESTS += ['jar.mn']
-
 USE_EXTENSION_MANIFEST = True
 NO_JS_MANIFEST = True
 
-FINAL_TARGET_PP_FILES += [
-    'install.rdf',
+FINAL_TARGET_FILES += [
+    'api.js',
+    'manifest.json',
+    'schema.json',
 ]
 
-FINAL_TARGET_FILES += [
-    'bootstrap.js',
+FINAL_TARGET_FILES.content += [
+    '../modules/Assert.jsm',
+    'content/MockColorPicker.jsm',
+    'content/MockFilePicker.jsm',
+    'content/MockPermissionPrompt.jsm',
+    'content/MozillaLogger.js',
+    'content/specialpowers.js',
+    'content/specialpowersAPI.js',
+    'content/SpecialPowersObserver.jsm',
+    'content/SpecialPowersObserverAPI.js',
 ]
 
 with Files("**"):
     BUG_COMPONENT = ("Testing", "Mochitest")
new file mode 100644
--- /dev/null
+++ b/testing/specialpowers/schema.json
@@ -0,0 +1,1 @@
+[]