mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1924861 - Only show the first history entry if it has user interaction. r=dom-core,omc-reviewers,sessionstore-reviewers,dao,peterv,tabbrowser-reviewers,mviar,sfoster
Differential Revision: https://phabricator.services.mozilla.com/D221390
This commit is contained in:
parent
bf5d05ec06
commit
262a8eb2f9
@ -2524,10 +2524,8 @@ function FillHistoryMenu(event) {
|
||||
if (
|
||||
BrowserUtils.navigationRequireUserInteraction &&
|
||||
entry.hasUserInteraction === false &&
|
||||
// Always allow going to the first and last navigation points.
|
||||
// Always list the current and last navigation points.
|
||||
j != end - 1 &&
|
||||
j != start &&
|
||||
// Always display the current entry
|
||||
j != index
|
||||
) {
|
||||
continue;
|
||||
|
@ -22,6 +22,9 @@ add_task(async function checkReturnToAboutHome() {
|
||||
for (let useFrame of [false, true]) {
|
||||
let tab = await openErrorPage(BAD_CERT, useFrame);
|
||||
let browser = tab.linkedBrowser;
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
|
||||
is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
|
||||
is(
|
||||
@ -83,6 +86,9 @@ add_task(async function checkReturnToPreviousPage() {
|
||||
if (useFrame) {
|
||||
tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
|
||||
browser = tab.linkedBrowser;
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
|
||||
BrowserTestUtils.startLoadingURIString(browser, GOOD_PAGE_2);
|
||||
await BrowserTestUtils.browserLoaded(browser, false, GOOD_PAGE_2);
|
||||
@ -90,6 +96,9 @@ add_task(async function checkReturnToPreviousPage() {
|
||||
} else {
|
||||
tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
|
||||
browser = gBrowser.selectedBrowser;
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
|
||||
info("Loading and waiting for the cert error");
|
||||
let certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
|
||||
|
@ -9,6 +9,9 @@ add_task(async function () {
|
||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, firstLocation);
|
||||
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function () {
|
||||
// Mark the first entry as having been interacted with.
|
||||
content.document.notifyUserGestureActivation();
|
||||
|
||||
// Push the state before maximizing the window and clicking below.
|
||||
content.history.pushState("page2", "page2", "page2");
|
||||
});
|
||||
|
@ -6,6 +6,7 @@ add_task(async function () {
|
||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
|
||||
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
|
||||
content.document.notifyUserGestureActivation();
|
||||
content.history.pushState({}, "2", "2.html");
|
||||
});
|
||||
|
||||
|
@ -13,6 +13,11 @@ add_task(async function checkBackFromInvalidURI() {
|
||||
"about:robots",
|
||||
true
|
||||
);
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function () {
|
||||
// Mark the first entry as having been interacted with.
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
|
||||
info("Loaded about:robots");
|
||||
|
||||
gURLBar.value = "::2600";
|
||||
|
@ -36,8 +36,12 @@ for (let itemsToClear of prefs) {
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let startHistory = content.history.length;
|
||||
content.document.notifyUserGestureActivation();
|
||||
content.history.pushState({}, "");
|
||||
content.document.notifyUserGestureActivation();
|
||||
content.history.pushState({}, "");
|
||||
content.document.notifyUserGestureActivation();
|
||||
|
||||
content.history.back();
|
||||
await new Promise(function (r) {
|
||||
content.onpopstate = r;
|
||||
|
@ -254,6 +254,11 @@ add_task(async function test_aboutwelcome_addonspicker() {
|
||||
["button[data-l10n-id='btn-1-install']"]
|
||||
);
|
||||
|
||||
// Mark the first entry as having been interacted with.
|
||||
SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
|
||||
// Navigate to the next screen to test state on forward/back navigation
|
||||
await clickVisibleButton(browser, "button[value='secondary_button']");
|
||||
// Update the message stub to reflect the addon install
|
||||
|
@ -159,6 +159,10 @@ async function openAboutWelcome() {
|
||||
"about:welcome",
|
||||
true
|
||||
);
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function () {
|
||||
// Mark the first entry as having been interacted with.
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
registerCleanupFunction(() => {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
@ -39,6 +39,10 @@ async function openMRAboutWelcome() {
|
||||
"about:welcome",
|
||||
true
|
||||
);
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function () {
|
||||
// Mark the first entry as having been interacted with.
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
|
||||
return {
|
||||
browser: tab.linkedBrowser,
|
||||
|
@ -23,8 +23,11 @@ async function createPrivateWindow() {
|
||||
privateWindow.gBrowser.selectedBrowser,
|
||||
[],
|
||||
async function () {
|
||||
content.document.notifyUserGestureActivation();
|
||||
content.history.pushState({}, "first item", "first-item.html");
|
||||
content.document.notifyUserGestureActivation();
|
||||
content.history.pushState({}, "second item", "second-item.html");
|
||||
content.document.notifyUserGestureActivation();
|
||||
content.history.pushState({}, "third item", "third-item.html");
|
||||
content.history.back();
|
||||
}
|
||||
|
@ -186,6 +186,11 @@ async function test_scroll_background_tabs(aURL) {
|
||||
let browser = tab.linkedBrowser;
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Add user interaction to the first entry.
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
|
||||
// Scroll down a little.
|
||||
await setScrollPosition(browser, SCROLL_X, SCROLL_Y);
|
||||
await checkScroll(
|
||||
|
@ -137,6 +137,7 @@ add_task(async function test_subframes() {
|
||||
|
||||
// Navigate the subframe.
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
content.document.notifyUserGestureActivation();
|
||||
content.document.querySelector("#a1").click();
|
||||
});
|
||||
await promiseBrowserLoaded(
|
||||
|
@ -40,7 +40,7 @@ async function navigateTo(browser, urls, expectedPersist) {
|
||||
"pageshow"
|
||||
);
|
||||
info(`Navigating back from uri=${browser.currentURI.spec}`);
|
||||
browser.goBack();
|
||||
browser.goBack(false);
|
||||
await pageShowPromise;
|
||||
info(`Got pageshow event`);
|
||||
// Now go forward
|
||||
@ -71,7 +71,7 @@ async function navigateTo(browser, urls, expectedPersist) {
|
||||
pageShowCheck
|
||||
);
|
||||
info(`Navigating back from uri=${browser.currentURI.spec}`);
|
||||
browser.goBack();
|
||||
browser.goBack(false);
|
||||
await pageShowPromise;
|
||||
info(`Got pageshow event`);
|
||||
// Check that the page did not get persisted
|
||||
|
@ -1223,14 +1223,6 @@ void CanonicalBrowsingContext::SetActiveSessionHistoryEntry(
|
||||
mActiveEntry->SharedInfo()->mCacheKey = aUpdatedCacheKey;
|
||||
}
|
||||
|
||||
if (oldActiveEntry) {
|
||||
// aInfo comes from the entry stored in the current document's docshell,
|
||||
// whose interaction state does not get updated. So we instead propagate
|
||||
// state from the previous canonical entry. See bug 1917369.
|
||||
mActiveEntry->SetHasUserInteraction(
|
||||
oldActiveEntry->GetHasUserInteraction());
|
||||
}
|
||||
|
||||
if (IsTop()) {
|
||||
Maybe<int32_t> previousEntryIndex, loadedEntryIndex;
|
||||
shistory->AddToRootSessionHistory(
|
||||
|
@ -3075,7 +3075,8 @@ nsDocShell::GetCanGoBack(bool* aCanGoBack) {
|
||||
}
|
||||
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
|
||||
if (rootSH) {
|
||||
*aCanGoBack = rootSH->CanGo(-1);
|
||||
*aCanGoBack = rootSH->CanGo(
|
||||
-1, StaticPrefs::browser_navigation_requireUserInteraction());
|
||||
MOZ_LOG(gSHLog, LogLevel::Verbose,
|
||||
("nsDocShell %p CanGoBack()->%d", this, *aCanGoBack));
|
||||
|
||||
@ -3084,6 +3085,24 @@ nsDocShell::GetCanGoBack(bool* aCanGoBack) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetCanGoBackIgnoringUserInteraction(bool* aCanGoBack) {
|
||||
*aCanGoBack = false;
|
||||
if (!IsNavigationAllowed(false)) {
|
||||
return NS_OK; // JS may not handle returning of an error code
|
||||
}
|
||||
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
|
||||
if (rootSH) {
|
||||
*aCanGoBack = rootSH->CanGo(-1, false);
|
||||
MOZ_LOG(gSHLog, LogLevel::Verbose,
|
||||
("nsDocShell %p CanGoBackIgnoringUserInteraction()->%d", this,
|
||||
*aCanGoBack));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetCanGoForward(bool* aCanGoForward) {
|
||||
*aCanGoForward = false;
|
||||
@ -3092,7 +3111,8 @@ nsDocShell::GetCanGoForward(bool* aCanGoForward) {
|
||||
}
|
||||
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
|
||||
if (rootSH) {
|
||||
*aCanGoForward = rootSH->CanGo(1);
|
||||
*aCanGoForward = rootSH->CanGo(
|
||||
1, StaticPrefs::browser_navigation_requireUserInteraction());
|
||||
MOZ_LOG(gSHLog, LogLevel::Verbose,
|
||||
("nsDocShell %p CanGoForward()->%d", this, *aCanGoForward));
|
||||
return NS_OK;
|
||||
|
@ -42,6 +42,13 @@ interface nsIWebNavigation : nsISupports
|
||||
*/
|
||||
readonly attribute boolean canGoBack;
|
||||
|
||||
/**
|
||||
* Indicates if the object can go back. If true this indicates that
|
||||
* there is back session history available for navigation, ignoring
|
||||
* whether or not the history has been interacted with by the user.
|
||||
*/
|
||||
readonly attribute boolean canGoBackIgnoringUserInteraction;
|
||||
|
||||
/**
|
||||
* Indicates if the object can go forward. If true this indicates that
|
||||
* there is forward session history available for navigation
|
||||
|
@ -124,13 +124,24 @@ void ChildSHistory::Reload(uint32_t aReloadFlags, ErrorResult& aRv) {
|
||||
aRv = shistory->Reload(aReloadFlags);
|
||||
}
|
||||
|
||||
bool ChildSHistory::CanGo(int32_t aOffset) {
|
||||
bool ChildSHistory::CanGo(int32_t aOffset, bool aRequireUserInteraction) {
|
||||
CheckedInt<int32_t> index = Index();
|
||||
index += aOffset;
|
||||
if (!index.isValid()) {
|
||||
return false;
|
||||
}
|
||||
return index.value() < Count() && index.value() >= 0;
|
||||
|
||||
if (!mHistory || aOffset >= 0) {
|
||||
return index.value() < Count() && index.value() >= 0;
|
||||
}
|
||||
|
||||
if (!aRequireUserInteraction) {
|
||||
return index.value() > 0;
|
||||
}
|
||||
|
||||
bool canGoBack;
|
||||
mHistory->CanGoBackFromEntryAtIndex(Index(), &canGoBack);
|
||||
return canGoBack;
|
||||
}
|
||||
|
||||
void ChildSHistory::Go(int32_t aOffset, bool aRequireUserInteraction,
|
||||
|
@ -64,8 +64,14 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
|
||||
* The CanGo and Go methods are called with an offset from the current index.
|
||||
* Positive numbers go forward in history, while negative numbers go
|
||||
* backwards.
|
||||
* aRequireUserInteraction is used in order to enable the back-button
|
||||
* intervention. This causes an additional check that there must be a previous
|
||||
* entry that has been user-interacted. This check is unnecessary when going
|
||||
* forwards as the latest entry is always available, whether it has been
|
||||
* interacted with or not. This feature is gated by the
|
||||
* browser.navigation.requireUserInteraction pref.
|
||||
*/
|
||||
bool CanGo(int32_t aOffset);
|
||||
bool CanGo(int32_t aOffset, bool aRequireUserInteraction);
|
||||
void Go(int32_t aOffset, bool aRequireUserInteraction, bool aUserActivation,
|
||||
ErrorResult& aRv);
|
||||
void AsyncGo(int32_t aOffset, bool aRequireUserInteraction,
|
||||
|
@ -287,4 +287,10 @@ interface nsISHistory: nsISupports
|
||||
in BrowsingContext aRootBC, in boolean aCloneChildren);
|
||||
|
||||
[noscript, notxpcom] boolean isEmptyOrHasEntriesForSingleTopLevelPage();
|
||||
|
||||
/**
|
||||
* Determine if we can navigate back in history from the entry at aIndex
|
||||
* to an entry that has user interaction.
|
||||
*/
|
||||
boolean canGoBackFromEntryAtIndex(in long aIndex);
|
||||
};
|
||||
|
@ -2057,6 +2057,24 @@ nsSHistory::HasUserInteractionAtIndex(int32_t aIndex) {
|
||||
return entry->GetHasUserInteraction();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHistory::CanGoBackFromEntryAtIndex(int32_t aIndex, bool* aCanGoBack) {
|
||||
*aCanGoBack = false;
|
||||
if (!StaticPrefs::browser_navigation_requireUserInteraction()) {
|
||||
*aCanGoBack = aIndex > 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
for (int32_t i = aIndex - 1; i >= 0; i--) {
|
||||
if (HasUserInteractionAtIndex(i)) {
|
||||
*aCanGoBack = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsSHistory::LoadNextPossibleEntry(
|
||||
int32_t aNewIndex, long aLoadType, uint32_t aHistCmd,
|
||||
nsTArray<LoadEntryResult>& aLoadResults, bool aLoadCurrentEntry,
|
||||
|
@ -280,6 +280,8 @@ skip-if = ["os == 'mac'"]
|
||||
["browser_history_triggeringprincipal_viewsource.js"]
|
||||
https_first_disabled = true
|
||||
|
||||
["browser_initial_entry_without_interaction.js"]
|
||||
|
||||
["browser_isInitialDocument.js"]
|
||||
https_first_disabled = true
|
||||
|
||||
|
@ -81,6 +81,15 @@ async function runTopLevelTest(loadMethod, useHashes = false) {
|
||||
TEST_PAGE + p + "entry=0"
|
||||
);
|
||||
let browser = tab.linkedBrowser;
|
||||
// Add some user interaction to entry 0
|
||||
await BrowserTestUtils.synthesizeMouse(
|
||||
"body",
|
||||
0,
|
||||
0,
|
||||
{},
|
||||
browser.browsingContext,
|
||||
true
|
||||
);
|
||||
|
||||
assertBackForwardState(false, false);
|
||||
|
||||
@ -196,6 +205,15 @@ async function runIframeTest(loadMethod) {
|
||||
IFRAME_PAGE + "?entry=0"
|
||||
);
|
||||
let browser = tab.linkedBrowser;
|
||||
// Add some user interaction to entry 0
|
||||
await BrowserTestUtils.synthesizeMouse(
|
||||
"body",
|
||||
0,
|
||||
0,
|
||||
{},
|
||||
browser.browsingContext,
|
||||
true
|
||||
);
|
||||
|
||||
assertBackForwardState(false, false);
|
||||
|
||||
@ -263,6 +281,15 @@ async function runIframeTest(loadMethod) {
|
||||
IFRAME_PAGE + "?entry=0"
|
||||
);
|
||||
browser = tab.linkedBrowser;
|
||||
// Add some user interaction to entry 0
|
||||
await BrowserTestUtils.synthesizeMouse(
|
||||
"body",
|
||||
0,
|
||||
0,
|
||||
{},
|
||||
browser.browsingContext,
|
||||
true
|
||||
);
|
||||
|
||||
await loadMethod(IFRAME_PAGE + "?entry=1");
|
||||
|
||||
|
@ -26,6 +26,9 @@ add_task(async function test_about_back() {
|
||||
let browser = tab.linkedBrowser;
|
||||
assertBackForwardState(false, false);
|
||||
|
||||
// Add some user interaction to the initial entry
|
||||
await BrowserTestUtils.synthesizeMouse("body", 0, 0, {}, browser, true);
|
||||
|
||||
await followLink(TEST_PAGE + "?entry=1");
|
||||
assertBackForwardState(true, false);
|
||||
|
||||
|
@ -31,6 +31,17 @@ async function runTest(privilegedLoad) {
|
||||
gBrowser,
|
||||
TEST_PAGE + "?entry=0"
|
||||
);
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
// Add some user interaction to the initial entry
|
||||
await BrowserTestUtils.synthesizeMouse(
|
||||
"body",
|
||||
0,
|
||||
0,
|
||||
{},
|
||||
browser.browsingContext,
|
||||
true
|
||||
);
|
||||
|
||||
assertBackForwardState(false, false);
|
||||
|
||||
|
@ -11,11 +11,13 @@ add_setup(async function () {
|
||||
add_task(async () => {
|
||||
await BrowserTestUtils.withNewTab(TEST_URI, async browser => {
|
||||
// Navigate away, after causing a user interaction.
|
||||
SpecialPowers.wrap(document).notifyUserGestureActivation();
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
content.document.notifyUserGestureActivation();
|
||||
});
|
||||
await followLink(TEST_URI + "2.html");
|
||||
|
||||
// Navigate again, without causing a user interaction.
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
content.history.pushState({}, "", "https://example.com/3.html");
|
||||
});
|
||||
|
||||
@ -27,7 +29,7 @@ add_task(async () => {
|
||||
await assertMenulist([TEST_URI + "3.html", TEST_URI]);
|
||||
|
||||
// Go back using history.back, which does not check for user interaction.
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
content.history.back();
|
||||
});
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "https://example.com/";
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.navigation.requireUserInteraction", true]],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async () => {
|
||||
await BrowserTestUtils.withNewTab(TEST_URI, async () => {
|
||||
// Navigate away, without causing a user interaction.
|
||||
await followLink(TEST_URI + "2.html");
|
||||
|
||||
// Wait for the session data to be flushed before continuing the test
|
||||
await new Promise(resolve =>
|
||||
SessionStore.getSessionHistory(gBrowser.selectedTab, resolve)
|
||||
);
|
||||
|
||||
// The entry with no interaction shouldn't appear.
|
||||
await assertMenulist([TEST_URI + "2.html"]);
|
||||
|
||||
const backButton = document.getElementById("back-button");
|
||||
ok(backButton.disabled, "The back button should be disabled.");
|
||||
});
|
||||
});
|
@ -28,11 +28,6 @@ add_task(async () => {
|
||||
// Navigate, causing a hashchange event to fire and call history.replaceState
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#link", {}, browser);
|
||||
|
||||
await assertMenulist([
|
||||
TEST_URI_2 + "#1",
|
||||
TEST_URI_2 + "#inject",
|
||||
TEST_URI_2,
|
||||
TEST_URI,
|
||||
]);
|
||||
await assertMenulist([TEST_URI_2 + "#1", TEST_URI_2, TEST_URI]);
|
||||
});
|
||||
});
|
||||
|
@ -20,6 +20,6 @@ add_task(async () => {
|
||||
// Navigate, causing a hashchange event to fire and call history.replaceState
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#link", {}, browser);
|
||||
|
||||
await assertMenulist([TEST_URI + "#1", TEST_URI + "#inject", TEST_URI]);
|
||||
await assertMenulist([TEST_URI + "#1", TEST_URI]);
|
||||
});
|
||||
});
|
||||
|
@ -27,6 +27,7 @@ async function test_set_focus_after_reuse_bcg() {
|
||||
SITE_B_URL
|
||||
);
|
||||
await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
|
||||
content.document.notifyUserGestureActivation();
|
||||
var button = content.document.querySelector("button");
|
||||
button.click();
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ interface ChildSHistory {
|
||||
[Pure]
|
||||
readonly attribute long index;
|
||||
|
||||
boolean canGo(long aOffset);
|
||||
boolean canGo(long aOffset, optional boolean aRequireUserInteraction = false);
|
||||
[Throws] undefined go(long aOffset, optional boolean aRequireUserInteraction = false, optional boolean aUserActivation = false);
|
||||
|
||||
/**
|
||||
|
@ -36,6 +36,9 @@ add_task(async function doTests() {
|
||||
browser,
|
||||
[TEST_URI, testDocDomain],
|
||||
(aTestURI, aTestDocDomain) => {
|
||||
// Mark the first entry as having been interacted with.
|
||||
content.document.notifyUserGestureActivation();
|
||||
|
||||
content.name = "Test";
|
||||
|
||||
if (aTestDocDomain) {
|
||||
|
@ -445,6 +445,13 @@ nsWebBrowser::GetCanGoBack(bool* aCanGoBack) {
|
||||
return mDocShell->GetCanGoBack(aCanGoBack);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowser::GetCanGoBackIgnoringUserInteraction(bool* aCanGoBack) {
|
||||
NS_ENSURE_STATE(mDocShell);
|
||||
|
||||
return mDocShell->GetCanGoBackIgnoringUserInteraction(aCanGoBack);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowser::GetCanGoForward(bool* aCanGoForward) {
|
||||
NS_ENSURE_STATE(mDocShell);
|
||||
|
@ -34,7 +34,16 @@ export class RemoteWebNavigation {
|
||||
|
||||
get canGoBack() {
|
||||
if (Services.appinfo.sessionHistoryInParent) {
|
||||
return this._browser.browsingContext.sessionHistory?.index > 0;
|
||||
const sessionHistory = this._browser.browsingContext.sessionHistory;
|
||||
return sessionHistory?.canGoBackFromEntryAtIndex(sessionHistory?.index);
|
||||
}
|
||||
return this._canGoBack;
|
||||
}
|
||||
|
||||
get canGoBackIgnoringUserInteraction() {
|
||||
if (Services.appinfo.sessionHistoryInParent) {
|
||||
const sessionHistory = this._browser.browsingContext.sessionHistory;
|
||||
return sessionHistory?.index > 0;
|
||||
}
|
||||
return this._canGoBack;
|
||||
}
|
||||
|
@ -895,7 +895,11 @@
|
||||
.navigationRequireUserInteraction
|
||||
) {
|
||||
var webNavigation = this.webNavigation;
|
||||
if (webNavigation.canGoBack) {
|
||||
if (
|
||||
requireUserInteraction
|
||||
? webNavigation.canGoBack
|
||||
: webNavigation.canGoBackIgnoringUserInteraction
|
||||
) {
|
||||
this._wrapURIChangeCall(() =>
|
||||
webNavigation.goBack(requireUserInteraction)
|
||||
);
|
||||
|
@ -195,6 +195,9 @@ function test() {
|
||||
);
|
||||
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, "about:crashes").then(tab => {
|
||||
// Mark the first entry as having been interacted with.
|
||||
content.document.notifyUserGestureActivation();
|
||||
|
||||
SpecialPowers.spawn(tab.linkedBrowser, [crashes], check_crash_list).then(
|
||||
() => check_submit_pending(tab, crashes)
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user