From 4db4ee53305dbf1f29d2f6ddadb5201a4854c590 Mon Sep 17 00:00:00 2001 From: 7nik Date: Mon, 23 Jun 2025 13:18:14 +0300 Subject: [PATCH] chore: rid of nodeType magic numbers (#16208) * chore: rid of nodeType magic numbers * lint --------- Co-authored-by: 7nik --- .../svelte/src/internal/client/constants.js | 5 +++++ .../src/internal/client/dev/elements.js | 7 ++++--- .../src/internal/client/dom/blocks/each.js | 4 ++-- .../src/internal/client/dom/blocks/html.js | 6 +++++- .../src/internal/client/dom/blocks/snippet.js | 4 ++-- .../client/dom/blocks/svelte-element.js | 4 ++-- .../internal/client/dom/blocks/svelte-head.js | 5 +++-- .../src/internal/client/dom/hydration.js | 5 +++-- .../src/internal/client/dom/operations.js | 9 ++++----- .../src/internal/client/dom/template.js | 7 ++++--- packages/svelte/src/internal/client/render.js | 5 +++-- packages/svelte/tests/html_equal.js | 19 ++++++++++--------- .../svelte/tests/runtime-browser/assert.js | 5 ++++- .../samples/template/_config.js | 3 ++- 14 files changed, 53 insertions(+), 35 deletions(-) diff --git a/packages/svelte/src/internal/client/constants.js b/packages/svelte/src/internal/client/constants.js index 98cef658bf..3ca915f98e 100644 --- a/packages/svelte/src/internal/client/constants.js +++ b/packages/svelte/src/internal/client/constants.js @@ -26,3 +26,8 @@ export const STATE_SYMBOL = Symbol('$state'); export const LEGACY_PROPS = Symbol('legacy props'); export const LOADING_ATTR_SYMBOL = Symbol(''); export const PROXY_PATH_SYMBOL = Symbol('proxy path'); + +export const ELEMENT_NODE = 1; +export const TEXT_NODE = 3; +export const COMMENT_NODE = 8; +export const DOCUMENT_FRAGMENT_NODE = 11; diff --git a/packages/svelte/src/internal/client/dev/elements.js b/packages/svelte/src/internal/client/dev/elements.js index 62ac09d784..f70f893d1e 100644 --- a/packages/svelte/src/internal/client/dev/elements.js +++ b/packages/svelte/src/internal/client/dev/elements.js @@ -1,4 +1,5 @@ /** @import { SourceLocation } from '#client' */ +import { COMMENT_NODE, DOCUMENT_FRAGMENT_NODE, ELEMENT_NODE } from '#client/constants'; import { HYDRATION_END, HYDRATION_START, HYDRATION_START_ELSE } from '../../../constants.js'; import { hydrating } from '../dom/hydration.js'; @@ -12,7 +13,7 @@ export function add_locations(fn, filename, locations) { return (/** @type {any[]} */ ...args) => { const dom = fn(...args); - var node = hydrating ? dom : dom.nodeType === 11 ? dom.firstChild : dom; + var node = hydrating ? dom : dom.nodeType === DOCUMENT_FRAGMENT_NODE ? dom.firstChild : dom; assign_locations(node, filename, locations); return dom; @@ -45,13 +46,13 @@ function assign_locations(node, filename, locations) { var depth = 0; while (node && i < locations.length) { - if (hydrating && node.nodeType === 8) { + if (hydrating && node.nodeType === COMMENT_NODE) { var comment = /** @type {Comment} */ (node); if (comment.data === HYDRATION_START || comment.data === HYDRATION_START_ELSE) depth += 1; else if (comment.data[0] === HYDRATION_END) depth -= 1; } - if (depth === 0 && node.nodeType === 1) { + if (depth === 0 && node.nodeType === ELEMENT_NODE) { assign_location(/** @type {Element} */ (node), filename, locations[i++]); } diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index b638a6d2da..7b12be58e8 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -34,7 +34,7 @@ import { } from '../../reactivity/effects.js'; import { source, mutable_source, internal_set } from '../../reactivity/sources.js'; import { array_from, is_array } from '../../../shared/utils.js'; -import { INERT } from '#client/constants'; +import { COMMENT_NODE, INERT } from '#client/constants'; import { queue_micro_task } from '../task.js'; import { active_effect, get } from '../../runtime.js'; import { DEV } from 'esm-env'; @@ -183,7 +183,7 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f for (var i = 0; i < length; i++) { if ( - hydrate_node.nodeType === 8 && + hydrate_node.nodeType === COMMENT_NODE && /** @type {Comment} */ (hydrate_node).data === HYDRATION_END ) { // The server rendered fewer items than expected, diff --git a/packages/svelte/src/internal/client/dom/blocks/html.js b/packages/svelte/src/internal/client/dom/blocks/html.js index 92c8243478..d7190abc66 100644 --- a/packages/svelte/src/internal/client/dom/blocks/html.js +++ b/packages/svelte/src/internal/client/dom/blocks/html.js @@ -10,6 +10,7 @@ import { DEV } from 'esm-env'; import { dev_current_component_function } from '../../context.js'; import { get_first_child, get_next_sibling } from '../operations.js'; import { active_effect } from '../../runtime.js'; +import { COMMENT_NODE } from '#client/constants'; /** * @param {Element} element @@ -67,7 +68,10 @@ export function html(node, get_value, svg = false, mathml = false, skip_warning var next = hydrate_next(); var last = next; - while (next !== null && (next.nodeType !== 8 || /** @type {Comment} */ (next).data !== '')) { + while ( + next !== null && + (next.nodeType !== COMMENT_NODE || /** @type {Comment} */ (next).data !== '') + ) { last = next; next = /** @type {TemplateNode} */ (get_next_sibling(next)); } diff --git a/packages/svelte/src/internal/client/dom/blocks/snippet.js b/packages/svelte/src/internal/client/dom/blocks/snippet.js index c6dce26bfe..32d88d4c60 100644 --- a/packages/svelte/src/internal/client/dom/blocks/snippet.js +++ b/packages/svelte/src/internal/client/dom/blocks/snippet.js @@ -1,7 +1,7 @@ /** @import { Snippet } from 'svelte' */ /** @import { Effect, TemplateNode } from '#client' */ /** @import { Getters } from '#shared' */ -import { EFFECT_TRANSPARENT } from '#client/constants'; +import { EFFECT_TRANSPARENT, ELEMENT_NODE } from '#client/constants'; import { branch, block, destroy_effect, teardown } from '../../reactivity/effects.js'; import { dev_current_component_function, @@ -102,7 +102,7 @@ export function createRawSnippet(fn) { var fragment = create_fragment_from_html(html); element = /** @type {Element} */ (get_first_child(fragment)); - if (DEV && (get_next_sibling(element) !== null || element.nodeType !== 1)) { + if (DEV && (get_next_sibling(element) !== null || element.nodeType !== ELEMENT_NODE)) { w.invalid_raw_snippet_render(); } diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js index 43f669e844..ffa57b2d8b 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js @@ -20,7 +20,7 @@ import { current_each_item, set_current_each_item } from './each.js'; import { active_effect } from '../../runtime.js'; import { component_context } from '../../context.js'; import { DEV } from 'esm-env'; -import { EFFECT_TRANSPARENT } from '#client/constants'; +import { EFFECT_TRANSPARENT, ELEMENT_NODE } from '#client/constants'; import { assign_nodes } from '../template.js'; import { is_raw_text_element } from '../../../../utils.js'; @@ -51,7 +51,7 @@ export function element(node, get_tag, is_svg, render_fn, get_namespace, locatio /** @type {null | Element} */ var element = null; - if (hydrating && hydrate_node.nodeType === 1) { + if (hydrating && hydrate_node.nodeType === ELEMENT_NODE) { element = /** @type {Element} */ (hydrate_node); hydrate_next(); } diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-head.js b/packages/svelte/src/internal/client/dom/blocks/svelte-head.js index db2a0c4ef1..66d3371836 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-head.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-head.js @@ -2,7 +2,7 @@ import { hydrate_node, hydrating, set_hydrate_node, set_hydrating } from '../hydration.js'; import { create_text, get_first_child, get_next_sibling } from '../operations.js'; import { block } from '../../reactivity/effects.js'; -import { HEAD_EFFECT } from '#client/constants'; +import { COMMENT_NODE, HEAD_EFFECT } from '#client/constants'; import { HYDRATION_START } from '../../../../constants.js'; /** @@ -37,7 +37,8 @@ export function head(render_fn) { while ( head_anchor !== null && - (head_anchor.nodeType !== 8 || /** @type {Comment} */ (head_anchor).data !== HYDRATION_START) + (head_anchor.nodeType !== COMMENT_NODE || + /** @type {Comment} */ (head_anchor).data !== HYDRATION_START) ) { head_anchor = /** @type {TemplateNode} */ (get_next_sibling(head_anchor)); } diff --git a/packages/svelte/src/internal/client/dom/hydration.js b/packages/svelte/src/internal/client/dom/hydration.js index ab3256da82..1f80b7922b 100644 --- a/packages/svelte/src/internal/client/dom/hydration.js +++ b/packages/svelte/src/internal/client/dom/hydration.js @@ -1,5 +1,6 @@ /** @import { TemplateNode } from '#client' */ +import { COMMENT_NODE } from '#client/constants'; import { HYDRATION_END, HYDRATION_ERROR, @@ -87,7 +88,7 @@ export function remove_nodes() { var node = hydrate_node; while (true) { - if (node.nodeType === 8) { + if (node.nodeType === COMMENT_NODE) { var data = /** @type {Comment} */ (node).data; if (data === HYDRATION_END) { @@ -109,7 +110,7 @@ export function remove_nodes() { * @param {TemplateNode} node */ export function read_hydration_instruction(node) { - if (!node || node.nodeType !== 8) { + if (!node || node.nodeType !== COMMENT_NODE) { w.hydration_mismatch(); throw HYDRATION_ERROR; } diff --git a/packages/svelte/src/internal/client/dom/operations.js b/packages/svelte/src/internal/client/dom/operations.js index 97062f04e3..4b35f0802f 100644 --- a/packages/svelte/src/internal/client/dom/operations.js +++ b/packages/svelte/src/internal/client/dom/operations.js @@ -3,6 +3,7 @@ import { hydrate_node, hydrating, set_hydrate_node } from './hydration.js'; import { DEV } from 'esm-env'; import { init_array_prototype_warnings } from '../dev/equality.js'; import { get_descriptor, is_extensible } from '../../shared/utils.js'; +import { TEXT_NODE } from '#client/constants'; // export these for reference in the compiled code, making global name deduplication unnecessary /** @type {Window} */ @@ -113,7 +114,7 @@ export function child(node, is_text) { // Child can be null if we have an element with a single child, like `

{text}

`, where `text` is empty if (child === null) { child = hydrate_node.appendChild(create_text()); - } else if (is_text && child.nodeType !== 3) { + } else if (is_text && child.nodeType !== TEXT_NODE) { var text = create_text(); child?.before(text); set_hydrate_node(text); @@ -143,7 +144,7 @@ export function first_child(fragment, is_text) { // if an {expression} is empty during SSR, there might be no // text node to hydrate — we must therefore create one - if (is_text && hydrate_node?.nodeType !== 3) { + if (is_text && hydrate_node?.nodeType !== TEXT_NODE) { var text = create_text(); hydrate_node?.before(text); @@ -174,11 +175,9 @@ export function sibling(node, count = 1, is_text = false) { return next_sibling; } - var type = next_sibling?.nodeType; - // if a sibling {expression} is empty during SSR, there might be no // text node to hydrate — we must therefore create one - if (is_text && type !== 3) { + if (is_text && next_sibling?.nodeType !== TEXT_NODE) { var text = create_text(); // If the next sibling is `null` and we're handling text then it's because // the SSR content was empty for the text, so we need to generate a new text diff --git a/packages/svelte/src/internal/client/dom/template.js b/packages/svelte/src/internal/client/dom/template.js index 0b77ab1396..ebbf0039b2 100644 --- a/packages/svelte/src/internal/client/dom/template.js +++ b/packages/svelte/src/internal/client/dom/template.js @@ -20,6 +20,7 @@ import { TEMPLATE_USE_MATHML, TEMPLATE_USE_SVG } from '../../../constants.js'; +import { COMMENT_NODE, DOCUMENT_FRAGMENT_NODE, TEXT_NODE } from '#client/constants'; /** * @param {TemplateNode} start @@ -264,7 +265,7 @@ function run_scripts(node) { // scripts were SSR'd, in which case they will run if (hydrating) return node; - const is_fragment = node.nodeType === 11; + const is_fragment = node.nodeType === DOCUMENT_FRAGMENT_NODE; const scripts = /** @type {HTMLElement} */ (node).tagName === 'SCRIPT' ? [/** @type {HTMLScriptElement} */ (node)] @@ -305,7 +306,7 @@ export function text(value = '') { var node = hydrate_node; - if (node.nodeType !== 3) { + if (node.nodeType !== TEXT_NODE) { // if an {expression} is empty during SSR, we need to insert an empty text node node.before((node = create_text())); set_hydrate_node(node); @@ -360,7 +361,7 @@ export function props_id() { if ( hydrating && hydrate_node && - hydrate_node.nodeType === 8 && + hydrate_node.nodeType === COMMENT_NODE && hydrate_node.textContent?.startsWith(`#`) ) { const id = hydrate_node.textContent.substring(1); diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 3256fe8274..ff6844453d 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -30,6 +30,7 @@ import * as w from './warnings.js'; import * as e from './errors.js'; import { assign_nodes } from './dom/template.js'; import { is_passive_event } from '../../utils.js'; +import { COMMENT_NODE } from './constants.js'; /** * This is normally true — block effects should run their intro transitions — @@ -107,7 +108,7 @@ export function hydrate(component, options) { var anchor = /** @type {TemplateNode} */ (get_first_child(target)); while ( anchor && - (anchor.nodeType !== 8 || /** @type {Comment} */ (anchor).data !== HYDRATION_START) + (anchor.nodeType !== COMMENT_NODE || /** @type {Comment} */ (anchor).data !== HYDRATION_START) ) { anchor = /** @type {TemplateNode} */ (get_next_sibling(anchor)); } @@ -124,7 +125,7 @@ export function hydrate(component, options) { if ( hydrate_node === null || - hydrate_node.nodeType !== 8 || + hydrate_node.nodeType !== COMMENT_NODE || /** @type {Comment} */ (hydrate_node).data !== HYDRATION_END ) { w.hydration_mismatch(); diff --git a/packages/svelte/tests/html_equal.js b/packages/svelte/tests/html_equal.js index 6948d8db32..b637e4d538 100644 --- a/packages/svelte/tests/html_equal.js +++ b/packages/svelte/tests/html_equal.js @@ -1,3 +1,4 @@ +import { COMMENT_NODE, ELEMENT_NODE, TEXT_NODE } from '#client/constants'; import { assert } from 'vitest'; /** @@ -35,7 +36,7 @@ function clean_children(node, opts) { }); for (let child of [...node.childNodes]) { - if (child.nodeType === 3) { + if (child.nodeType === TEXT_NODE) { let text = /** @type {Text} */ (child); if ( @@ -49,7 +50,7 @@ function clean_children(node, opts) { text.data = text.data.replace(/[^\S]+/g, ' '); - if (previous && previous.nodeType === 3) { + if (previous && previous.nodeType === TEXT_NODE) { const prev = /** @type {Text} */ (previous); prev.data += text.data; @@ -62,22 +63,22 @@ function clean_children(node, opts) { } } - if (child.nodeType === 8 && !opts.preserveComments) { + if (child.nodeType === COMMENT_NODE && !opts.preserveComments) { // comment child.remove(); continue; } // add newlines for better readability and potentially recurse into children - if (child.nodeType === 1 || child.nodeType === 8) { - if (previous?.nodeType === 3) { + if (child.nodeType === ELEMENT_NODE || child.nodeType === COMMENT_NODE) { + if (previous?.nodeType === TEXT_NODE) { const prev = /** @type {Text} */ (previous); prev.data = prev.data.replace(/^[^\S]+$/, '\n'); - } else if (previous?.nodeType === 1 || previous?.nodeType === 8) { + } else if (previous?.nodeType === ELEMENT_NODE || previous?.nodeType === COMMENT_NODE) { node.insertBefore(document.createTextNode('\n'), child); } - if (child.nodeType === 1) { + if (child.nodeType === ELEMENT_NODE) { has_element_children = true; clean_children(/** @type {Element} */ (child), opts); } @@ -87,12 +88,12 @@ function clean_children(node, opts) { } // collapse whitespace - if (node.firstChild && node.firstChild.nodeType === 3) { + if (node.firstChild && node.firstChild.nodeType === TEXT_NODE) { const text = /** @type {Text} */ (node.firstChild); text.data = text.data.trimStart(); } - if (node.lastChild && node.lastChild.nodeType === 3) { + if (node.lastChild && node.lastChild.nodeType === TEXT_NODE) { const text = /** @type {Text} */ (node.lastChild); text.data = text.data.trimEnd(); } diff --git a/packages/svelte/tests/runtime-browser/assert.js b/packages/svelte/tests/runtime-browser/assert.js index fb460c722a..48bde01410 100644 --- a/packages/svelte/tests/runtime-browser/assert.js +++ b/packages/svelte/tests/runtime-browser/assert.js @@ -1,5 +1,8 @@ /** @import { assert } from 'vitest' */ /** @import { CompileOptions, Warning } from '#compiler' */ + +import { ELEMENT_NODE } from '#client/constants'; + /** * @param {any} a * @param {any} b @@ -102,7 +105,7 @@ function normalize_children(node) { } for (let child of [...node.childNodes]) { - if (child.nodeType === 1 /* Element */) { + if (child.nodeType === ELEMENT_NODE) { normalize_children(child); } } diff --git a/packages/svelte/tests/runtime-legacy/samples/template/_config.js b/packages/svelte/tests/runtime-legacy/samples/template/_config.js index f827168542..7576b6fbb8 100644 --- a/packages/svelte/tests/runtime-legacy/samples/template/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/template/_config.js @@ -1,3 +1,4 @@ +import { COMMENT_NODE } from '#client/constants'; import { ok, test } from '../../test'; export default test({ @@ -41,7 +42,7 @@ export default test({ // get all childNodes of template3 except comments let childNodes = []; for (const node of template3.content.childNodes) { - if (node.nodeType !== 8) { + if (node.nodeType !== COMMENT_NODE) { childNodes.push(/** @type {Element} */ (node)); } }