As discussed in Are transitions and animations on Hotwire roadmap?, @sstephenson mentions that there would be utility in exposing appropriate seams to consumer applications.
One potential solution could involve dispatching the existing turbo:-prefixed events as a <turbo-frame> element progresses through a navigation. Those events could be dispatched and bubble up from the turbo-frame element, making the frame available as the CustomEvent.target when appropriate. Page-level turbo:-prefixed events would still dispatch off the document element.
In addition to the value it would bring for ancestors to be notified of various lifecycle hooks, it could also enable the cancelation of turbo-frame visitations, and could expose timing metrics as part of frame-scoped turbo:load events.
From a technical perspective, the events could be dispatched from the various empty FrameController hooks:
|
requestStarted(request: FetchRequest) { |
|
this.element.setAttribute("busy", "") |
|
} |
|
|
|
requestPreventedHandlingResponse(request: FetchRequest, response: FetchResponse) { |
|
this.resolveVisitPromise() |
|
} |
|
|
|
async requestSucceededWithResponse(request: FetchRequest, response: FetchResponse) { |
|
await this.loadResponse(response) |
|
this.resolveVisitPromise() |
|
} |
|
|
|
requestFailedWithResponse(request: FetchRequest, response: FetchResponse) { |
|
console.error(response) |
|
this.resolveVisitPromise() |
|
} |
|
|
|
requestErrored(request: FetchRequest, error: Error) { |
|
console.error(error) |
|
this.resolveVisitPromise() |
|
} |
|
|
|
requestFinished(request: FetchRequest) { |
|
this.element.removeAttribute("busy") |
|
} |
|
|
|
formSubmissionStarted(formSubmission: FormSubmission) { |
|
|
|
} |
|
|
|
formSubmissionSucceededWithResponse(formSubmission: FormSubmission, response: FetchResponse) { |
|
const frame = this.findFrameElement(formSubmission.formElement) |
|
frame.controller.loadResponse(response) |
|
} |
|
|
|
formSubmissionFailedWithResponse(formSubmission: FormSubmission, fetchResponse: FetchResponse) { |
|
|
|
} |
|
|
|
formSubmissionErrored(formSubmission: FormSubmission, error: Error) { |
|
|
|
} |
|
|
|
formSubmissionFinished(formSubmission: FormSubmission) { |
|
|
|
} |
Alternatively, a FrameController could be provided with its own Session instance scoped to the <turbo-frame> element (as opposed to the current implementation which operates on the document.documentElement element).
In theory, there could be a lot of value in unifying the implementations of how a page and a frame navigate, but might involve a larger set of architectural changes. Are there conceptual mismatches between a frame-scoped Session / Navigator pairing and the current implementation which relies on FormInterceptor and LinkInterceptor instances?
As discussed in Are transitions and animations on Hotwire roadmap?, @sstephenson mentions that there would be utility in exposing appropriate seams to consumer applications.
One potential solution could involve dispatching the existing
turbo:-prefixed events as a<turbo-frame>element progresses through a navigation. Those events could be dispatched and bubble up from theturbo-frameelement, making the frame available as theCustomEvent.targetwhen appropriate. Page-levelturbo:-prefixed events would still dispatch off thedocumentelement.In addition to the value it would bring for ancestors to be notified of various lifecycle hooks, it could also enable the cancelation of
turbo-framevisitations, and could expose timing metrics as part of frame-scopedturbo:loadevents.From a technical perspective, the events could be dispatched from the various empty
FrameControllerhooks:turbo/src/core/frames/frame_controller.ts
Lines 75 to 121 in c52d87c
Alternatively, a
FrameControllercould be provided with its ownSessioninstance scoped to the<turbo-frame>element (as opposed to the current implementation which operates on thedocument.documentElementelement).In theory, there could be a lot of value in unifying the implementations of how a page and a frame navigate, but might involve a larger set of architectural changes. Are there conceptual mismatches between a frame-scoped
Session/Navigatorpairing and the current implementation which relies onFormInterceptorandLinkInterceptorinstances?