diff --git a/.gitignore b/.gitignore index e044716..b1a4752 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,9 @@ lib-cov # Coverage directory used by tools like istanbul coverage +# playground - issue reproduction on local dev machine +src/playground + # nyc test coverage .nyc_output diff --git a/Slim.es6.js b/Slim.es6.js index 1b0f425..b2ac18a 100644 --- a/Slim.es6.js +++ b/Slim.es6.js @@ -1 +1 @@ -(function(window,document,HTMLElement){const __flags={isWCSupported:"customElements"in window&&"import"in document.createElement("link")&&"content"in document.createElement("template"),isIE11:!!window["MSInputMethodContext"]&&!!document["documentMode"],isChrome:undefined,isEdge:undefined,isSafari:undefined,isFirefox:undefined};try{__flags.isChrome=/Chrome/.test(navigator.userAgent);__flags.isEdge=/Edge/.test(navigator.userAgent);__flags.isSafari=/Safari/.test(navigator.userAgent);__flags.isFirefox=/Firefox/.test(navigator.userAgent);if(__flags.isIE11||__flags.isEdge){__flags.isChrome=false;Object.defineProperty(Node.prototype,"children",function(){return this.childNodes})}}catch(err){}const _$="_slim_internals_";class Internals{constructor(){this.hasCustomTemplate=undefined;this.boundParent=null;this.repeater={};this.bindings={};this.reversed={};this.inbounds={};this.eventHandlers={};this.internetExploderClone=null;this.rootElement=null;this.createdCallbackInvoked=false;this.sourceText=null;this.excluded=false;this.autoBoundAttributes=[]}}class Slim extends HTMLElement{static dashToCamel(dash){return dash.indexOf("-")<0?dash:dash.replace(/-[a-z]/g,m=>{return m[1].toUpperCase()})}static camelToDash(camel){return camel.replace(/([A-Z])/g,"-$1").toLowerCase()}static get rxInject(){return/\{(.+[^(\((.+)\))])\}/}static get rxProp(){return/(.+[^(\((.+)\))])/}static get rxMethod(){return/(.+)(\((.+)\)){1}/}static lookup(target,expression,maybeRepeated){const chain=expression.split(".");let o;if(maybeRepeated&&maybeRepeated[_$].repeater[chain[0]]){o=maybeRepeated[_$].repeater}else{o=target}let i=0;while(o&&i{fn(target)})}static qSelectAll(target,selector){return[...target.querySelectorAll(selector)]}static unbind(source,target){const bindings=source[_$].bindings;Object.keys(bindings).forEach(key=>{const chain=bindings[key].chain.filter(binding=>{if(binding.target===target){binding.destroy();return false}return true});bindings[key].chain=chain})}static root(target){return target.__isSlim&&target.useShadow?target[_$].rootElement||target:target}static selectRecursive(target,force){const collection=[];const search=function(node,force){collection.push(node);const allow=!node.__isSlim||node.__isSlim&&!node.template||node.__isSlim&&node===target||force;if(allow){const children=[...Slim.root(node).children];children.forEach(childNode=>{search(childNode,force)})}};search(target,force);return collection}static removeChild(target){if(typeof target.remove==="function"){target.remove()}if(target.parentNode){target.parentNode.removeChild(target)}if(this._$(target).internetExploderClone){this.removeChild(this._$(target).internetExploderClone)}}static moveChildren(source,target){while(source.firstChild){target.appendChild(source.firstChild)}}static wrapGetterSetter(element,expression){const pName=expression.split(".")[0];let oSetter=element.__lookupSetter__(pName);if(oSetter&&oSetter[_$])return pName;if(typeof oSetter==="undefined"){oSetter=(()=>{})}const srcValue=element[pName];this._$(element).bindings[pName]=element[_$].bindings[pName]||{chain:[],value:srcValue};element[_$].bindings[pName].value=srcValue;const newSetter=function(v){oSetter.call(element,v);this[_$].bindings[pName].value=v;this._executeBindings(pName)};newSetter[_$]=true;element.__defineGetter__(pName,()=>element[_$].bindings[pName].value);element.__defineSetter__(pName,newSetter);return pName}static bindOwn(target,expression,executor){return Slim.bind(target,target,expression,executor)}static bind(source,target,expression,executor){Slim._$(source);Slim._$(target);if(target[_$].excluded)return;executor.source=source;executor.target=target;const pName=this.wrapGetterSetter(source,expression);if(!source[_$].reversed[pName]){source[_$].bindings[pName].chain.push(executor)}target[_$].inbounds[pName]=target[_$].inbounds[pName]||[];target[_$].inbounds[pName].push(executor);return executor}static update(target,...props){const children=Slim.selectRecursive(target);if(props.length===0){return children.forEach(child=>{Slim.commit(child)})}props.forEach(prop=>{children.forEach(child=>{Slim.commit(child,prop)})})}static commit(target,prop){let keys;let $=target[_$];let chain=[];if(prop){if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}}else{Object.keys(target[_$].inbounds).forEach(prop=>{if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}})}chain.forEach(x=>x())}constructor(){super();const init=()=>{this.__isSlim=true;Slim.debug("ctor",this.localName);if(Slim.checkCreationBlocking(this)){return}this.createdCallback()};if(__flags.isSafari){Slim.asap(init)}else init()}createdCallback(){if(this[_$]&&this[_$].createdCallbackInvoked)return;this._initialize();this[_$].createdCallbackInvoked=true;this.onBeforeCreated();Slim.executePlugins("create",this);this.render();this.onCreated()}connectedCallback(){this.onAdded();Slim.executePlugins("added",this)}disconnectedCallback(){this.onRemoved();Slim.executePlugins("removed",this)}attributeChangedCallback(attr,oldValue,newValue){if(newValue!==oldValue&&this[_$].autoBoundAttributes[attr]){const prop=Slim.dashToCamel(attr);this[prop]=newValue}}get _isInContext(){let node=this;while(node){node=node.parentNode;if(!node){return false}if(node instanceof Document){return true}}return false}_executeBindings(prop){Slim.debug("_executeBindings",this.localName);let all=this[_$].bindings;if(prop){all={[prop]:true}}Object.keys(all).forEach(pName=>{const o=this[_$].bindings[pName];o&&o.chain.forEach(binding=>binding())})}_bindChildren(children){Slim.debug("_bindChildren",this.localName);if(!children){children=Slim.qSelectAll(this,"*")}for(let child of children){Slim._$(child);if(child[_$].boundParent===this)continue;child[_$].boundParent=child[_$].boundParent||this;if(child.attributes.length){let i=0;let n=child.attributes.length;while(i{if(childNode.localName==="style"){this[_$].externalStyle=childNode;childNode.remove()}});const template=this[_$].hasCustomTemplate||this.template;if(template&&typeof template==="string"){const frag=document.createElement("slim-root-fragment");frag.innerHTML=template||"";const scopedChildren=Slim.qSelectAll(frag,"*");if(this[_$].externalStyle){this._bindChildren([this[_$].externalStyle])}this._bindChildren(scopedChildren);Slim.asap(()=>{Slim.moveChildren(frag,this[_$].rootElement||this);this[_$].externalStyle&&this[_$].rootElement.appendChild(this[_$].externalStyle);this._executeBindings();this.onRender();Slim.executePlugins("afterRender",this);this.dispatchEvent(new Event("afterRender"))})}}_initialize(){Slim.debug("_initialize",this.localName);Slim._$(this);this[_$].uniqueIndex=Slim.createUniqueIndex();if(this.useShadow){if(typeof HTMLElement.prototype.attachShadow==="undefined"){this[_$].rootElement=this.createShadowRoot()}else{this[_$].rootElement=this.attachShadow({mode:"open"})}}else{this[_$].rootElement=this}const observedAttributes=this.constructor.observedAttributes;if(observedAttributes){observedAttributes.forEach(attr=>{const pName=Slim.dashToCamel(attr);this[pName]=this.getAttribute(attr)})}}commit(...args){Slim.commit(this,...args)}update(...args){Slim.update(this,...args)}render(tpl){this._render(tpl)}onRender(){}onBeforeCreated(){}onCreated(){}onAdded(){}onRemoved(){}find(selector){return this[_$].rootElement.querySelector(selector)}findAll(selector){return Slim.qSelectAll(this[_$].rootElement,selector)}callAttribute(attr,data){const fnName=this.getAttribute(attr);if(fnName){return this[_$].boundParent[fnName](data)}}get useShadow(){return false}get template(){return Slim.tagToTemplateDict.get(Slim.tagOf(this.constructor))}}Slim.uniqueIndex=0;Slim.tagToClassDict=new Map;Slim.classToTagDict=new Map;Slim.tagToTemplateDict=new Map;Slim.plugins={create:[],added:[],beforeRender:[],afterRender:[],removed:[]};Slim.debug=(()=>{});Slim.asap=window&&window.requestAnimationFrame?cb=>window.requestAnimationFrame(cb):typeof setImmediate!=="undefined"?setImmediate:cb=>setTimeout(cb,0);Slim[_$]={customDirectives:new Map,uniqueCounter:0,supportedNativeEvents:["click","mouseover","mouseout","mousemove","mouseenter","mousedown","mouseup","dblclick","contextmenu","wheel","mouseleave","select","pointerlockchange","pointerlockerror","focus","blur","input","error","invalid","animationstart","animationend","animationiteration","reset","submit","resize","scroll","keydown","keypress","keyup","change"]};Slim.customDirective(attr=>attr.nodeName==="s:switch",(source,target,attribute)=>{const expression=attribute.value;let oldValue;const anchor=document.createComment(`switch:${expression}`);target.appendChild(anchor);const children=[...target.children];const defaultChildren=children.filter(child=>child.hasAttribute("s:default"));const fn=()=>{let value=Slim.lookup(source,expression,target);if(String(value)===oldValue)return;let useDefault=true;children.forEach(child=>{if(child.getAttribute("s:case")===String(value)){if(child.__isSlim){child.createdCallback()}anchor.parentNode.insertBefore(child,anchor);useDefault=false}else{Slim.removeChild(child)}});if(useDefault){defaultChildren.forEach(child=>{if(child.__isSlim){child.createdCallback()}anchor.parentNode.insertBefore(child,anchor)})}else{defaultChildren.forEach(child=>{Slim.removeChild(child)})}oldValue=String(value)};Slim.bind(source,target,expression,fn)});Slim.customDirective(attr=>/^s:case$/.exec(attr.nodeName),()=>{},true);Slim.customDirective(attr=>/^s:default$/.exec(attr.nodeName),()=>{},true);Slim.customDirective(attr=>Slim[_$].supportedNativeEvents.indexOf(attr.nodeName)>=0,(source,target,attribute)=>{const eventName=attribute.nodeName;const delegate=attribute.value;Slim._$(target).eventHandlers=target[_$].eventHandlers||{};const allHandlers=target[_$].eventHandlers;allHandlers[eventName]=allHandlers[eventName]||[];let handler=e=>{try{source[delegate].call(source,e)}catch(err){err.message=`Could not respond to event "${eventName}" on ${target.localName} -> "${delegate}" on ${source.localName} ... ${err.message}`;console.warn(err)}};allHandlers[eventName].push(handler);target.addEventListener(eventName,handler);handler=null});Slim.customDirective(attr=>attr.nodeName==="s:if",(source,target,attribute)=>{let expression=attribute.value;let path=expression;let isNegative=false;if(path.charAt(0)==="!"){path=path.slice(1);isNegative=true}let oldValue;const anchor=document.createComment(`if:${expression}`);target.parentNode.insertBefore(anchor,target);const fn=()=>{let value=!!Slim.lookup(source,path,target);if(isNegative){value=!value}if(value===oldValue)return;if(value){if(target.__isSlim){target.createdCallback()}anchor.parentNode.insertBefore(target,anchor.nextSibling)}else{Slim.removeChild(target)}oldValue=value};Slim.bind(source,target,path,fn)},true);Slim.customDirective(attr=>attr.nodeName==="bind",(source,target)=>{Slim._$(target);target[_$].sourceText=target.innerText;let updatedText="";const matches=target.innerText.match(/\{\{([^\}\}]+)+\}\}/g);const aggProps={};const textBinds={};if(matches){matches.forEach(expression=>{let oldValue;const rxM=/\{\{(.+)(\((.+)\)){1}\}\}/.exec(expression);if(rxM){const fnName=rxM[1];const pNames=rxM[3].split(" ").join("").split(",");pNames.map(path=>path.split(".")[0]).forEach(p=>aggProps[p]=true);textBinds[expression]=(target=>{const args=pNames.map(path=>Slim.lookup(source,path,target));const fn=source[fnName];const value=fn?fn.apply(source,args):undefined;if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")});return}const rxP=/\{\{(.+[^(\((.+)\))])\}\}/.exec(expression);if(rxP){const path=rxP[1];aggProps[path]=true;textBinds[expression]=(target=>{const value=Slim.lookup(source,path,target);if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")})}});const chainExecutor=()=>{updatedText=target[_$].sourceText;Object.keys(textBinds).forEach(expression=>{textBinds[expression](target)});target.innerText=updatedText};Object.keys(aggProps).forEach(prop=>{Slim.bind(source,target,prop,chainExecutor)})}});Slim.customDirective(attr=>attr.nodeName==="s:id",(source,target,attribute)=>{Slim._$(target).boundParent[attribute.value]=target});const wrappedRepeaterExecution=(source,templateNode,attribute)=>{let path=attribute.nodeValue;let tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}const repeater=document.createElement("slim-repeat");repeater[_$].boundParent=source;repeater.dataProp=tProp;repeater.dataPath=attribute.nodeValue;repeater.templateNode=templateNode.cloneNode(true);repeater.templateNode.removeAttribute("s:repeat");templateNode.parentNode.insertBefore(repeater,templateNode);Slim.removeChild(templateNode);Slim.bind(source,repeater,path,()=>{const dataSource=Slim.lookup(source,path);repeater.dataSource=dataSource||[]})};Slim.customDirective(attr=>/^(bind):(\S+)/.exec(attr.nodeName),(source,target,attribute,match)=>{const tAttr=match[2];const tProp=Slim.dashToCamel(tAttr);const expression=attribute.value;let oldValue;const rxM=Slim.rxMethod.exec(expression);if(rxM){const pNames=rxM[3].split(" ").join("").split(",");pNames.forEach(pName=>{Slim.bind(source,target,pName,()=>{const fn=Slim.lookup(source,rxM[1],target);const args=pNames.map(prop=>Slim.lookup(source,prop,target));const value=fn.apply(source,args);if(oldValue===value)return;target[tProp]=value;target.setAttribute(tAttr,value)})});return}const rxP=Slim.rxProp.exec(expression);if(rxP){const prop=rxP[1];Slim.bind(source,target,prop,()=>{const value=Slim.lookup(source,expression,target);if(oldValue===value)return;target.setAttribute(tAttr,value);target[tProp]=value})}});if(__flags.isChrome||__flags.isSafari||__flags.isFirefox)Slim.customDirective(attr=>attr.nodeName==="s:repeat",(source,templateNode,attribute)=>{if(__flags.isFirefox){if(["option","td","tr","th"].indexOf(templateNode.localName)<0){return wrappedRepeaterExecution(source,templateNode,attribute)}}let path=attribute.value;let tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}let clones=[];const hook=document.createComment(`${templateNode.localName} s:repeat="${attribute.value}"`);let templateHTML;Slim._$(hook);Slim.selectRecursive(templateNode,true).forEach(e=>Slim._$(e).excluded=true);templateNode.parentElement.insertBefore(hook,templateNode);templateNode.remove();Slim.unbind(source,templateNode);Slim.asap(()=>{templateNode.setAttribute("s:iterate","");templateNode.removeAttribute("s:repeat");templateHTML=templateNode.outerHTML;templateNode.innerHTML=""});let oldDataSource=[];Slim.bind(source,hook,path,()=>{const dataSource=Slim.lookup(source,path)||[];let offset=0;let restOfData=[];const diff=Array(dataSource.length);dataSource.forEach((d,i)=>{if(oldDataSource[i]!==d){diff[i]=true}});oldDataSource=dataSource.concat();let indices=Object.keys(diff);if(dataSource.lengthclone.remove());indices.forEach(index=>{const clone=clones[index];[clone].concat(Slim.qSelectAll(clone,"*")).forEach(t=>{t[_$].repeater[tProp]=dataSource[index];Slim.commit(t,tProp)})})}else{clones.length&&indices.forEach(index=>{const clone=clones[index];if(!clone)return;[clone].concat(Slim.qSelectAll(clone,"*")).forEach(t=>{t[_$].repeater[tProp]=dataSource[index];Slim.commit(t,tProp)})});restOfData=dataSource.slice(clones.length);offset=clones.length}if(!restOfData.length)return;const range=document.createRange();range.setStartBefore(hook);let html=Array(restOfData.length).fill(templateHTML).join("");const frag=range.createContextualFragment(html);let all=[];let i=0;while(i{all.push(t);Slim._$(t).repeater[tProp]=dataSource[i+offset];Slim.commit(t,tProp)});i++}source._bindChildren(all);all.forEach(t=>{if(t.__isSlim){t.createdCallback();Slim.asap(()=>{Slim.commit(t,tProp);t[tProp]=t[_$].repeater[tProp]})}else{Slim.commit(t,tProp);t[tProp]=t[_$].repeater[tProp]}});hook.parentElement.insertBefore(frag,hook)});source[_$].reversed[tProp]=true},true);else Slim.customDirective(attr=>/^s:repeat$/.test(attr.nodeName),(source,templateNode,attribute)=>{wrappedRepeaterExecution(source,templateNode,attribute)},true);class SlimRepeater extends Slim{get dataSource(){return this._dataSource}set dataSource(v){if(this._dataSource!==v){this._dataSource=v;this.render()}}get boundParent(){return this[_$].boundParent}_bindChildren(tree){tree=Array.prototype.slice.call(tree);const directChildren=Array.prototype.filter.call(tree,child=>child.parentNode.localName==="slim-root-fragment");directChildren.forEach((child,index)=>{child.setAttribute("s:iterate",`${this.dataPath} : ${index}`);Slim.selectRecursive(child).forEach(e=>{Slim._$(e).repeater[this.dataProp]=this.dataSource[index];if(e instanceof Slim){e[this.dataProp]=this.dataSource[index]}})})}onRender(){if(!this.boundParent)return;const tree=Slim.selectRecursive(this);this.boundParent&&this.boundParent._bindChildren(tree);this.boundParent._executeBindings()}render(...args){if(!this.boundParent)return;Slim.qSelectAll(this,"*").forEach(e=>{Slim.unbind(this.boundParent,e)});if(!this.dataSource||!this.templateNode||!this.boundParent){return super.render("")}const newTemplate=Array(this.dataSource.length).fill(this.templateNode.outerHTML).join("");this.innerHTML="";super.render(newTemplate)}}Slim.tag("slim-repeat",SlimRepeater);if(window){window["Slim"]=Slim}if(typeof module!=="undefined"){module.exports.Slim=Slim}})(window,document,HTMLElement); \ No newline at end of file +(function(window,document,HTMLElement){const __flags={isWCSupported:"customElements"in window&&"import"in document.createElement("link")&&"content"in document.createElement("template"),isIE11:!!window["MSInputMethodContext"]&&!!document["documentMode"],isChrome:undefined,isEdge:undefined,isSafari:undefined,isFirefox:undefined};try{__flags.isChrome=/Chrome/.test(navigator.userAgent);__flags.isEdge=/Edge/.test(navigator.userAgent);__flags.isSafari=/Safari/.test(navigator.userAgent);__flags.isFirefox=/Firefox/.test(navigator.userAgent);if(__flags.isIE11||__flags.isEdge){__flags.isChrome=false;Object.defineProperty(Node.prototype,"children",function(){return this.childNodes})}}catch(err){}const _$="_slim_internals_";class Internals{constructor(){this.hasCustomTemplate=undefined;this.boundParent=null;this.repeater={};this.bindings={};this.reversed={};this.inbounds={};this.eventHandlers={};this.internetExploderClone=null;this.rootElement=null;this.createdCallbackInvoked=false;this.sourceText=null;this.excluded=false;this.autoBoundAttributes=[]}}class Slim extends HTMLElement{static dashToCamel(dash){return dash.indexOf("-")<0?dash:dash.replace(/-[a-z]/g,m=>{return m[1].toUpperCase()})}static camelToDash(camel){return camel.replace(/([A-Z])/g,"-$1").toLowerCase()}static get rxInject(){return/\{(.+[^(\((.+)\))])\}/}static get rxProp(){return/(.+[^(\((.+)\))])/}static get rxMethod(){return/(.+)(\((.+)\)){1}/}static lookup(target,expression,maybeRepeated){const chain=expression.split(".");let o;if(maybeRepeated&&maybeRepeated[_$].repeater[chain[0]]){o=maybeRepeated[_$].repeater}else{o=target}let i=0;while(o&&i{fn(target)})}static qSelectAll(target,selector){return[...target.querySelectorAll(selector)]}static unbind(source,target){const bindings=source[_$].bindings;Object.keys(bindings).forEach(key=>{const chain=bindings[key].chain.filter(binding=>{if(binding.target===target){binding.destroy();return false}return true});bindings[key].chain=chain})}static root(target){return target.__isSlim&&target.useShadow?target[_$].rootElement||target:target}static selectRecursive(target,force){const collection=[];const search=function(node,force){collection.push(node);const allow=!node.__isSlim||node.__isSlim&&!node.template||node.__isSlim&&node===target||force;if(allow){const children=[...Slim.root(node).children];children.forEach(childNode=>{search(childNode,force)})}};search(target,force);return collection}static removeChild(target){if(typeof target.remove==="function"){target.remove()}if(target.parentNode){target.parentNode.removeChild(target)}if(this._$(target).internetExploderClone){this.removeChild(this._$(target).internetExploderClone)}}static moveChildren(source,target){while(source.firstChild){target.appendChild(source.firstChild)}}static wrapGetterSetter(element,expression){const pName=expression.split(".")[0];let oSetter=element.__lookupSetter__(pName);if(oSetter&&oSetter[_$])return pName;if(typeof oSetter==="undefined"){oSetter=(()=>{})}const srcValue=element[pName];this._$(element).bindings[pName]=element[_$].bindings[pName]||{chain:[],value:srcValue};element[_$].bindings[pName].value=srcValue;const newSetter=function(v){oSetter.call(element,v);this[_$].bindings[pName].value=v;this._executeBindings(pName)};newSetter[_$]=true;element.__defineGetter__(pName,()=>element[_$].bindings[pName].value);element.__defineSetter__(pName,newSetter);return pName}static bindOwn(target,expression,executor){return Slim.bind(target,target,expression,executor)}static bind(source,target,expression,executor){Slim._$(source);Slim._$(target);if(target[_$].excluded)return;executor.source=source;executor.target=target;const pName=this.wrapGetterSetter(source,expression);if(!source[_$].reversed[pName]){source[_$].bindings[pName].chain.push(executor)}target[_$].inbounds[pName]=target[_$].inbounds[pName]||[];target[_$].inbounds[pName].push(executor);return executor}static update(target,...props){const children=Slim.selectRecursive(target);if(props.length===0){return children.forEach(child=>{Slim.commit(child)})}props.forEach(prop=>{children.forEach(child=>{Slim.commit(child,prop)})})}static commit(target,prop){let keys;let $=target[_$];let chain=[];if(prop){if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}}else{Object.keys(target[_$].inbounds).forEach(prop=>{if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}})}chain.forEach(x=>x())}constructor(){super();const init=()=>{this.__isSlim=true;Slim.debug("ctor",this.localName);if(Slim.checkCreationBlocking(this)){return}this.createdCallback()};if(__flags.isSafari){Slim.asap(init)}else init()}createdCallback(){if(this[_$]&&this[_$].createdCallbackInvoked)return;this._initialize();this[_$].createdCallbackInvoked=true;this.onBeforeCreated();Slim.executePlugins("create",this);this.render();this.onCreated()}connectedCallback(){this.onAdded();Slim.executePlugins("added",this)}disconnectedCallback(){this.onRemoved();Slim.executePlugins("removed",this)}attributeChangedCallback(attr,oldValue,newValue){if(newValue!==oldValue&&this[_$].autoBoundAttributes[attr]){const prop=Slim.dashToCamel(attr);this[prop]=newValue}}get _isInContext(){let node=this;while(node){node=node.parentNode;if(!node){return false}if(node instanceof Document){return true}}return false}_executeBindings(prop){Slim.debug("_executeBindings",this.localName);let all=this[_$].bindings;if(prop){all={[prop]:true}}Object.keys(all).forEach(pName=>{const o=this[_$].bindings[pName];o&&o.chain.forEach(binding=>binding())})}_bindChildren(children){Slim.debug("_bindChildren",this.localName);if(!children){children=Slim.qSelectAll(this,"*")}for(let child of children){Slim._$(child);if(child[_$].boundParent===this)continue;child[_$].boundParent=child[_$].boundParent||this;if(child.attributes.length){let i=0;let n=child.attributes.length;while(i{if(childNode.localName==="style"){this[_$].externalStyle=childNode;childNode.remove()}});const template=this[_$].hasCustomTemplate||this.template;if(template&&typeof template==="string"){const frag=document.createElement("slim-root-fragment");frag.innerHTML=template||"";const scopedChildren=Slim.qSelectAll(frag,"*");if(this[_$].externalStyle){this._bindChildren([this[_$].externalStyle])}this._bindChildren(scopedChildren);Slim.asap(()=>{Slim.moveChildren(frag,this[_$].rootElement||this);this[_$].externalStyle&&this[_$].rootElement.appendChild(this[_$].externalStyle);this._executeBindings();this.onRender();Slim.executePlugins("afterRender",this);this.dispatchEvent(new Event("afterRender"))})}}_initialize(){Slim.debug("_initialize",this.localName);Slim._$(this);this[_$].uniqueIndex=Slim.createUniqueIndex();if(this.useShadow){if(typeof HTMLElement.prototype.attachShadow==="undefined"){this[_$].rootElement=this.createShadowRoot()}else{this[_$].rootElement=this.attachShadow({mode:"open"})}}else{this[_$].rootElement=this}const observedAttributes=this.constructor.observedAttributes;if(observedAttributes){observedAttributes.forEach(attr=>{const pName=Slim.dashToCamel(attr);this[pName]=this.getAttribute(attr)})}}commit(...args){Slim.commit(this,...args)}update(...args){Slim.update(this,...args)}render(tpl){this._render(tpl)}onRender(){}onBeforeCreated(){}onCreated(){}onAdded(){}onRemoved(){}find(selector){return this[_$].rootElement.querySelector(selector)}findAll(selector){return Slim.qSelectAll(this[_$].rootElement,selector)}callAttribute(attr,data){const fnName=this.getAttribute(attr);if(fnName){return this[_$].boundParent[fnName](data)}}get useShadow(){return false}get template(){return Slim.tagToTemplateDict.get(Slim.tagOf(this.constructor))}}Slim.uniqueIndex=0;Slim.tagToClassDict=new Map;Slim.classToTagDict=new Map;Slim.tagToTemplateDict=new Map;Slim.plugins={create:[],added:[],beforeRender:[],afterRender:[],removed:[]};Slim.debug=(()=>{});Slim.asap=window&&window.requestAnimationFrame?cb=>window.requestAnimationFrame(cb):typeof setImmediate!=="undefined"?setImmediate:cb=>setTimeout(cb,0);Slim[_$]={customDirectives:new Map,uniqueCounter:0,supportedNativeEvents:["click","mouseover","mouseout","mousemove","mouseenter","mousedown","mouseup","dblclick","contextmenu","wheel","mouseleave","select","pointerlockchange","pointerlockerror","focus","blur","input","error","invalid","animationstart","animationend","animationiteration","reset","submit","resize","scroll","keydown","keypress","keyup","change"]};Slim.customDirective(attr=>attr.nodeName==="s:switch",(source,target,attribute)=>{const expression=attribute.value;let oldValue;const anchor=document.createComment(`switch:${expression}`);target.appendChild(anchor);const children=[...target.children];const defaultChildren=children.filter(child=>child.hasAttribute("s:default"));const fn=()=>{let value=Slim.lookup(source,expression,target);if(String(value)===oldValue)return;let useDefault=true;children.forEach(child=>{if(child.getAttribute("s:case")===String(value)){if(child.__isSlim){child.createdCallback()}anchor.parentNode.insertBefore(child,anchor);useDefault=false}else{Slim.removeChild(child)}});if(useDefault){defaultChildren.forEach(child=>{if(child.__isSlim){child.createdCallback()}anchor.parentNode.insertBefore(child,anchor)})}else{defaultChildren.forEach(child=>{Slim.removeChild(child)})}oldValue=String(value)};Slim.bind(source,target,expression,fn)});Slim.customDirective(attr=>/^s:case$/.exec(attr.nodeName),()=>{},true);Slim.customDirective(attr=>/^s:default$/.exec(attr.nodeName),()=>{},true);Slim.customDirective(attr=>Slim[_$].supportedNativeEvents.indexOf(attr.nodeName)>=0,(source,target,attribute)=>{const eventName=attribute.nodeName;const delegate=attribute.value;Slim._$(target).eventHandlers=target[_$].eventHandlers||{};const allHandlers=target[_$].eventHandlers;allHandlers[eventName]=allHandlers[eventName]||[];let handler=e=>{try{source[delegate].call(source,e)}catch(err){err.message=`Could not respond to event "${eventName}" on ${target.localName} -> "${delegate}" on ${source.localName} ... ${err.message}`;console.warn(err)}};allHandlers[eventName].push(handler);target.addEventListener(eventName,handler);handler=null});Slim.customDirective(attr=>attr.nodeName==="s:if",(source,target,attribute)=>{let expression=attribute.value;let path=expression;let isNegative=false;if(path.charAt(0)==="!"){path=path.slice(1);isNegative=true}let oldValue;const anchor=document.createComment(`if:${expression}`);target.parentNode.insertBefore(anchor,target);const fn=()=>{let value=!!Slim.lookup(source,path,target);if(isNegative){value=!value}if(value===oldValue)return;if(value){if(target.__isSlim){target.createdCallback()}anchor.parentNode.insertBefore(target,anchor.nextSibling)}else{Slim.removeChild(target)}oldValue=value};Slim.bind(source,target,path,fn)},true);Slim.customDirective(attr=>attr.nodeName==="bind",(source,target)=>{Slim._$(target);target[_$].sourceText=target.innerText;let updatedText="";const matches=target.innerText.match(/\{\{([^\}\}]+)+\}\}/g);const aggProps={};const textBinds={};if(matches){matches.forEach(expression=>{let oldValue;const rxM=/\{\{(.+)(\((.+)\)){1}\}\}/.exec(expression);if(rxM){const fnName=rxM[1];const pNames=rxM[3].split(" ").join("").split(",");pNames.map(path=>path.split(".")[0]).forEach(p=>aggProps[p]=true);textBinds[expression]=(target=>{const args=pNames.map(path=>Slim.lookup(source,path,target));const fn=source[fnName];const value=fn?fn.apply(source,args):undefined;if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")});return}const rxP=/\{\{(.+[^(\((.+)\))])\}\}/.exec(expression);if(rxP){const path=rxP[1];aggProps[path]=true;textBinds[expression]=(target=>{const value=Slim.lookup(source,path,target);if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")})}});const chainExecutor=()=>{updatedText=target[_$].sourceText;Object.keys(textBinds).forEach(expression=>{textBinds[expression](target)});target.innerText=updatedText};Object.keys(aggProps).forEach(prop=>{Slim.bind(source,target,prop,chainExecutor)})}});Slim.customDirective(attr=>attr.nodeName==="s:id",(source,target,attribute)=>{Slim._$(target).boundParent[attribute.value]=target});const wrappedRepeaterExecution=(source,templateNode,attribute)=>{let path=attribute.nodeValue;let tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}const repeater=document.createElement("slim-repeat");repeater[_$].boundParent=source;repeater.dataProp=tProp;repeater.dataPath=attribute.nodeValue;repeater.templateNode=templateNode.cloneNode(true);repeater.templateNode.removeAttribute("s:repeat");templateNode.parentNode.insertBefore(repeater,templateNode);Slim.removeChild(templateNode);Slim.bind(source,repeater,path,()=>{const dataSource=Slim.lookup(source,path);repeater.dataSource=dataSource||[]})};Slim.customDirective(attr=>/^(bind):(\S+)/.exec(attr.nodeName),(source,target,attribute,match)=>{const tAttr=match[2];const tProp=Slim.dashToCamel(tAttr);const expression=attribute.value;let oldValue;const rxM=Slim.rxMethod.exec(expression);if(rxM){const pNames=rxM[3].split(" ").join("").split(",");pNames.forEach(pName=>{Slim.bind(source,target,pName,()=>{const fn=Slim.lookup(source,rxM[1],target);const args=pNames.map(prop=>Slim.lookup(source,prop,target));const value=fn.apply(source,args);if(oldValue===value)return;target[tProp]=value;target.setAttribute(tAttr,value)})});return}const rxP=Slim.rxProp.exec(expression);if(rxP){const prop=rxP[1];Slim.bind(source,target,prop,()=>{const value=Slim.lookup(source,expression,target);if(oldValue===value)return;target.setAttribute(tAttr,value);target[tProp]=value})}});if(__flags.isChrome||__flags.isSafari||__flags.isFirefox)Slim.customDirective(attr=>attr.nodeName==="s:repeat",(source,templateNode,attribute)=>{if(__flags.isFirefox){if(["option","td","tr","th"].indexOf(templateNode.localName)<0){return wrappedRepeaterExecution(source,templateNode,attribute)}}let path=attribute.value;let tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}let clones=[];const hook=document.createComment(`${templateNode.localName} s:repeat="${attribute.value}"`);let templateHTML;Slim._$(hook);Slim.selectRecursive(templateNode,true).forEach(e=>Slim._$(e).excluded=true);templateNode.parentElement.insertBefore(hook,templateNode);templateNode.remove();Slim.unbind(source,templateNode);Slim.asap(()=>{templateNode.setAttribute("s:iterate","");templateNode.removeAttribute("s:repeat");templateHTML=templateNode.outerHTML;templateNode.innerHTML=""});let oldDataSource=[];Slim.bind(source,hook,path,()=>{const dataSource=Slim.lookup(source,path)||[];let offset=0;let restOfData=[];const diff=Array(dataSource.length);dataSource.forEach((d,i)=>{if(oldDataSource[i]!==d){diff[i]=true}});oldDataSource=dataSource.concat();let indices=Object.keys(diff);if(dataSource.lengthclone.remove());indices.forEach(index=>{const clone=clones[index];[clone].concat(Slim.qSelectAll(clone,"*")).forEach(t=>{t[_$].repeater[tProp]=dataSource[index];Slim.commit(t,tProp)})})}else{clones.length&&indices.forEach(index=>{const clone=clones[index];if(!clone)return;[clone].concat(Slim.qSelectAll(clone,"*")).forEach(t=>{t[_$].repeater[tProp]=dataSource[index];Slim.commit(t,tProp)})});restOfData=dataSource.slice(clones.length);offset=clones.length}if(!restOfData.length)return;const range=document.createRange();range.setStartBefore(hook);let html=Array(restOfData.length).fill(templateHTML).join("");const frag=range.createContextualFragment(html);let all=[];let i=0;while(i{all.push(t);Slim._$(t).repeater[tProp]=dataSource[i+offset];Slim.commit(t,tProp)});i++}source._bindChildren(all);all.forEach(t=>{if(t.__isSlim){t.createdCallback();Slim.asap(()=>{Slim.commit(t,tProp);t[tProp]=t[_$].repeater[tProp]})}else{Slim.commit(t,tProp);t[tProp]=t[_$].repeater[tProp]}});hook.parentElement.insertBefore(frag,hook)});source[_$].reversed[tProp]=true},true);else Slim.customDirective(attr=>/^s:repeat$/.test(attr.nodeName),(source,templateNode,attribute)=>{wrappedRepeaterExecution(source,templateNode,attribute)},true);class SlimRepeater extends Slim{get dataSource(){return this._dataSource}set dataSource(v){if(this._dataSource!==v){this._dataSource=v;this.render()}}get boundParent(){return this[_$].boundParent}_bindChildren(tree){tree=Array.prototype.slice.call(tree);const directChildren=Array.prototype.filter.call(tree,child=>child.parentNode.localName==="slim-root-fragment");directChildren.forEach((child,index)=>{child.setAttribute("s:iterate",`${this.dataPath} : ${index}`);Slim.selectRecursive(child).forEach(e=>{Slim._$(e).repeater[this.dataProp]=this.dataSource[index];e[this.dataProp]=this.dataSource[index];if(e instanceof Slim){e[this.dataProp]=this.dataSource[index]}})})}onRender(){if(!this.boundParent)return;const tree=Slim.selectRecursive(this);this.boundParent&&this.boundParent._bindChildren(tree);this.boundParent._executeBindings()}render(...args){if(!this.boundParent)return;Slim.qSelectAll(this,"*").forEach(e=>{Slim.unbind(this.boundParent,e)});if(!this.dataSource||!this.templateNode||!this.boundParent){return super.render("")}const newTemplate=Array(this.dataSource.length).fill(this.templateNode.outerHTML).join("");this.innerHTML="";super.render(newTemplate)}}Slim.tag("slim-repeat",SlimRepeater);if(window){window["Slim"]=Slim}if(typeof module!=="undefined"){module.exports.Slim=Slim}})(window,document,HTMLElement); \ No newline at end of file diff --git a/Slim.js b/Slim.js index 2e12b68..ff1d5fd 100644 --- a/Slim.js +++ b/Slim.js @@ -1106,6 +1106,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons child.setAttribute('s:iterate', _this6.dataPath + ' : ' + index); Slim.selectRecursive(child).forEach(function (e) { Slim._$(e).repeater[_this6.dataProp] = _this6.dataSource[index]; + e[_this6.dataProp] = _this6.dataSource[index]; if (e instanceof Slim) { e[_this6.dataProp] = _this6.dataSource[index]; } diff --git a/Slim.min.js b/Slim.min.js index 3f923cb..200021b 100644 --- a/Slim.min.js +++ b/Slim.min.js @@ -1 +1 @@ -"use strict";var _get=function get(object,property,receiver){if(object===null)object=Function.prototype;var desc=Object.getOwnPropertyDescriptor(object,property);if(desc===undefined){var parent=Object.getPrototypeOf(object);if(parent===null){return undefined}else{return get(parent,property,receiver)}}else if("value"in desc){return desc.value}else{var getter=desc.get;if(getter===undefined){return undefined}return getter.call(receiver)}};var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();var _createClass=function(){function defineProperties(target,props){for(var i=0;i1?_len-1:0),_key=1;_key<_len;_key++){props[_key-1]=arguments[_key]}if(props.length===0){return children.forEach(function(child){Slim.commit(child)})}props.forEach(function(prop){children.forEach(function(child){Slim.commit(child,prop)})})}},{key:"commit",value:function commit(target,prop){var keys=void 0;var $=target[_$2];var chain=[];if(prop){if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}}else{Object.keys(target[_$2].inbounds).forEach(function(prop){if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}})}chain.forEach(function(x){return x()})}},{key:"rxInject",get:function get(){return/\{(.+[^(\((.+)\))])\}/}},{key:"rxProp",get:function get(){return/(.+[^(\((.+)\))])/}},{key:"rxMethod",get:function get(){return/(.+)(\((.+)\)){1}/}}]);function Slim(){_classCallCheck(this,Slim);var _this=_possibleConstructorReturn(this,(Slim.__proto__||Object.getPrototypeOf(Slim)).call(this));var init=function init(){_this.__isSlim=true;Slim.debug("ctor",_this.localName);if(Slim.checkCreationBlocking(_this)){return}_this.createdCallback()};if(__flags.isSafari){Slim.asap(init)}else init();return _this}_createClass(Slim,[{key:"createdCallback",value:function createdCallback(){if(this[_$2]&&this[_$2].createdCallbackInvoked)return;this._initialize();this[_$2].createdCallbackInvoked=true;this.onBeforeCreated();Slim.executePlugins("create",this);this.render();this.onCreated()}},{key:"connectedCallback",value:function connectedCallback(){this.onAdded();Slim.executePlugins("added",this)}},{key:"disconnectedCallback",value:function disconnectedCallback(){this.onRemoved();Slim.executePlugins("removed",this)}},{key:"attributeChangedCallback",value:function attributeChangedCallback(attr,oldValue,newValue){if(newValue!==oldValue&&this[_$2].autoBoundAttributes[attr]){var prop=Slim.dashToCamel(attr);this[prop]=newValue}}},{key:"_executeBindings",value:function _executeBindings(prop){var _this2=this;Slim.debug("_executeBindings",this.localName);var all=this[_$2].bindings;if(prop){all=_defineProperty({},prop,true)}Object.keys(all).forEach(function(pName){var o=_this2[_$2].bindings[pName];o&&o.chain.forEach(function(binding){return binding()})})}},{key:"_bindChildren",value:function _bindChildren(children){Slim.debug("_bindChildren",this.localName);if(!children){children=Slim.qSelectAll(this,"*")}var _iteratorNormalCompletion2=true;var _didIteratorError2=false;var _iteratorError2=undefined;try{for(var _iterator2=children[Symbol.iterator](),_step2;!(_iteratorNormalCompletion2=(_step2=_iterator2.next()).done);_iteratorNormalCompletion2=true){var child=_step2.value;Slim._$(child);if(child[_$2].boundParent===this)continue;child[_$2].boundParent=child[_$2].boundParent||this;if(child.attributes.length){var i=0;var n=child.attributes.length;while(i=0},function(source,target,attribute){var eventName=attribute.nodeName;var delegate=attribute.value;Slim._$(target).eventHandlers=target[_$2].eventHandlers||{};var allHandlers=target[_$2].eventHandlers;allHandlers[eventName]=allHandlers[eventName]||[];var handler=function handler(e){try{source[delegate].call(source,e)}catch(err){err.message='Could not respond to event "'+eventName+'" on '+target.localName+' -> "'+delegate+'" on '+source.localName+" ... "+err.message;console.warn(err)}};allHandlers[eventName].push(handler);target.addEventListener(eventName,handler);handler=null});Slim.customDirective(function(attr){return attr.nodeName==="s:if"},function(source,target,attribute){var expression=attribute.value;var path=expression;var isNegative=false;if(path.charAt(0)==="!"){path=path.slice(1);isNegative=true}var oldValue=void 0;var anchor=document.createComment("if:"+expression);target.parentNode.insertBefore(anchor,target);var fn=function fn(){var value=!!Slim.lookup(source,path,target);if(isNegative){value=!value}if(value===oldValue)return;if(value){if(target.__isSlim){target.createdCallback()}anchor.parentNode.insertBefore(target,anchor.nextSibling)}else{Slim.removeChild(target)}oldValue=value};Slim.bind(source,target,path,fn)},true);Slim.customDirective(function(attr){return attr.nodeName==="bind"},function(source,target){Slim._$(target);target[_$2].sourceText=target.innerText;var updatedText="";var matches=target.innerText.match(/\{\{([^\}\}]+)+\}\}/g);var aggProps={};var textBinds={};if(matches){matches.forEach(function(expression){var oldValue=void 0;var rxM=/\{\{(.+)(\((.+)\)){1}\}\}/.exec(expression);if(rxM){var fnName=rxM[1];var pNames=rxM[3].split(" ").join("").split(",");pNames.map(function(path){return path.split(".")[0]}).forEach(function(p){return aggProps[p]=true});textBinds[expression]=function(target){var args=pNames.map(function(path){return Slim.lookup(source,path,target)});var fn=source[fnName];var value=fn?fn.apply(source,args):undefined;if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")};return}var rxP=/\{\{(.+[^(\((.+)\))])\}\}/.exec(expression);if(rxP){var path=rxP[1];aggProps[path]=true;textBinds[expression]=function(target){var value=Slim.lookup(source,path,target);if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")}}});var chainExecutor=function chainExecutor(){updatedText=target[_$2].sourceText;Object.keys(textBinds).forEach(function(expression){textBinds[expression](target)});target.innerText=updatedText};Object.keys(aggProps).forEach(function(prop){Slim.bind(source,target,prop,chainExecutor)})}});Slim.customDirective(function(attr){return attr.nodeName==="s:id"},function(source,target,attribute){Slim._$(target).boundParent[attribute.value]=target});var wrappedRepeaterExecution=function wrappedRepeaterExecution(source,templateNode,attribute){var path=attribute.nodeValue;var tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}var repeater=document.createElement("slim-repeat");repeater[_$2].boundParent=source;repeater.dataProp=tProp;repeater.dataPath=attribute.nodeValue;repeater.templateNode=templateNode.cloneNode(true);repeater.templateNode.removeAttribute("s:repeat");templateNode.parentNode.insertBefore(repeater,templateNode);Slim.removeChild(templateNode);Slim.bind(source,repeater,path,function(){var dataSource=Slim.lookup(source,path);repeater.dataSource=dataSource||[]})};Slim.customDirective(function(attr){return/^(bind):(\S+)/.exec(attr.nodeName)},function(source,target,attribute,match){var tAttr=match[2];var tProp=Slim.dashToCamel(tAttr);var expression=attribute.value;var oldValue=void 0;var rxM=Slim.rxMethod.exec(expression);if(rxM){var pNames=rxM[3].split(" ").join("").split(",");pNames.forEach(function(pName){Slim.bind(source,target,pName,function(){var fn=Slim.lookup(source,rxM[1],target);var args=pNames.map(function(prop){return Slim.lookup(source,prop,target)});var value=fn.apply(source,args);if(oldValue===value)return;target[tProp]=value;target.setAttribute(tAttr,value)})});return}var rxP=Slim.rxProp.exec(expression);if(rxP){var prop=rxP[1];Slim.bind(source,target,prop,function(){var value=Slim.lookup(source,expression,target);if(oldValue===value)return;target.setAttribute(tAttr,value);target[tProp]=value})}});if(__flags.isChrome||__flags.isSafari||__flags.isFirefox)Slim.customDirective(function(attr){return attr.nodeName==="s:repeat"},function(source,templateNode,attribute){if(__flags.isFirefox){if(["option","td","tr","th"].indexOf(templateNode.localName)<0){return wrappedRepeaterExecution(source,templateNode,attribute)}}var path=attribute.value;var tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}var clones=[];var hook=document.createComment(templateNode.localName+' s:repeat="'+attribute.value+'"');var templateHTML=void 0;Slim._$(hook);Slim.selectRecursive(templateNode,true).forEach(function(e){return Slim._$(e).excluded=true});templateNode.parentElement.insertBefore(hook,templateNode);templateNode.remove();Slim.unbind(source,templateNode);Slim.asap(function(){templateNode.setAttribute("s:iterate","");templateNode.removeAttribute("s:repeat");templateHTML=templateNode.outerHTML;templateNode.innerHTML=""});var oldDataSource=[];Slim.bind(source,hook,path,function(){var dataSource=Slim.lookup(source,path)||[];var offset=0;var restOfData=[];var diff=Array(dataSource.length);dataSource.forEach(function(d,i){if(oldDataSource[i]!==d){diff[i]=true}});oldDataSource=dataSource.concat();var indices=Object.keys(diff);if(dataSource.length1?_len-1:0),_key=1;_key<_len;_key++){props[_key-1]=arguments[_key]}if(props.length===0){return children.forEach(function(child){Slim.commit(child)})}props.forEach(function(prop){children.forEach(function(child){Slim.commit(child,prop)})})}},{key:"commit",value:function commit(target,prop){var keys=void 0;var $=target[_$2];var chain=[];if(prop){if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}}else{Object.keys(target[_$2].inbounds).forEach(function(prop){if($.inbounds[prop]){chain=chain.concat($.inbounds[prop]||[])}if($.bindings[prop]){chain=chain.concat($.bindings[prop].chain)}})}chain.forEach(function(x){return x()})}},{key:"rxInject",get:function get(){return/\{(.+[^(\((.+)\))])\}/}},{key:"rxProp",get:function get(){return/(.+[^(\((.+)\))])/}},{key:"rxMethod",get:function get(){return/(.+)(\((.+)\)){1}/}}]);function Slim(){_classCallCheck(this,Slim);var _this=_possibleConstructorReturn(this,(Slim.__proto__||Object.getPrototypeOf(Slim)).call(this));var init=function init(){_this.__isSlim=true;Slim.debug("ctor",_this.localName);if(Slim.checkCreationBlocking(_this)){return}_this.createdCallback()};if(__flags.isSafari){Slim.asap(init)}else init();return _this}_createClass(Slim,[{key:"createdCallback",value:function createdCallback(){if(this[_$2]&&this[_$2].createdCallbackInvoked)return;this._initialize();this[_$2].createdCallbackInvoked=true;this.onBeforeCreated();Slim.executePlugins("create",this);this.render();this.onCreated()}},{key:"connectedCallback",value:function connectedCallback(){this.onAdded();Slim.executePlugins("added",this)}},{key:"disconnectedCallback",value:function disconnectedCallback(){this.onRemoved();Slim.executePlugins("removed",this)}},{key:"attributeChangedCallback",value:function attributeChangedCallback(attr,oldValue,newValue){if(newValue!==oldValue&&this[_$2].autoBoundAttributes[attr]){var prop=Slim.dashToCamel(attr);this[prop]=newValue}}},{key:"_executeBindings",value:function _executeBindings(prop){var _this2=this;Slim.debug("_executeBindings",this.localName);var all=this[_$2].bindings;if(prop){all=_defineProperty({},prop,true)}Object.keys(all).forEach(function(pName){var o=_this2[_$2].bindings[pName];o&&o.chain.forEach(function(binding){return binding()})})}},{key:"_bindChildren",value:function _bindChildren(children){Slim.debug("_bindChildren",this.localName);if(!children){children=Slim.qSelectAll(this,"*")}var _iteratorNormalCompletion2=true;var _didIteratorError2=false;var _iteratorError2=undefined;try{for(var _iterator2=children[Symbol.iterator](),_step2;!(_iteratorNormalCompletion2=(_step2=_iterator2.next()).done);_iteratorNormalCompletion2=true){var child=_step2.value;Slim._$(child);if(child[_$2].boundParent===this)continue;child[_$2].boundParent=child[_$2].boundParent||this;if(child.attributes.length){var i=0;var n=child.attributes.length;while(i=0},function(source,target,attribute){var eventName=attribute.nodeName;var delegate=attribute.value;Slim._$(target).eventHandlers=target[_$2].eventHandlers||{};var allHandlers=target[_$2].eventHandlers;allHandlers[eventName]=allHandlers[eventName]||[];var handler=function handler(e){try{source[delegate].call(source,e)}catch(err){err.message='Could not respond to event "'+eventName+'" on '+target.localName+' -> "'+delegate+'" on '+source.localName+" ... "+err.message;console.warn(err)}};allHandlers[eventName].push(handler);target.addEventListener(eventName,handler);handler=null});Slim.customDirective(function(attr){return attr.nodeName==="s:if"},function(source,target,attribute){var expression=attribute.value;var path=expression;var isNegative=false;if(path.charAt(0)==="!"){path=path.slice(1);isNegative=true}var oldValue=void 0;var anchor=document.createComment("if:"+expression);target.parentNode.insertBefore(anchor,target);var fn=function fn(){var value=!!Slim.lookup(source,path,target);if(isNegative){value=!value}if(value===oldValue)return;if(value){if(target.__isSlim){target.createdCallback()}anchor.parentNode.insertBefore(target,anchor.nextSibling)}else{Slim.removeChild(target)}oldValue=value};Slim.bind(source,target,path,fn)},true);Slim.customDirective(function(attr){return attr.nodeName==="bind"},function(source,target){Slim._$(target);target[_$2].sourceText=target.innerText;var updatedText="";var matches=target.innerText.match(/\{\{([^\}\}]+)+\}\}/g);var aggProps={};var textBinds={};if(matches){matches.forEach(function(expression){var oldValue=void 0;var rxM=/\{\{(.+)(\((.+)\)){1}\}\}/.exec(expression);if(rxM){var fnName=rxM[1];var pNames=rxM[3].split(" ").join("").split(",");pNames.map(function(path){return path.split(".")[0]}).forEach(function(p){return aggProps[p]=true});textBinds[expression]=function(target){var args=pNames.map(function(path){return Slim.lookup(source,path,target)});var fn=source[fnName];var value=fn?fn.apply(source,args):undefined;if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")};return}var rxP=/\{\{(.+[^(\((.+)\))])\}\}/.exec(expression);if(rxP){var path=rxP[1];aggProps[path]=true;textBinds[expression]=function(target){var value=Slim.lookup(source,path,target);if(oldValue===value)return;updatedText=updatedText.split(expression).join(value||"")}}});var chainExecutor=function chainExecutor(){updatedText=target[_$2].sourceText;Object.keys(textBinds).forEach(function(expression){textBinds[expression](target)});target.innerText=updatedText};Object.keys(aggProps).forEach(function(prop){Slim.bind(source,target,prop,chainExecutor)})}});Slim.customDirective(function(attr){return attr.nodeName==="s:id"},function(source,target,attribute){Slim._$(target).boundParent[attribute.value]=target});var wrappedRepeaterExecution=function wrappedRepeaterExecution(source,templateNode,attribute){var path=attribute.nodeValue;var tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}var repeater=document.createElement("slim-repeat");repeater[_$2].boundParent=source;repeater.dataProp=tProp;repeater.dataPath=attribute.nodeValue;repeater.templateNode=templateNode.cloneNode(true);repeater.templateNode.removeAttribute("s:repeat");templateNode.parentNode.insertBefore(repeater,templateNode);Slim.removeChild(templateNode);Slim.bind(source,repeater,path,function(){var dataSource=Slim.lookup(source,path);repeater.dataSource=dataSource||[]})};Slim.customDirective(function(attr){return/^(bind):(\S+)/.exec(attr.nodeName)},function(source,target,attribute,match){var tAttr=match[2];var tProp=Slim.dashToCamel(tAttr);var expression=attribute.value;var oldValue=void 0;var rxM=Slim.rxMethod.exec(expression);if(rxM){var pNames=rxM[3].split(" ").join("").split(",");pNames.forEach(function(pName){Slim.bind(source,target,pName,function(){var fn=Slim.lookup(source,rxM[1],target);var args=pNames.map(function(prop){return Slim.lookup(source,prop,target)});var value=fn.apply(source,args);if(oldValue===value)return;target[tProp]=value;target.setAttribute(tAttr,value)})});return}var rxP=Slim.rxProp.exec(expression);if(rxP){var prop=rxP[1];Slim.bind(source,target,prop,function(){var value=Slim.lookup(source,expression,target);if(oldValue===value)return;target.setAttribute(tAttr,value);target[tProp]=value})}});if(__flags.isChrome||__flags.isSafari||__flags.isFirefox)Slim.customDirective(function(attr){return attr.nodeName==="s:repeat"},function(source,templateNode,attribute){if(__flags.isFirefox){if(["option","td","tr","th"].indexOf(templateNode.localName)<0){return wrappedRepeaterExecution(source,templateNode,attribute)}}var path=attribute.value;var tProp="data";if(path.indexOf(" as")){tProp=path.split(" as ")[1]||tProp;path=path.split(" as ")[0]}var clones=[];var hook=document.createComment(templateNode.localName+' s:repeat="'+attribute.value+'"');var templateHTML=void 0;Slim._$(hook);Slim.selectRecursive(templateNode,true).forEach(function(e){return Slim._$(e).excluded=true});templateNode.parentElement.insertBefore(hook,templateNode);templateNode.remove();Slim.unbind(source,templateNode);Slim.asap(function(){templateNode.setAttribute("s:iterate","");templateNode.removeAttribute("s:repeat");templateHTML=templateNode.outerHTML;templateNode.innerHTML=""});var oldDataSource=[];Slim.bind(source,hook,path,function(){var dataSource=Slim.lookup(source,path)||[];var offset=0;var restOfData=[];var diff=Array(dataSource.length);dataSource.forEach(function(d,i){if(oldDataSource[i]!==d){diff[i]=true}});oldDataSource=dataSource.concat();var indices=Object.keys(diff);if(dataSource.length { Slim._$(e).repeater[this.dataProp] = this.dataSource[index] + e[this.dataProp] = this.dataSource[index] if (e instanceof Slim) { e[this.dataProp] = this.dataSource[index] }