Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit d3453e9

Browse files
Othmane BENTALEBbaiwusanyu-c
Othmane BENTALEB
andauthored
fix: multiple ce instances styles tracking (#114)
* fix: multiple ce instances styles tracking * chore: Sync the latest code --------- Co-authored-by: baiwusanyu-c <[email protected]>
1 parent 5d9d8d7 commit d3453e9

File tree

3 files changed

+83
-63
lines changed

3 files changed

+83
-63
lines changed
Lines changed: 71 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,37 @@
11
import type { MagicStringBase } from 'magic-string-ast'
22
import type {
3+
BlockStatement,
34
CallExpression,
45
ClassDeclaration,
56
ClassMethod,
67
Identifier,
8+
IfStatement,
79
MemberExpression,
810
VariableDeclarator,
911
} from '@babel/types'
1012

11-
const _childStylesAnchor = '\n this._childStylesAnchor = null;'
13+
const _childStylesAnchor = '\n this._childStylesAnchor = null;\n this._childStylesSet = new Set();'
1214

1315
const injectBindFnContent
14-
= 'instance.addCEChildStyle = this._addChildStyles.bind(this);\n'
15-
+ ' instance.removeCEChildStyle = this._removeChildStyles.bind(this);\n '
16+
= ' instance.ceContext = {\n'
17+
+ ' addCEChildStyle: this._addChildStyles.bind(this),\n'
18+
+ ' removeCEChildStyles: this._removeChildStyles.bind(this),\n'
19+
+ ' };\n'
1620

17-
const injectAddAndRemoveStyle = '_addChildStyles(styles, instance) {\n'
21+
const injectAddAndRemoveStyle = '// The method used by custom element child components\n'
22+
+ ' // to add styles to the shadow dom\n'
23+
+ ' _addChildStyles(styles, uid, hasAttr) {\n'
1824
+ ' if (styles) {\n'
19-
+ ' const styleContent = styles.join();\n'
20-
// eslint-disable-next-line no-template-curly-in-string
21-
+ ' const ceKey = `__${this._instance.uid}`;\n'
22-
+ ' let ceKeySet = /* @__PURE__ */ new Set();\n'
23-
+ ' if (ceChildStyleMap.has(styleContent)) {\n'
24-
+ ' ceKeySet = ceChildStyleMap.get(styleContent);\n'
25-
+ ' if (ceKeySet.has(ceKey)) {\n'
26-
+ ' ceKeySet.add(ceKey);\n'
27-
+ ' ceChildStyleMap.set(styleContent, ceKeySet);\n'
28-
+ ' return;\n'
29-
+ ' }\n'
30-
+ ' }\n'
31-
+ ' ceKeySet.add(ceKey);\n'
32-
+ ' ceChildStyleMap.set(styleContent, ceKeySet);\n'
33-
// eslint-disable-next-line no-template-curly-in-string
34-
+ ' const ceStyleId = `data-v-ce-${instance.uid}`;\n'
25+
+ ' const isRepeated = this.isHasChildStyle(styles);\n'
26+
+ ' if (isRepeated && !hasAttr)\n'
27+
+ ' return;\n'
3528
+ ' styles.forEach((css, index) => {\n'
3629
+ ' const s = document.createElement("style");\n'
3730
+ ' s.textContent = css;\n'
38-
+ ' s.setAttribute(ceStyleId, "");\n'
31+
// eslint-disable-next-line no-template-curly-in-string
32+
+ ' s.setAttribute(`data-v-ce-${uid}`, "");\n'
3933
+ ' if (this._childStylesAnchor) {\n'
40-
+ ' this.shadowRoot.insertBefore(\n'
41-
+ ' s,\n'
42-
+ ' this._childStylesAnchor\n'
43-
+ ' );\n'
34+
+ ' this.shadowRoot.insertBefore(s, this._childStylesAnchor);\n'
4435
+ ' } else {\n'
4536
+ ' this.shadowRoot.appendChild(s);\n'
4637
+ ' }\n'
@@ -51,38 +42,43 @@ const injectAddAndRemoveStyle = '_addChildStyles(styles, instance) {\n'
5142
+ ' });\n'
5243
+ ' }\n'
5344
+ ' }\n'
54-
+ ' _removeChildStyles(styles, uid) {\n'
45+
+ ' _removeChildStyles(uid) {\n'
46+
+ ' {\n'
47+
// eslint-disable-next-line no-template-curly-in-string
48+
+ ' const styleList = this.shadowRoot.querySelectorAll(`[data-v-ce-${uid}]`);\n'
49+
+ ' let oldStyleContentList = [];\n'
50+
+ ' styleList.length > 0 && styleList.forEach((s) => {\n'
51+
+ ' oldStyleContentList.unshift(s.innerHTML);\n'
52+
+ ' this.shadowRoot.removeChild(s);\n'
53+
+ ' const anchor = this.shadowRoot.querySelectorAll("style");\n'
54+
+ ' this._childStylesAnchor = anchor.length > 0 ? anchor[anchor.length - 1] : void 0;\n'
55+
+ ' });\n'
56+
+ ' this._childStylesSet.delete(oldStyleContentList.join());\n'
57+
+ ' }\n'
58+
+ ' }\n'
59+
+ ' isHasChildStyle(styles) {\n'
5560
+ ' if (styles) {\n'
5661
+ ' const styleContent = styles.join();\n'
57-
+ ' let cecStyle = /* @__PURE__ */ new Set();\n'
58-
+ ' if (ceChildStyleMap.has(styleContent)) {\n'
59-
// eslint-disable-next-line no-template-curly-in-string
60-
+ ' const ceKey = `__${this._instance.uid}`;\n'
61-
+ ' cecStyle = ceChildStyleMap.get(styleContent);\n'
62-
+ ' cecStyle.delete(ceKey);\n'
63-
+ ' if (cecStyle.size === 0) {\n'
64-
// eslint-disable-next-line no-template-curly-in-string
65-
+ ' const sList = this.shadowRoot.querySelectorAll(`[data-v-ce-${uid}]`);\n'
66-
+ ' sList.length > 0 && sList.forEach((s) => this.shadowRoot.removeChild(s));\n'
67-
+ ' const archor = this.shadowRoot.querySelectorAll("style");\n'
68-
+ ' this._childStylesAnchor = archor.length > 0 ? archor[archor.length - 1] : void 0;\n'
69-
+ ' ceChildStyleMap.delete(styleContent);\n'
70-
+ ' } else {\n'
71-
+ ' ceChildStyleMap.set(styleContent, cecStyle);\n'
72-
+ ' }\n'
62+
+ ' if (this._childStylesSet.has(styleContent)) {\n'
63+
+ ' return true;\n'
7364
+ ' }\n'
65+
+ ' this._childStylesSet.add(styleContent);\n'
66+
+ ' return false;\n'
7467
+ ' }\n'
7568
+ ' }'
7669

7770
const injectApplyStyles = '\n this._childStylesAnchor = s;'
78-
const injectCEChildStyleMap = 'const ceChildStyleMap = /* @__PURE__ */ new Map();\n'
71+
const injectApplyStylesCERoot = '\n s.setAttribute(`data-v-ce-root`, \'\')\n'
7972
let isVueElementIdentifier = false
8073
let isBaseClassIdentifier = false
8174
let isApplyStylesIdentifier = false
75+
let isCeReloadIdentifier = false
76+
let isCreateVnodeIdentifier = false
77+
const injectCreateVNode = '\nthis._childStylesSet.clear();\n'
8278
export function injectApiCustomElement(
8379
mgcStr: MagicStringBase,
84-
node: Identifier | CallExpression | MemberExpression,
85-
parent: VariableDeclarator | CallExpression | ClassDeclaration | ClassMethod,
80+
node: Identifier | CallExpression | MemberExpression | IfStatement | BlockStatement,
81+
parent: VariableDeclarator | CallExpression | ClassDeclaration | ClassMethod | IfStatement | MemberExpression,
8682
) {
8783
if (node.type === 'Identifier'
8884
&& node.name === 'VueElement'
@@ -128,7 +124,36 @@ export function injectApiCustomElement(
128124
isApplyStylesIdentifier = false
129125
isVueElementIdentifier = false
130126
isBaseClassIdentifier = false
127+
mgcStr.prependLeft(node.start! - 1, injectApplyStylesCERoot)
131128
mgcStr.prependRight(node.end! + 1, injectApplyStyles)
132-
mgcStr.prependLeft(0, injectCEChildStyleMap)
129+
}
130+
131+
if (node.type === 'Identifier'
132+
&& node.name === '_createVNode'
133+
&& parent
134+
&& parent.type === 'ClassMethod'
135+
&& isVueElementIdentifier
136+
&& isBaseClassIdentifier)
137+
isCreateVnodeIdentifier = true
138+
139+
if (node.type === 'Identifier'
140+
&& node.name === 'ceReload'
141+
&& parent
142+
&& parent.type === 'MemberExpression'
143+
&& isCreateVnodeIdentifier
144+
&& isVueElementIdentifier
145+
&& isBaseClassIdentifier)
146+
isCeReloadIdentifier = true
147+
148+
if (isCeReloadIdentifier
149+
&& isVueElementIdentifier
150+
&& isCreateVnodeIdentifier
151+
&& isBaseClassIdentifier
152+
&& node.type === 'BlockStatement'
153+
&& parent
154+
&& parent.type === 'IfStatement') {
155+
isCeReloadIdentifier = false
156+
isCreateVnodeIdentifier = false
157+
mgcStr.prependRight(node.end! + 1, injectCreateVNode)
133158
}
134159
}

packages/sub-style/src/inject/inject-component.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@ import type { MagicStringBase } from 'magic-string-ast'
33

44
let isCreateComponentInstance = false
55
let VariableDeclarationInst = false
6-
const injectToCompContent = '\n isCEChild: parent && (parent.isCE || parent.isCEChild),\n'
7-
+ ' addCEChildStyle:\n'
8-
+ ' parent && parent.addCEChildStyle ? parent.addCEChildStyle : null,\n'
9-
+ ' removeCEChildStyle:\n'
10-
+ ' parent && parent.removeCEChildStyle ? parent.removeCEChildStyle : null,\n'
11-
+ ' cecStyleIds: null,'
6+
const injectToCompContent = '\n ceContext: parent && (parent.isCE || parent.ceContext) ? parent.ceContext : null,\n'
127
export function injectToComponent(
138
mgcStr: MagicStringBase,
149
node: Identifier | ObjectExpression,

packages/sub-style/src/inject/inject-render.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@ import type {
66
VariableDeclarator,
77
} from '@babel/types'
88

9-
const injectToUnMountContent = ''
10-
+ 'if (vnode.component.isCEChild && vnode.component.removeCEChildStyle) {\n'
11-
+ ' vnode.component.removeCEChildStyle(\n'
12-
+ ' vnode.component.type.styles,\n'
13-
+ ' vnode.component.uid\n'
14-
+ ' )\n'
15-
+ ' }'
9+
const injectToUnMountContent = 'if (vnode.component.ceContext && isHmrUpdating) {\n'
10+
+ ' vnode.component.ceContext.removeCEChildStyles(vnode.component.uid);\n'
11+
+ ' }\n'
1612

1713
const injectToBaseCreateRendererContent = 'if (instance && instance.parent) {\n'
1814
+ ' if (!(instance.parent.type.__asyncLoader && instance.parent.isCE)) {\n'
19-
+ ' const styles = instance.isCEChild && instance.type.styles || null;\n'
20-
+ ' if (instance.addCEChildStyle && styles) {\n'
21-
+ ' instance.addCEChildStyle(styles, instance);\n'
15+
+ ' const styles = instance.ceContext && instance.type.styles || null;\n'
16+
+ ' if (instance.ceContext && styles) {\n'
17+
+ ' instance.ceContext.addCEChildStyle(\n'
18+
+ ' styles,\n'
19+
+ ' instance.uid,\n'
20+
+ ' instance.hasStyleAttrs\n'
21+
+ ' );\n'
2222
+ ' }\n'
2323
+ ' }\n'
24-
+ ' }'
24+
+ ' }\n'
2525

2626
let isComponentUpdateFnIdentifier = false
2727
let isUnmountIdentifier = false

0 commit comments

Comments
 (0)