@mpxjs/webpack-plugin 2.9.64 → 2.9.65

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 (73) hide show
  1. package/lib/config.js +38 -10
  2. package/lib/platform/style/wx/index.js +52 -17
  3. package/lib/platform/template/wx/index.js +12 -8
  4. package/lib/react/style-helper.js +2 -5
  5. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -1
  6. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -1
  7. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +3 -2
  8. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -1
  9. package/lib/runtime/components/react/dist/mpx-icon.jsx +3 -2
  10. package/lib/runtime/components/react/dist/mpx-image/index.jsx +2 -1
  11. package/lib/runtime/components/react/dist/mpx-input.jsx +2 -1
  12. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -1
  13. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -2
  14. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -1
  15. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +2 -1
  16. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +2 -1
  17. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +2 -1
  18. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +2 -1
  19. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +2 -1
  20. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +4 -2
  21. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +3 -2
  22. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +2 -1
  23. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -1
  24. package/lib/runtime/components/react/dist/mpx-radio.jsx +3 -2
  25. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +3 -1
  26. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +2 -1
  27. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +2 -1
  28. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -2
  29. package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -2
  30. package/lib/runtime/components/react/dist/mpx-text.jsx +2 -1
  31. package/lib/runtime/components/react/dist/mpx-view.jsx +15 -4
  32. package/lib/runtime/components/react/dist/mpx-web-view.jsx +3 -2
  33. package/lib/runtime/components/react/dist/useNodesRef.js +1 -5
  34. package/lib/runtime/components/react/dist/utils.jsx +48 -36
  35. package/lib/runtime/components/react/mpx-button.tsx +3 -1
  36. package/lib/runtime/components/react/mpx-checkbox-group.tsx +3 -1
  37. package/lib/runtime/components/react/mpx-checkbox.tsx +4 -1
  38. package/lib/runtime/components/react/mpx-form.tsx +2 -1
  39. package/lib/runtime/components/react/mpx-icon.tsx +3 -2
  40. package/lib/runtime/components/react/mpx-image/index.tsx +2 -1
  41. package/lib/runtime/components/react/mpx-input.tsx +2 -1
  42. package/lib/runtime/components/react/mpx-label.tsx +2 -1
  43. package/lib/runtime/components/react/mpx-movable-area.tsx +3 -2
  44. package/lib/runtime/components/react/mpx-movable-view.tsx +2 -1
  45. package/lib/runtime/components/react/mpx-picker/date.tsx +2 -1
  46. package/lib/runtime/components/react/mpx-picker/index.tsx +2 -1
  47. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +2 -1
  48. package/lib/runtime/components/react/mpx-picker/region.tsx +2 -1
  49. package/lib/runtime/components/react/mpx-picker/selector.tsx +2 -1
  50. package/lib/runtime/components/react/mpx-picker/time.tsx +4 -2
  51. package/lib/runtime/components/react/mpx-picker-view-column.tsx +3 -2
  52. package/lib/runtime/components/react/mpx-picker-view.tsx +2 -1
  53. package/lib/runtime/components/react/mpx-radio-group.tsx +2 -1
  54. package/lib/runtime/components/react/mpx-radio.tsx +3 -2
  55. package/lib/runtime/components/react/mpx-scroll-view.tsx +3 -1
  56. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +2 -1
  57. package/lib/runtime/components/react/mpx-swiper/index.tsx +4 -1
  58. package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -1
  59. package/lib/runtime/components/react/mpx-switch.tsx +2 -1
  60. package/lib/runtime/components/react/mpx-text.tsx +2 -1
  61. package/lib/runtime/components/react/mpx-view.tsx +16 -4
  62. package/lib/runtime/components/react/mpx-web-view.tsx +3 -2
  63. package/lib/runtime/components/react/types/global.d.ts +11 -1
  64. package/lib/runtime/components/react/useNodesRef.ts +1 -6
  65. package/lib/runtime/components/react/utils.tsx +65 -46
  66. package/lib/runtime/components/web/mpx-scroll-view.vue +25 -5
  67. package/lib/style-compiler/index.js +5 -4
  68. package/lib/template-compiler/compiler.js +105 -141
  69. package/lib/utils/const.js +2 -1
  70. package/lib/web/processStyles.js +6 -2
  71. package/lib/web/processTemplate.js +2 -3
  72. package/lib/wxml/loader.js +1 -1
  73. package/package.json +5 -4
@@ -34,6 +34,7 @@
34
34
  import { ScrollView } from 'react-native-gesture-handler'
35
35
  import { View, RefreshControl, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle } from 'react-native'
36
36
  import { JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef } from 'react'
37
+ import { useAnimatedRef } from 'react-native-reanimated'
37
38
  import { warn } from '@mpxjs/utils'
38
39
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
39
40
  import useNodesRef, { HandlerRef } from './useNodesRef'
@@ -150,7 +151,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
150
151
 
151
152
  const { textStyle, innerStyle } = splitStyle(normalStyle)
152
153
 
153
- const { nodeRef: scrollViewRef } = useNodesRef(props, ref, {
154
+ const scrollViewRef = useAnimatedRef<ScrollView>()
155
+ useNodesRef(props, ref, scrollViewRef, {
154
156
  scrollOffset: scrollOptions,
155
157
  node: {
156
158
  scrollEnabled: scrollX || scrollY,
@@ -89,7 +89,8 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
89
89
  const defaultY = (defaultHeight * initOffsetIndex) || 0
90
90
  // 内部存储上一次的offset值
91
91
  const autoplayTimerRef = useRef<ReturnType <typeof setTimeout> | null>(null)
92
- const { nodeRef: scrollViewRef } = useNodesRef<ScrollView & View, CarouseProps>(props, ref, {})
92
+ const scrollViewRef = useRef<ScrollView & View>(null)
93
+ useNodesRef<ScrollView & View, CarouseProps>(props, ref, scrollViewRef, {})
93
94
  const {
94
95
  // 存储layout布局信息
95
96
  layoutRef,
@@ -45,7 +45,10 @@ const _SwiperWrapper = forwardRef<HandlerRef<ScrollView, SwiperProps>, SwiperPro
45
45
  bindchange: props.bindchange,
46
46
  easingFunction: props['easing-function'] || 'default'
47
47
  }
48
- const { nodeRef } = useNodesRef<ScrollView, SwiperProps>(props, ref, {})
48
+
49
+ const nodeRef = useRef(null)
50
+ useNodesRef<ScrollView, SwiperProps>(props, ref, nodeRef, {})
51
+
49
52
  const innerProps = useInnerProps(props, {
50
53
  ref: nodeRef
51
54
  }, [
@@ -25,7 +25,8 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
25
25
  } = props
26
26
 
27
27
  const { textProps } = splitProps(props)
28
- const { nodeRef } = useNodesRef(props, ref, {})
28
+ const nodeRef = useRef(null)
29
+ useNodesRef(props, ref, nodeRef, {})
29
30
 
30
31
  const {
31
32
  normalStyle,
@@ -76,7 +76,8 @@ const _Switch = forwardRef<HandlerRef<Switch, _SwitchProps>, _SwitchProps>((prop
76
76
  setIsChecked(checked)
77
77
  }, [checked])
78
78
 
79
- const { nodeRef } = useNodesRef<Switch, _SwitchProps>(props, ref)
79
+ const nodeRef = useRef(null)
80
+ useNodesRef<Switch, _SwitchProps>(props, ref, nodeRef)
80
81
 
81
82
  const {
82
83
  layoutRef,
@@ -48,7 +48,8 @@ const _Text = forwardRef<HandlerRef<Text, _TextProps>, _TextProps>((props, ref):
48
48
  parentHeight
49
49
  })
50
50
 
51
- const { nodeRef } = useNodesRef<Text, _TextProps>(props, ref)
51
+ const nodeRef = useRef(null)
52
+ useNodesRef<Text, _TextProps>(props, ref, nodeRef)
52
53
 
53
54
  const innerProps = useInnerProps(props, {
54
55
  ref: nodeRef,
@@ -114,6 +114,17 @@ const applyHandlers = (handlers: Handler[], args: any[]) => {
114
114
  }
115
115
  }
116
116
 
117
+ const normalizeStyle = (style: ExtendedViewStyle = {}) => {
118
+ ['backgroundSize', 'backgroundPosition'].forEach(name => {
119
+ if (style[name] && typeof style[name] === 'string') {
120
+ if (style[name].trim()) {
121
+ style[name] = style[name].split(' ')
122
+ }
123
+ }
124
+ })
125
+ return style
126
+ }
127
+
117
128
  const isPercent = (val: string | number | undefined): val is string => typeof val === 'string' && PERCENT_REGEX.test(val)
118
129
 
119
130
  const isBackgroundSizeKeyword = (val: string | number): boolean => typeof val === 'string' && /^cover|contain$/.test(val)
@@ -501,7 +512,7 @@ function normalizeBackgroundSize (backgroundSize: Exclude<ExtendedViewStyle['bac
501
512
  }
502
513
 
503
514
  function preParseImage (imageStyle?: ExtendedViewStyle) {
504
- const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = imageStyle || {}
515
+ const { backgroundImage = '', backgroundSize = ['auto'], backgroundPosition = [0, 0] } = normalizeStyle(imageStyle) || {}
505
516
  const { type, src, linearInfo } = parseBgImage(backgroundImage)
506
517
 
507
518
  return {
@@ -589,8 +600,8 @@ function wrapImage (imageStyle?: ExtendedViewStyle) {
589
600
  }
590
601
  setImageSizeWidth(sizeInfo.current.width)
591
602
  setImageSizeHeight(sizeInfo.current.height)
592
- setShow(true)
593
603
  }
604
+ setShow(true)
594
605
  } else if (sizeInfo.current) {
595
606
  setLayoutInfoWidth(width)
596
607
  setLayoutInfoHeight(height)
@@ -600,7 +611,7 @@ function wrapImage (imageStyle?: ExtendedViewStyle) {
600
611
  }
601
612
  }
602
613
 
603
- return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, width: '100%', height: '100%', overflow: 'hidden' }}>
614
+ return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
604
615
  {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} /> }
605
616
  {show && type === 'image' && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
606
617
  </View>
@@ -686,7 +697,8 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
686
697
  throw new Error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.')
687
698
  }
688
699
 
689
- const { nodeRef } = useNodesRef<View, _ViewProps>(props, ref, {
700
+ const nodeRef = useRef(null)
701
+ useNodesRef<View, _ViewProps>(props, ref, nodeRef, {
690
702
  defaultStyle
691
703
  })
692
704
 
@@ -1,4 +1,4 @@
1
- import { forwardRef, JSX, useEffect } from 'react'
1
+ import { forwardRef, JSX, useEffect, useRef } from 'react'
2
2
  import { noop, warn } from '@mpxjs/utils'
3
3
  import { Portal } from '@ant-design/react-native'
4
4
  import { getCustomEvent } from './getInnerListeners'
@@ -59,7 +59,8 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
59
59
  bottom: 0 as number
60
60
  }
61
61
 
62
- const { nodeRef: webViewRef } = useNodesRef<WebView, WebViewProps>(props, ref, {
62
+ const webViewRef = useRef<WebView>(null)
63
+ useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
63
64
  defaultStyle: defaultWebViewStyle
64
65
  })
65
66
 
@@ -26,6 +26,16 @@ declare module '@mpxjs/utils' {
26
26
  export function isObject (value): value is Object
27
27
  export function error (msg: string, location?: string, e?: any): void
28
28
  export function warn (msg: string, location?: string, e?: any): void
29
+ export function getFocusedNavigation (): {
30
+ insets: {
31
+ top: number
32
+ bottom: number
33
+ left: number
34
+ right: number
35
+ }
36
+ } | undefined
29
37
  }
30
38
 
31
- declare let global: Record<string, any>
39
+ declare let global: {
40
+ __formatValue (value: string): string | number
41
+ } & Record<string, any>
@@ -10,8 +10,7 @@ export type HandlerRef<T, P> = {
10
10
  }
11
11
  }
12
12
 
13
- export default function useNodesRef<T, P> (props: P, ref: ForwardedRef<HandlerRef<T, P>>, instance:Obj = {}) {
14
- const nodeRef = useRef<T>(null)
13
+ export default function useNodesRef<T, P> (props: P, ref: ForwardedRef<HandlerRef<T, P>>, nodeRef: RefObject<T>, instance:Obj = {}) {
15
14
  const _props = useRef<P | null>(null)
16
15
  _props.current = props
17
16
 
@@ -26,8 +25,4 @@ export default function useNodesRef<T, P> (props: P, ref: ForwardedRef<HandlerRe
26
25
  }
27
26
  }
28
27
  })
29
-
30
- return {
31
- nodeRef
32
- }
33
28
  }
@@ -1,8 +1,9 @@
1
1
  import { useEffect, useRef, ReactNode, ReactElement, FunctionComponent, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
- import { Dimensions, StyleSheet, LayoutChangeEvent, TextStyle } from 'react-native'
3
- import { isObject, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils'
2
+ import { LayoutChangeEvent, TextStyle } from 'react-native'
3
+ import { isObject, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
4
4
  import { VarContext } from './context'
5
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
6
+ import { initialWindowMetrics } from 'react-native-safe-area-context'
6
7
 
7
8
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
8
9
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
@@ -14,19 +15,26 @@ export const DEFAULT_UNLAY_STYLE = {
14
15
  opacity: 0
15
16
  }
16
17
 
17
- export function rpx (value: number) {
18
- const { width } = Dimensions.get('screen')
19
- // rn 单位 dp = 1(css)px = 1 物理像素 * pixelRatio(像素比)
20
- // px = rpx * (750 / 屏幕宽度)
21
- return value * width / 750
22
- }
23
-
24
- const rpxRegExp = /^\s*(-?\d+(\.\d+)?)rpx\s*$/
25
- const pxRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
26
- const hairlineRegExp = /^\s*hairlineWidth\s*$/
27
18
  const varDecRegExp = /^--.*/
28
19
  const varUseRegExp = /var\(/
29
20
  const calcUseRegExp = /calc\(/
21
+ const envUseRegExp = /env\(/
22
+
23
+ const safeAreaInsetMap: Record<string, 'top' | 'right' | 'bottom' | 'left'> = {
24
+ 'safe-area-inset-top': 'top',
25
+ 'safe-area-inset-right': 'right',
26
+ 'safe-area-inset-bottom': 'bottom',
27
+ 'safe-area-inset-left': 'left'
28
+ }
29
+
30
+ function getSafeAreaInset (name: string) {
31
+ const navigation = getFocusedNavigation()
32
+ const insets = {
33
+ ...initialWindowMetrics?.insets,
34
+ ...navigation?.insets
35
+ }
36
+ return insets[safeAreaInsetMap[name]]
37
+ }
30
38
 
31
39
  export function omit<T, K extends string> (obj: T, fields: K[]): Omit<T, K> {
32
40
  const shallowCopy: any = Object.assign({}, obj)
@@ -122,9 +130,9 @@ export function groupBy<T extends Record<string, any>> (
122
130
  }
123
131
 
124
132
  export function splitStyle<T extends Record<string, any>> (styleObj: T): {
125
- textStyle?: Partial<T>;
126
- backgroundStyle?: Partial<T>;
127
- innerStyle?: Partial<T>;
133
+ textStyle?: Partial<T>
134
+ backgroundStyle?: Partial<T>
135
+ innerStyle?: Partial<T>
128
136
  } {
129
137
  return groupBy(styleObj, (key) => {
130
138
  if (TEXT_STYLE_REGEX.test(key)) {
@@ -135,9 +143,9 @@ export function splitStyle<T extends Record<string, any>> (styleObj: T): {
135
143
  return 'innerStyle'
136
144
  }
137
145
  }) as {
138
- textStyle: Partial<T>;
139
- backgroundStyle: Partial<T>;
140
- innerStyle: Partial<T>;
146
+ textStyle: Partial<T>
147
+ backgroundStyle: Partial<T>
148
+ innerStyle: Partial<T>
141
149
  }
142
150
  }
143
151
 
@@ -157,19 +165,6 @@ const parentHeightPercentRule: Record<string, boolean> = {
157
165
  bottom: true
158
166
  }
159
167
 
160
- // todo calc时处理角度和时间等单位
161
- function formatValue (value: string) {
162
- let matched
163
- if ((matched = pxRegExp.exec(value))) {
164
- return +matched[1]
165
- } else if ((matched = rpxRegExp.exec(value))) {
166
- return rpx(+matched[1])
167
- } else if (hairlineRegExp.test(value)) {
168
- return StyleSheet.hairlineWidth
169
- }
170
- return value
171
- }
172
-
173
168
  interface PercentConfig {
174
169
  fontSize?: number | string
175
170
  width?: number
@@ -226,11 +221,11 @@ function resolveVar (input: string, varContext: Record<string, any>) {
226
221
  if (varUseRegExp.test(varValue)) {
227
222
  varValue = '' + resolveVar(varValue, varContext)
228
223
  } else {
229
- varValue = '' + formatValue(varValue)
224
+ varValue = '' + global.__formatValue(varValue)
230
225
  }
231
226
  replaced.replace(start, end - 1, varValue)
232
227
  })
233
- return formatValue(replaced.source())
228
+ return global.__formatValue(replaced.source())
234
229
  }
235
230
 
236
231
  function transformVar (styleObj: Record<string, any>, varKeyPaths: Array<Array<string>>, varContext: Record<string, any>) {
@@ -241,6 +236,22 @@ function transformVar (styleObj: Record<string, any>, varKeyPaths: Array<Array<s
241
236
  })
242
237
  }
243
238
 
239
+ function transformEnv (styleObj: Record<string, any>, envKeyPaths: Array<Array<string>>) {
240
+ envKeyPaths.forEach((envKeyPath) => {
241
+ setStyle(styleObj, envKeyPath, ({ target, key, value }) => {
242
+ const parsed = parseFunc(value, 'env')
243
+ const replaced = new ReplaceSource(value)
244
+ parsed.forEach(({ start, end, args }) => {
245
+ const name = args[0]
246
+ const fallback = args[1] || ''
247
+ const value = '' + (getSafeAreaInset(name) ?? global.__formatValue(fallback))
248
+ replaced.replace(start, end - 1, value)
249
+ })
250
+ target[key] = global.__formatValue(replaced.source())
251
+ })
252
+ })
253
+ }
254
+
244
255
  function transformCalc (styleObj: Record<string, any>, calcKeyPaths: Array<Array<string>>, formatter: (value: string, key: string) => number) {
245
256
  calcKeyPaths.forEach((calcKeyPath) => {
246
257
  setStyle(styleObj, calcKeyPath, ({ target, key, value }) => {
@@ -257,7 +268,7 @@ function transformCalc (styleObj: Record<string, any>, calcKeyPaths: Array<Array
257
268
  error(`calc(${exp}) parse error.`, undefined, e)
258
269
  }
259
270
  })
260
- target[key] = formatValue(replaced.source())
271
+ target[key] = global.__formatValue(replaced.source())
261
272
  })
262
273
  })
263
274
  }
@@ -279,6 +290,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
279
290
  const varKeyPaths: Array<Array<string>> = []
280
291
  const percentKeyPaths: Array<Array<string>> = []
281
292
  const calcKeyPaths: Array<Array<string>> = []
293
+ const envKeyPaths: Array<Array<string>> = []
282
294
  const [width, setWidth] = useState(0)
283
295
  const [height, setHeight] = useState(0)
284
296
 
@@ -298,6 +310,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
298
310
  varKeyPaths.push(keyPath.slice())
299
311
  }
300
312
  }
313
+
301
314
  // traverse var
302
315
  traverseStyle(styleObj, [varVisitor])
303
316
  hasVarDec = hasVarDec || !!externalVarContext
@@ -318,6 +331,12 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
318
331
  transformVar(normalStyle, varKeyPaths, varContextRef.current)
319
332
  }
320
333
 
334
+ function envVisitor ({ value, keyPath }: VisitorArg) {
335
+ if (envUseRegExp.test(value)) {
336
+ envKeyPaths.push(keyPath.slice())
337
+ }
338
+ }
339
+
321
340
  function calcVisitor ({ value, keyPath }: VisitorArg) {
322
341
  if (calcUseRegExp.test(value)) {
323
342
  calcKeyPaths.push(keyPath.slice())
@@ -328,13 +347,13 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
328
347
  if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) {
329
348
  hasSelfPercent = true
330
349
  percentKeyPaths.push(keyPath.slice())
331
- } else if (key === 'fontSize' || key === 'lineHeight') {
350
+ } else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
332
351
  percentKeyPaths.push(keyPath.slice())
333
352
  }
334
353
  }
335
354
 
336
- // traverse calc & percent
337
- traverseStyle(normalStyle, [percentVisitor, calcVisitor])
355
+ // traverse env & calc & percent
356
+ traverseStyle(normalStyle, [envVisitor, percentVisitor, calcVisitor])
338
357
 
339
358
  const percentConfig = {
340
359
  width,
@@ -345,6 +364,8 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
345
364
  parentFontSize
346
365
  }
347
366
 
367
+ // apply env
368
+ transformEnv(normalStyle, envKeyPaths)
348
369
  // apply percent
349
370
  transformPercent(normalStyle, percentKeyPaths, percentConfig)
350
371
  // apply calc
@@ -353,7 +374,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
353
374
  const resolved = resolvePercent(value, key, percentConfig)
354
375
  return typeof resolved === 'number' ? resolved : 0
355
376
  } else {
356
- const formatted = formatValue(value)
377
+ const formatted = global.__formatValue(value)
357
378
  if (typeof formatted === 'number') {
358
379
  return formatted
359
380
  } else {
@@ -409,11 +430,9 @@ export function traverseStyle (styleObj: Record<string, any>, visitors: Array<(a
409
430
  traverse(styleObj)
410
431
  }
411
432
 
412
- export function setStyle (styleObj: Record<string, any>, keyPath: Array<string>, setter: (arg: VisitorArg) => void, needClone = false) {
433
+ export function setStyle (styleObj: Record<string, any>, keyPath: Array<string>, setter: (arg: VisitorArg) => void) {
413
434
  let target = styleObj
414
- const firstKey = keyPath[0]
415
435
  const lastKey = keyPath[keyPath.length - 1]
416
- if (needClone) target[firstKey] = diffAndCloneA(target[firstKey]).clone
417
436
  for (let i = 0; i < keyPath.length - 1; i++) {
418
437
  target = target[keyPath[i]]
419
438
  if (!target) return
@@ -427,8 +446,8 @@ export function setStyle (styleObj: Record<string, any>, keyPath: Array<string>,
427
446
  }
428
447
 
429
448
  export function splitProps<T extends Record<string, any>> (props: T): {
430
- textProps?: Partial<T>;
431
- innerProps?: Partial<T>;
449
+ textProps?: Partial<T>
450
+ innerProps?: Partial<T>
432
451
  } {
433
452
  return groupBy(props, (key) => {
434
453
  if (TEXT_PROPS_REGEX.test(key)) {
@@ -437,8 +456,8 @@ export function splitProps<T extends Record<string, any>> (props: T): {
437
456
  return 'innerProps'
438
457
  }
439
458
  }) as {
440
- textProps: Partial<T>;
441
- innerProps: Partial<T>;
459
+ textProps: Partial<T>
460
+ innerProps: Partial<T>
442
461
  }
443
462
  }
444
463
 
@@ -450,7 +469,7 @@ interface LayoutConfig {
450
469
  onLayout?: (event?: LayoutChangeEvent) => void
451
470
  nodeRef: React.RefObject<any>
452
471
  }
453
- export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }:LayoutConfig) => {
472
+ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }: LayoutConfig) => {
454
473
  const layoutRef = useRef({})
455
474
  const hasLayoutRef = useRef(false)
456
475
  const layoutStyle: Record<string, any> = !hasLayoutRef.current && hasSelfPercent ? DEFAULT_UNLAY_STYLE : {}
@@ -9,6 +9,7 @@
9
9
  BScroll.use(PullDown)
10
10
 
11
11
  let mutationObserver = null
12
+ let resizeObserver = null
12
13
 
13
14
  export default {
14
15
  name: 'mpx-scroll-view',
@@ -357,11 +358,15 @@
357
358
  let minTop
358
359
  let maxBottom
359
360
  childrenArr.forEach(item => {
360
- const temp = item.getBoundingClientRect()
361
- minLeft = getMinLength(minLeft, temp.left)
362
- minTop = getMinLength(minTop, temp.top)
363
- maxRight = getMaxLength(maxRight, temp.right)
364
- maxBottom = getMaxLength(maxBottom, temp.bottom)
361
+ const left = item.offsetLeft
362
+ const top = item.offsetTop
363
+ const width = item.offsetWidth
364
+ const height = item.offsetHeight
365
+
366
+ minLeft = getMinLength(minLeft, left)
367
+ minTop = getMinLength(minTop, top)
368
+ maxRight = getMaxLength(maxRight, left + width)
369
+ maxBottom = getMaxLength(maxBottom, top + height)
365
370
  })
366
371
  const width = maxRight - minLeft || 0
367
372
  const height = maxBottom - minTop || 0
@@ -399,6 +404,17 @@
399
404
  const config = { attributes: true, childList: true, subtree: true }
400
405
  mutationObserver.observe(this.$refs.wrapper, config)
401
406
  }
407
+ if (typeof ResizeObserver !== 'undefined') {
408
+ let isFirstResize = true
409
+ resizeObserver = new ResizeObserver(() => {
410
+ if (isFirstResize) {
411
+ isFirstResize = false
412
+ return
413
+ }
414
+ this.debounceRefresh()
415
+ })
416
+ resizeObserver.observe(this.$refs.wrapper)
417
+ }
402
418
  },
403
419
  mutationObserverHandler (mutations) {
404
420
  let needRefresh = false
@@ -428,6 +444,10 @@
428
444
  mutationObserver.disconnect()
429
445
  mutationObserver = null
430
446
  }
447
+ if (resizeObserver) {
448
+ resizeObserver.disconnect()
449
+ resizeObserver = null
450
+ }
431
451
  }
432
452
  },
433
453
  render (createElement) {
@@ -18,7 +18,8 @@ module.exports = function (css, map) {
18
18
  const cb = this.async()
19
19
  const { resourcePath, queryObj } = parseRequest(this.resource)
20
20
  const mpx = this.getMpx()
21
- const id = queryObj.moduleId || queryObj.mid || '_' + mpx.pathHash(resourcePath)
21
+ const mpxStyleOptions = (queryObj.mpxStyleOptions && JSON.parse(queryObj.mpxStyleOptions)) || {}
22
+ const id = queryObj.moduleId || mpxStyleOptions.mid || '_' + mpx.pathHash(resourcePath)
22
23
  const appInfo = mpx.appInfo
23
24
  const defs = mpx.defs
24
25
  const mode = mpx.mode
@@ -46,14 +47,14 @@ module.exports = function (css, map) {
46
47
  config.options
47
48
  )
48
49
  // ali平台下处理scoped和host选择器
49
- if (mode === 'ali') {
50
- if (queryObj.scoped) {
50
+ if (mode === 'ali' || mode === 'web') {
51
+ if (queryObj.scoped || mpxStyleOptions.scoped) {
51
52
  plugins.push(scopeId({ id }))
52
53
  }
53
54
  plugins.push(transSpecial({ id }))
54
55
  }
55
56
 
56
- if (mode === 'web' || isReact(mode)) {
57
+ if (isReact(mode)) {
57
58
  plugins.push(transSpecial({ id }))
58
59
  }
59
60