| Index: LayoutTests/imported/web-platform-tests/html/syntax/parsing/template.js
|
| diff --git a/LayoutTests/imported/web-platform-tests/html/syntax/parsing/template.js b/LayoutTests/imported/web-platform-tests/html/syntax/parsing/template.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b249fb64c71c16f1b6cefcc59668699f769a2341
|
| --- /dev/null
|
| +++ b/LayoutTests/imported/web-platform-tests/html/syntax/parsing/template.js
|
| @@ -0,0 +1,214 @@
|
| + /*
|
| + * Template code
|
| + *
|
| + * A template is just a javascript structure. An element is represented as:
|
| + *
|
| + * [tag_name, {attr_name:attr_value}, child1, child2]
|
| + *
|
| + * the children can either be strings (which act like text nodes), other templates or
|
| + * functions (see below)
|
| + *
|
| + * A text node is represented as
|
| + *
|
| + * ["{text}", value]
|
| + *
|
| + * String values have a simple substitution syntax; ${foo} represents a variable foo.
|
| + *
|
| + * It is possible to embed logic in templates by using a function in a place where a
|
| + * node would usually go. The function must either return part of a template or null.
|
| + *
|
| + * In cases where a set of nodes are required as output rather than a single node
|
| + * with children it is possible to just use a list
|
| + * [node1, node2, node3]
|
| + *
|
| + * Usage:
|
| + *
|
| + * render(template, substitutions) - take a template and an object mapping
|
| + * variable names to parameters and return either a DOM node or a list of DOM nodes
|
| + *
|
| + * substitute(template, substitutions) - take a template and variable mapping object,
|
| + * make the variable substitutions and return the substituted template
|
| + *
|
| + */
|
| +
|
| + function is_single_node(template)
|
| + {
|
| + return typeof template[0] === "string";
|
| + }
|
| +
|
| + function substitute(template, substitutions)
|
| + {
|
| + if (typeof template === "function") {
|
| + var replacement = template(substitutions);
|
| + if (replacement)
|
| + {
|
| + var rv = substitute(replacement, substitutions);
|
| + return rv;
|
| + }
|
| + else
|
| + {
|
| + return null;
|
| + }
|
| + }
|
| + else if (is_single_node(template))
|
| + {
|
| + return substitute_single(template, substitutions);
|
| + }
|
| + else
|
| + {
|
| + return filter(map(template, function(x) {
|
| + return substitute(x, substitutions);
|
| + }), function(x) {return x !== null;});
|
| + }
|
| + }
|
| + expose(substitute, "template.substitute");
|
| +
|
| + function substitute_single(template, substitutions)
|
| + {
|
| + var substitution_re = /\${([^ }]*)}/g;
|
| +
|
| + function do_substitution(input) {
|
| + var components = input.split(substitution_re);
|
| + var rv = [];
|
| + for (var i=0; i<components.length; i+=2)
|
| + {
|
| + rv.push(components[i]);
|
| + if (components[i+1])
|
| + {
|
| + rv.push(substitutions[components[i+1]]);
|
| + }
|
| + }
|
| + return rv;
|
| + }
|
| +
|
| + var rv = [];
|
| + rv.push(do_substitution(String(template[0])).join(""));
|
| +
|
| + if (template[0] === "{text}") {
|
| + substitute_children(template.slice(1), rv);
|
| + } else {
|
| + substitute_attrs(template[1], rv);
|
| + substitute_children(template.slice(2), rv);
|
| + }
|
| +
|
| + function substitute_attrs(attrs, rv)
|
| + {
|
| + rv[1] = {};
|
| + for (name in template[1])
|
| + {
|
| + if (attrs.hasOwnProperty(name))
|
| + {
|
| + var new_name = do_substitution(name).join("");
|
| + var new_value = do_substitution(attrs[name]).join("");
|
| + rv[1][new_name] = new_value;
|
| + };
|
| + }
|
| + }
|
| +
|
| + function substitute_children(children, rv)
|
| + {
|
| + for (var i=0; i<children.length; i++)
|
| + {
|
| + if (children[i] instanceof Object) {
|
| + var replacement = substitute(children[i], substitutions);
|
| + if (replacement !== null)
|
| + {
|
| + if (is_single_node(replacement))
|
| + {
|
| + rv.push(replacement);
|
| + }
|
| + else
|
| + {
|
| + extend(rv, replacement);
|
| + }
|
| + }
|
| + }
|
| + else
|
| + {
|
| + extend(rv, do_substitution(String(children[i])));
|
| + }
|
| + }
|
| + return rv;
|
| + }
|
| +
|
| + return rv;
|
| + }
|
| +
|
| + function make_dom_single(template)
|
| + {
|
| + if (template[0] === "{text}")
|
| + {
|
| + var element = document.createTextNode("");
|
| + for (var i=1; i<template.length; i++)
|
| + {
|
| + element.data += template[i];
|
| + }
|
| + }
|
| + else
|
| + {
|
| + var element = document.createElement(template[0]);
|
| + for (name in template[1]) {
|
| + if (template[1].hasOwnProperty(name))
|
| + {
|
| + element.setAttribute(name, template[1][name]);
|
| + }
|
| + }
|
| + for (var i=2; i<template.length; i++)
|
| + {
|
| + if (template[i] instanceof Object)
|
| + {
|
| + var sub_element = make_dom(template[i]);
|
| + element.appendChild(sub_element);
|
| + }
|
| + else
|
| + {
|
| + var text_node = document.createTextNode(template[i]);
|
| + element.appendChild(text_node);
|
| + }
|
| + }
|
| + }
|
| +
|
| + return element;
|
| + }
|
| +
|
| +
|
| +
|
| + function make_dom(template, substitutions)
|
| + {
|
| + if (is_single_node(template))
|
| + {
|
| + return make_dom_single(template);
|
| + }
|
| + else
|
| + {
|
| + return map(template, function(x) {
|
| + return make_dom_single(x);
|
| + });
|
| + }
|
| + }
|
| +
|
| + function render(template, substitutions)
|
| + {
|
| + return make_dom(substitute(template, substitutions));
|
| + }
|
| + expose(render, "template.render");
|
| +
|
| +function expose(object, name)
|
| +{
|
| + var components = name.split(".");
|
| + var target = window;
|
| + for (var i=0; i<components.length - 1; i++)
|
| + {
|
| + if (!(components[i] in target))
|
| + {
|
| + target[components[i]] = {};
|
| + }
|
| + target = target[components[i]];
|
| + }
|
| + target[components[components.length - 1]] = object;
|
| +}
|
| +
|
| +function extend(array, items)
|
| +{
|
| + Array.prototype.push.apply(array, items);
|
| +}
|
|
|