|
|
|
@ -1,5 +1,4 @@
|
|
|
|
|
import { hydrate_anchor, hydrate_nodes, hydrating } from './hydration.js';
|
|
|
|
|
import { get_descriptor } from '../utils.js';
|
|
|
|
|
import { DEV } from 'esm-env';
|
|
|
|
|
import { init_array_prototype_warnings } from '../dev/equality.js';
|
|
|
|
|
|
|
|
|
@ -15,24 +14,6 @@ var element_prototype;
|
|
|
|
|
/** @type {Text} */
|
|
|
|
|
var text_prototype;
|
|
|
|
|
|
|
|
|
|
/** @type {typeof Node.prototype.appendChild} */
|
|
|
|
|
var append_child_method;
|
|
|
|
|
|
|
|
|
|
/** @type {typeof Node.prototype.cloneNode} */
|
|
|
|
|
var clone_node_method;
|
|
|
|
|
|
|
|
|
|
/** @type {(this: Node) => ChildNode | null} */
|
|
|
|
|
var first_child_get;
|
|
|
|
|
|
|
|
|
|
/** @type {(this: Node) => ChildNode | null} */
|
|
|
|
|
var next_sibling_get;
|
|
|
|
|
|
|
|
|
|
/** @type {(this: Node, text: string ) => void} */
|
|
|
|
|
var text_content_set;
|
|
|
|
|
|
|
|
|
|
/** @type {(this: Element, class_name: string) => void} */
|
|
|
|
|
var class_name_set;
|
|
|
|
|
|
|
|
|
|
// export these for reference in the compiled code, making global name deduplication unnecessary
|
|
|
|
|
/**
|
|
|
|
|
* @type {Window}
|
|
|
|
@ -56,9 +37,6 @@ export function init_operations() {
|
|
|
|
|
element_prototype = Element.prototype;
|
|
|
|
|
text_prototype = Text.prototype;
|
|
|
|
|
|
|
|
|
|
append_child_method = node_prototype.appendChild;
|
|
|
|
|
clone_node_method = node_prototype.cloneNode;
|
|
|
|
|
|
|
|
|
|
$window = window;
|
|
|
|
|
$document = document;
|
|
|
|
|
|
|
|
|
@ -80,47 +58,6 @@ export function init_operations() {
|
|
|
|
|
|
|
|
|
|
init_array_prototype_warnings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
first_child_get = /** @type {(this: Node) => ChildNode | null} */ (
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
get_descriptor(node_prototype, 'firstChild').get
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
next_sibling_get = /** @type {(this: Node) => ChildNode | null} */ (
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
get_descriptor(node_prototype, 'nextSibling').get
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
text_content_set = /** @type {(this: Node, text: string ) => void} */ (
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
get_descriptor(node_prototype, 'textContent').set
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
class_name_set = /** @type {(this: Element, class_name: string) => void} */ (
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
get_descriptor(element_prototype, 'className').set
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template {Element} E
|
|
|
|
|
* @template {Node} T
|
|
|
|
|
* @param {E} element
|
|
|
|
|
* @param {T} child
|
|
|
|
|
*/
|
|
|
|
|
export function append_child(element, child) {
|
|
|
|
|
append_child_method.call(element, child);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template {Node} N
|
|
|
|
|
* @param {N} node
|
|
|
|
|
* @param {boolean} deep
|
|
|
|
|
* @returns {N}
|
|
|
|
|
*/
|
|
|
|
|
/*#__NO_SIDE_EFFECTS__*/
|
|
|
|
|
export function clone_node(node, deep) {
|
|
|
|
|
return /** @type {N} */ (clone_node_method.call(node, deep));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @returns {Text} */
|
|
|
|
@ -135,7 +72,7 @@ export function empty() {
|
|
|
|
|
*/
|
|
|
|
|
/*#__NO_SIDE_EFFECTS__*/
|
|
|
|
|
export function child(node) {
|
|
|
|
|
const child = first_child_get.call(node);
|
|
|
|
|
const child = node.firstChild;
|
|
|
|
|
if (!hydrating) return child;
|
|
|
|
|
|
|
|
|
|
// Child can be null if we have an element with a single child, like `<p>{text}</p>`, where `text` is empty
|
|
|
|
@ -155,7 +92,7 @@ export function child(node) {
|
|
|
|
|
export function first_child(fragment, is_text) {
|
|
|
|
|
if (!hydrating) {
|
|
|
|
|
// when not hydrating, `fragment` is a `DocumentFragment` (the result of calling `open_frag`)
|
|
|
|
|
return first_child_get.call(/** @type {DocumentFragment} */ (fragment));
|
|
|
|
|
return /** @type {DocumentFragment} */ (fragment).firstChild;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// when we _are_ hydrating, `fragment` is an array of nodes
|
|
|
|
@ -181,7 +118,7 @@ export function first_child(fragment, is_text) {
|
|
|
|
|
*/
|
|
|
|
|
/*#__NO_SIDE_EFFECTS__*/
|
|
|
|
|
export function sibling(node, is_text = false) {
|
|
|
|
|
const next_sibling = next_sibling_get.call(node);
|
|
|
|
|
const next_sibling = node.nextSibling;
|
|
|
|
|
|
|
|
|
|
if (!hydrating) {
|
|
|
|
|
return next_sibling;
|
|
|
|
@ -205,23 +142,13 @@ export function sibling(node, is_text = false) {
|
|
|
|
|
return hydrate_anchor(/** @type {Node} */ (next_sibling));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template {Element} N
|
|
|
|
|
* @param {N} node
|
|
|
|
|
* @param {string} class_name
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
export function set_class_name(node, class_name) {
|
|
|
|
|
class_name_set.call(node, class_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template {Node} N
|
|
|
|
|
* @param {N} node
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
export function clear_text_content(node) {
|
|
|
|
|
text_content_set.call(node, '');
|
|
|
|
|
node.textContent = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @param {string} name */
|
|
|
|
|