Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/svelte/src/internal/client/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
7 changes: 4 additions & 3 deletions packages/svelte/src/internal/client/dev/elements.js
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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;
Expand Down Expand Up @@ -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++]);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/svelte/src/internal/client/dom/blocks/each.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion packages/svelte/src/internal/client/dom/blocks/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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));
}
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte/src/internal/client/dom/blocks/snippet.js
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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();
}
Expand Down
5 changes: 3 additions & 2 deletions packages/svelte/src/internal/client/dom/blocks/svelte-head.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -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));
}
Expand Down
5 changes: 3 additions & 2 deletions packages/svelte/src/internal/client/dom/hydration.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/** @import { TemplateNode } from '#client' */

import { COMMENT_NODE } from '#client/constants';
import {
HYDRATION_END,
HYDRATION_ERROR,
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}
Expand Down
9 changes: 4 additions & 5 deletions packages/svelte/src/internal/client/dom/operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -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} */
Expand Down Expand Up @@ -113,7 +114,7 @@ export function child(node, is_text) {
// Child can be null if we have an element with a single child, like `<p>{text}</p>`, 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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions packages/svelte/src/internal/client/dom/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions packages/svelte/src/internal/client/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 —
Expand Down Expand Up @@ -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));
}
Expand All @@ -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();
Expand Down
19 changes: 10 additions & 9 deletions packages/svelte/tests/html_equal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { COMMENT_NODE, ELEMENT_NODE, TEXT_NODE } from '#client/constants';
import { assert } from 'vitest';

/**
Expand Down Expand Up @@ -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 (
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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();
}
Expand Down
5 changes: 4 additions & 1 deletion packages/svelte/tests/runtime-browser/assert.js
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { COMMENT_NODE } from '#client/constants';
import { ok, test } from '../../test';

export default test({
Expand Down Expand Up @@ -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));
}
}
Expand Down