Skip to content

Commit

Permalink
Yield visit() as part of Event Details
Browse files Browse the repository at this point in the history
Provide handlers with a way to transform the `fetchResponse` into a
`Turbo.visit()` call without any knowledge of the internal structure or
logic necessary to do so.
  • Loading branch information
seanpdoyle committed Nov 18, 2021
1 parent 712516d commit f0f0dee
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 15 deletions.
11 changes: 9 additions & 2 deletions src/core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,15 @@ export class Session implements FormSubmitObserverDelegate, HistoryDelegate, Lin
this.notifyApplicationAfterFrameRender(fetchResponse, frame);
}

async frameMissing(fetchResponse: FetchResponse, target: FrameElement) {
dispatch("turbo:frame-missing", { target, detail: { fetchResponse } })
frameMissing(fetchResponse: FetchResponse, target: FrameElement) {
const visit = async (options: Partial<VisitOptions> = {}) => {
const responseHTML = await fetchResponse.responseHTML
const { location, redirected, statusCode } = fetchResponse

this.visit(location, { response: { redirected, statusCode, responseHTML }, ...options })
}

dispatch("turbo:frame-missing", { target, detail: { fetchResponse, visit }, cancelable: true })
}

// Application events
Expand Down
11 changes: 2 additions & 9 deletions src/tests/fixtures/frames.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,7 @@
if (target.id == "add-turbo-action-to-frame") {
target.closest("turbo-frame")?.setAttribute("data-turbo-action", "advance")
} else if (target.id == "propose-visit-when-frame-missing") {
addEventListener("turbo:frame-missing", async (event) => {
const { detail: { fetchResponse } } = event
const { location, redirected, statusCode, responseHTML } = fetchResponse
const response = { redirected, statusCode, responseHTML: await responseHTML }

window.Turbo.visit(location, { response })
}, { once: true })
addEventListener("turbo:frame-missing", ({ detail: { visit } }) => visit(), { once: true })
}
})
</script>
Expand Down Expand Up @@ -86,8 +80,7 @@ <h2>Frames: #nested-child</h2>

<turbo-frame id="missing">
<a href="/src/tests/fixtures/frames/frame.html">Missing frame</a>
<form action="/__turbo/redirect">
<input type="hidden" name="path" value="/src/tests/fixtures/frames/frame.html">
<form action="/src/tests/fixtures/frames/frame.html">
<button>Missing frame</button>
</form>
</turbo-frame>
Expand Down
10 changes: 6 additions & 4 deletions src/tests/functional/frame_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ export class FrameTests extends TurboDriveTestCase {
async "test navigating frame resulting in response without matching frame can be re-purposed to navigate entire page"() {
await this.proposeVisitWhenFrameIsMissingInResponse()
await this.clickSelector("#missing a")
await this.nextEventNamed("turbo:load")
await this.nextEventOnTarget("missing", "turbo:frame-missing")
await this.nextBody

this.assert.notOk(await this.hasSelector("#missing"))
this.assert.equal(await (await this.querySelector("h1")).getVisibleText(), "Frames: #frame")
Expand All @@ -434,7 +435,8 @@ export class FrameTests extends TurboDriveTestCase {
async "test submitting frame resulting in response without matching frame can be re-purposed to navigate entire page"() {
await this.proposeVisitWhenFrameIsMissingInResponse()
await this.clickSelector("#missing button")
await this.nextEventNamed("turbo:load")
await this.nextEventOnTarget("missing", "turbo:frame-missing")
await this.nextBody

this.assert.notOk(await this.hasSelector("#missing"))
this.assert.equal(await (await this.querySelector("h1")).getVisibleText(), "Frames: #frame")
Expand All @@ -455,8 +457,8 @@ export class FrameTests extends TurboDriveTestCase {
return this.evaluate(() => window.frameScriptEvaluationCount)
}

proposeVisitWhenFrameIsMissingInResponse(): Promise<void> {
return this.clickSelector("#propose-visit-when-frame-missing")
async proposeVisitWhenFrameIsMissingInResponse(): Promise<void> {
return await this.clickSelector("#propose-visit-when-frame-missing")
}
}

Expand Down

0 comments on commit f0f0dee

Please sign in to comment.