🐛 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';
|
const STYLE_TAG_NAME = 'STYLE';
|
||||||
|
|
||||||
export const styleElementTargetSymbol = Symbol('target');
|
export const styleElementTargetSymbol = Symbol('target');
|
||||||
|
export const styleElementRefNodeNo = Symbol('refNodeNo');
|
||||||
const overwrittenSymbol = Symbol('qiankun-overwritten');
|
const overwrittenSymbol = Symbol('qiankun-overwritten');
|
||||||
|
|
||||||
type DynamicDomMutationTarget = 'head' | 'body';
|
type DynamicDomMutationTarget = 'head' | 'body';
|
||||||
|
|
@ -21,10 +22,12 @@ type DynamicDomMutationTarget = 'head' | 'body';
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLLinkElement {
|
interface HTMLLinkElement {
|
||||||
[styleElementTargetSymbol]: DynamicDomMutationTarget;
|
[styleElementTargetSymbol]: DynamicDomMutationTarget;
|
||||||
|
[styleElementRefNodeNo]?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HTMLStyleElement {
|
interface HTMLStyleElement {
|
||||||
[styleElementTargetSymbol]: DynamicDomMutationTarget;
|
[styleElementTargetSymbol]: DynamicDomMutationTarget;
|
||||||
|
[styleElementRefNodeNo]?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Function {
|
interface Function {
|
||||||
|
|
@ -156,6 +159,15 @@ function convertLinkAsStyle(
|
||||||
return styleElement;
|
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 styledComponentCSSRulesMap = new WeakMap<HTMLStyleElement, CSSRuleList>();
|
||||||
const dynamicScriptAttachedCommentMap = new WeakMap<HTMLScriptElement, Comment>();
|
const dynamicScriptAttachedCommentMap = new WeakMap<HTMLScriptElement, Comment>();
|
||||||
const dynamicLinkAttachedInlineStyleMap = new WeakMap<HTMLLinkElement, HTMLStyleElement>();
|
const dynamicLinkAttachedInlineStyleMap = new WeakMap<HTMLLinkElement, HTMLStyleElement>();
|
||||||
|
|
@ -230,11 +242,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: {
|
||||||
return rawDOMAppendOrInsertBefore.call(this, element, refChild) as T;
|
return rawDOMAppendOrInsertBefore.call(this, element, refChild) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperty(stylesheetElement, styleElementTargetSymbol, {
|
defineNonEnumerableProperty(stylesheetElement, styleElementTargetSymbol, target);
|
||||||
value: target,
|
|
||||||
writable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const appWrapper = appWrapperGetter();
|
const appWrapper = appWrapperGetter();
|
||||||
|
|
||||||
|
|
@ -262,9 +270,23 @@ function getOverwrittenAppendChildOrInsertBefore(opts: {
|
||||||
|
|
||||||
const mountDOM = target === 'head' ? getAppWrapperHeadElement(appWrapper) : appWrapper;
|
const mountDOM = target === 'head' ? getAppWrapperHeadElement(appWrapper) : appWrapper;
|
||||||
|
|
||||||
dynamicStyleSheetElements.push(stylesheetElement);
|
|
||||||
const referenceNode = mountDOM.contains(refChild) ? refChild : null;
|
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: {
|
case SCRIPT_TAG_NAME: {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import {
|
||||||
patchHTMLDynamicAppendPrototypeFunctions,
|
patchHTMLDynamicAppendPrototypeFunctions,
|
||||||
rebuildCSSRules,
|
rebuildCSSRules,
|
||||||
recordStyledComponentsCSSRules,
|
recordStyledComponentsCSSRules,
|
||||||
|
styleElementRefNodeNo,
|
||||||
styleElementTargetSymbol,
|
styleElementTargetSymbol,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
|
||||||
|
|
@ -35,6 +36,7 @@ Object.defineProperty(nativeGlobal, '__currentLockingSandbox__', {
|
||||||
});
|
});
|
||||||
|
|
||||||
const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
|
const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
|
||||||
|
const rawHeadInsertBefore = HTMLHeadElement.prototype.insertBefore;
|
||||||
|
|
||||||
// Share proxyAttachContainerConfigMap between multiple qiankun instance, thus they could access the same record
|
// Share proxyAttachContainerConfigMap between multiple qiankun instance, thus they could access the same record
|
||||||
nativeGlobal.__proxyAttachContainerConfigMap__ =
|
nativeGlobal.__proxyAttachContainerConfigMap__ =
|
||||||
|
|
@ -279,9 +281,19 @@ export function patchStrictSandbox(
|
||||||
if (!appWrapper.contains(stylesheetElement)) {
|
if (!appWrapper.contains(stylesheetElement)) {
|
||||||
const mountDom =
|
const mountDom =
|
||||||
stylesheetElement[styleElementTargetSymbol] === 'head' ? getAppWrapperHeadElement(appWrapper) : appWrapper;
|
stylesheetElement[styleElementTargetSymbol] === 'head' ? getAppWrapperHeadElement(appWrapper) : appWrapper;
|
||||||
|
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);
|
rawHeadAppendChild.call(mountDom, stylesheetElement);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user