diff --git a/src/Ast/index.js b/src/Ast/index.js index 3afe11a..f328440 100644 --- a/src/Ast/index.js +++ b/src/Ast/index.js @@ -39,7 +39,7 @@ const singleLineComment = /({{--.*?--}})/g class Ast { constructor (tags, template) { this._tags = tags - this._blockExpression = new RegExp(`^\\s*\\@(${_.keys(tags).join('|')})(?:\\((.*)\\))?`) + this._blockExpression = new RegExp(`^\\s*\\@(!?)(${_.keys(tags).join('|')})(?:\\((.*)\\))?`) this._template = template this._ast = [] this._insideBlockComment = false @@ -55,15 +55,17 @@ class Ast { * @param {String} tag * @param {String} args * @param {Number} index + * @param {Boolean} selfClosing * * @return {Object} * * @private */ - _tokenForTag (line, tag, args, index) { + _tokenForTag (line, tag, args, index, selfClosing) { return { tag, args, + selfClosing, childs: [], body: line, lineno: index + 1, @@ -117,9 +119,9 @@ class Ast { /** * Look for opening of a custom tag. */ - const [, tag, args] = this._blockExpression.exec(line) || [] + const [, selfClosing, tag, args] = this._blockExpression.exec(line) || [] if (tag) { - return this._tokenForTag(line, tag, args, index) + return this._tokenForTag(line, tag, args, index, !!selfClosing) } /** @@ -245,7 +247,7 @@ class Ast { * then we need to push it to list of opened tags and wait * for it to close. */ - if (token.tag && (token.tag === 'comment' || this._tags[token.tag].isBlock === true)) { + if (token.tag && this._tags[token.tag].isBlock === true && !token.selfClosing) { this._openedTags.push(token) } diff --git a/test/unit/ast.spec.js b/test/unit/ast.spec.js index 4b0d734..855a7b7 100644 --- a/test/unit/ast.spec.js +++ b/test/unit/ast.spec.js @@ -242,4 +242,25 @@ test.group('Template Compiler', (group) => { assert.lengthOf(ast[0].childs[1].childs, 1) assert.equal(ast[0].childs[2].body.trim(), '') }) + + test('should be able to define self closing block tags', (assert) => { + const statement = ` + @!yield('foo') + ` + const tags = { + yield: { + name: 'yield', + isBlock: true, + fn: function () {} + } + } + + const ast = new Ast(tags, statement).parse() + assert.equal(ast[0].tag, 'yield') + assert.deepEqual(ast[0].childs, []) + assert.equal(ast[0].args, `'foo'`) + assert.equal(ast[0].lineno, 1) + assert.equal(ast[0].selfClosing, true) + assert.equal(ast[0].body, `@!yield('foo')`) + }) })