diff --git a/src/generators/dom/Block.ts b/src/generators/dom/Block.ts index c0c32a45aa..f851727276 100644 --- a/src/generators/dom/Block.ts +++ b/src/generators/dom/Block.ts @@ -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; }); } } diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index de7ff1fc96..c30e6801f9 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -147,7 +147,7 @@ export default function dom( const textContent = stringify(options.dev ? `${css}\n/*# sourceMappingURL=${cssMap.toUrl()} */` : - css); + css, { onlyEscapeAtSymbol: true }); builder.addBlock(deindent` function @add_css () { @@ -281,9 +281,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`; @@ -302,13 +301,13 @@ export default function dom( }); result = - `import { ${names.join(', ')} } from ${stringify(sharedPath)};\n\n` + + `import { ${names.join(', ')} } from ${JSON.stringify(sharedPath)};\n\n` + result; } else if (format === 'cjs') { const SHARED = '__shared'; - let requires = `var ${SHARED} = require( ${stringify(sharedPath)} );`; + let requires = `var ${SHARED} = require( ${JSON.stringify(sharedPath)} );`; used.forEach(name => { const alias = generator.alias(name); requires += `\nvar ${alias} = ${SHARED}.${name};`; diff --git a/src/generators/server-side-rendering/index.ts b/src/generators/server-side-rendering/index.ts index 59f9701e7a..0f1771da7a 100644 --- a/src/generators/server-side-rendering/index.ts +++ b/src/generators/server-side-rendering/index.ts @@ -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;', '&': '&', '<': '<', '>': '>' @@ -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 }); diff --git a/src/generators/server-side-rendering/visitors/Component.ts b/src/generators/server-side-rendering/visitors/Component.ts index 75785d6ffd..0b04a13b11 100644 --- a/src/generators/server-side-rendering/visitors/Component.ts +++ b/src/generators/server-side-rendering/visitors/Component.ts @@ -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; diff --git a/src/utils/stringify.ts b/src/utils/stringify.ts index c16ac7a937..ab83bec5b4 100644 --- a/src/utils/stringify.ts +++ b/src/utils/stringify.ts @@ -1,7 +1,9 @@ -export function stringify(data: string) { - return JSON.stringify(escape(data)); +export function stringify(data: string, options = {}) { + return JSON.stringify(escape(data, options)); } -export function escape(data: string) { - return data.replace(/([^\\@#])?([@#])/g, '$1\\$2'); +export function escape(data: string, { onlyEscapeAtSymbol = false } = {}) { + return data.replace(onlyEscapeAtSymbol ? /(@+)/g : /(@+|#+)/g, (match: string) => { + return match + match[0]; + }); } diff --git a/test/runtime/samples/component-static-at-symbol/Email.html b/test/runtime/samples/component-static-at-symbol/Email.html new file mode 100644 index 0000000000..629ae71a04 --- /dev/null +++ b/test/runtime/samples/component-static-at-symbol/Email.html @@ -0,0 +1 @@ +email diff --git a/test/runtime/samples/component-static-at-symbol/_config.js b/test/runtime/samples/component-static-at-symbol/_config.js new file mode 100644 index 0000000000..a2f60e3de7 --- /dev/null +++ b/test/runtime/samples/component-static-at-symbol/_config.js @@ -0,0 +1,3 @@ +export default { + html: `email` +}; diff --git a/test/runtime/samples/component-static-at-symbol/main.html b/test/runtime/samples/component-static-at-symbol/main.html new file mode 100644 index 0000000000..f8a0e1c6cd --- /dev/null +++ b/test/runtime/samples/component-static-at-symbol/main.html @@ -0,0 +1,9 @@ + + +