From 2db01fb33fb4789aa0ddd75787432ca3450d36f7 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Wed, 20 Oct 2021 13:34:05 -0700 Subject: [PATCH] [fix] fire navigation-end event only at end of navigation (#2649) --- .changeset/chatty-apricots-fly.md | 5 +++ packages/kit/src/runtime/client/renderer.js | 20 +++++---- packages/kit/src/runtime/client/router.js | 17 +++++--- .../apps/basics/src/routes/redirect/_tests.js | 2 +- .../apps/basics/src/routes/redirect/c.svelte | 2 +- .../apps/basics/src/routes/routing/_tests.js | 12 ++---- .../src/routes/routing/shadow/_tests.js | 4 +- packages/kit/test/test.js | 42 ++++++++++++------- 8 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 .changeset/chatty-apricots-fly.md diff --git a/.changeset/chatty-apricots-fly.md b/.changeset/chatty-apricots-fly.md new file mode 100644 index 000000000000..fed096789767 --- /dev/null +++ b/.changeset/chatty-apricots-fly.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +[fix] fire navigation-end event only at end of navigation diff --git a/packages/kit/src/runtime/client/renderer.js b/packages/kit/src/runtime/client/renderer.js index 92e9f1cf5d4d..79d15f9600d5 100644 --- a/packages/kit/src/runtime/client/renderer.js +++ b/packages/kit/src/runtime/client/renderer.js @@ -204,10 +204,13 @@ export class Renderer { this._init(result); } - /** @param {{ path: string, query: URLSearchParams }} destination */ - notify({ path, query }) { - dispatchEvent(new CustomEvent('sveltekit:navigation-start')); - + /** + * @param {import('./types').NavigationInfo} info + * @param {string[]} chain + * @param {boolean} no_cache + * @param {{hash?: string, scroll: { x: number, y: number } | null, keepfocus: boolean}} [opts] + */ + async handle_navigation(info, chain, no_cache, opts) { if (this.started) { this.stores.navigating.set({ from: { @@ -215,11 +218,13 @@ export class Renderer { query: this.current.page.query }, to: { - path, - query + path: info.path, + query: info.query } }); } + + await this.update(info, chain, no_cache, opts); } /** @@ -291,11 +296,12 @@ export class Renderer { } await 0; - dispatchEvent(new CustomEvent('sveltekit:navigation-end')); + this.loading.promise = null; this.loading.id = null; if (!this.router) return; + const leaf_node = navigation_result.state.branch[navigation_result.state.branch.length - 1]; if (leaf_node && leaf_node.module.router === false) { this.router.disable(); diff --git a/packages/kit/src/runtime/client/router.js b/packages/kit/src/runtime/client/router.js index 9c9a01023982..79c8cb7f710c 100644 --- a/packages/kit/src/runtime/client/router.js +++ b/packages/kit/src/runtime/client/router.js @@ -39,6 +39,8 @@ export class Router { this.base = base; this.routes = routes; this.trailing_slash = trailing_slash; + /** Keeps tracks of multiple navigations caused by redirects during rendering */ + this.navigating = 0; /** @type {import('./renderer').Renderer} */ this.renderer = renderer; @@ -253,6 +255,11 @@ export class Router { throw new Error('Attempted to navigate to a URL that does not belong to this app'); } + if (!this.navigating) { + dispatchEvent(new CustomEvent('sveltekit:navigation-start')); + } + this.navigating++; + // remove trailing slashes if (info.path !== '/') { const has_trailing_slash = info.path.endsWith('/'); @@ -269,11 +276,11 @@ export class Router { } } - this.renderer.notify({ - path: info.path, - query: info.query - }); + await this.renderer.handle_navigation(info, chain, false, { hash, scroll, keepfocus }); - await this.renderer.update(info, chain, false, { hash, scroll, keepfocus }); + this.navigating--; + if (!this.navigating) { + dispatchEvent(new CustomEvent('sveltekit:navigation-end')); + } } } diff --git a/packages/kit/test/apps/basics/src/routes/redirect/_tests.js b/packages/kit/test/apps/basics/src/routes/redirect/_tests.js index 9522daabe147..2c76ba30b1a1 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/_tests.js +++ b/packages/kit/test/apps/basics/src/routes/redirect/_tests.js @@ -5,7 +5,7 @@ export default function (test) { test('redirect', '/redirect', async ({ base, page, clicknav }) => { await clicknav('[href="/redirect/a"]'); - assert.equal(page.url(), `${base}/redirect/c`); + await page.waitForURL(`${base}/redirect/c`); assert.equal(await page.textContent('h1'), 'c'); }); diff --git a/packages/kit/test/apps/basics/src/routes/redirect/c.svelte b/packages/kit/test/apps/basics/src/routes/redirect/c.svelte index 70f3d5c81534..232c276f86cb 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/c.svelte +++ b/packages/kit/test/apps/basics/src/routes/redirect/c.svelte @@ -1 +1 @@ -