feat: use bracket matching instead of `ssr:n` comments (#10904)

* use short comments

* use bracket matching

* fix

* update snapshots

* update tests

* fix
pull/10889/head
Rich Harris 9 months ago committed by GitHub
parent f1d9afe32f
commit 8685d497e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -27,6 +27,9 @@ import { regex_starts_with_newline, regex_whitespaces_strict } from '../../patte
import { DOMBooleanAttributes } from '../../../../constants.js'; import { DOMBooleanAttributes } from '../../../../constants.js';
import { sanitize_template_string } from '../../../utils/sanitize_template_string.js'; import { sanitize_template_string } from '../../../utils/sanitize_template_string.js';
const block_open = t_string('<![>');
const block_close = t_string('<!]>');
/** /**
* @param {string} value * @param {string} value
* @returns {import('./types').TemplateString} * @returns {import('./types').TemplateString}
@ -52,15 +55,6 @@ function t_statement(value) {
return { type: 'statement', value }; return { type: 'statement', value };
} }
/**
* @param {import('./types').ServerTransformState} state
* @returns {[import('estree').VariableDeclaration, import('estree').Identifier]}
*/
function serialize_anchor(state) {
const id = state.scope.root.unique('anchor');
return [b.const(id, b.call('$.create_anchor', b.id('$$payload'))), id];
}
/** /**
* @param {import('./types').Template[]} template * @param {import('./types').Template[]} template
* @param {import('estree').Identifier} out * @param {import('estree').Identifier} out
@ -1237,12 +1231,10 @@ const template_visitors = {
}, },
HtmlTag(node, context) { HtmlTag(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
const raw = /** @type {import('estree').Expression} */ (context.visit(node.expression)); const raw = /** @type {import('estree').Expression} */ (context.visit(node.expression));
context.state.template.push(t_expression(raw)); context.state.template.push(t_expression(raw));
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
ConstTag(node, { state, visit }) { ConstTag(node, { state, visit }) {
const declaration = node.declaration.declarations[0]; const declaration = node.declaration.declarations[0];
@ -1273,10 +1265,8 @@ const template_visitors = {
}, },
RenderTag(node, context) { RenderTag(node, context) {
const state = context.state; const state = context.state;
const [anchor, anchor_id] = serialize_anchor(state);
state.init.push(anchor); state.template.push(block_open);
state.template.push(t_expression(anchor_id));
const callee = unwrap_optional(node.expression).callee; const callee = unwrap_optional(node.expression).callee;
const raw_args = unwrap_optional(node.expression).arguments; const raw_args = unwrap_optional(node.expression).arguments;
@ -1302,7 +1292,7 @@ const template_visitors = {
) )
); );
state.template.push(t_expression(anchor_id)); state.template.push(block_close);
}, },
ClassDirective(node) { ClassDirective(node) {
error(node, 'INTERNAL', 'Node should have been handled elsewhere'); error(node, 'INTERNAL', 'Node should have been handled elsewhere');
@ -1427,9 +1417,7 @@ const template_visitors = {
} }
}; };
const [el_anchor, anchor_id] = serialize_anchor(context.state); context.state.template.push(block_open);
context.state.init.push(el_anchor);
context.state.template.push(t_expression(anchor_id));
const main = create_block(node, node.fragment.nodes, { const main = create_block(node, node.fragment.nodes, {
...context, ...context,
@ -1465,7 +1453,7 @@ const template_visitors = {
) )
) )
), ),
t_expression(anchor_id) block_close
); );
if (context.state.options.dev) { if (context.state.options.dev) {
context.state.template.push(t_statement(b.stmt(b.call('$.pop_element')))); context.state.template.push(t_statement(b.stmt(b.call('$.pop_element'))));
@ -1473,9 +1461,7 @@ const template_visitors = {
}, },
EachBlock(node, context) { EachBlock(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
const each_node_meta = node.metadata; const each_node_meta = node.metadata;
const collection = /** @type {import('estree').Expression} */ (context.visit(node.expression)); const collection = /** @type {import('estree').Expression} */ (context.visit(node.expression));
@ -1486,14 +1472,6 @@ const template_visitors = {
: b.id(node.index); : b.id(node.index);
const children = node.body.nodes; const children = node.body.nodes;
const [each_dec, each_id] = serialize_anchor(state);
/** @type {import('./types').Anchor} */
const anchor = {
type: 'Anchor',
id: each_id
};
const array_id = state.scope.root.unique('each_array'); const array_id = state.scope.root.unique('each_array');
state.init.push(b.const(array_id, b.call('$.ensure_array_like', collection))); state.init.push(b.const(array_id, b.call('$.ensure_array_like', collection)));
@ -1507,11 +1485,14 @@ const template_visitors = {
each.push(b.let(node.index, index)); each.push(b.let(node.index, index));
} }
each.push(b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(block_open.value))));
each.push( each.push(
each_dec, .../** @type {import('estree').Statement[]} */ (create_block(node, children, context))
.../** @type {import('estree').Statement[]} */ (create_block(node, children, context, anchor))
); );
each.push(b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(block_close.value))));
const for_loop = b.for( const for_loop = b.for(
b.let(index, b.literal(0)), b.let(index, b.literal(0)),
b.binary('<', index, b.member(array_id, b.id('length'))), b.binary('<', index, b.member(array_id, b.id('length'))),
@ -1535,13 +1516,11 @@ const template_visitors = {
} else { } else {
state.template.push(t_statement(for_loop)); state.template.push(t_statement(for_loop));
} }
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
IfBlock(node, context) { IfBlock(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
// Insert ssr:if:true/false anchors in addition to the other anchors so that // Insert ssr:if:true/false anchors in addition to the other anchors so that
// the if block can catch hydration mismatches (false on the server, true on the client and vice versa) // the if block can catch hydration mismatches (false on the server, true on the client and vice versa)
@ -1568,13 +1547,11 @@ const template_visitors = {
) )
) )
); );
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
AwaitBlock(node, context) { AwaitBlock(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
state.template.push( state.template.push(
t_statement( t_statement(
@ -1608,16 +1585,14 @@ const template_visitors = {
) )
); );
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
KeyBlock(node, context) { KeyBlock(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
const body = create_block(node, node.fragment.nodes, context); const body = create_block(node, node.fragment.nodes, context);
state.template.push(t_statement(b.block(body))); state.template.push(t_statement(b.block(body)));
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
SnippetBlock(node, context) { SnippetBlock(node, context) {
// TODO hoist where possible // TODO hoist where possible
@ -1635,34 +1610,28 @@ const template_visitors = {
}, },
Component(node, context) { Component(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
const call = serialize_inline_component(node, node.name, context); const call = serialize_inline_component(node, node.name, context);
state.template.push(t_statement(call)); state.template.push(t_statement(call));
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
SvelteSelf(node, context) { SvelteSelf(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
const call = serialize_inline_component(node, context.state.analysis.name, context); const call = serialize_inline_component(node, context.state.analysis.name, context);
state.template.push(t_statement(call)); state.template.push(t_statement(call));
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
SvelteComponent(node, context) { SvelteComponent(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
const call = serialize_inline_component( const call = serialize_inline_component(
node, node,
/** @type {import('estree').Expression} */ (context.visit(node.expression)), /** @type {import('estree').Expression} */ (context.visit(node.expression)),
context context
); );
state.template.push(t_statement(call)); state.template.push(t_statement(call));
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
LetDirective(node, { state }) { LetDirective(node, { state }) {
if (node.expression && node.expression.type !== 'Identifier') { if (node.expression && node.expression.type !== 'Identifier') {
@ -1745,9 +1714,7 @@ const template_visitors = {
}, },
SlotElement(node, context) { SlotElement(node, context) {
const state = context.state; const state = context.state;
const [dec, id] = serialize_anchor(state); state.template.push(block_open);
state.init.push(dec);
state.template.push(t_expression(id));
/** @type {import('estree').Property[]} */ /** @type {import('estree').Property[]} */
const props = []; const props = [];
@ -1794,7 +1761,7 @@ const template_visitors = {
const slot = b.call('$.slot', b.id('$$payload'), expression, props_expression, fallback); const slot = b.call('$.slot', b.id('$$payload'), expression, props_expression, fallback);
state.template.push(t_statement(b.stmt(slot))); state.template.push(t_statement(b.stmt(slot)));
state.template.push(t_expression(id)); state.template.push(block_close);
}, },
SvelteHead(node, context) { SvelteHead(node, context) {
const state = context.state; const state = context.state;

@ -39,7 +39,7 @@ export function update_hydrate_nodes(first, insert_text) {
} }
/** /**
* Returns all nodes between the first `<!--ssr:...-->` comment tag pair encountered. * Returns all nodes between the first `<![>...<!]>` comment tag pair encountered.
* @param {Node | null} node * @param {Node | null} node
* @param {boolean} [insert_text] Whether to insert an empty text node if `nodes` is empty * @param {boolean} [insert_text] Whether to insert an empty text node if `nodes` is empty
* @returns {import('#client').TemplateNode[] | null} * @returns {import('#client').TemplateNode[] | null}
@ -50,34 +50,43 @@ function get_hydrate_nodes(node, insert_text = false) {
var current_node = /** @type {null | import('#client').TemplateNode} */ (node); var current_node = /** @type {null | import('#client').TemplateNode} */ (node);
/** @type {null | string} */ var depth = 0;
var target_depth = null;
var will_start = false;
var started = false;
while (current_node !== null) { while (current_node !== null) {
if (current_node.nodeType === 8) { if (current_node.nodeType === 8) {
var data = /** @type {Comment} */ (current_node).data; var data = /** @type {Comment} */ (current_node).data;
if (data.startsWith('ssr:')) { if (data === '[') {
var depth = data.slice(4); depth += 1;
will_start = true;
} else if (data === ']') {
if (!started) {
// TODO get rid of this — it exists because each blocks are doubly wrapped
return null;
}
if (target_depth === null) { if (--depth === 0) {
target_depth = depth;
} else if (depth === target_depth) {
if (insert_text && nodes.length === 0) { if (insert_text && nodes.length === 0) {
var text = empty(); var text = empty();
nodes.push(text); nodes.push(text);
current_node.before(text); current_node.before(text);
} }
return nodes; return nodes;
} else {
nodes.push(current_node);
} }
} }
} else if (target_depth !== null) { }
if (started) {
nodes.push(current_node); nodes.push(current_node);
} }
current_node = /** @type {null | import('#client').TemplateNode} */ (current_node.nextSibling); current_node = /** @type {null | import('#client').TemplateNode} */ (current_node.nextSibling);
started = will_start;
} }
return null; return null;
@ -103,7 +112,7 @@ export function hydrate_block_anchor(node) {
export function capture_fragment_from_node(node) { export function capture_fragment_from_node(node) {
if ( if (
node.nodeType === 8 && node.nodeType === 8 &&
/** @type {Comment} */ (node).data.startsWith('ssr:') && /** @type {Comment} */ (node).data === '[' &&
hydrate_nodes[hydrate_nodes.length - 1] !== node hydrate_nodes[hydrate_nodes.length - 1] !== node
) { ) {
const nodes = /** @type {Node[]} */ (get_hydrate_nodes(node)); const nodes = /** @type {Node[]} */ (get_hydrate_nodes(node));

@ -1,5 +1,11 @@
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { append_child, create_element, empty, init_operations } from './dom/operations.js'; import {
append_child,
clear_text_content,
create_element,
empty,
init_operations
} from './dom/operations.js';
import { PassiveDelegatedEvents } from '../../constants.js'; import { PassiveDelegatedEvents } from '../../constants.js';
import { remove } from './dom/reconciler.js'; import { remove } from './dom/reconciler.js';
import { flush_sync, push, pop, current_component_context } from './runtime.js'; import { flush_sync, push, pop, current_component_context } from './runtime.js';
@ -170,9 +176,9 @@ export function hydrate(component, options) {
: ''), : ''),
error error
); );
remove(nodes);
first_child.remove(); clear_text_content(container);
nodes[nodes.length - 1]?.nextSibling?.remove();
set_hydrating(false); set_hydrating(false);
return mount(component, options); return mount(component, options);
} else { } else {

@ -162,13 +162,12 @@ export function element(payload, tag, attributes_fn, children_fn) {
payload.out += `>`; payload.out += `>`;
if (!VoidElements.has(tag)) { if (!VoidElements.has(tag)) {
const anchor = tag !== 'textarea' ? create_anchor(payload) : null; if (tag !== 'textarea') {
if (anchor !== null) { payload.out += '<![>';
payload.out += anchor;
} }
children_fn(); children_fn();
if (anchor !== null) { if (tag !== 'textarea') {
payload.out += anchor; payload.out += '<!]>';
} }
payload.out += `</${tag}>`; payload.out += `</${tag}>`;
} }
@ -187,12 +186,10 @@ export let on_destroy = [];
*/ */
export function render(component, options) { export function render(component, options) {
const payload = create_payload(); const payload = create_payload();
const root_anchor = create_anchor(payload);
const root_head_anchor = create_anchor(payload.head);
const prev_on_destroy = on_destroy; const prev_on_destroy = on_destroy;
on_destroy = []; on_destroy = [];
payload.out += root_anchor; payload.out += '<![>';
if (options.context) { if (options.context) {
$.push({}); $.push({});
@ -203,14 +200,14 @@ export function render(component, options) {
if (options.context) { if (options.context) {
$.pop(); $.pop();
} }
payload.out += root_anchor; payload.out += '<!]>';
for (const cleanup of on_destroy) cleanup(); for (const cleanup of on_destroy) cleanup();
on_destroy = prev_on_destroy; on_destroy = prev_on_destroy;
return { return {
head: head:
payload.head.out || payload.head.title payload.head.out || payload.head.title
? payload.head.title + root_head_anchor + payload.head.out + root_head_anchor ? payload.head.title + '<![>' + payload.head.out + '<!]>'
: '', : '',
html: payload.out html: payload.out
}; };
@ -284,17 +281,16 @@ export function attr(name, value, boolean) {
*/ */
export function css_props(payload, is_html, props, component) { export function css_props(payload, is_html, props, component) {
const styles = style_object_to_string(props); const styles = style_object_to_string(props);
const anchor = create_anchor(payload);
if (is_html) { if (is_html) {
payload.out += `<div style="display: contents; ${styles}">${anchor}`; payload.out += `<div style="display: contents; ${styles}"><![>`;
} else { } else {
payload.out += `<g style="${styles}">${anchor}`; payload.out += `<g style="${styles}"><![>`;
} }
component(); component();
if (is_html) { if (is_html) {
payload.out += `${anchor}</div>`; payload.out += `<!]></div>`;
} else { } else {
payload.out += `${anchor}</g>`; payload.out += `<!]></g>`;
} }
} }
@ -634,12 +630,6 @@ export function ensure_array_like(array_like_or_iterator) {
: Array.from(array_like_or_iterator); : Array.from(array_like_or_iterator);
} }
/** @param {{ anchor: number }} payload */
export function create_anchor(payload) {
const depth = payload.anchor++;
return `<!ssr:${depth}>`;
}
/** /**
* @param {number} timeout * @param {number} timeout
* @returns {() => void} * @returns {() => void}

@ -12,7 +12,7 @@ function get_html(ssr) {
// ssr rendered HTML has an extra newline prefixed within `<pre>` tag, // ssr rendered HTML has an extra newline prefixed within `<pre>` tag,
// if the <pre> tag starts with `\n` // if the <pre> tag starts with `\n`
// because when browser parses the SSR rendered HTML, it will ignore the 1st '\n' character // because when browser parses the SSR rendered HTML, it will ignore the 1st '\n' character
return `${ssr ? '<!--ssr:0-->' : ''}<pre id="pre"> A return `${ssr ? '<!--[-->' : ''}<pre id="pre"> A
B B
<span> <span>
C C
@ -35,5 +35,5 @@ function get_html(ssr) {
leading newlines</pre></div> <div id="pre-without-leading-newline"><pre>without spaces</pre> <pre> with spaces </pre> <pre>${' '} leading newlines</pre></div> <div id="pre-without-leading-newline"><pre>without spaces</pre> <pre> with spaces </pre> <pre>${' '}
newline after leading space</pre></div> <pre id="pre-with-multiple-leading-newlines"> newline after leading space</pre></div> <pre id="pre-with-multiple-leading-newlines">
multiple leading newlines</pre>${ssr ? '<!--ssr:0-->' : ''}`; multiple leading newlines</pre>${ssr ? '<!--]-->' : ''}`;
} }

@ -11,7 +11,7 @@ export default test({
if (variant === 'dom') { if (variant === 'dom') {
assert.ok(!span.previousSibling); assert.ok(!span.previousSibling);
} else { } else {
assert.ok(span.previousSibling?.textContent?.startsWith('ssr:')); // ssr commment node assert.ok(span.previousSibling?.textContent === '['); // ssr commment node
} }
component.raw = '<span>bar</span>'; component.raw = '<span>bar</span>';

@ -4,17 +4,17 @@ export default test({
withoutNormalizeHtml: true, withoutNormalizeHtml: true,
// Unable to test `html` with `<textarea>` content // Unable to test `html` with `<textarea>` content
// as the textarea#value will not show within `innerHtml` // as the textarea#value will not show within `innerHtml`
ssrHtml: `<!--ssr:0--><textarea id="textarea"> A ssrHtml: `<!--[--><textarea id="textarea"> A
B B
</textarea> <div id="div-with-textarea"><textarea> A </textarea> <div id="div-with-textarea"><textarea> A
B B
</textarea></div> <div id="textarea-with-leading-newline"><textarea>leading newline</textarea> <textarea> leading newline and spaces</textarea> <textarea> </textarea></div> <div id="textarea-with-leading-newline"><textarea>leading newline</textarea> <textarea> leading newline and spaces</textarea> <textarea>
leading newlines</textarea></div> <div id="textarea-without-leading-newline"><textarea>without spaces</textarea> <textarea> with spaces </textarea> <textarea> leading newlines</textarea></div> <div id="textarea-without-leading-newline"><textarea>without spaces</textarea> <textarea> with spaces </textarea> <textarea>${' '}
newline after leading space</textarea></div> <textarea id="textarea-with-multiple-leading-newlines"> newline after leading space</textarea></div> <textarea id="textarea-with-multiple-leading-newlines">
multiple leading newlines</textarea> <div id="div-with-textarea-with-multiple-leading-newlines"><textarea> multiple leading newlines</textarea> <div id="div-with-textarea-with-multiple-leading-newlines"><textarea>
multiple leading newlines</textarea></div><!--ssr:0-->`, multiple leading newlines</textarea></div><!--]-->`,
test({ assert, target }) { test({ assert, target }) {
// Test for <textarea> tag // Test for <textarea> tag
const elementTextarea = /** @type {HTMLTextAreaElement} */ (target.querySelector('#textarea')); const elementTextarea = /** @type {HTMLTextAreaElement} */ (target.querySelector('#textarea'));

@ -1,5 +1 @@
<!--ssr:0--> <![><p>before</p><!-- a comment --><p>after</p><!]>
<p>before</p>
<!-- a comment -->
<p>after</p>
<!--ssr:0-->

@ -1 +1 @@
<!ssr:0><div>Just a dummy page.</div><!ssr:0> <![><div>Just a dummy page.</div><!]>

@ -14,4 +14,4 @@ export default function Bind_this($$anchor, $$props) {
$.bind_this(Foo(node, {}), ($$value) => foo = $$value, () => foo); $.bind_this(Foo(node, {}), ($$value) => foo = $$value, () => foo);
$.close_frag($$anchor, fragment); $.close_frag($$anchor, fragment);
$.pop(); $.pop();
} }

@ -4,11 +4,8 @@ import * as $ from "svelte/internal/server";
export default function Bind_this($$payload, $$props) { export default function Bind_this($$payload, $$props) {
$.push(false); $.push(false);
$$payload.out += `<![>`;
const anchor = $.create_anchor($$payload);
$$payload.out += `${anchor}`;
Foo($$payload, {}); Foo($$payload, {});
$$payload.out += `${anchor}`; $$payload.out += `<!]>`;
$.pop(); $.pop();
} }

@ -45,4 +45,4 @@ export default function Main($$anchor, $$props) {
$.close_frag($$anchor, fragment); $.close_frag($$anchor, fragment);
$.pop(); $.pop();
} }

@ -28,4 +28,4 @@ export default function Each_string_template($$anchor, $$props) {
$.close_frag($$anchor, fragment); $.close_frag($$anchor, fragment);
$.pop(); $.pop();
} }

@ -5,18 +5,18 @@ import * as $ from "svelte/internal/server";
export default function Each_string_template($$payload, $$props) { export default function Each_string_template($$payload, $$props) {
$.push(false); $.push(false);
const anchor = $.create_anchor($$payload);
const each_array = $.ensure_array_like(['foo', 'bar', 'baz']); const each_array = $.ensure_array_like(['foo', 'bar', 'baz']);
$$payload.out += `${anchor}`; $$payload.out += `<![>`;
for (let $$index = 0; $$index < each_array.length; $$index++) { for (let $$index = 0; $$index < each_array.length; $$index++) {
const thing = each_array[$$index]; const thing = each_array[$$index];
const anchor_1 = $.create_anchor($$payload);
$$payload.out += `${anchor_1}${$.escape(thing)}, ${anchor_1}`; $$payload.out += "<![>";
$$payload.out += `${$.escape(thing)}, `;
$$payload.out += "<!]>";
} }
$$payload.out += `${anchor}`; $$payload.out += `<!]>`;
$.pop(); $.pop();
} }

@ -33,4 +33,4 @@ export default function Function_prop_no_getter($$anchor, $$props) {
$.close_frag($$anchor, fragment); $.close_frag($$anchor, fragment);
$.pop(); $.pop();
} }

@ -12,9 +12,8 @@ export default function Function_prop_no_getter($$payload, $$props) {
} }
const plusOne = (num) => num + 1; const plusOne = (num) => num + 1;
const anchor = $.create_anchor($$payload);
$$payload.out += `${anchor}`; $$payload.out += `<![>`;
Button($$payload, { Button($$payload, {
onmousedown: () => count += 1, onmousedown: () => count += 1,
@ -25,6 +24,6 @@ export default function Function_prop_no_getter($$payload, $$props) {
} }
}); });
$$payload.out += `${anchor}`; $$payload.out += `<!]>`;
$.pop(); $.pop();
} }

@ -14,4 +14,4 @@ export default function Hello_world($$anchor, $$props) {
$.close($$anchor, h1); $.close($$anchor, h1);
$.pop(); $.pop();
} }

@ -36,4 +36,4 @@ export default function State_proxy_literal($$anchor, $$props) {
$.pop(); $.pop();
} }
$.delegate(["click"]); $.delegate(["click"]);

@ -14,4 +14,4 @@ export default function Svelte_element($$anchor, $$props) {
$.element(node, tag, false); $.element(node, tag, false);
$.close_frag($$anchor, fragment); $.close_frag($$anchor, fragment);
$.pop(); $.pop();
} }

@ -6,10 +6,9 @@ export default function Svelte_element($$payload, $$props) {
$.push(true); $.push(true);
let { tag = 'hr' } = $$props; let { tag = 'hr' } = $$props;
const anchor = $.create_anchor($$payload);
$$payload.out += `${anchor}`; $$payload.out += `<![>`;
if (tag) $.element($$payload, tag, () => {}, () => {}); if (tag) $.element($$payload, tag, () => {}, () => {});
$$payload.out += `${anchor}`; $$payload.out += `<!]>`;
$.pop(); $.pop();
} }
Loading…
Cancel
Save