Bug 1446676: Part 1a - Add stub bootstrap.js script to load overlays from legacy non-restartless add-ons. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Fri, 16 Mar 2018 21:27:49 -0700
changeset 769181 3b302b24bd91ddb622e993f54e9eb903abcb4483
parent 769180 9f91a3b882a06915d61a19f8aa80eb19eb988b53
child 769182 eef52b4947f3b601a708115c6b3256fb6865d52f
push id103061
push usermaglione.k@gmail.com
push dateSun, 18 Mar 2018 22:05:48 +0000
reviewersaswan
bugs1446676
milestone61.0a1
Bug 1446676: Part 1a - Add stub bootstrap.js script to load overlays from legacy non-restartless add-ons. r?aswan Several of our test automation add-ons are non-restartless, but only rely on loading a single overlay into browser windows. This stub bootstrap.js script allows us to run those extensions as bootstrapped extensions with the same behavior as before, and with no other changes. MozReview-Commit-ID: 1RNbUw95cbE
testing/talos/talos/bootstrap.js
new file mode 100644
--- /dev/null
+++ b/testing/talos/talos/bootstrap.js
@@ -0,0 +1,79 @@
+"use strict";
+
+// PLEASE NOTE:
+//
+// The canonical version of this file lives in testing/talos/talos, and
+// is duplicated in a number of test add-ons in directories below it.
+// Please do not update one withput updating all.
+
+// Reads the chrome.manifest from a legacy non-restartless extension and loads
+// its overlays into the appropriate top-level windows.
+
+ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+Cu.importGlobalProperties(["TextDecoder"]);
+
+class DefaultMap extends Map {
+  constructor(defaultConstructor = undefined, init = undefined) {
+    super(init);
+    if (defaultConstructor) {
+      this.defaultConstructor = defaultConstructor;
+    }
+  }
+
+  get(key) {
+    let value = super.get(key);
+    if (value === undefined && !this.has(key)) {
+      value = this.defaultConstructor(key);
+      this.set(key, value);
+    }
+    return value;
+  }
+}
+
+const windowTracker = {
+  init() {
+    Services.ww.registerNotification(this);
+  },
+
+  overlays: new DefaultMap(() => new Set()),
+
+  async observe(window, topic, data) {
+    if (topic === "domwindowopened") {
+      await new Promise(resolve =>
+        window.addEventListener("DOMWindowCreated", resolve, {once: true}));
+
+      let {document} = window;
+      let {documentURI} = document;
+
+      if (this.overlays.has(documentURI)) {
+        for (let overlay of this.overlays.get(documentURI)) {
+          document.loadOverlay(overlay, null);
+        }
+      }
+    }
+  },
+};
+
+function readSync(uri) {
+  let channel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true});
+  let buffer = NetUtil.readInputStream(channel.open2());
+  return new TextDecoder().decode(buffer);
+}
+
+function startup(data, reason) {
+  windowTracker.init();
+
+  for (let line of readSync(data.resourceURI.resolve("chrome.manifest")).split("\n")) {
+    let [directive, ...args] = line.trim().split(/\s+/);
+    if (directive === "overlay") {
+      let [url, overlay] = args;
+      windowTracker.overlays.get(url).add(overlay);
+    }
+  }
+}
+
+function shutdown(data, reason) {}
+function install(data, reason) {}
+function uninstall(data, reason) {}