async-script-loader
Version:
Load a script asynchronously
208 lines (171 loc) • 5.57 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global['caret-pos'] = {})));
}(this, (function (exports) { 'use strict';
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var rngBrowser = createCommonjsModule(function (module) {
// Unique ID creation requires a high quality random # generator. In the
// browser this is a little complicated due to unknown quality of Math.random()
// and inconsistent support for the `crypto` API. We do the best we can via
// feature-detection
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues.bind(crypto)) ||
(typeof(msCrypto) != 'undefined' && msCrypto.getRandomValues.bind(msCrypto));
if (getRandomValues) {
// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
module.exports = function whatwgRNG() {
getRandomValues(rnds8);
return rnds8;
};
} else {
// Math.random()-based (RNG)
//
// If all else fails, use Math.random(). It's fast, but is of unspecified
// quality.
var rnds = new Array(16);
module.exports = function mathRNG() {
for (var i = 0, r; i < 16; i++) {
if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
}
return rnds;
};
}
});
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = [];
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1);
}
function bytesToUuid(buf, offset) {
var i = offset || 0;
var bth = byteToHex;
return bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]];
}
var bytesToUuid_1 = bytesToUuid;
function v4(options, buf, offset) {
var i = buf && offset || 0;
if (typeof(options) == 'string') {
buf = options === 'binary' ? new Array(16) : null;
options = null;
}
options = options || {};
var rnds = options.random || (options.rng || rngBrowser)();
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
// Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ++ii) {
buf[i + ii] = rnds[ii];
}
}
return buf || bytesToUuid_1(rnds);
}
var v4_1 = v4;
var LOADED = 'loaded';
var ERROR = 'error';
var scriptMap = new Map();
/**
* Clean up the callback
*
* @param {string} callback The callback function name
*
* @return {void}
*/
var cleanup = function cleanup(callback) {
if (!window[callback] || typeof window[callback] !== 'function') {
return;
}
window[callback] = null;
};
/**
* Load a script asynchronously
*
* @param {string} script The script to load
* @param {bool} reload If the script should be loaded even if it was loaded before
*
* @return {Promise}
*/
var load = function load(script) {
var reload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var src = script;
var id = v4_1();
var key = reload ? '' + script + id : script;
if (scriptMap.has(key)) {
var item = scriptMap.get(key);
if (item.promise) {
return item.promise;
}
if (item.error) {
return Promise.resolve(item.error);
}
return Promise.resolve(null, item);
}
var callbackName = 'callback_' + v4_1().replace(/-/g, '_');
var tag = window.document.createElement('script');
tag.type = 'text/javascript';
tag.async = false;
// Create the promise to return if it is already
// resolving
var promise = new Promise(function (resolve, reject) {
var handleResult = function handleResult(state) {
return function (evt) {
var instance = scriptMap.get(key);
if (state === LOADED) {
instance.loaded = true;
resolve(evt);
} else if (state === ERROR) {
instance.error = evt;
reject(evt);
}
instance.promise = null;
scriptMap.set(key, instance);
cleanup(callbackName);
};
};
// Add error handlers
tag.onerror = handleResult(ERROR);
tag.onreadystatechange = function () {
handleResult(tag.readyState);
};
// Replace callback if there is one
// or just resolve the promise
if (script.match(/callback=CALLBACK_PLACEHOLDER/)) {
src = src.replace(/(callback=)[^&]+/, '$1' + callbackName);
window[callbackName] = handleResult(LOADED);
} else {
tag.onload = handleResult(LOADED);
tag.addEventListener('load', tag.onload);
}
// Start loading the script
tag.src = src;
window.document.body.appendChild(tag);
});
var initialState = {
loaded: false,
error: false,
promise: promise
};
scriptMap.set(key, initialState);
return promise;
};
exports.load = load;
exports['default'] = load;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=main.js.map