import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import canUseDom from "./canUseDom"; import contains from "./contains"; var APPEND_ORDER = 'data-rc-order'; var APPEND_PRIORITY = 'data-rc-priority'; var MARK_KEY = "rc-util-key"; var containerCache = new Map(); function getMark() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, mark = _ref.mark; if (mark) { return mark.startsWith('data-') ? mark : "data-".concat(mark); } return MARK_KEY; } function getContainer(option) { if (option.attachTo) { return option.attachTo; } var head = document.querySelector('head'); return head || document.body; } function getOrder(prepend) { if (prepend === 'queue') { return 'prependQueue'; } return prepend ? 'prepend' : 'append'; } /** * Find style which inject by rc-util */ function findStyles(container) { return Array.from((containerCache.get(container) || container).children).filter(function (node) { return node.tagName === 'STYLE'; }); } export function injectCSS(css) { var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!canUseDom()) { return null; } var csp = option.csp, prepend = option.prepend, _option$priority = option.priority, priority = _option$priority === void 0 ? 0 : _option$priority; var mergedOrder = getOrder(prepend); var isPrependQueue = mergedOrder === 'prependQueue'; var styleNode = document.createElement('style'); styleNode.setAttribute(APPEND_ORDER, mergedOrder); if (isPrependQueue && priority) { styleNode.setAttribute(APPEND_PRIORITY, "".concat(priority)); } if (csp !== null && csp !== void 0 && csp.nonce) { styleNode.nonce = csp === null || csp === void 0 ? void 0 : csp.nonce; } styleNode.innerHTML = css; var container = getContainer(option); var firstChild = container.firstChild; if (prepend) { // If is queue `prepend`, it will prepend first style and then append rest style if (isPrependQueue) { var existStyle = (option.styles || findStyles(container)).filter(function (node) { // Ignore style which not injected by rc-util with prepend if (!['prepend', 'prependQueue'].includes(node.getAttribute(APPEND_ORDER))) { return false; } // Ignore style which priority less then new style var nodePriority = Number(node.getAttribute(APPEND_PRIORITY) || 0); return priority >= nodePriority; }); if (existStyle.length) { container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling); return styleNode; } } // Use `insertBefore` as `prepend` container.insertBefore(styleNode, firstChild); } else { container.appendChild(styleNode); } return styleNode; } function findExistNode(key) { var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var container = getContainer(option); return (option.styles || findStyles(container)).find(function (node) { return node.getAttribute(getMark(option)) === key; }); } export function removeCSS(key) { var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var existNode = findExistNode(key, option); if (existNode) { var container = getContainer(option); container.removeChild(existNode); } } /** * qiankun will inject `appendChild` to insert into other */ function syncRealContainer(container, option) { var cachedRealContainer = containerCache.get(container); // Find real container when not cached or cached container removed if (!cachedRealContainer || !contains(document, cachedRealContainer)) { var placeholderStyle = injectCSS('', option); var parentNode = placeholderStyle.parentNode; containerCache.set(container, parentNode); container.removeChild(placeholderStyle); } } /** * manually clear container cache to avoid global cache in unit testes */ export function clearContainerCache() { containerCache.clear(); } export function updateCSS(css, key) { var originOption = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var container = getContainer(originOption); var styles = findStyles(container); var option = _objectSpread(_objectSpread({}, originOption), {}, { styles: styles }); // Sync real parent syncRealContainer(container, option); var existNode = findExistNode(key, option); if (existNode) { var _option$csp, _option$csp2; if ((_option$csp = option.csp) !== null && _option$csp !== void 0 && _option$csp.nonce && existNode.nonce !== ((_option$csp2 = option.csp) === null || _option$csp2 === void 0 ? void 0 : _option$csp2.nonce)) { var _option$csp3; existNode.nonce = (_option$csp3 = option.csp) === null || _option$csp3 === void 0 ? void 0 : _option$csp3.nonce; } if (existNode.innerHTML !== css) { existNode.innerHTML = css; } return existNode; } var newNode = injectCSS(css, option); newNode.setAttribute(getMark(option), key); return newNode; }