rework handling of non-root <script> and <style>

pull/1163/head
Conduitry 7 years ago
parent 1719a318ad
commit 5d0f44ef41

@ -232,7 +232,7 @@ export default class Element extends Node {
);
} else {
block.builders.create.addLine(
`${name}.innerHTML = ${stringify(this.children.map(toHTML).join(''))};`
`${name}.innerHTML = ${stringify(this.children.map(node => toHTML(node, false)).join(''))};`
);
}
} else {
@ -414,8 +414,10 @@ export default class Element extends Node {
);
}
function toHTML(node: Element | Text) {
if (node.type === 'Text') return escapeHTML(node.data);
function toHTML(node: Element | Text, dontEscapeText: Boolean) {
if (node.type === 'Text') {
return dontEscapeText ? node.data : escapeHTML(node.data);
}
let open = `<${node.name}`;
@ -433,11 +435,9 @@ export default class Element extends Node {
if (isVoidElementName(node.name)) return open + '>';
if (node.name === 'script' || node.name === 'style') {
return `${open}>${node.data}</${node.name}>`;
}
const shouldNotEscapeText = node.name === 'script' || node.name === 'style';
return `${open}>${node.children.map(toHTML).join('')}</${node.name}>`;
return `${open}>${node.children.map(node => toHTML(node, shouldNotEscapeText)).join('')}</${node.name}>`;
}
}

@ -68,8 +68,6 @@ export default function visitElement(
if (node.name === 'textarea' && textareaContents !== undefined) {
generator.append(textareaContents);
} else if (node.name === 'script' || node.name === 'style') {
generator.append(escape(node.data));
} else {
node.children.forEach((child: Node) => {
visit(generator, block, child);

@ -8,5 +8,14 @@ export default function visitText(
block: Block,
node: Node
) {
generator.append(escapeHTML(escape(node.data).replace(/(\${|`|\\)/g, '\\$1')));
let text = escape(node.data).replace(/(\${|`|\\)/g, '\\$1');
if (
!node.parent ||
node.parent.type !== 'Element' ||
(node.parent.name !== 'script' && node.parent.name !== 'style')
) {
// unless this Text node is inside a <script> or <style> element, escape &,<,>
text = escapeHTML(text);
}
generator.append(text);
}

@ -224,10 +224,22 @@ export default function tag(parser: Parser) {
);
parser.read(/<\/textarea>/);
element.end = parser.index;
} else if (name === 'script' || name === 'style') {
} else if (name === 'script') {
// special case
element.data = parser.readUntil(new RegExp(`</${name}>`));
parser.eat(`</${name}>`, true);
const start = parser.index;
const data = parser.readUntil(/<\/script>/);
const end = parser.index;
element.children.push({ start, end, type: 'Text', data });
parser.eat('</script>', true);
element.end = parser.index;
} else if (name === 'style') {
// special case
element.children = readSequence(
parser,
() =>
parser.template.slice(parser.index, parser.index + 8) === '</style>'
);
parser.read(/<\/style>/);
element.end = parser.index;
} else {
parser.stack.push(element);

Loading…
Cancel
Save