diff --git a/browser/components/extensions/parent/ext-tabs.js b/browser/components/extensions/parent/ext-tabs.js index 3f3c64a263ea..293926c79886 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"); @@ -569,18 +567,9 @@ this.tabs = class extends ExtensionAPI { } } - // Only set disallowInheritPrincipal on non-discardable urls as it - // will override creating a lazy browser. Setting triggeringPrincipal - // will ensure other cases are handled, but setting it may prevent - // creating about and data urls. - let discardable = url && !url.startsWith("about:"); - if (!discardable) { - // Make sure things like about:blank and data: URIs never inherit, - // and instead always get a NullPrincipal. - options.disallowInheritPrincipal = true; - } else { - options.triggeringPrincipal = context.principal; - } + // Make sure things like about:blank and data: URIs never inherit, + // and instead always get a NullPrincipal. + options.disallowInheritPrincipal = true; tabListener.initTabReady(); let currentTab = window.gBrowser.selectedTab; @@ -593,47 +582,26 @@ this.tabs = class extends ExtensionAPI { } } - // Simple properties - const properties = ["index", "pinned", "title"]; - for (let prop of properties) { - if (createProperties[prop] != null) { - options[prop] = createProperties[prop]; - } + if (createProperties.index != null) { + options.index = createProperties.index; } - let active = createProperties.active !== null ? - createProperties.active : !createProperties.discarded; - if (createProperties.discarded) { - if (active) { - return Promise.reject({message: `Active tabs cannot be created and discarded.`}); - } - if (createProperties.pinned) { - return Promise.reject({message: `Pinned tabs cannot be created and discarded.`}); - } - if (!discardable) { - return Promise.reject({message: `Cannot create a discarded new tab or "about" urls.`}); - } - options.createLazyBrowser = true; - } else if (createProperties.title) { - return Promise.reject({message: `Title may only be set for discarded tabs.`}); + if (createProperties.pinned != null) { + options.pinned = createProperties.pinned; } let nativeTab = window.gBrowser.addTab(url || window.BROWSER_NEW_TAB_URL, options); - if (createProperties.discarded) { - SessionStore.setTabState(nativeTab, { - entries: [{ - url: url, - title: options.title, - triggeringPrincipal_base64: Utils.serializePrincipal(context.principal), - }], - }); - } + let active = true; + if (createProperties.active !== null) { + active = createProperties.active; + } if (active) { window.gBrowser.selectedTab = nativeTab; - if (!url) { - window.focusAndSelectUrlBar(); - } + } + + if (active && !url) { + window.focusAndSelectUrlBar(); } if (createProperties.url && diff --git a/browser/components/extensions/schemas/tabs.json b/browser/components/extensions/schemas/tabs.json index 7bb8e9a43508..9907c900d9be 100644 --- a/browser/components/extensions/schemas/tabs.json +++ b/browser/components/extensions/schemas/tabs.json @@ -584,19 +584,7 @@ }, "openInReaderMode": { "type": "boolean", - "optional": true, - "description": "Whether the document in the tab should be opened in reader mode." - }, - "discarded": { - "type": "boolean", - "optional": true, - "description": "Whether the tab is marked as 'discarded' when created." - }, - "title": { - "type": "string", - "optional": true, - "description": "The title used for display if the tab is created in discarded mode." - } + "optional": true, "description": "Whether the document in the tab should be opened in reader mode."} } }, { diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_discarded.js b/browser/components/extensions/test/browser/browser_ext_tabs_discarded.js index eb6bcf983de6..dbc3d30948bf 100644 --- a/browser/components/extensions/test/browser/browser_ext_tabs_discarded.js +++ b/browser/components/extensions/test/browser/browser_ext_tabs_discarded.js @@ -11,33 +11,60 @@ let lazyTabState = {entries: [{url: "http://example.com/", triggeringPrincipal_b add_task(async function test_discarded() { let extension = ExtensionTestUtils.loadExtension({ manifest: { - "permissions": ["tabs", "webNavigation"], + "permissions": ["tabs"], }, background: async function() { - browser.webNavigation.onCompleted.addListener(async (details) => { - browser.test.log(`webNav onCompleted received for ${details.tabId}`); - let updatedTab = await browser.tabs.get(details.tabId); + let onCreatedTabData = []; + let discardedEventData = []; + + async function finishTest() { + browser.test.assertEq(0, discardedEventData.length, "number of discarded events fired"); + + onCreatedTabData.sort((data1, data2) => data1.index - data2.index); + browser.test.assertEq(false, onCreatedTabData[0].discarded, "non-lazy tab onCreated discard property"); + browser.test.assertEq(true, onCreatedTabData[1].discarded, "lazy tab onCreated discard property"); + + let tabs = await browser.tabs.query({currentWindow: true}); + tabs.sort((tab1, tab2) => tab1.index - tab2.index); + + browser.test.assertEq(false, tabs[1].discarded, "non-lazy tab query discard property"); + browser.test.assertEq(true, tabs[2].discarded, "lazy tab query discard property"); + + let updatedTab = await browser.tabs.update(tabs[2].id, {active: true}); browser.test.assertEq(false, updatedTab.discarded, "lazy to non-lazy update discard property"); + browser.test.assertEq(false, discardedEventData[0], "lazy to non-lazy onUpdated discard property"); + browser.test.notifyPass("test-finished"); - }, {url: [{hostContains: "example.com"}]}); + } + + browser.tabs.onUpdated.addListener(function(tabId, updatedInfo) { + if ("discarded" in updatedInfo) { + discardedEventData.push(updatedInfo.discarded); + } + }); browser.tabs.onCreated.addListener(function(tab) { - browser.test.assertEq(true, tab.discarded, "non-lazy tab onCreated discard property"); - browser.tabs.update(tab.id, {active: true}); + onCreatedTabData.push({discarded: tab.discarded, index: tab.index}); + if (onCreatedTabData.length == 2) { + finishTest(); + } }); }, }); await extension.startup(); - let testTab = BrowserTestUtils.addTab(gBrowser, "about:blank", {createLazyBrowser: true}); - SessionStore.setTabState(testTab, lazyTabState); + let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com"); + + let tab2 = BrowserTestUtils.addTab(gBrowser, "about:blank", {createLazyBrowser: true}); + SessionStore.setTabState(tab2, JSON.stringify(lazyTabState)); await extension.awaitFinish("test-finished"); await extension.unload(); - BrowserTestUtils.removeTab(testTab); + BrowserTestUtils.removeTab(tab1); + BrowserTestUtils.removeTab(tab2); }); // If discard is called immediately after creating a new tab, the new tab may not have loaded, @@ -78,41 +105,3 @@ add_task(async function test_create_then_discard() { await extension.awaitFinish("test-finished"); await extension.unload(); }); - -add_task(async function test_create_discarded() { - let extension = ExtensionTestUtils.loadExtension({ - manifest: { - "permissions": ["tabs", "webNavigation"], - }, - - background: async function() { - let tabOpts = { - url: "http://example.com/", - active: false, - discarded: true, - title: "discarded tab", - }; - - browser.webNavigation.onCompleted.addListener(async (details) => { - let activeTab = await browser.tabs.get(details.tabId); - browser.test.assertEq(tabOpts.url, activeTab.url, "restored tab url matches active tab url"); - browser.test.assertEq("mochitest index /", activeTab.title, "restored tab title is correct"); - browser.tabs.remove(details.tabId); - browser.test.notifyPass("test-finished"); - }, {url: [{hostContains: "example.com"}]}); - - browser.tabs.onCreated.addListener(tab => { - browser.test.assertEq(tabOpts.active, tab.active, "lazy tab is not active"); - browser.test.assertEq(tabOpts.discarded, tab.discarded, "lazy tab is discarded"); - browser.test.assertEq(tabOpts.url, tab.url, "lazy tab url is correct"); - browser.test.assertEq(tabOpts.title, tab.title, "lazy tab title is correct"); - browser.tabs.update(tab.id, {active: true}); - }); - - browser.tabs.create(tabOpts); - }, - }); - await extension.startup(); - await extension.awaitFinish("test-finished"); - await extension.unload(); -}); diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm index 38d1ef86b925..dc43ebc8f767 100644 --- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -2386,10 +2386,7 @@ var SessionStoreInternal = { // Note that we cannot simply replace the contents of the cache // as |aState| can be an incomplete state that will be completed // by |restoreTabs|. - let tabState = aState; - if (typeof tabState == "string") { - tabState = JSON.parse(aState); - } + let tabState = JSON.parse(aState); if (!tabState) { throw Components.Exception("Invalid state string: not JSON", Cr.NS_ERROR_INVALID_ARG); } diff --git a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_basic.html b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_basic.html index 315f52122930..825cdc78df14 100644 --- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_basic.html +++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_basic.html @@ -302,15 +302,12 @@ add_task(async function test_webRequest_tabId_browser() { async function background(url) { let tabId; browser.test.onMessage.addListener(async (msg, expected) => { - if (msg == "create") { - let tab = await browser.tabs.create({url}); - tabId = tab.id; - return; - } await browser.tabs.remove(tabId); browser.test.sendMessage("done"); }); - browser.test.sendMessage("origin", browser.runtime.getURL("/")); + + let tab = await browser.tabs.create({url}); + tabId = tab.id; } let pageUrl = `${SimpleTest.getTestFileURL("file_sample.html")}?nocache=${Math.random()}`; @@ -337,15 +334,13 @@ add_task(async function test_webRequest_tabId_browser() { }; } - await tabExt.startup(); - let origin = await tabExt.awaitMessage("origin"); - - // expecting origin == extension baseUrl - extension.sendMessage("set-expected", {expect, origin}); + // expecting origin == undefined + extension.sendMessage("set-expected", {expect}); await extension.awaitMessage("continue"); - // open a tab from an extension principal - tabExt.sendMessage("create"); + // open a tab from a system principal + await tabExt.startup(); + await extension.awaitMessage("done"); tabExt.sendMessage("done"); await tabExt.awaitMessage("done");