@tarojs/plugin-platform-harmony-ets 4.0.0-canary.8 → 4.0.0

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 (135) 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 +23 -8
  4. package/dist/apis/framework/index.ts +1 -5
  5. package/dist/apis/index.ts +27 -17
  6. package/dist/apis/media/image/index.ts +169 -17
  7. package/dist/apis/network/request.ts +5 -5
  8. package/dist/apis/route/index.ts +15 -0
  9. package/dist/apis/storage/index.ts +146 -78
  10. package/dist/apis/ui/animation/animation.ts +71 -29
  11. package/dist/apis/ui/background.ts +2 -1
  12. package/dist/apis/ui/interaction/index.ts +58 -59
  13. package/dist/apis/ui/navigation-bar/index.ts +1 -1
  14. package/dist/apis/ui/pull-down-refresh.ts +9 -3
  15. package/dist/apis/ui/scroll/index.ts +5 -5
  16. package/dist/apis/ui/tab-bar.ts +3 -3
  17. package/dist/apis/utils/index.ts +21 -2
  18. package/dist/apis/utils/permissions.ts +6 -0
  19. package/dist/apis/wxml/IntersectionObserver.ts +18 -10
  20. package/dist/apis/wxml/index.ts +2 -0
  21. package/dist/apis/wxml/selectorQuery.ts +26 -13
  22. package/dist/components-harmony-ets/button.ets +63 -77
  23. package/dist/components-harmony-ets/canvas.ets +51 -0
  24. package/dist/components-harmony-ets/checkbox.ets +75 -258
  25. package/dist/components-harmony-ets/form.ets +51 -158
  26. package/dist/components-harmony-ets/icon.ets +33 -83
  27. package/dist/components-harmony-ets/image.ets +35 -79
  28. package/dist/components-harmony-ets/index.ets +92 -0
  29. package/dist/components-harmony-ets/innerHtml.ets +11 -6
  30. package/dist/components-harmony-ets/input.ets +64 -101
  31. package/dist/components-harmony-ets/label.ets +72 -174
  32. package/dist/components-harmony-ets/listView.ets +31 -0
  33. package/dist/components-harmony-ets/movableArea.ets +126 -0
  34. package/dist/components-harmony-ets/movableView.ets +93 -0
  35. package/dist/components-harmony-ets/navigationBar.ets +65 -0
  36. package/dist/components-harmony-ets/pageMeta.ets +94 -0
  37. package/dist/components-harmony-ets/picker.ets +46 -163
  38. package/dist/components-harmony-ets/progress.ets +52 -0
  39. package/dist/components-harmony-ets/pseudo.ets +80 -0
  40. package/dist/components-harmony-ets/radio.ets +80 -264
  41. package/dist/components-harmony-ets/richText.ets +20 -102
  42. package/dist/components-harmony-ets/scrollList.ets +108 -0
  43. package/dist/components-harmony-ets/scrollView.ets +71 -160
  44. package/dist/components-harmony-ets/slider.ets +22 -82
  45. package/dist/components-harmony-ets/stickySection.ets +42 -0
  46. package/dist/components-harmony-ets/style.ets +410 -0
  47. package/dist/components-harmony-ets/swiper.ets +64 -87
  48. package/dist/components-harmony-ets/switch.ets +39 -99
  49. package/dist/components-harmony-ets/{index.ts → tag.ts} +6 -0
  50. package/dist/components-harmony-ets/text.ets +111 -113
  51. package/dist/components-harmony-ets/textArea.ets +51 -95
  52. package/dist/components-harmony-ets/utils/AttributeManager.ets +2 -2
  53. package/dist/components-harmony-ets/utils/DynamicCenter.ts +2 -2
  54. package/dist/components-harmony-ets/utils/flexManager.ets +50 -19
  55. package/dist/components-harmony-ets/utils/helper.ets +20 -8
  56. package/dist/components-harmony-ets/utils/htmlParser/HarmonyHTMLParser.ts +1 -2
  57. package/dist/components-harmony-ets/utils/htmlParser/index.ts +1 -1
  58. package/dist/components-harmony-ets/utils/index.ts +54 -50
  59. package/dist/components-harmony-ets/utils/styles.ets +172 -92
  60. package/dist/components-harmony-ets/video.ets +37 -88
  61. package/dist/components-harmony-ets/view.ets +63 -159
  62. package/dist/components-harmony-ets/webView.ets +41 -98
  63. package/dist/index.d.ts +152 -0
  64. package/dist/index.js +187 -56
  65. package/dist/index.js.map +1 -1
  66. package/dist/runtime-ets/bom/document.ts +6 -4
  67. package/dist/runtime-ets/bom/getComputedStyle.ts +2 -2
  68. package/dist/runtime-ets/bom/window.ts +9 -2
  69. package/dist/runtime-ets/current.ts +5 -1
  70. package/dist/runtime-ets/dom/bind.ts +28 -12
  71. package/dist/runtime-ets/dom/class-list.ts +2 -2
  72. package/dist/runtime-ets/dom/cssNesting.ts +419 -0
  73. package/dist/runtime-ets/dom/cssStyleDeclaration.ts +28 -42
  74. package/dist/runtime-ets/dom/document.ts +22 -8
  75. package/dist/runtime-ets/dom/element/canvas.ts +136 -0
  76. package/dist/runtime-ets/dom/element/element.ts +376 -57
  77. package/dist/runtime-ets/dom/element/form.ts +31 -26
  78. package/dist/runtime-ets/dom/element/index.ts +30 -2
  79. package/dist/runtime-ets/dom/element/movableArea.ts +11 -0
  80. package/dist/runtime-ets/dom/element/movableView.ts +248 -0
  81. package/dist/runtime-ets/dom/element/normal.ts +35 -8
  82. package/dist/runtime-ets/dom/element/progress.ts +11 -0
  83. package/dist/runtime-ets/dom/element/scrollView.ts +1 -0
  84. package/dist/runtime-ets/dom/element/text.ts +1 -8
  85. package/dist/runtime-ets/dom/element/video.ts +5 -4
  86. package/dist/runtime-ets/dom/element/webView.ts +12 -5
  87. package/dist/runtime-ets/dom/event.ts +3 -5
  88. package/dist/runtime-ets/dom/eventTarget.ts +2 -3
  89. package/dist/runtime-ets/dom/node.ts +65 -32
  90. package/dist/runtime-ets/dom/stylesheet/covertWeb2Hm.ts +418 -237
  91. package/dist/runtime-ets/dom/stylesheet/index.ts +29 -311
  92. package/dist/runtime-ets/dom/stylesheet/type.ts +53 -11
  93. package/dist/runtime-ets/dom/stylesheet/util.ts +33 -27
  94. package/dist/runtime-ets/index.ts +2 -2
  95. package/dist/runtime-ets/interface/event.ts +1 -1
  96. package/dist/runtime-ets/utils/index.ts +74 -13
  97. package/dist/runtime-ets/utils/info.ts +2 -2
  98. package/dist/runtime-framework/react/app.ts +25 -30
  99. package/dist/runtime-framework/react/hooks.ts +3 -4
  100. package/dist/runtime-framework/react/index.ts +0 -2
  101. package/dist/runtime-framework/react/native-page.ts +219 -82
  102. package/dist/runtime-framework/react/page.ts +6 -10
  103. package/dist/runtime-framework/react/utils/index.ts +3 -3
  104. package/dist/runtime-framework/solid/app.ts +30 -46
  105. package/dist/runtime-framework/solid/connect.ts +21 -3
  106. package/dist/runtime-framework/solid/hooks.ts +17 -12
  107. package/dist/runtime-framework/solid/index.ts +6 -2
  108. package/dist/runtime-framework/solid/page.ts +85 -31
  109. package/dist/runtime-framework/solid/reconciler/props.ts +70 -25
  110. package/dist/runtime-framework/solid/reconciler/render.ts +16 -6
  111. package/dist/runtime-framework/solid/reconciler/use.ts +0 -1
  112. package/dist/runtime-framework/solid/utils/index.ts +3 -5
  113. package/dist/runtime-utils.d.ts +827 -0
  114. package/dist/runtime-utils.js +618 -245
  115. package/dist/runtime-utils.js.map +1 -1
  116. package/dist/runtime.d.ts +1 -0
  117. package/dist/runtime.js +618 -245
  118. package/dist/runtime.js.map +1 -1
  119. package/index.js +3 -1
  120. package/package.json +14 -15
  121. package/static/media/cancel.svg +1 -1
  122. package/static/media/circle.svg +1 -1
  123. package/static/media/clear.svg +1 -1
  124. package/static/media/download.svg +1 -1
  125. package/static/media/info.svg +1 -1
  126. package/static/media/info_circle.svg +1 -1
  127. package/static/media/search.svg +1 -1
  128. package/static/media/success.svg +1 -1
  129. package/static/media/success_no_circle.svg +1 -1
  130. package/static/media/warn.svg +1 -1
  131. package/types/harmony.d.ts +5 -0
  132. package/types/index.d.ts +4 -0
  133. package/types/runtime.d.ts +3 -1
  134. package/dist/runtime-ets/utils/bind.ts +0 -24
  135. /package/dist/runtime-framework/solid/{contant.ts → constant.ts} +0 -0
@@ -1,59 +1,90 @@
1
- import type { TaroElement } from '@tarojs/runtime'
1
+ import type { TaroElement, HarmonyStyle } from '@tarojs/runtime'
2
+ import { isUndefined } from '@tarojs/shared'
3
+ import { getNormalAttributes } from './styles'
2
4
 
3
5
  interface IFlexOptions {
4
6
  direction: FlexDirection,
5
7
  justifyContent: FlexAlign,
6
- alignItems: VerticalAlign | HorizontalAlign,
7
- // Row 和 Column 不支持下面两个属性
8
- // wrap: FlexWrap,
9
- // alignContent: FlexAlignContent
8
+ alignItems: ItemAlign,
9
+ wrap?: FlexWrap,
10
+ alignContent?: FlexAlign
10
11
  }
11
12
 
12
13
  class FlexManager {
13
14
  static isFlexNode (node: TaroElement): boolean {
14
15
  return !!node.hmStyle?.display?.includes('flex')
15
16
  }
16
-
17
+
17
18
  static convertFlexAlignItemsToColumnOrRow (direction: FlexDirection, alignItems: ItemAlign | undefined): VerticalAlign | HorizontalAlign {
18
19
  if (direction === FlexDirection.Column) {
19
20
  switch (alignItems) {
20
- case ItemAlign.Start:
21
- return HorizontalAlign.Start
21
+ case ItemAlign.Center:
22
+ return HorizontalAlign.Center
22
23
  case ItemAlign.End:
23
24
  return HorizontalAlign.End
24
25
  default:
25
- return HorizontalAlign.Center
26
+ return HorizontalAlign.Start
26
27
  }
27
28
  } else {
28
29
  switch (alignItems) {
29
- case ItemAlign.Start:
30
- return VerticalAlign.Top
30
+ case ItemAlign.Center:
31
+ return VerticalAlign.Center
31
32
  case ItemAlign.End:
32
33
  return VerticalAlign.Bottom
33
34
  default:
34
- return VerticalAlign.Center
35
+ return VerticalAlign.Top
35
36
  }
36
37
  }
37
38
  }
38
39
 
40
+ static useFlexLayout (node: TaroElement): boolean {
41
+ const hmStyle: HarmonyStyle = getNormalAttributes(node) || {}
42
+ const isReverse = hmStyle.flexDirection && [FlexDirection.RowReverse, FlexDirection.ColumnReverse].indexOf(hmStyle.flexDirection) !== -1;
43
+ const isUnknownAlign = [ItemAlign.Stretch, ItemAlign.Baseline].indexOf(hmStyle.alignItems!) !== -1;
44
+ return !isUndefined(hmStyle.flexWrap) || isReverse || isUnknownAlign;
45
+ }
46
+
39
47
  static flexOptions (node: TaroElement): IFlexOptions {
40
- const hmStyle = node.hmStyle
48
+ const hmStyle: HarmonyStyle = getNormalAttributes(node) || {}
41
49
  const isFlex = FlexManager.isFlexNode(node)
42
- const justifyContent: FlexAlign = isFlex ? (hmStyle.justifyContent || FlexAlign.Center) : FlexAlign.Start
43
-
44
50
  let flexDirection = hmStyle.flexDirection
45
51
  if (!flexDirection && flexDirection !== 0) {
46
52
  flexDirection = hmStyle.display === 'flex' ? FlexDirection.Row : FlexDirection.Column
47
53
  }
48
54
 
49
- const alignItems = isFlex ? FlexManager.convertFlexAlignItemsToColumnOrRow(flexDirection, hmStyle.alignItems) : HorizontalAlign.Start
50
-
51
55
  return {
52
- alignItems,
53
- justifyContent,
56
+ alignItems: isFlex ? (isUndefined(hmStyle.alignItems) ? ItemAlign.Start : hmStyle.alignItems) : ItemAlign.Start,
57
+ justifyContent: isFlex ? (isUndefined(hmStyle.justifyContent) ? FlexAlign.Start : hmStyle.justifyContent) : FlexAlign.Start,
54
58
  direction: flexDirection,
59
+ wrap: isFlex ? hmStyle.flexWrap: FlexWrap.NoWrap,
60
+ alignContent: isFlex ? hmStyle.alignContent: FlexAlign.Start
55
61
  }
56
62
  }
63
+
64
+ static direction (node: TaroElement): FlexDirection {
65
+ const hmStyle: HarmonyStyle = getNormalAttributes(node)
66
+ let flexDirection = hmStyle.flexDirection
67
+ if (!flexDirection && flexDirection !== 0) {
68
+ flexDirection = hmStyle.display === 'flex' ? FlexDirection.Row : FlexDirection.Column
69
+ }
70
+ return flexDirection
71
+ }
72
+
73
+ static alignItems<T> (node: TaroElement): T {
74
+ const hmStyle: HarmonyStyle = getNormalAttributes(node)
75
+ const isFlex = FlexManager.isFlexNode(node)
76
+ let flexDirection = hmStyle.flexDirection
77
+ if (!flexDirection && flexDirection !== 0) {
78
+ flexDirection = hmStyle.display === 'flex' ? FlexDirection.Row : FlexDirection.Column
79
+ }
80
+ return (isFlex ? FlexManager.convertFlexAlignItemsToColumnOrRow(flexDirection, hmStyle.alignItems) : HorizontalAlign.Start) as T
81
+ }
82
+
83
+ static justifyContent (node: TaroElement): FlexAlign {
84
+ const hmStyle: HarmonyStyle = getNormalAttributes(node)
85
+ const isFlex = FlexManager.isFlexNode(node)
86
+ return isFlex ? (isUndefined(hmStyle.justifyContent) ? FlexAlign.Start : hmStyle.justifyContent) : FlexAlign.Start
87
+ }
57
88
  }
58
89
 
59
90
  export { FlexManager }
@@ -1,7 +1,8 @@
1
- import { getNormalAttributes, getFontAttributes } from './styles'
1
+ import { VIEW } from '@tarojs/runtime/dist/runtime.esm'
2
2
 
3
- import type { Func } from '@tarojs/runtime/dist/runtime.esm'
4
- import type { TaroElement } from '@tarojs/runtime'
3
+ import { getNormalAttributes, getFontAttributes, getStyleAttr } from './styles'
4
+
5
+ import type { TaroElement, TaroNode, TaroAny } from '@tarojs/runtime'
5
6
 
6
7
  export const parseStyles = (styles = ''): Record<string, string> => {
7
8
  const styleObj: Record<string, string> = {}
@@ -9,7 +10,7 @@ export const parseStyles = (styles = ''): Record<string, string> => {
9
10
  .split(';')
10
11
  .filter((style) => style.split(':').length === 2)
11
12
  .map((style) => [
12
- style.split(':')[0].trim().replace(new RegExp("/-./g"), c => c.substring(1).toUpperCase()),
13
+ style.split(':')[0].trim().replace(new RegExp("-([a-z])", "g"), (_, letter: string): string => letter.toUpperCase()),
13
14
  style.split(':')[1].trim()
14
15
  ])
15
16
  .forEach((style) => {
@@ -20,7 +21,7 @@ export const parseStyles = (styles = ''): Record<string, string> => {
20
21
  return styleObj
21
22
  }
22
23
 
23
- export function shouldBindEvent (cb: Func, node: TaroElement | null, eventNames: string[], disabled = false) {
24
+ export function shouldBindEvent (cb: TaroAny, node: TaroElement | null, eventNames: string[], disabled = false): TaroAny {
24
25
  if (!node || node._attrs?.disabled || disabled) return null
25
26
  if (!node.__listeners) {
26
27
  return null
@@ -31,9 +32,20 @@ export function shouldBindEvent (cb: Func, node: TaroElement | null, eventNames:
31
32
  }
32
33
 
33
34
  export function getNodeThresholds (node: TaroElement): number[] | null {
34
- if (!node) return null
35
+ return node?._nodeInfo?.thresholds || null
36
+ }
35
37
 
36
- return node?._nodeInfo.thresholds || null
38
+ export function isTagFirstChild (node: TaroElement, tagName = VIEW, level = 0): boolean {
39
+ const parent: TaroElement | null = node.parentElement
40
+ const list: TaroNode[] = node.parentNode?.childNodes || []
41
+ if (list.length < 1 || level < 0) return false
42
+ else if (!parent) return true
43
+
44
+ if (parent.nodeName === tagName.toUpperCase()) {
45
+ return list[0] === node
46
+ } else {
47
+ return (list[0] === node) && isTagFirstChild(parent, tagName, --level)
48
+ }
37
49
  }
38
50
 
39
- export { getNormalAttributes, getFontAttributes }
51
+ export { getNormalAttributes, getFontAttributes, getStyleAttr }
@@ -99,5 +99,4 @@ function parseTag(htmlString, startIndex) {
99
99
  return tag
100
100
  }
101
101
 
102
-
103
- export default parseHTML
102
+ export default parseHTML
@@ -15,7 +15,7 @@ function buildDomTree(dom: TTreeNode) {
15
15
  case 'span': tagName = 'text'; break
16
16
  }
17
17
  if (!tagName) return null
18
-
18
+
19
19
  const ele = document.createElement(tagName)
20
20
  attributes && Object.keys(attributes).forEach(key => {
21
21
  if (key === 'style') {
@@ -1,5 +1,8 @@
1
1
  import { convertNumber2VP } from '@tarojs/runtime'
2
- import { isNumber } from '@tarojs/shared'
2
+ import { isNumber, isUndefined } from '@tarojs/shared'
3
+
4
+ import type { RichTextProps } from '@tarojs/components/types/RichText'
5
+ import type { TaroRichTextElement } from '@tarojs/runtime'
3
6
 
4
7
  export function getSingleSelector(range, rangeKey): any[] {
5
8
  return range.map((data) => data[rangeKey])
@@ -18,66 +21,67 @@ export function getMultiSelector(ctx, range, rangeKey, value) {
18
21
  }))
19
22
  }
20
23
 
21
- export function getUnit (val) {
22
- if (/\d+(vp)$/.test(val)) {
24
+ export function getUnit (val: string | number): string {
25
+ if (isNumber(val) || /\d+px$/.test(val)) {
26
+ return convertNumber2VP(parseFloat(val as string))
27
+ } else if (/\d+(vp)$/.test(val)) {
23
28
  return val
24
- } else if (isNumber(val) || /\d+px$/.test(val)) {
25
- return convertNumber2VP(parseFloat(val))
26
29
  }
27
30
  return val
28
31
  }
29
32
 
30
- function handleNodeStyleData (dataValue: string, handler: (values: string[]) => { [key: string]: string } | void) {
31
- let res: any = {}
32
- if (dataValue) {
33
- const values = dataValue.trim().split(/\s+/)
34
- const data = handler(values)
35
-
36
- if (!data) return res
37
-
38
- res = data
33
+ export function generateText (node: TaroRichTextElement): string {
34
+ return parseHtmlNode(node._attrs.nodes || '')
35
+ }
39
36
 
40
- Object.keys(res).forEach(key => {
41
- const exec = `${res[key]}`.match(/(\d+)(px)$/)
42
- if (exec && values.length > 1) {
43
- res[key] = getUnit(+exec[1])
44
- }
45
- })
37
+ // 将nodeTree转换成harmony需要的string结构
38
+ function nodeToHtml(node: RichTextProps.Text | RichTextProps.HTMLElement): string {
39
+ if (node.type === 'text') {
40
+ return node.text
41
+ }
42
+ if (node.attrs) {
43
+ const attributes = Object.entries(node.attrs)
44
+ .map((item: [string, string]) => `${item[0]}="${item[1]}"`)
45
+ .join(' ')
46
+ const childrenHtml: string = typeof node.children === 'string' ? node.children : (node.children || []).map((child: RichTextProps.Text | RichTextProps.HTMLElement) => nodeToHtml(child)).join('')
47
+ return `<${node.name}${attributes ? ' ' + attributes : ''}>${childrenHtml}</${node.name}>`
46
48
  }
49
+ return ''
50
+ }
47
51
 
48
- return res
52
+ function parseHtmlNode (nodes: Array<RichTextProps.Text | RichTextProps.HTMLElement> | string) {
53
+ return typeof nodes === 'string' ? nodes : `<div>${nodes.map(node => nodeToHtml(node)).join('')}</div>`
49
54
  }
50
55
 
51
- export function getNodeBorderRadiusData (dataValue: string) {
52
- return handleNodeStyleData(dataValue, values => {
53
- switch (values.length) {
54
- case 1:
55
- return { topLeft: values[0], topRight: values[0], bottomRight: values[0], bottomLeft: values[0] }
56
- case 2:
57
- return { topLeft: values[0], topRight: values[1], bottomRight: values[0], bottomLeft: values[1] }
58
- case 3:
59
- return { topLeft: values[0], topRight: values[1], bottomRight: values[2], bottomLeft: values[1] }
60
- case 4:
61
- return { topLeft: values[0], topRight: values[1], bottomRight: values[2], bottomLeft: values[3] }
62
- default:
63
- break
56
+ // 背景偏移算法:https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-position
57
+ export function computeBackgroundPosition(style) {
58
+ let offsetX = style.backgroundPosition?.x || 0
59
+ let offsetY = style.backgroundPosition?.y || 0
60
+ if (style.backgroundSize && typeof style.backgroundSize !== 'number') {
61
+ if (!isUndefined(style.backgroundSize.width) && style.width) {
62
+ if (typeof style.backgroundPosition.x === 'string' && style.backgroundPosition.x.indexOf('%') > 0) {
63
+ // (container width - image width) * (position x%) = (x offset value)
64
+ const width = parseFloat(style.width)
65
+ const bgWidth = parseFloat(style.backgroundSize.width)
66
+ const bgOffsetX = parseFloat(style.backgroundPosition.x)
67
+ offsetX = Number((width - bgWidth) * (bgOffsetX) / 100) || 0
68
+ }
69
+ }
70
+ if (!isUndefined(style.backgroundSize.height) && style.height) {
71
+ if (typeof style.backgroundPosition.y === 'string' && style.backgroundPosition.y.indexOf('%') > 0) {
72
+ // (container height - image height) * (position y%) = (y offset value)
73
+ const height = parseFloat(style.height)
74
+ const bgHeight = parseFloat(style.backgroundSize.height)
75
+ const bgOffsetY = parseFloat(style.backgroundPosition.y)
76
+ offsetY = Number((height - bgHeight) * (bgOffsetY) / 100) || 0
77
+ }
64
78
  }
65
- })
79
+ }
80
+
81
+ return { offsetX, offsetY }
66
82
  }
67
83
 
68
- export function getNodeMarginOrPaddingData (dataValue: string) {
69
- return handleNodeStyleData(dataValue, values => {
70
- switch (values.length) {
71
- case 1:
72
- return { top: values[0], right: values[0], bottom: values[0], left: values[0] }
73
- case 2:
74
- return { top: values[0], right: values[1], bottom: values[0], left: values[1] }
75
- case 3:
76
- return { top: values[0], right: values[1], bottom: values[2], left: values[1] }
77
- case 4:
78
- return { top: values[0], right: values[1], bottom: values[2], left: values[3] }
79
- default:
80
- break
81
- }
82
- })
84
+ export function convertVp2Px(val: string | number) {
85
+ const vp = parseFloat(`${val}`)
86
+ return vp2px(vp)
83
87
  }
@@ -1,125 +1,205 @@
1
1
  import { isUndefined } from '@tarojs/shared'
2
2
  import { ObjectAssign } from '@tarojs/runtime'
3
3
 
4
- import { FlexManager } from './FlexManager'
5
- import { TEXT_DEFAULT_STYLE } from './constant/style'
4
+ import { FlexManager } from './flexManager'
6
5
 
7
6
  import type { StandardProps, TextProps } from '@tarojs/components/types'
8
- import type { TaroAny, TaroElement, TaroStyleType, TaroTextStyleType, HarmonyType, HarmonyStyle } from '@tarojs/runtime'
7
+ import type { TaroAny, TaroElement, TaroStyleType, TaroTextStyleType, HarmonyStyle } from '@tarojs/runtime'
9
8
 
10
9
  export function getFontAttributes (node: TaroElement): TaroTextStyleType {
11
- const hmStyle = node.hmStyle
10
+ let hmStyle = getNormalAttributes(node)
12
11
  const attrs: TextProps = node._attrs || {}
13
12
 
13
+ if (!hmStyle) return {}
14
+
15
+ let lineHeight = hmStyle.lineHeight
16
+ if (!isUndefined(hmStyle.verticalAlign)) {
17
+ lineHeight = 0
18
+ }
19
+
20
+ let WebkitLineClamp = attrs.maxLines || hmStyle.WebkitLineClamp || Infinity
21
+ if (hmStyle.textOverflow && !isUndefined(hmStyle.textOverflow.overflow)) {
22
+ switch (hmStyle.textOverflow.overflow) {
23
+ case TextOverflow.Clip:
24
+ case TextOverflow.Ellipsis:
25
+ case TextOverflow.None: WebkitLineClamp = WebkitLineClamp || 1; break
26
+ default: break
27
+ }
28
+ }
29
+
30
+ const isFlexText = hmStyle.display === 'flex'
31
+ let textAlign = hmStyle.textAlign
32
+ let verticalAlign = hmStyle.verticalAlign
33
+
34
+ // 按照 w3c 规范,一旦设置了 display: flex,textAlign 和 verticalAlign 都会直接失效
35
+ // 需要使用 justifyContent 和 alignItems
36
+ if (isFlexText) {
37
+ switch (hmStyle.justifyContent) {
38
+ case FlexAlign.Start:
39
+ textAlign = TextAlign.Start
40
+ break
41
+ case FlexAlign.Center:
42
+ textAlign = TextAlign.Center
43
+ break
44
+ case FlexAlign.End:
45
+ textAlign = TextAlign.End
46
+ break
47
+ case FlexAlign.SpaceBetween:
48
+ case FlexAlign.SpaceAround:
49
+ textAlign = TextAlign.JUSTIFY
50
+ break
51
+ default:
52
+ textAlign = TextAlign.Start
53
+ break
54
+ }
55
+ switch (hmStyle.alignItems) {
56
+ case ItemAlign.Start:
57
+ verticalAlign = Alignment.Top
58
+ break
59
+ case ItemAlign.Center:
60
+ verticalAlign = Alignment.Center
61
+ break
62
+ case ItemAlign.End:
63
+ verticalAlign = Alignment.End
64
+ break
65
+ default:
66
+ verticalAlign = Alignment.Top
67
+ break
68
+ }
69
+ }
70
+
14
71
  const attributes: TaroAny = {
15
- WebkitLineClamp: attrs.maxLines || hmStyle.WebkitLineClamp || Infinity,
72
+ textAlign,
73
+ verticalAlign,
74
+ WebkitLineClamp: WebkitLineClamp,
16
75
  // 已做处理的属性
17
76
  letterSpacing: hmStyle.letterSpacing,
18
- textAlign: hmStyle.textAlign,
19
- textOverflow: hmStyle.textOverflow
77
+ textOverflow: hmStyle.textOverflow,
78
+ lineHeight: lineHeight
20
79
  }
21
80
 
22
81
  return attributes
23
82
  }
24
83
 
25
84
  // 模拟 div 自动撑满父元素的情况
26
- function isMaxWidthView (node: TaroElement) {
85
+ export function isMaxWidthView (node: TaroElement) {
27
86
  const parentNode: TaroElement = node.parentNode as TaroElement
28
-
29
- return node.tagName === 'VIEW' && parentNode.tagName === 'VIEW' &&
30
- !(FlexManager.isFlexNode(parentNode) && FlexManager.flexOptions(parentNode).direction !== FlexDirection.Column)
87
+
88
+ return node.tagName === 'VIEW' && parentNode && parentNode.tagName === 'VIEW' && !FlexManager.isFlexNode(parentNode)
31
89
  }
32
90
 
33
- export function getNormalAttributes (node: TaroElement): TaroStyleType {
91
+ export function getNormalAttributes (node: TaroElement, initStyle?: HarmonyStyle): HarmonyStyle {
92
+ if (!node) return {}
93
+
34
94
  const hmStyle = node.hmStyle
95
+
96
+ if (!hmStyle) return {}
35
97
 
36
98
  const _nid = node._nid
37
99
  const _attrs: StandardProps = node._attrs || {}
38
100
 
39
- let linearGradient: HarmonyType.LinearGradient | undefined = undefined
40
- // 渐变
41
- if (hmStyle.backgroundImage?.colors) {
42
- linearGradient = hmStyle.backgroundImage
43
- }
101
+ let normalAttributes = hmStyle
102
+
103
+ // 覆盖属性
104
+ normalAttributes.id = _attrs.id || _nid.toString()
44
105
 
45
- let normalAttributes: HarmonyStyle = {
46
- // Flex相关
47
- flexBasis: hmStyle.flexBasis,
48
- flexGrow: hmStyle.flexGrow,
49
- flexShrink: hmStyle.flexShrink,
50
- alignSelf: hmStyle.alignSelf,
51
- // 尺寸相关
52
- width: isMaxWidthView(node) && isUndefined(hmStyle.width) ? '100%' : hmStyle.width,
53
- height: hmStyle.height,
54
- minHeight: hmStyle.minHeight,
55
- maxHeight: hmStyle.maxHeight,
56
- minWidth: hmStyle.minWidth,
57
- maxWidth: hmStyle.maxWidth,
58
- marginTop: hmStyle.marginTop,
59
- marginRight: hmStyle.marginRight,
60
- marginBottom: hmStyle.marginBottom,
61
- marginLeft: hmStyle.marginLeft,
62
- paddingTop: hmStyle.paddingTop,
63
- paddingRight: hmStyle.paddingRight,
64
- paddingBottom: hmStyle.paddingBottom,
65
- paddingLeft: hmStyle.paddingLeft,
66
- // 边框相关
67
- borderStyle: hmStyle.borderStyle,
68
- borderTopStyle: hmStyle.borderTopStyle,
69
- borderRightStyle: hmStyle.borderRightStyle,
70
- borderBottomStyle: hmStyle.borderBottomStyle,
71
- borderLeftStyle: hmStyle.borderLeftStyle,
72
- borderWidth: hmStyle.borderWidth,
73
- borderTopWidth: hmStyle.borderTopWidth,
74
- borderRightWidth: hmStyle.borderRightWidth,
75
- borderBottomWidth: hmStyle.borderBottomWidth,
76
- borderLeftWidth: hmStyle.borderLeftWidth,
77
- borderColor: hmStyle.borderColor,
78
- borderTopColor: hmStyle.borderTopColor,
79
- borderRightColor: hmStyle.borderRightColor,
80
- borderBottomColor: hmStyle.borderBottomColor,
81
- borderLeftColor: hmStyle.borderLeftColor,
82
- borderRadius: hmStyle.borderRadius,
83
- borderTopLeftRadius: hmStyle.borderTopLeftRadius,
84
- borderTopRightRadius: hmStyle.borderTopRightRadius,
85
- borderBottomRightRadius: hmStyle.borderBottomRightRadius,
86
- borderBottomLeftRadius: hmStyle.borderBottomLeftRadius,
87
- // 背景相关
88
- backgroundColor: hmStyle.backgroundColor,
89
- backgroundImage: hmStyle.backgroundImage,
90
- backgroundSize: hmStyle.backgroundSize,
91
- backgroundRepeat: hmStyle.backgroundRepeat,
92
- backgroundPosition: hmStyle.backgroundPosition,
93
- linearGradient,
94
- // 变换相关
95
- transform: hmStyle.transform,
96
- transformOrigin: {
97
- x: hmStyle.transformOrigin?.x || 0,
98
- y: hmStyle.transformOrigin?.y || 0
99
- },
100
- // 通用文本相关
101
- color: hmStyle.color,
102
- fontSize: hmStyle.fontSize,
103
- fontStyle: hmStyle.fontStyle,
104
- fontWeight: hmStyle.fontWeight,
105
- fontFamily: hmStyle.fontFamily || TEXT_DEFAULT_STYLE.FONT_FAMILY,
106
- lineHeight: hmStyle.lineHeight,
107
- textDecoration: hmStyle.textDecoration,
108
- // 其他
109
- overflow: hmStyle.overflow,
110
- id: _attrs.id || _nid,
111
- opacity: hmStyle.opacity,
112
- // focus: _attrs.focus || false,
106
+ let pseudoStylesheet = getPseudoClass(node)
107
+ if (pseudoStylesheet) {
108
+ normalAttributes = ObjectAssign({}, normalAttributes, pseudoStylesheet)
113
109
  }
114
110
 
115
- // taro_page 等写死在运行时里的节点,没有 _nodeInfo
116
- if (node._nodeInfo) {
117
- const overwriteStyle: TaroStyleType = node._nodeInfo?.overwriteStyle
111
+ // 初始化默认的值
112
+ if (initStyle) {
113
+ normalAttributes = ObjectAssign({}, initStyle, normalAttributes)
114
+ }
115
+ return normalAttributes
116
+ }
118
117
 
119
- // 处理覆盖属性:如动画的覆盖
120
- if (overwriteStyle) {
121
- normalAttributes = ObjectAssign(normalAttributes, overwriteStyle)
118
+ // 应用伪类样式
119
+ function getPseudoClass (node: TaroElement): HarmonyStyle | null {
120
+ // 伪类
121
+ const _pseudo_class = Object.keys(node._pseudo_class)
122
+ if (_pseudo_class.length) {
123
+ for (let i = 0; i < _pseudo_class.length; i++) {
124
+ const pseudoKey = _pseudo_class[i]
125
+ const pseudoStylesheet = node._pseudo_class[pseudoKey]
126
+ if (!pseudoStylesheet) continue
127
+ switch(pseudoKey) {
128
+ case "::first-child": {
129
+ if (node.parentNode?.firstChild?._nid === node._nid) {
130
+ return pseudoStylesheet.hmStyle
131
+ }
132
+ break
133
+ }
134
+ case "::last-child": {
135
+ if (node.parentNode?.lastChild?._nid === node._nid) {
136
+ return pseudoStylesheet.hmStyle
137
+ }
138
+ break
139
+ }
140
+ case "::empty": {
141
+ if (node.children?.length === 0) {
142
+ return pseudoStylesheet.hmStyle
143
+ }
144
+ break
145
+ }
146
+ default: {
147
+ // 解析nth-child()
148
+ // 找出当前节点在父节点中的位置
149
+ // 公式
150
+ let matchs: [number, number] | null = null
151
+ if (pseudoKey === '::nth-child(odd)') {
152
+ matchs = [2, 1]
153
+ } else if (pseudoKey === '::nth-child(even)') {
154
+ matchs = [2, 0]
155
+ } else {
156
+ matchs = parseNthChild(pseudoKey)
157
+ }
158
+ if (matchs) {
159
+ let index = node.parentNode?.childNodes.findIndex((child) => child._nid === node._nid)
160
+ if (isUndefined(index)) return null
161
+ else {
162
+ index = index + 1
163
+ if (matchs[0] === 0) {
164
+ if (index === matchs[1]) {
165
+ return pseudoStylesheet.hmStyle
166
+ }
167
+ } else {
168
+ if ((index - matchs[1]) % matchs[0] === 0) {
169
+ return pseudoStylesheet.hmStyle
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
122
176
  }
123
177
  }
124
- return normalAttributes
178
+ return null
179
+ }
180
+
181
+ // 正则匹配nth-child
182
+ function parseNthChild(selector: string): [number, number] | null {
183
+ const regex = /nth-child\((?:(-?\d*)n\s*)?([+-]?\s*\d+)?\)/;
184
+ const match = selector.match(regex);
185
+
186
+ if (match) {
187
+ const a = match[1] ? parseInt(match[1]) : 0;
188
+ const b = match[2] ? parseInt(match[2]) : 0;
189
+ return [a, b];
190
+ } else {
191
+ return null;
192
+ }
125
193
  }
194
+
195
+
196
+ export function getStyleAttr(node: TaroElement | null, key: string): TaroAny {
197
+ if (!node) return null
198
+ const hmStyle = node.hmStyle
199
+ if (!hmStyle) return null
200
+ // 覆盖属性
201
+ if (key === 'width') {
202
+ return isMaxWidthView(node) && isUndefined(hmStyle.width) ? '100%' : hmStyle.width
203
+ }
204
+ return hmStyle[key]
205
+ }