UNPKG

uce-loader

Version:

A minimalistic, framework agnostic, lazy Custom Elements loader

44 lines (41 loc) 1.62 kB
// https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name const ignore = /^(?:annotation-xml|color-profile|font-face(?:|-format|-name|-src|-uri)|missing-glyph)$/i; const loaded = new Set; /** * @typedef {Object} Options * @prop {Node} [container=document] - where to monitor Custom Elements * @prop {function} on - a callback invoked per each new Custom Element */ /** * Start observing a document, or a specific container, and automatically * download once Custom Elements from a specific path. * @param {Options} options configuration options * @returns {MutationObserver} the disconnect-able `container` observer */ export default (options) => { const target = options.container || document; const load = mutations => { for (let i = 0, {length} = mutations; i < length; i++) { for (let {addedNodes} = mutations[i], j = 0, {length} = addedNodes; j < length; j++ ) { const node = addedNodes[j]; const {children, getAttribute, tagName} = node; if (getAttribute) { const is = (getAttribute.call(node, 'is') || tagName).toLowerCase(); if (0 < is.indexOf('-') && !loaded.has(is) && !ignore.test(is)) { loaded.add(is); customElements.get(is) || options.on(is); } crawl(children); } } } }; const crawl = addedNodes => { load([{addedNodes}]) }; crawl([document == target ? target.documentElement : target]); const observer = new MutationObserver(load); observer.observe(target, {subtree: true, childList: true}); return observer; };