Skip to content

Commit 8510e7e

Browse files
authored
1 parent eaaecc3 commit 8510e7e

File tree

1 file changed

+101
-80
lines changed

1 file changed

+101
-80
lines changed

app/assets/javascripts/es-module-shims.js

Lines changed: 101 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* ES Module Shims 1.0.0 */
1+
/* ES Module Shims 1.0.4 */
22
(function () {
33

44
const edge = navigator.userAgent.match(/Edge\/\d\d\.\d+$/);
@@ -201,7 +201,7 @@
201201
let shimMode = !!esmsInitOptions$1.shimMode;
202202
const resolveHook = shimMode && esmsInitOptions$1.resolve;
203203

204-
const skip = esmsInitOptions$1.skip ? new RegExp(esmsInitOptions$1.skip) : /^https:\/\/(cdn\.skypack\.dev|jspm\.dev)\//;
204+
const skip = esmsInitOptions$1.skip ? new RegExp(esmsInitOptions$1.skip) : null;
205205

206206
let nonce = esmsInitOptions$1.nonce;
207207

@@ -329,7 +329,35 @@
329329

330330
let importMap = { imports: {}, scopes: {} };
331331
let importMapSrcOrLazy = false;
332-
let importMapPromise = featureDetectionPromise.then(() => undefined);
332+
let baselinePassthrough;
333+
334+
const initPromise = featureDetectionPromise.then(() => {
335+
baselinePassthrough = supportsDynamicImport && supportsImportMeta && supportsImportMaps && (!jsonModulesEnabled || supportsJsonAssertions) && (!cssModulesEnabled || supportsCssAssertions) && !importMapSrcOrLazy && !false;
336+
// shim mode is determined on initialization, no late shim mode
337+
if (!shimMode && document.querySelectorAll('script[type="module-shim"],script[type="importmap-shim"]').length)
338+
setShimMode();
339+
if (shimMode || !baselinePassthrough) {
340+
new MutationObserver(mutations => {
341+
for (const mutation of mutations) {
342+
if (mutation.type !== 'childList') continue;
343+
for (const node of mutation.addedNodes) {
344+
if (node.tagName === 'SCRIPT') {
345+
if (!shimMode && node.type === 'module' || shimMode && node.type === 'module-shim')
346+
processScript(node);
347+
if (!shimMode && node.type === 'importmap' || shimMode && node.type === 'importmap-shim')
348+
processImportMap(node);
349+
}
350+
else if (node.tagName === 'LINK' && node.rel === 'modulepreload')
351+
processPreload(node);
352+
}
353+
}
354+
}).observe(document, { childList: true, subtree: true });
355+
processImportMaps();
356+
processScriptsAndPreloads();
357+
return undefined;
358+
}
359+
});
360+
let importMapPromise = initPromise;
333361

334362
let acceptingImportMaps = true;
335363
let nativeAcceptingImportMaps = true;
@@ -344,7 +372,7 @@
344372
}
345373
await importMapPromise;
346374
// early analysis opt-out - no need to even fetch if we have feature support
347-
if (!shimMode && supportsDynamicImport && supportsImportMeta && supportsImportMaps && (!jsonModulesEnabled || supportsJsonAssertions) && (!cssModulesEnabled || supportsCssAssertions) && !importMapSrcOrLazy && !false) {
375+
if (!shimMode && baselinePassthrough) {
348376
// for polyfill case, only dynamic import needs a return value here, and dynamic import will never pass nativelyLoaded
349377
if (nativelyLoaded)
350378
return null;
@@ -390,7 +418,17 @@
390418
}
391419

392420
async function importShim (id, parentUrl = baseUrl, _assertion) {
393-
processScripts();
421+
// needed for shim check
422+
await initPromise;
423+
if (acceptingImportMaps || shimMode || !baselinePassthrough) {
424+
processImportMaps();
425+
if (!shimMode) {
426+
acceptingImportMaps = false;
427+
}
428+
else {
429+
nativeAcceptingImportMaps = false;
430+
}
431+
}
394432
await importMapPromise;
395433
return topLevelLoad((await resolve(id, parentUrl)).r || throwUnresolved(id, parentUrl), { credentials: 'same-origin' });
396434
}
@@ -400,7 +438,6 @@
400438
const meta = {};
401439

402440
async function importMetaResolve (id, parentUrl = this.url) {
403-
await importMapPromise;
404441
return (await resolve(id, `${parentUrl}`)).r || throwUnresolved(id, parentUrl);
405442
}
406443

@@ -608,7 +645,7 @@
608645
if (d !== -1) return;
609646
if (!r)
610647
throwUnresolved(n, load.r || load.u);
611-
if (skip.test(r)) return { b: r };
648+
if (skip && skip.test(r)) return { b: r };
612649
if (childFetchOpts.integrity)
613650
childFetchOpts = Object.assign({}, childFetchOpts, { integrity: undefined });
614651
return getOrCreateLoad(r, childFetchOpts).f;
@@ -618,19 +655,16 @@
618655
return load;
619656
}
620657

621-
function processScripts () {
658+
function processScriptsAndPreloads () {
659+
for (const script of document.querySelectorAll(shimMode ? 'script[type="module-shim"]' : 'script[type="module"]'))
660+
processScript(script);
622661
for (const link of document.querySelectorAll('link[rel="modulepreload"]'))
623662
processPreload(link);
624-
const scripts = document.querySelectorAll('script[type="module-shim"],script[type="importmap-shim"],script[type="module"],script[type="importmap"]');
625-
// early shim mode opt-in
626-
if (!shimMode) {
627-
for (const script of scripts) {
628-
if (script.type.endsWith('-shim'))
629-
setShimMode();
630-
}
631-
}
632-
for (const script of scripts)
633-
processScript(script);
663+
}
664+
665+
function processImportMaps () {
666+
for (const script of document.querySelectorAll(shimMode ? 'script[type="importmap-shim"]' : 'script[type="importmap"]'))
667+
processImportMap(script);
634668
}
635669

636670
function getFetchOpts (script) {
@@ -656,73 +690,74 @@
656690
document.dispatchEvent(new Event('DOMContentLoaded'));
657691
}
658692
// this should always trigger because we assume es-module-shims is itself a domcontentloaded requirement
659-
document.addEventListener('DOMContentLoaded', domContentLoadedCheck);
693+
document.addEventListener('DOMContentLoaded', async () => {
694+
await initPromise;
695+
domContentLoadedCheck();
696+
if (shimMode || !baselinePassthrough) {
697+
processImportMaps();
698+
processScriptsAndPreloads();
699+
}
700+
});
660701

661702
let readyStateCompleteCnt = 1;
662703
if (document.readyState === 'complete')
663704
readyStateCompleteCheck();
664705
else
665-
document.addEventListener('readystatechange', readyStateCompleteCheck);
706+
document.addEventListener('readystatechange', async () => {
707+
await initPromise;
708+
readyStateCompleteCheck();
709+
});
666710
function readyStateCompleteCheck () {
667711
if (--readyStateCompleteCnt === 0 && !noLoadEventRetriggers)
668712
document.dispatchEvent(new Event('readystatechange'));
669713
}
670714

671-
function processScript (script) {
672-
if (script.ep) // ep marker = script processed
715+
function processImportMap (script) {
716+
if (!acceptingImportMaps)
673717
return;
674-
const shim = script.type.endsWith('-shim');
675-
if (shim && !shimMode) setShimMode();
676-
const type = shimMode ? script.type.slice(0, -5) : script.type;
677-
// dont process module scripts in shim mode or noshim module scripts in polyfill mode
678-
if (!shim && shimMode || script.getAttribute('noshim') !== null)
718+
if (script.ep) // ep marker = script processed
679719
return;
680720
// empty inline scripts sometimes show before domready
681721
if (!script.src && !script.innerHTML)
682722
return;
683723
script.ep = true;
684-
if (type === 'module') {
685-
// does this load block readystate complete
686-
const isReadyScript = readyStateCompleteCnt > 0;
687-
// does this load block DOMContentLoaded
688-
const isDomContentLoadedScript = domContentLoadedCnt > 0;
689-
if (isReadyScript) readyStateCompleteCnt++;
690-
if (isDomContentLoadedScript) domContentLoadedCnt++;
691-
const loadPromise = topLevelLoad(script.src || `${baseUrl}?${id++}`, getFetchOpts(script), !script.src && script.innerHTML, !shimMode, isReadyScript && lastStaticLoadPromise).then(() => {
692-
if (!noLoadEventRetriggers)
693-
triggerLoadEvent(script);
694-
}).catch(e => {
695-
if (!noLoadEventRetriggers)
696-
triggerLoadEvent(script);
697-
// setTimeout(() => { throw e; });
698-
onerror(e);
699-
});
700-
if (isReadyScript)
701-
lastStaticLoadPromise = loadPromise.then(readyStateCompleteCheck);
702-
if (isDomContentLoadedScript)
703-
loadPromise.then(domContentLoadedCheck);
724+
// we dont currently support multiple, external or dynamic imports maps in polyfill mode to match native
725+
if (script.src || !nativeAcceptingImportMaps) {
726+
if (!shimMode)
727+
return;
728+
importMapSrcOrLazy = true;
704729
}
705-
else if (acceptingImportMaps && type === 'importmap') {
706-
// we dont currently support multiple, external or dynamic imports maps in polyfill mode to match native
707-
if (script.src || !nativeAcceptingImportMaps) {
708-
if (!shimMode)
709-
return;
710-
importMapSrcOrLazy = true;
711-
}
712-
if (!shimMode) {
713-
acceptingImportMaps = false;
714-
}
715-
else {
716-
nativeAcceptingImportMaps = false;
717-
}
718-
importMapPromise = importMapPromise.then(async () => {
719-
importMap = resolveAndComposeImportMap(script.src ? await (await fetchHook(script.src)).json() : JSON.parse(script.innerHTML), script.src || baseUrl, importMap);
720-
});
730+
if (!shimMode) {
731+
acceptingImportMaps = false;
721732
}
733+
else {
734+
nativeAcceptingImportMaps = false;
735+
}
736+
importMapPromise = importMapPromise.then(async () => {
737+
importMap = resolveAndComposeImportMap(script.src ? await (await fetchHook(script.src)).json() : JSON.parse(script.innerHTML), script.src || baseUrl, importMap);
738+
});
722739
}
723740

724-
function triggerLoadEvent (script) {
725-
script.dispatchEvent(new Event('load'));
741+
function processScript (script) {
742+
if (script.ep) // ep marker = script processed
743+
return;
744+
if (script.getAttribute('noshim') !== null)
745+
return;
746+
// empty inline scripts sometimes show before domready
747+
if (!script.src && !script.innerHTML)
748+
return;
749+
script.ep = true;
750+
// does this load block readystate complete
751+
const isReadyScript = readyStateCompleteCnt > 0;
752+
// does this load block DOMContentLoaded
753+
const isDomContentLoadedScript = domContentLoadedCnt > 0;
754+
if (isReadyScript) readyStateCompleteCnt++;
755+
if (isDomContentLoadedScript) domContentLoadedCnt++;
756+
const loadPromise = topLevelLoad(script.src || `${baseUrl}?${id++}`, getFetchOpts(script), !script.src && script.innerHTML, !shimMode, isReadyScript && lastStaticLoadPromise).catch(onerror);
757+
if (isReadyScript)
758+
lastStaticLoadPromise = loadPromise.then(readyStateCompleteCheck);
759+
if (isDomContentLoadedScript)
760+
loadPromise.then(domContentLoadedCheck);
726761
}
727762

728763
const fetchCache = {};
@@ -735,22 +770,8 @@
735770
fetchCache[link.href] = doFetch(link.href, getFetchOpts(link));
736771
}
737772

738-
new MutationObserver(mutations => {
739-
for (const mutation of mutations) {
740-
if (mutation.type !== 'childList') continue;
741-
for (const node of mutation.addedNodes) {
742-
if (node.tagName === 'SCRIPT' && node.type)
743-
processScript(node);
744-
else if (node.tagName === 'LINK' && node.rel === 'modulepreload')
745-
processPreload(node);
746-
}
747-
}
748-
}).observe(document, { childList: true, subtree: true });
749-
750773
function throwUnresolved (id, parentUrl) {
751774
throw Error("Unable to resolve specifier '" + id + (parentUrl ? "' from " + parentUrl : "'"));
752775
}
753776

754-
processScripts();
755-
756-
}());
777+
}());

0 commit comments

Comments
 (0)