🐛 keep dynamic stylesheet inserted order by insertBefore way (#2574)
This commit is contained in:
parent
9fe0236a64
commit
69759a57e5
|
|
@ -14,6 +14,7 @@ const LINK_TAG_NAME = 'LINK';
|
|||
const STYLE_TAG_NAME = 'STYLE';
|
||||
|
||||
export const styleElementTargetSymbol = Symbol('target');
|
||||
export const styleElementRefNodeNo = Symbol('refNodeNo');
|
||||
const overwrittenSymbol = Symbol('qiankun-overwritten');
|
||||
|
||||
type DynamicDomMutationTarget = 'head' | 'body';
|
||||
|
|
@ -21,10 +22,12 @@ type DynamicDomMutationTarget = 'head' | 'body';
|
|||
declare global {
|
||||
interface HTMLLinkElement {
|
||||
[styleElementTargetSymbol]: DynamicDomMutationTarget;
|
||||
[styleElementRefNodeNo]?: number;
|
||||
}
|
||||
|
||||
interface HTMLStyleElement {
|
||||
[styleElementTargetSymbol]: DynamicDomMutationTarget;
|
||||
[styleElementRefNodeNo]?: number;
|
||||
}
|
||||
|
||||
interface Function {
|
||||
|
|
@ -156,6 +159,15 @@ function convertLinkAsStyle(
|
|||
return styleElement;
|
||||
}
|
||||
|
||||
const defineNonEnumerableProperty = (target: any, key: string | symbol, value: any) => {
|
||||
Object.defineProperty(target, key, {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value,
|
||||
});
|
||||
};
|
||||
|
||||
const styledComponentCSSRulesMap = new WeakMap<HTMLStyleElement, CSSRuleList>();
|
||||
const dynamicScriptAttachedCommentMap = new WeakMap<HTMLScriptElement, Comment>();
|
||||
const dynamicLinkAttachedInlineStyleMap = new WeakMap<HTMLLinkElement, HTMLStyleElement>();
|
||||
|
|
@ -230,11 +242,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: {
|
|||
return rawDOMAppendOrInsertBefore.call(this, element, refChild) as T;
|
||||
}
|
||||
|
||||
Object.defineProperty(stylesheetElement, styleElementTargetSymbol, {
|
||||
value: target,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
defineNonEnumerableProperty(stylesheetElement, styleElementTargetSymbol, target);
|
||||
|
||||
const appWrapper = appWrapperGetter();
|
||||
|
||||
|
|
@ -262,9 +270,23 @@ function getOverwrittenAppendChildOrInsertBefore(opts: {
|
|||
|
||||
const mountDOM = target === 'head' ? getAppWrapperHeadElement(appWrapper) : appWrapper;
|
||||
|
||||
dynamicStyleSheetElements.push(stylesheetElement);
|
||||
const referenceNode = mountDOM.contains(refChild) ? refChild : null;
|
||||
return rawDOMAppendOrInsertBefore.call(mountDOM, stylesheetElement, referenceNode);
|
||||
|
||||
let refNo: number | undefined;
|
||||
if (referenceNode) {
|
||||
refNo = Array.from(mountDOM.childNodes).indexOf(referenceNode);
|
||||
}
|
||||
|
||||
const result = rawDOMAppendOrInsertBefore.call(mountDOM, stylesheetElement, referenceNode);
|
||||
|
||||
// record refNo thus we can keep order while remounting
|
||||
if (typeof refNo === 'number' && refNo !== -1) {
|
||||
defineNonEnumerableProperty(stylesheetElement, styleElementRefNodeNo, refNo);
|
||||
}
|
||||
// record dynamic style elements after insert succeed
|
||||
dynamicStyleSheetElements.push(stylesheetElement);
|
||||
|
||||
return result as T;
|
||||
}
|
||||
|
||||
case SCRIPT_TAG_NAME: {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
patchHTMLDynamicAppendPrototypeFunctions,
|
||||
rebuildCSSRules,
|
||||
recordStyledComponentsCSSRules,
|
||||
styleElementRefNodeNo,
|
||||
styleElementTargetSymbol,
|
||||
} from './common';
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ Object.defineProperty(nativeGlobal, '__currentLockingSandbox__', {
|
|||
});
|
||||
|
||||
const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
|
||||
const rawHeadInsertBefore = HTMLHeadElement.prototype.insertBefore;
|
||||
|
||||
// Share proxyAttachContainerConfigMap between multiple qiankun instance, thus they could access the same record
|
||||
nativeGlobal.__proxyAttachContainerConfigMap__ =
|
||||
|
|
@ -279,8 +281,18 @@ export function patchStrictSandbox(
|
|||
if (!appWrapper.contains(stylesheetElement)) {
|
||||
const mountDom =
|
||||
stylesheetElement[styleElementTargetSymbol] === 'head' ? getAppWrapperHeadElement(appWrapper) : appWrapper;
|
||||
rawHeadAppendChild.call(mountDom, stylesheetElement);
|
||||
return true;
|
||||
const refNo = stylesheetElement[styleElementRefNodeNo];
|
||||
|
||||
if (typeof refNo === 'number' && refNo !== -1) {
|
||||
const refNode = mountDom.childNodes[refNo];
|
||||
if (refNode) {
|
||||
rawHeadInsertBefore.call(mountDom, stylesheetElement, refNode);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
rawHeadAppendChild.call(mountDom, stylesheetElement);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user