handle @foo and #foo edge cases

pull/673/head
Rich Harris 8 years ago
parent acf889d8b5
commit 2fa784ecc3

@ -254,11 +254,14 @@ export default function dom(
let result = builder let result = builder
.toString() .toString()
.replace(/@(\w+)\b/g, (match: string, name: string) => { .replace(/(\\)?@(\w*)/g, (match: string, escaped: string, name: string) => {
if (escaped) return match.slice(1);
if (name in shared) { if (name in shared) {
if (options.dev && `${name}Dev` in shared) name = `${name}Dev`; if (options.dev && `${name}Dev` in shared) name = `${name}Dev`;
usedHelpers.add(name); usedHelpers.add(name);
} }
return generator.alias(name); return generator.alias(name);
}); });

@ -2,7 +2,6 @@ import deindent from '../../utils/deindent';
import Generator from '../Generator'; import Generator from '../Generator';
import Block from './Block'; import Block from './Block';
import visit from './visit'; import visit from './visit';
import stringify from '../../utils/stringify';
import { removeNode, removeObjectKey } from '../../utils/removeNode'; import { removeNode, removeObjectKey } from '../../utils/removeNode';
import { Parsed, Node, CompileOptions } from '../../interfaces'; import { Parsed, Node, CompileOptions } from '../../interfaces';
@ -84,7 +83,7 @@ export default function ssr(
var ${name} = {}; var ${name} = {};
${name}.filename = ${stringify(options.filename)}; ${name}.filename = ${JSON.stringify(options.filename)};
${name}.data = function () { ${name}.data = function () {
return ${templateProperties.data ? `@template.data()` : `{}`}; return ${templateProperties.data ? `@template.data()` : `{}`};
@ -124,7 +123,7 @@ export default function ssr(
deindent` deindent`
components.push({ components.push({
filename: ${name}.filename, filename: ${name}.filename,
css: ${stringify(generator.css)}, css: ${JSON.stringify(generator.css)},
map: null // TODO map: null // TODO
}); });
`} `}
@ -169,7 +168,7 @@ export default function ssr(
function __escape ( html ) { function __escape ( html ) {
return String( html ).replace( /["'&<>]/g, match => escaped[ match ] ); return String( html ).replace( /["'&<>]/g, match => escaped[ match ] );
} }
`.replace(/@(\w+)/g, (match, name) => generator.alias(name)); `.replace(/(\\)?@(\w*)/g, (match: string, escaped: string, name: string) => escaped ? match.slice(1) : generator.alias(name));
return generator.generate(result, options, { name, format }); return generator.generate(result, options, { name, format });
} }

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

@ -7,5 +7,5 @@ export default function visitText(
block: Block, block: Block,
node: Node node: Node
) { ) {
generator.append(node.data.replace(/(\${|`|\\)/g, '\\$1')); generator.append(node.data.replace(/(\${|`|\\)/g, '\\$1').replace(/([^\\])?([@#])/g, '$1\\$2'));
} }

@ -0,0 +1,3 @@
export default {
html: `#foo`
};

@ -0,0 +1,3 @@
export default {
html: `@foo`
};

@ -34,7 +34,7 @@ describe("ssr", () => {
// add .solo to a sample directory name to only run that test, or // add .solo to a sample directory name to only run that test, or
// .show to always show the output. or both // .show to always show the output. or both
const solo = /\.solo/.test(dir); const solo = /\.solo/.test(dir);
let show = /\.show/.test(dir); const show = /\.show/.test(dir);
if (solo && process.env.CI) { if (solo && process.env.CI) {
throw new Error("Forgot to remove `solo: true` from test"); throw new Error("Forgot to remove `solo: true` from test");
@ -42,36 +42,27 @@ describe("ssr", () => {
(solo ? it.only : it)(dir, () => { (solo ? it.only : it)(dir, () => {
dir = path.resolve("test/server-side-rendering/samples", dir); dir = path.resolve("test/server-side-rendering/samples", dir);
try {
const component = require(`${dir}/main.html`); const component = require(`${dir}/main.html`);
const expectedHtml = tryToReadFile(`${dir}/_expected.html`); const expectedHtml = tryToReadFile(`${dir}/_expected.html`);
const expectedCss = tryToReadFile(`${dir}/_expected.css`) || ""; const expectedCss = tryToReadFile(`${dir}/_expected.css`) || "";
const data = tryToLoadJson(`${dir}/data.json`); const data = tryToLoadJson(`${dir}/data.json`);
let html;
let css;
let error;
try { const html = component.render(data);
html = component.render(data); const css = component.renderCss().css;
css = component.renderCss().css;
} catch (e) {
show = true;
error = e;
}
if (show) showOutput(dir, { generate: "ssr" });
if (error) throw error;
fs.writeFileSync(`${dir}/_actual.html`, html); fs.writeFileSync(`${dir}/_actual.html`, html);
if (css) fs.writeFileSync(`${dir}/_actual.css`, css); if (css) fs.writeFileSync(`${dir}/_actual.css`, css);
try {
assert.htmlEqual(html, expectedHtml); assert.htmlEqual(html, expectedHtml);
assert.equal( assert.equal(
css.replace(/^\s+/gm, ""), css.replace(/^\s+/gm, ""),
expectedCss.replace(/^\s+/gm, "") expectedCss.replace(/^\s+/gm, "")
); );
if (show) showOutput(dir, { generate: 'ssr' });
} catch (err) { } catch (err) {
showOutput(dir, { generate: 'ssr' }); showOutput(dir, { generate: 'ssr' });
throw err; throw err;

Loading…
Cancel
Save