-
Notifications
You must be signed in to change notification settings - Fork 430
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
Morphing + complete frame issue : Stop reloading turbo frames when complete attribute changes #1175
Morphing + complete frame issue : Stop reloading turbo frames when complete attribute changes #1175
Conversation
} else if (name == "src") { | ||
this.delegate.sourceURLChanged() | ||
} else { | ||
} else if (name == "disabled") { |
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.
figured it's a bit safer
@Intrepidd if you mark the
Would that cover your use case? |
No, I want the frame to be replaced with the content from the page that is being refreshed. Imagine a page where you have a list of record as rows, and by clicking on an edit button (one on each row) you transform the row to a form, through a turbo frame. When submitting the form, you expect it to "close" and render as if you refresh the page ( this behavior happens naturally ) But with a morph refresh, this will happen then a few milliseconds later the form will "open" again. I can try to write a repro if that helps understanding the issue ? |
@jorgemanrubia here is a repository with a repro : https://github.com/Intrepidd/turbo_8_bug_demo And here is a video of the issue CleanShot.2024-02-09.at.10.03.56.mp4As you can see, the frame first resets with the content of the index (expected) but then since the morphing removes the |
510c9ef
to
a8f0845
Compare
@Intrepidd changing the As a workaround here, you could prevent the morphing of the attribute relying on the event. Is not ideal, but that should do it. For example with this stimulus controller: import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
prevent(event) {
event.preventDefault()
}
} To use like: <%= turbo_frame_tag "frame", data: { controller: "event-default", action: "turbo:before-morph-attribute->event-default#prevent" } do %>
# ... As a longer term solution, I wonder if we could use some convention around the current |
@jorgemanrubia Thanks for having a look ! I understand, however this callback is not documented as far as I know, and doesn't seem to make sense in the first place, I fail to understand when such behaviour is expected or wanted. Do you know why it is here in the first place ? I would argue that now more than ever is the perfect time to make a "breaking" change as people are going to upgrade from 7 to 8 and expect some breaking changes.
There is definitely going to be some improvements around the But this would still leave the broken behaviour when no refresh attribute is specified, wouldn't it ? |
@afcapel @seanpdoyle what do you think about removing that callback? I'm trying to think of real scenarios where one wants to mutate the |
From the commit message (the
|
Thanks for the context @seanpdoyle, I had missed that. It seems that this is an internal implementation detail. No reference to this behavior in the docs. So it seems that @Intrepidd original approach is good: it's a callback we can remove. Of course, we need to make sure that |
Good ! Thanks to you both 🙏 What are the next steps to make it a go ? We should probably write a regression test but it's a bit tricky to test that the frame does not reload after a bit of time :
|
@Intrepidd why not try to imitate the example you used in the description for the test: after morphing, the turbo frame contents – which changed through the test – should be reset to the initial state? |
@jorgemanrubia the problem is that it does get changed to the initial state but shortly after switches to the navigated state once the frame has been reloaded. So I'm afraid such test will pass even if the frame gets reloaded in the end. I'll draft up something and we can iterate if needed |
3ae4c66
to
5afc89e
Compare
@jorgemanrubia I managed to write a spec that seems to fail on |
Hi @jorgemanrubia, @Intrepidd, any updates on this PR? This issue is affecting my projects as well, am happy to help. |
Waiting as well regarding the specs 🙏 |
@Intrepidd sorry what's the problem with the specs? The referred flakiness? Is that happening in CI? We definitely need to sort that out, if you want to help with that @benwalks. |
5afc89e
to
14e263e
Compare
14e263e
to
a235658
Compare
@jorgemanrubia my specs were indeed flaky but I think I managed to fix it. So I don't think there are any blockers anymore for this ? |
Thanks a lot @jorgemanrubia for merging ! Any chance we can get a release soon ? As I believe this issue is a blocker for some to update to turbo 8. Thanks ! |
@Intrepidd I've just cut a new release https://github.com/hotwired/turbo/releases/tag/v8.0.4 |
I actually was relying on removing the 'complete' attribute as a convenient way to be able to reload a turbo_frame. I was doing it using turbo_power and sending turbo_streams like |
You may use the reload method. FrameElement.reload() is a function that reloads the frame element from its src. |
Thanks @alexgerber. I have discovered that turbo_power has |
Thanks for fixing this @Intrepidd 😍 |
I encountered the following problem :
consider a turbo frame like so on index.html
When the link is clicked, the HTML will look like this
If the page is then refreshed with morphing, my expectation was that everything will return to the initial state.
However, in practice, the frame first appears to be reset, but then is reloaded and ends up in the second state.
This is because we have a callback that reloads the frame when there is any change on the
complete
attribute :turbo/src/core/frames/frame_controller.js
Lines 101 to 105 in e2e5782
The morphing causes this attribute to change thus the frame to reload.
I don't really understand why we want to reload a frame when the
complete
attribute changes, isn't it supposed to be only a read-only value ?This PR removes the callback on the
complete
attribute, this is probably very naive, happy to explore another route if you point me in the right direction !Repro and video in this comment : #1175 (comment)