@tarojs/plugin-platform-harmony-cpp 4.1.0 → 4.1.1-alpha.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 (223) hide show
  1. package/dist/index.js +1237 -0
  2. package/dist/runtime/apis/apis.ts +20 -0
  3. package/dist/runtime/apis/base/crypto.ts +4 -0
  4. package/dist/runtime/apis/base/debug.ts +5 -0
  5. package/dist/runtime/apis/base/index.ts +13 -0
  6. package/dist/runtime/apis/base/performance.ts +8 -0
  7. package/dist/runtime/apis/base/system.ts +181 -0
  8. package/dist/runtime/apis/base/update.ts +5 -0
  9. package/dist/runtime/apis/base/weapp/app-event.ts +75 -0
  10. package/dist/runtime/apis/base/weapp/life-cycle.ts +21 -0
  11. package/dist/runtime/apis/canvas/index.ts +27 -0
  12. package/dist/runtime/apis/data-analysis/index.ts +6 -0
  13. package/dist/runtime/apis/device/accelerometer.ts +79 -0
  14. package/dist/runtime/apis/device/accessibility.ts +4 -0
  15. package/dist/runtime/apis/device/battery.ts +24 -0
  16. package/dist/runtime/apis/device/bluetooth-ble.ts +19 -0
  17. package/dist/runtime/apis/device/bluetooth-peripheral.ts +6 -0
  18. package/dist/runtime/apis/device/bluetooth.ts +16 -0
  19. package/dist/runtime/apis/device/calendar.ts +5 -0
  20. package/dist/runtime/apis/device/clipboard.ts +85 -0
  21. package/dist/runtime/apis/device/compass.ts +21 -0
  22. package/dist/runtime/apis/device/contact.ts +5 -0
  23. package/dist/runtime/apis/device/crypto.ts +4 -0
  24. package/dist/runtime/apis/device/gyroscope.ts +77 -0
  25. package/dist/runtime/apis/device/iBeacon.ts +10 -0
  26. package/dist/runtime/apis/device/index.ts +24 -0
  27. package/dist/runtime/apis/device/keyboard.ts +63 -0
  28. package/dist/runtime/apis/device/memory.ts +11 -0
  29. package/dist/runtime/apis/device/motion.ts +6 -0
  30. package/dist/runtime/apis/device/network.ts +123 -0
  31. package/dist/runtime/apis/device/nfc.ts +10 -0
  32. package/dist/runtime/apis/device/phone.ts +44 -0
  33. package/dist/runtime/apis/device/scan.ts +4 -0
  34. package/dist/runtime/apis/device/screen.ts +80 -0
  35. package/dist/runtime/apis/device/sms.ts +4 -0
  36. package/dist/runtime/apis/device/vibrate.ts +32 -0
  37. package/dist/runtime/apis/device/wifi.ts +15 -0
  38. package/dist/runtime/apis/ext/index.ts +5 -0
  39. package/dist/runtime/apis/files/index.ts +136 -0
  40. package/dist/runtime/apis/files/manager.ts +942 -0
  41. package/dist/runtime/apis/framework/index.ts +48 -0
  42. package/dist/runtime/apis/harmony/task-pool.ts +39 -0
  43. package/dist/runtime/apis/index.ts +61 -0
  44. package/dist/runtime/apis/location/index.ts +133 -0
  45. package/dist/runtime/apis/media/EditorContext.ts +32 -0
  46. package/dist/runtime/apis/media/audio/index.ts +36 -0
  47. package/dist/runtime/apis/media/background-audio/index.ts +16 -0
  48. package/dist/runtime/apis/media/camera.ts +16 -0
  49. package/dist/runtime/apis/media/common.ts +58 -0
  50. package/dist/runtime/apis/media/image/index.ts +291 -0
  51. package/dist/runtime/apis/media/index.ts +13 -0
  52. package/dist/runtime/apis/media/live.ts +5 -0
  53. package/dist/runtime/apis/media/map.ts +4 -0
  54. package/dist/runtime/apis/media/media-recorder.ts +4 -0
  55. package/dist/runtime/apis/media/recorder.ts +6 -0
  56. package/dist/runtime/apis/media/video/VideoContext.ts +67 -0
  57. package/dist/runtime/apis/media/video/index.ts +45 -0
  58. package/dist/runtime/apis/media/video-decoder.ts +4 -0
  59. package/dist/runtime/apis/media/video-processing.ts +4 -0
  60. package/dist/runtime/apis/media/voip.ts +19 -0
  61. package/dist/runtime/apis/navigate/index.ts +8 -0
  62. package/dist/runtime/apis/network/downloadFile.ts +85 -0
  63. package/dist/runtime/apis/network/index.ts +7 -0
  64. package/dist/runtime/apis/network/mdns.ts +13 -0
  65. package/dist/runtime/apis/network/request.ts +140 -0
  66. package/dist/runtime/apis/network/tcp.ts +4 -0
  67. package/dist/runtime/apis/network/udp.ts +4 -0
  68. package/dist/runtime/apis/network/uploadFile.ts +105 -0
  69. package/dist/runtime/apis/network/webSocket.ts +126 -0
  70. package/dist/runtime/apis/open-api/account.ts +4 -0
  71. package/dist/runtime/apis/open-api/address.ts +4 -0
  72. package/dist/runtime/apis/open-api/authorize.ts +5 -0
  73. package/dist/runtime/apis/open-api/card.ts +5 -0
  74. package/dist/runtime/apis/open-api/channels-live.ts +11 -0
  75. package/dist/runtime/apis/open-api/customer-service.ts +4 -0
  76. package/dist/runtime/apis/open-api/device-voip.ts +5 -0
  77. package/dist/runtime/apis/open-api/facial.ts +7 -0
  78. package/dist/runtime/apis/open-api/favorites.ts +5 -0
  79. package/dist/runtime/apis/open-api/group.ts +4 -0
  80. package/dist/runtime/apis/open-api/index.ts +21 -0
  81. package/dist/runtime/apis/open-api/invoice.ts +5 -0
  82. package/dist/runtime/apis/open-api/license-plate.ts +4 -0
  83. package/dist/runtime/apis/open-api/login.ts +6 -0
  84. package/dist/runtime/apis/open-api/my-miniprogram.ts +4 -0
  85. package/dist/runtime/apis/open-api/privacy.ts +7 -0
  86. package/dist/runtime/apis/open-api/red-package.ts +4 -0
  87. package/dist/runtime/apis/open-api/settings.ts +5 -0
  88. package/dist/runtime/apis/open-api/soter.ts +6 -0
  89. package/dist/runtime/apis/open-api/subscribe-message.ts +6 -0
  90. package/dist/runtime/apis/open-api/user-info.ts +70 -0
  91. package/dist/runtime/apis/open-api/werun.ts +5 -0
  92. package/dist/runtime/apis/payment/index.ts +6 -0
  93. package/dist/runtime/apis/route/index.ts +88 -0
  94. package/dist/runtime/apis/share/index.ts +33 -0
  95. package/dist/runtime/apis/storage/background-fetch.ts +7 -0
  96. package/dist/runtime/apis/storage/cache-manager.ts +4 -0
  97. package/dist/runtime/apis/storage/index.ts +203 -0
  98. package/dist/runtime/apis/ui/animation/animation.ts +264 -0
  99. package/dist/runtime/apis/ui/animation/index.ts +7 -0
  100. package/dist/runtime/apis/ui/background.ts +20 -0
  101. package/dist/runtime/apis/ui/custom-component.ts +1 -0
  102. package/dist/runtime/apis/ui/fonts.ts +4 -0
  103. package/dist/runtime/apis/ui/index.ts +12 -0
  104. package/dist/runtime/apis/ui/interaction/index.ts +198 -0
  105. package/dist/runtime/apis/ui/menu.ts +4 -0
  106. package/dist/runtime/apis/ui/navigation-bar/index.ts +72 -0
  107. package/dist/runtime/apis/ui/pull-down-refresh.ts +47 -0
  108. package/dist/runtime/apis/ui/scroll/index.ts +82 -0
  109. package/dist/runtime/apis/ui/sticky.ts +4 -0
  110. package/dist/runtime/apis/ui/tab-bar.ts +144 -0
  111. package/dist/runtime/apis/ui/window.ts +20 -0
  112. package/dist/runtime/apis/utils/constant.ts +1 -0
  113. package/dist/runtime/apis/utils/handler.ts +117 -0
  114. package/dist/runtime/apis/utils/index.ts +105 -0
  115. package/dist/runtime/apis/utils/permissions.ts +6 -0
  116. package/dist/runtime/apis/utils/types.ts +12 -0
  117. package/dist/runtime/apis/utils/unit.ts +104 -0
  118. package/dist/runtime/apis/utils/validate.ts +87 -0
  119. package/dist/runtime/apis/worker/index.ts +4 -0
  120. package/dist/runtime/apis/wxml/index.ts +17 -0
  121. package/dist/runtime/apis/wxml/intersectionObserver.ts +100 -0
  122. package/dist/runtime/apis/wxml/nodesRef.ts +58 -0
  123. package/dist/runtime/apis/wxml/selectorQuery.ts +221 -0
  124. package/dist/runtime/apischunk/index.d.ts +802 -0
  125. package/dist/runtime/apischunk/index.js +5054 -0
  126. package/dist/runtime/components/deprecated.ets +43 -0
  127. package/dist/runtime/components/index.ets +49 -0
  128. package/dist/runtime/components/innerHtml.ets +16 -0
  129. package/dist/runtime/components/navigationBar.ets +65 -0
  130. package/dist/runtime/components/pageMeta.ets +94 -0
  131. package/dist/runtime/components/richText.ets +24 -0
  132. package/dist/runtime/components/slider.ets +119 -0
  133. package/dist/runtime/components/style.ets +286 -0
  134. package/dist/runtime/components/switch.ets +73 -0
  135. package/dist/runtime/components/tag.ts +58 -0
  136. package/dist/runtime/components/utils/AttributeManager.ets +252 -0
  137. package/dist/runtime/components/utils/DynamicCenter.ts +41 -0
  138. package/dist/runtime/components/utils/constant/event.ets +25 -0
  139. package/dist/runtime/components/utils/constant/style.ets +91 -0
  140. package/dist/runtime/components/utils/events.ts +26 -0
  141. package/dist/runtime/components/utils/flexManager.ets +49 -0
  142. package/dist/runtime/components/utils/helper.ets +51 -0
  143. package/dist/runtime/components/utils/htmlParser/HarmonyHTMLParser.ts +100 -0
  144. package/dist/runtime/components/utils/htmlParser/index.ts +58 -0
  145. package/dist/runtime/components/utils/index.ts +77 -0
  146. package/dist/runtime/components/utils/styles.ets +41 -0
  147. package/dist/runtime/components/video.ets +119 -0
  148. package/dist/runtime/components/webView.ets +55 -0
  149. package/dist/runtime/components/xComponent.ets +89 -0
  150. package/dist/runtime/framework/app.ts +248 -0
  151. package/dist/runtime/framework/connect.ts +24 -0
  152. package/dist/runtime/framework/constant.ts +3 -0
  153. package/dist/runtime/framework/hooks.ts +99 -0
  154. package/dist/runtime/framework/index.ts +15 -0
  155. package/dist/runtime/framework/native-page.ts +511 -0
  156. package/dist/runtime/framework/page.ts +256 -0
  157. package/dist/runtime/framework/utils/index.ts +17 -0
  158. package/dist/runtime/framework/utils/is.ts +26 -0
  159. package/dist/runtime/framework-reconciler/componentTree.ts +81 -0
  160. package/dist/runtime/framework-reconciler/constant.ts +86 -0
  161. package/dist/runtime/framework-reconciler/domInput.ts +90 -0
  162. package/dist/runtime/framework-reconciler/event.ts +108 -0
  163. package/dist/runtime/framework-reconciler/index.ts +99 -0
  164. package/dist/runtime/framework-reconciler/inputValueTracking.ts +106 -0
  165. package/dist/runtime/framework-reconciler/props.ts +132 -0
  166. package/dist/runtime/framework-reconciler/reconciler.ts +202 -0
  167. package/dist/runtime/framework-reconciler/render.ts +139 -0
  168. package/dist/runtime/framework-reconciler/workTags.ts +53 -0
  169. package/dist/runtime/runtime-cpp/bom/URL.ts +2 -0
  170. package/dist/runtime/runtime-cpp/bom/document.ts +45 -0
  171. package/dist/runtime/runtime-cpp/bom/history.ts +1 -0
  172. package/dist/runtime/runtime-cpp/bom/location.ts +1 -0
  173. package/dist/runtime/runtime-cpp/bom/navigator.ts +1 -0
  174. package/dist/runtime/runtime-cpp/bom/raf.ts +1 -0
  175. package/dist/runtime/runtime-cpp/bom/window.ts +57 -0
  176. package/dist/runtime/runtime-cpp/constant.ts +29 -0
  177. package/dist/runtime/runtime-cpp/current.ts +48 -0
  178. package/dist/runtime/runtime-cpp/dom/class-list.ts +41 -0
  179. package/dist/runtime/runtime-cpp/dom/comment.ts +9 -0
  180. package/dist/runtime/runtime-cpp/dom/dataSource.ts +87 -0
  181. package/dist/runtime/runtime-cpp/dom/document.ts +113 -0
  182. package/dist/runtime/runtime-cpp/dom/element/canvas.ts +285 -0
  183. package/dist/runtime/runtime-cpp/dom/element/element.ts +262 -0
  184. package/dist/runtime/runtime-cpp/dom/element/form.ts +371 -0
  185. package/dist/runtime/runtime-cpp/dom/element/index.ts +129 -0
  186. package/dist/runtime/runtime-cpp/dom/element/movable.ts +250 -0
  187. package/dist/runtime/runtime-cpp/dom/element/normal.ts +123 -0
  188. package/dist/runtime/runtime-cpp/dom/element/scroll_view.ts +32 -0
  189. package/dist/runtime/runtime-cpp/dom/element/text.ts +9 -0
  190. package/dist/runtime/runtime-cpp/dom/element/video.ts +66 -0
  191. package/dist/runtime/runtime-cpp/dom/element/web_view.ts +72 -0
  192. package/dist/runtime/runtime-cpp/dom/event-source.ts +1 -0
  193. package/dist/runtime/runtime-cpp/dom/event.ts +187 -0
  194. package/dist/runtime/runtime-cpp/dom/eventTarget.ts +81 -0
  195. package/dist/runtime/runtime-cpp/dom/node.ts +307 -0
  196. package/dist/runtime/runtime-cpp/dom/style.ts +44 -0
  197. package/dist/runtime/runtime-cpp/dom/stylesheet/index.ts +379 -0
  198. package/dist/runtime/runtime-cpp/dom/stylesheet/type.ts +212 -0
  199. package/dist/runtime/runtime-cpp/dom/stylesheet/util.ts +186 -0
  200. package/dist/runtime/runtime-cpp/emitter/emitter.ts +29 -0
  201. package/dist/runtime/runtime-cpp/env.ts +1 -0
  202. package/dist/runtime/runtime-cpp/harmony-library.ts +1 -0
  203. package/dist/runtime/runtime-cpp/index.ts +79 -0
  204. package/dist/runtime/runtime-cpp/interface/event.ts +10 -0
  205. package/dist/runtime/runtime-cpp/interface/index.ts +7 -0
  206. package/dist/runtime/runtime-cpp/next-tick.ts +14 -0
  207. package/dist/runtime/runtime-cpp/system.ts +213 -0
  208. package/dist/runtime/runtime-cpp/utils/index.ts +63 -0
  209. package/dist/runtime/runtime-cpp/utils/info.ts +123 -0
  210. package/dist/runtime/runtime-cpp/utils/page.ts +12 -0
  211. package/dist/runtime/runtime-cpp/utils/router.ts +1 -0
  212. package/dist/runtime/runtime-harmony/apis/helper.ets +33 -0
  213. package/dist/runtime/runtime-harmony/apis/network/common.ets +41 -0
  214. package/dist/runtime/runtime-harmony/apis/network/downloadFile.ets +327 -0
  215. package/dist/runtime/runtime-harmony/apis/network/index.ets +58 -0
  216. package/dist/runtime/runtime-harmony/apis/network/request.ets +206 -0
  217. package/dist/runtime/runtime-harmony/apis/network/uploadFile.ets +190 -0
  218. package/dist/runtime/runtime-harmony/apis/route.ets +110 -0
  219. package/dist/runtime/runtime-harmony/apis/taskpool.ets +149 -0
  220. package/dist/runtime/runtime-harmony/index.ets +41 -0
  221. package/dist/runtime/runtime-harmony/utils.ts +53 -0
  222. package/package.json +24 -23
  223. package/LICENSE +0 -174
@@ -0,0 +1,99 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ import { ensure, isFunction } from '@tarojs/shared'
3
+
4
+ import { internalInstanceKey } from './constant'
5
+ import { finishEventHandler } from './event'
6
+ import { TaroReconciler } from './reconciler'
7
+ import { ContainerMap, createRoot, render } from './render'
8
+
9
+ import type { TaroElement } from '@tarojs/runtime'
10
+ import type { ReactNode } from 'react'
11
+
12
+ let isInsideEventHandler = false
13
+
14
+ // 重新包裹 batchedUpdates,使其可以在触发事件后执行 finishEventHandler
15
+ const unstable_batchedUpdates = (fn, a) => {
16
+ if (isInsideEventHandler) {
17
+ return fn(a)
18
+ }
19
+
20
+ isInsideEventHandler = true
21
+
22
+ try {
23
+ return TaroReconciler.batchedUpdates(fn, a)
24
+ } finally {
25
+ isInsideEventHandler = false
26
+ finishEventHandler()
27
+ }
28
+ }
29
+
30
+ function unmountComponentAtNode (dom: TaroElement) {
31
+ ensure(dom && [1, 8, 9, 11].includes(dom.nodeType), 'unmountComponentAtNode(...): Target container is not a DOM element.')
32
+
33
+ const root = ContainerMap.get(dom)
34
+
35
+ if (!root) return false
36
+
37
+ unstable_batchedUpdates(() => {
38
+ root.unmount(() => {
39
+ ContainerMap.delete(dom)
40
+ })
41
+ }, null)
42
+
43
+ return true
44
+ }
45
+
46
+ function findDOMNode (comp?: TaroElement | ReactNode) {
47
+ if (comp == null) {
48
+ return null
49
+ }
50
+
51
+ const nodeType = (comp as TaroElement).nodeType
52
+ if (nodeType === 1 || nodeType === 3) {
53
+ return comp
54
+ }
55
+
56
+ return TaroReconciler.findHostInstance(comp as Record<string, any>)
57
+ }
58
+
59
+ const portalType = isFunction(Symbol) && Symbol.for
60
+ ? Symbol.for('react.portal')
61
+ : 0xeaca
62
+
63
+ function createPortal (
64
+ children: ReactNode,
65
+ containerInfo: TaroElement,
66
+ key?: string
67
+ ) {
68
+ return {
69
+ $$typeof: portalType,
70
+ key: key == null ? null : String(key),
71
+ children,
72
+ containerInfo,
73
+ implementation: null
74
+ }
75
+ }
76
+
77
+ const flushSync = TaroReconciler.flushSync
78
+
79
+ export {
80
+ createPortal,
81
+ createRoot,
82
+ findDOMNode,
83
+ flushSync,
84
+ internalInstanceKey,
85
+ render,
86
+ unmountComponentAtNode,
87
+ unstable_batchedUpdates,
88
+ }
89
+
90
+ export default {
91
+ render,
92
+ flushSync,
93
+ createRoot,
94
+ unstable_batchedUpdates,
95
+ unmountComponentAtNode,
96
+ findDOMNode,
97
+ createPortal,
98
+ internalInstanceKey
99
+ }
@@ -0,0 +1,106 @@
1
+ import type { FormElement } from '@tarojs/runtime'
2
+
3
+ function isCheckable (elem: FormElement) {
4
+ const type = elem.type
5
+ const nodeName = elem.nodeName
6
+
7
+ return (
8
+ nodeName &&
9
+ nodeName.toLowerCase() === 'input' &&
10
+ (type === 'checkbox' || type === 'radio')
11
+ )
12
+ }
13
+
14
+ function getTracker (node) {
15
+ return node._valueTracker
16
+ }
17
+
18
+ function detachTracker (node) {
19
+ node._valueTracker = null
20
+ }
21
+
22
+ // 之所以单独创建一个 tacker,是为了统一监听不同 type 的 input 值
23
+ // 比如 type=checkbox 或者 type=radio,就需要监听 checked,而不是 value
24
+ // 虽然目前还未实现 checkbox 和 radio 的 finishEventHandle,但后续不好说,所以先统一和 react 一样的写法
25
+ // 需要特别注意的是,tracker 初始化时的值为 node 的初始值,但后续会变更为事件的 detail.value 值
26
+ function trackValueOnNode (node: any) {
27
+ const valueField = isCheckable(node) ? 'checked' : 'value'
28
+ const descriptor = Object.getOwnPropertyDescriptor(
29
+ node.constructor.prototype,
30
+ valueField,
31
+ )
32
+
33
+ let currentValue = '' + node[valueField]
34
+
35
+ if (
36
+ node.hasOwnProperty(valueField) ||
37
+ typeof descriptor === 'undefined' ||
38
+ typeof descriptor.get !== 'function' ||
39
+ typeof descriptor.set !== 'function'
40
+ ) {
41
+ return
42
+ }
43
+
44
+ const { get, set } = descriptor
45
+
46
+ Object.defineProperty(node, valueField, {
47
+ configurable: true,
48
+ enumerable: descriptor.enumerable,
49
+ get: function () {
50
+ return get.call(this)
51
+ },
52
+ set: function (value) {
53
+ currentValue = '' + value
54
+ set.call(this, value)
55
+ },
56
+ })
57
+
58
+ const tracker = {
59
+ getValue () {
60
+ return currentValue
61
+ },
62
+ setValue (value) {
63
+ currentValue = '' + value
64
+ },
65
+ stopTracking () {
66
+ detachTracker(node)
67
+ delete node[valueField]
68
+ },
69
+ }
70
+ return tracker
71
+ }
72
+
73
+ export function track (node) {
74
+ if (getTracker(node)) {
75
+ return
76
+ }
77
+
78
+ node._valueTracker = trackValueOnNode(node)
79
+ }
80
+
81
+ export function updateValueIfChanged (node, nextValue: string) {
82
+ if (!node) {
83
+ return false
84
+ }
85
+
86
+ const tracker = getTracker(node)
87
+
88
+ if (!tracker) {
89
+ return true
90
+ }
91
+
92
+ const lastValue = tracker.getValue()
93
+
94
+ if (nextValue !== lastValue) {
95
+ tracker.setValue(nextValue)
96
+ return true
97
+ }
98
+ return false
99
+ }
100
+
101
+ export function stopTracking (node) {
102
+ const tracker = getTracker(node)
103
+ if (tracker) {
104
+ tracker.stopTracking()
105
+ }
106
+ }
@@ -0,0 +1,132 @@
1
+ import { FormElement, TaroNativeModule } from '@tarojs/runtime'
2
+ import { isFunction, isObject } from '@tarojs/shared'
3
+
4
+ import type { TaroElement } from '@tarojs/runtime'
5
+
6
+ export type Props = Record<string, unknown>
7
+
8
+ function isEventName (s: string) {
9
+ return s[0] === 'o' && s[1] === 'n'
10
+ }
11
+
12
+ function isEqual (obj1, obj2) {
13
+ // 首先检查引用是否相同
14
+ if (obj1 === obj2) {
15
+ return true
16
+ }
17
+
18
+ // 如果两者中有一个不是对象,或者为 null,直接返回 false
19
+ if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
20
+ return false
21
+ }
22
+
23
+ // 获取两个对象键的数组
24
+ const keys1 = Object.keys(obj1)
25
+ const keys2 = Object.keys(obj2)
26
+
27
+ // 如果键的数量不相同,对象显然不相等
28
+ if (keys1.length !== keys2.length) {
29
+ return false
30
+ }
31
+
32
+ // 遍历对象的每个键,比较两个对象同一键的值
33
+ for (let i = 0; i < keys1.length; i++) {
34
+ const key = keys1[i]
35
+ if (obj1[key] !== obj2[key]) {
36
+ return false
37
+ }
38
+ }
39
+
40
+ // 如果所有键的值都相等,返回 true
41
+ return true
42
+ }
43
+
44
+ export function updateProps (dom: TaroElement, oldProps: Props, newProps: Props) {
45
+ const updatePayload = getUpdatePayload(dom, oldProps, newProps)
46
+ if (updatePayload) {
47
+ updatePropsByPayload(dom, oldProps, updatePayload)
48
+ }
49
+ }
50
+
51
+ interface DangerouslySetInnerHTML {
52
+ __html?: string
53
+ }
54
+
55
+ export function updatePropsByPayload (dom: TaroElement, oldProps: Props, updatePayload: any[]) {
56
+ if (!(dom as any).isETS) {
57
+ return TaroNativeModule.updatePropsByPayload(dom, oldProps, updatePayload)
58
+ }
59
+
60
+ for (let i = 0; i < updatePayload.length; i += 2) {
61
+ let name = updatePayload[i]
62
+
63
+ if (['key', 'children', 'ref'].includes(name)) {
64
+ // skip
65
+ return
66
+ }
67
+
68
+ const value = updatePayload[i + 1]
69
+ const oldValue = oldProps[name]
70
+
71
+ name = name === 'className' ? 'class' : name
72
+ if (isEventName(name)) {
73
+ setEvent(dom, name, value, oldValue)
74
+ } else if (name === 'dangerouslySetInnerHTML') {
75
+ const newHtml = (value as DangerouslySetInnerHTML)?.__html ?? ''
76
+ const oldHtml = (oldValue as DangerouslySetInnerHTML)?.__html ?? ''
77
+ if (newHtml || oldHtml) {
78
+ if (oldHtml !== newHtml) {
79
+ dom.innerHTML = newHtml
80
+ }
81
+ }
82
+ } else if (!isFunction(value)) {
83
+ if (value == null) {
84
+ dom.removeAttribute(name)
85
+ } else {
86
+ dom.setAttribute(name, value as string)
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ export function getUpdatePayload (dom: TaroElement, oldProps: Props, newProps: Props) {
93
+ let i: string
94
+ let updatePayload: any[] | null = null
95
+
96
+ for (i in oldProps) {
97
+ if (!(i in newProps)) {
98
+ updatePayload ||= []
99
+ updatePayload.push(i, null)
100
+ }
101
+ }
102
+ for (i in newProps) {
103
+ if (oldProps[i] !== newProps[i] || (dom instanceof FormElement && i === 'value')) {
104
+ // 如果都是 style,且 style 里面的值相等,则无需记录到 payload 中
105
+ if (i === 'style' && isObject(oldProps[i]) && isObject(newProps[i]) && isEqual(oldProps[i], newProps[i])) continue
106
+
107
+ updatePayload ||= []
108
+ updatePayload.push(i, newProps[i])
109
+ }
110
+ }
111
+
112
+ return updatePayload
113
+ }
114
+
115
+ function setEvent (dom: TaroElement, name: string, value: unknown, oldValue?: unknown) {
116
+ const isCapture = name.endsWith('Capture')
117
+ let eventName = name.toLowerCase().slice(2)
118
+ if (isCapture) {
119
+ eventName = eventName.slice(0, -7)
120
+ }
121
+
122
+ if (isFunction(value)) {
123
+ if (oldValue) {
124
+ dom.removeEventListener(eventName, oldValue, false)
125
+ dom.addEventListener(eventName, value, { isCapture, sideEffect: false })
126
+ } else {
127
+ dom.addEventListener(eventName, value, isCapture)
128
+ }
129
+ } else {
130
+ dom.removeEventListener(eventName, oldValue)
131
+ }
132
+ }
@@ -0,0 +1,202 @@
1
+ /* eslint-disable @typescript-eslint/indent */
2
+ import { document, FormElement } from '@tarojs/runtime'
3
+ import { isBoolean, isUndefined, noop } from '@tarojs/shared'
4
+ import Reconciler from 'react-reconciler'
5
+ import { DefaultEventPriority } from 'react-reconciler/constants'
6
+
7
+ import { detachDeletedInstance, precacheFiberNode, updateFiberProps } from './componentTree'
8
+ import { track } from './inputValueTracking'
9
+ import { getUpdatePayload, Props, updateProps, updatePropsByPayload } from './props'
10
+
11
+ import type { TaroElement, TaroText } from '@tarojs/runtime'
12
+ import type { Fiber, HostConfig } from 'react-reconciler'
13
+
14
+ const hostConfig: HostConfig<
15
+ string, // Type
16
+ Props, // Props
17
+ TaroElement, // Container
18
+ TaroElement, // Instance
19
+ TaroText, // TextInstance
20
+ TaroElement, // SuspenseInstance
21
+ TaroElement, // HydratableInstance
22
+ TaroElement, // PublicInstance
23
+ Record<string, any>, // HostContext
24
+ string[], // UpdatePayload
25
+ unknown, // ChildSet
26
+ unknown, // TimeoutHandle
27
+ unknown // NoTimeout
28
+ > = {
29
+ // below keys order by {React ReactFiberHostConfig.custom.js}, convenient for comparing each other.
30
+
31
+ // -------------------
32
+ // required by @types/react-reconciler
33
+ // -------------------
34
+ getPublicInstance (inst: TaroElement) {
35
+ return inst
36
+ },
37
+ getRootHostContext () {
38
+ return {}
39
+ },
40
+ getChildHostContext (parentHostContext) {
41
+ return parentHostContext
42
+ },
43
+ prepareForCommit (..._: any[]) {
44
+ return null
45
+ },
46
+ resetAfterCommit: noop,
47
+ createInstance (type, props: Props, _rootContainerInstance: any, _hostContext: any, internalInstanceHandle: Fiber) {
48
+ const element = document.createElement(type)
49
+
50
+ precacheFiberNode(internalInstanceHandle, element)
51
+ updateFiberProps(element, props)
52
+
53
+ return element
54
+ },
55
+ appendInitialChild (parent, child) {
56
+ parent.appendChild(child)
57
+ },
58
+ finalizeInitialChildren (dom, type: string, props: any) {
59
+ let newProps = props
60
+ if (dom instanceof FormElement) {
61
+ const [defaultName, defaultKey] = ['switch', 'checkbox', 'radio'].includes(type) ? ['checked', 'defaultChecked'] : ['value', 'defaultValue']
62
+ if (props.hasOwnProperty(defaultKey)) {
63
+ newProps = { ...newProps, [defaultName]: props[defaultKey] }
64
+ delete newProps[defaultKey]
65
+ }
66
+ }
67
+
68
+ updateProps(dom, {}, newProps) // 提前执行更新属性操作,Taro 在 Page 初始化后会立即从 dom 读取必要信息
69
+
70
+ if (type === 'input' || type === 'textarea') {
71
+ track(dom)
72
+ }
73
+
74
+ return false
75
+ },
76
+ prepareUpdate (instance, _, oldProps, newProps) {
77
+ return getUpdatePayload(instance, oldProps, newProps)
78
+ },
79
+ shouldSetTextContent () {
80
+ return false
81
+ },
82
+ createTextInstance (text: string, _rootContainerInstance: any, _hostContext: any, internalInstanceHandle: Fiber) {
83
+ const textNode = document.createTextNode(text)
84
+
85
+ precacheFiberNode(internalInstanceHandle, textNode)
86
+
87
+ return textNode
88
+ },
89
+ scheduleTimeout: setTimeout,
90
+ cancelTimeout: clearTimeout,
91
+ noTimeout: -1,
92
+ isPrimaryRenderer: true,
93
+ warnsIfNotActing: true,
94
+ supportsMutation: true,
95
+ supportsPersistence: false,
96
+ supportsHydration: false,
97
+ getInstanceFromNode: () => null,
98
+ beforeActiveInstanceBlur: noop,
99
+ afterActiveInstanceBlur: noop,
100
+ preparePortalMount: noop,
101
+ prepareScopeUpdate: noop,
102
+ getInstanceFromScope: () => null,
103
+ getCurrentEventPriority () {
104
+ return DefaultEventPriority
105
+ },
106
+ detachDeletedInstance,
107
+
108
+ // -------------------
109
+ // Microtasks
110
+ // (optional)
111
+ // -------------------
112
+ supportsMicrotasks: true,
113
+ scheduleMicrotask: isUndefined(Promise)
114
+ ? setTimeout
115
+ : (callback) =>
116
+ Promise.resolve(null)
117
+ .then(callback)
118
+ .catch(function (error) {
119
+ setTimeout(() => {
120
+ throw error
121
+ })
122
+ }),
123
+
124
+ // -------------------
125
+ // Mutation
126
+ // (required if supportsMutation is true)
127
+ // -------------------
128
+ appendChild (parent, child) {
129
+ parent.appendChild(child)
130
+ },
131
+ appendChildToContainer (parent, child) {
132
+ parent.appendChild(child)
133
+ },
134
+ commitTextUpdate (textInst, _, newText) {
135
+ textInst.nodeValue = newText
136
+ },
137
+ commitMount: noop,
138
+ commitUpdate (dom, updatePayload, _, oldProps, newProps) {
139
+ if (!updatePayload) return
140
+ // payload 只包含 children 的时候,不应该再继续触发后续的属性比较和更新的逻辑了
141
+ if (updatePayload.length === 2 && updatePayload.includes('children')) return
142
+
143
+ updatePropsByPayload(dom, oldProps, updatePayload)
144
+ updateFiberProps(dom, newProps)
145
+ },
146
+ insertBefore (parent, child, refChild) {
147
+ parent.insertBefore(child, refChild)
148
+ },
149
+ insertInContainerBefore (parent, child, refChild) {
150
+ parent.insertBefore(child, refChild)
151
+ },
152
+ removeChild (parent, child) {
153
+ parent.removeChild(child)
154
+ },
155
+ removeChildFromContainer (parent, child) {
156
+ parent.removeChild(child)
157
+ },
158
+ resetTextContent: noop,
159
+ hideInstance (instance) {
160
+ const style = instance.style
161
+ style.setProperty('display', 'none')
162
+ },
163
+ hideTextInstance (textInstance) {
164
+ textInstance.nodeValue = ''
165
+ },
166
+ unhideInstance (instance, props) {
167
+ const styleProp = props.style as { display?: any }
168
+ let display = styleProp?.hasOwnProperty('display') ? styleProp.display : null
169
+ display = display == null || isBoolean(display) || display === '' ? '' : ('' + display).trim()
170
+ // eslint-disable-next-line dot-notation
171
+ instance.style['display'] = display
172
+ },
173
+ unhideTextInstance (textInstance, text) {
174
+ textInstance.nodeValue = text
175
+ },
176
+ clearContainer (element) {
177
+ if (element.childNodes.length > 0) {
178
+ element.textContent = ''
179
+ }
180
+ }
181
+ }
182
+
183
+ const TaroReconciler = Reconciler(hostConfig)
184
+
185
+ if (process.env.NODE_ENV !== 'production') {
186
+ const foundDevTools = TaroReconciler.injectIntoDevTools({
187
+ bundleType: 1,
188
+ version: '18.0.0',
189
+ rendererPackageName: 'taro-react'
190
+ })
191
+ if (!foundDevTools) {
192
+ // eslint-disable-next-line no-console
193
+ console.info(
194
+ '%cDownload the React DevTools ' +
195
+ 'for a better development experience: ' +
196
+ 'https://reactjs.org/link/react-devtools',
197
+ 'font-weight:bold'
198
+ )
199
+ }
200
+ }
201
+
202
+ export { TaroReconciler }
@@ -0,0 +1,139 @@
1
+ import { hooks } from '@tarojs/shared'
2
+
3
+ import { markContainerAsRoot } from './componentTree'
4
+ import { getEventPriority } from './constant'
5
+ import { enqueueStateRestore, getTargetInstForInputOrChangeEvent, RestoreType } from './event'
6
+ import { TaroReconciler } from './reconciler'
7
+
8
+ import type { TaroElement, TaroEvent } from '@tarojs/runtime'
9
+ import type { ReactNode } from 'react'
10
+ import type { OpaqueRoot } from 'react-reconciler'
11
+
12
+ export const ContainerMap: WeakMap<TaroElement, Root> = new WeakMap()
13
+
14
+ type Renderer = typeof TaroReconciler
15
+
16
+ type CreateRootOptions = {
17
+ unstable_strictMode?: boolean
18
+ unstable_concurrentUpdatesByDefault?: boolean
19
+ unstable_transitionCallbacks?: any
20
+ identifierPrefix?: string
21
+ onRecoverableError?: (error: any) => void
22
+ }
23
+
24
+ export type Callback = () => void | null | undefined
25
+
26
+ class Root {
27
+ private renderer: Renderer
28
+ public internalRoot: OpaqueRoot
29
+
30
+ public constructor (renderer: Renderer, domContainer: TaroElement, options?: CreateRootOptions) {
31
+ this.renderer = renderer
32
+ this.initInternalRoot(renderer, domContainer, options)
33
+ }
34
+
35
+ private initInternalRoot (renderer: Renderer, domContainer: TaroElement, options?: CreateRootOptions) {
36
+ // Since react-reconciler v0.27, createContainer need more parameters
37
+ // @see:https://github.com/facebook/react/blob/0b974418c9a56f6c560298560265dcf4b65784bc/packages/react-reconciler/src/ReactFiberReconciler.js#L248
38
+ const containerInfo = domContainer
39
+ if (options) {
40
+ const tag = 1 // ConcurrentRoot
41
+ const concurrentUpdatesByDefaultOverride = false
42
+ let isStrictMode = false
43
+ let identifierPrefix = ''
44
+ let onRecoverableError = (error: any) => console.error(error)
45
+ let transitionCallbacks = null
46
+ if (options.unstable_strictMode === true) {
47
+ isStrictMode = true
48
+ }
49
+ if (options.identifierPrefix !== undefined) {
50
+ identifierPrefix = options.identifierPrefix
51
+ }
52
+ if (options.onRecoverableError !== undefined) {
53
+ onRecoverableError = options.onRecoverableError
54
+ }
55
+ if (options.unstable_transitionCallbacks !== undefined) {
56
+ transitionCallbacks = options.unstable_transitionCallbacks
57
+ }
58
+
59
+ this.internalRoot = renderer.createContainer(
60
+ containerInfo,
61
+ tag,
62
+ null, // hydrationCallbacks
63
+ isStrictMode,
64
+ concurrentUpdatesByDefaultOverride,
65
+ identifierPrefix,
66
+ onRecoverableError,
67
+ transitionCallbacks
68
+ )
69
+ } else {
70
+ const tag = 0 // LegacyRoot
71
+ this.internalRoot = renderer.createContainer(
72
+ containerInfo,
73
+ tag,
74
+ null, // hydrationCallbacks
75
+ false, // isStrictMode
76
+ false, // concurrentUpdatesByDefaultOverride,
77
+ '', // identifierPrefix
78
+ () => {}, // onRecoverableError, this isn't reachable because onRecoverableError isn't called in the legacy API.
79
+ null // transitionCallbacks
80
+ )
81
+ }
82
+ }
83
+
84
+ public render (children: ReactNode, cb: Callback) {
85
+ const { renderer, internalRoot } = this
86
+ renderer.updateContainer(children, internalRoot, null, cb)
87
+ return renderer.getPublicRootInstance(internalRoot)
88
+ }
89
+
90
+ public unmount (cb: Callback) {
91
+ this.renderer.updateContainer(null, this.internalRoot, null, cb)
92
+ }
93
+ }
94
+
95
+ export function render (element: ReactNode, domContainer: TaroElement, cb: Callback) {
96
+ const oldRoot = ContainerMap.get(domContainer)
97
+ if (oldRoot != null) {
98
+ return oldRoot.render(element, cb)
99
+ }
100
+
101
+ const root = new Root(TaroReconciler, domContainer)
102
+ ContainerMap.set(domContainer, root)
103
+ return root.render(element, cb)
104
+ }
105
+
106
+ export function createRoot (domContainer: TaroElement, options: CreateRootOptions = {}) {
107
+ const oldRoot = ContainerMap.get(domContainer)
108
+ if (oldRoot != null) {
109
+ return oldRoot
110
+ }
111
+ // options should be an object
112
+ const root = new Root(TaroReconciler, domContainer, options)
113
+ ContainerMap.set(domContainer, root)
114
+
115
+ markContainerAsRoot(root?.internalRoot?.current, domContainer)
116
+
117
+ hooks.tap('dispatchTaroEvent', (e: TaroEvent, node: TaroElement) => {
118
+ const eventPriority = getEventPriority(e.type)
119
+
120
+ TaroReconciler.runWithPriority(eventPriority, () => {
121
+ node.dispatchEvent(e)
122
+ })
123
+ })
124
+
125
+ // 对比 event.detail.value 和 node.tracker.value,判断 value 值是否有变动,存在变动则塞入队列中
126
+ hooks.tap('modifyTaroEvent', (e: TaroEvent, node: TaroElement) => {
127
+ const inst = getTargetInstForInputOrChangeEvent(e, node)
128
+
129
+ if (!inst) return
130
+
131
+ // 这里塞入的是 event.detail.value,也就是事件的值,在受控组件中,你可以理解为需要被变更的值
132
+ // 后续会在 finishEventHandler 中,使用最新的 fiber.props.value 来与其比较
133
+ // 如果不一致,则表示需要更新,会执行 node.value = fiber.props.value 的更新操作
134
+ const nextValue = e.mpEvent?.detail?.value as unknown as RestoreType
135
+ enqueueStateRestore({ target: node, value: nextValue })
136
+ })
137
+
138
+ return root
139
+ }