Skip to content

Commit

Permalink
Add support for data-turbo-action="refresh" to force a morph
Browse files Browse the repository at this point in the history
  • Loading branch information
krschacht committed Jan 29, 2024
1 parent b7187f1 commit bff8075
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 4 deletions.
4 changes: 3 additions & 1 deletion src/core/drive/page_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ export class PageView extends View {
}

isPageRefresh(visit) {
return !visit || (this.lastRenderedLocation.pathname === visit.location.pathname && visit.action === "replace")
return !visit ||
(this.lastRenderedLocation.pathname === visit.location.pathname && visit.action === "replace") ||
visit.action === "refresh"
}

shouldPreserveScrollPosition(visit) {
Expand Down
4 changes: 3 additions & 1 deletion src/core/drive/visit.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ export const SystemStatusCode = {
export const Direction = {
advance: "forward",
restore: "back",
replace: "none"
replace: "none",
refresh: "none"
}

export class Visit {
Expand Down Expand Up @@ -388,6 +389,7 @@ export class Visit {
getHistoryMethodForAction(action) {
switch (action) {
case "replace":
case "refresh":
return history.replaceState
case "advance":
case "restore":
Expand Down
2 changes: 1 addition & 1 deletion src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function registerAdapter(adapter) {
* @param location Location to visit (a URL or path)
* @param options Options to apply
* @param options.action Type of history navigation to apply ("restore",
* "replace" or "advance")
* "replace", "refresh", or "advance")
* @param options.historyChanged Specifies whether the browser history has
* already been changed for this visit or not
* @param options.referrer Specifies the referrer of this visit such that
Expand Down
27 changes: 27 additions & 0 deletions src/tests/fixtures/page_refresh_action_destination.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html id="html" data-skip-event-details="turbo:submit-start turbo:submit-end turbo:fetch-request-error">
<head>
<meta charset="utf-8">
<meta name="turbo-refresh-method" content="morph">
<meta name="turbo-refresh-scroll" content="reset">

<title>Turbo</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
<script src="/src/tests/fixtures/test.js"></script>
</head>
<body>
<h1>Page to be refreshed</h1>

<h2 id="subtitle">The subtitle will be replaced with morphing. Imagine we are now on a /posts/123 page within the same complex layout.</h2>

<p><a id="refresh-link" data-turbo-action="refresh" href="/src/tests/fixtures/page_refresh_action_destination.html">Link to a new page but explicitly set the action to refresh</a></p>

<form id="form" action="/__turbo/redirect" method="post" class="redirect" data-turbo-action="refresh">
<input id="form-text" type="text" name="text" value="">
<input type="hidden" name="path" value="/src/tests/fixtures/page_refresh_action_destination.html">
<input type="hidden" name="sleep" value="50">
<input id="form-submit" type="submit" value="form[method=post]" data-turbo-action="refresh">
</form>
</body>
</html>
27 changes: 27 additions & 0 deletions src/tests/fixtures/page_refresh_action_origin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html id="html" data-skip-event-details="turbo:submit-start turbo:submit-end turbo:fetch-request-error">
<head>
<meta charset="utf-8">
<meta name="turbo-refresh-method" content="morph">
<meta name="turbo-refresh-scroll" content="reset">

<title>Turbo</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
<script src="/src/tests/fixtures/test.js"></script>
</head>
<body>
<h1>Page to be refreshed</h1>

<h2 id="subtitle">The subtitle will be replaced with morphing. Imagine this page is a /posts/new page within a complex layout.</h2>

<p><a id="refresh-link" data-turbo-action="refresh" href="/src/tests/fixtures/page_refresh_action_destination.html">Link to a new page but explicitly set the action to refresh</a></p>

<form id="form" action="/__turbo/redirect" method="post" class="redirect" data-turbo-action="refresh">
<input id="form-text" type="text" name="text" value="">
<input type="hidden" name="path" value="/src/tests/fixtures/page_refresh_action_destination.html">
<input type="hidden" name="sleep" value="50">
<input id="form-submit" type="submit" value="form[method=post]" data-turbo-action="refresh">
</form>
</body>
</html>
21 changes: 21 additions & 0 deletions src/tests/functional/page_refresh_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,27 @@ test("turbo:before-morph-attribute Stimulus listeners can handle morphing attrib
await expect(page.locator("#test-output")).toHaveText("connected")
})

test("renders a page refresh with morphing when the paths are different but data-turbo-action form is set to 'refresh'", async ({ page }) => {
const subtitle = await page.locator("#subtitle")

await page.goto("/src/tests/fixtures/page_refresh_action_origin.html")

await page.click("#form-submit")
await nextEventNamed(page, "turbo:render", { renderMethod: "morph" })
await nextBeat()
await expect(subtitle).toHaveText("The subtitle will be replaced with morphing. Imagine we are now on a /posts/123 page within the same complex layout.")
})

test("renders a page refresh with morphing when the paths are different but data-turbo-action link is set to 'refresh'", async ({ page }) => {
const subtitle = await page.locator("#subtitle")
//page.on('console', message => console.log(message.text()))

await page.goto("/src/tests/fixtures/page_refresh_action_origin.html")

await page.click("#refresh-link")
await nextEventNamed(page, "turbo:render", { renderMethod: "morph" })
await expect(subtitle).toHaveText("The subtitle will be replaced with morphing. Imagine we are now on a /posts/123 page within the same complex layout.")
})

test("renders a page refresh with morphing when the paths are the same but search params are different", async ({ page }) => {
await page.goto("/src/tests/fixtures/page_refresh.html")
Expand Down
3 changes: 2 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export function waitForLoad(element, timeoutInMilliseconds = 2000) {
export function getHistoryMethodForAction(action) {
switch (action) {
case "replace":
case "refresh":
return history.replaceState
case "advance":
case "restore":
Expand All @@ -155,7 +156,7 @@ export function getHistoryMethodForAction(action) {
}

export function isAction(action) {
return action == "advance" || action == "replace" || action == "restore"
return action == "advance" || action == "replace" || action == "restore" || action == "refresh"
}

export function getVisitAction(...elements) {
Expand Down

0 comments on commit bff8075

Please sign in to comment.