@mpxjs/api-proxy 2.9.53 → 2.9.58

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 (57) hide show
  1. package/@types/index.d.ts +7 -7
  2. package/package.json +20 -4
  3. package/src/common/js/promisify.js +3 -1
  4. package/src/common/js/utils.js +13 -1
  5. package/src/common/js/web.js +0 -12
  6. package/src/platform/api/action-sheet/ActionSheet.js +3 -7
  7. package/src/platform/api/action-sheet/index.android.js +1 -0
  8. package/src/platform/api/action-sheet/index.ios.js +1 -0
  9. package/src/platform/api/action-sheet/rnActionSheet.jsx +127 -0
  10. package/src/platform/api/app/index.android.js +1 -0
  11. package/src/platform/api/app/index.ios.js +1 -0
  12. package/src/platform/api/app/index.web.js +5 -4
  13. package/src/platform/api/clipboard-data/rnClipboard.js +5 -5
  14. package/src/platform/api/create-selector-query/index.android.js +1 -0
  15. package/src/platform/api/create-selector-query/index.ios.js +9 -0
  16. package/src/platform/api/create-selector-query/rnNodesRef.js +262 -0
  17. package/src/platform/api/create-selector-query/rnSelectQuery.js +43 -0
  18. package/src/platform/api/device/network/getNetworkType.js +4 -4
  19. package/src/platform/api/device/network/rnNetwork.js +3 -3
  20. package/src/platform/api/image/Preview.js +3 -3
  21. package/src/platform/api/location/index.ali.js +31 -0
  22. package/src/platform/api/location/index.android.js +1 -0
  23. package/src/platform/api/location/index.ios.js +31 -0
  24. package/src/platform/api/location/index.js +13 -0
  25. package/src/platform/api/location/index.web.js +36 -0
  26. package/src/platform/api/make-phone-call/rnMakePhone.js +3 -3
  27. package/src/platform/api/modal/Modal.js +12 -15
  28. package/src/platform/api/modal/index.android.js +1 -0
  29. package/src/platform/api/modal/index.ios.js +1 -0
  30. package/src/platform/api/modal/rnModal.jsx +149 -0
  31. package/src/platform/api/next-tick/index.android.js +1 -0
  32. package/src/platform/api/next-tick/index.ios.js +1 -0
  33. package/src/platform/api/page-scroll-to/index.web.js +3 -3
  34. package/src/platform/api/pull-down/index.web.js +5 -5
  35. package/src/platform/api/request/index.web.js +3 -6
  36. package/src/platform/api/route/index.ios.js +9 -9
  37. package/src/platform/api/route/index.web.js +15 -18
  38. package/src/platform/api/screen-brightness/index.android.js +1 -0
  39. package/src/platform/api/screen-brightness/index.ios.js +1 -0
  40. package/src/platform/api/screen-brightness/rnScreenBrightness.js +53 -0
  41. package/src/platform/api/set-navigation-bar/index.android.js +1 -0
  42. package/src/platform/api/set-navigation-bar/index.ios.js +41 -0
  43. package/src/platform/api/set-navigation-bar/index.web.js +3 -3
  44. package/src/platform/api/socket/SocketTask.js +7 -17
  45. package/src/platform/api/socket/index.web.js +3 -3
  46. package/src/platform/api/storage/index.web.js +11 -12
  47. package/src/platform/api/storage/rnStorage.js +12 -12
  48. package/src/platform/api/system/index.web.js +2 -2
  49. package/src/platform/api/system/rnSystem.js +3 -3
  50. package/src/platform/api/tab-bar/index.web.js +9 -9
  51. package/src/platform/api/toast/Toast.js +3 -3
  52. package/src/platform/api/toast/error.png +0 -0
  53. package/src/platform/api/toast/index.android.js +1 -0
  54. package/src/platform/api/toast/index.ios.js +1 -0
  55. package/src/platform/api/toast/rnToast.jsx +189 -0
  56. package/src/platform/api/toast/success.png +0 -0
  57. 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
- ? Parameters<W[K]> extends [{ success?: (res: infer R) => any }?, ...any[]]
6
- ? (...args: Parameters<W[K]>) => ReturnType<W[K]> & Promise<R>
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
- Parameters<V> extends [{ success?: (res: infer R) => any }, ...any[]]
13
- ? (options: O) => ReturnType<V> & Promise<R>
14
- : (options: O) => ReturnType<V>
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: string[], customBlackList: string[]) => object
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.53",
3
+ "version": "2.9.58",
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.50",
40
+ "@mpxjs/utils": "^2.9.58",
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-safe-area-context": "^4.10.1"
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": "505776958d34f5fea4e0b6141a0dc83ef572eb08"
83
+ "gitHead": "49fe4c4bc46ff4bf87cd8adde37981d4b4134aa7"
68
84
  }
@@ -29,7 +29,9 @@ const blackList = [
29
29
  'createOffscreenCanvas',
30
30
  'reportEvent',
31
31
  'connectSocket',
32
- 'base64ToArrayBuffer'
32
+ 'base64ToArrayBuffer',
33
+ 'getDeviceInfo',
34
+ 'getWindowInfo'
33
35
  ]
34
36
 
35
37
  function getMapFromList (list) {
@@ -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
  }
@@ -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 { webHandleSuccess, webHandleFail, createDom, bindTap, getRootElement } from '../../../common/js'
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
- webHandleSuccess(res, opts.success, opts.complete)
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
- webHandleFail(err, opts.fail, opts.complete)
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 '../../../common/js'
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 { webHandleSuccess, webHandleFail } from '../../../common/js/web'
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
- webHandleFail(result, fail, complete)
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
- webHandleSuccess(result, success, complete)
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
- webHandleSuccess(result, success, complete)
29
+ successHandle(result, success, complete)
30
30
  }).catch(() => {
31
31
  const result = {
32
32
  errMsg: 'setClipboardData:fail'
33
33
  }
34
- webHandleFail(result, fail, complete)
34
+ failHandle(result, fail, complete)
35
35
  })
36
36
  }
37
37
 
@@ -0,0 +1 @@
1
+ export * from './index.ios'
@@ -0,0 +1,9 @@
1
+ import SelectorQuery from './rnSelectQuery'
2
+
3
+ function createSelectorQuery () {
4
+ return new SelectorQuery()
5
+ }
6
+
7
+ export {
8
+ createSelectorQuery
9
+ }
@@ -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