|
1 | 1 | /** @import { Node } from './types.js' */ |
2 | 2 | import { escape_html } from '../../../../../escaping.js'; |
3 | 3 | import { is_void } from '../../../../../utils.js'; |
| 4 | +import * as b from '../../../../utils/builders.js'; |
4 | 5 |
|
5 | 6 | /** |
6 | 7 | * @param {Node[]} items |
7 | 8 | */ |
8 | 9 | export function template_to_string(items) { |
9 | | - return items.map((el) => stringify(el)).join(''); |
| 10 | + return b.template([b.quasi(items.map(stringify).join(''), true)], []); |
10 | 11 | } |
11 | 12 |
|
12 | 13 | /** |
13 | | - * |
14 | | - * @param {Node} el |
15 | | - * @returns |
| 14 | + * @param {Node} node |
16 | 15 | */ |
17 | | -function stringify(el) { |
18 | | - let str = ``; |
19 | | - if (el.type === 'element') { |
20 | | - // we create the <tagname part |
21 | | - str += `<${el.name}`; |
22 | | - // we concatenate all the prop to it |
23 | | - for (let [prop, value] of Object.entries(el.attributes ?? {})) { |
24 | | - if (value == null) { |
25 | | - str += ` ${prop}`; |
26 | | - } else { |
27 | | - str += ` ${prop}="${escape_html(value, true)}"`; |
| 16 | +function stringify(node) { |
| 17 | + switch (node.type) { |
| 18 | + case 'element': { |
| 19 | + let str = `<${node.name}`; |
| 20 | + |
| 21 | + for (const key in node.attributes) { |
| 22 | + const value = node.attributes[key]; |
| 23 | + |
| 24 | + str += ` ${key}`; |
| 25 | + if (value !== undefined) str += `="${escape_html(value, true)}"`; |
28 | 26 | } |
| 27 | + |
| 28 | + str += `>`; |
| 29 | + str += node.children.map(stringify); |
| 30 | + |
| 31 | + if (!is_void(node.name)) { |
| 32 | + str += `</${node.name}>`; |
| 33 | + } |
| 34 | + |
| 35 | + return str; |
29 | 36 | } |
30 | | - // then we close the opening tag |
31 | | - str += `>`; |
32 | | - // we stringify all the children and concatenate them |
33 | | - for (let child of el.children ?? []) { |
34 | | - str += stringify(child); |
35 | | - } |
36 | | - // if it's not void we also add the closing tag |
37 | | - if (!is_void(el.name)) { |
38 | | - str += `</${el.name}>`; |
| 37 | + |
| 38 | + case 'text': { |
| 39 | + return node.nodes.map((node) => node.raw).join(''); |
39 | 40 | } |
40 | | - } else if (el.type === 'text') { |
41 | | - str += el.nodes.map((node) => node.raw).join(''); |
42 | | - } else if (el.type === 'anchor') { |
43 | | - if (el.data) { |
44 | | - str += `<!--${el.data}-->`; |
45 | | - } else { |
46 | | - str += `<!>`; |
| 41 | + |
| 42 | + case 'anchor': { |
| 43 | + return node.data ? `<!--${node.data}-->` : '<!>'; |
47 | 44 | } |
48 | 45 | } |
49 | | - |
50 | | - return str; |
51 | 46 | } |
0 commit comments