diff --git a/src/sandbox/__tests__/proxySandbox.test.ts b/src/sandbox/__tests__/proxySandbox.test.ts index d46b997..3c52550 100644 --- a/src/sandbox/__tests__/proxySandbox.test.ts +++ b/src/sandbox/__tests__/proxySandbox.test.ts @@ -4,7 +4,7 @@ */ import { isBoundedFunction } from '../../utils'; -import { documentAttachProxyMap } from '../common'; +import { getCurrentRunningSandboxProxy } from '../common'; import ProxySandbox from '../proxySandbox'; beforeAll(() => { @@ -201,26 +201,42 @@ test('hasOwnProperty should always returns same reference', () => { expect(proxy.testA.hasOwnProperty).toBe(proxy.testB.hasOwnProperty); }); -test('document accessing should modify the attachDocProxySymbol value every time', () => { +test('document and eval accessing should modify the attachDocProxySymbol value every time', () => { const proxy1 = new ProxySandbox('doc-access-test1').proxy; const proxy2 = new ProxySandbox('doc-access-test2').proxy; + const proxy3 = new ProxySandbox('eval-access-test1').proxy; + const proxy4 = new ProxySandbox('eval-access-test2').proxy; const d1 = proxy1.document; - expect(documentAttachProxyMap.get(d1)).toBe(proxy1); + expect(getCurrentRunningSandboxProxy()).toBe(proxy1); const d2 = proxy2.document; - expect(documentAttachProxyMap.get(d2)).toBe(proxy2); + expect(getCurrentRunningSandboxProxy()).toBe(proxy2); expect(d1).toBe(d2); expect(d1).toBe(document); + + // @ts-ignore + const eval1 = proxy3.eval; + expect(getCurrentRunningSandboxProxy()).toBe(proxy3); + // @ts-ignore + const eval2 = proxy4.eval; + expect(getCurrentRunningSandboxProxy()).toBe(proxy4); + + expect(eval1).toBe(eval2); + // eslint-disable-next-line no-eval + expect(eval1).toBe(eval); }); -test('document attachDocProxySymbol mark should be remove before next tasl', (done) => { +test('document attachDocProxySymbol mark should be remove before next task', (done) => { const { proxy } = new ProxySandbox('doc-symbol'); + // just access + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-unused-vars const d1 = proxy.document; - expect(documentAttachProxyMap.get(d1)).toBe(proxy); + expect(getCurrentRunningSandboxProxy()).toBe(proxy); setTimeout(() => { - expect(documentAttachProxyMap.get(d1)).toBeUndefined(); + expect(getCurrentRunningSandboxProxy()).toBeNull(); done(); }); }); diff --git a/src/sandbox/common.ts b/src/sandbox/common.ts index 068d660..1388923 100644 --- a/src/sandbox/common.ts +++ b/src/sandbox/common.ts @@ -5,7 +5,14 @@ import { isBoundedFunction, isCallable, isConstructable } from '../utils'; -export const documentAttachProxyMap = new WeakMap(); +let currentRunningSandboxProxy: WindowProxy | null; +export function getCurrentRunningSandboxProxy() { + return currentRunningSandboxProxy; +} + +export function setCurrentRunningSandboxProxy(proxy: WindowProxy | null) { + currentRunningSandboxProxy = proxy; +} const functionBoundedValueMap = new WeakMap(); export function getTargetValue(target: any, value: any): any { diff --git a/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts b/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts index d046c09..407f63b 100644 --- a/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts +++ b/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts @@ -4,7 +4,7 @@ */ import { Freer } from '../../../interfaces'; -import { documentAttachProxyMap } from '../../common'; +import { getCurrentRunningSandboxProxy } from '../../common'; import { ContainerConfig, isHijackingTag, @@ -27,11 +27,9 @@ function patchDocumentCreateElement() { ): HTMLElement { const element = rawDocumentCreateElement.call(this, tagName, options); if (isHijackingTag(tagName)) { - // 这里使用document来获取比this更加健壮,因为之前set的时候是传入的document: - // 因为document不一定是原生的document,这种情况出现在qiankun本身就在另一个沙箱下运行的情况,而那个沙箱可能连document都重写了。 - const attachProxy = documentAttachProxyMap.get(document); - if (attachProxy) { - const proxyContainerConfig = proxyAttachContainerConfigMap.get(attachProxy); + const currentRunningSandboxProxy = getCurrentRunningSandboxProxy(); + if (currentRunningSandboxProxy) { + const proxyContainerConfig = proxyAttachContainerConfigMap.get(currentRunningSandboxProxy); if (proxyContainerConfig) { elementAttachContainerConfigMap.set(element, proxyContainerConfig); } diff --git a/src/sandbox/proxySandbox.ts b/src/sandbox/proxySandbox.ts index 6140c9e..9d7202e 100644 --- a/src/sandbox/proxySandbox.ts +++ b/src/sandbox/proxySandbox.ts @@ -5,7 +5,7 @@ */ import { SandBox, SandBoxType } from '../interfaces'; import { nextTick } from '../utils'; -import { documentAttachProxyMap, getTargetValue } from './common'; +import { getTargetValue, setCurrentRunningSandboxProxy } from './common'; /** * fastest(at most time) unique array method @@ -50,7 +50,6 @@ const unscopables = { String: true, Boolean: true, Math: true, - eval: true, Number: true, Symbol: true, parseFloat: true, @@ -223,13 +222,20 @@ 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') { - documentAttachProxyMap.set(document, proxy); + if (p === 'document' || p === 'eval') { + setCurrentRunningSandboxProxy(proxy); + // FIXME if you have any other good ideas // 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(() => documentAttachProxyMap.delete(document)); - return document; + // this approach is just a workaround, it could not cover all complex cases, such as the micro app runs in the same task context with master in some case + nextTick(() => setCurrentRunningSandboxProxy(null)); + switch (p) { + case 'document': + return document; + case 'eval': + // eslint-disable-next-line no-eval + return eval; + // no default + } } // eslint-disable-next-line no-bitwise