diff --git a/src/core/drive/morph_renderer.js b/src/core/drive/morph_renderer.js index 2c5d14874..11142463e 100644 --- a/src/core/drive/morph_renderer.js +++ b/src/core/drive/morph_renderer.js @@ -11,6 +11,10 @@ export class MorphRenderer extends PageRenderer { return "morph" } + get shouldAutofocus() { + return false + } + // Private async #morphBody() { diff --git a/src/core/renderer.js b/src/core/renderer.js index 56e73983e..f0a02f581 100644 --- a/src/core/renderer.js +++ b/src/core/renderer.js @@ -16,6 +16,10 @@ export class Renderer { return true } + get shouldAutofocus() { + return true + } + get reloadReason() { return } @@ -40,9 +44,11 @@ export class Renderer { } focusFirstAutofocusableElement() { - const element = this.connectedSnapshot.firstAutofocusableElement - if (element) { - element.focus() + if (this.shouldAutofocus) { + const element = this.connectedSnapshot.firstAutofocusableElement + if (element) { + element.focus() + } } } diff --git a/src/tests/fixtures/page_refresh.html b/src/tests/fixtures/page_refresh.html index ee2ff20b6..689953b99 100644 --- a/src/tests/fixtures/page_refresh.html +++ b/src/tests/fixtures/page_refresh.html @@ -122,7 +122,7 @@

Element with Stimulus controller

Link to another page

- + diff --git a/src/tests/functional/autofocus_tests.js b/src/tests/functional/autofocus_tests.js index 726ef8307..d8f07fa86 100644 --- a/src/tests/functional/autofocus_tests.js +++ b/src/tests/functional/autofocus_tests.js @@ -1,4 +1,5 @@ import { expect, test } from "@playwright/test" +import { nextBody, nextEventNamed } from "../helpers/page" test.beforeEach(async ({ page }) => { await page.goto("/src/tests/fixtures/autofocus.html") @@ -74,3 +75,29 @@ test("receiving a Turbo Stream message with an [autofocus] element when an eleme }) await expect(page.locator("#first-autofocus-element")).toBeFocused() }) + +test("don't focus on [autofocus] elements on page refreshes with morphing", async ({ page }) => { + await page.goto("/src/tests/fixtures/page_refresh.html") + + const input = await page.locator("input[autofocus]") + + await page.evaluate(() => { + document.getElementById("refresh-after-navigation-link").focus() + }) + + await nextBody(page) + + const link = await page.locator("#refresh-after-navigation-link") + expect(link).toBeFocused() + expect(input).not.toBeFocused() + + await page.evaluate(() => { + document.querySelector("#form").requestSubmit() + }) + + await nextEventNamed(page, "turbo:render", { renderMethod: "morph" }) + await nextBody(page) + + expect(input).not.toBeFocused() + expect(link).toBeFocused() +}) diff --git a/src/tests/functional/page_refresh_tests.js b/src/tests/functional/page_refresh_tests.js index c5c116c08..448b79285 100644 --- a/src/tests/functional/page_refresh_tests.js +++ b/src/tests/functional/page_refresh_tests.js @@ -109,7 +109,7 @@ test("renders a page refresh with morphing when the paths are the same but searc await nextEventNamed(page, "turbo:render", { renderMethod: "morph" }) }) -test("renders a page refresh with morphing when the GET form paths are the same but search params are diferent", async ({ page }) => { +test("renders a page refresh with morphing when the GET form paths are the same but search params are different", async ({ page }) => { await page.goto("/src/tests/fixtures/page_refresh.html") const input = page.locator("form[method=get] input[name=query]")