Bug 1529411 - Fire onCreated before onRemoved when closing last tab with browser.tabs.closeWindowWithLastTab=false. r=mixedpuppy
authorOriol Brufau <oriol-bugzilla@hotmail.com>
Thu, 28 Feb 2019 00:10:30 +0000
changeset 519474 5570cf4346a807801c535758f1b82dae1ca63f3f
parent 519473 28bc841f06fc5f4d01defbacc80e017f701a8d57
child 519475 a56af9e8313bd344d1f0b497efa6b45b94802c6a
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmixedpuppy
bugs1529411
milestone67.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 1529411 - Fire onCreated before onRemoved when closing last tab with browser.tabs.closeWindowWithLastTab=false. r=mixedpuppy Differential Revision: https://phabricator.services.mozilla.com/D20584
browser/components/extensions/parent/ext-browser.js
browser/components/extensions/test/browser/browser_ext_tabs_events.js
--- a/browser/components/extensions/parent/ext-browser.js
+++ b/browser/components/extensions/parent/ext-browser.js
@@ -455,36 +455,27 @@ class TabTracker extends TabTrackerBase 
           // Handle the adoption.
           this.adopt(nativeTab, adoptedTab);
           if (adoptedTab.linkedPanel) {
             adoptedTab.linkedBrowser.messageManager.sendAsyncMessage("Extension:SetFrameData", {
               windowId: windowTracker.getId(nativeTab.ownerGlobal),
             });
           }
         } else {
-          // Save the size of the current tab, since the newly-created tab will
-          // likely be active by the time the promise below resolves and the
-          // event is dispatched.
+          if (!event.originalTarget.parentNode) {
+            // If the tab is already be destroyed, do nothing.
+            return;
+          }
           const currentTab = nativeTab.ownerGlobal.gBrowser.selectedTab;
           const {frameLoader} = currentTab.linkedBrowser;
           const currentTabSize = {
             width: frameLoader.lazyWidth,
             height: frameLoader.lazyHeight,
           };
-
-          // We need to delay sending this event until the next tick, since the
-          // tab could have been created with a lazy browser but still not have
-          // been assigned a SessionStore tab state with the URL and title.
-          Promise.resolve().then(() => {
-            if (!event.originalTarget.parentNode) {
-              // If the tab is already be destroyed, do nothing.
-              return;
-            }
-            this.emitCreated(event.originalTarget, currentTabSize);
-          });
+          this.emitCreated(event.originalTarget, currentTabSize);
         }
         break;
 
       case "TabClose":
         let {adoptedBy} = event.detail;
         if (adoptedBy) {
           // This tab is being closed because it was adopted by a new window.
           // Handle the adoption in case it was created as the first tab of a
@@ -492,31 +483,31 @@ class TabTracker extends TabTrackerBase 
           // opened.
           this.adopt(adoptedBy, nativeTab);
         } else {
           this.emitRemoved(nativeTab, false);
         }
         break;
 
       case "TabSelect":
-        // Because we are delaying calling emitCreated above, we also need to
-        // delay sending this event because it shouldn't fire before onCreated.
+        // We need to delay sending this event because it shouldn't fire before
+        // onRemoved when the active tab is removed.
         Promise.resolve().then(() => {
           if (!nativeTab.parentNode) {
             // If the tab is already be destroyed, do nothing.
             return;
           }
           this.emitActivated(nativeTab, event.detail.previousTab);
         });
         break;
 
       case "TabMultiSelect":
         if (this.has("tabs-highlighted")) {
-          // Because we are delaying calling emitCreated above, we also need to
-          // delay sending this event because it shouldn't fire before onCreated.
+          // Because we are delaying calling emitActivated above, we also need to
+          // delay sending this event because it shouldn't fire before onActivated.
           Promise.resolve().then(() => {
             this.emitHighlighted(event.target.ownerGlobal);
           });
         }
         break;
     }
   }
 
--- a/browser/components/extensions/test/browser/browser_ext_tabs_events.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_events.js
@@ -396,22 +396,23 @@ add_task(async function testLastTabRemov
   const CLOSE_WINDOW_PREF = "browser.tabs.closeWindowWithLastTab";
   await SpecialPowers.pushPrefEnv({set: [
     [CLOSE_WINDOW_PREF, false],
   ]});
 
   async function background() {
     let windowId;
     browser.tabs.onCreated.addListener(tab => {
-      browser.test.assertEq(windowId, tab.windowId,
-                            "expecting onCreated after onRemoved on the same window");
+      windowId = tab.windowId;
       browser.test.sendMessage("tabCreated", `${tab.width}x${tab.height}`);
     });
     browser.tabs.onRemoved.addListener((tabId, info) => {
-      windowId = info.windowId;
+      browser.test.assertEq(windowId, info.windowId,
+                            "expecting onRemoved after onCreated on the same window");
+      browser.test.sendMessage("tabRemoved");
     });
   }
 
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       "permissions": ["tabs"],
     },
     background,
@@ -421,16 +422,17 @@ add_task(async function testLastTabRemov
   await extension.startup();
 
   const oldBrowser = newWin.gBrowser.selectedBrowser;
   const expectedDims = `${oldBrowser.clientWidth}x${oldBrowser.clientHeight}`;
   BrowserTestUtils.removeTab(newWin.gBrowser.selectedTab);
 
   const actualDims = await extension.awaitMessage("tabCreated");
   is(actualDims, expectedDims, "created tab reports a size same to the removed last tab");
+  await extension.awaitMessage("tabRemoved");
 
   await extension.unload();
   await BrowserTestUtils.closeWindow(newWin);
   SpecialPowers.clearUserPref(CLOSE_WINDOW_PREF);
 });
 
 add_task(async function testTabActivationEvent() {
   async function background() {