From 3db7444bcc1cf7ca49a63916d6480ce2be5f7288 Mon Sep 17 00:00:00 2001 From: eldadfux Date: Thu, 23 May 2019 00:03:37 +0300 Subject: [PATCH] Updated readme file --- README.new.md | 42 + app/views/console/comps/header.phtml | 3 +- public/dist/scripts/app-all.js | 48 +- public/dist/scripts/app.js | 48 +- public/scripts/dependencies/litespeed.js | 942 ++++++++++++++++++++--- public/scripts/views/general/switch.js | 2 +- public/scripts/views/service.js | 1 - 7 files changed, 917 insertions(+), 169 deletions(-) diff --git a/README.new.md b/README.new.md index d0eb5b485d..2eb34d6687 100644 --- a/README.new.md +++ b/README.new.md @@ -104,6 +104,48 @@ Getting started with Appwrite is as easy as creating a new project, choosing you ## SDKs +Currently we are supporting a few SDK libraries and we are constantly working on adding new ones. + +Below is a list of currently supported platforms and languages. If you wish to help us add support to your platform of choice you can go over to our [PHP SDK Generator](https://github.com/appwrite/php-sdk-generator) project and view our contribution guide. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FrameworkLanguage / PlatformMaintainersOfficial?
*[PHP](https://github.com/appwrite/sdk-for-php)Appwrite Team
*[Javascript](https://github.com/appwrite/sdk-for-js)Appwrite Team
*[Ruby](https://github.com/appwrite/sdk-for-ruby)Appwrite Team
*[Python](https://github.com/appwrite/sdk-for-python)Appwrite Team
+ ## Contributing All code contributions - including those of people having commit access - must go through a pull request and approved by a core developer before being merged. This is to ensure proper review of all the code. diff --git a/app/views/console/comps/header.phtml b/app/views/console/comps/header.phtml index 6f1350f6bd..5759d583e4 100644 --- a/app/views/console/comps/header.phtml +++ b/app/views/console/comps/header.phtml @@ -1,4 +1,3 @@ -
diff --git a/public/dist/scripts/app-all.js b/public/dist/scripts/app-all.js index 3af2ad5fde..653275cff7 100644 --- a/public/dist/scripts/app-all.js +++ b/public/dist/scripts/app-all.js @@ -1949,8 +1949,7 @@ if(service.instance){return service.instance;} let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;let skip=false;if(service.watch&&name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){let handler={name:service.name,watch:function(){},get:function(target,key){if(key==="__name"){return this.name;} if(key==="__watch"){return this.watch;} if(key==="__proxy"){return true;} -if(typeof target[key]==='object'&&target[key]!==null&&!target[key].__proxy){let handler=Object.assign({},this);handler.name=handler.name+'.'+key;return new Proxy(target[key],handler)} -else{return target[key];}},set:function(target,key,value,receiver){if(key==="__name"){return this.name=value;} +if(typeof target[key]==='object'&&target[key]!==null&&!target[key].__proxy){let handler=Object.assign({},this);handler.name=handler.name+'.'+key;return new Proxy(target[key],handler)}else{return target[key];}},set:function(target,key,value,receiver){if(key==="__name"){return this.name=value;} if(key==="__watch"){return this.watch=value;} target[key]=value;let path=receiver.__name+'.'+key;document.dispatchEvent(new CustomEvent(path+'.changed'));if(skip){return true;} skip=true;container.set('$prop',key,true);container.set('$value',value,true);container.resolve(this.watch);container.set('$key',null,true);container.set('$value',null,true);skip=false;return true;},};instance=new Proxy(instance,handler);} @@ -1960,8 +1959,7 @@ let self=this;let FN_ARGS=/^function\s*[^\(]*\(\s*([^\)]*)\)/m;let text=target.t object=object[path.shift()];} if(value){object[path.shift()]=value;return true;} if(!object){return null;} -let shift=path.shift();if(!shift){result=object;} -else{return object[shift];} +let shift=path.shift();if(!shift){result=object;}else{return object[shift];} return result;};let 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 service=event.split('.').slice(0,1).pop();listeners[service]=listeners[service]||{};listeners[service][event]=true;let printer=function(){if(!document.body.contains(element)){element=null;document.removeEventListener(event,printer,false);return false;} callback();};document.addEventListener(event,printer);};let container={set:set,get:get,resolve:resolve,path:path,bind:bind,stock:stock,listeners:listeners,};set('container',container,true,false,false);return container;}();window.ls.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');} @@ -1970,8 +1968,7 @@ if(typeof url!=='string'){throw new Error('var url must be of type string');} for(i=0;i-1?part.substr(0,eq):part;let val=eq>-1?decodeURIComponent(part.substr(eq+1)):'';let from=key.indexOf('[');if(from===-1){result[decodeURIComponent(key)]=val;} -else{let to=key.indexOf(']');let index=decodeURIComponent(key.substring(from+1,to));key=decodeURIComponent(key.substring(0,from));if(!result[key]){result[key]=[];} -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),hash:window.location.hash};return state;},true,true);window.ls.container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix,cast=false){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);} +part=part.split('+').join(' ');let eq=part.indexOf('=');let key=eq>-1?part.substr(0,eq):part;let val=eq>-1?decodeURIComponent(part.substr(eq+1)):'';let from=key.indexOf('[');if(from===-1){result[decodeURIComponent(key)]=val;}else{let to=key.indexOf(']');let index=decodeURIComponent(key.substring(from+1,to));key=decodeURIComponent(key.substring(0,from));if(!result[key]){result[key]=[];} +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),hash:window.location.hash};return state;},true,true);window.ls.container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix,cast=false){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;result=(((typeof result==='object')||(typeof result==='string'))&&cast)?'\''+result+'\'':result;if(reference.length>=2){for(let i=1;i/g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});window.ls=window.ls||{};window.ls.container.set('window',window,true,false,false).set('document',window.document,true,false,false).set('element',window.document,true,false,false);window.ls.run=function(window){try{this.view.render(window.document);} -catch(error){let handler=window.ls.container.resolve(this.error);handler(error);}};window.ls.error=function(){return function(error){console.error('ls-error',error.message,error.stack,error.toString());}};window.ls.router=window.ls.container.get('router');window.ls.view=window.ls.container.get('view');window.ls.filter=window.ls.container.get('filter');window.ls.container.get('view').add({selector:'data-ls-router',repeat:false,controller:function(element,window,document,view,router){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},};let init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} +return value.replace(/&/g,'&').replace(//g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});window.ls=window.ls||{};window.ls.container.set('window',window,true,false,false).set('document',window.document,true,false,false).set('element',window.document,true,false,false);window.ls.run=function(window){try{this.view.render(window.document);}catch(error){let handler=window.ls.container.resolve(this.error);handler(error);}};window.ls.error=function(){return function(error){console.error('ls-error',error.message,error.stack,error.toString());}};window.ls.router=window.ls.container.get('router');window.ls.view=window.ls.container.get('view');window.ls.filter=window.ls.container.get('filter');window.ls.container.get('view').add({selector:'data-ls-router',repeat:false,controller:function(element,window,document,view,router){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},};let init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} router.reset();if(null===route){return;} -scope.template=(undefined!==route.view.template)?route.view.template:null;scope.controller=(undefined!==route.view.controller)?route.view.controller:function(){};document.dispatchEvent(new CustomEvent('state-change'));if(firstFromServer&&null===router.getPrevious()){scope.template='';} -else if(null!==router.getPrevious()){view.render(element);} +scope.template=(undefined!==route.view.template)?route.view.template:null;scope.controller=(undefined!==route.view.controller)?route.view.controller:function(){};document.dispatchEvent(new CustomEvent('state-change'));if(firstFromServer&&null===router.getPrevious()){scope.template='';}else if(null!==router.getPrevious()){view.render(element);} document.dispatchEvent(new CustomEvent('state-changed'));};let findParent=function(tagName,el){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;} while(el=el.parentNode){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;}} return null;};element.setAttribute('data-ls-scope','');view.add(scope);document.addEventListener('click',function(event){let target=findParent('a',event.target);if(!target){return false;} @@ -2023,25 +2014,20 @@ event.preventDefault();if(window.location===target.href){return false;} route.view.state=(undefined===route.view.state)?true:route.view.state;if(true===route.view.state){if(router.getPrevious()&&router.getPrevious().view&&(router.getPrevious().view.scope!==route.view.scope)){window.location.href=target.href;return false;} window.history.pushState({},'Unknown',target.href);} init(route);return true;});window.addEventListener('popstate',function(){init(router.match(window.location));});window.addEventListener('hashchange',function(){init(router.match(window.location));});init(router.match(window.location));}});window.ls.container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,container,$as,$prefix){let attrs=element.getAttribute('data-ls-attrs').trim().split(',');let paths=[];let check=function(){for(let i=0;i';} +if(value){element.value=value;} +container.set('$index',null,true,false,false);container.set('$prefix','',true,false,false);container.set('$as','',true,false,false);};let template=(element.children.length===1)?element.children[0]:window.document.createElement('li');echo();container.bind(element,expr,echo);container.bind(element,expr+'.length',echo);}});window.ls.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='Missing template "'+template+'"';} return;} http.get(template).then(function(element){return function(data){parse(data,element);}}(element),function(){throw new Error('Failed loading template');});}});window.ls.error=function(){return function(error){alert(error);console.error('ERROR-APP',error);}};window.addEventListener('error',function(event){alert(event.error.message);console.error('ERROR-EVENT:',event.error.message,event.error.stack);});document.addEventListener('logout',function(){if(window.ls.router.getCurrent().view.scope==='console'){state.change('/auth/signin');}});document.addEventListener('http-get-401',function(){document.dispatchEvent(new CustomEvent('logout'));},true);(function(window){"use strict";window.ls.container.set('alerts',function(window){let service={};let counter=0;let event=new CustomEvent('alerted',{bubbles:false,cancelable:true});service.list=[];service.remove=function(id){let message=this.get(id);if(message&&message.remove&&typeof message.remove==='function'){message.remove();} this.list=this.list.filter(function(obj){return obj.id!==parseInt(id);});window.document.dispatchEvent(event);};service.get=function(id){id=parseInt(id);let result=this.list.filter(function(obj){return obj.id===id;});if(result[0]){return result[0];} @@ -2219,7 +2205,7 @@ if(!element){return;} try{container.set(service.replace('.','-'),JSON.parse(data),true,true);if(debug)console.log('%cservice ready: "'+service.replace('.','-')+'"','color:green');if(debug)console.log('%cservice:','color:blue',container.get(service.replace('.','-')));}catch(e){container.set(service.replace('.','-'),{},true);} element.$lsSkip=false;view.render(element);},function(exception){if(loaderId!==null){alerts.remove(loaderId);} if(!element){return;}});};let events=event.trim().split(',');for(let y=0;y-1?part.substr(0,eq):part;let val=eq>-1?decodeURIComponent(part.substr(eq+1)):'';let from=key.indexOf('[');if(from===-1){result[decodeURIComponent(key)]=val;} -else{let to=key.indexOf(']');let index=decodeURIComponent(key.substring(from+1,to));key=decodeURIComponent(key.substring(0,from));if(!result[key]){result[key]=[];} -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),hash:window.location.hash};return state;},true,true);window.ls.container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix,cast=false){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);} +part=part.split('+').join(' ');let eq=part.indexOf('=');let key=eq>-1?part.substr(0,eq):part;let val=eq>-1?decodeURIComponent(part.substr(eq+1)):'';let from=key.indexOf('[');if(from===-1){result[decodeURIComponent(key)]=val;}else{let to=key.indexOf(']');let index=decodeURIComponent(key.substring(from+1,to));key=decodeURIComponent(key.substring(0,from));if(!result[key]){result[key]=[];} +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),hash:window.location.hash};return state;},true,true);window.ls.container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix,cast=false){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;result=(((typeof result==='object')||(typeof result==='string'))&&cast)?'\''+result+'\'':result;if(reference.length>=2){for(let i=1;i/g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});window.ls=window.ls||{};window.ls.container.set('window',window,true,false,false).set('document',window.document,true,false,false).set('element',window.document,true,false,false);window.ls.run=function(window){try{this.view.render(window.document);} -catch(error){let handler=window.ls.container.resolve(this.error);handler(error);}};window.ls.error=function(){return function(error){console.error('ls-error',error.message,error.stack,error.toString());}};window.ls.router=window.ls.container.get('router');window.ls.view=window.ls.container.get('view');window.ls.filter=window.ls.container.get('filter');window.ls.container.get('view').add({selector:'data-ls-router',repeat:false,controller:function(element,window,document,view,router){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},};let init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} +return value.replace(/&/g,'&').replace(//g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});window.ls=window.ls||{};window.ls.container.set('window',window,true,false,false).set('document',window.document,true,false,false).set('element',window.document,true,false,false);window.ls.run=function(window){try{this.view.render(window.document);}catch(error){let handler=window.ls.container.resolve(this.error);handler(error);}};window.ls.error=function(){return function(error){console.error('ls-error',error.message,error.stack,error.toString());}};window.ls.router=window.ls.container.get('router');window.ls.view=window.ls.container.get('view');window.ls.filter=window.ls.container.get('filter');window.ls.container.get('view').add({selector:'data-ls-router',repeat:false,controller:function(element,window,document,view,router){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},};let init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} router.reset();if(null===route){return;} -scope.template=(undefined!==route.view.template)?route.view.template:null;scope.controller=(undefined!==route.view.controller)?route.view.controller:function(){};document.dispatchEvent(new CustomEvent('state-change'));if(firstFromServer&&null===router.getPrevious()){scope.template='';} -else if(null!==router.getPrevious()){view.render(element);} +scope.template=(undefined!==route.view.template)?route.view.template:null;scope.controller=(undefined!==route.view.controller)?route.view.controller:function(){};document.dispatchEvent(new CustomEvent('state-change'));if(firstFromServer&&null===router.getPrevious()){scope.template='';}else if(null!==router.getPrevious()){view.render(element);} document.dispatchEvent(new CustomEvent('state-changed'));};let findParent=function(tagName,el){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;} while(el=el.parentNode){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;}} return null;};element.setAttribute('data-ls-scope','');view.add(scope);document.addEventListener('click',function(event){let target=findParent('a',event.target);if(!target){return false;} @@ -81,25 +72,20 @@ event.preventDefault();if(window.location===target.href){return false;} route.view.state=(undefined===route.view.state)?true:route.view.state;if(true===route.view.state){if(router.getPrevious()&&router.getPrevious().view&&(router.getPrevious().view.scope!==route.view.scope)){window.location.href=target.href;return false;} window.history.pushState({},'Unknown',target.href);} init(route);return true;});window.addEventListener('popstate',function(){init(router.match(window.location));});window.addEventListener('hashchange',function(){init(router.match(window.location));});init(router.match(window.location));}});window.ls.container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,container,$as,$prefix){let attrs=element.getAttribute('data-ls-attrs').trim().split(',');let paths=[];let check=function(){for(let i=0;i';} +if(value){element.value=value;} +container.set('$index',null,true,false,false);container.set('$prefix','',true,false,false);container.set('$as','',true,false,false);};let template=(element.children.length===1)?element.children[0]:window.document.createElement('li');echo();container.bind(element,expr,echo);container.bind(element,expr+'.length',echo);}});window.ls.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='Missing template "'+template+'"';} return;} http.get(template).then(function(element){return function(data){parse(data,element);}}(element),function(){throw new Error('Failed loading template');});}});window.ls.error=function(){return function(error){alert(error);console.error('ERROR-APP',error);}};window.addEventListener('error',function(event){alert(event.error.message);console.error('ERROR-EVENT:',event.error.message,event.error.stack);});document.addEventListener('logout',function(){if(window.ls.router.getCurrent().view.scope==='console'){state.change('/auth/signin');}});document.addEventListener('http-get-401',function(){document.dispatchEvent(new CustomEvent('logout'));},true);(function(window){"use strict";window.ls.container.set('alerts',function(window){let service={};let counter=0;let event=new CustomEvent('alerted',{bubbles:false,cancelable:true});service.list=[];service.remove=function(id){let message=this.get(id);if(message&&message.remove&&typeof message.remove==='function'){message.remove();} this.list=this.list.filter(function(obj){return obj.id!==parseInt(id);});window.document.dispatchEvent(event);};service.get=function(id){id=parseInt(id);let result=this.list.filter(function(obj){return obj.id===id;});if(result[0]){return result[0];} @@ -277,7 +263,7 @@ if(!element){return;} try{container.set(service.replace('.','-'),JSON.parse(data),true,true);if(debug)console.log('%cservice ready: "'+service.replace('.','-')+'"','color:green');if(debug)console.log('%cservice:','color:blue',container.get(service.replace('.','-')));}catch(e){container.set(service.replace('.','-'),{},true);} element.$lsSkip=false;view.render(element);},function(exception){if(loaderId!==null){alerts.remove(loaderId);} if(!element){return;}});};let events=event.trim().split(',');for(let y=0;y 1) { + if (!object) { + return null; + } + object = object[path.shift()]; + } + if (value) { + object[path.shift()] = value; + return true; + } + if (!object) { + return null; + } + let shift = path.shift(); + if (!shift) { + result = object; + } else { + return object[shift]; + } + return result; + }; + let 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 service = event.split('.').slice(0, 1).pop(); + listeners[service] = listeners[service] || {}; + listeners[service][event] = true; + let printer = function () { + if (!document.body.contains(element)) { + element = null; + document.removeEventListener(event, printer, false); + return false; + } + callback(); + }; + document.addEventListener(event, printer); + }; + let container = {set: set, get: get, resolve: resolve, path: path, bind: bind, stock: stock, listeners: listeners,}; + set('container', container, true, false, false); + return container; +}(); +window.ls.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'); + } + if (typeof headers !== 'object') { + throw new Error('var headers must be of type object'); + } + if (typeof url !== 'string') { + throw new Error('var url must be of type string'); + } + for (i = 0; i < globalParams.length; i++) { + url = addParam(url, globalParams[i].key, globalParams[i].value); + } + return new Promise(function (resolve, reject) { + let xmlhttp = new XMLHttpRequest(); + xmlhttp.open(method, url, true); + xmlhttp.setRequestHeader('Ajax', '1'); + for (i = 0; i < globalHeaders.length; i++) { + xmlhttp.setRequestHeader(globalHeaders[i].key, globalHeaders[i].value); + } + for (let key in headers) { + if (headers.hasOwnProperty(key)) { + xmlhttp.setRequestHeader(key, headers[key]); + } + } + xmlhttp.onload = function () { + if (4 === xmlhttp.readyState && 200 === xmlhttp.status) { + resolve(xmlhttp.response); + } else { + document.dispatchEvent(new CustomEvent('http-' + method.toLowerCase() + '-' + xmlhttp.status)); + reject(new Error(xmlhttp.statusText)); + } + }; + if (progress) { + xmlhttp.addEventListener('progress', progress); + xmlhttp.upload.addEventListener('progress', progress, false); + } + xmlhttp.onerror = function () { + reject(new Error("Network Error")); + }; + xmlhttp.send(payload); + }) + }; + return { + 'get': function (url) { + return request('GET', url, {}, '') + }, 'post': function (url, headers, payload) { + return request('POST', url, headers, payload) + }, 'put': function (url, headers, payload) { + return request('PUT', url, headers, payload) + }, 'patch': function (url, headers, payload) { + return request('PATCH', url, headers, payload) + }, 'delete': function (url) { + return request('DELETE', url, {}, '') + }, 'addGlobalParam': function (key, value) { + globalParams.push({key: key, value: value}); + }, 'addGlobalHeader': function (key, value) { + globalHeaders.push({key: key, value: value}); + } + } +}, true, false); +window.ls.container.set('cookie', function (document) { + function get(name) { + let value = "; " + document.cookie, parts = value.split("; " + name + "="); + if (parts.length === 2) { + return parts.pop().split(";").shift(); + } + return null; + } -window.ls=window.ls||{};window.ls.container=function(){let stock={};let listeners={};let set=function(name,object,singleton,watch=true){if(typeof name!=='string'){throw new Error('var name must be of type string');} - if(typeof singleton!=='boolean'){throw new Error('var singleton "'+singleton+'" of service "'+name+'" must be of type boolean');} - stock[name]={name:name,object:object,singleton:singleton,instance:null,watch:watch,};let binds=listeners[name]||{};for(let key in binds){if(binds.hasOwnProperty(key)){document.dispatchEvent(new CustomEvent(key));}} - return this;};let get=function(name){let service=(undefined!==stock[name])?stock[name]:null;if(null==service){return null;} - if(service.instance){return service.instance;} - let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;let skip=false;if(service.watch&&name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){let handler={name:service.name,watch:function(){},get:function(target,key){if(key==="__name"){return this.name;} - if(key==="__watch"){return this.watch;} - if(key==="__proxy"){return true;} - if(typeof target[key]==='object'&&target[key]!==null&&!target[key].__proxy){let handler=Object.assign({},this);handler.name=handler.name+'.'+key;return new Proxy(target[key],handler)} - else{return target[key];}},set:function(target,key,value,receiver){if(key==="__name"){return this.name=value;} - if(key==="__watch"){return this.watch=value;} - target[key]=value;let path=receiver.__name+'.'+key;document.dispatchEvent(new CustomEvent(path+'.changed'));if(skip){return true;} - skip=true;container.set('$prop',key,true);container.set('$value',value,true);container.resolve(this.watch);container.set('$key',null,true);container.set('$value',null,true);skip=false;return true;},};instance=new Proxy(instance,handler);} - if(service.singleton){service.instance=instance;} - return instance;};let resolve=function(target){if(!target){return function(){};} - let self=this;let FN_ARGS=/^function\s*[^\(]*\(\s*([^\)]*)\)/m;let text=target.toString()||'';let args=text.match(FN_ARGS)[1].split(',');return target.apply(target,args.map(function(value){return self.get(value.trim());}));};let path=function(path,value,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');path=path.replace(as+'.',prefix+'.').split('.');let name=path.shift();let object=this.get(name);let result=null;while(path.length>1){if(!object){return null;} - object=object[path.shift()];} - if(value){object[path.shift()]=value;return true;} - if(!object){return null;} - let shift=path.shift();if(!shift){result=object;} - else{return object[shift];} - return result;};let 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 service=event.split('.').slice(0,1).pop();listeners[service]=listeners[service]||{};listeners[service][event]=true;let printer=function(){if(!document.body.contains(element)){element=null;document.removeEventListener(event,printer,false);return false;} - callback();};document.addEventListener(event,printer);};let container={set:set,get:get,resolve:resolve,path:path,bind:bind,stock:stock,listeners:listeners,};set('container',container,true,false,false);return container;}();window.ls.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');} - if(typeof headers!=='object'){throw new Error('var headers must be of type object');} - if(typeof url!=='string'){throw new Error('var url must be of type string');} - for(i=0;i-1?part.substr(0,eq):part;let val=eq>-1?decodeURIComponent(part.substr(eq+1)):'';let from=key.indexOf('[');if(from===-1){result[decodeURIComponent(key)]=val;} - else{let to=key.indexOf(']');let index=decodeURIComponent(key.substring(from+1,to));key=decodeURIComponent(key.substring(0,from));if(!result[key]){result[key]=[];} - 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),hash:window.location.hash};return state;},true,true);window.ls.container.set('expression',function(container,filter,$as,$prefix){let reg=/(\{{.*?\}})/gi;let paths=[];return{parse:function(string,def,as,prefix,cast=false){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;result=(((typeof result==='object')||(typeof result==='string'))&&cast)?'\''+result+'\'':result;if(reference.length>=2){for(let i=1;i/g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});window.ls=window.ls||{};window.ls.container.set('window',window,true,false,false).set('document',window.document,true,false,false).set('element',window.document,true,false,false);window.ls.run=function(window){try{this.view.render(window.document);} -catch(error){let handler=window.ls.container.resolve(this.error);handler(error);}};window.ls.error=function(){return function(error){console.error('ls-error',error.message,error.stack,error.toString());}};window.ls.router=window.ls.container.get('router');window.ls.view=window.ls.container.get('view');window.ls.filter=window.ls.container.get('filter');window.ls.container.get('view').add({selector:'data-ls-router',repeat:false,controller:function(element,window,document,view,router){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},};let init=function(route){window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} - router.reset();if(null===route){return;} - scope.template=(undefined!==route.view.template)?route.view.template:null;scope.controller=(undefined!==route.view.controller)?route.view.controller:function(){};document.dispatchEvent(new CustomEvent('state-change'));if(firstFromServer&&null===router.getPrevious()){scope.template='';} - else if(null!==router.getPrevious()){view.render(element);} - document.dispatchEvent(new CustomEvent('state-changed'));};let findParent=function(tagName,el){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;} - while(el=el.parentNode){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;}} - return null;};element.setAttribute('data-ls-scope','');view.add(scope);document.addEventListener('click',function(event){let target=findParent('a',event.target);if(!target){return false;} - if(!target.href){return false;} - if((event.metaKey)){return false;} - if((target.hasAttribute('target'))&&('_blank'===target.getAttribute('target'))){return false;} - if(target.hostname!==window.location.hostname){return false;} - let route=router.match(target);if(null===route){return false;} - event.preventDefault();if(window.location===target.href){return false;} - route.view.state=(undefined===route.view.state)?true:route.view.state;if(true===route.view.state){if(router.getPrevious()&&router.getPrevious().view&&(router.getPrevious().view.scope!==route.view.scope)){window.location.href=target.href;return false;} - window.history.pushState({},'Unknown',target.href);} - init(route);return true;});window.addEventListener('popstate',function(){init(router.match(window.location));});window.addEventListener('hashchange',function(){init(router.match(window.location));});init(router.match(window.location));}});window.ls.container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,container,$as,$prefix){let attrs=element.getAttribute('data-ls-attrs').trim().split(',');let paths=[];let check=function(){for(let i=0;i';} - return;} - http.get(template).then(function(element){return function(data){parse(data,element);}}(element),function(){throw new Error('Failed loading template');});}}); \ No newline at end of file + function set(name, value, days) { + let date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + let expires = (0 < days) ? 'expires=' + date.toUTCString() : 'expires=0'; + document.cookie = name + "=" + value + ";" + expires + ";path=/"; + return this; + } + + return {'get': get, 'set': set} +}, true, false); +window.ls.container.set('view', function (http, container) { + let stock = {}; + let execute = function (view, node, container) { + container.set('element', node, true, false, false); + container.resolve(view.controller); + if (true !== view.repeat) { + node.removeAttribute(view.selector); + } + }; + let parse = function (node, skip) { + 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) { + return; + } + if (attrs && attrsLen) { + for (let x = 0; x < attrsLen; x++) { + if (node.$lsSkip === true) { + break; + } + let pointer = (!/Edge/.test(navigator.userAgent)) ? x : (attrsLen - 1) - x; + let length = attrsLen; + let attr = attrs[pointer]; + if (!stock[attr]) { + continue; + } + let comp = stock[attr]; + if (typeof comp.template === "function") { + comp.template = container.resolve(comp.template); + } + if (!comp.template) { + (function (comp, node, container) { + execute(comp, node, container); + })(comp, node, container); + if (length !== attrsLen) { + x--; + } + continue; + } + node.classList.remove('load-end'); + node.classList.add('load-start'); + node.$lsSkip = true; + 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(comp, node, container); + })(comp, node, container); + parse(node, true); + } + }(node, comp), function (error) { + throw new Error('Failed to load comp template: ' + error.message); + }); + } + } + } + if (true === node.$lsSkip) { + return; + } + let list = (node) ? node.childNodes : []; + if (node.$lsSkip === true) { + list = []; + } + for (let i = 0; i < list.length; i++) { + let child = list[i]; + parse(child); + } + }; + return { + stock: stock, 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: function (element) { + parse(element); + element.dispatchEvent(new window.Event('rendered', {bubbles: false})); + } + } +}, true, false); +window.ls.container.set('router', 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); + 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 + ((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]; + value.path = (value.path.substring(0, 1) !== '/') ? location.pathname + value.path : value.path; + let match = new RegExp("^" + value.path.replace(/:[^\s/]+/g, '([\\w-]+)') + "$"); + let found = url.match(match); + if (found) { + previous = current; + current = value; + return value; + } + } + return null + }; + let change = function (URL, replace) { + if (!replace) { + window.history.pushState({}, '', URL); + } else { + window.history.replaceState({}, '', URL); + } + window.dispatchEvent(new PopStateEvent('popstate', {})); + return this; + }; + let reload = function () { + return change(window.location.href); + }; + let getJsonFromUrl = function (URL) { + let query; + if (URL) { + let pos = location.href.indexOf('?'); + if (pos === -1) return []; + query = location.href.substr(pos + 1); + } else { + query = location.search.substr(1); + } + let result = {}; + query.split('&').forEach(function (part) { + if (!part) { + return; + } + part = part.split('+').join(' '); + let eq = part.indexOf('='); + let key = eq > -1 ? part.substr(0, eq) : part; + let val = eq > -1 ? decodeURIComponent(part.substr(eq + 1)) : ''; + let from = key.indexOf('['); + if (from === -1) { + result[decodeURIComponent(key)] = val; + } else { + let to = key.indexOf(']'); + let index = decodeURIComponent(key.substring(from + 1, to)); + key = decodeURIComponent(key.substring(0, from)); + if (!result[key]) { + result[key] = []; + } + 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), + hash: window.location.hash + }; + return state; +}, true, true); +window.ls.container.set('expression', function (container, filter, $as, $prefix) { + let reg = /(\{{.*?\}})/gi; + let paths = []; + return { + parse: function (string, def, as, prefix, cast = false) { + 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; + result = (((typeof result === 'object') || (typeof result === 'string')) && cast) ? '\'' + result + '\'' : result; + if (reference.length >= 2) { + for (let i = 1; i < reference.length; i++) { + result = filter.apply(reference[i], result); + } + } + return result; + }); + }, getPaths: function () { + return paths; + }, + } +}, true, false); +window.ls.container.set('filter', function (container) { + let filters = {}; + let add = function (name, callback) { + filters[name] = callback; + return this; + }; + let apply = function (name, value) { + container.set('$value', value, true, false, false); + 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, false); +window.ls.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, '/'); +}); +window.ls = window.ls || {}; +window.ls.container.set('window', window, true, false, false).set('document', window.document, true, false, false).set('element', window.document, true, false, false); +window.ls.run = function (window) { + try { + this.view.render(window.document); + } catch (error) { + let handler = window.ls.container.resolve(this.error); + handler(error); + } +}; +window.ls.error = function () { + return function (error) { + console.error('ls-error', error.message, error.stack, error.toString()); + } +}; +window.ls.router = window.ls.container.get('router'); +window.ls.view = window.ls.container.get('view'); +window.ls.filter = window.ls.container.get('filter'); +window.ls.container.get('view').add({ + selector: 'data-ls-router', repeat: false, controller: function (element, window, document, view, router) { + let firstFromServer = (element.getAttribute('data-first-from-server') === 'true'); + let scope = { + selector: 'data-ls-scope', template: false, repeat: true, controller: function () { + }, + }; + let init = function (route) { + window.scrollTo(0, 0); + if (window.document.body.scrollTo) { + window.document.body.scrollTo(0, 0); + } + router.reset(); + if (null === route) { + return; + } + scope.template = (undefined !== route.view.template) ? route.view.template : null; + scope.controller = (undefined !== route.view.controller) ? route.view.controller : function () { + }; + document.dispatchEvent(new CustomEvent('state-change')); + if (firstFromServer && null === router.getPrevious()) { + scope.template = ''; + } else if (null !== router.getPrevious()) { + view.render(element); + } + document.dispatchEvent(new CustomEvent('state-changed')); + }; + let findParent = function (tagName, el) { + if ((el.nodeName || el.tagName).toLowerCase() === tagName.toLowerCase()) { + return el; + } + while (el = el.parentNode) { + if ((el.nodeName || el.tagName).toLowerCase() === tagName.toLowerCase()) { + return el; + } + } + return null; + }; + element.setAttribute('data-ls-scope', ''); + view.add(scope); + document.addEventListener('click', function (event) { + let target = findParent('a', event.target); + if (!target) { + return false; + } + if (!target.href) { + return false; + } + if ((event.metaKey)) { + return false; + } + if ((target.hasAttribute('target')) && ('_blank' === target.getAttribute('target'))) { + return false; + } + if (target.hostname !== window.location.hostname) { + return false; + } + let route = router.match(target); + if (null === route) { + return false; + } + event.preventDefault(); + if (window.location === target.href) { + return false; + } + route.view.state = (undefined === route.view.state) ? true : route.view.state; + if (true === route.view.state) { + if (router.getPrevious() && router.getPrevious().view && (router.getPrevious().view.scope !== route.view.scope)) { + window.location.href = target.href; + return false; + } + window.history.pushState({}, 'Unknown', target.href); + } + init(route); + return true; + }); + window.addEventListener('popstate', function () { + init(router.match(window.location)); + }); + window.addEventListener('hashchange', function () { + init(router.match(window.location)); + }); + init(router.match(window.location)); + } +}); +window.ls.container.get('view').add({ + selector: 'data-ls-attrs', controller: function (element, expression, container, $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]; + let key = expression.parse(attr.substring(0, attr.indexOf('=')), null, $as, $prefix) || null; + paths = paths.concat(expression.getPaths()); + let value = expression.parse(attr.substring(attr.indexOf('=') + 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); + } + } +}); +window.ls.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' || value === 'true' || value === 'false') { + if (value === true || value === 'true') { + element.setAttribute('checked', 'checked'); + element.checked = true; + } else { + element.removeAttribute('checked'); + element.checked = false; + } + 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); + element.addEventListener('change', sync); + } + } 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(); + echo(result, true); + for (let i = 0; i < paths.length; i++) { + container.bind(element, paths[i], function () { + echo(expression.parse(syntax, null, $as, $prefix), false); + }); + } + } +}); +window.ls.container.get('view').add({ + selector: 'data-ls-if', controller: function (element, expression, container, $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, true).replace(/(\r\n|\n|\r)/gm, ' '))); + } catch (error) { + throw new Error('Failed to evaluate expression "' + syntax + ' (resulted with: "' + result + '")": ' + error); + } + if (debug) { + console.info('debug-ls-if result:', result); + } + paths = expression.getPaths(); + element.$lsSkip = !result; + 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); + } + } +}); +window.ls.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 as = element.getAttribute('data-ls-as'); + let echo = function () { + let value = element.value || null; + 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] = template.cloneNode(true); + element.appendChild(children[prop]); + (function (index) { + let context = expr + '.' + index; + container.set(as, container.path(context), true); + container.set('$index', index, true, false, false); + container.set('$prefix', context, true, false, false); + container.set('$as', as, true, false, false); + view.render(children[prop]); + })(prop); + } + + if(value) { + element.value = value; + } + + container.set('$index', null, true, false, false); + container.set('$prefix', '', true, false, false); + container.set('$as', '', true, false, false); + }; + let template = (element.children.length === 1) ? element.children[0] : window.document.createElement('li'); + echo(); + container.bind(element, expr, echo); + container.bind(element, expr + '.length', echo); + } +}); +window.ls.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 = 'Missing template "' + template + '"'; + } + return; + } + http.get(template).then(function (element) { + return function (data) { + parse(data, element); + } + }(element), function () { + throw new Error('Failed loading template'); + }); + } +}); \ No newline at end of file diff --git a/public/scripts/views/general/switch.js b/public/scripts/views/general/switch.js index 47c070e3f1..b6a108449c 100644 --- a/public/scripts/views/general/switch.js +++ b/public/scripts/views/general/switch.js @@ -1,7 +1,7 @@ (function (window) { window.ls.container.get('view').add({ selector: 'data-switch', - controller: function(element, router, window) { + controller: function(element, router, document) { let debug = (element.dataset['debug']); let project = router.params.project || null; diff --git a/public/scripts/views/service.js b/public/scripts/views/service.js index 2af9e29f81..ae5637c07d 100644 --- a/public/scripts/views/service.js +++ b/public/scripts/views/service.js @@ -148,7 +148,6 @@ break; default: document.addEventListener(events[y], exec); - console.log('def', events[y].trim()); } if (debug) console.log('%cregistered: "' + events[y].trim() + '" (' + service + ')', 'color:blue');