Bug 1451463: Make Quitter a WebExtension experiment. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 03 Apr 2018 17:19:26 -0700
changeset 777458 bcfc87388774b5e8435ae4eb67338fa33981ca65
parent 777024 ca5d6727f7240140729ef36aa05a57239ab53c95
push id105214
push usermaglione.k@gmail.com
push dateWed, 04 Apr 2018 19:55:42 +0000
reviewersaswan
bugs1451463
milestone61.0a1
Bug 1451463: Make Quitter a WebExtension experiment. r?aswan MozReview-Commit-ID: IaEizP4i2tp
build/pgo/profileserver.py
toolkit/components/extensions/WebExtensionPolicy.cpp
tools/quitter/background.js
tools/quitter/bootstrap.js
tools/quitter/chrome.manifest
tools/quitter/contentscript.js
tools/quitter/install.rdf
tools/quitter/jar.mn
tools/quitter/manifest.json
tools/quitter/moz.build
tools/quitter/parent.js
tools/quitter/quitter@mozilla.org.xpi
tools/quitter/schema.json
--- a/build/pgo/profileserver.py
+++ b/build/pgo/profileserver.py
@@ -78,17 +78,17 @@ if __name__ == '__main__':
                 if os.path.exists(vcdir):
                     env['PATH'] = '%s;%s' % (vcdir, env['PATH'])
                     break
 
         # Run Firefox a first time to initialize its profile
         runner = FirefoxRunner(profile=profile,
                                binary=build.get_binary_path(
                                    where="staged-package"),
-                               cmdargs=['javascript:Quitter.quit()'],
+                               cmdargs=['data:text/html,<script>Quitter.quit()</script>'],
                                env=env)
         runner.start()
         runner.wait()
 
         jarlog = os.getenv("JARLOG_FILE")
         if jarlog:
             env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog)
             print "jarlog: %s" % env["MOZ_JAR_LOG_FILE"]
--- a/toolkit/components/extensions/WebExtensionPolicy.cpp
+++ b/toolkit/components/extensions/WebExtensionPolicy.cpp
@@ -483,17 +483,18 @@ WebExtensionContentScript::Matches(const
   if (!mMatchAboutBlank && aDoc.URL().InheritsPrincipal()) {
     return false;
   }
 
   // Top-level about:blank is a special case. We treat it as a match if
   // matchAboutBlank is true and it has the null principal. In all other
   // cases, we test the URL of the principal that it inherits.
   if (mMatchAboutBlank && aDoc.IsTopLevel() &&
-      aDoc.URL().Spec().EqualsLiteral("about:blank") &&
+      (aDoc.URL().Spec().EqualsLiteral("about:blank") ||
+       aDoc.URL().Scheme() == nsGkAtoms::data) &&
       aDoc.Principal() && aDoc.Principal()->GetIsNullPrincipal()) {
     return true;
   }
 
   if (mExtension->IsRestrictedDoc(aDoc)) {
     return false;
   }
 
new file mode 100644
--- /dev/null
+++ b/tools/quitter/background.js
@@ -0,0 +1,9 @@
+"use strict";
+
+/* eslint-env webextensions */
+
+browser.runtime.onMessage.addListener(msg => {
+  if (msg === "quit") {
+    browser.quitter.quit();
+  }
+});
deleted file mode 100644
--- a/tools/quitter/bootstrap.js
+++ /dev/null
@@ -1,42 +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/. */
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-const CHILD_SCRIPT = "chrome://quitter/content/contentscript.js";
-
-const quitterObserver = {
-  init() {
-    Services.mm.addMessageListener("Quitter.Quit", this);
-    Services.mm.loadFrameScript(CHILD_SCRIPT, true);
-  },
-
-  uninit() {
-    Services.mm.removeMessageListener("Quitter.Quit", this);
-    Services.mm.removeDelayedFrameScript(CHILD_SCRIPT, true);
-  },
-
-  /**
-   * messageManager callback function
-   * This will get requests from our API in the window and process them in chrome for it
-   **/
-  receiveMessage(aMessage) {
-    switch (aMessage.name) {
-      case "Quitter.Quit":
-        Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
-        break;
-    }
-  }
-};
-
-function startup(data, reason) {
-  quitterObserver.init();
-}
-
-function shutdown(data, reason) {
-  quitterObserver.uninit();
-}
-
-function install(data, reason) {}
-function uninstall(data, reason) {}
deleted file mode 100644
--- a/tools/quitter/chrome.manifest
+++ /dev/null
@@ -1,1 +0,0 @@
-content quitter chrome/quitter/content/
--- a/tools/quitter/contentscript.js
+++ b/tools/quitter/contentscript.js
@@ -1,35 +1,14 @@
 /* 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/. */
-
-/* eslint-env mozilla/frame-script */
+"use strict";
 
-function Quitter() {
-}
+/* eslint-env webextensions */
+/* globals cloneInto */
 
-Quitter.prototype = {
+const Quitter = {
   toString() { return "[Quitter]"; },
-  quit() { sendSyncMessage("Quitter.Quit", {}); }
+  quit() { browser.runtime.sendMessage("quit"); },
 };
 
-// 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 QuitterManager() {
-  addEventListener("DOMWindowCreated", this, false);
-}
-
-QuitterManager.prototype = {
-  handleEvent: function handleEvent(aEvent) {
-    var quitter = new Quitter(window);
-    var window = aEvent.target.defaultView;
-    window.wrappedJSObject.Quitter = Cu.cloneInto({
-      toString: quitter.toString.bind(quitter),
-      quit: quitter.quit.bind(quitter)
-    }, window, {cloneFunctions: true});
-  }
-};
-
-var quittermanager = new QuitterManager();
+window.wrappedJSObject.Quitter = cloneInto(Quitter, window, {cloneFunctions: true});
deleted file mode 100644
--- a/tools/quitter/jar.mn
+++ /dev/null
@@ -1,3 +0,0 @@
-quitter.jar:
-% content quitter %content/
-  content/contentscript.js (contentscript.js)
rename from tools/quitter/install.rdf
rename to tools/quitter/manifest.json
--- a/tools/quitter/install.rdf
+++ b/tools/quitter/manifest.json
@@ -1,36 +1,34 @@
-<?xml version="1.0"?>
+{
+  "manifest_version": 2,
 
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  "applications": {
+    "gecko": {"id": "quitter@mozilla.org"}
+  },
 
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>quitter@mozilla.org</em:id>
-    <em:version>2018.03.19</em:version>
-    <em:type>2</em:type>
-    <em:bootstrap>true</em:bootstrap>
+  "name": "Quitter",
+  "description": "Quit",
+  "version": "2018.04.03",
+  "author": "Mozilla",
+
+  "background": {
+    "scripts": ["background.js"]
+  },
 
-    <!-- Target Application this extension can install into,
-         with minimum and maximum supported versions. -->
-    <em:targetApplication>
-      <Description>
-        <!-- Firefox -->
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>45</em:minVersion>
-        <em:maxVersion>*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-    <em:targetApplication>
-      <Description>
-        <!-- Fennec -->
-        <em:id>{aa3c5121-dab2-40e2-81ca-7ea25febc110}</em:id>
-        <em:minVersion>45</em:minVersion>
-        <em:maxVersion>*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
+  "content_scripts": [{
+    "js": ["contentscript.js"],
+    "run_at": "document_start",
+    "match_about_blank": true,
+    "matches": ["<all_urls>"]
+  }],
 
-    <!-- Front End MetaData -->
-    <em:name>Quitter</em:name>
-    <em:description>Adds a quit method that content pages can use to quit the application.</em:description>
-    <em:creator>Mozilla</em:creator>
-  </Description>
-</RDF>
+  "experiment_apis": {
+    "quitter": {
+      "schema": "schema.json",
+      "parent": {
+        "scopes": ["addon_parent"],
+        "script": "parent.js",
+        "paths": [["quitter", "quit"]]
+      }
+    }
+  }
+}
--- a/tools/quitter/moz.build
+++ b/tools/quitter/moz.build
@@ -1,18 +1,18 @@
 # -*- 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 = 'quitter'
 
-JAR_MANIFESTS += ['jar.mn']
-
 USE_EXTENSION_MANIFEST = True
 NO_JS_MANIFEST = True
 
 FINAL_TARGET_FILES += [
-    'bootstrap.js',
-    'chrome.manifest',
-    'install.rdf',
+    'background.js',
+    'contentscript.js',
+    'manifest.json',
+    'parent.js',
+    'schema.json',
 ]
new file mode 100644
--- /dev/null
+++ b/tools/quitter/parent.js
@@ -0,0 +1,17 @@
+"use strict";
+
+/* globals ExtensionAPI */
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+this.quitter = class extends ExtensionAPI {
+  getAPI(context) {
+    return {
+      quitter: {
+        quit() {
+          Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
+        },
+      },
+    };
+  }
+};
index f4e7d81117c12ff6c00d54cf191b398765e68ab5..0ac4fad933876c19458acdb8acfd1b9bae208d75
GIT binary patch
literal 1743
zc$^FHW@Zs#W?<l8i0N$hx#@CxSrr2V!z>`?1>&T{<m~jK{L;J>y{ux>o<Oc<0|A%+
z-$lIlg=E+?EK$$kUs$TmUFy7fc9h1wy@I86ZI#A7r@dB8`;oYgIYU~dcH@oKC(Ycv
zUrdFbYION>8!XwOp*nw)#Q7(S?|5#Vf8zV&ie%knud8c>+qC~NOq{>txWI+I#<N$O
z$Cbq8Uf^5*YF&x;nxp>%;Ewd^ZT6A8S2op-k%8d`5DNeunVg?jlA2dioLrPyPy%$P
z>jX#t!v;L9@BfPW+vZ;O5Oi1b^O)RbW@w_vQRoqz&z&`Sl7+Ux+x?HrE?Y!yv)`Y-
zd&Yy(d}T8`R_BT@qKWUEnO7bSshgCzf&D$F&%(|Rw-qCQ#z$Y5dL44@TFQ)sOx~Ry
z!7?K6uB<(j#LfHo_WajpsyhALEzYmVd6IDYNXWv?d&CbMi%ZMSzF6^@)6M$Fq^(mQ
zaLn46p7*|ck!7{Ed|7LT*rPBFpDrE$i5Ff=olB2Y+a9=P?PKX8_L7iG=BK-^?bax{
zfA8wPE2S+fk0w66@%`%=jsq2*)1Ic-Jec8Fw?Qy=yL4}%i-O-l#rpjQ@;`Z&uMCKv
z#P1?mBd)n(g3Rr<5S8$?8g6?R2i^<*Ss`J0a@O3^sqaI?OKt~!-BKyHZ{50o|8Mu|
zZPh$y94ym*&&Klb-^lL|CcH42ms*bq>+5~ZJ{c-3xq85G&SQckh}^`y%(T>EP%!7`
z`39W!J8U4Z=ef4l{KYFo_&5}g@E1IY3B7jBaBcK)vvX340sr=9ub=#7LVJ4J@y(y_
z=a?lir0@IE@yY%8#R~N}v)$WH^0XxMGN}}(n5^cs%`E-;Q^Ut!{^MMpMSbs^{~KR(
zdj8ncM`iAfBL^33elt0B(b<Ic?xMaY&KVy+GRyJJHvaQ>zpcD&XT-{R-Y)G~bG}f`
zLBT6uMQV%w&YF0)_{Cq@`>}3?5tB9F2Ut%je`Hms*&cbIMlx?^|4GjSGE2W}@g8MS
z{KU63C?uWJeSUzP?hb8FL$zA}?0t_#*G$#C^|5!cti|kqyjHUw@f_57tDhU*FkN*s
zBge}6DO03!(ybg+W?OCO`4PbEaKBnT(nNnpnMd)}g(4d+NFFIJyrDnymQa5TU#OYs
zpL6H0++jcjtUy<@k4av{kHf$KH3J4NCy*{kECQxsV6eveJDxsdz_a&zc*|U~pBe8@
zl?w!ZSk_^maLqtF)_QUX%gy@j(nc4{JwJV#G+m@qFycg{rkK}ENfWzyS?4#@aj=yc
z>Xb*%kX#xj-lZ#dwDQ`zw@RLo0!2P4g?T>C8Mi9@<ZjALcy~_ewf1(`sozf>-MCLx
zy@}<2LhV@|3yV4RbLMd^a6FlrnLJ_5N;bXb0HM}}5+CoG$#?RH_I={Ktg2(``RdDx
zNK4s@-EVdso_*B!O#GYT^-(^T|IYvA^=skP)iQAipC0LG_VHP{@>&Yehg*S|8;FaO
zGg5OCAqlA0kgq|3$F<zgafWSUxFRqy97=H2U^cvWS6*a^_wE0mqI8$+X>rlqwEO%;
ztMy?k&k4<_4LW^#n^WImM@gUUE3#u{#imRw?mbaon`RbX)G()O{-X@xzK5mNsdfe1
z`*<e{@&|Y`GTAfZD&kZaAV8sENh1S#fyc$50G4EAkYH#C^iErO`Z6Orjchz-;e>4b
zQY=LkvJDJ3EYGY3nVfeCOvCudHehB+WE%vT&@w2B@%(jd>p{k%(a6SQCQM}GvzU>R
zDN5MfoS?S~WMqM+K8S|#k&VVo3CKo=u%M(16vG)8?OFjc6paq>W@Q7ZVFf}^U_WF5
F@c;(qr4;}G
new file mode 100644
--- /dev/null
+++ b/tools/quitter/schema.json
@@ -0,0 +1,13 @@
+[
+  {
+    "namespace": "quitter",
+    "functions": [
+      {
+        "name": "quit",
+        "type": "function",
+        "async": true,
+        "parameters": []
+      }
+    ]
+  }
+]