From 5af1e0bb5ae4b8b98e409845f03b78d3f4b6904e 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 | 6 ++++++ src/tests/fixtures/frames/disabled.html | 13 +++++++++++++ .../fixtures/frames/disabled_recursive.html | 16 ++++++++++++++++ src/tests/functional/frame_tests.ts | 15 +++++++++++++-- 5 files changed, 50 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 b85ba3bcb..8068cc92e 100644 --- a/src/core/frames/frame_controller.ts +++ b/src/core/frames/frame_controller.ts @@ -290,11 +290,11 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest let element const id = CSS.escape(this.id) - 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 40debb498..b99e41739 100644 --- a/src/tests/fixtures/frames.html +++ b/src/tests/fixtures/frames.html @@ -100,9 +100,15 @@

Frames: #nested-child

data-turbo-eval=false script

+ + + + + + Visit self.html Visit form-redirect.html 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 95300a8a5..665d3e2f5 100644 --- a/src/tests/functional/frame_tests.ts +++ b/src/tests/functional/frame_tests.ts @@ -146,6 +146,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") @@ -156,6 +162,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")) @@ -205,8 +217,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") }