0
0
mirror of https://github.com/sveltejs/svelte.git synced 2024-12-01 17:30:59 +01:00

Merge branch 'master' into sigil-component-attribute-ssr

This commit is contained in:
Conduitry 2018-02-09 08:32:35 -05:00 committed by GitHub
commit 7b282e58a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 164 additions and 12 deletions

View File

@ -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. <head>, 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}>`;
}
}

View File

@ -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);

View File

@ -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 + ')}'
);
}

View File

@ -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 <script> or <style> element, escape &,<,>
text = escapeHTML(text);
}
generator.append(escape(escapeTemplate(text)));
}

View File

@ -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);

View File

@ -0,0 +1,52 @@
export default {
data: {
color: 'red',
foo: '/* < & > */',
},
html: `
<div>
<style>
/* something with < and > */
div {
color: blue;
}
</style>
foo
</div>
<div>
<div>
<style>
div > div {
color: blue;
}
</style>
foo
</div>
</div>
<div>
<style>
/* something with < and > */
/* < & > */
div {
color: red;
}
</style>
foo
</div>
<div>
<div>
<style>
/* < & > */
div > div {
color: red;
}
</style>
foo
</div>
</div>
`,
};

View File

@ -0,0 +1,43 @@
<div>
<style>
/* something with < and > */
div {
color: blue;
}
</style>
foo
</div>
<div>
<div>
<style>
div > div {
color: blue;
}
</style>
foo
</div>
</div>
<div>
<style>
/* something with < and > */
{{foo}}
div {
color: {{color}};
}
</style>
foo
</div>
<div>
<div>
<style>
{{foo}}
div > div {
color: {{color}};
}
</style>
foo
</div>
</div>

View File

@ -0,0 +1,9 @@
export default {
'skip-ssr': true,
html: `
<div>foo</div>
<div>foo<div>foo</div></div>
`,
};

View File

@ -0,0 +1,5 @@
<noscript>foo</noscript>
<div>foo<noscript>foo</noscript></div>
<div>foo<div>foo<noscript>foo</noscript></div></div>

View File

@ -0,0 +1,8 @@
export default {
html: `
<div>
<style>div { color: red; }</style>
<script>alert('<>');</script>
</div>
`
};

View File

@ -0,0 +1,4 @@
<div>
<style>div { color: red; }</style>
<script>alert('<>');</script>
</div>