@mpxjs/webpack-plugin 2.10.15 → 2.10.16
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/lib/dependencies/DynamicEntryDependency.js +1 -1
- package/lib/dependencies/ImportDependency.js +102 -0
- package/lib/{retry-runtime-module.js → dependencies/RetryRuntimeModule.js} +1 -1
- package/lib/index.js +11 -10
- package/lib/platform/template/wx/component-config/slider.js +12 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -1
- package/lib/resolver/AddEnvPlugin.js +13 -0
- package/lib/resolver/AddModePlugin.js +18 -0
- package/lib/runtime/components/react/dist/mpx-progress.jsx +26 -22
- package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
- package/lib/runtime/components/react/dist/mpx-view.jsx +7 -10
- package/lib/runtime/components/react/mpx-progress.tsx +26 -24
- package/lib/runtime/components/react/mpx-slider.tsx +444 -0
- package/lib/runtime/components/react/mpx-view.tsx +7 -10
- package/lib/runtime/components/web/mpx-input.vue +1 -1
- package/lib/runtime/components/web/mpx-scroll-view.vue +7 -1
- package/lib/runtime/components/web/mpx-video.vue +12 -1
- package/lib/runtime/optionProcessor.js +3 -1
- package/lib/runtime/optionProcessorReact.js +4 -2
- package/lib/template-compiler/compiler.js +10 -6
- package/lib/utils/chain-assign.js +47 -0
- package/lib/utils/check-core-version-match.js +75 -15
- package/lib/wxs/pre-loader.js +5 -5
- package/package.json +5 -4
- 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
|
|
@@ -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
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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,
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
import { processSize } from '../../utils'
|
|
5
5
|
import BScroll from '@better-scroll/core'
|
|
6
6
|
import PullDown from '@better-scroll/pull-down'
|
|
7
|
+
import MouseWheel from '@better-scroll/mouse-wheel'
|
|
7
8
|
import throttle from 'lodash/throttle'
|
|
8
9
|
import debounce from 'lodash/debounce'
|
|
9
10
|
|
|
10
11
|
BScroll.use(PullDown)
|
|
12
|
+
BScroll.use(MouseWheel)
|
|
11
13
|
|
|
12
14
|
let mutationObserver = null
|
|
13
15
|
let resizeObserver = null
|
|
@@ -222,7 +224,11 @@
|
|
|
222
224
|
bounce: false,
|
|
223
225
|
stopPropagation: true,
|
|
224
226
|
bindToWrapper: true,
|
|
225
|
-
eventPassthrough: (this.scrollX && 'vertical') || (this.scrollY && 'horizontal') || ''
|
|
227
|
+
eventPassthrough: (this.scrollX && 'vertical') || (this.scrollY && 'horizontal') || '',
|
|
228
|
+
mouseWheel: {
|
|
229
|
+
speed: 20,
|
|
230
|
+
easeTime: 300
|
|
231
|
+
}
|
|
226
232
|
}
|
|
227
233
|
if (this.refresherEnabled) {
|
|
228
234
|
originBsOptions.bounce = true
|
|
@@ -148,6 +148,11 @@
|
|
|
148
148
|
},
|
|
149
149
|
controls: function (show) {
|
|
150
150
|
this.$emit('controlstoggle', inheritEvent('controlstoggle', {}, { show }))
|
|
151
|
+
},
|
|
152
|
+
objectFit (val) {
|
|
153
|
+
if (this._player && this._player.video) {
|
|
154
|
+
this._player.video.style.objectFit = val
|
|
155
|
+
}
|
|
151
156
|
}
|
|
152
157
|
},
|
|
153
158
|
mounted () {
|
|
@@ -189,6 +194,9 @@
|
|
|
189
194
|
if (this.initialTime) {
|
|
190
195
|
this._player.seek(this.initialTime)
|
|
191
196
|
}
|
|
197
|
+
if (this.objectFit) {
|
|
198
|
+
this._player.video.style.objectFit = this.objectFit
|
|
199
|
+
}
|
|
192
200
|
},
|
|
193
201
|
initStyle () {
|
|
194
202
|
|
|
@@ -239,7 +247,10 @@
|
|
|
239
247
|
|
|
240
248
|
this._player.on('progress', (e) => {
|
|
241
249
|
const eNode = e.target
|
|
242
|
-
|
|
250
|
+
let buffered = 0
|
|
251
|
+
if (eNode?.buffered && eNode.buffered.length > 0) {
|
|
252
|
+
buffered = (eNode.buffered.end(0)) / (eNode?.duration)
|
|
253
|
+
}
|
|
243
254
|
this.$emit('progress', inheritEvent('progress', e, { buffered: buffered * 100 }))
|
|
244
255
|
})
|
|
245
256
|
|
|
@@ -108,7 +108,9 @@ registered in parent context!`)
|
|
|
108
108
|
export function getComponent (component, extendOptions) {
|
|
109
109
|
component = component.__esModule ? component.default : component
|
|
110
110
|
// eslint-disable-next-line
|
|
111
|
-
if (extendOptions
|
|
111
|
+
if (extendOptions && !component.__mpxExtended) {
|
|
112
|
+
extend(component, extendOptions, { __mpxExtended: true })
|
|
113
|
+
}
|
|
112
114
|
return component
|
|
113
115
|
}
|
|
114
116
|
|
|
@@ -5,7 +5,9 @@ import { extend } from './utils'
|
|
|
5
5
|
export function getComponent (component, extendOptions) {
|
|
6
6
|
component = component.__esModule ? component.default : component
|
|
7
7
|
// eslint-disable-next-line
|
|
8
|
-
if (extendOptions
|
|
8
|
+
if (extendOptions && !component.__mpxExtended) {
|
|
9
|
+
extend(component, extendOptions, { __mpxExtended: true })
|
|
10
|
+
}
|
|
9
11
|
return component
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -15,7 +17,7 @@ export function getAsyncSuspense (commonProps) {
|
|
|
15
17
|
result = memo(forwardRef(function (props, ref) {
|
|
16
18
|
return createElement(AsyncSuspense,
|
|
17
19
|
extend({}, commonProps, {
|
|
18
|
-
innerProps:
|
|
20
|
+
innerProps: extend({}, props, { ref })
|
|
19
21
|
})
|
|
20
22
|
)
|
|
21
23
|
}))
|
|
@@ -176,11 +176,11 @@ const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
|
|
|
176
176
|
const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
|
|
177
177
|
// 添加~前缀避免wxs绝对路径在存在projectRoot时被拼接为错误路径
|
|
178
178
|
const i18nWxsRequest = '~' + i18nWxsLoaderPath + '!' + i18nWxsPath
|
|
179
|
-
const i18nModuleName = '
|
|
179
|
+
const i18nModuleName = '_i_'
|
|
180
180
|
const stringifyWxsPath = '~' + normalize.lib('runtime/stringify.wxs')
|
|
181
|
-
const stringifyModuleName = '
|
|
181
|
+
const stringifyModuleName = '_s_'
|
|
182
182
|
const optionalChainWxsPath = '~' + normalize.lib('runtime/oc.wxs')
|
|
183
|
-
const optionalChainWxsName = '
|
|
183
|
+
const optionalChainWxsName = '_oc_' // 改成_oc解决web下_o重名问题
|
|
184
184
|
|
|
185
185
|
const tagRES = /(\{\{(?:.|\n|\r)+?\}\})(?!})/
|
|
186
186
|
const tagRE = /\{\{((?:.|\n|\r)+?)\}\}(?!})/
|
|
@@ -1383,7 +1383,11 @@ function processEvent (el, options) {
|
|
|
1383
1383
|
const targetConfigs = isCapture ? eventConfigMap[type].captureConfigs : eventConfigMap[type].configs
|
|
1384
1384
|
targetConfigs.push(Object.assign({ name }, parsedFunc))
|
|
1385
1385
|
if (modifiers.indexOf('proxy') > -1 || options.forceProxyEvent) {
|
|
1386
|
-
|
|
1386
|
+
if (isCapture) {
|
|
1387
|
+
eventConfigMap[type].captureProxy = true
|
|
1388
|
+
} else {
|
|
1389
|
+
eventConfigMap[type].proxy = true
|
|
1390
|
+
}
|
|
1387
1391
|
}
|
|
1388
1392
|
}
|
|
1389
1393
|
}
|
|
@@ -1423,10 +1427,10 @@ function processEvent (el, options) {
|
|
|
1423
1427
|
}
|
|
1424
1428
|
|
|
1425
1429
|
for (const type in eventConfigMap) {
|
|
1426
|
-
const { configs = [], captureConfigs = [], proxy } = eventConfigMap[type]
|
|
1430
|
+
const { configs = [], captureConfigs = [], proxy, captureProxy } = eventConfigMap[type]
|
|
1427
1431
|
|
|
1428
1432
|
let needBubblingBind = isNeedBind(configs, proxy)
|
|
1429
|
-
let needCaptureBind = isNeedBind(captureConfigs,
|
|
1433
|
+
let needCaptureBind = isNeedBind(captureConfigs, captureProxy)
|
|
1430
1434
|
|
|
1431
1435
|
const escapedType = dash2hump(type)
|
|
1432
1436
|
// 排除特殊情况
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 链式合并方法的工具函数
|
|
3
|
+
*
|
|
4
|
+
* 在多条件分支下使用 Object.assign 会导致同名方法被覆盖,
|
|
5
|
+
* 这个函数通过创建组合函数来确保所有方法都能按顺序执行。
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} target - 目标 visitor 对象
|
|
8
|
+
* @param {Object} source - 要链式分配的 visitor 方法对象
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const visitor = {}
|
|
12
|
+
*
|
|
13
|
+
* // 第一次合并
|
|
14
|
+
* chainAssign(visitor, {
|
|
15
|
+
* CallExpression(path) {
|
|
16
|
+
* console.log('第一个处理器')
|
|
17
|
+
* }
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* // 第二次合并 - 不会覆盖,而是组合执行
|
|
21
|
+
* chainAssign(visitor, {
|
|
22
|
+
* CallExpression(path) {
|
|
23
|
+
* console.log('第二个处理器')
|
|
24
|
+
* }
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* // 执行时会依次输出:
|
|
28
|
+
* // 第一个处理器
|
|
29
|
+
* // 第二个处理器
|
|
30
|
+
*/
|
|
31
|
+
module.exports = function chainAssign (target, source) {
|
|
32
|
+
for (const [key, value] of Object.entries(source)) {
|
|
33
|
+
if (target[key]) {
|
|
34
|
+
// 如果已存在同名方法,创建组合函数依次执行
|
|
35
|
+
const originalMethod = target[key]
|
|
36
|
+
target[key] = function (path) {
|
|
37
|
+
originalMethod.call(this, path)
|
|
38
|
+
// 只有当节点没有停止遍历或被移除时才继续执行
|
|
39
|
+
if (!path.removed && !path.shouldStop) {
|
|
40
|
+
value.call(this, path)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
target[key] = value
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|