diff --git a/package.json b/package.json index 9725d71530..a45d1863e3 100644 --- a/package.json +++ b/package.json @@ -30,12 +30,12 @@ "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", "codecov": "codecov", "precodecov": "npm run coverage", - "build": "rollup -c && npm run tsd", + "build": "rollup -c", "prepare": "npm run build", "dev": "rollup -cw", "pretest": "npm run build", "posttest": "agadoo internal/index.mjs", - "prepublishOnly": "npm run lint && PUBLISH=true npm test", + "prepublishOnly": "npm run lint && npm run tsd && PUBLISH=true npm test", "tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly", "lint": "eslint \"{src,test}/**/*.{ts,js}\"" }, diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts index 3c28820a9e..ee85dd860b 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts @@ -123,8 +123,8 @@ export default class AttributeWrapper { : b` if (${option}.__value === ${last}) { ${option}.selected = true; - break; - }`; + ${'break'}; + }`; // TODO the 'break' is gross, but it's unsyntactic otherwise... updater = b` for (var ${i} = 0; ${i} < ${element.var}.options.length; ${i} += 1) { diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 3c5dedf7dd..788624b820 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -2,12 +2,12 @@ import Renderer from '../../Renderer'; import Element from '../../../nodes/Element'; import Wrapper from '../shared/Wrapper'; import Block from '../../Block'; -import { is_void, quote_prop_if_necessary, quote_name_if_necessary, sanitize } from '../../../../utils/names'; +import { is_void, sanitize } from '../../../../utils/names'; import FragmentWrapper from '../Fragment'; import { escape_html, string_literal } from '../../../utils/stringify'; import TextWrapper from '../Text'; import fix_attribute_casing from './fix_attribute_casing'; -import { b, x } from 'code-red'; +import { b, x, p } from 'code-red'; import { namespaces } from '../../../../utils/namespaces'; import AttributeWrapper from './Attribute'; import StyleAttributeWrapper from './StyleAttribute'; @@ -381,8 +381,7 @@ export default class ElementWrapper extends Wrapper { get_claim_statement(nodes: Identifier) { const attributes = this.node.attributes .filter((attr) => attr.type === 'Attribute') - .map((attr) => `${quote_name_if_necessary(attr.name)}: true`) - .join(', '); + .map((attr) => p`${attr.name}: true`); const name = this.node.namespace ? this.node.name @@ -603,7 +602,7 @@ export default class ElementWrapper extends Wrapper { updates.push(condition ? x`${condition} && ${snippet}` : snippet); } else { - const snippet = x`{ ${quote_name_if_necessary(attr.name)}: ${attr.get_value(block)} }`; + const snippet = x`{ ${attr.name}: ${attr.get_value(block)} }`; initial_props.push(snippet); updates.push(condition ? x`${condition} && ${snippet}` : snippet); @@ -813,7 +812,7 @@ export default class ElementWrapper extends Wrapper { snippet = expression.manipulate(block); dependencies = expression.dependencies; } else { - snippet = `${quote_prop_if_necessary(name)}`; + snippet = name; dependencies = new Set([name]); } const updater = b`@toggle_class(${this.var}, "${name}", ${snippet});`; diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 5031bb8cde..4ac181715b 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -3,7 +3,7 @@ import Renderer from '../../Renderer'; import Block from '../../Block'; import InlineComponent from '../../../nodes/InlineComponent'; import FragmentWrapper from '../Fragment'; -import { quote_name_if_necessary, sanitize } from '../../../../utils/names'; +import { sanitize } from '../../../../utils/names'; import add_to_set from '../../../utils/add_to_set'; import { b, x } from 'code-red'; import Attribute from '../../../nodes/Attribute'; @@ -254,7 +254,7 @@ export default class InlineComponentWrapper extends Wrapper { } changes.push(condition ? x`${condition} && ${value_object}` : value_object); } else { - const obj = x`{ ${quote_name_if_necessary(name)}: ${attr.get_value(block)} }`; + const obj = x`{ ${name}: ${attr.get_value(block)} }`; initial_props.push(obj); changes.push(condition ? x`${condition} && ${obj}` : x`${levels}[${i}]`); diff --git a/src/compiler/parse/read/expression.ts b/src/compiler/parse/read/expression.ts index 78a28ba72b..1126711fe2 100644 --- a/src/compiler/parse/read/expression.ts +++ b/src/compiler/parse/read/expression.ts @@ -1,6 +1,7 @@ import { parse_expression_at } from '../acorn'; import { Parser } from '../index'; import { Identifier, Node, SimpleLiteral } from 'estree'; +import { whitespace } from '../../utils/patterns'; const literals = new Map([['true', true], ['false', false], ['null', null]]); @@ -35,7 +36,30 @@ export default function read_expression(parser: Parser): Node { try { const node = parse_expression_at(parser.template, parser.index); - parser.index = node.end; + + let num_parens = 0; + + for (let i = parser.index; i < node.start; i += 1) { + if (parser.template[i] === '(') num_parens += 1; + } + + let index = node.end; + while (num_parens > 0) { + const char = parser.template[index]; + + if (char === ')') { + num_parens -= 1; + } else if (!whitespace.test(char)) { + parser.error({ + code: 'unexpected-token', + message: 'Expected )' + }, index); + } + + index += 1; + } + + parser.index = index; return node as Node; } catch (err) { diff --git a/test/runtime/samples/class-helper/_config.js b/test/runtime/samples/class-helper/_config.js index 2c4606fbe8..c38cc88240 100644 --- a/test/runtime/samples/class-helper/_config.js +++ b/test/runtime/samples/class-helper/_config.js @@ -5,7 +5,7 @@ export default { html: `
`, - test({ assert, component, target, window }) { + test({ assert, component, target }) { component.user = { active: false }; assert.htmlEqual(target.innerHTML, `