Skip to content
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

fix: don't stash away original history methods so other libs can monkeypatch it #11657

Merged
merged 2 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bright-moose-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sveltejs/kit": patch
---

fix: don't stash away original `history` methods so other libs can monkeypatch it
30 changes: 18 additions & 12 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,29 +64,37 @@ const scroll_positions = storage.get(SCROLL_KEY) ?? {};
*/
const snapshots = storage.get(SNAPSHOT_KEY) ?? {};

const original_push_state = BROWSER ? history.pushState : () => {};
const original_replace_state = BROWSER ? history.replaceState : () => {};

if (DEV && BROWSER) {
let warned = false;

const warn = () => {
if (warned) return;

// Rather than saving a pointer to the original history methods, which would prevent monkeypatching by other libs,
// inspect the stack trace to see if we're being called from within SvelteKit.
let stack = new Error().stack?.split('\n');
if (!stack) return;
if (!stack[0].includes('https:') && !stack[0].includes('http:')) stack = stack.slice(1); // Chrome includes the error message in the stack
stack = stack.slice(2); // remove `warn` and the place where `warn` was called
if (stack[0].includes(import.meta.url)) return;

warned = true;

console.warn(
"Avoid using `history.pushState(...)` and `history.replaceState(...)` as these will conflict with SvelteKit's router. Use the `pushState` and `replaceState` imports from `$app/navigation` instead."
);
};

const push_state = history.pushState;
history.pushState = (...args) => {
warn();
return original_push_state.apply(history, args);
return push_state.apply(history, args);
};

const replace_state = history.replaceState;
history.replaceState = (...args) => {
warn();
return original_replace_state.apply(history, args);
return replace_state.apply(history, args);
};
}

Expand Down Expand Up @@ -252,8 +260,7 @@ export async function start(_app, _target, hydrate) {
current_history_index = current_navigation_index = Date.now();

// create initial history entry, so we can return here
original_replace_state.call(
history,
history.replaceState(
{
...history.state,
[HISTORY_INDEX]: current_history_index,
Expand Down Expand Up @@ -1296,7 +1303,7 @@ async function navigate({
[STATES_KEY]: state
};

const fn = replace_state ? original_replace_state : original_push_state;
const fn = replace_state ? history.replaceState : history.pushState;
fn.call(history, entry, '', url);

if (!replace_state) {
Expand Down Expand Up @@ -1812,7 +1819,7 @@ export function pushState(url, state) {
[STATES_KEY]: state
};

original_push_state.call(history, opts, '', resolve_url(url));
history.pushState(opts, '', resolve_url(url));

page = { ...page, state };
root.$set({ page });
Expand Down Expand Up @@ -1849,7 +1856,7 @@ export function replaceState(url, state) {
[STATES_KEY]: state
};

original_replace_state.call(history, opts, '', resolve_url(url));
history.replaceState(opts, '', resolve_url(url));

page = { ...page, state };
root.$set({ page });
Expand Down Expand Up @@ -2180,8 +2187,7 @@ function _start_router() {
// we need to update history, otherwise we have to leave it alone
if (hash_navigating) {
hash_navigating = false;
original_replace_state.call(
history,
history.replaceState(
{
...history.state,
[HISTORY_INDEX]: ++current_history_index,
Expand Down
1 change: 1 addition & 0 deletions packages/kit/src/runtime/client/fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function unlock_fetch() {
if (DEV && BROWSER) {
let can_inspect_stack_trace = false;

// detect whether async stack traces work
const check_stack_trace = async () => {
const stack = /** @type {string} */ (new Error().stack);
can_inspect_stack_trace = stack.includes('check_stack_trace');
Expand Down