🐛 identify host app dynamic creation (#897)
This commit is contained in:
parent
7a538cce9f
commit
cbaad7ed2d
|
|
@ -1,24 +1,8 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Button, Modal } from 'antd';
|
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() {
|
export default function() {
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
useEffect(() => {
|
|
||||||
dispatchUIEvent();
|
|
||||||
}, []);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button onClick={() => setVisible(true)}>CLICK ME</Button>
|
<Button onClick={() => setVisible(true)}>CLICK ME</Button>
|
||||||
|
|
|
||||||
|
|
@ -195,8 +195,8 @@ test('hasOwnProperty should always returns same reference', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('document accessing should modify the attachDocProxySymbol value every time', () => {
|
test('document accessing should modify the attachDocProxySymbol value every time', () => {
|
||||||
const proxy1 = new ProxySandbox('doc-access-test1').proxy as any;
|
const proxy1 = new ProxySandbox('doc-access-test1').proxy;
|
||||||
const proxy2 = new ProxySandbox('doc-access-test2').proxy as any;
|
const proxy2 = new ProxySandbox('doc-access-test2').proxy;
|
||||||
|
|
||||||
const d1 = proxy1.document;
|
const d1 = proxy1.document;
|
||||||
expect(d1[attachDocProxySymbol]).toBe(proxy1);
|
expect(d1[attachDocProxySymbol]).toBe(proxy1);
|
||||||
|
|
@ -207,6 +207,37 @@ test('document accessing should modify the attachDocProxySymbol value every time
|
||||||
expect(d1).toBe(document);
|
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', () => {
|
test('bounded function should not be rebounded', () => {
|
||||||
const proxy = new ProxySandbox('bound-fn-test').proxy as any;
|
const proxy = new ProxySandbox('bound-fn-test').proxy as any;
|
||||||
const fn = () => {};
|
const fn = () => {};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* @since 2020-3-31
|
* @since 2020-3-31
|
||||||
*/
|
*/
|
||||||
import { SandBox, SandBoxType } from '../interfaces';
|
import { SandBox, SandBoxType } from '../interfaces';
|
||||||
import { uniq } from '../utils';
|
import { nextTick, uniq } from '../utils';
|
||||||
import { attachDocProxySymbol, getTargetValue } from './common';
|
import { attachDocProxySymbol, getTargetValue } from './common';
|
||||||
import { clearSystemJsProps, interceptSystemJsProps } from './noise/systemjs';
|
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
|
// mark the symbol to document while accessing as document.createElement could know is invoked by which sandbox for dynamic append patcher
|
||||||
if (p === 'document') {
|
if (p === 'document') {
|
||||||
document[attachDocProxySymbol] = proxy;
|
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;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,14 @@ export function sleep(ms: number) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
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) {
|
export function isConstructable(fn: () => void | FunctionConstructor) {
|
||||||
const constructableFunctionRegex = /^function\b\s[A-Z].*/;
|
const constructableFunctionRegex = /^function\b\s[A-Z].*/;
|
||||||
const classRegex = /^class\b/;
|
const classRegex = /^class\b/;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user