wigjs
Version:
Minimalistic, scalable, extensible, dependency-less Front-end factory for HTML5 applications
4 lines • 13.8 kB
JavaScript
/**
* wig - 0.2.1
*/
!function(a,b){"function"==typeof define&&define.amd?define(function(){return a.wig=b({})}):"object"==typeof exports?module.exports=b({}):a.wig=b({})}(this,function(a){function b(a){var b,c,d=Array.prototype.slice.call(arguments,1),e=d.length;for(c=0;e>c;c+=1)if(d[c]&&"object"==typeof d[c])for(b in d[c])a[b]=d[c][b];return a}function c(a,b){return b.appendChild(a.getNode()),d.viewHelper.paint(a),d.viewHelper.notifyAttach(a),a}var d=a.env={},e=a.Class=function(){};e.extend=function(a,c){var d,e=this,f=Object.create(e.prototype);return d=a&&a.hasOwnProperty("constructor")?a.constructor:function(){e.apply(this,arguments)},b(f,a),b(d,c),d.extend=e.extend,d.prototype=f,d.prototype.constructor=d,d},b(d,{getElement:function(a,b){return b?a.querySelector(b):a},getFocusedElement:function(){return document.activeElement},compile:function(a,b){return d.compiler.compile(a,b)}});var f=a.module={},g=0,h=function(){},i="wig_view_id",j="data-"+i,k=Array.prototype.indexOf;d.DATA_ATTRIBUTE=i;var l=f.Compiler=e.extend({start:"{{",end:"}}",constructor:function(){this.templateCache=new o,this.regExp=new RegExp(this.start+"\\s*[\\w\\d\\.]+\\s*"+this.end,"gim")},replacer:function(a,b){var c=b[a[0]],d=a.length,e=b,f=0;if(d>1){for(;e&&d>f;)e=e[a[f++]];c=e}return c},compilerMethodFactory:function(a){var b=a.substring(this.start.length,a.length-this.end.length);return b=b.trim().split("."),this.replacer.bind(this,b)},generateCompiledResult:function(a){var b,c,d=a.match(this.regExp),e=0;if(d){for(b=a.split(this.regExp),c=[];d.length>0;)c.push(b[e],this.compilerMethodFactory(d.shift())),e+=1;c.push(b[e]),this.templateCache.set(a,c)}return this.templateCache.get(a)||a},compile:function(a,b){var c,d,e,f=this.templateCache.get(a),g="";if(f||(f=this.generateCompiledResult(a)),b&&"object"==typeof b)for(d=0,e=f.length;e>d;d++)c=f[d],g+="function"==typeof c?c(b):c;return g},getCompiled:function(a){return this.templateCache.get(a)},disposeMarkups:function(){this.templateCache.empty()}}),m=f.DOM=e.extend({initNode:function(a,c,d,e){var f,g=c;if(b(a,d),b(a.dataset,e),Array.isArray(c))g=c.join(" ");else if(c&&"object"==typeof c){g=[];for(f in c)c.hasOwnProperty(f)&&c[f]&&g.push(f);g=g.join(" ")}return g&&(a.className=g),a},findClosestViewNode:function(a,b){var c;do{if(c=a.getAttribute(b),null!=c)return c;a=a.parentNode}while(a!==document)},attachNodeToParent:function(a,b,c){"number"==typeof c?b.insertBefore(a,b.children[c]):b.appendChild(a)}}),n=f.Insurer=a.Class.extend({is:{notDefined:function(a,b){if("undefined"==typeof a||null===a)throw new TypeError(b||"Argument is not defined!")},defined:function(a,b){if("undefined"!=typeof a||null===a)throw new TypeError(b||"Argument is defined (not null and not undefined)!")}},exists:{object:function(a,b){if(null==a||"object"!=typeof a)throw new TypeError(b||"Argument must be a function!")}}}),o=f.Registry=e.extend({constructor:function(){this.root={}},get:function(a){return this.root[a]},set:function(a,b){this.root[a]=b},unset:function(a){delete this.root[a]},each:function(a,b){var c,d;if("function"==typeof a)for(c in this.root)d=this.get(c),a.call(b||this,c,d)},empty:function(){Object.keys(this.root).forEach(this.unset,this)}}),p=f.ViewRegistry=o.extend({registerView:function(a,b){var c=a.getID(),d=new q(a,b);this.set(c,d)},removeView:function(a){"string"!=typeof a&&(a=a.getID()),this.get(a).contextRegistry.empty(),this.unset(a)},getCustomEventsForView:function(a){return this.get(a).getCustomEvents()},getContextRegistryForView:function(a){return this.get(a).getContextRegistry()},setContextForChildView:function(a,b,c){this.getContextRegistryForView(a).set(b,c)},emptyViewContextRegistry:function(a){this.getContextRegistryForView(a).empty()}}),q=f.ViewRegistryItem=e.extend({constructor:function(a,b){this.view=a,this.parent=b&&b.getID(),this.children=[],this.customEvents={},this.contextRegistry=new o},getCustomEvents:function(){return this.customEvents},getContextRegistry:function(){return this.contextRegistry}}),r=f.Selection=e.extend({constructor:function(a){this.DOM=a,this.id=void 0,this.path=void 0,this.start=0,this.end=0},preserveSelection:function(){var b=a.env.getFocusedElement();this.start=b.selectionStart,this.end=b.selectionEnd},getIndexOfNode:function(a,b){var c=[];do c.push(a.classList[0]||k.call(a.parentNode.children,a)),a=a.parentNode;while(a!==b);return c},preserveSelectionInView:function(b){var c,d=a.env.getFocusedElement(),e=this.DOM.findClosestViewNode(d,j),f=b.getID();if(e&&e===f){try{this.preserveSelection()}catch(g){}c=b.getNode(),this.id=f,d!==c&&(this.path=d.id||this.getIndexOfNode(d,c))}},restoreSelection:function(a){"function"==typeof a.setSelectionRange&&a.setSelectionRange(this.start,this.end)},findNodeByIndex:function(a,b){if("number"==typeof a)b=b.children[a];else if(b=b.children[0],b.classList[0]!==a)do b=b.nextSibling;while(b.classList[0]!==a);return b},restoreSelectionInView:function(a){var b,c=a.getNode(),d=this.path;if(this.id&&this.id===a.getID()){if(d&&d.length>0)do b=d.pop(),c=this.findNodeByIndex(b,c);while(0!==d.length);try{this.restoreSelection(c)}catch(e){}c.focus(),this.id=void 0,this.path=void 0}}}),s=f.UIEventProxy=e.extend({listeners:[],constructor:function(a,b){this.DOM=a,this.ViewManager=b,this.listener=this.listener.bind(this)},findFirstViewAndFireEvent:function(a,b){do{if(d.viewHelper.hasEvent(b,a))return void d.viewHelper.fireDOMEvent(b,a);b=this.ViewManager.getParentView(b)}while(b)},addListener:function(a,b){a.addEventListener(b,this.listener)},removeListener:function(a,b){a.removeEventListener(b,this.listener)},listener:function(a){var b=this.DOM.findClosestViewNode(a.target,j),c=this.ViewManager.getView(b);return c?this.findFirstViewAndFireEvent(a,c):void 0},startListenTo:function(a){this.isListeningTo(a)||(this.listeners.push(a),this.addListener(document,a))},stopListenTo:function(a){var b=this.listeners.indexOf(a);b>-1&&(this.removeListener(document,a),this.listeners.splice(b,1))},isListeningTo:function(a){return this.listeners.indexOf(a)>-1}}),t=f.ViewHelper=e.extend({constructor:function(a,b,c,d){e.apply(this,arguments),this.DOM=c,this.Insurer=d,this.ViewManager=a,this.UIEventProxy=b},createChildView:function(a,b,c){var d=new b(c);return this.ViewManager.registerChildForView(a,d),d},initializeChildren:function(a){for(var b,c=this.ViewManager.getChildViews(a.getID()),d=c.length,e=0;d>e;)b=this.ViewManager.getView(c[e]),b.initialize(),e+=1},paint:function(a){var b=a.getNode(),c=this.ViewManager.compileTemplate(a);b.innerHTML=c||"",this._emptyAndPreserveChildContext(a),a.render(),this.updateCSSClasses(a),this.paintChildren(a)},paintChildren:function(a){for(var b,c=this.ViewManager.getChildViews(a.getID()),d=c.length,e=0;d>e;)b=this.ViewManager.getView(c[e]),this.ViewManager.updateView(b),e+=1},paintChildView:function(a,b){var c=a.getView(b);c&&this.ViewManager.updateView(c)},updateCSSClasses:function(a){var b=[a.className],c=a.getCSS();a.css&&b.push(a.css),c&&b.push(c),this.DOM.initNode(a.getNode(),b)},destroy:function(a){var b=a.getNode(),c=b.parentNode;this.undelegateAll(a),this.notifyDetach(a),c&&c.removeChild(b),this.ViewManager.emptyView(a),b.innerHTML="",a.node=null},notifyAttach:function(a){var b=this.ViewManager;a.attached=!0,a.onAttach(),b.getChildViews(a.getID()).forEach(b.notifyViewAboutAttach,b)},notifyDetach:function(a){var b=this.ViewManager;a.attached=!1,a.onDetach(),b.getChildViews(a.getID()).forEach(b.notifyViewAboutDetach,b)},cleanupContext:function(a,b){var c,d,e=a.expects;for(delete b.id,delete b.css,delete b.node,"object"!=typeof e||Array.isArray(e)||(e=Object.keys(e)),d=e.length;d--;)c=e[d],this.Insurer.is.defined(a[c],"["+c+"] is already defined on the View instance!"),a[c]=b[c],delete b[c]},_serializeAndRemoveView:function(a,b){this.ViewManager.serializeChildForView(a,b),a.removeView(b)},_emptyAndPreserveChildContext:function(a){var b=a.getID(),c=this.ViewManager.getChildViews(b);for(this.ViewManager.emptyContextRegistryForView(b);c.length>0;)this._serializeAndRemoveView(a,c[0])},getSelectorForChild:function(a,b){var c=a.getView(b),d=c.getID().split(".").pop();return a.renderMap[d]||a.renderMap["*"]},initializeWithContext:function(a,b){this.cleanupContext(a,b),a.set(b),this.initialize(a)},initialize:function(a){var b={},c=[a.className],d=a.getAttributes();b[i]=a.getID(),a.css&&c.push(a.css),this.DOM.initNode(a.getNode(),c,d,b),Object.keys(a.events).forEach(a.listenFor,a),this.initializeChildren(a)},serialize:function(a){return b({},a.defaults,a.context)},fireDOMEvent:function(a,b){var c=a.events[b.type];return"function"!=typeof c&&(c=a[c]),c?c.call(a,b):void 0},hasEvent:function(a,b){return!(!a.events||!a.events[b.type])},undelegateType:function(a,b){for(var c,d=a.getID(),e=this.ViewManager.getCustomEventsForView(d),f=e[b],g=f.length;g--;)c=a.find(f[g]),this.UIEventProxy.removeListener(c,b)},undelegateAll:function(a){var b=a.getID(),c=this.ViewManager.getCustomEventsForView(b);Object.keys(c).forEach(this.undelegateType.bind(this,a))}}),u=f.ViewManager=e.extend({constructor:function(a,b,c){this.DOM=b,this.Selection=c,this.ViewRegistry=a},getView:function(a){var b=this.ViewRegistry.get(a);return b&&b.view},getParent:function(a){var b=this.ViewRegistry.get(a);return b&&b.parent},getChildViews:function(a){var b=this.ViewRegistry.get(a);return b&&b.children},getParentView:function(a){var b=a.getID(),c=this.getParent(b);return this.getView(c)},getViewAtNode:function(a){return this.getView(a.dataset[i])},getRootNodeMapping:function(a,b){var c=b.getID(),e=d.viewHelper.getSelectorForChild(a,c),f=a.getNode();return d.getElement(f,e)},compileTemplate:function(a){var b=a.template,c=d.viewHelper.serialize(a);return"function"==typeof b?a.template(c):(Array.isArray(b)&&(b=b.join("")),d.compile(b,c))},updateView:function(a){var b,c=a.getNode(),e=this.getParentView(a),f=c.parentNode;d.viewHelper.undelegateAll(a),this.Selection.preserveSelectionInView(a),e&&(f=this.getRootNodeMapping(e,a)),b=k.call(f.children,c),b>-1&&f.removeChild(c),d.viewHelper.paint(a),this.DOM.attachNodeToParent(c,f,b),this.Selection.restoreSelectionInView(a)},notifyViewAboutAttach:function(a){var b=this.getView(a);d.viewHelper.notifyAttach(b)},notifyViewAboutDetach:function(a){var b=this.getView(a);d.viewHelper.notifyDetach(b)},removeViewFromParent:function(a){var b=this.getParentView(a),c=a.getID();b?b.removeView(c):d.viewHelper.destroy(a)},destroyViewAtNode:function(a){var b=this.getViewAtNode(a);b&&b.remove()},inheritCSS:function(a,b){return b?a+" "+b:a},getCustomEventsForView:function(a){return this.ViewRegistry.getCustomEventsForView(a)},registerChildForView:function(a,b){this.ViewRegistry.registerView(b,a),this.getChildViews(a.getID()).push(b.getID())},serializeChildForView:function(a,b){var c=a.getView(b),e=d.viewHelper.serialize(c);this.ViewRegistry.setContextForChildView(a.getID(),b,e)},emptyContextRegistryForView:function(a){this.ViewRegistry.emptyViewContextRegistry(a)},emptyView:function(a){this.getChildViews(a.getID()).forEach(a.removeView,a),this.ViewRegistry.removeView(a)}});a.extend=b,d.generateID=function(a){return(a||0)+g++},a.env.init=function(){this.dom=new m,this.insurer=new n,this.compiler=new l,this.viewRegistry=new p,this.selection=new r(this.dom),this.viewManager=new u(this.viewRegistry,this.dom,this.selection),this.uiEventProxy=new s(this.dom,this.viewManager),this.viewHelper=new t(this.viewManager,this.uiEventProxy,this.dom,this.insurer)},a.renderView=c;var v=a.View=e.extend({constructor:function(a){a=a||{},this._ID=a.id||d.generateID("v"),d.viewRegistry.registerView(this),this.css=a.css||"",this.node=a.node||document.createElement(this.tagName),this.context={},this.attached=!1,d.viewHelper.initializeWithContext(this,a)},tagName:"div",className:"View",defaults:{},renderMap:{},events:{},View:v,expects:{},template:"",get:function(a){return this.context[a]||this.defaults[a]},getID:function(){return this._ID},getNode:function(){return this.node},set:function(a){var c;a&&"object"==typeof a&&(c=b({},this.defaults,this.context,a),b(this.context,this.parseContext(c)||c))},setNode:function(a){a&&(this.node=a,this.initialize())},find:function(a){var b=this.getNode();return a?d.getElement(b,a):b},update:function(a){d.viewHelper.notifyDetach(this),this.set(a),d.viewManager.updateView(this),d.viewHelper.notifyAttach(this)},empty:function(){d.viewManager.getChildViews(this.getID()).forEach(this.removeView,this)},remove:function(){d.viewManager.removeViewFromParent(this)},addView:function(a,c){var e,f,g,h,i,j=this.getID(),k=d.viewRegistry.getContextRegistryForView(j);return a&&"object"==typeof a&&(c=a,a=this.View||v),c=c||{},h=j+"."+(c.id||d.generateID("v")),e=k.get(h),f=b({},e,c),g=b(f,{id:h}),i=d.viewHelper.createChildView(this,a,g),this.attached&&d.viewHelper.paintChildView(this,h),i},getView:function(a){var b=d.viewManager.getChildViews(this.getID());return"number"==typeof a&&a<b.length&&(a=b[a]),-1===b.indexOf(a)&&(a=this.getID()+"."+a),d.viewManager.getView(a)},removeView:function(a){var b,c=this.getView(a),e=d.viewManager.getChildViews(this.getID());c&&(b=e.indexOf(c.getID()),b>-1&&(d.viewHelper.destroy(c),e.splice(b,1)))},delegate:function(a,b){var c,e=this.getID(),f=d.viewRegistry.getCustomEventsForView(e);f[a]||(f[a]=[]),-1===f[a].indexOf(b)&&(c=this.find(b),d.uiEventProxy.addListener(c,a),f[a].push(b||""))},listenFor:function(a){d.uiEventProxy.startListenTo(a)},getCSS:function(){return""},getAttributes:function(){return{}},parseContext:function(a){return a},onAttach:h,onDetach:h,render:h});return v.extend=function(a,b){return b=b||{},b.add=v.add,a.className=d.viewManager.inheritCSS(this.prototype.className,a.className),e.extend.call(this,a,b)},v.add=function(a,b){return d.insurer.exists.object(b,"Parent View cannot be undefined!"),b.addView(this,a)},a.env.init(),a});