Skip to content

Commit f3979cd

Browse files
committed
When performing a restoration visit, consider the original visit's direction and apply it appropriately according to whether traveling forward or backward in history stack.
This de-couples a visit's history direction from its view transition direction. Multi-page applications may now implement coherent view transitions using any combination of turbo links and the browser's back & forward buttons.
1 parent c29b9b9 commit f3979cd

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

src/core/drive/history.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,13 @@ export class History {
8787
this.location = new URL(window.location.href)
8888
const { restorationIdentifier, restorationIndex } = turbo
8989
this.restorationIdentifier = restorationIdentifier
90-
const direction = restorationIndex > this.currentIndex ? "forward" : "back"
91-
this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location, restorationIdentifier, direction)
90+
const direction = this.restorationVisitDirection(restorationIdentifier, restorationIndex)
91+
92+
this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(
93+
this.location,
94+
restorationIdentifier,
95+
direction
96+
)
9297
this.currentIndex = restorationIndex
9398
}
9499
}
@@ -109,4 +114,16 @@ export class History {
109114
pageIsLoaded() {
110115
return this.pageLoaded || document.readyState == "complete"
111116
}
117+
118+
restorationVisitDirection(restorationIdentifier, restorationIndex) {
119+
const historyDirection = restorationIndex > this.currentIndex ? "forward" : "back"
120+
const originalVisitDirection =
121+
this.restorationData[restorationIdentifier]?.direction === "back" ? "back" : "forward"
122+
123+
return historyDirection === "forward" ? originalVisitDirection : this.oppositeDirection(originalVisitDirection)
124+
}
125+
126+
oppositeDirection(direction) {
127+
return direction === "forward" ? "back" : "forward"
128+
}
112129
}

src/core/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export function registerAdapter(adapter) {
3434
* @param options Options to apply
3535
* @param options.action Type of history navigation to apply ("restore",
3636
* "replace" or "advance")
37+
* @param options.direction Logical direction of the navigation, applies to
38+
* view transitions ("forward", "back")
3739
* @param options.historyChanged Specifies whether the browser history has
3840
* already been changed for this visit or not
3941
* @param options.referrer Specifies the referrer of this visit such that

src/core/session.js

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ export class Session {
9595
visit(location, options = {}) {
9696
const frameElement = options.frame ? document.getElementById(options.frame) : null
9797

98+
if (["forward", "back"].includes(options.direction)) {
99+
this.history.updateRestorationData({ direction: options.direction })
100+
}
101+
98102
if (frameElement instanceof FrameElement) {
99103
const action = options.action || getVisitAction(frameElement)
100104

0 commit comments

Comments
 (0)