From 3c98ba79858dfab4735c0357b16ee5fdf078be21 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 3 Dec 2017 14:30:25 -0500 Subject: [PATCH] parse :Switch tags --- src/parse/state/tag.ts | 35 +++++++++------ .../samples/component-dynamic/input.html | 1 + .../samples/component-dynamic/output.json | 43 +++++++++++++++++++ 3 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 test/parser/samples/component-dynamic/input.html create mode 100644 test/parser/samples/component-dynamic/output.json diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index ffe9a40218..d2c17e30fa 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -15,9 +15,10 @@ import { Node } from '../../interfaces'; const validTagName = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/; const SELF = ':Self'; +const SWITCH = ':Switch'; const metaTags = { - ':Window': true, + ':Window': true }; const specials = new Map([ @@ -104,6 +105,15 @@ export default function tag(parser: Parser) { } } + const element: Node = { + start, + end: null, // filled in later + type: 'Element', + name, + attributes: [], + children: [], + }; + parser.allowWhitespace(); if (isClosingTag) { @@ -156,12 +166,18 @@ export default function tag(parser: Parser) { } } - const attributes = []; + if (name === SWITCH) { + parser.eat('{', true); + element.expression = readExpression(parser); + parser.allowWhitespace(); + parser.eat('}', true); + } + const uniqueNames = new Set(); let attribute; while ((attribute = readAttribute(parser, uniqueNames))) { - attributes.push(attribute); + element.attributes.push(attribute); parser.allowWhitespace(); } @@ -179,19 +195,10 @@ export default function tag(parser: Parser) { } parser.eat('>', true); - parser[special.property] = special.read(parser, start, attributes); + parser[special.property] = special.read(parser, start, element.attributes); return; } - const element: Node = { - start, - end: null, // filled in later - type: 'Element', - name, - attributes, - children: [], - }; - parser.current().children.push(element); const selfClosing = parser.eat('/') || isVoidElementName(name); @@ -242,6 +249,8 @@ function readTagName(parser: Parser) { return SELF; } + if (parser.eat(SWITCH)) return SWITCH; + const name = parser.readUntil(/(\s|\/|>)/); if (name in metaTags) return name; diff --git a/test/parser/samples/component-dynamic/input.html b/test/parser/samples/component-dynamic/input.html new file mode 100644 index 0000000000..1c4e872902 --- /dev/null +++ b/test/parser/samples/component-dynamic/input.html @@ -0,0 +1 @@ +<:Switch {foo ? Foo : Bar}> \ No newline at end of file diff --git a/test/parser/samples/component-dynamic/output.json b/test/parser/samples/component-dynamic/output.json new file mode 100644 index 0000000000..22b32bb932 --- /dev/null +++ b/test/parser/samples/component-dynamic/output.json @@ -0,0 +1,43 @@ +{ + "hash": 755548012, + "html": { + "start": 0, + "end": 37, + "type": "Fragment", + "children": [ + { + "start": 0, + "end": 37, + "type": "Element", + "name": ":Switch", + "attributes": [], + "children": [], + "expression": { + "type": "ConditionalExpression", + "start": 10, + "end": 25, + "test": { + "type": "Identifier", + "start": 10, + "end": 13, + "name": "foo" + }, + "consequent": { + "type": "Identifier", + "start": 16, + "end": 19, + "name": "Foo" + }, + "alternate": { + "type": "Identifier", + "start": 22, + "end": 25, + "name": "Bar" + } + } + } + ] + }, + "css": null, + "js": null +} \ No newline at end of file