vike 0.4.199-commit-33e1230 → 0.4.199-commit-5883046
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
- package/dist/esm/client/client-routing-runtime/history.d.ts +4 -6
- package/dist/esm/client/client-routing-runtime/history.js +32 -17
- package/dist/esm/client/client-routing-runtime/initClientRouter.js +0 -3
- package/dist/esm/client/client-routing-runtime/initOnPopState.d.ts +4 -9
- package/dist/esm/client/client-routing-runtime/initOnPopState.js +19 -21
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +2 -2
- package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
- package/dist/esm/utils/PROJECT_VERSION.js +1 -1
- package/dist/esm/utils/projectInfo.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export {
|
|
2
|
-
type
|
|
1
|
+
export { getHistoryState, enhanceHistoryState, pushHistoryState, type ScrollPosition, saveScrollPosition };
|
|
2
|
+
type StateEnhanced = {
|
|
3
3
|
timestamp: number;
|
|
4
4
|
scrollPosition: null | ScrollPosition;
|
|
5
5
|
triggeredBy: 'user' | 'vike' | 'browser';
|
|
@@ -9,9 +9,7 @@ type ScrollPosition = {
|
|
|
9
9
|
x: number;
|
|
10
10
|
y: number;
|
|
11
11
|
};
|
|
12
|
-
type StateNotInitialized = null | undefined | Partial<StateVikeEnhanced> | StateVikeEnhanced;
|
|
13
12
|
declare function enhanceHistoryState(): void;
|
|
14
|
-
declare function getHistoryState():
|
|
13
|
+
declare function getHistoryState(): StateEnhanced;
|
|
15
14
|
declare function saveScrollPosition(): void;
|
|
16
|
-
declare function
|
|
17
|
-
declare function monkeyPatchHistoryPushState(): void;
|
|
15
|
+
declare function pushHistoryState(url: string, overwriteLastHistoryEntry: boolean): void;
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { getHistoryState, enhanceHistoryState, pushHistoryState, saveScrollPosition };
|
|
2
2
|
import { assert, assertUsage, hasProp, isObject } from './utils.js';
|
|
3
|
+
let initStateEnhanced;
|
|
4
|
+
init();
|
|
3
5
|
// `window.history.state === null` when:
|
|
4
6
|
// - The very first render
|
|
5
7
|
// - Click on `<a href="#some-hash" />`
|
|
6
8
|
// - `location.hash = 'some-hash'`
|
|
7
9
|
function enhanceHistoryState() {
|
|
8
|
-
const
|
|
9
|
-
if (isVikeEnhanced(
|
|
10
|
+
const stateNotEnhanced = getStateNotEnhanced();
|
|
11
|
+
if (isVikeEnhanced(stateNotEnhanced))
|
|
10
12
|
return;
|
|
11
|
-
const stateVikeEnhanced = enhance(
|
|
13
|
+
const stateVikeEnhanced = enhance(stateNotEnhanced);
|
|
12
14
|
replaceHistoryState(stateVikeEnhanced);
|
|
13
15
|
}
|
|
14
|
-
function enhance(
|
|
16
|
+
function enhance(stateNotEnhanced) {
|
|
15
17
|
const timestamp = getTimestamp();
|
|
16
18
|
const scrollPosition = getScrollPosition();
|
|
17
19
|
const triggeredBy = 'browser';
|
|
18
20
|
let stateVikeEnhanced;
|
|
19
|
-
if (!
|
|
21
|
+
if (!stateNotEnhanced) {
|
|
20
22
|
stateVikeEnhanced = {
|
|
21
23
|
timestamp,
|
|
22
24
|
scrollPosition,
|
|
@@ -27,24 +29,32 @@ function enhance(stateNotInitialized) {
|
|
|
27
29
|
else {
|
|
28
30
|
// State information may be incomplete if `window.history.state` is set by an old Vike version. (E.g. `state.timestamp` was introduced for `pageContext.isBackwardNavigation` in `0.4.19`.)
|
|
29
31
|
stateVikeEnhanced = {
|
|
30
|
-
timestamp:
|
|
31
|
-
scrollPosition:
|
|
32
|
-
triggeredBy:
|
|
32
|
+
timestamp: stateNotEnhanced.timestamp ?? timestamp,
|
|
33
|
+
scrollPosition: stateNotEnhanced.scrollPosition ?? scrollPosition,
|
|
34
|
+
triggeredBy: stateNotEnhanced.triggeredBy ?? triggeredBy,
|
|
33
35
|
_isVikeEnhanced: true
|
|
34
36
|
};
|
|
35
37
|
}
|
|
36
38
|
assert(isVikeEnhanced(stateVikeEnhanced));
|
|
37
39
|
return stateVikeEnhanced;
|
|
38
40
|
}
|
|
39
|
-
function
|
|
40
|
-
const state =
|
|
41
|
+
function getStateEnhanced() {
|
|
42
|
+
const state = getStateNotEnhanced();
|
|
43
|
+
// This assert() will most likely eventually cause issues. Let's then:
|
|
44
|
+
// - Replace the assert() call with enhanceHistoryState()
|
|
45
|
+
// - Remove the race condition buster `initStateEnhanced` as it won't be needed anymore
|
|
41
46
|
assert(isVikeEnhanced(state));
|
|
42
47
|
return state;
|
|
43
48
|
}
|
|
44
|
-
function
|
|
49
|
+
function getStateNotEnhanced() {
|
|
45
50
|
const state = window.history.state;
|
|
46
51
|
return state;
|
|
47
52
|
}
|
|
53
|
+
function getHistoryState() {
|
|
54
|
+
if (!initStateEnhanced)
|
|
55
|
+
enhanceHistoryState(); // avoid race condition
|
|
56
|
+
return getStateEnhanced();
|
|
57
|
+
}
|
|
48
58
|
function getScrollPosition() {
|
|
49
59
|
const scrollPosition = { x: window.scrollX, y: window.scrollY };
|
|
50
60
|
return scrollPosition;
|
|
@@ -54,13 +64,13 @@ function getTimestamp() {
|
|
|
54
64
|
}
|
|
55
65
|
function saveScrollPosition() {
|
|
56
66
|
const scrollPosition = getScrollPosition();
|
|
57
|
-
const state =
|
|
67
|
+
const state = getStateEnhanced();
|
|
58
68
|
replaceHistoryState({ ...state, scrollPosition });
|
|
59
69
|
}
|
|
60
|
-
function
|
|
70
|
+
function pushHistoryState(url, overwriteLastHistoryEntry) {
|
|
61
71
|
if (!overwriteLastHistoryEntry) {
|
|
62
72
|
const timestamp = getTimestamp();
|
|
63
|
-
|
|
73
|
+
pushState({
|
|
64
74
|
timestamp,
|
|
65
75
|
// I don't remember why I set it to `null`, maybe because setting it now would be too early? (Maybe there is a delay between renderPageClientSide() is finished and the browser updating the scroll position.) Anyways, it seems like autoSaveScrollPosition() is enough.
|
|
66
76
|
scrollPosition: null,
|
|
@@ -69,14 +79,14 @@ function pushHistory(url, overwriteLastHistoryEntry) {
|
|
|
69
79
|
}, url);
|
|
70
80
|
}
|
|
71
81
|
else {
|
|
72
|
-
replaceHistoryState(
|
|
82
|
+
replaceHistoryState(getStateEnhanced(), url);
|
|
73
83
|
}
|
|
74
84
|
}
|
|
75
85
|
function replaceHistoryState(state, url) {
|
|
76
86
|
const url_ = url ?? null; // Passing `undefined` chokes older Edge versions.
|
|
77
87
|
window.history.replaceState(state, '', url_);
|
|
78
88
|
}
|
|
79
|
-
function
|
|
89
|
+
function pushState(state, url) {
|
|
80
90
|
// Vike should call window.history.pushState() (and not the orignal `pushStateOriginal()`) so that other tools (e.g. user tracking) can listen to Vike's pushState() calls, see https://github.com/vikejs/vike/issues/1582.
|
|
81
91
|
window.history.pushState(state, '', url);
|
|
82
92
|
}
|
|
@@ -114,3 +124,8 @@ function assertStateVikeEnhanced(state) {
|
|
|
114
124
|
assert(hasProp(state.scrollPosition, 'x', 'number') && hasProp(state.scrollPosition, 'y', 'number'));
|
|
115
125
|
}
|
|
116
126
|
}
|
|
127
|
+
function init() {
|
|
128
|
+
enhanceHistoryState();
|
|
129
|
+
initStateEnhanced = true;
|
|
130
|
+
monkeyPatchHistoryPushState();
|
|
131
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { initClientRouter };
|
|
2
2
|
import { assert } from './utils.js';
|
|
3
|
-
import { enhanceHistoryState, monkeyPatchHistoryPushState } from './history.js';
|
|
4
3
|
import { getRenderCount, renderPageClientSide } from './renderPageClientSide.js';
|
|
5
4
|
import { initOnPopState } from './initOnPopState.js';
|
|
6
5
|
import { initOnLinkClick } from './initOnLinkClick.js';
|
|
@@ -29,9 +28,7 @@ async function renderFirstPage() {
|
|
|
29
28
|
}
|
|
30
29
|
function initHistoryAndScroll() {
|
|
31
30
|
setupNativeScrollRestoration();
|
|
32
|
-
enhanceHistoryState();
|
|
33
31
|
autoSaveScrollPosition();
|
|
34
|
-
monkeyPatchHistoryPushState();
|
|
35
32
|
// Handle back-/forward navigation
|
|
36
33
|
initOnPopState();
|
|
37
34
|
}
|
|
@@ -3,25 +3,20 @@ export { updateState };
|
|
|
3
3
|
export { onPopState };
|
|
4
4
|
declare function initOnPopState(): void;
|
|
5
5
|
type Listener = (arg: {
|
|
6
|
-
|
|
6
|
+
previous: ReturnType<typeof getInfo>;
|
|
7
7
|
}) => void | boolean;
|
|
8
8
|
/** Control client-side navigation.
|
|
9
9
|
*
|
|
10
10
|
* https://vike.dev/onPopState
|
|
11
11
|
*/
|
|
12
12
|
declare function onPopState(listener: Listener): void;
|
|
13
|
-
declare function
|
|
13
|
+
declare function getInfo(): {
|
|
14
14
|
url: `/${string}`;
|
|
15
|
-
|
|
15
|
+
state: {
|
|
16
16
|
timestamp: number;
|
|
17
17
|
scrollPosition: null | import("./history.js").ScrollPosition;
|
|
18
18
|
triggeredBy: "user" | "vike" | "browser";
|
|
19
19
|
_isVikeEnhanced: true;
|
|
20
|
-
}
|
|
21
|
-
timestamp: number;
|
|
22
|
-
scrollPosition: null | import("./history.js").ScrollPosition;
|
|
23
|
-
triggeredBy: "user" | "vike" | "browser";
|
|
24
|
-
_isVikeEnhanced: true;
|
|
25
|
-
}> | null | undefined;
|
|
20
|
+
};
|
|
26
21
|
};
|
|
27
22
|
declare function updateState(): void;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export { initOnPopState };
|
|
2
2
|
export { updateState };
|
|
3
3
|
export { onPopState };
|
|
4
|
-
import {
|
|
4
|
+
import { getCurrentUrl, getGlobalObject } from './utils.js';
|
|
5
5
|
import { enhanceHistoryState, getHistoryState } from './history.js';
|
|
6
6
|
import { renderPageClientSide } from './renderPageClientSide.js';
|
|
7
7
|
import { setScrollPosition } from './setScrollPosition.js';
|
|
8
|
-
const globalObject = getGlobalObject('initOnPopState.ts', {
|
|
8
|
+
const globalObject = getGlobalObject('initOnPopState.ts', { previous: getInfo(), listeners: [] });
|
|
9
9
|
function initOnPopState() {
|
|
10
10
|
// - The popstate event is trigged upon:
|
|
11
11
|
// - Back-/forward navigation.
|
|
@@ -17,25 +17,20 @@ function initOnPopState() {
|
|
|
17
17
|
// - `location.hash = 'some-hash'`
|
|
18
18
|
// - The `event` argument of `window.addEventListener('popstate', (event) => /*...*/)` is useless: the History API doesn't provide the previous state (the popped state), see https://stackoverflow.com/questions/48055323/is-history-state-always-the-same-as-popstate-event-state
|
|
19
19
|
window.addEventListener('popstate', async () => {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
const isNewState = window.history.state === null;
|
|
21
|
+
if (isNewState)
|
|
22
|
+
enhanceHistoryState();
|
|
23
|
+
const { previous } = globalObject;
|
|
24
|
+
const current = getInfo();
|
|
25
|
+
globalObject.previous = current;
|
|
26
|
+
const scrollTarget = current.state.scrollPosition || undefined;
|
|
27
|
+
const isHashNavigation = removeHash(current.url) === removeHash(previous.url);
|
|
28
28
|
// - `history.state === null` when:
|
|
29
29
|
// - Click on `<a href="#some-hash" />` (note that Vike's `initOnLinkClick()` handler skips hash links)
|
|
30
30
|
// - `location.hash = 'some-hash'`
|
|
31
31
|
// - `history.state !== null` when `popstate` was triggered by the user clicking on his browser's forward/backward history button.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
assert(isHashNavigation);
|
|
35
|
-
// The browser already scrolled to `#${hash}` => the current scroll position is the right one => we save it with `enhanceHistoryState()`.
|
|
36
|
-
enhanceHistoryState();
|
|
37
|
-
globalObject.previousState = getState();
|
|
38
|
-
}
|
|
32
|
+
const isHashNavigationNew = isHashNavigation && isNewState;
|
|
33
|
+
const isBackwardNavigation = !current.state.timestamp || !previous.state.timestamp ? null : current.state.timestamp < previous.state.timestamp;
|
|
39
34
|
// We have to scroll ourselves because we use `window.history.scrollRestoration = 'manual'`. So far this seems to work. Alternatives in case it doesn't work:
|
|
40
35
|
// - Alternative: we use `window.history.scrollRestoration = 'auto'`
|
|
41
36
|
// - Problem: I don't think it's possbible to set `window.history.scrollRestoration = 'auto'` only for hash navigation and not for non-hash navigations?
|
|
@@ -49,11 +44,14 @@ function initOnPopState() {
|
|
|
49
44
|
if (!isHashNavigationNew) {
|
|
50
45
|
setScrollPosition(scrollTarget);
|
|
51
46
|
}
|
|
47
|
+
else {
|
|
48
|
+
// The browser already scrolled to `#${hash}` => the current scroll position is the right one => we saved it with `enhanceHistoryState()`.
|
|
49
|
+
}
|
|
52
50
|
return;
|
|
53
51
|
}
|
|
54
52
|
let abort;
|
|
55
53
|
globalObject.listeners.forEach((listener) => {
|
|
56
|
-
abort || (abort = listener({
|
|
54
|
+
abort || (abort = listener({ previous }));
|
|
57
55
|
});
|
|
58
56
|
if (abort)
|
|
59
57
|
return;
|
|
@@ -67,15 +65,15 @@ function initOnPopState() {
|
|
|
67
65
|
function onPopState(listener) {
|
|
68
66
|
globalObject.listeners.push(listener);
|
|
69
67
|
}
|
|
70
|
-
function
|
|
68
|
+
function getInfo() {
|
|
71
69
|
return {
|
|
72
70
|
url: getCurrentUrl(),
|
|
73
|
-
|
|
71
|
+
state: getHistoryState()
|
|
74
72
|
};
|
|
75
73
|
}
|
|
76
74
|
function removeHash(url) {
|
|
77
75
|
return url.split('#')[0];
|
|
78
76
|
}
|
|
79
77
|
function updateState() {
|
|
80
|
-
globalObject.
|
|
78
|
+
globalObject.previous = getInfo();
|
|
81
79
|
}
|
|
@@ -10,7 +10,7 @@ import { assertInfo, assertWarning, isReact } from './utils.js';
|
|
|
10
10
|
import { executeOnRenderClientHook } from '../shared/executeOnRenderClientHook.js';
|
|
11
11
|
import { assertHook, getHook } from '../../shared/hooks/getHook.js';
|
|
12
12
|
import { isErrorFetchingStaticAssets, loadUserFilesClientSide } from '../shared/loadUserFilesClientSide.js';
|
|
13
|
-
import {
|
|
13
|
+
import { pushHistoryState } from './history.js';
|
|
14
14
|
import { assertNoInfiniteAbortLoop, getPageContextFromAllRewrites, isAbortError, logAbortErrorHandled } from '../../shared/route/abort.js';
|
|
15
15
|
import { route } from '../../shared/route/index.js';
|
|
16
16
|
import { isClientSideRoutable } from './isClientSideRoutable.js';
|
|
@@ -469,7 +469,7 @@ function changeUrl(url, overwriteLastHistoryEntry) {
|
|
|
469
469
|
if (getCurrentUrl() === url)
|
|
470
470
|
return;
|
|
471
471
|
browserNativeScrollRestoration_disable();
|
|
472
|
-
|
|
472
|
+
pushHistoryState(url, overwriteLastHistoryEntry);
|
|
473
473
|
updateState();
|
|
474
474
|
}
|
|
475
475
|
function handleErrorFetchingStaticAssets(err, pageContext, isFirstRender) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PROJECT_VERSION: "0.4.199-commit-
|
|
1
|
+
export declare const PROJECT_VERSION: "0.4.199-commit-5883046";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Automatically updated by @brillout/release-me
|
|
2
|
-
export const PROJECT_VERSION = '0.4.199-commit-
|
|
2
|
+
export const PROJECT_VERSION = '0.4.199-commit-5883046';
|