@mpxjs/api-proxy 2.9.53 → 2.9.59
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/@types/index.d.ts +7 -7
- package/package.json +20 -4
- package/src/common/js/promisify.js +3 -1
- package/src/common/js/utils.js +13 -1
- package/src/common/js/web.js +0 -12
- package/src/platform/api/action-sheet/ActionSheet.js +3 -7
- package/src/platform/api/action-sheet/index.android.js +1 -0
- package/src/platform/api/action-sheet/index.ios.js +1 -0
- package/src/platform/api/action-sheet/rnActionSheet.jsx +127 -0
- package/src/platform/api/app/index.android.js +1 -0
- package/src/platform/api/app/index.ios.js +1 -0
- package/src/platform/api/app/index.web.js +5 -4
- package/src/platform/api/clipboard-data/rnClipboard.js +5 -5
- package/src/platform/api/create-intersection-observer/IntersectionObserver.js +5 -5
- package/src/platform/api/create-selector-query/index.android.js +1 -0
- package/src/platform/api/create-selector-query/index.ios.js +9 -0
- package/src/platform/api/create-selector-query/rnNodesRef.js +262 -0
- package/src/platform/api/create-selector-query/rnSelectQuery.js +43 -0
- package/src/platform/api/device/network/getNetworkType.js +4 -4
- package/src/platform/api/device/network/rnNetwork.js +3 -3
- package/src/platform/api/image/Preview.js +3 -3
- package/src/platform/api/location/index.ali.js +31 -0
- package/src/platform/api/location/index.android.js +1 -0
- package/src/platform/api/location/index.ios.js +31 -0
- package/src/platform/api/location/index.js +13 -0
- package/src/platform/api/location/index.web.js +36 -0
- package/src/platform/api/make-phone-call/rnMakePhone.js +3 -3
- package/src/platform/api/modal/Modal.js +12 -15
- package/src/platform/api/modal/index.android.js +1 -0
- package/src/platform/api/modal/index.ios.js +1 -0
- package/src/platform/api/modal/rnModal.jsx +149 -0
- package/src/platform/api/next-tick/index.android.js +1 -0
- package/src/platform/api/next-tick/index.ios.js +1 -0
- package/src/platform/api/page-scroll-to/index.web.js +3 -3
- package/src/platform/api/pull-down/index.web.js +5 -5
- package/src/platform/api/request/index.web.js +3 -6
- package/src/platform/api/route/index.ios.js +9 -9
- package/src/platform/api/route/index.web.js +15 -18
- package/src/platform/api/screen-brightness/index.android.js +1 -0
- package/src/platform/api/screen-brightness/index.ios.js +1 -0
- package/src/platform/api/screen-brightness/rnScreenBrightness.js +53 -0
- package/src/platform/api/set-navigation-bar/index.android.js +1 -0
- package/src/platform/api/set-navigation-bar/index.ios.js +41 -0
- package/src/platform/api/set-navigation-bar/index.web.js +3 -3
- package/src/platform/api/socket/SocketTask.js +7 -17
- package/src/platform/api/socket/index.web.js +3 -3
- package/src/platform/api/storage/index.web.js +11 -12
- package/src/platform/api/storage/rnStorage.js +12 -12
- package/src/platform/api/system/index.web.js +2 -2
- package/src/platform/api/system/rnSystem.js +3 -3
- package/src/platform/api/tab-bar/index.web.js +9 -9
- package/src/platform/api/toast/Toast.js +3 -3
- package/src/platform/api/toast/error.png +0 -0
- package/src/platform/api/toast/index.android.js +1 -0
- package/src/platform/api/toast/index.ios.js +1 -0
- package/src/platform/api/toast/rnToast.jsx +189 -0
- package/src/platform/api/toast/success.png +0 -0
- package/src/platform/index.js +3 -0
package/@types/index.d.ts
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
type AddPromise<W> = {
|
|
4
4
|
[K in keyof W]: W[K] extends (...args: any) => any
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
? Parameters<W[K]> extends [{ success?: (res: infer R) => any }?, ...any[]]
|
|
6
|
+
? (...args: Parameters<W[K]>) => ReturnType<W[K]> & Promise<R>
|
|
7
|
+
: W[K]
|
|
7
8
|
: W[K]
|
|
8
|
-
: W[K]
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
type AddParam<O, V extends (...args: any) => any> =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
Parameters<V> extends [{ success?: (res: infer R) => any }, ...any[]]
|
|
13
|
+
? (options: O) => ReturnType<V> & Promise<R>
|
|
14
|
+
: (options: O) => ReturnType<V>
|
|
15
15
|
// @ts-ignore
|
|
16
16
|
type PickApiValue<T extends keyof WechatMiniprogram.Wx> = Pick<WechatMiniprogram.Wx, T>[T]
|
|
17
17
|
// @ts-ignore
|
|
@@ -33,7 +33,7 @@ declare module '@mpxjs/core' {
|
|
|
33
33
|
|
|
34
34
|
export const getProxy: (...args: any) => void
|
|
35
35
|
|
|
36
|
-
export const promisify: (listObj: object, whiteList
|
|
36
|
+
export const promisify: (listObj: object, whiteList?: string[], customBlackList?: string[]) => Record<string, any>
|
|
37
37
|
|
|
38
38
|
export const showActionSheet: WechatMiniprogram.Wx['showActionSheet']
|
|
39
39
|
export const addPhoneContact: WechatMiniprogram.Wx['addPhoneContact']
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/api-proxy",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.59",
|
|
4
4
|
"description": "convert miniprogram API at each end",
|
|
5
5
|
"module": "src/index.js",
|
|
6
6
|
"types": "@types/index.d.ts",
|
|
@@ -37,15 +37,19 @@
|
|
|
37
37
|
},
|
|
38
38
|
"homepage": "https://github.com/didi/mpx#readme",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@mpxjs/utils": "^2.9.
|
|
40
|
+
"@mpxjs/utils": "^2.9.59",
|
|
41
41
|
"axios": "^1.7.3"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
+
"@ant-design/react-native": "^5.1.3",
|
|
44
45
|
"@react-native-async-storage/async-storage": "^1.23.1",
|
|
45
46
|
"@react-native-clipboard/clipboard": "^1.14.0",
|
|
46
47
|
"@react-native-community/netinfo": "^11.2.1",
|
|
48
|
+
"expo-brightness": "~11.8.0",
|
|
47
49
|
"react-native-device-info": "^10.13.2",
|
|
48
|
-
"react-native-
|
|
50
|
+
"react-native-get-location": "^4.0.1",
|
|
51
|
+
"react-native-safe-area-context": "^4.10.1",
|
|
52
|
+
"react-native-webview": "^13.10.5"
|
|
49
53
|
},
|
|
50
54
|
"peerDependenciesMeta": {
|
|
51
55
|
"@react-native-async-storage/async-storage": {
|
|
@@ -62,7 +66,19 @@
|
|
|
62
66
|
},
|
|
63
67
|
"react-native-safe-area-context": {
|
|
64
68
|
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"react-native-get-location": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"@ant-design/react-native": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"expo-brightness": {
|
|
77
|
+
"optional": true
|
|
78
|
+
},
|
|
79
|
+
"react-native-webview": {
|
|
80
|
+
"optional": true
|
|
65
81
|
}
|
|
66
82
|
},
|
|
67
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "aa001c11cc7b21772fc6f9f5bcdd13118fc6d67c"
|
|
68
84
|
}
|
package/src/common/js/utils.js
CHANGED
|
@@ -77,6 +77,16 @@ function throwSSRWarning (info) {
|
|
|
77
77
|
console.error(`[Mpx runtime error]: Dangerous API! ${info}, It may cause some problems, please use this method with caution`)
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
function successHandle (result, success, complete) {
|
|
81
|
+
typeof success === 'function' && success(result)
|
|
82
|
+
typeof complete === 'function' && complete(result)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function failHandle (result, fail, complete) {
|
|
86
|
+
typeof fail === 'function' && fail(result)
|
|
87
|
+
typeof complete === 'function' && complete(result)
|
|
88
|
+
}
|
|
89
|
+
|
|
80
90
|
const ENV_OBJ = getEnvObj()
|
|
81
91
|
|
|
82
92
|
export {
|
|
@@ -88,5 +98,7 @@ export {
|
|
|
88
98
|
isBrowser,
|
|
89
99
|
throwSSRWarning,
|
|
90
100
|
ENV_OBJ,
|
|
91
|
-
defineUnsupportedProps
|
|
101
|
+
defineUnsupportedProps,
|
|
102
|
+
successHandle,
|
|
103
|
+
failHandle
|
|
92
104
|
}
|
package/src/common/js/web.js
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
function webHandleSuccess (result, success, complete) {
|
|
2
|
-
typeof success === 'function' && success(result)
|
|
3
|
-
typeof complete === 'function' && complete(result)
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
function webHandleFail (result, fail, complete) {
|
|
7
|
-
typeof fail === 'function' && fail(result)
|
|
8
|
-
typeof complete === 'function' && complete(result)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
1
|
function isTabBarPage (url, router) {
|
|
12
2
|
const tabBarPagesMap = global.__tabBarPagesMap
|
|
13
3
|
if (!tabBarPagesMap || !url) return false
|
|
@@ -49,8 +39,6 @@ function getRootElement () {
|
|
|
49
39
|
}
|
|
50
40
|
|
|
51
41
|
export {
|
|
52
|
-
webHandleSuccess,
|
|
53
|
-
webHandleFail,
|
|
54
42
|
createDom,
|
|
55
43
|
bindTap,
|
|
56
44
|
getRootElement,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { successHandle, failHandle, createDom, bindTap, getRootElement } from '../../../common/js'
|
|
2
2
|
import '../../../common/stylus/ActionSheet.styl'
|
|
3
3
|
|
|
4
4
|
export default class ActionSheet {
|
|
@@ -44,8 +44,7 @@ export default class ActionSheet {
|
|
|
44
44
|
errMsg: 'showActionSheet:ok',
|
|
45
45
|
tapIndex: index
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
// this.toPromiseResolve(res)
|
|
47
|
+
successHandle(res, opts.success, opts.complete)
|
|
49
48
|
}))
|
|
50
49
|
list.appendChild(sheet)
|
|
51
50
|
})
|
|
@@ -57,8 +56,7 @@ export default class ActionSheet {
|
|
|
57
56
|
this.tempListeners.push(bindTap(this.cancelBtn, () => {
|
|
58
57
|
this.hide()
|
|
59
58
|
const err = { errMsg: 'showActionSheet:fail cancel' }
|
|
60
|
-
|
|
61
|
-
// !opts.fail && this.toPromiseReject(err)
|
|
59
|
+
failHandle(err, opts.fail, opts.complete)
|
|
62
60
|
}))
|
|
63
61
|
// make transition next frame
|
|
64
62
|
this.actionSheet.classList.add('show')
|
|
@@ -66,8 +64,6 @@ export default class ActionSheet {
|
|
|
66
64
|
setTimeout(() => {
|
|
67
65
|
this.box.classList.add('show')
|
|
68
66
|
}, 17)
|
|
69
|
-
|
|
70
|
-
// return this.toPromiseInitPromise()
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
hide () {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './rnActionSheet'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './rnActionSheet'
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { View, TouchableHighlight, Text, StyleSheet, Button, Animated } from 'react-native'
|
|
2
|
+
import { successHandle, failHandle } from '../../../common/js'
|
|
3
|
+
import { Portal } from '@ant-design/react-native'
|
|
4
|
+
function showActionSheet (options) {
|
|
5
|
+
const { alertText, itemList = [], itemColor = '#000000', success, fail, complete } = options
|
|
6
|
+
let actionSheetKey
|
|
7
|
+
const slideAnim = new Animated.Value(500)
|
|
8
|
+
const slideIn = () => {
|
|
9
|
+
// Will change fadeAnim value to 1 in 5 seconds
|
|
10
|
+
Animated.timing(slideAnim, {
|
|
11
|
+
toValue: 0,
|
|
12
|
+
duration: 200,
|
|
13
|
+
useNativeDriver: true,
|
|
14
|
+
}).start()
|
|
15
|
+
}
|
|
16
|
+
const slideOut = () => {
|
|
17
|
+
// Will change fadeAnim value to 1 in 5 seconds
|
|
18
|
+
Animated.timing(slideAnim, {
|
|
19
|
+
toValue: 500,
|
|
20
|
+
duration: 200,
|
|
21
|
+
useNativeDriver: true,
|
|
22
|
+
}).start(() => {
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
if (itemList.length === 0 || itemList.length > 6) {
|
|
26
|
+
const result = {
|
|
27
|
+
errMsg: 'showActionSheet:fail parameter error: itemList should not be large than 6'
|
|
28
|
+
}
|
|
29
|
+
if (itemList.length === 0) {
|
|
30
|
+
result.errno = 1001
|
|
31
|
+
result.errMsg = 'showActionSheet:fail parameter error: parameter.itemList should have at least 1 item;'
|
|
32
|
+
}
|
|
33
|
+
failHandle(result, fail, complete)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
const styles = StyleSheet.create({
|
|
37
|
+
actionActionMask: {
|
|
38
|
+
left: 0,
|
|
39
|
+
top: 0,
|
|
40
|
+
bottom: 0,
|
|
41
|
+
right: 0,
|
|
42
|
+
backgroundColor: 'rgba(0,0,0,0.6)',
|
|
43
|
+
position: 'absolute',
|
|
44
|
+
zIndex: 1000
|
|
45
|
+
},
|
|
46
|
+
actionSheetContent: {
|
|
47
|
+
left: 0,
|
|
48
|
+
right: 0,
|
|
49
|
+
position: 'absolute',
|
|
50
|
+
bottom: 0,
|
|
51
|
+
backgroundColor: '#ffffff',
|
|
52
|
+
borderTopLeftRadius: 10,
|
|
53
|
+
borderTopRightRadius: 10,
|
|
54
|
+
transform: [{
|
|
55
|
+
translateY: -500
|
|
56
|
+
}]
|
|
57
|
+
},
|
|
58
|
+
itemStyle: {
|
|
59
|
+
paddingTop: 15,
|
|
60
|
+
paddingBottom: 15,
|
|
61
|
+
justifyContent: 'center',
|
|
62
|
+
alignItems: 'center',
|
|
63
|
+
borderBottomWidth: 1,
|
|
64
|
+
borderBottomStyle: 'solid',
|
|
65
|
+
borderBottomColor: 'rgba(0,0,0,0.1)'
|
|
66
|
+
},
|
|
67
|
+
itemTextStyle: {
|
|
68
|
+
fontSize: 18
|
|
69
|
+
},
|
|
70
|
+
buttonStyle: {
|
|
71
|
+
fontSize: 18,
|
|
72
|
+
paddingTop: 10,
|
|
73
|
+
paddingBottom: 10
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
const remove = function () {
|
|
77
|
+
if (actionSheetKey) {
|
|
78
|
+
slideOut()
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
Portal.remove(actionSheetKey)
|
|
81
|
+
actionSheetKey = null
|
|
82
|
+
}, 200)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const selectAction = function (index) {
|
|
86
|
+
const result = {
|
|
87
|
+
errMsg: 'showActionSheet:ok',
|
|
88
|
+
tapIndex: index
|
|
89
|
+
}
|
|
90
|
+
successHandle(result, success, complete)
|
|
91
|
+
remove()
|
|
92
|
+
}
|
|
93
|
+
const cancelAction = function () {
|
|
94
|
+
const result = {
|
|
95
|
+
errMsg: 'showActionSheet:fail cancel'
|
|
96
|
+
}
|
|
97
|
+
failHandle(result, fail, complete)
|
|
98
|
+
remove()
|
|
99
|
+
}
|
|
100
|
+
let alertTextList = []
|
|
101
|
+
if (alertText) {
|
|
102
|
+
alertTextList = [alertText]
|
|
103
|
+
}
|
|
104
|
+
const ActionSheetView = <TouchableHighlight underlayColor="rgba(0,0,0,0.6)" onPress={cancelAction} style={styles.actionActionMask}>
|
|
105
|
+
<Animated.View
|
|
106
|
+
style={[
|
|
107
|
+
styles.actionSheetContent,
|
|
108
|
+
{
|
|
109
|
+
transform: [{translateY: slideAnim}]
|
|
110
|
+
}
|
|
111
|
+
]}>
|
|
112
|
+
{ alertTextList.map((item, index) => <View key={index} style={ styles.itemStyle }><Text style={[styles.itemTextStyle, { color: '#666666' }]}>{item}</Text></View>) }
|
|
113
|
+
{ itemList.map((item, index) => <TouchableHighlight key={index} underlayColor="#ececec" onPress={() => selectAction(index)} style={ [styles.itemStyle, itemList.length -1 === index ? {
|
|
114
|
+
borderBottomWidth: 6,
|
|
115
|
+
borderBottomStyle: 'solid',
|
|
116
|
+
borderBottomColor: '#f7f7f7'
|
|
117
|
+
} : {}] }><Text style={[styles.itemTextStyle, { color: itemColor }]}>{item}</Text></TouchableHighlight>) }
|
|
118
|
+
<View style={styles.buttonStyle}><Button color={'#000000'} title={'取消'} onPress={cancelAction}></Button></View>
|
|
119
|
+
</Animated.View>
|
|
120
|
+
</TouchableHighlight>
|
|
121
|
+
actionSheetKey = Portal.add(ActionSheetView)
|
|
122
|
+
slideIn()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
showActionSheet
|
|
127
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.web'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.web'
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { isBrowser } from '
|
|
1
|
+
import { isBrowser, isReact } from '@mpxjs/utils'
|
|
2
|
+
|
|
2
3
|
global.__mpxAppCbs = global.__mpxAppCbs || {
|
|
3
4
|
show: [],
|
|
4
5
|
hide: [],
|
|
@@ -7,7 +8,7 @@ global.__mpxAppCbs = global.__mpxAppCbs || {
|
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
function onError (callback) {
|
|
10
|
-
if (isBrowser) {
|
|
11
|
+
if (isBrowser || isReact) {
|
|
11
12
|
global.__mpxAppCbs.error.push(callback)
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -19,7 +20,7 @@ function offError (callback) {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
function onAppShow (callback) {
|
|
22
|
-
if (isBrowser) {
|
|
23
|
+
if (isBrowser || isReact) {
|
|
23
24
|
global.__mpxAppCbs.show.push(callback)
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -31,7 +32,7 @@ function offAppShow (callback) {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
function onAppHide (callback) {
|
|
34
|
-
if (isBrowser) {
|
|
35
|
+
if (isBrowser || isReact) {
|
|
35
36
|
global.__mpxAppCbs.hide.push(callback)
|
|
36
37
|
}
|
|
37
38
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Clipboard from '@react-native-clipboard/clipboard'
|
|
2
|
-
import {
|
|
2
|
+
import { successHandle, failHandle } from '../../../common/js'
|
|
3
3
|
import { type } from '@mpxjs/utils'
|
|
4
4
|
const setClipboardData = function (options) {
|
|
5
5
|
const { data, success, fail, complete } = options
|
|
@@ -9,14 +9,14 @@ const setClipboardData = function (options) {
|
|
|
9
9
|
errno: 1001,
|
|
10
10
|
errMsg: errStr
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
failHandle(result, fail, complete)
|
|
13
13
|
return
|
|
14
14
|
}
|
|
15
15
|
Clipboard.setString(data)
|
|
16
16
|
const result = {
|
|
17
17
|
errMsg: 'setClipboardData:ok'
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
successHandle(result, success, complete)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const getClipboardData = function (options) {
|
|
@@ -26,12 +26,12 @@ const getClipboardData = function (options) {
|
|
|
26
26
|
data,
|
|
27
27
|
errMsg: 'getClipboardData:ok'
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
successHandle(result, success, complete)
|
|
30
30
|
}).catch(() => {
|
|
31
31
|
const result = {
|
|
32
32
|
errMsg: 'setClipboardData:fail'
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
failHandle(result, fail, complete)
|
|
35
35
|
})
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -66,12 +66,12 @@ class WebIntersectionObserver {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
observe (targetSelector, callback) {
|
|
69
|
-
nextTick(
|
|
70
|
-
if (!targetSelector) {
|
|
71
|
-
|
|
72
|
-
return
|
|
69
|
+
nextTick(() => {
|
|
70
|
+
if (!document.querySelector(targetSelector)) {
|
|
71
|
+
console.warn(`[mpx runtime warn]: Node ${JSON.stringify(targetSelector)} is not found. Intersection observer will not trigger.`)
|
|
72
|
+
return
|
|
73
73
|
}
|
|
74
|
-
this._observer =
|
|
74
|
+
this._observer = this.initObserver()
|
|
75
75
|
this._callback = callback
|
|
76
76
|
let targetElement = []
|
|
77
77
|
if (this._options.observeAll) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.ios'
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import {
|
|
2
|
+
noop,
|
|
3
|
+
isBoolean,
|
|
4
|
+
dash2hump,
|
|
5
|
+
collectDataset,
|
|
6
|
+
hump2dash,
|
|
7
|
+
isArray
|
|
8
|
+
} from '@mpxjs/utils'
|
|
9
|
+
import { StyleSheet } from 'react-native'
|
|
10
|
+
|
|
11
|
+
const flushRefFns = (nodeInstances, fns, single) => {
|
|
12
|
+
// wx的数据格式:对于具体方法接受到的回调传参,如果获取的 nodeRef 只有一个,那么只需要返回一条数据而不是数组,但是 exec 里面统一都是数组
|
|
13
|
+
const mountedNodeInstance = nodeInstances
|
|
14
|
+
.map((instance) => instance.getNodeInstance())
|
|
15
|
+
.filter(({ nodeRef }) => nodeRef.current) // 如果有 nodeRef,表明目前组件处于挂载中
|
|
16
|
+
if (mountedNodeInstance.length) {
|
|
17
|
+
return Promise.all(
|
|
18
|
+
mountedNodeInstance.map((instance) => flushFns(instance, fns))
|
|
19
|
+
).then((result = []) => (single ? result[0] : result))
|
|
20
|
+
} else {
|
|
21
|
+
return Promise.resolve(single ? null : [])
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const flushFns = (nodeInstance, fns) => {
|
|
26
|
+
return Promise.all(fns.map((fn) => fn(nodeInstance))).then((res) => {
|
|
27
|
+
return res.reduce((preVal, curVal) => {
|
|
28
|
+
return Object.assign(preVal, curVal)
|
|
29
|
+
}, {})
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const wrapFn = (fn) => {
|
|
34
|
+
return (nodeRef) => {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
fn(nodeRef, resolve)
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const getMeasureProps = (measureProps = []) => {
|
|
42
|
+
return wrapFn((nodeInstance, resolve) => {
|
|
43
|
+
const nodeRef = nodeInstance.nodeRef.current
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
nodeRef.measure(function (x, y, width, height, pageX, pageY) {
|
|
46
|
+
const rectAndSize = {
|
|
47
|
+
width,
|
|
48
|
+
height,
|
|
49
|
+
left: pageX,
|
|
50
|
+
top: pageY,
|
|
51
|
+
right: pageX + width,
|
|
52
|
+
bottom: pageY + height
|
|
53
|
+
}
|
|
54
|
+
const result = measureProps.reduce((preVal, key) => {
|
|
55
|
+
return Object.assign(preVal, { [key]: rectAndSize[key] || 0 })
|
|
56
|
+
}, {})
|
|
57
|
+
resolve(result)
|
|
58
|
+
})
|
|
59
|
+
}, 30) // 延迟,等待组件在rn视图上真正渲染出来
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const getDataset = (props) => {
|
|
64
|
+
return wrapFn((nodeRef, resolve) => {
|
|
65
|
+
props = nodeRef.props.current
|
|
66
|
+
resolve({
|
|
67
|
+
dataset: collectDataset(props)
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const getPlainProps = (config) => {
|
|
73
|
+
return wrapFn((nodeRef, resolve) => {
|
|
74
|
+
const res = {}
|
|
75
|
+
const props = nodeRef.props.current
|
|
76
|
+
config.forEach((key) => {
|
|
77
|
+
// props 属性默认不转驼峰,用户写什么格式不会变化,取值做兼容
|
|
78
|
+
res[key] = props[key] || props[hump2dash(key)] || ''
|
|
79
|
+
})
|
|
80
|
+
resolve(res)
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const getComputedStyle = (config = []) => {
|
|
85
|
+
return wrapFn((nodeRef, resolve) => {
|
|
86
|
+
config = new Set(config)
|
|
87
|
+
const res = {}
|
|
88
|
+
const styles = nodeRef.props.current.style || []
|
|
89
|
+
const defaultStyle = nodeRef.instance.defaultStyle || {}
|
|
90
|
+
const computedStyle = StyleSheet.flatten([defaultStyle, ...styles])
|
|
91
|
+
config.forEach((key) => {
|
|
92
|
+
const humpKey = dash2hump(key)
|
|
93
|
+
// 取 style 的 key 是根据传入的 key 来设置,传什么设置什么 key,只不过取值需要做兼容
|
|
94
|
+
res[key] = computedStyle[key] || computedStyle[humpKey] || ''
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
resolve(res)
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const getInstanceConfig = (config) => {
|
|
102
|
+
return wrapFn((nodeRef, resolve) => {
|
|
103
|
+
const instance = nodeRef.instance
|
|
104
|
+
resolve({ [config]: instance[config] || {} })
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const defaultScrollOffset = {
|
|
109
|
+
scrollLeft: 0,
|
|
110
|
+
scrollTop: 0,
|
|
111
|
+
scrollHeight: 0,
|
|
112
|
+
scrollWidth: 0
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const getScrollOffset = () => {
|
|
116
|
+
return wrapFn((nodeRef, resolve) => {
|
|
117
|
+
const instance = nodeRef.instance
|
|
118
|
+
resolve(
|
|
119
|
+
(instance.scrollOffset && instance.scrollOffset.current) ||
|
|
120
|
+
defaultScrollOffset
|
|
121
|
+
)
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const RECT = ['left', 'top', 'right', 'bottom']
|
|
126
|
+
const SIZE = ['width', 'height']
|
|
127
|
+
|
|
128
|
+
class NodeRef {
|
|
129
|
+
constructor (nodeRefs = [], selectorQuery, single) {
|
|
130
|
+
if (!isArray(nodeRefs)) {
|
|
131
|
+
nodeRefs = [nodeRefs]
|
|
132
|
+
}
|
|
133
|
+
this.nodeRefs = nodeRefs
|
|
134
|
+
this.selectorQuery = selectorQuery
|
|
135
|
+
this.single = single
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
fields (config, cb = noop) {
|
|
139
|
+
const plainProps = []
|
|
140
|
+
const measureProps = []
|
|
141
|
+
const computedStyle = []
|
|
142
|
+
const fns = []
|
|
143
|
+
|
|
144
|
+
for (const key in config) {
|
|
145
|
+
const value = config[key]
|
|
146
|
+
if (Array.isArray(value) && value.length) {
|
|
147
|
+
if (key === 'properties') {
|
|
148
|
+
// wx 最终输出的 properties 字段都会转化为驼峰,所以在这里提前处理为最终的字段格式
|
|
149
|
+
plainProps.push(...value.map((v) => dash2hump(v)))
|
|
150
|
+
} else if (key === 'computedStyle') {
|
|
151
|
+
const _computedStyle = config.computedStyle
|
|
152
|
+
for (let i = _computedStyle.length - 1; i >= 0; i--) {
|
|
153
|
+
const style = _computedStyle[i]
|
|
154
|
+
if (RECT.includes(style) || SIZE.includes(style)) {
|
|
155
|
+
measureProps.push(style)
|
|
156
|
+
_computedStyle.splice(i, 1)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (_computedStyle.length) {
|
|
160
|
+
computedStyle.push(..._computedStyle)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} else if (isBoolean(value) && value) {
|
|
164
|
+
switch (key) {
|
|
165
|
+
case 'rect':
|
|
166
|
+
measureProps.push(...RECT)
|
|
167
|
+
break
|
|
168
|
+
case 'size':
|
|
169
|
+
measureProps.push(...SIZE)
|
|
170
|
+
break
|
|
171
|
+
case 'scrollOffset':
|
|
172
|
+
fns.push(getScrollOffset())
|
|
173
|
+
break
|
|
174
|
+
case 'dataset':
|
|
175
|
+
fns.push(getDataset())
|
|
176
|
+
break
|
|
177
|
+
case 'node':
|
|
178
|
+
case 'context':
|
|
179
|
+
case 'ref':
|
|
180
|
+
fns.push(getInstanceConfig(key))
|
|
181
|
+
break
|
|
182
|
+
default:
|
|
183
|
+
plainProps.push(key)
|
|
184
|
+
break
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (plainProps.length) {
|
|
190
|
+
fns.push(getPlainProps(plainProps))
|
|
191
|
+
}
|
|
192
|
+
if (measureProps.length) {
|
|
193
|
+
const nodeInstance =
|
|
194
|
+
this.nodeRefs[0] && this.nodeRefs[0].getNodeInstance()
|
|
195
|
+
const hasMeasureFn =
|
|
196
|
+
nodeInstance &&
|
|
197
|
+
nodeInstance.nodeRef.current &&
|
|
198
|
+
nodeInstance.nodeRef.current.measure
|
|
199
|
+
if (hasMeasureFn) {
|
|
200
|
+
fns.push(getMeasureProps(measureProps))
|
|
201
|
+
} else {
|
|
202
|
+
computedStyle.push(...measureProps)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (computedStyle.length) {
|
|
206
|
+
fns.push(getComputedStyle(computedStyle))
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const runCb = () => {
|
|
210
|
+
return flushRefFns(this.nodeRefs, fns, this.single).then((result) => {
|
|
211
|
+
cb(result)
|
|
212
|
+
return result
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
this.selectorQuery._queueCb.push(runCb)
|
|
217
|
+
|
|
218
|
+
return this.selectorQuery
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
boundingClientRect (cb = noop) {
|
|
222
|
+
const config = {
|
|
223
|
+
id: true,
|
|
224
|
+
dataset: true,
|
|
225
|
+
rect: true,
|
|
226
|
+
size: true
|
|
227
|
+
}
|
|
228
|
+
return this.fields(config, cb)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
context (cb = noop) {
|
|
232
|
+
const config = {
|
|
233
|
+
context: true
|
|
234
|
+
}
|
|
235
|
+
return this.fields(config, cb)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
node (cb = noop) {
|
|
239
|
+
const config = {
|
|
240
|
+
node: true
|
|
241
|
+
}
|
|
242
|
+
return this.fields(config, cb)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
ref (cb = noop) {
|
|
246
|
+
const config = {
|
|
247
|
+
ref: true
|
|
248
|
+
}
|
|
249
|
+
return this.fields(config, cb)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
scrollOffset (cb = noop) {
|
|
253
|
+
const config = {
|
|
254
|
+
id: true,
|
|
255
|
+
dataset: true,
|
|
256
|
+
scrollOffset: true
|
|
257
|
+
}
|
|
258
|
+
return this.fields(config, cb)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export default NodeRef
|