diff --git a/src/core/drive/page_view.js b/src/core/drive/page_view.js index 1583f25a0..442cdd704 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") + if (!visit) { return true } + + return 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 ec7565979..5b23812cb 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 { @@ -389,6 +390,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..f4e30c566 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/core/session.js b/src/core/session.js index eb0c9880c..03b1ecc41 100644 --- a/src/core/session.js +++ b/src/core/session.js @@ -108,10 +108,12 @@ export class Session { } refresh(url, requestId) { + const refreshUrl = url || document.baseURI const isRecentRequest = requestId && this.recentRequests.has(requestId) + if (!isRecentRequest) { this.cache.exemptPageFromPreview() - this.visit(url, { action: "replace" }) + this.visit(refreshUrl, { action: "refresh" }) } } diff --git a/src/tests/functional/page_refresh_tests.js b/src/tests/functional/page_refresh_tests.js index 06a041787..f6da27695 100644 --- a/src/tests/functional/page_refresh_tests.js +++ b/src/tests/functional/page_refresh_tests.js @@ -319,3 +319,10 @@ async function assertPageScroll(page, top, left) { expect(scrollTop).toEqual(top) expect(scrollLeft).toEqual(left) } + +test("Turbo.session.refresh() will refresh current page", async ({ page }) => { + await page.goto("/src/tests/fixtures/page_refresh.html") + await page.evaluate(() => window.Turbo.session.refresh()) + + await nextEventNamed(page, "turbo:render", { renderMethod: "morph" }) +}) \ No newline at end of file diff --git a/src/tests/functional/visit_tests.js b/src/tests/functional/visit_tests.js index 782871747..065ebf22c 100644 --- a/src/tests/functional/visit_tests.js +++ b/src/tests/functional/visit_tests.js @@ -256,6 +256,13 @@ test("Visit direction attribute on a replace visit", async ({ page }) => { await assertVisitDirectionAttribute(page, "none") }) +test("Visit direction when refreshing", async ({ page }) => { + page.evaluate(() => window.Turbo.session.refresh()) + + await assertVisitDirectionAttribute(page, "none") +}) + + test("Turbo history state after a reload", async ({ page }) => { await page.click("#same-origin-link") await nextEventNamed(page, "turbo:load")