diff --git a/src/core/frames/frame_controller.ts b/src/core/frames/frame_controller.ts index 2e2d84baa..8e682e454 100644 --- a/src/core/frames/frame_controller.ts +++ b/src/core/frames/frame_controller.ts @@ -4,7 +4,7 @@ import { FetchResponse } from "../../http/fetch_response" import { AppearanceObserver, AppearanceObserverDelegate } from "../../observers/appearance_observer" import { clearBusyState, getAttribute, parseHTMLDocument, markAsBusy } from "../../util" import { FormSubmission, FormSubmissionDelegate } from "../drive/form_submission" -import { Visit } from "../drive/visit" +import { Visit, VisitDelegate } from "../drive/visit" import { Snapshot } from "../snapshot" import { ViewDelegate } from "../view" import { getAction, expandURL, urlsAreEqual, locationIsVisitable, Locatable } from "../url" @@ -261,23 +261,12 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest const action = getAttribute("data-turbo-action", submitter, element, frame) if (isAction(action)) { - const clone = frame.cloneNode(true) + const delegate = new SnapshotSubstitution(frame) const proposeVisit = () => { - const { ownerDocument, id, src } = frame - if (src) { - const snapshotHTML = ownerDocument.documentElement.outerHTML - let snapshot: Snapshot - - const delegate = { - visitStarted(visit: Visit) { - snapshot = visit.view.snapshot - }, - visitCachedSnapshot() { - snapshot.element.querySelector("#" + id)?.replaceWith(clone) - } - } - - session.visit(src, { willRender: false, action, snapshotHTML, delegate }) + if (frame.src) { + const snapshotHTML = frame.ownerDocument.documentElement.outerHTML + + session.visit(frame.src, { willRender: false, action, snapshotHTML, delegate }) } } @@ -403,6 +392,29 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest } } +class SnapshotSubstitution implements Partial { + private readonly clone: Node + private readonly id: string + private snapshot?: Snapshot + + constructor(element: FrameElement) { + this.clone = element.cloneNode(true) + this.id = element.id + } + + visitStarted(visit: Visit) { + this.snapshot = visit.view.snapshot + } + + visitCachedSnapshot() { + const { snapshot, id, clone } = this + + if (snapshot) { + snapshot.element.querySelector("#" + id)?.replaceWith(clone) + } + } +} + function getFrameElementById(id: string | null) { if (id != null) { const element = document.getElementById(id)