@seznam/szn-select
Version:
Accessible HTML selectbox with customizable UI. Based on web components and easy to integrate with various frameworks like React or Angular.
97 lines (79 loc) • 4.19 kB
JavaScript
/* global makeSznSelectBundleScript */
;
(function () {
var LOADER_ATTRIBUTE_PREFIX = 'data-szn-select--loader-urls--';
var SUPPORTED_LOADER_ATTRIBUTES = ['package', 'es2016', 'es3', 'bundle-elements-es2016', 'bundle-elements-es3', 'bundle-full-ce', 'bundle-full-es2016', 'bundle-full-es3'];
'use strict';
var makeSznSelectBundleScript = function (global) {
// eslint-disable-line no-unused-vars
var BUNDLES = {
ELEMENT_ES2016: 'es2016',
ELEMENT_ES3: 'es3',
ELEMENTS_ES2016: 'bundle-elements.es2016',
ELEMENTS_ES3: 'bundle-elements.es3',
ALL_CE: 'bundle-full.ce',
ALL_ES2016: 'bundle-full.es2016',
ALL_ES3: 'bundle-full.es3'
};
var DEFAULT_PACKAGE_URL = 'https://cdn.jsdelivr.net/npm/@seznam/szn-select@1.x/';
function makeBundleLoadScript(urlsConfiguration, useAsyncLoading) {
if (typeof self === 'undefined') {
throw new Error('The loader can only be used at the client-side');
}
if (global.SznElements && global.SznElements['szn-tethered'] && global.SznElements['szn-select']) {
return null; // already loaded
}
var bundleUrl = getSznSelectBundleUrl(urlsConfiguration);
var script = document.createElement('script');
script.async = useAsyncLoading;
script.defer = useAsyncLoading;
script.src = bundleUrl;
return script;
}
function getSznSelectBundleUrl(urlsConfiguration) {
// Firefox 52-based browsers (e.g. Palemoon) have faulty support for for-scoped const variable declarations
var firefoxVersionMatch = navigator.userAgent.match(/ Firefox\/(\d+)/);
var firefoxVersion = firefoxVersionMatch && parseInt(firefoxVersionMatch[1], 10);
var supportsForConst = !firefoxVersion || firefoxVersion > 52;
var es2016Supported = supportsForConst && global.Proxy && Array.prototype.includes;
var runtimeLoaded = global.SznElements && global.SznElements.init && global.SznElements.injectStyles;
var dependenciesLoaded = runtimeLoaded && global.SznElements['szn-tethered'];
var bundleToLoad = dependenciesLoaded ? es2016Supported ? BUNDLES.ELEMENT_ES2016 : BUNDLES.ELEMENT_ES3 : runtimeLoaded ? es2016Supported ? BUNDLES.ELEMENTS_ES2016 : BUNDLES.ELEMENTS_ES3 : global.customElements ? BUNDLES.ALL_CE : es2016Supported ? BUNDLES.ALL_ES2016 : BUNDLES.ALL_ES3;
return urlsConfiguration[bundleToLoad] || function () {
var baseUrl = urlsConfiguration["package"] || DEFAULT_PACKAGE_URL;
return /\/$/.test(baseUrl) ? baseUrl : "".concat(baseUrl, "/");
}() + "szn-select.".concat(bundleToLoad, ".min.js");
}
return makeBundleLoadScript;
}(self);
var loaderScript = getLoaderScript();
var urlsConfiguration = loadUrlsConfig(loaderScript);
var script = makeSznSelectBundleScript(urlsConfiguration, loaderScript.async);
if (!script) {
return;
} // TODO: do not use document.write if the hosts do not match: https://www.chromestatus.com/feature/5718547946799104
if (['interactive', 'complete'].indexOf(document.readyState) === -1) {
document.write(script.outerHTML);
} else {
(document.head || document.querySelector('head')).appendChild(script); // document.head is supported since IE9
}
function loadUrlsConfig(loaderScriptElement) {
var urls = {};
var attributes = loaderScriptElement.attributes;
for (var i = attributes.length - 1; i >= 0; i--) {
var attribute = attributes[i];
if (!/^data-szn-select--loader-urls--/.test(attribute.name)) {
continue;
}
var optionNameParts = attribute.name.substring(30).split('-');
var optionName = optionNameParts.length > 1 ? "".concat(optionNameParts.slice(0, -1).join('-'), ".").concat(optionNameParts[optionNameParts.length - 1]) : optionNameParts[0];
urls[optionName] = attribute.value;
}
return urls;
}
function getLoaderScript() {
return document.currentScript || document.querySelector("[".concat(LOADER_ATTRIBUTE_PREFIX).concat(SUPPORTED_LOADER_ATTRIBUTES.join("],[".concat(LOADER_ATTRIBUTE_PREFIX)), "]")) || {
attributes: [] // there is no overriding configuration
};
}
})();