Skip to content

Commit

Permalink
Add the target element to turbo:before-fetch-request and turbo:before…
Browse files Browse the repository at this point in the history
…-fetch-response events (#367)

Co-authored-by: John Kapantzakis <kapantzak@192.168.2.5>
  • Loading branch information
kapantzak and John Kapantzakis committed Sep 1, 2021
1 parent eab256b commit c9c1c11
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/core/drive/form_submission.ts
Expand Up @@ -54,7 +54,7 @@ export class FormSubmission {
this.formElement = formElement
this.submitter = submitter
this.formData = buildFormData(formElement, submitter)
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body)
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement)
this.mustRedirect = mustRedirect
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/frames/frame_controller.ts
Expand Up @@ -233,7 +233,7 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest
// Private

private async visit(url: Locatable) {
const request = new FetchRequest(this, FetchMethod.get, expandURL(url))
const request = new FetchRequest(this, FetchMethod.get, expandURL(url), undefined, this.element)

return new Promise<void>(resolve => {
this.resolveVisitPromise = () => {
Expand Down
17 changes: 14 additions & 3 deletions src/http/fetch_request.ts
@@ -1,4 +1,5 @@
import { FetchResponse } from "./fetch_response"
import { FrameElement } from "../elements/frame_element"
import { dispatch } from "../util"

export interface FetchRequestDelegate {
Expand Down Expand Up @@ -47,10 +48,11 @@ export class FetchRequest {
readonly headers: FetchRequestHeaders
readonly url: URL
readonly body?: FetchRequestBody
readonly target?: FrameElement | HTMLFormElement | null
readonly abortController = new AbortController
private resolveRequestPromise = (value: any) => {}

constructor(delegate: FetchRequestDelegate, method: FetchMethod, location: URL, body: FetchRequestBody = new URLSearchParams) {
constructor(delegate: FetchRequestDelegate, method: FetchMethod, location: URL, body: FetchRequestBody = new URLSearchParams, target: FrameElement | HTMLFormElement | null = null) {
this.delegate = delegate
this.method = method
this.headers = this.defaultHeaders
Expand All @@ -60,6 +62,7 @@ export class FetchRequest {
this.body = body
this.url = location
}
this.target = target
}

get location(): URL {
Expand Down Expand Up @@ -98,7 +101,7 @@ export class FetchRequest {

async receive(response: Response): Promise<FetchResponse> {
const fetchResponse = new FetchResponse(response)
const event = dispatch("turbo:before-fetch-response", { cancelable: true, detail: { fetchResponse } })
const event = dispatch("turbo:before-fetch-response", { cancelable: true, detail: { fetchResponse }, target: this.target as EventTarget })
if (event.defaultPrevented) {
this.delegate.requestPreventedHandlingResponse(this, fetchResponse)
} else if (fetchResponse.succeeded) {
Expand Down Expand Up @@ -137,7 +140,15 @@ export class FetchRequest {

private async allowRequestToBeIntercepted(fetchOptions: RequestInit) {
const requestInterception = new Promise(resolve => this.resolveRequestPromise = resolve)
const event = dispatch("turbo:before-fetch-request", { cancelable: true, detail: { fetchOptions, url: this.url.href, resume: this.resolveRequestPromise } })
const event = dispatch("turbo:before-fetch-request", {
cancelable: true,
detail: {
fetchOptions,
url: this.url.href,
resume: this.resolveRequestPromise
},
target: this.target as EventTarget
})
if (event.defaultPrevented) await requestInterception
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/tests/fixtures/form.html
Expand Up @@ -137,7 +137,7 @@
</div>
<hr>
<div id="targets-frame">
<form action="/__turbo/redirect" method="post" data-turbo-frame="frame" class="one">
<form id="form_one" action="/__turbo/redirect" method="post" data-turbo-frame="frame" class="one">
<input type="hidden" name="path" value="/src/tests/fixtures/one.html">
<button type="submit">Submit</button>
</form>
Expand Down
10 changes: 10 additions & 0 deletions src/tests/functional/form_submission_tests.ts
Expand Up @@ -400,6 +400,16 @@ export class FormSubmissionTests extends TurboDriveTestCase {
this.assert.equal(await message.getVisibleText(), "Link!")
}

async "test turbo:before-fetch-request fires on the form element"() {
await this.clickSelector('#targets-frame form.one [type="submit"]')
this.assert.ok(await this.nextEventOnTarget("form_one", "turbo:before-fetch-request"))
}

async "test turbo:before-fetch-response fires on the form element"() {
await this.clickSelector('#targets-frame form.one [type="submit"]')
this.assert.ok(await this.nextEventOnTarget("form_one", "turbo:before-fetch-response"))
}

get formSubmitted(): Promise<boolean> {
return this.hasSelector("html[data-form-submitted]")
}
Expand Down
10 changes: 10 additions & 0 deletions src/tests/functional/frame_tests.ts
Expand Up @@ -199,6 +199,16 @@ export class FrameTests extends TurboDriveTestCase {
this.assert.equal(requestLogs.length, 0)
}

async "test turbo:before-fetch-request fires on the frame element"() {
await this.clickSelector("#hello a")
this.assert.ok(await this.nextEventOnTarget("frame", "turbo:before-fetch-request"))
}

async "test turbo:before-fetch-response fires on the frame element"() {
await this.clickSelector("#hello a")
this.assert.ok(await this.nextEventOnTarget("frame", "turbo:before-fetch-response"))
}

get frameScriptEvaluationCount(): Promise<number | undefined> {
return this.evaluate(() => window.frameScriptEvaluationCount)
}
Expand Down

0 comments on commit c9c1c11

Please sign in to comment.