Skip to content

Commit

Permalink
Extract SnapshotSubstitution from FrameController
Browse files Browse the repository at this point in the history
To refactor the `proposeVisitIfNavigatedWithAction()` implementation,
this commit extracts the `SnapshotSubstitution` to manage replacing
`Snapshot` references to `<turbo-frame>` 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.
  • Loading branch information
seanpdoyle committed Nov 13, 2021
1 parent 23963f1 commit 33507e5
Showing 1 changed file with 29 additions and 17 deletions.
46 changes: 29 additions & 17 deletions src/core/frames/frame_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 })
}
}

Expand Down Expand Up @@ -403,6 +392,29 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest
}
}

class SnapshotSubstitution implements Partial<VisitDelegate> {
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)
Expand Down

0 comments on commit 33507e5

Please sign in to comment.