248 lines
No EOL
7.3 KiB
JavaScript
Executable file
248 lines
No EOL
7.3 KiB
JavaScript
Executable file
"use strict";
|
|
|
|
var _objectWithoutProperties = require("babel-runtime/helpers/object-without-properties")["default"];
|
|
|
|
var _extends = require("babel-runtime/helpers/extends")["default"];
|
|
|
|
var _Map = require("babel-runtime/core-js/map")["default"];
|
|
|
|
var _getIterator = require("babel-runtime/core-js/get-iterator")["default"];
|
|
|
|
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"];
|
|
|
|
exports.__esModule = true;
|
|
exports["default"] = makeAsyncScript;
|
|
|
|
var _react = require("react");
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var SCRIPT_MAP = new _Map();
|
|
|
|
// A counter used to generate a unique id for each component that uses the function
|
|
var idCount = 0;
|
|
|
|
function makeAsyncScript(Component, scriptURL, options) {
|
|
options = options || {};
|
|
var funcs = {
|
|
displayName: "AsyncScriptLoader",
|
|
|
|
propTypes: {
|
|
asyncScriptOnLoad: _react.PropTypes.func
|
|
},
|
|
|
|
statics: {
|
|
asyncScriptLoaderTriggerOnScriptLoaded: function asyncScriptLoaderTriggerOnScriptLoaded() {
|
|
var mapEntry = SCRIPT_MAP.get(scriptURL);
|
|
if (!mapEntry || !mapEntry.loaded) {
|
|
throw new Error("Script is not loaded.");
|
|
}
|
|
for (var _iterator = mapEntry.observers.values(), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _getIterator(_iterator);;) {
|
|
var _ref;
|
|
|
|
if (_isArray) {
|
|
if (_i >= _iterator.length) break;
|
|
_ref = _iterator[_i++];
|
|
} else {
|
|
_i = _iterator.next();
|
|
if (_i.done) break;
|
|
_ref = _i.value;
|
|
}
|
|
|
|
var observer = _ref;
|
|
|
|
observer(mapEntry);
|
|
}
|
|
delete window[options.callbackName];
|
|
}
|
|
},
|
|
|
|
getInitialState: function getInitialState() {
|
|
return {};
|
|
},
|
|
|
|
asyncScriptLoaderGetScriptLoaderID: function asyncScriptLoaderGetScriptLoaderID() {
|
|
if (!this.__scriptLoaderID) {
|
|
this.__scriptLoaderID = "async-script-loader-" + idCount++;
|
|
}
|
|
return this.__scriptLoaderID;
|
|
},
|
|
|
|
getComponent: function getComponent() {
|
|
return this.childComponent;
|
|
},
|
|
|
|
componentDidMount: function componentDidMount() {
|
|
var _this = this;
|
|
|
|
var key = this.asyncScriptLoaderGetScriptLoaderID();
|
|
var _options = options;
|
|
var globalName = _options.globalName;
|
|
var callbackName = _options.callbackName;
|
|
|
|
if (globalName && typeof window[globalName] !== "undefined") {
|
|
SCRIPT_MAP.set(scriptURL, { loaded: true, observers: new _Map() });
|
|
}
|
|
|
|
if (SCRIPT_MAP.has(scriptURL)) {
|
|
var entry = SCRIPT_MAP.get(scriptURL);
|
|
if (entry.loaded || entry.errored) {
|
|
this.asyncScriptLoaderHandleLoad(entry);
|
|
return;
|
|
}
|
|
entry.observers.set(key, this.asyncScriptLoaderHandleLoad);
|
|
return;
|
|
}
|
|
|
|
var observers = new _Map();
|
|
observers.set(key, this.asyncScriptLoaderHandleLoad);
|
|
SCRIPT_MAP.set(scriptURL, {
|
|
loaded: false,
|
|
observers: observers
|
|
});
|
|
|
|
var script = document.createElement("script");
|
|
|
|
script.src = scriptURL;
|
|
script.async = 1;
|
|
|
|
var callObserverFuncAndRemoveObserver = function callObserverFuncAndRemoveObserver(func) {
|
|
if (SCRIPT_MAP.has(scriptURL)) {
|
|
var mapEntry = SCRIPT_MAP.get(scriptURL);
|
|
var observersMap = mapEntry.observers;
|
|
|
|
for (var _iterator2 = observersMap, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _getIterator(_iterator2);;) {
|
|
var _ref2;
|
|
|
|
if (_isArray2) {
|
|
if (_i2 >= _iterator2.length) break;
|
|
_ref2 = _iterator2[_i2++];
|
|
} else {
|
|
_i2 = _iterator2.next();
|
|
if (_i2.done) break;
|
|
_ref2 = _i2.value;
|
|
}
|
|
|
|
var obsKey = _ref2[0];
|
|
var observer = _ref2[1];
|
|
|
|
if (func(observer)) {
|
|
observersMap["delete"](obsKey);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
if (callbackName && typeof window !== "undefined") {
|
|
window[callbackName] = AsyncScriptLoader.asyncScriptLoaderTriggerOnScriptLoaded;
|
|
}
|
|
|
|
script.onload = function () {
|
|
var mapEntry = SCRIPT_MAP.get(scriptURL);
|
|
mapEntry.loaded = true;
|
|
callObserverFuncAndRemoveObserver(function (observer) {
|
|
if (callbackName) {
|
|
return false;
|
|
}
|
|
observer(mapEntry);
|
|
return true;
|
|
});
|
|
};
|
|
script.onerror = function (event) {
|
|
var mapEntry = SCRIPT_MAP.get(scriptURL);
|
|
mapEntry.errored = true;
|
|
callObserverFuncAndRemoveObserver(function (observer) {
|
|
observer(mapEntry);
|
|
return true;
|
|
});
|
|
};
|
|
|
|
// (old) MSIE browsers may call "onreadystatechange" instead of "onload"
|
|
script.onreadystatechange = function () {
|
|
if (_this.readyState === "loaded") {
|
|
// wait for other events, then call onload if default onload hadn't been called
|
|
window.setTimeout(function () {
|
|
if (SCRIPT_MAP.get(scriptURL).loaded !== true) {
|
|
script.onload();
|
|
}
|
|
}, 0);
|
|
}
|
|
};
|
|
|
|
document.body.appendChild(script);
|
|
},
|
|
|
|
asyncScriptLoaderHandleLoad: function asyncScriptLoaderHandleLoad(state) {
|
|
this.setState(state, this.props.asyncScriptOnLoad);
|
|
},
|
|
|
|
componentWillUnmount: function componentWillUnmount() {
|
|
// Clean the observer entry
|
|
var mapEntry = SCRIPT_MAP.get(scriptURL);
|
|
if (mapEntry) {
|
|
mapEntry.observers["delete"](this.asyncScriptLoaderGetScriptLoaderID());
|
|
}
|
|
},
|
|
|
|
render: function render() {
|
|
var _this2 = this;
|
|
|
|
var globalName = options.globalName;
|
|
var _props = this.props;
|
|
var asyncScriptOnLoad = _props.asyncScriptOnLoad;
|
|
|
|
var childProps = _objectWithoutProperties(_props, ["asyncScriptOnLoad"]);
|
|
|
|
if (globalName && typeof window !== "undefined") {
|
|
childProps[globalName] = typeof window[globalName] !== "undefined" ? window[globalName] : undefined;
|
|
}
|
|
return _react2["default"].createElement(Component, _extends({ ref: function (comp) {
|
|
_this2.childComponent = comp;
|
|
} }, childProps));
|
|
}
|
|
|
|
};
|
|
|
|
if (options.exposeFuncs) {
|
|
var _loop = function () {
|
|
if (_isArray3) {
|
|
if (_i3 >= _iterator3.length) return "break";
|
|
_ref3 = _iterator3[_i3++];
|
|
} else {
|
|
_i3 = _iterator3.next();
|
|
if (_i3.done) return "break";
|
|
_ref3 = _i3.value;
|
|
}
|
|
|
|
var funcToExpose = _ref3;
|
|
|
|
/* eslint-disable no-loop-func */
|
|
funcs[funcToExpose] = function () {
|
|
var _childComponent;
|
|
|
|
return (_childComponent = this.childComponent)[funcToExpose].apply(_childComponent, arguments);
|
|
};
|
|
/* eslint-enable no-loop-func */
|
|
};
|
|
|
|
for (var _iterator3 = options.exposeFuncs, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _getIterator(_iterator3);;) {
|
|
var _ref3;
|
|
|
|
var _ret = _loop();
|
|
|
|
if (_ret === "break") break;
|
|
}
|
|
}
|
|
var AsyncScriptLoader = _react2["default"].createClass(funcs);
|
|
|
|
return AsyncScriptLoader;
|
|
}
|
|
|
|
module.exports = exports["default"];
|
|
|
|
|
|
//////////////////
|
|
// WEBPACK FOOTER
|
|
// ./~/react-async-script/lib/async-script-loader.js
|
|
// module id = 478
|
|
// module chunks = 4
|