@tarojs/plugin-platform-harmony-ets 4.0.0-alpha.2 → 4.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/apis/base/system.ts +73 -20
  2. package/dist/apis/canvas/index.ts +10 -1
  3. package/dist/apis/device/clipboard.ts +16 -8
  4. package/dist/apis/framework/index.ts +1 -5
  5. package/dist/apis/index.ts +25 -17
  6. package/dist/apis/media/image/index.ts +1 -1
  7. package/dist/apis/storage/index.ts +146 -78
  8. package/dist/apis/ui/animation/animation.ts +71 -29
  9. package/dist/apis/ui/background.ts +2 -1
  10. package/dist/apis/ui/interaction/index.ts +42 -59
  11. package/dist/apis/ui/navigation-bar/index.ts +1 -1
  12. package/dist/apis/ui/pull-down-refresh.ts +9 -3
  13. package/dist/apis/ui/scroll/index.ts +5 -5
  14. package/dist/apis/ui/tab-bar.ts +3 -3
  15. package/dist/apis/utils/index.ts +2 -1
  16. package/dist/apis/wxml/IntersectionObserver.ts +18 -10
  17. package/dist/apis/wxml/selectorQuery.ts +26 -13
  18. package/dist/components-harmony-ets/button.ets +64 -34
  19. package/dist/components-harmony-ets/canvas.ets +51 -0
  20. package/dist/components-harmony-ets/checkbox.ets +72 -61
  21. package/dist/components-harmony-ets/form.ets +51 -29
  22. package/dist/components-harmony-ets/icon.ets +31 -19
  23. package/dist/components-harmony-ets/image.ets +34 -14
  24. package/dist/components-harmony-ets/index.ets +92 -0
  25. package/dist/components-harmony-ets/innerHtml.ets +11 -6
  26. package/dist/components-harmony-ets/input.ets +49 -41
  27. package/dist/components-harmony-ets/label.ets +71 -44
  28. package/dist/components-harmony-ets/listView.ets +26 -0
  29. package/dist/components-harmony-ets/movableArea.ets +126 -0
  30. package/dist/components-harmony-ets/movableView.ets +93 -0
  31. package/dist/components-harmony-ets/navigationBar.ets +65 -0
  32. package/dist/components-harmony-ets/pageMeta.ets +94 -0
  33. package/dist/components-harmony-ets/picker.ets +42 -38
  34. package/dist/components-harmony-ets/progress.ets +52 -0
  35. package/dist/components-harmony-ets/pseudo.ets +80 -0
  36. package/dist/components-harmony-ets/radio.ets +74 -64
  37. package/dist/components-harmony-ets/richText.ets +14 -30
  38. package/dist/components-harmony-ets/scrollList.ets +94 -0
  39. package/dist/components-harmony-ets/scrollView.ets +61 -57
  40. package/dist/components-harmony-ets/slider.ets +18 -14
  41. package/dist/components-harmony-ets/stickySection.ets +42 -0
  42. package/dist/components-harmony-ets/style.ets +381 -130
  43. package/dist/components-harmony-ets/swiper.ets +61 -20
  44. package/dist/components-harmony-ets/switch.ets +36 -32
  45. package/dist/components-harmony-ets/{index.ts → tag.ts} +6 -0
  46. package/dist/components-harmony-ets/text.ets +135 -49
  47. package/dist/components-harmony-ets/textArea.ets +50 -35
  48. package/dist/components-harmony-ets/utils/AttributeManager.ets +1 -1
  49. package/dist/components-harmony-ets/utils/DynamicCenter.ts +2 -2
  50. package/dist/components-harmony-ets/utils/flexManager.ets +49 -19
  51. package/dist/components-harmony-ets/utils/helper.ets +18 -5
  52. package/dist/components-harmony-ets/utils/htmlParser/HarmonyHTMLParser.ts +1 -2
  53. package/dist/components-harmony-ets/utils/htmlParser/index.ts +1 -1
  54. package/dist/components-harmony-ets/utils/index.ts +54 -50
  55. package/dist/components-harmony-ets/utils/styles.ets +170 -93
  56. package/dist/components-harmony-ets/video.ets +34 -21
  57. package/dist/components-harmony-ets/view.ets +63 -52
  58. package/dist/components-harmony-ets/webView.ets +40 -34
  59. package/dist/index.d.ts +152 -0
  60. package/dist/index.js +99 -55
  61. package/dist/index.js.map +1 -1
  62. package/dist/runtime-ets/bom/document.ts +6 -4
  63. package/dist/runtime-ets/bom/getComputedStyle.ts +2 -2
  64. package/dist/runtime-ets/bom/window.ts +7 -0
  65. package/dist/runtime-ets/current.ts +3 -0
  66. package/dist/runtime-ets/dom/bind.ts +28 -12
  67. package/dist/runtime-ets/dom/class-list.ts +2 -2
  68. package/dist/runtime-ets/dom/cssNesting.ts +419 -0
  69. package/dist/runtime-ets/dom/cssStyleDeclaration.ts +28 -42
  70. package/dist/runtime-ets/dom/document.ts +8 -11
  71. package/dist/runtime-ets/dom/element/canvas.ts +136 -0
  72. package/dist/runtime-ets/dom/element/element.ts +348 -57
  73. package/dist/runtime-ets/dom/element/form.ts +31 -26
  74. package/dist/runtime-ets/dom/element/index.ts +30 -2
  75. package/dist/runtime-ets/dom/element/movableArea.ts +11 -0
  76. package/dist/runtime-ets/dom/element/movableView.ts +244 -0
  77. package/dist/runtime-ets/dom/element/normal.ts +35 -8
  78. package/dist/runtime-ets/dom/element/progress.ts +11 -0
  79. package/dist/runtime-ets/dom/element/scrollView.ts +1 -0
  80. package/dist/runtime-ets/dom/element/text.ts +1 -8
  81. package/dist/runtime-ets/dom/element/video.ts +5 -4
  82. package/dist/runtime-ets/dom/element/webView.ts +12 -5
  83. package/dist/runtime-ets/dom/event.ts +2 -4
  84. package/dist/runtime-ets/dom/eventTarget.ts +2 -3
  85. package/dist/runtime-ets/dom/node.ts +54 -29
  86. package/dist/runtime-ets/dom/stylesheet/covertWeb2Hm.ts +416 -235
  87. package/dist/runtime-ets/dom/stylesheet/index.ts +29 -311
  88. package/dist/runtime-ets/dom/stylesheet/type.ts +51 -9
  89. package/dist/runtime-ets/dom/stylesheet/util.ts +33 -27
  90. package/dist/runtime-ets/index.ts +2 -1
  91. package/dist/runtime-ets/interface/event.ts +1 -1
  92. package/dist/runtime-ets/utils/index.ts +73 -13
  93. package/dist/runtime-ets/utils/info.ts +2 -2
  94. package/dist/runtime-framework/react/app.ts +9 -4
  95. package/dist/runtime-framework/react/hooks.ts +0 -1
  96. package/dist/runtime-framework/react/index.ts +0 -2
  97. package/dist/runtime-framework/react/native-page.ts +154 -77
  98. package/dist/runtime-framework/react/page.ts +3 -8
  99. package/dist/runtime-framework/solid/app.ts +25 -45
  100. package/dist/runtime-framework/solid/connect.ts +21 -3
  101. package/dist/runtime-framework/solid/hooks.ts +16 -11
  102. package/dist/runtime-framework/solid/index.ts +6 -2
  103. package/dist/runtime-framework/solid/page.ts +84 -30
  104. package/dist/runtime-framework/solid/reconciler/props.ts +70 -25
  105. package/dist/runtime-framework/solid/reconciler/render.ts +16 -6
  106. package/dist/runtime-framework/solid/reconciler/use.ts +0 -1
  107. package/dist/runtime-framework/solid/utils/index.ts +0 -2
  108. package/dist/runtime-utils.d.ts +827 -0
  109. package/dist/runtime-utils.js +435 -218
  110. package/dist/runtime-utils.js.map +1 -1
  111. package/dist/runtime.d.ts +1 -0
  112. package/dist/runtime.js +435 -218
  113. package/dist/runtime.js.map +1 -1
  114. package/index.js +3 -1
  115. package/package.json +14 -15
  116. package/static/media/cancel.svg +1 -1
  117. package/static/media/circle.svg +1 -1
  118. package/static/media/clear.svg +1 -1
  119. package/static/media/download.svg +1 -1
  120. package/static/media/info.svg +1 -1
  121. package/static/media/info_circle.svg +1 -1
  122. package/static/media/search.svg +1 -1
  123. package/static/media/success.svg +1 -1
  124. package/static/media/success_no_circle.svg +1 -1
  125. package/static/media/warn.svg +1 -1
  126. package/types/harmony.d.ts +4 -0
  127. package/types/index.d.ts +4 -0
  128. package/types/runtime.d.ts +1 -1
  129. /package/dist/runtime-framework/solid/{contant.ts → constant.ts} +0 -0
@@ -0,0 +1,419 @@
1
+ import { parseClasses } from '../utils'
2
+
3
+ import type { CSSProperties, ReactElement } from 'react'
4
+ // 抽出来的嵌套查询
5
+ // const __nesting_style__ = [
6
+ // {
7
+ // selectors: ['container', '>', 'hello', ' ', 'txt'],
8
+ // declaration: {
9
+ // _color: "#00F00F",
10
+ // _fontSize: convertNumber2VP(40),
11
+ // }
12
+ // },
13
+ // ]
14
+ //
15
+ // function Index() {
16
+ // return __combine_nesting_style__(jsx(TaroViewTagName, {
17
+ // className: "container aaa",
18
+ // style: calcDynamicStyle(__inner_style__(), "container", null),
19
+ // children: [
20
+ // jsx(TaroTextTagName, {
21
+ // className: "txt cc",
22
+ // style: calcDynamicStyle(__inner_style__(), "txt", null),
23
+ // children: "Hello!"
24
+ // }),
25
+ // jsx(TaroViewTagName, {
26
+ // className: "hello",
27
+ // style: calcDynamicStyle(__inner_style__(), "hello", null),
28
+ // children: [
29
+ // jsx(TaroTextTagName, {
30
+ // className: "txt",
31
+ // style: calcDynamicStyle(__inner_style__(), "txt", null),
32
+ // children: "wo2rld!"
33
+ // }),
34
+ // jsx(TaroTextTagName, {
35
+ // className: "txt2",
36
+ // style: calcDynamicStyle(__inner_style__(), "txt2", null),
37
+ // children: "Hello wo2rld!"
38
+ // })
39
+ // ]
40
+ // })
41
+ // ]
42
+ // }), __nesting_style__);
43
+ // }
44
+
45
+ type TMappingNode = {
46
+ node: ReactElement
47
+ children: TMapping
48
+ descendants: TMapping
49
+ }
50
+
51
+ type TMapping = Record<string, TMappingNode>
52
+
53
+ type TSelectorNode = {
54
+ mapping: TMapping
55
+ node: ReactElement
56
+ }
57
+
58
+ export type NestingStyle = {
59
+ node: ReactElement
60
+ selectors: string[]
61
+ declaration: Record<string, any>
62
+ }[]
63
+
64
+ // 构建映射表
65
+ function depthTraversal(root: ReactElement) {
66
+ const class_mapping: TMapping = {}
67
+ // 记录别名,防止冲突
68
+ const selector_alias: Record<string, string[]> = {}
69
+ // 统计重名次数:{ txt: 1, cc: 2 }
70
+ const selector_alias_count: Record<string, number> = {}
71
+
72
+ const traverse = (tree) => {
73
+ const result: Record<string, TMapping> = {}
74
+ if (tree && tree.props) {
75
+ // 兜底适配:如果Taro组件被原封不动的再别的地方导出使用,导致无法在编译环境添加__hmStyle
76
+ // import { View } from '../../../~/components'
77
+ // hack:如果是taro节点,但是被赋予了__styleSheet,则走一下__styleSheet转__hmStyle
78
+ if (tree.props.__styleSheet && typeof tree.type !== 'function') {
79
+ tree.props.__hmStyle = Object.assign({}, tree.props.__hmStyle, tree.props.__styleSheet.value)
80
+ }
81
+
82
+ // 后代选择器
83
+ const descendant_map = {
84
+ node: tree,
85
+ children: {},
86
+ descendants: {}
87
+ }
88
+
89
+ if (tree.props.children) {
90
+ // 遍历叶子节点
91
+ if (tree.props.children instanceof Array) {
92
+ for (let i = 0; i < tree.props.children.length; i++) {
93
+ // 收集叶子节点所拥有的类名
94
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
95
+ processLeaf(tree.props.children[i], descendant_map)
96
+ }
97
+ } else if (typeof tree.props.children !== 'string') {
98
+ // 收集叶子节点所拥有的类名
99
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
100
+ processLeaf(tree.props.children, descendant_map)
101
+ }
102
+ }
103
+ // 拆分classnames
104
+ const classnames = parseClasses(tree.props.className || '')
105
+ for (let i = 0; i < classnames.length; i++) {
106
+ const cls = classnames[i]
107
+ let name = cls
108
+ if (selector_alias_count[name]) {
109
+ // 存在重名,需要使用别名替代
110
+ const oldName = name
111
+ name = `___${name}${selector_alias_count[oldName]}`
112
+ selector_alias_count[oldName] = selector_alias_count[oldName] + 1
113
+ selector_alias[oldName] ? selector_alias[oldName].push(name) : (selector_alias[oldName] = [name])
114
+ }
115
+ selector_alias_count[name] = 1
116
+
117
+ class_mapping[name] = descendant_map
118
+ result[name] = {
119
+ ref: descendant_map,
120
+ node: tree
121
+ }
122
+ }
123
+ }
124
+ return result
125
+ }
126
+
127
+ const processLeaf = (leaf, descendant_map: TMappingNode) => {
128
+ if (!leaf) return
129
+
130
+ const queue = [leaf]
131
+
132
+ while (queue.length > 0) {
133
+ const current = queue.shift()
134
+
135
+ if (current instanceof Array) {
136
+ for (let i = 0; i < current.length; i++) {
137
+ queue.push(current[i])
138
+ }
139
+ continue
140
+ }
141
+
142
+ const leaf_map = traverse(current)
143
+ if (!leaf_map) continue
144
+
145
+ // 直接后代
146
+ Object.assign(descendant_map.children, leaf_map)
147
+
148
+ // 子孙后代
149
+ const grandchild: (Record<string, TMapping> | TMapping)[] = [leaf_map]
150
+ Object.keys(leaf_map).forEach(key => {
151
+ const leaf_child_map = class_mapping[key]
152
+ if (leaf_child_map?.descendants) {
153
+ grandchild.push(leaf_child_map.descendants)
154
+ }
155
+ })
156
+ Object.assign(descendant_map.descendants, ...grandchild)
157
+ }
158
+ }
159
+
160
+ traverse(root)
161
+ return {
162
+ mapping: class_mapping,
163
+ alias: selector_alias
164
+ }
165
+ }
166
+
167
+ // 将嵌套样式与节点合并
168
+ function combineStyle(nestingStyle: NestingStyle, class_mapping: TMapping, alias: Record<string, string[]>) {
169
+ const findElement = (selector_string, combinator_type, selector_mapping, remainder_selector, declaration) => {
170
+ // 防止修改原数组
171
+ if (selector_string instanceof Array) {
172
+ selector_string = selector_string.slice()
173
+ }
174
+ let selector_list = [selector_string]
175
+ const selector_nodes: TSelectorNode[] = []
176
+ let shouldUseCombinations = false
177
+ // 判断是否存在别名
178
+ if (selector_string instanceof Array) {
179
+ // 多类选择器类名,需要进行排列组合选择了,一对多的查找 ['a', 'b'],需要找出所有a和b都指向同一个node的节点
180
+ selector_string.forEach((item, i) => {
181
+ if (alias[item]) {
182
+ selector_string[i] = [item, ...alias[item]]
183
+ }
184
+ })
185
+ shouldUseCombinations = true
186
+ } else if (alias[selector_string]) {
187
+ selector_list = selector_list.concat(alias[selector_string])
188
+ }
189
+
190
+ for (let i = 0; i < selector_list.length; i++) {
191
+ const selector = selector_list[i]
192
+ if (selector instanceof Array) {
193
+ let hitElements: any
194
+ // 如果是数组,说明他是一个多类选择器:.a.b,我们需要搜索这两个类名都指向同一个node
195
+ if (shouldUseCombinations) {
196
+ hitElements = generateCombinations(selector, (combination) => {
197
+ // combination 是组合后的选择器['parent', 'child']
198
+ const _obj = findSendNode(combination, selector_mapping)
199
+ if (_obj) return _obj
200
+ })
201
+ } else {
202
+ hitElements = findSendNode(selector, selector_mapping)
203
+ }
204
+ // 找出最后搜寻出来的node
205
+ if (hitElements) {
206
+ let objs = [hitElements]
207
+ objs = flattenArray(objs)
208
+ objs.forEach(obj => {
209
+ if (typeof obj.node.type === 'function') {
210
+ // 自定义组件,往下传递需要搜寻的内容向里面搜寻
211
+ const nestingData = {
212
+ selectors: [selector_string, combinator_type, ...remainder_selector.slice()],
213
+ declaration: declaration
214
+ }
215
+ obj.node.props.__nesting = obj.node.props.__nesting
216
+ ? [...obj.node.props.__nesting, nestingData] : [nestingData]
217
+ }
218
+ selector_nodes.push({
219
+ // @ts-ignore
220
+ mapping: (obj.ref || obj)[combinator_type === ' > ' ? 'children' : 'descendants'],
221
+ node: obj.node
222
+ })
223
+ })
224
+ }
225
+ } else {
226
+ // 查询选择器的节点
227
+ const object = selector_mapping[selector]
228
+ if (object) {
229
+ if (typeof object.node.type === 'function') {
230
+ // 自定义组件,往下传递需要搜寻的内容向里面搜寻
231
+ const nestingData = {
232
+ selectors: [selector_string, combinator_type, ...remainder_selector.slice()],
233
+ declaration: declaration
234
+ }
235
+ object.node.props.__nesting = object.node.props.__nesting
236
+ ? [...object.node.props.__nesting, nestingData] : [nestingData]
237
+ }
238
+ selector_nodes.push({
239
+ mapping: (object.ref || object)[combinator_type === ' > ' ? 'children' : 'descendants'],
240
+ node: object.node
241
+ })
242
+ }
243
+ }
244
+ }
245
+ return selector_nodes
246
+ }
247
+ const findSelector = (selectors: string[], current_mapping: any, declaration: any): TSelectorNode[] => {
248
+ const workQueue: { selectors: string[], current_mapping: any }[] = [{ selectors, current_mapping }]
249
+ let resultElements: TSelectorNode[] = []
250
+ while (workQueue.length > 0) {
251
+ const { selectors: currentSelectors, current_mapping: currentMapping } = workQueue.shift()!
252
+ const new_selectors = currentSelectors.slice()
253
+ const selector_string = new_selectors.shift()
254
+ const combinator_type = new_selectors.shift()
255
+
256
+ const _elements = findElement(selector_string, combinator_type, currentMapping, new_selectors, declaration)
257
+
258
+ if (_elements.length) {
259
+ if (new_selectors.length) {
260
+ _elements.forEach(element => {
261
+ workQueue.push({ selectors: new_selectors.slice(), current_mapping: element.mapping })
262
+ })
263
+ } else {
264
+ resultElements = resultElements.concat(_elements)
265
+ }
266
+ }
267
+ }
268
+
269
+ return resultElements
270
+ }
271
+ if (nestingStyle && nestingStyle instanceof Array) {
272
+ // 合并样式
273
+ nestingStyle.forEach(({ selectors, declaration }) => {
274
+ // 获取选中的节点列表
275
+ const selectors_elements = findSelector(selectors, class_mapping, declaration)
276
+ for (let i = 0; i < selectors_elements.length; i++) {
277
+ const ele = selectors_elements[i].node
278
+ if (ele && typeof ele !== 'function') {
279
+ // 直接注入到__hmStyle
280
+ // Hack: ReactElement会在dev模式下被冻结,所以在dev模式下,我们会将Object.freeze覆盖使其失效
281
+ if (ele.props.__hmStyle) {
282
+ ele.props.__hmStyle = Object.assign({}, ele.props.__hmStyle, declaration)
283
+ } else {
284
+ ele.props.__hmStyle = declaration
285
+ }
286
+ }
287
+ }
288
+ })
289
+ }
290
+ }
291
+
292
+ // 排列组合选择器,找出符合的组合
293
+ // let arrayA = [1, 2, 3];
294
+ // let arrayB = [4, 5, 6];
295
+ // let arrayC = 'abc'
296
+ // let result = generateCombinations([arrayA, arrayB, arrayC], (combination) => { if (combination[0] == 3 ) { return combination }})
297
+ // console.log(result) => [3, 4, "abc"]
298
+ function generateCombinations (arrays: (string[] | string)[], cbFn, currentCombination: (string[] | string)[] = []) {
299
+ if (arrays.length === 0) {
300
+ // 当所有数组都被处理完时,将当前组合添加到结果中
301
+ return cbFn(currentCombination.slice())
302
+ }
303
+ // 取出当前数组
304
+ const currentArray = arrays[0]
305
+ if (currentArray instanceof Array) {
306
+ // 遍历当前数组的每个元素
307
+ const eles: TMappingNode[] = []
308
+ for (let i = 0; i < currentArray.length; i++) {
309
+ // 将当前元素添加到当前组合中
310
+ currentCombination.push(currentArray[i])
311
+ // 递归处理剩余的数组
312
+ const shouldStop = generateCombinations(arrays.slice(1), cbFn, currentCombination)
313
+ if (shouldStop) {
314
+ eles.push(shouldStop)
315
+ }
316
+ // 回溯,移除最后一个元素,尝试其他组合
317
+ currentCombination.pop()
318
+ }
319
+ return eles
320
+ } else {
321
+ // 如果不是数组,直接将当前元素添加到当前组合中
322
+ currentCombination.push(currentArray)
323
+ // 递归处理剩余的数组
324
+ const shouldStop = generateCombinations(arrays.slice(1), cbFn, currentCombination)
325
+ if (shouldStop) {
326
+ return shouldStop
327
+ }
328
+ // 回溯,移除最后一个元素,尝试其他组合
329
+ currentCombination.pop()
330
+ }
331
+ return false
332
+ }
333
+
334
+ // 多类选择器辅助函数:.a.b => 这里的.a .b其实都是指向同一个node
335
+ // 匹配寻找所有选择器都指向同一个node
336
+ function findSendNode (selectorArr: string[], selector_mapping: TMapping) {
337
+ let obj: any = null
338
+ for (let i = 0; i < selectorArr.length; i++) {
339
+ // 查询选择器的节点
340
+ const object = selector_mapping[selectorArr[i]]
341
+ if (object) {
342
+ if (!obj) { obj = object }
343
+ if (object.node === obj.node) continue
344
+ }
345
+ obj = null
346
+ break
347
+ }
348
+ return obj
349
+ }
350
+
351
+ function insertParentStyle(data: {key: string, value: CSSProperties}, class_mapping: TMapping, alias: Record<string, string[]>) {
352
+ const { key, value } = data
353
+ key.split(' ').forEach(key => {
354
+ let classnames = [key]
355
+ if (alias[key]) {
356
+ classnames = classnames.concat(alias[key])
357
+ }
358
+ classnames.forEach(name => {
359
+ if (class_mapping[name]) {
360
+ // 插入样式
361
+ const ele = class_mapping[key].node
362
+ if (ele) {
363
+ // 直接注入到__hmStyle
364
+ // Hack: ReactElement会在dev模式下被冻结,所以在dev模式下,我们会将Object.freeze覆盖使其失效
365
+ if (ele.props.__hmStyle) {
366
+ ele.props.__hmStyle = Object.assign({}, ele.props.__hmStyle, value)
367
+ } else {
368
+ ele.props.__hmStyle = value
369
+ }
370
+ }
371
+ }
372
+ })
373
+ })
374
+ }
375
+
376
+ // 合并嵌套样式
377
+ // 1、构建映射表,生成一份扁平的样式表结构
378
+ // 2、遍历嵌套样式,根据选择器查找节点,合并样式
379
+ export function __combine_nesting_style__(react_tree: ReactElement, styles: NestingStyle | null = null) {
380
+ if (react_tree) {
381
+ let newStyle = styles
382
+ const parentProps: {
383
+ __styleSheet?: {key: string, value: CSSProperties}
384
+ __nesting?: NestingStyle
385
+ } = // @ts-ignore
386
+ react_tree._owner?.pendingProps // Hack:取出父组件的props,考虑版本问题,取的内部属性,可能会有问题
387
+
388
+ if (newStyle || (parentProps && (parentProps.__styleSheet || parentProps.__nesting))) {
389
+ // 1、循环一遍,构建出一颗JSX映射表
390
+ const { mapping, alias } = depthTraversal(react_tree)
391
+ if (parentProps) {
392
+ // 2、如果自定义节点,则增加合成__stylesheet步骤,将父节点的样式合并到当前节点
393
+ if (parentProps.__styleSheet) {
394
+ insertParentStyle(parentProps.__styleSheet, mapping, alias)
395
+ // @ts-ignore
396
+ parentProps.__styleSheet = null // 释放内存
397
+ }
398
+ // 3、如果自定节点,存在需要往下查询的嵌套样式,需要合并到子组件
399
+ if (parentProps.__nesting) {
400
+ newStyle = (newStyle || []).concat(parentProps.__nesting)
401
+ // @ts-ignore
402
+ parentProps.__nesting = null // 释放内存
403
+ }
404
+ }
405
+ // 4、合并嵌套样式样式
406
+ if (newStyle && newStyle.length) {
407
+ combineStyle(newStyle, mapping, alias)
408
+ }
409
+ }
410
+ }
411
+ return react_tree
412
+ }
413
+
414
+ // 拍平数组
415
+ function flattenArray(arr) {
416
+ return arr.reduce((acc, val) => {
417
+ return acc.concat(Array.isArray(val) ? flattenArray(val) : val)
418
+ }, [])
419
+ }
@@ -1,7 +1,7 @@
1
- import { isObject, toCamelCase, toDashed } from '@tarojs/shared'
1
+ import { isObject, isUndefined, toCamelCase, toDashed } from '@tarojs/shared'
2
2
 
3
3
  import { TaroElement } from './element/element'
4
- import convertWebStyle2HmStyle, { WEB_STYLE_MAP } from './stylesheet/covertWeb2Hm'
4
+ import convertWebStyle2HmStyle from './stylesheet/covertWeb2Hm'
5
5
 
6
6
  class CSSStyleDeclaration {
7
7
  // eslint-disable-next-line no-useless-constructor
@@ -23,9 +23,11 @@ class CSSStyleDeclaration {
23
23
  }
24
24
 
25
25
  public set cssText (value: string) {
26
+ // 复制,防止被篡改到attr上的原始内容
27
+ this._st.hmStyle = Object.assign({}, this.el._attrs?.__hmStyle) || {}
26
28
  if (value === '' || value === undefined || value === null) {
27
- // TODO: 清空 stylesheet 里面的 hmstyle
28
- // this.el._st = {}
29
+ // 清空style,只保留class的样式
30
+ return
29
31
  }
30
32
 
31
33
  const rules = value.split(';')
@@ -40,7 +42,7 @@ class CSSStyleDeclaration {
40
42
  const [propName, ...valList] = rule.split(':')
41
43
  const val = valList.join(':')
42
44
 
43
- if (typeof val === undefined) {
45
+ if (typeof val === 'undefined') {
44
46
  continue
45
47
  }
46
48
  this.setProperty(propName.trim(), val.trim())
@@ -48,65 +50,49 @@ class CSSStyleDeclaration {
48
50
  }
49
51
 
50
52
  public setProperty (prop: string, value: any): void {
51
- const node = this.el
52
-
53
53
  prop = prop.includes('-') ? toCamelCase(prop) : prop
54
-
55
- const webStyleList = WEB_STYLE_MAP[prop]
56
- const needUpdateProperty = !prop.startsWith('_') && webStyleList && webStyleList.length > 0
57
-
54
+ const node = this.el
58
55
  if ((typeof value === 'string' && value.length) || typeof value === 'number' || isObject(value)) {
59
- if (needUpdateProperty) {
60
- const newProperty = convertWebStyle2HmStyle({ [prop]: value })
61
-
62
- Object.keys(newProperty).forEach(key => {
63
- node._st[key] = newProperty[key]
64
- })
65
- } else {
66
- node._st[prop] = value
67
- }
56
+ convertWebStyle2HmStyle({ [prop]: value }, node)
68
57
  } else if (!value) {
69
- // '' | undefined | null
70
- if (needUpdateProperty) {
71
- webStyleList.forEach(key => {
72
- this.removeProperty(key)
73
- })
74
- } else {
58
+ if (value === '') {
59
+ // value设置为null或者''了
75
60
  this.removeProperty(prop)
61
+ return
76
62
  }
63
+ // 判断class的样式表中是否存在该属性
64
+ // 如果存在,则style删除,无需把hmStyle的值删除
65
+ // 如果不存在,则hmStyle上该样式是style设置的,需要删除
66
+ if (isUndefined(this.el._attrs?.__hmStyle?.[prop])) {
67
+ if (this.el && this.el._st) {
68
+ this.el._st.hmStyle[prop] = this.el._attrs?.__hmStyle?.[prop]
69
+ }
70
+ return
71
+ }
72
+ this.removeProperty(prop)
77
73
  }
78
74
  }
79
75
 
80
76
  public getPropertyValue (prop: string): string | number {
81
- const node = this.el
82
77
  prop = prop.includes('-') ? toCamelCase(prop) : prop
78
+ const node = this.el
83
79
  const value = node._st[prop]
84
80
  return value === undefined ? '' : value
85
81
  }
86
82
 
87
83
  public removeProperty (prop: string): string | number {
88
- const node = this.el
89
84
  prop = prop.includes('-') ? toCamelCase(prop) : prop
90
- const value = node._st[prop]
91
- if (prop.startsWith('_')) {
92
- prop = prop.replace('_', '')
93
- }
94
- if (value === undefined) {
95
- // node._st[prop] = undefined
96
- delete node._st.hmStyle[prop]
97
- return ''
98
- } else {
99
- delete node._st.hmStyle[prop]
100
- // node._st[prop] = undefined
101
- // node._st = { ...node._st }
102
- return value
103
- }
85
+ const node = this.el
86
+ const value = node._st.hmStyle[prop]
87
+ delete node._st.hmStyle[prop]
88
+ return value
104
89
  }
105
90
  }
106
91
 
107
92
  type ICSSStyleDeclaration = CSSStyleDeclaration & Record<string, any>
108
93
 
109
94
  function createCSSStyleDeclaration (node: TaroElement): CSSStyleDeclaration {
95
+ // FIXME 临时使用 Proxy 代理,后续需要优化
110
96
  return new Proxy(new CSSStyleDeclaration(node), {
111
97
  set (target, prop: string, value) {
112
98
  if (prop === 'cssText') {
@@ -4,7 +4,6 @@ import { isUndefined } from '@tarojs/shared'
4
4
  import { Current } from '../current'
5
5
  import { findChildNodeWithDFS, getPageScrollerOrNode } from '../utils'
6
6
  import { TaroComment } from './comment'
7
- import { createCSSStyleDeclaration } from './cssStyleDeclaration'
8
7
  import { TaroElement } from './element/element'
9
8
  import { NodeType, TaroNode, TaroTextNode } from './node'
10
9
 
@@ -36,6 +35,7 @@ class TaroDocument extends TaroNode {
36
35
  case 'div': tagName = 'view'; break
37
36
  case 'p': tagName = 'text'; break
38
37
  case 'span': tagName = 'text'; break
38
+ case 'a': tagName = 'text'; break
39
39
  }
40
40
  // @ts-ignore
41
41
  if (Current?.createHarmonyElement) {
@@ -45,8 +45,6 @@ class TaroDocument extends TaroNode {
45
45
  node = new TaroElement(tagName)
46
46
  }
47
47
  node._doc = this
48
- // Hack: 此 Proxy 不能放在 Element 类内定义,否则响应式更新会失效
49
- node._style = createCSSStyleDeclaration(node)
50
48
  return node
51
49
  }
52
50
 
@@ -63,7 +61,6 @@ class TaroDocument extends TaroNode {
63
61
  return new TaroComment(data)
64
62
  }
65
63
 
66
-
67
64
  public getElementById<T extends TaroElement> (id: string | undefined | null): T | null {
68
65
  const el = eventSource.get(id)
69
66
  return isUndefined(el) ? null : el as unknown as T
@@ -72,20 +69,20 @@ class TaroDocument extends TaroNode {
72
69
  public querySelector (selectors: string): TaroElement | null {
73
70
  const taro = (Current as any).taro
74
71
  const page = taro.getCurrentInstance().page
75
- const element = getPageScrollerOrNode(page.node, page)
76
-
77
- if (element == null) return null
78
-
72
+ const element = getPageScrollerOrNode(page?.node, page)
73
+
74
+ if (!element) return null
75
+
79
76
  return findChildNodeWithDFS(element, selectors)
80
77
  }
81
78
 
82
79
  public querySelectorAll (selectors: string): TaroElement[] {
83
80
  const taro = (Current as any).taro
84
81
  const page = taro.getCurrentInstance().page
85
- const element = getPageScrollerOrNode(page.node, page)
86
-
82
+ const element = getPageScrollerOrNode(page?.node, page)
83
+
87
84
  if (element == null) return []
88
-
85
+
89
86
  return findChildNodeWithDFS(element, selectors, true) || []
90
87
  }
91
88
  // @Todo