From bff80751159bd6d55708bc27212d6d69cd3bfd6b Mon Sep 17 00:00:00 2001 From: Keith Schacht Date: Mon, 29 Jan 2024 16:18:13 -0600 Subject: [PATCH] Add support for `data-turbo-action="refresh"` to force a morph --- src/core/drive/page_view.js | 4 ++- src/core/drive/visit.js | 4 ++- src/core/index.js | 2 +- .../page_refresh_action_destination.html | 27 +++++++++++++++++++ .../fixtures/page_refresh_action_origin.html | 27 +++++++++++++++++++ src/tests/functional/page_refresh_tests.js | 21 +++++++++++++++ src/util.js | 3 ++- 7 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 src/tests/fixtures/page_refresh_action_destination.html create mode 100644 src/tests/fixtures/page_refresh_action_origin.html diff --git a/src/core/drive/page_view.js b/src/core/drive/page_view.js index 1583f25a0..3fb3f0778 100644 --- a/src/core/drive/page_view.js +++ b/src/core/drive/page_view.js @@ -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) { diff --git a/src/core/drive/visit.js b/src/core/drive/visit.js index 132819507..ce9b6ca91 100644 --- a/src/core/drive/visit.js +++ b/src/core/drive/visit.js @@ -39,7 +39,8 @@ export const SystemStatusCode = { export const Direction = { advance: "forward", restore: "back", - replace: "none" + replace: "none", + refresh: "none" } export class Visit { @@ -388,6 +389,7 @@ export class Visit { getHistoryMethodForAction(action) { switch (action) { case "replace": + case "refresh": return history.replaceState case "advance": case "restore": diff --git a/src/core/index.js b/src/core/index.js index a4a4f2d23..3b494341b 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -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 diff --git a/src/tests/fixtures/page_refresh_action_destination.html b/src/tests/fixtures/page_refresh_action_destination.html new file mode 100644 index 000000000..92b52917d --- /dev/null +++ b/src/tests/fixtures/page_refresh_action_destination.html @@ -0,0 +1,27 @@ + + + + + + + + Turbo + + + + + +

Page to be refreshed

+ +

The subtitle will be replaced with morphing. Imagine we are now on a /posts/123 page within the same complex layout.

+ +

Link to a new page but explicitly set the action to refresh

+ +
+ + + + +
+ + diff --git a/src/tests/fixtures/page_refresh_action_origin.html b/src/tests/fixtures/page_refresh_action_origin.html new file mode 100644 index 000000000..ea0489cab --- /dev/null +++ b/src/tests/fixtures/page_refresh_action_origin.html @@ -0,0 +1,27 @@ + + + + + + + + Turbo + + + + + +

Page to be refreshed

+ +

The subtitle will be replaced with morphing. Imagine this page is a /posts/new page within a complex layout.

+ +

Link to a new page but explicitly set the action to refresh

+ +
+ + + + +
+ + diff --git a/src/tests/functional/page_refresh_tests.js b/src/tests/functional/page_refresh_tests.js index 9db411665..d1b59bb5e 100644 --- a/src/tests/functional/page_refresh_tests.js +++ b/src/tests/functional/page_refresh_tests.js @@ -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") diff --git a/src/util.js b/src/util.js index dcb15c31b..6485a9762 100644 --- a/src/util.js +++ b/src/util.js @@ -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": @@ -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) {