-
Notifications
You must be signed in to change notification settings - Fork 436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prepare Frame Form Submission fetch headers #166
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,13 +42,15 @@ export interface FetchRequestOptions { | |
export class FetchRequest { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The changes to this file can be simplified by asking the delegate to prepare headers in diff --git a/src/http/fetch_request.ts b/src/http/fetch_request.ts
index 532ea3e..b4205a2 100644
--- a/src/http/fetch_request.ts
+++ b/src/http/fetch_request.ts
@@ -50,13 +50,13 @@ export class FetchRequest {
constructor(delegate: FetchRequestDelegate, method: FetchMethod, location: URL, body: FetchRequestBody = new URLSearchParams) {
this.delegate = delegate
this.method = method
+ this.headers = this.defaultHeaders
if (this.isIdempotent) {
this.url = mergeFormDataEntries(location, [ ...body.entries() ])
} else {
this.body = body
this.url = location
}
- this.headers = prepareHeadersForRequest(this)
}
get location(): URL {
@@ -77,8 +77,9 @@ export class FetchRequest {
async perform(): Promise<FetchResponse> {
const { fetchOptions } = this
- dispatch("turbo:before-fetch-request", { detail: { fetchOptions } })
try {
+ this.delegate.prepareHeadersForRequest?.(this.headers, this)
+ dispatch("turbo:before-fetch-request", { detail: { fetchOptions } })
this.delegate.requestStarted(this)
const response = await fetch(this.url.href, fetchOptions)
return await this.receive(response)
@@ -121,14 +122,12 @@ export class FetchRequest {
get abortSignal() {
return this.abortController.signal
}
-}
-function prepareHeadersForRequest(fetchRequest: FetchRequest) {
- const headers = { "Accept": "text/html, application/xhtml+xml" }
- if (typeof fetchRequest.delegate.prepareHeadersForRequest == "function") {
- fetchRequest.delegate.prepareHeadersForRequest(headers, fetchRequest)
+ get defaultHeaders() {
+ return {
+ "Accept": "text/html, application/xhtml+xml"
+ }
}
- return headers
}
function mergeFormDataEntries(url: URL, entries: [string, FormDataEntryValue][]): URL { |
||
readonly delegate: FetchRequestDelegate | ||
readonly method: FetchMethod | ||
readonly headers: FetchRequestHeaders | ||
readonly url: URL | ||
readonly body?: FetchRequestBody | ||
readonly abortController = new AbortController | ||
|
||
constructor(delegate: FetchRequestDelegate, method: FetchMethod, location: URL, body: FetchRequestBody = new URLSearchParams) { | ||
this.delegate = delegate | ||
this.method = method | ||
this.headers = this.defaultHeaders | ||
if (this.isIdempotent) { | ||
this.url = mergeFormDataEntries(location, [ ...body.entries() ]) | ||
} else { | ||
|
@@ -75,6 +77,7 @@ export class FetchRequest { | |
|
||
async perform(): Promise<FetchResponse> { | ||
const { fetchOptions } = this | ||
this.delegate.prepareHeadersForRequest?.(this.headers, this) | ||
dispatch("turbo:before-fetch-request", { detail: { fetchOptions } }) | ||
try { | ||
this.delegate.requestStarted(this) | ||
|
@@ -112,27 +115,19 @@ export class FetchRequest { | |
} | ||
} | ||
|
||
get isIdempotent() { | ||
return this.method == FetchMethod.get | ||
get defaultHeaders() { | ||
return { | ||
"Accept": "text/html, application/xhtml+xml" | ||
} | ||
} | ||
|
||
get headers() { | ||
const headers = { ...this.defaultHeaders } | ||
if (typeof this.delegate.prepareHeadersForRequest == "function") { | ||
this.delegate.prepareHeadersForRequest(headers, this) | ||
} | ||
return headers | ||
get isIdempotent() { | ||
return this.method == FetchMethod.get | ||
} | ||
|
||
get abortSignal() { | ||
return this.abortController.signal | ||
} | ||
|
||
get defaultHeaders() { | ||
return { | ||
"Accept": "text/html, application/xhtml+xml" | ||
} | ||
} | ||
} | ||
|
||
function mergeFormDataEntries(url: URL, entries: [string, FormDataEntryValue][]): URL { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main instinct was to prefer a more explicit, layered mutation over the recursive style proposed by https://github.com/hotwired/turbo/pull/110/files#diff-68b647dc2963716dc27c070f261d0b942ee9c00be7c4149ecb3a5acd94842d40, but the more I pulled on that thread, the more changes it required to stick.
Is there an alternative delegator pattern that could still leverage the late-binding values that the
get headers()
property provides without recursively walking a chain of objects that coincidentally declareprepareHeadersForRequest()
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the only impact we are aware of right now involves forms. We could consider isolating the change to forms only. Something like:
src/core/drive/form_submission.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point. What bothers me the most is that checking that
this.delegate
(aFormSubmissionDelegate
instance) is of a different interface than theFetchRequestDelegate
. The fact that they both declareprepareHeadersForRequest
is a coincidence that signals to me that there's some more Typescript-driven design thinking we need to do to chain these things together in a more type-aware manner.The change in this PR is at least more explicit in that way: FrameController has direct access to a FormSubmission instance, which itself has direct access to a FetchRequest. It's access that circumvents the delegator pattern, but it at least interacts with properties that are type checked and are part of the intermediate objects' public interfaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.