@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.
- package/LICENSE +160 -0
- package/dist/apis/apis.ts +15 -0
- package/dist/apis/base/index.ts +5 -0
- package/dist/apis/base/system.ts +77 -0
- package/dist/apis/device/accelerometer.ts +76 -0
- package/dist/apis/device/battery.ts +24 -0
- package/dist/apis/device/clipboard.ts +70 -0
- package/dist/apis/device/index.ts +9 -0
- package/dist/apis/device/keyboard.ts +62 -0
- package/dist/apis/device/memory.ts +4 -0
- package/dist/apis/device/network.ts +72 -0
- package/dist/apis/device/phone.ts +43 -0
- package/dist/apis/device/screen.ts +79 -0
- package/dist/apis/device/vibrate.ts +24 -0
- package/dist/apis/files/index.ts +135 -0
- package/dist/apis/files/manager.ts +941 -0
- package/dist/apis/framework/index.ts +32 -0
- package/dist/apis/index.ts +124 -0
- package/dist/apis/location/index.ts +133 -0
- package/dist/apis/media/common.ts +74 -0
- package/dist/apis/media/image.ts +122 -0
- package/dist/apis/media/index.ts +3 -0
- package/dist/apis/media/video.ts +86 -0
- package/dist/apis/navigate/index.ts +8 -0
- package/dist/apis/network/downloadFile.ts +113 -0
- package/dist/apis/network/index.ts +4 -0
- package/dist/apis/network/request.ts +113 -0
- package/dist/apis/network/uploadFile.ts +158 -0
- package/dist/apis/network/webSocket.ts +130 -0
- package/dist/apis/open-api/index.ts +7 -0
- package/dist/apis/open-api/user-info/index.ts +85 -0
- package/dist/apis/page/index.ts +92 -0
- package/dist/apis/route/index.ts +138 -0
- package/dist/apis/storage/index.ts +133 -0
- package/dist/apis/tabbar/index.ts +147 -0
- package/dist/apis/ui/animation.ts +222 -0
- package/dist/apis/ui/background.ts +35 -0
- package/dist/apis/ui/index.ts +14 -0
- package/dist/apis/ui/interaction/index.ts +195 -0
- package/dist/apis/ui/navigation-bar/index.ts +33 -0
- package/dist/apis/ui/pull-down-refresh.ts +41 -0
- package/dist/apis/utils/handler.ts +116 -0
- package/dist/apis/utils/index.ts +85 -0
- package/dist/apis/utils/types.ts +12 -0
- package/dist/apis/utils/validate.ts +87 -0
- package/dist/apis/wxml/IntersectionObserver.ts +119 -0
- package/dist/apis/wxml/index.ts +12 -0
- package/dist/apis/wxml/nodesRef.ts +56 -0
- package/dist/apis/wxml/selectorQuery.ts +287 -0
- package/dist/components/components-react.js +51 -0
- package/dist/components/components-react.js.map +1 -0
- package/dist/components-harmony/button/index.css +109 -0
- package/dist/components-harmony/button/index.hml +31 -0
- package/dist/components-harmony/button/index.js +105 -0
- package/dist/components-harmony/camera/index.hml +6 -0
- package/dist/components-harmony/camera/index.js +12 -0
- package/dist/components-harmony/checkbox/index.hml +11 -0
- package/dist/components-harmony/checkbox/index.js +60 -0
- package/dist/components-harmony/checkbox-group/index.hml +3 -0
- package/dist/components-harmony/checkbox-group/index.js +22 -0
- package/dist/components-harmony/cover-image/index.css +4 -0
- package/dist/components-harmony/cover-image/index.hml +9 -0
- package/dist/components-harmony/cover-image/index.js +15 -0
- package/dist/components-harmony/form/index.hml +10 -0
- package/dist/components-harmony/form/index.js +11 -0
- package/dist/components-harmony/icon/index.css +27 -0
- package/dist/components-harmony/icon/index.hml +54 -0
- package/dist/components-harmony/icon/index.js +17 -0
- package/dist/components-harmony/image/index.css +5 -0
- package/dist/components-harmony/image/index.hml +11 -0
- package/dist/components-harmony/image/index.js +28 -0
- package/dist/components-harmony/input/index.hml +21 -0
- package/dist/components-harmony/input/index.js +98 -0
- package/dist/components-harmony/label/index.hml +3 -0
- package/dist/components-harmony/label/index.js +6 -0
- package/dist/components-harmony/navbar/index.css +56 -0
- package/dist/components-harmony/navbar/index.hml +9 -0
- package/dist/components-harmony/navbar/index.js +30 -0
- package/dist/components-harmony/navigator/index.css +8 -0
- package/dist/components-harmony/navigator/index.hml +9 -0
- package/dist/components-harmony/navigator/index.js +104 -0
- package/dist/components-harmony/picker/index.hml +25 -0
- package/dist/components-harmony/picker/index.js +132 -0
- package/dist/components-harmony/picker-view/index.hml +23 -0
- package/dist/components-harmony/picker-view/index.js +161 -0
- package/dist/components-harmony/picker-view-column/index.hml +3 -0
- package/dist/components-harmony/picker-view-column/index.js +3 -0
- package/dist/components-harmony/progress/index.css +4 -0
- package/dist/components-harmony/progress/index.hml +28 -0
- package/dist/components-harmony/progress/index.js +23 -0
- package/dist/components-harmony/radio/index.hml +11 -0
- package/dist/components-harmony/radio/index.js +41 -0
- package/dist/components-harmony/radio-group/index.hml +3 -0
- package/dist/components-harmony/radio-group/index.js +11 -0
- package/dist/components-harmony/rich-text/index.hml +5 -0
- package/dist/components-harmony/rich-text/index.js +16 -0
- package/dist/components-harmony/scroll-view/index.css +5 -0
- package/dist/components-harmony/scroll-view/index.hml +12 -0
- package/dist/components-harmony/scroll-view/index.js +65 -0
- package/dist/components-harmony/slider/index.hml +16 -0
- package/dist/components-harmony/slider/index.js +53 -0
- package/dist/components-harmony/swiper/index.css +3 -0
- package/dist/components-harmony/swiper/index.hml +14 -0
- package/dist/components-harmony/swiper/index.js +19 -0
- package/dist/components-harmony/switch/index.hml +7 -0
- package/dist/components-harmony/switch/index.js +16 -0
- package/dist/components-harmony/tabbar/index.css +7 -0
- package/dist/components-harmony/tabbar/index.hml +26 -0
- package/dist/components-harmony/tabbar/index.js +42 -0
- package/dist/components-harmony/textarea/index.hml +24 -0
- package/dist/components-harmony/textarea/index.js +92 -0
- package/dist/components-harmony/utils/index.js +41 -0
- package/dist/components-harmony/video/index.hml +7 -0
- package/dist/components-harmony/video/index.js +73 -0
- package/dist/components-harmony/web-view/index.hml +8 -0
- package/dist/components-harmony/web-view/index.js +22 -0
- package/dist/components-harmony-ets/base.ets +63 -0
- package/dist/components-harmony-ets/button.ets +119 -0
- package/dist/components-harmony-ets/checkbox.ets +219 -0
- package/dist/components-harmony-ets/element.ets +223 -0
- package/dist/components-harmony-ets/form.ets +149 -0
- package/dist/components-harmony-ets/icon.ets +84 -0
- package/dist/components-harmony-ets/image.ets +85 -0
- package/dist/components-harmony-ets/index.ts +49 -0
- package/dist/components-harmony-ets/innerHtml.ets +79 -0
- package/dist/components-harmony-ets/input.ets +195 -0
- package/dist/components-harmony-ets/label.ets +111 -0
- package/dist/components-harmony-ets/picker.ets +370 -0
- package/dist/components-harmony-ets/radio.ets +225 -0
- package/dist/components-harmony-ets/richText.ets +97 -0
- package/dist/components-harmony-ets/scrollView.ets +199 -0
- package/dist/components-harmony-ets/slider.ets +159 -0
- package/dist/components-harmony-ets/swiper.ets +204 -0
- package/dist/components-harmony-ets/switch.ets +113 -0
- package/dist/components-harmony-ets/text.ets +97 -0
- package/dist/components-harmony-ets/textArea.ets +169 -0
- package/dist/components-harmony-ets/utils/AttributeManager.ets +250 -0
- package/dist/components-harmony-ets/utils/DynamicCenter.ts +48 -0
- package/dist/components-harmony-ets/utils/constant/event.ets +25 -0
- package/dist/components-harmony-ets/utils/constant/icon.ts +19 -0
- package/dist/components-harmony-ets/utils/constant/style.ets +88 -0
- package/dist/components-harmony-ets/utils/events.ts +24 -0
- package/dist/components-harmony-ets/utils/flexManager.ets +107 -0
- package/dist/components-harmony-ets/utils/helper.ets +99 -0
- package/dist/components-harmony-ets/utils/htmlParser/HarmonyHTMLParser.ts +103 -0
- package/dist/components-harmony-ets/utils/htmlParser/index.ts +56 -0
- package/dist/components-harmony-ets/utils/index.ts +83 -0
- package/dist/components-harmony-ets/utils/styles.ets +91 -0
- package/dist/components-harmony-ets/video.ets +161 -0
- package/dist/components-harmony-ets/view.ets +79 -0
- package/dist/index.js +1183 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime-ets/bom/document.ts +38 -0
- package/dist/runtime-ets/bom/getComputedStyle.ts +5 -0
- package/dist/runtime-ets/bom/navigator.ts +21 -0
- package/dist/runtime-ets/bom/raf.ts +37 -0
- package/dist/runtime-ets/bom/window.ts +44 -0
- package/dist/runtime-ets/constant.ts +29 -0
- package/dist/runtime-ets/current.ts +16 -0
- package/dist/runtime-ets/dom/class-list.ts +117 -0
- package/dist/runtime-ets/dom/comment.ts +10 -0
- package/dist/runtime-ets/dom/cssStyleDeclaration.ts +105 -0
- package/dist/runtime-ets/dom/document.ts +108 -0
- package/dist/runtime-ets/dom/element.ts +457 -0
- package/dist/runtime-ets/dom/event.ts +164 -0
- package/dist/runtime-ets/dom/eventTarget.ts +98 -0
- package/dist/runtime-ets/dom/node.ts +215 -0
- package/dist/runtime-ets/dom/stylesheet/index.ts +687 -0
- package/dist/runtime-ets/dom/stylesheet/type.ts +136 -0
- package/dist/runtime-ets/dom/stylesheet/util.ts +134 -0
- package/dist/runtime-ets/dom/text.ts +19 -0
- package/dist/runtime-ets/index.ts +19 -0
- package/dist/runtime-ets/interface/event.ts +9 -0
- package/dist/runtime-ets/interface/index.ts +1 -0
- package/dist/runtime-ets/utils/bind.ts +35 -0
- package/dist/runtime-ets/utils/index.ts +135 -0
- package/dist/runtime-ets/utils/info.ts +128 -0
- package/dist/runtime-framework/react/app.ts +256 -0
- package/dist/runtime-framework/react/connect.ts +24 -0
- package/dist/runtime-framework/react/constant.ts +5 -0
- package/dist/runtime-framework/react/hooks.ts +101 -0
- package/dist/runtime-framework/react/index.ts +16 -0
- package/dist/runtime-framework/react/page.ts +263 -0
- package/dist/runtime-framework/react/utils/index.ts +25 -0
- package/dist/runtime-framework/react/utils/is.ts +46 -0
- package/dist/runtime-framework/solid/README.md +99 -0
- package/dist/runtime-framework/solid/app.ts +200 -0
- package/dist/runtime-framework/solid/connect.ts +11 -0
- package/dist/runtime-framework/solid/contant.ts +5 -0
- package/dist/runtime-framework/solid/hooks.ts +88 -0
- package/dist/runtime-framework/solid/index.ts +10 -0
- package/dist/runtime-framework/solid/page.ts +202 -0
- package/dist/runtime-framework/solid/reconciler/h.ts +132 -0
- package/dist/runtime-framework/solid/reconciler/index.ts +3 -0
- package/dist/runtime-framework/solid/reconciler/props.ts +151 -0
- package/dist/runtime-framework/solid/reconciler/render.ts +61 -0
- package/dist/runtime-framework/solid/reconciler/use.ts +8 -0
- package/dist/runtime-framework/solid/utils/index.ts +49 -0
- package/dist/runtime-framework/solid/utils/is.ts +46 -0
- package/dist/runtime-utils.js +4149 -0
- package/dist/runtime-utils.js.map +1 -0
- package/dist/runtime.js +4150 -0
- package/dist/runtime.js.map +1 -0
- package/dist/template/container.js +7 -0
- package/index.js +4 -0
- package/package.json +54 -0
- package/types/api.d.ts +4 -0
- package/types/component.d.ts +4 -0
- package/types/harmony.d.ts +11 -0
- package/types/runtime.d.ts +15 -0
- package/types/taro.d.ts +7 -0
- 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,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'
|