Skip to content

Commit

Permalink
✨ Add support for ternary conditionals
Browse files Browse the repository at this point in the history
  • Loading branch information
skerit committed May 5, 2024
1 parent 9b9ca35 commit 6e085dc
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Clean up custom element `renderCustomTemplate` function
* Add initial reactive variable support
* Allow assigning an element to a reference using `:ref` syntax
* Add support for ternary conditionals

## 2.3.19 (2024-04-13)

Expand Down
11 changes: 11 additions & 0 deletions lib/expression/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,17 @@ Expression.setMethod(function getTokenValue(token, vars) {
result = this.getObjectLiteralValue(token.object, vars);
} else if (token.array) {
result = this.getArrayLiteralValue(token.array, vars);
} else if (token.condition) {

let condition_result = this.parseExpression(token.condition, vars);

if (this.isTruthy(condition_result)) {
if (token.truthy) {
result = this.parseExpression(token.truthy, vars);
}
} else if (token.falsy) {
result = this.parseExpression(token.falsy, vars);
}
} else if (Array.isArray(token)) {
result = this.parseExpression(token, vars);
}
Expand Down
55 changes: 50 additions & 5 deletions lib/parser/expressions_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ const IN_LITERAL = Symbol('literal'),
IN_ARGUMENTS = Symbol('arguments'),
IN_OPTIONS = Symbol('options'),
IN_PATH_EXPRESSION = Symbol('path_expression'),
IN_EACH_EXPRESSION = Symbol('each_expression');
IN_EACH_EXPRESSION = Symbol('each_expression'),
IN_CONDITIONAL_TRUE = Symbol('conditional_true'),
IN_CONDITIONAL_FALSE = Symbol('conditional_false');

/**
* Expressions parser class:
Expand Down Expand Up @@ -447,7 +449,7 @@ Eparser.setMethod(function getArguments() {
* @since 2.0.0
* @version 2.0.0
*
* @return {Object}
* @return {Object[]}
*/
Eparser.setMethod(function getArrayLiteral() {

Expand Down Expand Up @@ -507,7 +509,7 @@ Eparser.setMethod(function getArrayLiteral() {
* @since 2.0.0
* @version 2.0.0
*
* @return {Object}
* @return {Object[]}
*/
Eparser.setMethod(function getObjectLiteral() {

Expand Down Expand Up @@ -573,17 +575,41 @@ Eparser.setMethod(function getExpressionForEach() {
return this.getExpression(0, IN_EACH_EXPRESSION);
});

/**
* Get the conditional expression
*
* @author Jelle De Loecker <[email protected]>
* @since 2.4.0
* @version 2.4.0
*
* @param {Object|Array} condition
* @param {number} level
*
* @return {Object}
*/
Eparser.setMethod(function getConditionalExpression(condition, level) {

let truthy = this.getExpression(level, IN_CONDITIONAL_TRUE),
falsy = this.getExpression(level, IN_CONDITIONAL_FALSE);

return [{
condition,
truthy,
falsy
}];
});

/**
* Get expression
*
* @author Jelle De Loecker <[email protected]>
* @since 1.2.9
* @version 2.3.19
* @version 2.4.0
*
* @param {Number} level
* @param {Symbol} state Are we in some kind of literal ({}, [])
*
* @return {Object}
* @return {Object[]}
*/
Eparser.setMethod(function getExpression(level, state) {

Expand Down Expand Up @@ -622,6 +648,20 @@ Eparser.setMethod(function getExpression(level, state) {
prev = this.previous_token;
entry = result[result.length - 1];

// See if this is the start of a conditional ternary expression
if (token.value === '?') {
if (!entry) {
throw new Error('Unexpected `?` token');
}

// @TODO: make sure there is a colon somewhere?

this.goToNext();
let condition = result.pop();
push('conditional', this.getConditionalExpression(condition, level + 1));
continue;
}

// Get object literals
if (token.value == '{') {
this.goToNext();
Expand All @@ -640,6 +680,11 @@ Eparser.setMethod(function getExpression(level, state) {
break;
}

if (state == IN_CONDITIONAL_TRUE && token.value == ':') {
this.goToNext();
break;
}

if (token.value == '(') {

if (prev && !prev.keyword && entry) {
Expand Down
18 changes: 17 additions & 1 deletion test/10-expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ describe('Expressions', function() {
createTests(tests);
});

describe('Conditional', () => {

let tests = [
[
`{{ (c eq "a") ? "A" : "NO" }}`,
`NO`
],
[
`{{ (c eq "c") ? "C" : "NO" }}`,
`C`
]
];

createTests(tests);
});

describe('Switch', function() {

var tests = [
Expand Down Expand Up @@ -648,7 +664,7 @@ NO
var tests = [
[
`{% block "test" %}TESTING{% /block %}<he-block data-he-name="test"></he-block>`,
`<he-block data-he-name="test" data-hid="hserverside-0" data-he-template="test_174">TESTING</he-block>`
`<he-block data-he-name="test" data-hid="hserverside-0" data-he-template="test_176">TESTING</he-block>`
],
[
`€{% if true %}€<span>€</span>{% /if %}`,
Expand Down

0 comments on commit 6e085dc

Please sign in to comment.