xtal-sip
Version:
Dynamically "water" a custom element tag with the necessary dependencies to sprout the tag from an inert seedling to a thing of beauty.
119 lines (118 loc) • 4.51 kB
JavaScript
//TODO: return import when available?
export async function preemptiveImport(arg) {
const ctx = arg[3] || {};
arg[3] = ctx;
let linkTagId = arg[0];
if (linkTagId !== undefined) {
if (typeof (linkTagId) === 'function') {
linkTagId = linkTagId(ctx);
}
ctx.path = linkTagId;
const linkTag = self[linkTagId];
if (linkTag === undefined) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', e => {
preemptiveImport(arg);
});
return;
}
else {
if (self['link-debug']) {
console.warn(`link tag with id ${linkTagId} not found.`);
}
}
}
else {
if (linkTag.localName === 'link') { //security precaution
if (linkTag.dataset.loaded === 'true') {
return;
}
//TODO: dry
switch (linkTag.rel) {
case 'modulelazyload':
case 'modulepreload': {
const scriptTag = document.createElement('script');
scriptTag.type = 'module';
scriptTag.integrity = linkTag.integrity;
scriptTag.src = linkTag.href;
scriptTag.crossOrigin = linkTag.crossOrigin;
document.head.appendChild(scriptTag);
linkTag.dataset.loaded = 'true';
return;
}
case 'lazyload':
case 'preload': {
switch (linkTag.as) {
case 'script': {
const scriptTag = document.createElement('script');
scriptTag.integrity = linkTag.integrity;
scriptTag.crossOrigin = linkTag.crossOrigin;
scriptTag.src = linkTag.href;
document.head.appendChild(scriptTag);
linkTag.dataset.loaded = 'true';
return;
}
case 'style': {
const styleTag = document.createElement('link');
styleTag.rel = 'stylesheet';
styleTag.integrity = linkTag.integrity;
styleTag.crossOrigin = linkTag.crossOrigin;
styleTag.href = linkTag.href;
document.head.appendChild(styleTag);
return;
}
}
}
}
}
}
}
//No go for linkTag, try importmap.
const dynamicImport = arg[1];
switch (typeof dynamicImport) {
case 'function': {
try {
const actualPath = await dynamicImport(ctx);
if (typeof actualPath === 'string') {
await import(actualPath);
}
return;
}
catch (e) { }
}
}
//No luck with importMap, try CDN
let CDNPath = arg[2];
const options = arg[4] || { cssScope: 'na' };
if (CDNPath !== undefined) {
if (typeof CDNPath === 'function') {
CDNPath = CDNPath(ctx);
}
if (options !== undefined && options.cssScope !== 'na') {
const cssScope = options.cssScope;
if (cssScope !== undefined) {
const styleTag = document.createElement('link');
styleTag.rel = 'stylesheet';
styleTag.href = CDNPath;
switch (cssScope) {
case 'global':
document.head.appendChild(styleTag);
break;
case 'shadow':
//TODO: Constructible Stylesheets.
options.host.appendChild(styleTag);
break;
}
}
else {
import(CDNPath);
}
}
else {
import(CDNPath);
}
}
else {
throw `Unable to resolve ${linkTagId} and ${dynamicImport.toString()}`;
}
}