only escape attribute values when rendering HTML

pull/2065/head
Rich Harris 6 years ago
parent e9b714110c
commit cb2799d1ef

@ -63,7 +63,7 @@ export default class SlotWrapper extends Wrapper {
get_slot_changes = renderer.component.getUniqueName(`get_${slot_name}_slot_changes`); get_slot_changes = renderer.component.getUniqueName(`get_${slot_name}_slot_changes`);
get_slot_context = renderer.component.getUniqueName(`get_${slot_name}_slot_context`); get_slot_context = renderer.component.getUniqueName(`get_${slot_name}_slot_context`);
const context_props = get_slot_data(attributes); const context_props = get_slot_data(attributes, false);
const changes_props = []; const changes_props = [];
const dependencies = new Set(); const dependencies = new Set();

@ -78,7 +78,7 @@ export default function(node, renderer, options) {
args.push(snip(attribute.expression)); args.push(snip(attribute.expression));
} else { } else {
if (attribute.name === 'value' && node.name === 'textarea') { if (attribute.name === 'value' && node.name === 'textarea') {
textareaContents = stringify_attribute(attribute); textareaContents = stringify_attribute(attribute, true);
} else if (attribute.isTrue) { } else if (attribute.isTrue) {
args.push(`{ ${quoteNameIfNecessary(attribute.name)}: true }`); args.push(`{ ${quoteNameIfNecessary(attribute.name)}: true }`);
} else if ( } else if (
@ -89,7 +89,7 @@ export default function(node, renderer, options) {
// a boolean attribute with one non-Text chunk // a boolean attribute with one non-Text chunk
args.push(`{ ${quoteNameIfNecessary(attribute.name)}: ${snip(attribute.chunks[0])} }`); args.push(`{ ${quoteNameIfNecessary(attribute.name)}: ${snip(attribute.chunks[0])} }`);
} else { } else {
args.push(`{ ${quoteNameIfNecessary(attribute.name)}: \`${stringify_attribute(attribute)}\` }`); args.push(`{ ${quoteNameIfNecessary(attribute.name)}: \`${stringify_attribute(attribute, true)}\` }`);
} }
} }
}); });
@ -100,7 +100,7 @@ export default function(node, renderer, options) {
if (attribute.type !== 'Attribute') return; if (attribute.type !== 'Attribute') return;
if (attribute.name === 'value' && node.name === 'textarea') { if (attribute.name === 'value' && node.name === 'textarea') {
textareaContents = stringify_attribute(attribute); textareaContents = stringify_attribute(attribute, true);
} else if (attribute.isTrue) { } else if (attribute.isTrue) {
openingTag += ` ${attribute.name}`; openingTag += ` ${attribute.name}`;
} else if ( } else if (
@ -112,14 +112,14 @@ export default function(node, renderer, options) {
openingTag += '${' + snip(attribute.chunks[0]) + ' ? " ' + attribute.name + '" : "" }'; openingTag += '${' + snip(attribute.chunks[0]) + ' ? " ' + attribute.name + '" : "" }';
} else if (attribute.name === 'class' && classExpr) { } else if (attribute.name === 'class' && classExpr) {
addClassAttribute = false; addClassAttribute = false;
openingTag += ` class="\${[\`${stringify_attribute(attribute)}\`, ${classExpr}].join(' ').trim() }"`; openingTag += ` class="\${[\`${stringify_attribute(attribute, true)}\`, ${classExpr}].join(' ').trim() }"`;
} else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') { } else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') {
const { name } = attribute; const { name } = attribute;
const snippet = snip(attribute.chunks[0]); const snippet = snip(attribute.chunks[0]);
openingTag += '${(v => v == null ? "" : ` ' + name + '="${@escape(' + snippet + ')}"`)(' + snippet + ')}'; openingTag += '${(v => v == null ? "" : ` ' + name + '="${@escape(' + snippet + ')}"`)(' + snippet + ')}';
} else { } else {
openingTag += ` ${attribute.name}="${stringify_attribute(attribute)}"`; openingTag += ` ${attribute.name}="${stringify_attribute(attribute, true)}"`;
} }
}); });
} }

@ -7,7 +7,7 @@ export default function(node, renderer, options) {
const slot_name = name && name.chunks[0].data || 'default'; const slot_name = name && name.chunks[0].data || 'default';
const prop = quotePropIfNecessary(slot_name); const prop = quotePropIfNecessary(slot_name);
const slot_data = get_slot_data(node.attributes); const slot_data = get_slot_data(node.attributes, true);
const arg = slot_data.length > 0 ? `{ ${slot_data.join(', ')} }` : ''; const arg = slot_data.length > 0 ? `{ ${slot_data.join(', ')} }` : '';

@ -1,7 +1,7 @@
import { snip } from './snip'; import { snip } from './snip';
import { stringify_attribute } from './stringify_attribute'; import { stringify_attribute } from './stringify_attribute';
export default function(attributes) { export default function get_slot_data(attributes, is_ssr: boolean) {
return attributes return attributes
.filter(attribute => attribute.name !== 'name') .filter(attribute => attribute.name !== 'name')
.map(attribute => { .map(attribute => {
@ -11,7 +11,7 @@ export default function(attributes) {
? '""' ? '""'
: attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text' : attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text'
? snip(attribute.chunks[0]) ? snip(attribute.chunks[0])
: '`' + stringify_attribute(attribute) + '`'; : '`' + stringify_attribute(attribute, is_ssr) + '`';
return `${attribute.name}: ${value}`; return `${attribute.name}: ${value}`;
}); });

@ -3,14 +3,16 @@ import Node from '../compile/nodes/shared/Node';
import { escapeTemplate, escape } from './stringify'; import { escapeTemplate, escape } from './stringify';
import { snip } from './snip'; import { snip } from './snip';
export function stringify_attribute(attribute: Attribute) { export function stringify_attribute(attribute: Attribute, is_ssr: boolean) {
return attribute.chunks return attribute.chunks
.map((chunk: Node) => { .map((chunk: Node) => {
if (chunk.type === 'Text') { if (chunk.type === 'Text') {
return escapeTemplate(escape(chunk.data).replace(/"/g, '"')); return escapeTemplate(escape(chunk.data).replace(/"/g, '"'));
} }
return '${@escape(' + snip(chunk) + ')}'; return is_ssr
? '${@escape(' + snip(chunk) + ')}'
: '${' + snip(chunk) + '}';
}) })
.join(''); .join('');
} }
Loading…
Cancel
Save