Skip to content

Commit 94f392d

Browse files
swjainjknack
authored andcommitted
Fixed issues #656 & #657 (#658)
* Fixing grammar for ID token to accept unicode ctrl characters in the range of \u0001 - \u001F * Adding support for russian character set * Fixed #657 to support registration of helpers written in ES6's const/let syntax * Fixing CompositeTemplateLoaderTest.resolveSourceAtFs() to not fail on windows because of path separator '\' * Fixing checkstyle errors
1 parent 3b702a4 commit 94f392d

6 files changed

Lines changed: 80 additions & 4 deletions

File tree

handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsLexer.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ ID
333333
fragment
334334
ID_START
335335
:
336-
[a-zA-Z_$@:\u00C0-\u00FF]
336+
[a-zA-ZА-Яа-я_$@:\u0001-\u001E\u00C0-\u00FF]
337337
;
338338
339339
fragment

handlebars/src/main/java/com/github/jknack/handlebars/helper/DefaultHelperRegistry.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import java.util.HashSet;
3636
import java.util.Map;
3737
import java.util.Map.Entry;
38+
import java.util.regex.Matcher;
39+
import java.util.regex.Pattern;
3840
import java.util.Set;
3941

4042
import org.slf4j.Logger;
@@ -88,6 +90,9 @@ public class DefaultHelperRegistry implements HelperRegistry {
8890
/** Engine. */
8991
private ScriptEngine engine;
9092

93+
/** ES6's let/const declaration Pattern. */
94+
private Pattern es6VarPattern = Pattern.compile("(?:^|[\\s(;])(let|const)\\s+");
95+
9196
{
9297
// make sure default helpers are registered
9398
registerBuiltinsHelpers(this);
@@ -186,7 +191,7 @@ public HelperRegistry registerHelpers(final String filename, final String source
186191
notNull(filename, "The filename is required.");
187192
notEmpty(source, "The source is required.");
188193
ScriptEngine engine = engine();
189-
Throwing.run(() -> engine.eval(source));
194+
Throwing.run(() -> engine.eval(adaptES6Literals(source)));
190195
return this;
191196
}
192197

@@ -195,6 +200,25 @@ public Set<Entry<String, Helper<?>>> helpers() {
195200
return this.helpers.entrySet();
196201
}
197202

203+
/**
204+
* Since nashorn doesn't yet supports the ES6's "const" or "let" literals.
205+
* This method adapts the given helper source written in ES6 to work
206+
* with nashorn (by converting let/const to var).
207+
*
208+
* @param source the helper source.
209+
* @return the adapted helper source.
210+
**/
211+
private String adaptES6Literals(final String source) {
212+
Matcher m = es6VarPattern.matcher(source);
213+
StringBuffer sb = new StringBuffer();
214+
while (m.find()) {
215+
StringBuffer buf = new StringBuffer(m.group());
216+
buf.replace(m.start(1) - m.start(), m.end(1) - m.start(), "var");
217+
m.appendReplacement(sb, buf.toString());
218+
}
219+
return m.appendTail(sb).toString();
220+
}
221+
198222
/**
199223
* <p>
200224
* Register all the helper methods for the given helper source.

handlebars/src/test/java/com/github/jknack/handlebars/internal/HbsParserTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ public class HbsParserTest {
1414
public void hello() {
1515
parse("Hello {{who}}\n!");
1616
}
17+
18+
@Test
19+
public void subExpr() {
20+
// below expression has unicode char with value: \u0001
21+
parse("{{datawithCtrlChar}}");
22+
}
1723

1824
@Test
1925
public void rawblock() {

handlebars/src/test/java/com/github/jknack/handlebars/io/CompositeTemplateLoaderTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ public void sourceAtFs() throws IOException {
7979

8080
@Test
8181
public void resolveSourceAtFs() throws IOException {
82-
assertEquals(new File("src/test/resources/inheritance", "home.hbs").getPath(),
83-
loader.resolve("home"));
82+
assertTrue(new File("src/test/resources/inheritance", "home.hbs").getPath()
83+
.compareTo(new File(loader.resolve("home")).getPath()) == 0
84+
);
8485
}
8586

8687
@Test(expected = UnsupportedOperationException.class)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.github.jknack.handlebars.issues;
2+
3+
import java.io.File;
4+
5+
import org.junit.Test;
6+
7+
import com.github.jknack.handlebars.AbstractTest;
8+
import com.github.jknack.handlebars.Handlebars;
9+
10+
/**
11+
* https://github.com/jknack/handlebars.java/issues/657
12+
**/
13+
public class Issue657 extends AbstractTest {
14+
15+
@Override
16+
protected void configure(final Handlebars handlebars) {
17+
18+
try {
19+
handlebars.registerHelpers(new File("src/test/resources/issue657.js"));
20+
} catch (Exception ex) {
21+
throw new IllegalStateException(ex);
22+
}
23+
24+
}
25+
26+
@Test
27+
public void shouldAllowES6LetOrConstLiterals() throws Exception {
28+
29+
shouldCompileTo("{{#and great magnificent}}Hello 657{{/and}}",
30+
$("great", true, "magnificent", true),
31+
"Hello 657");
32+
}
33+
34+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Handlebars.registerHelper('and', function () {
2+
const len = arguments.length - 1;
3+
const options = arguments[len];
4+
let val = true;
5+
for (let i = 0; i < len; i++) {
6+
if(!val)
7+
break;
8+
val = val && arguments[i];
9+
}
10+
return val ? options.fn(context) : options.inverse(context);
11+
});

0 commit comments

Comments
 (0)