diff --git a/src/sandbox/patchers/dynamicAppend.ts b/src/sandbox/patchers/dynamicAppend.ts index f93da56..c601359 100644 --- a/src/sandbox/patchers/dynamicAppend.ts +++ b/src/sandbox/patchers/dynamicAppend.ts @@ -82,6 +82,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: { rawDOMAppendOrInsertBefore: (newChild: T, refChild?: Node | null) => T; scopedCSS: boolean; excludeAssetFilter?: CallableFunction; + elementAttachmentMap: WeakMap; }) { return function appendChildOrInsertBefore( this: HTMLHeadElement | HTMLBodyElement, @@ -191,6 +192,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: { }); const dynamicScriptCommentElement = document.createComment(`dynamic script ${src} replaced by qiankun`); + opts.elementAttachmentMap.set(element, dynamicScriptCommentElement); return rawDOMAppendOrInsertBefore.call(mountDOM, dynamicScriptCommentElement, referenceNode); } @@ -200,6 +202,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: { error: element.onerror, }); const dynamicInlineScriptCommentElement = document.createComment('dynamic inline script replaced by qiankun'); + opts.elementAttachmentMap.set(element, dynamicInlineScriptCommentElement); return rawDOMAppendOrInsertBefore.call(mountDOM, dynamicInlineScriptCommentElement, referenceNode); } @@ -215,6 +218,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: { function getNewRemoveChild(opts: { appWrapperGetter: CallableFunction; headOrBodyRemoveChild: typeof HTMLElement.prototype.removeChild; + elementAttachmentMap: WeakMap; }) { return function removeChild(this: HTMLHeadElement | HTMLBodyElement, child: T) { const { headOrBodyRemoveChild } = opts; @@ -231,8 +235,9 @@ function getNewRemoveChild(opts: { // container may had been removed while app unmounting if the removeChild action was async const container = appWrapperGetter(); - if (container.contains(child)) { - return rawRemoveChild.call(container, child) as T; + const attachedElement = opts.elementAttachmentMap.get(child as any) || child; + if (container.contains(attachedElement)) { + return rawRemoveChild.call(container, attachedElement) as T; } } } catch (e) { @@ -252,6 +257,8 @@ function patchHTMLDynamicAppendPrototypeFunctions( dynamicStyleSheetElements: HTMLStyleElement[], excludeAssetFilter?: CallableFunction, ) { + const elementAttachmentMap = new WeakMap(); + // Just overwrite it while it have not been overwrite if ( HTMLHeadElement.prototype.appendChild === rawHeadAppendChild && @@ -267,6 +274,7 @@ function patchHTMLDynamicAppendPrototypeFunctions( dynamicStyleSheetElements, scopedCSS, excludeAssetFilter, + elementAttachmentMap, }) as typeof rawHeadAppendChild; HTMLBodyElement.prototype.appendChild = getOverwrittenAppendChildOrInsertBefore({ rawDOMAppendOrInsertBefore: rawBodyAppendChild, @@ -277,6 +285,7 @@ function patchHTMLDynamicAppendPrototypeFunctions( dynamicStyleSheetElements, scopedCSS, excludeAssetFilter, + elementAttachmentMap, }) as typeof rawBodyAppendChild; HTMLHeadElement.prototype.insertBefore = getOverwrittenAppendChildOrInsertBefore({ @@ -288,6 +297,7 @@ function patchHTMLDynamicAppendPrototypeFunctions( dynamicStyleSheetElements, scopedCSS, excludeAssetFilter, + elementAttachmentMap, }) as typeof rawHeadInsertBefore; } @@ -299,10 +309,12 @@ function patchHTMLDynamicAppendPrototypeFunctions( HTMLHeadElement.prototype.removeChild = getNewRemoveChild({ appWrapperGetter, headOrBodyRemoveChild: rawHeadRemoveChild, + elementAttachmentMap, }); HTMLBodyElement.prototype.removeChild = getNewRemoveChild({ appWrapperGetter, headOrBodyRemoveChild: rawBodyRemoveChild, + elementAttachmentMap, }); }