2023-06-22 14:56:24 +00:00
|
|
|
import { getBasePath } from './utilities/base-path.js';
|
2023-02-22 19:18:04 +00:00
|
|
|
|
|
|
|
const observer = new MutationObserver(mutations => {
|
|
|
|
for (const { addedNodes } of mutations) {
|
|
|
|
for (const node of addedNodes) {
|
|
|
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
|
|
discover(node as Element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks a node for undefined elements and attempts to register them.
|
|
|
|
*/
|
2023-03-13 15:47:37 +00:00
|
|
|
export async function discover(root: Element | ShadowRoot) {
|
|
|
|
const rootTagName = root instanceof Element ? root.tagName.toLowerCase() : '';
|
|
|
|
const rootIsCustomElement = rootTagName?.includes('-');
|
2023-02-22 19:18:04 +00:00
|
|
|
const tags = [...root.querySelectorAll(':not(:defined)')]
|
|
|
|
.map(el => el.tagName.toLowerCase())
|
|
|
|
.filter(tag => tag.startsWith('sl-'));
|
|
|
|
|
|
|
|
// If the root element is an undefined custom element, add it to the list
|
|
|
|
if (rootIsCustomElement && !customElements.get(rootTagName)) {
|
2023-03-13 15:47:37 +00:00
|
|
|
tags.push(rootTagName);
|
2023-02-22 19:18:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Make the list unique
|
|
|
|
const tagsToRegister = [...new Set(tags)];
|
|
|
|
|
|
|
|
await Promise.allSettled(tagsToRegister.map(tagName => register(tagName)));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Registers an element by tag name.
|
|
|
|
*/
|
|
|
|
function register(tagName: string): Promise<void> {
|
|
|
|
const tagWithoutPrefix = tagName.replace(/^sl-/i, '');
|
|
|
|
const path = getBasePath(`components/${tagWithoutPrefix}/${tagWithoutPrefix}.js`);
|
|
|
|
|
|
|
|
// If the element is already defined, there's nothing more to do
|
|
|
|
if (customElements.get(tagName)) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register it
|
|
|
|
return new Promise((resolve, reject) => {
|
2023-07-03 19:17:43 +00:00
|
|
|
import(path).then(() => resolve()).catch(() => reject(new Error(`Unable to autoload <${tagName}> from ${path}`)));
|
2023-02-22 19:18:04 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initial discovery
|
|
|
|
discover(document.body);
|
|
|
|
|
|
|
|
// Listen for new undefined elements
|
2023-05-17 20:50:34 +00:00
|
|
|
observer.observe(document.documentElement, { subtree: true, childList: true });
|