Bug 1443221 - Do not send a webNavigation API event for a browser which is adopting an existent tab in a new window. r=mixedpuppy
authorLuca Greco <lgreco@mozilla.com>
Mon, 09 Apr 2018 15:39:49 +0200
changeset 412968 4bdc8b9244705508152e90a05f746def85492733
parent 412967 a061dfd9f1b14c2f5dd74f5c7d82fbfb76fd6f60
child 412969 93c851a45ec74718a3fe6569e9ac3f2797820906
push id33828
push userarchaeopteryx@coole-files.de
push dateThu, 12 Apr 2018 19:19:41 +0000
treeherdermozilla-central@6e22c4a726c2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmixedpuppy
bugs1443221
milestone61.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 1443221 - Do not send a webNavigation API event for a browser which is adopting an existent tab in a new window. r=mixedpuppy MozReview-Commit-ID: GG9cSB5hdhA
browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js
toolkit/components/extensions/parent/ext-webNavigation.js
--- a/browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js
+++ b/browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js
@@ -133,8 +133,93 @@ add_task(async function testWindowCreate
 
     background,
   });
 
   await extension.startup();
   await extension.awaitFinish("window-create");
   await extension.unload();
 });
+
+add_task(async function testWebNavigationOnWindowCreateTabId() {
+  async function background() {
+    const webNavEvents = [];
+    const onceTabsAttached = [];
+
+    let promiseTabAttached = (tab) => {
+      return new Promise(resolve => {
+        browser.tabs.onAttached.addListener(function listener(tabId) {
+          if (tabId !== tab.id) {
+            return;
+          }
+          browser.tabs.onAttached.removeListener(listener);
+          resolve();
+        });
+      });
+    };
+
+    // Listen to webNavigation.onCompleted events to ensure that
+    // it is not going to be fired when we move the existent tabs
+    // to new windows.
+    browser.webNavigation.onCompleted.addListener((data) => {
+      webNavEvents.push(data);
+    });
+
+    // Wait for the list of urls needed to select the test tabs,
+    // and then move these tabs to a new window and assert that
+    // no webNavigation.onCompleted events should be received
+    // while the tabs are being adopted into the new windows.
+    browser.test.onMessage.addListener(async (msg, testTabURLs) => {
+      if (msg !== "testTabURLs") {
+        return;
+      }
+
+      // Retrieve the tabs list and filter out the tabs that should
+      // not be moved into a new window.
+      let allTabs = await browser.tabs.query({});
+      let testTabs = allTabs.filter(tab => {
+        return testTabURLs.includes(tab.url);
+      });
+
+      browser.test.assertEq(2, testTabs.length, "Got the expected number of test tabs");
+
+      for (let tab of testTabs) {
+        onceTabsAttached.push(promiseTabAttached(tab));
+        await browser.windows.create({tabId: tab.id});
+      }
+
+      // Wait the tabs to have been attached to the new window and then assert that no
+      // webNavigation.onCompleted event has been received.
+      browser.test.log("Waiting tabs move to new window to be attached");
+      await Promise.all(onceTabsAttached);
+
+      browser.test.assertEq("[]", JSON.stringify(webNavEvents),
+                            "No webNavigation.onCompleted event should have been received");
+
+      // Remove all the test tabs before exiting the test successfully.
+      for (let tab of testTabs) {
+        await browser.tabs.remove(tab.id);
+      }
+
+      browser.test.notifyPass("webNavigation-on-window-create-tabId");
+    });
+  }
+
+  const testURLs = ["http://example.com/", "http://example.org/"];
+
+  for (let url of testURLs) {
+    await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+  }
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs", "webNavigation"],
+    },
+    background,
+  });
+
+  await extension.startup();
+
+  await extension.sendMessage("testTabURLs", testURLs);
+
+  await extension.awaitFinish("webNavigation-on-window-create-tabId");
+  await extension.unload();
+});
--- a/toolkit/components/extensions/parent/ext-webNavigation.js
+++ b/toolkit/components/extensions/parent/ext-webNavigation.js
@@ -115,16 +115,24 @@ class WebNavigationEventManager extends 
           data2.frameId = data.frameId;
           data2.parentFrameId = data.parentFrameId;
         }
 
         if (data.sourceFrameId != undefined) {
           data2.sourceFrameId = data.sourceFrameId;
         }
 
+        // Do not send a webNavigation event when the data.browser is related to a tab from a
+        // new window opened to adopt an existent tab (See Bug 1443221 for a rationale).
+        const chromeWin = data.browser.ownerGlobal;
+        if (chromeWin && chromeWin.arguments && chromeWin.arguments[0] instanceof chromeWin.XULElement &&
+            chromeWin.gBrowser.selectedBrowser === data.browser) {
+          return;
+        }
+
         // Fills in tabId typically.
         Object.assign(data2, tabTracker.getBrowserData(data.browser));
         if (data2.tabId < 0) {
           return;
         }
 
         if (data.sourceTabBrowser) {
           data2.sourceTabId = tabTracker.getBrowserData(data.sourceTabBrowser).tabId;