Strip newline logic to src/compiler/compile/nodes/Eleement.ts

pull/7280/head
yosuke ota 4 years ago
parent 1464caf170
commit 7d4990c5d4

@ -198,6 +198,16 @@ export default class Element extends Node {
this.namespace = get_namespace(parent as Element, this, component.namespace); this.namespace = get_namespace(parent as Element, this, component.namespace);
if (this.namespace !== namespaces.foreign) { if (this.namespace !== namespaces.foreign) {
if (this.name === 'pre' || this.name === 'textarea') {
const first = info.children[0];
if (first && first.type === 'Text') {
// The leading newline character should be stripped.
// see https://html.spec.whatwg.org/multipage/syntax.html#element-restrictions
// see https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
first.data = first.data.replace(start_newline, '');
}
}
if (this.name === 'textarea') { if (this.name === 'textarea') {
if (info.children.length > 0) { if (info.children.length > 0) {
const value_attribute = info.attributes.find(node => node.name === 'value'); const value_attribute = info.attributes.find(node => node.name === 'value');
@ -208,12 +218,6 @@ export default class Element extends Node {
// this is an egregious hack, but it's the easiest way to get <textarea> // this is an egregious hack, but it's the easiest way to get <textarea>
// children treated the same way as a value attribute // children treated the same way as a value attribute
const first = info.children[0];
if (first && first.type === 'Text') {
// The leading newline character should be stripped.
// see https://html.spec.whatwg.org/multipage/syntax.html#element-restrictions
first.data = first.data.replace(start_newline, '');
}
info.attributes.push({ info.attributes.push({
type: 'Attribute', type: 'Attribute',
name: 'value', name: 'value',

@ -49,15 +49,6 @@ export default class Text extends Node {
return this.within_pre(); return this.within_pre();
} }
/**
* @returns If true, the leading newline character should be stripped.
* @see https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
*/
should_strip_leading_newline(): boolean {
const parent = this.parent;
return parent.type === 'Element' && parent.name === 'pre' && parent.children[0] === this;
}
within_pre(): boolean { within_pre(): boolean {
let node = this.parent; let node = this.parent;
while (node) { while (node) {

@ -21,7 +21,6 @@ import Block from '../Block';
import { trim_start, trim_end } from '../../../utils/trim'; import { trim_start, trim_end } from '../../../utils/trim';
import { link } from '../../../utils/link'; import { link } from '../../../utils/link';
import { Identifier } from 'estree'; import { Identifier } from 'estree';
import { start_newline } from '../../../utils/patterns';
const wrappers = { const wrappers = {
AwaitBlock, AwaitBlock,
@ -131,8 +130,6 @@ export default class FragmentWrapper {
if (first && first.node.type === 'Text') { if (first && first.node.type === 'Text') {
if (!first.node.keep_space()) { if (!first.node.keep_space()) {
first.data = trim_start(first.data); first.data = trim_start(first.data);
} else if (first.node.should_strip_leading_newline()) {
first.data = first.data.replace(start_newline, '');
} }
if (!first.data) { if (!first.data) {
first.var = null; first.var = null;

@ -8,6 +8,7 @@ import Expression from '../../nodes/shared/Expression';
import remove_whitespace_children from './utils/remove_whitespace_children'; import remove_whitespace_children from './utils/remove_whitespace_children';
import fix_attribute_casing from '../../render_dom/wrappers/Element/fix_attribute_casing'; import fix_attribute_casing from '../../render_dom/wrappers/Element/fix_attribute_casing';
import { namespaces } from '../../../utils/namespaces'; import { namespaces } from '../../../utils/namespaces';
import { start_newline } from '../../../utils/patterns';
export default function(node: Element, renderer: Renderer, options: RenderOptions) { export default function(node: Element, renderer: Renderer, options: RenderOptions) {
@ -176,6 +177,15 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
renderer.add_string(`</${node.name}>`); renderer.add_string(`</${node.name}>`);
} }
} else { } else {
if (node.name === 'pre') {
// Two or more leading newlines are required to restore the leading newline immediately after `<pre>`.
// see https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
// see https://html.spec.whatwg.org/multipage/syntax.html#element-restrictions
const first = children[0];
if (first && first.type === 'Text' && start_newline.test(first.data)) {
renderer.add_string('\n');
}
}
renderer.render(children, options); renderer.render(children, options);
if (!is_void(node.name)) { if (!is_void(node.name)) {

@ -1,5 +1,4 @@
<pre> <pre> A
A
B B
<span> <span>
C C
@ -18,8 +17,7 @@
F F
</div> </div>
<div><pre> <div><pre> A
A
B B
<span> <span>
C C
@ -29,10 +27,8 @@
F F
</pre></div> </pre></div>
<div id="pre-with-leading-newline"><pre> <div id="pre-with-leading-newline"><pre>leading newline</pre>
leading newline</pre> <pre> leading newline and spaces</pre>
<pre>
leading newline and spaces</pre>
<pre> <pre>
leading newlines</pre></div> leading newlines</pre></div>

Loading…
Cancel
Save