diff --git a/browser/base/content/browser-gestureSupport.js b/browser/base/content/browser-gestureSupport.js index 37882559733d..0c8d4371a878 100644 --- a/browser/base/content/browser-gestureSupport.js +++ b/browser/base/content/browser-gestureSupport.js @@ -736,6 +736,19 @@ var gHistorySwipeAnimation = { } }, + _willGoBack: function HSA_willGoBack(aVal) { + return ( + ((aVal > 0 && this.isLTR) || (aVal < 0 && !this.isLTR)) && this._canGoBack + ); + }, + + _willGoForward: function HSA_willGoForward(aVal) { + return ( + ((aVal > 0 && !this.isLTR) || (aVal < 0 && this.isLTR)) && + this._canGoForward + ); + }, + /** * Updates the animation between two pages in history. * @@ -765,28 +778,25 @@ var gHistorySwipeAnimation = { // Compute the icon radius based on preferences. const radius = this.minRadius + progress * (this.maxRadius - this.minRadius); - if ((aVal >= 0 && this.isLTR) || (aVal <= 0 && !this.isLTR)) { - // The intention is to go back. - if (this._canGoBack) { - this._prevBox.collapsed = false; - this._nextBox.collapsed = true; - this._prevBox.style.translate = `${translate}px 0px`; - if (radius >= 0) { - this._prevBox - .querySelectorAll("circle")[1] - .setAttribute("r", `${radius}`); - } - - if (Math.abs(aVal) >= 0.25) { - // If `aVal` goes above 0.25, it means history navigation will be - // triggered once after the user lifts their fingers, it's time to - // trigger __indicator__ animations by adding `will-navigate` class. - this._prevBox.querySelector("svg").classList.add("will-navigate"); - } else { - this._prevBox.querySelector("svg").classList.remove("will-navigate"); - } + if (this._willGoBack(aVal)) { + this._prevBox.collapsed = false; + this._nextBox.collapsed = true; + this._prevBox.style.translate = `${translate}px 0px`; + if (radius >= 0) { + this._prevBox + .querySelectorAll("circle")[1] + .setAttribute("r", `${radius}`); } - } else if (this._canGoForward) { + + if (Math.abs(aVal) >= 0.25) { + // If `aVal` goes above 0.25, it means history navigation will be + // triggered once after the user lifts their fingers, it's time to + // trigger __indicator__ animations by adding `will-navigate` class. + this._prevBox.querySelector("svg").classList.add("will-navigate"); + } else { + this._prevBox.querySelector("svg").classList.remove("will-navigate"); + } + } else if (this._willGoForward(aVal)) { // The intention is to go forward. this._nextBox.collapsed = false; this._prevBox.collapsed = true; @@ -803,6 +813,11 @@ var gHistorySwipeAnimation = { } else { this._nextBox.querySelector("svg").classList.remove("will-navigate"); } + } else { + this._prevBox.collapsed = true; + this._nextBox.collapsed = true; + this._prevBox.style.translate = "none"; + this._nextBox.style.translate = "none"; } }, diff --git a/widget/tests/browser/browser_test_swipe_gesture.js b/widget/tests/browser/browser_test_swipe_gesture.js index 6c791be2ce86..e3152b4bc363 100644 --- a/widget/tests/browser/browser_test_swipe_gesture.js +++ b/widget/tests/browser/browser_test_swipe_gesture.js @@ -830,7 +830,7 @@ add_task(async () => { await SpecialPowers.pushPrefEnv({ set: [ ["browser.gesture.swipe.left", "Browser:BackOrBackDuplicate"], - ["browser.gesture.swipe.eight", "Browser:ForwardOrForwardDuplicate"], + ["browser.gesture.swipe.right", "Browser:ForwardOrForwardDuplicate"], ["widget.disable-swipe-tracker", false], ["widget.swipe.velocity-twitch-tolerance", 0.0000001], ["widget.swipe.success-velocity-contribution", 0.5], @@ -892,6 +892,90 @@ add_task(async () => { await SpecialPowers.popPrefEnv(); }); +add_task(async () => { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.gesture.swipe.left", "Browser:BackOrBackDuplicate"], + ["browser.gesture.swipe.right", "Browser:ForwardOrForwardDuplicate"], + ["widget.disable-swipe-tracker", false], + ["widget.swipe.velocity-twitch-tolerance", 0.0000001], + ["widget.swipe.success-velocity-contribution", 0.5], + ], + }); + + // Load three pages and go to the second page so that it can be navigated + // to both back and forward. + const tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:about", + true /* waitForLoad */ + ); + + BrowserTestUtils.loadURIString(tab.linkedBrowser, "about:mozilla"); + await BrowserTestUtils.browserLoaded( + tab.linkedBrowser, + false /* includeSubFrames */, + "about:mozilla" + ); + + BrowserTestUtils.loadURIString(tab.linkedBrowser, "about:home"); + await BrowserTestUtils.browserLoaded( + tab.linkedBrowser, + false /* includeSubFrames */, + "about:home" + ); + + gBrowser.goBack(); + await BrowserTestUtils.browserLoaded( + tab.linkedBrowser, + false /* includeSubFrames */, + "about:mozilla" + ); + + // Make sure we can go back and go forward. + ok(gBrowser.webNavigation.canGoBack); + ok(gBrowser.webNavigation.canGoForward); + + // Start a history back pan gesture but keep touching. + await panLeftToRightBegin(tab.linkedBrowser, 100, 100, 1); + + ok( + !gHistorySwipeAnimation._prevBox.collapsed, + "The icon box for the previous navigation should NOT be collapsed" + ); + ok( + gHistorySwipeAnimation._nextBox.collapsed, + "The icon box for the next navigation should be collapsed" + ); + + // Pan back to the opposite direction so that the gesture should be cancelled. + // eslint-disable-next-line no-undef + await NativePanHandler.promiseNativePanEvent( + tab.linkedBrowser, + 100, + 100, + // eslint-disable-next-line no-undef + NativePanHandler.delta, + 0, + // eslint-disable-next-line no-undef + NativePanHandler.updatePhase + ); + + ok( + gHistorySwipeAnimation._prevBox.collapsed, + "The icon box for the previous navigation should be collapsed" + ); + ok( + gHistorySwipeAnimation._nextBox.collapsed, + "The icon box for the next navigation should be collapsed" + ); + + await panLeftToRightEnd(tab.linkedBrowser, 100, 100, 0); + + BrowserTestUtils.removeTab(tab); + await SpecialPowers.popPrefEnv(); +}); + // NOTE: This test listens wheel events so that it causes an overscroll issue // (bug 1800022). To avoid the bug, we need to run this test case at the end // of this file.