Skip to content

Commit

Permalink
add support for tag params using pipe syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
mlrawlings committed Jan 14, 2019
1 parent 4b67d58 commit 801c0c9
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 21 deletions.
119 changes: 99 additions & 20 deletions Parser.js
Expand Up @@ -94,6 +94,7 @@ const CODE_PERIOD = 46;
const CODE_COMMA = 44;
const CODE_SEMICOLON = 59;
const CODE_NUMBER_SIGN = 35;
const CODE_PIPE = 124;

const BODY_PARSED_TEXT = 1; // Body of a tag is treated as text, but placeholders will be parsed
const BODY_STATIC_TEXT = 2;// Body of a tag is treated as text and placeholders will *not* be parsed
Expand Down Expand Up @@ -381,6 +382,7 @@ class Parser extends BaseParser {
tagNameParts: null,
attributes: [],
argument: undefined,
params: undefined,
pos: parser.pos,
indent: indent,
nestedIndent: null, // This will get set when we know what hte nested indent is
Expand Down Expand Up @@ -1615,25 +1617,9 @@ class Parser extends BaseParser {
eol: openTagEOL,

eof: openTagEOF,

expression(expression) {
var argument = getAndRemoveArgument(expression);

if (argument) {
// The tag has an argument that we need to slice off

if (currentOpenTag.argument != null) {
notifyError(expression.endPos,
'ILLEGAL_TAG_ARGUMENT',
'A tag can only have one argument');
}

currentOpenTag.argument = argument;
currentOpenTag.tagNameEnd = expression.pos + expression.lastLeftParenPos + 1;
} else {
currentOpenTag.tagNameEnd = expression.endPos;
}

currentOpenTag.tagNameEnd = expression.endPos;

if (expression.value) {
currentOpenTag.tagName += expression.value;
Expand Down Expand Up @@ -1669,6 +1655,67 @@ class Parser extends BaseParser {
}
});

var STATE_TAG_ARGS = Parser.createState({
name: 'STATE_TAG_ARGS',

eol: openTagEOL,

eof: openTagEOF,

expression(expression) {
var value = expression.value;
if (value.charCodeAt(value.length-1) !== CODE_CLOSE_PAREN) {
throw new Error('Invalid argument')
}
expression.value = value.slice(1, value.length-1);
expression.pos += 1;
expression.endPos -= 1;
currentOpenTag.argument = expression;

if (parser.lookAtCharCodeAhead(1) === CODE_PIPE) {
parser.enterState(STATE_TAG_PARAMS);
} else {
parser.enterState(STATE_WITHIN_OPEN_TAG);
}
},

enter(oldState) {
if (oldState !== STATE_EXPRESSION) {
beginExpression();
}
},

char(ch, code) {
throw new Error('Illegal state');
}
});

var STATE_TAG_PARAMS = Parser.createState({
name: 'STATE_TAG_PARAMS',

eol: openTagEOL,

eof: openTagEOF,

expression(expression) {
var value = expression.value;
expression.value = value.slice(1);
expression.pos += 1;
currentOpenTag.params = expression;
parser.enterState(STATE_WITHIN_OPEN_TAG);
},

enter(oldState) {
if (oldState !== STATE_EXPRESSION) {
beginExpression();
}
},

char(ch, code) {
throw new Error('Illegal state');
}
});



// We enter STATE_CDATA after we see "<![CDATA["
Expand Down Expand Up @@ -2086,7 +2133,7 @@ class Parser extends BaseParser {

return notifyError(currentPart.pos,
'INVALID_EXPRESSION',
'EOF reached will parsing expression');
'EOF reached while parsing expression');
}
},

Expand Down Expand Up @@ -2145,6 +2192,16 @@ class Parser extends BaseParser {
}
return;
}
} else if (code === CODE_PIPE && parentState === STATE_TAG_PARAMS) {
if (depth === 0) {
currentPart.groupStack.push(code);
currentPart.isStringLiteral = false;
currentPart.value += ch;
return
} else if (depth === 1) {
endExpression();
return;
}
} else if (code === CODE_OPEN_PAREN ||
code === CODE_OPEN_SQUARE_BRACKET ||
code === CODE_OPEN_CURLY_BRACE) {
Expand Down Expand Up @@ -2199,7 +2256,10 @@ class Parser extends BaseParser {
if (currentPart.groupStack.length === 0) {
if (code === CODE_CLOSE_PAREN) {
currentPart.lastRightParenPos = currentPart.value.length - 1;
} else if (code === CODE_CLOSE_CURLY_BRACE && parentState === STATE_PLACEHOLDER) {
}
var endPlaceholder = code === CODE_CLOSE_CURLY_BRACE && parentState === STATE_PLACEHOLDER;
var endTagArgs = code === CODE_CLOSE_PAREN && parentState === STATE_TAG_ARGS;
if (endPlaceholder || endTagArgs) {
currentPart.endPos = parser.pos + 1;
endExpression();
return;
Expand Down Expand Up @@ -2360,6 +2420,15 @@ class Parser extends BaseParser {
}
}

if (currentPart.parentState === STATE_TAG_PARAMS) {
if (code === CODE_PIPE) {
endExpression();
parser.rewind(1);
parser.enterState(STATE_TAG_PARAMS);
return;
}
}

if (currentPart.parentState === STATE_TAG_NAME) {
if (checkForEscapedEscapedPlaceholder(ch, code)) {
currentPart.value += '\\';
Expand All @@ -2380,6 +2449,16 @@ class Parser extends BaseParser {
parser.rewind(1);
beginTagNameShorthand();
return;
} else if (parser.lookAtCharCodeAhead(1) === CODE_OPEN_PAREN) {
currentPart.value += ch;
endExpression();
parser.enterState(STATE_TAG_ARGS);
return;
} else if (code === CODE_PIPE) {
endExpression();
parser.rewind(1);
parser.enterState(STATE_TAG_PARAMS);
return;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions notify-util.js
Expand Up @@ -112,6 +112,7 @@ exports.createNotifiers = function(parser, listeners) {
tagNameExpression: tagInfo.tagNameExpression,
emptyTagName: tagInfo.emptyTagName,
argument: tagInfo.argument,
params: tagInfo.params,
pos: tagInfo.pos,
endPos: tagInfo.endPos,
tagNameEndPos: tagInfo.tagNameEndPos,
Expand Down
2 changes: 1 addition & 1 deletion test/autotest/attr-name-with-html-chars/input.htmljs
@@ -1 +1 @@
| <span>hello frank</span>
tagname <span>hello frank</span>
2 changes: 2 additions & 0 deletions test/autotest/param-tag/expected.html
@@ -0,0 +1,2 @@
<for|x, y, { destrucure=default }| of=array>
</for>
1 change: 1 addition & 0 deletions test/autotest/param-tag/input.htmljs
@@ -0,0 +1 @@
<for|x, y, { destrucure=default }| of=array></for>
5 changes: 5 additions & 0 deletions test/util/TreeBuilder.js
Expand Up @@ -115,6 +115,7 @@ class ElementNode {
var tagName = event.tagName;
var tagNameExpression = event.tagNameExpression;
var argument = event.argument;
var params = event.params;
var attributes = event.attributes;
var openTagOnly = event.openTagOnly === true;
var selfClosed = event.selfClosed === true;
Expand All @@ -129,6 +130,10 @@ class ElementNode {
str += '(' + argument.value + ')';
}

if (params) {
str += '|' + params.value + '|';
}

if (out.includePositions) {
str += ':' + event.pos;
}
Expand Down

0 comments on commit 801c0c9

Please sign in to comment.