@zstackui/qiankun 2.6.3-beta-5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +116 -0
  3. package/dist/index.umd.js +8681 -0
  4. package/dist/index.umd.js.map +1 -0
  5. package/dist/index.umd.min.js +4 -0
  6. package/dist/index.umd.min.js.map +1 -0
  7. package/dist/src/__tests__/globalState.test.d.ts +5 -0
  8. package/dist/src/__tests__/utils.test.d.ts +1 -0
  9. package/dist/src/addons/engineFlag.d.ts +6 -0
  10. package/dist/src/addons/index.d.ts +6 -0
  11. package/dist/src/addons/runtimePublicPath.d.ts +6 -0
  12. package/dist/src/apis.d.ts +7 -0
  13. package/dist/src/effects.d.ts +3 -0
  14. package/dist/src/error.d.ts +3 -0
  15. package/dist/src/errorHandler.d.ts +7 -0
  16. package/dist/src/globalState.d.ts +7 -0
  17. package/dist/src/index.d.ts +11 -0
  18. package/dist/src/interfaces.d.ts +107 -0
  19. package/dist/src/loader.d.ts +8 -0
  20. package/dist/src/prefetch.d.ts +14 -0
  21. package/dist/src/sandbox/__tests__/common.test.d.ts +5 -0
  22. package/dist/src/sandbox/__tests__/proxySandbox.test.d.ts +10 -0
  23. package/dist/src/sandbox/common.d.ts +21 -0
  24. package/dist/src/sandbox/index.d.ts +40 -0
  25. package/dist/src/sandbox/legacy/__tests__/sandbox.test.d.ts +5 -0
  26. package/dist/src/sandbox/legacy/sandbox.d.ts +28 -0
  27. package/dist/src/sandbox/patchers/__tests__/css.test.d.ts +5 -0
  28. package/dist/src/sandbox/patchers/__tests__/interval.test.d.ts +5 -0
  29. package/dist/src/sandbox/patchers/css.d.ts +17 -0
  30. package/dist/src/sandbox/patchers/dynamicAppend/__tests__/common.test.d.ts +1 -0
  31. package/dist/src/sandbox/patchers/dynamicAppend/common.d.ts +22 -0
  32. package/dist/src/sandbox/patchers/dynamicAppend/forLooseSandbox.d.ts +17 -0
  33. package/dist/src/sandbox/patchers/dynamicAppend/forStrictSandbox.d.ts +12 -0
  34. package/dist/src/sandbox/patchers/dynamicAppend/index.d.ts +6 -0
  35. package/dist/src/sandbox/patchers/historyListener.d.ts +5 -0
  36. package/dist/src/sandbox/patchers/index.d.ts +9 -0
  37. package/dist/src/sandbox/patchers/interval.d.ts +5 -0
  38. package/dist/src/sandbox/patchers/windowListener.d.ts +5 -0
  39. package/dist/src/sandbox/proxySandbox.d.ts +23 -0
  40. package/dist/src/sandbox/snapshotSandbox.d.ts +20 -0
  41. package/dist/src/utils.d.ts +44 -0
  42. package/dist/src/version.d.ts +1 -0
  43. package/es/addons/engineFlag.d.ts +6 -0
  44. package/es/addons/engineFlag.js +50 -0
  45. package/es/addons/index.d.ts +6 -0
  46. package/es/addons/index.js +13 -0
  47. package/es/addons/runtimePublicPath.d.ts +6 -0
  48. package/es/addons/runtimePublicPath.js +57 -0
  49. package/es/apis.d.ts +7 -0
  50. package/es/apis.js +278 -0
  51. package/es/effects.d.ts +3 -0
  52. package/es/effects.js +33 -0
  53. package/es/error.d.ts +3 -0
  54. package/es/error.js +16 -0
  55. package/es/errorHandler.d.ts +7 -0
  56. package/es/errorHandler.js +13 -0
  57. package/es/globalState.d.ts +7 -0
  58. package/es/globalState.js +101 -0
  59. package/es/index.d.ts +11 -0
  60. package/es/index.js +11 -0
  61. package/es/interfaces.d.ts +107 -0
  62. package/es/interfaces.js +8 -0
  63. package/es/loader.d.ts +8 -0
  64. package/es/loader.js +600 -0
  65. package/es/prefetch.d.ts +14 -0
  66. package/es/prefetch.js +125 -0
  67. package/es/sandbox/common.d.ts +21 -0
  68. package/es/sandbox/common.js +157 -0
  69. package/es/sandbox/index.d.ts +40 -0
  70. package/es/sandbox/index.js +105 -0
  71. package/es/sandbox/legacy/sandbox.d.ts +28 -0
  72. package/es/sandbox/legacy/sandbox.js +142 -0
  73. package/es/sandbox/patchers/css.d.ts +17 -0
  74. package/es/sandbox/patchers/css.js +186 -0
  75. package/es/sandbox/patchers/dynamicAppend/common.d.ts +22 -0
  76. package/es/sandbox/patchers/dynamicAppend/common.js +306 -0
  77. package/es/sandbox/patchers/dynamicAppend/forLooseSandbox.d.ts +17 -0
  78. package/es/sandbox/patchers/dynamicAppend/forLooseSandbox.js +77 -0
  79. package/es/sandbox/patchers/dynamicAppend/forStrictSandbox.d.ts +12 -0
  80. package/es/sandbox/patchers/dynamicAppend/forStrictSandbox.js +103 -0
  81. package/es/sandbox/patchers/dynamicAppend/index.d.ts +6 -0
  82. package/es/sandbox/patchers/dynamicAppend/index.js +6 -0
  83. package/es/sandbox/patchers/historyListener.d.ts +5 -0
  84. package/es/sandbox/patchers/historyListener.js +54 -0
  85. package/es/sandbox/patchers/index.d.ts +9 -0
  86. package/es/sandbox/patchers/index.js +45 -0
  87. package/es/sandbox/patchers/interval.d.ts +5 -0
  88. package/es/sandbox/patchers/interval.js +34 -0
  89. package/es/sandbox/patchers/windowListener.d.ts +5 -0
  90. package/es/sandbox/patchers/windowListener.js +34 -0
  91. package/es/sandbox/proxySandbox.d.ts +23 -0
  92. package/es/sandbox/proxySandbox.js +315 -0
  93. package/es/sandbox/snapshotSandbox.d.ts +20 -0
  94. package/es/sandbox/snapshotSandbox.js +59 -0
  95. package/es/utils.d.ts +44 -0
  96. package/es/utils.js +215 -0
  97. package/es/version.d.ts +1 -0
  98. package/es/version.js +1 -0
  99. package/lib/addons/engineFlag.d.ts +6 -0
  100. package/lib/addons/engineFlag.js +55 -0
  101. package/lib/addons/index.d.ts +6 -0
  102. package/lib/addons/index.js +21 -0
  103. package/lib/addons/runtimePublicPath.d.ts +6 -0
  104. package/lib/addons/runtimePublicPath.js +63 -0
  105. package/lib/apis.d.ts +7 -0
  106. package/lib/apis.js +288 -0
  107. package/lib/effects.d.ts +3 -0
  108. package/lib/effects.js +42 -0
  109. package/lib/error.d.ts +3 -0
  110. package/lib/error.js +23 -0
  111. package/lib/errorHandler.d.ts +7 -0
  112. package/lib/errorHandler.js +33 -0
  113. package/lib/globalState.d.ts +7 -0
  114. package/lib/globalState.js +110 -0
  115. package/lib/index.d.ts +11 -0
  116. package/lib/index.js +89 -0
  117. package/lib/interfaces.d.ts +107 -0
  118. package/lib/interfaces.js +14 -0
  119. package/lib/loader.d.ts +8 -0
  120. package/lib/loader.js +606 -0
  121. package/lib/prefetch.d.ts +14 -0
  122. package/lib/prefetch.js +132 -0
  123. package/lib/sandbox/common.d.ts +21 -0
  124. package/lib/sandbox/common.js +169 -0
  125. package/lib/sandbox/index.d.ts +40 -0
  126. package/lib/sandbox/index.js +123 -0
  127. package/lib/sandbox/legacy/sandbox.d.ts +28 -0
  128. package/lib/sandbox/legacy/sandbox.js +148 -0
  129. package/lib/sandbox/patchers/css.d.ts +17 -0
  130. package/lib/sandbox/patchers/css.js +193 -0
  131. package/lib/sandbox/patchers/dynamicAppend/common.d.ts +22 -0
  132. package/lib/sandbox/patchers/dynamicAppend/common.js +322 -0
  133. package/lib/sandbox/patchers/dynamicAppend/forLooseSandbox.d.ts +17 -0
  134. package/lib/sandbox/patchers/dynamicAppend/forLooseSandbox.js +84 -0
  135. package/lib/sandbox/patchers/dynamicAppend/forStrictSandbox.d.ts +12 -0
  136. package/lib/sandbox/patchers/dynamicAppend/forStrictSandbox.js +110 -0
  137. package/lib/sandbox/patchers/dynamicAppend/index.d.ts +6 -0
  138. package/lib/sandbox/patchers/dynamicAppend/index.js +19 -0
  139. package/lib/sandbox/patchers/historyListener.d.ts +5 -0
  140. package/lib/sandbox/patchers/historyListener.js +62 -0
  141. package/lib/sandbox/patchers/index.d.ts +9 -0
  142. package/lib/sandbox/patchers/index.js +57 -0
  143. package/lib/sandbox/patchers/interval.d.ts +5 -0
  144. package/lib/sandbox/patchers/interval.js +42 -0
  145. package/lib/sandbox/patchers/windowListener.d.ts +5 -0
  146. package/lib/sandbox/patchers/windowListener.js +42 -0
  147. package/lib/sandbox/proxySandbox.d.ts +23 -0
  148. package/lib/sandbox/proxySandbox.js +321 -0
  149. package/lib/sandbox/snapshotSandbox.d.ts +20 -0
  150. package/lib/sandbox/snapshotSandbox.js +65 -0
  151. package/lib/utils.d.ts +44 -0
  152. package/lib/utils.js +240 -0
  153. package/lib/version.d.ts +1 -0
  154. package/lib/version.js +7 -0
  155. package/package.json +137 -0
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @author Saviio
3
+ * @since 2020-4-19
4
+ */
5
+ export declare class ScopedCSS {
6
+ private static ModifiedTag;
7
+ private sheet;
8
+ private swapNode;
9
+ constructor();
10
+ process(styleNode: HTMLStyleElement, prefix?: string): void;
11
+ private rewrite;
12
+ private ruleStyle;
13
+ private ruleMedia;
14
+ private ruleSupport;
15
+ }
16
+ export declare const QiankunCSSRewriteAttr = "data-qiankun";
17
+ export declare const process: (appWrapper: HTMLElement, stylesheetElement: HTMLStyleElement | HTMLLinkElement, appName: string) => void;
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.process = exports.ScopedCSS = exports.QiankunCSSRewriteAttr = void 0;
8
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
+ /**
11
+ * @author Saviio
12
+ * @since 2020-4-19
13
+ */
14
+ // https://developer.mozilla.org/en-US/docs/Web/API/CSSRule
15
+ var RuleType;
16
+ (function (RuleType) {
17
+ // type: rule will be rewrote
18
+ RuleType[RuleType["STYLE"] = 1] = "STYLE";
19
+ RuleType[RuleType["MEDIA"] = 4] = "MEDIA";
20
+ RuleType[RuleType["SUPPORTS"] = 12] = "SUPPORTS";
21
+ // type: value will be kept
22
+ RuleType[RuleType["IMPORT"] = 3] = "IMPORT";
23
+ RuleType[RuleType["FONT_FACE"] = 5] = "FONT_FACE";
24
+ RuleType[RuleType["PAGE"] = 6] = "PAGE";
25
+ RuleType[RuleType["KEYFRAMES"] = 7] = "KEYFRAMES";
26
+ RuleType[RuleType["KEYFRAME"] = 8] = "KEYFRAME";
27
+ })(RuleType || (RuleType = {}));
28
+ var arrayify = function arrayify(list) {
29
+ return [].slice.call(list, 0);
30
+ };
31
+ var rawDocumentBodyAppend = HTMLBodyElement.prototype.appendChild;
32
+ var ScopedCSS = exports.ScopedCSS = /*#__PURE__*/function () {
33
+ function ScopedCSS() {
34
+ (0, _classCallCheck2.default)(this, ScopedCSS);
35
+ var styleNode = document.createElement('style');
36
+ rawDocumentBodyAppend.call(document.body, styleNode);
37
+ this.swapNode = styleNode;
38
+ this.sheet = styleNode.sheet;
39
+ this.sheet.disabled = true;
40
+ }
41
+ return (0, _createClass2.default)(ScopedCSS, [{
42
+ key: "process",
43
+ value: function process(styleNode) {
44
+ var _this = this;
45
+ var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
46
+ var _a;
47
+ if (styleNode.textContent !== '') {
48
+ var textNode = document.createTextNode(styleNode.textContent || '');
49
+ this.swapNode.appendChild(textNode);
50
+ var sheet = this.swapNode.sheet; // type is missing
51
+ var rules = arrayify((_a = sheet === null || sheet === void 0 ? void 0 : sheet.cssRules) !== null && _a !== void 0 ? _a : []);
52
+ var css = this.rewrite(rules, prefix);
53
+ // eslint-disable-next-line no-param-reassign
54
+ styleNode.textContent = css;
55
+ // cleanup
56
+ this.swapNode.removeChild(textNode);
57
+ return;
58
+ }
59
+ var mutator = new MutationObserver(function (mutations) {
60
+ var _a;
61
+ for (var i = 0; i < mutations.length; i += 1) {
62
+ var mutation = mutations[i];
63
+ if (ScopedCSS.ModifiedTag in styleNode) {
64
+ return;
65
+ }
66
+ if (mutation.type === 'childList') {
67
+ var _sheet = styleNode.sheet;
68
+ var _rules = arrayify((_a = _sheet === null || _sheet === void 0 ? void 0 : _sheet.cssRules) !== null && _a !== void 0 ? _a : []);
69
+ var _css = _this.rewrite(_rules, prefix);
70
+ // eslint-disable-next-line no-param-reassign
71
+ styleNode.textContent = _css;
72
+ // eslint-disable-next-line no-param-reassign
73
+ styleNode[ScopedCSS.ModifiedTag] = true;
74
+ }
75
+ }
76
+ });
77
+ // since observer will be deleted when node be removed
78
+ // we dont need create a cleanup function manually
79
+ // see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/disconnect
80
+ mutator.observe(styleNode, {
81
+ childList: true
82
+ });
83
+ }
84
+ }, {
85
+ key: "rewrite",
86
+ value: function rewrite(rules) {
87
+ var _this2 = this;
88
+ var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
89
+ var css = '';
90
+ rules.forEach(function (rule) {
91
+ switch (rule.type) {
92
+ case RuleType.STYLE:
93
+ css += _this2.ruleStyle(rule, prefix);
94
+ break;
95
+ case RuleType.MEDIA:
96
+ css += _this2.ruleMedia(rule, prefix);
97
+ break;
98
+ case RuleType.SUPPORTS:
99
+ css += _this2.ruleSupport(rule, prefix);
100
+ break;
101
+ default:
102
+ css += "".concat(rule.cssText);
103
+ break;
104
+ }
105
+ });
106
+ return css;
107
+ }
108
+ // handle case:
109
+ // .app-main {}
110
+ // html, body {}
111
+ // eslint-disable-next-line class-methods-use-this
112
+ }, {
113
+ key: "ruleStyle",
114
+ value: function ruleStyle(rule, prefix) {
115
+ var rootSelectorRE = /((?:[^\w\-.#]|^)(body|html|:root))/gm;
116
+ var rootCombinationRE = /(html[^\w{[]+)/gm;
117
+ var selector = rule.selectorText.trim();
118
+ var cssText = rule.cssText;
119
+ // handle html { ... }
120
+ // handle body { ... }
121
+ // handle :root { ... }
122
+ if (selector === 'html' || selector === 'body' || selector === ':root') {
123
+ return cssText.replace(rootSelectorRE, prefix);
124
+ }
125
+ // handle html body { ... }
126
+ // handle html > body { ... }
127
+ if (rootCombinationRE.test(rule.selectorText)) {
128
+ var siblingSelectorRE = /(html[^\w{]+)(\+|~)/gm;
129
+ // since html + body is a non-standard rule for html
130
+ // transformer will ignore it
131
+ if (!siblingSelectorRE.test(rule.selectorText)) {
132
+ cssText = cssText.replace(rootCombinationRE, '');
133
+ }
134
+ }
135
+ // handle grouping selector, a,span,p,div { ... }
136
+ cssText = cssText.replace(/^[\s\S]+{/, function (selectors) {
137
+ return selectors.replace(/(^|,\n?)([^,]+)/g, function (item, p, s) {
138
+ // handle div,body,span { ... }
139
+ if (rootSelectorRE.test(item)) {
140
+ return item.replace(rootSelectorRE, function (m) {
141
+ // do not discard valid previous character, such as body,html or *:not(:root)
142
+ var whitePrevChars = [',', '('];
143
+ if (m && whitePrevChars.includes(m[0])) {
144
+ return "".concat(m[0]).concat(prefix);
145
+ }
146
+ // replace root selector with prefix
147
+ return prefix;
148
+ });
149
+ }
150
+ return "".concat(p).concat(prefix, " ").concat(s.replace(/^ */, ''));
151
+ });
152
+ });
153
+ return cssText;
154
+ }
155
+ // handle case:
156
+ // @media screen and (max-width: 300px) {}
157
+ }, {
158
+ key: "ruleMedia",
159
+ value: function ruleMedia(rule, prefix) {
160
+ var css = this.rewrite(arrayify(rule.cssRules), prefix);
161
+ return "@media ".concat(rule.conditionText, " {").concat(css, "}");
162
+ }
163
+ // handle case:
164
+ // @supports (display: grid) {}
165
+ }, {
166
+ key: "ruleSupport",
167
+ value: function ruleSupport(rule, prefix) {
168
+ var css = this.rewrite(arrayify(rule.cssRules), prefix);
169
+ return "@supports ".concat(rule.conditionText, " {").concat(css, "}");
170
+ }
171
+ }]);
172
+ }();
173
+ ScopedCSS.ModifiedTag = 'Symbol(style-modified-qiankun)';
174
+ var processor;
175
+ var QiankunCSSRewriteAttr = exports.QiankunCSSRewriteAttr = 'data-qiankun';
176
+ var process = exports.process = function process(appWrapper, stylesheetElement, appName) {
177
+ // lazy singleton pattern
178
+ if (!processor) {
179
+ processor = new ScopedCSS();
180
+ }
181
+ if (stylesheetElement.tagName === 'LINK') {
182
+ console.warn('Feature: sandbox.experimentalStyleIsolation is not support for link element yet.');
183
+ }
184
+ var mountDOM = appWrapper;
185
+ if (!mountDOM) {
186
+ return;
187
+ }
188
+ var tag = (mountDOM.tagName || '').toLowerCase();
189
+ if (tag && stylesheetElement.tagName === 'STYLE') {
190
+ var prefix = "".concat(tag, "[").concat(QiankunCSSRewriteAttr, "=\"").concat(appName, "\"]");
191
+ processor.process(stylesheetElement, prefix);
192
+ }
193
+ };
@@ -0,0 +1,22 @@
1
+ export declare const rawHeadAppendChild: <T extends Node>(node: T) => T;
2
+ export declare function isHijackingTag(tagName?: string): boolean;
3
+ /**
4
+ * Check if a style element is a styled-component liked.
5
+ * A styled-components liked element is which not have textContext but keep the rules in its styleSheet.cssRules.
6
+ * Such as the style element generated by styled-components and emotion.
7
+ * @param element
8
+ */
9
+ export declare function isStyledComponentsLike(element: HTMLStyleElement): number | false | undefined;
10
+ export declare function recordStyledComponentsCSSRules(styleElements: HTMLStyleElement[]): void;
11
+ export declare function getStyledElementCSSRules(styledElement: HTMLStyleElement): CSSRuleList | undefined;
12
+ export type ContainerConfig = {
13
+ appName: string;
14
+ proxy: WindowProxy;
15
+ strictGlobal: boolean;
16
+ dynamicStyleSheetElements: HTMLStyleElement[];
17
+ appWrapperGetter: CallableFunction;
18
+ scopedCSS: boolean;
19
+ excludeAssetFilter?: CallableFunction;
20
+ };
21
+ export declare function patchHTMLDynamicAppendPrototypeFunctions(isInvokedByMicroApp: (element: HTMLElement) => boolean, containerConfigGetter: (element: HTMLElement) => ContainerConfig): () => void;
22
+ export declare function rebuildCSSRules(styleSheetElements: HTMLStyleElement[], reAppendElement: (stylesheetElement: HTMLStyleElement) => boolean): void;
@@ -0,0 +1,322 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.getStyledElementCSSRules = getStyledElementCSSRules;
9
+ exports.isHijackingTag = isHijackingTag;
10
+ exports.isStyledComponentsLike = isStyledComponentsLike;
11
+ exports.patchHTMLDynamicAppendPrototypeFunctions = patchHTMLDynamicAppendPrototypeFunctions;
12
+ exports.rawHeadAppendChild = void 0;
13
+ exports.rebuildCSSRules = rebuildCSSRules;
14
+ exports.recordStyledComponentsCSSRules = recordStyledComponentsCSSRules;
15
+ var _isFunction2 = _interopRequireDefault(require("lodash/isFunction"));
16
+ var _importHtmlEntry = require("import-html-entry");
17
+ var _apis = require("../../../apis");
18
+ var css = _interopRequireWildcard(require("../css"));
19
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
20
+ /**
21
+ * @author Kuitos
22
+ * @since 2019-10-21
23
+ */
24
+
25
+ var rawHeadAppendChild = exports.rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
26
+ var rawHeadRemoveChild = HTMLHeadElement.prototype.removeChild;
27
+ var rawBodyAppendChild = HTMLBodyElement.prototype.appendChild;
28
+ var rawBodyRemoveChild = HTMLBodyElement.prototype.removeChild;
29
+ var rawHeadInsertBefore = HTMLHeadElement.prototype.insertBefore;
30
+ var rawRemoveChild = HTMLElement.prototype.removeChild;
31
+ var SCRIPT_TAG_NAME = 'SCRIPT';
32
+ var LINK_TAG_NAME = 'LINK';
33
+ var STYLE_TAG_NAME = 'STYLE';
34
+ function isHijackingTag(tagName) {
35
+ return (tagName === null || tagName === void 0 ? void 0 : tagName.toUpperCase()) === LINK_TAG_NAME || (tagName === null || tagName === void 0 ? void 0 : tagName.toUpperCase()) === STYLE_TAG_NAME || (tagName === null || tagName === void 0 ? void 0 : tagName.toUpperCase()) === SCRIPT_TAG_NAME;
36
+ }
37
+ /**
38
+ * Check if a style element is a styled-component liked.
39
+ * A styled-components liked element is which not have textContext but keep the rules in its styleSheet.cssRules.
40
+ * Such as the style element generated by styled-components and emotion.
41
+ * @param element
42
+ */
43
+ function isStyledComponentsLike(element) {
44
+ var _a, _b;
45
+ return !element.textContent && (((_a = element.sheet) === null || _a === void 0 ? void 0 : _a.cssRules.length) || ((_b = getStyledElementCSSRules(element)) === null || _b === void 0 ? void 0 : _b.length));
46
+ }
47
+ function patchCustomEvent(e, elementGetter) {
48
+ Object.defineProperties(e, {
49
+ srcElement: {
50
+ get: elementGetter
51
+ },
52
+ target: {
53
+ get: elementGetter
54
+ }
55
+ });
56
+ return e;
57
+ }
58
+ function manualInvokeElementOnLoad(element) {
59
+ // we need to invoke the onload event manually to notify the event listener that the script was completed
60
+ // here are the two typical ways of dynamic script loading
61
+ // 1. element.onload callback way, which webpack and loadjs used, see https://github.com/muicss/loadjs/blob/master/src/loadjs.js#L138
62
+ // 2. addEventListener way, which toast-loader used, see https://github.com/pyrsmk/toast/blob/master/src/Toast.ts#L64
63
+ var loadEvent = new CustomEvent('load');
64
+ var patchedEvent = patchCustomEvent(loadEvent, function () {
65
+ return element;
66
+ });
67
+ if ((0, _isFunction2.default)(element.onload)) {
68
+ element.onload(patchedEvent);
69
+ } else {
70
+ element.dispatchEvent(patchedEvent);
71
+ }
72
+ }
73
+ function manualInvokeElementOnError(element) {
74
+ var errorEvent = new CustomEvent('error');
75
+ var patchedEvent = patchCustomEvent(errorEvent, function () {
76
+ return element;
77
+ });
78
+ if ((0, _isFunction2.default)(element.onerror)) {
79
+ element.onerror(patchedEvent);
80
+ } else {
81
+ element.dispatchEvent(patchedEvent);
82
+ }
83
+ }
84
+ function convertLinkAsStyle(element, postProcess) {
85
+ var fetchFn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : fetch;
86
+ var styleElement = document.createElement('style');
87
+ var href = element.href;
88
+ // add source link element href
89
+ styleElement.dataset.qiankunHref = href;
90
+ fetchFn(href).then(function (res) {
91
+ return res.text();
92
+ }).then(function (styleContext) {
93
+ styleElement.appendChild(document.createTextNode(styleContext));
94
+ postProcess(styleElement);
95
+ manualInvokeElementOnLoad(element);
96
+ }).catch(function () {
97
+ return manualInvokeElementOnError(element);
98
+ });
99
+ return styleElement;
100
+ }
101
+ var styledComponentCSSRulesMap = new WeakMap();
102
+ var dynamicScriptAttachedCommentMap = new WeakMap();
103
+ var dynamicLinkAttachedInlineStyleMap = new WeakMap();
104
+ function recordStyledComponentsCSSRules(styleElements) {
105
+ styleElements.forEach(function (styleElement) {
106
+ /*
107
+ With a styled-components generated style element, we need to record its cssRules for restore next re-mounting time.
108
+ We're doing this because the sheet of style element is going to be cleaned automatically by browser after the style element dom removed from document.
109
+ see https://www.w3.org/TR/cssom-1/#associated-css-style-sheet
110
+ */
111
+ if (styleElement instanceof HTMLStyleElement && isStyledComponentsLike(styleElement)) {
112
+ if (styleElement.sheet) {
113
+ // record the original css rules of the style element for restore
114
+ styledComponentCSSRulesMap.set(styleElement, styleElement.sheet.cssRules);
115
+ }
116
+ }
117
+ });
118
+ }
119
+ function getStyledElementCSSRules(styledElement) {
120
+ return styledComponentCSSRulesMap.get(styledElement);
121
+ }
122
+ function getOverwrittenAppendChildOrInsertBefore(opts) {
123
+ return function appendChildOrInsertBefore(newChild) {
124
+ var refChild = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
125
+ var _a, _b;
126
+ var element = newChild;
127
+ var rawDOMAppendOrInsertBefore = opts.rawDOMAppendOrInsertBefore,
128
+ isInvokedByMicroApp = opts.isInvokedByMicroApp,
129
+ containerConfigGetter = opts.containerConfigGetter;
130
+ if (!isHijackingTag(element.tagName) || !isInvokedByMicroApp(element)) {
131
+ return rawDOMAppendOrInsertBefore.call(this, element, refChild);
132
+ }
133
+ if (element.tagName) {
134
+ var containerConfig = containerConfigGetter(element);
135
+ var appName = containerConfig.appName,
136
+ appWrapperGetter = containerConfig.appWrapperGetter,
137
+ proxy = containerConfig.proxy,
138
+ strictGlobal = containerConfig.strictGlobal,
139
+ dynamicStyleSheetElements = containerConfig.dynamicStyleSheetElements,
140
+ scopedCSS = containerConfig.scopedCSS,
141
+ excludeAssetFilter = containerConfig.excludeAssetFilter;
142
+ switch (element.tagName) {
143
+ case LINK_TAG_NAME:
144
+ case STYLE_TAG_NAME:
145
+ {
146
+ var stylesheetElement = newChild;
147
+ var _stylesheetElement = stylesheetElement,
148
+ href = _stylesheetElement.href;
149
+ if (excludeAssetFilter && href && excludeAssetFilter(href)) {
150
+ return rawDOMAppendOrInsertBefore.call(this, element, refChild);
151
+ }
152
+ var mountDOM = appWrapperGetter();
153
+ if (scopedCSS) {
154
+ // exclude link elements like <link rel="icon" href="favicon.ico">
155
+ var linkElementUsingStylesheet = ((_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === LINK_TAG_NAME && element.rel === 'stylesheet' && element.href;
156
+ if (linkElementUsingStylesheet) {
157
+ var _fetch = typeof _apis.frameworkConfiguration.fetch === 'function' ? _apis.frameworkConfiguration.fetch : (_b = _apis.frameworkConfiguration.fetch) === null || _b === void 0 ? void 0 : _b.fn;
158
+ stylesheetElement = convertLinkAsStyle(element, function (styleElement) {
159
+ return css.process(mountDOM, styleElement, appName);
160
+ }, _fetch);
161
+ dynamicLinkAttachedInlineStyleMap.set(element, stylesheetElement);
162
+ } else {
163
+ css.process(mountDOM, stylesheetElement, appName);
164
+ }
165
+ }
166
+ // eslint-disable-next-line no-shadow
167
+ dynamicStyleSheetElements.push(stylesheetElement);
168
+ var referenceNode = mountDOM.contains(refChild) ? refChild : null;
169
+ return rawDOMAppendOrInsertBefore.call(mountDOM, stylesheetElement, referenceNode);
170
+ }
171
+ case SCRIPT_TAG_NAME:
172
+ {
173
+ var _element = element,
174
+ src = _element.src,
175
+ text = _element.text;
176
+ // some script like jsonp maybe not support cors which should't use execScripts
177
+ if (excludeAssetFilter && src && excludeAssetFilter(src)) {
178
+ return rawDOMAppendOrInsertBefore.call(this, element, refChild);
179
+ }
180
+ var _mountDOM = appWrapperGetter();
181
+ var _fetch2 = _apis.frameworkConfiguration.fetch;
182
+ var _referenceNode = _mountDOM.contains(refChild) ? refChild : null;
183
+ if (src) {
184
+ (0, _importHtmlEntry.execScripts)(null, [src], proxy, {
185
+ fetch: _fetch2,
186
+ strictGlobal: strictGlobal,
187
+ beforeExec: function beforeExec() {
188
+ var isCurrentScriptConfigurable = function isCurrentScriptConfigurable() {
189
+ var descriptor = Object.getOwnPropertyDescriptor(document, 'currentScript');
190
+ return !descriptor || descriptor.configurable;
191
+ };
192
+ if (isCurrentScriptConfigurable()) {
193
+ Object.defineProperty(document, 'currentScript', {
194
+ get: function get() {
195
+ return element;
196
+ },
197
+ configurable: true
198
+ });
199
+ }
200
+ },
201
+ success: function success() {
202
+ manualInvokeElementOnLoad(element);
203
+ element = null;
204
+ },
205
+ error: function error() {
206
+ manualInvokeElementOnError(element);
207
+ element = null;
208
+ }
209
+ });
210
+ var dynamicScriptCommentElement = document.createComment("dynamic script ".concat(src, " replaced by qiankun"));
211
+ dynamicScriptAttachedCommentMap.set(element, dynamicScriptCommentElement);
212
+ return rawDOMAppendOrInsertBefore.call(_mountDOM, dynamicScriptCommentElement, _referenceNode);
213
+ }
214
+ // inline script never trigger the onload and onerror event
215
+ (0, _importHtmlEntry.execScripts)(null, ["<script>".concat(text, "</script>")], proxy, {
216
+ strictGlobal: strictGlobal
217
+ });
218
+ var dynamicInlineScriptCommentElement = document.createComment('dynamic inline script replaced by qiankun');
219
+ dynamicScriptAttachedCommentMap.set(element, dynamicInlineScriptCommentElement);
220
+ return rawDOMAppendOrInsertBefore.call(_mountDOM, dynamicInlineScriptCommentElement, _referenceNode);
221
+ }
222
+ default:
223
+ break;
224
+ }
225
+ }
226
+ return rawDOMAppendOrInsertBefore.call(this, element, refChild);
227
+ };
228
+ }
229
+ function getNewRemoveChild(headOrBodyRemoveChild, appWrapperGetterGetter) {
230
+ return function removeChild(child) {
231
+ var tagName = child.tagName;
232
+ if (!isHijackingTag(tagName)) return headOrBodyRemoveChild.call(this, child);
233
+ try {
234
+ var attachedElement;
235
+ switch (tagName) {
236
+ case LINK_TAG_NAME:
237
+ {
238
+ attachedElement = dynamicLinkAttachedInlineStyleMap.get(child) || child;
239
+ break;
240
+ }
241
+ case SCRIPT_TAG_NAME:
242
+ {
243
+ attachedElement = dynamicScriptAttachedCommentMap.get(child) || child;
244
+ break;
245
+ }
246
+ default:
247
+ {
248
+ attachedElement = child;
249
+ }
250
+ }
251
+ // container may had been removed while app unmounting if the removeChild action was async
252
+ var appWrapperGetter = appWrapperGetterGetter(child);
253
+ var container = appWrapperGetter();
254
+ if (container.contains(attachedElement)) {
255
+ return rawRemoveChild.call(container, attachedElement);
256
+ }
257
+ } catch (e) {
258
+ console.warn(e);
259
+ }
260
+ return headOrBodyRemoveChild.call(this, child);
261
+ };
262
+ }
263
+ function patchHTMLDynamicAppendPrototypeFunctions(isInvokedByMicroApp, containerConfigGetter) {
264
+ // Just overwrite it while it have not been overwrite
265
+ if (HTMLHeadElement.prototype.appendChild === rawHeadAppendChild && HTMLBodyElement.prototype.appendChild === rawBodyAppendChild && HTMLHeadElement.prototype.insertBefore === rawHeadInsertBefore) {
266
+ HTMLHeadElement.prototype.appendChild = getOverwrittenAppendChildOrInsertBefore({
267
+ rawDOMAppendOrInsertBefore: rawHeadAppendChild,
268
+ containerConfigGetter: containerConfigGetter,
269
+ isInvokedByMicroApp: isInvokedByMicroApp
270
+ });
271
+ HTMLBodyElement.prototype.appendChild = getOverwrittenAppendChildOrInsertBefore({
272
+ rawDOMAppendOrInsertBefore: rawBodyAppendChild,
273
+ containerConfigGetter: containerConfigGetter,
274
+ isInvokedByMicroApp: isInvokedByMicroApp
275
+ });
276
+ HTMLHeadElement.prototype.insertBefore = getOverwrittenAppendChildOrInsertBefore({
277
+ rawDOMAppendOrInsertBefore: rawHeadInsertBefore,
278
+ containerConfigGetter: containerConfigGetter,
279
+ isInvokedByMicroApp: isInvokedByMicroApp
280
+ });
281
+ }
282
+ // Just overwrite it while it have not been overwrite
283
+ if (HTMLHeadElement.prototype.removeChild === rawHeadRemoveChild && HTMLBodyElement.prototype.removeChild === rawBodyRemoveChild) {
284
+ HTMLHeadElement.prototype.removeChild = getNewRemoveChild(rawHeadRemoveChild, function (element) {
285
+ return containerConfigGetter(element).appWrapperGetter;
286
+ });
287
+ HTMLBodyElement.prototype.removeChild = getNewRemoveChild(rawBodyRemoveChild, function (element) {
288
+ return containerConfigGetter(element).appWrapperGetter;
289
+ });
290
+ }
291
+ return function unpatch() {
292
+ HTMLHeadElement.prototype.appendChild = rawHeadAppendChild;
293
+ HTMLHeadElement.prototype.removeChild = rawHeadRemoveChild;
294
+ HTMLBodyElement.prototype.appendChild = rawBodyAppendChild;
295
+ HTMLBodyElement.prototype.removeChild = rawBodyRemoveChild;
296
+ HTMLHeadElement.prototype.insertBefore = rawHeadInsertBefore;
297
+ };
298
+ }
299
+ function rebuildCSSRules(styleSheetElements, reAppendElement) {
300
+ styleSheetElements.forEach(function (stylesheetElement) {
301
+ // re-append the dynamic stylesheet to sub-app container
302
+ var appendSuccess = reAppendElement(stylesheetElement);
303
+ if (appendSuccess) {
304
+ /*
305
+ get the stored css rules from styled-components generated element, and the re-insert rules for them.
306
+ note that we must do this after style element had been added to document, which stylesheet would be associated to the document automatically.
307
+ check the spec https://www.w3.org/TR/cssom-1/#associated-css-style-sheet
308
+ */
309
+ if (stylesheetElement instanceof HTMLStyleElement && isStyledComponentsLike(stylesheetElement)) {
310
+ var cssRules = getStyledElementCSSRules(stylesheetElement);
311
+ if (cssRules) {
312
+ // eslint-disable-next-line no-plusplus
313
+ for (var i = 0; i < cssRules.length; i++) {
314
+ var cssRule = cssRules[i];
315
+ var cssStyleSheetElement = stylesheetElement.sheet;
316
+ cssStyleSheetElement.insertRule(cssRule.cssText, cssStyleSheetElement.cssRules.length);
317
+ }
318
+ }
319
+ }
320
+ }
321
+ });
322
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @author Kuitos
3
+ * @since 2020-10-13
4
+ */
5
+ import type { Freer } from '../../../interfaces';
6
+ /**
7
+ * Just hijack dynamic head append, that could avoid accidentally hijacking the insertion of elements except in head.
8
+ * Such a case: ReactDOM.createPortal(<style>.test{color:blue}</style>, container),
9
+ * this could made we append the style element into app wrapper but it will cause an error while the react portal unmounting, as ReactDOM could not find the style in body children list.
10
+ * @param appName
11
+ * @param appWrapperGetter
12
+ * @param proxy
13
+ * @param mounting
14
+ * @param scopedCSS
15
+ * @param excludeAssetFilter
16
+ */
17
+ export declare function patchLooseSandbox(appName: string, appWrapperGetter: () => HTMLElement | ShadowRoot, proxy: Window, mounting?: boolean, scopedCSS?: boolean, excludeAssetFilter?: CallableFunction): Freer;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.patchLooseSandbox = patchLooseSandbox;
7
+ var _singleSpa = require("single-spa");
8
+ var _common = require("./common");
9
+ /**
10
+ * @author Kuitos
11
+ * @since 2020-10-13
12
+ */
13
+
14
+ var bootstrappingPatchCount = 0;
15
+ var mountingPatchCount = 0;
16
+ /**
17
+ * Just hijack dynamic head append, that could avoid accidentally hijacking the insertion of elements except in head.
18
+ * Such a case: ReactDOM.createPortal(<style>.test{color:blue}</style>, container),
19
+ * this could made we append the style element into app wrapper but it will cause an error while the react portal unmounting, as ReactDOM could not find the style in body children list.
20
+ * @param appName
21
+ * @param appWrapperGetter
22
+ * @param proxy
23
+ * @param mounting
24
+ * @param scopedCSS
25
+ * @param excludeAssetFilter
26
+ */
27
+ function patchLooseSandbox(appName, appWrapperGetter, proxy) {
28
+ var mounting = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
29
+ var scopedCSS = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
30
+ var excludeAssetFilter = arguments.length > 5 ? arguments[5] : undefined;
31
+ var dynamicStyleSheetElements = [];
32
+ var unpatchDynamicAppendPrototypeFunctions = (0, _common.patchHTMLDynamicAppendPrototypeFunctions)(
33
+ /*
34
+ check if the currently specified application is active
35
+ While we switch page from qiankun app to a normal react routing page, the normal one may load stylesheet dynamically while page rendering,
36
+ but the url change listener must to wait until the current call stack is flushed.
37
+ This scenario may cause we record the stylesheet from react routing page dynamic injection,
38
+ and remove them after the url change triggered and qiankun app is unmouting
39
+ see https://github.com/ReactTraining/history/blob/master/modules/createHashHistory.js#L222-L230
40
+ */
41
+ function () {
42
+ return (0, _singleSpa.checkActivityFunctions)(window.location).some(function (name) {
43
+ return name === appName;
44
+ });
45
+ }, function () {
46
+ return {
47
+ appName: appName,
48
+ appWrapperGetter: appWrapperGetter,
49
+ proxy: proxy,
50
+ strictGlobal: false,
51
+ scopedCSS: scopedCSS,
52
+ dynamicStyleSheetElements: dynamicStyleSheetElements,
53
+ excludeAssetFilter: excludeAssetFilter
54
+ };
55
+ });
56
+ if (!mounting) bootstrappingPatchCount++;
57
+ if (mounting) mountingPatchCount++;
58
+ return function free() {
59
+ // bootstrap patch just called once but its freer will be called multiple times
60
+ if (!mounting && bootstrappingPatchCount !== 0) bootstrappingPatchCount--;
61
+ if (mounting) mountingPatchCount--;
62
+ var allMicroAppUnmounted = mountingPatchCount === 0 && bootstrappingPatchCount === 0;
63
+ // release the overwrite prototype after all the micro apps unmounted
64
+ if (allMicroAppUnmounted) unpatchDynamicAppendPrototypeFunctions();
65
+ (0, _common.recordStyledComponentsCSSRules)(dynamicStyleSheetElements);
66
+ // As now the sub app content all wrapped with a special id container,
67
+ // the dynamic style sheet would be removed automatically while unmoutting
68
+ return function rebuild() {
69
+ (0, _common.rebuildCSSRules)(dynamicStyleSheetElements, function (stylesheetElement) {
70
+ var appWrapper = appWrapperGetter();
71
+ if (!appWrapper.contains(stylesheetElement)) {
72
+ // Using document.head.appendChild ensures that appendChild invocation can also directly use the HTMLHeadElement.prototype.appendChild method which is overwritten at mounting phase
73
+ document.head.appendChild.call(appWrapper, stylesheetElement);
74
+ return true;
75
+ }
76
+ return false;
77
+ });
78
+ // As the patcher will be invoked every mounting phase, we could release the cache for gc after rebuilding
79
+ if (mounting) {
80
+ dynamicStyleSheetElements = [];
81
+ }
82
+ };
83
+ };
84
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @author Kuitos
3
+ * @since 2020-10-13
4
+ */
5
+ import type { Freer } from '../../../interfaces';
6
+ import type { ContainerConfig } from './common';
7
+ declare global {
8
+ interface Window {
9
+ __proxyAttachContainerConfigMap__: WeakMap<WindowProxy, ContainerConfig>;
10
+ }
11
+ }
12
+ export declare function patchStrictSandbox(appName: string, appWrapperGetter: () => HTMLElement | ShadowRoot, proxy: Window, mounting?: boolean, scopedCSS?: boolean, excludeAssetFilter?: CallableFunction): Freer;