@mpxjs/webpack-plugin 2.9.69-beta.0 → 2.9.69-beta.10
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/config.js +3 -1
- package/lib/index.js +17 -1
- package/lib/platform/style/wx/index.js +18 -18
- package/lib/platform/template/wx/component-config/movable-view.js +8 -1
- package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
- package/lib/platform/template/wx/index.js +3 -1
- package/lib/react/processScript.js +6 -4
- package/lib/resolver/AddEnvPlugin.js +1 -0
- package/lib/resolver/AddModePlugin.js +1 -0
- package/lib/runtime/components/react/context.ts +25 -0
- package/lib/runtime/components/react/dist/context.js +4 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +5 -6
- package/lib/runtime/components/react/dist/locale-provider.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
- package/lib/runtime/components/react/dist/mpx-image.jsx +13 -9
- package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +2 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +72 -57
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-portal/portal-consumer.jsx +23 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +93 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +40 -0
- package/lib/runtime/components/react/dist/mpx-portal.jsx +13 -0
- package/lib/runtime/components/react/dist/mpx-provider.jsx +31 -0
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +18 -9
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +31 -8
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +437 -372
- package/lib/runtime/components/react/dist/mpx-view.jsx +18 -53
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +163 -49
- package/lib/runtime/components/react/dist/pickerFaces.js +3 -8
- package/lib/runtime/components/react/dist/useAnimationHooks.js +31 -14
- package/lib/runtime/components/react/dist/utils.jsx +120 -4
- package/lib/runtime/components/react/getInnerListeners.ts +5 -7
- package/lib/runtime/components/react/locale-provider.tsx +83 -0
- package/lib/runtime/components/react/mpx-button.tsx +20 -57
- package/lib/runtime/components/react/mpx-image.tsx +41 -25
- package/lib/runtime/components/react/mpx-input.tsx +1 -1
- package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker/time.tsx +2 -1
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +196 -163
- package/lib/runtime/components/react/mpx-picker-view.tsx +35 -37
- package/lib/runtime/components/react/mpx-portal/portal-consumer.tsx +32 -0
- package/lib/runtime/components/react/mpx-portal/portal-host.tsx +127 -0
- package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +64 -0
- package/lib/runtime/components/react/mpx-portal.tsx +30 -0
- package/lib/runtime/components/react/mpx-provider.tsx +51 -0
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +12 -18
- package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
- package/lib/runtime/components/react/mpx-scroll-view.tsx +29 -18
- package/lib/runtime/components/react/mpx-swiper-item.tsx +45 -11
- package/lib/runtime/components/react/mpx-swiper.tsx +743 -0
- package/lib/runtime/components/react/mpx-view.tsx +22 -65
- package/lib/runtime/components/react/mpx-web-view.tsx +199 -47
- package/lib/runtime/components/react/pickerFaces.ts +10 -7
- package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
- package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
- package/lib/runtime/components/react/{pickerOverlay.tsx → pickerViewOverlay.tsx} +5 -3
- package/lib/runtime/components/react/types/global.d.ts +10 -1
- package/lib/runtime/components/react/useAnimationHooks.ts +35 -15
- package/lib/runtime/components/react/utils.tsx +139 -5
- package/lib/style-compiler/index.js +3 -4
- package/lib/style-compiler/strip-conditional-loader.js +118 -0
- package/lib/template-compiler/compiler.js +10 -15
- package/lib/utils/pre-process-json.js +5 -9
- package/lib/wxss/loader.js +15 -2
- package/package.json +1 -1
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
- package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
- package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
WithTimingConfig,
|
|
14
14
|
AnimationCallback
|
|
15
15
|
} from 'react-native-reanimated'
|
|
16
|
+
import { error } from '@mpxjs/utils'
|
|
16
17
|
import { ExtendedViewStyle } from './types/common'
|
|
17
18
|
import type { _ViewProps } from './mpx-view'
|
|
18
19
|
|
|
@@ -39,10 +40,10 @@ export type AnimationProp = {
|
|
|
39
40
|
// 微信 timingFunction 和 RN Easing 对应关系
|
|
40
41
|
const EasingKey = {
|
|
41
42
|
linear: Easing.linear,
|
|
42
|
-
ease: Easing.ease,
|
|
43
|
-
'ease-in': Easing.in(Easing.
|
|
44
|
-
'ease-in-out': Easing.inOut(Easing.
|
|
45
|
-
'ease-out': Easing.out(Easing.
|
|
43
|
+
ease: Easing.inOut(Easing.ease),
|
|
44
|
+
'ease-in': Easing.in(Easing.poly(3)),
|
|
45
|
+
'ease-in-out': Easing.inOut(Easing.poly(3)),
|
|
46
|
+
'ease-out': Easing.out(Easing.poly(3))
|
|
46
47
|
// 'step-start': '',
|
|
47
48
|
// 'step-end': ''
|
|
48
49
|
}
|
|
@@ -110,7 +111,7 @@ const parseTransform = (transformStr: string) => {
|
|
|
110
111
|
const values = parseValues(transformStr)
|
|
111
112
|
const transform: {[propName: string]: string|number|number[]}[] = []
|
|
112
113
|
values.forEach(item => {
|
|
113
|
-
const match = item.match(/([/\w]+)\((
|
|
114
|
+
const match = item.match(/([/\w]+)\((.+)\)/)
|
|
114
115
|
if (match && match.length >= 3) {
|
|
115
116
|
let key = match[1]
|
|
116
117
|
const val = match[2]
|
|
@@ -166,20 +167,32 @@ const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
|
|
|
166
167
|
})
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
170
|
-
const { style = {}, animation } = props
|
|
170
|
+
export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean }) {
|
|
171
|
+
const { style = {}, animation, enableAnimation } = props
|
|
172
|
+
|
|
173
|
+
const enableStyleAnimation = enableAnimation || !!animation
|
|
174
|
+
const enableAnimationRef = useRef(enableStyleAnimation)
|
|
175
|
+
if (enableAnimationRef.current !== enableStyleAnimation) {
|
|
176
|
+
error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!enableAnimationRef.current) return { enableStyleAnimation: false }
|
|
180
|
+
|
|
171
181
|
const originalStyle = formatStyle(style)
|
|
172
182
|
// id 标识
|
|
173
183
|
const id = animation?.id || -1
|
|
174
184
|
// 有动画样式的 style key
|
|
185
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
175
186
|
const animatedStyleKeys = useSharedValue([] as (string|string[])[])
|
|
176
187
|
// 记录动画key的style样式值 没有的话设置为false
|
|
188
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
177
189
|
const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean})
|
|
178
190
|
// const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
|
|
179
191
|
// ** 全量 style prop sharedValue
|
|
180
192
|
// 不能做增量的原因:
|
|
181
193
|
// 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
|
|
182
194
|
// 2 尝试用 useSharedValue,因为实际触发的 style prop 需要是 sharedValue 才能驱动动画,若外层 shareValMap 也是 sharedValue,动画无法驱动。
|
|
195
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
183
196
|
const shareValMap = useMemo(() => {
|
|
184
197
|
return Object.keys(InitialValue).reduce((valMap, key) => {
|
|
185
198
|
const defaultVal = getInitialVal(key, isTransform(key))
|
|
@@ -188,6 +201,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
188
201
|
}, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
|
|
189
202
|
}, [])
|
|
190
203
|
// ** 获取动画样式prop & 驱动动画
|
|
204
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
191
205
|
useEffect(() => {
|
|
192
206
|
if (id === -1) return
|
|
193
207
|
// 更新动画样式 key map
|
|
@@ -208,6 +222,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
208
222
|
// })
|
|
209
223
|
// }, [style])
|
|
210
224
|
// ** 清空动画
|
|
225
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
211
226
|
useEffect(() => {
|
|
212
227
|
return () => {
|
|
213
228
|
Object.values(shareValMap).forEach((value) => {
|
|
@@ -240,14 +255,13 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
240
255
|
}
|
|
241
256
|
// 添加每个key的多次step动画
|
|
242
257
|
animatedKeys.forEach(key => {
|
|
258
|
+
const ruleV = isTransform(key) ? transform.get(key) : rules.get(key)
|
|
243
259
|
// key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
|
|
244
|
-
const toVal =
|
|
245
|
-
?
|
|
246
|
-
:
|
|
247
|
-
?
|
|
248
|
-
:
|
|
249
|
-
? lastValueMap[key]
|
|
250
|
-
: shareValMap[key].value
|
|
260
|
+
const toVal = ruleV !== undefined
|
|
261
|
+
? ruleV
|
|
262
|
+
: index > 0
|
|
263
|
+
? lastValueMap[key]
|
|
264
|
+
: shareValMap[key].value
|
|
251
265
|
const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
|
|
252
266
|
needSetCallback = false
|
|
253
267
|
if (!sequence[key]) {
|
|
@@ -336,7 +350,8 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
336
350
|
}, {} as { [propName: string]: string | number })
|
|
337
351
|
}
|
|
338
352
|
// ** 生成动画样式
|
|
339
|
-
|
|
353
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
354
|
+
const animationStyle = useAnimatedStyle(() => {
|
|
340
355
|
// console.info(`useAnimatedStyle styles=`, originalStyle)
|
|
341
356
|
return animatedStyleKeys.value.reduce((styles, key) => {
|
|
342
357
|
// console.info('getAnimationStyles', key, shareValMap[key].value)
|
|
@@ -354,4 +369,9 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
354
369
|
return styles
|
|
355
370
|
}, {} as ExtendedViewStyle)
|
|
356
371
|
})
|
|
372
|
+
|
|
373
|
+
return {
|
|
374
|
+
enableStyleAnimation: enableAnimationRef.current,
|
|
375
|
+
animationStyle
|
|
376
|
+
}
|
|
357
377
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
|
|
2
|
-
import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
|
|
2
|
+
import { LayoutChangeEvent, TextStyle, ImageProps, Image, Platform } from 'react-native'
|
|
3
3
|
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
|
|
4
|
-
import { VarContext } from './context'
|
|
4
|
+
import { VarContext, ScrollViewContext } from './context'
|
|
5
5
|
import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
|
|
6
6
|
import { initialWindowMetrics } from 'react-native-safe-area-context'
|
|
7
7
|
import FastImage, { FastImageProps } from '@d11/react-native-fast-image'
|
|
8
|
-
import type { AnyFunc, ExtendedFunctionComponent } from './types/common'
|
|
8
|
+
import type { AnyFunc, ExtendedFunctionComponent, ExtendedViewStyle } from './types/common'
|
|
9
|
+
import { runOnJS } from 'react-native-reanimated'
|
|
10
|
+
import { Gesture } from 'react-native-gesture-handler'
|
|
9
11
|
|
|
10
12
|
export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
|
|
11
13
|
export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
|
|
@@ -18,6 +20,9 @@ export const HIDDEN_STYLE = {
|
|
|
18
20
|
opacity: 0
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
export const isIOS = Platform.OS === 'ios'
|
|
24
|
+
export const isAndroid = Platform.OS === 'android'
|
|
25
|
+
|
|
21
26
|
const varDecRegExp = /^--.*/
|
|
22
27
|
const varUseRegExp = /var\(/
|
|
23
28
|
const calcUseRegExp = /calc\(/
|
|
@@ -497,6 +502,7 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
|
|
|
497
502
|
props.onLayout && props.onLayout(e)
|
|
498
503
|
}
|
|
499
504
|
}
|
|
505
|
+
|
|
500
506
|
return {
|
|
501
507
|
layoutRef,
|
|
502
508
|
layoutStyle,
|
|
@@ -534,13 +540,14 @@ export const debounce = <T extends AnyFunc> (
|
|
|
534
540
|
): ((...args: Parameters<T>) => void) & { clear: () => void } => {
|
|
535
541
|
let timer: any
|
|
536
542
|
const wrapper = (...args: ReadonlyArray<any>) => {
|
|
537
|
-
clearTimeout(timer)
|
|
543
|
+
timer && clearTimeout(timer)
|
|
538
544
|
timer = setTimeout(() => {
|
|
539
545
|
func(...args)
|
|
540
546
|
}, delay)
|
|
541
547
|
}
|
|
542
548
|
wrapper.clear = () => {
|
|
543
|
-
clearTimeout(timer)
|
|
549
|
+
timer && clearTimeout(timer)
|
|
550
|
+
timer = null
|
|
544
551
|
}
|
|
545
552
|
return wrapper
|
|
546
553
|
}
|
|
@@ -610,3 +617,130 @@ export function pickStyle (styleObj: Record<string, any> = {}, pickedKeys: Array
|
|
|
610
617
|
return acc
|
|
611
618
|
}, {})
|
|
612
619
|
}
|
|
620
|
+
|
|
621
|
+
export function useHoverStyle ({ hoverStyle, hoverStartTime, hoverStayTime, disabled } : { hoverStyle?: ExtendedViewStyle, hoverStartTime: number, hoverStayTime: number, disabled?: boolean }) {
|
|
622
|
+
const enableHoverStyle = !!hoverStyle
|
|
623
|
+
const enableHoverStyleRef = useRef(enableHoverStyle)
|
|
624
|
+
if (enableHoverStyleRef.current !== enableHoverStyle) {
|
|
625
|
+
throw new Error('[Mpx runtime error]: hover-class use should be stable in the component lifecycle.')
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
if (!enableHoverStyle) return { enableHoverStyle }
|
|
629
|
+
|
|
630
|
+
const gestureRef = useContext(ScrollViewContext).gestureRef
|
|
631
|
+
const [isHover, setIsHover] = useState(false)
|
|
632
|
+
const dataRef = useRef<{
|
|
633
|
+
startTimer?: ReturnType<typeof setTimeout>
|
|
634
|
+
stayTimer?: ReturnType<typeof setTimeout>
|
|
635
|
+
}>({})
|
|
636
|
+
|
|
637
|
+
useEffect(() => {
|
|
638
|
+
return () => {
|
|
639
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
640
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
641
|
+
}
|
|
642
|
+
}, [])
|
|
643
|
+
|
|
644
|
+
const setStartTimer = () => {
|
|
645
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
646
|
+
dataRef.current.startTimer = setTimeout(() => {
|
|
647
|
+
setIsHover(true)
|
|
648
|
+
}, +hoverStartTime)
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
const setStayTimer = () => {
|
|
652
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
653
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
654
|
+
dataRef.current.stayTimer = setTimeout(() => {
|
|
655
|
+
setIsHover(false)
|
|
656
|
+
}, +hoverStayTime)
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
const gesture = useMemo(() => {
|
|
660
|
+
return Gesture.Pan()
|
|
661
|
+
.onTouchesDown(() => {
|
|
662
|
+
'worklet'
|
|
663
|
+
if (disabled) return
|
|
664
|
+
runOnJS(setStartTimer)()
|
|
665
|
+
})
|
|
666
|
+
.onTouchesUp(() => {
|
|
667
|
+
'worklet'
|
|
668
|
+
if (disabled) return
|
|
669
|
+
runOnJS(setStayTimer)()
|
|
670
|
+
})
|
|
671
|
+
}, [disabled])
|
|
672
|
+
|
|
673
|
+
if (gestureRef) {
|
|
674
|
+
gesture.simultaneousWithExternalGesture(gestureRef)
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
return {
|
|
678
|
+
isHover,
|
|
679
|
+
gesture,
|
|
680
|
+
enableHoverStyle
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
export function useHover ({ enableHover, hoverStartTime, hoverStayTime, disabled } : { enableHover: boolean, hoverStartTime: number, hoverStayTime: number, disabled?: boolean }) {
|
|
685
|
+
const enableHoverRef = useRef(enableHover)
|
|
686
|
+
if (enableHoverRef.current !== enableHover) {
|
|
687
|
+
error('[Mpx runtime error]: hover-class use should be stable in the component lifecycle.')
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (!enableHoverRef.current) return { isHover: false }
|
|
691
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
692
|
+
const gestureRef = useContext(ScrollViewContext).gestureRef
|
|
693
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
694
|
+
const [isHover, setIsHover] = useState(false)
|
|
695
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
696
|
+
const dataRef = useRef<{
|
|
697
|
+
startTimer?: ReturnType<typeof setTimeout>
|
|
698
|
+
stayTimer?: ReturnType<typeof setTimeout>
|
|
699
|
+
}>({})
|
|
700
|
+
|
|
701
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
702
|
+
useEffect(() => {
|
|
703
|
+
return () => {
|
|
704
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
705
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
706
|
+
}
|
|
707
|
+
}, [])
|
|
708
|
+
|
|
709
|
+
const setStartTimer = () => {
|
|
710
|
+
if (disabled) return
|
|
711
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
712
|
+
dataRef.current.startTimer = setTimeout(() => {
|
|
713
|
+
setIsHover(true)
|
|
714
|
+
}, +hoverStartTime)
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
const setStayTimer = () => {
|
|
718
|
+
if (disabled) return
|
|
719
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
|
|
720
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
|
|
721
|
+
dataRef.current.stayTimer = setTimeout(() => {
|
|
722
|
+
setIsHover(false)
|
|
723
|
+
}, +hoverStayTime)
|
|
724
|
+
}
|
|
725
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
726
|
+
const gesture = useMemo(() => {
|
|
727
|
+
return Gesture.Pan()
|
|
728
|
+
.onTouchesDown(() => {
|
|
729
|
+
'worklet'
|
|
730
|
+
runOnJS(setStartTimer)()
|
|
731
|
+
})
|
|
732
|
+
.onTouchesUp(() => {
|
|
733
|
+
'worklet'
|
|
734
|
+
runOnJS(setStayTimer)()
|
|
735
|
+
})
|
|
736
|
+
}, [])
|
|
737
|
+
|
|
738
|
+
if (gestureRef) {
|
|
739
|
+
gesture.simultaneousWithExternalGesture(gestureRef)
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return {
|
|
743
|
+
isHover,
|
|
744
|
+
gesture
|
|
745
|
+
}
|
|
746
|
+
}
|
|
@@ -4,7 +4,6 @@ const loadPostcssConfig = require('./load-postcss-config')
|
|
|
4
4
|
const { MPX_ROOT_VIEW, MPX_DISABLE_EXTRACTOR_CACHE } = require('../utils/const')
|
|
5
5
|
const rpx = require('./plugins/rpx')
|
|
6
6
|
const vw = require('./plugins/vw')
|
|
7
|
-
const pluginCondStrip = require('./plugins/conditional-strip')
|
|
8
7
|
const scopeId = require('./plugins/scope-id')
|
|
9
8
|
const transSpecial = require('./plugins/trans-special')
|
|
10
9
|
const cssArrayList = require('./plugins/css-array-list')
|
|
@@ -58,9 +57,9 @@ module.exports = function (css, map) {
|
|
|
58
57
|
plugins.push(transSpecial({ id }))
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
plugins.push(pluginCondStrip({
|
|
62
|
-
|
|
63
|
-
}))
|
|
60
|
+
// plugins.push(pluginCondStrip({
|
|
61
|
+
// defs
|
|
62
|
+
// }))
|
|
64
63
|
|
|
65
64
|
for (const item of transRpxRules) {
|
|
66
65
|
const {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const MagicString = require('magic-string')
|
|
2
|
+
|
|
3
|
+
function cssConditionalStrip (cssContent, defs) {
|
|
4
|
+
const ms = new MagicString(cssContent)
|
|
5
|
+
|
|
6
|
+
// 正则匹配 @mpx-if, @mpx-elif, @mpx-else, @mpx-endif 的模式
|
|
7
|
+
const ifPattern = /\/\*\s*@mpx-if\s*\((.*?)\)\s*\*\//gs
|
|
8
|
+
const elifPattern = /\/\*\s*@mpx-elif\s*\((.*?)\)\s*\*\//gs
|
|
9
|
+
const elsePattern = /\/\*\s*@mpx-else\s*\*\//gs
|
|
10
|
+
const endifPattern = /\/\*\s*@mpx-endif\s*\*\//gs
|
|
11
|
+
|
|
12
|
+
function evaluateCondition (condition) {
|
|
13
|
+
// 替换变量
|
|
14
|
+
for (const key in defs) {
|
|
15
|
+
condition = condition.replace(new RegExp(`\\b${key}\\b`, 'g'), JSON.stringify(defs[key]))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 解析条件表达式
|
|
19
|
+
try {
|
|
20
|
+
// eslint-disable-next-line no-new-func
|
|
21
|
+
return Function('"use strict";return (' + condition + ')')()
|
|
22
|
+
} catch (e) {
|
|
23
|
+
throw new Error(`Failed to evaluate condition: ${condition}`)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let currentStart = 0
|
|
28
|
+
function processCondition (start, end, condition) {
|
|
29
|
+
const conditionResult = evaluateCondition(condition)
|
|
30
|
+
let hasElse = false
|
|
31
|
+
let elseStart = -1
|
|
32
|
+
let elseLen = 0
|
|
33
|
+
currentStart = end + 1
|
|
34
|
+
|
|
35
|
+
while (currentStart < ms.original.length) {
|
|
36
|
+
elsePattern.lastIndex = currentStart
|
|
37
|
+
const elseMatch = elsePattern.exec(ms.original)
|
|
38
|
+
if (elseMatch) {
|
|
39
|
+
elseLen = elseMatch[0].length
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
ifPattern.lastIndex = currentStart
|
|
43
|
+
const ifMatch = ifPattern.exec(ms.original)
|
|
44
|
+
|
|
45
|
+
elifPattern.lastIndex = currentStart
|
|
46
|
+
const elseIfMatch = elifPattern.exec(ms.original)
|
|
47
|
+
|
|
48
|
+
endifPattern.lastIndex = currentStart
|
|
49
|
+
const endifMatch = endifPattern.exec(ms.original)
|
|
50
|
+
|
|
51
|
+
const nextIf = ifMatch ? ifMatch.index : Infinity
|
|
52
|
+
const nextElseIf = elseIfMatch ? elseIfMatch.index : Infinity
|
|
53
|
+
const nextElse = elseMatch ? elseMatch.index : Infinity
|
|
54
|
+
const nextEndif = endifMatch ? endifMatch.index : Infinity
|
|
55
|
+
|
|
56
|
+
const nextMarker = Math.min(nextIf, nextElseIf, nextElse, nextEndif)
|
|
57
|
+
|
|
58
|
+
if (nextMarker === Infinity) break
|
|
59
|
+
|
|
60
|
+
if (nextMarker === nextElse) {
|
|
61
|
+
// 处理 @mpx-else
|
|
62
|
+
hasElse = true
|
|
63
|
+
elseStart = nextElse
|
|
64
|
+
currentStart = elseMatch.index + elseLen
|
|
65
|
+
ms.remove(elseStart, elseStart + elseLen) // 移除 @mpx-else 注释
|
|
66
|
+
} else if (nextMarker === nextElseIf) {
|
|
67
|
+
// 处理 @mpx-elif
|
|
68
|
+
if (!conditionResult) {
|
|
69
|
+
// 前边的if为false,则直接移除前边代码
|
|
70
|
+
ms.remove(start, nextElseIf)
|
|
71
|
+
}
|
|
72
|
+
currentStart = nextElseIf + elseIfMatch[0].length
|
|
73
|
+
ms.remove(nextElseIf, nextElseIf + elseIfMatch[0].length) // 移除 @mpx-elif 注释
|
|
74
|
+
processCondition(nextElseIf, nextElseIf + elseIfMatch[0].length, elseIfMatch[1])
|
|
75
|
+
} else if (nextMarker === nextIf) {
|
|
76
|
+
// 处理嵌套的 @mpx-if
|
|
77
|
+
// 如果遇到了新的 @mpx-if,则递归处理
|
|
78
|
+
currentStart = nextIf + ifMatch[0].length
|
|
79
|
+
ms.remove(nextIf, nextIf + ifMatch[0].length) // 移除 @mpx-if 注释
|
|
80
|
+
processCondition(nextIf, nextIf + ifMatch[0].length, ifMatch[1])
|
|
81
|
+
} else if (nextMarker === nextEndif) {
|
|
82
|
+
// 处理 @mpx-endif block块
|
|
83
|
+
if (conditionResult && hasElse) {
|
|
84
|
+
// 移除 @mpx-else 至 @mpx-endif 代码
|
|
85
|
+
ms.remove(elseStart, endifMatch.index + endifMatch[0].length)
|
|
86
|
+
} else if (!conditionResult && hasElse) {
|
|
87
|
+
ms.remove(start, elseStart + elseLen)
|
|
88
|
+
} else if (!conditionResult) {
|
|
89
|
+
ms.remove(start, endifMatch.index + endifMatch[0].length)
|
|
90
|
+
}
|
|
91
|
+
ms.remove(endifMatch.index, endifMatch.index + endifMatch[0].length) // 移除 @mpx-endif 注释
|
|
92
|
+
currentStart = endifMatch.index + endifMatch[0].length
|
|
93
|
+
break
|
|
94
|
+
}
|
|
95
|
+
// 兜底更新当前开始位置
|
|
96
|
+
if (currentStart < nextMarker) {
|
|
97
|
+
currentStart = nextMarker + 1
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let match
|
|
103
|
+
while ((match = ifPattern.exec(ms.original)) !== null) {
|
|
104
|
+
processCondition(match.index, ifPattern.lastIndex, match[1])
|
|
105
|
+
// 移除匹配到的 @mpx-if 注释
|
|
106
|
+
ms.remove(match.index, match.index + match[0].length)
|
|
107
|
+
ifPattern.lastIndex = currentStart
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return ms.toString()
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = function (css) {
|
|
114
|
+
this.cacheable()
|
|
115
|
+
const mpx = this.getMpx()
|
|
116
|
+
const defs = mpx.defs
|
|
117
|
+
return cssConditionalStrip(css, defs)
|
|
118
|
+
}
|
|
@@ -117,7 +117,6 @@ let hasOptionalChaining = false
|
|
|
117
117
|
let processingTemplate = false
|
|
118
118
|
const rulesResultMap = new Map()
|
|
119
119
|
let usingComponents = []
|
|
120
|
-
let usingComponentsInfo = {}
|
|
121
120
|
|
|
122
121
|
function updateForScopesMap () {
|
|
123
122
|
forScopesMap = {}
|
|
@@ -637,7 +636,6 @@ function parse (template, options) {
|
|
|
637
636
|
|
|
638
637
|
if (typeof options.usingComponentsInfo === 'string') options.usingComponentsInfo = JSON.parse(options.usingComponentsInfo)
|
|
639
638
|
usingComponents = Object.keys(options.usingComponentsInfo)
|
|
640
|
-
usingComponentsInfo = options.usingComponentsInfo
|
|
641
639
|
|
|
642
640
|
const _warn = content => {
|
|
643
641
|
const currentElementRuleResult = rulesResultMap.get(currentEl) || rulesResultMap.set(currentEl, {
|
|
@@ -1209,7 +1207,7 @@ function processEventReact (el) {
|
|
|
1209
1207
|
for (const type in eventConfigMap) {
|
|
1210
1208
|
const { configs } = eventConfigMap[type]
|
|
1211
1209
|
if (!configs.length) continue
|
|
1212
|
-
const needBind = configs.length > 1 || configs[0].hasArgs
|
|
1210
|
+
const needBind = configs.length > 1 || configs[0].hasArgs || tagRE.test(configs[0].value)
|
|
1213
1211
|
if (needBind) {
|
|
1214
1212
|
configs.forEach(({ name }) => {
|
|
1215
1213
|
if (name) {
|
|
@@ -1773,7 +1771,7 @@ function processRefReact (el, meta) {
|
|
|
1773
1771
|
const selectorsConf = selectors.map(item => `["${item.prefix}", ${item.selector}]`)
|
|
1774
1772
|
addAttrs(el, [{
|
|
1775
1773
|
name: 'ref',
|
|
1776
|
-
value: `{{ this.__getRefVal('${type}', [${selectorsConf}]) }}`
|
|
1774
|
+
value: `{{ this.__getRefVal('${type}', [${selectorsConf}], 'ref_fn_${++refId}') }}`
|
|
1777
1775
|
}])
|
|
1778
1776
|
}
|
|
1779
1777
|
|
|
@@ -2187,20 +2185,16 @@ function isRealNode (el) {
|
|
|
2187
2185
|
return !virtualNodeTagMap[el.tag]
|
|
2188
2186
|
}
|
|
2189
2187
|
|
|
2190
|
-
function isComponentNode (el) {
|
|
2188
|
+
function isComponentNode (el, options) {
|
|
2191
2189
|
return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component'
|
|
2192
2190
|
}
|
|
2193
2191
|
|
|
2194
|
-
function
|
|
2195
|
-
return
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
|
-
function isReactComponent (el) {
|
|
2199
|
-
return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn
|
|
2192
|
+
function isReactComponent (el, options) {
|
|
2193
|
+
return !isComponentNode(el, options) && isRealNode(el) && !el.isBuiltIn
|
|
2200
2194
|
}
|
|
2201
2195
|
|
|
2202
2196
|
function processExternalClasses (el, options) {
|
|
2203
|
-
const isComponent = isComponentNode(el)
|
|
2197
|
+
const isComponent = isComponentNode(el, options)
|
|
2204
2198
|
const classLikeAttrNames = isComponent ? ['class'].concat(options.externalClasses) : ['class']
|
|
2205
2199
|
|
|
2206
2200
|
classLikeAttrNames.forEach((classLikeAttrName) => {
|
|
@@ -2314,7 +2308,8 @@ function postProcessAliComponentRootView (el, options, meta) {
|
|
|
2314
2308
|
{ condition: /^style$/, action: 'move' },
|
|
2315
2309
|
{ condition: /^slot$/, action: 'move' }
|
|
2316
2310
|
]
|
|
2317
|
-
const
|
|
2311
|
+
const tagName = el.tag
|
|
2312
|
+
const mid = options.usingComponentsInfo[tagName]?.mid || moduleId
|
|
2318
2313
|
const processAppendAttrsRules = [
|
|
2319
2314
|
{ name: 'class', value: `${MPX_ROOT_VIEW} host-${mid}` }
|
|
2320
2315
|
]
|
|
@@ -2421,7 +2416,7 @@ function processShow (el, options, root) {
|
|
|
2421
2416
|
show = has ? `{{${parseMustacheWithContext(show).result}&&mpxShow}}` : '{{mpxShow}}'
|
|
2422
2417
|
}
|
|
2423
2418
|
if (show === undefined) return
|
|
2424
|
-
if (isComponentNode(el
|
|
2419
|
+
if (isComponentNode(el, options)) {
|
|
2425
2420
|
if (show === '') {
|
|
2426
2421
|
show = '{{false}}'
|
|
2427
2422
|
}
|
|
@@ -2720,7 +2715,7 @@ function closeElement (el, options, meta) {
|
|
|
2720
2715
|
}
|
|
2721
2716
|
})
|
|
2722
2717
|
}
|
|
2723
|
-
if (isComponentNode(el) && !hasVirtualHost && mode === 'ali' && el.tag !== 'component') {
|
|
2718
|
+
if (isComponentNode(el, options) && !hasVirtualHost && mode === 'ali' && el.tag !== 'component') {
|
|
2724
2719
|
postProcessAliComponentRootView(el, options, meta)
|
|
2725
2720
|
}
|
|
2726
2721
|
}
|
|
@@ -6,7 +6,6 @@ const addQuery = require('./add-query')
|
|
|
6
6
|
const resolve = require('./resolve')
|
|
7
7
|
const getJSONContent = require('./get-json-content')
|
|
8
8
|
const getRulesRunner = require('../platform')
|
|
9
|
-
const { matchCondition } = require('./match-condition')
|
|
10
9
|
const async = require('async')
|
|
11
10
|
|
|
12
11
|
module.exports = function ({
|
|
@@ -20,7 +19,8 @@ module.exports = function ({
|
|
|
20
19
|
}, callback) {
|
|
21
20
|
const mpx = loaderContext.getMpx()
|
|
22
21
|
const context = loaderContext.context
|
|
23
|
-
const
|
|
22
|
+
const mode = mpx.mode
|
|
23
|
+
const pagesMap = mpx.pagesMap
|
|
24
24
|
async.waterfall([
|
|
25
25
|
(callback) => {
|
|
26
26
|
getJSONContent(json, null, loaderContext, callback)
|
|
@@ -78,8 +78,8 @@ module.exports = function ({
|
|
|
78
78
|
componentGenerics = Object.assign({}, ret.componentGenerics)
|
|
79
79
|
}
|
|
80
80
|
if (usingComponents) {
|
|
81
|
-
const setUsingComponentInfo = (name,
|
|
82
|
-
usingComponentsInfo[name] =
|
|
81
|
+
const setUsingComponentInfo = (name, moduleId) => {
|
|
82
|
+
usingComponentsInfo[name] = { mid: moduleId }
|
|
83
83
|
}
|
|
84
84
|
async.eachOf(usingComponents, (component, name, callback) => {
|
|
85
85
|
if (ctorType === 'app') {
|
|
@@ -96,11 +96,7 @@ module.exports = function ({
|
|
|
96
96
|
if (err) return callback(err)
|
|
97
97
|
const { rawResourcePath } = parseRequest(resource)
|
|
98
98
|
const moduleId = mpx.getModuleId(rawResourcePath, ctorType === 'app')
|
|
99
|
-
|
|
100
|
-
setUsingComponentInfo(name, {
|
|
101
|
-
mid: moduleId,
|
|
102
|
-
hasVirtualHost
|
|
103
|
-
})
|
|
99
|
+
setUsingComponentInfo(name, moduleId)
|
|
104
100
|
callback()
|
|
105
101
|
})
|
|
106
102
|
}, (err) => {
|
package/lib/wxss/loader.js
CHANGED
|
@@ -32,6 +32,13 @@ const {
|
|
|
32
32
|
} = require('./utils')
|
|
33
33
|
const createHelpers = require('../helpers')
|
|
34
34
|
|
|
35
|
+
const RN_PRESET_OPTIMISATION = {
|
|
36
|
+
reduceInitial: false,
|
|
37
|
+
normalizeWhitespace: false,
|
|
38
|
+
minifyFontValues: false,
|
|
39
|
+
convertValues: false
|
|
40
|
+
}
|
|
41
|
+
|
|
35
42
|
module.exports = async function loader (content, map, meta) {
|
|
36
43
|
const rawOptions = this.getOptions(schema)
|
|
37
44
|
const plugins = []
|
|
@@ -41,6 +48,7 @@ module.exports = async function loader (content, map, meta) {
|
|
|
41
48
|
const externals = mpx.externals
|
|
42
49
|
const root = mpx.projectRoot
|
|
43
50
|
const sourceMap = mpx.cssSourceMap || false
|
|
51
|
+
const isRN = ['ios', 'android', 'harmony'].includes(mpx.mode)
|
|
44
52
|
|
|
45
53
|
let options
|
|
46
54
|
|
|
@@ -152,12 +160,17 @@ module.exports = async function loader (content, map, meta) {
|
|
|
152
160
|
if (this.minimize) {
|
|
153
161
|
const cssnano = require('cssnano')
|
|
154
162
|
const minimizeOptions = rawOptions.minimize || {}
|
|
163
|
+
const presetOptimisation = Object.assign(
|
|
164
|
+
{},
|
|
165
|
+
isRN ? RN_PRESET_OPTIMISATION : {},
|
|
166
|
+
minimizeOptions.optimisation
|
|
167
|
+
)
|
|
155
168
|
let cssnanoConfig = {
|
|
156
|
-
preset: ['cssnano-preset-default',
|
|
169
|
+
preset: ['cssnano-preset-default', presetOptimisation]
|
|
157
170
|
}
|
|
158
171
|
if (minimizeOptions.advanced) {
|
|
159
172
|
cssnanoConfig = {
|
|
160
|
-
preset: ['cssnano-preset-advanced',
|
|
173
|
+
preset: ['cssnano-preset-advanced', presetOptimisation]
|
|
161
174
|
}
|
|
162
175
|
}
|
|
163
176
|
plugins.push(cssnano(cssnanoConfig))
|