From 6eb8444839c0f87b6320b17ddf6f4ad0cde1ca5f Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Sun, 14 Nov 2021 20:48:35 -0500 Subject: [PATCH] Treat response `turbo-frame[disabled]` as missing When a response body has a `turbo-frame` element with an `[id]` that matches the requesting frame, ignore it if it's `[disabled]`. --- src/core/frames/frame_controller.ts | 4 ++-- src/tests/fixtures/frames.html | 7 +++++++ src/tests/fixtures/frames/disabled.html | 13 +++++++++++++ .../fixtures/frames/disabled_recursive.html | 16 ++++++++++++++++ src/tests/functional/frame_tests.ts | 15 +++++++++++++-- 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/tests/fixtures/frames/disabled.html create mode 100644 src/tests/fixtures/frames/disabled_recursive.html diff --git a/src/core/frames/frame_controller.ts b/src/core/frames/frame_controller.ts index 031cb30ec..00ec6e136 100644 --- a/src/core/frames/frame_controller.ts +++ b/src/core/frames/frame_controller.ts @@ -291,11 +291,11 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest const id = CSS.escape(this.id) try { - if (element = activateElement(container.querySelector(`turbo-frame#${id}`), this.currentURL)) { + if (element = activateElement(container.querySelector(`turbo-frame:not([disabled])#${id}`), this.currentURL)) { return element } - if (element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.currentURL)) { + if (element = activateElement(container.querySelector(`turbo-frame:not([disabled])[src][recurse~=${id}]`), this.currentURL)) { await element.loaded return await this.extractForeignFrameElement(element) } diff --git a/src/tests/fixtures/frames.html b/src/tests/fixtures/frames.html index a061e4c33..c7cc7030f 100644 --- a/src/tests/fixtures/frames.html +++ b/src/tests/fixtures/frames.html @@ -110,6 +110,13 @@

Frames: #nested-child

+ + + + + + + diff --git a/src/tests/fixtures/frames/disabled.html b/src/tests/fixtures/frames/disabled.html new file mode 100644 index 000000000..b38300b0c --- /dev/null +++ b/src/tests/fixtures/frames/disabled.html @@ -0,0 +1,13 @@ + + + + + Disabled Frame + + + + +

Frame: #disabled loaded

+
+ + diff --git a/src/tests/fixtures/frames/disabled_recursive.html b/src/tests/fixtures/frames/disabled_recursive.html new file mode 100644 index 000000000..ac48697bd --- /dev/null +++ b/src/tests/fixtures/frames/disabled_recursive.html @@ -0,0 +1,16 @@ + + + + + Disabled Recursive Frame + + + + +

Frame: #disabled_recursive loaded

+ +

Frame: #disabled_composer loaded

+
+
+ + diff --git a/src/tests/functional/frame_tests.ts b/src/tests/functional/frame_tests.ts index b3e13a3e8..ccd80b705 100644 --- a/src/tests/functional/frame_tests.ts +++ b/src/tests/functional/frame_tests.ts @@ -148,6 +148,12 @@ export class FrameTests extends TurboDriveTestCase { this.assert.ok(await this.querySelector("#recursive details:not([open])")) } + async "test loading a page with a does not lazily loads the matching frame"() { + await this.nextBeat + + this.assert.notOk(await this.hasSelector("#disabled_recursive h2")) + } + async "test submitting a form that redirects to a page with a which lazily loads a matching frame"() { await this.nextBeat await this.clickSelector("#recursive summary") @@ -158,6 +164,12 @@ export class FrameTests extends TurboDriveTestCase { this.assert.ok(await this.querySelector("#recursive details:not([open])")) } + async "test loading a page with a does not lazily load the matching frame"() { + await this.nextBeat + + this.assert.notOk(await this.hasSelector("#disabled h2")) + } + async "test removing [disabled] attribute from eager-loaded frame navigates it"() { await this.remote.execute(() => document.getElementById("frame")?.setAttribute("disabled", "")) await this.remote.execute((src: string) => document.getElementById("frame")?.setAttribute("src", "/src/tests/fixtures/frames/frame.html")) @@ -207,8 +219,7 @@ export class FrameTests extends TurboDriveTestCase { async "test 'turbo:frame-render' is triggered after frame has finished rendering"() { await this.clickSelector("#frame-part") - await this.nextEventNamed("turbo:frame-render") // recursive - const { fetchResponse } = await this.nextEventNamed("turbo:frame-render") + const { fetchResponse } = await this.nextEventOnTarget("part", "turbo:frame-render") this.assert.include(fetchResponse.response.url, "/src/tests/fixtures/frames/part.html") }