UNPKG

@quenk/wml-runtime

Version:
267 lines 8.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var property = require("property-seek"); var Maybe_1 = require("afpl/lib/monad/Maybe"); ; /** * Component is an abstract Widget implementation * that can be used instead of manually implementing the whole interface. * */ var Component = (function () { /** * attrs is the attributes this Component excepts. */ /** * children is an array of content passed to this Component. */ function Component(attrs, children) { this.attrs = attrs; this.children = children; } Component.prototype.rendered = function () { }; Component.prototype.removed = function () { }; Component.prototype.render = function () { return this.view.render(); }; return Component; }()); exports.Component = Component; ; /** * read a value form an object. * * This is an alternative to regular property access that will throw exceptions * if any of the values in the part are null. * @param {string} path - The path to look up on the object. * @param {object} o - The object * @param {A} [defaultValue] - This value is returned if the value is not set. * @private */ exports.read = function (path, o, defaultValue) { var ret = property.get(path.split(':').join('.'), o); return (ret != null) ? ret : defaultValue; }; /** * @private */ var adopt = function (child, e) { switch (typeof child) { case 'string': case 'number': case 'boolean': e.appendChild(document.createTextNode('' + child)); case 'object': e.appendChild(child); break; default: throw new TypeError("Can not adopt child " + child + " of type " + typeof child); } }; /** * @private */ exports.box = function () { var content = []; for (var _i = 0; _i < arguments.length; _i++) { content[_i] = arguments[_i]; } var frag = document.createDocumentFragment(); content.forEach(function (c) { return frag.appendChild(c); }); return frag; }; /** * @private */ exports.domify = function (a) { if (a instanceof Array) { return exports.box.apply(null, a.map(exports.domify)); } else if ((typeof a === 'string') || (typeof a === 'number') || (typeof a === 'boolean')) { return exports.text(a); } else if (a instanceof Node) { return a; } else if (a == null) { return _empty; } else { throw new TypeError("Can not use '" + a + "'(typeof " + typeof a + ") as Content!"); } }; /** * @private */ var _empty = document.createDocumentFragment(); /** * @private */ exports.empty = function () { return _empty; }; /** * text creates a new TextNode. * @private */ exports.text = function (value) { return document.createTextNode('' + value); }; /** * node is called to create a regular DOM node * @private */ exports.node = function (tag, attributes, children, view) { var e = document.createElement(tag); if (typeof attributes['html'] === 'object') Object.keys(attributes['html']).forEach(function (key) { var value = attributes['html'][key]; if (typeof value === 'function') { e[key] = value; } else if (typeof value === 'string') { if (value !== '') e.setAttribute(key, value); } else if (typeof value === 'boolean') { e.setAttribute(key, "" + value); } }); children.forEach(function (c) { return adopt(c, e); }); var id = attributes['wml'].id; var group = attributes.wml.group; if (id) view.register(id, e); if (group) view.registerGroup(group, e); return e; }; /** * widget creates and renders a new wml widget instance. * @param {function} Construtor * @param {object} attributes * @param {array<string|number|Widget>} children * @param {View} view * @private * @return {Widget} */ exports.widget = function (Constructor, attributes, children, view) { var childs = []; var w; children.forEach(function (child) { return (child instanceof Array) ? childs.push.apply(childs, child) : childs.push(child); }); w = new Constructor(attributes, childs); var id = attributes.wml.id; var group = attributes.wml.group; if (id) view.register(id, w); if (group) view.registerGroup(group, w); view.widgets.push(w); return w.render(); }; /** * ifE provides an if then expression * @private */ exports.ifE = function (predicate, positive, negative) { return (predicate) ? positive() : negative(); }; /** * forE provides a for expression * @private */ exports.forE = function (collection, cb, cb2) { var frag = document.createDocumentFragment(); if (collection instanceof Array) { if (collection.length > 0) collection.forEach(function (v, k, a) { return frag.appendChild(cb(v, k, a)); }); else frag.appendChild(cb2()); } else if (typeof collection === 'object') { var l = Object.keys(collection); if (l.length > 0) l.forEach(function (k) { return frag.appendChild(cb(collection[k], k, collection)); }); else frag.appendChild(cb2()); } return frag; }; /** * switchE simulates a switch statement * @param {string|number|boolean} value * @param {object} cases * @private */ exports.switchE = function (value, cases) { var result = cases[value]; var defaul = cases['default']; if (result) return result; if (defaul) return defaul; }; /** * AppView is the concrete implementation of a View. * * @property {<C>} context - The context the view is rendered in. */ var AppView = (function () { function AppView(context) { this.context = context; this.ids = {}; this.groups = {}; this.widgets = []; } AppView.prototype.register = function (id, w) { if (this.ids.hasOwnProperty(id)) throw new Error("Duplicate id '" + id + "' detected!"); this.ids[id] = w; return this; }; AppView.prototype.registerGroup = function (group, e) { this.groups[group] = this.groups[group] || []; this.groups[group].push(e); return this; }; AppView.prototype.findById = function (id) { return Maybe_1.Maybe.fromAny(this.ids[id]); }; AppView.prototype.findGroupByName = function (name) { return Maybe_1.Maybe.fromArray(this.groups[name]); }; AppView.prototype.invalidate = function () { var childs; var realFirstChild; var realFirstChildIndex; var tree = (this._fragRoot) ? this._fragRoot : this.tree; var parent = tree.parentNode; if (tree == null) throw new ReferenceError('Cannot invalidate a view that has not been rendered!'); if (tree.parentNode == null) throw new ReferenceError('Attempt to invalidate a view that has not been inserted to DOM!'); childs = tree.parentNode.children; //for some reason the reference stored does not have the correct parent node. //we do this to get a 'live' version of the node. for (var i = 0; i < childs.length; i++) if (childs[i] === tree) { realFirstChild = childs[i]; realFirstChildIndex = i; } parent.replaceChild(this.render(), realFirstChild); }; AppView.prototype.render = function () { this.ids = {}; this.widgets.forEach(function (w) { return w.removed(); }); this.widgets = []; this._fragRoot = null; this.tree = this.template(this, this.context); this.ids['root'] = (this.ids['root']) ? this.ids['root'] : this.tree; if (this.tree.nodeName === (document.createDocumentFragment()).nodeName) this._fragRoot = this.tree.firstChild; this.widgets.forEach(function (w) { return w.rendered(); }); return this.tree; }; return AppView; }()); exports.AppView = AppView; //# sourceMappingURL=index.js.map