Bug 1722567 - Save group of closed tabs to restore the all group. r=kashav
When a group of tabs is closed, save the it in session data so tabs could be restored together. Differential Revision: https://phabricator.services.mozilla.com/D121110
This commit is contained in:
@@ -8273,7 +8273,6 @@ function undoCloseTab(aIndex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SessionStore.setLastClosedTabCount(window, 1);
|
|
||||||
|
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2583,7 +2583,6 @@
|
|||||||
document
|
document
|
||||||
.getElementById("History:UndoCloseTab")
|
.getElementById("History:UndoCloseTab")
|
||||||
.setAttribute("data-l10n-args", JSON.stringify({ tabCount: 1 }));
|
.setAttribute("data-l10n-args", JSON.stringify({ tabCount: 1 }));
|
||||||
SessionStore.setLastClosedTabCount(window, 1);
|
|
||||||
|
|
||||||
// if we're adding tabs, we're past interrupt mode, ditch the owner
|
// if we're adding tabs, we're past interrupt mode, ditch the owner
|
||||||
if (this.selectedTab.owner) {
|
if (this.selectedTab.owner) {
|
||||||
@@ -3425,7 +3424,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let initialTabCount = tabs.length;
|
SessionStore.resetLastClosedTabCount(window);
|
||||||
this._clearMultiSelectionLocked = true;
|
this._clearMultiSelectionLocked = true;
|
||||||
|
|
||||||
// Guarantee that _clearMultiSelectionLocked lock gets released.
|
// Guarantee that _clearMultiSelectionLocked lock gets released.
|
||||||
@@ -3437,6 +3436,7 @@
|
|||||||
let aParams = { animate, prewarmed: true };
|
let aParams = { animate, prewarmed: true };
|
||||||
|
|
||||||
for (let tab of tabs) {
|
for (let tab of tabs) {
|
||||||
|
tab._closedInGroup = true;
|
||||||
if (tab.selected) {
|
if (tab.selected) {
|
||||||
lastToClose = tab;
|
lastToClose = tab;
|
||||||
let toBlurTo = this._findTabToBlurTo(lastToClose, tabs);
|
let toBlurTo = this._findTabToBlurTo(lastToClose, tabs);
|
||||||
@@ -3516,6 +3516,10 @@
|
|||||||
// Now run again sequentially the beforeunload listeners that will result in a prompt.
|
// Now run again sequentially the beforeunload listeners that will result in a prompt.
|
||||||
for (let tab of tabsWithBeforeUnloadPrompt) {
|
for (let tab of tabsWithBeforeUnloadPrompt) {
|
||||||
this.removeTab(tab, aParams);
|
this.removeTab(tab, aParams);
|
||||||
|
if (!tab.closing) {
|
||||||
|
// If we abort the closing of the tab.
|
||||||
|
tab._closedInGroup = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid changing the selected browser several times by removing it,
|
// Avoid changing the selected browser several times by removing it,
|
||||||
@@ -3529,17 +3533,14 @@
|
|||||||
|
|
||||||
this._clearMultiSelectionLocked = false;
|
this._clearMultiSelectionLocked = false;
|
||||||
this.avoidSingleSelectedTab();
|
this.avoidSingleSelectedTab();
|
||||||
let closedTabsCount =
|
|
||||||
initialTabCount - tabs.filter(t => t.isConnected && !t.closing).length;
|
|
||||||
// Don't use document.l10n.setAttributes because the FTL file is loaded
|
// Don't use document.l10n.setAttributes because the FTL file is loaded
|
||||||
// lazily and we won't be able to resolve the string.
|
// lazily and we won't be able to resolve the string.
|
||||||
document
|
document.getElementById("History:UndoCloseTab").setAttribute(
|
||||||
.getElementById("History:UndoCloseTab")
|
"data-l10n-args",
|
||||||
.setAttribute(
|
JSON.stringify({
|
||||||
"data-l10n-args",
|
tabCount: SessionStore.getLastClosedTabCount(window),
|
||||||
JSON.stringify({ tabCount: closedTabsCount })
|
})
|
||||||
);
|
);
|
||||||
SessionStore.setLastClosedTabCount(window, closedTabsCount);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
removeCurrentTab(aParams) {
|
removeCurrentTab(aParams) {
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ add_task(async function withMultiSelectedTabs() {
|
|||||||
ok(tab2.multiselected, "Tab2 is multiselected");
|
ok(tab2.multiselected, "Tab2 is multiselected");
|
||||||
ok(tab3.multiselected, "Tab3 is multiselected");
|
ok(tab3.multiselected, "Tab3 is multiselected");
|
||||||
ok(tab4.multiselected, "Tab4 is multiselected");
|
ok(tab4.multiselected, "Tab4 is multiselected");
|
||||||
is(gBrowser.multiSelectedTabsCount, 3, "Two multiselected tabs");
|
is(gBrowser.multiSelectedTabsCount, 3, "Three multiselected tabs");
|
||||||
|
|
||||||
gBrowser.removeMultiSelectedTabs();
|
gBrowser.removeMultiSelectedTabs();
|
||||||
await TestUtils.waitForCondition(
|
await TestUtils.waitForCondition(
|
||||||
() => gBrowser.tabs.length == 2,
|
() => SessionStore.getLastClosedTabCount(window) == 3,
|
||||||
"wait for the multiselected tabs to close"
|
"wait for the multi selected tabs to close in SessionStore"
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
SessionStore.getLastClosedTabCount(window),
|
SessionStore.getLastClosedTabCount(window),
|
||||||
@@ -44,6 +44,13 @@ add_task(async function withMultiSelectedTabs() {
|
|||||||
() => gBrowser.tabs.length == 5,
|
() => gBrowser.tabs.length == 5,
|
||||||
"wait for the tabs to reopen"
|
"wait for the tabs to reopen"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
SessionStore.getLastClosedTabCount(window),
|
||||||
|
SessionStore.getClosedTabCount(window) ? 1 : 0,
|
||||||
|
"LastClosedTabCount should be reset"
|
||||||
|
);
|
||||||
|
|
||||||
info("waiting for the browsers to finish loading");
|
info("waiting for the browsers to finish loading");
|
||||||
// Check that the tabs are restored in the correct order
|
// Check that the tabs are restored in the correct order
|
||||||
for (let tabId of [2, 3, 4]) {
|
for (let tabId of [2, 3, 4]) {
|
||||||
@@ -61,6 +68,67 @@ add_task(async function withMultiSelectedTabs() {
|
|||||||
gBrowser.removeAllTabsBut(initialTab);
|
gBrowser.removeAllTabsBut(initialTab);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function withBothGroupsAndTab() {
|
||||||
|
let initialTab = gBrowser.selectedTab;
|
||||||
|
let tab1 = await addTab("https://example.com/1");
|
||||||
|
let tab2 = await addTab("https://example.com/2");
|
||||||
|
let tab3 = await addTab("https://example.com/3");
|
||||||
|
|
||||||
|
gBrowser.selectedTab = tab2;
|
||||||
|
await triggerClickOn(tab3, { shiftKey: true });
|
||||||
|
|
||||||
|
ok(!initialTab.multiselected, "InitialTab is not multiselected");
|
||||||
|
ok(!tab1.multiselected, "Tab1 is not multiselected");
|
||||||
|
ok(tab2.multiselected, "Tab2 is multiselected");
|
||||||
|
ok(tab3.multiselected, "Tab3 is multiselected");
|
||||||
|
is(gBrowser.multiSelectedTabsCount, 2, "Two multiselected tabs");
|
||||||
|
|
||||||
|
gBrowser.removeMultiSelectedTabs();
|
||||||
|
await TestUtils.waitForCondition(
|
||||||
|
() => gBrowser.tabs.length == 2,
|
||||||
|
"wait for the multiselected tabs to close"
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
SessionStore.getLastClosedTabCount(window),
|
||||||
|
2,
|
||||||
|
"SessionStore should know how many tabs were just closed"
|
||||||
|
);
|
||||||
|
|
||||||
|
let tab4 = await addTab("http://example.com/4");
|
||||||
|
|
||||||
|
is(
|
||||||
|
SessionStore.getLastClosedTabCount(window),
|
||||||
|
2,
|
||||||
|
"LastClosedTabCount should be the same"
|
||||||
|
);
|
||||||
|
|
||||||
|
gBrowser.removeTab(tab4);
|
||||||
|
|
||||||
|
await TestUtils.waitForCondition(
|
||||||
|
() => SessionStore.getLastClosedTabCount(window) == 1,
|
||||||
|
"wait for the tab to close in SessionStore"
|
||||||
|
);
|
||||||
|
|
||||||
|
let count = 3;
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
is(
|
||||||
|
SessionStore.getLastClosedTabCount(window),
|
||||||
|
1,
|
||||||
|
"LastClosedTabCount should be one"
|
||||||
|
);
|
||||||
|
undoCloseTab();
|
||||||
|
|
||||||
|
await TestUtils.waitForCondition(
|
||||||
|
() => gBrowser.tabs.length == count,
|
||||||
|
"wait for the tabs to reopen"
|
||||||
|
);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
gBrowser.removeAllTabsBut(initialTab);
|
||||||
|
});
|
||||||
|
|
||||||
add_task(async function withCloseTabsToTheRight() {
|
add_task(async function withCloseTabsToTheRight() {
|
||||||
let initialTab = gBrowser.selectedTab;
|
let initialTab = gBrowser.selectedTab;
|
||||||
let tab1 = await addTab("https://example.com/1");
|
let tab1 = await addTab("https://example.com/1");
|
||||||
|
|||||||
@@ -309,8 +309,9 @@ var SessionStore = {
|
|||||||
getLastClosedTabCount(aWindow) {
|
getLastClosedTabCount(aWindow) {
|
||||||
return SessionStoreInternal.getLastClosedTabCount(aWindow);
|
return SessionStoreInternal.getLastClosedTabCount(aWindow);
|
||||||
},
|
},
|
||||||
setLastClosedTabCount(aWindow, aNumber) {
|
|
||||||
return SessionStoreInternal.setLastClosedTabCount(aWindow, aNumber);
|
resetLastClosedTabCount(aWindow) {
|
||||||
|
SessionStoreInternal.resetLastClosedTabCount(aWindow);
|
||||||
},
|
},
|
||||||
|
|
||||||
getClosedTabCount: function ss_getClosedTabCount(aWindow) {
|
getClosedTabCount: function ss_getClosedTabCount(aWindow) {
|
||||||
@@ -763,7 +764,6 @@ var SessionStoreInternal = {
|
|||||||
|
|
||||||
this._initPrefs();
|
this._initPrefs();
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
this._closedTabCache = new WeakMap();
|
|
||||||
|
|
||||||
Services.telemetry
|
Services.telemetry
|
||||||
.getHistogramById("FX_SESSION_RESTORE_PRIVACY_LEVEL")
|
.getHistogramById("FX_SESSION_RESTORE_PRIVACY_LEVEL")
|
||||||
@@ -1198,7 +1198,7 @@ var SessionStoreInternal = {
|
|||||||
this._closedTabs.has(permanentKey) &&
|
this._closedTabs.has(permanentKey) &&
|
||||||
!this._crashedBrowsers.has(permanentKey)
|
!this._crashedBrowsers.has(permanentKey)
|
||||||
) {
|
) {
|
||||||
let { closedTabs, tabData } = this._closedTabs.get(permanentKey);
|
let { winData, closedTabs, tabData } = this._closedTabs.get(permanentKey);
|
||||||
|
|
||||||
// We expect no further updates.
|
// We expect no further updates.
|
||||||
this._closedTabs.delete(permanentKey);
|
this._closedTabs.delete(permanentKey);
|
||||||
@@ -1215,12 +1215,12 @@ var SessionStoreInternal = {
|
|||||||
// the list of closed tabs when it was closed (because we deemed
|
// the list of closed tabs when it was closed (because we deemed
|
||||||
// the state not worth saving) then add it to the window's list
|
// the state not worth saving) then add it to the window's list
|
||||||
// of closed tabs now.
|
// of closed tabs now.
|
||||||
this.saveClosedTabData(closedTabs, tabData);
|
this.saveClosedTabData(winData, closedTabs, tabData);
|
||||||
} else if (!shouldSave && index > -1) {
|
} else if (!shouldSave && index > -1) {
|
||||||
// Remove from the list of closed tabs. The update messages sent
|
// Remove from the list of closed tabs. The update messages sent
|
||||||
// after the tab was closed changed enough state so that we no
|
// after the tab was closed changed enough state so that we no
|
||||||
// longer consider its data interesting enough to keep around.
|
// longer consider its data interesting enough to keep around.
|
||||||
this.removeClosedTabData(closedTabs, index);
|
this.removeClosedTabData(winData, closedTabs, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1477,6 +1477,7 @@ var SessionStoreInternal = {
|
|||||||
tabs: [],
|
tabs: [],
|
||||||
selected: 0,
|
selected: 0,
|
||||||
_closedTabs: [],
|
_closedTabs: [],
|
||||||
|
_lastClosedTabGroupCount: -1,
|
||||||
busy: false,
|
busy: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2494,9 +2495,11 @@ var SessionStoreInternal = {
|
|||||||
image: aWindow.gBrowser.getIcon(aTab),
|
image: aWindow.gBrowser.getIcon(aTab),
|
||||||
pos: aTab._tPos,
|
pos: aTab._tPos,
|
||||||
closedAt: Date.now(),
|
closedAt: Date.now(),
|
||||||
|
closedInGroup: aTab._closedInGroup,
|
||||||
};
|
};
|
||||||
|
|
||||||
let closedTabs = this._windows[aWindow.__SSi]._closedTabs;
|
let winData = this._windows[aWindow.__SSi];
|
||||||
|
let closedTabs = winData._closedTabs;
|
||||||
|
|
||||||
// Determine whether the tab contains any information worth saving. Note
|
// Determine whether the tab contains any information worth saving. Note
|
||||||
// that there might be pending state changes queued in the child that
|
// that there might be pending state changes queued in the child that
|
||||||
@@ -2507,12 +2510,12 @@ var SessionStoreInternal = {
|
|||||||
// of the list but those cases should be extremely rare and
|
// of the list but those cases should be extremely rare and
|
||||||
// do probably never occur when using the browser normally.
|
// do probably never occur when using the browser normally.
|
||||||
// (Tests or add-ons might do weird things though.)
|
// (Tests or add-ons might do weird things though.)
|
||||||
this.saveClosedTabData(closedTabs, tabData);
|
this.saveClosedTabData(winData, closedTabs, tabData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember the closed tab to properly handle any last updates included in
|
// Remember the closed tab to properly handle any last updates included in
|
||||||
// the final "update" message sent by the frame script's unload handler.
|
// the final "update" message sent by the frame script's unload handler.
|
||||||
this._closedTabs.set(permanentKey, { closedTabs, tabData });
|
this._closedTabs.set(permanentKey, { winData, closedTabs, tabData });
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2626,12 +2629,14 @@ var SessionStoreInternal = {
|
|||||||
* all tabs already in the list. The list will be truncated to contain a
|
* all tabs already in the list. The list will be truncated to contain a
|
||||||
* maximum of |this._max_tabs_undo| entries.
|
* maximum of |this._max_tabs_undo| entries.
|
||||||
*
|
*
|
||||||
* @param closedTabs (array)
|
* @param winData (object)
|
||||||
* The list of closed tabs for a window.
|
* The data of the window.
|
||||||
* @param tabData (object)
|
* @param tabData (object)
|
||||||
* The tabData to be inserted.
|
* The tabData to be inserted.
|
||||||
|
* @param closedTabs (array)
|
||||||
|
* The list of closed tabs for a window.
|
||||||
*/
|
*/
|
||||||
saveClosedTabData(closedTabs, tabData) {
|
saveClosedTabData(winData, closedTabs, tabData) {
|
||||||
// Find the index of the first tab in the list
|
// Find the index of the first tab in the list
|
||||||
// of closed tabs that was closed before our tab.
|
// of closed tabs that was closed before our tab.
|
||||||
let index = closedTabs.findIndex(tab => {
|
let index = closedTabs.findIndex(tab => {
|
||||||
@@ -2651,6 +2656,18 @@ var SessionStoreInternal = {
|
|||||||
closedTabs.splice(index, 0, tabData);
|
closedTabs.splice(index, 0, tabData);
|
||||||
this._closedObjectsChanged = true;
|
this._closedObjectsChanged = true;
|
||||||
|
|
||||||
|
if (tabData.closedInGroup) {
|
||||||
|
if (winData._lastClosedTabGroupCount < this._max_tabs_undo) {
|
||||||
|
if (winData._lastClosedTabGroupCount < 0) {
|
||||||
|
winData._lastClosedTabGroupCount = 1;
|
||||||
|
} else {
|
||||||
|
winData._lastClosedTabGroupCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
winData._lastClosedTabGroupCount = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Truncate the list of closed tabs, if needed.
|
// Truncate the list of closed tabs, if needed.
|
||||||
if (closedTabs.length > this._max_tabs_undo) {
|
if (closedTabs.length > this._max_tabs_undo) {
|
||||||
closedTabs.splice(this._max_tabs_undo, closedTabs.length);
|
closedTabs.splice(this._max_tabs_undo, closedTabs.length);
|
||||||
@@ -2662,16 +2679,24 @@ var SessionStoreInternal = {
|
|||||||
* the tab's final message is still pending we will simply discard it when
|
* the tab's final message is still pending we will simply discard it when
|
||||||
* it arrives so that the tab doesn't reappear in the list.
|
* it arrives so that the tab doesn't reappear in the list.
|
||||||
*
|
*
|
||||||
* @param closedTabs (array)
|
* @param winData (object)
|
||||||
* The list of closed tabs for a window.
|
* The data of the window.
|
||||||
* @param index (uint)
|
* @param index (uint)
|
||||||
* The index of the tab to remove.
|
* The index of the tab to remove.
|
||||||
|
* @param closedTabs (array)
|
||||||
|
* The list of closed tabs for a window.
|
||||||
*/
|
*/
|
||||||
removeClosedTabData(closedTabs, index) {
|
removeClosedTabData(winData, closedTabs, index) {
|
||||||
// Remove the given index from the list.
|
// Remove the given index from the list.
|
||||||
let [closedTab] = closedTabs.splice(index, 1);
|
let [closedTab] = closedTabs.splice(index, 1);
|
||||||
this._closedObjectsChanged = true;
|
this._closedObjectsChanged = true;
|
||||||
|
|
||||||
|
// If the tab is part of the last closed group,
|
||||||
|
// we need to deduct the tab from the count.
|
||||||
|
if (index < winData._lastClosedTabGroupCount) {
|
||||||
|
winData._lastClosedTabGroupCount--;
|
||||||
|
}
|
||||||
|
|
||||||
// If the closed tab's state still has a .permanentKey property then we
|
// If the closed tab's state still has a .permanentKey property then we
|
||||||
// haven't seen its final update message yet. Remove it from the map of
|
// haven't seen its final update message yet. Remove it from the map of
|
||||||
// closed tabs so that we will simply discard its last messages and will
|
// closed tabs so that we will simply discard its last messages and will
|
||||||
@@ -3100,24 +3125,21 @@ var SessionStoreInternal = {
|
|||||||
|
|
||||||
getLastClosedTabCount(aWindow) {
|
getLastClosedTabCount(aWindow) {
|
||||||
if ("__SSi" in aWindow) {
|
if ("__SSi" in aWindow) {
|
||||||
// Blank tabs cannot be undo-closed, so the number returned by
|
|
||||||
// the ClosedTabCache can be greater than the return value of
|
|
||||||
// getClosedTabCount. We won't restore blank tabs, so we return
|
|
||||||
// the minimum of these two values.
|
|
||||||
return Math.min(
|
return Math.min(
|
||||||
this._closedTabCache.get(aWindow) || 1,
|
Math.max(this._windows[aWindow.__SSi]._lastClosedTabGroupCount, 1),
|
||||||
this.getClosedTabCount(aWindow)
|
this.getClosedTabCount(aWindow)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
|
throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
|
||||||
},
|
},
|
||||||
setLastClosedTabCount(aWindow, aNumber) {
|
|
||||||
if ("__SSi" in aWindow) {
|
|
||||||
return this._closedTabCache.set(aWindow, aNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
|
resetLastClosedTabCount(aWindow) {
|
||||||
|
if ("__SSi" in aWindow) {
|
||||||
|
this._windows[aWindow.__SSi]._lastClosedTabGroupCount = -1;
|
||||||
|
} else {
|
||||||
|
throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getClosedTabCount: function ssi_getClosedTabCount(aWindow) {
|
getClosedTabCount: function ssi_getClosedTabCount(aWindow) {
|
||||||
@@ -3163,11 +3185,11 @@ var SessionStoreInternal = {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var closedTabs = this._windows[aWindow.__SSi]._closedTabs;
|
let winData = this._windows[aWindow.__SSi];
|
||||||
|
|
||||||
// default to the most-recently closed tab
|
// default to the most-recently closed tab
|
||||||
aIndex = aIndex || 0;
|
aIndex = aIndex || 0;
|
||||||
if (!(aIndex in closedTabs)) {
|
if (!(aIndex in winData._closedTabs)) {
|
||||||
throw Components.Exception(
|
throw Components.Exception(
|
||||||
"Invalid index: not in the closed tabs",
|
"Invalid index: not in the closed tabs",
|
||||||
Cr.NS_ERROR_INVALID_ARG
|
Cr.NS_ERROR_INVALID_ARG
|
||||||
@@ -3175,7 +3197,11 @@ var SessionStoreInternal = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fetch the data of closed tab, while removing it from the array
|
// fetch the data of closed tab, while removing it from the array
|
||||||
let { state, pos } = this.removeClosedTabData(closedTabs, aIndex);
|
let { state, pos } = this.removeClosedTabData(
|
||||||
|
winData,
|
||||||
|
winData._closedTabs,
|
||||||
|
aIndex
|
||||||
|
);
|
||||||
|
|
||||||
// create a new tab
|
// create a new tab
|
||||||
let tabbrowser = aWindow.gBrowser;
|
let tabbrowser = aWindow.gBrowser;
|
||||||
@@ -3202,11 +3228,11 @@ var SessionStoreInternal = {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var closedTabs = this._windows[aWindow.__SSi]._closedTabs;
|
let winData = this._windows[aWindow.__SSi];
|
||||||
|
|
||||||
// default to the most-recently closed tab
|
// default to the most-recently closed tab
|
||||||
aIndex = aIndex || 0;
|
aIndex = aIndex || 0;
|
||||||
if (!(aIndex in closedTabs)) {
|
if (!(aIndex in winData._closedTabs)) {
|
||||||
throw Components.Exception(
|
throw Components.Exception(
|
||||||
"Invalid index: not in the closed tabs",
|
"Invalid index: not in the closed tabs",
|
||||||
Cr.NS_ERROR_INVALID_ARG
|
Cr.NS_ERROR_INVALID_ARG
|
||||||
@@ -3214,7 +3240,7 @@ var SessionStoreInternal = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove closed tab from the array
|
// remove closed tab from the array
|
||||||
this.removeClosedTabData(closedTabs, aIndex);
|
this.removeClosedTabData(winData, winData._closedTabs, aIndex);
|
||||||
|
|
||||||
// Notify of changes to closed objects.
|
// Notify of changes to closed objects.
|
||||||
this._notifyOfClosedObjectsChange();
|
this._notifyOfClosedObjectsChange();
|
||||||
@@ -3499,7 +3525,7 @@ var SessionStoreInternal = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (let index of indexes.reverse()) {
|
for (let index of indexes.reverse()) {
|
||||||
this.removeClosedTabData(windowState._closedTabs, index);
|
this.removeClosedTabData(windowState, windowState._closedTabs, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user