UNPKG

symbiotic

Version:

A lightweight DOM attachment framework

7 lines (6 loc) 6.12 kB
/*! * Symbiote - A lightweight DOM attachment framework * @version 1.0.0 * @license MIT */ var Symbiote=function(e){"use strict";const t={id:new Map,class:new Map,tag:new Map,other:new Set};function o(e){return!/:[a-zA-Z-]/.test(e)}function s(e){const o=e.trim();if(o.startsWith("#")){const e=o.slice(1).split(/[^-_a-zA-Z0-9]/,1)[0];return t.id.has(e)||t.id.set(e,new Set),void t.id.get(e).add(o)}if(o.includes(".")){const e=o.match(/\.[a-zA-Z0-9_-]+/g);if(e){for(const s of e){const e=s.slice(1);t.class.has(e)||t.class.set(e,new Set),t.class.get(e).add(o)}return}}const s=o.split(/[\s.#[:]/,1)[0].toLowerCase();if(s&&(/^[a-z][a-z0-9-]*$/.test(s)||"*"===s))return t.tag.has(s)||t.tag.set(s,new Set),void t.tag.get(s).add(o);if(o.startsWith("[")){const e=o.match(/^([a-z][a-z0-9-]*)\[/);if(e){const s=e[1];return t.tag.has(s)||t.tag.set(s,new Set),void t.tag.get(s).add(o)}}t.other.add(o)}function c(e){const o=e.trim();let s=!1;if(o.startsWith("#")){const e=o.slice(1).split(/[^-_a-zA-Z0-9]/,1)[0],c=t.id.get(e);c&&(c.delete(o),c.size||t.id.delete(e),s=!0)}else if(o.includes(".")){const e=o.match(/\.[a-zA-Z0-9_-]+/g);if(e)for(const c of e){const e=c.slice(1),n=t.class.get(e);n&&(n.delete(o),n.size||t.class.delete(e),s=!0)}}else{const e=o.split(/[\s.#[:]/,1)[0].toLowerCase();if(e&&(/^[a-z][a-z0-9-]*$/.test(e)||"*"===e)){const c=t.tag.get(e);c&&(c.delete(o),c.size||t.tag.delete(e),s=!0)}}if(!s&&o.startsWith("[")){const e=o.match(/^([a-z][a-z0-9-]*)\[/);if(e){const c=e[1],n=t.tag.get(c);n&&(n.delete(o),n.size||t.tag.delete(c),s=!0)}}s||t.other.delete(o)}function*n(e){const o=new Set,s=e.id?.trim();if(s&&t.id.has(s))for(const e of t.id.get(s))o.add(e);if(e.classList&&e.classList.length)for(const s of e.classList){const e=t.class.get(s);if(e)for(const t of e)o.add(t)}const c=e.tagName?.toLowerCase();if(c){const e=t.tag.get(c);if(e)for(const t of e)o.add(t);const s=t.tag.get("*");if(s)for(const e of s)o.add(e)}for(const e of t.other)o.add(e);yield*o}const r=new WeakMap,a=new WeakMap,i=new WeakMap;function d(e){let t=r.get(e);return t||(t=new Set,r.set(e,t)),t}function h(e){let t=a.get(e);return t||(t=new Map,a.set(e,t)),t}function l(e,t){if("function"!=typeof t)return;let o=i.get(e);o||(o=new Set,i.set(e,o)),o.add(t)}const u=new Map,f=new Set;class m{#e=null;#t=new Set;#o=!1;#s=null;constructor(e={}){if(e&&"object"==typeof e)for(const[t,c]of Object.entries(e))o(t)&&(u.set(t,c),s(t));this.#e=new MutationObserver((e=>{for(const t of e)if("childList"===t.type)t.addedNodes.forEach((e=>this.#c(e))),t.removedNodes.forEach((e=>this.#n(e)));else if("attributes"===t.type){const e=t.target;1===e.nodeType&&this.#r(e)}}))}async attach(e=document.body){e===document.body&&await new Promise((e=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e()})),this.#s=e,this.#e.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeOldValue:!0}),this.#a(e)}batch(e){return"function"==typeof e?this.#i(e):Promise.resolve()}update(){this.#s&&this.#a(this.#s,!0)}destroy(){var e;e=this,f.delete(e),this.#e&&this.#e.disconnect(),this.#s&&this.#n(this.#s),this.#s=null}cleanup(e){(this.#s||document).querySelectorAll(e).forEach((t=>this.#d(t,e)))}checkFor(e){(this.#s||document).querySelectorAll(e).forEach((t=>{d(t).has(e)||this.#h(t,e,u.get(e))}))}#a(e,t=!1){this.#e.disconnect();const o=document.createTreeWalker(e,1,null,!1);let s=1===e.nodeType?e:null;for(s&&this.#l(s,t);s=o.nextNode();)this.#l(s,t);this.#s&&this.#e.observe(this.#s,{childList:!0,subtree:!0,attributes:!0,attributeOldValue:!0})}#c(e){if(e&&"number"==typeof e.nodeType&&(1===e.nodeType&&this.#l(e,!0),e.hasChildNodes&&e.childNodes&&e.childNodes.length)){const t=document.createTreeWalker(e,1,null,!1);let o;for(;o=t.nextNode();)this.#l(o,!0)}}#l(e,t){if(1===e.nodeType){t&&this.#r(e);for(const t of n(e)){const s=u.get(t);if(!s)continue;!d(e).has(t)&&o(t)&&e.matches(t)&&this.#h(e,t,s)}}}#r(e){const t=d(e);if(t.size)for(const o of Array.from(t))e.matches(o)||this.#d(e,o);for(const s of n(e)){const c=u.get(s);c&&!t.has(s)&&o(s)&&e.matches(s)&&this.#h(e,s,c)}}#h(e,t,o){if(!o)return;const s=d(e);if(s.has(t))return;const c="TEMPLATE"===e.tagName?[this.#u(e),this.#f()]:[e,this.#f()];try{const n=o(...c);if("function"==typeof n){h(e).set(t,n)}s.add(t)}catch(e){console.error(`Error attaching selector "${t}":`,e)}}#d(e,t){const o=d(e);if(!o.has(t))return;const s=h(e),c=s.get(t);if(c){try{c()}catch(e){console.error(e)}s.delete(t)}o.delete(t),0===o.size&&r.delete(e),0===s.size&&a.delete(e)}#m(e){const t=h(e);if(t)for(const[o]of t)this.#d(e,o);!function(e){const t=i.get(e);if(t){for(const e of t)try{e()}catch(e){console.error(e)}t.clear(),i.delete(e)}}(e)}#n(e){if(e&&"number"==typeof e.nodeType&&(1===e.nodeType&&this.#m(e),e.hasChildNodes&&e.childNodes&&e.childNodes.length)){const t=e.ownerDocument.createTreeWalker(e,1,null,!1);let o;for(;o=t.nextNode();)this.#m(o)}}#f(){return e=>this.batch(e)}#u(e){let t=[];const o=()=>{for(const e of t)this.#n(e),e.parentNode&&e.parentNode.removeChild(e);t=[]};return s=>{o();const c=document.importNode(e.content,!0);if(t=Array.from(c.children),e.after(c),"function"==typeof s)for(const e of t)if(1===e.nodeType)try{const t=s(e,this.#f());"function"==typeof t&&l(e,t)}catch(e){console.error("Error in template child setup:",e)}}}#i(e){return new Promise(((t,o)=>{this.#t.add({operations:e,resolve:t,reject:o}),this.#g()}))}#g(){if(this.#o)return;this.#o=!0;("undefined"!=typeof requestAnimationFrame?requestAnimationFrame:e=>setTimeout(e,0))((()=>{this.#t.forEach((e=>{try{e.operations(),e.resolve()}catch(t){e.reject(t)}})),this.#o=!1,this.#t.clear()}))}}function g(e){const t=new m(e);var o;return o=t,f.add(o),t}return e.createSymbiote=g,e.default=g,e.defineSetup=function(e,t){return o(e)?null===t?(u.has(e)&&(f.forEach((t=>{t.cleanup(e)})),u.delete(e),c(e)),{remove(){}}):(u.has(e)&&(f.forEach((t=>{t.cleanup(e)})),c(e)),u.set(e,t),s(e),f.forEach((t=>{t.checkFor(e)})),{remove:()=>{f.forEach((t=>t.cleanup(e))),u.delete(e),c(e)}}):(console.warn(`Ignoring unstable selector: ${e}`),{remove(){}})},Object.defineProperty(e,"__esModule",{value:!0}),e}({});