dynamicCSS.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.canUseDom = canUseDom;
  6. exports.injectCSS = injectCSS;
  7. exports.removeCSS = removeCSS;
  8. exports.clearContainerCache = clearContainerCache;
  9. exports.updateCSS = updateCSS;
  10. function canUseDom() {
  11. return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
  12. }
  13. function contains(root, n) {
  14. if (!root) {
  15. return false;
  16. } // Use native if support
  17. if (root.contains) {
  18. return root.contains(n);
  19. }
  20. return false;
  21. }
  22. var APPEND_ORDER = 'data-vc-order';
  23. var MARK_KEY = "vc-icon-key";
  24. var containerCache = new Map();
  25. function getMark() {
  26. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  27. mark = _ref.mark;
  28. if (mark) {
  29. return mark.startsWith('data-') ? mark : "data-".concat(mark);
  30. }
  31. return MARK_KEY;
  32. }
  33. function getContainer(option) {
  34. if (option.attachTo) {
  35. return option.attachTo;
  36. }
  37. var head = document.querySelector('head');
  38. return head || document.body;
  39. }
  40. function getOrder(prepend) {
  41. if (prepend === 'queue') {
  42. return 'prependQueue';
  43. }
  44. return prepend ? 'prepend' : 'append';
  45. }
  46. /**
  47. * Find style which inject by rc-util
  48. */
  49. function findStyles(container) {
  50. return Array.from((containerCache.get(container) || container).children).filter(function (node) {
  51. return node.tagName === 'STYLE';
  52. });
  53. }
  54. function injectCSS(css) {
  55. var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  56. if (!canUseDom()) {
  57. return null;
  58. }
  59. var csp = option.csp,
  60. prepend = option.prepend;
  61. var styleNode = document.createElement('style');
  62. styleNode.setAttribute(APPEND_ORDER, getOrder(prepend));
  63. if (csp && csp.nonce) {
  64. styleNode.nonce = csp.nonce;
  65. }
  66. styleNode.innerHTML = css;
  67. var container = getContainer(option);
  68. var firstChild = container.firstChild;
  69. if (prepend) {
  70. // If is queue `prepend`, it will prepend first style and then append rest style
  71. if (prepend === 'queue') {
  72. var existStyle = findStyles(container).filter(function (node) {
  73. return ['prepend', 'prependQueue'].includes(node.getAttribute(APPEND_ORDER));
  74. });
  75. if (existStyle.length) {
  76. container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling);
  77. return styleNode;
  78. }
  79. } // Use `insertBefore` as `prepend`
  80. container.insertBefore(styleNode, firstChild);
  81. } else {
  82. container.appendChild(styleNode);
  83. }
  84. return styleNode;
  85. }
  86. function findExistNode(key) {
  87. var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  88. var container = getContainer(option);
  89. return findStyles(container).find(function (node) {
  90. return node.getAttribute(getMark(option)) === key;
  91. });
  92. }
  93. 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. * qiankun will inject `appendChild` to insert into other
  103. */
  104. function syncRealContainer(container, option) {
  105. var cachedRealContainer = containerCache.get(container); // Find real container when not cached or cached container removed
  106. if (!cachedRealContainer || !contains(document, cachedRealContainer)) {
  107. var placeholderStyle = injectCSS('', option);
  108. var parentNode = placeholderStyle.parentNode;
  109. containerCache.set(container, parentNode);
  110. container.removeChild(placeholderStyle);
  111. }
  112. }
  113. /**
  114. * manually clear container cache to avoid global cache in unit testes
  115. */
  116. function clearContainerCache() {
  117. containerCache.clear();
  118. }
  119. function updateCSS(css, key) {
  120. var option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  121. var container = getContainer(option); // Sync real parent
  122. syncRealContainer(container, option);
  123. var existNode = findExistNode(key, option);
  124. if (existNode) {
  125. if (option.csp && option.csp.nonce && existNode.nonce !== option.csp.nonce) {
  126. existNode.nonce = option.csp.nonce;
  127. }
  128. if (existNode.innerHTML !== css) {
  129. existNode.innerHTML = css;
  130. }
  131. return existNode;
  132. }
  133. var newNode = injectCSS(css, option);
  134. newNode.setAttribute(getMark(option), key);
  135. return newNode;
  136. }