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[]} */ /** @type {Expression[]} */
const args = [ const args = [
state.is_functional_template_mode 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)], []) : b.template([b.quasi(template_to_string(state.template), true)], [])
]; ];

@ -1,56 +1,24 @@
/** /**
* @import { TemplateOperations } from "../types.js" * @import { TemplateOperations } from "../types.js"
* @import { Namespace } from "#compiler" * @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 { NAMESPACE_SVG, NAMESPACE_MATHML } from '../../../../../constants.js';
import * as b from '../../../../utils/builders.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'; 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 {TemplateOperations} items
* @param {Namespace} namespace
*/ */
export function template_to_functions(items, namespace) { export function template_to_functions(items) {
let elements = []; let elements = b.array([]);
let body = [];
let scope = new Scope();
/** /**
* @type {Array<Element>} * @type {Array<Element>}
*/ */
let elements_stack = []; let elements_stack = [];
/**
* @type {Array<string>}
*/
let namespace_stack = [];
/**
* @type {number}
*/
let foreign_object_count = 0;
/** /**
* @type {Element | undefined} * @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 // we closed one element, we remove it from the stack and eventually revert back
// the namespace to the previous one // the namespace to the previous one
if (instruction.kind === 'pop_element') { if (instruction.kind === 'pop_element') {
const removed = elements_stack.pop(); elements_stack.pop();
if (removed?.namespaced) {
namespace_stack.pop();
}
if (removed?.element === 'foreignObject') {
foreign_object_count--;
}
continue; 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 // @ts-expect-error we can't be here if `swap_current_element` but TS doesn't know that
const value = map[instruction.kind]( 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' ...(instruction.kind === 'create_element'
? [ ? []
foreign_object_count > 0 : [instruction.kind === 'set_prop' ? last_current_element : elements_stack.at(-1)]),
? undefined
: namespace_stack.at(-1) ??
(namespace === 'svg'
? NAMESPACE_SVG
: namespace === 'mathml'
? NAMESPACE_MATHML
: undefined)
]
: []),
...(instruction.args ?? []) ...(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 // 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 // append the element/node/anchor to the current active element or push it in the elements array
if (instruction.kind !== 'set_prop') { if (instruction.kind !== 'set_prop') {
if (elements_stack.length >= 1 && value) { if (elements_stack.length >= 1 && value !== undefined) {
const { call } = map.insert(/** @type {Element} */ (elements_stack.at(-1)), value); map.insert(/** @type {Element} */ (elements_stack.at(-1)), value);
body.push(call); } else if (value !== undefined) {
} else if (value) { elements.elements.push(value);
elements.push(b.id(value.name));
} }
// keep track of the last created element (it will be pushed to the stack after the props are set) // keep track of the last created element (it will be pushed to the stack after the props are set)
if (instruction.kind === 'create_element') { if (instruction.kind === 'create_element') {
last_current_element = /** @type {Element} */ (value); 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 * @param {string} element
* @returns {Element} * @returns {Element}
*/ */
function create_element(scope, namespace, element) { function create_element(element) {
const name = scope.generate(element); return b.object([b.prop('init', b.id('e'), b.literal(element))]);
let fn = namespace != null ? 'document.createElementNS' : 'document.createElement'; }
let args = [b.literal(element)];
if (namespace != null) { /**
args.unshift(b.literal(namespace)); *
} * @param {Element} element
const call = b.var(name, b.call(fn, ...args)); * @param {string} name
/** * @param {Expression} init
* if there's an "is" attribute we can't just add it as a property, it needs to be * @returns {Property}
* specified on creation like this `document.createElement('button', { is: 'my-button' })` */
* function get_or_create_prop(element, name, init) {
* Since the props are appended after the creation we change the generated call arguments and we push let prop = element.properties.find(
* the is attribute later on on `set_prop` (prop) => prop.type === 'Property' && /** @type {Identifier} */ (prop.key).name === name
* @param {string} value );
*/ if (!prop) {
function add_is(value) { prop = b.prop('init', b.id(name), init);
/** @type {CallExpression} */ (call.declarations[0].init).arguments.push( element.properties.push(prop);
b.object([b.prop('init', b.literal('is'), b.literal(value))])
);
} }
return { return /** @type {Property} */ (prop);
call,
name,
element,
add_is,
namespaced: namespace != null
};
} }
/** /**
* @param {Scope} scope * @param {Element} element
* @param {string} data * @param {string} data
* @returns {Anchor} * @returns {Anchor}
*/ */
function create_anchor(scope, data = '') { function create_anchor(element, data = '') {
const name = scope.generate('comment'); if (!element) return data ? b.array([b.literal(data)]) : null;
return { const c = get_or_create_prop(element, 'c', b.array([]));
call: b.var(name, b.call('document.createComment', b.literal(data))), /** @type {ArrayExpression} */ (c.value).elements.push(data ? b.array([b.literal(data)]) : null);
name
};
} }
/** /**
* @param {Scope} scope * @param {Element} element
* @param {string} value * @param {string} value
* @returns {Text} * @returns {Text}
*/ */
function create_text(scope, value) { function create_text(element, value) {
const name = scope.generate('text'); if (!element) return b.literal(value);
return { const c = get_or_create_prop(element, 'c', b.array([]));
call: b.var(name, b.call('document.createTextNode', b.literal(value))), /** @type {ArrayExpression} */ (c.value).elements.push(b.literal(value));
name
};
} }
/** /**
* *
* @param {Element} el * @param {Element} element
* @param {string} prop * @param {string} prop
* @param {string} value * @param {string} value
*/ */
function set_prop(el, prop, value) { function set_prop(element, prop, value) {
// see comment above about the "is" attribute const p = get_or_create_prop(element, 'p', b.object([]));
if (prop === 'is') { if (prop === 'is') {
el.add_is(value); element.properties.push(b.prop('init', b.id(prop), b.literal(value)));
return; return;
} }
const [namespace] = prop.split(':'); const prop_correct_case = fix_attribute_casing(prop);
let fn = namespace !== prop ? '.setAttributeNS' : '.setAttribute';
let args = [b.literal(fix_attribute_casing(prop)), b.literal(value ?? '')];
// attributes like `xlink:href` need to be set with the `xlink` namespace const is_valid_id = regex_is_valid_identifier.test(prop_correct_case);
if (namespace === 'xlink') {
args.unshift(b.literal('http://www.w3.org/1999/xlink'));
}
return { /** @type {ObjectExpression} */ (p.value).properties.push(
call: b.call(el.name + fn, ...args) b.prop(
}; 'init',
(is_valid_id ? b.id : b.literal)(prop_correct_case),
b.literal(value),
!is_valid_id
)
);
} }
/** /**
* *
* @param {Element} el * @param {Element} element
* @param {Node} child * @param {Element} child
* @param {Node} [anchor]
*/ */
function insert(el, child, anchor) { function insert(element, child) {
return { const c = get_or_create_prop(element, 'c', b.array([]));
call: b.call( /** @type {ArrayExpression} */ (c.value).elements.push(child);
// 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')
)
};
} }
let map = { let map = {

@ -204,3 +204,44 @@ export function sibling(node, count = 1, is_text = false) {
export function clear_text_content(node) { export function clear_text_content(node) {
node.textContent = ''; 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 { Effect, TemplateNode } from '#client' */
import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from './hydration.js'; 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 { create_fragment_from_html } from './reconciler.js';
import { active_effect } from '../runtime.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 * @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 * @param {number} flags
* @returns {() => Node | Node[]} * @returns {() => Node | Node[]}
*/ */
/*#__NO_SIDE_EFFECTS__*/ /*#__NO_SIDE_EFFECTS__*/
export function template_fn(fn, flags) { export function template_fn(structure, flags) {
var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0; var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;
var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0; var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0;
@ -84,7 +160,7 @@ export function template_fn(fn, flags) {
} }
if (node === undefined) { if (node === undefined) {
node = fn(); node = structure_to_fragment(structure);
if (!is_fragment) node = /** @type {Node} */ (get_first_child(node)); 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 * @param {number} flags
* @returns {() => Node | Node[]} * @returns {() => Node | Node[]}
*/ /*#__NO_SIDE_EFFECTS__*/ */ /*#__NO_SIDE_EFFECTS__*/
export function template_with_script_fn(fn, flags) { export function template_with_script_fn(structure, flags) {
var templated_fn = template_fn(fn, flags); var templated_fn = template_fn(structure, flags);
return () => run_scripts(/** @type {Element | DocumentFragment} */ (templated_fn())); 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 {number} flags
* @param {'svg' | 'math'} ns * @param {'svg' | 'math'} ns
* @returns {() => Node | Node[]} * @returns {() => Node | Node[]}
*/ */
/*#__NO_SIDE_EFFECTS__*/ /*#__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; var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;
/** @type {Element | DocumentFragment} */ /** @type {Element | DocumentFragment} */
@ -201,7 +277,7 @@ export function ns_template_fn(fn, flags, ns = 'svg') {
} }
if (!node) { if (!node) {
var fragment = /** @type {DocumentFragment} */ (fn()); var fragment = structure_to_fragment(structure, ns);
if (is_fragment) { if (is_fragment) {
node = document.createDocumentFragment(); 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 * @param {number} flags
* @returns {() => Node | Node[]} * @returns {() => Node | Node[]}
*/ */
/*#__NO_SIDE_EFFECTS__*/ /*#__NO_SIDE_EFFECTS__*/
export function svg_template_with_script_fn(fn, flags) { export function svg_template_with_script_fn(structure, flags) {
var templated_fn = ns_template_fn(fn, flags); var templated_fn = ns_template_fn(structure, flags);
return () => run_scripts(/** @type {Element | DocumentFragment} */ (templated_fn())); 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 * @param {number} flags
* @returns {() => Node | Node[]} * @returns {() => Node | Node[]}
*/ */
/*#__NO_SIDE_EFFECTS__*/ /*#__NO_SIDE_EFFECTS__*/
export function mathml_template_fn(fn, flags) { export function mathml_template_fn(structure, flags) {
return ns_template_fn(fn, flags, 'math'); return ns_template_fn(structure, flags, 'math');
} }
/** /**

@ -5,23 +5,7 @@ function increment(_, counter) {
counter.count += 1; counter.count += 1;
} }
var root = $.template_fn( var root = $.template_fn([{ e: 'button', c: [' '] }, ' ', , ' '], 1);
() => {
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
);
export default function Await_block_scope($$anchor) { export default function Await_block_scope($$anchor) {
let counter = $.proxy({ count: 0 }); let counter = $.proxy({ count: 0 });

@ -10,18 +10,7 @@ const snippet = ($$anchor) => {
$.append($$anchor, text); $.append($$anchor, text);
}; };
var root = $.template_fn( var root = $.template_fn([,, ' '], 1);
() => {
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
);
export default function Bind_component_snippet($$anchor) { export default function Bind_component_snippet($$anchor) {
let value = $.state(''); let value = $.state('');

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

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

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

@ -4,23 +4,15 @@ import * as $ from 'svelte/internal/client';
var on_click = (_, count) => $.update(count); var on_click = (_, count) => $.update(count);
var root = $.template_fn( var root = $.template_fn(
() => { [
var h1 = document.createElement('h1'); { e: 'h1' },
var text = document.createTextNode(' '); ' ',
var b = document.createElement('b'); { e: 'b' },
var text_1 = document.createTextNode(' '); ' ',
var button = document.createElement('button'); { e: 'button', c: [' '] },
var text_2 = document.createTextNode(' '); ' ',
{ e: 'h1' }
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;
},
1 1
); );

@ -2,20 +2,7 @@ import 'svelte/internal/disclose-version';
import 'svelte/internal/flags/legacy'; import 'svelte/internal/flags/legacy';
import * as $ from 'svelte/internal/client'; import * as $ from 'svelte/internal/client';
var root = $.template_fn( var root = $.template_fn([{ e: 'p' }, ' ', { e: 'p' }, ' ', ,], 1);
() => {
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
);
export default function Purity($$anchor) { export default function Purity($$anchor) {
var fragment = root(); var fragment = root();

@ -2,238 +2,94 @@ import 'svelte/internal/disclose-version';
import * as $ from 'svelte/internal/client'; import * as $ from 'svelte/internal/client';
var root = $.template_fn( var root = $.template_fn(
() => { [
var header = document.createElement('header'); {
var nav = document.createElement('nav'); e: 'header',
c: [
header.insertBefore(nav, undefined) {
e: 'nav',
var a = document.createElement('a'); c: [
{ e: 'a', p: { href: '/' }, c: ['Home'] },
nav.insertBefore(a, undefined) ' ',
a.setAttribute('href', '/') {
e: 'a',
var text = document.createTextNode('Home'); p: { href: '/away' },
c: ['Away']
a.insertBefore(text, undefined) }
]
var text_1 = document.createTextNode(' '); }
]
nav.insertBefore(text_1, undefined) },
' ',
var a_1 = document.createElement('a'); {
e: 'main',
nav.insertBefore(a_1, undefined) c: [
a_1.setAttribute('href', '/away') { e: 'h1', c: [' '] },
' ',
var text_2 = document.createTextNode('Away'); {
e: 'div',
a_1.insertBefore(text_2, undefined) p: { class: 'static' },
c: [
var text_3 = document.createTextNode(' '); {
var main = document.createElement('main'); e: 'p',
var h1 = document.createElement('h1'); c: ['we don\'t need to traverse these nodes']
}
main.insertBefore(h1, undefined) ]
},
var text_4 = document.createTextNode(' '); ' ',
{ e: 'p', c: ['or'] },
h1.insertBefore(text_4, undefined) ' ',
{ e: 'p', c: ['these'] },
var text_5 = document.createTextNode(' '); ' ',
{ e: 'p', c: ['ones'] },
main.insertBefore(text_5, undefined) ' ',
,
var div = document.createElement('div'); ' ',
{ e: 'p', c: ['these'] },
main.insertBefore(div, undefined) ' ',
div.setAttribute('class', 'static') { e: 'p', c: ['trailing'] },
' ',
var p = document.createElement('p'); { e: 'p', c: ['nodes'] },
' ',
div.insertBefore(p, undefined) { e: 'p', c: ['can'] },
' ',
var text_6 = document.createTextNode('we don\'t need to traverse these nodes'); { e: 'p', c: ['be'] },
' ',
p.insertBefore(text_6, undefined) { e: 'p', c: ['completely'] },
' ',
var text_7 = document.createTextNode(' '); { e: 'p', c: ['ignored'] }
]
main.insertBefore(text_7, undefined) },
' ',
var p_1 = document.createElement('p'); {
e: 'cant-skip',
main.insertBefore(p_1, undefined) c: [{ e: 'custom-elements' }]
},
var text_8 = document.createTextNode('or'); ' ',
{ e: 'div', c: [{ e: 'input' }] },
p_1.insertBefore(text_8, undefined) ' ',
{ e: 'div', c: [{ e: 'source' }] },
var text_9 = document.createTextNode(' '); ' ',
{
main.insertBefore(text_9, undefined) e: 'select',
c: [{ e: 'option', c: ['a'] }]
var p_2 = document.createElement('p'); },
' ',
main.insertBefore(p_2, undefined) {
e: 'img',
var text_10 = document.createTextNode('these'); p: { src: '...', alt: '', loading: 'lazy' }
},
p_2.insertBefore(text_10, undefined) ' ',
{
var text_11 = document.createTextNode(' '); e: 'div',
c: [
main.insertBefore(text_11, undefined) {
e: 'img',
var p_3 = document.createElement('p'); p: { src: '...', alt: '', loading: 'lazy' }
}
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;
},
3 3
); );

@ -9,21 +9,13 @@ function reset(_, str, tpl) {
} }
var root = $.template_fn( var root = $.template_fn(
() => { [
var input = document.createElement('input'); { e: 'input' },
var text = document.createTextNode(' '); ' ',
var input_1 = document.createElement('input'); { e: 'input' },
var text_1 = document.createTextNode(' '); ' ',
var button = document.createElement('button'); { e: 'button', c: ['reset'] }
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;
},
1 1
); );

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

Loading…
Cancel
Save