Skip to content

Commit

Permalink
Fix viewmodel restore on back/forward navigation
Browse files Browse the repository at this point in the history
* In Firefox, this worked, but also restored it on page reloads
* In Chromium, viewmodel was always reset to the initial state

This patch unifies the behavior to restore the viewmodel, but not if it is in page reload
  • Loading branch information
exyi committed Aug 16, 2024
1 parent d824028 commit 8b6325c
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions src/Framework/Framework/Resources/Scripts/dotvvm-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,20 @@ export function getStateManager(): StateManager<RootViewModel> { return getCoreS

let initialViewModelWrapper: any;

function isBrowserReload() {
return (performance.getEntriesByType("navigation").at(-1) as PerformanceNavigationTiming)?.type == "reload";

Check failure on line 73 in src/Framework/Framework/Resources/Scripts/dotvvm-base.ts

View workflow job for this annotation

GitHub Actions / JS unit tests

TypeError: performance.getEntriesByType is not a function at isBrowserReload (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/Resources/Scripts/dotvvm-base.ts:73:25) at initCore (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/Resources/Scripts/dotvvm-base.ts:84:10) at Object.init (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/Resources/Scripts/dotvvm-root.ts:37:13) at initDotvvm (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/Resources/Scripts/tests/helper.ts:48:12) at Object.<anonymous> (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/Resources/Scripts/tests/sanity.test.ts:9:15) at Promise.then.completed (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/utils.js:298:28) at new Promise (<anonymous>) at callAsyncCircusFn (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/utils.js:231:10) at _callCircusTest (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/run.js:316:40) at processTicksAndRejections (node:internal/process/task_queues:96:5) at _runTest (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/run.js:252:3) at _runTestsForDescribeBlock (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/run.js:126:9) at run (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/run.js:71:3) at runAndTransformResultsToJestFormat (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) at jestAdapter (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) at runTestInternal (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-runner/build/runTest.js:367:16) at runTest (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-runner/build/runTest.js:444:34) at Object.worker (/home/runner/work/dotvvm/dotvvm/src/Framework/Framework/node_modules/jest-runner/build/testWorker.js:106:12)
}

export function initCore(culture: string): void {
if (currentCoreState) {
throw new Error("DotVVM is already loaded");
}

// load the viewmodel
const thisViewModel = initialViewModelWrapper = JSON.parse(getViewModelStorageElement().value);
// if it is back-navigation, we use the viewmodel from history.state
const thisViewModel = initialViewModelWrapper =
(isBrowserReload() ? null : history.state?.viewModel) ??
JSON.parse(getViewModelStorageElement().value);

resourceLoader.registerResources(thisViewModel.renderedResources)

Expand Down Expand Up @@ -125,7 +132,7 @@ const getViewModelStorageElement = () =>

function persistViewModel() {
const viewModel = getState()
const persistedViewModel = { ...initialViewModelWrapper, viewModel };

getViewModelStorageElement().value = JSON.stringify(persistedViewModel);
history.replaceState({ viewModel: { ...initialViewModelWrapper, viewModel } }, "")
// avoid storing the viewmodel hidden field, as Firefox would also reuse it on page reloads
getViewModelStorageElement()?.remove()
}

0 comments on commit 8b6325c

Please sign in to comment.