bindom
Version:
Tiny, powerful data binding & web application framework
2 lines (1 loc) • 24.8 kB
JavaScript
const t=new Map,e=new Map;function getClass(n,o=3e3){return t.has(n)?Promise.resolve(t.get(n)):(e.has(n)||e.set(n,[]),new Promise(((t,r)=>e.get(n).push({resolve:t,timeoutId:iniTimeout(n,o,r)}))))}function iniTimeout(t,e,n){return setTimeout((()=>n(new Error(`Failed to register required class "${t}" after ${e}ms`))),e)}function addClass(n,o={}){!function checkNew({name:e}){if(!t.has(e))return;throw new Error(`Cannot register class "${e}", because it already exists`)}(n);const r={Class:n,...o};t.set(n.name,r),function resolveWait({name:t},n){if(!e.has(t))return;for(const{resolve:o,timeoutId:r}of e.get(t))clearTimeout(r),o(n);e.delete(t)}(n,r)}const n=/^(attr:)|@/,o=/^(prop:)|\./,r=/^((text:)|§)$/;class Quary extends Array{constructor(t,e){if(0===t)return super(0);let n;n=Array.isArray(t)?t:"string"==typeof t?[quary.template(t)]:t instanceof Quary?t:t instanceof NodeList||t instanceof HTMLCollection?Array.from(t):[t.shadowRoot||t],e&&(n=find(n,e)),super(...n)}access(t,e){const[,n,o]=t.match(/^(.)(.*)$/),r=arguments.length>1;switch(n){case"@":return r?this.attr(o,e):this.map((t=>t.getAttribute(o)));case".":return r?this.prop(o,e):this.map((t=>t[o]));case"§":return r?this.text(e):this.map((t=>t.nodeType===Node.TEXT_NODE&&t.nodeValue||textNode(t)&&textNode(t).nodeValue));default:throw new Error('Key in calls to "access" must start with "@", ".", or "§"')}}addClass(t){for(const e of this)e.classList&&e.classList.add(t);return this}after(t){for(const e of this){const n=e.parentNode;e===n.lastChild?toNodes(n,t,(t=>n.appendChild(t))):toNodes(n,t,(t=>n.insertBefore(t,e.nextSibling)))}return this}append(t){for(const e of this)toNodes(e,t,(t=>e.appendChild(t)));return this}attr(t,e){if(1===arguments.length)return this[0]&&this[0].getAttribute&&this[0].getAttribute(t);if(void 0===e||!1===e||null===e)for(const e of this)e.removeAttribute&&e.removeAttribute(t);else{"string"!=typeof e&&(e=JSON.stringify(e));for(const n of this)n.setAttribute&&n.setAttribute(t,e)}return this}before(t){for(const e of this)toNodes(e.parentNode,t,(t=>e.parentNode.insertBefore(t,e)));return this}call(t,...e){return this.map((n=>n[t]&&n[t](...e)))}ccall(t,...e){for(const n of this)n[t]&&n[t](...e);return this}emit(t,e){if(t instanceof Event&&e)throw new Error("EITHER pass an Event instance OR optionally pass customEventInit");"string"==typeof t&&(t=new CustomEvent(t,e||{}));for(const e of this)e.dispatchEvent&&e.dispatchEvent(t);return this}hasClass(t){for(const e of this)if(e.classList&&e.classList.contains(t))return!0;return!1}off(t,e){for(const s of this)if(n.test(t))try{s[obsKey(attrFilter(t))][e].disconnect()}catch(t){}else if(o.test(t))offProp(s,t,e);else if(r.test(t))try{s[obsKey({characterData:!0,subtree:!0})][e].disconnect()}catch(t){}else s.removeEventListener&&s.removeEventListener(t,e._quaryNoSelf||e);return this}on(t,e,s){const i=3===arguments.length&&"noSelf"===e;2===arguments.length&&(s=e);for(const e of this)r.test(t)?observer(e,i,s,{characterData:!0,subtree:!0}):n.test(t)?observer(e,i,s,attrFilter(t)):o.test(t)?onProp(e,t,i,s):e.addEventListener&&e.addEventListener(t,i?noSelf(s):s);return this}once(t,e){for(const s of this)r.test(t)?onceObserver(s,e,{characterData:!0,subtree:!0}):n.test(t)?onceObserver(s,e,attrFilter(t)):o.test(t)?onceProp(s,t,e):s.addEventListener&&s.addEventListener(t,e,{once:!0});return this}prepend(t){for(const e of this)e.firstChild?toNodes(e,t,(t=>e.insertBefore(t,e.firstChild))):toNodes(e,t,(t=>e.appendChild(t)));return this}prop(t,e){if(1===arguments.length)return this[0]&&this[0][t];for(const n of this)n[t]=e;return this}query(t){return new Quary(find(this,t))}removeClass(t){for(const e of this)e.classList&&e.classList.remove(t);return this}shadow(t,e={mode:"open"}){for(const n of this){if(!n.attachShadow)continue;const o=n.attachShadow(e);t&&o.appendChild(s.template(t))}return this}text(t){if(!arguments.length)return this[0]&&this[0].firstChild&&(this[0].firstChild.nodeType===Node.TEXT_NODE&&this[0].firstChild.nodeValue||textNode(this[0])&&textNode(this[0]).nodeValue);for(const e of this)e.firstChild&&e.firstChild.nodeType===Node.TEXT_NODE?e.firstChild.nodeValue=t:textNode(e,!0).nodeValue=t;return this}toggleClass(t,e){if(1===arguments.length)for(const e of this)e.classList&&e.classList.toggle(t);else{e=!!e;for(const n of this)n.classList&&n.classList.toggle(t,e)}return this}when(t){return new Promise((e=>this.once(t,e)))}}function quary(t,e){return new Quary(t,e)}const s=quary;function toNodes(t,e,n){if(e instanceof HTMLTemplateElement)return n(e.content.cloneNode(!0));if(e instanceof Node)return n(e);if(e.constructor===Object&&(e=quary.template(e)),"function"==typeof e)return function isProcessDynNodes(t){return a&&t&&t.prototype&&t.prototype.constructor===a}(e)?e(t,n):n(e());e instanceof Array||(e=new Quary(e));for(const t of e)n(t)}function find(t,e){const n=[];for(let o=0;o<t.length;o++)if(/:host/.test(e))for(let r of e.split(","))if(/^\s*:host\s*/.test(r)){r=r.replace(/^\s*:host\s*/,"");let e=t[o].host||t[o];"string"==typeof e&&(e=t[o]),/[^\s]/.test(r)?n.push(...e.querySelectorAll(r)):n.push(e)}else n.push(...t[o].querySelectorAll(r));else t[o].querySelectorAll&&n.push(...t[o].querySelectorAll(e));return n}function textNode(t,e){for(let e=0;e<t.childNodes.length;e++)if(t.childNodes[e].nodeType===Node.TEXT_NODE)return t.childNodes[e];if(e)return console.warn&&console.warn('Quary is creating a text node. For performance reason you should put the text node into your DOM from the start (e.g. as an empty space or zero width space "​")'),t.appendChild(document.createTextNode("")),t.lastChild}function attrFilter(t){return{attributes:!0,attributeFilter:[t.replace(n,"")]}}function onceObserver(t,e,n){const o=observer(t,!1,(function(...t){o.disconnect(),e(...t)}),n,e)}function observer(t,e,n,o,r=n){const s=new MutationObserver(e?noSelf(n,!0):n);return s.observe(t,o),t[obsKey(o)]?t[obsKey(o)][r]=s:t[obsKey(o)]={[r]:s},s}function obsKey(t){return`_quaryObserver${JSON.stringify(t)}`}function offProp(t,e,n){const r=e.replace(o,""),s=propKey(r);if(!t[s])return;const i=t[s].listener,a=i.indexOf(n._quaryNoSelf||n);if(-1!==a&&i.splice(a,1),i.length)return;const c=t[s].value;delete t[s],delete t[r],t[r]=c}function onceProp(t,e,n){onProp(t,e,!1,(function _onceListener(...o){offProp(t,e,_onceListener),n(...o)}))}function onProp(t,e,n,r){const s=e.replace(o,""),i=propKey(s);let a;t[i]?a=!0:t[i]={listener:[]},t[i].listener.push(n?noSelf(r):r),a||((t instanceof HTMLInputElement&&("value"===s||"checked"===s)||t instanceof HTMLSelectElement&&"value"===s)&&onInputValueChange(t,s,i,e),function onPropertyChange(t,e,n,o){(Object.prototype.hasOwnProperty.call(t,e)||void 0!==t[e])&&(t[n].value=t[e],delete t[e]);const r=function htmlElementProperty(t,e){try{for(;t;){t=Object.getPrototypeOf(t);const n=Object.getOwnPropertyDescriptor(t,e);if(n)return n}}catch(t){return}}(t,e);Object.defineProperty(t,e,{get:function(){return r?r.get.call(this):t[n].value},set:function(e){return r?(r.set.call(this,e),t[n].value=r.get.call(this)):t[n].value=e,tell(t,t[n],o),e},enumerable:!0,configurable:!0})}(t,s,i))}function onInputValueChange(t,e,n,o){const r=`${n}-Listener`;if(!t[r])switch(e){case"value":t[r]=!0,t.addEventListener("change",(()=>{t[n].value=t.value,tell(t,t[n],o)}));break;case"checked":t[r]=!0,t.addEventListener("change",(()=>{t[n].checked=t.checked,tell(t,t[n],o)}))}}function propKey(t){return`_quaryProp${t}`}function tell(t,e,n){for(const o of e.listener)o(e.value,t,n)}function noSelf(t,e){let n;return t._quaryNoSelf=function(){n||(n=!0,t(),e?setTimeout((function(){n=!1})):n=!1)}}const i={};let a;function parse(t,e,n,o){const r=e.map(function parseBoundNode(t,{noRoot:e}={}){return function(n){const o=e?t=>parseSingleBinding(!1,sq(n),t):e=>parseSingleBinding(t.includes(n),sq(n),e);return n.dataset.bind.replace(/\s+/g,";").replace(/(?:^;)|(?:;$)/g,"").split(";").filter((t=>t)).map(o).filter((t=>t))}}(t,o)).flat();return function assemble(t,e){const n={};let o;const setStage=t=>o=e.filter((({key:e})=>e.length>t));for(let t=0;setStage(t).length;t++)for(const e of o)setMap(n,t,e);return n}(0,r)}function sq(t){return t.shadowRoot?quary(t,":host"):quary(t)}function parseSingleBinding(t,e,n){const o=/÷/.test(n)?"÷":":",r=n.split(o);!function validateSingleBinding(t){if(2!==t.length)throw new Error(`Invalid binding "${t.join(":")}"; expecting "key:domBindExpression" or "key÷domBindExpression"`)}(r);const s=function parseKey(t,[e],n){return t?!/^\^/.test(n)&&n.split("."):e.hasAttribute("data-class")?!!/^\^/.test(n)&&n.replace(/^\^/,"").split("."):n.split(".")}(t,e,r[0]);if(s)return function bindingDefinition(t,e,n){const o={node:t,key:n,to:parseDomExp(e[1])};!/^\^/.test(e[0])&&t.attr("data-class")&&{attr:1,prop:1,text:1}[o.to.type]&&(o.hostBinding=!0);return o}(e,r,s)}function parseDomExp(t){const e=t.replace(/(?:^[.!@§])|(?:\(\)$)/,"");return/^\./.test(t)?{type:"prop",on:t,key:e}:/^!/.test(t)?{type:"event",on:t,key:e}:/^@/.test(t)?{type:"attr",on:t,key:e}:/^§/.test(t)?{type:"text",on:t,key:e}:/^\*$/.test(t)?{type:"node"}:/\(\)$/.test(t)?{type:"func",key:e}:void function bindExpErr(t){throw new Error(`Invalid DOM-bind-expression "${t}"; expecting ".property" or "!event" or "@attribute" or "§" (for text)`)}(t)}function setMap(t,e,n){let o=t;for(let t=0;t<e;t++)o=o[n.key[t]].def;const r=n.key[e];n.key.length===e+1?function setMapLeaf(t,e,n){t[e]?Array.isArray(t[e].def)||inconsistentBindings(n):t[e]={def:[]};t[e].def.push(n)}(o,r,n):o[r]&&Array.isArray(o[r].def)?inconsistentBindings(n):o[r]||(o[r]={def:{}})}function inconsistentBindings({key:t}){throw new Error(`Inconsistent binding for ${t.join(".")}; EITHER nested object OR binding`)}function bindObject(t,e,n=[]){for(const[o,r]of Object.entries(e)){const{get:e,set:s}=accessor(t,r.def,n.concat([o]));Object.defineProperty(t,o,{get:e,set:s,configurable:!0})}return t}function addProperty(t,e,n,o){for(const{obj:r,prop:s}of path(t,n)){e[s]=o;const{get:t,set:i}=accessor(r,o.def,n);Object.defineProperty(r,s,{get:t,set:i,configurable:!0})}}function updateProperty(t,e,n){for(const{obj:o,prop:r}of path(t,n)){const{def:t}=e[r],s=revertObj(t,o,r);if(!t.length)return delete e[r];t.revertProp||void 0===s||(o[r]=s[0]);const{get:i,set:a}=accessor(o,t,n);Object.defineProperty(o,r,{get:i,set:a,configurable:!0})}}function revertObj(t,e,n){let o;try{o=Object.prototype.hasOwnProperty.call(e,n)?[e[n]]:void 0}catch(t){}return delete e[n],t.revertProp&&e.defineProperty(n,t.revertProp),o}function accessor(t,e,n){return Array.isArray(e)?1===e.length?simpleAccessor(t,e[0]):function arrayAccessor(t,e){return e=e.map((e=>simpleAccessor(t,e))),{get:()=>e[0].get(),set:t=>e.map((({set:e})=>e(t)))}}(t,e):function objectAccessor(t,e,n){const o=t[n.at(-1)]||{};return bindObject(o,e,n),{get:()=>o,set:t=>(Object.entries(t).forEach((([t,e])=>o[t]=e)),o)}}(t,e,n)}function simpleAccessor(t,e){switch(e.to.type){case"event":return function eventAccessor(t,e){return registerListener(t,e,e.to.key,(t=>t)),{get(){throw new Error(`Cannot get event "${e.to.key}" with key "${e.key}"`)},set:t=>e.node.emit(e.to.key,t)}}(t,e);case"func":return function funcAccessor({node:t,to:e,key:n}){return{get:()=>(...n)=>t.call(e.key,...n),set(){throw new Error(`Cannot assign to bound function "${e.key}" with key "${n}"`)}}}(e);case"node":return function nodeAccessor({node:t,key:e}){return{get:()=>t,set(){throw new Error(`Cannot assign to bound node with key "${e}"`)}}}(e);case"text":return function textAccessor(t,e){registerListener(t,e,"§",(()=>e.node.text()));const n={get:()=>e.node.text(),set:t=>e.node.text(t)};return propagateToDom(t,e,n),n}(t,e);default:return function defaultAccessor(t,e){const n={get:()=>e.node[e.to.type](e.to.key),set:t=>e.node[e.to.type](e.to.key,t)};return function defaultPropagtation(t,e,n){const o="prop"===e.to.type&&Object.prototype.hasOwnProperty.call(e.node[0],e.to.key);registerListener(t,e,e.to.on,(()=>n.get())),function hasPath(t,{key:e}){for(const{obj:n,prop:o}of path(t,e))return Object.prototype.hasOwnProperty.call(n,o)}(t,e)||("attr"===e.to.type&&function propagatePreAttribute(t,e){if(!e.hostBinding||!e.node[0].hasAttribute(e.to.key)||!e.eventListener)return;setTimeout((()=>e.eventListener.handler(e.node.attr(e.to.key))))}(0,e),"prop"===e.to.type&&function propagatePreProperty(t,e,n){if(!e.hostBinding||!n||!e.eventListener)return;setTimeout((()=>e.eventListener.handler(e.node[0][e.to.key])))}(0,e,o));propagateToDom(t,e,n)}(t,e,n),n}(t,e)}}function registerListener(t,e,n,o){const r=getSetter(t,e.key.at(-1),e);let s;if(r)s=function propagateToBound(t,e,n,o){return function(r){for(const{obj:s,prop:i}of path(t,e))s===t&&i===e[0]?n.call(t,o(r)):s[i]=o(r)}}(t,e.key,r,o);else{if(!e.hostBinding)return;s=function propagateToProxy(t,e,n){return function(o){for(const{obj:r,prop:s}of path(t,e))r[s]!==n(o)&&(r[s]=n(o))}}(t,e.key,o)}e.eventListener={evt:n,handler:s},e.node.on(n,s)}function getSetter(t,e,n){if(Object.prototype.hasOwnProperty.call(t,e)){const o=Object.getOwnPropertyDescriptor(t,e);return n&&(n.revertProp=o),o.set}const o=Object.getPrototypeOf(t);if(o)return getSetter(o,e)}function*path(t,e){for(const n of e.slice(0,-1))if(!(t=t[n]))return;yield{obj:t,prop:e.at(-1)}}function propagateToDom(t,e,n){const o=e.key.at(-1);Object.prototype.hasOwnProperty.call(t,o)&&n.set(t[o])}function selectBound(t){const e=t.query("[data-class]");return t.query("[data-bind]").filter((t=>{for(const n of e){if(parentBinding(n,t))return!0;if(n.contains(t))return!1}return!0})).concat(t.filter((t=>t.matches&&t.matches("[data-bind]"))))}function parentBinding(t,e){return t===e&&/\^[^:]+:/.test(t.getAttribute("data-bind"))}function isLeaf(t,e){const n=Array.isArray(t.def);if(n!==Array.isArray(e.def))throw new Error(`Cannot add/remove ${e.def} to/from ${t.def}`);return n}function scopeIds(t,e){const n=`${e}Id`;return t.dataset&&t.dataset[n]?t.dataset[n].split(",").map((t=>parseInt(t,10))):[]}function moveId(t,e,n,o){t.dataset&&scopeIds(t,n).includes(e)&&(removeId(t,e,n),function addId(t,e,n){t.dataset[`${n}Id`]=[...scopeIds(t,n),e].join(",")}(t,e,o))}function removeId(t,e,n){if(!t.dataset)return;const o=scopeIds(t,n).filter((t=>t!==e));o.length?t.dataset[`${n}Id`]=o.join(","):delete t.dataset[`${n}Id`]}function findEntryPoints(t,e,n,o=[]){for(const[r,s]of Object.entries(n)){const n=o.concat(r);e[r]?isLeaf(e[r],s)?mergeEntry(t,e,r,n,s.def):findEntryPoints(t,e[r].def,s.def,n):addProperty(t,e,n,s)}}function mergeEntry(t,e,n,o,r){e[n].def.push(...r),updateProperty(t,e,o)}function removeNodes({forgetScope:t,scopeId:e,object:n,rootNodes:o,map:r,mutated:s}){const i=selectBound(s);findRmPoints(n,r,parse(o,i)),o.emit("beforeUnbind"),t?i.forEach((t=>removeId(t,e,"bound"))):i.forEach((t=>moveId(t,e,"bound","bind"))),o.emit("removedBound",{bubbles:!0})}function findRmPoints(t,e,n,o=[]){for(const[r,s]of Object.entries(n))if(e[r])if(isLeaf(e[r],s)){const n=o.concat(r);rmEntry(t,e,r,s.def,n)}else removeNestedEntries(t,e,r,s,o)}function removeNestedEntries(t,e,n,o,r){findRmPoints(t,e[n].def,o.def,r),Object.keys(e[n].def).length||(delete e[n],delete t[n])}function rmEntry(t,e,n,o,r){const{def:s}=e[n];for(const t of o){const e=s.indexOf(s.find((({node:e})=>e[0]===t.node[0])));s.splice(e,1).forEach(removeEventListener)}1===s.length&&function convertToSimple(t,e,n,o,r){if(removeEventListener(r[0]),"event"===r[0].to.type)return updateProperty(t,e,o);const s=n in t,i=t[n];updateProperty(t,e,o),s&&(t[n]=i)}(t,e,n,r,s),s.length||updateProperty(t,e,r)}function removeEventListener({node:t,eventListener:{evt:e,handler:n}={}}){n&&t.off(e,n)}quary.template=function(t){if("string"==typeof t){if(i[t])return i[t].content.cloneNode(!0);const e=document.createElement("template");return e.innerHTML=t,i[t]=e,e.content.cloneNode(!0)}return t instanceof HTMLTemplateElement?t.content.cloneNode(!0):function dynTemplate(t){const{array:e=[void 0],chunks:n,id:o="default",update:r}=t,i=t.template,c=`_quaryChildArrayDynNode${o}`,d=`_quaryChildArrayTimeout${o}`;function processDynNodes(o,a){o[d]&&(clearTimeout(o[d]),delete o[d]),o[c]||(o[c]=[]);const u=o[c];if(Object.prototype.hasOwnProperty.call(t,"condition")&&!t.condition)return removeNodes(0);function removeNodes(t){for(let e=t;e<u.length;e++)for(let t=0;t<u[e].length;t++)o.removeChild(u[e][t]);u.splice(t)}function iterDynNodeChunk(r){r>=e.length?t.done&&t.done():!n||r%n?iterNodeArray(r):o[d]=setTimeout((()=>iterNodeArray(r)))}function iterNodeArray(t){let n=o[c][t];if(!n){const t=s.template(i);n=s(t.childNodes),a(t),o[c].push(n)}r&&r(s(n),e[t],t),delete o[d],iterDynNodeChunk(++t)}u.length>e.length&&removeNodes(e.length),iterDynNodeChunk(0)}return a=processDynNodes.prototype.constructor,processDynNodes}(t)};const c=new Map;class MutationEvaluator{constructor(t,e,n){this.mutationProp=t,this.handle=e,this.biound=n}process(t){const e=t.map((t=>Array.from(t[this.mutationProp]))).flat();e.length&&(this.timeout?this.nodes.push(...e):(this.timeout=setTimeout(this.flush.bind(this)),this.nodes=e))}flush(){delete this.timeout,function removeMoved(){const t=d.nodes,e=u.nodes;if(!t||!e)return;const n=t.filter((t=>e.includes(t)));if(!n.length)return;d.nodes=t.filter((t=>!n.includes(t))),u.nodes=e.filter((t=>!n.includes(t)))}(),function evaluateMutation(t,e,n){if(!t.length)return;const o=quary(t).query("[data-bind]").concat(t.filter((t=>t.matches&&t.matches("[data-bind]"))));if(!o.length)return;boundScopes(o.filter(unique),n).forEach(e)}(this.nodes.filter(unique),this.handle,this.biound),delete this.nodes}}const d=new MutationEvaluator("addedNodes",(function addNodes({scopeId:t,object:e,rootNodes:n,map:o,mutated:r}){findEntryPoints(e,o,parse(n,selectBound(r))),r.forEach((e=>moveId(e,t,"bind","bound"))),n.emit("addedBound",{bubbles:!0})}),"bind"),u=new MutationEvaluator("removedNodes",removeNodes,"bound");function unique(t,e,n){return n.indexOf(t)===e}function observe(t){d.process(t),u.process(t)}function boundScopes(t,e){const n={};for(const o of t)addToScope(n,o,e);return Object.values(n)}function addToScope(t,e,n){for(const o of scopeIds(e,n))t[o]?t[o].mutated.push(e):t[o]={...c.get(o),mutated:quary(e),scopeId:o}}let f=0;function monitor(t,e,n,o){const r=f++;c.set(r,{object:t,map:e,rootNodes:o}),function addIdToDom(t,e,n){e.forEach((({dataset:e})=>e.boundId=e.boundId?`${e.boundId},${t}`:t)),addIdToTemplates(n,t)}(r,n,o),function iniObserver(){if(f>1)return;new MutationObserver(observe).observe(document,{childList:!0,subtree:!0})}()}function addIdToTemplates(t,e){(function filterBranch(t,e){return t.query(e).concat(t.filter((t=>t.matches&&t.matches(e))))})(t,"template:not([data-class])").forEach((({content:t})=>{const n=quary(t.children);selectBound(n).attr("data-bind-id",e),addIdToTemplates(n,e)}))}function unbind(t,e){const n=t.query("[data-bind]").concat(t.filter((t=>t.matches&&t.matches("[data-bind]"))));if(!n.length)return;const o=boundScopes(n,"bound");e?o.filter(function filter(t){if("object"==typeof t)return({object:e})=>t===e;if("number"==typeof t)return({scopeId:e})=>t===e;if("string"==typeof t){const e=parseInt(t,10);return({scopeId:t})=>e===t}}(e)).forEach(rmNodes):o.forEach(rmNodes)}function rmNodes(t){removeNodes(Object.assign({forgetScope:!0},t))}function bind(t,e,n){const o=selectBound(e),r=parse(e,o,0,n);return monitor(t,r,o,e),function boundObject(t,e){return bindObject(t,e)}(t,r)}Quary.prototype.bind=function(t={}){return bind(t,this)},Quary.prototype.unbind=function(t){return unbind(this,t)};const l=new Map;function addStyle(t){return l.has(t)||(quary(document.head).append(`<style>${t}</style>`),l.set(t,document.head.lastChild)),l.get(t)}let p=0;const h=new WeakMap,y=new WeakMap,m=new WeakMap,b=new WeakMap;function insertAndBindTemplate(t,e={}){return withOutBinding(!0,t,e)}function insertTemplate(t,e={}){return withOutBinding(!1,t,e)}async function withOutBinding(t,e,n){const o=function determineParent(t){return t.dataset.parent?function findParent(t){let e=t.parentElement;const n=t.dataset.parent;for(;e;){const t=e.querySelector(n);if(t)return quary(t);e=e.parentElement}return}(t):t.dataset.insert?quary(t.parentElement):quary(t,":host")}(e);if(!o)return;const r=function determineInsertMethod(t){return t.dataset.insert?t.dataset.insert:t.dataset.parent?"append":"before"}(e),s=await function debounceGetInsertOptions(t,e,n,o){return new Promise((async r=>{b.set(e,r);const s=await async function getInsertOptions(t,e,n,o){const{id:r,Class:s}=await async function getTemplate(t,e,n){if(!h.has(e))return await iniTemplate(t,e);if(!t)return h.get(e);const o=h.get(e);return o.Class.name===e.dataset.class?o:(n(o.id),await updateTemplate(e,o,!0))}(t,e,o),i={id:r,template:e,...n,done:done(e,n)};t&&(i.update=function executeBind({Class:t,update:e,updateStrategy:n}){return function(o,r,s){if(function doReOrNewBind(t,[e],n){return!t||"rebind"===t||y.get(e)!==n&&(y.set(e,n),!0)}(n,o,t))!function reOrNewBind(t,e,n,o,r){const s=o.constructor.name===t.name,i=s?o:new t;n.unbind(n.prop("proxy"));const a=bind(i,quary(n),{noRoot:!0});n.forEach((t=>function iniProxy$1(t,e){Object.defineProperty(t,"proxy",{get:()=>e,set(t){Object.assign(e,t)},configurable:!0})}(t,a))),s||n.forEach((t=>t.proxy=o));"Object"!==t.name&&n.addClass(t.name);e&&e(n,o,r);n.emit("bound",{detail:o})}(t,e,o,r,s);else{!function updateDom(t,e,n,o,r){if(!r&&function isIdentical([t],e){if(m.get(t)===e)return!0;m.set(t,e)}(t,e))return;t.forEach((t=>t.proxy=e)),o&&o(t,e,n);t.emit("updated",{detail:e})}(o,r,s,e,"always"===n)}}}(Object.assign(n,{Class:s})));t&&!n.array&&(i.array=[new s]);return i}(t,e,n,o);b.get(e)===r&&(b.delete(e),r(s))}))}(t,e,n,(t=>o[r]({id:t,template:e,array:[]})));return o[r](s)}async function iniTemplate(t,e){if(!t)return h.set(e,{id:"sq-instantiate-template-"+p++}),h.get(e);const n={id:"sq-instantiate-template-"+p++};return await updateTemplate(e,n),h.set(e,n),n}async function updateTemplate(t,e,n){const{Class:o,style:r,template:s}=await getClass(t.dataset.class);r&&addStyle(r);const i=quary(t.content);return n&&i.append({array:[],id:e.id}),s&&i.append({template:s,id:e.id}),e.Class=o,e}function done(t,{done:e}){return function(){quary(t).emit("inserted"),e&&e()}}const g=new WeakMap;customElements.define("if-dom",class extends HTMLTemplateElement{get if(){return g.get(this)}set if(t){g.set(this,t),(this.hasAttribute("data-class")?insertAndBindTemplate:insertTemplate)(this,{condition:t})}},{extends:"template"});const v=new WeakMap;function defaultLoopClass(e){e.hasAttribute("data-class")||(function hasClass(e){return t.has(e)}("Object")||addClass(Object),e.setAttribute("data-class","Object"))}async function dataClassAttributeChangedCallback(t,e,n){if("data-class"!==t||!n)return;const o=await getClass(n),r=quary(this);!function iniDom(t,e,n,{bindHost:o,style:r,template:s}){r&&addStyle(r);e?t.removeClass(e):function markPersistentChildren(t){t.forEach((({childNodes:t})=>quary(t).forEach((t=>t._sqBindPersistent=!0))))}(t);t.addClass(n),s&&function append(t,e){t.append({condition:!1,id:"dom-bind",template:e}),t.forEach((({childNodes:t})=>quary(t).filter((t=>!t._sqBindPersistent)).call("remove"))),t.append({condition:!0,id:"dom-bind",template:e})}(t,s);if(!o)return;const i=t.attr("data-bind");if(i&&-1!==i.indexOf(o))return;t.attr("data-bind",i?`${i};${o}`:o)}(r,e,n,o),e&&await async function cleanUpOldHostBinding(t,e){const{bindHost:n}=await getClass(e);if(!n)return;const o=t.attr("data-bind").replace(n,"").replace(/;;/g,";").replace(/;$/g,"");t.attr("data-bind",o)}(r,e),function ini(t,{Class:e},n){const o=new e,r=t.prop("proxy");r&&t.unbind(r);(function iniProxy(t,e){Object.defineProperty(t,"proxy",{get:()=>e,set(t){Object.assign(e,t)},configurable:!0})})(t[0],t.bind(o)),r&&null===n&&(t[0].proxy=r);t.emit("bound",{detail:o})}(r,o,e)}customElements.define("loop-dom",class extends HTMLTemplateElement{constructor(...t){const e=super(...t);return defaultLoopClass(e),e}get array(){return v.get(this)}set array(t){const e=function handleUpdateStrategy(t,e){const[n,o]=t.dataset.update&&t.dataset.update.split(",")||[];if(!n)return;return"unidentical"===n&&e===v.get(t)?"skip":o||n}(this,t);"skip"!==e&&(v.set(this,t),defaultLoopClass(this),insertAndBindTemplate(this,function options(t,e,n){const toItem=t=>"object"==typeof t?t:{item:t},o={array:e.map(toItem)};n&&(o.updateStrategy=n);t.hasAttribute("data-chunks")&&(o.chunks=parseInt(t.getAttribute("data-chunks"),10));return o}(this,t,e)))}},{extends:"template"}),customElements.define("bind-dom",class SqBind extends HTMLElement{static get observedAttributes(){return["data-class"]}async attributeChangedCallback(...t){dataClassAttributeChangedCallback.call(this,...t)}});export{addClass,addStyle,bind,dataClassAttributeChangedCallback,quary as default,insertAndBindTemplate,insertTemplate};