Skip to content

Commit

Permalink
Added support for machty#326 but removed workaround code with no dede…
Browse files Browse the repository at this point in the history
…nting close bracket in multi-line declarations because it leads to syntax glitches
  • Loading branch information
evgenibir committed Mar 24, 2021
1 parent b1d1c3c commit 727a885
Show file tree
Hide file tree
Showing 16 changed files with 133 additions and 54 deletions.
5 changes: 3 additions & 2 deletions lib/parser.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ colonContent = ': ' _ c:contentStatement { return c; }
// and any nested content inside of it.
htmlElement = h:inHtmlTag nested:htmlTerminator
{
parseInHtml(...h);
if (nested && nested.length > 0) {
nested = castStringsToTextNodes(nested);
builder.add('childNodes', nested);
Expand Down Expand Up @@ -265,7 +266,7 @@ htmlTerminator
div [
foo=bar ]
*/
/ _ inlineComment? DEDENT? ']' TERM
/ _ inlineComment? DEDENT ']' TERM

/ h:htmlNestedTextNodes {
return h;
Expand Down Expand Up @@ -464,7 +465,7 @@ mustacheEndBracketAndNested
= foo [
foo=bar ]
*/
/ _ DEDENT? ']' TERM {
/ _ DEDENT ']' TERM {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/pegjs/html/bound-attr-with-mustache.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ boundAttributeWithSingleMustache

return [builder.generateAssignedMustache(value, k)];
}
/ k:key '=' value:singleMustacheStatement {
/ k:key '=' value:singleMustacheStatement !{ return /[\[\]]/g.test(value) } {
value = value.trim().replace(/[]/g, '');

return [builder.generateAssignedMustache(value, k)];
Expand Down
2 changes: 1 addition & 1 deletion lib/pegjs/html/helper-with-mustache.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ bracketedAttr = INDENT* _ attr:mustacheAttr (_ inlineComment)* TERM* {

openBracket = '[' _ inlineComment? TERM+
closeBracket 'Closing bracket'
= DEDENT? _ ']'
= DEDENT _ ']'

mustacheAttr = mustacheKeyValue / subexpression / mustacheAttrValue

Expand Down
8 changes: 4 additions & 4 deletions lib/pegjs/html/tag-component.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@ start = inHtmlTag

openBracket = '[' _ inlineComment? TERM+
closeBracket 'Closing bracket'
= DEDENT? _ ']'
= DEDENT _ ']'
commentWithSpace = (_ comment) { return []; }

inTagMustache = m:helperValue {
return builder.generateMustache(m, true);
} / statement

inHtmlTag
= h:htmlStart startingInTagMustaches:inTagMustache* blockParams:blockParams? __ openBracket modifiers:bracketedModifier* fullAttributes:(bracketedAttribute / commentWithSpace / blankLine)* _ &closeBracket
= h:htmlStart startingInTagMustaches:inTagMustache* blockParams:blockParams? __ openBracket modifiers:bracketedModifier* fullAttributes:(bracketedAttribute / commentWithSpace / blankLine)* _ closeBracket
{
// Filter out comments
fullAttributes = fullAttributes.filter(function(attr) {
return attr && attr.length > 0;
});
return parseInHtml(h, startingInTagMustaches.concat(modifiers), fullAttributes, blockParams);
return [h, startingInTagMustaches.concat(modifiers), fullAttributes, blockParams]
}
/ h:htmlStart inTagMustaches:inTagMustache* fullAttributes:attribute* blockParams:blockParams?
{
return parseInHtml(h, inTagMustaches, fullAttributes, blockParams);
return [h, inTagMustaches, fullAttributes, blockParams]
}

htmlStart
Expand Down
8 changes: 4 additions & 4 deletions lib/pegjs/html/tag-html.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
start = tagHtml

openBracket = '[' _ inlineComment? TERM+
closeBracket = DEDENT? _ ']'
closeBracket = DEDENT _ ']'
commentWithSpace = (_ comment) { return []; }

inTagMustache = m:helperValue {
Expand All @@ -34,17 +34,17 @@ inTagMustache = m:helperValue {
This also needs to absorb comments for when using brackets
*/
tagHtml
= h:htmlStart startingInTagMustaches:inTagMustache* __ openBracket modifiers:bracketedModifier* fullAttributes:(bracketedAttribute / commentWithSpace / blankLine)* &closeBracket
= h:htmlStart startingInTagMustaches:inTagMustache* __ openBracket modifiers:bracketedModifier* fullAttributes:(bracketedAttribute / commentWithSpace / blankLine)* closeBracket
{
// Filter out comments
fullAttributes = fullAttributes.filter(function(attr) {
return attr && attr.length > 0;
});
return parseInHtml(h, startingInTagMustaches.concat(modifiers), fullAttributes);
return [h, startingInTagMustaches.concat(modifiers), fullAttributes]
}
/ h:htmlStart inTagMustaches:inTagMustache* fullAttributes:attribute*
{
return parseInHtml(h, inTagMustaches, fullAttributes);
return [h, inTagMustaches, fullAttributes]
}


Expand Down
6 changes: 3 additions & 3 deletions lib/pegjs/mustache/attr-statement.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mustacheAttrs = bracketedAttrs / mustacheAttr*
```
*/

bracketedAttrs = initialAttrs:(mustacheAttrValue / subexpression)* _ openBracket attrs:(bracketedAttr / commentWithSpace / blankLine)+ &closeBracket _ {
bracketedAttrs = initialAttrs:(mustacheAttrValue / subexpression)* _ openBracket attrs:(bracketedAttr / commentWithSpace / blankLine)+ closeBracket _ {
if (initialAttrs && initialAttrs.length)
for (const i of initialAttrs)
attrs.unshift(i);
Expand All @@ -42,7 +42,7 @@ bracketedAttr = INDENT* _ attr:mustacheAttr (_ inlineComment)* TERM* {

openBracket = '[' _ inlineComment? TERM+
closeBracket 'Closing bracket'
= DEDENT? _ ']'
= DEDENT _ ']'


/**
Expand Down Expand Up @@ -92,7 +92,7 @@ subexpressionClose 'Closing ) for Subexpression'

// Bracketed attrs in a subexpression are different than normal mustache attrs because they cannot have nested content. As a result, we need to absorb the closeBracket here instead of upstream
subexpressionBracketAttrs 'Subexpression bracketed attribute'
= attrs:bracketedAttrs closeBracket {
= attrs:bracketedAttrs {
return attrs.join(' ');
}

Expand Down
2 changes: 1 addition & 1 deletion lib/pegjs/text-nodes.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ textNodes = first:preMustacheText? tail:(mustacheStatement preMustacheText?)* TE
preMustacheText
= $preMustacheUnit+
preMustacheUnit
= !nonMustacheUnit c:. { return c; }
= !nonMustacheUnit c:. !{ return /[\[\]]/g.test(c) } { return c; }

/**
Duplicates
Expand Down
72 changes: 66 additions & 6 deletions tests/integration/basic-syntax/multi-line-parameters-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@ import { w } from 'tests/support/utils';

module('basic syntax: multi-line-parameters', function (hooks) {
test('bracketed attributes', function (assert) {
const emblem = "p [\n id=\"yes\"\n class=\"no\" ]\n | Bracketed Attributes FTW!";
const emblem = "p [\n id=\"yes\"\n class=\"no\" \n]\n | Bracketed Attributes FTW!";

assert.compilesTo(emblem, '<p id="yes" class="no">Bracketed Attributes FTW!</p>');
});

test('bracketed mustache attributes', function (assert) {
const emblem = "p [\n onclick={ action 'foo' }\n class=\"no\" ]\n | Bracketed Attributes FTW!";
const emblem = "p [\n onclick={ action 'foo' }\n class=\"no\" \n]\n | Bracketed Attributes FTW!";

assert.compilesTo(emblem, '<p onclick={{action \'foo\'}} class="no">Bracketed Attributes FTW!</p>');
});

test('bracketed text', function (assert) {
const emblem = "p [ Bracketed text is cool ]";

assert.compilesTo(emblem, '<p>[ Bracketed text is cool ]</p>');
assert.compilerThrows(emblem, '<p>[ Bracketed text is cool ]</p>');
});

test('bracketed text indented', function (assert) {
const emblem = "p\n | [ Bracketed text is cool ]";

assert.compilesTo(emblem, '<p>[ Bracketed text is cool ]</p>');
assert.compilerThrows(emblem, '<p>[ Bracketed text is cool ]</p>');
});

test('bracketed statement with comment and blank lines', function (assert) {
Expand All @@ -38,11 +38,71 @@ module('basic syntax: multi-line-parameters', function (hooks) {
});

test('bracketed statement end bracket', function (assert) {
const emblem = w('div [',
const emblem = w(
'div [',
' foo=bar',
' ',
' data=baz ]');
' data=baz',
']'
);

assert.compilesTo(emblem, '<div foo={{bar}} data={{baz}}></div>');
});

test('bracketed statement and block', function (assert) {
const emblem = w(
'a [',
' href={ generate-link foo.bar }',
' ',
']',
' | Foo',
);

assert.compilesTo(emblem, '<a href={{generate-link foo.bar}}>Foo</a>');
});

test('bracketed statement and block - case 2', function (assert) {
const emblem = w(
'a [',
' href={ generate-link foo.bar }',
' ',
'] ',
' | Foo',
);

assert.compilesTo(emblem, '<a href={{generate-link foo.bar}}>Foo</a>');
});

test('bracketed statement and block - case 3', function (assert) {
const emblem = w(
'a [',
' href={ generate-link foo.bar }',
' ',
']: foo',
);

assert.compilesTo(emblem, '<a href={{generate-link foo.bar}}>{{foo}}</a>');
});

test('bracketed statement and block - case 4', function (assert) {
const emblem = w(
'a [',
' href={ generate-link foo.bar }',
' ',
']: = foo',
);

assert.compilesTo(emblem, '<a href={{generate-link foo.bar}}>{{foo}}</a>');
});

test('bracketed statement and block - case 5', function (assert) {
const emblem = w(
'a [',
' href={generate-link foo.bar}',
' ',
']: | Foo',
);

assert.compilesTo(emblem, '<a href={{generate-link foo.bar}}>Foo</a>');
});
});
3 changes: 2 additions & 1 deletion tests/integration/ember/blocks-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ module('ember: blocks', function (hooks) {
const emblem = w(
"= component 'my-component' [",
' foo',
' bar=baz ] as |left right|',
' bar=baz',
'] as |left right|',
' span class={ left } = right'
);

Expand Down
8 changes: 8 additions & 0 deletions tests/integration/ember/link-to-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ module('ember: link-to', function (hooks) {
assert.compilesTo(emblem, '<ul><li>{{#link-to "index"}}Home{{/link-to}}</li><li>{{#link-to "about"}}About Us{{/link-to}}</li></ul>');
});

test('example 6', function (assert) {
const emblem = w(
'= link-to "items.list" (query-params page=2): | Go to page 2'
);

assert.compilesTo(emblem, '{{#link-to "items.list" (query-params page=2)}}Go to page 2{{/link-to}}');
});

test("brace works with text pipe", function (assert) {
const emblem = "= link-to 'users.view' user | View user #{ user.name } ${ user.id }";

Expand Down
21 changes: 6 additions & 15 deletions tests/integration/glimmer/brackets-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module('glimmer: brackets', function (hooks) {
'',
'%MyComponent [',
' @foo=bar',
' @baz=\'food\' ]'
' @baz=\'food\'',
']'
);

assert.compilesTo(emblem, '<MyComponent @foo={{bar}} @baz=\"food\"></MyComponent>');
Expand All @@ -30,7 +31,8 @@ module('glimmer: brackets', function (hooks) {
'',
'%MyComponent [',
' ',
' @something="false" ]',
' @something="false"',
']',
' p Bracketed helper attrs!'
);

Expand All @@ -55,7 +57,8 @@ module('glimmer: brackets', function (hooks) {
'%MyComponent [',
' onclick={ action \'doSometing\' foo bar }',
' change=\'otherAction\'',
' @something="false" ]',
' @something="false"',
']',
' p Bracketed helper attrs!'
);

Expand Down Expand Up @@ -89,18 +92,6 @@ module('glimmer: brackets', function (hooks) {
});

test('tag modifiers with multi-line', function (assert) {
const emblem = w(
'%MyComponent{did-insert this.handler} [',
' {on "input" @onInput}',
' ',
' @something="false" ]',
' p Bracketed helper attrs!'
);

assert.compilesTo(emblem, '<MyComponent {{did-insert this.handler}} {{on "input" @onInput}} @something=\"false\"><p>Bracketed helper attrs!</p></MyComponent>');
});

test('tag modifiers with multi-line - second case', function (assert) {
const emblem = w(
'%MyComponent{did-insert this.handler} [',
' {on "input" @onInput}',
Expand Down
3 changes: 2 additions & 1 deletion tests/integration/mustache/block-statements-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ module('mustache: block statements', function (hooks) {
test("multi-line mustaches can have array indexes with blocks", function (assert) {
const emblem = w(
'my-component [',
' value=child.[0] ]',
' value=child.[0]',
']',
' | Thing'
);

Expand Down
9 changes: 6 additions & 3 deletions tests/integration/mustache/handlebars-expressions-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,20 @@ module('mustache: handlebars expressions', function (hooks) {
});

test("in brackets", function (assert) {
const emblem = "p [\n id=id some-data=data.ok]\n";
const emblem = "p [\n id=id some-data=data.ok\n]\n";

assert.compilesTo(emblem, '<p id={{id}} some-data={{data.ok}}></p>');
});

test('brackets with empty lines', function (assert) {
const emblem = w('p [',
const emblem = w(
'p [',
' id=id',
' ',
'',
' some-data=data.ok]');
' some-data=data.ok',
']'
);

assert.compilesTo(emblem, '<p id={{id}} some-data={{data.ok}}></p>');
});
Expand Down
6 changes: 4 additions & 2 deletions tests/integration/mustache/html-attributes-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ module('mustache: html attributes', function (hooks) {
"div{did-insert this.handler} [",
' {on "input" @onInput}',
' ',
' class="test" ]',
' class="test"',
']'
);

assert.compilesTo(emblem, '<div {{did-insert this.handler}} {{on "input" @onInput}} class="test"></div>');
Expand Down Expand Up @@ -249,7 +250,8 @@ module('mustache: html attributes', function (hooks) {
"%some-new-tag{did-insert this.handler} [",
' {on "input" @onInput}',
' ',
' class="test" ]',
' class="test"',
']'
);

assert.compilesTo(emblem, '<some-new-tag {{did-insert this.handler}} {{on "input" @onInput}} class="test"></some-new-tag>');
Expand Down
Loading

0 comments on commit 727a885

Please sign in to comment.