diff --git a/src/parse/index.js b/src/parse/index.js index ee0c1d8dfb..29122d69bc 100644 --- a/src/parse/index.js +++ b/src/parse/index.js @@ -32,6 +32,7 @@ export default function parse ( template, options = {} ) { index: 0, template, stack: [], + metaTags: {}, current () { return this.stack[ this.stack.length - 1 ]; diff --git a/src/parse/state/tag.js b/src/parse/state/tag.js index f315ef69e4..396bd46244 100644 --- a/src/parse/state/tag.js +++ b/src/parse/state/tag.js @@ -11,6 +11,10 @@ const invalidUnquotedAttributeCharacters = /[\s"'=<>\/`]/; const SELF = ':Self'; +const metaTags = { + ':Window': true +}; + const specials = { script: { read: readScript, @@ -81,6 +85,22 @@ export default function tag ( parser ) { const name = readTagName( parser ); + if ( name in metaTags ) { + if ( name in parser.metaTags ) { + if ( isClosingTag && parser.current().children.length ) { + parser.error( `<${name}> cannot have children`, parser.current().children[0].start ); + } + + parser.error( `A component can only have one <${name}> tag`, start ); + } + + parser.metaTags[ name ] = true; + + if ( parser.stack.length > 1 ) { + parser.error( `<${name}> tags cannot be inside elements or blocks`, start ); + } + } + parser.allowWhitespace(); if ( isClosingTag ) { @@ -194,6 +214,9 @@ function readTagName ( parser ) { } const name = parser.readUntil( /(\s|\/|>)/ ); + + if ( name in metaTags ) return name; + if ( !validTagName.test( name ) ) { parser.error( `Expected valid tag name`, start ); } diff --git a/test/parser/samples/error-window-children/error.json b/test/parser/samples/error-window-children/error.json new file mode 100644 index 0000000000..8ff51ca8fb --- /dev/null +++ b/test/parser/samples/error-window-children/error.json @@ -0,0 +1,8 @@ +{ + "message": "<:Window> cannot have children", + "loc": { + "line": 1, + "column": 9 + }, + "pos": 9 +} \ No newline at end of file diff --git a/test/parser/samples/error-window-children/input.html b/test/parser/samples/error-window-children/input.html new file mode 100644 index 0000000000..eff4bebe50 --- /dev/null +++ b/test/parser/samples/error-window-children/input.html @@ -0,0 +1 @@ +<:Window>contents \ No newline at end of file diff --git a/test/parser/samples/error-window-duplicate/error.json b/test/parser/samples/error-window-duplicate/error.json new file mode 100644 index 0000000000..1e86fafea2 --- /dev/null +++ b/test/parser/samples/error-window-duplicate/error.json @@ -0,0 +1,8 @@ +{ + "message": "A component can only have one <:Window> tag", + "loc": { + "line": 2, + "column": 0 + }, + "pos": 11 +} \ No newline at end of file diff --git a/test/parser/samples/error-window-duplicate/input.html b/test/parser/samples/error-window-duplicate/input.html new file mode 100644 index 0000000000..683468e436 --- /dev/null +++ b/test/parser/samples/error-window-duplicate/input.html @@ -0,0 +1,2 @@ +<:Window/> +<:Window/> \ No newline at end of file diff --git a/test/parser/samples/error-window-inside-block/error.json b/test/parser/samples/error-window-inside-block/error.json new file mode 100644 index 0000000000..d6f6bd2f33 --- /dev/null +++ b/test/parser/samples/error-window-inside-block/error.json @@ -0,0 +1,8 @@ +{ + "message": "<:Window> tags cannot be inside elements or blocks", + "loc": { + "line": 2, + "column": 1 + }, + "pos": 13 +} \ No newline at end of file diff --git a/test/parser/samples/error-window-inside-block/input.html b/test/parser/samples/error-window-inside-block/input.html new file mode 100644 index 0000000000..b361517056 --- /dev/null +++ b/test/parser/samples/error-window-inside-block/input.html @@ -0,0 +1,3 @@ +{{#if foo}} + <:Window/> +{{/if}} \ No newline at end of file diff --git a/test/parser/samples/error-window-inside-element/error.json b/test/parser/samples/error-window-inside-element/error.json new file mode 100644 index 0000000000..5c28694d61 --- /dev/null +++ b/test/parser/samples/error-window-inside-element/error.json @@ -0,0 +1,8 @@ +{ + "message": "<:Window> tags cannot be inside elements or blocks", + "loc": { + "line": 2, + "column": 1 + }, + "pos": 7 +} \ No newline at end of file diff --git a/test/parser/samples/error-window-inside-element/input.html b/test/parser/samples/error-window-inside-element/input.html new file mode 100644 index 0000000000..edda05bfbb --- /dev/null +++ b/test/parser/samples/error-window-inside-element/input.html @@ -0,0 +1,3 @@ +
+ <:Window/> +
> \ No newline at end of file