Skip to content

Commit

Permalink
Turbo.visit(..., { frame: "frame" })
Browse files Browse the repository at this point in the history
Add support for driving a `<turbo-frame>` element from a
`Turbo.visit(...)` call.

Internally, Turbo has some constraints for finding and driving a
`<turbo-frame>` element, namely that it has an `[id]` attribute and that
it is not marked with a `[disabled]` attribute.

Supporting `Turbo.visit` calls that specify a `frame:` option
provide an opportunity to encapsulate those details from callers while
still providing element finding utility.
  • Loading branch information
seanpdoyle committed Jul 28, 2022
1 parent 1563ebb commit 7e12fa5
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/core/drive/visit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export type VisitOptions = {
updateHistory: boolean
restorationIdentifier?: string
shouldCacheSnapshot: boolean
frame?: string
}

const defaultOptions: VisitOptions = {
Expand Down
10 changes: 9 additions & 1 deletion src/core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,15 @@ export class Session
}

visit(location: Locatable, options: Partial<VisitOptions> = {}): Promise<void> {
return this.navigator.proposeVisit(expandURL(location), options)
const { frame } = options || {}
const frameElement = document.getElementById(frame || "")

if (frameElement instanceof FrameElement) {
frameElement.src = location.toString()
return frameElement.loaded
} else {
return this.navigator.proposeVisit(expandURL(location), options)
}
}

connectStreamSource(source: StreamSource) {
Expand Down
2 changes: 1 addition & 1 deletion src/elements/frame_element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface FrameElementDelegate extends LinkInterceptorDelegate, FormSubmi
export class FrameElement extends HTMLElement {
static delegateConstructor: new (element: FrameElement) => FrameElementDelegate

loaded: Promise<FetchResponse | void> = Promise.resolve()
loaded: Promise<void> = Promise.resolve()
readonly delegate: FrameElementDelegate

static get observedAttributes(): FrameElementObservedAttribute[] {
Expand Down
16 changes: 16 additions & 0 deletions src/tests/functional/frame_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ test.beforeEach(async ({ page }) => {
await readEventLogs(page)
})

test("test navigating a frame with Turbo.visit", async ({ page }) => {
const pathname = "/src/tests/fixtures/frames/frame.html"

await page.locator("#frame").evaluate((frame) => frame.setAttribute("disabled", ""))
await page.evaluate((pathname) => window.Turbo.visit(pathname, { frame: "frame" }), pathname)
await nextBeat()

assert.equal(await page.textContent("#frame h2"), "Frames: #frame", "does not navigate a disabled frame")

await page.locator("#frame").evaluate((frame) => frame.removeAttribute("disabled"))
await page.evaluate((pathname) => window.Turbo.visit(pathname, { frame: "frame" }), pathname)
await nextBeat()

assert.equal(await page.textContent("#frame h2"), "Frame: loaded", "navigates the target frame")
})

test("test navigating a frame a second time does not leak event listeners", async ({ page }) => {
await withoutChangingEventListenersCount(page, async () => {
await page.click("#outer-frame-link")
Expand Down

0 comments on commit 7e12fa5

Please sign in to comment.