diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js index a32a1cc209f5..a042c5814809 100644 --- a/browser/base/content/tabbrowser.js +++ b/browser/base/content/tabbrowser.js @@ -2306,6 +2306,7 @@ window._gBrowser = { sameProcessAsFrameLoader, skipAnimation, skipBackgroundNotify, + title, triggeringPrincipal, userContextId, recordExecution, @@ -2549,6 +2550,13 @@ window._gBrowser = { userContextId); b.registeredOpenURI = lazyBrowserURI; } + SessionStore.setTabState(t, { + entries: [{ + url: lazyBrowserURI ? lazyBrowserURI.spec : "about:blank", + title, + triggeringPrincipal_base64: Utils.serializePrincipal(triggeringPrincipal), + }], + }); } else { this._insertBrowser(t, true); } @@ -3809,12 +3817,15 @@ window._gBrowser = { // the same remote type and process as the one we're swapping in. // This makes sure we don't get a short-lived process for the new tab. let linkedBrowser = aTab.linkedBrowser; + let createLazyBrowser = !aTab.linkedPanel; let params = { eventDetail: { adoptedTab: aTab }, preferredRemoteType: linkedBrowser.remoteType, sameProcessAsFrameLoader: linkedBrowser.frameLoader, skipAnimation: true, index: aIndex, + createLazyBrowser, + allowInheritPrincipal: createLazyBrowser, }; let numPinned = this._numPinnedTabs; @@ -3831,10 +3842,12 @@ window._gBrowser = { aTab.parentNode._finishAnimateTabMove(); - // Stop the about:blank load. - newBrowser.stop(); - // Make sure it has a docshell. - newBrowser.docShell; + if (!createLazyBrowser) { + // Stop the about:blank load. + newBrowser.stop(); + // Make sure it has a docshell. + newBrowser.docShell; + } if (!this.swapBrowsersAndCloseOther(newTab, aTab)) { // Swapping wasn't permitted. Bail out. diff --git a/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js b/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js index 0ef998b315c8..bb4df30431be 100644 --- a/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js +++ b/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js @@ -44,3 +44,52 @@ add_task(async function test() { BrowserTestUtils.closeWindow(newWindow); BrowserTestUtils.removeTab(tab4); }); + +add_task(async function testLazyTabs() { + let params = {createLazyBrowser: true}; + let tabs = []; + let numTabs = 4; + for (let i = 0; i < numTabs; ++i) { + tabs.push(BrowserTestUtils.addTab(gBrowser, `http://example.com/?${i}`, params)); + } + + await BrowserTestUtils.switchTab(gBrowser, tabs[0]); + for (let i = 1; i < numTabs; ++i) { + await triggerClickOn(tabs[i], { ctrlKey: true }); + } + + isnot(tabs[0].linkedPanel, "", `Tab 0 shouldn't be lazy`); + for (let i = 1; i < numTabs; ++i) { + is(tabs[i].linkedPanel, "", `Tab ${i} should be lazy`); + } + + is(gBrowser.multiSelectedTabsCount, numTabs, `${numTabs} multiselected tabs`); + for (let i = 0; i < numTabs; ++i) { + ok(tabs[i].multiselected, `Tab ${i} should be multiselected`); + } + + let newWindow = gBrowser.replaceTabsWithWindow(tabs[0]); + + await TestUtils.waitForCondition(() => newWindow.gBrowser, `Wait for gBrowser`); + await TestUtils.waitForCondition(() => newWindow.gBrowser.visibleTabs.length == numTabs, + `Wait for all ${numTabs} tabs to get moved to the new window`); + tabs = newWindow.gBrowser.tabs; + + isnot(tabs[0].linkedPanel, "", `Tab 0 should continue not being lazy`); + // FIXME: bug 1521923 - First inactive tab to be moved into another window loses laziness + todo_is(tabs[1].linkedPanel, "", `Tab 1 should continue being lazy`); + for (let i = 2; i < numTabs; ++i) { + is(tabs[i].linkedPanel, "", `Tab ${i} should continue being lazy`); + } + + is(tabs[0].linkedBrowser.currentURI.spec, `http://example.com/?0`, + `Tab 0 should have the right URL`); + todo_is(SessionStore.getLazyTabValue(tabs[1], "url"), `http://example.com/?1`, + `Tab 1 should have the right lazy URL`); + for (let i = 2; i < numTabs; ++i) { + is(SessionStore.getLazyTabValue(tabs[i], "url"), `http://example.com/?${i}`, + `Tab ${i} should have the right lazy URL`); + } + + BrowserTestUtils.closeWindow(newWindow); +}); diff --git a/browser/base/content/test/tabs/browser_multiselect_tabs_reopen_in_container.js b/browser/base/content/test/tabs/browser_multiselect_tabs_reopen_in_container.js index 368d14dc84cb..1b5c91ea945b 100644 --- a/browser/base/content/test/tabs/browser_multiselect_tabs_reopen_in_container.js +++ b/browser/base/content/test/tabs/browser_multiselect_tabs_reopen_in_container.js @@ -56,7 +56,7 @@ add_task(async function testReopen() { let tab1 = await addTab("http://mochi.test:8888/1"); let tab2 = await addTab("http://mochi.test:8888/2"); let tab3 = await addTab("http://mochi.test:8888/3"); - let tab4 = await addTab("http://mochi.test:8888/3", {createLazyBrowser: true}); + let tab4 = BrowserTestUtils.addTab(gBrowser, "http://mochi.test:8888/3", {createLazyBrowser: true}); await BrowserTestUtils.switchTab(gBrowser, tab1); diff --git a/browser/components/extensions/parent/ext-tabs.js b/browser/components/extensions/parent/ext-tabs.js index 72574f26124f..de2256c52d33 100644 --- a/browser/components/extensions/parent/ext-tabs.js +++ b/browser/components/extensions/parent/ext-tabs.js @@ -14,8 +14,6 @@ ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter(this, "SessionStore", "resource:///modules/sessionstore/SessionStore.jsm"); -ChromeUtils.defineModuleGetter(this, "Utils", - "resource://gre/modules/sessionstore/Utils.jsm"); XPCOMUtils.defineLazyGetter(this, "strBundle", function() { return Services.strings.createBundle("chrome://global/locale/extensions.properties"); @@ -634,15 +632,6 @@ this.tabs = class extends ExtensionAPI { options.triggeringPrincipal = principal; let nativeTab = window.gBrowser.addTab(url, options); - if (createProperties.discarded) { - SessionStore.setTabState(nativeTab, { - entries: [{ - url: url, - title: options.title, - triggeringPrincipal_base64: Utils.serializePrincipal(principal), - }], - }); - } if (active) { window.gBrowser.selectedTab = nativeTab;