diff --git a/ui/wolf.ui.js b/ui/wolf.ui.js index fb68514..2c71004 100644 --- a/ui/wolf.ui.js +++ b/ui/wolf.ui.js @@ -231,7 +231,9 @@ */ function loadLibrary(path) { UI.fetchFragment(path, dom => { - UI.readTemplate(dom); + UI.readTemplate(dom, null, { + + }); }); } @@ -273,7 +275,7 @@ * @param {*} ext ctor extended info */ function renderControlDOM(ext) { - var tux = ext.customController.render(); + var tux = ext.customController.build(); if (!tux) return []; if (!Array.isArray(tux)) @@ -380,12 +382,7 @@ controller.$init = function (template) { if (template.$ && template.$.length && !allowChildren) throw new Error("wolf:" + id + " does not allow child nodes"); - }; - controller.$ctor = function (template, ext) { - var parentCustom = ext.customController; - ext = {}.merge(ext); //Copy of ext instance - // Initialize attributes and script var values = getControlAttributesTable(controller, template); var API = { ui: (name, clone) => { @@ -404,19 +401,19 @@ return data; return null; }, - childs: name => ext.getChildNodes(name), + childs: name => { + //ID for usage on future with multiple chilnodes block definitions + return template.$; + }, global: controlGlobal, - parent: ext.parent, values: values, } var script = scriptFactory ? new scriptFactory(API, K, D, UI, TOOLS) : {}; API.controller = script; API.instanceTemplate = (templ, ext2) => UI.instanceTemplate(templ, ext2 ? ext2 : { parent: ext.parent, customController: script }) - if (!script.render) - script.render = () => { - for (var k in ui)//return first if any - return ui[k]; - throw new Error("wolf:" + id + " does not have ui defined"); + if (!script.build) + script.build = () => { + return ui[""]; } // Event mirror and attribute hook @@ -429,12 +426,23 @@ if (k.startsWith("event:") && !script["$" + k.substring(6)]) { script["$" + k.substring(6)] = function () { }; //Empty event } + template.$api = API; + template.$c = script; - ext.getChildNodes = function (id) { - //ID for usage on future with multiple chilnodes block definitions - return template.$; - } - ext.customController = script; + //TODO: Create control defined custom properties for attributes that change the attribute values + script.init && script.init(); + }; + + controller.$ctor = function (template, ext) { + var parentCustom = ext.customController; + ext = {}.merge(ext); //Copy of ext instance + // Initialize attributes and script + + var values = template.$api.values; + template.$api.parent = ext.parent; //TODO: Not here, thsi is shared between renderings of same template + + ext.getChildNodes = template.$api.childs; + ext.customController = template.$c; ext.parentCustom = parentCustom; //TODO: Replace with a local binding (bindings to values object only, creating a local model only for this control) // - access this local binding with {$name} @@ -467,9 +475,6 @@ } } } - //TODO: Create control defined custom properties for attributes that change the attribute values - script.init && script.init(); - // Generate DOM return renderControlDOM(ext); }; diff --git a/wolf.js b/wolf.js index 11357c1..238b491 100644 --- a/wolf.js +++ b/wolf.js @@ -751,10 +751,40 @@ /** * Template class */ - function Template() { - + function Template(type, attributes, childs) { + if (type) + this.$t = type; + if (attributes) + this.merge(attributes); + if (childs) + if (type) { + if (childs.push) + this.$ = childs; + else + this.$ = [childs]; + } else + this.$ = childs; } + Object.defineProperty(Template.prototype, "$set", { + value: function (attributeName, attributeValue) { + this[attributeName] = attributeValue; + return this; + } + }); + + Object.defineProperty(Template.prototype, "$add", { + value: function (child) { + if (this.$t) { + if (!this.$) + this.$ = []; + this.$.push(child); + } else + this.$ = child; + return this; + } + }); + /** Initializes an application, an application is only a definition of the container element in the document * and the url of the application controller, a single web page can contains several applications * @param {string} ctrlUrl url for the application controller @@ -834,7 +864,7 @@ throw new Error("wolf:repeat requires a child"); }, $ctor: template => { - var hook = document.createElement(template.$[0].type); + var hook = document.createElement(template.$[0].$t); setTimeout(() => { template.items.bindRepeater(hook.parentElement, hook.nextSibling, template.$); hook.parentElement.removeChild(hook);//Clear hook @@ -876,11 +906,7 @@ if (!(items instanceof D.Binding)) throw new Error("Only bindings can be used on xwolf:repeat"); delete template.repeat; - return { - $t: "wolf:repeat", - items: items, - $: [template] - }; + return new Template("wolf:repeat", { $w: wolfElements.repeat, items: items }, template); } }, @@ -1049,7 +1075,7 @@ if (path && path[0] == '/') return path; var base; - if (template.type == "#app" || (contextPath && contextPath[0] == "/")) + if (template.$t == "#app" || (contextPath && contextPath[0] == "/")) base = contextPath; else { base = element.getParent().getContextPath(); @@ -1210,17 +1236,26 @@ } /** * Process an element template and it's childs, preparing the logics and binding maps - * @param {element} element + * @param {*} node DOM node to read as template + * @param {*} parent parent template + * @param {*} tcontext template processing context (extended api for reading) + * @param {funciton} tcontext.readValue function for checking the value for templates */ - function readTemplate(node, parent) { + function readTemplate(node, parent, tcontext) { /** * @callback readTemplate_callback * @param {*} template template processed completely */ var templ = new Template(), initiators = []; + tcontext = tcontext || {};; function valOrBinding(val) { + if (tcontext.readValue) { + var v = tcontext.readValue(val); + if (v) + return v; + } if (typeof val === "string" && val.indexOf('{') >= 0) return new D.Binding(val); return val; @@ -1257,6 +1292,8 @@ var aval = valOrBinding(node.getAttribute(attr)); if ((aval instanceof D.Binding) && !attri.bindable) throw new Error(tagname + " attribute " + attr + " can not be binded"); + if (!(aval instanceof D.Binding) && attri.bindable == "mandatory") + throw new Error(tagname + " attribute " + attr + " should be binded"); templ[attr] = aval; }); for (var k in wdef) { @@ -1727,7 +1764,7 @@ result[i] = cloneTemplate(templ[i]); return result; } - var clone = {}.merge(templ); + var clone = new Template().merge(templ); // Does not clone events?? delete clone.$e; @@ -1771,6 +1808,7 @@ cloneTemplate: cloneTemplate, // queryTemplate: queryTemplate, DRAFT // hackTemplate: hackTemplate, DRAFT + Template: Template, } })();