Merge mozilla-central to mozilla-inbound. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 22 Oct 2016 23:03:08 +0200
changeset 319055 c20146f38762bfc9849ec976ab39b3e63ad5f97e
parent 319054 8613eb3daab21899a5044030c5e224eaaf851ad6 (current diff)
parent 318962 60dd82380d43a2b681f50842238f829204486290 (diff)
child 319056 795b9e63823c3750fd9c1a573cdbb0961c994bad
push id30858
push userryanvm@gmail.com
push dateSun, 23 Oct 2016 17:17:41 +0000
treeherdermozilla-central@a9a41b69f3f9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone52.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
Merge mozilla-central to mozilla-inbound. r=merge a=merge
toolkit/components/extensions/test/mochitest/file_with_about_blank.html
toolkit/components/extensions/test/mochitest/test_ext_contentscript_about_blank.html
--- a/toolkit/components/extensions/ExtensionContent.jsm
+++ b/toolkit/components/extensions/ExtensionContent.jsm
@@ -90,17 +90,16 @@ var apiManager = new class extends Schem
 // Represents a content script.
 function Script(extension, options, deferred = PromiseUtils.defer()) {
   this.extension = extension;
   this.options = options;
   this.run_at = this.options.run_at;
   this.js = this.options.js || [];
   this.css = this.options.css || [];
   this.remove_css = this.options.remove_css;
-  this.match_about_blank = this.options.match_about_blank;
 
   this.deferred = deferred;
 
   this.matches_ = new MatchPattern(this.options.matches);
   this.exclude_matches_ = new MatchPattern(this.options.exclude_matches || null);
   // TODO: MatchPattern should pre-mangle host-only patterns so that we
   // don't need to call a separate match function.
   this.matches_host_ = new MatchPattern(this.options.matchesHost || null);
@@ -130,22 +129,16 @@ Script.prototype = {
     let uri = window.document.documentURIObject;
 
     // If mozAddonManager is present on this page, don't allow
     // content scripts.
     if (window.navigator.mozAddonManager !== undefined) {
       return false;
     }
 
-    if (this.match_about_blank && ["about:blank", "about:srcdoc"].includes(uri.spec)) {
-      // When matching about:blank/srcdoc documents, the checks below
-      // need to be performed against the "owner" document's URI.
-      uri = window.document.nodePrincipal.URI;
-    }
-
     if (!(this.matches_.matches(uri) || this.matches_host_.matchesIgnoringPath(uri))) {
       return false;
     }
 
     if (this.exclude_matches_.matches(uri)) {
       return false;
     }
 
@@ -162,16 +155,18 @@ Script.prototype = {
     if (this.options.frame_id != null) {
       if (WebNavigationFrames.getFrameId(window) != this.options.frame_id) {
         return false;
       }
     } else if (!this.options.all_frames && window.top != window) {
       return false;
     }
 
+    // TODO: match_about_blank.
+
     return true;
   },
 
   cleanup(window) {
     if (!this.remove_css) {
       let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
 
@@ -416,60 +411,44 @@ DocumentManager = {
 
   // Map[windowId -> Map[extensionId -> ExtensionContext]]
   contentScriptWindows: new Map(),
 
   // Map[windowId -> ExtensionContext]
   extensionPageWindows: new Map(),
 
   init() {
-    Services.obs.addObserver(this, "content-document-global-created", false);
     Services.obs.addObserver(this, "document-element-inserted", false);
     Services.obs.addObserver(this, "inner-window-destroyed", false);
   },
 
   uninit() {
-    Services.obs.removeObserver(this, "content-document-global-created");
     Services.obs.removeObserver(this, "document-element-inserted");
     Services.obs.removeObserver(this, "inner-window-destroyed");
   },
 
   getWindowState(contentWindow) {
     let readyState = contentWindow.document.readyState;
     if (readyState == "complete") {
       return "document_idle";
     }
     if (readyState == "interactive") {
       return "document_end";
     }
     return "document_start";
   },
 
   observe: function(subject, topic, data) {
-    // For some types of documents (about:blank), we only see the first
-    // notification, for others (data: URIs) we only observe the second.
-    if (topic == "content-document-global-created" || topic == "document-element-inserted") {
+    if (topic == "document-element-inserted") {
       let document = subject;
       let window = document && document.defaultView;
-
-      if (topic == "content-document-global-created") {
-        window = subject;
-        document = window && window.document;
-      }
-
       if (!document || !document.location || !window) {
         return;
       }
 
-      // Make sure we always load exactly once (notice != used as logical XOR),
-      // usually on document-element-inserted, except for about:blank documents.
-      if ((topic == "content-document-global-created") != (window.location.href == "about:blank")) {
-        return;
-      }
-
       // Make sure we only load into frames that ExtensionContent.init
       // was called on (i.e., not frames for social or sidebars).
       let mm = getWindowMessageManager(window);
       if (!mm || !ExtensionContent.globals.has(mm)) {
         return;
       }
 
       // Enable the content script APIs should be available in subframes' window
@@ -479,18 +458,17 @@ DocumentManager = {
 
       if (ExtensionManagement.getAPILevelForWindow(window, extensionId) == CONTENTSCRIPT_PRIVILEGES) {
         let extension = ExtensionManager.get(extensionId);
         if (extension) {
           DocumentManager.getExtensionPageContext(extension, window);
         }
       }
 
-      this.trigger(window);
-
+      this.trigger("document_start", window);
       /* eslint-disable mozilla/balanced-listeners */
       window.addEventListener("DOMContentLoaded", this, true);
       window.addEventListener("load", this, true);
       /* eslint-enable mozilla/balanced-listeners */
     } else if (topic == "inner-window-destroyed") {
       let windowId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
 
       MessageChannel.abortResponses({innerWindowID: windowId});
@@ -522,19 +500,19 @@ DocumentManager = {
       // listening on.
       return;
     }
     window.removeEventListener(event.type, this, true);
 
     // Need to check if we're still on the right page? Greasemonkey does this.
 
     if (event.type == "DOMContentLoaded") {
-      this.trigger(window);
+      this.trigger("document_end", window);
     } else if (event.type == "load") {
-      this.trigger(window);
+      this.trigger("document_idle", window);
     }
   },
 
   // Used to executeScript, insertCSS and removeCSS.
   executeScript(global, extensionId, options) {
     let extension = ExtensionManager.get(extensionId);
 
     let executeInWin = (window) => {
@@ -660,17 +638,17 @@ DocumentManager = {
     MessageChannel.abortResponses({extensionId});
 
     this.extensionCount--;
     if (this.extensionCount == 0) {
       this.uninit();
     }
   },
 
-  trigger(window) {
+  trigger(when, window) {
     let state = this.getWindowState(window);
 
     if (state == "document_start") {
       for (let extension of ExtensionManager.extensions.values()) {
         for (let script of extension.scripts) {
           if (script.matches(window)) {
             let context = this.getContentScriptContext(extension, window);
             context.addScript(script);
deleted file mode 100644
--- a/toolkit/components/extensions/test/mochitest/file_with_about_blank.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <meta charset="utf-8">
-</head>
-<body>
-  <iframe id="a_b" src="about:blank"></iframe>
-  <iframe srcdoc="galactica actual" src="adama"></iframe>
-</body>
-</html>
--- a/toolkit/components/extensions/test/mochitest/mochitest.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest.ini
@@ -13,17 +13,16 @@ support-files =
   file_webNavigation_frameClientRedirect.html
   file_webNavigation_frameRedirect.html
   file_webNavigation_manualSubframe.html
   file_webNavigation_manualSubframe_page1.html
   file_webNavigation_manualSubframe_page2.html
   file_WebNavigation_page1.html
   file_WebNavigation_page2.html
   file_WebNavigation_page3.html
-  file_with_about_blank.html
   file_image_good.png
   file_image_bad.png
   file_image_redirect.png
   file_style_good.css
   file_style_bad.css
   file_style_redirect.css
   file_script_good.js
   file_script_bad.js
@@ -46,17 +45,16 @@ skip-if = os == 'android' # Android does
 [test_ext_content_security_policy.html]
 [test_ext_contentscript.html]
 [test_ext_contentscript_api_injection.html]
 [test_ext_contentscript_context.html]
 [test_ext_contentscript_create_iframe.html]
 [test_ext_contentscript_devtools_metadata.html]
 [test_ext_contentscript_exporthelpers.html]
 [test_ext_contentscript_css.html]
-[test_ext_contentscript_about_blank.html]
 [test_ext_contentscript_teardown.html]
 skip-if = (os == 'android') # Android does not support tabs API. Bug 1260250
 [test_ext_exclude_include_globs.html]
 [test_ext_i18n_css.html]
 [test_ext_generate.html]
 [test_ext_notifications.html]
 [test_ext_permission_xhr.html]
 [test_ext_runtime_connect.html]
deleted file mode 100644
--- a/toolkit/components/extensions/test/mochitest/test_ext_contentscript_about_blank.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>Test content script match_about_blank option</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-
-<script type="text/javascript">
-"use strict";
-
-add_task(function* test_contentscript_about_blank() {
-  const manifest = {
-    content_scripts: [
-      {
-        match_about_blank: true,
-        matches: ["http://mochi.test/*/file_with_about_blank.html", "http://example.com/*"],
-        all_frames: true,
-        css: ["all.css"],
-        js: ["all.js"],
-      }, {
-        matches: ["http://mochi.test/*/file_with_about_blank.html"],
-        css: ["mochi_without.css"],
-        js: ["mochi_without.js"],
-        all_frames: true,
-      }, {
-        match_about_blank: true,
-        matches: ["http://mochi.test/*/file_with_about_blank.html"],
-        css: ["mochi_with.css"],
-        js: ["mochi_with.js"],
-        all_frames: true,
-      },
-    ],
-  };
-
-  const files = {
-    "all.js": function() {
-      browser.runtime.sendMessage("all");
-    },
-    "all.css": `
-      body { color: red; }
-    `,
-    "mochi_without.js": function() {
-      browser.runtime.sendMessage("mochi_without");
-    },
-    "mochi_without.css": `
-      body { background: yellow; }
-    `,
-    "mochi_with.js": function() {
-      browser.runtime.sendMessage("mochi_with");
-    },
-    "mochi_with.css": `
-      body { text-align: right; }
-    `,
-  };
-
-  function background() {
-    browser.runtime.onMessage.addListener((script, {url}) => {
-      const kind = url.startsWith("about:") ? url : "top";
-      browser.test.sendMessage("script", [script, kind, url]);
-      browser.test.sendMessage(`${script}:${kind}`);
-    });
-  }
-
-  const PATH = "tests/toolkit/components/extensions/test/mochitest/file_with_about_blank.html";
-  const extension = ExtensionTestUtils.loadExtension({manifest, files, background});
-  yield extension.startup();
-
-  let count = 0;
-  extension.onMessage("script", script => {
-    info(`script ran: ${script}`);
-    count++;
-  });
-
-  let win = window.open("http://example.com/" + PATH);
-  yield Promise.all([
-    extension.awaitMessage("all:top"),
-    extension.awaitMessage("all:about:blank"),
-    extension.awaitMessage("all:about:srcdoc"),
-  ]);
-  is(count, 3, "exactly 3 scripts ran");
-  win.close();
-
-  win = window.open("http://mochi.test:8888/" + PATH);
-  yield Promise.all([
-    extension.awaitMessage("all:top"),
-    extension.awaitMessage("all:about:blank"),
-    extension.awaitMessage("all:about:srcdoc"),
-    extension.awaitMessage("mochi_without:top"),
-    extension.awaitMessage("mochi_with:top"),
-    extension.awaitMessage("mochi_with:about:blank"),
-    extension.awaitMessage("mochi_with:about:srcdoc"),
-  ]);
-
-  let style = win.getComputedStyle(win.document.body);
-  is(style.color, "rgb(255, 0, 0)", "top window text color is red");
-  is(style.backgroundColor, "rgb(255, 255, 0)", "top window background is yellow");
-  is(style.textAlign, "right", "top window text is right-aligned");
-
-  let a_b = win.document.getElementById("a_b");
-  style = a_b.contentWindow.getComputedStyle(a_b.contentDocument.body);
-  is(style.color, "rgb(255, 0, 0)", "about:blank iframe text color is red");
-  is(style.backgroundColor, "transparent", "about:blank iframe background is transparent");
-  is(style.textAlign, "right", "about:blank text is right-aligned");
-
-  is(count, 10, "exactly 7 more scripts ran");
-  win.close();
-
-  yield extension.unload();
-});
-</script>
-
-</body>
-</html>