saner escaping/unescaping of `@` and `#` sigils

pull/750/head
Conduitry 7 years ago
parent ff814ecfa4
commit b869e48bff

@ -355,8 +355,8 @@ export default class Block {
${properties}
};
}
`.replace(/(\\\\)?#(\w*)/g, (match, escaped, name) => {
return escaped ? match.slice(2) : this.alias(name);
`.replace(/(#+)(\w*)/g, (match: string, sigil: string, name: string) => {
return sigil === '#' ? this.alias(name) : sigil.slice(1) + name;
});
}
}

@ -145,9 +145,12 @@ export default function dom(
if (generator.stylesheet.hasStyles && options.css !== false) {
const { css, cssMap } = generator.stylesheet.render(options.filename);
const textContent = stringify(options.dev ?
// special case: we only want to escape '@' and not '#', because at this point all we'll be unescaping is '@'
const textContent = JSON.stringify((options.dev ?
`${css}\n/*# sourceMappingURL=${cssMap.toUrl()} */` :
css);
css).replace(/(@+)/g, (match: string) => {
return match + match[0];
}));
builder.addBlock(deindent`
function @add_css () {
@ -281,9 +284,8 @@ export default function dom(
let result = builder
.toString()
.replace(/(\\\\)?([@#])(\w*)/g, (match: string, escaped: string, sigil: string, name: string) => {
if (escaped) return match.slice(2);
if (sigil !== '@') return match;
.replace(/(@+)(\w*)/g, (match: string, sigil: string, name: string) => {
if (sigil !== '@') return sigil.slice(1) + name;
if (name in shared) {
if (options.dev && `${name}Dev` in shared) name = `${name}Dev`;

@ -6,6 +6,7 @@ import preprocess from './preprocess';
import visit from './visit';
import { removeNode, removeObjectKey } from '../../utils/removeNode';
import { Parsed, Node, CompileOptions } from '../../interfaces';
import { stringify } from '../../utils/stringify';
export class SsrGenerator extends Generator {
bindings: string[];
@ -93,7 +94,7 @@ export default function ssr(
var ${name} = {};
${name}.filename = ${JSON.stringify(options.filename)};
${name}.filename = ${stringify(options.filename)};
${name}.data = function () {
return ${templateProperties.data ? `@template.data()` : `{}`};
@ -133,8 +134,8 @@ export default function ssr(
deindent`
components.push({
filename: ${name}.filename,
css: ${JSON.stringify(css)},
map: ${JSON.stringify(cssMap)}
css: ${stringify(css)},
map: ${stringify(cssMap.toString())}
});
`}
@ -169,7 +170,7 @@ export default function ssr(
var escaped = {
'"': '"',
"'": ''',
"'": '&##39;',
'&': '&',
'<': '&lt;',
'>': '&gt;'
@ -178,11 +179,8 @@ export default function ssr(
function __escape ( html ) {
return String( html ).replace( /["'&<>]/g, match => escaped[ match ] );
}
`.replace(/(\\)?([@#])(\w*)/g, (match: string, escaped: string, sigil: string, name: string) => {
if (escaped) return match.slice(1);
if (sigil !== '@') return match;
return generator.alias(name);
`.replace(/(@+|#+)(\w*)/g, (match: string, sigil: string, name: string) => {
return sigil === '@' ? generator.alias(name) : sigil.slice(1) + name;
});
return generator.generate(result, options, { name, format });

@ -5,6 +5,7 @@ import Block from '../Block';
import { Node } from '../../../interfaces';
import getObject from '../../../utils/getObject';
import getTailSnippet from '../../../utils/getTailSnippet';
import { stringify } from '../../../utils/stringify';
export default function visitComponent(
generator: SsrGenerator,
@ -41,7 +42,7 @@ export default function visitComponent(
} else if (attribute.value.length === 1) {
const chunk = attribute.value[0];
if (chunk.type === 'Text') {
value = isNaN(chunk.data) ? JSON.stringify(chunk.data) : chunk.data;
value = isNaN(chunk.data) ? stringify(chunk.data) : chunk.data;
} else {
const { snippet } = block.contextualise(chunk.expression);
value = snippet;

@ -3,5 +3,7 @@ export function stringify(data: string) {
}
export function escape(data: string) {
return data.replace(/([^\\@#])?([@#])/g, '$1\\$2');
return data.replace(/(@+|#+)/g, (match: string) => {
return match + match[0];
});
}

Loading…
Cancel
Save