UNPKG

5.1 kBJavaScriptView Raw
1import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2import canUseDom from "./canUseDom";
3import contains from "./contains";
4var APPEND_ORDER = 'data-rc-order';
5var APPEND_PRIORITY = 'data-rc-priority';
6var MARK_KEY = "rc-util-key";
7var containerCache = new Map();
8function getMark() {
9 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
10 mark = _ref.mark;
11 if (mark) {
12 return mark.startsWith('data-') ? mark : "data-".concat(mark);
13 }
14 return MARK_KEY;
15}
16function getContainer(option) {
17 if (option.attachTo) {
18 return option.attachTo;
19 }
20 var head = document.querySelector('head');
21 return head || document.body;
22}
23function getOrder(prepend) {
24 if (prepend === 'queue') {
25 return 'prependQueue';
26 }
27 return prepend ? 'prepend' : 'append';
28}
29
30/**
31 * Find style which inject by rc-util
32 */
33function findStyles(container) {
34 return Array.from((containerCache.get(container) || container).children).filter(function (node) {
35 return node.tagName === 'STYLE';
36 });
37}
38export function injectCSS(css) {
39 var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
40 if (!canUseDom()) {
41 return null;
42 }
43 var csp = option.csp,
44 prepend = option.prepend,
45 _option$priority = option.priority,
46 priority = _option$priority === void 0 ? 0 : _option$priority;
47 var mergedOrder = getOrder(prepend);
48 var isPrependQueue = mergedOrder === 'prependQueue';
49 var styleNode = document.createElement('style');
50 styleNode.setAttribute(APPEND_ORDER, mergedOrder);
51 if (isPrependQueue && priority) {
52 styleNode.setAttribute(APPEND_PRIORITY, "".concat(priority));
53 }
54 if (csp !== null && csp !== void 0 && csp.nonce) {
55 styleNode.nonce = csp === null || csp === void 0 ? void 0 : csp.nonce;
56 }
57 styleNode.innerHTML = css;
58 var container = getContainer(option);
59 var firstChild = container.firstChild;
60 if (prepend) {
61 // If is queue `prepend`, it will prepend first style and then append rest style
62 if (isPrependQueue) {
63 var existStyle = (option.styles || findStyles(container)).filter(function (node) {
64 // Ignore style which not injected by rc-util with prepend
65 if (!['prepend', 'prependQueue'].includes(node.getAttribute(APPEND_ORDER))) {
66 return false;
67 }
68
69 // Ignore style which priority less then new style
70 var nodePriority = Number(node.getAttribute(APPEND_PRIORITY) || 0);
71 return priority >= nodePriority;
72 });
73 if (existStyle.length) {
74 container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling);
75 return styleNode;
76 }
77 }
78
79 // Use `insertBefore` as `prepend`
80 container.insertBefore(styleNode, firstChild);
81 } else {
82 container.appendChild(styleNode);
83 }
84 return styleNode;
85}
86function findExistNode(key) {
87 var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
88 var container = getContainer(option);
89 return (option.styles || findStyles(container)).find(function (node) {
90 return node.getAttribute(getMark(option)) === key;
91 });
92}
93export function removeCSS(key) {
94 var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
95 var existNode = findExistNode(key, option);
96 if (existNode) {
97 var container = getContainer(option);
98 container.removeChild(existNode);
99 }
100}
101
102/**
103 * qiankun will inject `appendChild` to insert into other
104 */
105function syncRealContainer(container, option) {
106 var cachedRealContainer = containerCache.get(container);
107
108 // Find real container when not cached or cached container removed
109 if (!cachedRealContainer || !contains(document, cachedRealContainer)) {
110 var placeholderStyle = injectCSS('', option);
111 var parentNode = placeholderStyle.parentNode;
112 containerCache.set(container, parentNode);
113 container.removeChild(placeholderStyle);
114 }
115}
116
117/**
118 * manually clear container cache to avoid global cache in unit testes
119 */
120export function clearContainerCache() {
121 containerCache.clear();
122}
123export function updateCSS(css, key) {
124 var originOption = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
125 var container = getContainer(originOption);
126 var styles = findStyles(container);
127 var option = _objectSpread(_objectSpread({}, originOption), {}, {
128 styles: styles
129 });
130
131 // Sync real parent
132 syncRealContainer(container, option);
133 var existNode = findExistNode(key, option);
134 if (existNode) {
135 var _option$csp, _option$csp2;
136 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)) {
137 var _option$csp3;
138 existNode.nonce = (_option$csp3 = option.csp) === null || _option$csp3 === void 0 ? void 0 : _option$csp3.nonce;
139 }
140 if (existNode.innerHTML !== css) {
141 existNode.innerHTML = css;
142 }
143 return existNode;
144 }
145 var newNode = injectCSS(css, option);
146 newNode.setAttribute(getMark(option), key);
147 return newNode;
148}
\No newline at end of file