From 682c2eb847cc3f3435226ec105b2894d60de146c Mon Sep 17 00:00:00 2001 From: John Ratcliff Date: Mon, 18 Dec 2017 16:34:14 +0000 Subject: [PATCH 1/3] Named Args Syntax - Allow for `@foo` mustache to reference named arguments - Allow for glimmer components to use `@` in arguments --- lib/pegjs/key.pegjs | 2 +- lib/pegjs/mustache/attr-statement.pegjs | 1 + lib/pegjs/mustache/name-character.pegjs | 2 +- tests/integration/glimmer-component-test.js | 48 +++++++++++++-------- tests/integration/mustaches-test.js | 3 ++ 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/lib/pegjs/key.pegjs b/lib/pegjs/key.pegjs index 73ae265..cdce5bd 100644 --- a/lib/pegjs/key.pegjs +++ b/lib/pegjs/key.pegjs @@ -3,4 +3,4 @@ start = key key "Key" - = $((nmchar / ':' / '.')*) + = $((nmchar / ':' / '.' / '@')*) diff --git a/lib/pegjs/mustache/attr-statement.pegjs b/lib/pegjs/mustache/attr-statement.pegjs index 54c1f40..31a97f9 100644 --- a/lib/pegjs/mustache/attr-statement.pegjs +++ b/lib/pegjs/mustache/attr-statement.pegjs @@ -36,6 +36,7 @@ closeBracket = DEDENT? _ ']' - key/value pair - subexpression - a mustache value (i.e. positional params) + - positional params */ mustacheAttr = mustacheKeyValue / subexpression / mustacheAttrValue diff --git a/lib/pegjs/mustache/name-character.pegjs b/lib/pegjs/mustache/name-character.pegjs index fdf527a..53f6d06 100644 --- a/lib/pegjs/mustache/name-character.pegjs +++ b/lib/pegjs/mustache/name-character.pegjs @@ -1,7 +1,7 @@ start = newMustacheNameChar // a character that can be in a mustache name -newMustacheNameChar = [-_/A-Za-z0-9] / arrayIndex / '.' +newMustacheNameChar = [-_/A-Za-z0-9] / arrayIndex / '.' / '@' // Ember requires that array indexes have a . before them arrayIndex = '.[' newMustacheNameChar* ']' diff --git a/tests/integration/glimmer-component-test.js b/tests/integration/glimmer-component-test.js index df57a5b..ec6a4f4 100644 --- a/tests/integration/glimmer-component-test.js +++ b/tests/integration/glimmer-component-test.js @@ -7,10 +7,10 @@ QUnit.module("glimmer-components"); test("basic syntax", function(){ var emblem = w( - "% my-component value=foo data-hint='not-my-component%%::'" + "% my-component @value=foo data-hint='not-my-component%%::'" ); compilesTo(emblem, - ''); + ''); }); test("basic syntax with legacy quoting", function(){ @@ -25,10 +25,10 @@ test("basic syntax with legacy quoting", function(){ test("names with :", function(){ var emblem = w( - "% inputs:my-component value=foo" + "% inputs:my-component @value=foo" ); compilesTo(emblem, - ''); + ''); }); // @TODO @@ -36,20 +36,20 @@ test("names with :", function(){ test("Blocks", function() { var emblem = w( - "% my-component value=foo", + "% my-component @value=foo", " |Hi!" ); compilesTo(emblem, - 'Hi!'); + 'Hi!'); }); test("Block params", function() { var emblem = w( - "% my-component value=foo as |comp1 comp2|", + "% my-component @value=foo as |comp1 comp2|", " = comp.name" ); compilesTo(emblem, - '{{comp.name}}'); + '{{comp.name}}'); }); // @TODO: What should the result of this be? @@ -58,10 +58,10 @@ test("Block params", function() { test('brackets with string', function(){ var emblem = w('', '%my-component [', - ' foo=bar', - ' baz=\'food\' ]'); + ' @foo=bar', + ' @baz=\'food\' ]'); compilesTo( - emblem, ''); + emblem, ''); }); // Invalid @@ -70,10 +70,10 @@ test('brackets with string', function(){ test('bracketed nested block', function(){ var emblem = w('', '%my-component [', - ' something="false" ]', + ' @something="false" ]', ' p Bracketed helper attrs!'); compilesTo( - emblem, '

Bracketed helper attrs!

'); + emblem, '

Bracketed helper attrs!

'); }); test('bracketed nested with actions', function(){ @@ -81,19 +81,19 @@ test('bracketed nested with actions', function(){ '%my-component [', ' onclick={ action \'doSometing\' foo bar }', ' change=\'otherAction\'', - ' something="false" ]', + ' @something="false" ]', ' p Bracketed helper attrs!'); compilesTo( - emblem, '

Bracketed helper attrs!

'); + emblem, '

Bracketed helper attrs!

'); }); // @TODO: should these support mustache-like syntax? (i.e. %my-component value=(foo) ) test("Sub-expressions", function() { var emblem = w( - "% my-component value={ (or (eq foo 'bar') (eq foo 'baz')) }" + "% my-component @value={ (or (eq foo 'bar') (eq foo 'baz')) }" ); compilesTo(emblem, - ''); + ''); }); test('recursive nesting part 2', function(){ @@ -103,3 +103,17 @@ test('recursive nesting part 2', function(){ ' p Hello'); compilesTo(emblem, '

Hello

'); }); + +test('named block support', function() { + var emblem = w( + '% x-modal', + ' % @header as |@title|', + ' |Header #{title}', + ' % @body', + ' |Body', + ' % @footer', + ' |Footer' + ) + + compilesTo(emblem, '<@header as |@title|>Header {{title}}<@body>Body<@footer>Footer'); +}); diff --git a/tests/integration/mustaches-test.js b/tests/integration/mustaches-test.js index 3588455..87037cd 100644 --- a/tests/integration/mustaches-test.js +++ b/tests/integration/mustaches-test.js @@ -17,6 +17,9 @@ test("various one-liners", function(){ '{{foo}}{{arf}}

{{foo}}

{{goo}}

'); }); +test('named argument syntax', function() { + compilesTo('= @bar', '{{@bar}}'); +}); test("double =='s un-escape", function(){ var emblem = w( From 173ad4c37ed91b71f14780a6107c7d85059f568b Mon Sep 17 00:00:00 2001 From: John Ratcliff Date: Mon, 18 Dec 2017 17:03:28 +0000 Subject: [PATCH 2/3] Add named block support --- lib/pegjs/html/tag-string.pegjs | 2 +- tests/integration/mustaches-test.js | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/pegjs/html/tag-string.pegjs b/lib/pegjs/html/tag-string.pegjs index ae9fd44..c4af46a 100644 --- a/lib/pegjs/html/tag-string.pegjs +++ b/lib/pegjs/html/tag-string.pegjs @@ -4,4 +4,4 @@ start = tagString tagString = c:$tagChar+ -tagChar = [_a-zA-Z0-9-] / nonSeparatorColon +tagChar = [_a-zA-Z0-9-] / nonSeparatorColon / '@' diff --git a/tests/integration/mustaches-test.js b/tests/integration/mustaches-test.js index 87037cd..10a08b1 100644 --- a/tests/integration/mustaches-test.js +++ b/tests/integration/mustaches-test.js @@ -529,3 +529,27 @@ test('mustache with else if and complex statements', function() { compilesTo(emblem, '{{#if foo}}

Hi!

{{else if (eq 1 (and-or a=b showHidden=(eq 1 2)))}}

Wow what was that?

{{/if}}'); }); + +test('named block support', function() { + var emblem = w( + '= x-modal', + ' % @header as |@title|', + ' |Header #{title}', + ' % @body', + ' |Body', + ' % @footer', + ' |Footer' + ) + + compilesTo(emblem, '{{#x-modal}}<@header as |@title|>Header {{title}}<@body>Body<@footer>Footer{{/x-modal}}'); +}); + +test('named block with block param', function() { + var emblem = w( + '= x-layout as |@widget|', + ' = @widget as |a b c|', + ' |Hi.' + ) + + compilesTo(emblem, '{{#x-layout as |@widget|}}{{#@widget as |a b c|}}Hi.{{/@widget}}{{/x-layout}}'); +}); From 36dca449e4b41ae1b3b25f23bac039d7c487ed72 Mon Sep 17 00:00:00 2001 From: John Ratcliff Date: Wed, 20 Dec 2017 15:11:10 +0000 Subject: [PATCH 3/3] Glimmer attributes will not auto-quote --- lib/pegjs/html/boolean-attr.pegjs | 2 +- lib/pegjs/non-glimmer-key.pegjs | 6 ++++++ tests/integration/glimmer-component-test.js | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 lib/pegjs/non-glimmer-key.pegjs diff --git a/lib/pegjs/html/boolean-attr.pegjs b/lib/pegjs/html/boolean-attr.pegjs index b28e380..346c0de 100644 --- a/lib/pegjs/html/boolean-attr.pegjs +++ b/lib/pegjs/html/boolean-attr.pegjs @@ -1,4 +1,4 @@ -@import "../key.pegjs" as key +@import "../non-glimmer-key.pegjs" as key start = booleanAttribute diff --git a/lib/pegjs/non-glimmer-key.pegjs b/lib/pegjs/non-glimmer-key.pegjs new file mode 100644 index 0000000..73ae265 --- /dev/null +++ b/lib/pegjs/non-glimmer-key.pegjs @@ -0,0 +1,6 @@ +@import "./nmchar.pegjs" as nmchar + +start = key + +key "Key" + = $((nmchar / ':' / '.')*) diff --git a/tests/integration/glimmer-component-test.js b/tests/integration/glimmer-component-test.js index ec6a4f4..282165f 100644 --- a/tests/integration/glimmer-component-test.js +++ b/tests/integration/glimmer-component-test.js @@ -23,6 +23,14 @@ test("basic syntax with legacy quoting", function(){ }); }); +test("boolean attribute passed in as component input", function() { + var emblem = w( + "% my-component @multiselect=false" + ); + compilesTo(emblem, + ''); +}); + test("names with :", function(){ var emblem = w( "% inputs:my-component @value=foo"