зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1644914 - Give out user interactions to session history entries when system principal initiates a load. r=smaug
This is a pretty cheap way of fixing this bug by saying nsDocShell::loadURI calls done with a system principal will add user interaction to the current page. This takes advantage of the fact that all UI code for loading URIs goes through this code path. Note that during debugging I've found other cases where SH entries would be added with a system principal, most notably when navigating to URL hashes/fragments (example.com#hash). I'm not sure why this is happening but it doesn't go through nsDocShell::loadURI. Differential Revision: https://phabricator.services.mozilla.com/D127558
This commit is contained in:
Родитель
e664fcf0f0
Коммит
479107443c
|
@ -850,6 +850,29 @@ nsresult nsDocShell::LoadURI(nsDocShellLoadState* aLoadState,
|
|||
"Shouldn't be loading from an entry when calling InternalLoad "
|
||||
"from LoadURI");
|
||||
|
||||
// If we have a system triggering principal, we can assume that this load was
|
||||
// triggered by some UI in the browser chrome, such as the URL bar or
|
||||
// bookmark bar. This should count as a user interaction for the current sh
|
||||
// entry, so that the user may navigate back to the current entry, from the
|
||||
// entry that is going to be added as part of this load.
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal =
|
||||
aLoadState->TriggeringPrincipal();
|
||||
if (triggeringPrincipal && triggeringPrincipal->IsSystemPrincipal()) {
|
||||
if (mozilla::SessionHistoryInParent()) {
|
||||
WindowContext* topWc = mBrowsingContext->GetTopWindowContext();
|
||||
if (topWc && !topWc->IsDiscarded()) {
|
||||
MOZ_ALWAYS_SUCCEEDS(topWc->SetSHEntryHasUserInteraction(true));
|
||||
}
|
||||
} else {
|
||||
bool oshe = false;
|
||||
nsCOMPtr<nsISHEntry> currentSHEntry;
|
||||
GetCurrentSHEntry(getter_AddRefs(currentSHEntry), &oshe);
|
||||
if (currentSHEntry) {
|
||||
currentSHEntry->SetHasUserInteraction(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = InternalLoad(aLoadState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ support-files =
|
|||
skip-if =
|
||||
os == "linux" && bits == 64 && !debug # Bug 1607713
|
||||
[browser_backforward_userinteraction_about.js]
|
||||
[browser_backforward_userinteraction_systemprincipal.js]
|
||||
[browser_bug1543077-3.js]
|
||||
[browser_bug1594938.js]
|
||||
[browser_bug1206879.js]
|
||||
|
|
|
@ -353,12 +353,6 @@ add_task(async function test_pushState() {
|
|||
await runTopLevelTest(pushState);
|
||||
});
|
||||
|
||||
// Test that when the pref is flipped, we are skipping history
|
||||
// entries without user interaction when using loadURI.
|
||||
add_task(async function test_loadURI() {
|
||||
await runTopLevelTest(loadURI);
|
||||
});
|
||||
|
||||
// Test that when the pref is flipped, we are skipping history
|
||||
// entries without user interaction when following a link.
|
||||
add_task(async function test_followLink() {
|
||||
|
|
|
@ -26,10 +26,10 @@ add_task(async function test_about_back() {
|
|||
let browser = tab.linkedBrowser;
|
||||
assertBackForwardState(false, false);
|
||||
|
||||
await loadURI(TEST_PAGE + "?entry=1");
|
||||
await followLink(TEST_PAGE + "?entry=1");
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
await loadURI(TEST_PAGE + "?entry=2");
|
||||
await followLink(TEST_PAGE + "?entry=2");
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
// Add some user interaction to entry 2
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE =
|
||||
getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://example.com"
|
||||
) + "dummy_page.html";
|
||||
|
||||
async function runTest(privilegedLoad) {
|
||||
// Test with both pref on and off
|
||||
for (let requireUserInteraction of [true, false]) {
|
||||
Services.prefs.setBoolPref(
|
||||
"browser.navigation.requireUserInteraction",
|
||||
requireUserInteraction
|
||||
);
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
TEST_PAGE + "?entry=0"
|
||||
);
|
||||
|
||||
assertBackForwardState(false, false);
|
||||
|
||||
await followLink(TEST_PAGE + "?entry=1");
|
||||
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
await followLink(TEST_PAGE + "?entry=2");
|
||||
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
await followLink(TEST_PAGE + "?entry=3");
|
||||
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
// Entry 4 will be added through a user action in browser chrome,
|
||||
// giving user interaction to entry 3. Entry 4 should not gain automatic
|
||||
// user interaction.
|
||||
await privilegedLoad(TEST_PAGE + "?entry=4");
|
||||
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
await followLink(TEST_PAGE + "?entry=5");
|
||||
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
if (!requireUserInteraction) {
|
||||
await goBack(TEST_PAGE + "?entry=4");
|
||||
}
|
||||
await goBack(TEST_PAGE + "?entry=3");
|
||||
|
||||
if (!requireUserInteraction) {
|
||||
await goBack(TEST_PAGE + "?entry=2");
|
||||
await goBack(TEST_PAGE + "?entry=1");
|
||||
}
|
||||
|
||||
assertBackForwardState(true, true);
|
||||
|
||||
await goBack(TEST_PAGE + "?entry=0");
|
||||
|
||||
assertBackForwardState(false, true);
|
||||
|
||||
if (!requireUserInteraction) {
|
||||
await goForward(TEST_PAGE + "?entry=1");
|
||||
await goForward(TEST_PAGE + "?entry=2");
|
||||
}
|
||||
|
||||
await goForward(TEST_PAGE + "?entry=3");
|
||||
|
||||
assertBackForwardState(true, true);
|
||||
|
||||
if (!requireUserInteraction) {
|
||||
await goForward(TEST_PAGE + "?entry=4");
|
||||
}
|
||||
|
||||
await goForward(TEST_PAGE + "?entry=5");
|
||||
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
|
||||
Services.prefs.clearUserPref("browser.navigation.requireUserInteraction");
|
||||
}
|
||||
|
||||
// Test that we add a user interaction flag to the previous site when loading
|
||||
// a new site from user interaction with privileged UI, e.g. through the
|
||||
// URL bar.
|
||||
add_task(async function test_urlBar() {
|
||||
await runTest(async function(url) {
|
||||
info(`Loading ${url} via the URL bar.`);
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let loaded = BrowserTestUtils.browserLoaded(browser, false, url);
|
||||
gURLBar.focus();
|
||||
gURLBar.value = url;
|
||||
gURLBar.goButton.click();
|
||||
await loaded;
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче