Skip to content

Commit

Permalink
Allow for simple JSON data in templates. Fixes #428.
Browse files Browse the repository at this point in the history
  • Loading branch information
wkeese committed Sep 16, 2015
1 parent e526945 commit 24e48a3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 13 deletions.
28 changes: 15 additions & 13 deletions handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,30 +49,32 @@ define(["./Template", "require", "requirejs-dplugins/Promise!"], function (Templ
* @returns {string} like "'hello' + this.foo + 'world'"
*/
function toJs(text, convertUndefinedToBlank) {
var inVar, parts = [];
var pos = 0, length = text.length, insideBraces = false, parts = [];

(text || "").split(/({{|}})/).forEach(function (str) {
if (str === "{{") {
inVar = true;
} else if (str === "}}") {
inVar = false;
} else if (inVar) {
// it's a property or a JS expression
while (pos < length) {
var bracesIndex = text.indexOf(insideBraces ? "}}" : "{{", pos),
str = text.substring(pos, bracesIndex === -1 ? length : bracesIndex);
if (insideBraces) {
// str is a property name or a JS expression.
var prop = str.trim();
if (/this\./.test(prop)) {
// JS expression (ex: this.selectionMode === "multiple")
parts.push("(" + str + ")");
parts.push("(" + prop + ")");
} else {
// Property (ex: selectionMode) or path (ex: item.foo)
parts.push(convertUndefinedToBlank ? "(this." + prop + "== null ? '' : this." + prop + ")" :
"this." + prop);
}
} else if (str) {
} else {
// string literal, single quote it and escape special characters
parts.push("'" +
str.replace(/(['\\])/g, "\\$1").replace(/\n/g, "\\n").replace(/\t/g, "\\t") + "'");
if (str) {
parts.push("'" +
str.replace(/(['\\])/g, "\\$1").replace(/\n/g, "\\n").replace(/\t/g, "\\t") + "'");
}
}
});
pos = bracesIndex === -1 ? length : bracesIndex + 2;
insideBraces = !insideBraces;
}

return parts.join(" + ");
}
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,20 @@ define([
assert.strictEqual(myList.firstChild.getAttribute("foo"), "a.b('c,d')", "single quotes prop");
assert.strictEqual(myList.firstChild.getAttribute("bar"), "\\\"hello\"", "double quotes, backslash prop");
assert.strictEqual(myList.firstChild.textContent, "\"\\bill'\\\n\twas \n\there'", "node text");

// Also check that a template can contain JSON (even though it's probably not a good idea).
// The }} should have no effect since there's no {{.
var TestJson = register("handlebars-json", [HTMLElement, Widget], {
template: handlebars.compile(
"<template>" +
"<div attr=\"{name: {first: 'john', last: 'doe'}}\"></div>" +
"<span>hello</span>" +
"</template>")
});
var myJson = new TestJson();

assert.strictEqual(myJson.children[0].getAttribute("attr"), "{name: {first: 'john', last: 'doe'}}", "json");
assert.strictEqual(myJson.children[1].textContent, "hello", "parsing after json");
},

"attach-event": {
Expand Down

0 comments on commit 24e48a3

Please sign in to comment.