@mpxjs/webpack-plugin 2.10.7-beta.4 → 2.10.7-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/file-loader.js +1 -1
- package/lib/index.js +8 -35
- package/lib/platform/json/wx/index.js +25 -43
- package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
- package/lib/platform/template/wx/index.js +1 -2
- package/lib/react/index.js +1 -3
- package/lib/react/processJSON.js +17 -72
- package/lib/react/processScript.js +3 -4
- package/lib/react/script-helper.js +18 -92
- package/lib/runtime/components/react/AsyncContainer.tsx +7 -35
- package/lib/runtime/components/react/dist/AsyncContainer.jsx +4 -23
- package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +28 -14
- package/lib/runtime/components/react/dist/useAnimationHooks.js +87 -2
- package/lib/runtime/components/react/getInnerListeners.ts +1 -1
- package/lib/runtime/components/react/mpx-movable-view.tsx +2 -2
- package/lib/runtime/components/react/mpx-web-view.tsx +33 -13
- package/lib/runtime/components/react/types/global.d.ts +0 -15
- package/lib/runtime/components/react/useAnimationHooks.ts +85 -2
- package/lib/template-compiler/compiler.js +1 -1
- package/lib/utils/dom-tag-config.js +3 -17
- package/lib/web/script-helper.js +1 -1
- package/package.json +1 -1
- package/lib/react/LoadAsyncChunkModule.js +0 -68
- package/lib/runtime/components/react/AsyncSuspense.tsx +0 -81
- package/lib/runtime/components/react/dist/AsyncSuspense.jsx +0 -68
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import { Component, Suspense } from 'react';
|
|
2
2
|
import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native';
|
|
3
3
|
import FastImage from '@d11/react-native-fast-image';
|
|
4
|
-
import Animated, { useAnimatedStyle } from 'react-native-reanimated';
|
|
5
|
-
export const PageWrapper = ({ children }) => {
|
|
6
|
-
const animatedStyle = useAnimatedStyle(() => ({
|
|
7
|
-
transform: [{ translateY: -0 }],
|
|
8
|
-
flexBasis: 'auto',
|
|
9
|
-
flex: 1
|
|
10
|
-
}));
|
|
11
|
-
return (<Animated.View style={[
|
|
12
|
-
animatedStyle
|
|
13
|
-
]}>
|
|
14
|
-
{children}
|
|
15
|
-
</Animated.View>);
|
|
16
|
-
};
|
|
17
4
|
const styles = StyleSheet.create({
|
|
18
5
|
container: {
|
|
19
6
|
flex: 1,
|
|
@@ -63,12 +50,12 @@ const styles = StyleSheet.create({
|
|
|
63
50
|
textAlign: 'center'
|
|
64
51
|
}
|
|
65
52
|
});
|
|
66
|
-
|
|
53
|
+
const DefaultLoading = () => {
|
|
67
54
|
return (<View style={styles.container}>
|
|
68
55
|
<FastImage style={styles.loadingImage} source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/439jiCVOtNOnEv9F2LaDs_loading.gif' }} resizeMode={FastImage.resizeMode.contain}></FastImage>
|
|
69
56
|
</View>);
|
|
70
57
|
};
|
|
71
|
-
|
|
58
|
+
const DefaultFallback = ({ onReload }) => {
|
|
72
59
|
return (<View style={styles.container}>
|
|
73
60
|
<Image source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/Vak5mZvezPpKV5ZJI6P9b_drn-fallbak.png' }} style={styles.errorImage} resizeMode="contain"/>
|
|
74
61
|
<Text style={styles.errorText}>网络出了点问题,请查看网络环境</Text>
|
|
@@ -143,17 +130,11 @@ export default class AsyncContainer extends Component {
|
|
|
143
130
|
}
|
|
144
131
|
render() {
|
|
145
132
|
if (this.state.hasError) {
|
|
146
|
-
|
|
147
|
-
return this.errorFallback;
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
return (<PageWrapper>{this.errorFallback}</PageWrapper>);
|
|
151
|
-
}
|
|
133
|
+
return this.errorFallback;
|
|
152
134
|
}
|
|
153
135
|
else {
|
|
154
136
|
return (<Suspense fallback={this.suspenseFallback} key={this.state.key}>
|
|
155
|
-
{
|
|
156
|
-
{/* {this.props.children(this.props.props)} */}
|
|
137
|
+
{this.props.children(this.props.props)}
|
|
157
138
|
</Suspense>);
|
|
158
139
|
}
|
|
159
140
|
}
|
|
@@ -8,7 +8,7 @@ const globalEventState = {
|
|
|
8
8
|
const getTouchEvent = (type, event, config) => {
|
|
9
9
|
const { navigation, propsRef, layoutRef } = config;
|
|
10
10
|
const props = propsRef.current;
|
|
11
|
-
const {
|
|
11
|
+
const { y: navigationY = 0 } = navigation?.layout || {};
|
|
12
12
|
const nativeEvent = event.nativeEvent;
|
|
13
13
|
const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent;
|
|
14
14
|
const { id } = props;
|
|
@@ -233,14 +233,14 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
233
233
|
setHeight(height || 0);
|
|
234
234
|
}
|
|
235
235
|
nodeRef.current?.measure((x, y, width, height) => {
|
|
236
|
-
const {
|
|
236
|
+
const { y: navigationY = 0 } = navigation?.layout || {};
|
|
237
237
|
layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 };
|
|
238
238
|
resetBoundaryAndCheck({ width, height });
|
|
239
239
|
});
|
|
240
240
|
props.onLayout && props.onLayout(e);
|
|
241
241
|
};
|
|
242
242
|
const extendEvent = useCallback((e, type) => {
|
|
243
|
-
const {
|
|
243
|
+
const { y: navigationY = 0 } = navigation?.layout || {};
|
|
244
244
|
const touchArr = [e.changedTouches, e.allTouches];
|
|
245
245
|
touchArr.forEach(touches => {
|
|
246
246
|
touches && touches.forEach((item) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { forwardRef, useRef, useContext, useMemo, useState } from 'react';
|
|
2
2
|
import { warn, isFunction } from '@mpxjs/utils';
|
|
3
3
|
import Portal from './mpx-portal/index';
|
|
4
|
-
import { usePreventRemove } from '@react-navigation/native';
|
|
5
4
|
import { getCustomEvent } from './getInnerListeners';
|
|
6
5
|
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
|
|
7
6
|
import { WebView } from 'react-native-webview';
|
|
@@ -56,8 +55,8 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
56
55
|
const webViewRef = useRef(null);
|
|
57
56
|
const fristLoaded = useRef(false);
|
|
58
57
|
const isLoadError = useRef(false);
|
|
59
|
-
const isNavigateBack = useRef(false);
|
|
60
58
|
const statusCode = useRef('');
|
|
59
|
+
const [isLoaded, setIsLoaded] = useState(true);
|
|
61
60
|
const defaultWebViewStyle = {
|
|
62
61
|
position: 'absolute',
|
|
63
62
|
left: 0,
|
|
@@ -65,18 +64,27 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
65
64
|
top: 0,
|
|
66
65
|
bottom: 0
|
|
67
66
|
};
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (isNavigateBack.current) {
|
|
73
|
-
navigation?.dispatch(data.action);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
67
|
+
const canGoBack = useRef(false);
|
|
68
|
+
const isNavigateBack = useRef(false);
|
|
69
|
+
const beforeRemoveHandle = (e) => {
|
|
70
|
+
if (canGoBack.current && !isNavigateBack.current) {
|
|
76
71
|
webViewRef.current?.goBack();
|
|
72
|
+
e.preventDefault();
|
|
77
73
|
}
|
|
78
74
|
isNavigateBack.current = false;
|
|
79
|
-
}
|
|
75
|
+
};
|
|
76
|
+
const navigation = useNavigation();
|
|
77
|
+
// useEffect(() => {
|
|
78
|
+
// let beforeRemoveSubscription:any
|
|
79
|
+
// if (__mpx_mode__ !== 'ios') {
|
|
80
|
+
// beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
|
|
81
|
+
// }
|
|
82
|
+
// return () => {
|
|
83
|
+
// if (isFunction(beforeRemoveSubscription)) {
|
|
84
|
+
// beforeRemoveSubscription()
|
|
85
|
+
// }
|
|
86
|
+
// }
|
|
87
|
+
// }, [])
|
|
80
88
|
useNodesRef(props, ref, webViewRef, {
|
|
81
89
|
style: defaultWebViewStyle
|
|
82
90
|
});
|
|
@@ -123,13 +131,13 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
123
131
|
};
|
|
124
132
|
const _changeUrl = function (navState) {
|
|
125
133
|
if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
|
|
134
|
+
canGoBack.current = navState.canGoBack;
|
|
126
135
|
currentPage.__webViewUrl = navState.url;
|
|
127
|
-
setIsIntercept(navState.canGoBack);
|
|
128
136
|
}
|
|
129
137
|
};
|
|
130
138
|
const _onLoadProgress = function (event) {
|
|
131
139
|
if (__mpx_mode__ !== 'ios') {
|
|
132
|
-
|
|
140
|
+
canGoBack.current = event.nativeEvent.canGoBack;
|
|
133
141
|
}
|
|
134
142
|
};
|
|
135
143
|
const _message = function (res) {
|
|
@@ -219,6 +227,7 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
219
227
|
};
|
|
220
228
|
const onLoadEndHandle = function (res) {
|
|
221
229
|
fristLoaded.current = true;
|
|
230
|
+
setIsLoaded(true);
|
|
222
231
|
const src = res.nativeEvent?.url;
|
|
223
232
|
if (isLoadError.current) {
|
|
224
233
|
isLoadError.current = false;
|
|
@@ -266,13 +275,18 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
266
275
|
setPageLoadErr(true);
|
|
267
276
|
}
|
|
268
277
|
};
|
|
278
|
+
const onLoadStart = function () {
|
|
279
|
+
if (!fristLoaded.current) {
|
|
280
|
+
setIsLoaded(false);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
269
283
|
return (<Portal>
|
|
270
284
|
{pageLoadErr
|
|
271
285
|
? (<View style={[styles.loadErrorContext, defaultWebViewStyle]}>
|
|
272
286
|
<View style={styles.loadErrorText}><Text style={{ fontSize: 14, color: '#999999' }}>{currentErrorText.text}</Text></View>
|
|
273
287
|
<View style={styles.loadErrorButton} onTouchEnd={_reload}><Text style={{ fontSize: 12, color: '#666666' }}>{currentErrorText.button}</Text></View>
|
|
274
288
|
</View>)
|
|
275
|
-
: (<WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} onLoadEnd={onLoadEnd} onHttpError={onHttpError} onError={onError} allowsBackForwardNavigationGestures={true}></WebView>)}
|
|
289
|
+
: (<WebView style={defaultWebViewStyle} pointerEvents={isLoaded ? 'auto' : 'none'} source={{ uri: src }} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} onLoadEnd={onLoadEnd} onHttpError={onHttpError} onError={onError} onLoadStart={onLoadStart} allowsBackForwardNavigationGestures={true}></WebView>)}
|
|
276
290
|
</Portal>);
|
|
277
291
|
});
|
|
278
292
|
_WebView.displayName = 'MpxWebview';
|
|
@@ -48,6 +48,90 @@ const InitialValue = Object.assign({
|
|
|
48
48
|
const TransformOrigin = 'transformOrigin';
|
|
49
49
|
// transform
|
|
50
50
|
const isTransform = (key) => Object.keys(TransformInitial).includes(key);
|
|
51
|
+
// 多value解析
|
|
52
|
+
const parseValues = (str, char = ' ') => {
|
|
53
|
+
let stack = 0;
|
|
54
|
+
let temp = '';
|
|
55
|
+
const result = [];
|
|
56
|
+
for (let i = 0; i < str.length; i++) {
|
|
57
|
+
if (str[i] === '(') {
|
|
58
|
+
stack++;
|
|
59
|
+
}
|
|
60
|
+
else if (str[i] === ')') {
|
|
61
|
+
stack--;
|
|
62
|
+
}
|
|
63
|
+
// 非括号内 或者 非分隔字符且非空
|
|
64
|
+
if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
|
|
65
|
+
temp += str[i];
|
|
66
|
+
}
|
|
67
|
+
if ((stack === 0 && str[i] === char) || i === str.length - 1) {
|
|
68
|
+
result.push(temp);
|
|
69
|
+
temp = '';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
};
|
|
74
|
+
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
75
|
+
const parseTransform = (transformStr) => {
|
|
76
|
+
const values = parseValues(transformStr);
|
|
77
|
+
const transform = [];
|
|
78
|
+
values.forEach(item => {
|
|
79
|
+
const match = item.match(/([/\w]+)\((.+)\)/);
|
|
80
|
+
if (match && match.length >= 3) {
|
|
81
|
+
let key = match[1];
|
|
82
|
+
const val = match[2];
|
|
83
|
+
switch (key) {
|
|
84
|
+
case 'translateX':
|
|
85
|
+
case 'translateY':
|
|
86
|
+
case 'scaleX':
|
|
87
|
+
case 'scaleY':
|
|
88
|
+
case 'rotateX':
|
|
89
|
+
case 'rotateY':
|
|
90
|
+
case 'rotateZ':
|
|
91
|
+
case 'rotate':
|
|
92
|
+
case 'skewX':
|
|
93
|
+
case 'skewY':
|
|
94
|
+
case 'perspective':
|
|
95
|
+
// rotate 处理成 rotateZ
|
|
96
|
+
key = key === 'rotate' ? 'rotateZ' : key;
|
|
97
|
+
// 单个值处理
|
|
98
|
+
transform.push({ [key]: global.__formatValue(val) });
|
|
99
|
+
break;
|
|
100
|
+
case 'matrix':
|
|
101
|
+
transform.push({ [key]: parseValues(val, ',').map(val => +val) });
|
|
102
|
+
break;
|
|
103
|
+
case 'translate':
|
|
104
|
+
case 'scale':
|
|
105
|
+
case 'skew':
|
|
106
|
+
case 'translate3d': // x y 支持 z不支持
|
|
107
|
+
case 'scale3d': // x y 支持 z不支持
|
|
108
|
+
{
|
|
109
|
+
// 2 个以上的值处理
|
|
110
|
+
key = key.replace('3d', '');
|
|
111
|
+
const vals = parseValues(val, ',').splice(0, 3);
|
|
112
|
+
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
113
|
+
if (vals.length === 1 && key === 'scale') {
|
|
114
|
+
vals.push(vals[0]);
|
|
115
|
+
}
|
|
116
|
+
const xyz = ['X', 'Y', 'Z'];
|
|
117
|
+
transform.push(...vals.map((v, index) => {
|
|
118
|
+
return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
|
|
119
|
+
}));
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
return transform;
|
|
126
|
+
};
|
|
127
|
+
// format style
|
|
128
|
+
const formatStyle = (style) => {
|
|
129
|
+
if (!style.transform || Array.isArray(style.transform))
|
|
130
|
+
return style;
|
|
131
|
+
return Object.assign({}, style, {
|
|
132
|
+
transform: parseTransform(style.transform)
|
|
133
|
+
});
|
|
134
|
+
};
|
|
51
135
|
// transform 数组转对象
|
|
52
136
|
function getTransformObj(transforms) {
|
|
53
137
|
'worklet';
|
|
@@ -56,7 +140,7 @@ function getTransformObj(transforms) {
|
|
|
56
140
|
}, {});
|
|
57
141
|
}
|
|
58
142
|
export default function useAnimationHooks(props) {
|
|
59
|
-
const { style
|
|
143
|
+
const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props;
|
|
60
144
|
const enableStyleAnimation = enableAnimation || !!animation;
|
|
61
145
|
const enableAnimationRef = useRef(enableStyleAnimation);
|
|
62
146
|
if (enableAnimationRef.current !== enableStyleAnimation) {
|
|
@@ -64,6 +148,7 @@ export default function useAnimationHooks(props) {
|
|
|
64
148
|
}
|
|
65
149
|
if (!enableAnimationRef.current)
|
|
66
150
|
return { enableStyleAnimation: false };
|
|
151
|
+
const originalStyle = formatStyle(style);
|
|
67
152
|
// id 标识
|
|
68
153
|
const id = animation?.id || -1;
|
|
69
154
|
// 有动画样式的 style key
|
|
@@ -92,7 +177,7 @@ export default function useAnimationHooks(props) {
|
|
|
92
177
|
useEffect(() => {
|
|
93
178
|
// style 更新后同步更新 lastStyleRef & shareValMap
|
|
94
179
|
updateStyleVal();
|
|
95
|
-
}, [
|
|
180
|
+
}, [style]);
|
|
96
181
|
// ** 获取动画样式prop & 驱动动画
|
|
97
182
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
98
183
|
useEffect(() => {
|
|
@@ -24,7 +24,7 @@ const getTouchEvent = (
|
|
|
24
24
|
) => {
|
|
25
25
|
const { navigation, propsRef, layoutRef } = config
|
|
26
26
|
const props = propsRef.current
|
|
27
|
-
const {
|
|
27
|
+
const { y: navigationY = 0 } = navigation?.layout || {}
|
|
28
28
|
const nativeEvent = event.nativeEvent
|
|
29
29
|
const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent
|
|
30
30
|
const { id } = props
|
|
@@ -340,7 +340,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
340
340
|
setHeight(height || 0)
|
|
341
341
|
}
|
|
342
342
|
nodeRef.current?.measure((x: number, y: number, width: number, height: number) => {
|
|
343
|
-
const {
|
|
343
|
+
const { y: navigationY = 0 } = navigation?.layout || {}
|
|
344
344
|
layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft: 0, offsetTop: 0 }
|
|
345
345
|
resetBoundaryAndCheck({ width, height })
|
|
346
346
|
})
|
|
@@ -348,7 +348,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
|
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
const extendEvent = useCallback((e: any, type: 'start' | 'move' | 'end') => {
|
|
351
|
-
const {
|
|
351
|
+
const { y: navigationY = 0 } = navigation?.layout || {}
|
|
352
352
|
const touchArr = [e.changedTouches, e.allTouches]
|
|
353
353
|
touchArr.forEach(touches => {
|
|
354
354
|
touches && touches.forEach((item: { absoluteX: number; absoluteY: number; pageX: number; pageY: number; clientX: number; clientY: number }) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { forwardRef, useRef, useContext, useMemo, useState } from 'react'
|
|
1
|
+
import { forwardRef, useRef, useContext, useMemo, useState, useCallback, useEffect } from 'react'
|
|
2
2
|
import { warn, isFunction } from '@mpxjs/utils'
|
|
3
3
|
import Portal from './mpx-portal/index'
|
|
4
|
-
import { usePreventRemove, PreventRemoveEvent } from '@react-navigation/native'
|
|
5
4
|
import { getCustomEvent } from './getInnerListeners'
|
|
6
5
|
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
|
|
7
6
|
import { WebView } from 'react-native-webview'
|
|
@@ -76,6 +75,7 @@ const styles = StyleSheet.create({
|
|
|
76
75
|
borderRadius: 10
|
|
77
76
|
}
|
|
78
77
|
})
|
|
78
|
+
|
|
79
79
|
const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element | null => {
|
|
80
80
|
const { src, bindmessage, bindload, binderror } = props
|
|
81
81
|
const mpx = global.__mpx
|
|
@@ -100,8 +100,8 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
100
100
|
const webViewRef = useRef<WebView>(null)
|
|
101
101
|
const fristLoaded = useRef<boolean>(false)
|
|
102
102
|
const isLoadError = useRef<boolean>(false)
|
|
103
|
-
const isNavigateBack = useRef<boolean>(false)
|
|
104
103
|
const statusCode = useRef<string|number>('')
|
|
104
|
+
const [isLoaded, setIsLoaded] = useState<boolean>(true)
|
|
105
105
|
const defaultWebViewStyle = {
|
|
106
106
|
position: 'absolute' as const,
|
|
107
107
|
left: 0,
|
|
@@ -109,18 +109,30 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
109
109
|
top: 0,
|
|
110
110
|
bottom: 0
|
|
111
111
|
}
|
|
112
|
+
const canGoBack = useRef<boolean>(false)
|
|
113
|
+
const isNavigateBack = useRef<boolean>(false)
|
|
112
114
|
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
usePreventRemove(isIntercept, (event: PreventRemoveEvent) => {
|
|
116
|
-
const { data } = event
|
|
117
|
-
if (isNavigateBack.current) {
|
|
118
|
-
navigation?.dispatch(data.action)
|
|
119
|
-
} else {
|
|
115
|
+
const beforeRemoveHandle = (e: Event) => {
|
|
116
|
+
if (canGoBack.current && !isNavigateBack.current) {
|
|
120
117
|
webViewRef.current?.goBack()
|
|
118
|
+
e.preventDefault()
|
|
121
119
|
}
|
|
122
120
|
isNavigateBack.current = false
|
|
123
|
-
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const navigation = useNavigation()
|
|
124
|
+
|
|
125
|
+
// useEffect(() => {
|
|
126
|
+
// let beforeRemoveSubscription:any
|
|
127
|
+
// if (__mpx_mode__ !== 'ios') {
|
|
128
|
+
// beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
|
|
129
|
+
// }
|
|
130
|
+
// return () => {
|
|
131
|
+
// if (isFunction(beforeRemoveSubscription)) {
|
|
132
|
+
// beforeRemoveSubscription()
|
|
133
|
+
// }
|
|
134
|
+
// }
|
|
135
|
+
// }, [])
|
|
124
136
|
|
|
125
137
|
useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
|
|
126
138
|
style: defaultWebViewStyle
|
|
@@ -171,14 +183,14 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
171
183
|
}
|
|
172
184
|
const _changeUrl = function (navState: WebViewNavigation) {
|
|
173
185
|
if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
|
|
186
|
+
canGoBack.current = navState.canGoBack
|
|
174
187
|
currentPage.__webViewUrl = navState.url
|
|
175
|
-
setIsIntercept(navState.canGoBack)
|
|
176
188
|
}
|
|
177
189
|
}
|
|
178
190
|
|
|
179
191
|
const _onLoadProgress = function (event: WebViewProgressEvent) {
|
|
180
192
|
if (__mpx_mode__ !== 'ios') {
|
|
181
|
-
|
|
193
|
+
canGoBack.current = event.nativeEvent.canGoBack
|
|
182
194
|
}
|
|
183
195
|
}
|
|
184
196
|
const _message = function (res: WebViewMessageEvent) {
|
|
@@ -267,6 +279,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
267
279
|
}
|
|
268
280
|
const onLoadEndHandle = function (res: WebViewEvent) {
|
|
269
281
|
fristLoaded.current = true
|
|
282
|
+
setIsLoaded(true)
|
|
270
283
|
const src = res.nativeEvent?.url
|
|
271
284
|
if (isLoadError.current) {
|
|
272
285
|
isLoadError.current = false
|
|
@@ -312,6 +325,11 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
312
325
|
setPageLoadErr(true)
|
|
313
326
|
}
|
|
314
327
|
}
|
|
328
|
+
const onLoadStart = function () {
|
|
329
|
+
if (!fristLoaded.current) {
|
|
330
|
+
setIsLoaded(false)
|
|
331
|
+
}
|
|
332
|
+
}
|
|
315
333
|
|
|
316
334
|
return (
|
|
317
335
|
<Portal>
|
|
@@ -324,6 +342,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
324
342
|
)
|
|
325
343
|
: (<WebView
|
|
326
344
|
style={ defaultWebViewStyle }
|
|
345
|
+
pointerEvents={ isLoaded ? 'auto' : 'none' }
|
|
327
346
|
source={{ uri: src }}
|
|
328
347
|
ref={webViewRef}
|
|
329
348
|
javaScriptEnabled={true}
|
|
@@ -334,6 +353,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
334
353
|
onLoadEnd={onLoadEnd}
|
|
335
354
|
onHttpError={onHttpError}
|
|
336
355
|
onError={onError}
|
|
356
|
+
onLoadStart={onLoadStart}
|
|
337
357
|
allowsBackForwardNavigationGestures={true}
|
|
338
358
|
></WebView>)}
|
|
339
359
|
</Portal>
|
|
@@ -42,21 +42,6 @@ declare let global: {
|
|
|
42
42
|
|
|
43
43
|
declare module '@react-navigation/native' {
|
|
44
44
|
export function useNavigation (): Record<string, any>
|
|
45
|
-
export function usePreventRemove(
|
|
46
|
-
enabled: boolean,
|
|
47
|
-
callback: (e: { data: { action: any } }) => void
|
|
48
|
-
): void;
|
|
49
|
-
export interface PreventRemoveEvent {
|
|
50
|
-
data: {
|
|
51
|
-
action: NavigationAction;
|
|
52
|
-
route: {
|
|
53
|
-
key: string;
|
|
54
|
-
name: string;
|
|
55
|
-
params?: unknown;
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
preventDefault(): void;
|
|
59
|
-
}
|
|
60
45
|
}
|
|
61
46
|
|
|
62
47
|
declare module '*.png'
|
|
@@ -84,6 +84,88 @@ const InitialValue: ExtendedViewStyle = Object.assign({
|
|
|
84
84
|
const TransformOrigin = 'transformOrigin'
|
|
85
85
|
// transform
|
|
86
86
|
const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
|
|
87
|
+
// 多value解析
|
|
88
|
+
const parseValues = (str: string, char = ' ') => {
|
|
89
|
+
let stack = 0
|
|
90
|
+
let temp = ''
|
|
91
|
+
const result = []
|
|
92
|
+
for (let i = 0; i < str.length; i++) {
|
|
93
|
+
if (str[i] === '(') {
|
|
94
|
+
stack++
|
|
95
|
+
} else if (str[i] === ')') {
|
|
96
|
+
stack--
|
|
97
|
+
}
|
|
98
|
+
// 非括号内 或者 非分隔字符且非空
|
|
99
|
+
if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
|
|
100
|
+
temp += str[i]
|
|
101
|
+
}
|
|
102
|
+
if ((stack === 0 && str[i] === char) || i === str.length - 1) {
|
|
103
|
+
result.push(temp)
|
|
104
|
+
temp = ''
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return result
|
|
108
|
+
}
|
|
109
|
+
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
110
|
+
const parseTransform = (transformStr: string) => {
|
|
111
|
+
const values = parseValues(transformStr)
|
|
112
|
+
const transform: {[propName: string]: string|number|number[]}[] = []
|
|
113
|
+
values.forEach(item => {
|
|
114
|
+
const match = item.match(/([/\w]+)\((.+)\)/)
|
|
115
|
+
if (match && match.length >= 3) {
|
|
116
|
+
let key = match[1]
|
|
117
|
+
const val = match[2]
|
|
118
|
+
switch (key) {
|
|
119
|
+
case 'translateX':
|
|
120
|
+
case 'translateY':
|
|
121
|
+
case 'scaleX':
|
|
122
|
+
case 'scaleY':
|
|
123
|
+
case 'rotateX':
|
|
124
|
+
case 'rotateY':
|
|
125
|
+
case 'rotateZ':
|
|
126
|
+
case 'rotate':
|
|
127
|
+
case 'skewX':
|
|
128
|
+
case 'skewY':
|
|
129
|
+
case 'perspective':
|
|
130
|
+
// rotate 处理成 rotateZ
|
|
131
|
+
key = key === 'rotate' ? 'rotateZ' : key
|
|
132
|
+
// 单个值处理
|
|
133
|
+
transform.push({ [key]: global.__formatValue(val) })
|
|
134
|
+
break
|
|
135
|
+
case 'matrix':
|
|
136
|
+
transform.push({ [key]: parseValues(val, ',').map(val => +val) })
|
|
137
|
+
break
|
|
138
|
+
case 'translate':
|
|
139
|
+
case 'scale':
|
|
140
|
+
case 'skew':
|
|
141
|
+
case 'translate3d': // x y 支持 z不支持
|
|
142
|
+
case 'scale3d': // x y 支持 z不支持
|
|
143
|
+
{
|
|
144
|
+
// 2 个以上的值处理
|
|
145
|
+
key = key.replace('3d', '')
|
|
146
|
+
const vals = parseValues(val, ',').splice(0, 3)
|
|
147
|
+
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
148
|
+
if (vals.length === 1 && key === 'scale') {
|
|
149
|
+
vals.push(vals[0])
|
|
150
|
+
}
|
|
151
|
+
const xyz = ['X', 'Y', 'Z']
|
|
152
|
+
transform.push(...vals.map((v, index) => {
|
|
153
|
+
return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) }
|
|
154
|
+
}))
|
|
155
|
+
break
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
return transform
|
|
161
|
+
}
|
|
162
|
+
// format style
|
|
163
|
+
const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
|
|
164
|
+
if (!style.transform || Array.isArray(style.transform)) return style
|
|
165
|
+
return Object.assign({}, style, {
|
|
166
|
+
transform: parseTransform(style.transform)
|
|
167
|
+
})
|
|
168
|
+
}
|
|
87
169
|
|
|
88
170
|
// transform 数组转对象
|
|
89
171
|
function getTransformObj (transforms: { [propName: string]: string | number }[]) {
|
|
@@ -94,7 +176,7 @@ function getTransformObj (transforms: { [propName: string]: string | number }[])
|
|
|
94
176
|
}
|
|
95
177
|
|
|
96
178
|
export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean, layoutRef: MutableRefObject<any>, transitionend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void }) {
|
|
97
|
-
const { style
|
|
179
|
+
const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props
|
|
98
180
|
const enableStyleAnimation = enableAnimation || !!animation
|
|
99
181
|
const enableAnimationRef = useRef(enableStyleAnimation)
|
|
100
182
|
if (enableAnimationRef.current !== enableStyleAnimation) {
|
|
@@ -103,6 +185,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
|
|
|
103
185
|
|
|
104
186
|
if (!enableAnimationRef.current) return { enableStyleAnimation: false }
|
|
105
187
|
|
|
188
|
+
const originalStyle = formatStyle(style)
|
|
106
189
|
// id 标识
|
|
107
190
|
const id = animation?.id || -1
|
|
108
191
|
// 有动画样式的 style key
|
|
@@ -131,7 +214,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
|
|
|
131
214
|
useEffect(() => {
|
|
132
215
|
// style 更新后同步更新 lastStyleRef & shareValMap
|
|
133
216
|
updateStyleVal()
|
|
134
|
-
}, [
|
|
217
|
+
}, [style])
|
|
135
218
|
// ** 获取动画样式prop & 驱动动画
|
|
136
219
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
137
220
|
useEffect(() => {
|
|
@@ -180,7 +180,7 @@ const i18nModuleName = '_i'
|
|
|
180
180
|
const stringifyWxsPath = '~' + normalize.lib('runtime/stringify.wxs')
|
|
181
181
|
const stringifyModuleName = '_s'
|
|
182
182
|
const optionalChainWxsPath = '~' + normalize.lib('runtime/oc.wxs')
|
|
183
|
-
const optionalChainWxsName = '
|
|
183
|
+
const optionalChainWxsName = '_o'
|
|
184
184
|
|
|
185
185
|
const tagRES = /(\{\{(?:.|\n|\r)+?\}\})(?!})/
|
|
186
186
|
const tagRE = /\{\{((?:.|\n|\r)+?)\}\}(?!})/
|
|
@@ -72,7 +72,7 @@ const isNativeMiniTag = makeMap(
|
|
|
72
72
|
* 是否为mpx内置组件
|
|
73
73
|
* collected from packages/webpack-plugin/lib/runtime/components/web/
|
|
74
74
|
*/
|
|
75
|
-
const
|
|
75
|
+
const isBuildInTag = makeMap(
|
|
76
76
|
'mpx-image,mpx-picker-view,mpx-slider,mpx-textarea,mpx-input,mpx-picker,' +
|
|
77
77
|
'mpx-swiper-item,mpx-video,mpx-button,mpx-keep-alive,mpx-progress,' +
|
|
78
78
|
'mpx-swiper,mpx-view,mpx-checkbox-group,mpx-movable-area,mpx-radio-group,' +
|
|
@@ -81,19 +81,6 @@ const isBuildInWebTag = makeMap(
|
|
|
81
81
|
'mpx-icon,mpx-picker-view-column,mpx-scroll-view,mpx-text'
|
|
82
82
|
)
|
|
83
83
|
|
|
84
|
-
/**
|
|
85
|
-
* 是否为mpx2rn内置组件
|
|
86
|
-
*/
|
|
87
|
-
const isBuildInReactTag = makeMap(
|
|
88
|
-
'mpx-web-view,mpx-view,mpx-video,mpx-textarea,mpx-text,mpx-switch,' +
|
|
89
|
-
'mpx-swiper,mpx-swiper-item,mpx-simple-view,mpx-simple-text,mpx-scroll-view,' +
|
|
90
|
-
'mpx-root-portal,mpx-radio,mpx-radio-group,mpx-navigator,mpx-movable-view,' +
|
|
91
|
-
'mpx-movable-area,mpx-label,mpx-keyboard-avoiding-view,mpx-input,mpx-inline-text,' +
|
|
92
|
-
'mpx-image,mpx-form,mpx-checkbox,mpx-checkbox-group,mpx-button,' +
|
|
93
|
-
'mpx-rich-text,mpx-portal,mpx-popup,mpx-picker-view-column,mpx-picker-view,mpx-picker,' +
|
|
94
|
-
'mpx-icon,mpx-canvas'
|
|
95
|
-
)
|
|
96
|
-
|
|
97
84
|
const isSpace = makeMap('ensp,emsp,nbsp')
|
|
98
85
|
|
|
99
86
|
const isContWidth = makeMap('col,colgroup,img,table,td,th,tr')
|
|
@@ -118,12 +105,11 @@ module.exports = {
|
|
|
118
105
|
isVoidTag,
|
|
119
106
|
isNonPhrasingTag,
|
|
120
107
|
isRichTextTag,
|
|
121
|
-
|
|
108
|
+
isBuildInTag,
|
|
122
109
|
isUnaryTag,
|
|
123
110
|
isSpace,
|
|
124
111
|
isContWidth,
|
|
125
112
|
isContHeight,
|
|
126
113
|
isNativeMiniTag,
|
|
127
|
-
isContConRow
|
|
128
|
-
isBuildInReactTag
|
|
114
|
+
isContConRow
|
|
129
115
|
}
|
package/lib/web/script-helper.js
CHANGED
|
@@ -13,7 +13,7 @@ function stringifyRequest (loaderContext, request) {
|
|
|
13
13
|
|
|
14
14
|
function getAsyncChunkName (chunkName) {
|
|
15
15
|
if (chunkName && typeof chunkName !== 'boolean') {
|
|
16
|
-
return `/* webpackChunkName: "${chunkName}
|
|
16
|
+
return `/* webpackChunkName: "${chunkName}" */`
|
|
17
17
|
}
|
|
18
18
|
return ''
|
|
19
19
|
}
|