|
| 1 | +// Note that the first argument to instantiateTemplate was changed to |
| 2 | +// be the template itself, not its name, to make testing easier. |
| 3 | + |
| 4 | +function instantiateTemplate(template, values) { |
| 5 | + function instantiateText(text, values) { |
| 6 | + return text.replace(/\{\{(\w+)\}\}/g, function(_, name) { |
| 7 | + return values[name]; |
| 8 | + }); |
| 9 | + } |
| 10 | + function attr(node, attrName) { |
| 11 | + return node.nodeType == document.ELEMENT_NODE && |
| 12 | + node.getAttribute(attrName); |
| 13 | + } |
| 14 | + function instantiate(node, values) { |
| 15 | + if (node.nodeType == document.ELEMENT_NODE) { |
| 16 | + var copy = node.cloneNode(); |
| 17 | + for (var i = 0; i < node.childNodes.length; i++) { |
| 18 | + var child = node.childNodes[i]; |
| 19 | + |
| 20 | + var when = attr(child, "template-when"), unless = attr(child, "template-unless"); |
| 21 | + if (when && !values[when] || unless && values[unless]) |
| 22 | + continue; |
| 23 | + |
| 24 | + var repeat = attr(child, "template-repeat"); |
| 25 | + if (repeat) |
| 26 | + (values[repeat] || []).forEach(function(element) { |
| 27 | + copy.appendChild(instantiate(child, element)); |
| 28 | + }); |
| 29 | + else |
| 30 | + copy.appendChild(instantiate(child, values)); |
| 31 | + } |
| 32 | + return copy; |
| 33 | + } else if (node.nodeType == document.TEXT_NODE) { |
| 34 | + return document.createTextNode(instantiateText(node.nodeValue, values)); |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | + return instantiate(template, values); |
| 39 | +} |
| 40 | + |
| 41 | +// A simple test function to verify that the above actually works |
| 42 | + |
| 43 | +function test(template, values, expected) { |
| 44 | + var testTemplate = document.createElement("div"); |
| 45 | + testTemplate.innerHTML = template; |
| 46 | + var result = instantiateTemplate(testTemplate, values).innerHTML; |
| 47 | + if (result != expected) |
| 48 | + console.log("Unexpected instantiation. Expected\n " + expected + "\ngot\n " + result); |
| 49 | +} |
| 50 | + |
| 51 | +test('<h1 template-when="header">{{header}}</h1>', |
| 52 | + {header: "One"}, |
| 53 | + '<h1 template-when="header">One</h1>'); |
| 54 | + |
| 55 | +test('<h1 template-when="header">{{header}}</h1>', |
| 56 | + {header: false}, |
| 57 | + ''); |
| 58 | + |
| 59 | +test('<p><img src="icon.png" template-unless="noicon">Hello</p>', |
| 60 | + {noicon: true}, |
| 61 | + '<p>Hello</p>'); |
| 62 | + |
| 63 | +test('<ol><li template-repeat="items">{{name}}: {{score}}</li></ol>', |
| 64 | + {items: [{name: "Alice", score: "10"}, {name: "Bob", score: "7"}]}, |
| 65 | + '<ol><li template-repeat="items">Alice: 10</li><li template-repeat="items">Bob: 7</li></ol>'); |
0 commit comments