@mpxjs/webpack-plugin 2.10.15-5 → 2.10.15-prelease.1

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 (45) hide show
  1. package/lib/dependencies/DynamicEntryDependency.js +1 -1
  2. package/lib/dependencies/ImportDependency.js +102 -0
  3. package/lib/{retry-runtime-module.js → dependencies/RetryRuntimeModule.js} +1 -1
  4. package/lib/index.js +13 -15
  5. package/lib/platform/template/wx/component-config/progress.js +12 -0
  6. package/lib/platform/template/wx/component-config/slider.js +12 -0
  7. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  8. package/lib/platform/template/wx/index.js +3 -1
  9. package/lib/resolver/AddEnvPlugin.js +13 -0
  10. package/lib/resolver/AddModePlugin.js +18 -0
  11. package/lib/runtime/components/react/dist/getInnerListeners.js +35 -21
  12. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +102 -34
  13. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +3 -5
  14. package/lib/runtime/components/react/dist/mpx-progress.jsx +163 -0
  15. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +38 -7
  16. package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
  17. package/lib/runtime/components/react/dist/mpx-swiper.jsx +9 -16
  18. package/lib/runtime/components/react/dist/mpx-view.jsx +7 -10
  19. package/lib/runtime/components/react/dist/mpx-web-view.jsx +20 -1
  20. package/lib/runtime/components/react/getInnerListeners.ts +41 -22
  21. package/lib/runtime/components/react/mpx-movable-view.tsx +156 -48
  22. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +4 -8
  23. package/lib/runtime/components/react/mpx-progress.tsx +259 -0
  24. package/lib/runtime/components/react/mpx-scroll-view.tsx +39 -7
  25. package/lib/runtime/components/react/mpx-slider.tsx +444 -0
  26. package/lib/runtime/components/react/mpx-swiper.tsx +9 -16
  27. package/lib/runtime/components/react/mpx-view.tsx +7 -10
  28. package/lib/runtime/components/react/mpx-web-view.tsx +22 -1
  29. package/lib/runtime/components/react/types/getInnerListeners.d.ts +7 -2
  30. package/lib/runtime/components/web/mpx-input.vue +14 -0
  31. package/lib/runtime/components/web/mpx-movable-area.vue +43 -19
  32. package/lib/runtime/components/web/mpx-movable-view.vue +93 -3
  33. package/lib/runtime/components/web/mpx-scroll-view.vue +7 -1
  34. package/lib/runtime/components/web/mpx-swiper.vue +1 -2
  35. package/lib/runtime/components/web/mpx-video.vue +12 -1
  36. package/lib/runtime/components/web/mpx-web-view.vue +3 -3
  37. package/lib/runtime/optionProcessor.js +3 -1
  38. package/lib/runtime/optionProcessorReact.js +4 -2
  39. package/lib/template-compiler/compiler.js +69 -35
  40. package/lib/utils/chain-assign.js +47 -0
  41. package/lib/utils/check-core-version-match.js +75 -15
  42. package/lib/wxs/pre-loader.js +5 -5
  43. package/lib/wxss/utils.js +1 -1
  44. package/package.json +3 -2
  45. package/lib/dependencies/ImportDependencyTemplate.js +0 -50
@@ -0,0 +1,444 @@
1
+ /**
2
+ * ✔ min 最小值
3
+ * ✔ max 最大值
4
+ * ✔ step 步长
5
+ * ✔ disabled 是否禁用
6
+ * ✔ value 当前取值
7
+ * ✔ color 背景条的颜色(已废弃,使用 backgroundColor)
8
+ * ✔ selected-color 已选择的颜色(已废弃,使用 activeColor)
9
+ * ✔ activeColor 已选择的颜色
10
+ * ✔ backgroundColor 背景条的颜色
11
+ * ✔ block-size 滑块的大小
12
+ * ✔ block-color 滑块的颜色
13
+ * ✘ show-value 是否显示当前 value
14
+ * ✔ bindchange 完成一次拖动后触发的事件
15
+ * ✔ bindchanging 拖动过程中触发的事件
16
+ */
17
+ import {
18
+ JSX,
19
+ useRef,
20
+ forwardRef,
21
+ useEffect,
22
+ useState,
23
+ createElement,
24
+ ForwardedRef,
25
+ useContext,
26
+ useMemo
27
+ } from 'react'
28
+ import {
29
+ View,
30
+ ViewStyle
31
+ } from 'react-native'
32
+ import { GestureDetector, Gesture, GestureStateChangeEvent, PanGestureHandlerEventPayload } from 'react-native-gesture-handler'
33
+ import Animated, { useSharedValue, useAnimatedStyle, runOnJS } from 'react-native-reanimated'
34
+ import { warn } from '@mpxjs/utils'
35
+
36
+ import useInnerProps, { getCustomEvent } from './getInnerListeners'
37
+ import useNodesRef, { HandlerRef } from './useNodesRef'
38
+ import { useLayout, useTransformStyle, extendObject, useRunOnJSCallback } from './utils'
39
+ import Portal from './mpx-portal'
40
+ import { FormContext, FormFieldValue } from './context'
41
+
42
+ export interface SliderProps {
43
+ min?: number
44
+ max?: number
45
+ step?: number
46
+ disabled?: boolean
47
+ value?: number
48
+ color?: string
49
+ 'selected-color'?: string
50
+ activeColor?: string
51
+ backgroundColor?: string
52
+ 'block-size'?: number
53
+ 'block-color'?: string
54
+ name?: string
55
+ bindchange?: (event: any) => void
56
+ catchchange?: (event: any) => void
57
+ bindchanging?: (event: any) => void
58
+ catchchanging?: (event: any) => void
59
+ style?: ViewStyle & Record<string, any>
60
+ 'enable-offset'?: boolean
61
+ 'enable-var'?: boolean
62
+ 'external-var-context'?: Record<string, any>
63
+ 'parent-font-size'?: number
64
+ 'parent-width'?: number
65
+ 'parent-height'?: number
66
+ }
67
+
68
+ const Slider = forwardRef<
69
+ HandlerRef<View, SliderProps>,
70
+ SliderProps
71
+ >((props: SliderProps, ref: ForwardedRef<HandlerRef<View, SliderProps>>): JSX.Element => {
72
+ const {
73
+ min: rawMin = 0,
74
+ max: rawMax = 100,
75
+ step: rawStep = 1,
76
+ disabled = false,
77
+ value: rawValue,
78
+ color,
79
+ 'selected-color': selectedColor,
80
+ activeColor = selectedColor || color || '#1aad19',
81
+ backgroundColor = color || '#e9e9e9',
82
+ 'block-size': rawBlockSize = 28,
83
+ 'block-color': blockColor = '#ffffff',
84
+ name,
85
+ style = {},
86
+ 'enable-var': enableVar,
87
+ 'external-var-context': externalVarContext,
88
+ 'parent-font-size': parentFontSize,
89
+ 'parent-width': parentWidth,
90
+ 'parent-height': parentHeight
91
+ } = props
92
+
93
+ // 确保数值类型正确
94
+ const min = typeof rawMin === 'string' ? parseFloat(rawMin) : rawMin
95
+ const max = typeof rawMax === 'string' ? parseFloat(rawMax) : rawMax
96
+ const step = typeof rawStep === 'string' ? parseFloat(rawStep) : rawStep
97
+ const value = rawValue !== undefined ? (typeof rawValue === 'string' ? parseFloat(rawValue) : rawValue) : undefined
98
+ const blockSize = typeof rawBlockSize === 'string' ? parseFloat(rawBlockSize) : rawBlockSize
99
+
100
+ // 如果没有提供 value,则使用 min 作为默认值
101
+ const defaultValue = value !== undefined ? value : min
102
+ const nodeRef = useRef(null)
103
+ const trackRef = useRef(null)
104
+ const [currentValue, setCurrentValue] = useState(defaultValue)
105
+ const [trackWidth, setTrackWidth] = useState(0)
106
+
107
+ const thumbPosition = useSharedValue(0)
108
+ const isDragging = useSharedValue(false)
109
+ const startDragPosition = useSharedValue(0) // 记录拖拽开始时的位置
110
+ const startDragValue = useSharedValue(0) // 记录拖拽开始时的值
111
+
112
+ let formValuesMap: Map<string, FormFieldValue> | undefined
113
+
114
+ const propsRef = useRef(props)
115
+ propsRef.current = props
116
+
117
+ const formContext = useContext(FormContext)
118
+
119
+ if (formContext) {
120
+ formValuesMap = formContext.formValuesMap
121
+ }
122
+
123
+ const {
124
+ normalStyle,
125
+ hasSelfPercent,
126
+ setWidth,
127
+ setHeight,
128
+ hasPositionFixed
129
+ } = useTransformStyle(style, {
130
+ enableVar,
131
+ externalVarContext,
132
+ parentFontSize,
133
+ parentWidth,
134
+ parentHeight
135
+ })
136
+
137
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({
138
+ props,
139
+ hasSelfPercent,
140
+ setWidth,
141
+ setHeight,
142
+ nodeRef
143
+ })
144
+
145
+ useNodesRef(props, ref, nodeRef, {
146
+ style: normalStyle
147
+ })
148
+
149
+ // 使用 useRunOnJSCallback 处理手势回调
150
+ const runOnJSCallbackRef = useRef({
151
+ triggerChangeEvent: (newValue: number) => {
152
+ setCurrentValue(newValue)
153
+ const currentProps = propsRef.current
154
+ const changeHandler = currentProps.bindchange || currentProps.catchchange
155
+ if (changeHandler) {
156
+ changeHandler(getCustomEvent('change', {}, { layoutRef, detail: { value: newValue } }, currentProps))
157
+ }
158
+ },
159
+ triggerChangingEvent: (newValue: number) => {
160
+ const currentProps = propsRef.current
161
+ const changingHandler = currentProps.bindchanging || currentProps.catchchanging
162
+ if (changingHandler) {
163
+ changingHandler(getCustomEvent('changing', {}, { layoutRef, detail: { value: newValue } }, currentProps))
164
+ }
165
+ }
166
+ })
167
+ const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
168
+
169
+ // 限制步长,确保 step 大于 0,并且可被 (max - min) 整除
170
+ const validateStep = (step: number, min: number, max: number): number => {
171
+ if (step <= 0) return 1
172
+ if ((max - min) % step !== 0) {
173
+ warn(`Step ${step} is not a divisor of range ${max - min}`)
174
+ }
175
+ return step
176
+ }
177
+
178
+ const validStep = validateStep(step, min, max)
179
+
180
+ // 将值约束在 min-max 范围内,并按步长对齐
181
+ const constrainValue = (val: number, minVal: number = min, maxVal: number = max, stepVal: number = validStep): number => {
182
+ const constrained = Math.max(minVal, Math.min(maxVal, val))
183
+ const steps = Math.round((constrained - minVal) / stepVal)
184
+ return minVal + steps * stepVal
185
+ }
186
+
187
+ // 计算滑块位置
188
+ const getThumbPosition = (val: number, trackW: number = trackWidth, minVal: number = min, maxVal: number = max): number => {
189
+ if (trackW === 0) return 0
190
+ const percentage = (val - minVal) / (maxVal - minVal)
191
+ const position = percentage * trackW
192
+ return position
193
+ }
194
+
195
+ // 手势处理
196
+ const panGesture = useMemo(() => {
197
+ const getThumbPositionWorklet = (val: number, trackW: number, minVal: number, maxVal: number): number => {
198
+ 'worklet'
199
+ if (trackW === 0) return 0
200
+ const percentage = (val - minVal) / (maxVal - minVal)
201
+ return percentage * trackW
202
+ }
203
+
204
+ const constrainValueWorklet = (val: number, minVal: number, maxVal: number, stepVal: number): number => {
205
+ 'worklet'
206
+ const constrained = Math.max(minVal, Math.min(maxVal, val))
207
+ const steps = Math.round((constrained - minVal) / stepVal)
208
+ return minVal + steps * stepVal
209
+ }
210
+
211
+ return Gesture.Pan()
212
+ .enabled(!disabled) // 通过手势启用状态控制是否可拖拽
213
+ .onBegin(() => {
214
+ 'worklet'
215
+ if (trackWidth === 0) return
216
+ isDragging.value = true
217
+ // 记录拖拽开始时的位置 - 使用当前的动画位置
218
+ startDragPosition.value = thumbPosition.value
219
+ // 根据当前位置反推值
220
+ const percentage = thumbPosition.value / trackWidth
221
+ const currentVal = min + percentage * (max - min)
222
+ startDragValue.value = constrainValueWorklet(currentVal, min, max, validStep)
223
+ })
224
+ .onUpdate((event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
225
+ 'worklet'
226
+ if (trackWidth === 0) return
227
+
228
+ // 基于拖拽开始位置计算新位置
229
+ const newX = startDragPosition.value + event.translationX
230
+ const clampedX = Math.max(0, Math.min(trackWidth, newX))
231
+
232
+ // 计算新值
233
+ const percentage = clampedX / trackWidth
234
+ const rawValue = min + percentage * (max - min)
235
+ const newValue = constrainValueWorklet(rawValue, min, max, validStep)
236
+
237
+ // 更新滑块位置 - 使用约束后的值对应的位置
238
+ const constrainedPosition = getThumbPositionWorklet(newValue, trackWidth, min, max)
239
+ thumbPosition.value = constrainedPosition
240
+
241
+ // 只触发 changing 事件,不更新 currentValue(避免干扰拖拽)
242
+ runOnJS(runOnJSCallback)('triggerChangingEvent', newValue)
243
+ })
244
+ .onEnd((event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
245
+ 'worklet'
246
+ isDragging.value = false
247
+
248
+ // 基于拖拽开始位置计算最终位置
249
+ const newX = startDragPosition.value + event.translationX
250
+ const clampedX = Math.max(0, Math.min(trackWidth, newX))
251
+ const percentage = clampedX / trackWidth
252
+ const rawValue = min + percentage * (max - min)
253
+ const finalValue = constrainValueWorklet(rawValue, min, max, validStep)
254
+
255
+ // 确保滑块位置与最终值匹配
256
+ const finalPosition = getThumbPositionWorklet(finalValue, trackWidth, min, max)
257
+ thumbPosition.value = finalPosition
258
+
259
+ // 更新 currentValue 并触发 change 事件
260
+ runOnJS(runOnJSCallback)('triggerChangeEvent', finalValue)
261
+ })
262
+ }, [disabled, trackWidth, min, max, validStep, runOnJSCallback])
263
+
264
+ // 当 value 属性变化时更新位置
265
+ useEffect(() => {
266
+ const newValue = constrainValue(defaultValue)
267
+ setCurrentValue(newValue)
268
+ // 同时更新动画位置
269
+ thumbPosition.value = getThumbPosition(newValue)
270
+ }, [defaultValue, min, max, validStep])
271
+
272
+ // 当 trackWidth 变化时更新滑块位置
273
+ useEffect(() => {
274
+ // 只在非拖拽状态下更新位置
275
+ if (!isDragging.value) {
276
+ thumbPosition.value = getThumbPosition(currentValue)
277
+ }
278
+ }, [trackWidth, currentValue])
279
+
280
+ // 动画样式
281
+ const animatedThumbStyle = useAnimatedStyle(() => {
282
+ const blockSizeNum = Math.max(12, Math.min(28, blockSize))
283
+ const trackHeight = 4
284
+ return {
285
+ position: 'absolute',
286
+ top: -((blockSizeNum - trackHeight) / 2),
287
+ left: Math.max(0, Math.min(trackWidth - blockSizeNum, thumbPosition.value - (blockSizeNum / 2))),
288
+ width: blockSizeNum,
289
+ height: blockSizeNum,
290
+ justifyContent: 'center',
291
+ alignItems: 'center'
292
+ }
293
+ })
294
+
295
+ // 轨道布局回调
296
+ const onTrackLayout = (event: any) => {
297
+ const { width } = event.nativeEvent.layout
298
+ setTrackWidth(width)
299
+ }
300
+
301
+ // 表单相关处理
302
+ const resetValue = () => {
303
+ const currentProps = propsRef.current
304
+ const currentValue = currentProps.value !== undefined ? currentProps.value : currentProps.min || 0
305
+ const parsedValue = typeof currentValue === 'string' ? parseFloat(currentValue) : currentValue
306
+ const currentMin = typeof currentProps.min === 'string' ? parseFloat(currentProps.min) : (currentProps.min || 0)
307
+ const currentMax = typeof currentProps.max === 'string' ? parseFloat(currentProps.max) : (currentProps.max || 100)
308
+ const currentStep = typeof currentProps.step === 'string' ? parseFloat(currentProps.step) : (currentProps.step || 1)
309
+ const resetVal = parsedValue !== undefined ? parsedValue : currentMin
310
+ const validatedStep = validateStep(currentStep, currentMin, currentMax)
311
+ const constrainedVal = constrainValue(resetVal, currentMin, currentMax, validatedStep)
312
+ setCurrentValue(constrainedVal)
313
+ thumbPosition.value = getThumbPosition(constrainedVal, trackWidth, currentMin, currentMax)
314
+ }
315
+
316
+ const getValue = () => {
317
+ return currentValue
318
+ }
319
+
320
+ if (formValuesMap) {
321
+ if (!name) {
322
+ warn('If a form component is used, the name attribute is required.')
323
+ } else {
324
+ formValuesMap.set(name, { getValue, resetValue })
325
+ }
326
+ }
327
+
328
+ useEffect(() => {
329
+ return () => {
330
+ if (formValuesMap && name) {
331
+ formValuesMap.delete(name)
332
+ }
333
+ }
334
+ }, [])
335
+
336
+ // 样式定义
337
+ const blockSizeNum = Math.max(12, Math.min(28, blockSize))
338
+ const trackHeight = 4
339
+
340
+ const containerStyle: ViewStyle = extendObject({} as ViewStyle, {
341
+ flexDirection: 'row' as const,
342
+ alignItems: 'center' as const,
343
+ minHeight: Math.max(blockSizeNum + 8, 40),
344
+ paddingHorizontal: 14 // 固定内边距,不受 block-size 影响
345
+ }, normalStyle, layoutStyle)
346
+
347
+ const trackStyle: ViewStyle = {
348
+ flex: 1,
349
+ height: trackHeight,
350
+ backgroundColor,
351
+ borderRadius: trackHeight / 2,
352
+ position: 'relative'
353
+ }
354
+
355
+ // 动画进度条样式
356
+ const animatedProgressStyle = useAnimatedStyle(() => {
357
+ return {
358
+ height: '100%',
359
+ backgroundColor: activeColor,
360
+ borderRadius: trackHeight / 2,
361
+ width: Math.max(0, thumbPosition.value)
362
+ }
363
+ })
364
+
365
+ const thumbStyle: ViewStyle = {
366
+ width: blockSizeNum,
367
+ height: blockSizeNum,
368
+ backgroundColor: blockColor,
369
+ borderRadius: blockSizeNum / 2,
370
+ shadowColor: '#000',
371
+ shadowOffset: { width: 0, height: 2 },
372
+ shadowOpacity: 0.2,
373
+ shadowRadius: 4,
374
+ elevation: 4
375
+ }
376
+
377
+ const innerProps = useInnerProps(
378
+ extendObject({}, props, layoutProps, {
379
+ ref: nodeRef
380
+ }),
381
+ [
382
+ 'min',
383
+ 'max',
384
+ 'step',
385
+ 'disabled',
386
+ 'value',
387
+ 'color',
388
+ 'selected-color',
389
+ 'activeColor',
390
+ 'backgroundColor',
391
+ 'block-size',
392
+ 'block-color',
393
+ 'bindchange',
394
+ 'catchchange',
395
+ 'bindchanging',
396
+ 'catchchanging'
397
+ ],
398
+ { layoutRef }
399
+ )
400
+
401
+ const sliderContent = createElement(
402
+ View,
403
+ extendObject({}, innerProps, { style: containerStyle }),
404
+ // 轨道容器
405
+ createElement(
406
+ View,
407
+ {
408
+ style: trackStyle,
409
+ onLayout: onTrackLayout,
410
+ ref: trackRef
411
+ },
412
+ // 进度条 - 使用动画样式
413
+ createElement(Animated.View, {
414
+ style: animatedProgressStyle
415
+ }),
416
+ // 滑块容器
417
+ createElement(
418
+ GestureDetector,
419
+ {
420
+ gesture: panGesture
421
+ },
422
+ createElement(
423
+ Animated.View,
424
+ {
425
+ style: [animatedThumbStyle]
426
+ },
427
+ // 滑块
428
+ createElement(View, {
429
+ style: thumbStyle
430
+ })
431
+ )
432
+ )
433
+ )
434
+ )
435
+
436
+ if (hasPositionFixed) {
437
+ return createElement(Portal, null, sliderContent)
438
+ }
439
+
440
+ return sliderContent
441
+ })
442
+
443
+ Slider.displayName = 'MpxSlider'
444
+ export default Slider
@@ -207,8 +207,6 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
207
207
  const strVelocity = 'velocity' + dir.toUpperCase() as StrVelocityType
208
208
  // 标识手指触摸和抬起, 起点在onBegin
209
209
  const touchfinish = useSharedValue(true)
210
- // 记录onUpdate时的方向,用于进行onFinalize中的值修正
211
- const preUpdateTransDir = useSharedValue(0)
212
210
  // 记录上一帧的绝对定位坐标
213
211
  const preAbsolutePos = useSharedValue(0)
214
212
  // 记录从onBegin 到 onTouchesUp 时移动的距离
@@ -431,9 +429,11 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
431
429
  }
432
430
  }, [])
433
431
 
434
- function handleSwiperChange (current: number) {
435
- const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef })
436
- bindchange && bindchange(eventData)
432
+ function handleSwiperChange (current: number, pCurrent: number) {
433
+ if (pCurrent !== currentIndex.value) {
434
+ const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef })
435
+ bindchange && bindchange(eventData)
436
+ }
437
437
  }
438
438
 
439
439
  const runOnJSCallbackRef = useRef({
@@ -482,7 +482,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
482
482
  // 1. 用户在当前页切换选中项,动画;用户携带选中index打开到swiper页直接选中不走动画
483
483
  useAnimatedReaction(() => currentIndex.value, (newIndex: number, preIndex: number) => {
484
484
  // 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
485
- if (newIndex !== preIndex && preIndex !== null && preIndex !== undefined && bindchange) {
485
+ if (newIndex !== preIndex && bindchange) {
486
486
  runOnJS(runOnJSCallback)('handleSwiperChange', newIndex, propCurrent)
487
487
  }
488
488
  })
@@ -517,9 +517,9 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
517
517
  }, [children.length])
518
518
 
519
519
  useEffect(() => {
520
- // 1. 如果用户在touch的过程中, 外部更新了current以内部为准(小程序表现)
520
+ // 1. 如果用户在touch的过程中, 外部更新了current以外部为准(小程序表现)
521
521
  // 2. 手指滑动过程中更新索引,外部会把current再传入进来,导致offset直接更新,增加判断不同才更新
522
- if (propCurrent !== currentIndex.value && touchfinish.value) {
522
+ if (propCurrent !== currentIndex.value) {
523
523
  updateCurrent(propCurrent, step.value)
524
524
  }
525
525
  }, [propCurrent])
@@ -757,7 +757,6 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
757
757
  translation: moveDistance,
758
758
  transdir: moveDistance
759
759
  }
760
- preUpdateTransDir.value = moveDistance
761
760
  // 1. 支持滑动中超出一半更新索引的能力:只更新索引并不会影响onFinalize依据当前offset计算的索引
762
761
  const { half } = computeHalf(eventData)
763
762
  if (childrenLength.value > 1 && half) {
@@ -795,17 +794,11 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
795
794
  'worklet'
796
795
  if (touchfinish.value) return
797
796
  touchfinish.value = true
798
- /**
799
- * 安卓修正
800
- * 问题:部分安卓机型onFinalize中拿到的absoluteX 有问题
801
- * 案例:比如手指从右向左滑的时候,onUpdate拿到的是241.64346313476562, 而onFinalize中拿到的是241.81817626953125,理论上onFinalize中应该比onUpdate小才对吧
802
- * 解决方式:修正
803
- */
804
797
  // 触发过onUpdate正常情况下e[strAbso] - preAbsolutePos.value=0; 未触发过onUpdate的情况下e[strAbso] - preAbsolutePos.value 不为0
805
798
  const moveDistance = e[strAbso] - preAbsolutePos.value
806
799
  const eventData = {
807
800
  translation: moveDistance,
808
- transdir: Math.abs(moveDistance) > 1 ? moveDistance : preUpdateTransDir.value
801
+ transdir: moveDistance !== 0 ? moveDistance : e[strAbso] - moveTranstion.value
809
802
  }
810
803
  // 1. 只有一个元素:循环 和 非循环状态,都走回弹效果
811
804
  if (childrenLength.value === 1) {
@@ -287,16 +287,13 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
287
287
  } else { // 数值类型 ImageStyle
288
288
  // 数值类型设置为 stretch
289
289
  imageProps.resizeMode = 'stretch'
290
- if (type === 'linear') {
291
- const dimensionWidth = calcPercent(width as NumberVal, layoutWidth) || 0
292
- const dimensionHeight = calcPercent(height as NumberVal, layoutHeight) || 0
293
- // ios 上 linear 组件只要重新触发渲染,在渲染过程中 width 或者 height 被设置为 0,即使后面再更新为正常宽高,也会渲染不出来
294
- if (dimensionWidth && dimensionHeight) {
295
- dimensions = {
296
- width: dimensionWidth,
297
- height: dimensionHeight
298
- } as { width: NumberVal, height: NumberVal }
299
- }
290
+ if (type === 'linear' && (!layoutWidth || !layoutHeight)) {
291
+ // ios linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来
292
+ // 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。
293
+ dimensions = {
294
+ width: 0,
295
+ height: 0
296
+ } as { width: NumberVal, height: NumberVal }
300
297
  } else {
301
298
  dimensions = {
302
299
  width: isPercent(width) ? width : +width,
@@ -76,6 +76,7 @@ const styles = StyleSheet.create({
76
76
  borderRadius: 10
77
77
  }
78
78
  })
79
+
79
80
  const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element | null => {
80
81
  const { src, bindmessage, bindload, binderror } = props
81
82
  const mpx = global.__mpx
@@ -126,10 +127,27 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
126
127
  style: defaultWebViewStyle
127
128
  })
128
129
 
130
+ const hostValidate = (url: string) => {
131
+ const host = url && new URL(url).host
132
+ const hostWhitelists = mpx.config.rnConfig?.webviewConfig?.hostWhitelists || []
133
+ if (hostWhitelists.length) {
134
+ return hostWhitelists.some((item: string) => {
135
+ return host.endsWith(item)
136
+ })
137
+ } else {
138
+ return true
139
+ }
140
+ }
141
+
129
142
  if (!src) {
130
143
  return null
131
144
  }
132
145
 
146
+ if (!hostValidate(src)) {
147
+ console.error('访问页面域名不符合domainWhiteLists白名单配置,请确认是否正确配置该域名白名单')
148
+ return null
149
+ }
150
+
133
151
  const _reload = function () {
134
152
  if (__mpx_mode__ !== 'ios') {
135
153
  fristLoaded.current = false // 安卓需要重新设置
@@ -182,6 +200,9 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
182
200
  }
183
201
  }
184
202
  const _message = function (res: WebViewMessageEvent) {
203
+ if (!hostValidate(res.nativeEvent?.url)) {
204
+ return
205
+ }
185
206
  let data: MessageData = {}
186
207
  let asyncCallback
187
208
  const navObj = promisify({ redirectTo, navigateTo, navigateBack, reLaunch, switchTab })
@@ -232,7 +253,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
232
253
  break
233
254
  default:
234
255
  if (type) {
235
- const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type]
256
+ const implement = mpx.config.rnConfig.webviewConfig && mpx.config.rnConfig.webviewConfig.apiImplementations && mpx.config.rnConfig.webviewConfig.apiImplementations[type]
236
257
  if (isFunction(implement)) {
237
258
  asyncCallback = Promise.resolve(implement(...params))
238
259
  } else {
@@ -84,12 +84,16 @@ interface ExtendedNativeTouchEvent extends NativeTouchEvent {
84
84
  _stoppedEventTypes?: Set<string>
85
85
  }
86
86
 
87
+ interface GlobalEventState {
88
+ needPress: boolean
89
+ identifier: null | number
90
+ }
91
+
87
92
  export {
88
93
  NativeTouchEvent,
89
94
  Props,
90
95
  AdditionalProps,
91
96
  RemoveProps,
92
- UseInnerPropsConfig,
93
97
  InnerRef,
94
98
  LayoutRef,
95
99
  PropsRef,
@@ -98,5 +102,6 @@ export {
98
102
  ExtendedNativeTouchEvent,
99
103
  EventConfig,
100
104
  RawConfig,
101
- EventType
105
+ EventType,
106
+ GlobalEventState
102
107
  }
@@ -56,6 +56,20 @@
56
56
  if (val !== -1) this.setSelectionRange(undefined, val)
57
57
  },
58
58
  immediate: true
59
+ },
60
+ focus: {
61
+ handler (val) {
62
+ if (val) {
63
+ this.$nextTick(() => {
64
+ this.$refs.input.focus()
65
+ })
66
+ } else {
67
+ this.$nextTick(() => {
68
+ this.$refs.input.blur()
69
+ })
70
+ }
71
+ },
72
+ immediate: true
59
73
  }
60
74
  },
61
75
  render (createElement) {