@tarojs/plugin-platform-harmony-ets 4.0.0-beta.3 → 4.0.0-beta.31

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 (103) hide show
  1. package/dist/apis/base/system.ts +53 -20
  2. package/dist/apis/canvas/index.ts +10 -1
  3. package/dist/apis/framework/index.ts +1 -5
  4. package/dist/apis/index.ts +27 -12
  5. package/dist/apis/network/request.ts +5 -5
  6. package/dist/apis/route/index.ts +15 -0
  7. package/dist/apis/storage/index.ts +205 -63
  8. package/dist/apis/ui/animation/animation.ts +2 -1
  9. package/dist/apis/utils/index.ts +1 -1
  10. package/dist/apis/wxml/IntersectionObserver.ts +18 -10
  11. package/dist/apis/wxml/index.ts +2 -0
  12. package/dist/components-harmony-ets/button.ets +50 -78
  13. package/dist/components-harmony-ets/canvas.ets +51 -0
  14. package/dist/components-harmony-ets/checkbox.ets +23 -209
  15. package/dist/components-harmony-ets/form.ets +44 -158
  16. package/dist/components-harmony-ets/icon.ets +38 -83
  17. package/dist/components-harmony-ets/image.ets +29 -78
  18. package/dist/components-harmony-ets/index.ets +53 -0
  19. package/dist/components-harmony-ets/innerHtml.ets +11 -6
  20. package/dist/components-harmony-ets/input.ets +11 -67
  21. package/dist/components-harmony-ets/label.ets +58 -172
  22. package/dist/components-harmony-ets/movableArea.ets +96 -0
  23. package/dist/components-harmony-ets/movableView.ets +74 -0
  24. package/dist/components-harmony-ets/picker.ets +32 -147
  25. package/dist/components-harmony-ets/progress.ets +54 -0
  26. package/dist/components-harmony-ets/pseudo.ets +80 -0
  27. package/dist/components-harmony-ets/radio.ets +23 -210
  28. package/dist/components-harmony-ets/richText.ets +22 -102
  29. package/dist/components-harmony-ets/scrollView.ets +73 -169
  30. package/dist/components-harmony-ets/slider.ets +11 -72
  31. package/dist/components-harmony-ets/style.ets +280 -0
  32. package/dist/components-harmony-ets/swiper.ets +37 -87
  33. package/dist/components-harmony-ets/switch.ets +11 -71
  34. package/dist/components-harmony-ets/text.ets +57 -89
  35. package/dist/components-harmony-ets/textArea.ets +11 -67
  36. package/dist/components-harmony-ets/utils/AttributeManager.ets +1 -1
  37. package/dist/components-harmony-ets/utils/DynamicCenter.ts +1 -1
  38. package/dist/components-harmony-ets/utils/flexManager.ets +11 -9
  39. package/dist/components-harmony-ets/utils/helper.ets +4 -5
  40. package/dist/components-harmony-ets/utils/htmlParser/HarmonyHTMLParser.ts +1 -2
  41. package/dist/components-harmony-ets/utils/htmlParser/index.ts +1 -1
  42. package/dist/components-harmony-ets/utils/index.ts +50 -51
  43. package/dist/components-harmony-ets/utils/styles.ets +167 -87
  44. package/dist/components-harmony-ets/video.ets +41 -89
  45. package/dist/components-harmony-ets/view.ets +53 -159
  46. package/dist/components-harmony-ets/webView.ets +44 -99
  47. package/dist/index.d.ts +151 -0
  48. package/dist/index.js +69 -32
  49. package/dist/index.js.map +1 -1
  50. package/dist/runtime-ets/bom/window.ts +7 -0
  51. package/dist/runtime-ets/current.ts +3 -0
  52. package/dist/runtime-ets/dom/bind.ts +20 -6
  53. package/dist/runtime-ets/dom/cssNesting.ts +393 -0
  54. package/dist/runtime-ets/dom/cssStyleDeclaration.ts +12 -40
  55. package/dist/runtime-ets/dom/document.ts +22 -8
  56. package/dist/runtime-ets/dom/element/canvas.ts +136 -0
  57. package/dist/runtime-ets/dom/element/element.ts +128 -51
  58. package/dist/runtime-ets/dom/element/form.ts +15 -18
  59. package/dist/runtime-ets/dom/element/index.ts +16 -3
  60. package/dist/runtime-ets/dom/element/movableArea.ts +12 -0
  61. package/dist/runtime-ets/dom/element/movableView.ts +193 -0
  62. package/dist/runtime-ets/dom/element/normal.ts +8 -3
  63. package/dist/runtime-ets/dom/element/progress.ts +12 -0
  64. package/dist/runtime-ets/dom/element/scrollView.ts +1 -0
  65. package/dist/runtime-ets/dom/element/text.ts +1 -8
  66. package/dist/runtime-ets/dom/element/video.ts +5 -3
  67. package/dist/runtime-ets/dom/element/webView.ts +8 -0
  68. package/dist/runtime-ets/dom/event.ts +0 -1
  69. package/dist/runtime-ets/dom/eventTarget.ts +0 -3
  70. package/dist/runtime-ets/dom/node.ts +29 -27
  71. package/dist/runtime-ets/dom/stylesheet/covertWeb2Hm.ts +189 -211
  72. package/dist/runtime-ets/dom/stylesheet/index.ts +28 -308
  73. package/dist/runtime-ets/dom/stylesheet/type.ts +18 -6
  74. package/dist/runtime-ets/dom/stylesheet/util.ts +31 -25
  75. package/dist/runtime-ets/index.ts +2 -2
  76. package/dist/runtime-ets/interface/event.ts +1 -1
  77. package/dist/runtime-ets/utils/index.ts +43 -10
  78. package/dist/runtime-ets/utils/info.ts +1 -1
  79. package/dist/runtime-framework/react/app.ts +7 -2
  80. package/dist/runtime-framework/react/index.ts +0 -2
  81. package/dist/runtime-framework/react/native-page.ts +22 -12
  82. package/dist/runtime-framework/react/page.ts +3 -8
  83. package/dist/runtime-framework/solid/app.ts +25 -45
  84. package/dist/runtime-framework/solid/connect.ts +21 -3
  85. package/dist/runtime-framework/solid/hooks.ts +16 -11
  86. package/dist/runtime-framework/solid/index.ts +6 -2
  87. package/dist/runtime-framework/solid/page.ts +84 -30
  88. package/dist/runtime-framework/solid/reconciler/props.ts +65 -20
  89. package/dist/runtime-framework/solid/reconciler/render.ts +16 -6
  90. package/dist/runtime-framework/solid/reconciler/use.ts +0 -1
  91. package/dist/runtime-framework/solid/utils/index.ts +0 -2
  92. package/dist/runtime-utils.d.ts +827 -0
  93. package/dist/runtime-utils.js +273 -109
  94. package/dist/runtime-utils.js.map +1 -1
  95. package/dist/runtime.d.ts +1 -0
  96. package/dist/runtime.js +273 -109
  97. package/dist/runtime.js.map +1 -1
  98. package/index.js +3 -1
  99. package/package.json +13 -13
  100. package/types/index.d.ts +4 -0
  101. package/dist/runtime-ets/utils/bind.ts +0 -24
  102. /package/dist/components-harmony-ets/{index.ts → tag.ts} +0 -0
  103. /package/dist/runtime-framework/solid/{contant.ts → constant.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  // @ts-nocheck
2
- import matrix4 from '@ohos.matrix4'
2
+ // import matrix4 from '@ohos.matrix4'
3
3
  import { isNumber } from '@tarojs/shared'
4
4
 
5
5
  import { convertNumber2VP } from '../../'
@@ -163,7 +163,6 @@ export class FlexManager {
163
163
  }
164
164
  }
165
165
 
166
-
167
166
  export class BORDER_STYLE_MAP {
168
167
  static solid = BorderStyle.Solid
169
168
  static dotted = BorderStyle.Dotted
@@ -184,39 +183,39 @@ export class BORDER_STYLE_MAP {
184
183
  case BorderStyle.Solid: return 'solid'
185
184
  default: return ''
186
185
  }
187
-
188
186
  }
189
187
  }
190
188
 
191
-
192
189
  export function getNodeMarginOrPaddingData (dataValue: string) {
193
190
  let res: any = {}
194
191
  if (dataValue) {
195
- const values = dataValue.trim().split(new RegExp('\\s+'))
192
+ const values = dataValue.toString().trim().split(new RegExp('\\s+'))
193
+ let val1: string
194
+ let val2: string
196
195
  switch (values.length) {
197
196
  case 1:
198
- res = { top: values[0], right: values[0], bottom: values[0], left: values[0] }
197
+ val1 = getUnit(values[0])
198
+ res = { top: val1, right: val1, bottom: val1, left: val1 }
199
199
  break
200
200
  case 2:
201
- res = { top: values[0], right: values[1], bottom: values[0], left: values[1] }
201
+ val1 = getUnit(values[0])
202
+ val2 = getUnit(values[1])
203
+ res = { top: val1, right: val2, bottom: val1, left: val2 }
202
204
  break
203
205
  case 3:
204
- res = { top: values[0], right: values[1], bottom: values[2], left: values[1] }
206
+ val2 = getUnit(values[1])
207
+ res = { top: getUnit(values[0]), right: val2, bottom: getUnit(values[2]), left: val2 }
205
208
  break
206
209
  case 4:
207
- res = { top: values[0], right: values[1], bottom: values[2], left: values[3] }
210
+ res = { top: getUnit(values[0]), right: getUnit(values[1]), bottom: getUnit(values[2]), left: getUnit(values[3]) }
208
211
  break
209
212
  default:
210
213
  break
211
214
  }
212
- Object.keys(res).forEach(key => {
213
- res[key] = getUnit(res[key]) || 0
214
- })
215
215
  }
216
216
  return res
217
217
  }
218
218
 
219
-
220
219
  export function getUnit (val) {
221
220
  // 空的字符串代表 Reconciler remove 了这个 prop,不进行后面的逻辑了
222
221
  if (val === '') return val
@@ -228,9 +227,9 @@ export function getUnit (val) {
228
227
  }
229
228
  if (val) {
230
229
  // 匹配vw\vh
231
- const exec = val.match(/(\d+)(vw|vh|px)$/)
230
+ const exec = val.match(/(-?\d*(\.\d+)?)(vw|vh|px)$/)
232
231
  if (exec) {
233
- const [, num, unit] = exec
232
+ const [, num, , unit] = exec
234
233
  return convertNumber2VP(parseFloat(num), unit)
235
234
  }
236
235
  }
@@ -238,19 +237,26 @@ export function getUnit (val) {
238
237
  }
239
238
 
240
239
  export function getTransform(transform) {
240
+ // if (transform) {
241
+ // return transform.reduce((res, item) => {
242
+ // switch (item.type) {
243
+ // case 'Translate': return res.translate(item.value)
244
+ // case 'Scale': return res.scale(item.value)
245
+ // case 'Rotate': return res.rotate(item.value)
246
+ // case 'Matrix': return res.combine(matrix4.init(item.value))
247
+ // }
248
+ // return res
249
+ // }, matrix4.identity())
250
+ // }
251
+ const result = {}
241
252
  if (transform) {
242
- return transform.reduce((res, item) => {
243
- switch (item.type) {
244
- case 'Translate': return res.translate(item.value)
245
- case 'Scale': return res.scale(item.value)
246
- case 'Rotate': return res.rotate(item.value)
247
- case 'Matrix': return res.combine(matrix4.init(item.value))
248
- }
249
- return res
250
- }, matrix4.identity())
253
+ transform.forEach((item) => {
254
+ result[item.type] = item.value
255
+ })
256
+ return result
251
257
  }
252
258
  }
253
259
 
254
260
  export function capitalizeFirstLetter (str: string) {
255
261
  return str.charAt(0).toUpperCase() + str.slice(1)
256
- }
262
+ }
@@ -10,9 +10,9 @@ export * from './dom/element'
10
10
  export * from './dom/event'
11
11
  export * from './dom/node'
12
12
  export * from './dom/stylesheet'
13
+ export * from './dom/cssNesting'
13
14
  export * from './interface'
14
15
  export * from './utils'
15
- export * from './utils/bind'
16
16
  export * from './utils/info'
17
- export { URLSearchParams, eventSource } from '@tarojs/runtime/dist/runtime.esm'
17
+ export { URL, URLSearchParams, eventSource, Events } from '@tarojs/runtime/dist/runtime.esm'
18
18
  export { hooks } from '@tarojs/shared'
@@ -7,4 +7,4 @@ export interface EventOptions {
7
7
  export interface EventHandler<T = any, R = void> {
8
8
  (...args: T[]): R
9
9
  _stop?: boolean
10
- }
10
+ }
@@ -42,24 +42,54 @@ export function convertNumber2VP (value: number, unit = 'px') {
42
42
  if (unit === 'vw' || unit === 'vh') {
43
43
  return (value / 100 * (unit === 'vw' ? display.width: display.height)) + 'px'
44
44
  }
45
+ if (unit === 'PX') {
46
+ // 特殊单位:相当于PX、pX、Px
47
+ return pxTransformHelper(value, 'PX')
48
+ }
45
49
  return pxTransformHelper(value, 'vp')
46
50
  }
47
51
 
48
- export function calcDynamicStyle (styleSheet: Record<string, CSSProperties>, classNames: string, style: CSSProperties): CSSProperties {
52
+ export function parseClasses (classNames: string | string[] = []): string[] {
53
+ if (typeof classNames === 'string') {
54
+ return classNames.includes(' ') ? classNames.split(' ') : [classNames]
55
+ } else if (Array.isArray(classNames)) {
56
+ return classNames // Note: 不考虑支持单个元素传入多个类名的情况,过于损耗性能
57
+ }
58
+
59
+ return []
60
+ }
61
+
62
+ // 合并静态样式,从样式表里面找到对应的样式
63
+ export function calcStaticStyle (styleSheet: Record<string, CSSProperties>, classNames: string | string[] = [], style: CSSProperties): CSSProperties {
49
64
  const obj: CSSProperties[] = []
50
- const classes = typeof classNames === 'string' ? classNames.split(' ') : []
51
- for (let i = 0; i < classes.length; i++) {
52
- const className = classes[i]
53
- if (styleSheet[className]) {
54
- obj.push(styleSheet[className])
65
+ const classes = parseClasses(classNames)
66
+ if (classes.length === 1) {
67
+ if (style) {
68
+ return Object.assign({}, styleSheet[classes[0]], style)
69
+ } else {
70
+ // 同一个引用
71
+ return styleSheet[classes[0]]
72
+ }
73
+ } else {
74
+ for (let i = 0; i < classes.length; i++) {
75
+ const className = classes[i]
76
+ if (styleSheet[className]) {
77
+ obj.push(styleSheet[className])
78
+ }
79
+ }
80
+ if (style) {
81
+ obj.push(style)
55
82
  }
83
+ return Object.assign.apply(null, [{}].concat(obj))
56
84
  }
85
+ }
57
86
 
87
+ // 动态样式计算,需要经过web2harmony进行反转
88
+ export function calcDynamicStyle (style: CSSProperties): CSSProperties {
58
89
  if (style) {
59
- obj.push(convertWebStyle2HmStyle(style))
90
+ return convertWebStyle2HmStyle(style)
60
91
  }
61
-
62
- return Object.assign.apply(null, [{}].concat(obj))
92
+ return {}
63
93
  }
64
94
 
65
95
  export function getPageScrollerOrNode (scrollerOrNode: any, page: any) {
@@ -76,6 +106,10 @@ export function getPageScrollerOrNode (scrollerOrNode: any, page: any) {
76
106
  return scrollerOrNode
77
107
  }
78
108
 
109
+ export function ObjectKeys(obj: object): string[] {
110
+ return Object.keys(obj)
111
+ }
112
+
79
113
  export function ObjectAssign(...objects) {
80
114
  return Object.assign.apply(this, [{}].concat(...objects))
81
115
  }
@@ -91,7 +125,6 @@ export function bindFn (fn: any, ctx: any, ...args: any) {
91
125
  }
92
126
  }
93
127
 
94
-
95
128
  // 使用深度优先遍历寻找节点树中对应的子节点,且只需要找到第一个
96
129
  // 通过 selector 判断是 id 还是 selector,从 node 的 id 和 className 属性中寻找
97
130
  export function findChildNodeWithDFS<T extends TaroElement = TaroElement> (node: TaroElement, selector: string | ((ele: T) => boolean), selectAll: true): T[] | null;
@@ -50,7 +50,7 @@ function tapCallbackToNodeAndUpdate (node: TaroElement, eventName: string, callb
50
50
  callback && callback(...eventResult)
51
51
  }
52
52
 
53
- if (!node._isDynamicNode || !node._isCompileMode) {
53
+ if (!node._isDynamicNode && node._isCompileMode) {
54
54
  node.updateComponent()
55
55
  }
56
56
  }
@@ -1,10 +1,11 @@
1
1
  import { Current, document } from '@tarojs/runtime' // eslint-disable-line import/no-duplicates
2
- import { AppInstance, eventCenter } from '@tarojs/runtime/dist/runtime.esm' // eslint-disable-line import/no-duplicates
2
+ import { eventCenter } from '@tarojs/runtime/dist/runtime.esm' // eslint-disable-line import/no-duplicates
3
3
 
4
4
  import { setReconciler } from './connect'
5
5
  import { injectPageInstance } from './page'
6
6
  import { EMPTY_OBJ, incrementId, isClassComponent } from './utils'
7
7
 
8
+ import type { AppInstance } from '@tarojs/runtime'
8
9
  import type React from 'react'
9
10
 
10
11
  let h: typeof React.createElement
@@ -237,7 +238,11 @@ export function createReactApp (
237
238
  }
238
239
  } as unknown as AppInstance
239
240
 
240
- Current.app = app
241
+ if (Current.app) {
242
+ Current.app = Object.assign(app, Current.app)
243
+ } else {
244
+ Current.app = app
245
+ }
241
246
 
242
247
  return app
243
248
  }
@@ -2,8 +2,6 @@ import { hooks } from '@tarojs/shared'
2
2
 
3
3
  import * as taroHooks from './hooks'
4
4
 
5
- // declare const __TARO_FRAMEWORK__: string;
6
-
7
5
  hooks.tap('initNativeApi', function (taro) {
8
6
  for (const hook in taroHooks) {
9
7
  taro[hook] = taroHooks[hook]
@@ -1,15 +1,14 @@
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,
@@ -55,8 +54,6 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
55
54
  this.ctx.component = this
56
55
  const rootElement = this.root.current!
57
56
  rootElement.ctx = this.ctx
58
- // TODO: performUpdate
59
- // rootElement.performUpdate(true)
60
57
  }
61
58
 
62
59
  render () {
@@ -80,13 +77,24 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
80
77
 
81
78
  componentDidMount () {
82
79
  if (isDefaultEntryDom) {
83
- Current.app = this
80
+ if (Current.app) {
81
+ Current.app = Object.assign(this, Current.app)
82
+ } else {
83
+ Current.app = this
84
+ }
84
85
  } else {
85
86
  nativeComponentApp = this
86
87
  }
87
88
  cb && cb()
88
89
  }
89
90
 
91
+ // React 16 uncaught error 会导致整个应用 crash,
92
+ // 目前把错误缩小到页面
93
+ componentDidCatch (error, info: React.ErrorInfo) {
94
+ console.warn(error)
95
+ console.error(info.componentStack)
96
+ }
97
+
90
98
  mount (Component, compId, getCtx, cb?) {
91
99
  const isReactComponent = isClassComponent(R, Component)
92
100
  const inject = (node?: any) => node && injectPageInstance(node, compId)
@@ -153,7 +161,7 @@ function initNativeComponentEntry (params: InitNativeComponentEntryParams) {
153
161
  // create
154
162
  const nativeApp = document.createElement('nativeComponent')
155
163
  // insert
156
- app.appendChild(nativeApp)
164
+ app?.appendChild(nativeApp)
157
165
  app = nativeApp
158
166
  }
159
167
  // eslint-disable-next-line react/no-deprecated
@@ -253,7 +261,7 @@ export function createNativePageConfig (Component, pageName: string, react: type
253
261
  window.trigger(CONTEXT_ACTIONS.DESTORY, $taroPath)
254
262
  // 触发onUnload生命周期
255
263
  safeExecute($taroPath, ONUNLOAD)
256
- resetCurrent()
264
+ resetCurrent.call(this)
257
265
  unmounting = true
258
266
  Current.app!.unmount!($taroPath, () => {
259
267
  unmounting = false
@@ -274,6 +282,7 @@ export function createNativePageConfig (Component, pageName: string, react: type
274
282
  safeExecute(this.$taroPath, ON_READY)
275
283
  // 通过事件触发子组件的生命周期
276
284
  requestAnimationFrame(() => eventCenter.trigger(getOnReadyEventKey(id)))
285
+ this.onReady = {}
277
286
  this.onReady.called = true
278
287
  })
279
288
  },
@@ -306,12 +315,13 @@ export function createNativePageConfig (Component, pageName: string, react: type
306
315
  }
307
316
 
308
317
  function resetCurrent () {
309
- // 小程序插件页面卸载之后返回到宿主页面时,需重置Current页面和路由。否则引发插件组件二次加载异常 fix:#11991
310
- Current.page = null
311
- Current.router = null
318
+ if (Current.page === this) {
319
+ // 小程序插件页面卸载之后返回到宿主页面时,需重置Current页面和路由。否则引发插件组件二次加载异常 fix:#11991
320
+ Current.page = null
321
+ Current.router = null
322
+ }
312
323
  }
313
324
 
314
-
315
325
  LIFECYCLES.forEach((lifecycle) => {
316
326
  pageObj[lifecycle] = function () {
317
327
  return safeExecute(this.$taroPath, lifecycle, ...arguments)
@@ -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-react/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'