diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts index 5c0ffabf1466..ab9c5b8dc4d9 100644 --- a/src/generators/nodes/Element.ts +++ b/src/generators/nodes/Element.ts @@ -432,6 +432,10 @@ 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}>`; } } @@ -756,4 +760,4 @@ const events = [ node.isMediaNode() && (name === 'buffered' || name === 'seekable') } -]; \ No newline at end of file +]; diff --git a/src/generators/server-side-rendering/visitors/Element.ts b/src/generators/server-side-rendering/visitors/Element.ts index a1645d0860e2..db728d6e8da3 100644 --- a/src/generators/server-side-rendering/visitors/Element.ts +++ b/src/generators/server-side-rendering/visitors/Element.ts @@ -60,6 +60,8 @@ export default function visitElement( if (node.name === 'textarea' && textareaContents !== undefined) { generator.append(textareaContents); + } else if (node.name === 'script' || node.name === 'style') { + generator.append(node.data); } else { node.children.forEach((child: Node) => { visit(generator, block, child); diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index dae32bc3df93..a659dc6d3d76 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -213,6 +213,7 @@ export default function tag(parser: Parser) { parser.eat('>', true); if (selfClosing) { + // don't push self-closing elements onto the stack element.end = parser.index; } else if (name === 'textarea') { // special case @@ -223,8 +224,12 @@ export default function tag(parser: Parser) { ); parser.read(/<\/textarea>/); element.end = parser.index; + } else if (name === 'script' || name === 'style') { + // special case + element.data = parser.readUntil(new RegExp(`${name}>`)); + parser.eat(`${name}>`, true); + element.end = parser.index; } else { - // don't push self-closing elements onto the stack parser.stack.push(element); } } diff --git a/src/utils/stringify.ts b/src/utils/stringify.ts index b5f982eb1d81..0fb151c16239 100644 --- a/src/utils/stringify.ts +++ b/src/utils/stringify.ts @@ -9,13 +9,11 @@ export function escape(data: string, { onlyEscapeAtSymbol = false } = {}) { } const escaped = { - '"': '"', - "'": '#39;', '&': '&', '<': '<', - '>': '>' + '>': '>', }; export function escapeHTML(html) { - return String(html).replace(/["'&<>]/g, match => escaped[match]); -} \ No newline at end of file + return String(html).replace(/[&<>]/g, match => escaped[match]); +} diff --git a/test/runtime/samples/html-non-entities-inside-elements/_config.js b/test/runtime/samples/html-non-entities-inside-elements/_config.js new file mode 100644 index 000000000000..bc217d6d020c --- /dev/null +++ b/test/runtime/samples/html-non-entities-inside-elements/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` +
foo: ''
+foo: ''