litespeed.js
Advanced tools
Comparing version 0.2.6 to 0.2.7
@@ -8,5 +8,9 @@ | ||
return null;} | ||
if(service.instance===null){let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;if(name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){instance=new Proxy(instance,{name:service.name,get:function(obj,prop){if(prop==="__name"){return this.name;} | ||
if(service.instance===null){let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;let skip=false;if(name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){instance=new Proxy(instance,{name:service.name,watch:function(){},get:function(obj,prop){if(prop==="__name"){return this.name;} | ||
if(prop==="__watch"){return this.watch;} | ||
if(typeof obj[prop]==='object'&&obj[prop]!==null){let handler=Object.assign({},this);handler.name=handler.name+'.'+prop;return new Proxy(obj[prop],handler)} | ||
else{return obj[prop];}},set:function(obj,prop,value,receiver){obj[prop]=value;let path=receiver.__name+'.'+prop;console.log('updated',path+'.changed',value);document.dispatchEvent(new CustomEvent(path+'.changed'));return true;},});} | ||
else{return obj[prop];}},set:function(obj,prop,value,receiver){if(prop==="__name"){return this.name=value;} | ||
if(prop==="__watch"){return this.watch=value;} | ||
obj[prop]=value;let path=receiver.__name+'.'+prop;document.dispatchEvent(new CustomEvent(path+'.changed'));if(skip){return true;} | ||
skip=true;container.set('$prop',prop,true);container.set('$value',value,true);container.resolve(this.watch);container.set('$prop',null,true);container.set('$value',null,true);skip=false;return true;},});} | ||
if(service.singleton){service.instance=instance;} | ||
@@ -20,3 +24,4 @@ return instance;} | ||
let shift=path.shift();if(undefined==shift){return object;} | ||
return object[shift];};let container={set:set,get:get,resolve:resolve,path:path,bind:function(element,path,callback,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');document.addEventListener(path.replace(as,prefix)+'.changed',function(){console.log('update callback triggered');callback();});},setCachePrefix:setCachePrefix,getCachePrefix:getCachePrefix};set('container',container,true);return container;}();container.set('http',function(document){let globalParams=[],globalHeaders=[];let addParam=function(url,param,value){param=encodeURIComponent(param);let a=document.createElement('a');param+=(value?"="+encodeURIComponent(value):"");a.href=url;a.search+=(a.search?"&":"")+param;return a.href;};let request=function(method,url,headers,payload,progress){let i;if(-1===['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS','CONNECT','PATCH'].indexOf(method)){throw new Error('var method must contain a valid HTTP method name');} | ||
return object[shift];};let container={set:set,get:get,resolve:resolve,path:path,bind:function(element,path,callback,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');let event=path.replace(as,prefix)+'.changed';let printer=function(){if(!document.body.contains(element)){console.log('cleaned dom');element=null;document.removeEventListener(event,printer,false);return false;} | ||
callback();};document.addEventListener(event,printer);},setCachePrefix:setCachePrefix,getCachePrefix:getCachePrefix};set('container',container,true);return container;}();container.set('http',function(document){let globalParams=[],globalHeaders=[];let addParam=function(url,param,value){param=encodeURIComponent(param);let a=document.createElement('a');param+=(value?"="+encodeURIComponent(value):"");a.href=url;a.search+=(a.search?"&":"")+param;return a.href;};let request=function(method,url,headers,payload,progress){let i;if(-1===['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS','CONNECT','PATCH'].indexOf(method)){throw new Error('var method must contain a valid HTTP method name');} | ||
if(typeof url!=='string'){throw new Error('var url must be of type string');} | ||
@@ -59,5 +64,5 @@ if(typeof headers!=='object'){throw new Error('var headers must be of type object');} | ||
stock[object.selector]=object;return this;},render:function(element){parse(element);element.dispatchEvent(new window.Event('rendered',{bubbles:false}));}}},true);container.set('state',function(window){let states=[];let current=null;let previous=null;let getPrevious=function(){return previous;};let setPrevious=function(value){previous=value;return this;};let getCurrent=function(){return current;};let setCurrent=function(value){current=value;return this;};let setParam=function(key,value){state.params[key]=value;return this;};let getParam=function(key,def){if(key in state.params){return state.params[key];} | ||
return def;};let getParams=function(){return state.params;};let getURL=function(){return window.location.href;};let reset=function(){state.params=getJsonFromUrl(window.location.search);};let add=function(path,view){if(typeof path!=='string'){throw new Error('path must be of type string');} | ||
return def;};let getParams=function(){return state.params;};let getURL=function(){return window.location.href;};let reset=function(){state.params=getJsonFromUrl(window.location.search);state.hash=window.location.hash;};let add=function(path,view){if(typeof path!=='string'){throw new Error('path must be of type string');} | ||
if(typeof view!=='object'){throw new Error('view must be of type object');} | ||
states[states.length++]={path:path,view:view};return this;};let match=function(location){let url=location.pathname;states.sort(function(a,b){return b.path.length-a.path.length;});states.sort(function(a,b){let n=b.path.split('/').length-a.path.split('/').length;if(n!==0){return n;} | ||
states[states.length++]={path:path,view:view};return this;};let match=function(location){let url=location.pathname+((location.hash)?location.hash:'');states.sort(function(a,b){return b.path.length-a.path.length;});states.sort(function(a,b){let n=b.path.split('/').length-a.path.split('/').length;if(n!==0){return n;} | ||
return b.path.length-a.path.length;});for(let i=0;i<states.length;i++){let value=states[i],match=new RegExp("^"+value.path.replace(/:[^\s/]+/g,'([\\w-]+)')+"$");let found=url.match(match);if(found){previous=current;current=value;return value;}} | ||
@@ -71,6 +76,6 @@ return null};let change=function(URL,replace){if(!replace){window.history.pushState({},'',URL);} | ||
if(!index){result[key].push(val);} | ||
else{result[key][index]=val;}}});return result;};let state={setParam:setParam,getParam:getParam,getParams:getParams,getURL:getURL,add:add,change:change,reload:reload,reset:reset,match:match,getCurrent:getCurrent,setCurrent:setCurrent,getPrevious:getPrevious,setPrevious:setPrevious,params:getJsonFromUrl(window.location.search)};return state;},true);container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix){def=def||'';paths=[];return string.replace(reg,function(match) | ||
else{result[key][index]=val;}}});return result;};let state={setParam:setParam,getParam:getParam,getParams:getParams,getURL:getURL,add:add,change:change,reload:reload,reset:reset,match:match,getCurrent:getCurrent,setCurrent:setCurrent,getPrevious:getPrevious,setPrevious:setPrevious,params:getJsonFromUrl(window.location.search),hash:window.location.hash};return state;},true);container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix){def=def||'';paths=[];return string.replace(reg,function(match) | ||
{let reference=match.substring(2,match.length-2).replace('[\'','.').replace('\']','').trim();reference=reference.split('|');let path=(reference[0]||'');let result=container.path(path,undefined,as,prefix);if(!paths.includes(path)){paths.push(path);} | ||
result=(null===result||undefined===result)?def:result;result=(typeof result==='object')?JSON.stringify(result):result;if(reference.length>=2){for(let i=1;i<reference.length;i++){result=filter.apply(result,reference[i],{});}} | ||
return result;});},getPaths:function(){return paths;},}},true);container.set('filter',function(){let filters={};let add=function(name,callback){filters[name]=callback;return this;};let apply=function(value,name){return filters[name](value);};add('uppercase',function(value){return value.toUpperCase();});add('lowercase',function(value){return value.toLowerCase();});return{add:add,apply:apply}},true);container.get('filter').add('escape',function(value){if(typeof value!=='string'){return value;} | ||
return result;});},getPaths:function(){return paths;},}},true);container.set('filter',function(container){let filters={};let add=function(name,callback){filters[name]=callback;return this;};let apply=function(value,name){container.set('$value',value,true);return container.resolve(filters[name]);};add('uppercase',function(value){return value.toUpperCase();});add('lowercase',function(value){return value.toLowerCase();});return{add:add,apply:apply}},true);container.get('filter').add('escape',function(value){if(typeof value!=='string'){return value;} | ||
return value.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});container.set('window',window,true).set('document',window.document,true).set('element',window.document,true);let app=function(version){return{run:function(window){try{container.get('http').addGlobalParam('version',version);this.view.render(window.document);} | ||
@@ -93,23 +98,24 @@ catch(error){var handler=container.resolve(this.error);handler(error);}},error:function(){return function(error){console.error('error',error.message,error.stack,error.toString());}},container:container,view:container.get('view')}};container.get('view').add({selector:'data-ls-init',controller:function(element,window,document,view,state){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},state:true},init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} | ||
init(route);return true;});window.addEventListener('popstate',function(){let route=state.match(window.location);if(state.getPrevious()&&state.getPrevious().view&&(state.getPrevious().view.scope!==route.view.scope)){window.location.reload();return false;} | ||
init(route);});init(state.match(window.location));}});container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,$as,$prefix){let attrs=element.dataset['lsAttrs'].trim().split(',');let paths=[];let check=function(){for(let i=0;i<attrs.length;i++){let attr=attrs[i].split('=');let key=(attr[0])?expression.parse(attr[0],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());let value=(attr[1])?expression.parse(attr[1],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());if(!key){return null;} | ||
init(route);});init(state.match(window.location));}});container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,$as,$prefix){let attrs=element.getAttribute('data-ls-attrs').trim().split(',');let paths=[];let check=function(){for(let i=0;i<attrs.length;i++){let attr=attrs[i].split('=');let key=(attr[0])?expression.parse(attr[0],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());let value=(attr[1])?expression.parse(attr[1],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());if(!key){return null;} | ||
element.setAttribute(key,value);}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-bind',controller:function(element,expression,container,$prefix,$as){let echo=function(value,bind=true){if(element.tagName==='INPUT'||element.tagName==='SELECT'||element.tagName==='BUTTON'||element.tagName==='TEXTAREA'){let type=element.getAttribute('type');if('radio'===type){if(value.toString()===element.value){element.setAttribute('checked','checked');} | ||
else{element.removeAttribute('checked');}} | ||
if('checkbox'===type){if(typeof value==='boolean'){if(value===true){element.setAttribute('checked','checked');element.value=true;} | ||
if('checkbox'===type){value=JSON.parse(value);if(typeof value==='boolean'){if(value===true){element.setAttribute('checked','checked');element.value=true;} | ||
else{element.removeAttribute('checked');element.value=false;} | ||
if(bind){element.addEventListener('change',function(){container.path(path,element.checked,$as,$prefix);});}} | ||
if(bind){element.addEventListener('change',function(){for(let i=0;i<paths.length;i++){container.path(paths[i],element.checked,$as,$prefix);}});}} | ||
return;} | ||
if(element.value!==value){element.value=value;} | ||
if(bind){element.addEventListener('input',sync);}} | ||
else{if(element.innerText!==value){element.innerHTML=value;}}};let sync=(function(as,prefix){return function(){container.path(path,element.value,as,prefix);}})($as,$prefix);let path=element.dataset['lsBind'];let result=container.path(path);container.bind(element,path,function(){echo(container.path(path,undefined,$as,$prefix),false);});echo(result,true);}});container.get('view').add({selector:'data-ls-if',controller:function(element,expression,$as,$prefix){let result='';let syntax=element.dataset['lsIf']||'';let debug=element.dataset['debug']||false;let paths=[];let check=function(){if(debug){console.info('debug-ls-if',expression.parse(syntax,'undefined',$as,$prefix));} | ||
else{if(element.innerText!==value){element.innerHTML=value;}}};let sync=(function(as,prefix){return function(){for(let i=0;i<paths.length;i++){container.path(paths[i],element.value,as,prefix);}}})($as,$prefix);let syntax=element.getAttribute('data-ls-bind');let result=expression.parse(syntax,null,$as,$prefix);let paths=expression.getPaths();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],function(){echo(expression.parse(syntax,null,$as,$prefix),false);});} | ||
echo(result,true);}});container.get('view').add({selector:'data-ls-if',controller:function(element,expression,$as,$prefix){let result='';let syntax=element.getAttribute('data-ls-if')||'';let debug=element.getAttribute('data-debug')||false;let paths=[];let check=function(){if(debug){console.info('debug-ls-if',expression.parse(syntax,'undefined',$as,$prefix));} | ||
try{result=!!(eval(expression.parse(syntax,'undefined',$as,$prefix).replace(/(\r\n|\n|\r)/gm,' ')));} | ||
catch(error){throw new Error('Failed to evaluate expression "'+syntax+'": '+error);} | ||
paths=expression.getPaths();if(!result){element.style.visibility='hidden';element.style.display='none';} | ||
else{element.style.removeProperty('display');element.style.removeProperty('visibility');}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-loop',template:false,repeat:false,nested:false,controller:function(element,view,container,window){let expr=element.dataset['lsLoop'];let echo=function(){let array=container.path(expr);array=(!array)?[]:array;while(element.hasChildNodes()){element.removeChild(element.lastChild);} | ||
else{element.style.removeProperty('display');element.style.removeProperty('visibility');}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-loop',template:false,repeat:false,nested:false,controller:function(element,view,container,window){let expr=element.getAttribute('data-ls-loop');let echo=function(){let array=container.path(expr);array=(!array)?[]:array;while(element.hasChildNodes()){element.removeChild(element.lastChild);element.lastChild=null;} | ||
if(array instanceof Array&&typeof array!=='object'){throw new Error('Reference value must be array or object. '+(typeof array)+' given');} | ||
let children=[];element.$lsSkip=true;element.style.visibility=(0===array.length)?'hidden':'visible';for(let prop in array){if(!array.hasOwnProperty(prop)){continue;} | ||
children[prop]=children[prop]||element.backup.cloneNode(true);element.appendChild(children[prop]);(function(index){let context=expr+'.'+index;container.set(element.dataset['lsAs'],container.path(context),true);container.set('$index',index,true);container.set('$prefix',context,true);container.set('$as',element.dataset['lsAs'],true);view.render(children[prop]);})(prop);} | ||
children[prop]=children[prop]||element.backup.cloneNode(true);element.appendChild(children[prop]);(function(index){let context=expr+'.'+index;container.set(element.getAttribute('data-ls-as'),container.path(context),true);container.set('$index',index,true);container.set('$prefix',context,true);container.set('$as',element.getAttribute('data-ls-as'),true);view.render(children[prop]);})(prop);} | ||
container.set('$index',null,true);container.set('$prefix','',true);container.set('$as','',true);};element.template=(element.template)?element.template:(element.children.length===1)?element.children[0].innerHTML:'';if(!element.backup){element.backup=(element.children.length===1)?element.children[0]:window.document.createElement('li');} | ||
echo();document.addEventListener(expr+'.changed',echo);document.addEventListener(expr+'.length.changed',echo);}});container.get('view').add({selector:'data-ls-template',template:false,repeat:true,controller:function(element,view,http,expression,document){let template=expression.parse(element.dataset['lsTemplate']);let type=element.dataset['type']||'url';element.innerHTML='';let parse=function(data,element){element.innerHTML=data;view.render(element);element.dispatchEvent(new CustomEvent('template-loaded',{bubbles:true,cancelable:false}));};if('script'===type){let inlineTemplate=document.getElementById(template);if(inlineTemplate&&inlineTemplate.innerHTML){parse(inlineTemplate.innerHTML,element);} | ||
echo();container.bind(element,expr,echo);container.bind(element,expr+'.length',echo);}});container.get('view').add({selector:'data-ls-template',template:false,repeat:true,controller:function(element,view,http,expression,document){let template=expression.parse(element.getAttribute('data-ls-template'));let type=element.getAttribute('data-type')||'url';element.innerHTML='';let parse=function(data,element){element.innerHTML=data;view.render(element);element.dispatchEvent(new CustomEvent('template-loaded',{bubbles:true,cancelable:false}));};if('script'===type){let inlineTemplate=document.getElementById(template);if(inlineTemplate&&inlineTemplate.innerHTML){parse(inlineTemplate.innerHTML,element);} | ||
else{element.innerHTML='<span style="color: red">Missing template "'+template+'"</span>';} | ||
return;} | ||
http.get(template).then(function(element){return function(data){parse(data,element);}}(element),function(){throw new Error('Failed loading template');});}}); |
@@ -8,5 +8,9 @@ | ||
return null;} | ||
if(service.instance===null){let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;if(name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){instance=new Proxy(instance,{name:service.name,get:function(obj,prop){if(prop==="__name"){return this.name;} | ||
if(service.instance===null){let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;let skip=false;if(name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){instance=new Proxy(instance,{name:service.name,watch:function(){},get:function(obj,prop){if(prop==="__name"){return this.name;} | ||
if(prop==="__watch"){return this.watch;} | ||
if(typeof obj[prop]==='object'&&obj[prop]!==null){let handler=Object.assign({},this);handler.name=handler.name+'.'+prop;return new Proxy(obj[prop],handler)} | ||
else{return obj[prop];}},set:function(obj,prop,value,receiver){obj[prop]=value;let path=receiver.__name+'.'+prop;console.log('updated',path+'.changed',value);document.dispatchEvent(new CustomEvent(path+'.changed'));return true;},});} | ||
else{return obj[prop];}},set:function(obj,prop,value,receiver){if(prop==="__name"){return this.name=value;} | ||
if(prop==="__watch"){return this.watch=value;} | ||
obj[prop]=value;let path=receiver.__name+'.'+prop;document.dispatchEvent(new CustomEvent(path+'.changed'));if(skip){return true;} | ||
skip=true;container.set('$prop',prop,true);container.set('$value',value,true);container.resolve(this.watch);container.set('$prop',null,true);container.set('$value',null,true);skip=false;return true;},});} | ||
if(service.singleton){service.instance=instance;} | ||
@@ -20,3 +24,4 @@ return instance;} | ||
let shift=path.shift();if(undefined==shift){return object;} | ||
return object[shift];};let container={set:set,get:get,resolve:resolve,path:path,bind:function(element,path,callback,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');document.addEventListener(path.replace(as,prefix)+'.changed',function(){console.log('update callback triggered');callback();});},setCachePrefix:setCachePrefix,getCachePrefix:getCachePrefix};set('container',container,true);return container;}();container.set('http',function(document){let globalParams=[],globalHeaders=[];let addParam=function(url,param,value){param=encodeURIComponent(param);let a=document.createElement('a');param+=(value?"="+encodeURIComponent(value):"");a.href=url;a.search+=(a.search?"&":"")+param;return a.href;};let request=function(method,url,headers,payload,progress){let i;if(-1===['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS','CONNECT','PATCH'].indexOf(method)){throw new Error('var method must contain a valid HTTP method name');} | ||
return object[shift];};let container={set:set,get:get,resolve:resolve,path:path,bind:function(element,path,callback,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');let event=path.replace(as,prefix)+'.changed';let printer=function(){if(!document.body.contains(element)){console.log('cleaned dom');element=null;document.removeEventListener(event,printer,false);return false;} | ||
callback();};document.addEventListener(event,printer);},setCachePrefix:setCachePrefix,getCachePrefix:getCachePrefix};set('container',container,true);return container;}();container.set('http',function(document){let globalParams=[],globalHeaders=[];let addParam=function(url,param,value){param=encodeURIComponent(param);let a=document.createElement('a');param+=(value?"="+encodeURIComponent(value):"");a.href=url;a.search+=(a.search?"&":"")+param;return a.href;};let request=function(method,url,headers,payload,progress){let i;if(-1===['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS','CONNECT','PATCH'].indexOf(method)){throw new Error('var method must contain a valid HTTP method name');} | ||
if(typeof url!=='string'){throw new Error('var url must be of type string');} | ||
@@ -76,5 +81,5 @@ if(typeof headers!=='object'){throw new Error('var headers must be of type object');} | ||
return{'toJson':toJson}},true);container.set('state',function(window){let states=[];let current=null;let previous=null;let getPrevious=function(){return previous;};let setPrevious=function(value){previous=value;return this;};let getCurrent=function(){return current;};let setCurrent=function(value){current=value;return this;};let setParam=function(key,value){state.params[key]=value;return this;};let getParam=function(key,def){if(key in state.params){return state.params[key];} | ||
return def;};let getParams=function(){return state.params;};let getURL=function(){return window.location.href;};let reset=function(){state.params=getJsonFromUrl(window.location.search);};let add=function(path,view){if(typeof path!=='string'){throw new Error('path must be of type string');} | ||
return def;};let getParams=function(){return state.params;};let getURL=function(){return window.location.href;};let reset=function(){state.params=getJsonFromUrl(window.location.search);state.hash=window.location.hash;};let add=function(path,view){if(typeof path!=='string'){throw new Error('path must be of type string');} | ||
if(typeof view!=='object'){throw new Error('view must be of type object');} | ||
states[states.length++]={path:path,view:view};return this;};let match=function(location){let url=location.pathname;states.sort(function(a,b){return b.path.length-a.path.length;});states.sort(function(a,b){let n=b.path.split('/').length-a.path.split('/').length;if(n!==0){return n;} | ||
states[states.length++]={path:path,view:view};return this;};let match=function(location){let url=location.pathname+((location.hash)?location.hash:'');states.sort(function(a,b){return b.path.length-a.path.length;});states.sort(function(a,b){let n=b.path.split('/').length-a.path.split('/').length;if(n!==0){return n;} | ||
return b.path.length-a.path.length;});for(let i=0;i<states.length;i++){let value=states[i],match=new RegExp("^"+value.path.replace(/:[^\s/]+/g,'([\\w-]+)')+"$");let found=url.match(match);if(found){previous=current;current=value;return value;}} | ||
@@ -88,6 +93,6 @@ return null};let change=function(URL,replace){if(!replace){window.history.pushState({},'',URL);} | ||
if(!index){result[key].push(val);} | ||
else{result[key][index]=val;}}});return result;};let state={setParam:setParam,getParam:getParam,getParams:getParams,getURL:getURL,add:add,change:change,reload:reload,reset:reset,match:match,getCurrent:getCurrent,setCurrent:setCurrent,getPrevious:getPrevious,setPrevious:setPrevious,params:getJsonFromUrl(window.location.search)};return state;},true);container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix){def=def||'';paths=[];return string.replace(reg,function(match) | ||
else{result[key][index]=val;}}});return result;};let state={setParam:setParam,getParam:getParam,getParams:getParams,getURL:getURL,add:add,change:change,reload:reload,reset:reset,match:match,getCurrent:getCurrent,setCurrent:setCurrent,getPrevious:getPrevious,setPrevious:setPrevious,params:getJsonFromUrl(window.location.search),hash:window.location.hash};return state;},true);container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix){def=def||'';paths=[];return string.replace(reg,function(match) | ||
{let reference=match.substring(2,match.length-2).replace('[\'','.').replace('\']','').trim();reference=reference.split('|');let path=(reference[0]||'');let result=container.path(path,undefined,as,prefix);if(!paths.includes(path)){paths.push(path);} | ||
result=(null===result||undefined===result)?def:result;result=(typeof result==='object')?JSON.stringify(result):result;if(reference.length>=2){for(let i=1;i<reference.length;i++){result=filter.apply(result,reference[i],{});}} | ||
return result;});},getPaths:function(){return paths;},}},true);container.set('filter',function(){let filters={};let add=function(name,callback){filters[name]=callback;return this;};let apply=function(value,name){return filters[name](value);};add('uppercase',function(value){return value.toUpperCase();});add('lowercase',function(value){return value.toLowerCase();});return{add:add,apply:apply}},true);container.get('filter').add('escape',function(value){if(typeof value!=='string'){return value;} | ||
return result;});},getPaths:function(){return paths;},}},true);container.set('filter',function(container){let filters={};let add=function(name,callback){filters[name]=callback;return this;};let apply=function(value,name){container.set('$value',value,true);return container.resolve(filters[name]);};add('uppercase',function(value){return value.toUpperCase();});add('lowercase',function(value){return value.toLowerCase();});return{add:add,apply:apply}},true);container.get('filter').add('escape',function(value){if(typeof value!=='string'){return value;} | ||
return value.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});container.set('window',window,true).set('document',window.document,true).set('element',window.document,true);let app=function(version){return{run:function(window){try{container.get('http').addGlobalParam('version',version);this.view.render(window.document);} | ||
@@ -110,13 +115,13 @@ catch(error){var handler=container.resolve(this.error);handler(error);}},error:function(){return function(error){console.error('error',error.message,error.stack,error.toString());}},container:container,view:container.get('view')}};container.get('view').add({selector:'data-ls-init',controller:function(element,window,document,view,state){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},state:true},init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} | ||
init(route);return true;});window.addEventListener('popstate',function(){let route=state.match(window.location);if(state.getPrevious()&&state.getPrevious().view&&(state.getPrevious().view.scope!==route.view.scope)){window.location.reload();return false;} | ||
init(route);});init(state.match(window.location));}});container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,$as,$prefix){let attrs=element.dataset['lsAttrs'].trim().split(',');let paths=[];let check=function(){for(let i=0;i<attrs.length;i++){let attr=attrs[i].split('=');let key=(attr[0])?expression.parse(attr[0],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());let value=(attr[1])?expression.parse(attr[1],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());if(!key){return null;} | ||
element.setAttribute(key,value);}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-if',controller:function(element,expression,$as,$prefix){let result='';let syntax=element.dataset['lsIf']||'';let debug=element.dataset['debug']||false;let paths=[];let check=function(){if(debug){console.info('debug-ls-if',expression.parse(syntax,'undefined',$as,$prefix));} | ||
init(route);});init(state.match(window.location));}});container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,$as,$prefix){let attrs=element.getAttribute('data-ls-attrs').trim().split(',');let paths=[];let check=function(){for(let i=0;i<attrs.length;i++){let attr=attrs[i].split('=');let key=(attr[0])?expression.parse(attr[0],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());let value=(attr[1])?expression.parse(attr[1],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());if(!key){return null;} | ||
element.setAttribute(key,value);}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-if',controller:function(element,expression,$as,$prefix){let result='';let syntax=element.getAttribute('data-ls-if')||'';let debug=element.getAttribute('data-debug')||false;let paths=[];let check=function(){if(debug){console.info('debug-ls-if',expression.parse(syntax,'undefined',$as,$prefix));} | ||
try{result=!!(eval(expression.parse(syntax,'undefined',$as,$prefix).replace(/(\r\n|\n|\r)/gm,' ')));} | ||
catch(error){throw new Error('Failed to evaluate expression "'+syntax+'": '+error);} | ||
paths=expression.getPaths();if(!result){element.style.visibility='hidden';element.style.display='none';} | ||
else{element.style.removeProperty('display');element.style.removeProperty('visibility');}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-loop',template:false,repeat:false,nested:false,controller:function(element,view,container,window){let expr=element.dataset['lsLoop'];let echo=function(){let array=container.path(expr);array=(!array)?[]:array;while(element.hasChildNodes()){element.removeChild(element.lastChild);} | ||
else{element.style.removeProperty('display');element.style.removeProperty('visibility');}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-loop',template:false,repeat:false,nested:false,controller:function(element,view,container,window){let expr=element.getAttribute('data-ls-loop');let echo=function(){let array=container.path(expr);array=(!array)?[]:array;while(element.hasChildNodes()){element.removeChild(element.lastChild);element.lastChild=null;} | ||
if(array instanceof Array&&typeof array!=='object'){throw new Error('Reference value must be array or object. '+(typeof array)+' given');} | ||
let children=[];element.$lsSkip=true;element.style.visibility=(0===array.length)?'hidden':'visible';for(let prop in array){if(!array.hasOwnProperty(prop)){continue;} | ||
children[prop]=children[prop]||element.backup.cloneNode(true);element.appendChild(children[prop]);(function(index){let context=expr+'.'+index;container.set(element.dataset['lsAs'],container.path(context),true);container.set('$index',index,true);container.set('$prefix',context,true);container.set('$as',element.dataset['lsAs'],true);view.render(children[prop]);})(prop);} | ||
children[prop]=children[prop]||element.backup.cloneNode(true);element.appendChild(children[prop]);(function(index){let context=expr+'.'+index;container.set(element.getAttribute('data-ls-as'),container.path(context),true);container.set('$index',index,true);container.set('$prefix',context,true);container.set('$as',element.getAttribute('data-ls-as'),true);view.render(children[prop]);})(prop);} | ||
container.set('$index',null,true);container.set('$prefix','',true);container.set('$as','',true);};element.template=(element.template)?element.template:(element.children.length===1)?element.children[0].innerHTML:'';if(!element.backup){element.backup=(element.children.length===1)?element.children[0]:window.document.createElement('li');} | ||
echo();document.addEventListener(expr+'.changed',echo);document.addEventListener(expr+'.length.changed',echo);}});container.get('view').add({selector:'data-ls-alt',template:false,repeat:true,controller:function(element,expression){element.alt=expression.parse(element.dataset['lsAlt']);}});container.get('view').add({selector:'data-ls-class',template:false,repeat:true,controller:function(element,expression){element.className=expression.parse(element.dataset['lsClass']);}});container.get('view').add({selector:'data-ls-echo',template:false,repeat:true,controller:function(element,expression,filter){let def=expression.parse(element.getAttribute('data-default')||'');let filterName=element.getAttribute('data-filter')||'';let filterOptions=JSON.parse(element.getAttribute('data-filter-options')||'{}');let result=expression.parse(element.dataset['lsEcho']);result=result||def;if(filterName){result=filter.apply(result,filterName,filterOptions);} | ||
echo();container.bind(element,expr,echo);container.bind(element,expr+'.length',echo);}});container.get('view').add({selector:'data-ls-alt',template:false,repeat:true,controller:function(element,expression){element.alt=expression.parse(element.dataset['lsAlt']);}});container.get('view').add({selector:'data-ls-class',template:false,repeat:true,controller:function(element,expression){element.className=expression.parse(element.dataset['lsClass']);}});container.get('view').add({selector:'data-ls-echo',template:false,repeat:true,controller:function(element,expression,filter){let def=expression.parse(element.getAttribute('data-default')||'');let filterName=element.getAttribute('data-filter')||'';let filterOptions=JSON.parse(element.getAttribute('data-filter-options')||'{}');let result=expression.parse(element.dataset['lsEcho']);result=result||def;if(filterName){result=filter.apply(result,filterName,filterOptions);} | ||
if(element.tagName==='INPUT'||element.tagName==='OPTION'||element.tagName==='SELECT'||element.tagName==='BUTTON'||element.tagName==='TEXTAREA'){let type=element.getAttribute('type');if('radio'===type){if(result.toString()===def){element.setAttribute('checked','checked');} | ||
@@ -123,0 +128,0 @@ else{element.removeAttribute('checked');}} |
@@ -8,5 +8,9 @@ | ||
return null;} | ||
if(service.instance===null){let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;if(name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){instance=new Proxy(instance,{name:service.name,get:function(obj,prop){if(prop==="__name"){return this.name;} | ||
if(service.instance===null){let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;let skip=false;if(name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){instance=new Proxy(instance,{name:service.name,watch:function(){},get:function(obj,prop){if(prop==="__name"){return this.name;} | ||
if(prop==="__watch"){return this.watch;} | ||
if(typeof obj[prop]==='object'&&obj[prop]!==null){let handler=Object.assign({},this);handler.name=handler.name+'.'+prop;return new Proxy(obj[prop],handler)} | ||
else{return obj[prop];}},set:function(obj,prop,value,receiver){obj[prop]=value;let path=receiver.__name+'.'+prop;console.log('updated',path+'.changed',value);document.dispatchEvent(new CustomEvent(path+'.changed'));return true;},});} | ||
else{return obj[prop];}},set:function(obj,prop,value,receiver){if(prop==="__name"){return this.name=value;} | ||
if(prop==="__watch"){return this.watch=value;} | ||
obj[prop]=value;let path=receiver.__name+'.'+prop;document.dispatchEvent(new CustomEvent(path+'.changed'));if(skip){return true;} | ||
skip=true;container.set('$prop',prop,true);container.set('$value',value,true);container.resolve(this.watch);container.set('$prop',null,true);container.set('$value',null,true);skip=false;return true;},});} | ||
if(service.singleton){service.instance=instance;} | ||
@@ -20,3 +24,4 @@ return instance;} | ||
let shift=path.shift();if(undefined==shift){return object;} | ||
return object[shift];};let container={set:set,get:get,resolve:resolve,path:path,bind:function(element,path,callback,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');document.addEventListener(path.replace(as,prefix)+'.changed',function(){console.log('update callback triggered');callback();});},setCachePrefix:setCachePrefix,getCachePrefix:getCachePrefix};set('container',container,true);return container;}();container.set('http',function(document){let globalParams=[],globalHeaders=[];let addParam=function(url,param,value){param=encodeURIComponent(param);let a=document.createElement('a');param+=(value?"="+encodeURIComponent(value):"");a.href=url;a.search+=(a.search?"&":"")+param;return a.href;};let request=function(method,url,headers,payload,progress){let i;if(-1===['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS','CONNECT','PATCH'].indexOf(method)){throw new Error('var method must contain a valid HTTP method name');} | ||
return object[shift];};let container={set:set,get:get,resolve:resolve,path:path,bind:function(element,path,callback,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');let event=path.replace(as,prefix)+'.changed';let printer=function(){if(!document.body.contains(element)){console.log('cleaned dom');element=null;document.removeEventListener(event,printer,false);return false;} | ||
callback();};document.addEventListener(event,printer);},setCachePrefix:setCachePrefix,getCachePrefix:getCachePrefix};set('container',container,true);return container;}();container.set('http',function(document){let globalParams=[],globalHeaders=[];let addParam=function(url,param,value){param=encodeURIComponent(param);let a=document.createElement('a');param+=(value?"="+encodeURIComponent(value):"");a.href=url;a.search+=(a.search?"&":"")+param;return a.href;};let request=function(method,url,headers,payload,progress){let i;if(-1===['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS','CONNECT','PATCH'].indexOf(method)){throw new Error('var method must contain a valid HTTP method name');} | ||
if(typeof url!=='string'){throw new Error('var url must be of type string');} | ||
@@ -59,5 +64,5 @@ if(typeof headers!=='object'){throw new Error('var headers must be of type object');} | ||
stock[object.selector]=object;return this;},render:function(element){parse(element);element.dispatchEvent(new window.Event('rendered',{bubbles:false}));}}},true);container.set('state',function(window){let states=[];let current=null;let previous=null;let getPrevious=function(){return previous;};let setPrevious=function(value){previous=value;return this;};let getCurrent=function(){return current;};let setCurrent=function(value){current=value;return this;};let setParam=function(key,value){state.params[key]=value;return this;};let getParam=function(key,def){if(key in state.params){return state.params[key];} | ||
return def;};let getParams=function(){return state.params;};let getURL=function(){return window.location.href;};let reset=function(){state.params=getJsonFromUrl(window.location.search);};let add=function(path,view){if(typeof path!=='string'){throw new Error('path must be of type string');} | ||
return def;};let getParams=function(){return state.params;};let getURL=function(){return window.location.href;};let reset=function(){state.params=getJsonFromUrl(window.location.search);state.hash=window.location.hash;};let add=function(path,view){if(typeof path!=='string'){throw new Error('path must be of type string');} | ||
if(typeof view!=='object'){throw new Error('view must be of type object');} | ||
states[states.length++]={path:path,view:view};return this;};let match=function(location){let url=location.pathname;states.sort(function(a,b){return b.path.length-a.path.length;});states.sort(function(a,b){let n=b.path.split('/').length-a.path.split('/').length;if(n!==0){return n;} | ||
states[states.length++]={path:path,view:view};return this;};let match=function(location){let url=location.pathname+((location.hash)?location.hash:'');states.sort(function(a,b){return b.path.length-a.path.length;});states.sort(function(a,b){let n=b.path.split('/').length-a.path.split('/').length;if(n!==0){return n;} | ||
return b.path.length-a.path.length;});for(let i=0;i<states.length;i++){let value=states[i],match=new RegExp("^"+value.path.replace(/:[^\s/]+/g,'([\\w-]+)')+"$");let found=url.match(match);if(found){previous=current;current=value;return value;}} | ||
@@ -71,6 +76,6 @@ return null};let change=function(URL,replace){if(!replace){window.history.pushState({},'',URL);} | ||
if(!index){result[key].push(val);} | ||
else{result[key][index]=val;}}});return result;};let state={setParam:setParam,getParam:getParam,getParams:getParams,getURL:getURL,add:add,change:change,reload:reload,reset:reset,match:match,getCurrent:getCurrent,setCurrent:setCurrent,getPrevious:getPrevious,setPrevious:setPrevious,params:getJsonFromUrl(window.location.search)};return state;},true);container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix){def=def||'';paths=[];return string.replace(reg,function(match) | ||
else{result[key][index]=val;}}});return result;};let state={setParam:setParam,getParam:getParam,getParams:getParams,getURL:getURL,add:add,change:change,reload:reload,reset:reset,match:match,getCurrent:getCurrent,setCurrent:setCurrent,getPrevious:getPrevious,setPrevious:setPrevious,params:getJsonFromUrl(window.location.search),hash:window.location.hash};return state;},true);container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix){def=def||'';paths=[];return string.replace(reg,function(match) | ||
{let reference=match.substring(2,match.length-2).replace('[\'','.').replace('\']','').trim();reference=reference.split('|');let path=(reference[0]||'');let result=container.path(path,undefined,as,prefix);if(!paths.includes(path)){paths.push(path);} | ||
result=(null===result||undefined===result)?def:result;result=(typeof result==='object')?JSON.stringify(result):result;if(reference.length>=2){for(let i=1;i<reference.length;i++){result=filter.apply(result,reference[i],{});}} | ||
return result;});},getPaths:function(){return paths;},}},true);container.set('filter',function(){let filters={};let add=function(name,callback){filters[name]=callback;return this;};let apply=function(value,name){return filters[name](value);};add('uppercase',function(value){return value.toUpperCase();});add('lowercase',function(value){return value.toLowerCase();});return{add:add,apply:apply}},true);container.get('filter').add('escape',function(value){if(typeof value!=='string'){return value;} | ||
return result;});},getPaths:function(){return paths;},}},true);container.set('filter',function(container){let filters={};let add=function(name,callback){filters[name]=callback;return this;};let apply=function(value,name){container.set('$value',value,true);return container.resolve(filters[name]);};add('uppercase',function(value){return value.toUpperCase();});add('lowercase',function(value){return value.toLowerCase();});return{add:add,apply:apply}},true);container.get('filter').add('escape',function(value){if(typeof value!=='string'){return value;} | ||
return value.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});container.set('window',window,true).set('document',window.document,true).set('element',window.document,true);let app=function(version){return{run:function(window){try{container.get('http').addGlobalParam('version',version);this.view.render(window.document);} | ||
@@ -93,23 +98,24 @@ catch(error){var handler=container.resolve(this.error);handler(error);}},error:function(){return function(error){console.error('error',error.message,error.stack,error.toString());}},container:container,view:container.get('view')}};container.get('view').add({selector:'data-ls-init',controller:function(element,window,document,view,state){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},state:true},init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} | ||
init(route);return true;});window.addEventListener('popstate',function(){let route=state.match(window.location);if(state.getPrevious()&&state.getPrevious().view&&(state.getPrevious().view.scope!==route.view.scope)){window.location.reload();return false;} | ||
init(route);});init(state.match(window.location));}});container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,$as,$prefix){let attrs=element.dataset['lsAttrs'].trim().split(',');let paths=[];let check=function(){for(let i=0;i<attrs.length;i++){let attr=attrs[i].split('=');let key=(attr[0])?expression.parse(attr[0],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());let value=(attr[1])?expression.parse(attr[1],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());if(!key){return null;} | ||
init(route);});init(state.match(window.location));}});container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,$as,$prefix){let attrs=element.getAttribute('data-ls-attrs').trim().split(',');let paths=[];let check=function(){for(let i=0;i<attrs.length;i++){let attr=attrs[i].split('=');let key=(attr[0])?expression.parse(attr[0],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());let value=(attr[1])?expression.parse(attr[1],null,$as,$prefix):null;paths=paths.concat(expression.getPaths());if(!key){return null;} | ||
element.setAttribute(key,value);}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-bind',controller:function(element,expression,container,$prefix,$as){let echo=function(value,bind=true){if(element.tagName==='INPUT'||element.tagName==='SELECT'||element.tagName==='BUTTON'||element.tagName==='TEXTAREA'){let type=element.getAttribute('type');if('radio'===type){if(value.toString()===element.value){element.setAttribute('checked','checked');} | ||
else{element.removeAttribute('checked');}} | ||
if('checkbox'===type){if(typeof value==='boolean'){if(value===true){element.setAttribute('checked','checked');element.value=true;} | ||
if('checkbox'===type){value=JSON.parse(value);if(typeof value==='boolean'){if(value===true){element.setAttribute('checked','checked');element.value=true;} | ||
else{element.removeAttribute('checked');element.value=false;} | ||
if(bind){element.addEventListener('change',function(){container.path(path,element.checked,$as,$prefix);});}} | ||
if(bind){element.addEventListener('change',function(){for(let i=0;i<paths.length;i++){container.path(paths[i],element.checked,$as,$prefix);}});}} | ||
return;} | ||
if(element.value!==value){element.value=value;} | ||
if(bind){element.addEventListener('input',sync);}} | ||
else{if(element.innerText!==value){element.innerHTML=value;}}};let sync=(function(as,prefix){return function(){container.path(path,element.value,as,prefix);}})($as,$prefix);let path=element.dataset['lsBind'];let result=container.path(path);container.bind(element,path,function(){echo(container.path(path,undefined,$as,$prefix),false);});echo(result,true);}});container.get('view').add({selector:'data-ls-if',controller:function(element,expression,$as,$prefix){let result='';let syntax=element.dataset['lsIf']||'';let debug=element.dataset['debug']||false;let paths=[];let check=function(){if(debug){console.info('debug-ls-if',expression.parse(syntax,'undefined',$as,$prefix));} | ||
else{if(element.innerText!==value){element.innerHTML=value;}}};let sync=(function(as,prefix){return function(){for(let i=0;i<paths.length;i++){container.path(paths[i],element.value,as,prefix);}}})($as,$prefix);let syntax=element.getAttribute('data-ls-bind');let result=expression.parse(syntax,null,$as,$prefix);let paths=expression.getPaths();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],function(){echo(expression.parse(syntax,null,$as,$prefix),false);});} | ||
echo(result,true);}});container.get('view').add({selector:'data-ls-if',controller:function(element,expression,$as,$prefix){let result='';let syntax=element.getAttribute('data-ls-if')||'';let debug=element.getAttribute('data-debug')||false;let paths=[];let check=function(){if(debug){console.info('debug-ls-if',expression.parse(syntax,'undefined',$as,$prefix));} | ||
try{result=!!(eval(expression.parse(syntax,'undefined',$as,$prefix).replace(/(\r\n|\n|\r)/gm,' ')));} | ||
catch(error){throw new Error('Failed to evaluate expression "'+syntax+'": '+error);} | ||
paths=expression.getPaths();if(!result){element.style.visibility='hidden';element.style.display='none';} | ||
else{element.style.removeProperty('display');element.style.removeProperty('visibility');}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-loop',template:false,repeat:false,nested:false,controller:function(element,view,container,window){let expr=element.dataset['lsLoop'];let echo=function(){let array=container.path(expr);array=(!array)?[]:array;while(element.hasChildNodes()){element.removeChild(element.lastChild);} | ||
else{element.style.removeProperty('display');element.style.removeProperty('visibility');}};check();for(let i=0;i<paths.length;i++){container.bind(element,paths[i],check);}}});container.get('view').add({selector:'data-ls-loop',template:false,repeat:false,nested:false,controller:function(element,view,container,window){let expr=element.getAttribute('data-ls-loop');let echo=function(){let array=container.path(expr);array=(!array)?[]:array;while(element.hasChildNodes()){element.removeChild(element.lastChild);element.lastChild=null;} | ||
if(array instanceof Array&&typeof array!=='object'){throw new Error('Reference value must be array or object. '+(typeof array)+' given');} | ||
let children=[];element.$lsSkip=true;element.style.visibility=(0===array.length)?'hidden':'visible';for(let prop in array){if(!array.hasOwnProperty(prop)){continue;} | ||
children[prop]=children[prop]||element.backup.cloneNode(true);element.appendChild(children[prop]);(function(index){let context=expr+'.'+index;container.set(element.dataset['lsAs'],container.path(context),true);container.set('$index',index,true);container.set('$prefix',context,true);container.set('$as',element.dataset['lsAs'],true);view.render(children[prop]);})(prop);} | ||
children[prop]=children[prop]||element.backup.cloneNode(true);element.appendChild(children[prop]);(function(index){let context=expr+'.'+index;container.set(element.getAttribute('data-ls-as'),container.path(context),true);container.set('$index',index,true);container.set('$prefix',context,true);container.set('$as',element.getAttribute('data-ls-as'),true);view.render(children[prop]);})(prop);} | ||
container.set('$index',null,true);container.set('$prefix','',true);container.set('$as','',true);};element.template=(element.template)?element.template:(element.children.length===1)?element.children[0].innerHTML:'';if(!element.backup){element.backup=(element.children.length===1)?element.children[0]:window.document.createElement('li');} | ||
echo();document.addEventListener(expr+'.changed',echo);document.addEventListener(expr+'.length.changed',echo);}});container.get('view').add({selector:'data-ls-template',template:false,repeat:true,controller:function(element,view,http,expression,document){let template=expression.parse(element.dataset['lsTemplate']);let type=element.dataset['type']||'url';element.innerHTML='';let parse=function(data,element){element.innerHTML=data;view.render(element);element.dispatchEvent(new CustomEvent('template-loaded',{bubbles:true,cancelable:false}));};if('script'===type){let inlineTemplate=document.getElementById(template);if(inlineTemplate&&inlineTemplate.innerHTML){parse(inlineTemplate.innerHTML,element);} | ||
echo();container.bind(element,expr,echo);container.bind(element,expr+'.length',echo);}});container.get('view').add({selector:'data-ls-template',template:false,repeat:true,controller:function(element,view,http,expression,document){let template=expression.parse(element.getAttribute('data-ls-template'));let type=element.getAttribute('data-type')||'url';element.innerHTML='';let parse=function(data,element){element.innerHTML=data;view.render(element);element.dispatchEvent(new CustomEvent('template-loaded',{bubbles:true,cancelable:false}));};if('script'===type){let inlineTemplate=document.getElementById(template);if(inlineTemplate&&inlineTemplate.innerHTML){parse(inlineTemplate.innerHTML,element);} | ||
else{element.innerHTML='<span style="color: red">Missing template "'+template+'"</span>';} | ||
return;} | ||
http.get(template).then(function(element){return function(data){parse(data,element);}}(element),function(){throw new Error('Failed loading template');});}}); |
{ | ||
"name": "litespeed.js", | ||
"version": "v0.2.6", | ||
"version": "v0.2.7", | ||
"private": false, | ||
@@ -5,0 +5,0 @@ "main": "gulpfile.js", |
@@ -29,3 +29,3 @@ <p> | ||
```html | ||
<script src="https://cdn.jsdelivr.net/npm/litespeed.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/litespeed.js@v0.2.6"></script> | ||
``` | ||
@@ -32,0 +32,0 @@ |
@@ -88,2 +88,3 @@ /** | ||
let instance = (typeof service.object === 'function') ? this.resolve(service.object) : service.object; | ||
let skip = false; | ||
@@ -94,2 +95,4 @@ if(name !== 'window' && name !== 'document' && name !== 'element' && typeof instance === 'object' && instance !== null) { | ||
watch: function() {}, | ||
get: function(obj, prop) { | ||
@@ -101,2 +104,6 @@ | ||
if(prop === "__watch") { | ||
return this.watch; | ||
} | ||
if (typeof obj[prop] === 'object' && obj[prop] !== null) { | ||
@@ -115,2 +122,10 @@ let handler = Object.assign({}, this); | ||
set: function(obj, prop, value, receiver) { | ||
if(prop === "__name") { | ||
return this.name = value; | ||
} | ||
if(prop === "__watch") { | ||
return this.watch = value; | ||
} | ||
obj[prop] = value; | ||
@@ -120,6 +135,22 @@ | ||
console.log('updated', path + '.changed', value); | ||
//console.log('updated', path + '.changed', value); | ||
document.dispatchEvent(new CustomEvent(path + '.changed')); | ||
if(skip) { // Avoid endless loop, when watch callback triggers changes itself | ||
return true; | ||
} | ||
skip = true; | ||
container.set('$prop', prop, true); | ||
container.set('$value', value, true); | ||
container.resolve(this.watch); | ||
container.set('$prop', null, true); | ||
container.set('$value', null, true); | ||
skip = false; | ||
return true; | ||
@@ -203,6 +234,17 @@ }, | ||
prefix = (prefix) ? prefix : container.get('$prefix'); | ||
document.addEventListener(path.replace(as, prefix) + '.changed', function () { | ||
console.log('update callback triggered'); | ||
let event = path.replace(as, prefix) + '.changed'; | ||
let printer = function () { | ||
if(!document.body.contains(element)) { // Clean DOM | ||
console.log('cleaned dom'); | ||
element = null; | ||
document.removeEventListener(event, printer, false); | ||
return false; | ||
} | ||
callback(); | ||
}); | ||
}; | ||
document.addEventListener(event, printer); | ||
}, | ||
@@ -209,0 +251,0 @@ setCachePrefix: setCachePrefix, |
@@ -6,3 +6,3 @@ /** | ||
*/ | ||
container.set('filter', function() { | ||
container.set('filter', function(container) { | ||
let filters = {}; | ||
@@ -16,3 +16,4 @@ | ||
let apply = function (value, name) { | ||
return filters[name](value); | ||
container.set('$value', value, true); | ||
return container.resolve(filters[name]); | ||
}; | ||
@@ -19,0 +20,0 @@ |
@@ -77,2 +77,3 @@ container.set('state', function(window) { | ||
state.params = getJsonFromUrl(window.location.search); | ||
state.hash = window.location.hash; | ||
}; | ||
@@ -125,3 +126,3 @@ | ||
let match = function(location) { | ||
let url = location.pathname; | ||
let url = location.pathname + ((location.hash) ? location.hash : ''); | ||
@@ -254,3 +255,4 @@ states.sort(function(a, b){ return b.path.length - a.path.length;}); // order by length | ||
setPrevious: setPrevious, | ||
params: getJsonFromUrl(window.location.search) | ||
params: getJsonFromUrl(window.location.search), | ||
hash: window.location.hash | ||
}; | ||
@@ -257,0 +259,0 @@ |
container.get('view').add({ | ||
selector: 'data-ls-attrs', | ||
controller: function(element, expression, $as, $prefix) { | ||
let attrs = element.dataset['lsAttrs'].trim().split(','); | ||
let attrs = element.getAttribute('data-ls-attrs').trim().split(','); | ||
let paths = []; | ||
@@ -6,0 +6,0 @@ let check = function () { |
@@ -23,2 +23,4 @@ container.get('view').add({ | ||
if('checkbox' === type) { | ||
value = JSON.parse(value); | ||
if(typeof value === 'boolean') { | ||
@@ -36,3 +38,5 @@ if(value === true) { | ||
element.addEventListener('change', function () { | ||
container.path(path, element.checked, $as, $prefix); | ||
for(let i = 0; i < paths.length; i++) { | ||
container.path(paths[i], element.checked, $as, $prefix); | ||
} | ||
}); | ||
@@ -63,12 +67,17 @@ } | ||
return function () { | ||
container.path(path, element.value, as, prefix); | ||
for(let i = 0; i < paths.length; i++) { | ||
container.path(paths[i], element.value, as, prefix); | ||
} | ||
} | ||
})($as, $prefix); | ||
let path = element.dataset['lsBind']; | ||
let result = container.path(path); | ||
let syntax = element.getAttribute('data-ls-bind'); | ||
let result = expression.parse(syntax, null, $as, $prefix); | ||
let paths = expression.getPaths(); | ||
container.bind(element, path, function () { | ||
echo(container.path(path, undefined, $as, $prefix), false); | ||
}); | ||
for(let i = 0; i < paths.length; i++) { | ||
container.bind(element, paths[i], function () { | ||
echo(expression.parse(syntax, null, $as, $prefix), false); | ||
}); | ||
} | ||
@@ -75,0 +84,0 @@ echo(result, true); |
@@ -5,4 +5,4 @@ container.get('view').add({ | ||
let result = ''; | ||
let syntax = element.dataset['lsIf'] || ''; | ||
let debug = element.dataset['debug'] || false; | ||
let syntax = element.getAttribute('data-ls-if') || ''; | ||
let debug = element.getAttribute('data-debug') || false; | ||
let paths = []; | ||
@@ -9,0 +9,0 @@ let check = function () { |
@@ -7,3 +7,3 @@ container.get('view').add({ | ||
controller: function(element, view, container, window) { | ||
let expr = element.dataset['lsLoop']; | ||
let expr = element.getAttribute('data-ls-loop'); | ||
let echo = function() { | ||
@@ -16,2 +16,4 @@ let array = container.path(expr); | ||
element.removeChild(element.lastChild); | ||
element.lastChild = null; | ||
} | ||
@@ -42,6 +44,6 @@ | ||
container.set(element.dataset['lsAs'], container.path(context), true); | ||
container.set(element.getAttribute('data-ls-as'), container.path(context), true); | ||
container.set('$index', index, true); | ||
container.set('$prefix', context, true); | ||
container.set('$as', element.dataset['lsAs'], true); | ||
container.set('$as', element.getAttribute('data-ls-as'), true); | ||
@@ -65,5 +67,8 @@ view.render(children[prop]); | ||
document.addEventListener(expr + '.changed', echo); | ||
document.addEventListener(expr + '.length.changed', echo); | ||
container.bind(element, expr, echo); | ||
container.bind(element, expr + '.length', echo); | ||
//document.addEventListener(expr + '.changed', echo); | ||
//document.addEventListener(expr + '.length.changed', echo); | ||
} | ||
}); |
@@ -6,4 +6,4 @@ container.get('view').add({ | ||
controller: function(element, view, http, expression, document) { | ||
let template = expression.parse(element.dataset['lsTemplate']); | ||
let type = element.dataset['type'] || 'url'; | ||
let template = expression.parse(element.getAttribute('data-ls-template')); | ||
let type = element.getAttribute('data-type') || 'url'; | ||
@@ -10,0 +10,0 @@ element.innerHTML = ''; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
314788
2384