@micro-zoe/micro-app 1.0.0-rc.20 → 1.0.0-rc.22

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.
package/lib/index.d.ts CHANGED
@@ -148,6 +148,7 @@ declare module '@micro-zoe/micro-app/libs/utils' {
148
148
  export function isAudioElement(target: unknown): target is HTMLAudioElement;
149
149
  export function isVideoElement(target: unknown): target is HTMLVideoElement;
150
150
  export function isLinkElement(target: unknown): target is HTMLLinkElement;
151
+ export function isBodyElement(target: unknown): target is HTMLBodyElement;
151
152
  export function isStyleElement(target: unknown): target is HTMLStyleElement;
152
153
  export function isScriptElement(target: unknown): target is HTMLScriptElement;
153
154
  export function isIFrameElement(target: unknown): target is HTMLIFrameElement;
package/lib/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = '1.0.0-rc.20';
1
+ const version = '1.0.0-rc.22';
2
2
  // do not use isUndefined
3
3
  const isBrowser = typeof window !== 'undefined';
4
4
  // do not use isUndefined
@@ -101,6 +101,9 @@ function isVideoElement(target) {
101
101
  function isLinkElement(target) {
102
102
  return toTypeString(target) === '[object HTMLLinkElement]';
103
103
  }
104
+ function isBodyElement(target) {
105
+ return toTypeString(target) === '[object HTMLBodyElement]';
106
+ }
104
107
  function isStyleElement(target) {
105
108
  return toTypeString(target) === '[object HTMLStyleElement]';
106
109
  }
@@ -1234,16 +1237,17 @@ function scopedCSS(styleElement, app, linkPath) {
1234
1237
  const prefix = createPrefix(app.name);
1235
1238
  if (!parser)
1236
1239
  parser = new CSSParser();
1240
+ const escapeRegExp = (regStr) => regStr.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1237
1241
  if (styleElement.textContent) {
1238
1242
  commonAction(styleElement, app.name, prefix, app.url, linkPath);
1239
1243
  const observer = new MutationObserver(() => {
1240
- const escapedPrefix = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1244
+ const escapedPrefix = escapeRegExp(prefix);
1241
1245
  const isPrefixed = styleElement.textContent && new RegExp(escapedPrefix).test(styleElement.textContent);
1242
1246
  observer.disconnect();
1243
1247
  if (!isPrefixed) {
1244
1248
  styleElement.__MICRO_APP_HAS_SCOPED__ = false;
1249
+ scopedCSS(styleElement, app, linkPath);
1245
1250
  }
1246
- scopedCSS(styleElement, app, linkPath);
1247
1251
  });
1248
1252
  observer.observe(styleElement, { childList: true, characterData: true });
1249
1253
  }
@@ -1678,6 +1682,8 @@ const BASE_SCOPE_WINDOW_EVENT = [
1678
1682
  'appstate-change',
1679
1683
  'statechange',
1680
1684
  'mounted',
1685
+ 'error'
1686
+ // 'beforeunload', // remove at 2024.5.30 by cangdu
1681
1687
  ];
1682
1688
  // bind event of with sandbox
1683
1689
  const SCOPE_WINDOW_EVENT_OF_WITH = BASE_SCOPE_WINDOW_EVENT;
@@ -2124,7 +2130,7 @@ function execScripts(app, initHook) {
2124
2130
  * @param callback callback of module script
2125
2131
  */
2126
2132
  function runScript(address, app, scriptInfo, callback, replaceElement) {
2127
- var _a;
2133
+ var _a, _b;
2128
2134
  try {
2129
2135
  actionsBeforeRunScript(app);
2130
2136
  const appSpaceData = scriptInfo.appSpace[app.name];
@@ -2164,9 +2170,16 @@ function runScript(address, app, scriptInfo, callback, replaceElement) {
2164
2170
  }
2165
2171
  }
2166
2172
  catch (e) {
2167
- console.error(`[micro-app from ${replaceElement ? 'runDynamicScript' : 'runScript'}] app ${app.name}: `, e, address);
2173
+ console.warn(`[micro-app from ${replaceElement ? 'runDynamicScript' : 'runScript'}] app ${app.name}: `, e, address);
2168
2174
  // throw error in with sandbox to parent app
2169
- throw e;
2175
+ const error = e;
2176
+ let throwError = true;
2177
+ if (typeof ((_b = microApp === null || microApp === void 0 ? void 0 : microApp.options) === null || _b === void 0 ? void 0 : _b.excludeRunScriptFilter) === 'function') {
2178
+ throwError = microApp.options.excludeRunScriptFilter(address, error, app.name, app.url) !== true;
2179
+ }
2180
+ if (throwError) {
2181
+ throw e;
2182
+ }
2170
2183
  }
2171
2184
  }
2172
2185
  /**
@@ -2324,53 +2337,49 @@ function processCode(configs, code, address) {
2324
2337
 
2325
2338
  /**
2326
2339
  * Recursively process each child element
2327
- * @param parent parent element
2340
+ * @param body body element
2328
2341
  * @param app app
2329
2342
  * @param microAppHead micro-app-head element
2330
2343
  */
2331
- function flatChildren(parent, app, microAppHead, fiberStyleTasks) {
2332
- const children = Array.from(parent.children);
2333
- children.length && children.forEach((child) => {
2334
- flatChildren(child, app, microAppHead, fiberStyleTasks);
2335
- });
2336
- for (const dom of children) {
2337
- if (isLinkElement(dom)) {
2338
- if (dom.hasAttribute('exclude') || checkExcludeUrl(dom.getAttribute('href'), app.name)) {
2339
- parent.replaceChild(document.createComment('link element with exclude attribute ignored by micro-app'), dom);
2340
- }
2341
- else if (!(dom.hasAttribute('ignore') || checkIgnoreUrl(dom.getAttribute('href'), app.name))) {
2342
- extractLinkFromHtml(dom, parent, app);
2343
- }
2344
- else if (dom.hasAttribute('href')) {
2345
- globalEnv.rawSetAttribute.call(dom, 'href', CompletionPath(dom.getAttribute('href'), app.url));
2346
- }
2344
+ function flatBodyChildren(body, app, fiberStyleTasks) {
2345
+ if (!body || !isBodyElement(body)) {
2346
+ return;
2347
+ }
2348
+ const links = Array.from(body.getElementsByTagName('link'));
2349
+ links.map((dom) => {
2350
+ if (dom.hasAttribute('exclude') || checkExcludeUrl(dom.getAttribute('href'), app.name)) {
2351
+ dom.parentElement.replaceChild(document.createComment('link element with exclude attribute ignored by micro-app'), dom);
2347
2352
  }
2348
- else if (isStyleElement(dom)) {
2349
- if (dom.hasAttribute('exclude')) {
2350
- parent.replaceChild(document.createComment('style element with exclude attribute ignored by micro-app'), dom);
2351
- }
2352
- else if (app.scopecss && !dom.hasAttribute('ignore')) {
2353
- injectFiberTask(fiberStyleTasks, () => scopedCSS(dom, app));
2354
- }
2353
+ else if (!(dom.hasAttribute('ignore') || checkIgnoreUrl(dom.getAttribute('href'), app.name))) {
2354
+ extractLinkFromHtml(dom, dom.parentElement, app);
2355
2355
  }
2356
- else if (isScriptElement(dom)) {
2357
- extractScriptElement(dom, parent, app);
2356
+ else if (dom.hasAttribute('href')) {
2357
+ globalEnv.rawSetAttribute.call(dom, 'href', CompletionPath(dom.getAttribute('href'), app.url));
2358
2358
  }
2359
- else if (isImageElement(dom) && dom.hasAttribute('src')) {
2359
+ return dom;
2360
+ });
2361
+ const styles = Array.from(body.getElementsByTagName('style'));
2362
+ styles.map((dom) => {
2363
+ if (dom.hasAttribute('exclude')) {
2364
+ dom.parentElement.replaceChild(document.createComment('style element with exclude attribute ignored by micro-app'), dom);
2365
+ }
2366
+ else if (app.scopecss && !dom.hasAttribute('ignore')) {
2367
+ injectFiberTask(fiberStyleTasks, () => scopedCSS(dom, app));
2368
+ }
2369
+ return dom;
2370
+ });
2371
+ const scripts = Array.from(body.getElementsByTagName('script'));
2372
+ scripts.map((dom) => {
2373
+ extractScriptElement(dom, dom.parentElement, app);
2374
+ return dom;
2375
+ });
2376
+ const images = Array.from(body.getElementsByTagName('img'));
2377
+ images.map((dom) => {
2378
+ if (dom.hasAttribute('src')) {
2360
2379
  globalEnv.rawSetAttribute.call(dom, 'src', CompletionPath(dom.getAttribute('src'), app.url));
2361
2380
  }
2362
- /**
2363
- * Don't remove meta and title, they have some special scenes
2364
- * e.g.
2365
- * document.querySelector('meta[name="viewport"]') // for flexible
2366
- * document.querySelector('meta[name="baseurl"]').baseurl // for api request
2367
- *
2368
- * Title point to main app title, child app title used to be compatible with some special scenes
2369
- */
2370
- // else if (dom instanceof HTMLMetaElement || dom instanceof HTMLTitleElement) {
2371
- // parent.removeChild(dom)
2372
- // }
2373
- }
2381
+ return dom;
2382
+ });
2374
2383
  }
2375
2384
  /**
2376
2385
  * Extract link and script, bind style scope
@@ -2387,7 +2396,7 @@ function extractSourceDom(htmlStr, app) {
2387
2396
  return logError(msg, app.name);
2388
2397
  }
2389
2398
  const fiberStyleTasks = app.isPrefetch || app.fiber ? [] : null;
2390
- flatChildren(wrapElement, app, microAppHead, fiberStyleTasks);
2399
+ flatBodyChildren(wrapElement, app, fiberStyleTasks);
2391
2400
  /**
2392
2401
  * Style and link are parallel, as it takes a lot of time for link to request resources. During this period, style processing can be performed to improve efficiency.
2393
2402
  */
@@ -6005,9 +6014,9 @@ function patchDocumentPrototype(appName, microAppWindow) {
6005
6014
  }
6006
6015
  // query element👇
6007
6016
  function querySelector(selectors) {
6008
- var _a;
6017
+ var _a, _b;
6009
6018
  const _this = getBindTarget(this);
6010
- if (selectors === 'body') {
6019
+ if (selectors === 'body' && ((_a = microApp === null || microApp === void 0 ? void 0 : microApp.options) === null || _a === void 0 ? void 0 : _a.inheritBaseBody) !== true) {
6011
6020
  return this.body;
6012
6021
  }
6013
6022
  if (!selectors ||
@@ -6026,7 +6035,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
6026
6035
  *
6027
6036
  * Issue: https://github.com/jd-opensource/micro-app/issues/1335
6028
6037
  */
6029
- const result = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.querySelector(selectors);
6038
+ const result = (_b = appInstanceMap.get(appName)) === null || _b === void 0 ? void 0 : _b.querySelector(selectors);
6030
6039
  return result || selectors === 'base' ? result : rawMicroQuerySelector.call(microDocument, selectors);
6031
6040
  }
6032
6041
  function querySelectorAll(selectors) {
@@ -6151,10 +6160,10 @@ function patchDocumentProperty(appName, microAppWindow, sandbox) {
6151
6160
  enumerable: true,
6152
6161
  configurable: true,
6153
6162
  get: () => {
6154
- var _a;
6163
+ var _a, _b;
6155
6164
  throttleDeferForIframeAppName(appName);
6156
- if (tagName === 'body') {
6157
- return (_a = sandbox.options.container) === null || _a === void 0 ? void 0 : _a.querySelector('micro-app-body');
6165
+ if (tagName === 'body' && ((_a = microApp === null || microApp === void 0 ? void 0 : microApp.options) === null || _a === void 0 ? void 0 : _a.inheritBaseBody) !== true) {
6166
+ return ((_b = sandbox.options.container) === null || _b === void 0 ? void 0 : _b.querySelector('micro-app-body')) || rawDocument[tagName];
6158
6167
  }
6159
6168
  return rawDocument[tagName];
6160
6169
  },