diff --git a/.changeset/real-trees-unite.md b/.changeset/real-trees-unite.md new file mode 100644 index 000000000..67ff5f82a --- /dev/null +++ b/.changeset/real-trees-unite.md @@ -0,0 +1,5 @@ +--- +"@qiankunjs/sandbox": patch +--- + +fix(sandbox): compatible with dynamically appending stylesheets to detached containers diff --git a/packages/sandbox/src/patchers/dynamicAppend/common.ts b/packages/sandbox/src/patchers/dynamicAppend/common.ts index 243717363..115d30936 100644 --- a/packages/sandbox/src/patchers/dynamicAppend/common.ts +++ b/packages/sandbox/src/patchers/dynamicAppend/common.ts @@ -163,7 +163,18 @@ export function getOverwrittenAppendChildOrInsertBefore( rawNode: stylesheetElement, }); - const result = appendChild.call(this, transpiledStyleSheetElement, referenceNode); + const stylesheetTargetDetached = !document.contains(this); + if (stylesheetTargetDetached) { + warn( + `Trying to append stylesheet element ${ + ('href' in transpiledStyleSheetElement && transpiledStyleSheetElement.href) || + transpiledStyleSheetElement.dataset.href + } to a detached container which may cause unexpected behaviors!`, + ); + } + // FIXME we have to set the target container to global document to trigger style rendering while the real container was detached + const targetContainerDOM = stylesheetTargetDetached ? document[target] : this; + const result = appendChild.call(targetContainerDOM, transpiledStyleSheetElement, referenceNode); // record refNo thus we can keep order while remounting if (typeof refNo === 'number' && refNo !== -1) { @@ -216,10 +227,10 @@ export function getOverwrittenAppendChildOrInsertBefore( ); } /* - FIXME we have to set the target container to global document head to trigger script evaluation while the real container was detached, + FIXME we have to set the target container to global document to trigger script evaluation while the real container was detached, as dynamic append script element to detached element will not trigger script evaluation automatically */ - const targetContainerDOM = scriptTargetDetached ? document.head : this; + const targetContainerDOM = scriptTargetDetached ? document[target] : this; const result = appendChild.call(targetContainerDOM, transpiledScriptElement, refChild) as T; // the script have no src attribute after transpile, indicating that the script needs to wait for the src to be filled