diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts index 48852c27ea..a512b21d94 100644 --- a/src/generators/nodes/Element.ts +++ b/src/generators/nodes/Element.ts @@ -162,6 +162,8 @@ export default class Element extends Node { this.generator.slots.add(slotName); } + if (this.name === 'noscript') return; + const childState = { parentNode: this.var, parentNodes: parentNodes && block.getUniqueName(`${this.var}_nodes`) // if we're in unclaimable territory, i.e.
, parentNodes is null @@ -415,7 +417,15 @@ export default class Element extends Node { } function toHTML(node: Element | Text) { - if (node.type === 'Text') return escapeHTML(node.data); + if (node.type === 'Text') { + return node.parent && + node.parent.type === 'Element' && + (node.parent.name === 'script' || node.parent.name === 'style') + ? node.data + : escapeHTML(node.data); + } + + if (node.name === 'noscript') return ''; let open = `<${node.name}`; @@ -433,10 +443,6 @@ 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}>`; - } - return `${open}>${node.children.map(toHTML).join('')}${node.name}>`; } } diff --git a/src/generators/server-side-rendering/visitors/Element.ts b/src/generators/server-side-rendering/visitors/Element.ts index 486f0f01a3..21ec923e3d 100644 --- a/src/generators/server-side-rendering/visitors/Element.ts +++ b/src/generators/server-side-rendering/visitors/Element.ts @@ -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); diff --git a/src/generators/server-side-rendering/visitors/MustacheTag.ts b/src/generators/server-side-rendering/visitors/MustacheTag.ts index 29fa7aa083..795e78dd33 100644 --- a/src/generators/server-side-rendering/visitors/MustacheTag.ts +++ b/src/generators/server-side-rendering/visitors/MustacheTag.ts @@ -10,5 +10,11 @@ export default function visitMustacheTag( block.contextualise(node.expression); const { snippet } = node.metadata; - generator.append('${__escape(' + snippet + ')}'); + generator.append( + node.parent && + node.parent.type === 'Element' && + node.parent.name === 'style' + ? '${' + snippet + '}' + : '${__escape(' + snippet + ')}' + ); } diff --git a/src/generators/server-side-rendering/visitors/Text.ts b/src/generators/server-side-rendering/visitors/Text.ts index 092aa535c0..ecb37e433c 100644 --- a/src/generators/server-side-rendering/visitors/Text.ts +++ b/src/generators/server-side-rendering/visitors/Text.ts @@ -8,5 +8,14 @@ export default function visitText( block: Block, node: Node ) { - generator.append(escapeTemplate(escapeHTML(escape(node.data)))); + let text = node.data; + if ( + !node.parent || + node.parent.type !== 'Element' || + (node.parent.name !== 'script' && node.parent.name !== 'style') + ) { + // unless this Text node is inside a ', true); + element.end = parser.index; + } else if (name === 'style') { + // special case + element.children = readSequence( + parser, + () => + parser.template.slice(parser.index, parser.index + 8) === '' + ); + parser.read(/<\/style>/); element.end = parser.index; } else { parser.stack.push(element); diff --git a/test/runtime/samples/non-root-style-interpolation/_config.js b/test/runtime/samples/non-root-style-interpolation/_config.js new file mode 100644 index 0000000000..01cefdd67e --- /dev/null +++ b/test/runtime/samples/non-root-style-interpolation/_config.js @@ -0,0 +1,52 @@ +export default { + data: { + color: 'red', + foo: '/* < & > */', + }, + + html: ` +