UNPKG

litespeed.js

Version:

Lite & fast micro javascript framework that is easy to learn

201 lines (153 loc) 6.21 kB
/** * View * * Manage application scopes and different views */ window.ls.container.set('view', function(http, container) { let stock = {}; let execute = function(view, node, container) { container.set('element', node, true, false); container.resolve(view.controller); if(true !== view.repeat) { // Remove view that should not repeat itself node.removeAttribute(view.selector); } }; let parse = function (node, skip, callback) { if(node.tagName === 'SCRIPT') { return; } if(node.attributes && skip !== true) { let attrs = []; let attrsLen = node.attributes.length; for (let x = 0; x < attrsLen; x++) { attrs.push(node.attributes[x].nodeName); } if(1 !== node.nodeType) { // Skip text nodes return; } //console.log('in DOM?', document.body.contains(node), node, node.nodeType); if(attrs && attrsLen) { // Loop threw child attributes // if(node && node.parentNode && node.parentNode.replaceChild) { // Remove previous refs // console.info('Clean DOM Node (single)', node); // let new_element = node.cloneNode(true); // node.parentNode.replaceChild(new_element, node); // node = new_element; // console.info('empty node', node); // } for (let x = 0; x < attrsLen; x++) { if (node.$lsSkip === true) { // Stop render if comp has set $lsSkip break; } let pointer = (!/Edge/.test(navigator.userAgent)) ? x : (attrsLen -1) - x; let length = attrsLen; let attr = attrs[pointer]; if(!stock[attr]) { continue; // No such view component } let comp = stock[attr]; if (typeof comp.template === "function") { // If template is function and not string resolve it first comp.template = container.resolve(comp.template); } if(!comp.template) { // Execute with no template (function (comp, node, container) { execute(comp, node, container); })(comp, node, container); if(length !== attrsLen) { x--; } if(callback) { callback(); } continue; } node.classList.remove('load-end'); node.classList.add('load-start'); node.$lsSkip = true; // Load new view template http.get(comp.template) .then(function(node, comp) { return function(data){ node.$lsSkip = false; node.innerHTML = data; node.classList.remove('load-start'); node.classList.add('load-end'); (function (comp, node, container) { // Execute after template has been loaded execute(comp, node, container); })(comp, node, container); // re-render specific scope children after template is loaded parse(node, true); if(callback) { callback(); } } }(node, comp), function(error) { throw new Error('Failed to load comp template: ' + error.message); } ); } } } if(true === node.$lsSkip) { // ELEMENT told not to render child nodes return; } let list = (node) ? node.childNodes : []; if(node.$lsSkip === true) { list = []; } // Run on tree for (let i = 0; i < list.length; i++) { // Loop threw all DOM children let child = list[i]; parse(child); } }; return { stock: stock, /** * Add View * * Adds a new comp definition to application comp stack. * * @param object * @returns {add} */ add: function(object) { if(typeof object !== 'object') { throw new Error('object must be of type object'); } let defaults = { 'selector': '', 'controller': function () {}, 'template': '', 'repeat': false, 'protected': false }; for (let prop in defaults) { if (!defaults.hasOwnProperty(prop)) { continue; } if (prop in object) { continue; } object[prop] = defaults[prop]; } if(!object.selector) { throw new Error('View component is missing a selector attribute'); } stock[object.selector] = object; return this; }, /** * Render * * Render all view components in a given scope. * * @param element * @returns view */ render: function(element, callback) { parse(element, false, callback); element.dispatchEvent(new window.Event('rendered', {bubbles: false})); } } }, true, false);