@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
@@ -1,19 +1,18 @@
1
1
  import { Current, document, requestAnimationFrame, TaroElement, window } from '@tarojs/runtime' // eslint-disable-line import/no-duplicates
2
- import { CONTEXT_ACTIONS, env, eventCenter, TFunc } from '@tarojs/runtime/dist/runtime.esm' // eslint-disable-line import/no-duplicates
2
+ import { addLeadingSlash, CONTEXT_ACTIONS, env, eventCenter, TFunc } from '@tarojs/runtime/dist/runtime.esm' // eslint-disable-line import/no-duplicates
3
3
  import { ensure, hooks, isUndefined } from '@tarojs/shared'
4
4
 
5
5
  import { ReactMeta as reactMeta } from './app'
6
6
  import { setReconciler } from './connect'
7
7
  import { ON_HIDE, ON_READY, ON_SHOW } from './constant'
8
8
  import {
9
- addLeadingSlash,
10
9
  getOnHideEventKey,
11
10
  getOnReadyEventKey,
12
- getOnShowEventKey,
11
+ getOnShowEventKey,
13
12
  getPath,
14
13
  injectPageInstance,
15
14
  removePageInstance,
16
- safeExecute
15
+ safeExecute,
17
16
  } from './page'
18
17
  import { EMPTY_OBJ, incrementId, isClassComponent } from './utils'
19
18
 
@@ -53,47 +52,64 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
53
52
 
54
53
  componentDidMount () {
55
54
  this.ctx.component = this
56
- const rootElement = this.root.current!
57
- rootElement.ctx = this.ctx
58
- // TODO: performUpdate
59
- // rootElement.performUpdate(true)
55
+ if (this.root.current) {
56
+ this.root.current = this.ctx
57
+ }
58
+ }
59
+
60
+ // React 16 uncaught error 会导致整个应用 crash,
61
+ // 目前把错误缩小到页面
62
+ componentDidCatch (error, info: React.ErrorInfo) {
63
+ console.warn(error)
64
+ console.error(info.componentStack)
60
65
  }
61
66
 
62
67
  render () {
63
- return (
64
- h(
65
- 'view',
66
- {
67
- ref: this.root,
68
- id: this.props.compId
69
- },
70
- this.props.renderComponent(this.ctx)
71
- )
68
+ return h(
69
+ 'view',
70
+ {
71
+ ref: this.root,
72
+ id: this.props.compId,
73
+ },
74
+ this.props.renderComponent(this.ctx)
72
75
  )
73
76
  }
74
77
  }
75
78
 
76
79
  class Entry extends R.Component<Record<any, any>, IEntryState> {
77
80
  state: IEntryState = {
78
- components: []
81
+ components: [],
79
82
  }
80
83
 
81
84
  componentDidMount () {
82
85
  if (isDefaultEntryDom) {
83
- Current.app = this
86
+ if (Current.app) {
87
+ Current.app = Object.assign(this, Current.app)
88
+ } else {
89
+ Current.app = this
90
+ }
84
91
  } else {
85
92
  nativeComponentApp = this
86
93
  }
87
94
  cb && cb()
88
95
  }
89
96
 
97
+ // React 16 uncaught error 会导致整个应用 crash,
98
+ // 目前把错误缩小到页面
99
+ componentDidCatch (error, info: React.ErrorInfo) {
100
+ console.warn(error)
101
+ console.error(info.componentStack)
102
+ }
103
+
90
104
  mount (Component, compId, getCtx, cb?) {
91
105
  const isReactComponent = isClassComponent(R, Component)
92
106
  const inject = (node?: any) => node && injectPageInstance(node, compId)
93
- const refs = isReactComponent ? { ref: inject } : {
94
- forwardedRef: inject,
95
- reactReduxForwardedRef: inject
96
- }
107
+ const refs = isReactComponent
108
+ ? { ref: inject }
109
+ : {
110
+ forwardedRef: inject,
111
+ reactReduxForwardedRef: inject,
112
+ }
97
113
  if (reactMeta.PageContext === EMPTY_OBJ) {
98
114
  reactMeta.PageContext = R.createContext('')
99
115
  }
@@ -107,42 +123,43 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
107
123
  return h(
108
124
  reactMeta.PageContext.Provider,
109
125
  { value: compId },
110
- h(
111
- Component,
112
- {
113
- // TODO: 传递 Props
114
- ...(ctx.props || {}),
115
- ...refs,
116
- $scope: ctx
117
- }
118
- )
126
+ h(Component, {
127
+ // TODO: 传递 Props
128
+ ...(ctx.props || {}),
129
+ ...refs,
130
+ $scope: ctx,
131
+ })
119
132
  )
120
- }
121
- })
133
+ },
134
+ }),
122
135
  }
123
- this.setState({
124
- components: [...this.state.components, item]
125
- }, () => cb && cb())
136
+ this.setState(
137
+ {
138
+ components: [...this.state.components, item],
139
+ },
140
+ () => cb && cb()
141
+ )
126
142
  }
127
143
 
128
144
  unmount (compId, cb?) {
129
145
  const components = this.state.components
130
- const index = components.findIndex(item => item.compId === compId)
146
+ const index = components.findIndex((item) => item.compId === compId)
131
147
  const next = [...components.slice(0, index), ...components.slice(index + 1)]
132
- this.setState({
133
- components: next
134
- }, () => {
135
- removePageInstance(compId)
136
- cb && cb()
137
- })
148
+ this.setState(
149
+ {
150
+ components: next,
151
+ },
152
+ () => {
153
+ removePageInstance(compId)
154
+ cb && cb()
155
+ }
156
+ )
138
157
  }
139
158
 
140
159
  render () {
141
160
  const components = this.state.components
142
161
 
143
- return (
144
- components.map(({ element }) => element)
145
- )
162
+ return components.map(({ element }) => element)
146
163
  }
147
164
  }
148
165
 
@@ -153,30 +170,26 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
153
170
  // create
154
171
  const nativeApp = document.createElement('nativeComponent')
155
172
  // insert
156
- app.appendChild(nativeApp)
173
+ app?.appendChild(nativeApp)
157
174
  app = nativeApp
158
175
  }
159
176
  // eslint-disable-next-line react/no-deprecated
160
- ReactDOM.render(
161
- h(Entry, {}),
162
- app
163
- )
177
+ ReactDOM.render(h(Entry, {}), app)
164
178
  }
165
179
 
166
- export function createNativePageConfig (Component, pageName: string, react: typeof React, reactDOM: typeof ReactDOM, pageConfig) {
180
+ export function createNativePageConfig (
181
+ Component,
182
+ pageName: string,
183
+ react: typeof React,
184
+ reactDOM: typeof ReactDOM,
185
+ pageConfig
186
+ ) {
167
187
  reactMeta.R = react
168
188
  h = react.createElement
169
189
  ReactDOM = reactDOM
170
190
  setReconciler(ReactDOM)
171
- const [
172
- ONLOAD,
173
- ONUNLOAD,
174
- ONREADY,
175
- ONSHOW,
176
- ONHIDE,
177
- LIFECYCLES,
178
- SIDE_EFFECT_LIFECYCLES
179
- ] = hooks.call('getMiniLifecycleImpl')!.page
191
+ const [ONLOAD, ONUNLOAD, ONREADY, ONSHOW, ONHIDE, LIFECYCLES, SIDE_EFFECT_LIFECYCLES] =
192
+ hooks.call('getMiniLifecycleImpl')!.page
180
193
  let unmounting = false
181
194
  let prepareMountList: (() => void)[] = []
182
195
  let pageElement: TaroElement | null = null
@@ -191,7 +204,7 @@ export function createNativePageConfig (Component, pageName: string, react: type
191
204
  $taroPath: page.$taroPath,
192
205
  onReady: getOnReadyEventKey(id),
193
206
  onShow: getOnShowEventKey(id),
194
- onHide: getOnHideEventKey(id)
207
+ onHide: getOnHideEventKey(id),
195
208
  }
196
209
  if (!isUndefined(page.exitState)) {
197
210
  Current.router.exitState = page.exitState
@@ -201,12 +214,14 @@ export function createNativePageConfig (Component, pageName: string, react: type
201
214
  const pageObj: Record<string, any> = {
202
215
  options: pageConfig,
203
216
  [ONLOAD] (options: Readonly<Record<string, unknown>> = {}, cb?: TFunc) {
204
- hasLoaded = new Promise(resolve => { loadResolver = resolve })
217
+ hasLoaded = new Promise((resolve) => {
218
+ loadResolver = resolve
219
+ })
205
220
  Current.page = this as any
206
221
  this.config = pageConfig || {}
207
222
  // this.$taroPath 是页面唯一标识
208
223
  const uniqueOptions = Object.assign({}, options, { $taroTimestamp: Date.now() })
209
- const $taroPath = this.$taroPath = getPath(id, uniqueOptions)
224
+ const $taroPath = (this.$taroPath = getPath(id, uniqueOptions))
210
225
 
211
226
  // this.$taroParams 作为暴露给开发者的页面参数对象,可以被随意修改
212
227
  if (this.$taroParams == null) {
@@ -234,7 +249,7 @@ export function createNativePageConfig (Component, pageName: string, react: type
234
249
  ReactDOM,
235
250
  cb: () => {
236
251
  Current.app!.mount!(Component, $taroPath, () => this, mountCallback)
237
- }
252
+ },
238
253
  })
239
254
  } else {
240
255
  Current.app!.mount!(Component, $taroPath, () => this, mountCallback)
@@ -253,7 +268,7 @@ export function createNativePageConfig (Component, pageName: string, react: type
253
268
  window.trigger(CONTEXT_ACTIONS.DESTORY, $taroPath)
254
269
  // 触发onUnload生命周期
255
270
  safeExecute($taroPath, ONUNLOAD)
256
- resetCurrent()
271
+ resetCurrent.call(this)
257
272
  unmounting = true
258
273
  Current.app!.unmount!($taroPath, () => {
259
274
  unmounting = false
@@ -263,7 +278,7 @@ export function createNativePageConfig (Component, pageName: string, react: type
263
278
  pageElement = null
264
279
  }
265
280
  if (prepareMountList.length) {
266
- prepareMountList.forEach(fn => fn())
281
+ prepareMountList.forEach((fn) => fn())
267
282
  prepareMountList = []
268
283
  }
269
284
  })
@@ -274,6 +289,7 @@ export function createNativePageConfig (Component, pageName: string, react: type
274
289
  safeExecute(this.$taroPath, ON_READY)
275
290
  // 通过事件触发子组件的生命周期
276
291
  requestAnimationFrame(() => eventCenter.trigger(getOnReadyEventKey(id)))
292
+ this.onReady = {}
277
293
  this.onReady.called = true
278
294
  })
279
295
  },
@@ -306,12 +322,13 @@ export function createNativePageConfig (Component, pageName: string, react: type
306
322
  }
307
323
 
308
324
  function resetCurrent () {
309
- // 小程序插件页面卸载之后返回到宿主页面时,需重置Current页面和路由。否则引发插件组件二次加载异常 fix:#11991
310
- Current.page = null
311
- Current.router = null
325
+ if (Current.page === this) {
326
+ // 小程序插件页面卸载之后返回到宿主页面时,需重置Current页面和路由。否则引发插件组件二次加载异常 fix:#11991
327
+ Current.page = null
328
+ Current.router = null
329
+ }
312
330
  }
313
331
 
314
-
315
332
  LIFECYCLES.forEach((lifecycle) => {
316
333
  pageObj[lifecycle] = function () {
317
334
  return safeExecute(this.$taroPath, lifecycle, ...arguments)
@@ -319,11 +336,8 @@ export function createNativePageConfig (Component, pageName: string, react: type
319
336
  })
320
337
 
321
338
  // onShareAppMessage 和 onShareTimeline 一样,会影响小程序右上方按钮的选项,因此不能默认注册。
322
- SIDE_EFFECT_LIFECYCLES.forEach(lifecycle => {
323
- if (Component[lifecycle] ||
324
- Component.prototype?.[lifecycle] ||
325
- Component[lifecycle.replace(/^on/, 'enable')]
326
- ) {
339
+ SIDE_EFFECT_LIFECYCLES.forEach((lifecycle) => {
340
+ if (Component[lifecycle] || Component.prototype?.[lifecycle] || Component[lifecycle.replace(/^on/, 'enable')]) {
327
341
  pageObj[lifecycle] = function (...args) {
328
342
  const target = args[0]?.target
329
343
  if (target?.id) {
@@ -342,3 +356,66 @@ export function createNativePageConfig (Component, pageName: string, react: type
342
356
 
343
357
  return pageObj
344
358
  }
359
+
360
+ export function createNativeComponentConfig (
361
+ Component,
362
+ react: typeof React,
363
+ reactdom,
364
+ componentConfig
365
+ ) {
366
+ reactMeta.R = react
367
+ h = react.createElement
368
+ ReactDOM = reactdom
369
+ setReconciler(ReactDOM)
370
+ const { isNewBlended } = componentConfig
371
+
372
+ const componentObj: Record<string, any> = {
373
+ options: componentConfig,
374
+ onLoad (
375
+ options: Readonly<Record<string, unknown>> = {}, // eslint-disable-line @typescript-eslint/no-unused-vars
376
+ cb?: TFunc
377
+ ) {
378
+ const app = isNewBlended ? nativeComponentApp : Current.app
379
+
380
+ const mountComponent = () => {
381
+ const app = isNewBlended ? nativeComponentApp : Current.app
382
+ const compId = (this.compId = getNativeCompId())
383
+
384
+ this.config = componentConfig
385
+ app!.mount!(
386
+ Component,
387
+ compId,
388
+ () => this,
389
+ () => {
390
+ const el = document.getElementById(compId)
391
+
392
+ if (!el) {
393
+ throw new Error(`没有找到组件实例。`)
394
+ } else {
395
+ el.ctx = this
396
+ cb && cb(el)
397
+ }
398
+ }
399
+ )
400
+ }
401
+
402
+ if (!app) {
403
+ initNativeComponentEntry({
404
+ R: react,
405
+ ReactDOM,
406
+ isDefaultEntryDom: !isNewBlended,
407
+ cb: mountComponent,
408
+ })
409
+ } else {
410
+ mountComponent()
411
+ }
412
+ },
413
+
414
+ onUnload () {
415
+ const app = isNewBlended ? nativeComponentApp : Current.app
416
+ app!.unmount!(this.compId)
417
+ },
418
+ }
419
+
420
+ return componentObj
421
+ }
@@ -1,5 +1,5 @@
1
1
  import { Current, document, requestAnimationFrame, window } from '@tarojs/runtime' // eslint-disable-line import/no-duplicates
2
- import { CONTEXT_ACTIONS, env, eventCenter } from '@tarojs/runtime/dist/runtime.esm' // 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
3
  import { hooks, isArray, isFunction, isUndefined } from '@tarojs/shared'
4
4
 
5
5
  import { ON_HIDE, ON_LOAD, ON_READY, ON_SHOW, ON_UNLOAD } from './constant'
@@ -23,13 +23,6 @@ export function removePageInstance (id: string) {
23
23
  instances.delete(id)
24
24
  }
25
25
 
26
- export function addLeadingSlash (path?: string): string {
27
- if (path == null) {
28
- return ''
29
- }
30
- return path.charAt(0) === '/' ? path : '/' + path
31
- }
32
-
33
26
  export function safeExecute (path: string, lifecycle: string, ...args: unknown[]) {
34
27
  const instance = instances.get(path)
35
28
 
@@ -184,6 +177,8 @@ export function createPageConfig (component: any, pageName?: string, pageConfig?
184
177
  safeExecute(this.$taroPath, ON_READY)
185
178
  // 通过事件触发子组件的生命周期
186
179
  requestAnimationFrame(() => eventCenter.trigger(getOnReadyEventKey(id)))
180
+ this.onReady = {}
181
+ this.onReady.called = true
187
182
  })
188
183
  },
189
184
  [ONSHOW] (options = {}) {
@@ -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,10 +31,7 @@ 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 = 'app'
39
35
 
40
36
  if (ReactMeta.Container === EMPTY_OBJ) {
41
37
  const Container = document.createElement('view')
@@ -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,29 @@ 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('root', { id }, children)
79
72
  },
80
73
  }),
81
74
  })
82
75
  }
83
76
 
84
- if (!isWeb) {
85
- renderReactRoot()
86
- }
87
-
88
- const [ONLAUNCH, ONSHOW, ONHIDE] = hooks.call('getMiniLifecycleImpl')!.app
77
+ renderReactRoot()
89
78
 
90
- const appObj: AppInstance = Object.create(
79
+ const app: AppInstance = Object.create(
91
80
  {
92
- mount(component: Component, id: string, cb: () => void) {
81
+ mount(component: SolidComponent, id: string, cb: () => void) {
93
82
  setPages((old) => [
94
83
  ...old,
95
84
  { id, component },
96
85
  ])
97
86
  batch(cb)
98
87
  },
99
-
100
88
  unmount(id: string, cb: () => void) {
101
- setPages(
102
- pages().filter((item) => {
103
- return item.id !== id
104
- })
105
- )
89
+ const idx = elements().findIndex((item) => item.id === id)
90
+ setElements((old) => {
91
+ old.splice(idx, 1)
92
+ return old
93
+ })
106
94
  batch(cb)
107
95
  },
108
96
  },
@@ -112,15 +100,10 @@ export function createSolidApp(App: Component, config: AppConfig) {
112
100
  value: config,
113
101
  }),
114
102
 
115
- [ONLAUNCH]: setDefaultDescriptor({
103
+ onLaunch: setDefaultDescriptor({
116
104
  value(options) {
117
105
  setRouterParams(options)
118
106
 
119
- if (isWeb) {
120
- // 由于 H5 路由初始化的时候会清除 app 下的 dom 元素,所以需要在路由初始化后执行 render
121
- renderReactRoot()
122
- }
123
-
124
107
  const onLaunch = () => {
125
108
  const app = getAppInstance()
126
109
 
@@ -151,28 +134,25 @@ export function createSolidApp(App: Component, config: AppConfig) {
151
134
 
152
135
  onLaunch()
153
136
  triggerAppHook('onLaunch', options)
137
+ eventCenter.trigger('__taroRouterLaunch', options)
154
138
  },
155
139
  }),
156
-
157
- [ONSHOW]: setDefaultDescriptor({
140
+ onShow: setDefaultDescriptor({
158
141
  value(options) {
159
142
  setRouterParams(options)
160
143
  triggerAppHook('onShow', options)
161
144
  },
162
145
  }),
163
-
164
- [ONHIDE]: setDefaultDescriptor({
146
+ onHide: setDefaultDescriptor({
165
147
  value() {
166
148
  triggerAppHook('onHide')
167
149
  },
168
150
  }),
169
-
170
151
  onError: setDefaultDescriptor({
171
152
  value(error: string) {
172
153
  triggerAppHook('onError', error)
173
154
  },
174
155
  }),
175
-
176
156
  onPageNotFound: setDefaultDescriptor({
177
157
  value(res: unknown) {
178
158
  triggerAppHook('onPageNotFound', res)
@@ -195,6 +175,6 @@ export function createSolidApp(App: Component, config: AppConfig) {
195
175
  }
196
176
  }
197
177
 
198
- Current.app = appObj
199
- return appObj
178
+ Current.app = app
179
+ return app
200
180
  }
@@ -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
- PageLifeCycle,
5
- TFunc
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,6 +10,12 @@ 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
20
  return (fn: TFunc) => {
20
21
  const id = ReactMeta.PageContext || HOOKS_APP_ID
@@ -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'