@tarojs/plugin-platform-harmony-ets 3.7.0-alpha.27

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 (212) hide show
  1. package/LICENSE +160 -0
  2. package/dist/apis/apis.ts +15 -0
  3. package/dist/apis/base/index.ts +5 -0
  4. package/dist/apis/base/system.ts +77 -0
  5. package/dist/apis/device/accelerometer.ts +76 -0
  6. package/dist/apis/device/battery.ts +24 -0
  7. package/dist/apis/device/clipboard.ts +70 -0
  8. package/dist/apis/device/index.ts +9 -0
  9. package/dist/apis/device/keyboard.ts +62 -0
  10. package/dist/apis/device/memory.ts +4 -0
  11. package/dist/apis/device/network.ts +72 -0
  12. package/dist/apis/device/phone.ts +43 -0
  13. package/dist/apis/device/screen.ts +79 -0
  14. package/dist/apis/device/vibrate.ts +24 -0
  15. package/dist/apis/files/index.ts +135 -0
  16. package/dist/apis/files/manager.ts +941 -0
  17. package/dist/apis/framework/index.ts +32 -0
  18. package/dist/apis/index.ts +124 -0
  19. package/dist/apis/location/index.ts +133 -0
  20. package/dist/apis/media/common.ts +74 -0
  21. package/dist/apis/media/image.ts +122 -0
  22. package/dist/apis/media/index.ts +3 -0
  23. package/dist/apis/media/video.ts +86 -0
  24. package/dist/apis/navigate/index.ts +8 -0
  25. package/dist/apis/network/downloadFile.ts +113 -0
  26. package/dist/apis/network/index.ts +4 -0
  27. package/dist/apis/network/request.ts +113 -0
  28. package/dist/apis/network/uploadFile.ts +158 -0
  29. package/dist/apis/network/webSocket.ts +130 -0
  30. package/dist/apis/open-api/index.ts +7 -0
  31. package/dist/apis/open-api/user-info/index.ts +85 -0
  32. package/dist/apis/page/index.ts +92 -0
  33. package/dist/apis/route/index.ts +138 -0
  34. package/dist/apis/storage/index.ts +133 -0
  35. package/dist/apis/tabbar/index.ts +147 -0
  36. package/dist/apis/ui/animation.ts +222 -0
  37. package/dist/apis/ui/background.ts +35 -0
  38. package/dist/apis/ui/index.ts +14 -0
  39. package/dist/apis/ui/interaction/index.ts +195 -0
  40. package/dist/apis/ui/navigation-bar/index.ts +33 -0
  41. package/dist/apis/ui/pull-down-refresh.ts +41 -0
  42. package/dist/apis/utils/handler.ts +116 -0
  43. package/dist/apis/utils/index.ts +85 -0
  44. package/dist/apis/utils/types.ts +12 -0
  45. package/dist/apis/utils/validate.ts +87 -0
  46. package/dist/apis/wxml/IntersectionObserver.ts +119 -0
  47. package/dist/apis/wxml/index.ts +12 -0
  48. package/dist/apis/wxml/nodesRef.ts +56 -0
  49. package/dist/apis/wxml/selectorQuery.ts +287 -0
  50. package/dist/components/components-react.js +51 -0
  51. package/dist/components/components-react.js.map +1 -0
  52. package/dist/components-harmony/button/index.css +109 -0
  53. package/dist/components-harmony/button/index.hml +31 -0
  54. package/dist/components-harmony/button/index.js +105 -0
  55. package/dist/components-harmony/camera/index.hml +6 -0
  56. package/dist/components-harmony/camera/index.js +12 -0
  57. package/dist/components-harmony/checkbox/index.hml +11 -0
  58. package/dist/components-harmony/checkbox/index.js +60 -0
  59. package/dist/components-harmony/checkbox-group/index.hml +3 -0
  60. package/dist/components-harmony/checkbox-group/index.js +22 -0
  61. package/dist/components-harmony/cover-image/index.css +4 -0
  62. package/dist/components-harmony/cover-image/index.hml +9 -0
  63. package/dist/components-harmony/cover-image/index.js +15 -0
  64. package/dist/components-harmony/form/index.hml +10 -0
  65. package/dist/components-harmony/form/index.js +11 -0
  66. package/dist/components-harmony/icon/index.css +27 -0
  67. package/dist/components-harmony/icon/index.hml +54 -0
  68. package/dist/components-harmony/icon/index.js +17 -0
  69. package/dist/components-harmony/image/index.css +5 -0
  70. package/dist/components-harmony/image/index.hml +11 -0
  71. package/dist/components-harmony/image/index.js +28 -0
  72. package/dist/components-harmony/input/index.hml +21 -0
  73. package/dist/components-harmony/input/index.js +98 -0
  74. package/dist/components-harmony/label/index.hml +3 -0
  75. package/dist/components-harmony/label/index.js +6 -0
  76. package/dist/components-harmony/navbar/index.css +56 -0
  77. package/dist/components-harmony/navbar/index.hml +9 -0
  78. package/dist/components-harmony/navbar/index.js +30 -0
  79. package/dist/components-harmony/navigator/index.css +8 -0
  80. package/dist/components-harmony/navigator/index.hml +9 -0
  81. package/dist/components-harmony/navigator/index.js +104 -0
  82. package/dist/components-harmony/picker/index.hml +25 -0
  83. package/dist/components-harmony/picker/index.js +132 -0
  84. package/dist/components-harmony/picker-view/index.hml +23 -0
  85. package/dist/components-harmony/picker-view/index.js +161 -0
  86. package/dist/components-harmony/picker-view-column/index.hml +3 -0
  87. package/dist/components-harmony/picker-view-column/index.js +3 -0
  88. package/dist/components-harmony/progress/index.css +4 -0
  89. package/dist/components-harmony/progress/index.hml +28 -0
  90. package/dist/components-harmony/progress/index.js +23 -0
  91. package/dist/components-harmony/radio/index.hml +11 -0
  92. package/dist/components-harmony/radio/index.js +41 -0
  93. package/dist/components-harmony/radio-group/index.hml +3 -0
  94. package/dist/components-harmony/radio-group/index.js +11 -0
  95. package/dist/components-harmony/rich-text/index.hml +5 -0
  96. package/dist/components-harmony/rich-text/index.js +16 -0
  97. package/dist/components-harmony/scroll-view/index.css +5 -0
  98. package/dist/components-harmony/scroll-view/index.hml +12 -0
  99. package/dist/components-harmony/scroll-view/index.js +65 -0
  100. package/dist/components-harmony/slider/index.hml +16 -0
  101. package/dist/components-harmony/slider/index.js +53 -0
  102. package/dist/components-harmony/swiper/index.css +3 -0
  103. package/dist/components-harmony/swiper/index.hml +14 -0
  104. package/dist/components-harmony/swiper/index.js +19 -0
  105. package/dist/components-harmony/switch/index.hml +7 -0
  106. package/dist/components-harmony/switch/index.js +16 -0
  107. package/dist/components-harmony/tabbar/index.css +7 -0
  108. package/dist/components-harmony/tabbar/index.hml +26 -0
  109. package/dist/components-harmony/tabbar/index.js +42 -0
  110. package/dist/components-harmony/textarea/index.hml +24 -0
  111. package/dist/components-harmony/textarea/index.js +92 -0
  112. package/dist/components-harmony/utils/index.js +41 -0
  113. package/dist/components-harmony/video/index.hml +7 -0
  114. package/dist/components-harmony/video/index.js +73 -0
  115. package/dist/components-harmony/web-view/index.hml +8 -0
  116. package/dist/components-harmony/web-view/index.js +22 -0
  117. package/dist/components-harmony-ets/base.ets +63 -0
  118. package/dist/components-harmony-ets/button.ets +119 -0
  119. package/dist/components-harmony-ets/checkbox.ets +219 -0
  120. package/dist/components-harmony-ets/element.ets +223 -0
  121. package/dist/components-harmony-ets/form.ets +149 -0
  122. package/dist/components-harmony-ets/icon.ets +84 -0
  123. package/dist/components-harmony-ets/image.ets +85 -0
  124. package/dist/components-harmony-ets/index.ts +49 -0
  125. package/dist/components-harmony-ets/innerHtml.ets +79 -0
  126. package/dist/components-harmony-ets/input.ets +195 -0
  127. package/dist/components-harmony-ets/label.ets +111 -0
  128. package/dist/components-harmony-ets/picker.ets +370 -0
  129. package/dist/components-harmony-ets/radio.ets +225 -0
  130. package/dist/components-harmony-ets/richText.ets +97 -0
  131. package/dist/components-harmony-ets/scrollView.ets +199 -0
  132. package/dist/components-harmony-ets/slider.ets +159 -0
  133. package/dist/components-harmony-ets/swiper.ets +204 -0
  134. package/dist/components-harmony-ets/switch.ets +113 -0
  135. package/dist/components-harmony-ets/text.ets +97 -0
  136. package/dist/components-harmony-ets/textArea.ets +169 -0
  137. package/dist/components-harmony-ets/utils/AttributeManager.ets +250 -0
  138. package/dist/components-harmony-ets/utils/DynamicCenter.ts +48 -0
  139. package/dist/components-harmony-ets/utils/constant/event.ets +25 -0
  140. package/dist/components-harmony-ets/utils/constant/icon.ts +19 -0
  141. package/dist/components-harmony-ets/utils/constant/style.ets +88 -0
  142. package/dist/components-harmony-ets/utils/events.ts +24 -0
  143. package/dist/components-harmony-ets/utils/flexManager.ets +107 -0
  144. package/dist/components-harmony-ets/utils/helper.ets +99 -0
  145. package/dist/components-harmony-ets/utils/htmlParser/HarmonyHTMLParser.ts +103 -0
  146. package/dist/components-harmony-ets/utils/htmlParser/index.ts +56 -0
  147. package/dist/components-harmony-ets/utils/index.ts +83 -0
  148. package/dist/components-harmony-ets/utils/styles.ets +91 -0
  149. package/dist/components-harmony-ets/video.ets +161 -0
  150. package/dist/components-harmony-ets/view.ets +79 -0
  151. package/dist/index.js +1183 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/runtime-ets/bom/document.ts +38 -0
  154. package/dist/runtime-ets/bom/getComputedStyle.ts +5 -0
  155. package/dist/runtime-ets/bom/navigator.ts +21 -0
  156. package/dist/runtime-ets/bom/raf.ts +37 -0
  157. package/dist/runtime-ets/bom/window.ts +44 -0
  158. package/dist/runtime-ets/constant.ts +29 -0
  159. package/dist/runtime-ets/current.ts +16 -0
  160. package/dist/runtime-ets/dom/class-list.ts +117 -0
  161. package/dist/runtime-ets/dom/comment.ts +10 -0
  162. package/dist/runtime-ets/dom/cssStyleDeclaration.ts +105 -0
  163. package/dist/runtime-ets/dom/document.ts +108 -0
  164. package/dist/runtime-ets/dom/element.ts +457 -0
  165. package/dist/runtime-ets/dom/event.ts +164 -0
  166. package/dist/runtime-ets/dom/eventTarget.ts +98 -0
  167. package/dist/runtime-ets/dom/node.ts +215 -0
  168. package/dist/runtime-ets/dom/stylesheet/index.ts +687 -0
  169. package/dist/runtime-ets/dom/stylesheet/type.ts +136 -0
  170. package/dist/runtime-ets/dom/stylesheet/util.ts +134 -0
  171. package/dist/runtime-ets/dom/text.ts +19 -0
  172. package/dist/runtime-ets/index.ts +19 -0
  173. package/dist/runtime-ets/interface/event.ts +9 -0
  174. package/dist/runtime-ets/interface/index.ts +1 -0
  175. package/dist/runtime-ets/utils/bind.ts +35 -0
  176. package/dist/runtime-ets/utils/index.ts +135 -0
  177. package/dist/runtime-ets/utils/info.ts +128 -0
  178. package/dist/runtime-framework/react/app.ts +256 -0
  179. package/dist/runtime-framework/react/connect.ts +24 -0
  180. package/dist/runtime-framework/react/constant.ts +5 -0
  181. package/dist/runtime-framework/react/hooks.ts +101 -0
  182. package/dist/runtime-framework/react/index.ts +16 -0
  183. package/dist/runtime-framework/react/page.ts +263 -0
  184. package/dist/runtime-framework/react/utils/index.ts +25 -0
  185. package/dist/runtime-framework/react/utils/is.ts +46 -0
  186. package/dist/runtime-framework/solid/README.md +99 -0
  187. package/dist/runtime-framework/solid/app.ts +200 -0
  188. package/dist/runtime-framework/solid/connect.ts +11 -0
  189. package/dist/runtime-framework/solid/contant.ts +5 -0
  190. package/dist/runtime-framework/solid/hooks.ts +88 -0
  191. package/dist/runtime-framework/solid/index.ts +10 -0
  192. package/dist/runtime-framework/solid/page.ts +202 -0
  193. package/dist/runtime-framework/solid/reconciler/h.ts +132 -0
  194. package/dist/runtime-framework/solid/reconciler/index.ts +3 -0
  195. package/dist/runtime-framework/solid/reconciler/props.ts +151 -0
  196. package/dist/runtime-framework/solid/reconciler/render.ts +61 -0
  197. package/dist/runtime-framework/solid/reconciler/use.ts +8 -0
  198. package/dist/runtime-framework/solid/utils/index.ts +49 -0
  199. package/dist/runtime-framework/solid/utils/is.ts +46 -0
  200. package/dist/runtime-utils.js +4149 -0
  201. package/dist/runtime-utils.js.map +1 -0
  202. package/dist/runtime.js +4150 -0
  203. package/dist/runtime.js.map +1 -0
  204. package/dist/template/container.js +7 -0
  205. package/index.js +4 -0
  206. package/package.json +54 -0
  207. package/types/api.d.ts +4 -0
  208. package/types/component.d.ts +4 -0
  209. package/types/harmony.d.ts +11 -0
  210. package/types/runtime.d.ts +15 -0
  211. package/types/taro.d.ts +7 -0
  212. package/types/webpack-sources.d.ts +108 -0
@@ -0,0 +1,256 @@
1
+ // eslint-disable-next-line import/no-duplicates
2
+ import { Current, document } from '@tarojs/runtime'
3
+ // eslint-disable-next-line import/no-duplicates
4
+ import { eventCenter } from '@tarojs/runtime/dist/runtime.esm'
5
+
6
+ import { setReconciler } from './connect'
7
+ import { injectPageInstance } from './page'
8
+ import { EMPTY_OBJ, incrementId, isClassComponent } from './utils'
9
+
10
+ import type React from 'react'
11
+
12
+ let h: typeof React.createElement
13
+ let ReactDOM
14
+
15
+ interface IReactMeta {
16
+ PageContext: React.Context<string>
17
+ R: typeof React
18
+ Container: any
19
+ }
20
+
21
+ export const ReactMeta: IReactMeta = {
22
+ R: EMPTY_OBJ,
23
+ Container: EMPTY_OBJ,
24
+ PageContext: EMPTY_OBJ
25
+ }
26
+
27
+ const pageKeyId = incrementId()
28
+
29
+ export function connectReactPage (
30
+ R: typeof React,
31
+ id: string
32
+ ) {
33
+ return (Page): React.ComponentClass<any> => {
34
+ // eslint-disable-next-line dot-notation
35
+ const isReactComponent = isClassComponent(R, Page)
36
+ const inject = (node?: any) => node && injectPageInstance(node, id)
37
+ const refs = isReactComponent ? { ref: inject } : {
38
+ forwardedRef: inject,
39
+ // 兼容 react-redux 7.20.1+
40
+ reactReduxForwardedRef: inject
41
+ }
42
+
43
+ if (ReactMeta.PageContext === EMPTY_OBJ) {
44
+ ReactMeta.PageContext = R.createContext('')
45
+ }
46
+
47
+ return class PageWrapper extends R.Component<any, { hasError: boolean }> {
48
+ state = {
49
+ hasError: false
50
+ }
51
+
52
+ static getDerivedStateFromError (error: Error) {
53
+ Current.app?.onError?.(error.message + error.stack)
54
+ return { hasError: true }
55
+ }
56
+
57
+ // React 16 uncaught error 会导致整个应用 crash,
58
+ // 目前把错误缩小到页面
59
+ componentDidCatch (error, info: React.ErrorInfo) {
60
+ console.warn(error)
61
+ console.error(info.componentStack)
62
+ }
63
+
64
+ render () {
65
+ const children = this.state.hasError
66
+ ? []
67
+ : h(ReactMeta.PageContext.Provider, { value: id }, h(Page, {
68
+ ...this.props,
69
+ ...refs
70
+ }))
71
+
72
+ // TODO root
73
+ return h(
74
+ 'view',
75
+ { id, className: 'taro_page' },
76
+ children
77
+ )
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ export function createReactApp (
84
+ App,
85
+ react,
86
+ dom,
87
+ _config?: any
88
+ ) {
89
+ ReactMeta.R = react
90
+ h = react.createElement
91
+ ReactDOM = dom
92
+ const appInstanceRef = react.createRef()
93
+ const isReactComponent = isClassComponent(react, App)
94
+ let appWrapper: AppWrapper
95
+ let appWrapperResolver: (value: AppWrapper) => void
96
+ const appWrapperPromise = new Promise<AppWrapper>(resolve => (appWrapperResolver = resolve))
97
+
98
+ setReconciler(ReactDOM)
99
+
100
+ function getAppInstance (): any {
101
+ return appInstanceRef.current
102
+ }
103
+
104
+ function waitAppWrapper (cb: () => void) {
105
+ appWrapper ? cb() : appWrapperPromise.then(() => cb())
106
+ }
107
+
108
+ function renderReactRoot () {
109
+ const appId = 'app'
110
+
111
+ if (ReactMeta.Container === EMPTY_OBJ) {
112
+ const Container = document.createElement('view')
113
+
114
+ Container.id = appId
115
+ ReactMeta.Container = Container
116
+ }
117
+
118
+ const root = ReactDOM.createRoot(ReactMeta.Container)
119
+ root.render?.(h(AppWrapper as any))
120
+ }
121
+
122
+ class AppWrapper extends react.Component {
123
+ private pages: Array<any> = []
124
+ private elements: Array<any> = []
125
+
126
+ constructor (props) {
127
+ super(props)
128
+ appWrapper = this
129
+ appWrapperResolver(this)
130
+ }
131
+
132
+ public mount (pageComponent: any, id: string, cb: () => void) {
133
+ const pageWrapper = connectReactPage(react, id)(pageComponent)
134
+ const key = id + pageKeyId()
135
+ const page = () => h(pageWrapper, { key, tid: id })
136
+ this.pages.push(page)
137
+ this.forceUpdate(cb)
138
+ }
139
+
140
+ public unmount (id: string, cb: () => void) {
141
+ const elements = this.elements
142
+ const idx = elements.findIndex(item => item.props.tid === id)
143
+ elements.splice(idx, 1)
144
+ this.forceUpdate(cb)
145
+ }
146
+
147
+ public render () {
148
+ const { pages, elements } = this
149
+
150
+ while (pages.length > 0) {
151
+ const page = pages.pop()!
152
+ elements.push(page())
153
+ }
154
+
155
+ let props: React.ComponentProps<any> | null = null
156
+
157
+ if (isReactComponent) {
158
+ props = { ref: appInstanceRef }
159
+ }
160
+
161
+ return h(
162
+ App,
163
+ props,
164
+ elements.slice()
165
+ )
166
+ }
167
+ }
168
+
169
+ renderReactRoot()
170
+
171
+ const app = {
172
+ render (cb: () => void) {
173
+ appWrapper.forceUpdate(cb)
174
+ },
175
+ mount (component: any, id: string, cb: () => void) {
176
+ if (appWrapper) {
177
+ appWrapper.mount(component, id, cb)
178
+ } else {
179
+ appWrapperPromise.then(appWrapper => appWrapper.mount(component, id, cb))
180
+ }
181
+ },
182
+
183
+ unmount (id: string, cb: () => void) {
184
+ appWrapper?.unmount(id, cb)
185
+ },
186
+ onLaunch (launchParam?: any) {
187
+ waitAppWrapper(() => {
188
+ // 用户编写的入口组件实例
189
+ const app = getAppInstance()
190
+ this.$app = app
191
+
192
+ if (app) {
193
+ // 把 App Class 上挂载的额外属性同步到全局 app 对象中
194
+ if (app.taroGlobalData) {
195
+ const globalData = app.taroGlobalData
196
+ const keys = Object.keys(globalData)
197
+ const descriptors = Object.getOwnPropertyDescriptors(globalData)
198
+ keys.forEach(key => {
199
+ Object.defineProperty(this, key, {
200
+ configurable: true,
201
+ enumerable: true,
202
+ get () {
203
+ return globalData[key]
204
+ },
205
+ set (value) {
206
+ globalData[key] = value
207
+ }
208
+ })
209
+ })
210
+ Object.defineProperties(this, descriptors)
211
+ }
212
+
213
+ app.onCreate?.()
214
+ }
215
+
216
+ eventCenter.trigger('__taroRouterLaunch', launchParam)
217
+ })
218
+ },
219
+ onShow () {
220
+ waitAppWrapper(() => {
221
+ /**
222
+ * trigger lifecycle
223
+ */
224
+ const app = getAppInstance()
225
+ // class component, componentDidShow
226
+ app?.componentDidShow?.()
227
+ })
228
+ },
229
+ onHide () {
230
+ waitAppWrapper(() => {
231
+ /**
232
+ * trigger lifecycle
233
+ */
234
+ const app = getAppInstance()
235
+ // class component, componentDidShow
236
+ app?.componentDidHide?.()
237
+ })
238
+ }
239
+ }
240
+
241
+ // TODO: function componennt hook
242
+ // function triggerAppHook (lifecycle: string, ...option) {
243
+ // const instance = getPageInstance('taro-app')
244
+ // if (instance) {
245
+ // const app = getAppInstance()
246
+ // const func = hooks.call('getLifecycle', instance, lifecycle)
247
+ // if (Array.isArray(func)) {
248
+ // func.forEach(cb => cb.apply(app, option))
249
+ // }
250
+ // }
251
+ // }
252
+
253
+ Current.app = app
254
+
255
+ return app
256
+ }
@@ -0,0 +1,24 @@
1
+ import { hooks } from '@tarojs/shared'
2
+
3
+ import { ensureIsArray } from './utils'
4
+
5
+ export function setReconciler (ReactDOM) {
6
+ hooks.tap('batchedEventUpdates', function (cb) {
7
+ ReactDOM.unstable_batchedUpdates(cb)
8
+ })
9
+
10
+ hooks.tap('mergePageInstance', function (prev, next) {
11
+ if (!prev || !next) return
12
+
13
+ // 子组件使用 lifecycle hooks 注册了生命周期后,会存在 prev,里面是注册的生命周期回调。
14
+
15
+ // prev 使用 Object.create(null) 创建,H5 的 fast-refresh 可能也会导致存在 prev,要排除这些意外产生的 prev
16
+ if ('constructor' in prev) return
17
+
18
+ Object.keys(prev).forEach(item => {
19
+ const prevList = prev[item]
20
+ const nextList = ensureIsArray<() => any>(next[item])
21
+ next[item] = nextList.concat(prevList)
22
+ })
23
+ })
24
+ }
@@ -0,0 +1,5 @@
1
+ export const ON_SHOW = 'onShow'
2
+ export const ON_HIDE = 'onHide'
3
+ export const ON_LOAD = 'onLoad'
4
+ export const ON_UNLOAD = 'onUnload'
5
+ export const ON_READY = 'onReady'
@@ -0,0 +1,101 @@
1
+ import { Current } from '@tarojs/runtime'
2
+ import { isArray, isFunction } from '@tarojs/shared'
3
+
4
+ import { ReactMeta } from './app'
5
+ import { getPageInstance, injectPageInstance } from './page'
6
+ import { HOOKS_APP_ID } from './utils'
7
+
8
+ import type {
9
+ AppInstance,
10
+ Func,
11
+ Instance,
12
+ PageLifeCycle,
13
+ PageProps
14
+ } from '@tarojs/runtime/dist/runtime.esm'
15
+
16
+ const createTaroHook = (lifecycle: keyof PageLifeCycle | keyof AppInstance) => {
17
+ return (fn: Func) => {
18
+ const { R: React, PageContext } = ReactMeta
19
+ const id = React.useContext(PageContext) || HOOKS_APP_ID
20
+ const instRef = React.useRef<Instance<PageProps>>()
21
+
22
+ // hold fn ref and keep up to date
23
+ const fnRef = React.useRef(fn)
24
+ if (fnRef.current !== fn) fnRef.current = fn
25
+
26
+ React.useLayoutEffect(() => {
27
+
28
+ let inst = instRef.current = getPageInstance(id)
29
+ let first = false
30
+ if (!inst) {
31
+ first = true
32
+ instRef.current = Object.create(null)
33
+ inst = instRef.current!
34
+ }
35
+
36
+ // callback is immutable but inner function is up to date
37
+ const callback = (...args: any) => fnRef.current(...args)
38
+
39
+ if (isFunction(inst[lifecycle])) {
40
+ (inst[lifecycle]) = [inst[lifecycle], callback]
41
+ } else {
42
+ (inst[lifecycle]) = [
43
+ ...((inst[lifecycle]) || []),
44
+ callback
45
+ ]
46
+ }
47
+
48
+ if (first) {
49
+ injectPageInstance(inst!, id)
50
+ }
51
+ return () => {
52
+ const inst = instRef.current
53
+ if (!inst) return
54
+ const list = inst![lifecycle]
55
+ if (list === callback) {
56
+ (inst[lifecycle]) = undefined
57
+ } else if (isArray(list)) {
58
+ (inst[lifecycle]) = list.filter(item => item !== callback)
59
+ }
60
+ instRef.current = undefined
61
+ }
62
+ }, [])
63
+ }
64
+ }
65
+
66
+ /** LifeCycle */
67
+ export const useDidHide = createTaroHook('componentDidHide')
68
+ export const useDidShow = createTaroHook('componentDidShow')
69
+
70
+ /** App */
71
+ export const useError = createTaroHook('onError')
72
+ export const useUnhandledRejection = createTaroHook('onUnhandledRejection')
73
+ export const useLaunch = createTaroHook('onLaunch')
74
+ export const usePageNotFound = createTaroHook('onPageNotFound')
75
+
76
+ /** Page */
77
+ export const useLoad = createTaroHook('onLoad')
78
+ export const usePageScroll = createTaroHook('onPageScroll')
79
+ export const usePullDownRefresh = createTaroHook('onPullDownRefresh')
80
+ export const usePullIntercept = createTaroHook('onPullIntercept')
81
+ export const useReachBottom = createTaroHook('onReachBottom')
82
+ export const useResize = createTaroHook('onResize')
83
+ export const useUnload = createTaroHook('onUnload')
84
+
85
+ /** Mini-Program */
86
+ export const useAddToFavorites = createTaroHook('onAddToFavorites')
87
+ export const useOptionMenuClick = createTaroHook('onOptionMenuClick')
88
+ export const useSaveExitState = createTaroHook('onSaveExitState')
89
+ export const useShareAppMessage = createTaroHook('onShareAppMessage')
90
+ export const useShareTimeline = createTaroHook('onShareTimeline')
91
+ export const useTitleClick = createTaroHook('onTitleClick')
92
+
93
+ /** Router */
94
+ export const useReady = createTaroHook('onReady')
95
+ export const useRouter = (dynamic = false) => {
96
+ const React = ReactMeta.R
97
+ return dynamic ? Current.router : React.useMemo(() => Current.router, [])
98
+ }
99
+ export const useTabItemTap = createTaroHook('onTabItemTap')
100
+
101
+ export const useScope = () => undefined
@@ -0,0 +1,16 @@
1
+ import { hooks } from '@tarojs/shared'
2
+
3
+ import * as taroHooks from './hooks'
4
+
5
+ // declare const __TARO_FRAMEWORK__: string;
6
+
7
+ hooks.tap('initNativeApi', function (taro) {
8
+ for (const hook in taroHooks) {
9
+ taro[hook] = taroHooks[hook]
10
+ }
11
+ })
12
+
13
+ export * from './app'
14
+ export * from './connect'
15
+ export * from './hooks'
16
+ export * from './page'
@@ -0,0 +1,263 @@
1
+ // eslint-disable-next-line import/no-duplicates
2
+ import { Current, document, requestAnimationFrame, window } from '@tarojs/runtime'
3
+ // eslint-disable-next-line import/no-duplicates
4
+ import { CONTEXT_ACTIONS, env, eventCenter } from '@tarojs/runtime/dist/runtime.esm'
5
+ import { hooks, isArray, isFunction, isUndefined } from '@tarojs/shared'
6
+
7
+ import { ON_HIDE, ON_LOAD, ON_READY, ON_SHOW, ON_UNLOAD } from './constant'
8
+ import { incrementId } from './utils'
9
+
10
+ import type { PageConfig } from '@tarojs/taro'
11
+
12
+ // TODO TYPE
13
+ const instances = new Map<string, any>()
14
+ const pageId = incrementId()
15
+
16
+ // TODO TYPE
17
+ export function injectPageInstance (inst: any, id: string) {
18
+ hooks.call('mergePageInstance', instances.get(id), inst)
19
+ instances.set(id, inst)
20
+ }
21
+
22
+ // TODO TYPE
23
+ export function getPageInstance (id: string): any {
24
+ return instances.get(id)
25
+ }
26
+
27
+ export function removePageInstance (id: string) {
28
+ instances.delete(id)
29
+ }
30
+
31
+ export function addLeadingSlash (path?: string): string {
32
+ if (path == null) {
33
+ return ''
34
+ }
35
+ return path.charAt(0) === '/' ? path : '/' + path
36
+ }
37
+
38
+ export function safeExecute (path: string, lifecycle: string, ...args: unknown[]) {
39
+ const instance = instances.get(path)
40
+
41
+ if (instance == null) {
42
+ return
43
+ }
44
+
45
+ lifecycle = lifecycle.replace(/^on(Show|Hide)$/, 'componentDid$1')
46
+ const func = instance[lifecycle]
47
+
48
+ if (isArray(func)) {
49
+ const res = func.map(fn => fn.apply(instance, args))
50
+ return res[0]
51
+ }
52
+
53
+ if (!isFunction(func)) {
54
+ return
55
+ }
56
+
57
+ return func.apply(instance, args)
58
+ }
59
+
60
+ export function stringify (obj?: Record<string, unknown>) {
61
+ if (obj == null) {
62
+ return ''
63
+ }
64
+ const path = Object.keys(obj).map((key) => {
65
+ return key + '=' + obj[key]
66
+ }).join('&')
67
+ return path === '' ? path : '?' + path
68
+ }
69
+
70
+ export function getPath (id: string, options?: Record<string, unknown>): string {
71
+ const idx = id.indexOf('?')
72
+
73
+ return `${idx > -1 ? id.substring(0, idx) : id}${stringify(options)}`
74
+ }
75
+
76
+ export function getOnReadyEventKey (path: string) {
77
+ return path + '.' + ON_READY
78
+ }
79
+
80
+ export function getOnShowEventKey (path: string) {
81
+ return path + '.' + ON_SHOW
82
+ }
83
+
84
+ export function getOnHideEventKey (path: string) {
85
+ return path + '.' + ON_HIDE
86
+ }
87
+
88
+ export function createPageConfig (component: any, pageName?: string, pageConfig?: PageConfig) {
89
+ // 小程序 Page 构造器是一个傲娇小公主,不能把复杂的对象挂载到参数上
90
+ const id = pageName ?? `taro_page_${pageId()}`
91
+ const [
92
+ ONLOAD,
93
+ ONUNLOAD,
94
+ ONREADY,
95
+ ONSHOW,
96
+ ONHIDE,
97
+ LIFECYCLES,
98
+ SIDE_EFFECT_LIFECYCLES,
99
+ ] = hooks.call('getMiniLifecycleImpl')!.page
100
+
101
+ // TODO TYPE
102
+ let pageElement: any = null
103
+ let unmounting = false
104
+ let prepareMountList: (() => void)[] = []
105
+
106
+ // TODO TYPE
107
+ function setCurrentRouter (page) {
108
+ const router = page.route || page.__route__ || page.$taroPath
109
+
110
+ Current.router = {
111
+ params: page.$taroParams!,
112
+ path: addLeadingSlash(router),
113
+ $taroPath: page.$taroPath,
114
+ onReady: getOnReadyEventKey(id),
115
+ onShow: getOnShowEventKey(id),
116
+ onHide: getOnHideEventKey(id)
117
+ }
118
+
119
+ if (!isUndefined(page.exitState)) {
120
+ Current.router.exitState = page.exitState
121
+ }
122
+ }
123
+
124
+ let loadResolver: (...args: any[]) => void
125
+ let hasLoaded: Promise<void>
126
+ const page = {
127
+ [ONLOAD] (options: Readonly<Record<string, unknown>> = {}, cb?: (...args: any[]) => any) {
128
+ hasLoaded = new Promise(resolve => { loadResolver = resolve })
129
+
130
+ Current.page = this as any
131
+
132
+ // this.$taroPath 是页面唯一标识
133
+ const uniqueOptions = Object.assign({}, options, { $taroTimestamp: Date.now() })
134
+ const $taroPath = this.$taroPath = getPath(id, uniqueOptions)
135
+
136
+ // this.$taroParams 作为暴露给开发者的页面参数对象,可以被随意修改
137
+ if (this.$taroParams == null) {
138
+ this.$taroParams = uniqueOptions
139
+ }
140
+
141
+ setCurrentRouter(this)
142
+
143
+ window.trigger(CONTEXT_ACTIONS.INIT, $taroPath)
144
+
145
+ const mount = () => {
146
+ Current.app!.mount!(component, $taroPath, () => {
147
+ pageElement = document.getElementById($taroPath)
148
+
149
+ if (!pageElement) {
150
+ throw new Error(`没有找到页面实例。`)
151
+ }
152
+
153
+ safeExecute($taroPath, ON_LOAD, this.$taroParams)
154
+ loadResolver()
155
+ cb && cb(pageElement)
156
+ pageElement.ctx = this
157
+ })
158
+ }
159
+
160
+ if (unmounting) {
161
+ prepareMountList.push(mount)
162
+ } else {
163
+ mount()
164
+ }
165
+ },
166
+ [ONUNLOAD] () {
167
+ const $taroPath = this.$taroPath
168
+ // 销毁当前页面的上下文信息
169
+ window.trigger(CONTEXT_ACTIONS.DESTORY, $taroPath)
170
+
171
+ // 触发onUnload生命周期
172
+ safeExecute($taroPath, ON_UNLOAD)
173
+ unmounting = true
174
+ Current.app!.unmount!($taroPath, () => {
175
+ unmounting = false
176
+ instances.delete($taroPath)
177
+ if (pageElement) {
178
+ pageElement.ctx = null
179
+ pageElement = null
180
+ }
181
+ if (prepareMountList.length) {
182
+ prepareMountList.forEach(fn => fn())
183
+ prepareMountList = []
184
+ }
185
+ })
186
+ },
187
+ [ONREADY] () {
188
+ hasLoaded.then(() => {
189
+ // 触发生命周期
190
+ safeExecute(this.$taroPath, ON_READY)
191
+ // 通过事件触发子组件的生命周期
192
+ requestAnimationFrame(() => eventCenter.trigger(getOnReadyEventKey(id)))
193
+ this.onReady.called = true
194
+ })
195
+ },
196
+ [ONSHOW] (options = {}) {
197
+ hasLoaded.then(() => {
198
+ // 设置 Current 的 page 和 router
199
+ Current.page = this as any
200
+ setCurrentRouter(this)
201
+ // 恢复上下文信息
202
+ window.trigger(CONTEXT_ACTIONS.RECOVER, this.$taroPath)
203
+ // 触发生命周期
204
+ safeExecute(this.$taroPath, ON_SHOW, options)
205
+ // 通过事件触发子组件的生命周期
206
+ requestAnimationFrame(() => eventCenter.trigger(getOnShowEventKey(id)))
207
+ })
208
+ },
209
+ [ONHIDE] () {
210
+ // 缓存当前页面上下文信息
211
+ window.trigger(CONTEXT_ACTIONS.RESTORE, this.$taroPath)
212
+
213
+ // 设置 Current 的 page 和 router
214
+ if (Current.page === this) {
215
+ Current.page = null
216
+ Current.router = null
217
+ }
218
+ // 触发生命周期
219
+ safeExecute(this.$taroPath, ON_HIDE)
220
+ // TODO 通过事件触发子组件的生命周期
221
+ eventCenter.trigger(getOnHideEventKey(id))
222
+ },
223
+ }
224
+
225
+ LIFECYCLES.forEach((lifecycle) => {
226
+ let isDefer = false
227
+ lifecycle = lifecycle.replace(/^defer:/, () => {
228
+ isDefer = true
229
+ return ''
230
+ })
231
+ page[lifecycle] = function () {
232
+ const exec = () => safeExecute(this.$taroPath, lifecycle, ...arguments)
233
+ if (isDefer) {
234
+ hasLoaded.then(exec)
235
+ } else {
236
+ return exec()
237
+ }
238
+ }
239
+ })
240
+
241
+ // onShareAppMessage 和 onShareTimeline 一样,会影响小程序右上方按钮的选项,因此不能默认注册。
242
+ SIDE_EFFECT_LIFECYCLES.forEach(lifecycle => {
243
+ if (component[lifecycle] ||
244
+ component.prototype?.[lifecycle] ||
245
+ component[lifecycle.replace(/^on/, 'enable')] ||
246
+ pageConfig?.[lifecycle.replace(/^on/, 'enable')]
247
+ ) {
248
+ page[lifecycle] = function (...args) {
249
+ const target = args[0]?.target as any
250
+ if (target?.id) {
251
+ const id = target.id
252
+ const element = env.document.getElementById(id)
253
+ if (element) {
254
+ target.dataset = element.dataset
255
+ }
256
+ }
257
+ return safeExecute(this.$taroPath, lifecycle, ...args)
258
+ }
259
+ }
260
+ })
261
+
262
+ return page
263
+ }
@@ -0,0 +1,25 @@
1
+ import { isArray } from './is'
2
+
3
+ export * from './is'
4
+ export { noop } from '@tarojs/shared'
5
+
6
+ export function capitalize (s: string) {
7
+ return s.charAt(0).toUpperCase() + s.slice(1)
8
+ }
9
+
10
+ export const incrementId = () => {
11
+ let n = 0
12
+ return () => (n++).toString()
13
+ }
14
+
15
+ export function ensureIsArray<T> (item: T | T[]): T[] {
16
+ if (isArray(item)) {
17
+ return item
18
+ } else {
19
+ return item ? [item] : []
20
+ }
21
+ }
22
+
23
+ export const EMPTY_OBJ: any = {}
24
+
25
+ export const HOOKS_APP_ID = 'taro-app'