diff --git a/app/assets/javascripts/es-module-shims.js b/app/assets/javascripts/es-module-shims.js index adb8173..2f34da5 100644 --- a/app/assets/javascripts/es-module-shims.js +++ b/app/assets/javascripts/es-module-shims.js @@ -1,804 +1,845 @@ -/* ES Module Shims 1.4.6 */ +/* ES Module Shims 1.5.5 */ (function () { - const noop = () => {}; - - const optionsScript = document.querySelector('script[type=esms-options]'); - - const esmsInitOptions = optionsScript ? JSON.parse(optionsScript.innerHTML) : self.esmsInitOptions ? self.esmsInitOptions : {}; - - let shimMode = !!esmsInitOptions.shimMode; - const resolveHook = globalHook(shimMode && esmsInitOptions.resolve); - - const skip = esmsInitOptions.skip ? new RegExp(esmsInitOptions.skip) : null; - - let nonce = esmsInitOptions.nonce; - - const mapOverrides = esmsInitOptions.mapOverrides; - - if (!nonce) { - const nonceElement = document.querySelector('script[nonce]'); - if (nonceElement) - nonce = nonceElement.nonce || nonceElement.getAttribute('nonce'); - } - - const onerror = globalHook(esmsInitOptions.onerror || noop); - const onpolyfill = esmsInitOptions.onpolyfill ? globalHook(esmsInitOptions.onpolyfill) : () => console.info(`OK: ^ TypeError module failure has been polyfilled`); - - const { revokeBlobURLs, noLoadEventRetriggers, enforceIntegrity } = esmsInitOptions; - - const fetchHook = esmsInitOptions.fetch ? globalHook(esmsInitOptions.fetch) : fetch; - - function globalHook (name) { - return typeof name === 'string' ? self[name] : name; - } - - const enable = Array.isArray(esmsInitOptions.polyfillEnable) ? esmsInitOptions.polyfillEnable : []; - const cssModulesEnabled = enable.includes('css-modules'); - const jsonModulesEnabled = enable.includes('json-modules'); - - function setShimMode () { - shimMode = true; - } - - const edge = !!navigator.userAgent.match(/Edge\/\d+\.\d+/); - - const baseUrl = document.baseURI; - - function createBlob (source, type = 'text/javascript') { - return URL.createObjectURL(new Blob([source], { type })); - } - - const eoop = err => setTimeout(() => { throw err }); - - const throwError = err => { (window.reportError || window.safari && console.error || eoop)(err), void onerror(err); }; - - function isURL (url) { - try { - new URL(url); - return true; - } - catch (_) { - return false; - } - } - - const backslashRegEx = /\\/g; - - /* - * Import maps implementation - * - * To make lookups fast we pre-resolve the entire import map - * and then match based on backtracked hash lookups - * - */ - function resolveUrl (relUrl, parentUrl) { - return resolveIfNotPlainOrUrl(relUrl, parentUrl) || (relUrl.indexOf(':') !== -1 ? relUrl : resolveIfNotPlainOrUrl('./' + relUrl, parentUrl)); - } - - function resolveIfNotPlainOrUrl (relUrl, parentUrl) { - // strip off any trailing query params or hashes - parentUrl = parentUrl && parentUrl.split('#')[0].split('?')[0]; - if (relUrl.indexOf('\\') !== -1) - relUrl = relUrl.replace(backslashRegEx, '/'); - // protocol-relative - if (relUrl[0] === '/' && relUrl[1] === '/') { - return parentUrl.slice(0, parentUrl.indexOf(':') + 1) + relUrl; - } - // relative-url - else if (relUrl[0] === '.' && (relUrl[1] === '/' || relUrl[1] === '.' && (relUrl[2] === '/' || relUrl.length === 2 && (relUrl += '/')) || - relUrl.length === 1 && (relUrl += '/')) || - relUrl[0] === '/') { - const parentProtocol = parentUrl.slice(0, parentUrl.indexOf(':') + 1); - // Disabled, but these cases will give inconsistent results for deep backtracking - //if (parentUrl[parentProtocol.length] !== '/') - // throw new Error('Cannot resolve'); - // read pathname from parent URL - // pathname taken to be part after leading "/" - let pathname; - if (parentUrl[parentProtocol.length + 1] === '/') { - // resolving to a :// so we need to read out the auth and host - if (parentProtocol !== 'file:') { - pathname = parentUrl.slice(parentProtocol.length + 2); - pathname = pathname.slice(pathname.indexOf('/') + 1); - } - else { - pathname = parentUrl.slice(8); - } - } - else { - // resolving to :/ so pathname is the /... part - pathname = parentUrl.slice(parentProtocol.length + (parentUrl[parentProtocol.length] === '/')); - } - - if (relUrl[0] === '/') - return parentUrl.slice(0, parentUrl.length - pathname.length - 1) + relUrl; - - // join together and split for removal of .. and . segments - // looping the string instead of anything fancy for perf reasons - // '../../../../../z' resolved to 'x/y' is just 'z' - const segmented = pathname.slice(0, pathname.lastIndexOf('/') + 1) + relUrl; - - const output = []; - let segmentIndex = -1; - for (let i = 0; i < segmented.length; i++) { - // busy reading a segment - only terminate on '/' - if (segmentIndex !== -1) { - if (segmented[i] === '/') { - output.push(segmented.slice(segmentIndex, i + 1)); - segmentIndex = -1; - } - continue; - } - // new segment - check if it is relative - else if (segmented[i] === '.') { - // ../ segment - if (segmented[i + 1] === '.' && (segmented[i + 2] === '/' || i + 2 === segmented.length)) { - output.pop(); - i += 2; - continue; - } - // ./ segment - else if (segmented[i + 1] === '/' || i + 1 === segmented.length) { - i += 1; - continue; - } - } - // it is the start of a new segment - while (segmented[i] === '/') i++; - segmentIndex = i; - } - // finish reading out the last segment - if (segmentIndex !== -1) - output.push(segmented.slice(segmentIndex)); - return parentUrl.slice(0, parentUrl.length - pathname.length) + output.join(''); - } - } - - function resolveAndComposeImportMap (json, baseUrl, parentMap) { - const outMap = { imports: Object.assign({}, parentMap.imports), scopes: Object.assign({}, parentMap.scopes) }; - - if (json.imports) - resolveAndComposePackages(json.imports, outMap.imports, baseUrl, parentMap); - - if (json.scopes) - for (let s in json.scopes) { - const resolvedScope = resolveUrl(s, baseUrl); - resolveAndComposePackages(json.scopes[s], outMap.scopes[resolvedScope] || (outMap.scopes[resolvedScope] = {}), baseUrl, parentMap); - } - - return outMap; - } - - function getMatch (path, matchObj) { - if (matchObj[path]) - return path; - let sepIndex = path.length; - do { - const segment = path.slice(0, sepIndex + 1); - if (segment in matchObj) - return segment; - } while ((sepIndex = path.lastIndexOf('/', sepIndex - 1)) !== -1) - } - - function applyPackages (id, packages) { - const pkgName = getMatch(id, packages); - if (pkgName) { - const pkg = packages[pkgName]; - if (pkg === null) return; - return pkg + id.slice(pkgName.length); - } - } - - - function resolveImportMap (importMap, resolvedOrPlain, parentUrl) { - let scopeUrl = parentUrl && getMatch(parentUrl, importMap.scopes); - while (scopeUrl) { - const packageResolution = applyPackages(resolvedOrPlain, importMap.scopes[scopeUrl]); - if (packageResolution) - return packageResolution; - scopeUrl = getMatch(scopeUrl.slice(0, scopeUrl.lastIndexOf('/')), importMap.scopes); - } - return applyPackages(resolvedOrPlain, importMap.imports) || resolvedOrPlain.indexOf(':') !== -1 && resolvedOrPlain; - } - - function resolveAndComposePackages (packages, outPackages, baseUrl, parentMap) { - for (let p in packages) { - const resolvedLhs = resolveIfNotPlainOrUrl(p, baseUrl) || p; - if ((!shimMode || !mapOverrides) && outPackages[resolvedLhs] && (outPackages[resolvedLhs] !== packages[resolvedLhs])) { - throw Error(`Rejected map override "${resolvedLhs}" from ${outPackages[resolvedLhs]} to ${packages[resolvedLhs]}.`); - } - let target = packages[p]; - if (typeof target !== 'string') - continue; - const mapped = resolveImportMap(parentMap, resolveIfNotPlainOrUrl(target, baseUrl) || target, baseUrl); - if (mapped) { - outPackages[resolvedLhs] = mapped; - continue; - } - console.warn(`Mapping "${p}" -> "${packages[p]}" does not resolve`); - } - } - - let err; - window.addEventListener('error', _err => err = _err); - function dynamicImportScript (url, { errUrl = url } = {}) { - err = undefined; - const src = createBlob(`import*as m from'${url}';self._esmsi=m`); - const s = Object.assign(document.createElement('script'), { type: 'module', src }); - s.setAttribute('nonce', nonce); - s.setAttribute('noshim', ''); - const p = new Promise((resolve, reject) => { - // Safari is unique in supporting module script error events - s.addEventListener('error', cb); - s.addEventListener('load', cb); - - function cb (_err) { - document.head.removeChild(s); - if (self._esmsi) { - resolve(self._esmsi, baseUrl); - self._esmsi = undefined; - } - else { - reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading or executing the graph of ${errUrl} (check the console for ${src}).`)); - err = undefined; - } - } - }); - document.head.appendChild(s); - return p; - } - - let dynamicImport = dynamicImportScript; - - const supportsDynamicImportCheck = dynamicImportScript(createBlob('export default u=>import(u)')).then(_dynamicImport => { - if (_dynamicImport) - dynamicImport = _dynamicImport.default; - return !!_dynamicImport; + const noop = () => {}; + + const optionsScript = document.querySelector('script[type=esms-options]'); + + const esmsInitOptions = optionsScript ? JSON.parse(optionsScript.innerHTML) : {}; + Object.assign(esmsInitOptions, self.esmsInitOptions || {}); + + let shimMode = !!esmsInitOptions.shimMode; + + const importHook = globalHook(shimMode && esmsInitOptions.onimport); + const resolveHook = globalHook(shimMode && esmsInitOptions.resolve); + let fetchHook = esmsInitOptions.fetch ? globalHook(esmsInitOptions.fetch) : fetch; + const metaHook = esmsInitOptions.meta ? globalHook(shimModule && esmsInitOptions.meta) : noop; + + const skip = esmsInitOptions.skip ? new RegExp(esmsInitOptions.skip) : null; + + let nonce = esmsInitOptions.nonce; + + const mapOverrides = esmsInitOptions.mapOverrides; + + if (!nonce) { + const nonceElement = document.querySelector('script[nonce]'); + if (nonceElement) + nonce = nonceElement.nonce || nonceElement.getAttribute('nonce'); + } + + const onerror = globalHook(esmsInitOptions.onerror || noop); + const onpolyfill = esmsInitOptions.onpolyfill ? globalHook(esmsInitOptions.onpolyfill) : () => { + console.log('%c^^ Module TypeError above is polyfilled and can be ignored ^^', 'font-weight:900;color:#391'); + }; + + const { revokeBlobURLs, noLoadEventRetriggers, enforceIntegrity } = esmsInitOptions; + + function globalHook (name) { + return typeof name === 'string' ? self[name] : name; + } + + const enable = Array.isArray(esmsInitOptions.polyfillEnable) ? esmsInitOptions.polyfillEnable : []; + const cssModulesEnabled = enable.includes('css-modules'); + const jsonModulesEnabled = enable.includes('json-modules'); + + function setShimMode () { + shimMode = true; + } + + const edge = !navigator.userAgentData && !!navigator.userAgent.match(/Edge\/\d+\.\d+/); + + const baseUrl = document.baseURI; + + function createBlob (source, type = 'text/javascript') { + return URL.createObjectURL(new Blob([source], { type })); + } + + const eoop = err => setTimeout(() => { throw err }); + + const throwError = err => { (window.reportError || window.safari && console.error || eoop)(err), void onerror(err); }; + + function fromParent (parent) { + return parent ? ` imported from ${parent}` : ''; + } + + const backslashRegEx = /\\/g; + + function isURL (url) { + if (url.indexOf(':') === -1) return false; + try { + new URL(url); + return true; + } + catch (_) { + return false; + } + } + + /* + * Import maps implementation + * + * To make lookups fast we pre-resolve the entire import map + * and then match based on backtracked hash lookups + * + */ + function resolveUrl (relUrl, parentUrl) { + return resolveIfNotPlainOrUrl(relUrl, parentUrl) || (isURL(relUrl) ? relUrl : resolveIfNotPlainOrUrl('./' + relUrl, parentUrl)); + } + + function resolveIfNotPlainOrUrl (relUrl, parentUrl) { + // strip off any trailing query params or hashes + const queryHashIndex = parentUrl.indexOf('?', parentUrl.indexOf('#') === -1 ? parentUrl.indexOf('#') : parentUrl.length); + if (queryHashIndex !== -1) + parentUrl = parentUrl.slice(0, queryHashIndex); + if (relUrl.indexOf('\\') !== -1) + relUrl = relUrl.replace(backslashRegEx, '/'); + // protocol-relative + if (relUrl[0] === '/' && relUrl[1] === '/') { + return parentUrl.slice(0, parentUrl.indexOf(':') + 1) + relUrl; + } + // relative-url + else if (relUrl[0] === '.' && (relUrl[1] === '/' || relUrl[1] === '.' && (relUrl[2] === '/' || relUrl.length === 2 && (relUrl += '/')) || + relUrl.length === 1 && (relUrl += '/')) || + relUrl[0] === '/') { + const parentProtocol = parentUrl.slice(0, parentUrl.indexOf(':') + 1); + // Disabled, but these cases will give inconsistent results for deep backtracking + //if (parentUrl[parentProtocol.length] !== '/') + // throw new Error('Cannot resolve'); + // read pathname from parent URL + // pathname taken to be part after leading "/" + let pathname; + if (parentUrl[parentProtocol.length + 1] === '/') { + // resolving to a :// so we need to read out the auth and host + if (parentProtocol !== 'file:') { + pathname = parentUrl.slice(parentProtocol.length + 2); + pathname = pathname.slice(pathname.indexOf('/') + 1); + } + else { + pathname = parentUrl.slice(8); + } + } + else { + // resolving to :/ so pathname is the /... part + pathname = parentUrl.slice(parentProtocol.length + (parentUrl[parentProtocol.length] === '/')); + } + + if (relUrl[0] === '/') + return parentUrl.slice(0, parentUrl.length - pathname.length - 1) + relUrl; + + // join together and split for removal of .. and . segments + // looping the string instead of anything fancy for perf reasons + // '../../../../../z' resolved to 'x/y' is just 'z' + const segmented = pathname.slice(0, pathname.lastIndexOf('/') + 1) + relUrl; + + const output = []; + let segmentIndex = -1; + for (let i = 0; i < segmented.length; i++) { + // busy reading a segment - only terminate on '/' + if (segmentIndex !== -1) { + if (segmented[i] === '/') { + output.push(segmented.slice(segmentIndex, i + 1)); + segmentIndex = -1; + } + continue; + } + // new segment - check if it is relative + else if (segmented[i] === '.') { + // ../ segment + if (segmented[i + 1] === '.' && (segmented[i + 2] === '/' || i + 2 === segmented.length)) { + output.pop(); + i += 2; + continue; + } + // ./ segment + else if (segmented[i + 1] === '/' || i + 1 === segmented.length) { + i += 1; + continue; + } + } + // it is the start of a new segment + while (segmented[i] === '/') i++; + segmentIndex = i; + } + // finish reading out the last segment + if (segmentIndex !== -1) + output.push(segmented.slice(segmentIndex)); + return parentUrl.slice(0, parentUrl.length - pathname.length) + output.join(''); + } + } + + function resolveAndComposeImportMap (json, baseUrl, parentMap) { + const outMap = { imports: Object.assign({}, parentMap.imports), scopes: Object.assign({}, parentMap.scopes) }; + + if (json.imports) + resolveAndComposePackages(json.imports, outMap.imports, baseUrl, parentMap); + + if (json.scopes) + for (let s in json.scopes) { + const resolvedScope = resolveUrl(s, baseUrl); + resolveAndComposePackages(json.scopes[s], outMap.scopes[resolvedScope] || (outMap.scopes[resolvedScope] = {}), baseUrl, parentMap); + } + + return outMap; + } + + function getMatch (path, matchObj) { + if (matchObj[path]) + return path; + let sepIndex = path.length; + do { + const segment = path.slice(0, sepIndex + 1); + if (segment in matchObj) + return segment; + } while ((sepIndex = path.lastIndexOf('/', sepIndex - 1)) !== -1) + } + + function applyPackages (id, packages) { + const pkgName = getMatch(id, packages); + if (pkgName) { + const pkg = packages[pkgName]; + if (pkg === null) return; + return pkg + id.slice(pkgName.length); + } + } + + + function resolveImportMap (importMap, resolvedOrPlain, parentUrl) { + let scopeUrl = parentUrl && getMatch(parentUrl, importMap.scopes); + while (scopeUrl) { + const packageResolution = applyPackages(resolvedOrPlain, importMap.scopes[scopeUrl]); + if (packageResolution) + return packageResolution; + scopeUrl = getMatch(scopeUrl.slice(0, scopeUrl.lastIndexOf('/')), importMap.scopes); + } + return applyPackages(resolvedOrPlain, importMap.imports) || resolvedOrPlain.indexOf(':') !== -1 && resolvedOrPlain; + } + + function resolveAndComposePackages (packages, outPackages, baseUrl, parentMap) { + for (let p in packages) { + const resolvedLhs = resolveIfNotPlainOrUrl(p, baseUrl) || p; + if ((!shimMode || !mapOverrides) && outPackages[resolvedLhs] && (outPackages[resolvedLhs] !== packages[resolvedLhs])) { + throw Error(`Rejected map override "${resolvedLhs}" from ${outPackages[resolvedLhs]} to ${packages[resolvedLhs]}.`); + } + let target = packages[p]; + if (typeof target !== 'string') + continue; + const mapped = resolveImportMap(parentMap, resolveIfNotPlainOrUrl(target, baseUrl) || target, baseUrl); + if (mapped) { + outPackages[resolvedLhs] = mapped; + continue; + } + console.warn(`Mapping "${p}" -> "${packages[p]}" does not resolve`); + } + } + + let err; + window.addEventListener('error', _err => err = _err); + function dynamicImportScript (url, { errUrl = url } = {}) { + err = undefined; + const src = createBlob(`import*as m from'${url}';self._esmsi=m`); + const s = Object.assign(document.createElement('script'), { type: 'module', src }); + s.setAttribute('nonce', nonce); + s.setAttribute('noshim', ''); + const p = new Promise((resolve, reject) => { + // Safari is unique in supporting module script error events + s.addEventListener('error', cb); + s.addEventListener('load', cb); + + function cb (_err) { + document.head.removeChild(s); + if (self._esmsi) { + resolve(self._esmsi, baseUrl); + self._esmsi = undefined; + } + else { + reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading or executing the graph of ${errUrl} (check the console for ${src}).`)); + err = undefined; + } + } + }); + document.head.appendChild(s); + return p; + } + + let dynamicImport = dynamicImportScript; + + const supportsDynamicImportCheck = dynamicImportScript(createBlob('export default u=>import(u)')).then(_dynamicImport => { + if (_dynamicImport) + dynamicImport = _dynamicImport.default; + return !!_dynamicImport; }, noop); - // support browsers without dynamic import support (eg Firefox 6x) - let supportsJsonAssertions = false; - let supportsCssAssertions = false; - - let supportsImportMeta = false; - let supportsImportMaps = false; - - let supportsDynamicImport = false; - - const featureDetectionPromise = Promise.resolve(supportsDynamicImportCheck).then(_supportsDynamicImport => { - if (!_supportsDynamicImport) - return; - supportsDynamicImport = true; - - return Promise.all([ - dynamicImport(createBlob('import.meta')).then(() => supportsImportMeta = true, noop), - cssModulesEnabled && dynamicImport(createBlob('import"data:text/css,{}"assert{type:"css"}')).then(() => supportsCssAssertions = true, noop), - jsonModulesEnabled && dynamicImport(createBlob('import"data:text/json,{}"assert{type:"json"}')).then(() => supportsJsonAssertions = true, noop), - new Promise(resolve => { - self._$s = v => { - document.head.removeChild(iframe); - if (v) supportsImportMaps = true; - delete self._$s; - resolve(); - }; - const iframe = document.createElement('iframe'); - iframe.style.display = 'none'; - document.head.appendChild(iframe); - iframe.src = createBlob(`