Updated LS version
This commit is contained in:
parent
3ba3f53218
commit
647f9eae8e
|
@ -1,7 +1,4 @@
|
|||
<div data-service="projects.get"
|
||||
data-event="project-load"
|
||||
data-name="console-project"
|
||||
data-param-project-id="{{router.params.project}}">
|
||||
<div data-service="projects.get" data-event="project-load" data-name="console-project" data-param-project-id="{{router.params.project}}">
|
||||
</div>
|
||||
|
||||
<header class="clear">
|
||||
|
@ -14,13 +11,9 @@
|
|||
</label>
|
||||
</div>
|
||||
|
||||
<button style="overflow: visible;" class="setup-new tooltip round down" aria-label="Quick Start" data-tooltip="Create a new project"><i class="icon-plus"></i></button>
|
||||
<button style="overflow: visible;" class="project-only setup-new tooltip round down" aria-label="Quick Start" data-tooltip="Create a new project"><i class="icon-plus"></i></button>
|
||||
|
||||
<div class="account-box clear pull-end"
|
||||
data-service="account.get"
|
||||
data-name="account"
|
||||
data-scope="console"
|
||||
data-event="load">
|
||||
<div class="account-box clear pull-end" data-service="account.get" data-name="account" data-scope="console" data-event="load">
|
||||
|
||||
<div class="pull-end console-back">
|
||||
<a href="/console">Back to Console <i class="icon-right-open"></i></a>
|
||||
|
@ -103,33 +96,16 @@
|
|||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="list pull-start project-only"
|
||||
data-service="projects.list"
|
||||
data-event="load"
|
||||
data-name="projects"
|
||||
data-scope="console"
|
||||
data-singleton="true">
|
||||
<div class="list pull-start project-only" data-service="projects.list" data-event="load" data-name="projects" data-scope="console" data-singleton="true">
|
||||
</div>
|
||||
|
||||
<div class=""
|
||||
data-service="geo.get"
|
||||
data-name="geo"
|
||||
data-event="load"
|
||||
data-singleton="true">
|
||||
<div class="" data-service="geo.get" data-name="geo" data-event="load" data-singleton="true">
|
||||
</div>
|
||||
|
||||
<div class=""
|
||||
data-service="geo.countries.list"
|
||||
data-name="geo-countries"
|
||||
data-event="load"
|
||||
data-singleton="true">
|
||||
<div class="" data-service="geo.countries.list" data-name="geo-countries" data-event="load" data-singleton="true">
|
||||
</div>
|
||||
|
||||
<div class=""
|
||||
data-service="geo.countries.phones"
|
||||
data-name="geo-countries-phones"
|
||||
data-event="load"
|
||||
data-singleton="true">
|
||||
<div class="" data-service="geo.countries.phones" data-name="geo-countries-phones" data-event="load" data-singleton="true">
|
||||
</div>
|
||||
|
||||
<div data-ui-modal class="modal close" data-button-alias=".setup-new" data-button-icon="icon-plus" data-button-class="project-only" data-open-event="new-project">
|
||||
|
|
|
@ -59,7 +59,7 @@ $scopes = [ // TODO sync with project list
|
|||
<div class="row thin margin-bottom">
|
||||
<?php foreach ($scopes as $i => $scope) : ?>
|
||||
<div class="col span-6">
|
||||
<input type="checkbox" name="scopes" data-ls-bind="{{key.scopes}}" data-default="{{key.scopes}}" value="<?php echo $scope; ?>" /> <?php echo $scope; ?>
|
||||
<input type="checkbox" name="scopes" data-ls-bind="{{key.scopes}}" value="<?php echo $scope; ?>" /> <?php echo $scope; ?>
|
||||
</div>
|
||||
<?php if (($i + 1) % 2 === 0) : ?>
|
||||
</div>
|
||||
|
@ -69,9 +69,9 @@ $scopes = [ // TODO sync with project list
|
|||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit">Save</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<button type="submit">Save</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@ -85,7 +85,7 @@ $scopes = [ // TODO sync with project list
|
|||
|
||||
<div class="margin-bottom-tiny"><span data-ls-bind="{{key.name}}"></span> <span class="note">(<span data-ls-bind="{{key.scopes.length}}"></span> scopes granted)</span></div>
|
||||
|
||||
<div data-ui-modal class="modal close" data-button-text="Show Secret" data-button-class="link margin-top-small" data-button-icon="icon-right-open">
|
||||
<div data-ui-modal class="modal close" data-button-text="Show Secret" data-button-class="link">
|
||||
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
|
||||
|
||||
<h1>API Key Secret</h1>
|
||||
|
@ -130,11 +130,9 @@ $scopes = [ // TODO sync with project list
|
|||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</div>
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -72,36 +72,7 @@ use Utopia\Locale\Locale;
|
|||
|
||||
<hr />
|
||||
|
||||
<h3>Legal Information</h3>
|
||||
|
||||
<div class="row thin">
|
||||
<div class="col span-6">
|
||||
<label for="legalName">Legal Name</label>
|
||||
<input name="legalName" id="legalName" type="text" autocomplete="off" data-ls-bind="{{console-project.legalName}}" data-forms-text-direction>
|
||||
|
||||
<label for="legalCountry">Country</label>
|
||||
<select id="legalCountry" name="legalCountry" data-ls-options="{{geo-countries}}" data-ls-bind="{{console-project.legalCountry}}"></select>
|
||||
|
||||
<label for="legalCity">City</label>
|
||||
<input name="legalCity" id="legalCity" type="text" autocomplete="off" data-ls-bind="{{console-project.legalCity}}" data-forms-text-direction>
|
||||
</div>
|
||||
|
||||
<div class="col span-6">
|
||||
<label for="legalTaxId">Tax ID</label>
|
||||
<input name="legalTaxId" id="legalTaxId" type="text" autocomplete="off" data-ls-bind="{{console-project.legalTaxId}}" data-forms-text-direction>
|
||||
|
||||
<label for="legalState">State</label>
|
||||
<input name="legalState" id="legalState" type="text" autocomplete="off" data-ls-bind="{{console-project.legalState}}" data-forms-text-direction>
|
||||
|
||||
<label for="legalAddress">Address</label>
|
||||
<input name="legalAddress" id="legalAddress" type="text" autocomplete="off" data-ls-bind="{{console-project.legalAddress}}" data-forms-text-direction>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="" type="submit">Save</button>
|
||||
</div>
|
||||
<button class="" type="submit">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -114,7 +85,7 @@ use Utopia\Locale\Locale;
|
|||
</div>
|
||||
</form>
|
||||
</li>
|
||||
<li data-state="/console/privacy?project={{router.params.project}}">
|
||||
<li data-state="/console/settings/privacy?project={{router.params.project}}">
|
||||
|
||||
<form data-service="projects.update" data-scope="console" data-event="submit" data-param-project-id="{{router.params.project}}" data-success="alert,trigger" data-success-alert="Saved project successfully" data-success-triggers="project.update" data-error="alert" data-error-alert="Failed to update project">
|
||||
<h2>Privacy & Legal</h2>
|
||||
|
|
|
@ -51,7 +51,7 @@ $events = [
|
|||
<div class="row thin margin-bottom">
|
||||
<?php foreach ($events as $i => $event) : ?>
|
||||
<div class="col span-6">
|
||||
<input type="checkbox" name="events" data-ls-bind="<?php echo $event; ?>" data-default="{{webhook.events}}" /> <?php echo $event; ?>
|
||||
<input type="checkbox" name="events" data-ls-bind="{{webhook.events}}" value="<?php echo $event; ?>" /> <?php echo $event; ?>
|
||||
</div>
|
||||
<?php if (($i + 1) % 2 === 0) : ?>
|
||||
</div>
|
||||
|
@ -67,9 +67,9 @@ $events = [
|
|||
<label data-ls-attrs="for=secure-{{webhook.$uid}}">SSL / TLS</label>
|
||||
<p class="note">Certificate verification</p>
|
||||
|
||||
<input name="security" data-ls-attrs="id=secure-yes-{{webhook.$uid}}" type="radio" required data-ls-bind="1" data-default="{{webhook.security}}" /> <span>Enabled</span>
|
||||
<input name="security" data-ls-attrs="id=secure-yes-{{webhook.$uid}}" type="radio" required data-ls-bind="{{webhook.security}}" value="1" /> <span>Enabled</span>
|
||||
|
||||
<input name="security" data-ls-attrs="id=secure-no-{{webhook.$uid}}" type="radio" required data-ls-bind="0" data-default="{{webhook.security}}" /> <span>Disabled</span>
|
||||
<input name="security" data-ls-attrs="id=secure-no-{{webhook.$uid}}" type="radio" required data-ls-bind="{{webhook.security}}" value="0" /> <span>Disabled</span>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
@ -91,11 +91,9 @@ $events = [
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<button type="submit">Save</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</div>
|
||||
<button type="submit">Save</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@ -117,7 +115,7 @@ $events = [
|
|||
</div>
|
||||
|
||||
<div class="clear">
|
||||
<div data-ui-modal class="modal close" data-button-text="Add Webhook">
|
||||
<div data-ui-modal class="modal close box" data-button-text="Add Webhook">
|
||||
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
|
||||
|
||||
<h1>Add Webhook</h1>
|
||||
|
@ -173,11 +171,9 @@ $events = [
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</div>
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
53
public/dist/scripts/app-all.js
vendored
53
public/dist/scripts/app-all.js
vendored
File diff suppressed because one or more lines are too long
53
public/dist/scripts/app.js
vendored
53
public/dist/scripts/app.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/styles/default-ltr.css
vendored
2
public/dist/styles/default-ltr.css
vendored
File diff suppressed because one or more lines are too long
|
@ -1,111 +1,274 @@
|
|||
|
||||
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()=>{};}
|
||||
let self=this;const REGEX_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;const REGEX_FUNCTION_PARAMS=/(?:\s*(?:function\s*[^(]*)?\s*)((?:[^'"]|(?:(?:(['"])(?:(?:.*?[^\\]\2)|\2))))*?)\s*(?=(?:=>)|{)/m;const REGEX_PARAMETERS_VALUES=/\s*([\w\\$]+)\s*(?:=\s*((?:(?:(['"])(?:\3|(?:.*?[^\\]\3)))((\s*\+\s*)(?:(?:(['"])(?:\6|(?:.*?[^\\]\6)))|(?:[\w$]*)))*)|.*?))?\s*(?:,|$)/gm;function getParams(func){let functionAsString=func.toString();let params=[];let match;functionAsString=functionAsString.replace(REGEX_COMMENTS,'');functionAsString=functionAsString.match(REGEX_FUNCTION_PARAMS)[1];if(functionAsString.charAt(0)==='('){functionAsString=functionAsString.slice(1,-1);}
|
||||
while(match=REGEX_PARAMETERS_VALUES.exec(functionAsString)){params.push(match[1]);}
|
||||
return params;}
|
||||
let args=getParams(target);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=()=>{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;}
|
||||
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=()=>previous;let getCurrent=()=>current;let setPrevious=(value)=>{previous=value;return this;};let setCurrent=(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){let paths=[];return{regex:/(\{{.*?\}})/gi,parse:function(string,def,as,prefix,cast=false){def=def||'';paths=[];return string.replace(this.regex,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);}
|
||||
if(null===result||undefined===result){result=def;}
|
||||
else if(typeof result==='object'){result=JSON.stringify(result);}
|
||||
else if(((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:()=>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);return container.resolve(filters[name]);};add('uppercase',($value)=>{return $value.toUpperCase();});add('lowercase',($value)=>{return $value.toLowerCase();});return{add:add,apply:apply}},true,false);window.ls.container.get('filter').add('escape',value=>{if(typeof value!=='string'){return value;}
|
||||
return value.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});window.ls=window.ls||{};window.ls.container.set('window',window,true,false).set('document',window.document,true,false).set('element',window.document,true,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=()=>{return 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=()=>{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',()=>{for(let i=0;i<paths.length;i++){container.path(paths[i],element.checked,$as,$prefix);}});}}
|
||||
else{try{value=JSON.parse(value);element.checked=(Array.isArray(value)&&(value.indexOf(element.value)>-1));}
|
||||
catch{return null;}}}
|
||||
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=((as,prefix)=>{return()=>{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);element.addEventListener('looped',function(){echo(expression.parse(syntax,null,$as,$prefix),false);});for(let i=0;i<paths.length;i++){container.bind(element,paths[i],()=>{echo(expression.parse(syntax,null,$as,$prefix),false);});}}});window.ls.container.get('view').add({selector:'data-ls-if',controller:function(element,expression,container,view,$as,$prefix){let result='';let syntax=element.getAttribute('data-ls-if')||'';let debug=element.getAttribute('data-debug')||false;let paths=[];let check=()=>{if(debug){console.info('debug-ls-if',expression.parse(syntax.replace(/(\r\n|\n|\r)/gm,' '),'undefined',$as,$prefix,true));}
|
||||
try{result=(eval(expression.parse(syntax.replace(/(\r\n|\n|\r)/gm,' '),'undefined',$as,$prefix,true)));}
|
||||
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();let prv=element.$lsSkip;element.$lsSkip=!result;if(!result){element.style.visibility='hidden';element.style.display='none';}
|
||||
else{element.style.removeProperty('display');element.style.removeProperty('visibility');}
|
||||
if(prv===true&&element.$lsSkip===false){view.render(element)}};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 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]);(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);}
|
||||
container.set('$index',null,true,false,false);container.set('$prefix','',true,false,false);container.set('$as','',true,false,false);element.dispatchEvent(new Event('looped'));};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=(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');});}});
|
||||
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, }; if (!watch) { return this; }
|
||||
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 () => { }; }
|
||||
let self = this; const REGEX_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; const REGEX_FUNCTION_PARAMS = /(?:\s*(?:function\s*[^(]*)?\s*)((?:[^'"]|(?:(?:(['"])(?:(?:.*?[^\\]\2)|\2))))*?)\s*(?=(?:=>)|{)/m; const REGEX_PARAMETERS_VALUES = /\s*([\w\\$]+)\s*(?:=\s*((?:(?:(['"])(?:\3|(?:.*?[^\\]\3)))((\s*\+\s*)(?:(?:(['"])(?:\6|(?:.*?[^\\]\6)))|(?:[\w$]*)))*)|.*?))?\s*(?:,|$)/gm; function getParams(func) {
|
||||
let functionAsString = func.toString(); let params = []; let match; functionAsString = functionAsString.replace(REGEX_COMMENTS, ''); functionAsString = functionAsString.match(REGEX_FUNCTION_PARAMS)[1]; if (functionAsString.charAt(0) === '(') { functionAsString = functionAsString.slice(1, -1); }
|
||||
while (match = REGEX_PARAMETERS_VALUES.exec(functionAsString)) { params.push(match[1]); }
|
||||
return params;
|
||||
}
|
||||
let args = getParams(target); 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.indexOf('.') > -1) ? path.replace(as + '.', prefix + '.') : 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 !== null && value !== undefined) { 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.indexOf('.') > -1) ? path.replace(as + '.', prefix + '.') : path.replace(as, prefix)) + '.changed'; let service = event.split('.').slice(0, 1).pop(); listeners[service] = listeners[service] || {}; listeners[service][event] = true; let printer = () => {
|
||||
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); 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;
|
||||
}
|
||||
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.tagName === 'SCRIPT') { return; }
|
||||
if (node.attributes && skip !== true) {
|
||||
let attrs = []; let attrsLen = node.attributes.length; for (let x = 0; x < attrsLen; x++) { attrs.push(node.attributes[x].nodeName); }
|
||||
if (1 !== node.nodeType) { 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 = () => previous; let getCurrent = () => current; let setPrevious = (value) => { previous = value; return this; }; let setCurrent = (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) {
|
||||
let paths = []; return {
|
||||
regex: /(\{{.*?\}})/gi, parse: function (string, def, as, prefix, cast = false) {
|
||||
def = def || ''; paths = []; return string.replace(this.regex, 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); path = (path.indexOf('.') > -1) ? path.replace(as + '.', prefix + '.') : path.replace(as, prefix); if (!paths.includes(path)) { paths.push(path); }
|
||||
if (reference.length >= 2) { for (let i = 1; i < reference.length; i++) { result = filter.apply(reference[i], result); } }
|
||||
if (null === result || undefined === result) { result = def; }
|
||||
else if (typeof result === 'object') { result = JSON.stringify(result, null, 4); }
|
||||
else if (((typeof result === 'object') || (typeof result === 'string')) && cast) { result = '\'' + result + '\''; }
|
||||
return result;
|
||||
});
|
||||
}, getPaths: () => 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); return container.resolve(filters[name]); }; add('uppercase', ($value) => { return $value.toUpperCase(); }); add('lowercase', ($value) => { return $value.toLowerCase(); }); return { add: add, apply: apply } }, true, false); window.ls.container.get('filter').add('escape', value => {
|
||||
if (typeof value !== 'string') { return value; }
|
||||
return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"').replace(/\'/g, ''').replace(/\//g, '/');
|
||||
}); window.ls = window.ls || {}; window.ls.container.set('window', window, true, false).set('document', window.document, true, false).set('element', window.document, true, 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 = () => { return 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, tasks) {
|
||||
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) {
|
||||
let count = parseInt(element.getAttribute('data-ls-scope-count') || 0); element.setAttribute('data-ls-scope-count', count + 1); 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 (count === 1) { view.render(element); }
|
||||
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.removeAttribute('data-ls-router'); element.setAttribute('data-ls-scope', ''); element.setAttribute('data-ls-scope-count', 1); 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 = () => {
|
||||
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 (bind) {
|
||||
element.addEventListener('change', () => {
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
if (element.checked) { value = element.value; }
|
||||
container.path(paths[i], value, $as, $prefix);
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
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; }
|
||||
}
|
||||
else {
|
||||
try { value = JSON.parse(value); element.checked = (Array.isArray(value) && (value.indexOf(element.value) > -1)); value = element.value; }
|
||||
catch{ return null; }
|
||||
}
|
||||
if (bind) {
|
||||
element.addEventListener('change', () => {
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
let value = container.path(paths[i], undefined, $as, $prefix); let index = value.indexOf(element.value); if (element.checked && index < 0) { value.push(element.value); }
|
||||
if (!element.checked && index > -1) { value.splice(index, 1); }
|
||||
container.path(paths[i], value, $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 = ((as, prefix) => { return () => { 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); element.addEventListener('looped', function () { echo(expression.parse(syntax, null, $as, $prefix), false); }); for (let i = 0; i < paths.length; i++) { container.bind(element, paths[i], () => { echo(expression.parse(syntax, null, $as, $prefix), false); }); }
|
||||
}
|
||||
}); window.ls.container.get('view').add({
|
||||
selector: 'data-ls-if', controller: function (element, expression, container, view, $as, $prefix) {
|
||||
let result = ''; let syntax = element.getAttribute('data-ls-if') || ''; let debug = element.getAttribute('data-debug') || false; let paths = []; let check = () => {
|
||||
if (debug) { console.info('debug-ls-if', expression.parse(syntax.replace(/(\r\n|\n|\r)/gm, ' '), 'undefined', $as, $prefix, true)); }
|
||||
try { result = (eval(expression.parse(syntax.replace(/(\r\n|\n|\r)/gm, ' '), 'undefined', $as, $prefix, true))); }
|
||||
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(); let prv = element.$lsSkip; element.$lsSkip = !result; if (!result) { element.style.visibility = 'hidden'; element.style.display = 'none'; }
|
||||
else { element.style.removeProperty('display'); element.style.removeProperty('visibility'); }
|
||||
if (prv === true && element.$lsSkip === false) { view.render(element) }
|
||||
}; 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 array = container.path(expr); array = (!array) ? [] : array; let watch = !!(array && array.__proxy); 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]); (index => { let context = expr + '.' + index; container.set(as, container.path(context), true, watch); container.set('$index', index, true, false); container.set('$prefix', context, true, false); container.set('$as', as, true, false); view.render(children[prop]); })(prop);
|
||||
}
|
||||
container.set('$index', null, true, false, false); container.set('$prefix', '', true, false, false); container.set('$as', '', true, false, false); element.dispatchEvent(new Event('looped'));
|
||||
}; let template = (element.children.length === 1) ? element.children[0] : window.document.createElement('li'); 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 = ''; if ('script' === type) {
|
||||
let inlineTemplate = document.getElementById(template); if (inlineTemplate && inlineTemplate.innerHTML) { element.innerHTML = inlineTemplate.innerHTML; element.dispatchEvent(new CustomEvent('template-loaded', { bubbles: true, cancelable: false })); }
|
||||
else { element.innerHTML = '<span style="color: red">Missing template "' + template + '"</span>'; }
|
||||
return;
|
||||
}
|
||||
http.get(template).then(function (element) { return function (data) { element.innerHTML = data; view.render(element); element.dispatchEvent(new CustomEvent('template-loaded', { bubbles: true, cancelable: false })); } }(element), function () { throw new Error('Failed loading template'); });
|
||||
}
|
||||
});
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
window.ls.filter
|
||||
.add('gravatar', function ($value) {
|
||||
$value = JSON.parse($value || '{}');
|
||||
|
||||
// MD5 (Message-Digest Algorithm) by WebToolkit
|
||||
let MD5 = function(s){function L(k,d){return(k<<d)|(k>>>(32-d))}function K(G,k){let I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H)}if(I|d){if(x&1073741824){return(x^3221225472^F^H)}else{return(x^1073741824^F^H)}}else{return(x^F^H)}}function r(d,F,k){return(d&F)|((~d)&k)}function q(d,F,k){return(d&k)|(F&(~k))}function p(d,F,k){return(d^F^k)}function n(d,F,k){return(F^(d|(~k)))}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F)}function e(G){let Z;let F=G.length;let x=F+8;let k=(x-(x%64))/64;let I=(k+1)*16;let aa=Array(I-1);let d=0;let H=0;while(H<F){Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=(aa[Z]|(G.charCodeAt(H)<<d));H++}Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=aa[Z]|(128<<d);aa[I-2]=F<<3;aa[I-1]=F>>>29;return aa}function B(x){let k="",F="",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F="0"+G.toString(16);k=k+F.substr(F.length-2,2)}return k}function J(k){k=k.replace(/rn/g,"n");let d="";for(let F=0;F<k.length;F++){let x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x)}else{if((x>127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128)}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128)}}}return d}let C=Array();let P,h,E,v,g,Y,X,W,V;let S=7,Q=12,N=17,M=22;let A=5,z=9,y=14,w=20;let o=4,m=11,l=16,j=23;let U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g)}let i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase()};
|
||||
let size = 80;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
padding: 30px 50px;
|
||||
margin: 0 -50px;
|
||||
position: relative;
|
||||
border-bottom: solid 1px #ececec;
|
||||
border-bottom: solid 1px #ece5e5;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
|
@ -13,6 +13,7 @@
|
|||
color: @config-color-focus;
|
||||
font-weight: 600;
|
||||
margin-bottom: 30px !important;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
i:before {
|
||||
|
|
|
@ -51,6 +51,13 @@ img[src=""] {
|
|||
@import "comps/tabs";
|
||||
@import "dependencies/prism";
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
|
@ -72,7 +79,7 @@ body {
|
|||
}
|
||||
|
||||
main {
|
||||
min-height: 950px;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
|
|
@ -2,16 +2,19 @@
|
|||
color: @config-color-placeholder;
|
||||
text-align: @config-start;
|
||||
}
|
||||
|
||||
/* webkit solution */
|
||||
::-webkit-input-placeholder {
|
||||
text-align: @config-start;
|
||||
}
|
||||
|
||||
/* mozilla solution */
|
||||
input:-moz-placeholder {
|
||||
text-align: @config-start;
|
||||
}
|
||||
|
||||
button, .button {
|
||||
button,
|
||||
.button {
|
||||
display: inline-block;
|
||||
background: @config-color-focus;
|
||||
border-radius: 26px;
|
||||
|
@ -26,7 +29,8 @@ button, .button {
|
|||
position: relative;
|
||||
.text-one-liner;
|
||||
|
||||
&:hover, &:focus {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: @config-color-focus-dark;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
@ -35,22 +39,22 @@ button, .button {
|
|||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 0 10px!important;
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
|
||||
&.fill-aligned {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: @config-start;
|
||||
padding: 0 20px!important;
|
||||
padding: 0 20px !important;
|
||||
}
|
||||
|
||||
&.icon {
|
||||
.func-padding-end(30px)!important;
|
||||
.func-padding-end(30px) !important;
|
||||
}
|
||||
|
||||
&.icon-reduce {
|
||||
.func-padding-start(15px)!important;
|
||||
.func-padding-start(15px) !important;
|
||||
}
|
||||
|
||||
&.reverse {
|
||||
|
@ -61,7 +65,8 @@ button, .button {
|
|||
color: @config-color-focus;
|
||||
border: solid 2px @config-color-focus;
|
||||
|
||||
&:hover, &:focus {
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: @config-color-focus-dark;
|
||||
border-color: @config-color-focus-dark;
|
||||
}
|
||||
|
@ -90,10 +95,10 @@ button, .button {
|
|||
}
|
||||
|
||||
&.trans {
|
||||
background: transparent!important;
|
||||
background: transparent !important;
|
||||
|
||||
&.reverse {
|
||||
background: transparent!important;
|
||||
background: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,7 +122,8 @@ button, .button {
|
|||
}
|
||||
}
|
||||
|
||||
&.disabled, .disabled {
|
||||
&.disabled,
|
||||
.disabled {
|
||||
//opacity: .3;
|
||||
background: @config-color-fade-light;
|
||||
cursor: default;
|
||||
|
@ -130,7 +136,7 @@ button, .button {
|
|||
height: auto;
|
||||
line-height: normal;
|
||||
padding: 0;
|
||||
.func-padding-end(0)!important;
|
||||
.func-padding-end(0) !important;
|
||||
|
||||
&:hover {
|
||||
border-bottom: dotted 1px @config-color-link;
|
||||
|
@ -150,23 +156,23 @@ button, .button {
|
|||
}
|
||||
|
||||
&.facebook {
|
||||
color: #ffffff!important;
|
||||
background: #4070b4!important;
|
||||
color: #ffffff !important;
|
||||
background: #4070b4 !important;
|
||||
}
|
||||
|
||||
&.twitter {
|
||||
color: #ffffff!important;
|
||||
background: #56c2ea!important;
|
||||
color: #ffffff !important;
|
||||
background: #56c2ea !important;
|
||||
}
|
||||
|
||||
&.linkedin {
|
||||
color: #ffffff!important;
|
||||
background: #0076b5!important;
|
||||
color: #ffffff !important;
|
||||
background: #0076b5 !important;
|
||||
}
|
||||
|
||||
&.github {
|
||||
color: #ffffff!important;
|
||||
background: #7e7c7c!important;
|
||||
color: #ffffff !important;
|
||||
background: #7e7c7c !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
|
@ -180,7 +186,19 @@ label {
|
|||
line-height: normal;
|
||||
}
|
||||
|
||||
.input, input[type=text], input[type=date], input[type=datetime-local], input[type=number], input[type=url], input[type=email], input[type=file], input[type=password], input[type=tel], input[type=search], textarea, select {
|
||||
.input,
|
||||
input[type=text],
|
||||
input[type=date],
|
||||
input[type=datetime-local],
|
||||
input[type=number],
|
||||
input[type=url],
|
||||
input[type=email],
|
||||
input[type=file],
|
||||
input[type=password],
|
||||
input[type=tel],
|
||||
input[type=search],
|
||||
textarea,
|
||||
select {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-transform: translateZ(0px);
|
||||
|
@ -211,7 +229,7 @@ label {
|
|||
width: 100%;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0!important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,21 +259,23 @@ label {
|
|||
}
|
||||
}
|
||||
|
||||
input[type=email], input[type=url] {
|
||||
input[type=email],
|
||||
input[type=url] {
|
||||
direction: ltr;
|
||||
|
||||
&::placeholder
|
||||
{
|
||||
&::placeholder {
|
||||
text-align: left;
|
||||
direction: ltr;
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
select {
|
||||
background: transparent;
|
||||
-webkit-appearance: none;
|
||||
background-image: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 24 24'><path fill='%23868686' d='M7.406 7.828l4.594 4.594 4.594-4.594 1.406 1.406-6 6-6-6z'></path></svg>");
|
||||
background-position: @config-end 15px top 50%;
|
||||
background-position: @config-end 15px top 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #fff;
|
||||
width: ~"calc(100% - 62px)";
|
||||
|
@ -265,7 +285,7 @@ select {
|
|||
&:-webkit-autofill {
|
||||
background-image: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 24 24'><path fill='%23444' d='M7.406 7.828l4.594 4.594 4.594-4.594 1.406 1.406-6 6-6-6z'></path></svg>") !important;
|
||||
background-position: 100% 50% !important;
|
||||
background-repeat: no-repeat!important;
|
||||
background-repeat: no-repeat !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
|
@ -273,11 +293,12 @@ select {
|
|||
}
|
||||
}
|
||||
|
||||
input[type=search], input[type=search].strip {
|
||||
input[type=search],
|
||||
input[type=search].strip {
|
||||
background: transparent;
|
||||
-webkit-appearance: none;
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAdZJREFUWIXt1s2LjWEYBvDfnDMzFpNIamZIFrMiJYMyFmKhZKfOwoiFr2LFn2BByG6WVrKwMcjWxgoLIlKIUk6RrzAjZWZ8LO731FlwvB+PUbjq6X0X7/VeV/d9P9fz8IdRL8Hpw3x8w0xaOz9GNxq4gJeZcGs1cRab0fU7xLfgMSYzoT3YgNXYhIO4iM+4iTWphGs4jikcFSXvhEGczr4/UFW8C2N4jXUFudvwCYeqGNgnSr6yJH8rpkWLCqMfE9hdUryFE3iC3qLEk7ij+kT34Q32FiHV8Qr7K4q3cArXihCGxd5elMjARnzBvE4f1dreV+AtnicycC/7/7K8BhaIvqXCO3zFwrwGZtCT0EAtW9N5DTSxWGR/CizNns/yEgbFEK5NZGCnaEPHE7e9Ai9wA6OJDIzistgJubFdxHB/RfFVYgCHixJruI5x5dNwDm6J47sUhkTvjpUw0Y1zeOrXR3hHjOA9zmBuTs4Arog4/yhuUZWwHPdFMh7280BZgiP4ILJ/UuymqRQmejPxphiquzgvKnMJDzOxB9glZqiRiecykbfHdawX98EhcdxO4BGu4nYm2EJDzEKPSMIdYrBnFYUq8d/EP2di1gey3cS4ErflvxffASbhcakIINaMAAAAAElFTkSuQmCC");
|
||||
background-position: @config-start 3px top 50%;
|
||||
background-position: @config-start 3px top 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 20px 20px;
|
||||
width: ~"calc(100% - 62px)";
|
||||
|
@ -287,8 +308,8 @@ input[type=search], input[type=search].strip {
|
|||
|
||||
select[multiple] {
|
||||
min-height: 75px;
|
||||
padding: 5px 10px!important;
|
||||
.func-padding-end(50px)!important;
|
||||
padding: 5px 10px !important;
|
||||
.func-padding-end(50px) !important;
|
||||
|
||||
option {
|
||||
padding: 10px 4px;
|
||||
|
@ -324,13 +345,13 @@ fieldset {
|
|||
}
|
||||
|
||||
.file-preview {
|
||||
background: #fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAIElEQVQoU2NkYGAwZsAEZ9GFGIeIQix+wfQgyDODXSEAcUwGCrDSHgkAAAAASUVORK5CYII=)!important;
|
||||
background: #fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAIElEQVQoU2NkYGAwZsAEZ9GFGIeIQix+wfQgyDODXSEAcUwGCrDSHgkAAAAASUVORK5CYII=) !important;
|
||||
border: solid 1px #e2e2e2;
|
||||
box-shadow: inset 0 0 3px #a0a0a0;
|
||||
border-radius: 8px;
|
||||
width: ~"calc(100% - 2px)";
|
||||
max-height: 180px;
|
||||
visibility: visible!important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
.video-preview {
|
||||
|
@ -357,7 +378,7 @@ fieldset {
|
|||
border-radius: 10px;
|
||||
background: #e7e7e7;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 30px rgba(218,218,218,.5);
|
||||
box-shadow: 0 0 30px rgba(218, 218, 218, .5);
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
|
@ -423,7 +444,7 @@ fieldset {
|
|||
line-height: 24px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
box-shadow: none!important;
|
||||
box-shadow: none !important;
|
||||
border: none;
|
||||
height: auto;
|
||||
width: auto;
|
||||
|
@ -505,21 +526,23 @@ input[type=checkbox] {
|
|||
outline: none;
|
||||
}
|
||||
|
||||
&:focus:after, &:hover:after {
|
||||
&:focus:after,
|
||||
&:hover:after {
|
||||
outline: none;
|
||||
border-color: @config-color-focus-dark;
|
||||
border-color: #000000;
|
||||
}
|
||||
|
||||
&:checked:focus:after, &:checked:hover:after {
|
||||
outline: none;
|
||||
background: @config-color-focus-dark;
|
||||
&:checked:focus:after,
|
||||
&:checked:hover:after {
|
||||
border-color: @config-color-focus;
|
||||
}
|
||||
}
|
||||
|
||||
.input-copy {
|
||||
position: relative;
|
||||
|
||||
input, textarea {
|
||||
input,
|
||||
textarea {
|
||||
.func-padding-end(65px);
|
||||
width: ~"calc(100% - 82px)";
|
||||
resize: none;
|
||||
|
@ -549,12 +572,12 @@ input[type=checkbox] {
|
|||
.blue-snap {
|
||||
iframe {
|
||||
.input;
|
||||
float: none!important;
|
||||
height: 40px!important;
|
||||
width: ~"calc(100% - 32px)"!important;
|
||||
border: solid 1px #e2e2e2!important;
|
||||
background: transparent!important;
|
||||
position: static!important;
|
||||
float: none !important;
|
||||
height: 40px !important;
|
||||
width: ~"calc(100% - 32px)" !important;
|
||||
border: solid 1px #e2e2e2 !important;
|
||||
background: transparent !important;
|
||||
position: static !important;
|
||||
}
|
||||
|
||||
.error {
|
||||
|
@ -572,10 +595,10 @@ input[type=checkbox] {
|
|||
margin-bottom: 0;
|
||||
padding-top: 0;
|
||||
background: #ffffff;
|
||||
line-height: normal!important;
|
||||
line-height: normal !important;
|
||||
|
||||
&.hide {
|
||||
padding: 0!important;
|
||||
padding: 0 !important;
|
||||
height: 1px;
|
||||
min-height: 1px;
|
||||
max-height: 1px;
|
||||
|
@ -585,9 +608,10 @@ input[type=checkbox] {
|
|||
opacity: 0;
|
||||
}
|
||||
|
||||
[contenteditable=true]:empty:before{
|
||||
[contenteditable=true]:empty:before {
|
||||
content: attr(placeholder);
|
||||
display: block; /* For Firefox */
|
||||
display: block;
|
||||
/* For Firefox */
|
||||
color: @config-color-placeholder;
|
||||
}
|
||||
|
||||
|
@ -622,25 +646,34 @@ input[type=checkbox] {
|
|||
font-size: 13px;
|
||||
border-radius: 0;
|
||||
|
||||
&.pell-button-selected, &:focus, &:hover {
|
||||
&.pell-button-selected,
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: @config-color-link;
|
||||
}
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
text-align: inherit;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
b, strong {
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
ul,
|
||||
ol {
|
||||
margin: 0 0 20px 0;
|
||||
|
||||
li {
|
||||
display: list-item!important;
|
||||
display: list-item !important;
|
||||
list-style: inherit;
|
||||
margin-bottom: 10px;
|
||||
|
||||
|
@ -678,7 +711,8 @@ input[type=checkbox].switch {
|
|||
.func-padding-end(30px);
|
||||
}
|
||||
|
||||
&:focus, &:hover {
|
||||
&:focus,
|
||||
&:hover {
|
||||
&:after {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
@ -752,14 +786,14 @@ input[type=checkbox].switch {
|
|||
}
|
||||
|
||||
.grecaptcha-badge {
|
||||
box-shadow: none!important;
|
||||
border-radius: 10px!important;
|
||||
overflow: hidden!important;
|
||||
background: #4d92df!important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 10px !important;
|
||||
overflow: hidden !important;
|
||||
background: #4d92df !important;
|
||||
bottom: 25px;
|
||||
|
||||
&:hover {
|
||||
width: 256px!important;
|
||||
width: 256px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -795,8 +829,8 @@ hr {
|
|||
top: 0;
|
||||
width: ~"calc(100% - 20px)";
|
||||
height: ~"calc(100% - 20px)";
|
||||
.func-margin-end(0)!important;
|
||||
margin-bottom: 0!important;
|
||||
.func-margin-end(0) !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -805,7 +839,8 @@ hr {
|
|||
.pull-start;
|
||||
.margin-end;
|
||||
|
||||
&.disabled, &.disabled:hover {
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
border-color: inherit;
|
||||
|
@ -863,7 +898,9 @@ hr {
|
|||
background: #484848;
|
||||
color: #ffffff;
|
||||
z-index: 1;
|
||||
} /* '' */
|
||||
}
|
||||
|
||||
/* '' */
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
|
@ -979,7 +1016,8 @@ ol {
|
|||
padding: 0;
|
||||
.clear;
|
||||
|
||||
a, .link {
|
||||
a,
|
||||
.link {
|
||||
vertical-align: middle;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
|
@ -1029,8 +1067,11 @@ ol {
|
|||
opacity: .2;
|
||||
cursor: default;
|
||||
|
||||
a, button, .link, .button {
|
||||
cursor: default!important;
|
||||
a,
|
||||
button,
|
||||
.link,
|
||||
.button {
|
||||
cursor: default !important;
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
font-family: "fontello";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: none;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
background: #f6f9fc;
|
||||
|
||||
.project-only {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
&.show-nav {
|
||||
.project-only {
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
|||
line-height: 40px;
|
||||
padding: 15px 30px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, .10);
|
||||
margin: 0 -50px;
|
||||
z-index: 2;
|
||||
font-size: 14px;
|
||||
|
@ -188,7 +188,8 @@
|
|||
|
||||
.container {
|
||||
overflow: scroll;
|
||||
height: ~"calc(100% - 133px)";
|
||||
height: ~"calc(100% - 183px)";
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.project-box {
|
||||
|
@ -274,12 +275,12 @@
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
//background: #183142;
|
||||
padding-bottom: 0;
|
||||
border: none;
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
a {
|
||||
border-top: solid 1px #2a253a;
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
@ -348,6 +349,8 @@
|
|||
width: ~"calc(100% + 100px)";
|
||||
margin: 0 -50px;
|
||||
box-sizing: border-box;
|
||||
border-top: solid 1px #e7e7e7;
|
||||
background: transparent;
|
||||
.func-padding-end(30px);
|
||||
.func-padding-start(30px);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue