From 4ba8aea6a106b65ff99dad242d137c792b96a811 Mon Sep 17 00:00:00 2001 From: Dom Christie Date: Sat, 20 Jul 2024 21:18:51 +0100 Subject: [PATCH] Handle same-page anchor clicks by checking for absence of popstate data. Absent popstate event data suggests that the event originates from a same-page anchor click. Reconcile the empty state by incrementing the History's currentIndex, replacing the null history entry, setting the View's lastRenderedLocation, and then caching it --- src/core/drive/history.js | 11 +++++++---- src/core/session.js | 12 +++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/core/drive/history.js b/src/core/drive/history.js index 569b6a51d..16f11da53 100644 --- a/src/core/drive/history.js +++ b/src/core/drive/history.js @@ -78,14 +78,17 @@ export class History { // Event handlers onPopState = (event) => { - const { turbo } = event.state || {} - if (turbo) { - this.location = new URL(window.location.href) - const { restorationIdentifier, restorationIndex } = turbo + this.location = new URL(window.location.href) + + if (event.state?.turbo) { + const { restorationIdentifier, restorationIndex } = event.state.turbo this.restorationIdentifier = restorationIdentifier const direction = restorationIndex > this.currentIndex ? "forward" : "back" this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location, restorationIdentifier, direction) this.currentIndex = restorationIndex + } else { + this.currentIndex++ + this.delegate.historyPoppedWithEmptyState(this.location) } } } diff --git a/src/core/session.js b/src/core/session.js index 1047d4463..1e1ae92ed 100644 --- a/src/core/session.js +++ b/src/core/session.js @@ -190,6 +190,10 @@ export class Session { } } + historyPoppedWithEmptyState(location) { + this.#reconcileEmptyHistoryEntry(location) + } + // Scroll observer delegate scrollPositionChanged(position) { @@ -233,7 +237,7 @@ export class Session { // Navigator delegate allowsVisitingLocationWithAction(location, action) { - return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location) + return this.applicationAllowsVisitingLocation(location) } visitProposedToLocation(location, options) { @@ -469,6 +473,12 @@ export class Session { get snapshot() { return this.view.snapshot } + + #reconcileEmptyHistoryEntry(location) { + this.history.replace(location) + this.view.lastRenderedLocation = location + this.view.cacheSnapshot() + } } // Older versions of the Turbo Native adapters referenced the