@mpxjs/core 2.9.39 → 2.9.41-react.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.
- package/package.json +37 -3
- package/src/convertor/convertor.js +4 -1
- package/src/convertor/getConvertMode.js +3 -1
- package/src/convertor/wxToReact.js +31 -0
- package/src/core/proxy.js +27 -5
- package/src/core/transferOptions.js +9 -1
- package/src/{vuePlugin.js → external/vuePlugin.js} +1 -1
- package/src/index.js +6 -2
- package/src/platform/builtInMixins/directiveHelperMixin.android.js +2 -0
- package/src/platform/builtInMixins/directiveHelperMixin.ios.js +15 -0
- package/src/platform/builtInMixins/directiveHelperMixin.js +3 -0
- package/src/platform/builtInMixins/index.js +12 -2
- package/src/platform/builtInMixins/proxyEventMixin.android.js +2 -0
- package/src/platform/builtInMixins/proxyEventMixin.ios.js +49 -0
- package/src/platform/builtInMixins/proxyEventMixin.js +0 -11
- package/src/platform/builtInMixins/refsMixin.android.js +2 -0
- package/src/platform/builtInMixins/refsMixin.ios.js +311 -0
- package/src/platform/builtInMixins/styleHelperMixin.android.js +2 -0
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +141 -0
- package/src/platform/builtInMixins/styleHelperMixin.js +3 -0
- package/src/platform/createApp.android.js +2 -0
- package/src/platform/createApp.ios.js +103 -0
- package/src/platform/createApp.js +3 -5
- package/src/platform/export/api.web.js +1 -1
- package/src/platform/patch/ali/getDefaultOptions.js +4 -4
- package/src/platform/patch/index.js +9 -6
- package/src/platform/patch/react/getDefaultOptions.android.js +1 -0
- package/src/platform/patch/react/getDefaultOptions.ios.js +270 -0
- package/src/platform/patch/react/getDefaultOptions.js +1 -0
- package/src/platform/patch/swan/getDefaultOptions.js +1 -1
- package/src/platform/patch/web/getDefaultOptions.js +13 -3
- package/src/platform/patch/wx/getDefaultOptions.js +1 -1
- /package/src/{vue.js → external/vue.js} +0 -0
- /package/src/{vue.web.js → external/vue.web.js} +0 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { useEffect, useSyncExternalStore, useRef, createElement, memo, forwardRef, useImperativeHandle } from 'react'
|
|
2
|
+
import * as ReactNative from 'react-native'
|
|
3
|
+
import { ReactiveEffect } from '../../../observer/effect'
|
|
4
|
+
import { hasOwn, isFunction, noop, isObject, error, getByPath, collectDataset } from '@mpxjs/utils'
|
|
5
|
+
import MpxProxy from '../../../core/proxy'
|
|
6
|
+
import { BEFOREUPDATE, UPDATED } from '../../../core/innerLifecycle'
|
|
7
|
+
import mergeOptions from '../../../core/mergeOptions'
|
|
8
|
+
import { queueJob } from '../../../observer/scheduler'
|
|
9
|
+
|
|
10
|
+
function getNativeComponent (tagName) {
|
|
11
|
+
return getByPath(ReactNative, tagName)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getRootProps (props) {
|
|
15
|
+
const rootProps = {}
|
|
16
|
+
for (const key in props) {
|
|
17
|
+
if (hasOwn(props, key)) {
|
|
18
|
+
const match = /^(bind|catch|capture-bind|capture-catch|style):?(.*?)(?:\.(.*))?$/.exec(key)
|
|
19
|
+
if (match) {
|
|
20
|
+
rootProps[key] = props[key]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return rootProps
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function createEffect (proxy, components, props) {
|
|
28
|
+
const update = proxy.update = () => {
|
|
29
|
+
// pre render for props update
|
|
30
|
+
if (proxy.propsUpdatedFlag) {
|
|
31
|
+
proxy.updatePreRender()
|
|
32
|
+
}
|
|
33
|
+
if (proxy.isMounted()) {
|
|
34
|
+
proxy.callHook(BEFOREUPDATE)
|
|
35
|
+
proxy.pendingUpdatedFlag = true
|
|
36
|
+
}
|
|
37
|
+
// eslint-disable-next-line symbol-description
|
|
38
|
+
proxy.stateVersion = Symbol()
|
|
39
|
+
proxy.onStoreChange && proxy.onStoreChange()
|
|
40
|
+
}
|
|
41
|
+
update.id = proxy.uid
|
|
42
|
+
proxy.effect = new ReactiveEffect(() => {
|
|
43
|
+
return proxy.target.__injectedRender(createElement, components, getNativeComponent, getRootProps(props))
|
|
44
|
+
}, () => queueJob(update), proxy.scope)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function createInstance ({ propsRef, ref, type, rawOptions, currentInject, validProps, components }) {
|
|
48
|
+
const instance = Object.create({
|
|
49
|
+
setData (data, callback) {
|
|
50
|
+
return this.__mpxProxy.forceUpdate(data, { sync: true }, callback)
|
|
51
|
+
},
|
|
52
|
+
__getProps () {
|
|
53
|
+
const propsData = {}
|
|
54
|
+
const props = propsRef.current
|
|
55
|
+
if (props) {
|
|
56
|
+
Object.keys(props).forEach((key) => {
|
|
57
|
+
if (hasOwn(validProps, key) && !isFunction(props[key])) {
|
|
58
|
+
propsData[key] = props[key]
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
return propsData
|
|
63
|
+
},
|
|
64
|
+
__getSlot (name) {
|
|
65
|
+
const { children } = propsRef.current || {}
|
|
66
|
+
if (children) {
|
|
67
|
+
const result = []
|
|
68
|
+
if (Array.isArray(children)) {
|
|
69
|
+
children.forEach(child => {
|
|
70
|
+
if (child && child.props && child.props.slot === name) {
|
|
71
|
+
result.push(child)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
} else {
|
|
75
|
+
if (children && children.props && children.props.slot === name) {
|
|
76
|
+
result.push(children)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result.filter(item => {
|
|
80
|
+
if (this.__dispatchedSlotSet.has(item)) {
|
|
81
|
+
return false
|
|
82
|
+
} else {
|
|
83
|
+
this.__dispatchedSlotSet.add(item)
|
|
84
|
+
return true
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
return null
|
|
89
|
+
},
|
|
90
|
+
__injectedRender: currentInject.render || noop,
|
|
91
|
+
__getRefsData: currentInject.getRefsData || noop,
|
|
92
|
+
// render helper
|
|
93
|
+
_i (val, fn) {
|
|
94
|
+
let i, l, keys, key
|
|
95
|
+
const result = []
|
|
96
|
+
if (Array.isArray(val) || typeof val === 'string') {
|
|
97
|
+
for (i = 0, l = val.length; i < l; i++) {
|
|
98
|
+
result.push(fn.call(this, val[i], i))
|
|
99
|
+
}
|
|
100
|
+
} else if (typeof val === 'number') {
|
|
101
|
+
for (i = 0; i < val; i++) {
|
|
102
|
+
result.push(fn.call(this, i + 1, i))
|
|
103
|
+
}
|
|
104
|
+
} else if (isObject(val)) {
|
|
105
|
+
keys = Object.keys(val)
|
|
106
|
+
for (i = 0, l = keys.length; i < l; i++) {
|
|
107
|
+
key = keys[i]
|
|
108
|
+
result.push(fn.call(this, val[key], key, i))
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return result
|
|
112
|
+
},
|
|
113
|
+
triggerEvent (eventName, eventDetail) {
|
|
114
|
+
const props = propsRef.current
|
|
115
|
+
const handlerName = eventName.replace(/^./, matched => matched.toUpperCase()).replace(/-([a-z])/g, (match, p1) => p1.toUpperCase())
|
|
116
|
+
const handler = props && (props['bind' + handlerName] || props['catch' + handlerName] || props['capture-bind' + handlerName] || props['capture-catch' + handlerName])
|
|
117
|
+
if (handler && typeof handler === 'function') {
|
|
118
|
+
const timeStamp = +new Date()
|
|
119
|
+
const dataset = collectDataset(props)
|
|
120
|
+
const id = props.id || ''
|
|
121
|
+
const eventObj = {
|
|
122
|
+
type: eventName,
|
|
123
|
+
timeStamp,
|
|
124
|
+
target: {
|
|
125
|
+
id,
|
|
126
|
+
dataset,
|
|
127
|
+
targetDataset: dataset
|
|
128
|
+
},
|
|
129
|
+
currentTarget: {
|
|
130
|
+
id,
|
|
131
|
+
dataset
|
|
132
|
+
},
|
|
133
|
+
detail: eventDetail
|
|
134
|
+
}
|
|
135
|
+
handler.call(this, eventObj)
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
selectComponent () {
|
|
139
|
+
error('selectComponent is not supported in react native, please use ref instead')
|
|
140
|
+
},
|
|
141
|
+
selectAllComponents () {
|
|
142
|
+
error('selectAllComponents is not supported in react native, please use ref instead')
|
|
143
|
+
},
|
|
144
|
+
createSelectorQuery () {
|
|
145
|
+
error('createSelectorQuery is not supported in react native, please use ref instead')
|
|
146
|
+
},
|
|
147
|
+
createIntersectionObserver () {
|
|
148
|
+
error('createIntersectionObserver is not supported in react native, please use ref instead')
|
|
149
|
+
},
|
|
150
|
+
...rawOptions.methods
|
|
151
|
+
}, {
|
|
152
|
+
dataset: {
|
|
153
|
+
get () {
|
|
154
|
+
const props = propsRef.current
|
|
155
|
+
return collectDataset(props)
|
|
156
|
+
},
|
|
157
|
+
enumerable: true
|
|
158
|
+
},
|
|
159
|
+
id: {
|
|
160
|
+
get () {
|
|
161
|
+
const props = propsRef.current
|
|
162
|
+
return props.id
|
|
163
|
+
},
|
|
164
|
+
enumerable: true
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance)
|
|
169
|
+
proxy.created()
|
|
170
|
+
Object.assign(proxy, {
|
|
171
|
+
onStoreChange: null,
|
|
172
|
+
// eslint-disable-next-line symbol-description
|
|
173
|
+
stateVersion: Symbol(),
|
|
174
|
+
subscribe: (onStoreChange) => {
|
|
175
|
+
if (!proxy.effect) {
|
|
176
|
+
createEffect(proxy, components, propsRef.current)
|
|
177
|
+
// eslint-disable-next-line symbol-description
|
|
178
|
+
proxy.stateVersion = Symbol()
|
|
179
|
+
}
|
|
180
|
+
proxy.onStoreChange = onStoreChange
|
|
181
|
+
return () => {
|
|
182
|
+
proxy.effect && proxy.effect.stop()
|
|
183
|
+
proxy.effect = null
|
|
184
|
+
proxy.onStoreChange = null
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
getSnapshot: () => {
|
|
188
|
+
return proxy.stateVersion
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
// react数据响应组件更新管理器
|
|
192
|
+
if (!proxy.effect) {
|
|
193
|
+
createEffect(proxy, components, propsRef.current)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return instance
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
200
|
+
rawOptions = mergeOptions(rawOptions, type, false)
|
|
201
|
+
const { RootSiblingParent } = global.__navigationHelper
|
|
202
|
+
const components = currentInject.getComponents() || {}
|
|
203
|
+
const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
|
|
204
|
+
const defaultOptions = memo(forwardRef((props, ref) => {
|
|
205
|
+
const instanceRef = useRef(null)
|
|
206
|
+
const propsRef = useRef(props)
|
|
207
|
+
let isFirst = false
|
|
208
|
+
if (!instanceRef.current) {
|
|
209
|
+
isFirst = true
|
|
210
|
+
instanceRef.current = createInstance({ propsRef, ref, type, rawOptions, currentInject, validProps, components })
|
|
211
|
+
}
|
|
212
|
+
const instance = instanceRef.current
|
|
213
|
+
// reset instance
|
|
214
|
+
instance.__refs = {}
|
|
215
|
+
instance.__dispatchedSlotSet = new WeakSet()
|
|
216
|
+
useImperativeHandle(ref, () => {
|
|
217
|
+
return instance
|
|
218
|
+
})
|
|
219
|
+
const proxy = instance.__mpxProxy
|
|
220
|
+
|
|
221
|
+
if (!isFirst) {
|
|
222
|
+
// 处理props更新
|
|
223
|
+
propsRef.current = props
|
|
224
|
+
Object.keys(props).forEach(key => {
|
|
225
|
+
if (hasOwn(validProps, key) && !isFunction(props[key])) {
|
|
226
|
+
instance[key] = props[key]
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
proxy.propsUpdated()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
if (proxy.pendingUpdatedFlag) {
|
|
234
|
+
proxy.pendingUpdatedFlag = false
|
|
235
|
+
proxy.callHook(UPDATED)
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
useEffect(() => {
|
|
240
|
+
proxy.mounted()
|
|
241
|
+
return () => {
|
|
242
|
+
proxy.unmounted()
|
|
243
|
+
}
|
|
244
|
+
}, [])
|
|
245
|
+
|
|
246
|
+
useSyncExternalStore(proxy.subscribe, proxy.getSnapshot)
|
|
247
|
+
|
|
248
|
+
return proxy.effect.run()
|
|
249
|
+
}))
|
|
250
|
+
|
|
251
|
+
if (type === 'page') {
|
|
252
|
+
const Page = () => {
|
|
253
|
+
return createElement(RootSiblingParent,
|
|
254
|
+
null,
|
|
255
|
+
createElement(ReactNative.ScrollView,
|
|
256
|
+
{
|
|
257
|
+
style: {
|
|
258
|
+
...ReactNative.StyleSheet.absoluteFillObject
|
|
259
|
+
},
|
|
260
|
+
showsVerticalScrollIndicator: false
|
|
261
|
+
},
|
|
262
|
+
createElement(defaultOptions)
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
return Page
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return defaultOptions
|
|
270
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function getDefaultOptions () {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import mergeOptions from '../../../core/mergeOptions'
|
|
2
2
|
import { initProxy, filterOptions } from '../wx/getDefaultOptions'
|
|
3
3
|
|
|
4
|
-
export function getDefaultOptions (type,
|
|
4
|
+
export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
5
5
|
let hookNames = ['attached', 'ready', 'detached']
|
|
6
6
|
// 当用户传入page作为构造器构造页面时,修改所有关键hooks
|
|
7
7
|
if (rawOptions.__pageCtor__) {
|
|
@@ -3,7 +3,14 @@ import mergeOptions from '../../../core/mergeOptions'
|
|
|
3
3
|
import { diffAndCloneA, hasOwn } from '@mpxjs/utils'
|
|
4
4
|
import { getCurrentInstance as getCurrentVueInstance } from '../../export/index'
|
|
5
5
|
import MpxProxy, { setCurrentInstance, unsetCurrentInstance } from '../../../core/proxy'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
BEFORECREATE,
|
|
8
|
+
BEFOREUPDATE,
|
|
9
|
+
UPDATED,
|
|
10
|
+
BEFOREUNMOUNT,
|
|
11
|
+
UNMOUNTED,
|
|
12
|
+
SERVERPREFETCH
|
|
13
|
+
} from '../../../core/innerLifecycle'
|
|
7
14
|
|
|
8
15
|
function filterOptions (options) {
|
|
9
16
|
const newOptions = {}
|
|
@@ -37,7 +44,7 @@ function initProxy (context, rawOptions) {
|
|
|
37
44
|
}
|
|
38
45
|
}
|
|
39
46
|
|
|
40
|
-
export function getDefaultOptions (type,
|
|
47
|
+
export function getDefaultOptions ({ type, rawOptions = {} }) {
|
|
41
48
|
const rawSetup = rawOptions.setup
|
|
42
49
|
if (rawSetup) {
|
|
43
50
|
rawOptions.setup = (props) => {
|
|
@@ -78,7 +85,10 @@ export function getDefaultOptions (type, { rawOptions = {} }) {
|
|
|
78
85
|
if (this.__mpxProxy) this.__mpxProxy.callHook(BEFOREUNMOUNT)
|
|
79
86
|
},
|
|
80
87
|
destroyed () {
|
|
81
|
-
if (this.__mpxProxy)
|
|
88
|
+
if (this.__mpxProxy) {
|
|
89
|
+
this.__mpxProxy.state = UNMOUNTED
|
|
90
|
+
this.__mpxProxy.callHook(UNMOUNTED)
|
|
91
|
+
}
|
|
82
92
|
},
|
|
83
93
|
serverPrefetch () {
|
|
84
94
|
if (this.__mpxProxy) return this.__mpxProxy.callHook(SERVERPREFETCH)
|
|
@@ -161,7 +161,7 @@ export function initProxy (context, rawOptions, currentInject) {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
export function getDefaultOptions (type,
|
|
164
|
+
export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
165
165
|
let hookNames = ['attached', 'ready', 'detached']
|
|
166
166
|
// 当用户传入page作为构造器构造页面时,修改所有关键hooks
|
|
167
167
|
if (rawOptions.__pageCtor__) {
|
|
File without changes
|
|
File without changes
|