@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,17 +1,16 @@
1
- import { Current, document } from '@tarojs/runtime'
2
- import { hooks, isWebPlatform } from '@tarojs/shared'
1
+ import { createComponent, h, render } from '@tarojs/plugin-framework-solid/dist/reconciler'
2
+ import { Current, document } from '@tarojs/runtime' // eslint-disable-line import/no-duplicates
3
+ import { eventCenter } from '@tarojs/runtime/dist/runtime.esm' // eslint-disable-line import/no-duplicates
4
+ import { hooks } from '@tarojs/shared'
3
5
  import { batch, createContext, createRoot, createSignal, For } from 'solid-js'
4
6
 
5
7
  import { setReconciler } from './connect'
6
8
  import { getPageInstance, injectPageInstance } from './page'
7
- import { createComponent, h, render } from './reconciler'
8
9
  import { EMPTY_OBJ, HOOKS_APP_ID, setDefaultDescriptor, setRouterParams } from './utils'
9
10
 
10
11
  import type { AppInstance, Instance, PageLifeCycle, PageProps, ReactAppInstance } from '@tarojs/runtime'
11
12
  import type { AppConfig } from '@tarojs/taro'
12
- import type { Component } from './connect'
13
-
14
- const isWeb = isWebPlatform()
13
+ import type { SolidComponent } from './connect'
15
14
 
16
15
  export const ReactMeta = {
17
16
  R: EMPTY_OBJ,
@@ -19,7 +18,7 @@ export const ReactMeta = {
19
18
  PageContext: EMPTY_OBJ
20
19
  }
21
20
 
22
- export function createSolidApp(App: Component, config: AppConfig) {
21
+ export function createSolidApp(App: SolidComponent, config: AppConfig) {
23
22
  setReconciler()
24
23
 
25
24
  if (ReactMeta.PageContext === EMPTY_OBJ) {
@@ -32,13 +31,10 @@ export function createSolidApp(App: Component, config: AppConfig) {
32
31
  }
33
32
 
34
33
  function renderReactRoot() {
35
- let appId = 'app'
36
- if (isWeb) {
37
- appId = config?.appId || appId
38
- }
34
+ const appId = config?.appId || 'app'
39
35
 
40
36
  if (ReactMeta.Container === EMPTY_OBJ) {
41
- const Container = document.createElement('view')
37
+ const Container = document.getElementById(appId)
42
38
 
43
39
  Container.id = appId
44
40
  ReactMeta.Container = Container
@@ -48,17 +44,18 @@ export function createSolidApp(App: Component, config: AppConfig) {
48
44
  render(AppWrapper, root)
49
45
  }
50
46
  const [pages, setPages] = createSignal<any[]>([])
47
+ const [elements, setElements] = createSignal<any[]>([])
51
48
 
52
49
  function AppWrapper () {
53
50
  appRef = {} as unknown as ReactAppInstance
54
51
  return createComponent(App, {
55
- children: createComponent(For as unknown as Component, {
52
+ children: createComponent(For as unknown as SolidComponent, {
56
53
  get each() {
57
54
  return pages()
58
55
  },
59
56
  children: ({ id, component }) => {
60
57
  const children = () =>
61
- createComponent(ReactMeta.PageContext.Provider as unknown as Component, {
58
+ createComponent(ReactMeta.PageContext.Provider as unknown as SolidComponent, {
62
59
  value: id,
63
60
  children: () => {
64
61
  injectPageInstance(
@@ -71,38 +68,33 @@ export function createSolidApp(App: Component, config: AppConfig) {
71
68
  },
72
69
  })
73
70
 
74
- if (isWeb) {
75
- return h('div', { id, className: 'taro_page' }, children)
76
- } else {
77
- return h('root', { id }, children)
78
- }
71
+ return h(
72
+ 'taro-page',
73
+ { id, className: 'taro_page' },
74
+ children
75
+ )
79
76
  },
80
77
  }),
81
78
  })
82
79
  }
83
80
 
84
- if (!isWeb) {
85
- renderReactRoot()
86
- }
87
-
88
- const [ONLAUNCH, ONSHOW, ONHIDE] = hooks.call('getMiniLifecycleImpl')!.app
81
+ renderReactRoot()
89
82
 
90
- const appObj: AppInstance = Object.create(
83
+ const app: AppInstance = Object.create(
91
84
  {
92
- mount(component: Component, id: string, cb: () => void) {
85
+ mount(component: SolidComponent, id: string, cb: () => void) {
93
86
  setPages((old) => [
94
87
  ...old,
95
88
  { id, component },
96
89
  ])
97
90
  batch(cb)
98
91
  },
99
-
100
92
  unmount(id: string, cb: () => void) {
101
- setPages(
102
- pages().filter((item) => {
103
- return item.id !== id
104
- })
105
- )
93
+ const idx = elements().findIndex((item) => item.id === id)
94
+ setElements((old) => {
95
+ old.splice(idx, 1)
96
+ return old
97
+ })
106
98
  batch(cb)
107
99
  },
108
100
  },
@@ -112,15 +104,10 @@ export function createSolidApp(App: Component, config: AppConfig) {
112
104
  value: config,
113
105
  }),
114
106
 
115
- [ONLAUNCH]: setDefaultDescriptor({
107
+ onLaunch: setDefaultDescriptor({
116
108
  value(options) {
117
109
  setRouterParams(options)
118
110
 
119
- if (isWeb) {
120
- // 由于 H5 路由初始化的时候会清除 app 下的 dom 元素,所以需要在路由初始化后执行 render
121
- renderReactRoot()
122
- }
123
-
124
111
  const onLaunch = () => {
125
112
  const app = getAppInstance()
126
113
 
@@ -151,28 +138,25 @@ export function createSolidApp(App: Component, config: AppConfig) {
151
138
 
152
139
  onLaunch()
153
140
  triggerAppHook('onLaunch', options)
141
+ eventCenter.trigger('__taroRouterLaunch', options)
154
142
  },
155
143
  }),
156
-
157
- [ONSHOW]: setDefaultDescriptor({
144
+ onShow: setDefaultDescriptor({
158
145
  value(options) {
159
146
  setRouterParams(options)
160
147
  triggerAppHook('onShow', options)
161
148
  },
162
149
  }),
163
-
164
- [ONHIDE]: setDefaultDescriptor({
150
+ onHide: setDefaultDescriptor({
165
151
  value() {
166
152
  triggerAppHook('onHide')
167
153
  },
168
154
  }),
169
-
170
155
  onError: setDefaultDescriptor({
171
156
  value(error: string) {
172
157
  triggerAppHook('onError', error)
173
158
  },
174
159
  }),
175
-
176
160
  onPageNotFound: setDefaultDescriptor({
177
161
  value(res: unknown) {
178
162
  triggerAppHook('onPageNotFound', res)
@@ -195,6 +179,6 @@ export function createSolidApp(App: Component, config: AppConfig) {
195
179
  }
196
180
  }
197
181
 
198
- Current.app = appObj
199
- return appObj
182
+ Current.app = app
183
+ return app
200
184
  }
@@ -1,11 +1,29 @@
1
- import { TaroNode } from '@tarojs/runtime'
2
1
  import { hooks } from '@tarojs/shared'
3
2
  import { batch } from 'solid-js'
4
3
 
5
- export type Component = (props?: any) => TaroNode
4
+ import { ensureIsArray } from './utils'
6
5
 
7
- export function setReconciler() {
6
+ import type { TaroNode } from '@tarojs/runtime'
7
+
8
+ export type SolidComponent = (props?: any) => TaroNode
9
+
10
+ export function setReconciler () {
8
11
  hooks.tap('batchedEventUpdates', function (cb) {
9
12
  batch(cb)
10
13
  })
14
+
15
+ hooks.tap('mergePageInstance', function (prev, next) {
16
+ if (!prev || !next) return
17
+
18
+ // 子组件使用 lifecycle hooks 注册了生命周期后,会存在 prev,里面是注册的生命周期回调。
19
+
20
+ // prev 使用 Object.create(null) 创建,H5 的 fast-refresh 可能也会导致存在 prev,要排除这些意外产生的 prev
21
+ if ('constructor' in prev) return
22
+
23
+ Object.keys(prev).forEach(item => {
24
+ const prevList = prev[item]
25
+ const nextList = ensureIsArray<() => any>(next[item])
26
+ next[item] = nextList.concat(prevList)
27
+ })
28
+ })
11
29
  }
@@ -1,9 +1,4 @@
1
- import {
2
- AppInstance,
3
- Current,
4
- Func,
5
- PageLifeCycle
6
- } from '@tarojs/runtime'
1
+ import { Current } from '@tarojs/runtime'
7
2
  import { isArray, isFunction } from '@tarojs/shared'
8
3
  import {
9
4
  createMemo,
@@ -15,8 +10,14 @@ import { ReactMeta } from './app'
15
10
  import { getPageInstance, injectPageInstance } from './page'
16
11
  import { HOOKS_APP_ID } from './utils'
17
12
 
13
+ import type {
14
+ AppInstance,
15
+ PageLifeCycle,
16
+ TFunc
17
+ } from '@tarojs/runtime/dist/runtime.esm'
18
+
18
19
  const createTaroHook = (lifecycle: keyof PageLifeCycle | keyof AppInstance) => {
19
- return (fn: Func) => {
20
+ return (fn: TFunc) => {
20
21
  const id = ReactMeta.PageContext || HOOKS_APP_ID
21
22
 
22
23
  createRenderEffect(() => {
@@ -30,10 +31,13 @@ const createTaroHook = (lifecycle: keyof PageLifeCycle | keyof AppInstance) => {
30
31
  })
31
32
  }
32
33
 
33
- if (isFunction(inst![lifecycle])) {
34
- inst![lifecycle] = [inst?.[lifecycle], fn]
34
+ if (isFunction(inst[lifecycle])) {
35
+ inst[lifecycle] = [inst[lifecycle], fn]
35
36
  } else {
36
- inst![lifecycle] = [...(inst![lifecycle] || []), fn]
37
+ inst[lifecycle] = [
38
+ ...((inst[lifecycle]) || []),
39
+ fn
40
+ ]
37
41
  }
38
42
 
39
43
  if (first) {
@@ -43,9 +47,9 @@ const createTaroHook = (lifecycle: keyof PageLifeCycle | keyof AppInstance) => {
43
47
  onCleanup(() => {
44
48
  const list = inst![lifecycle]
45
49
  if (list === fn) {
46
- inst![lifecycle] = undefined
50
+ (inst[lifecycle]) = undefined
47
51
  } else if (isArray(list)) {
48
- inst![lifecycle] = list.filter((item) => item !== fn)
52
+ (inst[lifecycle]) = list.filter(item => item !== fn)
49
53
  }
50
54
  })
51
55
  })
@@ -58,6 +62,7 @@ export const useDidShow = createTaroHook('componentDidShow')
58
62
 
59
63
  /** App */
60
64
  export const useError = createTaroHook('onError')
65
+ export const useUnhandledRejection = createTaroHook('onUnhandledRejection')
61
66
  export const useLaunch = createTaroHook('onLaunch')
62
67
  export const usePageNotFound = createTaroHook('onPageNotFound')
63
68
 
@@ -1,8 +1,12 @@
1
1
  import { hooks } from '@tarojs/shared'
2
2
 
3
- // declare const __TARO_FRAMEWORK__: string;
3
+ import * as taroHooks from './hooks'
4
4
 
5
- hooks.tap('initNativeApi', function (_taro) {})
5
+ hooks.tap('initNativeApi', function (taro) {
6
+ for (const hook in taroHooks) {
7
+ taro[hook] = taroHooks[hook]
8
+ }
9
+ })
6
10
 
7
11
  export * from './app'
8
12
  export * from './connect'
@@ -1,13 +1,17 @@
1
- import { Current } from '@tarojs/runtime'
2
- import { isArray, isFunction, isUndefined } from '@tarojs/shared'
1
+ import { Current, document, requestAnimationFrame, window } from '@tarojs/runtime' // eslint-disable-line import/no-duplicates
2
+ import { addLeadingSlash, CONTEXT_ACTIONS, env, eventCenter } from '@tarojs/runtime/dist/runtime.esm' // eslint-disable-line import/no-duplicates
3
+ import { hooks, isArray, isFunction, isUndefined } from '@tarojs/shared'
3
4
 
4
- import { ON_HIDE, ON_LOAD, ON_READY, ON_SHOW, ON_UNLOAD } from './contant'
5
+ import { ON_HIDE, ON_LOAD, ON_READY, ON_SHOW, ON_UNLOAD } from './constant'
5
6
  import { incrementId } from './utils'
6
7
 
8
+ import type { PageConfig } from '@tarojs/taro'
9
+
7
10
  const instances = new Map<string, any>()
8
- const pageId = incrementId()
11
+ const pageId = incrementId(1)
9
12
 
10
13
  export function injectPageInstance (inst: any, id: string) {
14
+ hooks.call('mergePageInstance', instances.get(id), inst)
11
15
  instances.set(id, inst)
12
16
  }
13
17
 
@@ -19,13 +23,6 @@ export function removePageInstance (id: string) {
19
23
  instances.delete(id)
20
24
  }
21
25
 
22
- export function addLeadingSlash (path?: string): string {
23
- if (path == null) {
24
- return ''
25
- }
26
- return path.charAt(0) === '/' ? path : '/' + path
27
- }
28
-
29
26
  export function safeExecute (path: string, lifecycle: string, ...args: unknown[]) {
30
27
  const instance = instances.get(path)
31
28
 
@@ -33,6 +30,7 @@ export function safeExecute (path: string, lifecycle: string, ...args: unknown[]
33
30
  return
34
31
  }
35
32
 
33
+ lifecycle = lifecycle.replace(/^on(Show|Hide)$/, 'componentDid$1')
36
34
  const func = instance[lifecycle]
37
35
 
38
36
  if (isArray(func)) {
@@ -75,9 +73,19 @@ export function getOnHideEventKey (path: string) {
75
73
  return path + '.' + ON_HIDE
76
74
  }
77
75
 
78
- export function createPageConfig (component: any, pageName?: string) {
76
+ export function createPageConfig (component: any, pageName?: string, pageConfig?: PageConfig) {
79
77
  // 小程序 Page 构造器是一个傲娇小公主,不能把复杂的对象挂载到参数上
80
78
  const id = pageName ?? `taro_page_${pageId()}`
79
+ const [
80
+ ONLOAD,
81
+ ONUNLOAD,
82
+ ONREADY,
83
+ ONSHOW,
84
+ ONHIDE,
85
+ LIFECYCLES,
86
+ SIDE_EFFECT_LIFECYCLES,
87
+ ] = hooks.call('getMiniLifecycleImpl')!.page
88
+
81
89
  let pageElement: any = null
82
90
  let unmounting = false
83
91
  let prepareMountList: (() => void)[] = []
@@ -102,7 +110,7 @@ export function createPageConfig (component: any, pageName?: string) {
102
110
  let loadResolver: (...args: any[]) => void
103
111
  let hasLoaded: Promise<void>
104
112
  const page = {
105
- onLoad (options: Readonly<Record<string, unknown>> = {}, cb?: (...args: any[]) => any) {
113
+ [ONLOAD] (options: Readonly<Record<string, unknown>> = {}, cb?: (...args: any[]) => any) {
106
114
  hasLoaded = new Promise(resolve => { loadResolver = resolve })
107
115
 
108
116
  Current.page = this as any
@@ -118,21 +126,21 @@ export function createPageConfig (component: any, pageName?: string) {
118
126
 
119
127
  setCurrentRouter(this)
120
128
 
121
- // window.trigger(CONTEXT_ACTIONS.INIT, $taroPath)
129
+ window.trigger(CONTEXT_ACTIONS.INIT, $taroPath)
122
130
 
123
131
  const mount = () => {
132
+ // @ts-ignore
124
133
  Current.app!.mount!(component, $taroPath, () => {
125
- // pageElement = document.getElementById($taroPath)
134
+ pageElement = document.getElementById($taroPath)
126
135
 
127
- // if (!pageElement) {
128
- // throw new Error(`没有找到页面实例。`)
129
- // }
136
+ if (!pageElement) {
137
+ throw new Error(`没有找到页面实例。`)
138
+ }
130
139
 
131
140
  safeExecute($taroPath, ON_LOAD, this.$taroParams)
132
141
  loadResolver()
133
- cb && cb()
134
- // pageElement.ctx = this
135
- // pageElement.performUpdate(true, cb)
142
+ cb && cb(pageElement)
143
+ pageElement.ctx = this
136
144
  })
137
145
  }
138
146
 
@@ -142,10 +150,10 @@ export function createPageConfig (component: any, pageName?: string) {
142
150
  mount()
143
151
  }
144
152
  },
145
- onUnLoad () {
153
+ [ONUNLOAD] () {
146
154
  const $taroPath = this.$taroPath
147
155
  // 销毁当前页面的上下文信息
148
- // window.trigger(CONTEXT_ACTIONS.DESTORY, $taroPath)
156
+ window.trigger(CONTEXT_ACTIONS.DESTORY, $taroPath)
149
157
 
150
158
  // 触发onUnload生命周期
151
159
  safeExecute($taroPath, ON_UNLOAD)
@@ -163,22 +171,31 @@ export function createPageConfig (component: any, pageName?: string) {
163
171
  }
164
172
  })
165
173
  },
166
- onShow (options = {}) {
174
+ [ONREADY] () {
175
+ hasLoaded.then(() => {
176
+ // 触发生命周期
177
+ safeExecute(this.$taroPath, ON_READY)
178
+ // 通过事件触发子组件的生命周期
179
+ requestAnimationFrame(() => eventCenter.trigger(getOnReadyEventKey(id)))
180
+ this.onReady.called = true
181
+ })
182
+ },
183
+ [ONSHOW] (options = {}) {
167
184
  hasLoaded.then(() => {
168
185
  // 设置 Current 的 page 和 router
169
186
  Current.page = this as any
170
187
  setCurrentRouter(this)
171
188
  // 恢复上下文信息
172
- // window.trigger(CONTEXT_ACTIONS.RECOVER, this.$taroPath)
189
+ window.trigger(CONTEXT_ACTIONS.RECOVER, this.$taroPath)
173
190
  // 触发生命周期
174
191
  safeExecute(this.$taroPath, ON_SHOW, options)
175
- // TODO 通过事件触发子组件的生命周期
176
- // raf(() => eventCenter.trigger(getOnShowEventKey(id)))
192
+ // 通过事件触发子组件的生命周期
193
+ requestAnimationFrame(() => eventCenter.trigger(getOnShowEventKey(id)))
177
194
  })
178
195
  },
179
- onHide () {
196
+ [ONHIDE] () {
180
197
  // 缓存当前页面上下文信息
181
- // window.trigger(CONTEXT_ACTIONS.RESTORE, this.$taroPath)
198
+ window.trigger(CONTEXT_ACTIONS.RESTORE, this.$taroPath)
182
199
 
183
200
  // 设置 Current 的 page 和 router
184
201
  if (Current.page === this) {
@@ -188,9 +205,46 @@ export function createPageConfig (component: any, pageName?: string) {
188
205
  // 触发生命周期
189
206
  safeExecute(this.$taroPath, ON_HIDE)
190
207
  // TODO 通过事件触发子组件的生命周期
191
- // eventCenter.trigger(getOnHideEventKey(id))
192
- }
208
+ eventCenter.trigger(getOnHideEventKey(id))
209
+ },
193
210
  }
194
211
 
212
+ LIFECYCLES.forEach((lifecycle) => {
213
+ let isDefer = false
214
+ lifecycle = lifecycle.replace(/^defer:/, () => {
215
+ isDefer = true
216
+ return ''
217
+ })
218
+ page[lifecycle] = function () {
219
+ const exec = () => safeExecute(this.$taroPath, lifecycle, ...arguments)
220
+ if (isDefer) {
221
+ hasLoaded.then(exec)
222
+ } else {
223
+ return exec()
224
+ }
225
+ }
226
+ })
227
+
228
+ // onShareAppMessage 和 onShareTimeline 一样,会影响小程序右上方按钮的选项,因此不能默认注册。
229
+ SIDE_EFFECT_LIFECYCLES.forEach(lifecycle => {
230
+ if (component[lifecycle] ||
231
+ component.prototype?.[lifecycle] ||
232
+ component[lifecycle.replace(/^on/, 'enable')] ||
233
+ pageConfig?.[lifecycle.replace(/^on/, 'enable')]
234
+ ) {
235
+ page[lifecycle] = function (...args) {
236
+ const target = args[0]?.target as any
237
+ if (target?.id) {
238
+ const id = target.id
239
+ const element = env.document.getElementById(id)
240
+ if (element) {
241
+ target.dataset = element.dataset
242
+ }
243
+ }
244
+ return safeExecute(this.$taroPath, lifecycle, ...args)
245
+ }
246
+ }
247
+ })
248
+
195
249
  return page
196
250
  }
@@ -5,27 +5,32 @@ import type { Style, TaroElement } from '@tarojs/runtime'
5
5
 
6
6
  export type Props = Record<string, unknown>
7
7
 
8
+ const isHarmony = process.env.TARO_PLATFORM === 'harmony'
9
+ const IS_NON_DIMENSIONAL = /max|aspect|acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i
10
+
8
11
  function isEventName (s: string) {
9
12
  return s[0] === 'o' && s[1] === 'n'
10
13
  }
11
14
 
12
- const IS_NON_DIMENSIONAL = /max|aspect|acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i
15
+ function isEqual (obj1, obj2) {
16
+ return JSON.stringify(obj1) === JSON.stringify(obj2)
17
+ }
13
18
 
14
19
  export function updateProps (dom: TaroElement, oldProps: Props, newProps: Props) {
15
20
  const updatePayload = getUpdatePayload(dom, oldProps, newProps)
16
- if (updatePayload){
21
+ if (updatePayload) {
17
22
  updatePropsByPayload(dom, oldProps, updatePayload)
18
23
  }
19
24
  }
20
25
 
21
- export function updatePropsByPayload (dom: TaroElement, oldProps: Props, updatePayload: any[]){
22
- for (let i = 0; i < updatePayload.length; i += 2){ // key, value 成对出现
23
- const key = updatePayload[i]; const newProp = updatePayload[i+1]; const oldProp = oldProps[key]
26
+ export function updatePropsByPayload (dom: TaroElement, oldProps: Props, updatePayload: any[]) {
27
+ for (let i = 0; i < updatePayload.length; i += 2) { // key, value 成对出现
28
+ const key = updatePayload[i]; const newProp = updatePayload[i + 1]; const oldProp = oldProps[key]
24
29
  setProperty(dom, key, newProp, oldProp)
25
30
  }
26
31
  }
27
32
 
28
- export function getUpdatePayload (dom: TaroElement, oldProps: Props, newProps: Props){
33
+ export function getUpdatePayload (dom: TaroElement, oldProps: Props, newProps: Props) {
29
34
  let i: string
30
35
  let updatePayload: any[] | null = null
31
36
 
@@ -59,12 +64,11 @@ function setEvent (dom: TaroElement, name: string, value: unknown, oldValue?: un
59
64
 
60
65
  const compName = capitalize(toCamelCase(dom.tagName.toLowerCase()))
61
66
 
62
- if (eventName === 'click' && compName in internalComponents) {
67
+ if (eventName === 'click' && !isHarmony && compName in internalComponents) {
63
68
  eventName = 'tap'
64
69
  }
65
70
 
66
71
  if (isFunction(value)) {
67
- const isHarmony = process.env.TARO_PLATFORM === 'harmony'
68
72
  if (oldValue) {
69
73
  dom.removeEventListener(eventName, oldValue as any, !isHarmony ? false : undefined)
70
74
  dom.addEventListener(eventName, value, !isHarmony ? { isCapture, sideEffect: false } : undefined)
@@ -76,19 +80,24 @@ function setEvent (dom: TaroElement, name: string, value: unknown, oldValue?: un
76
80
  }
77
81
  }
78
82
 
79
- function setStyle (style: Style, key: string, value: string | number) {
80
- if (key[0] === '-') {
81
- style.setProperty(key, value.toString())
83
+ function setStyle (style: Style, key: string, value: unknown) {
84
+ if (key[0] === '-' && !isHarmony) {
82
85
  // css variables need not further judgment
86
+ style.setProperty(key, (value as string).toString())
83
87
  return
84
88
  }
85
89
 
86
- style[key] =
87
- isNumber(value) && IS_NON_DIMENSIONAL.test(key) === false
88
- ? convertNumber2PX(value)
89
- : value == null
90
- ? ''
91
- : value
90
+ if (isHarmony && key.startsWith('_')) {
91
+ // harmony样式已处理
92
+ style[key] = value == null ? '' : value
93
+ } else {
94
+ style[key] =
95
+ isNumber(value) && IS_NON_DIMENSIONAL.test(key) === false
96
+ ? convertNumber2PX(value)
97
+ : value == null
98
+ ? ''
99
+ : value
100
+ }
92
101
  }
93
102
 
94
103
  type StyleValue = Record<string, string | number>
@@ -99,13 +108,9 @@ interface DangerouslySetInnerHTML {
99
108
  export function setProperty (dom: TaroElement, name: string, value: unknown, oldValue?: unknown) {
100
109
  name = name === 'className' ? 'class' : name
101
110
 
102
- if (
103
- name === 'key' ||
104
- name === 'children' ||
105
- name === 'ref'
106
- ) {
107
- // skip
108
- } else if (name === 'style') {
111
+ if (['key', 'children', 'ref'].includes(name)) return
112
+
113
+ if (name === 'style') {
109
114
  const style = dom.style
110
115
  if (isString(value)) {
111
116
  style.cssText = value
@@ -118,6 +123,7 @@ export function setProperty (dom: TaroElement, name: string, value: unknown, old
118
123
  if (isObject<StyleValue>(oldValue)) {
119
124
  for (const i in oldValue) {
120
125
  if (!(value && i in (value as StyleValue))) {
126
+ // harmony设置style,路径设置路径如下:dom.style => cssStyleDeclaration.setProperty => convertWebStyle2HmStyle => dom._st.hmStyle
121
127
  setStyle(style, i, '')
122
128
  }
123
129
  }
@@ -125,12 +131,40 @@ export function setProperty (dom: TaroElement, name: string, value: unknown, old
125
131
 
126
132
  if (isObject<StyleValue>(value)) {
127
133
  for (const i in value) {
128
- if (!oldValue || value[i] !== (oldValue as StyleValue)[i]) {
134
+ if (!oldValue || !isEqual(value[i], (oldValue as StyleValue)[i])) {
129
135
  setStyle(style, i, value[i])
130
136
  }
131
137
  }
132
138
  }
133
139
  }
140
+ } else if (name === '__hmStyle') {
141
+ // 鸿蒙样式特殊处理
142
+ // @ts-ignore
143
+ const style = dom._st.hmStyle // __hmStyle是已经被处理过的鸿蒙样式,可以直接塞进hmStyle对象内
144
+ if (isObject<StyleValue>(oldValue)) {
145
+ for (const i in oldValue) {
146
+ if (!(value && i in (value as StyleValue))) {
147
+ // 鸿蒙伪类特殊处理
148
+ if (isHarmony && (i === '::after' || i === '::before')) {
149
+ setPseudo(dom, i, null)
150
+ } else {
151
+ style[i] = ''
152
+ }
153
+ }
154
+ }
155
+ }
156
+ if (isObject<StyleValue>(value)) {
157
+ for (const i in value) {
158
+ if (!oldValue || !isEqual(value[i], (oldValue as StyleValue)[i])) {
159
+ // 鸿蒙伪类特殊处理
160
+ if (isHarmony && (i === '::after' || i === '::before')) {
161
+ setPseudo(dom, i, value[i] as unknown as StyleValue)
162
+ } else {
163
+ style[i] = value[i]
164
+ }
165
+ }
166
+ }
167
+ }
134
168
  } else if (isEventName(name)) {
135
169
  setEvent(dom, name, value, oldValue)
136
170
  } else if (name === 'dangerouslySetInnerHTML') {
@@ -149,3 +183,14 @@ export function setProperty (dom: TaroElement, name: string, value: unknown, old
149
183
  }
150
184
  }
151
185
  }
186
+
187
+ // 设置鸿蒙伪类属性(特殊设置)
188
+ function setPseudo(dom: TaroElement, name: '::after' | '::before', value: StyleValue | null) {
189
+ if (name === '::after') {
190
+ // @ts-ignore
191
+ dom.set_pseudo_after(value)
192
+ } else if (name === '::before') {
193
+ // @ts-ignore
194
+ dom.set_pseudo_before(value)
195
+ }
196
+ }