diff --git a/ui/wolf.ui.js b/ui/wolf.ui.js index b3afd53..e46960e 100644 --- a/ui/wolf.ui.js +++ b/ui/wolf.ui.js @@ -190,51 +190,6 @@ } /** - * Creates the attribute handler that links the definition value/event links to the control usage template - * @param {*} ui List of UI templates defined in control usage - */ - function getTemplateAttributeHandler(ui) { - var attrlinks = {}; - function preHookAdd(id, value) { - var hl = attrlinks[id]; - if (!hl) - hl = attrlinks[id] = []; - hl.push(value); - } - function preHookUI(templ) { - if (templ.c) - templ.c.forEach(preHookUI); - if (templ.value && templ.value[0] == "$") - preHookAdd(templ.value, { t: templ }); - for (var k in templ.a) { - var attr = templ.a[k]; - if (attr && attr[0] == "$") - preHookAdd(attr, { t: templ, a: k }); - } - for (var k in templ.e) { - var event = templ.e[k]; - if (event && event[0] == "$") - preHookAdd(event, { t: templ, e: k }); - } - } - for (var k in ui) - ui[k].forEach(templ => { - preHookUI(templ); - }); - - function forEachOf(template, cb) { - for (var k in attrlinks) { - var alink = attrlinks[k]; - alink.forEach(alink => { - if (alink.t == template) - cb(k, alink); - }); - } - } - return { forEachOf: forEachOf }; - } - - /** * Generates the DOM of the control based on the script render method * @param {*} ext ctor extended info */ @@ -327,9 +282,6 @@ } } - // Preprocess hooks - var alinkHanlder = getTemplateAttributeHandler(ui); - // Controller logics controller.ctor = (template, ext) => { ext = {}.merge(ext); //Copy of ext instance @@ -361,56 +313,37 @@ script["$" + name] = eventProxy(values["event:" + name], name); } ext.customController = script; + ext.onInit = function (element, template) { + if (template.value && template.value[0] == "$") { + var data = values[template.value.substr(1)]; + if (data instanceof D.Binding) + data.bindExecutor(element, + null, + null, + read => n.nodeValue = read({ element: element }, "string") + ); + else + element.nodeValue = data; + } + for (var k in template.a) { + var attr = template.a[k]; + if (attr && attr[0] == "$") { + var data = values[attr.substr(1)]; + if (data instanceof D.Binding) + data.bindExecutor(element, + null, + null, + read => element.setAttribute(k, read({ element: element }, "string")) + ); + else + element.setAttribute(k, data); + } + } + } // Generate DOM var ux = renderControlDOM(ext); - // Scan generated nodes and set values or link bindings - // TODO: Workaround (use the new ext.onInit event for each control initialization) - function setValue(k, n, h) { - if (k && k[0] == "$") - k = k.substr(1); - var data = values[k]; - if (h.e) {// Hook to event - // if (!ext.parent) - // return; - // var pcontroller = ext.parent.getController(); - // if (!pcontroller) - // return; - // data = values["event:" + k]; - // if (!n.controlBase) - // n.controlBase = {}; - // n.controlBase[k] = pcontroller[data]; - } else if (h.a) // Hook to attribute - if (data instanceof D.Binding) - data.bindExecutor(n, - null, - null, - read => n.setAttribute(h.a, read({ element: n }, "string")) - ); - else - n.setAttribute(h.a, data); - else // Hook to text node - if (data instanceof D.Binding) - data.bindExecutor(n, - null, - null, - read => n.nodeValue = read({ element: n }, "string") - ); - else - n.nodeValue = data; - } - function scanDOM(node) { - node.controlBase = ext.parent; - for (var i = 0; i < node.childNodes.length; i++) - scanDOM(node.childNodes[i]); - alinkHanlder.forEachOf(node.getTemplate(), (k, alink) => { - setValue(k, node, alink); - }) - } - ux.forEach(node => scanDOM(node)); - - return ux; }; UI.registerElement(id, controller); diff --git a/wolf.js b/wolf.js index 05b0723..97d71f7 100644 --- a/wolf.js +++ b/wolf.js @@ -1070,57 +1070,63 @@ setContextPath: setContextPath, getContextPath: getContextPath, }); - return; - } - - element.merge({ - // Wolfed element API - getTemplate: getTemplate, - getController: getController, - getControllerElement: getControllerElement, - getApplication: getApplication, - getApplicationController: getApplicationController, - byId: byId, - getParent: getParent, - setContextPath: setContextPath, - getContextPath: getContextPath, - include: include, - }); - - // process standard attributes - for (var k in template.a) { - var value = template.a[k]; - if (value instanceof D.Binding) - value.bindElementAttribute(element, k); + // process text + if (template.value instanceof D.Binding) + template.value.bindTextNode(element); else - element.setAttribute(k, value); + element.nodeValue = template.value; + } else { + element.merge({ + // Wolfed element API + getTemplate: getTemplate, + getController: getController, + getControllerElement: getControllerElement, + getApplication: getApplication, + getApplicationController: getApplicationController, + byId: byId, + getParent: getParent, + setContextPath: setContextPath, + getContextPath: getContextPath, + include: include, + }); + + // process standard attributes + for (var k in template.a) { + var value = template.a[k]; + if (value instanceof D.Binding) + value.bindElementAttribute(element, k); + else + element.setAttribute(k, value); + } + // process wolf attributes + for (var k in template.w) { + var wattr = wolfAttributes[k]; + wattr.processor(element, template.w[k], template); + } + // process events + function installEvent(event, method) { + if (customController) + element.addEventListener(event, (evt) => { + var evtMethod = customController[method]; + if (!evtMethod) + throw new Error(`Method '${method}' not found for event '${k}' in custom controller.`); + evtMethod(element, evt); + }); + else + element.addEventListener(event, (evt) => { + var ctrl = element.getController(); + var evtMethod = ctrl[method]; + if (!evtMethod) + throw new Error(`Method '${method}' not found for event '${k}'.`); + evtMethod(element, evt); + }); + } + if (template.e) + for (var k in template.e) + installEvent(k, template.e[k]); } - // process wolf attributes - for (var k in template.w) { - var wattr = wolfAttributes[k]; - wattr.processor(element, template.w[k], template); - } - // process events - function installEvent(event, method) { - if (customController) - element.addEventListener(event, (evt) => { - var evtMethod = customController[method]; - if (!evtMethod) - throw new Error(`Method '${method}' not found for event '${k}' in custom controller.`); - evtMethod(element, evt); - }); - else - element.addEventListener(event, (evt) => { - var ctrl = element.getController(); - var evtMethod = ctrl[method]; - if (!evtMethod) - throw new Error(`Method '${method}' not found for event '${k}'.`); - evtMethod(element, evt); - }); - } - if (template.e) - for (var k in template.e) - installEvent(k, template.e[k]); + if (template.ctor) + template.ctor(element, template, ext); ext.onInit && ext.onInit(element, template); } @@ -1134,15 +1140,9 @@ */ function instanceTemplate(template, ext) { if (!template.type) { - var tnode = document.createTextNode(""); - processElement(tnode, template, ext); - if (template.value instanceof D.Binding) - template.value.bindTextNode(tnode); - else - tnode.nodeValue = template.value; - if (template.ctor) - template.ctor(tnode, template, ext); - return [tnode]; + var node = document.createTextNode(""); + processElement(node, template, ext); + return [node]; } else if (template.we) { return template.we.ctor(template, ext); } else if (template.type.substr(0, 5) == "wolf:") { @@ -1150,13 +1150,14 @@ } else { var node = document.createElement(template.type); processElement(node, template, ext); - for (var i in template.c) { - var nns = instanceTemplate(template.c[i], { parent: node }); - for (var j in nns) - node.appendChild(nns[j]); + if (template.c && template.c.length) { + var childExt = {}.merge(ext).merge({ parent: node }); + for (var i in template.c) { + var nns = instanceTemplate(template.c[i], childExt); + for (var j in nns) + node.appendChild(nns[j]); + } } - if (template.ctor) - template.ctor(node, template, ext); return [node]; } }