chore: alterative functional templating syntax (#15599)

* chore: alterative functional templating syntax

* fix: remove `.at(-1)`

* chore: move create elements, text, comment etc to `operations`

* chore: only use `append` to append to the fragment
custom-render-shim-dom
Paolo Ricciuti 5 months ago committed by GitHub
parent a48df4a44a
commit be398671ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -76,7 +76,7 @@ export function transform_template(state, context, namespace, template_name, fla
/** @type {Expression[]} */
const args = [
state.is_functional_template_mode
? template_to_functions(state.template, namespace)
? template_to_functions(state.template)
: b.template([b.quasi(template_to_string(state.template), true)], [])
];

@ -1,56 +1,24 @@
/**
* @import { TemplateOperations } from "../types.js"
* @import { Namespace } from "#compiler"
* @import { CallExpression, Statement } from "estree"
* @import { CallExpression, Statement, ObjectExpression, Identifier, ArrayExpression, Property, Expression, Literal } from "estree"
*/
import { NAMESPACE_SVG, NAMESPACE_MATHML } from '../../../../../constants.js';
import * as b from '../../../../utils/builders.js';
import { regex_is_valid_identifier } from '../../../patterns.js';
import fix_attribute_casing from './fix-attribute-casing.js';
class Scope {
declared = new Map();
/**
* @param {string} _name
*/
generate(_name) {
let name = _name.replace(/[^a-zA-Z0-9_$]/g, '_').replace(/^[0-9]/, '_');
if (!this.declared.has(name)) {
this.declared.set(name, 1);
return name;
}
let count = this.declared.get(name);
this.declared.set(name, count + 1);
return `${name}_${count}`;
}
}
/**
* @param {TemplateOperations} items
* @param {Namespace} namespace
*/
export function template_to_functions(items, namespace) {
let elements = [];
let body = [];
let scope = new Scope();
export function template_to_functions(items) {
let elements = b.array([]);
/**
* @type {Array<Element>}
*/
let elements_stack = [];
/**
* @type {Array<string>}
*/
let namespace_stack = [];
/**
* @type {number}
*/
let foreign_object_count = 0;
/**
* @type {Element | undefined}
*/
@ -71,89 +39,48 @@ export function template_to_functions(items, namespace) {
// we closed one element, we remove it from the stack and eventually revert back
// the namespace to the previous one
if (instruction.kind === 'pop_element') {
const removed = elements_stack.pop();
if (removed?.namespaced) {
namespace_stack.pop();
}
if (removed?.element === 'foreignObject') {
foreign_object_count--;
}
elements_stack.pop();
continue;
}
// if the inserted node is in the svg/mathml we push the namespace to the stack because we need to
// create with createElementNS
if (instruction.metadata?.svg || instruction.metadata?.mathml) {
namespace_stack.push(instruction.metadata.svg ? NAMESPACE_SVG : NAMESPACE_MATHML);
}
// @ts-expect-error we can't be here if `swap_current_element` but TS doesn't know that
const value = map[instruction.kind](
...[
// for set prop we need to send the last element (not the one in the stack since
// it get's added to the stack only after the push_element instruction)...for all the rest
// the first prop is a the scope to generate the name of the variable
...(instruction.kind === 'set_prop' ? [last_current_element] : [scope]),
// for create element we also need to add the namespace...namespaces in the stack get's precedence over
// the "global" namespace (and if we are in a foreignObject we default to html)
...(instruction.kind === 'create_element'
? [
foreign_object_count > 0
? undefined
: namespace_stack.at(-1) ??
(namespace === 'svg'
? NAMESPACE_SVG
: namespace === 'mathml'
? NAMESPACE_MATHML
: undefined)
]
: []),
? []
: [instruction.kind === 'set_prop' ? last_current_element : elements_stack.at(-1)]),
...(instruction.args ?? [])
]
);
if (value) {
// this will compose the body of the function
body.push(value.call);
}
// with set_prop we don't need to do anything else, in all other cases we also need to
// append the element/node/anchor to the current active element or push it in the elements array
if (instruction.kind !== 'set_prop') {
if (elements_stack.length >= 1 && value) {
const { call } = map.insert(/** @type {Element} */ (elements_stack.at(-1)), value);
body.push(call);
} else if (value) {
elements.push(b.id(value.name));
if (elements_stack.length >= 1 && value !== undefined) {
map.insert(/** @type {Element} */ (elements_stack.at(-1)), value);
} else if (value !== undefined) {
elements.elements.push(value);
}
// keep track of the last created element (it will be pushed to the stack after the props are set)
if (instruction.kind === 'create_element') {
last_current_element = /** @type {Element} */ (value);
if (last_current_element.element === 'foreignObject') {
foreign_object_count++;
}
}
}
}
// every function needs to return a fragment so we create one and push all the elements there
const fragment = scope.generate('fragment');
body.push(b.var(fragment, b.call('document.createDocumentFragment')));
body.push(b.call(fragment + '.append', ...elements));
body.push(b.return(b.id(fragment)));
return b.arrow([], b.block(body));
return elements;
}
/**
* @typedef {{ call: Statement, name: string, add_is: (value: string)=>void, namespaced: boolean; element: string; }} Element
* @typedef {ObjectExpression} Element
*/
/**
* @typedef {{ call: Statement, name: string }} Anchor
* @typedef {void | null | ArrayExpression} Anchor
*/
/**
* @typedef {{ call: Statement, name: string }} Text
* @typedef {void | Literal} Text
*/
/**
@ -161,109 +88,89 @@ export function template_to_functions(items, namespace) {
*/
/**
* @param {Scope} scope
* @param {Namespace} namespace
* @param {string} element
* @returns {Element}
*/
function create_element(scope, namespace, element) {
const name = scope.generate(element);
let fn = namespace != null ? 'document.createElementNS' : 'document.createElement';
let args = [b.literal(element)];
if (namespace != null) {
args.unshift(b.literal(namespace));
}
const call = b.var(name, b.call(fn, ...args));
/**
* if there's an "is" attribute we can't just add it as a property, it needs to be
* specified on creation like this `document.createElement('button', { is: 'my-button' })`
*
* Since the props are appended after the creation we change the generated call arguments and we push
* the is attribute later on on `set_prop`
* @param {string} value
*/
function add_is(value) {
/** @type {CallExpression} */ (call.declarations[0].init).arguments.push(
b.object([b.prop('init', b.literal('is'), b.literal(value))])
);
function create_element(element) {
return b.object([b.prop('init', b.id('e'), b.literal(element))]);
}
/**
*
* @param {Element} element
* @param {string} name
* @param {Expression} init
* @returns {Property}
*/
function get_or_create_prop(element, name, init) {
let prop = element.properties.find(
(prop) => prop.type === 'Property' && /** @type {Identifier} */ (prop.key).name === name
);
if (!prop) {
prop = b.prop('init', b.id(name), init);
element.properties.push(prop);
}
return {
call,
name,
element,
add_is,
namespaced: namespace != null
};
return /** @type {Property} */ (prop);
}
/**
* @param {Scope} scope
* @param {Element} element
* @param {string} data
* @returns {Anchor}
*/
function create_anchor(scope, data = '') {
const name = scope.generate('comment');
return {
call: b.var(name, b.call('document.createComment', b.literal(data))),
name
};
function create_anchor(element, data = '') {
if (!element) return data ? b.array([b.literal(data)]) : null;
const c = get_or_create_prop(element, 'c', b.array([]));
/** @type {ArrayExpression} */ (c.value).elements.push(data ? b.array([b.literal(data)]) : null);
}
/**
* @param {Scope} scope
* @param {Element} element
* @param {string} value
* @returns {Text}
*/
function create_text(scope, value) {
const name = scope.generate('text');
return {
call: b.var(name, b.call('document.createTextNode', b.literal(value))),
name
};
function create_text(element, value) {
if (!element) return b.literal(value);
const c = get_or_create_prop(element, 'c', b.array([]));
/** @type {ArrayExpression} */ (c.value).elements.push(b.literal(value));
}
/**
*
* @param {Element} el
* @param {Element} element
* @param {string} prop
* @param {string} value
*/
function set_prop(el, prop, value) {
// see comment above about the "is" attribute
function set_prop(element, prop, value) {
const p = get_or_create_prop(element, 'p', b.object([]));
if (prop === 'is') {
el.add_is(value);
element.properties.push(b.prop('init', b.id(prop), b.literal(value)));
return;
}
const [namespace] = prop.split(':');
let fn = namespace !== prop ? '.setAttributeNS' : '.setAttribute';
let args = [b.literal(fix_attribute_casing(prop)), b.literal(value ?? '')];
const prop_correct_case = fix_attribute_casing(prop);
// attributes like `xlink:href` need to be set with the `xlink` namespace
if (namespace === 'xlink') {
args.unshift(b.literal('http://www.w3.org/1999/xlink'));
}
const is_valid_id = regex_is_valid_identifier.test(prop_correct_case);
return {
call: b.call(el.name + fn, ...args)
};
/** @type {ObjectExpression} */ (p.value).properties.push(
b.prop(
'init',
(is_valid_id ? b.id : b.literal)(prop_correct_case),
b.literal(value),
!is_valid_id
)
);
}
/**
*
* @param {Element} el
* @param {Node} child
* @param {Node} [anchor]
* @param {Element} element
* @param {Element} child
*/
function insert(el, child, anchor) {
return {
call: b.call(
// if we have a template element we need to push into it's content rather than the element itself
el.name + (el.element === 'template' ? '.content' : '') + '.insertBefore',
b.id(child.name),
b.id(anchor?.name ?? 'undefined')
)
};
function insert(element, child) {
const c = get_or_create_prop(element, 'c', b.array([]));
/** @type {ArrayExpression} */ (c.value).elements.push(child);
}
let map = {

@ -204,3 +204,44 @@ export function sibling(node, count = 1, is_text = false) {
export function clear_text_content(node) {
node.textContent = '';
}
/**
*
* @param {string} tag
* @param {string} [namespace]
* @param {string} [is]
* @returns
*/
export function create_element(tag, namespace, is) {
let options = is ? { is } : undefined;
if (namespace) {
return document.createElementNS(namespace, tag, options);
}
return document.createElement(tag, options);
}
export function create_fragment() {
return document.createDocumentFragment();
}
/**
* @param {string} data
* @returns
*/
export function create_comment(data = '') {
return document.createComment(data);
}
/**
* @param {Element} element
* @param {string} key
* @param {string} value
* @returns
*/
export function set_attribute(element, key, value = '') {
if (key.startsWith('xlink:')) {
element.setAttributeNS('http://www.w3.org/1999/xlink', key, value);
return;
}
return element.setAttribute(key, value);
}

@ -1,9 +1,22 @@
/** @import { Effect, TemplateNode } from '#client' */
import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from './hydration.js';
import { create_text, get_first_child, is_firefox } from './operations.js';
import {
create_text,
get_first_child,
is_firefox,
create_element,
create_fragment,
create_comment,
set_attribute
} from './operations.js';
import { create_fragment_from_html } from './reconciler.js';
import { active_effect } from '../runtime.js';
import { TEMPLATE_FRAGMENT, TEMPLATE_USE_IMPORT_NODE } from '../../../constants.js';
import {
NAMESPACE_MATHML,
NAMESPACE_SVG,
TEMPLATE_FRAGMENT,
TEMPLATE_USE_IMPORT_NODE
} from '../../../constants.js';
/**
* @param {TemplateNode} start
@ -65,12 +78,75 @@ export function template(content, flags) {
}
/**
* @param {()=>(DocumentFragment | Node)} fn
* @typedef {{e: string, is?: string, p: Record<string, string>, c: Array<TemplateStructure>} | null | string | [string]} TemplateStructure
*/
/**
* @param {Array<TemplateStructure>} structure
* @param {'svg' | 'math'} [ns]
* @param {Array<string | undefined>} [namespace_stack]
*/
function structure_to_fragment(structure, ns, namespace_stack = [], foreign_object_count = 0) {
var fragment = create_fragment();
for (var i = 0; i < structure.length; i += 1) {
var item = structure[i];
if (item == null || Array.isArray(item)) {
const data = item ? item[0] : '';
fragment.append(create_comment(data));
} else if (typeof item === 'string') {
fragment.append(create_text(item));
continue;
} else {
let namespace =
foreign_object_count > 0
? undefined
: namespace_stack[namespace_stack.length - 1] ??
(ns
? ns === 'svg'
? NAMESPACE_SVG
: ns === 'math'
? NAMESPACE_MATHML
: undefined
: item.e === 'svg'
? NAMESPACE_SVG
: item.e === 'math'
? NAMESPACE_MATHML
: undefined);
if (namespace !== namespace_stack[namespace_stack.length - 1]) {
namespace_stack.push(namespace);
}
var element = create_element(item.e, namespace, item.is);
for (var key in item.p) {
set_attribute(element, key, item.p[key]);
}
if (item.c) {
(element.tagName === 'TEMPLATE'
? /** @type {HTMLTemplateElement} */ (element).content
: element
).append(
...structure_to_fragment(
item.c,
ns,
namespace_stack,
element.tagName === 'foreignObject' ? foreign_object_count + 1 : foreign_object_count
).childNodes
);
}
namespace_stack.pop();
fragment.append(element);
}
}
return fragment;
}
/**
* @param {Array<TemplateStructure>} structure
* @param {number} flags
* @returns {() => Node | Node[]}
*/
/*#__NO_SIDE_EFFECTS__*/
export function template_fn(fn, flags) {
export function template_fn(structure, flags) {
var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;
var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0;
@ -84,7 +160,7 @@ export function template_fn(fn, flags) {
}
if (node === undefined) {
node = fn();
node = structure_to_fragment(structure);
if (!is_fragment) node = /** @type {Node} */ (get_first_child(node));
}
@ -117,12 +193,12 @@ export function template_with_script(content, flags) {
}
/**
* @param {()=>(DocumentFragment | Node)} fn
* @param {Array<TemplateStructure>} structure
* @param {number} flags
* @returns {() => Node | Node[]}
*/ /*#__NO_SIDE_EFFECTS__*/
export function template_with_script_fn(fn, flags) {
var templated_fn = template_fn(fn, flags);
export function template_with_script_fn(structure, flags) {
var templated_fn = template_fn(structure, flags);
return () => run_scripts(/** @type {Element | DocumentFragment} */ (templated_fn()));
}
@ -182,13 +258,13 @@ export function ns_template(content, flags, ns = 'svg') {
}
/**
* @param {()=>(DocumentFragment | Node)} fn
* @param {Array<TemplateStructure>} structure
* @param {number} flags
* @param {'svg' | 'math'} ns
* @returns {() => Node | Node[]}
*/
/*#__NO_SIDE_EFFECTS__*/
export function ns_template_fn(fn, flags, ns = 'svg') {
export function ns_template_fn(structure, flags, ns = 'svg') {
var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;
/** @type {Element | DocumentFragment} */
@ -201,7 +277,7 @@ export function ns_template_fn(fn, flags, ns = 'svg') {
}
if (!node) {
var fragment = /** @type {DocumentFragment} */ (fn());
var fragment = structure_to_fragment(structure, ns);
if (is_fragment) {
node = document.createDocumentFragment();
@ -240,13 +316,13 @@ export function svg_template_with_script(content, flags) {
}
/**
* @param {()=>(DocumentFragment | Node)} fn
* @param {Array<TemplateStructure>} structure
* @param {number} flags
* @returns {() => Node | Node[]}
*/
/*#__NO_SIDE_EFFECTS__*/
export function svg_template_with_script_fn(fn, flags) {
var templated_fn = ns_template_fn(fn, flags);
export function svg_template_with_script_fn(structure, flags) {
var templated_fn = ns_template_fn(structure, flags);
return () => run_scripts(/** @type {Element | DocumentFragment} */ (templated_fn()));
}
@ -261,13 +337,13 @@ export function mathml_template(content, flags) {
}
/**
* @param {()=>(DocumentFragment | Node)} fn
* @param {Array<TemplateStructure>} structure
* @param {number} flags
* @returns {() => Node | Node[]}
*/
/*#__NO_SIDE_EFFECTS__*/
export function mathml_template_fn(fn, flags) {
return ns_template_fn(fn, flags, 'math');
export function mathml_template_fn(structure, flags) {
return ns_template_fn(structure, flags, 'math');
}
/**

@ -5,23 +5,7 @@ function increment(_, counter) {
counter.count += 1;
}
var root = $.template_fn(
() => {
var button = document.createElement('button');
var text = document.createTextNode(' ');
button.insertBefore(text, undefined)
var text_1 = document.createTextNode(' ');
var comment = document.createComment('');
var text_2 = document.createTextNode(' ');
var fragment = document.createDocumentFragment();
fragment.append(button, text_1, comment, text_2)
return fragment;
},
1
);
var root = $.template_fn([{ e: 'button', c: [' '] }, ' ', , ' '], 1);
export default function Await_block_scope($$anchor) {
let counter = $.proxy({ count: 0 });

@ -10,18 +10,7 @@ const snippet = ($$anchor) => {
$.append($$anchor, text);
};
var root = $.template_fn(
() => {
var comment = document.createComment('');
var comment_1 = document.createComment('');
var text = document.createTextNode(' ');
var fragment = document.createDocumentFragment();
fragment.append(comment, comment_1, text)
return fragment;
},
1
);
var root = $.template_fn([,, ' '], 1);
export default function Bind_component_snippet($$anchor) {
let value = $.state('');

@ -2,23 +2,19 @@ import 'svelte/internal/disclose-version';
import * as $ from 'svelte/internal/client';
var root = $.template_fn(
() => {
var div = document.createElement('div');
var text = document.createTextNode(' ');
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var text_1 = document.createTextNode(' ');
var custom_element = document.createElement('custom-element');
var text_2 = document.createTextNode(' ');
var div_1 = document.createElement('div');
var text_3 = document.createTextNode(' ');
var svg_1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var text_4 = document.createTextNode(' ');
var custom_element_1 = document.createElement('custom-element');
var fragment = document.createDocumentFragment();
fragment.append(div, text, svg, text_1, custom_element, text_2, div_1, text_3, svg_1, text_4, custom_element_1)
return fragment;
},
[
{ e: 'div' },
' ',
{ e: 'svg' },
' ',
{ e: 'custom-element' },
' ',
{ e: 'div' },
' ',
{ e: 'svg' },
' ',
{ e: 'custom-element' }
],
3
);

@ -2,17 +2,7 @@ import 'svelte/internal/disclose-version';
import 'svelte/internal/flags/legacy';
import * as $ from 'svelte/internal/client';
var root = $.template_fn(() => {
var h1 = document.createElement('h1');
var text = document.createTextNode('hello world');
h1.insertBefore(text, undefined)
var fragment = document.createDocumentFragment();
fragment.append(h1)
return fragment;
});
var root = $.template_fn([{ e: 'h1', c: ['hello world'] }]);
export default function Hello_world($$anchor) {
var h1 = root();

@ -2,17 +2,7 @@ import 'svelte/internal/disclose-version';
import 'svelte/internal/flags/legacy';
import * as $ from 'svelte/internal/client';
var root = $.template_fn(() => {
var h1 = document.createElement('h1');
var text = document.createTextNode('hello world');
h1.insertBefore(text, undefined)
var fragment = document.createDocumentFragment();
fragment.append(h1)
return fragment;
});
var root = $.template_fn([{ e: 'h1', c: ['hello world'] }]);
function Hmr($$anchor) {
var h1 = root();

@ -4,23 +4,15 @@ import * as $ from 'svelte/internal/client';
var on_click = (_, count) => $.update(count);
var root = $.template_fn(
() => {
var h1 = document.createElement('h1');
var text = document.createTextNode(' ');
var b = document.createElement('b');
var text_1 = document.createTextNode(' ');
var button = document.createElement('button');
var text_2 = document.createTextNode(' ');
button.insertBefore(text_2, undefined)
var text_3 = document.createTextNode(' ');
var h1_1 = document.createElement('h1');
var fragment = document.createDocumentFragment();
fragment.append(h1, text, b, text_1, button, text_3, h1_1)
return fragment;
},
[
{ e: 'h1' },
' ',
{ e: 'b' },
' ',
{ e: 'button', c: [' '] },
' ',
{ e: 'h1' }
],
1
);

@ -2,20 +2,7 @@ import 'svelte/internal/disclose-version';
import 'svelte/internal/flags/legacy';
import * as $ from 'svelte/internal/client';
var root = $.template_fn(
() => {
var p = document.createElement('p');
var text = document.createTextNode(' ');
var p_1 = document.createElement('p');
var text_1 = document.createTextNode(' ');
var comment = document.createComment('');
var fragment = document.createDocumentFragment();
fragment.append(p, text, p_1, text_1, comment)
return fragment;
},
1
);
var root = $.template_fn([{ e: 'p' }, ' ', { e: 'p' }, ' ', ,], 1);
export default function Purity($$anchor) {
var fragment = root();

@ -2,238 +2,94 @@ import 'svelte/internal/disclose-version';
import * as $ from 'svelte/internal/client';
var root = $.template_fn(
() => {
var header = document.createElement('header');
var nav = document.createElement('nav');
header.insertBefore(nav, undefined)
var a = document.createElement('a');
nav.insertBefore(a, undefined)
a.setAttribute('href', '/')
var text = document.createTextNode('Home');
a.insertBefore(text, undefined)
var text_1 = document.createTextNode(' ');
nav.insertBefore(text_1, undefined)
var a_1 = document.createElement('a');
nav.insertBefore(a_1, undefined)
a_1.setAttribute('href', '/away')
var text_2 = document.createTextNode('Away');
a_1.insertBefore(text_2, undefined)
var text_3 = document.createTextNode(' ');
var main = document.createElement('main');
var h1 = document.createElement('h1');
main.insertBefore(h1, undefined)
var text_4 = document.createTextNode(' ');
h1.insertBefore(text_4, undefined)
var text_5 = document.createTextNode(' ');
main.insertBefore(text_5, undefined)
var div = document.createElement('div');
main.insertBefore(div, undefined)
div.setAttribute('class', 'static')
var p = document.createElement('p');
div.insertBefore(p, undefined)
var text_6 = document.createTextNode('we don\'t need to traverse these nodes');
p.insertBefore(text_6, undefined)
var text_7 = document.createTextNode(' ');
main.insertBefore(text_7, undefined)
var p_1 = document.createElement('p');
main.insertBefore(p_1, undefined)
var text_8 = document.createTextNode('or');
p_1.insertBefore(text_8, undefined)
var text_9 = document.createTextNode(' ');
main.insertBefore(text_9, undefined)
var p_2 = document.createElement('p');
main.insertBefore(p_2, undefined)
var text_10 = document.createTextNode('these');
p_2.insertBefore(text_10, undefined)
var text_11 = document.createTextNode(' ');
main.insertBefore(text_11, undefined)
var p_3 = document.createElement('p');
main.insertBefore(p_3, undefined)
var text_12 = document.createTextNode('ones');
p_3.insertBefore(text_12, undefined)
var text_13 = document.createTextNode(' ');
main.insertBefore(text_13, undefined)
var comment = document.createComment('');
main.insertBefore(comment, undefined)
var text_14 = document.createTextNode(' ');
main.insertBefore(text_14, undefined)
var p_4 = document.createElement('p');
main.insertBefore(p_4, undefined)
var text_15 = document.createTextNode('these');
p_4.insertBefore(text_15, undefined)
var text_16 = document.createTextNode(' ');
main.insertBefore(text_16, undefined)
var p_5 = document.createElement('p');
main.insertBefore(p_5, undefined)
var text_17 = document.createTextNode('trailing');
p_5.insertBefore(text_17, undefined)
var text_18 = document.createTextNode(' ');
main.insertBefore(text_18, undefined)
var p_6 = document.createElement('p');
main.insertBefore(p_6, undefined)
var text_19 = document.createTextNode('nodes');
p_6.insertBefore(text_19, undefined)
var text_20 = document.createTextNode(' ');
main.insertBefore(text_20, undefined)
var p_7 = document.createElement('p');
main.insertBefore(p_7, undefined)
var text_21 = document.createTextNode('can');
p_7.insertBefore(text_21, undefined)
var text_22 = document.createTextNode(' ');
main.insertBefore(text_22, undefined)
var p_8 = document.createElement('p');
main.insertBefore(p_8, undefined)
var text_23 = document.createTextNode('be');
p_8.insertBefore(text_23, undefined)
var text_24 = document.createTextNode(' ');
main.insertBefore(text_24, undefined)
var p_9 = document.createElement('p');
main.insertBefore(p_9, undefined)
var text_25 = document.createTextNode('completely');
p_9.insertBefore(text_25, undefined)
var text_26 = document.createTextNode(' ');
main.insertBefore(text_26, undefined)
var p_10 = document.createElement('p');
main.insertBefore(p_10, undefined)
var text_27 = document.createTextNode('ignored');
p_10.insertBefore(text_27, undefined)
var text_28 = document.createTextNode(' ');
var cant_skip = document.createElement('cant-skip');
var custom_elements = document.createElement('custom-elements');
cant_skip.insertBefore(custom_elements, undefined)
var text_29 = document.createTextNode(' ');
var div_1 = document.createElement('div');
var input = document.createElement('input');
div_1.insertBefore(input, undefined)
var text_30 = document.createTextNode(' ');
var div_2 = document.createElement('div');
var source = document.createElement('source');
div_2.insertBefore(source, undefined)
var text_31 = document.createTextNode(' ');
var select = document.createElement('select');
var option = document.createElement('option');
select.insertBefore(option, undefined)
var text_32 = document.createTextNode('a');
option.insertBefore(text_32, undefined)
var text_33 = document.createTextNode(' ');
var img = document.createElement('img');
img.setAttribute('src', '...')
img.setAttribute('alt', '')
img.setAttribute('loading', 'lazy')
var text_34 = document.createTextNode(' ');
var div_3 = document.createElement('div');
var img_1 = document.createElement('img');
div_3.insertBefore(img_1, undefined)
img_1.setAttribute('src', '...')
img_1.setAttribute('alt', '')
img_1.setAttribute('loading', 'lazy')
var fragment = document.createDocumentFragment();
fragment.append(header, text_3, main, text_28, cant_skip, text_29, div_1, text_30, div_2, text_31, select, text_33, img, text_34, div_3)
return fragment;
},
[
{
e: 'header',
c: [
{
e: 'nav',
c: [
{ e: 'a', p: { href: '/' }, c: ['Home'] },
' ',
{
e: 'a',
p: { href: '/away' },
c: ['Away']
}
]
}
]
},
' ',
{
e: 'main',
c: [
{ e: 'h1', c: [' '] },
' ',
{
e: 'div',
p: { class: 'static' },
c: [
{
e: 'p',
c: ['we don\'t need to traverse these nodes']
}
]
},
' ',
{ e: 'p', c: ['or'] },
' ',
{ e: 'p', c: ['these'] },
' ',
{ e: 'p', c: ['ones'] },
' ',
,
' ',
{ e: 'p', c: ['these'] },
' ',
{ e: 'p', c: ['trailing'] },
' ',
{ e: 'p', c: ['nodes'] },
' ',
{ e: 'p', c: ['can'] },
' ',
{ e: 'p', c: ['be'] },
' ',
{ e: 'p', c: ['completely'] },
' ',
{ e: 'p', c: ['ignored'] }
]
},
' ',
{
e: 'cant-skip',
c: [{ e: 'custom-elements' }]
},
' ',
{ e: 'div', c: [{ e: 'input' }] },
' ',
{ e: 'div', c: [{ e: 'source' }] },
' ',
{
e: 'select',
c: [{ e: 'option', c: ['a'] }]
},
' ',
{
e: 'img',
p: { src: '...', alt: '', loading: 'lazy' }
},
' ',
{
e: 'div',
c: [
{
e: 'img',
p: { src: '...', alt: '', loading: 'lazy' }
}
]
}
],
3
);

@ -9,21 +9,13 @@ function reset(_, str, tpl) {
}
var root = $.template_fn(
() => {
var input = document.createElement('input');
var text = document.createTextNode(' ');
var input_1 = document.createElement('input');
var text_1 = document.createTextNode(' ');
var button = document.createElement('button');
var text_2 = document.createTextNode('reset');
button.insertBefore(text_2, undefined)
var fragment = document.createDocumentFragment();
fragment.append(input, text, input_1, text_1, button)
return fragment;
},
[
{ e: 'input' },
' ',
{ e: 'input' },
' ',
{ e: 'button', c: ['reset'] }
],
1
);

@ -1,17 +1,7 @@
import 'svelte/internal/disclose-version';
import * as $ from 'svelte/internal/client';
var root = $.template_fn(() => {
var p = document.createElement('p');
var text = document.createTextNode(' ');
p.insertBefore(text, undefined)
var fragment = document.createDocumentFragment();
fragment.append(p)
return fragment;
});
var root = $.template_fn([{ e: 'p', c: [' '] }]);
export default function Text_nodes_deriveds($$anchor) {
let count1 = 0;

Loading…
Cancel
Save