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
Fixed the persisted viewmodel in Chrome #687
base: main
Are you sure you want to change the base?
Fixed the persisted viewmodel in Chrome #687
Conversation
It was working a little bit too well. I've noticed that when you reload the page the viewmodel was also being restored. This has been fixed by checking on load if the page was reloaded through the Performance API Level 1 and Performance API Level 2. |
Thank you for pushing this forward!
This one is a bit problematic, I think we should handle it separately. I see two problems:
Hmm, this is how it works correctly in Firefox - Firefox does preserve form fields on reload, and I use it fairly often to reload a page while writing some comment. Ctrl+F5 drops the state. I think we should not break this behavior, but I don't have any idea how to do so :( |
Whoops, I didn't realize that the old way used
I'll revert this change. Good catch.
At work we're still using WebForms that has on some pages a giant viewstate, which our SEO team isn't a big fan of. That's why I made this change. But nonetheless I'll revert this change instead of fixing it. An XSS exploit is much more troublesome.
I couldn't find a solution for this either. I reverted the |
f97b2e1
to
3c1104d
Compare
Also reverted DotVVM.DomUtils.ts which included an unnecessary line change
if (!bindingContext) | ||
throw new Error(); | ||
var value = valueAccessor(); | ||
var innerBindingContext = bindingContext.extend((_a = {}, _a[foreachCollectionSymbol] = value.data, _a)); | ||
element.innerBindingContext = innerBindingContext; | ||
ko.applyBindingsToDescendants(innerBindingContext, element); | ||
return { controlsDescendantBindings: true }; // do not apply binding again | ||
var _a; |
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.
For some reason the TypeScript compiler moved the variables around...
I'll try to update my TypeScript compiler since the package is not defined in package.json
.
Wait, it is... Now I'm confused 😅
What about this:
This should keep the behavior of non-Chrome browsers unchanged, and fix the Chrome behavior. |
This is already the case in the commit I made yesterday.
This is the problem. There is no way to detect if the reload was a hard-reload. Chromium browsers reset their input-fields when the page was reloaded, Firefox does this only when it was a hard-reload. @exyi said he uses this behavior and this is why I only use the History API on Chromium-browsers. |
Oh, I see - that should work. :-) I am not sure about the detection of Chrome browser - since Microsoft will use Chromium in the next version of Edge, I expect there will be the same problem with the hidden fields. |
The development build of Edge (that is based on Chromium) has the same user agent and vendor (
I think this is a better solution. This way we don't have to whitelist browsers that doens't support reloading the I'll update this PR in the evening. |
This way we can see if the browser supports reloading the hidden input fields. If this is not the case the History API will be used.
577c15b
to
e492384
Compare
Done. I've added a new hidden input called |
After more testing I've found a bug with the History API. When you click a link that navigates to the same URL, Chrome doesn't add a new item in the history (page back). Because of this it'll use the same state thus the old viewmodel is being loaded, while you might expect the initial viewmodel. I've the feeling that this is a never ending war with Chrome 😅. |
What if we try to change |
I've replaced the
<input type="__dot_viewmodel_root">
with the history API as suggested in #685 (comment). I've tested and verified that the new implementation works in Edge, Chrome, Firefox and Internet Explorer. Since I don't have an Apple device at home I cannot test if the implementation works on Safari.Since the input tag is not necessary anymore I've also added the configuration option 'InlineViewModel', which puts the viewmodel in the script-tag instead of the input-tag. I made this an option so libraries that rely on
__dot_viewmodel_root
don't break.Before (
Debug = false, InlineViewModel = false
)After (
Debug = false, InlineViewModel = true
)If this is out-of-scope for this PR I can revert this change and make this a new PR.
fixes #685