diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index 16fa8f61ac82..8f9bbea78f59 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -22,7 +22,7 @@ import { HttpError, Redirect } from '../control.js'; import { stores } from './singletons.js'; import { unwrap_promises } from '../../utils/promises.js'; import * as devalue from 'devalue'; -import { INDEX_KEY, PRIORITY_PAGE, PRIORITY_VIEWPORT, SCROLL_KEY } from './constants.js'; +import { INDEX_KEY, PRELOAD_PRIORITIES, SCROLL_KEY } from './constants.js'; const routes = parse(nodes, server_loads, dictionary, matchers); @@ -1236,11 +1236,11 @@ export function create_client({ target, base }) { if (external) continue; - if (options.preload_code === PRIORITY_VIEWPORT) { + if (options.preload_code === PRELOAD_PRIORITIES.viewport) { observer.observe(a); } - if (options.preload_code === PRIORITY_PAGE) { + if (options.preload_code === PRELOAD_PRIORITIES.page) { preload_code(/** @type {URL} */ (url).pathname); } } diff --git a/packages/kit/src/runtime/client/constants.js b/packages/kit/src/runtime/client/constants.js index b661784ca359..14c986d5c07f 100644 --- a/packages/kit/src/runtime/client/constants.js +++ b/packages/kit/src/runtime/client/constants.js @@ -1,7 +1,10 @@ export const SCROLL_KEY = 'sveltekit:scroll'; export const INDEX_KEY = 'sveltekit:index'; -export const PRIORITY_TAP = 1; -export const PRIORITY_HOVER = 2; -export const PRIORITY_VIEWPORT = 3; -export const PRIORITY_PAGE = 4; +export const PRELOAD_PRIORITIES = /** @type {const} */ ({ + tap: 1, + hover: 2, + viewport: 3, + page: 4, + off: -1 +}); diff --git a/packages/kit/src/runtime/client/utils.js b/packages/kit/src/runtime/client/utils.js index a23cd6f4e4ef..4348b773ad65 100644 --- a/packages/kit/src/runtime/client/utils.js +++ b/packages/kit/src/runtime/client/utils.js @@ -1,7 +1,7 @@ import { writable } from 'svelte/store'; import { assets } from '../paths.js'; import { version } from '../env.js'; -import { PRIORITY_HOVER, PRIORITY_PAGE, PRIORITY_TAP, PRIORITY_VIEWPORT } from './constants.js'; +import { PRELOAD_PRIORITIES } from './constants.js'; /* global __SVELTEKIT_APP_VERSION_FILE__, __SVELTEKIT_APP_VERSION_POLL_INTERVAL__ */ @@ -26,34 +26,54 @@ export function scroll_state() { const warned = new WeakSet(); +/** @typedef {keyof typeof valid_link_options} LinkOptionName */ + +const valid_link_options = /** @type {const} */ ({ + 'preload-code': ['', 'off', 'tap', 'hover', 'viewport', 'page'], + 'preload-data': ['', 'off', 'tap', 'hover'], + noscroll: ['', 'off'], + reload: ['', 'off'] +}); + /** + * @template {LinkOptionName} T * @param {Element} element - * @param {string} name - * @param {string | null} value - * @param {string[]} options + * @param {T} name */ -function validate(element, name, value, options) { - if (warned.has(element)) return; - if (value === null) return; - if (!options.includes(value)) { - warned.add(element); +function link_option(element, name) { + const value = /** @type {typeof valid_link_options[T][number] | null} */ ( + element.getAttribute(`data-sveltekit-${name}`) + ); + + return __SVELTEKIT_DEV__ ? validate_link_option(element, name, value) : value; +} + +/** + * @template {LinkOptionName} T + * @template {typeof valid_link_options[T][number] | null} U + * @param {Element} element + * @param {T} name + * @param {U} value + */ +function validate_link_option(element, name, value) { + if (warned.has(element) || value === null) return /** @type {U} */ (null); + + // @ts-expect-error - includes is dumb + if (!valid_link_options[name].includes(value)) { console.error( - `Unexpected value for ${name} — should be one of ${options + `Unexpected value for ${name} — should be one of ${valid_link_options[name] .map((option) => JSON.stringify(option)) .join(', ')}`, element ); } + + return value; } -/** @type {Record} */ const levels = { - tap: PRIORITY_TAP, - hover: PRIORITY_HOVER, - viewport: PRIORITY_VIEWPORT, - page: PRIORITY_PAGE, - '': PRIORITY_HOVER, - off: -1 + ...PRELOAD_PRIORITIES, + '': PRELOAD_PRIORITIES.hover }; /** @@ -64,16 +84,16 @@ export function find_anchor(element, base) { /** @type {HTMLAnchorElement | SVGAElement | undefined} */ let a; - /** @type {string | null} */ + /** @type {typeof valid_link_options['noscroll'][number] | null} */ let noscroll = null; - /** @type {string | null} */ + /** @type {typeof valid_link_options['preload-code'][number] | null} */ let preload_code = null; - /** @type {string | null} */ + /** @type {typeof valid_link_options['preload-data'][number] | null} */ let preload_data = null; - /** @type {string | null} */ + /** @type {typeof valid_link_options['reload'][number] | null} */ let reload = null; while (element !== document.documentElement) { @@ -83,25 +103,10 @@ export function find_anchor(element, base) { } if (a) { - if (preload_code === null) preload_code = element.getAttribute('data-sveltekit-preload-code'); - if (preload_data === null) preload_data = element.getAttribute('data-sveltekit-preload-data'); - if (noscroll === null) noscroll = element.getAttribute('data-sveltekit-noscroll'); - if (reload === null) reload = element.getAttribute('data-sveltekit-reload'); - - if (__SVELTEKIT_DEV__) { - validate(element, 'data-sveltekit-preload-data', preload_data, ['', 'off', 'tap', 'hover']); - validate(element, 'data-sveltekit-preload-code', preload_code, [ - '', - 'off', - 'tap', - 'hover', - 'viewport', - 'page' - ]); - - validate(element, 'data-sveltekit-preload-data', noscroll, ['', 'off']); - validate(element, 'data-sveltekit-preload-data', reload, ['', 'off']); - } + if (preload_code === null) preload_code = link_option(element, 'preload-code'); + if (preload_data === null) preload_data = link_option(element, 'preload-data'); + if (noscroll === null) noscroll = link_option(element, 'noscroll'); + if (reload === null) reload = link_option(element, 'reload'); } // @ts-expect-error handle shadow roots diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 056557421782..99db5ee627f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -592,22 +592,6 @@ importers: uvu: 0.5.6 vite: 3.2.3 - packages/kit/test/prerendering/fallback: - specifiers: - '@sveltejs/kit': workspace:* - svelte: ^3.52.0 - svelte-check: ^2.9.2 - typescript: ^4.8.4 - uvu: ^0.5.6 - vite: ^3.2.1 - devDependencies: - '@sveltejs/kit': link:../../.. - svelte: 3.53.1 - svelte-check: 2.9.2_svelte@3.53.1 - typescript: 4.8.4 - uvu: 0.5.6 - vite: 3.2.3 - packages/kit/test/prerendering/options: specifiers: '@sveltejs/kit': workspace:*