chore: Switch `payload.out` to an array (#16428)

* chore: Switch `payload.out` to an array

* Apply suggestions from code review

* changeset
pull/16435/head
Elliott Johnson 2 months ago committed by GitHub
parent c2da1ebb85
commit f5db130e2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: Switch `payload.out` to an array

@ -44,12 +44,12 @@ export function EachBlock(node, context) {
);
if (node.fallback) {
const open = b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open));
const open = b.stmt(b.call(b.member(b.id('$$payload.out'), b.id('push')), block_open));
const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback));
fallback.body.unshift(
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
b.stmt(b.call(b.member(b.id('$$payload.out'), b.id('push')), b.literal(BLOCK_OPEN_ELSE)))
);
state.template.push(

@ -17,10 +17,12 @@ export function IfBlock(node, context) {
? /** @type {BlockStatement} */ (context.visit(node.alternate))
: b.block([]);
consequent.body.unshift(b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open)));
consequent.body.unshift(
b.stmt(b.call(b.member(b.id('$$payload.out'), b.id('push')), block_open))
);
alternate.body.unshift(
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
b.stmt(b.call(b.member(b.id('$$payload.out'), b.id('push')), b.literal(BLOCK_OPEN_ELSE)))
);
context.state.template.push(b.if(test, consequent, alternate), block_close);

@ -96,10 +96,10 @@ function is_statement(node) {
/**
* @param {Array<Statement | Expression>} template
* @param {Identifier} out
* @param {AssignmentOperator} operator
* @param {AssignmentOperator | 'push'} operator
* @returns {Statement[]}
*/
export function build_template(template, out = b.id('$$payload.out'), operator = '+=') {
export function build_template(template, out = b.id('$$payload.out'), operator = 'push') {
/** @type {string[]} */
let strings = [];
@ -110,18 +110,32 @@ export function build_template(template, out = b.id('$$payload.out'), operator =
const statements = [];
const flush = () => {
statements.push(
b.stmt(
b.assignment(
operator,
out,
b.template(
strings.map((cooked, i) => b.quasi(cooked, i === strings.length - 1)),
expressions
if (operator === 'push') {
statements.push(
b.stmt(
b.call(
b.member(out, b.id('push')),
b.template(
strings.map((cooked, i) => b.quasi(cooked, i === strings.length - 1)),
expressions
)
)
)
)
);
);
} else {
statements.push(
b.stmt(
b.assignment(
operator,
out,
b.template(
strings.map((cooked, i) => b.quasi(cooked, i === strings.length - 1)),
expressions
)
)
)
);
}
strings = [];
expressions = [];
};

@ -15,8 +15,10 @@ export function createRawSnippet(fn) {
// @ts-expect-error the types are a lie
return (/** @type {Payload} */ payload, /** @type {Params} */ ...args) => {
var getters = /** @type {Getters<Params>} */ (args.map((value) => () => value));
payload.out += fn(...getters)
.render()
.trim();
payload.out.push(
fn(...getters)
.render()
.trim()
);
};
}

@ -40,7 +40,7 @@ function print_error(payload, message) {
// eslint-disable-next-line no-console
console.error(message);
payload.head.out += `<script>console.error(${JSON.stringify(message)})</script>`;
payload.head.out.push(`<script>console.error(${JSON.stringify(message)})</script>`);
}
export function reset_elements() {

@ -33,23 +33,23 @@ const INVALID_ATTR_NAME_CHAR_REGEX =
* @returns {void}
*/
export function element(payload, tag, attributes_fn = noop, children_fn = noop) {
payload.out += '<!---->';
payload.out.push('<!---->');
if (tag) {
payload.out += `<${tag}`;
payload.out.push(`<${tag}`);
attributes_fn();
payload.out += `>`;
payload.out.push(`>`);
if (!is_void(tag)) {
children_fn();
if (!is_raw_text_element(tag)) {
payload.out += EMPTY_COMMENT;
payload.out.push(EMPTY_COMMENT);
}
payload.out += `</${tag}>`;
payload.out.push(`</${tag}>`);
}
}
payload.out += '<!---->';
payload.out.push('<!---->');
}
/**
@ -72,7 +72,7 @@ export function render(component, options = {}) {
const prev_on_destroy = on_destroy;
on_destroy = [];
payload.out += BLOCK_OPEN;
payload.out.push(BLOCK_OPEN);
let reset_reset_element;
@ -97,20 +97,22 @@ export function render(component, options = {}) {
reset_reset_element();
}
payload.out += BLOCK_CLOSE;
payload.out.push(BLOCK_CLOSE);
for (const cleanup of on_destroy) cleanup();
on_destroy = prev_on_destroy;
let head = payload.head.out + payload.head.title;
let head = payload.head.out.join('') + payload.head.title;
for (const { hash, code } of payload.css) {
head += `<style id="${hash}">${code}</style>`;
}
const body = payload.out.join('');
return {
head,
html: payload.out,
body: payload.out
html: body,
body: body
};
} finally {
abort();
@ -124,9 +126,9 @@ export function render(component, options = {}) {
*/
export function head(payload, fn) {
const head_payload = payload.head;
head_payload.out += BLOCK_OPEN;
head_payload.out.push(BLOCK_OPEN);
fn(head_payload);
head_payload.out += BLOCK_CLOSE;
head_payload.out.push(BLOCK_CLOSE);
}
/**
@ -141,21 +143,21 @@ export function css_props(payload, is_html, props, component, dynamic = false) {
const styles = style_object_to_string(props);
if (is_html) {
payload.out += `<svelte-css-wrapper style="display: contents; ${styles}">`;
payload.out.push(`<svelte-css-wrapper style="display: contents; ${styles}">`);
} else {
payload.out += `<g style="${styles}">`;
payload.out.push(`<g style="${styles}">`);
}
if (dynamic) {
payload.out += '<!---->';
payload.out.push('<!---->');
}
component();
if (is_html) {
payload.out += `<!----></svelte-css-wrapper>`;
payload.out.push(`<!----></svelte-css-wrapper>`);
} else {
payload.out += `<!----></g>`;
payload.out.push(`<!----></g>`);
}
}
@ -440,13 +442,13 @@ export function bind_props(props_parent, props_now) {
*/
function await_block(payload, promise, pending_fn, then_fn) {
if (is_promise(promise)) {
payload.out += BLOCK_OPEN;
payload.out.push(BLOCK_OPEN);
promise.then(null, noop);
if (pending_fn !== null) {
pending_fn();
}
} else if (then_fn !== null) {
payload.out += BLOCK_OPEN_ELSE;
payload.out.push(BLOCK_OPEN_ELSE);
then_fn(promise);
}
}
@ -493,7 +495,7 @@ export function once(get_value) {
*/
export function props_id(payload) {
const uid = payload.uid();
payload.out += '<!--#' + uid + '-->';
payload.out.push('<!--#' + uid + '-->');
return uid;
}
@ -562,10 +564,13 @@ export function valueless_option(payload, children) {
children();
var body = payload.out.slice(i);
var body = payload.out.slice(i).join('');
if (body.replace(/<!---->/g, '') === payload.select_value) {
// replace '>' with ' selected>' (closing tag will be added later)
payload.out = payload.out.slice(0, i - 1) + ' selected>' + body;
var last_item = payload.out[i - 1];
payload.out[i - 1] = last_item.slice(0, -1) + ' selected>';
// Remove the old items after position i and add the body as a single item
payload.out.splice(i, payload.out.length - i, body);
}
}

@ -1,11 +1,12 @@
export class HeadPayload {
/** @type {Set<{ hash: string; code: string }>} */
css = new Set();
out = '';
/** @type {string[]} */
out = [];
uid = () => '';
title = '';
constructor(css = new Set(), out = '', title = '', uid = () => '') {
constructor(css = new Set(), /** @type {string[]} */ out = [], title = '', uid = () => '') {
this.css = css;
this.out = out;
this.title = title;
@ -16,7 +17,8 @@ export class HeadPayload {
export class Payload {
/** @type {Set<{ hash: string; code: string }>} */
css = new Set();
out = '';
/** @type {string[]} */
out = [];
uid = () => '';
select_value = undefined;
@ -36,12 +38,12 @@ export class Payload {
export function copy_payload({ out, css, head, uid }) {
const payload = new Payload();
payload.out = out;
payload.out = [...out];
payload.css = new Set(css);
payload.uid = uid;
payload.head = new HeadPayload();
payload.head.out = head.out;
payload.head.out = [...head.out];
payload.head.css = new Set(head.css);
payload.head.title = head.title;
payload.head.uid = head.uid;
@ -56,7 +58,7 @@ export function copy_payload({ out, css, head, uid }) {
* @returns {void}
*/
export function assign_payload(p1, p2) {
p1.out = p2.out;
p1.out = [...p2.out];
p1.css = p2.css;
p1.head = p2.head;
p1.uid = p2.uid;

@ -8,7 +8,7 @@ export default function Await_block_scope($$payload) {
counter.count += 1;
}
$$payload.out += `<button>clicks: ${$.escape(counter.count)}</button> `;
$$payload.out.push(`<button>clicks: ${$.escape(counter.count)}</button> `);
$.await($$payload, promise, () => {}, (counter) => {});
$$payload.out += `<!--]--> ${$.escape(counter.count)}`;
$$payload.out.push(`<!--]--> ${$.escape(counter.count)}`);
}

@ -2,7 +2,7 @@ import * as $ from 'svelte/internal/server';
import TextInput from './Child.svelte';
function snippet($$payload) {
$$payload.out += `<!---->Something`;
$$payload.out.push(`<!---->Something`);
}
export default function Bind_component_snippet($$payload) {
@ -23,7 +23,7 @@ export default function Bind_component_snippet($$payload) {
}
});
$$payload.out += `<!----> value: ${$.escape(value)}`;
$$payload.out.push(`<!----> value: ${$.escape(value)}`);
}
do {

@ -3,11 +3,11 @@ import * as $ from 'svelte/internal/server';
export default function Delegated_locally_declared_shadowed($$payload) {
const each_array = $.ensure_array_like({ length: 1 });
$$payload.out += `<!--[-->`;
$$payload.out.push(`<!--[-->`);
for (let index = 0, $$length = each_array.length; index < $$length; index++) {
$$payload.out += `<button type="button"${$.attr('data-index', index)}>B</button>`;
$$payload.out.push(`<button type="button"${$.attr('data-index', index)}>B</button>`);
}
$$payload.out += `<!--]-->`;
$$payload.out.push(`<!--]-->`);
}

@ -6,5 +6,5 @@ export default function Main($$payload) {
let y = () => 'test';
$$payload.out += `<div${$.attr('foobar', x)}></div> <svg${$.attr('viewBox', x)}></svg> <custom-element${$.attr('foobar', x)}></custom-element> <div${$.attr('foobar', y())}></div> <svg${$.attr('viewBox', y())}></svg> <custom-element${$.attr('foobar', y())}></custom-element>`;
$$payload.out.push(`<div${$.attr('foobar', x)}></div> <svg${$.attr('viewBox', x)}></svg> <custom-element${$.attr('foobar', x)}></custom-element> <div${$.attr('foobar', y())}></div> <svg${$.attr('viewBox', y())}></svg> <custom-element${$.attr('foobar', y())}></custom-element>`);
}

@ -3,11 +3,11 @@ import * as $ from 'svelte/internal/server';
export default function Each_index_non_null($$payload) {
const each_array = $.ensure_array_like(Array(10));
$$payload.out += `<!--[-->`;
$$payload.out.push(`<!--[-->`);
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
$$payload.out += `<p>index: ${$.escape(i)}</p>`;
$$payload.out.push(`<p>index: ${$.escape(i)}</p>`);
}
$$payload.out += `<!--]-->`;
$$payload.out.push(`<!--]-->`);
}

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

@ -15,7 +15,7 @@ export default function Function_prop_no_getter($$payload) {
onmouseenter: () => count = plusOne(count),
children: ($$payload) => {
$$payload.out += `<!---->clicks: ${$.escape(count)}`;
$$payload.out.push(`<!---->clicks: ${$.escape(count)}`);
},
$$slots: { default: true }

@ -1,5 +1,5 @@
import * as $ from 'svelte/internal/server';
export default function Functional_templating($$payload) {
$$payload.out += `<h1>hello</h1> <div class="potato"><p>child element</p> <p>another child element</p></div>`;
$$payload.out.push(`<h1>hello</h1> <div class="potato"><p>child element</p> <p>another child element</p></div>`);
}

@ -1,5 +1,5 @@
import * as $ from 'svelte/internal/server';
export default function Hello_world($$payload) {
$$payload.out += `<h1>hello world</h1>`;
$$payload.out.push(`<h1>hello world</h1>`);
}

@ -1,5 +1,5 @@
import * as $ from 'svelte/internal/server';
export default function Hmr($$payload) {
$$payload.out += `<h1>hello world</h1>`;
$$payload.out.push(`<h1>hello world</h1>`);
}

@ -4,5 +4,5 @@ export default function Nullish_coallescence_omittance($$payload) {
let name = 'world';
let count = 0;
$$payload.out += `<h1>Hello, world!</h1> <b>123</b> <button>Count is ${$.escape(count)}</button> <h1>Hello, world</h1>`;
$$payload.out.push(`<h1>Hello, world!</h1> <b>123</b> <button>Count is ${$.escape(count)}</button> <h1>Hello, world</h1>`);
}

@ -1,7 +1,7 @@
import * as $ from 'svelte/internal/server';
export default function Purity($$payload) {
$$payload.out += `<p>0</p> <p>${$.escape(location.href)}</p> `;
$$payload.out.push(`<p>0</p> <p>${$.escape(location.href)}</p> `);
Child($$payload, { prop: encodeURIComponent('hello') });
$$payload.out += `<!---->`;
$$payload.out.push(`<!---->`);
}

@ -3,5 +3,5 @@ import * as $ from 'svelte/internal/server';
export default function Skip_static_subtree($$payload, $$props) {
let { title, content } = $$props;
$$payload.out += `<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1>${$.escape(title)}</h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> ${$.html(content)} <p>these</p> <p>trailing</p> <p>nodes</p> <p>can</p> <p>be</p> <p>completely</p> <p>ignored</p></main> <cant-skip><custom-elements with="attributes"></custom-elements></cant-skip> <div><input autofocus/></div> <div><source muted/></div> <select><option value="a"${$.maybe_selected($$payload, 'a')}>a</option></select> <img src="..." alt="" loading="lazy"/> <div><img src="..." alt="" loading="lazy"/></div>`;
$$payload.out.push(`<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1>${$.escape(title)}</h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> ${$.html(content)} <p>these</p> <p>trailing</p> <p>nodes</p> <p>can</p> <p>be</p> <p>completely</p> <p>ignored</p></main> <cant-skip><custom-elements with="attributes"></custom-elements></cant-skip> <div><input autofocus/></div> <div><source muted/></div> <select><option value="a"${$.maybe_selected($$payload, 'a')}>a</option></select> <img src="..." alt="" loading="lazy"/> <div><img src="..." alt="" loading="lazy"/></div>`);
}

@ -11,5 +11,5 @@ export default function State_proxy_literal($$payload) {
tpl = ``;
}
$$payload.out += `<input${$.attr('value', str)}/> <input${$.attr('value', tpl)}/> <button>reset</button>`;
$$payload.out.push(`<input${$.attr('value', str)}/> <input${$.attr('value', tpl)}/> <button>reset</button>`);
}

@ -12,5 +12,5 @@ export default function Text_nodes_deriveds($$payload) {
return count2;
}
$$payload.out += `<p>${$.escape(text1())}${$.escape(text2())}</p>`;
$$payload.out.push(`<p>${$.escape(text1())}${$.escape(text2())}</p>`);
}
Loading…
Cancel
Save