From 33507e5ecb48aa9adc3dfc180eea22f6673286b9 Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Fri, 12 Nov 2021 23:51:27 -0500 Subject: [PATCH] Extract SnapshotSubstitution from FrameController To refactor the `proposeVisitIfNavigatedWithAction()` implementation, this commit extracts the `SnapshotSubstitution` to manage replacing `Snapshot` references to `` elements whose visits are promoted to page-wide state. The class partially implement the `VisitDelegate` interface so that it can be passed directly as a `delegate:` option to the `session.visit()` call. --- src/core/frames/frame_controller.ts | 46 ++++++++++++++++++----------- 1 file changed, 29 insertions(+), 17 deletions(-) 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)