Bug 1275116 - Fix {document|target}UrlPatterns by passing in the correct arguments to SingleMatchPattern.match. r=kmag
authorMatthew Wein <mwein@mozilla.com>
Thu, 14 Jul 2016 14:41:03 -0700
changeset 348757 39ebdb2e59f25fecf13f2ca39ea74c3e73127a56
parent 348756 b6ebadfc57ba4755498651503c6db48d32489c16
child 348758 ee4f41614adc4297e1132511b32045fc9d2ce589
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1275116
milestone50.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 1275116 - Fix {document|target}UrlPatterns by passing in the correct arguments to SingleMatchPattern.match. r=kmag MozReview-Commit-ID: LLNu7jNfUZq G: changed browser/components/extensions/test/browser/head.js
browser/components/extensions/ext-contextMenus.js
browser/components/extensions/test/browser/browser.ini
browser/components/extensions/test/browser/browser_ext_contextMenus_urlPatterns.js
browser/components/extensions/test/browser/head.js
--- a/browser/components/extensions/ext-contextMenus.js
+++ b/browser/components/extensions/ext-contextMenus.js
@@ -435,25 +435,32 @@ MenuItem.prototype = {
 
   enabledForContext(contextData) {
     let contexts = getContexts(contextData);
     if (!this.contexts.some(n => contexts.has(n))) {
       return false;
     }
 
     let docPattern = this.documentUrlMatchPattern;
-    if (docPattern && !docPattern.matches(contextData.pageUrl)) {
+    let pageURI = Services.io.newURI(contextData.pageUrl, null, null);
+    if (docPattern && !docPattern.matches(pageURI)) {
       return false;
     }
 
-    let isMedia = contextData.onImage || contextData.onAudio || contextData.onVideo;
     let targetPattern = this.targetUrlMatchPattern;
-    if (isMedia && targetPattern && !targetPattern.matches(contextData.srcURL)) {
-      // TODO: double check if mediaURL is always set when we need it
-      return false;
+    if (targetPattern) {
+      let isMedia = contextData.onImage || contextData.onAudio || contextData.onVideo;
+      if (!isMedia) {
+        return false;
+      }
+      let srcURI = Services.io.newURI(contextData.srcUrl, null, null);
+      if (!targetPattern.matches(srcURI)) {
+        // TODO: double check if mediaURL is always set when we need it
+        return false;
+      }
     }
 
     return true;
   },
 };
 
 var gExtensionCount = 0;
 /* eslint-disable mozilla/balanced-listeners */
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -27,16 +27,17 @@ support-files =
 [browser_ext_commands_getAll.js]
 [browser_ext_commands_onCommand.js]
 [browser_ext_contentscript_connect.js]
 [browser_ext_contextMenus.js]
 [browser_ext_contextMenus_checkboxes.js]
 [browser_ext_contextMenus_icons.js]
 [browser_ext_contextMenus_radioGroups.js]
 [browser_ext_contextMenus_uninstall.js]
+[browser_ext_contextMenus_urlPatterns.js]
 [browser_ext_currentWindow.js]
 [browser_ext_getViews.js]
 [browser_ext_history.js]
 [browser_ext_incognito_popup.js]
 [browser_ext_lastError.js]
 [browser_ext_optionsPage_privileges.js]
 [browser_ext_pageAction_context.js]
 [browser_ext_pageAction_popup.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus_urlPatterns.js
@@ -0,0 +1,186 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(function* () {
+  let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
+    "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["contextMenus"],
+    },
+
+    background: function() {
+      // Test menu items using targetUrlPatterns.
+      browser.contextMenus.create({
+        title: "targetUrlPatterns-patternMatches-contextAll",
+        targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "targetUrlPatterns-patternMatches-contextImage",
+        targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
+        contexts: ["image"],
+      });
+
+      browser.contextMenus.create({
+        title: "targetUrlPatterns-patternDoesNotMatch-contextAll",
+        targetUrlPatterns: ["*://*/does-not-match"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "targetUrlPatterns-patternDoesNotMatch-contextImage",
+        targetUrlPatterns: ["*://*/does-not-match"],
+        contexts: ["image"],
+      });
+
+      // Test menu items using documentUrlPatterns.
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternMatches-contextAll",
+        documentUrlPatterns: ["*://*/*context.html"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternMatches-contextImage",
+        documentUrlPatterns: ["*://*/*context.html", "http://*/url-that-does-not-match"],
+        contexts: ["image"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternDoesNotMatch-contextAll",
+        documentUrlPatterns: ["*://*/does-not-match"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternDoesNotMatch-contextImage",
+        documentUrlPatterns: ["*://*/does-not-match"],
+        contexts: ["image"],
+      });
+
+      // Test menu items using both targetUrlPatterns and documentUrlPatterns.
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextAll",
+        documentUrlPatterns: ["*://*/*context.html"],
+        targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextAll",
+        documentUrlPatterns: ["*://does-not-match"],
+        targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextAll",
+        documentUrlPatterns: ["*://*/*context.html"],
+        targetUrlPatterns: ["*://does-not-match"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextAll",
+        documentUrlPatterns: ["*://does-not-match"],
+        targetUrlPatterns: ["*://does-not-match"],
+        contexts: ["all"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextImage",
+        documentUrlPatterns: ["*://*/*context.html"],
+        targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
+        contexts: ["image"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextImage",
+        documentUrlPatterns: ["*://does-not-match"],
+        targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
+        contexts: ["image"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextImage",
+        documentUrlPatterns: ["*://*/*context.html"],
+        targetUrlPatterns: ["*://does-not-match"],
+        contexts: ["image"],
+      });
+
+      browser.contextMenus.create({
+        title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextImage",
+        documentUrlPatterns: ["*://does-not-match"],
+        targetUrlPatterns: ["*://does-not-match"],
+        contexts: ["image"],
+      });
+
+      browser.test.notifyPass("contextmenus-urlPatterns");
+    },
+  });
+
+  function* confirmContextMenuItems(menu, expected) {
+    for (let [label, shouldShow] of expected) {
+      let items = menu.getElementsByAttribute("label", label);
+      if (shouldShow) {
+        is(items.length, 1, `The menu item for label ${label} was correctly shown`);
+      } else {
+        is(items.length, 0, `The menu item for label ${label} was correctly not shown`);
+      }
+    }
+  }
+
+  yield extension.startup();
+  yield extension.awaitFinish("contextmenus-urlPatterns");
+
+  let extensionContextMenu = yield openExtensionContextMenu("#img1");
+  let expected = [
+    ["targetUrlPatterns-patternMatches-contextAll", true],
+    ["targetUrlPatterns-patternMatches-contextImage", true],
+    ["targetUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["targetUrlPatterns-patternDoesNotMatch-contextImage", false],
+    ["documentUrlPatterns-patternMatches-contextAll", true],
+    ["documentUrlPatterns-patternMatches-contextImage", true],
+    ["documentUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["documentUrlPatterns-patternDoesNotMatch-contextImage", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextAll", true],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextAll", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextImage", true],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextImage", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
+  ];
+  yield confirmContextMenuItems(extensionContextMenu, expected);
+  yield closeContextMenu();
+
+  let contextMenu = yield openContextMenu("body");
+  expected = [
+    ["targetUrlPatterns-patternMatches-contextAll", false],
+    ["targetUrlPatterns-patternMatches-contextImage", false],
+    ["targetUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["targetUrlPatterns-patternDoesNotMatch-contextImage", false],
+    ["documentUrlPatterns-patternMatches-contextAll", true],
+    ["documentUrlPatterns-patternMatches-contextImage", false],
+    ["documentUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["documentUrlPatterns-patternDoesNotMatch-contextImage", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextAll", false],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextAll", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextImage", false],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextImage", false],
+    ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
+    ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
+  ];
+  yield confirmContextMenuItems(contextMenu, expected);
+  yield closeContextMenu();
+
+  yield extension.unload();
+  yield BrowserTestUtils.removeTab(tab1);
+});
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -119,33 +119,33 @@ function closeBrowserAction(extension, w
   let group = getBrowserActionWidget(extension);
 
   let node = win.document.getElementById(group.viewId);
   CustomizableUI.hidePanelForNode(node);
 
   return Promise.resolve();
 }
 
-function* openContextMenu(id) {
+function* openContextMenu(selector="#img1") {
   let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
   let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
-  yield BrowserTestUtils.synthesizeMouseAtCenter(id, {type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
+  yield BrowserTestUtils.synthesizeMouseAtCenter(selector, {type: "contextmenu"}, gBrowser.selectedBrowser);
   yield popupShownPromise;
   return contentAreaContextMenu;
 }
 
 function* closeContextMenu() {
   let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
   let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
   contentAreaContextMenu.hidePopup();
   yield popupHiddenPromise;
 }
 
-function* openExtensionContextMenu() {
-  let contextMenu = yield openContextMenu("#img1");
+function* openExtensionContextMenu(selector="#img1") {
+  let contextMenu = yield openContextMenu(selector);
   let topLevelMenu = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
 
   // Return null if the extension only has one item and therefore no extension menu.
   if (topLevelMenu.length == 0) {
     return null;
   }
 
   let extensionMenu = topLevelMenu[0].childNodes[0];