prevent top-level text being discarded - fixes #3027

pull/3102/head
Richard Harris 6 years ago
parent fc32147ea5
commit 960b548d14

@ -6,7 +6,6 @@ import { INode } from './interfaces';
export default class Text extends Node {
type: 'Text';
data: string;
use_space = false;
constructor(component: Component, parent: INode, scope: TemplateScope, info: any) {
super(component, parent, scope, info);
@ -20,8 +19,6 @@ export default class Text extends Node {
}
node = node.parent;
}
this.use_space = true;
}
}
}

@ -335,7 +335,7 @@ export default class ElementWrapper extends Wrapper {
function to_html(wrapper: ElementWrapper | TextWrapper) {
if (wrapper.node.type === 'Text') {
if (wrapper.node.use_space) return ' ';
if ((wrapper as TextWrapper).use_space()) return ' ';
const parent = wrapper.node.parent as Element;

@ -17,6 +17,7 @@ import { INode } from '../../nodes/interfaces';
import Renderer from '../Renderer';
import Block from '../Block';
import { trim_start, trim_end } from '../../../utils/trim';
import TextWrapper from './Text';
const wrappers = {
AwaitBlock,
@ -47,7 +48,7 @@ function trimmable_at(child: INode, next_sibling: Wrapper): boolean {
// 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 {
nodes: Wrapper[];
@ -91,8 +92,7 @@ export default class FragmentWrapper {
// *unless* there is no whitespace between this node and its next sibling
if (this.nodes.length === 0) {
const should_trim = (
// @ts-ignore todo: probably error, should it be next_sibling.node.data?
next_sibling ? (next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.data) && trimmable_at(child, next_sibling)) : !child.has_ancestor('EachBlock')
next_sibling ? (next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.node.data) && trimmable_at(child, next_sibling)) : !child.has_ancestor('EachBlock')
);
if (should_trim) {
@ -103,8 +103,7 @@ export default class FragmentWrapper {
// glue text nodes (which could e.g. be separated by comments) together
if (last_child && last_child.node.type === 'Text') {
// @ts-ignore todo: probably error, should it be last_child.node.data?
last_child.data = data + last_child.data;
(last_child as TextWrapper).data = data + (last_child as TextWrapper).data;
continue;
}

@ -49,12 +49,27 @@ export default class TextWrapper extends Wrapper {
this.var = this.skip ? null : 't';
}
use_space() {
if (this.renderer.component.component_options.preserveWhitespace) return false;
if (/[\S\u00A0]/.test(this.data)) return false;
let node = this.parent && this.parent.node;
while (node) {
if (node.type === 'Element' && node.name === 'pre') {
return false;
}
node = node.parent;
}
return true;
}
render(block: Block, parent_node: string, parent_nodes: string) {
if (this.skip) return;
block.add_element(
this.var,
this.node.use_space ? `@space()` : `@text(${stringify(this.data)})`,
this.use_space() ? `@space()` : `@text(${stringify(this.data)})`,
parent_nodes && `@claim_text(${parent_nodes}, ${stringify(this.data)})`,
parent_node
);

@ -0,0 +1,6 @@
export default {
html: `
before
<h1>after</h1>
`
};

@ -0,0 +1,5 @@
before
<!---->
<h1>after</h1>
Loading…
Cancel
Save