diff options
Diffstat (limited to 'tree/public/assets/js/vendor/view/OKTmplView.js')
| -rw-r--r-- | tree/public/assets/js/vendor/view/OKTmplView.js | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/tree/public/assets/js/vendor/view/OKTmplView.js b/tree/public/assets/js/vendor/view/OKTmplView.js new file mode 100644 index 0000000..86f1ee3 --- /dev/null +++ b/tree/public/assets/js/vendor/view/OKTmplView.js @@ -0,0 +1,97 @@ +/** + * An OK templating language I just made up + * + * Templates: + * <!-- Add data-ok-* attrs --> + * <span data-ok-msg></span + * + * Usage: + * // "Compile" + * var view = new OKTmplView('tmpl-id') + * // Attach to DOM before render + * document.body.appendChild(view.el) + * // Render to heart's content + * view.render(data) + */ +function OKTmplView (id) { + var $el = this.$el = $('#ok-' + id).children().clone() + var el = this.el = $el[0] + var pathMetas = reduceToPathMetas(el) + + this.render = function (data) { + data = data || {} + pathMetas.forEach(function (pathMeta) { + $el.find('[' + pathMeta.attr + ']').html( + getPath(data, pathMeta.path) + ) + }) + } + + this.hide = function () { + $el.hide() + } + + this.show = function () { + $el.show() + } + + function reduceToPathMetas (el) { + return flatten(next([el])) + + function next (children) { + return Array.prototype.slice.call(children) + .reduce(function (result, child) { + result.push(getPathMetas(child).concat(next(child.childNodes))) + return result + }, []) + } + + function getPathMetas (el) { + var attrs = Array.prototype.slice.call(el.attributes || []) + return attrs + .filter(specified) + .reduce(function (result, attrNode) { + if (/^data-ok-/.test(attrNode.nodeName)) { + result.push({ + attr: attrNode.nodeName, + path: attrNode.nodeName.split('-').slice(2), + }) + } + return result + }, []) + + function specified (attrNode) { + return typeof attrNode.specified === 'undefined' || + attrNode.specified + } + } + } +} + +/** + * Get value for key at path where path is an array of keys + */ +function getPath (obj, path) { + obj = obj || {} + path = path || [] + return path.reduce(function (obj, key, i) { + if (i < path.length - 1) + return obj[key] || {} + else + return obj[key] + }, obj) +} + +function flatten (list) { + var result = [] + next(list || []) + return result + + function next (list) { + list.forEach(function (item) { + return typeof item.length !== 'undefined' + ? next(item) + : result.push(item) + }) + } +} |
