refactor: private tab

This commit is contained in:
adamp01
2022-10-05 13:32:19 +01:00
committed by Alex Kontos
parent 732b2a4624
commit 1d86cc9c39
8 changed files with 1313 additions and 570 deletions

View File

@@ -29,7 +29,10 @@ export var PrivateBrowsingUtils = {
// This should be used only in frame scripts. // This should be used only in frame scripts.
isContentWindowPrivate: function pbu_isWindowPrivate(aWindow) { isContentWindowPrivate: function pbu_isWindowPrivate(aWindow) {
return this.privacyContextFromWindow(aWindow).usePrivateBrowsing; // Waterfox: Essential to prevent form data from being saved.
return this.privacyContextFromWindow(aWindow).usePrivateBrowsing
? true
: Services.prefs.getBoolPref("browser.tabs.selectedTabPrivate", false);
}, },
isBrowserPrivate(aBrowser) { isBrowserPrivate(aBrowser) {

View File

@@ -20,7 +20,7 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
ChromeManifest: "resource:///modules/ChromeManifest.sys.mjs", ChromeManifest: "resource:///modules/ChromeManifest.sys.mjs",
Overlays: "resource:///modules/Overlays.sys.mjs", Overlays: "resource:///modules/Overlays.sys.mjs",
PrefUtils: "resource:///modules/PrefUtils.jsm", PrefUtils: "resource:///modules/PrefUtils.jsm",
PrivateTab: "resource:///modules/PrivateTab.jsm", PrivateTab: "resource:///modules/PrivateTab.sys.mjs",
StatusBar: "resource:///modules/StatusBar.jsm", StatusBar: "resource:///modules/StatusBar.jsm",
TabFeatures: "resource:///modules/TabFeatures.jsm", TabFeatures: "resource:///modules/TabFeatures.jsm",
UICustomizations: "resource:///modules/UICustomizations.jsm", UICustomizations: "resource:///modules/UICustomizations.jsm",

View File

@@ -1,503 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const EXPORTED_SYMBOLS = ["PrivateTab"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { ContextualIdentityService } = ChromeUtils.import(
"resource://gre/modules/ContextualIdentityService.jsm"
);
const { PlacesUIUtils } = ChromeUtils.import(
"resource:///modules/PlacesUIUtils.jsm"
);
const { TabStateCache } = ChromeUtils.import(
"resource:///modules/sessionstore/TabStateCache.jsm"
);
const { TabStateFlusher } = ChromeUtils.import(
"resource:///modules/sessionstore/TabStateFlusher.jsm"
);
const { BrowserUtils } = ChromeUtils.import(
"resource:///modules/BrowserUtils.jsm"
);
const { PrefUtils } = ChromeUtils.import("resource:///modules/PrefUtils.jsm");
const PrivateTab = {
config: {
neverClearData: false, // TODO: change to pref controlled value; if you want to not record history but don"t care about other data, maybe even want to keep private logins
restoreTabsOnRestart: true,
doNotClearDataUntilFxIsClosed: false,
},
openTabs: new Set(),
BTN_ID: "privateTab-button",
BTN2_ID: "newPrivateTab-button",
get style() {
return `
@-moz-document url('chrome://browser/content/browser.xhtml') {
#private-mask[enabled="true"] {
display: block !important;
}
#${this.BTN_ID}, #${this.BTN2_ID} {
list-style-image: url(chrome://browser/skin/privateBrowsing.svg);
}
#tabbrowser-tabs[hasadjacentnewprivatetabbutton]:not([overflow="true"]) ~ #${this.BTN_ID},
#tabbrowser-tabs[overflow="true"] > #tabbrowser-arrowscrollbox > #${this.BTN2_ID},
#tabbrowser-tabs:not([hasadjacentnewprivatetabbutton]) > #tabbrowser-arrowscrollbox > #${this.BTN2_ID},
#TabsToolbar[customizing="true"] #${this.BTN2_ID} {
display: none;
}
.tabbrowser-tab[usercontextid="${this.container.userContextId}"] .tab-label {
text-decoration: underline !important;
text-decoration-color: -moz-nativehyperlinktext !important;
text-decoration-style: dashed !important;
}
.tabbrowser-tab[usercontextid="${this.container.userContextId}"][pinned] .tab-icon-image,
.tabbrowser-tab[usercontextid="${this.container.userContextId}"][pinned] .tab-throbber {
border-bottom: 1px dashed -moz-nativehyperlinktext !important;
}
}
`;
},
init(window) {
// Only init in a non-private window
if (!window.PrivateBrowsingUtils.isWindowPrivate(window)) {
window.PrivateTab = this;
this.initContainer("Private");
this.initObservers(window);
this.initListeners(window);
this.initCustomFunctions(window);
this.overridePlacesUIUtils();
this.updatePrivateMaskId(window);
BrowserUtils.setStyle(this.style);
}
},
initContainer(aName) {
ContextualIdentityService.ensureDataReady();
this.container = ContextualIdentityService._identities.find(
container => container.name == aName
);
if (this.container && this.container.icon == "private") {
ContextualIdentityService.remove(this.container.userContextId);
this.container = undefined;
}
if (!this.container) {
ContextualIdentityService.create(aName, "fingerprint", "purple");
this.container = ContextualIdentityService._identities.find(
container => container.name == aName
);
} else if (!this.config.neverClearData) {
this.clearData();
}
return this.container;
},
clearData() {
Services.clearData.deleteDataFromOriginAttributesPattern({
userContextId: this.container.userContextId,
});
},
initObservers(aWindow) {
this.setPrivateObserver();
},
initListeners(aWindow) {
this.initPrivateTabListeners(aWindow);
aWindow.document
.getElementById("placesContext")
?.addEventListener("popupshowing", this.placesContext);
aWindow.document
.getElementById("contentAreaContextMenu")
?.addEventListener("popupshowing", this.contentContext);
aWindow.document
.getElementById("contentAreaContextMenu")
?.addEventListener("popuphidden", this.hideContext);
aWindow.document
.getElementById("tabContextMenu")
?.addEventListener("popupshowing", this.tabContext);
aWindow.document
.getElementById("newPrivateTab-button")
?.addEventListener("click", this.toolbarClick);
},
async updatePrivateMaskId(aWindow) {
let privateMask = aWindow.document.getElementsByClassName(
"private-browsing-indicator"
)[0];
privateMask.id = "private-mask";
},
setPrivateObserver() {
if (!this.config.neverClearData) {
let observe = () => {
this.clearData();
if (!this.config.restoreTabsOnRestart) {
this.closeTabs();
}
};
Services.obs.addObserver(observe, "quit-application-granted");
}
},
closeTabs() {
ContextualIdentityService._forEachContainerTab((tab, tabbrowser) => {
if (tab.userContextId == this.container.userContextId) {
tabbrowser.removeTab(tab);
}
});
},
placesContext(aEvent) {
let win = aEvent.view;
if (!win) {
return;
}
let { document } = win;
let openAll = "placesContext_openBookmarkContainer:tabs";
let openAllLinks = "placesContext_openLinks:tabs";
let openTab = "placesContext_open:newtab";
// let document = event.target.ownerDocument;
document.getElementById("openPrivate").disabled = document.getElementById(
openTab
).disabled;
document.getElementById("openPrivate").hidden = document.getElementById(
openTab
).hidden;
document.getElementById(
"openAllPrivate"
).disabled = document.getElementById(openAll).disabled;
document.getElementById("openAllPrivate").hidden = document.getElementById(
openAll
).hidden;
document.getElementById(
"openAllLinksPrivate"
).disabled = document.getElementById(openAllLinks).disabled;
document.getElementById(
"openAllLinksPrivate"
).hidden = document.getElementById(openAllLinks).hidden;
},
isPrivate(aTab) {
return aTab.getAttribute("usercontextid") == this.container.userContextId;
},
contentContext(aEvent) {
let win = aEvent.view;
if (!win) {
return;
}
let { gContextMenu, gBrowser, PrivateTab } = win;
let tab = gBrowser.getTabForBrowser(gContextMenu.browser);
gContextMenu.showItem(
"openLinkInPrivateTab",
gContextMenu.onSaveableLink || gContextMenu.onPlainTextLink
);
let isPrivate = PrivateTab.isPrivate(tab);
if (isPrivate) {
gContextMenu.showItem("context-openlinkincontainertab", false);
}
},
hideContext(aEvent) {
if (!aEvent.view) {
return;
}
if (aEvent.target == this) {
aEvent.view.document.getElementById("openLinkInPrivateTab").hidden = true;
}
},
tabContext(aEvent) {
let win = aEvent.view;
if (!win) {
return;
}
let { document, PrivateTab } = win;
const isPrivate =
win.TabContextMenu.contextTab.userContextId ===
PrivateTab.container.userContextId;
document
.getElementById("toggleTabPrivateState")
.setAttribute("data-l10n-args", JSON.stringify({ isPrivate }));
},
openLink(aEvent) {
let win = aEvent.view;
if (!win) {
return;
}
let { gContextMenu, PrivateTab, document } = win;
win.openLinkIn(
gContextMenu.linkURL,
"tab",
gContextMenu._openLinkInParameters({
userContextId: PrivateTab.container.userContextId,
triggeringPrincipal: document.nodePrincipal,
})
);
},
toolbarClick(aEvent) {
let win = aEvent.view;
if (!win) {
return;
}
let { PrivateTab, document } = win;
if (aEvent.button == 0) {
PrivateTab.browserOpenTabPrivate(win);
} else if (aEvent.button == 2) {
document.popupNode = document.getElementById(PrivateTab.BTN_ID);
document
.getElementById("toolbar-context-menu")
.openPopup(this, "after_start", 14, -10, false, false);
document.getElementsByClassName(
"customize-context-removeFromToolbar"
)[0].disabled = false;
document.getElementsByClassName(
"customize-context-moveToPanel"
)[0].disabled = false;
aEvent.preventDefault();
}
},
overridePlacesUIUtils() {
/* globals BrowserWindowTracker */
// Unused vars required for eval to execute
// eslint-disable-next-line no-unused-vars
const { PlacesUtils } = ChromeUtils.import(
"resource://gre/modules/PlacesUtils.jsm"
);
// eslint-disable-next-line no-unused-vars
const { PrivateBrowsingUtils } = ChromeUtils.import(
"resource://gre/modules/PrivateBrowsingUtils.jsm"
);
// eslint-disable-next-line no-unused-vars
function getBrowserWindow(aWindow) {
// Prefer the caller window if it's a browser window, otherwise use
// the top browser window.
return aWindow &&
aWindow.document.documentElement.getAttribute("windowtype") ==
"navigator:browser"
? aWindow
: BrowserWindowTracker.getTopWindow();
}
// TODO: replace eval with new Function()();
try {
// eslint-disable-next-line no-eval
eval(
"PlacesUIUtils.openTabset = function " +
PlacesUIUtils.openTabset
.toString()
.replace(
/(\s+)(inBackground: loadInBackground,)/,
"$1$2$1userContextId: aEvent.userContextId || 0,"
)
);
} catch (ex) {}
},
openAllPrivate(event) {
event.userContextId = this.container.userContextId;
PlacesUIUtils.openSelectionInTabs(event);
},
openPrivateTab(event) {
let view = event.target.parentElement._view;
PlacesUIUtils._openNodeIn(view.selectedNode, "tab", view.ownerWindow, {
aPrivate: false,
userContextId: this.container.userContextId,
});
},
togglePrivate(aWindow, aTab = aWindow.gBrowser.selectedTab) {
let newTab;
const { gBrowser, gURLBar } = aWindow;
aTab.setAttribute("isToggling", true);
const shouldSelect = aTab == aWindow.gBrowser.selectedTab;
try {
newTab = gBrowser.duplicateTab(aTab);
if (shouldSelect) {
gBrowser.selectedTab = newTab;
const focusUrlbar = gURLBar.focused;
if (focusUrlbar) {
gURLBar.focus();
}
}
gBrowser.removeTab(aTab);
} catch (ex) {
// Can use this to pop up failure message
}
return newTab;
},
browserOpenTabPrivate(aWindow) {
aWindow.openTrustedLinkIn(aWindow.BROWSER_NEW_TAB_URL, "tab", {
userContextId: this.container.userContextId,
});
},
initPrivateTabListeners(aWindow) {
let { gBrowser } = aWindow;
gBrowser.tabContainer.addEventListener("TabSelect", this.onTabSelect);
gBrowser.tabContainer.addEventListener("TabOpen", this.onTabOpen);
gBrowser.privateListener = e => {
let browser = e.target;
let tab = gBrowser.getTabForBrowser(browser);
if (!tab) {
return;
}
let isPrivate = this.isPrivate(tab);
if (!isPrivate) {
if (this.observePrivateTabs) {
this.openTabs.delete(tab);
if (!this.openTabs.size) {
this.clearData();
}
}
return;
}
if (this.observePrivateTabs) {
this.openTabs.add(tab);
}
browser.browsingContext.useGlobalHistory = false;
};
aWindow.addEventListener("XULFrameLoaderCreated", gBrowser.privateListener);
if (this.observePrivateTabs) {
gBrowser.tabContainer.addEventListener("TabClose", this.onTabClose);
}
},
onTabSelect(aEvent) {
let tab = aEvent.target;
if (!tab) {
return;
}
let win = tab.ownerGlobal;
let { PrivateTab } = win;
let prevTab = aEvent.detail.previousTab;
let isPrivate = PrivateTab.isPrivate(tab);
if (tab.userContextId != prevTab.userContextId) {
// Show/hide private mask on browser window
PrivateTab.toggleMask(win);
// Ensure we don't save search suggestions for PrivateTab
win.gURLBar.isPrivate = isPrivate;
// Update selected tab private status for autofill
PrefUtils.set("browser.tabs.selectedTabPrivate", isPrivate);
}
},
async onTabOpen(aEvent) {
// Update tab state cache
let tab = aEvent.target;
if (!tab) {
return;
}
let { PrivateTab } = tab.ownerGlobal;
let isPrivate = PrivateTab.isPrivate(tab);
// if statement is temp solution to prevent containers being dropped on restart.
// The flushing and cache updating should only occur if the parent tab was
// private and the new tab is non-private OR the parent tab was non-private
// and the new tab is private. Otherwise we should rely on default behaviour.
// We also need to be wary of pinned state of tabs, as that may also have been
// affected in the same case.
if (isPrivate) {
let userContextId = isPrivate ? PrivateTab.container.userContextId : 0;
// Duplicating a tab copies the tab state cache from the parent tab.
// Therefore we need to flush the tab state to ensure it's updated,
// then overwrite the tab usercontextid so that any restored tabs
// are opened in the correct container, rather than that of their
// parent tab.
let browser = tab.linkedBrowser;
// Can't update tab state if we can't get the browser
if (browser) {
TabStateFlusher.flush(browser)
.then(() => {
TabStateCache.update(tab.linkedBrowser.permanentKey, {
isPrivate,
userContextId,
});
})
.catch(ex => {
// Sometimes tests fail here
});
}
}
},
onTabClose(aEvent) {
let tab = aEvent.target;
if (!tab) {
return;
}
let { PrivateTab } = tab.ownerGlobal;
if (PrivateTab.isPrivate(tab)) {
PrivateTab.openTabs.delete(tab);
if (!PrivateTab.openTabs.size) {
PrivateTab.clearData();
}
}
},
toggleMask(aWindow) {
let { gBrowser } = aWindow;
let privateMask = aWindow.document.getElementById("private-mask");
if (gBrowser.selectedTab.isToggling) {
privateMask.setAttribute(
"enabled",
gBrowser.selectedTab.userContextId == this.container.userContextId
? "false"
: "true"
);
} else {
privateMask.setAttribute(
"enabled",
gBrowser.selectedTab.userContextId == this.container.userContextId
? "true"
: "false"
);
}
},
get observePrivateTabs() {
return (
!this.config.neverClearData && !this.config.doNotClearDataUntilFxIsClosed
);
},
initCustomFunctions(aWindow) {
let { MozElements, PrivateTab } = aWindow;
MozElements.MozTab.prototype.getAttribute = function(att) {
if (att == "usercontextid" && this.getAttribute("isToggling", false)) {
this.removeAttribute("isToggling");
// If in private tab and we attempt to toggle, remove container, else convert to private tab
return PrivateTab.orig_getAttribute.call(this, att) ==
PrivateTab.container.userContextId
? 0
: PrivateTab.container.userContextId;
}
return PrivateTab.orig_getAttribute.call(this, att);
};
},
orig_getAttribute: Services.wm.getMostRecentBrowserWindow("navigator:browser")
.MozElements.MozTab.prototype.getAttribute,
};

File diff suppressed because it is too large Load Diff

View File

@@ -8,35 +8,34 @@
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<keyset id="privateTab-keyset" insertbefore="mainPopupSet"> <keyset id="privateTab-keyset" insertbefore="mainPopupSet">
<key id="togglePrivateTab-key" modifiers="alt control" key="T" oncommand="PrivateTab.togglePrivate(window)" /> <key id="togglePrivateTab-key" modifiers="alt control" key="T" />
<key id="newPrivateTab-key" modifiers="alt control" key="P" <key id="newPrivateTab-key" modifiers="alt control" key="P" />
oncommand="PrivateTab.browserOpenTabPrivate(window)" />
</keyset> </keyset>
<popupset id="mainPopupSet"> <popupset id="mainPopupSet">
<menupopup id="tabContextMenu"> <menupopup id="tabContextMenu">
<menuitem id="toggleTabPrivateState" data-l10n-id="private-tab" <menuitem id="toggleTabPrivateState" data-l10n-id="private-tab"
data-l10n-args="{&quot;isPrivate&quot;:false}" class="privatetab-icon" acceltext="Ctrl+Alt+T" data-l10n-args="{&quot;isPrivate&quot;:false}" class="privatetab-icon" acceltext="Ctrl+Alt+T"
oncommand="PrivateTab.togglePrivate(window, TabContextMenu.contextTab)" insertafter="context_pinTab" /> insertafter="context_pinTab" />
</menupopup> </menupopup>
<menupopup id="placesContext"> <menupopup id="placesContext">
<menuitem id="openAllPrivate" data-l10n-id="open-all-private" class="privatetab-icon" <menuitem id="openAllPrivate" data-l10n-id="open-all-private" class="privatetab-icon"
oncommand="PrivateTab.openAllPrivate(event);" insertafter="placesContext_openBookmarkLinks:tabs" /> insertafter="placesContext_openBookmarkLinks:tabs" />
<menuitem id="openPrivate" data-l10n-id="open-private-tab" class="privatetab-icon" <menuitem id="openPrivate" data-l10n-id="open-private-tab" class="privatetab-icon"
oncommand="PrivateTab.openPrivateTab(event);" insertafter="placesContext_open:newtab" /> insertafter="placesContext_open:newtab" />
<menuitem id="openAllLinksPrivate" data-l10n-id="open-all-links-private" class="privatetab-icon" <menuitem id="openAllLinksPrivate" data-l10n-id="open-all-links-private" class="privatetab-icon"
oncommand="PrivateTab.openAllPrivate(event);" insertafter="placesContext_openLinks:tabs" /> insertafter="placesContext_openLinks:tabs" />
</menupopup> </menupopup>
</popupset> </popupset>
<menupopup id="menu_FilePopup"> <menupopup id="menu_FilePopup">
<menuitem id="menu_newPrivateTab" data-l10n-id="new-private-tab" acceltext="Ctrl+Alt+P" <menuitem id="menu_newPrivateTab" data-l10n-id="new-private-tab" acceltext="Ctrl+Alt+P"
oncommand="PrivateTab.browserOpenTabPrivate(window)" insertafter="menu_newNavigatorTab" /> insertafter="menu_newNavigatorTab" />
</menupopup> </menupopup>
<menupopup id="contentAreaContextMenu"> <menupopup id="contentAreaContextMenu">
<menuitem id="openLinkInPrivateTab" data-l10n-id="open-link-private" class="privatetab-icon" <menuitem id="openLinkInPrivateTab" data-l10n-id="open-link-private" class="privatetab-icon"
oncommand="PrivateTab.openLink(event);" insertafter="context-openlinkintab" /> insertafter="context-openlinkintab" />
</menupopup> </menupopup>
</overlay> </overlay>

View File

@@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [ EXTRA_JS_MODULES += [
"PrivateTab.jsm", "PrivateTab.sys.mjs",
] ]
BROWSER_CHROME_MANIFESTS += ["test/browser/browser.ini"] BROWSER_CHROME_MANIFESTS += ["test/browser/browser.ini"]

View File

@@ -1,5 +1,3 @@
"use strict";
requestLongerTimeout(2); requestLongerTimeout(2);
async function togglePrivate(tab, skip = false) { async function togglePrivate(tab, skip = false) {
@@ -7,32 +5,32 @@ async function togglePrivate(tab, skip = false) {
return PrivateTab.togglePrivate(window, tab); return PrivateTab.togglePrivate(window, tab);
} }
await openTabContextMenu(tab); await openTabContextMenu(tab);
let openPrivate = document.getElementById("toggleTabPrivateState"); const openPrivate = document.getElementById("toggleTabPrivateState");
openPrivate.click(); openPrivate.click();
return gBrowser.selectedTab; return gBrowser.selectedTab;
} }
// Test elements exist in correct locations // Test elements exist in correct locations
add_task(async function testButtonsExist() { add_task(async function testButtonsExist() {
let b1 = document.getElementById("openAllPrivate"); const b1 = document.getElementById("openAllPrivate");
ok(b1, "Multiple bookmark context menu item added."); ok(b1, "Multiple bookmark context menu item added.");
let b2 = document.getElementById("openAllLinksPrivate"); const b2 = document.getElementById("openAllLinksPrivate");
ok(b2, "Multiple link context menu item added."); ok(b2, "Multiple link context menu item added.");
let b3 = document.getElementById("openPrivate"); const b3 = document.getElementById("openPrivate");
ok(b3, "New private tab item added."); ok(b3, "New private tab item added.");
let b4 = document.getElementById("menu_newPrivateTab"); const b4 = document.getElementById("menu_newPrivateTab");
ok(b4, "Menu item added."); ok(b4, "Menu item added.");
let b5 = document.getElementById("openLinkInPrivateTab"); const b5 = document.getElementById("openLinkInPrivateTab");
ok(b5, "Link context menu item added."); ok(b5, "Link context menu item added.");
let b6 = document.getElementById("toggleTabPrivateState"); const b6 = document.getElementById("toggleTabPrivateState");
ok(b6, "Tab context menu item added."); ok(b6, "Tab context menu item added.");
}); });
// Test container exists // Test container exists
add_task(async function testContainer() { add_task(async function testContainer() {
ContextualIdentityService.ensureDataReady(); ContextualIdentityService.ensureDataReady();
let container = ContextualIdentityService._identities.find( const container = ContextualIdentityService._identities.find(
c => c.name == "Private" (c) => c.name === "Private"
); );
ok(container, "Found Private container."); ok(container, "Found Private container.");
}); });
@@ -58,8 +56,8 @@ add_task(async function testAutofillNotStored() {
"http://mochi.test:8888/browser/browser/components/" + "http://mochi.test:8888/browser/browser/components/" +
"sessionstore/test/browser_formdata_sample.html"; "sessionstore/test/browser_formdata_sample.html";
const OUTER_VALUE = "browser_formdata_" + Math.random(); const OUTER_VALUE = `browser_formdata_${Math.random()}`;
const INNER_VALUE = "browser_formdata_" + Math.random(); const INNER_VALUE = `browser_formdata_${Math.random()}`;
// Creates a tab, loads a page with some form fields, // Creates a tab, loads a page with some form fields,
// modifies their values and closes the tab. // modifies their values and closes the tab.
@@ -68,7 +66,7 @@ add_task(async function testAutofillNotStored() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL); let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
// Toggle to a private tab // Toggle to a private tab
tab = await togglePrivate(tab, true); tab = await togglePrivate(tab, true);
let browser = tab.linkedBrowser; const browser = tab.linkedBrowser;
await promiseBrowserLoaded(browser); await promiseBrowserLoaded(browser);
// Modify form data. // Modify form data.
@@ -85,7 +83,7 @@ add_task(async function testAutofillNotStored() {
} }
await createAndRemoveTab(); await createAndRemoveTab();
let [ const [
{ {
state: { formdata }, state: { formdata },
}, },
@@ -99,7 +97,7 @@ add_task(async function testTabHistoryNotStored() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URI1); let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URI1);
// Make it private // Make it private
tab = await togglePrivate(tab, true); tab = await togglePrivate(tab, true);
let browser = tab.linkedBrowser; const browser = tab.linkedBrowser;
await promiseBrowserLoaded(browser); await promiseBrowserLoaded(browser);
// Open a new URL // Open a new URL
BrowserTestUtils.loadURI(browser, URI2); BrowserTestUtils.loadURI(browser, URI2);
@@ -107,14 +105,14 @@ add_task(async function testTabHistoryNotStored() {
// Remove tab to save state // Remove tab to save state
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
// Verify only non-private data stored // Verify only non-private data stored
let closedTabData = JSON.parse(SessionStore.getClosedTabData(window)).filter( const closedTabData = JSON.parse(SessionStore.getClosedTabData(window)).filter(
data => { (data) => {
return ( return (
data.state.entries[0].url === URI1 || data.state.entries[0].url === URI2 data.state.entries[0].url === URI1 || data.state.entries[0].url === URI2
); );
} }
); );
let privateData = closedTabData.filter(data => { const privateData = closedTabData.filter((data) => {
return data.state.isPrivate === true; return data.state.isPrivate === true;
}); });
const oneClosedTabWithNoPrivateData = const oneClosedTabWithNoPrivateData =
@@ -140,12 +138,12 @@ const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
async function getSuggestionResults() { async function getSuggestionResults() {
await UrlbarTestUtils.promiseSearchComplete(window); await UrlbarTestUtils.promiseSearchComplete(window);
let results = []; const results = [];
let matchCount = UrlbarTestUtils.getResultCount(window); const matchCount = UrlbarTestUtils.getResultCount(window);
for (let i = 0; i < matchCount; i++) { for (let i = 0; i < matchCount; i++) {
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, i); const result = await UrlbarTestUtils.getDetailsOfResultAt(window, i);
if ( if (
result.type == UrlbarUtils.RESULT_TYPE.SEARCH && result.type === UrlbarUtils.RESULT_TYPE.SEARCH &&
result.searchParams.suggestion result.searchParams.suggestion
) { ) {
result.index = i; result.index = i;
@@ -157,15 +155,15 @@ async function getSuggestionResults() {
// Must run first. // Must run first.
add_task(async function prepare() { add_task(async function prepare() {
let suggestionsEnabled = Services.prefs.getBoolPref(SUGGEST_URLBAR_PREF); const suggestionsEnabled = Services.prefs.getBoolPref(SUGGEST_URLBAR_PREF);
Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true); Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
let engine = await SearchTestUtils.promiseNewSearchEngine( const engine = await SearchTestUtils.promiseNewSearchEngine(
getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME
); );
let oldDefaultEngine = await Services.search.getDefault(); const oldDefaultEngine = await Services.search.getDefault();
await Services.search.setDefault(engine); await Services.search.setDefault(engine);
await UrlbarTestUtils.formHistory.clear(); await UrlbarTestUtils.formHistory.clear();
registerCleanupFunction(async function() { registerCleanupFunction(async () => {
Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, suggestionsEnabled); Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, suggestionsEnabled);
await Services.search.setDefault(oldDefaultEngine); await Services.search.setDefault(oldDefaultEngine);
@@ -184,7 +182,7 @@ add_task(async function testSearchSuggestionsNotStored() {
window, window,
value: "foo", value: "foo",
}); });
let results = await getSuggestionResults(); const results = await getSuggestionResults();
ok(!results.length, "Suggestion not be stored in private tab"); ok(!results.length, "Suggestion not be stored in private tab");
// Cleanup // Cleanup
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);

View File

@@ -1,37 +1,33 @@
"use strict"; const { TabStateFlusher } = ChromeUtils.importESModule(
"resource:///modules/sessionstore/TabStateFlusher.sys.mjs"
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
); );
const { TabStateFlusher } = ChromeUtils.import( const { TabStateCache } = ChromeUtils.importESModule(
"resource:///modules/sessionstore/TabStateFlusher.jsm" "resource:///modules/sessionstore/TabStateCache.sys.mjs"
); );
const { TabStateCache } = ChromeUtils.import( const { SearchTestUtils } = ChromeUtils.importESModule(
"resource:///modules/sessionstore/TabStateCache.jsm" "resource://testing-common/SearchTestUtils.sys.mjs"
);
const { SearchTestUtils } = ChromeUtils.import(
"resource://testing-common/SearchTestUtils.jsm"
); );
SearchTestUtils.init(this); SearchTestUtils.init(this);
const { UrlbarTestUtils } = ChromeUtils.import( const { UrlbarTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/UrlbarTestUtils.jsm" "resource://testing-common/UrlbarTestUtils.sys.mjs"
); );
UrlbarTestUtils.init(this); UrlbarTestUtils.init(this);
const { PrivateTab } = ChromeUtils.import("resource:///modules/PrivateTab.jsm"); const { PrivateTab } = ChromeUtils.importESModule(
"resource:///modules/PrivateTab.sys.mjs"
);
const URI1 = "https://test1.example.com/"; const _URI1 = "https://test1.example.com/";
const URI2 = "https://example.com/"; const _URI2 = "https://example.com/";
let OS = AppConstants.platform; const _OS = AppConstants.platform;
function promiseBrowserLoaded( function _promiseBrowserLoaded(
aBrowser, aBrowser,
ignoreSubFrames = true, ignoreSubFrames = true,
wantLoad = null wantLoad = null
@@ -41,21 +37,21 @@ function promiseBrowserLoaded(
// Removes the given tab immediately and returns a promise that resolves when // Removes the given tab immediately and returns a promise that resolves when
// all pending status updates (messages) of the closing tab have been received. // all pending status updates (messages) of the closing tab have been received.
function promiseRemoveTabAndSessionState(tab) { function _promiseRemoveTabAndSessionState(tab) {
let sessionUpdatePromise = BrowserTestUtils.waitForSessionStoreUpdate(tab); const sessionUpdatePromise = BrowserTestUtils.waitForSessionStoreUpdate(tab);
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
return sessionUpdatePromise; return sessionUpdatePromise;
} }
function setPropertyOfFormField(browserContext, selector, propName, newValue) { function _setPropertyOfFormField(browserContext, selector, propName, newValue) {
return SpecialPowers.spawn( return SpecialPowers.spawn(
browserContext, browserContext,
[selector, propName, newValue], [selector, propName, newValue],
(selectorChild, propNameChild, newValueChild) => { (selectorChild, propNameChild, newValueChild) => {
let node = content.document.querySelector(selectorChild); const node = content.document.querySelector(selectorChild);
node[propNameChild] = newValueChild; node[propNameChild] = newValueChild;
let event = node.ownerDocument.createEvent("UIEvents"); const event = node.ownerDocument.createEvent("UIEvents");
event.initUIEvent("input", true, true, node.ownerGlobal, 0); event.initUIEvent("input", true, true, node.ownerGlobal, 0);
node.dispatchEvent(event); node.dispatchEvent(event);
} }
@@ -65,10 +61,10 @@ function setPropertyOfFormField(browserContext, selector, propName, newValue) {
/** /**
* Helper for opening the toolbar context menu. * Helper for opening the toolbar context menu.
*/ */
async function openTabContextMenu(tab) { async function _openTabContextMenu(tab) {
info("Opening tab context menu"); info("Opening tab context menu");
let contextMenu = document.getElementById("tabContextMenu"); const contextMenu = document.getElementById("tabContextMenu");
let openTabContextMenuPromise = BrowserTestUtils.waitForPopupEvent( const openTabContextMenuPromise = BrowserTestUtils.waitForPopupEvent(
contextMenu, contextMenu,
"shown" "shown"
); );