From 9a856b2a22a0dfa088ab92e5f51d52b68c8c2b8e Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Mon, 25 Nov 2024 14:42:08 +0800 Subject: [PATCH 01/45] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 58 +++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 8a212a432b..93a2ff353c 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -53,6 +53,10 @@ interface MovableViewProps { bindvtouchmove?: (event: NativeSyntheticEvent) => void; catchhtouchmove?: (event: NativeSyntheticEvent) => void; catchvtouchmove?: (event: NativeSyntheticEvent) => void; + bindlongpress?: (event: NativeSyntheticEvent) => void; + catchlongpress?: (event: NativeSyntheticEvent) => void; + bindtap?: (event: NativeSyntheticEvent) => void; + catchtap?: (event: NativeSyntheticEvent) => void; onLayout?: (event: LayoutChangeEvent) => void; 'out-of-bounds'?: boolean; 'wait-for'?: Array; @@ -108,7 +112,11 @@ const _MovableView = forwardRef, MovableViewP catchvtouchmove, catchtouchmove, bindtouchend, - catchtouchend + catchtouchend, + bindlongpress, + catchlongpress, + bindtap, + catchtap } = props const { @@ -139,6 +147,8 @@ const _MovableView = forwardRef, MovableViewP const yInertialMotion = useSharedValue(false) const isFirstTouch = useSharedValue(true) const touchEvent = useSharedValue('') + const startTimer = useSharedValue(null) + const needTap = useSharedValue(true) const MovableAreaLayout = useContext(MovableAreaContext) @@ -384,9 +394,38 @@ const _MovableView = forwardRef, MovableViewP bindtouchend && runOnJS(bindtouchend)(e) catchtouchend && runOnJS(catchtouchend)(e) } + + const handleTriggerPress = (e: any) => { + 'worklet' + extendEvent(e) + bindlongpress && runOnJS(bindlongpress)(e) + catchlongpress && runOnJS(catchlongpress)(e) + } + + const handleTriggerTap = (e: any) => { + 'worklet' + extendEvent(e) + bindtap && runOnJS(bindtap)(e) + catchtap && runOnJS(catchtap)(e) + } + + const checkIsNeedTap = (e: NativeTouchEvent) => { + const tapDetailInfo = startPosition.value || { x: 0, y: 0 } + const nativeEvent = e.nativeEvent + const currentPageX = nativeEvent.changedTouches[0].x + const currentPageY = nativeEvent.changedTouches[0].y + if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) { + needTap.value = false + startTimer.value && clearTimeout(startTimer.value) + startTimer.value = null + } + } + const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' + startTimer.value = null + needTap.value = true const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } isMoving.value = false startPosition.value = { @@ -394,9 +433,16 @@ const _MovableView = forwardRef, MovableViewP y: changedTouches.y } handleTriggerStart(e) + if (catchlongpress || bindlongpress) { + startTimer.value = setTimeout(() => { + needTap.value = false + handleTriggerPress(e) + }, 350) + } }) .onTouchesMove((e: GestureTouchEvent) => { 'worklet' + checkIsNeedTap(e) isMoving.value = true const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } if (isFirstTouch.value) { @@ -428,9 +474,13 @@ const _MovableView = forwardRef, MovableViewP }) .onTouchesUp((e: GestureTouchEvent) => { 'worklet' + checkIsNeedTap(e) isFirstTouch.value = true isMoving.value = false handleTriggerEnd(e) + if (needTap.value) { + handleTriggerTap(e) + } if (disabled) return if (!inertia) { const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value }) @@ -500,9 +550,9 @@ const _MovableView = forwardRef, MovableViewP const injectCatchEvent = (props: Record) => { const eventHandlers: Record = {} const catchEventList = [ - { name: 'onTouchStart', value: ['catchtouchstart'] }, - { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] }, - { name: 'onTouchEnd', value: ['catchtouchend'] } + { name: 'onTouchStart', value: ['catchtouchstart', 'catchtap', 'catchlongpress'] }, + { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove', 'catchtap', 'catchlongpress'] }, + { name: 'onTouchEnd', value: ['catchtouchend', 'catchtap', 'catchlongpress'] } ] catchEventList.forEach(event => { event.value.forEach(name => { From 7992028db1e9782bb3ce047d6e29f6abe94ce65e Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Mon, 25 Nov 2024 14:43:21 +0800 Subject: [PATCH 02/45] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/mpx-movable-view.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 93a2ff353c..2bdad7d1d9 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -409,11 +409,10 @@ const _MovableView = forwardRef, MovableViewP catchtap && runOnJS(catchtap)(e) } - const checkIsNeedTap = (e: NativeTouchEvent) => { + const checkIsNeedTap = (e: GestureTouchEvent) => { const tapDetailInfo = startPosition.value || { x: 0, y: 0 } - const nativeEvent = e.nativeEvent - const currentPageX = nativeEvent.changedTouches[0].x - const currentPageY = nativeEvent.changedTouches[0].y + const currentPageX = e.changedTouches[0].x + const currentPageY = e.changedTouches[0].y if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) { needTap.value = false startTimer.value && clearTimeout(startTimer.value) From 3f1668e617a187f7f21748349d5e2dea59747d0a Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Mon, 25 Nov 2024 19:37:41 +0800 Subject: [PATCH 03/45] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 2bdad7d1d9..7d653be7ba 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -43,20 +43,20 @@ interface MovableViewProps { disabled?: boolean; animation?: boolean; bindchange?: (event: unknown) => void; - bindtouchstart?: (event: NativeSyntheticEvent) => void; - catchtouchstart?: (event: NativeSyntheticEvent) => void; - bindtouchmove?: (event: NativeSyntheticEvent) => void; - catchtouchmove?: (event: NativeSyntheticEvent) => void; - catchtouchend?: (event: NativeSyntheticEvent) => void; - bindtouchend?: (event: NativeSyntheticEvent) => void; - bindhtouchmove?: (event: NativeSyntheticEvent) => void; - bindvtouchmove?: (event: NativeSyntheticEvent) => void; - catchhtouchmove?: (event: NativeSyntheticEvent) => void; - catchvtouchmove?: (event: NativeSyntheticEvent) => void; - bindlongpress?: (event: NativeSyntheticEvent) => void; - catchlongpress?: (event: NativeSyntheticEvent) => void; - bindtap?: (event: NativeSyntheticEvent) => void; - catchtap?: (event: NativeSyntheticEvent) => void; + bindtouchstart?: (event: GestureTouchEvent) => void; + catchtouchstart?: (event: GestureTouchEvent) => void; + bindtouchmove?: (event: GestureTouchEvent) => void; + catchtouchmove?: (event: GestureTouchEvent) => void; + catchtouchend?: (event: GestureTouchEvent) => void; + bindtouchend?: (event: GestureTouchEvent) => void; + bindhtouchmove?: (event:GestureTouchEvent) => void; + bindvtouchmove?: (event: GestureTouchEvent) => void; + catchhtouchmove?: (event: GestureTouchEvent) => void; + catchvtouchmove?: (event: GestureTouchEvent) => void; + bindlongpress?: (event: GestureTouchEvent) => void; + catchlongpress?: (event:GestureTouchEvent) => void; + bindtap?: (event: GestureTouchEvent) => void; + catchtap?: (event: GestureTouchEvent) => void; onLayout?: (event: LayoutChangeEvent) => void; 'out-of-bounds'?: boolean; 'wait-for'?: Array; @@ -395,13 +395,6 @@ const _MovableView = forwardRef, MovableViewP catchtouchend && runOnJS(catchtouchend)(e) } - const handleTriggerPress = (e: any) => { - 'worklet' - extendEvent(e) - bindlongpress && runOnJS(bindlongpress)(e) - catchlongpress && runOnJS(catchlongpress)(e) - } - const handleTriggerTap = (e: any) => { 'worklet' extendEvent(e) @@ -409,17 +402,30 @@ const _MovableView = forwardRef, MovableViewP catchtap && runOnJS(catchtap)(e) } + const clearStartTimer = () => { + startTimer.value && clearTimeout(startTimer.value) + startTimer.value = null + } + const checkIsNeedTap = (e: GestureTouchEvent) => { + 'worklet' const tapDetailInfo = startPosition.value || { x: 0, y: 0 } - const currentPageX = e.changedTouches[0].x - const currentPageY = e.changedTouches[0].y - if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) { + const currentX = e.changedTouches[0].x + const currentY = e.changedTouches[0].y + if ((Math.abs(currentX - tapDetailInfo.x) > 1 || Math.abs(currentY - tapDetailInfo.y) > 1) && (needTap.value || startTimer.value)) { needTap.value = false - startTimer.value && clearTimeout(startTimer.value) - startTimer.value = null + runOnJS(clearStartTimer)() } } + const handleLongPress = (e: GestureTouchEvent) => { + startTimer.value = setTimeout(() => { + needTap.value = false + bindlongpress && bindlongpress(e) + catchlongpress && catchlongpress(e) + }, 350) + } + const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' @@ -433,10 +439,7 @@ const _MovableView = forwardRef, MovableViewP } handleTriggerStart(e) if (catchlongpress || bindlongpress) { - startTimer.value = setTimeout(() => { - needTap.value = false - handleTriggerPress(e) - }, 350) + runOnJS(handleLongPress)(e) } }) .onTouchesMove((e: GestureTouchEvent) => { From f27e456ce7ce54a3746c948dbd230f5e3b10be2e Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Wed, 27 Nov 2024 16:34:22 +0800 Subject: [PATCH 04/45] chore: add event --- .../components/react/mpx-movable-view.tsx | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 7d653be7ba..8e69976707 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -358,14 +358,12 @@ const _MovableView = forwardRef, MovableViewP const gesture = useMemo(() => { const handleTriggerStart = (e: any) => { 'worklet' - extendEvent(e) bindtouchstart && runOnJS(bindtouchstart)(e) catchtouchstart && runOnJS(catchtouchstart)(e) } const handleTriggerMove = (e: any) => { 'worklet' - extendEvent(e) const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove @@ -390,18 +388,24 @@ const _MovableView = forwardRef, MovableViewP const handleTriggerEnd = (e: any) => { 'worklet' - extendEvent(e) bindtouchend && runOnJS(bindtouchend)(e) catchtouchend && runOnJS(catchtouchend)(e) } const handleTriggerTap = (e: any) => { 'worklet' - extendEvent(e) bindtap && runOnJS(bindtap)(e) catchtap && runOnJS(catchtap)(e) } + const handleLongPress = (e: GestureTouchEvent) => { + startTimer.value = setTimeout(() => { + needTap.value = false + bindlongpress && bindlongpress(e) + catchlongpress && catchlongpress(e) + }, 350) + } + const clearStartTimer = () => { startTimer.value && clearTimeout(startTimer.value) startTimer.value = null @@ -414,29 +418,24 @@ const _MovableView = forwardRef, MovableViewP const currentY = e.changedTouches[0].y if ((Math.abs(currentX - tapDetailInfo.x) > 1 || Math.abs(currentY - tapDetailInfo.y) > 1) && (needTap.value || startTimer.value)) { needTap.value = false - runOnJS(clearStartTimer)() + if (catchlongpress || bindlongpress) { + runOnJS(clearStartTimer)() + } } } - const handleLongPress = (e: GestureTouchEvent) => { - startTimer.value = setTimeout(() => { - needTap.value = false - bindlongpress && bindlongpress(e) - catchlongpress && catchlongpress(e) - }, 350) - } - const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' + const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } startTimer.value = null needTap.value = true - const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } isMoving.value = false startPosition.value = { x: changedTouches.x, y: changedTouches.y } + extendEvent(e) handleTriggerStart(e) if (catchlongpress || bindlongpress) { runOnJS(handleLongPress)(e) @@ -444,13 +443,14 @@ const _MovableView = forwardRef, MovableViewP }) .onTouchesMove((e: GestureTouchEvent) => { 'worklet' + const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } checkIsNeedTap(e) isMoving.value = true - const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } if (isFirstTouch.value) { touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove' isFirstTouch.value = false } + extendEvent(e) handleTriggerMove(e) if (disabled) return const changeX = changedTouches.x - startPosition.value.x @@ -476,13 +476,17 @@ const _MovableView = forwardRef, MovableViewP }) .onTouchesUp((e: GestureTouchEvent) => { 'worklet' - checkIsNeedTap(e) isFirstTouch.value = true isMoving.value = false + extendEvent(e) handleTriggerEnd(e) + checkIsNeedTap(e) if (needTap.value) { handleTriggerTap(e) } + if (catchlongpress || bindlongpress) { + runOnJS(clearStartTimer)() + } if (disabled) return if (!inertia) { const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value }) From cfa5aefea77e25bc332f3cba6878ce8c59b93c65 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Wed, 27 Nov 2024 20:05:53 +0800 Subject: [PATCH 05/45] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 148 ++++++++++-------- 1 file changed, 82 insertions(+), 66 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 8e69976707..ee1e53e03e 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -33,6 +33,7 @@ import Animated, { useAnimatedReaction, withSpring } from 'react-native-reanimated' +import { collectDataset } from '@mpxjs/utils' interface MovableViewProps { children: ReactNode; @@ -42,6 +43,7 @@ interface MovableViewProps { y?: number; disabled?: boolean; animation?: boolean; + id?: string; bindchange?: (event: unknown) => void; bindtouchstart?: (event: GestureTouchEvent) => void; catchtouchstart?: (event: GestureTouchEvent) => void; @@ -49,12 +51,12 @@ interface MovableViewProps { catchtouchmove?: (event: GestureTouchEvent) => void; catchtouchend?: (event: GestureTouchEvent) => void; bindtouchend?: (event: GestureTouchEvent) => void; - bindhtouchmove?: (event:GestureTouchEvent) => void; + bindhtouchmove?: (event: GestureTouchEvent) => void; bindvtouchmove?: (event: GestureTouchEvent) => void; catchhtouchmove?: (event: GestureTouchEvent) => void; catchvtouchmove?: (event: GestureTouchEvent) => void; bindlongpress?: (event: GestureTouchEvent) => void; - catchlongpress?: (event:GestureTouchEvent) => void; + catchlongpress?: (event: GestureTouchEvent) => void; bindtap?: (event: GestureTouchEvent) => void; catchtap?: (event: GestureTouchEvent) => void; onLayout?: (event: LayoutChangeEvent) => void; @@ -163,10 +165,10 @@ const _MovableView = forwardRef, MovableViewP }) const hasSimultaneousHandlersChanged = prevSimultaneousHandlersRef.current.length !== (originSimultaneousHandlers?.length || 0) || - (originSimultaneousHandlers || []).some((handler, index) => handler !== prevSimultaneousHandlersRef.current[index]) + (originSimultaneousHandlers || []).some((handler, index) => handler !== prevSimultaneousHandlersRef.current[index]) const hasWaitForHandlersChanged = prevWaitForHandlersRef.current.length !== (waitFor?.length || 0) || - (waitFor || []).some((handler, index) => handler !== prevWaitForHandlersRef.current[index]) + (waitFor || []).some((handler, index) => handler !== prevWaitForHandlersRef.current[index]) if (hasSimultaneousHandlersChanged || hasWaitForHandlersChanged) { gestureSwitch.current = !gestureSwitch.current @@ -343,8 +345,7 @@ const _MovableView = forwardRef, MovableViewP props.onLayout && props.onLayout(e) } - const extendEvent = useCallback((e: any) => { - 'worklet' + const extendEvent = useCallback((e: any, obj?: Record) => { const touchArr = [e.changedTouches, e.allTouches] touchArr.forEach(touches => { touches && touches.forEach((item: { absoluteX: number; absoluteY: number; pageX: number; pageY: number }) => { @@ -352,65 +353,74 @@ const _MovableView = forwardRef, MovableViewP item.pageY = item.absoluteY }) }) - e.touches = e.allTouches - }, []) - - const gesture = useMemo(() => { - const handleTriggerStart = (e: any) => { - 'worklet' - bindtouchstart && runOnJS(bindtouchstart)(e) - catchtouchstart && runOnJS(catchtouchstart)(e) - } - - const handleTriggerMove = (e: any) => { - 'worklet' - const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove - const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove - - if (hasTouchmove) { - if (touchEvent.value === 'htouchmove') { - bindhtouchmove && runOnJS(bindhtouchmove)(e) - } else if (touchEvent.value === 'vtouchmove') { - bindvtouchmove && runOnJS(bindvtouchmove)(e) - } - bindtouchmove && runOnJS(bindtouchmove)(e) + Object.assign(e, { + touches: e.allTouches, + detail: { + x: e.changedTouches[0].absoluteX, + y: e.changedTouches[0].absoluteY + }, + currentTarget: { + id: props.id || '', + dataset: collectDataset(props), + offsetLeft: 0, + offsetTop: 0 } + }, obj) + }, []) - if (hasCatchTouchmove) { - if (touchEvent.value === 'htouchmove') { - catchhtouchmove && runOnJS(catchhtouchmove)(e) - } else if (touchEvent.value === 'vtouchmove') { - catchvtouchmove && runOnJS(catchvtouchmove)(e) - } - catchtouchmove && runOnJS(catchtouchmove)(e) - } - } - - const handleTriggerEnd = (e: any) => { - 'worklet' - bindtouchend && runOnJS(bindtouchend)(e) - catchtouchend && runOnJS(catchtouchend)(e) - } - - const handleTriggerTap = (e: any) => { - 'worklet' - bindtap && runOnJS(bindtap)(e) - catchtap && runOnJS(catchtap)(e) - } + const clearStartTimer = () => { + startTimer.value && clearTimeout(startTimer.value) + startTimer.value = null + } - const handleLongPress = (e: GestureTouchEvent) => { + const triggerStartOnJS = ({ e }: { e: GestureTouchEvent }) => { + extendEvent(e) + bindtouchstart && bindtouchstart(e) + catchtouchstart && catchtouchstart(e) + if (catchlongpress || bindlongpress) { startTimer.value = setTimeout(() => { needTap.value = false bindlongpress && bindlongpress(e) catchlongpress && catchlongpress(e) }, 350) } + } - const clearStartTimer = () => { - startTimer.value && clearTimeout(startTimer.value) - startTimer.value = null + const triggerMoveOnJS = ({ e, hasTouchmove, hasCatchTouchmove, touchEvent }: { e: GestureTouchEvent; hasTouchmove: boolean; hasCatchTouchmove: boolean; touchEvent: string }) => { + extendEvent(e) + if (hasTouchmove) { + if (touchEvent === 'htouchmove') { + bindhtouchmove && bindhtouchmove(e) + } else if (touchEvent === 'vtouchmove') { + bindvtouchmove && bindvtouchmove(e) + } + bindtouchmove && bindtouchmove(e) + } + + if (hasCatchTouchmove) { + if (touchEvent === 'htouchmove') { + catchhtouchmove && catchhtouchmove(e) + } else if (touchEvent === 'vtouchmove') { + catchvtouchmove && catchvtouchmove(e) + } + catchtouchmove && catchtouchmove(e) + } + } + + const triggerEndOnJS = ({ e }: { e: GestureTouchEvent }) => { + extendEvent(e) + bindtouchend && bindtouchend(e) + catchtouchend && catchtouchend(e) + if (needTap.value) { + bindtap && bindtap(e) + catchtap && catchtap(e) + } + if (catchlongpress || bindlongpress) { + clearStartTimer() } + } + const gesture = useMemo(() => { const checkIsNeedTap = (e: GestureTouchEvent) => { 'worklet' const tapDetailInfo = startPosition.value || { x: 0, y: 0 } @@ -424,6 +434,20 @@ const _MovableView = forwardRef, MovableViewP } } + const handleTriggerMove = (e: GestureTouchEvent) => { + 'worklet' + const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove + const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove + if (hasTouchmove || hasCatchTouchmove) { + runOnJS(triggerMoveOnJS)({ + e, + touchEvent: touchEvent.value, + hasTouchmove, + hasCatchTouchmove + }) + } + } + const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' @@ -435,22 +459,19 @@ const _MovableView = forwardRef, MovableViewP x: changedTouches.x, y: changedTouches.y } - extendEvent(e) - handleTriggerStart(e) - if (catchlongpress || bindlongpress) { - runOnJS(handleLongPress)(e) + if (bindtouchstart || catchtouchstart || bindlongpress || catchlongpress) { + runOnJS(triggerStartOnJS)({ e }) } }) .onTouchesMove((e: GestureTouchEvent) => { 'worklet' const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } - checkIsNeedTap(e) isMoving.value = true if (isFirstTouch.value) { touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove' isFirstTouch.value = false } - extendEvent(e) + checkIsNeedTap(e) handleTriggerMove(e) if (disabled) return const changeX = changedTouches.x - startPosition.value.x @@ -478,14 +499,9 @@ const _MovableView = forwardRef, MovableViewP 'worklet' isFirstTouch.value = true isMoving.value = false - extendEvent(e) - handleTriggerEnd(e) checkIsNeedTap(e) - if (needTap.value) { - handleTriggerTap(e) - } - if (catchlongpress || bindlongpress) { - runOnJS(clearStartTimer)() + if (bindtouchend || catchtouchend || bindtap || catchtap) { + runOnJS(triggerEndOnJS)({ e }) } if (disabled) return if (!inertia) { From fb285a1265af70bd3377744df40fa5ed98217d88 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 19:34:31 +0800 Subject: [PATCH 06/45] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 72 +++++-------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index cf48d936af..4a1a37fe41 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -19,7 +19,7 @@ */ import { useEffect, forwardRef, ReactNode, useContext, useCallback, useRef, useMemo, createElement } from 'react' import { StyleSheet, NativeSyntheticEvent, View, LayoutChangeEvent } from 'react-native' -import { getCustomEvent } from './getInnerListeners' +import useInnerProps, { getCustomEvent } from './getInnerListeners' import useNodesRef, { HandlerRef } from './useNodesRef' import { MovableAreaContext } from './context' import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject } from './utils' @@ -33,7 +33,7 @@ import Animated, { useAnimatedReaction, withSpring } from 'react-native-reanimated' -import { collectDataset } from '@mpxjs/utils' +import { collectDataset, noop } from '@mpxjs/utils' interface MovableViewProps { children: ReactNode; @@ -149,8 +149,6 @@ const _MovableView = forwardRef, MovableViewP const yInertialMotion = useSharedValue(false) const isFirstTouch = useSharedValue(true) const touchEvent = useSharedValue('') - const startTimer = useSharedValue(null) - const needTap = useSharedValue(true) const MovableAreaLayout = useContext(MovableAreaContext) @@ -368,22 +366,10 @@ const _MovableView = forwardRef, MovableViewP }, obj) }, []) - const clearStartTimer = () => { - startTimer.value && clearTimeout(startTimer.value) - startTimer.value = null - } - const triggerStartOnJS = ({ e }: { e: GestureTouchEvent }) => { extendEvent(e) bindtouchstart && bindtouchstart(e) catchtouchstart && catchtouchstart(e) - if (catchlongpress || bindlongpress) { - startTimer.value = setTimeout(() => { - needTap.value = false - bindlongpress && bindlongpress(e) - catchlongpress && catchlongpress(e) - }, 350) - } } const triggerMoveOnJS = ({ e, hasTouchmove, hasCatchTouchmove, touchEvent }: { e: GestureTouchEvent; hasTouchmove: boolean; hasCatchTouchmove: boolean; touchEvent: string }) => { @@ -411,29 +397,9 @@ const _MovableView = forwardRef, MovableViewP extendEvent(e) bindtouchend && bindtouchend(e) catchtouchend && catchtouchend(e) - if (needTap.value) { - bindtap && bindtap(e) - catchtap && catchtap(e) - } - if (catchlongpress || bindlongpress) { - clearStartTimer() - } } const gesture = useMemo(() => { - const checkIsNeedTap = (e: GestureTouchEvent) => { - 'worklet' - const tapDetailInfo = startPosition.value || { x: 0, y: 0 } - const currentX = e.changedTouches[0].x - const currentY = e.changedTouches[0].y - if ((Math.abs(currentX - tapDetailInfo.x) > 1 || Math.abs(currentY - tapDetailInfo.y) > 1) && (needTap.value || startTimer.value)) { - needTap.value = false - if (catchlongpress || bindlongpress) { - runOnJS(clearStartTimer)() - } - } - } - const handleTriggerMove = (e: GestureTouchEvent) => { 'worklet' const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove @@ -452,14 +418,12 @@ const _MovableView = forwardRef, MovableViewP .onTouchesDown((e: GestureTouchEvent) => { 'worklet' const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } - startTimer.value = null - needTap.value = true isMoving.value = false startPosition.value = { x: changedTouches.x, y: changedTouches.y } - if (bindtouchstart || catchtouchstart || bindlongpress || catchlongpress) { + if (bindtouchstart || catchtouchstart) { runOnJS(triggerStartOnJS)({ e }) } }) @@ -471,7 +435,6 @@ const _MovableView = forwardRef, MovableViewP touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove' isFirstTouch.value = false } - checkIsNeedTap(e) handleTriggerMove(e) if (disabled) return const changeX = changedTouches.x - startPosition.value.x @@ -499,7 +462,6 @@ const _MovableView = forwardRef, MovableViewP 'worklet' isFirstTouch.value = true isMoving.value = false - checkIsNeedTap(e) if (bindtouchend || catchtouchend || bindtap || catchtap) { runOnJS(triggerEndOnJS)({ e }) } @@ -526,8 +488,8 @@ const _MovableView = forwardRef, MovableViewP }) .onFinalize((e: GestureStateChangeEvent) => { 'worklet' - if (!inertia || disabled || !animation) return isMoving.value = false + if (!inertia || disabled || !animation) return if (direction === 'horizontal' || direction === 'all') { xInertialMotion.value = true offsetX.value = withDecay({ @@ -572,32 +534,34 @@ const _MovableView = forwardRef, MovableViewP const injectCatchEvent = (props: Record) => { const eventHandlers: Record = {} const catchEventList = [ - { name: 'onTouchStart', value: ['catchtouchstart', 'catchtap', 'catchlongpress'] }, - { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove', 'catchtap', 'catchlongpress'] }, - { name: 'onTouchEnd', value: ['catchtouchend', 'catchtap', 'catchlongpress'] } + { name: 'bindtouchstart', value: ['bindtouchstart'] }, + { name: 'bindtouchmove', value: ['bindtouchmove', 'bindvtouchmove', 'bindhtouchmove'] }, + { name: 'bindtouchend', value: ['bindtouchend'] }, + { name: 'catchtouchstart', value: ['catchtouchstart'] }, + { name: 'catchtouchmove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] }, + { name: 'catchtouchend', value: ['catchtouchend'] } ] catchEventList.forEach(event => { event.value.forEach(name => { if (props[name] && !eventHandlers[event.name]) { - eventHandlers[event.name] = (e: NativeSyntheticEvent) => { - e.stopPropagation() - } + eventHandlers[event.name] = noop } }) }) return eventHandlers } - const catchEventHandlers = injectCatchEvent(props) const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {} + const innerProps = useInnerProps(props, extendObject({ + ref: nodeRef, + onLayout: onLayout, + style: [innerStyle, animatedStyles, layoutStyle] + }, injectCatchEvent(props))) + return createElement(GestureDetector, { gesture: gesture }, createElement( Animated.View, - extendObject({ - ref: nodeRef, - onLayout: onLayout, - style: [innerStyle, animatedStyles, layoutStyle] - }, catchEventHandlers), + innerProps, wrapChildren( props, { From 312f55e3d1f759b4f87205fd08f21d4ad36972a8 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 20:43:41 +0800 Subject: [PATCH 07/45] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 4a1a37fe41..d9f4abc677 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -531,24 +531,23 @@ const _MovableView = forwardRef, MovableViewP } }) - const injectCatchEvent = (props: Record) => { - const eventHandlers: Record = {} - const catchEventList = [ - { name: 'bindtouchstart', value: ['bindtouchstart'] }, - { name: 'bindtouchmove', value: ['bindtouchmove', 'bindvtouchmove', 'bindhtouchmove'] }, - { name: 'bindtouchend', value: ['bindtouchend'] }, - { name: 'catchtouchstart', value: ['catchtouchstart'] }, - { name: 'catchtouchmove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] }, - { name: 'catchtouchend', value: ['catchtouchend'] } + const proxyTouchEvent = () => { + const handlers: Record = {} + + const events = [ + { type: 'touchstart' }, + { type: 'touchmove', alias: ['vtouchmove', 'htouchmove'] }, + { type: 'touchend' } ] - catchEventList.forEach(event => { - event.value.forEach(name => { - if (props[name] && !eventHandlers[event.name]) { - eventHandlers[event.name] = noop - } - }) + + events.forEach(({ type, alias = [] }) => { + const hasEvent = (prefix: string) => props[prefix + type as keyof MovableViewProps] || alias.some(name => props[prefix + name as keyof MovableViewProps]) + + if (hasEvent('bind')) handlers[`bind${type}`] = noop + if (hasEvent('catch')) handlers[`catch${type}`] = noop }) - return eventHandlers + + return handlers } const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {} @@ -557,7 +556,7 @@ const _MovableView = forwardRef, MovableViewP ref: nodeRef, onLayout: onLayout, style: [innerStyle, animatedStyles, layoutStyle] - }, injectCatchEvent(props))) + }, proxyTouchEvent())) return createElement(GestureDetector, { gesture: gesture }, createElement( Animated.View, From b8218b3d81642ba680447f02f18c0b8b3f215ec4 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 21:11:15 +0800 Subject: [PATCH 08/45] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index d9f4abc677..859cd0ff62 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -22,7 +22,7 @@ import { StyleSheet, NativeSyntheticEvent, View, LayoutChangeEvent } from 'react import useInnerProps, { getCustomEvent } from './getInnerListeners' import useNodesRef, { HandlerRef } from './useNodesRef' import { MovableAreaContext } from './context' -import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject } from './utils' +import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject, omit } from './utils' import { GestureDetector, Gesture, GestureTouchEvent, GestureStateChangeEvent, PanGestureHandlerEventPayload, PanGesture } from 'react-native-gesture-handler' import Animated, { useSharedValue, @@ -531,7 +531,7 @@ const _MovableView = forwardRef, MovableViewP } }) - const proxyTouchEvent = () => { + const rewriteCatchEvent = () => { const handlers: Record = {} const events = [ @@ -539,12 +539,11 @@ const _MovableView = forwardRef, MovableViewP { type: 'touchmove', alias: ['vtouchmove', 'htouchmove'] }, { type: 'touchend' } ] - events.forEach(({ type, alias = [] }) => { - const hasEvent = (prefix: string) => props[prefix + type as keyof MovableViewProps] || alias.some(name => props[prefix + name as keyof MovableViewProps]) - - if (hasEvent('bind')) handlers[`bind${type}`] = noop - if (hasEvent('catch')) handlers[`catch${type}`] = noop + const hasCatchEvent = + props[`catch${type}` as keyof typeof props] || + alias.some(name => props[`catch${name}` as keyof typeof props]) + if (hasCatchEvent) handlers[`catch${type}`] = noop }) return handlers @@ -552,11 +551,21 @@ const _MovableView = forwardRef, MovableViewP const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {} - const innerProps = useInnerProps(props, extendObject({ + // bind 相关 touch 事件直接由 gesture 触发,无须重复挂载 + // catch 相关 touch 事件需要重写并通过 useInnerProps 注入阻止冒泡逻辑 + const filterProps = omit(props, [ + 'bindtouchstart', + 'bindtouchmove', + 'bindvtouchmove', + 'bindhtouchmove', + 'bindtouchend' + ]) + + const innerProps = useInnerProps(filterProps, extendObject({ ref: nodeRef, onLayout: onLayout, style: [innerStyle, animatedStyles, layoutStyle] - }, proxyTouchEvent())) + }, rewriteCatchEvent())) return createElement(GestureDetector, { gesture: gesture }, createElement( Animated.View, From ee58acd02b5cc7effc88b0f7eb38327c71a6cee1 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 21:41:00 +0800 Subject: [PATCH 09/45] chore: del code --- .../lib/runtime/components/react/mpx-movable-view.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 859cd0ff62..1b6c976cf4 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -114,11 +114,7 @@ const _MovableView = forwardRef, MovableViewP catchvtouchmove, catchtouchmove, bindtouchend, - catchtouchend, - bindlongpress, - catchlongpress, - bindtap, - catchtap + catchtouchend } = props const { @@ -462,7 +458,7 @@ const _MovableView = forwardRef, MovableViewP 'worklet' isFirstTouch.value = true isMoving.value = false - if (bindtouchend || catchtouchend || bindtap || catchtap) { + if (bindtouchend || catchtouchend) { runOnJS(triggerEndOnJS)({ e }) } if (disabled) return From 5326576a2f97e6e65575682f59756542de922cd0 Mon Sep 17 00:00:00 2001 From: huajingwen Date: Fri, 20 Dec 2024 18:01:32 +0800 Subject: [PATCH 10/45] fix transform var --- packages/webpack-plugin/lib/platform/style/wx/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/platform/style/wx/index.js b/packages/webpack-plugin/lib/platform/style/wx/index.js index 8a8cc97e3d..327ff32b07 100644 --- a/packages/webpack-plugin/lib/platform/style/wx/index.js +++ b/packages/webpack-plugin/lib/platform/style/wx/index.js @@ -374,7 +374,7 @@ module.exports = function getSpec ({ warn, error }) { // transform 转换 const formatTransform = ({ prop, value, selector }, { mode }) => { // css var & 数组直接返回 - if (Array.isArray(value) || calcExp.test(value)) return { prop, value } + if (Array.isArray(value) || cssVariableExp.test(value)) return { prop, value } const values = parseValues(value) const transform = [] values.forEach(item => { From b6f616c01d07056c7de5368391608a17157c7083 Mon Sep 17 00:00:00 2001 From: wenwen Date: Mon, 23 Dec 2024 13:15:01 +0800 Subject: [PATCH 11/45] add cssVariableExp --- packages/webpack-plugin/lib/platform/style/wx/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/platform/style/wx/index.js b/packages/webpack-plugin/lib/platform/style/wx/index.js index 327ff32b07..702f199f59 100644 --- a/packages/webpack-plugin/lib/platform/style/wx/index.js +++ b/packages/webpack-plugin/lib/platform/style/wx/index.js @@ -374,7 +374,7 @@ module.exports = function getSpec ({ warn, error }) { // transform 转换 const formatTransform = ({ prop, value, selector }, { mode }) => { // css var & 数组直接返回 - if (Array.isArray(value) || cssVariableExp.test(value)) return { prop, value } + if (Array.isArray(value) || cssVariableExp.test(value) || calcExp.test(value)) return { prop, value } const values = parseValues(value) const transform = [] values.forEach(item => { From 664bb7020d1c409a62e22c9abcf634cb8ff8ffe1 Mon Sep 17 00:00:00 2001 From: wenwen Date: Mon, 23 Dec 2024 15:12:45 +0800 Subject: [PATCH 12/45] =?UTF-8?q?add=20parseValueFromParentheses=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20translateY(10px)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/platform/style/wx/index.js | 128 ++++++++++-------- .../components/react/useAnimationHooks.ts | 106 +++++++++------ 2 files changed, 138 insertions(+), 96 deletions(-) diff --git a/packages/webpack-plugin/lib/platform/style/wx/index.js b/packages/webpack-plugin/lib/platform/style/wx/index.js index 702f199f59..d28c279473 100644 --- a/packages/webpack-plugin/lib/platform/style/wx/index.js +++ b/packages/webpack-plugin/lib/platform/style/wx/index.js @@ -108,6 +108,32 @@ module.exports = function getSpec ({ warn, error }) { } return result } + // 解析 translateY(10px) 这种结构 + // 括号外作为key返回,括号内作为val返回 + const parseValueFromParentheses = (values) => { + let i = -1 + const len = values.length + let stack = 0 + let start = 0 + let key = '' + let val = '' + while (++i < len) { + const char = values[i] + if (char === '(') { + if (stack === 0) { + start = i + key = values.substring(0, start) + } + stack++ + } else if (char === ')') { + stack-- + if (stack === 0) { + val = values.substring(start, i + 1) + } + } + } + return { key, val } + } // const getDefaultValueFromVar = (str) => { // const totalVarExp = /^var\((.+)\)$/ // if (!totalVarExp.test(str)) return str @@ -374,65 +400,59 @@ module.exports = function getSpec ({ warn, error }) { // transform 转换 const formatTransform = ({ prop, value, selector }, { mode }) => { // css var & 数组直接返回 - if (Array.isArray(value) || cssVariableExp.test(value) || calcExp.test(value)) return { prop, value } + if (Array.isArray(value) || cssVariableExp.test(value)) return { prop, value } const values = parseValues(value) const transform = [] values.forEach(item => { - const match = item.match(/([/\w]+)\(([^)]+)\)/) - if (match && match.length >= 3) { - let key = match[1] - const val = match[2] - switch (key) { - case 'translateX': - case 'translateY': - case 'scaleX': - case 'scaleY': - case 'rotateX': - case 'rotateY': - case 'rotateZ': - case 'rotate': - case 'skewX': - case 'skewY': - case 'perspective': - // 单个值处理 - transform.push({ [key]: val }) - break - case 'matrix': - case 'matrix3d': - transform.push({ [key]: parseValues(val, ',').map(val => +val) }) - break - case 'translate': - case 'scale': - case 'skew': - case 'rotate3d': // x y z angle - case 'translate3d': // x y 支持 z不支持 - case 'scale3d': // x y 支持 z不支持 - { - // 2 个以上的值处理 - key = key.replace('3d', '') - const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) - // scale(.5) === scaleX(.5) scaleY(.5) - if (vals.length === 1 && key === 'scale') { - vals.push(vals[0]) - } - const xyz = ['X', 'Y', 'Z'] - transform.push(...vals.map((v, index) => { - if (key !== 'rotate' && index > 1) { - unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode }) - } - return { [`${key}${xyz[index] || ''}`]: v.trim() } - })) - break + let { key, val } = parseValueFromParentheses(item) + switch (key) { + case 'translateX': + case 'translateY': + case 'scaleX': + case 'scaleY': + case 'rotateX': + case 'rotateY': + case 'rotateZ': + case 'rotate': + case 'skewX': + case 'skewY': + case 'perspective': + // 单个值处理 + transform.push({ [key]: val }) + break + case 'matrix': + case 'matrix3d': + transform.push({ [key]: parseValues(val, ',').map(val => +val) }) + break + case 'translate': + case 'scale': + case 'skew': + case 'rotate3d': // x y z angle + case 'translate3d': // x y 支持 z不支持 + case 'scale3d': // x y 支持 z不支持 + { + // 2 个以上的值处理 + key = key.replace('3d', '') + const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) + // scale(.5) === scaleX(.5) scaleY(.5) + if (vals.length === 1 && key === 'scale') { + vals.push(vals[0]) + } + const xyz = ['X', 'Y', 'Z'] + transform.push(...vals.map((v, index) => { + if (key !== 'rotate' && index > 1) { + unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode }) } - case 'translateZ': - case 'scaleZ': - default: - // 不支持的属性处理 - unsupportedPropError({ prop, value, selector }, { mode }) - break + return { [`${key}${xyz[index] || ''}`]: v.trim() } + })) + break } - } else { - error(`Property [${prop}] is invalid in ${selector}, received [${value}], please check again!`) + case 'translateZ': + case 'scaleZ': + default: + // 不支持的属性处理 + unsupportedPropError({ prop, value, selector }, { mode }) + break } }) return { diff --git a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts index 77d1ac0503..4dd83152e8 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts @@ -105,54 +105,76 @@ const parseValues = (str: string, char = ' ') => { } return result } +// 解析 translateY(10px) 这种结构 +// 括号外作为key返回,括号内作为val返回 +const parseValueFromParentheses = (values: string) => { + let i = -1 + const len = values.length + let stack = 0 + let start = 0 + let key = '' + let val = '' + while (++i < len) { + const char = values[i] + if (char === '(') { + if (stack === 0) { + start = i + key = values.substring(0, start) + } + stack++ + } else if (char === ')') { + stack-- + if (stack === 0) { + val = values.substring(start, i + 1) + } + } + } + return { key, val } +} // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)' const parseTransform = (transformStr: string) => { const values = parseValues(transformStr) const transform: {[propName: string]: string|number|number[]}[] = [] values.forEach(item => { - const match = item.match(/([/\w]+)\(([^)]+)\)/) - if (match && match.length >= 3) { - let key = match[1] - const val = match[2] - switch (key) { - case 'translateX': - case 'translateY': - case 'scaleX': - case 'scaleY': - case 'rotateX': - case 'rotateY': - case 'rotateZ': - case 'rotate': - case 'skewX': - case 'skewY': - case 'perspective': - // 单个值处理 - transform.push({ [key]: global.__formatValue(val) }) - break - case 'matrix': - case 'matrix3d': - transform.push({ [key]: parseValues(val, ',').map(val => +val) }) - break - case 'translate': - case 'scale': - case 'skew': - case 'rotate3d': // x y z angle - case 'translate3d': // x y 支持 z不支持 - case 'scale3d': // x y 支持 z不支持 - { - // 2 个以上的值处理 - key = key.replace('3d', '') - const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) - // scale(.5) === scaleX(.5) scaleY(.5) - if (vals.length === 1 && key === 'scale') { - vals.push(vals[0]) - } - const xyz = ['X', 'Y', 'Z'] - transform.push(...vals.map((v, index) => { - return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) } - })) - break + let { key, val } = parseValueFromParentheses(item) + switch (key) { + case 'translateX': + case 'translateY': + case 'scaleX': + case 'scaleY': + case 'rotateX': + case 'rotateY': + case 'rotateZ': + case 'rotate': + case 'skewX': + case 'skewY': + case 'perspective': + // 单个值处理 + transform.push({ [key]: global.__formatValue(val) }) + break + case 'matrix': + case 'matrix3d': + transform.push({ [key]: parseValues(val, ',').map(val => +val) }) + break + case 'translate': + case 'scale': + case 'skew': + case 'rotate3d': // x y z angle + case 'translate3d': // x y 支持 z不支持 + case 'scale3d': // x y 支持 z不支持 + { + // 2 个以上的值处理 + key = key.replace('3d', '') + const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) + // scale(.5) === scaleX(.5) scaleY(.5) + if (vals.length === 1 && key === 'scale') { + vals.push(vals[0]) } + const xyz = ['X', 'Y', 'Z'] + transform.push(...vals.map((v, index) => { + return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) } + })) + break } } }) From ad20862f2f4cafda3a78eb67ca2804c192d80838 Mon Sep 17 00:00:00 2001 From: wenwen Date: Mon, 23 Dec 2024 17:07:03 +0800 Subject: [PATCH 13/45] =?UTF-8?q?add=20parseValueFromParentheses=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20translateY(10px)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/webpack-plugin/lib/platform/style/wx/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/platform/style/wx/index.js b/packages/webpack-plugin/lib/platform/style/wx/index.js index d28c279473..054ba0542d 100644 --- a/packages/webpack-plugin/lib/platform/style/wx/index.js +++ b/packages/webpack-plugin/lib/platform/style/wx/index.js @@ -128,7 +128,7 @@ module.exports = function getSpec ({ warn, error }) { } else if (char === ')') { stack-- if (stack === 0) { - val = values.substring(start, i + 1) + val = values.substring(start + 1, i) } } } From 3f781aa6c31f364e8209179b095b569f1e9f30c7 Mon Sep 17 00:00:00 2001 From: wenwen Date: Mon, 23 Dec 2024 17:28:02 +0800 Subject: [PATCH 14/45] fix Parentheses --- .../lib/runtime/components/react/useAnimationHooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts index 4dd83152e8..f9adad4c55 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts @@ -125,7 +125,7 @@ const parseValueFromParentheses = (values: string) => { } else if (char === ')') { stack-- if (stack === 0) { - val = values.substring(start, i + 1) + val = values.substring(start + 1, i) } } } From b058934a994df1f0440c09a013076b4534ec515c Mon Sep 17 00:00:00 2001 From: xuegan Date: Mon, 23 Dec 2024 20:44:44 +0800 Subject: [PATCH 15/45] =?UTF-8?q?fix:=20processShowStyle=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=98=AF=E5=90=A6=E4=B8=BA=20virtualHost=20=E7=9A=84?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/template-compiler/compiler.js | 6 +++++- .../webpack-plugin/lib/utils/pre-process-json.js | 14 +++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/webpack-plugin/lib/template-compiler/compiler.js b/packages/webpack-plugin/lib/template-compiler/compiler.js index dbe300bf09..0ef6604340 100644 --- a/packages/webpack-plugin/lib/template-compiler/compiler.js +++ b/packages/webpack-plugin/lib/template-compiler/compiler.js @@ -2189,6 +2189,10 @@ function isComponentNode (el, options) { return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component' } +function isVirtualHostNode (el, options) { + return options.usingComponentsInfo[el.tag]?.hvh +} + function isReactComponent (el, options) { return !isComponentNode(el, options) && isRealNode(el) && !el.isBuiltIn } @@ -2416,7 +2420,7 @@ function processShow (el, options, root) { show = has ? `{{${parseMustacheWithContext(show).result}&&mpxShow}}` : '{{mpxShow}}' } if (show === undefined) return - if (isComponentNode(el, options)) { + if (isComponentNode(el, options) && isVirtualHostNode(el, options)) { if (show === '') { show = '{{false}}' } diff --git a/packages/webpack-plugin/lib/utils/pre-process-json.js b/packages/webpack-plugin/lib/utils/pre-process-json.js index 0510cccf15..118afaf8e6 100644 --- a/packages/webpack-plugin/lib/utils/pre-process-json.js +++ b/packages/webpack-plugin/lib/utils/pre-process-json.js @@ -6,6 +6,7 @@ const addQuery = require('./add-query') const resolve = require('./resolve') const getJSONContent = require('./get-json-content') const getRulesRunner = require('../platform') +const { matchCondition } = require('./match-condition') const async = require('async') module.exports = function ({ @@ -19,8 +20,7 @@ module.exports = function ({ }, callback) { const mpx = loaderContext.getMpx() const context = loaderContext.context - const mode = mpx.mode - const pagesMap = mpx.pagesMap + const { mode, pagesMap, autoVirtualHostRules } = mpx async.waterfall([ (callback) => { getJSONContent(json, null, loaderContext, callback) @@ -78,8 +78,11 @@ module.exports = function ({ componentGenerics = Object.assign({}, ret.componentGenerics) } if (usingComponents) { - const setUsingComponentInfo = (name, moduleId) => { - usingComponentsInfo[name] = { mid: moduleId } + const setUsingComponentInfo = (name, moduleId, hasVirtualHost) => { + usingComponentsInfo[name] = { + mid: moduleId, + hvh: hasVirtualHost + } } async.eachOf(usingComponents, (component, name, callback) => { if (ctorType === 'app') { @@ -96,7 +99,8 @@ module.exports = function ({ if (err) return callback(err) const { rawResourcePath } = parseRequest(resource) const moduleId = mpx.getModuleId(rawResourcePath, ctorType === 'app') - setUsingComponentInfo(name, moduleId) + const hasVirtualHost = matchCondition(rawResourcePath, autoVirtualHostRules) + setUsingComponentInfo(name, moduleId, hasVirtualHost) callback() }) }, (err) => { From eb8a771fe00731a1099f2b29747e16b161f5853b Mon Sep 17 00:00:00 2001 From: wenwen Date: Mon, 23 Dec 2024 20:56:19 +0800 Subject: [PATCH 16/45] fix del parseValueFromParentheses & update match transform --- .../lib/platform/style/wx/index.js | 126 ++++++++---------- .../components/react/useAnimationHooks.ts | 106 ++++++--------- 2 files changed, 95 insertions(+), 137 deletions(-) diff --git a/packages/webpack-plugin/lib/platform/style/wx/index.js b/packages/webpack-plugin/lib/platform/style/wx/index.js index 054ba0542d..3ff144c1a7 100644 --- a/packages/webpack-plugin/lib/platform/style/wx/index.js +++ b/packages/webpack-plugin/lib/platform/style/wx/index.js @@ -108,32 +108,6 @@ module.exports = function getSpec ({ warn, error }) { } return result } - // 解析 translateY(10px) 这种结构 - // 括号外作为key返回,括号内作为val返回 - const parseValueFromParentheses = (values) => { - let i = -1 - const len = values.length - let stack = 0 - let start = 0 - let key = '' - let val = '' - while (++i < len) { - const char = values[i] - if (char === '(') { - if (stack === 0) { - start = i - key = values.substring(0, start) - } - stack++ - } else if (char === ')') { - stack-- - if (stack === 0) { - val = values.substring(start + 1, i) - } - } - } - return { key, val } - } // const getDefaultValueFromVar = (str) => { // const totalVarExp = /^var\((.+)\)$/ // if (!totalVarExp.test(str)) return str @@ -404,55 +378,61 @@ module.exports = function getSpec ({ warn, error }) { const values = parseValues(value) const transform = [] values.forEach(item => { - let { key, val } = parseValueFromParentheses(item) - switch (key) { - case 'translateX': - case 'translateY': - case 'scaleX': - case 'scaleY': - case 'rotateX': - case 'rotateY': - case 'rotateZ': - case 'rotate': - case 'skewX': - case 'skewY': - case 'perspective': - // 单个值处理 - transform.push({ [key]: val }) - break - case 'matrix': - case 'matrix3d': - transform.push({ [key]: parseValues(val, ',').map(val => +val) }) - break - case 'translate': - case 'scale': - case 'skew': - case 'rotate3d': // x y z angle - case 'translate3d': // x y 支持 z不支持 - case 'scale3d': // x y 支持 z不支持 - { - // 2 个以上的值处理 - key = key.replace('3d', '') - const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) - // scale(.5) === scaleX(.5) scaleY(.5) - if (vals.length === 1 && key === 'scale') { - vals.push(vals[0]) - } - const xyz = ['X', 'Y', 'Z'] - transform.push(...vals.map((v, index) => { - if (key !== 'rotate' && index > 1) { - unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode }) + const match = item.match(/([/\w]+)\(([^]+)\)/) + if (match && match.length >= 3) { + let key = match[1] + const val = match[2] + switch (key) { + case 'translateX': + case 'translateY': + case 'scaleX': + case 'scaleY': + case 'rotateX': + case 'rotateY': + case 'rotateZ': + case 'rotate': + case 'skewX': + case 'skewY': + case 'perspective': + // 单个值处理 + transform.push({ [key]: val }) + break + case 'matrix': + case 'matrix3d': + transform.push({ [key]: parseValues(val, ',').map(val => +val) }) + break + case 'translate': + case 'scale': + case 'skew': + case 'rotate3d': // x y z angle + case 'translate3d': // x y 支持 z不支持 + case 'scale3d': // x y 支持 z不支持 + { + // 2 个以上的值处理 + key = key.replace('3d', '') + const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) + // scale(.5) === scaleX(.5) scaleY(.5) + if (vals.length === 1 && key === 'scale') { + vals.push(vals[0]) } - return { [`${key}${xyz[index] || ''}`]: v.trim() } - })) - break + const xyz = ['X', 'Y', 'Z'] + transform.push(...vals.map((v, index) => { + if (key !== 'rotate' && index > 1) { + unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode }) + } + return { [`${key}${xyz[index] || ''}`]: v.trim() } + })) + break + } + case 'translateZ': + case 'scaleZ': + default: + // 不支持的属性处理 + unsupportedPropError({ prop, value, selector }, { mode }) + break } - case 'translateZ': - case 'scaleZ': - default: - // 不支持的属性处理 - unsupportedPropError({ prop, value, selector }, { mode }) - break + } else { + error(`Property [${prop}] is invalid in ${selector}, received [${value}], please check again!`) } }) return { diff --git a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts index f9adad4c55..feb8966ba7 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts @@ -105,76 +105,54 @@ const parseValues = (str: string, char = ' ') => { } return result } -// 解析 translateY(10px) 这种结构 -// 括号外作为key返回,括号内作为val返回 -const parseValueFromParentheses = (values: string) => { - let i = -1 - const len = values.length - let stack = 0 - let start = 0 - let key = '' - let val = '' - while (++i < len) { - const char = values[i] - if (char === '(') { - if (stack === 0) { - start = i - key = values.substring(0, start) - } - stack++ - } else if (char === ')') { - stack-- - if (stack === 0) { - val = values.substring(start + 1, i) - } - } - } - return { key, val } -} // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)' const parseTransform = (transformStr: string) => { const values = parseValues(transformStr) const transform: {[propName: string]: string|number|number[]}[] = [] values.forEach(item => { - let { key, val } = parseValueFromParentheses(item) - switch (key) { - case 'translateX': - case 'translateY': - case 'scaleX': - case 'scaleY': - case 'rotateX': - case 'rotateY': - case 'rotateZ': - case 'rotate': - case 'skewX': - case 'skewY': - case 'perspective': - // 单个值处理 - transform.push({ [key]: global.__formatValue(val) }) - break - case 'matrix': - case 'matrix3d': - transform.push({ [key]: parseValues(val, ',').map(val => +val) }) - break - case 'translate': - case 'scale': - case 'skew': - case 'rotate3d': // x y z angle - case 'translate3d': // x y 支持 z不支持 - case 'scale3d': // x y 支持 z不支持 - { - // 2 个以上的值处理 - key = key.replace('3d', '') - const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) - // scale(.5) === scaleX(.5) scaleY(.5) - if (vals.length === 1 && key === 'scale') { - vals.push(vals[0]) + const match = item.match(/([/\w]+)\(([^]+)\)/) + if (match && match.length >= 3) { + let key = match[1] + const val = match[2] + switch (key) { + case 'translateX': + case 'translateY': + case 'scaleX': + case 'scaleY': + case 'rotateX': + case 'rotateY': + case 'rotateZ': + case 'rotate': + case 'skewX': + case 'skewY': + case 'perspective': + // 单个值处理 + transform.push({ [key]: global.__formatValue(val) }) + break + case 'matrix': + case 'matrix3d': + transform.push({ [key]: parseValues(val, ',').map(val => +val) }) + break + case 'translate': + case 'scale': + case 'skew': + case 'rotate3d': // x y z angle + case 'translate3d': // x y 支持 z不支持 + case 'scale3d': // x y 支持 z不支持 + { + // 2 个以上的值处理 + key = key.replace('3d', '') + const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3) + // scale(.5) === scaleX(.5) scaleY(.5) + if (vals.length === 1 && key === 'scale') { + vals.push(vals[0]) + } + const xyz = ['X', 'Y', 'Z'] + transform.push(...vals.map((v, index) => { + return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) } + })) + break } - const xyz = ['X', 'Y', 'Z'] - transform.push(...vals.map((v, index) => { - return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) } - })) - break } } }) From cce5dc2979758ee4104273d043fc2384e1f91aa0 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 11:35:35 +0800 Subject: [PATCH 17/45] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0hook=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 12 +++++------- package.json | 1 + 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 37bb6af70f..3a4ddb27b9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,10 +5,7 @@ module.exports = { sourceType: 'module' }, extends: 'standard', - plugins: [ - 'html', - 'jest' - ], + plugins: ['html', 'jest', 'react-hooks'], globals: { wx: 'readonly', my: 'readonly', @@ -32,7 +29,8 @@ module.exports = { 'no-cond-assign': 0, camelcase: 0, indent: 0, - 'symbol-description': 0 + 'symbol-description': 0, + 'react-hooks/rules-of-hooks': 'error' }, env: { 'jest/globals': true, @@ -45,7 +43,7 @@ module.exports = { extends: [ 'standard', 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended' ], plugins: ['@typescript-eslint'], rules: { @@ -56,7 +54,7 @@ module.exports = { '@typescript-eslint/no-empty-interface': 0, '@typescript-eslint/no-unused-vars': 0, '@typescript-eslint/no-non-null-assertion': 0, - camelcase: 0, + camelcase: 0 } } ] diff --git a/package.json b/package.json index 3239959915..d57ad55a53 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "eslint-plugin-jest": "^27.0.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^5.1.1", + "eslint-plugin-react-hooks": "^5.1.0", "identity-obj-proxy": "^3.0.0", "jest": "^27.2.0", "lerna": "^8.1.8", From bbaa480a1eef829e1d843d0a7399e025a5f93b22 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 11:57:48 +0800 Subject: [PATCH 18/45] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9eslint?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 3a4ddb27b9..99a634496f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,7 +5,7 @@ module.exports = { sourceType: 'module' }, extends: 'standard', - plugins: ['html', 'jest', 'react-hooks'], + plugins: ['html', 'jest'], globals: { wx: 'readonly', my: 'readonly', @@ -29,8 +29,7 @@ module.exports = { 'no-cond-assign': 0, camelcase: 0, indent: 0, - 'symbol-description': 0, - 'react-hooks/rules-of-hooks': 'error' + 'symbol-description': 0 }, env: { 'jest/globals': true, @@ -56,6 +55,12 @@ module.exports = { '@typescript-eslint/no-non-null-assertion': 0, camelcase: 0 } + }, { + files: ['packages/webpack-plugin/**/*.{js,jsx,ts,tsx}'], + plugins: ['react-hooks'], + rules: { + 'react-hooks/rules-of-hooks': 'error' + } } ] } From ff14ed9c53d4cf101c4cce3a4bb0d6f159abb539 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 12:05:42 +0800 Subject: [PATCH 19/45] fix: error --- .../lib/runtime/components/react/mpx-view.tsx | 17 ++++++++++------- .../lib/runtime/components/react/utils.tsx | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index cdc8c02aef..098a20fa68 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -210,7 +210,7 @@ function calculateSizePosition (h: number, ch: number, val: string): number { /** * 获取图片的展示宽高 -* h - 用户设置的高度 +* h - 用户设���的高度 * lh - 容器的高度 * **/ const calcPercent = (h: NumberVal, lh: number) => { @@ -551,7 +551,7 @@ function inheritStyle (innerStyle: ExtendedViewStyle = {}) { : undefined) } -function wrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record, enableFastImage?: boolean) { +function WrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record, enableFastImage?: boolean) { // 预处理数据 const preImageInfo: PreImageInfo = preParseImage(imageStyle) // 预解析 @@ -660,7 +660,7 @@ function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, tex }) return [ - enableBackground ? wrapImage(backgroundStyle, innerStyle, enableFastImage) : null, + enableBackground ? WrapImage(backgroundStyle, innerStyle, enableFastImage) : null, children ] } @@ -777,11 +777,14 @@ const _View = forwardRef, _ViewProps>((viewProps, r if (enableAnimationRef.current !== enableAnimation) { error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.') } + const finalStyle = enableAnimationRef.current - ? [viewStyle, useAnimationHooks({ - animation, - style: viewStyle - })] + ? [viewStyle, + // eslint-disable-next-line react-hooks/rules-of-hooks + useAnimationHooks({ + animation, + style: viewStyle + })] : viewStyle const innerProps = useInnerProps( props, diff --git a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx index a00bb771ea..07bd9d0a3d 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx @@ -325,6 +325,7 @@ export function useTransformStyle (styleObj: Record = {}, { enableV // apply var const varContextRef = useRef({}) if (enableVarRef.current) { + // eslint-disable-next-line react-hooks/rules-of-hooks const varContext = useContext(VarContext) const newVarContext = Object.assign({}, varContext, externalVarContext, varStyle) // 缓存比较newVarContext是否发生变化 From e933eb0f05654d65edd97a6fb7064f774c2b9165 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 12:19:56 +0800 Subject: [PATCH 20/45] fix: error --- .../webpack-plugin/lib/runtime/components/react/mpx-view.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index 098a20fa68..f2e5d8c3e6 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -165,7 +165,7 @@ const checkNeedLayout = (preImageInfo: PreImageInfo) => { } /** -* h - 用户设置的高度 +* h - 用户设置的高度 * lh - 容器的高度 * ratio - 原始图片的宽高比 * **/ From 722007e8f5abe6902039a8bc9b1adb9e24e34fd8 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 12:21:03 +0800 Subject: [PATCH 21/45] fix: error --- .../webpack-plugin/lib/runtime/components/react/mpx-view.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index f2e5d8c3e6..b4576e83aa 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -165,7 +165,7 @@ const checkNeedLayout = (preImageInfo: PreImageInfo) => { } /** -* h - 用户设置的高度 +* h - 用户设置的高度。 * lh - 容器的高度 * ratio - 原始图片的宽高比 * **/ From 47be902831189bceb7bfec748075a1fe1a420917 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 12:21:48 +0800 Subject: [PATCH 22/45] fix: error --- .../webpack-plugin/lib/runtime/components/react/mpx-view.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index b4576e83aa..ce151951f7 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -165,7 +165,7 @@ const checkNeedLayout = (preImageInfo: PreImageInfo) => { } /** -* h - 用户设置的高度。 +* h - 用户设置的高度 * lh - 容器的高度 * ratio - 原始图片的宽高比 * **/ @@ -210,7 +210,7 @@ function calculateSizePosition (h: number, ch: number, val: string): number { /** * 获取图片的展示宽高 -* h - 用户设���的高度 +* h - 用户设置的高度 * lh - 容器的高度 * **/ const calcPercent = (h: NumberVal, lh: number) => { From 3b4dd641cee0f007fefd5d7d5646a917725f0e1a Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 14:12:59 +0800 Subject: [PATCH 23/45] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9scope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 99a634496f..0cd2003456 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -56,7 +56,7 @@ module.exports = { camelcase: 0 } }, { - files: ['packages/webpack-plugin/**/*.{js,jsx,ts,tsx}'], + files: ['packages/webpack-plugin/lib/runtime/components/react/**/*.{js,jsx,ts,tsx}'], plugins: ['react-hooks'], rules: { 'react-hooks/rules-of-hooks': 'error' From 730b39e31bc13841aea482f460d8e3927cedbaf2 Mon Sep 17 00:00:00 2001 From: xuegan Date: Tue, 24 Dec 2024 14:15:31 +0800 Subject: [PATCH 24/45] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9virtualHost?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E4=B8=BAgetCompnoentInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/template-compiler/compiler.js | 21 ++++++++++--------- .../lib/utils/pre-process-json.js | 12 +++++------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/webpack-plugin/lib/template-compiler/compiler.js b/packages/webpack-plugin/lib/template-compiler/compiler.js index 0ef6604340..022d5fc01a 100644 --- a/packages/webpack-plugin/lib/template-compiler/compiler.js +++ b/packages/webpack-plugin/lib/template-compiler/compiler.js @@ -117,6 +117,7 @@ let hasOptionalChaining = false let processingTemplate = false const rulesResultMap = new Map() let usingComponents = [] +let usingComponentsInfo = {} function updateForScopesMap () { forScopesMap = {} @@ -636,6 +637,7 @@ function parse (template, options) { if (typeof options.usingComponentsInfo === 'string') options.usingComponentsInfo = JSON.parse(options.usingComponentsInfo) usingComponents = Object.keys(options.usingComponentsInfo) + usingComponentsInfo = options.usingComponentsInfo const _warn = content => { const currentElementRuleResult = rulesResultMap.get(currentEl) || rulesResultMap.set(currentEl, { @@ -2185,20 +2187,20 @@ function isRealNode (el) { return !virtualNodeTagMap[el.tag] } -function isComponentNode (el, options) { +function isComponentNode (el) { return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component' } -function isVirtualHostNode (el, options) { - return options.usingComponentsInfo[el.tag]?.hvh +function getComponentInfo (el) { + return usingComponentsInfo[el.tag] || {} } -function isReactComponent (el, options) { - return !isComponentNode(el, options) && isRealNode(el) && !el.isBuiltIn +function isReactComponent (el) { + return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn } function processExternalClasses (el, options) { - const isComponent = isComponentNode(el, options) + const isComponent = isComponentNode(el) const classLikeAttrNames = isComponent ? ['class'].concat(options.externalClasses) : ['class'] classLikeAttrNames.forEach((classLikeAttrName) => { @@ -2312,8 +2314,7 @@ function postProcessAliComponentRootView (el, options, meta) { { condition: /^style$/, action: 'move' }, { condition: /^slot$/, action: 'move' } ] - const tagName = el.tag - const mid = options.usingComponentsInfo[tagName]?.mid || moduleId + const mid = getComponentInfo(el).mid const processAppendAttrsRules = [ { name: 'class', value: `${MPX_ROOT_VIEW} host-${mid}` } ] @@ -2420,7 +2421,7 @@ function processShow (el, options, root) { show = has ? `{{${parseMustacheWithContext(show).result}&&mpxShow}}` : '{{mpxShow}}' } if (show === undefined) return - if (isComponentNode(el, options) && isVirtualHostNode(el, options)) { + if (isComponentNode(el) && getComponentInfo(el).hasVirtualHost) { if (show === '') { show = '{{false}}' } @@ -2719,7 +2720,7 @@ function closeElement (el, options, meta) { } }) } - if (isComponentNode(el, options) && !hasVirtualHost && mode === 'ali' && el.tag !== 'component') { + if (isComponentNode(el) && !hasVirtualHost && mode === 'ali' && el.tag !== 'component') { postProcessAliComponentRootView(el, options, meta) } } diff --git a/packages/webpack-plugin/lib/utils/pre-process-json.js b/packages/webpack-plugin/lib/utils/pre-process-json.js index 118afaf8e6..6454a6553b 100644 --- a/packages/webpack-plugin/lib/utils/pre-process-json.js +++ b/packages/webpack-plugin/lib/utils/pre-process-json.js @@ -78,11 +78,8 @@ module.exports = function ({ componentGenerics = Object.assign({}, ret.componentGenerics) } if (usingComponents) { - const setUsingComponentInfo = (name, moduleId, hasVirtualHost) => { - usingComponentsInfo[name] = { - mid: moduleId, - hvh: hasVirtualHost - } + const setUsingComponentInfo = (name, info) => { + usingComponentsInfo[name] = info } async.eachOf(usingComponents, (component, name, callback) => { if (ctorType === 'app') { @@ -100,7 +97,10 @@ module.exports = function ({ const { rawResourcePath } = parseRequest(resource) const moduleId = mpx.getModuleId(rawResourcePath, ctorType === 'app') const hasVirtualHost = matchCondition(rawResourcePath, autoVirtualHostRules) - setUsingComponentInfo(name, moduleId, hasVirtualHost) + setUsingComponentInfo(name, { + mid: moduleId, + hasVirtualHost + }) callback() }) }, (err) => { From 40386b8eb93835baf8aeee409498ac816392d105 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 14:36:04 +0800 Subject: [PATCH 25/45] =?UTF-8?q?chore:=20=E8=BF=87=E6=BB=A4catch=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/mpx-movable-view.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 1b6c976cf4..b6410e9034 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -554,7 +554,12 @@ const _MovableView = forwardRef, MovableViewP 'bindtouchmove', 'bindvtouchmove', 'bindhtouchmove', - 'bindtouchend' + 'bindtouchend', + 'catchtouchstart', + 'catchtouchmove', + 'catchvtouchmove', + 'catchhtouchmove', + 'catchtouchend' ]) const innerProps = useInnerProps(filterProps, extendObject({ From 2a73cadb472e9bf7d61e7b1c5f62cc57fd5742aa Mon Sep 17 00:00:00 2001 From: wenwen Date: Tue, 24 Dec 2024 14:53:56 +0800 Subject: [PATCH 26/45] fix match exp --- packages/webpack-plugin/lib/platform/style/wx/index.js | 2 +- .../lib/runtime/components/react/useAnimationHooks.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webpack-plugin/lib/platform/style/wx/index.js b/packages/webpack-plugin/lib/platform/style/wx/index.js index 3ff144c1a7..4a8c5768ac 100644 --- a/packages/webpack-plugin/lib/platform/style/wx/index.js +++ b/packages/webpack-plugin/lib/platform/style/wx/index.js @@ -378,7 +378,7 @@ module.exports = function getSpec ({ warn, error }) { const values = parseValues(value) const transform = [] values.forEach(item => { - const match = item.match(/([/\w]+)\(([^]+)\)/) + const match = item.match(/([/\w]+)\((.+)\)/) if (match && match.length >= 3) { let key = match[1] const val = match[2] diff --git a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts index feb8966ba7..d2fe90334e 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts @@ -110,7 +110,7 @@ const parseTransform = (transformStr: string) => { const values = parseValues(transformStr) const transform: {[propName: string]: string|number|number[]}[] = [] values.forEach(item => { - const match = item.match(/([/\w]+)\(([^]+)\)/) + const match = item.match(/([/\w]+)\((.+)\)/) if (match && match.length >= 3) { let key = match[1] const val = match[2] From 4dce0440b0532204074f182c7d16f4d2c677c55e Mon Sep 17 00:00:00 2001 From: mackwang Date: Thu, 26 Dec 2024 13:49:51 +0800 Subject: [PATCH 27/45] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BC=96?= =?UTF-8?q?=E8=AF=91mpx=E6=96=87=E4=BB=B6stylus=E6=8A=A5=E9=94=99=E6=A0=88?= =?UTF-8?q?=E6=BA=A2=E5=87=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/webpack-plugin/lib/parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/parser.js b/packages/webpack-plugin/lib/parser.js index 6c7598cf9b..97db82f730 100644 --- a/packages/webpack-plugin/lib/parser.js +++ b/packages/webpack-plugin/lib/parser.js @@ -14,7 +14,7 @@ module.exports = (content, { filePath, needMap, mode, env }) => { output = compiler.parseComponent(content, { mode, filePath, - pad: 'line', + // pad: 'line', // stylus编译遇到大量空行时会出现栈溢出,故注释掉 env }) if (needMap) { From a89c7106be1323e835cfd56c6c9fad72e0a3c36c Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 26 Dec 2024 17:21:39 +0800 Subject: [PATCH 28/45] =?UTF-8?q?chore:=20canvas=E9=80=9A=E4=BF=A1?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/mpx-canvas/html.ts | 6 ++---- .../lib/runtime/components/react/mpx-canvas/index.tsx | 6 +++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/html.ts b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/html.ts index c8a3a8140b..e8d6bdbdfa 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/html.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/html.ts @@ -316,8 +316,7 @@ var handleError = function (err, message) { document.removeEventListener('message', handleIncomingMessage); }; -function handleIncomingMessage(e) { - var data = JSON.parse(e.data); +function handleIncomingMessage(data) { if (Array.isArray(data)) { for (var i = 0; i < data.length; i++) { try { @@ -335,8 +334,7 @@ function handleIncomingMessage(e) { } } -window.addEventListener('message', handleIncomingMessage); -document.addEventListener('message', handleIncomingMessage); +window.mpxWebviewMessageCallback = handleIncomingMessage diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx index b5b31cc3d1..3c56abde39 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx @@ -106,7 +106,11 @@ const _Canvas = forwardRef, CanvasPr useEffect(() => { const webviewPostMessage = (message: WebviewMessage) => { if (canvasRef.current.webview) { - canvasRef.current.webview.postMessage(JSON.stringify(message)) + const jsCode = ` + window.mpxWebviewMessageCallback(${JSON.stringify(message)}); + true; + ` + canvasRef.current.webview.injectJavaScript(jsCode) } } From 903e7993b2eadf59809e8a6f2998b662dd9bc23a Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 27 Dec 2024 13:41:18 +0800 Subject: [PATCH 29/45] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9tap=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/getInnerListeners.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 10f0ae1301..3bc80cda97 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -126,8 +126,8 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: const currentPageX = nativeEvent.changedTouches[0].pageX const currentPageY = nativeEvent.changedTouches[0].pageY if ( - Math.abs(currentPageX - tapDetailInfo.x) > 1 || - Math.abs(currentPageY - tapDetailInfo.y) > 1 + Math.abs(currentPageX - tapDetailInfo.x) > 3 || + Math.abs(currentPageY - tapDetailInfo.y) > 3 ) { ref.current!.needPress[type] = false ref.current!.startTimer[type] && From c98c741cb96dab54edf1db1e58daaa1fa386e446 Mon Sep 17 00:00:00 2001 From: WX-DongXing Date: Fri, 27 Dec 2024 17:19:01 +0800 Subject: [PATCH 30/45] fix: use default gesture config --- packages/core/src/platform/createApp.ios.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index 226894d9fc..b3ef722394 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -183,7 +183,6 @@ export default function createApp (option, config = {}) { const { initialRouteName, initialParams } = initialRouteRef.current const headerBackImageProps = Mpx.config.rnConfig.headerBackImageProps || null const navScreenOpts = { - gestureEnabled: true, // 7.x替换headerBackTitleVisible // headerBackButtonDisplayMode: 'minimal', headerBackTitleVisible: false, From efb3a643f577810909c79cd58bbc44bf5fd4f35c Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Tue, 31 Dec 2024 18:18:08 +0800 Subject: [PATCH 31/45] optimize useTransformStyle with memo & adjust host props inherit & support unocss var --- .../builtInMixins/styleHelperMixin.ios.js | 2 +- .../platform/patch/getDefaultOptions.ios.js | 15 +- .../lib/runtime/components/react/utils.tsx | 148 +++++++++++------- 3 files changed, 97 insertions(+), 68 deletions(-) diff --git a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js index 28fbe08a4a..3566007f75 100644 --- a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js +++ b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js @@ -181,7 +181,7 @@ export default function styleHelperMixin () { } else if (appClassMap[className]) { // todo 全局样式在每个页面和组件中生效,以支持全局原子类,后续支持样式模块复用后可考虑移除 Object.assign(result, appClassMap[className]) - } else if (this.__props[className] && isObject(this.__props[className])) { + } else if (isObject(this.__props[className])) { // externalClasses必定以对象形式传递下来 Object.assign(result, this.__props[className]) } diff --git a/packages/core/src/platform/patch/getDefaultOptions.ios.js b/packages/core/src/platform/patch/getDefaultOptions.ios.js index 1f44e346f6..ac4c5c7561 100644 --- a/packages/core/src/platform/patch/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/getDefaultOptions.ios.js @@ -3,7 +3,7 @@ import * as ReactNative from 'react-native' import { ReactiveEffect } from '../../observer/effect' import { watch } from '../../observer/watch' import { reactive, set, del } from '../../observer/reactive' -import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, callWithErrorHandling, wrapMethodsWithErrorHandling } from '@mpxjs/utils' +import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling } from '@mpxjs/utils' import MpxProxy from '../../core/proxy' import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE, REACTHOOKSEXEC } from '../../core/innerLifecycle' import mergeOptions from '../../core/mergeOptions' @@ -58,14 +58,12 @@ function createEffect (proxy, components) { proxy.toggleRecurse(true) } -function getRootProps (props) { +function getRootProps (props, validProps) { const rootProps = {} for (const key in props) { - if (hasOwn(props, key)) { - const match = /^(bind|catch|capture-bind|capture-catch|style|enable-var):?(.*?)(?:\.(.*))?$/.exec(key) - if (match) { - rootProps[key] = props[key] - } + const altKey = dash2hump(key) + if (!hasOwn(validProps, key) && !hasOwn(validProps, altKey) && key !== 'children') { + rootProps[key] = props[key] } } return rootProps @@ -474,7 +472,8 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { const root = useMemo(() => proxy.effect.run(), [finalMemoVersion]) if (root && root.props.ishost) { - const rootProps = getRootProps(props) + // 对于组件未注册的属性继承到host节点上,如事件、样式和其他属性等 + const rootProps = getRootProps(props, validProps) rootProps.style = Object.assign({}, root.props.style, rootProps.style) // update root props return cloneElement(root, rootProps) diff --git a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx index a00bb771ea..99a171d7ec 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx @@ -18,8 +18,10 @@ export const HIDDEN_STYLE = { opacity: 0 } -const varDecRegExp = /^--.*/ +const varDecRegExp = /^--/ const varUseRegExp = /var\(/ +const unoVarDecRegExp = /^--un-/ +const unoVarUseRegExp = /var\(--un-/ const calcUseRegExp = /calc\(/ const envUseRegExp = /env\(/ @@ -37,7 +39,7 @@ function getSafeAreaInset (name: string) { } export function omit (obj: T, fields: K[]): Omit { - const shallowCopy: any = Object.assign({}, obj) + const shallowCopy: any = extendObject({}, obj) for (let i = 0; i < fields.length; i += 1) { const key = fields[i] delete shallowCopy[key] @@ -77,7 +79,7 @@ export const parseInlineStyle = (inlineStyle = ''): Record => { const [k, v, ...rest] = style.split(':') if (rest.length || !v || !k) return styleObj const key = k.trim().replace(/-./g, c => c.substring(1).toUpperCase()) - return Object.assign(styleObj, { [key]: global.__formatValue(v.trim()) }) + return extendObject(styleObj, { [key]: global.__formatValue(v.trim()) }) }, {}) } @@ -286,11 +288,15 @@ interface TransformStyleConfig { export function useTransformStyle (styleObj: Record = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }: TransformStyleConfig) { const varStyle: Record = {} + const unoVarStyle: Record = {} const normalStyle: Record = {} + const normalStyleRef = useRef>({}) + const normalStyleChangedRef = useRef(false) let hasVarDec = false let hasVarUse = false let hasSelfPercent = false const varKeyPaths: Array> = [] + const unoVarKeyPaths: Array> = [] const percentKeyPaths: Array> = [] const calcKeyPaths: Array> = [] const envKeyPaths: Array> = [] @@ -299,7 +305,9 @@ export function useTransformStyle (styleObj: Record = {}, { enableV function varVisitor ({ key, value, keyPath }: VisitorArg) { if (keyPath.length === 1) { - if (varDecRegExp.test(key)) { + if (unoVarDecRegExp.test(key)) { + unoVarStyle[key] = value + } else if (varDecRegExp.test(key)) { hasVarDec = true varStyle[key] = value } else { @@ -308,25 +316,31 @@ export function useTransformStyle (styleObj: Record = {}, { enableV } } // 对于var定义中使用的var无需替换值,可以通过resolveVar递归解析出值 - if (!varDecRegExp.test(key) && varUseRegExp.test(value)) { - hasVarUse = true - varKeyPaths.push(keyPath.slice()) + if (!varDecRegExp.test(key)) { + // 一般情况下一个样式属性中不会混用unocss var和普通css var,可分开进行互斥处理 + if (unoVarUseRegExp.test(value)) { + unoVarKeyPaths.push(keyPath.slice()) + } else if (varUseRegExp.test(value)) { + hasVarUse = true + varKeyPaths.push(keyPath.slice()) + } } } - // traverse var + // traverse var & generate normalStyle traverseStyle(styleObj, [varVisitor]) + hasVarDec = hasVarDec || !!externalVarContext enableVar = enableVar || hasVarDec || hasVarUse const enableVarRef = useRef(enableVar) if (enableVarRef.current !== enableVar) { error('css variable use/declare should be stable in the component lifecycle, or you can set [enable-var] with true.') } - // apply var + // apply css var const varContextRef = useRef({}) if (enableVarRef.current) { const varContext = useContext(VarContext) - const newVarContext = Object.assign({}, varContext, externalVarContext, varStyle) + const newVarContext = extendObject({}, varContext, externalVarContext, varStyle) // 缓存比较newVarContext是否发生变化 if (diffAndCloneA(varContextRef.current, newVarContext).diff) { varContextRef.current = newVarContext @@ -334,70 +348,86 @@ export function useTransformStyle (styleObj: Record = {}, { enableV transformVar(normalStyle, varKeyPaths, varContextRef.current) } - function envVisitor ({ value, keyPath }: VisitorArg) { - if (envUseRegExp.test(value)) { - envKeyPaths.push(keyPath.slice()) - } + // apply unocss var + if (unoVarKeyPaths.length) { + transformVar(normalStyle, unoVarKeyPaths, unoVarStyle) } - function calcVisitor ({ value, keyPath }: VisitorArg) { - if (calcUseRegExp.test(value)) { - calcKeyPaths.push(keyPath.slice()) - } + const { clone, diff } = diffAndCloneA(normalStyle, normalStyleRef.current) + if (diff) { + normalStyleRef.current = clone + normalStyleChangedRef.current = !normalStyleChangedRef.current } - function percentVisitor ({ key, value, keyPath }: VisitorArg) { - if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) { - hasSelfPercent = true - percentKeyPaths.push(keyPath.slice()) - } else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) { - percentKeyPaths.push(keyPath.slice()) + const memoResult = useMemo(() => { + // transform can be memoized + function envVisitor ({ value, keyPath }: VisitorArg) { + if (envUseRegExp.test(value)) { + envKeyPaths.push(keyPath.slice()) + } } - } - // traverse env & calc & percent - traverseStyle(normalStyle, [envVisitor, percentVisitor, calcVisitor]) + function calcVisitor ({ value, keyPath }: VisitorArg) { + if (calcUseRegExp.test(value)) { + calcKeyPaths.push(keyPath.slice()) + } + } - const percentConfig = { - width, - height, - fontSize: normalStyle.fontSize, - parentWidth, - parentHeight, - parentFontSize - } + function percentVisitor ({ key, value, keyPath }: VisitorArg) { + if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) { + hasSelfPercent = true + percentKeyPaths.push(keyPath.slice()) + } else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) { + percentKeyPaths.push(keyPath.slice()) + } + } - // apply env - transformEnv(normalStyle, envKeyPaths) - // apply percent - transformPercent(normalStyle, percentKeyPaths, percentConfig) - // apply calc - transformCalc(normalStyle, calcKeyPaths, (value: string, key: string) => { - if (PERCENT_REGEX.test(value)) { - const resolved = resolvePercent(value, key, percentConfig) - return typeof resolved === 'number' ? resolved : 0 - } else { - const formatted = global.__formatValue(value) - if (typeof formatted === 'number') { - return formatted + // traverse env & calc & percent + traverseStyle(normalStyle, [envVisitor, percentVisitor, calcVisitor]) + + const percentConfig = { + width, + height, + fontSize: normalStyle.fontSize, + parentWidth, + parentHeight, + parentFontSize + } + + // apply env + transformEnv(normalStyle, envKeyPaths) + // apply percent + transformPercent(normalStyle, percentKeyPaths, percentConfig) + // apply calc + transformCalc(normalStyle, calcKeyPaths, (value: string, key: string) => { + if (PERCENT_REGEX.test(value)) { + const resolved = resolvePercent(value, key, percentConfig) + return typeof resolved === 'number' ? resolved : 0 } else { - warn('calc() only support number, px, rpx, % temporarily.') - return 0 + const formatted = global.__formatValue(value) + if (typeof formatted === 'number') { + return formatted + } else { + warn('calc() only support number, px, rpx, % temporarily.') + return 0 + } } + }) + // transform number enum stringify + transformStringify(normalStyle) + + return { + normalStyle, + hasSelfPercent } - }) - // transform number enum stringify - transformStringify(normalStyle) + }, [normalStyleChangedRef.current, width, height, parentWidth, parentHeight, parentFontSize]) - return { - normalStyle, - hasSelfPercent, + return extendObject({ hasVarDec, - enableVarRef, varContextRef, setWidth, setHeight - } + }, memoResult) } export interface VisitorArg { @@ -565,7 +595,7 @@ export const useStableCallback = ( } export const usePrevious = (value: T): T | undefined => { - const ref = useRef(undefined) + const ref = useRef() const prev = ref.current ref.current = value return prev From f4715f2f4322354a7501f4e414ac866cb8bcc104 Mon Sep 17 00:00:00 2001 From: wenwen Date: Thu, 2 Jan 2025 16:41:58 +0800 Subject: [PATCH 32/45] =?UTF-8?q?fix=20rule=20opacity=200=20=E5=8F=96?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E5=80=BC0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runtime/components/react/useAnimationHooks.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts index d2fe90334e..71a41f5379 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/useAnimationHooks.ts @@ -240,14 +240,13 @@ export default function useAnimationHooks (props: _ViewProps) { } // 添加每个key的多次step动画 animatedKeys.forEach(key => { + const ruleV = isTransform(key) ? transform.get(key) : rules.get(key) // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的 - const toVal = rules.get(key) !== undefined - ? rules.get(key) - : transform.get(key) !== undefined - ? transform.get(key) - : index > 0 - ? lastValueMap[key] - : shareValMap[key].value + const toVal = ruleV !== undefined + ? ruleV + : index > 0 + ? lastValueMap[key] + : shareValMap[key].value const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined) needSetCallback = false if (!sequence[key]) { From b7abd2b10542d6df3d8c2d11fc97db11ac597c93 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 2 Jan 2025 20:10:50 +0800 Subject: [PATCH 33/45] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3clientX=E3=80=81?= =?UTF-8?q?clientY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 18 ++++++++++-------- .../react/types/getInnerListeners.ts | 2 ++ .../runtime/components/react/types/global.d.ts | 6 ++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 10f0ae1301..7ab88af149 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,5 +1,5 @@ import { useRef, useMemo, RefObject } from 'react' -import { hasOwn, collectDataset } from '@mpxjs/utils' +import { hasOwn, collectDataset, getFocusedNavigation } from '@mpxjs/utils' import { omit, extendObject } from './utils' import eventConfigMap from './event.config' import { @@ -19,6 +19,8 @@ const getTouchEvent = ( props: Props, config: UseInnerPropsConfig ) => { + const navigation = getFocusedNavigation() + const { y: navigationY = 0 } = navigation?.layout || {} const nativeEvent = event.nativeEvent const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent const { id } = props @@ -49,24 +51,24 @@ const getTouchEvent = ( target, detail: { x: pageX, - y: pageY + y: pageY - navigationY }, touches: touches.map((item) => { return { identifier: item.identifier, pageX: item.pageX, - pageY: item.pageY, - clientX: item.locationX, - clientY: item.locationY + pageY: item.pageY - navigationY, + clientX: nativeEvent.screenX, + clientY: nativeEvent.screenY - navigationY } }), changedTouches: changedTouches.map((item) => { return { identifier: item.identifier, pageX: item.pageX, - pageY: item.pageY, - clientX: item.locationX, - clientY: item.locationY + pageY: item.pageY - navigationY, + clientX: nativeEvent.screenX, + clientY: nativeEvent.screenY - navigationY } }), persist: event.persist, diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index 78df219009..f097cc0260 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -14,6 +14,8 @@ type RemoveProps = string[]; type NativeTouchEvent = NativeSyntheticEvent interface NativeEvent { + screenY: any + screenX: any timestamp: number; pageX: number; pageY: number; diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts index 052fc1ac56..342059df0e 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts @@ -20,6 +20,12 @@ declare module '@mpxjs/utils' { left: number right: number }, + layout: { + x: number + y: number + width: number + height: number + }, setOptions: (params: Record) => void } | undefined } From 1c8b7f8833e851fb761b59d2ce2da916ed28e461 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 2 Jan 2025 20:57:11 +0800 Subject: [PATCH 34/45] fix: lint --- .../webpack-plugin/lib/runtime/components/react/mpx-view.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx index ce151951f7..9939bff0a1 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx @@ -551,7 +551,7 @@ function inheritStyle (innerStyle: ExtendedViewStyle = {}) { : undefined) } -function WrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record, enableFastImage?: boolean) { +function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record, enableFastImage?: boolean) { // 预处理数据 const preImageInfo: PreImageInfo = preParseImage(imageStyle) // 预解析 @@ -660,7 +660,8 @@ function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, tex }) return [ - enableBackground ? WrapImage(backgroundStyle, innerStyle, enableFastImage) : null, + // eslint-disable-next-line react-hooks/rules-of-hooks + enableBackground ? useWrapImage(backgroundStyle, innerStyle, enableFastImage) : null, children ] } From 3f65f98cd55a3f16e6b54c7ceceb1d3de8b30c50 Mon Sep 17 00:00:00 2001 From: xuegan Date: Fri, 3 Jan 2025 11:33:14 +0800 Subject: [PATCH 35/45] =?UTF-8?q?fix:=20=E8=BE=93=E5=87=BAali=E5=8C=85?= =?UTF-8?q?=E8=A3=B9root-view=20virtualHost=E5=88=A4=E6=96=AD=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/webpack-plugin/lib/template-compiler/compiler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webpack-plugin/lib/template-compiler/compiler.js b/packages/webpack-plugin/lib/template-compiler/compiler.js index 022d5fc01a..2c565454b5 100644 --- a/packages/webpack-plugin/lib/template-compiler/compiler.js +++ b/packages/webpack-plugin/lib/template-compiler/compiler.js @@ -2713,14 +2713,14 @@ function closeElement (el, options, meta) { if (!isTemplate) { if (!isNative) { postProcessComponentIs(el, (child) => { - if (!hasVirtualHost && mode === 'ali') { + if (!getComponentInfo(el).hasVirtualHost && mode === 'ali') { postProcessAliComponentRootView(child, options) } else { postProcessIf(child) } }) } - if (isComponentNode(el) && !hasVirtualHost && mode === 'ali' && el.tag !== 'component') { + if (isComponentNode(el) && !getComponentInfo(el).hasVirtualHost && mode === 'ali' && el.tag !== 'component') { postProcessAliComponentRootView(el, options, meta) } } From ad8f04de95865ffc2b50b8c0a7f87b5952fb8647 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Fri, 3 Jan 2025 11:45:32 +0800 Subject: [PATCH 36/45] v2.9.70 --- lerna.json | 2 +- packages/api-proxy/package.json | 4 ++-- packages/core/package.json | 8 ++++---- packages/fetch/package.json | 6 +++--- packages/pinia/package.json | 4 ++-- packages/store/package.json | 4 ++-- packages/utils/package.json | 2 +- packages/webpack-plugin/package.json | 8 ++++---- packages/webview-bridge/package.json | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lerna.json b/lerna.json index fa9f091534..edc1456c92 100644 --- a/lerna.json +++ b/lerna.json @@ -1,3 +1,3 @@ { - "version": "2.9.69" + "version": "2.9.70" } \ No newline at end of file diff --git a/packages/api-proxy/package.json b/packages/api-proxy/package.json index b4dd0a5985..780291bace 100644 --- a/packages/api-proxy/package.json +++ b/packages/api-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/api-proxy", - "version": "2.9.69", + "version": "2.9.70", "description": "convert miniprogram API at each end", "module": "src/index.js", "types": "@types/index.d.ts", @@ -37,7 +37,7 @@ }, "homepage": "https://github.com/didi/mpx#readme", "dependencies": { - "@mpxjs/utils": "^2.9.69", + "@mpxjs/utils": "^2.9.70", "axios": "^1.7.3" }, "peerDependencies": { diff --git a/packages/core/package.json b/packages/core/package.json index 5e0a073d0d..4c7dea508a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/core", - "version": "2.9.69", + "version": "2.9.70", "description": "mpx runtime core", "keywords": [ "miniprogram", @@ -19,7 +19,7 @@ ], "main": "src/index.js", "dependencies": { - "@mpxjs/utils": "^2.9.69", + "@mpxjs/utils": "^2.9.70", "lodash": "^4.1.1", "miniprogram-api-typings": "^3.10.0" }, @@ -30,9 +30,9 @@ "@mpxjs/store": "^2.9.0", "@react-navigation/native": "^7.0.3", "@react-navigation/stack": "^7.0.4", + "promise": "^8.3.0", "react": "*", "react-native": "*", - "promise": "^8.3.0", "react-native-gesture-handler": "^2.19.0", "react-native-linear-gradient": "^2.8.3", "react-native-safe-area-context": "^4.14.0", @@ -110,4 +110,4 @@ }, "sideEffects": false, "gitHead": "2d37697869b9bdda3efab92dda8c910b68fd05c0" -} \ No newline at end of file +} diff --git a/packages/fetch/package.json b/packages/fetch/package.json index 9aeaeaf9c7..9cccf50069 100644 --- a/packages/fetch/package.json +++ b/packages/fetch/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/fetch", - "version": "2.9.69", + "version": "2.9.70", "description": "mpx fetch lib", "author": "donghongping", "license": "Apache-2.0", @@ -29,8 +29,8 @@ "test": "echo \"Error: run tests from root\" && exit 1" }, "dependencies": { - "@mpxjs/api-proxy": "^2.9.69", - "@mpxjs/utils": "^2.9.69", + "@mpxjs/api-proxy": "^2.9.70", + "@mpxjs/utils": "^2.9.70", "path-to-regexp": "^6.2.0" }, "gitHead": "2d37697869b9bdda3efab92dda8c910b68fd05c0" diff --git a/packages/pinia/package.json b/packages/pinia/package.json index af0f442b15..08918eb462 100644 --- a/packages/pinia/package.json +++ b/packages/pinia/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/pinia", - "version": "2.9.69", + "version": "2.9.70", "description": "A pinia style store in miniprogram", "types": "@types/index.d.ts", "main": "src/index.js", @@ -31,7 +31,7 @@ "access": "public" }, "dependencies": { - "@mpxjs/utils": "^2.9.69" + "@mpxjs/utils": "^2.9.70" }, "peerDependencies": { "@mpxjs/core": "^2.9.0", diff --git a/packages/store/package.json b/packages/store/package.json index 47570130a4..d25bad9199 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/store", - "version": "2.9.69", + "version": "2.9.70", "description": "A store for mpx framework", "main": "src/index.js", "types": "@types/index.d.ts", @@ -26,7 +26,7 @@ }, "homepage": "https://github.com/didi/mpx#readme", "dependencies": { - "@mpxjs/utils": "^2.9.69" + "@mpxjs/utils": "^2.9.70" }, "peerDependencies": { "@mpxjs/core": "^2.9.0" diff --git a/packages/utils/package.json b/packages/utils/package.json index 60fc5904bd..2a526fa8b8 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/utils", - "version": "2.9.69", + "version": "2.9.70", "description": "A toolkit for mpx framework", "main": "src/index.js", "scripts": { diff --git a/packages/webpack-plugin/package.json b/packages/webpack-plugin/package.json index 84291a684d..f8aa7f321a 100644 --- a/packages/webpack-plugin/package.json +++ b/packages/webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/webpack-plugin", - "version": "2.9.69", + "version": "2.9.70", "description": "mpx compile core", "keywords": [ "mpx" @@ -28,7 +28,7 @@ "@better-scroll/wheel": "^2.5.1", "@better-scroll/zoom": "^2.5.1", "@mpxjs/template-engine": "^2.8.7", - "@mpxjs/utils": "^2.9.69", + "@mpxjs/utils": "^2.9.70", "acorn": "^8.11.3", "acorn-walk": "^7.2.0", "async": "^2.6.0", @@ -83,7 +83,7 @@ "devDependencies": { "@ant-design/react-native": "^5.2.2", "@d11/react-native-fast-image": "^8.6.12", - "@mpxjs/api-proxy": "^2.9.69", + "@mpxjs/api-proxy": "^2.9.70", "@types/babel-traverse": "^6.25.4", "@types/babel-types": "^7.0.4", "@types/react": "^18.2.79", @@ -91,8 +91,8 @@ "react-native-gesture-handler": "^2.18.1", "react-native-linear-gradient": "^2.8.3", "react-native-reanimated": "^3.15.2", - "react-native-svg": "^15.8.0", "react-native-safe-area-context": "^4.12.0", + "react-native-svg": "^15.8.0", "react-native-webview": "^13.12.2", "rimraf": "^6.0.1" }, diff --git a/packages/webview-bridge/package.json b/packages/webview-bridge/package.json index 598255d24a..e966417c8f 100644 --- a/packages/webview-bridge/package.json +++ b/packages/webview-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/webview-bridge", - "version": "2.9.58", + "version": "2.9.70", "description": "a bridge for mpx webview", "author": "skyadmin", "license": "ISC", From 677ed7180ba94fe04faa83e602e73bb19c2058ed Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 13:09:04 +0800 Subject: [PATCH 37/45] =?UTF-8?q?fix:=20longpress=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E8=AF=AF=E8=A7=A6=E5=8F=91=E5=A4=96=E5=B1=82tap=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 23 +++++++++++-------- .../react/types/getInnerListeners.ts | 4 ---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 7ab88af149..e1dd395e20 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -13,6 +13,10 @@ import { NativeTouchEvent } from './types/getInnerListeners' +const globalEventState = { + needPress: true +} + const getTouchEvent = ( type: string, event: NativeTouchEvent, @@ -113,7 +117,11 @@ function handleEmitEvent ( if (propsRef.current[event]) { const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event) if (match) { - oe.stopPropagation() + const eventType = match[2] + if ((eventType === 'tap' && type === 'tap') || + (eventType.startsWith('touch') && type === eventType)) { + oe.stopPropagation() + } } propsRef.current[event]( getTouchEvent(type, oe, propsRef.current, config) @@ -131,7 +139,7 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1 ) { - ref.current!.needPress[type] = false + globalEventState.needPress = false ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null @@ -151,7 +159,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: 'capture-bindlongpress' ] ref.current!.startTimer[type] = null - ref.current!.needPress[type] = true + globalEventState.needPress = true const nativeEvent = e.nativeEvent ref.current!.mpxPressInfo.detail = { x: nativeEvent.changedTouches[0].pageX, @@ -175,7 +183,8 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: captureBindlongpress ) { ref.current!.startTimer[type] = setTimeout(() => { - ref.current!.needPress[type] = false + // 只要触发过longpress, 全局就不再触发tap + globalEventState.needPress = false handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config) }, 350) } @@ -211,7 +220,7 @@ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: R clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config) - if (ref.current!.needPress[type]) { + if (globalEventState.needPress) { if (type === 'bubble' && config.disableTap) { return } @@ -275,10 +284,6 @@ const useInnerProps = ( bubble: null, capture: null }, - needPress: { - bubble: false, - capture: false - }, mpxPressInfo: { detail: { x: 0, diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index f097cc0260..5d1d767c42 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -38,10 +38,6 @@ interface InnerRef { bubble: null | ReturnType; capture: null | ReturnType; }; - needPress: { - bubble: boolean; - capture: boolean; - }; mpxPressInfo: { detail: { x: number; From 860ba6261ef901cf448bd5713f6eec96b92427fb Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 13:19:56 +0800 Subject: [PATCH 38/45] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/getInnerListeners.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index e1dd395e20..24a4305928 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -117,11 +117,7 @@ function handleEmitEvent ( if (propsRef.current[event]) { const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event) if (match) { - const eventType = match[2] - if ((eventType === 'tap' && type === 'tap') || - (eventType.startsWith('touch') && type === eventType)) { - oe.stopPropagation() - } + oe.stopPropagation() } propsRef.current[event]( getTouchEvent(type, oe, propsRef.current, config) From 1bfeb6d83cfaaa69dc8f500e14a0571dae990e75 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 14:59:10 +0800 Subject: [PATCH 39/45] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96getFocusedNavi?= =?UTF-8?q?gation=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 61 +++++++++++-------- .../react/types/getInnerListeners.ts | 9 ++- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 24a4305928..7c75b9dea0 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,4 +1,4 @@ -import { useRef, useMemo, RefObject } from 'react' +import { useRef, useMemo, RefObject, useEffect } from 'react' import { hasOwn, collectDataset, getFocusedNavigation } from '@mpxjs/utils' import { omit, extendObject } from './utils' import eventConfigMap from './event.config' @@ -10,7 +10,8 @@ import { InnerRef, SetTimeoutReturnType, LayoutRef, - NativeTouchEvent + NativeTouchEvent, + NavigationLayout } from './types/getInnerListeners' const globalEventState = { @@ -21,10 +22,10 @@ const getTouchEvent = ( type: string, event: NativeTouchEvent, props: Props, - config: UseInnerPropsConfig + config: UseInnerPropsConfig, + navigationLayout: NavigationLayout ) => { - const navigation = getFocusedNavigation() - const { y: navigationY = 0 } = navigation?.layout || {} + const { y: navigationY = 0 } = navigationLayout.current const nativeEvent = event.nativeEvent const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent const { id } = props @@ -62,8 +63,8 @@ const getTouchEvent = ( identifier: item.identifier, pageX: item.pageX, pageY: item.pageY - navigationY, - clientX: nativeEvent.screenX, - clientY: nativeEvent.screenY - navigationY + clientX: item.pageX, + clientY: item.pageY - navigationY } }), changedTouches: changedTouches.map((item) => { @@ -71,8 +72,8 @@ const getTouchEvent = ( identifier: item.identifier, pageX: item.pageX, pageY: item.pageY - navigationY, - clientX: nativeEvent.screenX, - clientY: nativeEvent.screenY - navigationY + clientX: item.pageX, + clientY: item.pageY - navigationY } }), persist: event.persist, @@ -111,7 +112,8 @@ function handleEmitEvent ( type: string, oe: NativeTouchEvent, propsRef: Record, - config: UseInnerPropsConfig + config: UseInnerPropsConfig, + navigationLayout: NavigationLayout ) { events.forEach((event) => { if (propsRef.current[event]) { @@ -120,7 +122,7 @@ function handleEmitEvent ( oe.stopPropagation() } propsRef.current[event]( - getTouchEvent(type, oe, propsRef.current, config) + getTouchEvent(type, oe, propsRef.current, config, navigationLayout) ) } }) @@ -142,7 +144,7 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: } } -function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) { +function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { e.persist() const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart'] const bubblePressEvent = ['catchlongpress', 'bindlongpress'] @@ -165,7 +167,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: type === 'bubble' ? bubbleTouchEvent : captureTouchEvent const currentPressEvent = type === 'bubble' ? bubblePressEvent : capturePressEvent - handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigationLayout) const { catchlongpress, bindlongpress, @@ -181,12 +183,12 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ref.current!.startTimer[type] = setTimeout(() => { // 只要触发过longpress, 全局就不再触发tap globalEventState.needPress = false - handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config) + handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigationLayout) }, 350) } } -function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) { +function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove'] const captureTouchEvent = [ 'capture-catchtouchmove', @@ -194,11 +196,11 @@ function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ] const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent - handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigationLayout) checkIsNeedPress(e, type, ref) } -function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) { +function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { // move event may not be triggered checkIsNeedPress(e, type, ref) const bubbleTouchEvent = ['catchtouchend', 'bindtouchend'] @@ -215,19 +217,22 @@ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: R ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigationLayout) if (globalEventState.needPress) { if (type === 'bubble' && config.disableTap) { return } - handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config) + handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigationLayout) } } function handleTouchcancel ( e: NativeTouchEvent, type: 'bubble' | 'capture', - ref: RefObject, propsRef: Record, config: UseInnerPropsConfig + ref: RefObject, + propsRef: Record, + config: UseInnerPropsConfig, + navigationLayout: NavigationLayout ) { const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel'] const captureTouchEvent = [ @@ -239,11 +244,11 @@ function handleTouchcancel ( ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigationLayout) } function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTouchEnd'|'onTouchCancel', type: 'bubble' | 'capture') { - return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) => { + return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) => { const handlerMap = { onTouchStart: handleTouchstart, onTouchMove: handleTouchmove, @@ -253,7 +258,7 @@ function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTou const handler = handlerMap[eventName] if (handler) { - handler(e, type, ref, propsRef, config) + handler(e, type, ref, propsRef, config, navigationLayout) } } } @@ -294,6 +299,8 @@ const useInnerProps = ( layoutRef: { current: {} }, disableTap: false } + const navigationLayout = useRef({ x: 0, y: 0, width: 0, height: 0 }) + const removeProps = [ 'children', 'enable-background', @@ -319,6 +326,12 @@ const useInnerProps = ( } } + useEffect(() => { + setTimeout(() => { + navigationLayout.current = getFocusedNavigation()?.layout || { x: 0, y: 0, width: 0, height: 0 } + }) + }, []) + const events = useMemo(() => { if (!rawEventKeys.length) { return {} @@ -335,7 +348,7 @@ const useInnerProps = ( touchEventList.forEach((item) => { if (finalEventKeys.includes(item.eventName)) { events[item.eventName] = (e: NativeTouchEvent) => - item.handler(e, ref, propsRef, config) + item.handler(e, ref, propsRef, config, navigationLayout) } }) diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index 5d1d767c42..f293714327 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -13,6 +13,12 @@ type RemoveProps = string[]; type NativeTouchEvent = NativeSyntheticEvent +type NavigationLayout = MutableRefObject<{ + x: number; + y: number; + width: number; + height: number; +}> interface NativeEvent { screenY: any screenX: any @@ -63,5 +69,6 @@ export { InnerRef, LayoutRef, SetTimeoutReturnType, - DataSetType + DataSetType, + NavigationLayout } From d02e08109062c10966d018b15097d8f445c4f3a5 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 15:04:24 +0800 Subject: [PATCH 40/45] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8ts=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/types/getInnerListeners.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index f293714327..f774446871 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -20,8 +20,6 @@ type NavigationLayout = MutableRefObject<{ height: number; }> interface NativeEvent { - screenY: any - screenX: any timestamp: number; pageX: number; pageY: number; From d9e7dca5783910813ad8a6ed61a5b63b381820f3 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 17:17:51 +0800 Subject: [PATCH 41/45] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9Navigation?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 47 +++++++++---------- .../react/types/getInnerListeners.ts | 9 +--- .../components/react/types/global.d.ts | 4 ++ 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 7c75b9dea0..33c0fac145 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,5 +1,6 @@ import { useRef, useMemo, RefObject, useEffect } from 'react' -import { hasOwn, collectDataset, getFocusedNavigation } from '@mpxjs/utils' +import { hasOwn, collectDataset } from '@mpxjs/utils' +import { useNavigation } from '@react-navigation/native' import { omit, extendObject } from './utils' import eventConfigMap from './event.config' import { @@ -11,7 +12,7 @@ import { SetTimeoutReturnType, LayoutRef, NativeTouchEvent, - NavigationLayout + Navigation } from './types/getInnerListeners' const globalEventState = { @@ -23,9 +24,9 @@ const getTouchEvent = ( event: NativeTouchEvent, props: Props, config: UseInnerPropsConfig, - navigationLayout: NavigationLayout + navigation: Navigation ) => { - const { y: navigationY = 0 } = navigationLayout.current + const { y: navigationY = 0 } = navigation?.layout || {} const nativeEvent = event.nativeEvent const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent const { id } = props @@ -113,7 +114,7 @@ function handleEmitEvent ( oe: NativeTouchEvent, propsRef: Record, config: UseInnerPropsConfig, - navigationLayout: NavigationLayout + navigation: Navigation ) { events.forEach((event) => { if (propsRef.current[event]) { @@ -122,7 +123,7 @@ function handleEmitEvent ( oe.stopPropagation() } propsRef.current[event]( - getTouchEvent(type, oe, propsRef.current, config, navigationLayout) + getTouchEvent(type, oe, propsRef.current, config, navigation) ) } }) @@ -144,7 +145,7 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: } } -function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { +function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) { e.persist() const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart'] const bubblePressEvent = ['catchlongpress', 'bindlongpress'] @@ -167,7 +168,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: type === 'bubble' ? bubbleTouchEvent : captureTouchEvent const currentPressEvent = type === 'bubble' ? bubblePressEvent : capturePressEvent - handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigation) const { catchlongpress, bindlongpress, @@ -183,12 +184,12 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ref.current!.startTimer[type] = setTimeout(() => { // 只要触发过longpress, 全局就不再触发tap globalEventState.needPress = false - handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigationLayout) + handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigation) }, 350) } } -function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { +function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) { const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove'] const captureTouchEvent = [ 'capture-catchtouchmove', @@ -196,11 +197,11 @@ function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ] const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent - handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigation) checkIsNeedPress(e, type, ref) } -function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { +function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) { // move event may not be triggered checkIsNeedPress(e, type, ref) const bubbleTouchEvent = ['catchtouchend', 'bindtouchend'] @@ -217,12 +218,12 @@ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: R ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigation) if (globalEventState.needPress) { if (type === 'bubble' && config.disableTap) { return } - handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigation) } } @@ -232,7 +233,7 @@ function handleTouchcancel ( ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, - navigationLayout: NavigationLayout + navigation: Navigation ) { const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel'] const captureTouchEvent = [ @@ -244,11 +245,11 @@ function handleTouchcancel ( ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigation) } function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTouchEnd'|'onTouchCancel', type: 'bubble' | 'capture') { - return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) => { + return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) => { const handlerMap = { onTouchStart: handleTouchstart, onTouchMove: handleTouchmove, @@ -258,7 +259,7 @@ function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTou const handler = handlerMap[eventName] if (handler) { - handler(e, type, ref, propsRef, config, navigationLayout) + handler(e, type, ref, propsRef, config, navigation) } } } @@ -299,7 +300,7 @@ const useInnerProps = ( layoutRef: { current: {} }, disableTap: false } - const navigationLayout = useRef({ x: 0, y: 0, width: 0, height: 0 }) + const navigation = useNavigation() const removeProps = [ 'children', @@ -326,12 +327,6 @@ const useInnerProps = ( } } - useEffect(() => { - setTimeout(() => { - navigationLayout.current = getFocusedNavigation()?.layout || { x: 0, y: 0, width: 0, height: 0 } - }) - }, []) - const events = useMemo(() => { if (!rawEventKeys.length) { return {} @@ -348,7 +343,7 @@ const useInnerProps = ( touchEventList.forEach((item) => { if (finalEventKeys.includes(item.eventName)) { events[item.eventName] = (e: NativeTouchEvent) => - item.handler(e, ref, propsRef, config, navigationLayout) + item.handler(e, ref, propsRef, config, navigation) } }) diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index f774446871..e5463c7275 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -13,12 +13,7 @@ type RemoveProps = string[]; type NativeTouchEvent = NativeSyntheticEvent -type NavigationLayout = MutableRefObject<{ - x: number; - y: number; - width: number; - height: number; -}> +type Navigation = Record interface NativeEvent { timestamp: number; pageX: number; @@ -68,5 +63,5 @@ export { LayoutRef, SetTimeoutReturnType, DataSetType, - NavigationLayout + Navigation } diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts index 342059df0e..68e417603a 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts @@ -33,3 +33,7 @@ declare module '@mpxjs/utils' { declare let global: { __formatValue (value: string): string | number } & Record + +declare module '@react-navigation/native' { + export function useNavigation (): any +} From ae9db31cbebb258b2ca8c5cb7b14ba99c7f3afa4 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Fri, 3 Jan 2025 18:02:47 +0800 Subject: [PATCH 42/45] adjust navigation in hooks --- .../components/react/getInnerListeners.ts | 2 +- .../runtime/components/react/types/common.ts | 20 ------ .../react/types/getInnerListeners.ts | 67 ------------------- .../components/react/types/global.d.ts | 2 +- .../lib/runtime/components/react/utils.tsx | 15 +++-- 5 files changed, 10 insertions(+), 96 deletions(-) delete mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/common.ts delete mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 6efc95e989..6d00a5ceba 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,4 +1,4 @@ -import { useRef, useMemo, RefObject, useEffect } from 'react' +import { useRef, useMemo, RefObject } from 'react' import { hasOwn, collectDataset } from '@mpxjs/utils' import { useNavigation } from '@react-navigation/native' import { omit, extendObject } from './utils' diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/common.ts b/packages/webpack-plugin/lib/runtime/components/react/types/common.ts deleted file mode 100644 index 716e3616c5..0000000000 --- a/packages/webpack-plugin/lib/runtime/components/react/types/common.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ViewStyle } from 'react-native' -import { FunctionComponent } from 'react' - -type NumberVal = number | `${number}%` -type backgroundPositionList = ['left' | 'right', NumberVal, 'top' | 'bottom', NumberVal] | [] - -export type ExtendedViewStyle = ViewStyle & { - backgroundImage?: string - backgroundSize?: Array - borderRadius?: string | number - backgroundPosition?: backgroundPositionList - [key: string]: any - transform?: {[key: string]: number | string}[] -} - -export type ExtendedFunctionComponent = FunctionComponent & { - isCustomText?: boolean -} - -export type AnyFunc = (...args: ReadonlyArray) => any diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts deleted file mode 100644 index e5463c7275..0000000000 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { MutableRefObject } from 'react' -import { NativeSyntheticEvent } from 'react-native' - -type LayoutRef = MutableRefObject - -type SetTimeoutReturnType = ReturnType - -type Props = Record - -type AdditionalProps = Record; - -type RemoveProps = string[]; - -type NativeTouchEvent = NativeSyntheticEvent - -type Navigation = Record -interface NativeEvent { - timestamp: number; - pageX: number; - pageY: number; - touches: TouchPoint[] - changedTouches: TouchPoint[] -} - -interface TouchPoint { - identifier: number; - pageX: number; - pageY: number; - clientX: number; - clientY: number; - locationX?: number; - locationY?: number; -} - -interface InnerRef { - startTimer: { - bubble: null | ReturnType; - capture: null | ReturnType; - }; - mpxPressInfo: { - detail: { - x: number; - y: number; - }; - }; -} -interface UseInnerPropsConfig { - layoutRef: LayoutRef; - disableTouch?: boolean; - disableTap?: boolean -} -interface DataSetType { - [key: string]: string; -} - -export { - NativeTouchEvent, - Props, - AdditionalProps, - RemoveProps, - UseInnerPropsConfig, - InnerRef, - LayoutRef, - SetTimeoutReturnType, - DataSetType, - Navigation -} diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts index 68e417603a..82d5a57476 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts @@ -35,5 +35,5 @@ declare let global: { } & Record declare module '@react-navigation/native' { - export function useNavigation (): any + export function useNavigation (): Record } diff --git a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx index 5c933aea4f..08fac95572 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx @@ -1,9 +1,10 @@ import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react' import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native' -import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils' +import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils' import { VarContext } from './context' import { ExpressionParser, parseFunc, ReplaceSource } from './parser' import { initialWindowMetrics } from 'react-native-safe-area-context' +import { useNavigation } from '@react-navigation/native' import FastImage, { FastImageProps } from '@d11/react-native-fast-image' import type { AnyFunc, ExtendedFunctionComponent } from './types/common' @@ -32,8 +33,7 @@ const safeAreaInsetMap: Record = { 'safe-area-inset-left': 'left' } -function getSafeAreaInset (name: string) { - const navigation = getFocusedNavigation() +function getSafeAreaInset (name: string, navigation: Record) { const insets = extendObject({}, initialWindowMetrics?.insets, navigation?.insets) return insets[safeAreaInsetMap[name]] } @@ -232,7 +232,7 @@ function transformVar (styleObj: Record, varKeyPaths: Array, envKeyPaths: Array>) { +function transformEnv (styleObj: Record, envKeyPaths: Array>, navigation: Record) { envKeyPaths.forEach((envKeyPath) => { setStyle(styleObj, envKeyPath, ({ target, key, value }) => { const parsed = parseFunc(value, 'env') @@ -240,7 +240,7 @@ function transformEnv (styleObj: Record, envKeyPaths: Array { const name = args[0] const fallback = args[1] || '' - const value = '' + (getSafeAreaInset(name) ?? global.__formatValue(fallback)) + const value = '' + (getSafeAreaInset(name, navigation) ?? global.__formatValue(fallback)) replaced.replace(start, end - 1, value) }) target[key] = global.__formatValue(replaced.source()) @@ -302,6 +302,7 @@ export function useTransformStyle (styleObj: Record = {}, { enableV const envKeyPaths: Array> = [] const [width, setWidth] = useState(0) const [height, setHeight] = useState(0) + const navigation = useNavigation() function varVisitor ({ key, value, keyPath }: VisitorArg) { if (keyPath.length === 1) { @@ -396,7 +397,7 @@ export function useTransformStyle (styleObj: Record = {}, { enableV } // apply env - transformEnv(normalStyle, envKeyPaths) + transformEnv(normalStyle, envKeyPaths, navigation) // apply percent transformPercent(normalStyle, percentKeyPaths, percentConfig) // apply calc @@ -595,7 +596,7 @@ export const useStableCallback = ( ) } -export const usePrevious = (value: T): T | undefined => { +export function usePrevious (value: T): T | undefined { const ref = useRef() const prev = ref.current ref.current = value From ec89f05648d2f9c192504d18bc2afc7543d1f78c Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Mon, 6 Jan 2025 12:59:03 +0800 Subject: [PATCH 43/45] add types --- .../components/react/types/common.d.ts | 20 ++++++ .../react/types/getInnerListeners.d.ts | 68 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts create mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts new file mode 100644 index 0000000000..716e3616c5 --- /dev/null +++ b/packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts @@ -0,0 +1,20 @@ +import { ViewStyle } from 'react-native' +import { FunctionComponent } from 'react' + +type NumberVal = number | `${number}%` +type backgroundPositionList = ['left' | 'right', NumberVal, 'top' | 'bottom', NumberVal] | [] + +export type ExtendedViewStyle = ViewStyle & { + backgroundImage?: string + backgroundSize?: Array + borderRadius?: string | number + backgroundPosition?: backgroundPositionList + [key: string]: any + transform?: {[key: string]: number | string}[] +} + +export type ExtendedFunctionComponent = FunctionComponent & { + isCustomText?: boolean +} + +export type AnyFunc = (...args: ReadonlyArray) => any diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts new file mode 100644 index 0000000000..317d483d62 --- /dev/null +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts @@ -0,0 +1,68 @@ +import { MutableRefObject } from 'react' +import { NativeSyntheticEvent } from 'react-native' + +type LayoutRef = MutableRefObject + +type SetTimeoutReturnType = ReturnType + +type Props = Record + +type AdditionalProps = Record; + +type RemoveProps = string[]; + +type NativeTouchEvent = NativeSyntheticEvent + +type Navigation = Record + +interface NativeEvent { + timestamp: number; + pageX: number; + pageY: number; + touches: TouchPoint[] + changedTouches: TouchPoint[] +} + +interface TouchPoint { + identifier: number; + pageX: number; + pageY: number; + clientX: number; + clientY: number; + locationX?: number; + locationY?: number; +} + +interface InnerRef { + startTimer: { + bubble: null | ReturnType; + capture: null | ReturnType; + }; + mpxPressInfo: { + detail: { + x: number; + y: number; + }; + }; +} +interface UseInnerPropsConfig { + layoutRef: LayoutRef; + disableTouch?: boolean; + disableTap?: boolean +} +interface DataSetType { + [key: string]: string; +} + +export { + NativeTouchEvent, + Props, + AdditionalProps, + RemoveProps, + UseInnerPropsConfig, + InnerRef, + LayoutRef, + SetTimeoutReturnType, + DataSetType, + Navigation +} From b8dee70155ab4ff34976e6cc09f546fd6031c223 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Wed, 8 Jan 2025 16:48:00 +0800 Subject: [PATCH 44/45] support hot launch in rn --- .../src/platform/api/system/index.web.js | 2 +- .../src/platform/api/system/rnSystem.js | 11 +--- packages/core/src/platform/createApp.ios.js | 59 ++++++++----------- packages/core/src/platform/createApp.js | 47 +++++++-------- packages/core/src/platform/export/inject.js | 5 +- .../platform/patch/getDefaultOptions.ios.js | 6 +- 6 files changed, 51 insertions(+), 79 deletions(-) diff --git a/packages/api-proxy/src/platform/api/system/index.web.js b/packages/api-proxy/src/platform/api/system/index.web.js index 2614aa2562..0e756b73d9 100644 --- a/packages/api-proxy/src/platform/api/system/index.web.js +++ b/packages/api-proxy/src/platform/api/system/index.web.js @@ -139,7 +139,7 @@ const getLaunchOptionsSync = function () { throwSSRWarning('getLaunchOptionsSync API is running in non browser environments') return } - return global.__mpxEnterOptions || {} + return global.__mpxLaunchOptions || {} } export { diff --git a/packages/api-proxy/src/platform/api/system/rnSystem.js b/packages/api-proxy/src/platform/api/system/rnSystem.js index acf3965ed9..abc0501466 100644 --- a/packages/api-proxy/src/platform/api/system/rnSystem.js +++ b/packages/api-proxy/src/platform/api/system/rnSystem.js @@ -41,18 +41,11 @@ const getWindowInfo = function () { } const getLaunchOptionsSync = function () { - const options = global.__mpxEnterOptions || {} - const { path, scene, query } = options - return { - path, - scene, - query - } + return global.__mpxLaunchOptions || {} } const getEnterOptionsSync = function () { - const result = getLaunchOptionsSync() - return result + return global.__mpxEnterOptions || {} } export { diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index b3ef722394..64123508ec 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -1,13 +1,12 @@ import transferOptions from '../core/transferOptions' import builtInKeysMap from './patch/builtInKeysMap' -import { makeMap, spreadProp, getFocusedNavigation, hasOwn, extend } from '@mpxjs/utils' +import { makeMap, spreadProp, getFocusedNavigation, hasOwn } from '@mpxjs/utils' import { mergeLifecycle } from '../convertor/mergeLifecycle' import { LIFECYCLE } from '../platform/patch/lifecycle/index' import Mpx from '../index' import { createElement, memo, useRef, useEffect } from 'react' import * as ReactNative from 'react-native' import { Image } from 'react-native' -import { ref } from '../observer/ref' const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app) @@ -30,22 +29,24 @@ function filterOptions (options, appData) { return newOptions } -function createAppInstance (appData) { - return extend({}, Mpx.prototype, appData) -} - -export default function createApp (option, config = {}) { +export default function createApp (options) { const appData = {} const { NavigationContainer, createStackNavigator, SafeAreaProvider } = global.__navigationHelper // app选项目前不需要进行转换 - const { rawOptions, currentInject } = transferOptions(option, 'app', false) + const { rawOptions, currentInject } = transferOptions(options, 'app', false) const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData) - defaultOptions.onAppInit && defaultOptions.onAppInit() // 在页面script执行前填充getApp() global.getApp = function () { return appData } + + defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData)) + defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData)) + defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData)) + defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData)) + defaultOptions.onAppInit && defaultOptions.onAppInit() + const pages = currentInject.getPages() || {} const firstPage = currentInject.firstPage const Stack = createStackNavigator() @@ -82,55 +83,43 @@ export default function createApp (option, config = {}) { } global.__mpxAppLaunched = false - - global.__mpxAppFocusedState = ref('show') + global.__mpxAppHotLaunched = false global.__mpxOptionsMap[currentInject.moduleId] = memo((props) => { - const instanceRef = useRef(null) - if (!instanceRef.current) { - instanceRef.current = createAppInstance(appData) - } - const instance = instanceRef.current const initialRouteRef = useRef({ initialRouteName: firstPage, initialParams: {} }) - if (!global.__mpxAppLaunched) { + if (!global.__mpxAppHotLaunched) { const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {} initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName initialRouteRef.current.initialParams = initialParams || initialRouteRef.current.initialParams global.__mpxAppOnLaunch = (navigation) => { - global.__mpxAppLaunched = true const state = navigation.getState() Mpx.config.rnConfig.onStateChange?.(state) const current = state.routes[state.index] - global.__mpxEnterOptions = { + const options = { path: current.name, query: current.params, scene: 0, shareTicket: '', referrerInfo: {} } - defaultOptions.onLaunch && defaultOptions.onLaunch.call(instance, global.__mpxEnterOptions) - defaultOptions.onShow && defaultOptions.onShow.call(instance, global.__mpxEnterOptions) + global.__mpxEnterOptions = options + if (!global.__mpxAppLaunched) { + global.__mpxLaunchOptions = options + defaultOptions.onLaunch && defaultOptions.onLaunch.call(appData, options) + } + global.__mpxAppCbs.show.forEach((cb) => { + cb(options) + }) + global.__mpxAppLaunched = true + global.__mpxAppHotLaunched = true } } useEffect(() => { - if (defaultOptions.onShow) { - global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(instance)) - } - if (defaultOptions.onHide) { - global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(instance)) - } - if (defaultOptions.onError) { - global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance)) - } - if (defaultOptions.onUnhandledRejection) { - global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(instance)) - } - const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => { if (currentState === 'active') { let options = global.__mpxEnterOptions @@ -177,6 +166,8 @@ export default function createApp (option, config = {}) { return () => { changeSubscription && changeSubscription.remove() resizeSubScription && resizeSubScription.remove() + // 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行 + global.__mpxAppHotLaunched = false } }, []) diff --git a/packages/core/src/platform/createApp.js b/packages/core/src/platform/createApp.js index 0f35cf97e5..e953d40b86 100644 --- a/packages/core/src/platform/createApp.js +++ b/packages/core/src/platform/createApp.js @@ -24,19 +24,19 @@ function filterOptions (options, appData) { return newOptions } -export default function createApp (option, config = {}) { - // 在App中挂载mpx对象供周边工具访问,如e2e测试 +export default function createApp (options, config = {}) { + const appData = {} + // app选项目前不需要进行转换 + const { rawOptions, currentInject } = transferOptions(options, 'app', false) const builtInMixins = [{ + // 在App中挂载mpx对象供周边工具访问,如e2e测试 getMpx () { return Mpx } }] - const appData = {} if (__mpx_mode__ === 'web') { builtInMixins.push({ created () { - Object.assign(this, Mpx.prototype) - Object.assign(this, appData) const current = this.$root.$options?.router?.currentRoute || {} const options = { path: current.path && current.path.replace(/^\//, ''), @@ -45,48 +45,41 @@ export default function createApp (option, config = {}) { shareTicket: '', referrerInfo: {} } + // web不分冷启动和热启动 global.__mpxEnterOptions = options - this.$options.onLaunch && this.$options.onLaunch.call(this, options) - if (isBrowser) { - if (this.$options.onShow) { - this.$options.onShow.call(this, options) - global.__mpxAppCbs.show.push(this.$options.onShow.bind(this)) - } - if (this.$options.onHide) { - global.__mpxAppCbs.hide.push(this.$options.onHide.bind(this)) - } - if (this.$options.onError) { - global.__mpxAppCbs.error.push(this.$options.onError.bind(this)) - } - if (this.$options.onUnhandledRejection) { - global.__mpxAppCbs.rejection.push(this.$options.onUnhandledRejection.bind(this)) - } - } + global.__mpxLaunchOptions = options + rawOptions.onLaunch && rawOptions.onLaunch.call(appData, options) + global.__mpxAppCbs.show.forEach((cb) => { + cb(options) + }) } }) } else { builtInMixins.push({ onLaunch () { - Object.assign(this, Mpx.prototype) + initAppProvides(rawOptions.provide, this) } }) } - // app选项目前不需要进行转换 - const { rawOptions, currentInject } = transferOptions(option, 'app', false) rawOptions.mixins = builtInMixins const defaultOptions = filterOptions(spreadProp(mergeOptions(rawOptions, 'app', false), 'methods'), appData) if (__mpx_mode__ === 'web') { - global.__mpxOptionsMap = global.__mpxOptionsMap || {} - global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions global.getApp = function () { if (!isBrowser) { console.error('[Mpx runtime error]: Dangerous API! global.getApp method is running in non browser environments') } return appData } + if (isBrowser) { + defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData)) + defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData)) + defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData)) + defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData)) + } + global.__mpxOptionsMap = global.__mpxOptionsMap || {} + global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions } else { - initAppProvides(rawOptions) defaultOptions.onAppInit && defaultOptions.onAppInit() const ctor = config.customCtor || global.currentCtor || App ctor(defaultOptions) diff --git a/packages/core/src/platform/export/inject.js b/packages/core/src/platform/export/inject.js index ea73092074..bc387994d0 100644 --- a/packages/core/src/platform/export/inject.js +++ b/packages/core/src/platform/export/inject.js @@ -11,11 +11,10 @@ const providesMap = { global.__mpxProvidesMap = providesMap /** @internal createApp() 初始化应用层 scope provide */ -export function initAppProvides (appOptions) { - const provideOpt = appOptions.provide +export function initAppProvides (provideOpt, instance) { if (provideOpt) { const provided = isFunction(provideOpt) - ? callWithErrorHandling(provideOpt.bind(appOptions), appOptions, 'createApp provide function') + ? callWithErrorHandling(provideOpt.bind(instance), instance, 'createApp provide function') : provideOpt if (isObject(provided)) { providesMap.__app = provided diff --git a/packages/core/src/platform/patch/getDefaultOptions.ios.js b/packages/core/src/platform/patch/getDefaultOptions.ios.js index ac4c5c7561..0189823b53 100644 --- a/packages/core/src/platform/patch/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/getDefaultOptions.ios.js @@ -365,14 +365,10 @@ function usePageStatus (navigation, pageId) { const blurSubscription = navigation.addListener('blur', () => { pageStatusMap[pageId] = 'hide' }) - const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => { - pageStatusMap[pageId] = value - }) return () => { focusSubscription() blurSubscription() - unWatchAppFocusedState() del(pageStatusMap, pageId) } }, [navigation]) @@ -442,7 +438,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { useEffect(() => { if (type === 'page') { - if (!global.__mpxAppLaunched && global.__mpxAppOnLaunch) { + if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) { global.__mpxAppOnLaunch(props.navigation) } proxy.callHook(ONLOAD, [props.route.params || {}]) From 53b8e0850298f5f5e7b69d69785eca2196743a78 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Wed, 8 Jan 2025 17:16:19 +0800 Subject: [PATCH 45/45] fix web app provide --- packages/core/src/platform/createApp.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/platform/createApp.js b/packages/core/src/platform/createApp.js index e953d40b86..f3e847cb61 100644 --- a/packages/core/src/platform/createApp.js +++ b/packages/core/src/platform/createApp.js @@ -36,6 +36,10 @@ export default function createApp (options, config = {}) { }] if (__mpx_mode__ === 'web') { builtInMixins.push({ + beforeCreate () { + // for vue provide vm access + Object.assign(this, appData) + }, created () { const current = this.$root.$options?.router?.currentRoute || {} const options = {