From aed1706696fe6396582126de729c8ebfc7f9d7fa Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 3 Aug 2017 22:37:47 -0400 Subject: [PATCH 1/4] failing tests for #741 --- test/runtime/samples/at-symbol-in-attribute/_config.js | 3 +++ test/runtime/samples/at-symbol-in-attribute/main.html | 1 + test/runtime/samples/attribute-static-quotemarks/_config.js | 3 +++ test/runtime/samples/attribute-static-quotemarks/main.html | 1 + 4 files changed, 8 insertions(+) create mode 100644 test/runtime/samples/at-symbol-in-attribute/_config.js create mode 100644 test/runtime/samples/at-symbol-in-attribute/main.html create mode 100644 test/runtime/samples/attribute-static-quotemarks/_config.js create mode 100644 test/runtime/samples/attribute-static-quotemarks/main.html diff --git a/test/runtime/samples/at-symbol-in-attribute/_config.js b/test/runtime/samples/at-symbol-in-attribute/_config.js new file mode 100644 index 0000000000..40a45579a3 --- /dev/null +++ b/test/runtime/samples/at-symbol-in-attribute/_config.js @@ -0,0 +1,3 @@ +export default { + html: `email` +}; \ No newline at end of file diff --git a/test/runtime/samples/at-symbol-in-attribute/main.html b/test/runtime/samples/at-symbol-in-attribute/main.html new file mode 100644 index 0000000000..2b5e73ebcf --- /dev/null +++ b/test/runtime/samples/at-symbol-in-attribute/main.html @@ -0,0 +1 @@ +email \ No newline at end of file diff --git a/test/runtime/samples/attribute-static-quotemarks/_config.js b/test/runtime/samples/attribute-static-quotemarks/_config.js new file mode 100644 index 0000000000..794d01c29f --- /dev/null +++ b/test/runtime/samples/attribute-static-quotemarks/_config.js @@ -0,0 +1,3 @@ +export default { + html: `foo` +}; \ No newline at end of file diff --git a/test/runtime/samples/attribute-static-quotemarks/main.html b/test/runtime/samples/attribute-static-quotemarks/main.html new file mode 100644 index 0000000000..5f9c68c53c --- /dev/null +++ b/test/runtime/samples/attribute-static-quotemarks/main.html @@ -0,0 +1 @@ +foo \ No newline at end of file From 5dc048282907a1a3aaec9b6cbd2c061193bdacb9 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 4 Aug 2017 11:00:36 -0400 Subject: [PATCH 2/4] rename test --- .../_config.js | 0 .../main.html | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/runtime/samples/{at-symbol-in-attribute => attribute-static-at-symbol}/_config.js (100%) rename test/runtime/samples/{at-symbol-in-attribute => attribute-static-at-symbol}/main.html (100%) diff --git a/test/runtime/samples/at-symbol-in-attribute/_config.js b/test/runtime/samples/attribute-static-at-symbol/_config.js similarity index 100% rename from test/runtime/samples/at-symbol-in-attribute/_config.js rename to test/runtime/samples/attribute-static-at-symbol/_config.js diff --git a/test/runtime/samples/at-symbol-in-attribute/main.html b/test/runtime/samples/attribute-static-at-symbol/main.html similarity index 100% rename from test/runtime/samples/at-symbol-in-attribute/main.html rename to test/runtime/samples/attribute-static-at-symbol/main.html From fb0b4156efd62edd2c93458d35059885512b5005 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 4 Aug 2017 11:24:12 -0400 Subject: [PATCH 3/4] =?UTF-8?q?fix=20escaping/unescaping=20=E2=80=94=20clo?= =?UTF-8?q?ses=20#741?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/generators/dom/index.ts | 2 +- src/generators/dom/visitors/Component/Attribute.ts | 2 +- src/generators/dom/visitors/Element/Attribute.ts | 2 +- src/generators/dom/visitors/Text.ts | 2 +- src/generators/server-side-rendering/index.ts | 7 ++++++- src/generators/server-side-rendering/visitors/Element.ts | 3 ++- src/generators/server-side-rendering/visitors/Text.ts | 3 ++- src/utils/stringify.ts | 6 +++++- 8 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index 950b9a3712..e2cbc4751c 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -4,7 +4,7 @@ import annotateWithScopes from '../../utils/annotateWithScopes'; import isReference from '../../utils/isReference'; import { walk } from 'estree-walker'; import deindent from '../../utils/deindent'; -import stringify from '../../utils/stringify'; +import { stringify } from '../../utils/stringify'; import CodeBuilder from '../../utils/CodeBuilder'; import visit from './visit'; import shared from './shared'; diff --git a/src/generators/dom/visitors/Component/Attribute.ts b/src/generators/dom/visitors/Component/Attribute.ts index 10ce5ad981..64f1a1d39f 100644 --- a/src/generators/dom/visitors/Component/Attribute.ts +++ b/src/generators/dom/visitors/Component/Attribute.ts @@ -2,7 +2,7 @@ import { DomGenerator } from '../../index'; import Block from '../../Block'; import { Node } from '../../../../interfaces'; import { State } from '../../interfaces'; -import stringify from '../../../../utils/stringify'; +import { stringify } from '../../../../utils/stringify'; export default function visitAttribute( generator: DomGenerator, diff --git a/src/generators/dom/visitors/Element/Attribute.ts b/src/generators/dom/visitors/Element/Attribute.ts index 2b7f3389d6..b03c379482 100644 --- a/src/generators/dom/visitors/Element/Attribute.ts +++ b/src/generators/dom/visitors/Element/Attribute.ts @@ -1,6 +1,6 @@ import attributeLookup from './lookup'; import deindent from '../../../../utils/deindent'; -import stringify from '../../../../utils/stringify'; +import { stringify } from '../../../../utils/stringify'; import getStaticAttributeValue from './getStaticAttributeValue'; import { DomGenerator } from '../../index'; import Block from '../../Block'; diff --git a/src/generators/dom/visitors/Text.ts b/src/generators/dom/visitors/Text.ts index bf7bf8fd4a..49135a129e 100644 --- a/src/generators/dom/visitors/Text.ts +++ b/src/generators/dom/visitors/Text.ts @@ -2,7 +2,7 @@ import { DomGenerator } from '../index'; import Block from '../Block'; import { Node } from '../../../interfaces'; import { State } from '../interfaces'; -import stringify from '../../../utils/stringify'; +import { stringify } from '../../../utils/stringify'; export default function visitText( generator: DomGenerator, diff --git a/src/generators/server-side-rendering/index.ts b/src/generators/server-side-rendering/index.ts index 53518e32ee..59f9701e7a 100644 --- a/src/generators/server-side-rendering/index.ts +++ b/src/generators/server-side-rendering/index.ts @@ -178,7 +178,12 @@ export default function ssr( function __escape ( html ) { return String( html ).replace( /["'&<>]/g, match => escaped[ match ] ); } - `.replace(/(\\)?@(\w*)/g, (match: string, escaped: string, name: string) => escaped ? match.slice(1) : generator.alias(name)); + `.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); + }); return generator.generate(result, options, { name, format }); } diff --git a/src/generators/server-side-rendering/visitors/Element.ts b/src/generators/server-side-rendering/visitors/Element.ts index 1dcded426f..6204366163 100644 --- a/src/generators/server-side-rendering/visitors/Element.ts +++ b/src/generators/server-side-rendering/visitors/Element.ts @@ -4,6 +4,7 @@ import visit from '../visit'; import visitWindow from './meta/Window'; import { SsrGenerator } from '../index'; import Block from '../Block'; +import { escape } from '../../../utils/stringify'; import { Node } from '../../../interfaces'; const meta = { @@ -14,7 +15,7 @@ function stringifyAttributeValue(block: Block, chunks: Node[]) { return chunks .map((chunk: Node) => { if (chunk.type === 'Text') { - return chunk.data; + return escape(chunk.data).replace(/"/g, '"'); } const { snippet } = block.contextualise(chunk.expression); diff --git a/src/generators/server-side-rendering/visitors/Text.ts b/src/generators/server-side-rendering/visitors/Text.ts index 493d32a936..0e897aaaa6 100644 --- a/src/generators/server-side-rendering/visitors/Text.ts +++ b/src/generators/server-side-rendering/visitors/Text.ts @@ -1,5 +1,6 @@ import { SsrGenerator } from '../index'; import Block from '../Block'; +import { escape } from '../../../utils/stringify'; import { Node } from '../../../interfaces'; export default function visitText( @@ -7,5 +8,5 @@ export default function visitText( block: Block, node: Node ) { - generator.append(node.data.replace(/(\${|`|\\)/g, '\\$1').replace(/([^\\@#])?([@#])/g, '$1\\$2')); + generator.append(escape(node.data).replace(/(\${|`|\\)/g, '\\$1')); } diff --git a/src/utils/stringify.ts b/src/utils/stringify.ts index b4c65addfd..01eff61eba 100644 --- a/src/utils/stringify.ts +++ b/src/utils/stringify.ts @@ -1,3 +1,7 @@ -export default function stringify(data: string) { +export function stringify(data: string) { return JSON.stringify(data.replace(/([^\\@#])?([@#])/g, '$1\\$2')); } + +export function escape(data: string) { + return data.replace(/([^\\@#])?([@#])/g, '$1\\$2'); +} From e2a803cd0b2865e863cb9cb9ca0f37eaf8dd498d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 4 Aug 2017 13:59:33 -0400 Subject: [PATCH 4/4] reuse helper --- src/utils/stringify.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/stringify.ts b/src/utils/stringify.ts index 01eff61eba..c16ac7a937 100644 --- a/src/utils/stringify.ts +++ b/src/utils/stringify.ts @@ -1,5 +1,5 @@ export function stringify(data: string) { - return JSON.stringify(data.replace(/([^\\@#])?([@#])/g, '$1\\$2')); + return JSON.stringify(escape(data)); } export function escape(data: string) {