diff --git a/src/core/frames/frame_controller.js b/src/core/frames/frame_controller.js index 7487e4363..8265a8193 100644 --- a/src/core/frames/frame_controller.js +++ b/src/core/frames/frame_controller.js @@ -131,7 +131,7 @@ export class FrameController { async loadResponse(fetchResponse) { if (fetchResponse.redirected || (fetchResponse.succeeded && fetchResponse.isHTML)) { - this.sourceURL = fetchResponse.response.url + this.sourceURL = fetchResponse.response.url + this.#hashFromSourceURL } try { @@ -530,6 +530,13 @@ export class FrameController { } } + get #hashFromSourceURL() { + if (this.sourceURL) { + return expandURL(this.sourceURL).hash + } + return "" + } + set sourceURL(sourceURL) { this.#ignoringChangesToAttribute("src", () => { this.element.src = sourceURL ?? null diff --git a/src/tests/fixtures/frames.html b/src/tests/fixtures/frames.html index 86d19e633..b28e6cbe0 100644 --- a/src/tests/fixtures/frames.html +++ b/src/tests/fixtures/frames.html @@ -40,6 +40,7 @@

Frames: #frame

Navigate #frame from within + Navigate #frame with hash Navigate #frame with ?key=value Navigate #frame from within with a[data-turbo-action="advance"] Visit one.html diff --git a/src/tests/functional/frame_tests.js b/src/tests/functional/frame_tests.js index 1987a74f6..e7706744c 100644 --- a/src/tests/functional/frame_tests.js +++ b/src/tests/functional/frame_tests.js @@ -848,6 +848,17 @@ test("a turbo-frame that has been driven by a[data-turbo-action] can be navigate await expect(page).toHaveURL(withPathname("/src/tests/fixtures/frames/hello.html")) }) +test("navigating a frame with a link that has a path and hash preserves the hash", async ({ page }) => { + await page.click("#link-frame-with-hash") + await nextEventNamed(page, "turbo:load") + + await expect(page.locator("#frame h2")).toHaveText("Frame: Loaded") + await expect(page).toHaveURL(/#frame-hash$/) + + const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + expect(src).toContain("#frame-hash") +}) + test("navigating turbo-frame from within with a[data-turbo-action=advance] pushes URL state", async ({ page }) => { await page.click("#link-nested-frame-action-advance") await nextEventNamed(page, "turbo:load")