diff --git a/src/compiler/compile/render_dom/wrappers/Fragment.js b/src/compiler/compile/render_dom/wrappers/Fragment.js
index fa8dadc788..d8bdd01a4b 100644
--- a/src/compiler/compile/render_dom/wrappers/Fragment.js
+++ b/src/compiler/compile/render_dom/wrappers/Fragment.js
@@ -20,25 +20,25 @@ import { trim_start, trim_end } from '../../../utils/trim.js';
import { link } from '../../../utils/link.js';
import { regex_starts_with_whitespace } from '../../../utils/patterns.js';
const wrappers = {
- AwaitBlock,
- Body,
- Comment,
- DebugTag,
- Document,
- EachBlock,
- Element,
- Head,
- IfBlock,
- InlineComponent,
- KeyBlock,
- MustacheTag,
- Options: null,
- RawMustacheTag,
- Slot,
- SlotTemplate,
- Text,
- Title,
- Window
+ AwaitBlock,
+ Body,
+ Comment,
+ DebugTag,
+ Document,
+ EachBlock,
+ Element,
+ Head,
+ IfBlock,
+ InlineComponent,
+ KeyBlock,
+ MustacheTag,
+ Options: null,
+ RawMustacheTag,
+ Slot,
+ SlotTemplate,
+ Text,
+ Title,
+ Window
};
/**
@@ -47,115 +47,116 @@ const wrappers = {
* @returns {boolean}
*/
function trimmable_at(child, next_sibling) {
- // Whitespace is trimmable if one of the following is true:
- // The child and its sibling share a common nearest each block (not at an each block boundary)
- // The next sibling's previous node is an each block
- return (next_sibling.node.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/) ||
- next_sibling.node.prev.type === 'EachBlock');
+ // Whitespace is trimmable if one of the following is true:
+ // The child and its sibling share a common nearest each block (not at an each block boundary)
+ // The next sibling's previous node is an each block
+ return (
+ next_sibling.node.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/) ||
+ next_sibling.node.prev.type === 'EachBlock'
+ );
}
export default class FragmentWrapper {
+ /** @type {import('./shared/Wrapper.js').default[]} */
+ nodes;
- /** @type {import('./shared/Wrapper.js').default[]} */
- nodes;
+ /**
+ * @param {import('../Renderer.js').default} renderer
+ * @param {import('../Block.js').default} block
+ * @param {import('../../nodes/interfaces.js').INode[]} nodes
+ * @param {import('./shared/Wrapper.js').default} parent
+ * @param {boolean} strip_whitespace
+ * @param {import('./shared/Wrapper.js').default} next_sibling
+ */
+ constructor(renderer, block, nodes, parent, strip_whitespace, next_sibling) {
+ this.nodes = [];
- /**
- * @param {import('../Renderer.js').default} renderer
- * @param {import('../Block.js').default} block
- * @param {import('../../nodes/interfaces.js').INode[]} nodes
- * @param {import('./shared/Wrapper.js').default} parent
- * @param {boolean} strip_whitespace
- * @param {import('./shared/Wrapper.js').default} next_sibling
- */
- constructor(renderer, block, nodes, parent, strip_whitespace, next_sibling) {
- this.nodes = [];
+ /** @type {import('./shared/Wrapper.js').default} */
+ let last_child;
- /** @type {import('./shared/Wrapper.js').default} */
- let last_child;
+ /** @type {import('./Window.js').default | undefined} */
+ let window_wrapper;
+ let i = nodes.length;
+ while (i--) {
+ const child = nodes[i];
+ if (!child.type) {
+ throw new Error('missing type');
+ }
+ if (!(child.type in wrappers)) {
+ throw new Error(`TODO implement ${child.type}`);
+ }
+ // special case — this is an easy way to remove whitespace surrounding
+ // . lil hacky but it works
+ if (child.type === 'Window') {
+ window_wrapper = new Window(renderer, block, parent, child);
+ continue;
+ }
+ if (child.type === 'Text') {
+ let { data } = child;
+ // We want to remove trailing whitespace inside an element/component/block,
+ // *unless* there is no whitespace between this node and its next sibling
+ if (this.nodes.length === 0) {
+ const should_trim = next_sibling
+ ? next_sibling.node.type === 'Text' &&
+ regex_starts_with_whitespace.test(next_sibling.node.data) &&
+ trimmable_at(child, next_sibling)
+ : !child.has_ancestor('EachBlock');
+ if (should_trim && !child.keep_space()) {
+ data = trim_end(data);
+ if (!data) continue;
+ }
+ }
+ // glue text nodes (which could e.g. be separated by comments) together
+ if (last_child && last_child.node.type === 'Text') {
+ /** @type {import('./Text.js').default} */ (last_child).data =
+ data + /** @type {import('./Text.js').default} */ (last_child).data;
+ continue;
+ }
+ const wrapper = new Text(renderer, block, parent, child, data);
+ if (wrapper.skip) continue;
+ this.nodes.unshift(wrapper);
+ link(last_child, (last_child = wrapper));
+ } else {
+ const Wrapper = wrappers[child.type];
+ if (!Wrapper || (child.type === 'Comment' && !renderer.options.preserveComments)) continue;
+ const wrapper = new Wrapper(
+ renderer,
+ block,
+ parent,
+ child,
+ strip_whitespace,
+ last_child || next_sibling
+ );
+ this.nodes.unshift(wrapper);
+ link(last_child, (last_child = wrapper));
+ }
+ }
+ if (strip_whitespace) {
+ const first = /** @type {import('./Text.js').default} */ (this.nodes[0]);
+ if (first && first.node.type === 'Text' && !first.node.keep_space()) {
+ first.data = trim_start(first.data);
+ if (!first.data) {
+ first.var = null;
+ this.nodes.shift();
+ if (this.nodes[0]) {
+ this.nodes[0].prev = null;
+ }
+ }
+ }
+ }
+ if (window_wrapper) {
+ this.nodes.unshift(window_wrapper);
+ link(last_child, window_wrapper);
+ }
+ }
- /** @type {import('./Window.js').default | undefined} */
- let window_wrapper;
- let i = nodes.length;
- while (i--) {
- const child = nodes[i];
- if (!child.type) {
- throw new Error('missing type');
- }
- if (!(child.type in wrappers)) {
- throw new Error(`TODO implement ${child.type}`);
- }
- // special case — this is an easy way to remove whitespace surrounding
- // . lil hacky but it works
- if (child.type === 'Window') {
- window_wrapper = new Window(renderer, block, parent, child);
- continue;
- }
- if (child.type === 'Text') {
- let { data } = child;
- // We want to remove trailing whitespace inside an element/component/block,
- // *unless* there is no whitespace between this node and its next sibling
- if (this.nodes.length === 0) {
- const should_trim = next_sibling
- ? next_sibling.node.type === 'Text' &&
- regex_starts_with_whitespace.test(next_sibling.node.data) &&
- trimmable_at(child, next_sibling)
- : !child.has_ancestor('EachBlock');
- if (should_trim && !child.keep_space()) {
- data = trim_end(data);
- if (!data)
- continue;
- }
- }
- // glue text nodes (which could e.g. be separated by comments) together
- if (last_child && last_child.node.type === 'Text') {
- ( /** @type {import('./Text.js').default} */(last_child)).data = data + ( /** @type {import('./Text.js').default} */(last_child)).data;
- continue;
- }
- const wrapper = new Text(renderer, block, parent, child, data);
- if (wrapper.skip)
- continue;
- this.nodes.unshift(wrapper);
- link(last_child, (last_child = wrapper));
- }
- else {
- const Wrapper = wrappers[child.type];
- if (!Wrapper || (child.type === 'Comment' && !renderer.options.preserveComments))
- continue;
- const wrapper = new Wrapper(renderer, block, parent, child, strip_whitespace, last_child || next_sibling);
- this.nodes.unshift(wrapper);
- link(last_child, (last_child = wrapper));
- }
- }
- if (strip_whitespace) {
- const first = /** @type {import('./Text.js').default} */ (this.nodes[0]);
- if (first && first.node.type === 'Text' && !first.node.keep_space()) {
- first.data = trim_start(first.data);
- if (!first.data) {
- first.var = null;
- this.nodes.shift();
- if (this.nodes[0]) {
- this.nodes[0].prev = null;
- }
- }
- }
- }
- if (window_wrapper) {
- this.nodes.unshift(window_wrapper);
- link(last_child, window_wrapper);
- }
- }
-
- /**
- * @param {import('../Block.js').default} block
- * @param {import('estree').Identifier} parent_node
- * @param {import('estree').Identifier} parent_nodes
- */
- render(block, parent_node, parent_nodes) {
- for (let i = 0; i < this.nodes.length; i += 1) {
- this.nodes[i].render(block, parent_node, parent_nodes);
- }
- }
+ /**
+ * @param {import('../Block.js').default} block
+ * @param {import('estree').Identifier} parent_node
+ * @param {import('estree').Identifier} parent_nodes
+ */
+ render(block, parent_node, parent_nodes) {
+ for (let i = 0; i < this.nodes.length; i += 1) {
+ this.nodes[i].render(block, parent_node, parent_nodes);
+ }
+ }
}
-
-
-
-