Bug 1436720 use sessionstore to track controlling extension, r=Gijs

MozReview-Commit-ID: ACzGfNDVFXm

--HG--
extra : rebase_source : 7b7c8123f74b437ae5dc37c254dfb090b9321d4b
This commit is contained in:
Shane Caraveo 2018-02-13 15:43:31 -07:00
Родитель 367a708eba
Коммит 4bea9207d6
4 изменённых файлов: 33 добавлений и 14 удалений

Просмотреть файл

@ -3897,6 +3897,7 @@
let event = document.createEvent("Events"); let event = document.createEvent("Events");
event.initEvent("TabShow", true, false); event.initEvent("TabShow", true, false);
aTab.dispatchEvent(event); aTab.dispatchEvent(event);
SessionStore.deleteTabValue(aTab, "hiddenBy");
} }
]]> ]]>
</body> </body>
@ -3904,6 +3905,7 @@
<method name="hideTab"> <method name="hideTab">
<parameter name="aTab"/> <parameter name="aTab"/>
<parameter name="aSource"/>
<body> <body>
<![CDATA[ <![CDATA[
if (!aTab.hidden && !aTab.pinned && !aTab.selected && if (!aTab.hidden && !aTab.pinned && !aTab.selected &&
@ -3918,6 +3920,9 @@
let event = document.createEvent("Events"); let event = document.createEvent("Events");
event.initEvent("TabHide", true, false); event.initEvent("TabHide", true, false);
aTab.dispatchEvent(event); aTab.dispatchEvent(event);
if (aSource) {
SessionStore.setTabValue(aTab, "hiddenBy", aSource);
}
} }
]]> ]]>
</body> </body>

Просмотреть файл

@ -11,6 +11,8 @@ ChromeUtils.defineModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm"); "resource://gre/modules/PromiseUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Services", ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm"); "resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "SessionStore",
"resource:///modules/sessionstore/SessionStore.jsm");
XPCOMUtils.defineLazyGetter(this, "strBundle", function() { XPCOMUtils.defineLazyGetter(this, "strBundle", function() {
return Services.strings.createBundle("chrome://global/locale/extensions.properties"); return Services.strings.createBundle("chrome://global/locale/extensions.properties");
@ -22,9 +24,6 @@ var {
const TABHIDE_PREFNAME = "extensions.webextensions.tabhide.enabled"; const TABHIDE_PREFNAME = "extensions.webextensions.tabhide.enabled";
// WeakMap[Tab -> ExtensionID]
let hiddenTabs = new WeakMap();
let tabListener = { let tabListener = {
tabReadyInitialized: false, tabReadyInitialized: false,
tabReadyPromises: new WeakMap(), tabReadyPromises: new WeakMap(),
@ -93,11 +92,9 @@ this.tabs = class extends ExtensionAPI {
// self-manage re-hiding tabs. // self-manage re-hiding tabs.
for (let tab of this.extension.tabManager.query()) { for (let tab of this.extension.tabManager.query()) {
let nativeTab = tabTracker.getTab(tab.id); let nativeTab = tabTracker.getTab(tab.id);
if (hiddenTabs.get(nativeTab) === this.extension.id) { if (nativeTab.hidden && nativeTab.ownerGlobal &&
hiddenTabs.delete(nativeTab); SessionStore.getTabValue(nativeTab, "hiddenBy") === this.extension.id) {
if (nativeTab.ownerGlobal) { nativeTab.ownerGlobal.gBrowser.showTab(nativeTab);
nativeTab.ownerGlobal.gBrowser.showTab(nativeTab);
}
} }
} }
} }
@ -301,8 +298,6 @@ this.tabs = class extends ExtensionAPI {
needed.push("discarded"); needed.push("discarded");
} else if (event.type == "TabShow") { } else if (event.type == "TabShow") {
needed.push("hidden"); needed.push("hidden");
// Always remove the tab from the hiddenTabs map.
hiddenTabs.delete(event.originalTarget);
} else if (event.type == "TabHide") { } else if (event.type == "TabHide") {
needed.push("hidden"); needed.push("hidden");
} }
@ -1064,7 +1059,6 @@ this.tabs = class extends ExtensionAPI {
for (let tabId of tabIds) { for (let tabId of tabIds) {
let tab = tabTracker.getTab(tabId); let tab = tabTracker.getTab(tabId);
if (tab.ownerGlobal) { if (tab.ownerGlobal) {
hiddenTabs.delete(tab);
tab.ownerGlobal.gBrowser.showTab(tab); tab.ownerGlobal.gBrowser.showTab(tab);
} }
} }
@ -1083,9 +1077,8 @@ this.tabs = class extends ExtensionAPI {
let tabs = tabIds.map(tabId => tabTracker.getTab(tabId)); let tabs = tabIds.map(tabId => tabTracker.getTab(tabId));
for (let tab of tabs) { for (let tab of tabs) {
if (tab.ownerGlobal && !tab.hidden) { if (tab.ownerGlobal && !tab.hidden) {
tab.ownerGlobal.gBrowser.hideTab(tab); tab.ownerGlobal.gBrowser.hideTab(tab, extension.id);
if (tab.hidden) { if (tab.hidden) {
hiddenTabs.set(tab, extension.id);
hidden.push(tabTracker.getId(tab)); hidden.push(tabTracker.getId(tab));
} }
} }

Просмотреть файл

@ -1,5 +1,9 @@
"use strict"; "use strict";
ChromeUtils.defineModuleGetter(this, "SessionStore",
"resource:///modules/sessionstore/SessionStore.jsm");
ChromeUtils.defineModuleGetter(this, "TabStateFlusher",
"resource:///modules/sessionstore/TabStateFlusher.jsm");
const {Utils} = ChromeUtils.import("resource://gre/modules/sessionstore/Utils.jsm", {}); const {Utils} = ChromeUtils.import("resource://gre/modules/sessionstore/Utils.jsm", {});
const triggeringPrincipal_base64 = Utils.SERIALIZED_SYSTEMPRINCIPAL; const triggeringPrincipal_base64 = Utils.SERIALIZED_SYSTEMPRINCIPAL;
@ -116,9 +120,26 @@ add_task(async function test_tabs_showhide() {
ok(!tabs[0].hidden, "first tab not hidden"); ok(!tabs[0].hidden, "first tab not hidden");
for (let i = 1; i < tabs.length; i++) { for (let i = 1; i < tabs.length; i++) {
ok(tabs[i].hidden, "tab hidden value is correct"); ok(tabs[i].hidden, "tab hidden value is correct");
let id = SessionStore.getTabValue(tabs[i], "hiddenBy");
is(id, extension.id, "tab hiddenBy value is correct");
await TabStateFlusher.flush(tabs[i].linkedBrowser);
} }
} }
// Close the other window then restore it to test that the tabs are
// restored with proper hidden state, and the correct extension id.
await BrowserTestUtils.closeWindow(otherwin);
otherwin = SessionStore.undoCloseWindow(0);
await BrowserTestUtils.waitForEvent(otherwin, "load");
let tabs = Array.from(otherwin.gBrowser.tabs.values());
ok(!tabs[0].hidden, "first tab not hidden");
for (let i = 1; i < tabs.length; i++) {
ok(tabs[i].hidden, "tab hidden value is correct");
let id = SessionStore.getTabValue(tabs[i], "hiddenBy");
is(id, extension.id, "tab hiddenBy value is correct");
}
// Test closing the last visible tab, the next tab which is hidden should become // Test closing the last visible tab, the next tab which is hidden should become
// the selectedTab and will be visible. // the selectedTab and will be visible.
ok(!otherwin.gBrowser.selectedTab.hidden, "selected tab is not hidden"); ok(!otherwin.gBrowser.selectedTab.hidden, "selected tab is not hidden");

Просмотреть файл

@ -3436,7 +3436,7 @@ var SessionStoreInternal = {
tabs.push(tab); tabs.push(tab);
if (tabData.hidden) { if (tabData.hidden) {
tabbrowser.hideTab(tab); tabbrowser.hideTab(tab, tabData.extData && tabData.extData.hiddenBy);
} }
if (tabData.pinned) { if (tabData.pinned) {