-
Notifications
You must be signed in to change notification settings - Fork 439
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
Create Frame Snapshot from Fetch Response HTML #887
Conversation
d42605e
to
61fe92a
Compare
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.
This looks good to me, @seanpdoyle. Thanks for tidying up!
I honestly didn't know if I should create an issue or write it here. Since v7.3.0 the turbo frame missing event doesn't break out of the frame anymore, this has a big impact for a project that I'm working on. We had to downgrade to v.7.2.5 again, and would like to have re-add this behavior back. Will this PR also support this? document.addEventListener('turbo:frame-missing', event => {
event.preventDefault() // Cancel event to not replace turbo-frame content with "Content missing"
// With 7.3.0: Break out of the turbo frame and visit the response url -> this sucks since we have to request a second time
event.detail.visit(event.detail.response.url) // Currently we have to do this
// Break out of the turbo frame and replace current view with its response -> doesn't currently work as the responseHTML is missing in the response
// TODO: Wait for https://github.com/hotwired/turbo/pull/887
// event.detail.visit(event.detail.response.url, { response: event.detail.response })
}) Maybe I'm unaware of something? |
61fe92a
to
3882c6a
Compare
After the changes made in [@hotwired/turbohotwired#867][] and changes made in [@hotwired/turbo-railshotwired#428][] (the canonical server-side implementation), Turbo expects full HTML documents in response to requests with `Turbo-Frame:` headers. Prior to this commit, the `FrameController` compensated for missing pieces of an HTML document by taking an HTML "snapshot" of the current page through the `<html>` element's [outerHTML][]. This commit changes the `fetchResponseLoaded` callback to read the `responseHTML` directly from the `FetchResponse`, since that will be a fully formed HTML document in Turbo v7.3.0 and later. To support that change, this commit also updates various `src/test/fixtures` files to render fully-formed HTML documents. [@hotwired/turbohotwired#867]: hotwired#867 [@hotwired/turbo-railshotwired#428]: hotwired/turbo-rails#428 [outerHTML]: https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
3882c6a
to
ed72ba1
Compare
I've rebased this to account for the migration away from TypeScript. |
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.
Thanks @seanpdoyle. This looks great.
@afcapel, is this something we can merge as part of the work you've been doing? Not sure if you've got a released planned or not.
Yes, it looks good, thanks @seanpdoyle! |
if (frame.src) { | ||
const { statusCode, redirected } = fetchResponse | ||
const responseHTML = frame.ownerDocument.documentElement.outerHTML | ||
const responseHTML = await fetchResponse.responseHTML |
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.
This will likely cause a full page reload because the responseHTML
will only have a minimal <head>
and therefore the tracked elements won't be identical.
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.
Thank you for catching this @domchristie. I'm not sure how to best resolve the issue mentioned in #1047. Do you have an idea on what to change?
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.
@seanpdoyle Can this line be reverted or will that break the intention of #867 / hotwired/turbo-rails#428?
Otherwise, I'm beginning to feel that the different visit usages warrant a different modelling.
For example:
- A standard Visit that navigates from one location to the next
- A same-page anchor Visit
- A redirected Visit
- A Frame Visit (promoted to a Visit using data-turbo-action
Each has different expectations and outcomes, which hints that they could be different classes that share the same API
#1044 (comment)
This would be a fairly big refactor, but might be worth it?
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.
#430 explores a FrameVisit
, but I'm unsure of what changes would be necessary to incorporate a fix for this issue.
Can this line be reverted or will that break the intention of #867 / hotwired/turbo-rails#4
I'm unsure of the implications of reverting it. Is there a conditional that could be introduced to support responses without a <head>
and responses from newer turbo-rails
versions that send a minimal head?
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.
I'm unsure of the implications of reverting it.
It seems like v7.3.0 includes #867 so reverting should work (although I'm not sure how!?)
Off the top of my head (pun intended ;), I'm not sure how HeadSnapshot
could distinguish between a "minimal layout" head from a frame visit and standard visit, where the page's tracked assets have actually changed
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.
but I'm unsure of what changes would be necessary to incorporate a fix for this issue.
It doesn't feel right to me that we call session.proposeVisitIfNavigatedWithAction
after rendering a frame response. (In the same way it doesn't feel right to propose a second visit after rendering a redirected response.) In these cases, we're not "visiting" a new location, we're just using the side-effects of the visit lifecycle.
In terms of what I had in mind for implementing different visit types: I was thinking that each Visit type could share an interface, and each implementation could respond accordingly (e.g. a RedirectVisit
wouldn't dispatch any events because the Visit lifecycle events have already been broadcast by the initial Visit.)
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.
Any progress?
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.
This change broke Restoration Visits with turbo-frame data-turbo-action="advance"
.
see:
- Issue: Turbo frame history not navigating properly w/ back button after upgrading from 7 to 8
- PR: Support back button (restore) even if page loaded in frame does not contain matching HEAD
Is this something we can revert or is there a different approach we can take?
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.
also see #1300
After the changes made in @hotwired/turbo#867 and changes made in @hotwired/turbo-rails#428 (the canonical server-side implementation), Turbo expects full HTML documents in response to requests with
Turbo-Frame:
headers.Prior to this commit, the
FrameController
compensated for missing pieces of an HTML document by taking an HTML "snapshot" of the current page through the<html>
element's outerHTML.This commit changes the
fetchResponseLoaded
callback to read theresponseHTML
directly from theFetchResponse
, since that will be a fully formed HTML document in Turbo v7.3.0 and later.To support that change, this commit also updates various
src/test/fixtures
files to render fully-formed HTML documents.