1
1
import type { MagicStringBase } from 'magic-string-ast'
2
2
import type {
3
+ BlockStatement ,
3
4
CallExpression ,
4
5
ClassDeclaration ,
5
6
ClassMethod ,
6
7
Identifier ,
8
+ IfStatement ,
7
9
MemberExpression ,
8
10
VariableDeclarator ,
9
11
} from '@babel/types'
10
12
11
- const _childStylesAnchor = '\n this._childStylesAnchor = null;'
13
+ const _childStylesAnchor = '\n this._childStylesAnchor = null;\n this._childStylesSet = new Set(); '
12
14
13
15
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'
16
20
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'
18
24
+ ' 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'
35
28
+ ' styles.forEach((css, index) => {\n'
36
29
+ ' const s = document.createElement("style");\n'
37
30
+ ' 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'
39
33
+ ' 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'
44
35
+ ' } else {\n'
45
36
+ ' this.shadowRoot.appendChild(s);\n'
46
37
+ ' }\n'
@@ -51,38 +42,43 @@ const injectAddAndRemoveStyle = '_addChildStyles(styles, instance) {\n'
51
42
+ ' });\n'
52
43
+ ' }\n'
53
44
+ ' }\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'
55
60
+ ' if (styles) {\n'
56
61
+ ' 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'
73
64
+ ' }\n'
65
+ + ' this._childStylesSet.add(styleContent);\n'
66
+ + ' return false;\n'
74
67
+ ' }\n'
75
68
+ ' }'
76
69
77
70
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'
79
72
let isVueElementIdentifier = false
80
73
let isBaseClassIdentifier = false
81
74
let isApplyStylesIdentifier = false
75
+ let isCeReloadIdentifier = false
76
+ let isCreateVnodeIdentifier = false
77
+ const injectCreateVNode = '\nthis._childStylesSet.clear();\n'
82
78
export function injectApiCustomElement (
83
79
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 ,
86
82
) {
87
83
if ( node . type === 'Identifier'
88
84
&& node . name === 'VueElement'
@@ -128,7 +124,36 @@ export function injectApiCustomElement(
128
124
isApplyStylesIdentifier = false
129
125
isVueElementIdentifier = false
130
126
isBaseClassIdentifier = false
127
+ mgcStr . prependLeft ( node . start ! - 1 , injectApplyStylesCERoot )
131
128
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 )
133
158
}
134
159
}
0 commit comments