UNPKG

ahooks

Version:
116 lines (115 loc) 4.48 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = require("react"); // {[path]: count} // remove external when no used var EXTERNAL_USED_COUNT = {}; var loadScript = function loadScript(path) { var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var script = document.querySelector("script[src=\"".concat(path, "\"]")); if (!script) { var newScript = document.createElement('script'); newScript.src = path; Object.keys(props).forEach(function (key) { newScript[key] = props[key]; }); newScript.setAttribute('data-status', 'loading'); document.body.appendChild(newScript); return { ref: newScript, status: 'loading' }; } return { ref: script, status: script.getAttribute('data-status') || 'ready' }; }; var loadCss = function loadCss(path) { var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var css = document.querySelector("link[href=\"".concat(path, "\"]")); if (!css) { var newCss = document.createElement('link'); newCss.rel = 'stylesheet'; newCss.href = path; Object.keys(props).forEach(function (key) { newCss[key] = props[key]; }); // IE9+ var isLegacyIECss = 'hideFocus' in newCss; // use preload in IE Edge (to detect load errors) if (isLegacyIECss && newCss.relList) { newCss.rel = 'preload'; newCss.as = 'style'; } newCss.setAttribute('data-status', 'loading'); document.head.appendChild(newCss); return { ref: newCss, status: 'loading' }; } return { ref: css, status: css.getAttribute('data-status') || 'ready' }; }; var useExternal = function useExternal(path, options) { var _useState = (0, _react.useState)(path ? 'loading' : 'unset'), _useState2 = (0, _slicedToArray2["default"])(_useState, 2), status = _useState2[0], setStatus = _useState2[1]; var ref = (0, _react.useRef)(undefined); (0, _react.useEffect)(function () { if (!path) { setStatus('unset'); return; } var pathname = path.replace(/[|#].*$/, ''); if ((options === null || options === void 0 ? void 0 : options.type) === 'css' || !(options === null || options === void 0 ? void 0 : options.type) && /(^css!|\.css$)/.test(pathname)) { var result = loadCss(path, options === null || options === void 0 ? void 0 : options.css); ref.current = result.ref; setStatus(result.status); } else if ((options === null || options === void 0 ? void 0 : options.type) === 'js' || !(options === null || options === void 0 ? void 0 : options.type) && /(^js!|\.js$)/.test(pathname)) { var _result = loadScript(path, options === null || options === void 0 ? void 0 : options.js); ref.current = _result.ref; setStatus(_result.status); } else { // do nothing console.error("Cannot infer the type of external resource, and please provide a type ('js' | 'css'). " + 'Refer to the https://ahooks.js.org/hooks/dom/use-external/#options'); } if (!ref.current) { return; } if (EXTERNAL_USED_COUNT[path] === undefined) { EXTERNAL_USED_COUNT[path] = 1; } else { EXTERNAL_USED_COUNT[path] += 1; } var handler = function handler(event) { var _a; var targetStatus = event.type === 'load' ? 'ready' : 'error'; (_a = ref.current) === null || _a === void 0 ? void 0 : _a.setAttribute('data-status', targetStatus); setStatus(targetStatus); }; ref.current.addEventListener('load', handler); ref.current.addEventListener('error', handler); return function () { var _a, _b, _c; (_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('load', handler); (_b = ref.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('error', handler); EXTERNAL_USED_COUNT[path] -= 1; if (EXTERNAL_USED_COUNT[path] === 0 && !(options === null || options === void 0 ? void 0 : options.keepWhenUnused)) { (_c = ref.current) === null || _c === void 0 ? void 0 : _c.remove(); } ref.current = undefined; }; }, [path]); return status; }; var _default = exports["default"] = useExternal;