diff --git a/src/core/frames/frame_controller.js b/src/core/frames/frame_controller.js index 07764fc86..306f33f74 100644 --- a/src/core/frames/frame_controller.js +++ b/src/core/frames/frame_controller.js @@ -424,7 +424,7 @@ export class FrameController { #findFrameElement(element, submitter) { const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target") - return getFrameElementById(id) ?? this.element + return FrameElement.getElementById(id) ?? this.element } async extractForeignFrameElement(container) { @@ -468,7 +468,7 @@ export class FrameController { } if (id) { - const frameElement = getFrameElementById(id) + const frameElement = FrameElement.getElementById(id) if (frameElement) { return !frameElement.disabled } @@ -554,15 +554,6 @@ export class FrameController { } } -function getFrameElementById(id) { - if (id != null) { - const element = document.getElementById(id) - if (element instanceof FrameElement) { - return element - } - } -} - function activateElement(element, currentURL) { if (element) { const src = element.getAttribute("src") diff --git a/src/core/frames/frame_redirector.js b/src/core/frames/frame_redirector.js index 10aeee6cc..f968c2dde 100644 --- a/src/core/frames/frame_redirector.js +++ b/src/core/frames/frame_redirector.js @@ -76,8 +76,9 @@ export class FrameRedirector { #findFrameElement(element, submitter) { const id = submitter?.getAttribute("data-turbo-frame") || element.getAttribute("data-turbo-frame") if (id && id != "_top") { - const frame = this.element.querySelector(`#${id}:not([disabled])`) - if (frame instanceof FrameElement) { + const frame = FrameElement.getElementById(id) + + if (frame && !frame.disabled && this.element.contains(frame)) { return frame } } diff --git a/src/core/session.js b/src/core/session.js index cdb978348..3c81f13f5 100644 --- a/src/core/session.js +++ b/src/core/session.js @@ -163,9 +163,9 @@ export class Session { const frameTarget = element.getAttribute("data-turbo-frame") const frame = frameTarget == "_top" ? null : - document.getElementById(frameTarget) || findClosestRecursively(element, "turbo-frame:not([disabled])") + FrameElement.getElementById(frameTarget) || findClosestRecursively(element, "turbo-frame") - if (isUnsafe || isStream || frame instanceof FrameElement) { + if (isUnsafe || isStream || (frame && !frame.disabled)) { return false } else { const location = new URL(element.href) diff --git a/src/elements/frame_element.js b/src/elements/frame_element.js index 8dc2890f3..f01c36c7e 100644 --- a/src/elements/frame_element.js +++ b/src/elements/frame_element.js @@ -28,6 +28,21 @@ export class FrameElement extends HTMLElement { return ["disabled", "loading", "src"] } + /** + * Returns the `` element located by its `[id]` attribute. + * Returns `null` when there is not element with a matching `[id]`, or when + * the element with a matching `[id]` is not a ``. + */ + static getElementById(id) { + if (id) { + const element = document.getElementById(id) + + if (element instanceof this) { + return element + } + } + } + constructor() { super() this.delegate = new FrameElement.delegateConstructor(this)