🐛 identify host app dynamic creation (#897)

This commit is contained in:
Kuitos 2020-08-26 11:32:46 +08:00 committed by GitHub
parent 7a538cce9f
commit cbaad7ed2d
4 changed files with 46 additions and 19 deletions

View File

@ -1,24 +1,8 @@
import React, { useState, useEffect } from 'react';
import { Button, Modal } from 'antd';
const dispatchUIEvent = () => {
const $a = document.createElement('a');
$a.onclick = () => {
console.log('log from UIEvent');
};
const evt = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: false,
});
$a.dispatchEvent(evt);
};
export default function() {
const [visible, setVisible] = useState(false);
useEffect(() => {
dispatchUIEvent();
}, []);
return (
<>
<Button onClick={() => setVisible(true)}>CLICK ME</Button>

View File

@ -195,8 +195,8 @@ test('hasOwnProperty should always returns same reference', () => {
});
test('document accessing should modify the attachDocProxySymbol value every time', () => {
const proxy1 = new ProxySandbox('doc-access-test1').proxy as any;
const proxy2 = new ProxySandbox('doc-access-test2').proxy as any;
const proxy1 = new ProxySandbox('doc-access-test1').proxy;
const proxy2 = new ProxySandbox('doc-access-test2').proxy;
const d1 = proxy1.document;
expect(d1[attachDocProxySymbol]).toBe(proxy1);
@ -207,6 +207,37 @@ test('document accessing should modify the attachDocProxySymbol value every time
expect(d1).toBe(document);
});
test('document attachDocProxySymbol mark should be remove before next tasl', done => {
const { proxy } = new ProxySandbox('doc-symbol');
const d1 = proxy.document;
expect(d1[attachDocProxySymbol]).toBe(proxy);
setTimeout(() => {
expect(d1[attachDocProxySymbol]).toBeUndefined();
done();
});
});
test('document should work well with MutationObserver', done => {
const docProxy = new ProxySandbox('doc').proxy;
const observer = new MutationObserver(mutations => {
if (mutations[0]) {
expect(mutations[0].target).toBe(document.body);
observer.disconnect();
done();
}
});
observer.observe(docProxy.document, {
attributes: true,
subtree: true,
childList: true,
});
docProxy.document.body.innerHTML = '<div></div>';
});
test('bounded function should not be rebounded', () => {
const proxy = new ProxySandbox('bound-fn-test').proxy as any;
const fn = () => {};

View File

@ -4,7 +4,7 @@
* @since 2020-3-31
*/
import { SandBox, SandBoxType } from '../interfaces';
import { uniq } from '../utils';
import { nextTick, uniq } from '../utils';
import { attachDocProxySymbol, getTargetValue } from './common';
import { clearSystemJsProps, interceptSystemJsProps } from './noise/systemjs';
@ -186,6 +186,10 @@ export default class ProxySandbox implements SandBox {
// mark the symbol to document while accessing as document.createElement could know is invoked by which sandbox for dynamic append patcher
if (p === 'document') {
document[attachDocProxySymbol] = proxy;
// remove the mark in next tick, thus we can identify whether it in micro app or not
// this approach is just a workaround, it could not cover all the complex scenarios, such as the micro app runs in the same task context with master in som case
// fixme if you have any other good ideas
nextTick(() => delete document[attachDocProxySymbol]);
return document;
}

View File

@ -14,6 +14,14 @@ export function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* run a callback after next tick
* @param cb
*/
export function nextTick(cb: () => void): void {
Promise.resolve().then(cb);
}
export function isConstructable(fn: () => void | FunctionConstructor) {
const constructableFunctionRegex = /^function\b\s[A-Z].*/;
const classRegex = /^class\b/;