@mpxjs/webpack-plugin 2.9.67 → 2.9.69-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/lib/index.js +30 -9
  2. package/lib/platform/json/wx/index.js +21 -8
  3. package/lib/platform/style/wx/index.js +51 -54
  4. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  5. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  6. package/lib/platform/template/wx/component-config/index.js +1 -1
  7. package/lib/platform/template/wx/component-config/input.js +1 -1
  8. package/lib/platform/template/wx/component-config/movable-view.js +8 -1
  9. package/lib/platform/template/wx/component-config/rich-text.js +8 -0
  10. package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
  11. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  12. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  13. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  14. package/lib/react/processStyles.js +14 -4
  15. package/lib/react/processTemplate.js +3 -0
  16. package/lib/resolver/AddEnvPlugin.js +1 -0
  17. package/lib/resolver/AddModePlugin.js +9 -8
  18. package/lib/runtime/components/react/context.ts +14 -0
  19. package/lib/runtime/components/react/dist/context.js +4 -0
  20. package/lib/runtime/components/react/dist/event.config.js +24 -24
  21. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -175
  22. package/lib/runtime/components/react/dist/mpx-button.jsx +77 -49
  23. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  24. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  25. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  26. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  27. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  28. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  29. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  30. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
  31. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  32. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  33. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  34. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  35. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  36. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  37. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  38. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  39. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  40. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +14 -14
  41. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  42. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  43. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  44. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  45. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  46. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  47. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  48. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  49. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +171 -88
  50. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
  51. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  52. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  53. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  54. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +62 -0
  55. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  56. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +53 -42
  57. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  58. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +28 -9
  59. package/lib/runtime/components/react/dist/mpx-swiper.jsx +608 -0
  60. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  61. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  62. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  63. package/lib/runtime/components/react/dist/mpx-view.jsx +67 -94
  64. package/lib/runtime/components/react/dist/mpx-web-view.jsx +152 -37
  65. package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
  66. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  67. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  68. package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
  69. package/lib/runtime/components/react/dist/useAnimationHooks.js +36 -10
  70. package/lib/runtime/components/react/dist/utils.jsx +129 -24
  71. package/lib/runtime/components/react/event.config.ts +25 -26
  72. package/lib/runtime/components/react/getInnerListeners.ts +238 -202
  73. package/lib/runtime/components/react/mpx-button.tsx +104 -57
  74. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  75. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  76. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  77. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  78. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  79. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  80. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  81. package/lib/runtime/components/react/mpx-canvas/index.tsx +296 -0
  82. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  83. package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
  84. package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
  85. package/lib/runtime/components/react/mpx-form.tsx +25 -28
  86. package/lib/runtime/components/react/mpx-icon.tsx +12 -17
  87. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  88. package/lib/runtime/components/react/mpx-input.tsx +77 -57
  89. package/lib/runtime/components/react/mpx-label.tsx +26 -27
  90. package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
  91. package/lib/runtime/components/react/mpx-movable-view.tsx +22 -26
  92. package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
  93. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  94. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  95. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  96. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  97. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  98. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  99. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  100. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
  101. package/lib/runtime/components/react/mpx-picker-view-column.tsx +276 -112
  102. package/lib/runtime/components/react/mpx-picker-view.tsx +137 -129
  103. package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
  104. package/lib/runtime/components/react/mpx-radio.tsx +45 -54
  105. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  106. package/lib/runtime/components/react/mpx-rich-text/index.tsx +115 -0
  107. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  108. package/lib/runtime/components/react/mpx-scroll-view.tsx +83 -73
  109. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  110. package/lib/runtime/components/react/mpx-swiper-item.tsx +41 -12
  111. package/lib/runtime/components/react/mpx-swiper.tsx +690 -0
  112. package/lib/runtime/components/react/mpx-switch.tsx +29 -23
  113. package/lib/runtime/components/react/mpx-text.tsx +14 -18
  114. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  115. package/lib/runtime/components/react/mpx-view.tsx +93 -117
  116. package/lib/runtime/components/react/mpx-web-view.tsx +162 -56
  117. package/lib/runtime/components/react/pickerFaces.ts +112 -0
  118. package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
  119. package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
  120. package/lib/runtime/components/react/pickerViewOverlay.tsx +34 -0
  121. package/lib/runtime/components/react/types/common.ts +2 -0
  122. package/lib/runtime/components/react/types/global.d.ts +7 -17
  123. package/lib/runtime/components/react/useAnimationHooks.ts +37 -12
  124. package/lib/runtime/components/react/utils.tsx +169 -29
  125. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  126. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  127. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  128. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  129. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  130. package/lib/runtime/optionProcessor.js +7 -38
  131. package/lib/runtime/utils.js +2 -0
  132. package/lib/style-compiler/index.js +3 -4
  133. package/lib/style-compiler/plugins/scope-id.js +30 -2
  134. package/lib/style-compiler/strip-conditional-loader.js +118 -0
  135. package/lib/template-compiler/bind-this.js +7 -2
  136. package/lib/template-compiler/compiler.js +66 -39
  137. package/lib/template-compiler/gen-node-react.js +3 -3
  138. package/package.json +6 -4
  139. package/LICENSE +0 -433
  140. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  141. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  142. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  143. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  144. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  145. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  146. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  147. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -525
  148. package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
  149. package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
  150. package/lib/runtime/components/web/event.js +0 -105
@@ -4,12 +4,12 @@
4
4
  * ✘ decode
5
5
  */
6
6
  import { Text } from 'react-native';
7
- import { useRef, forwardRef } from 'react';
7
+ import { useRef, forwardRef, createElement } from 'react';
8
8
  import useInnerProps from './getInnerListeners';
9
9
  import useNodesRef from './useNodesRef'; // 引入辅助函数
10
10
  import { useTransformStyle, wrapChildren } from './utils';
11
11
  const _Text = forwardRef((props, ref) => {
12
- const { style = {}, selectable, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'user-select': userSelect, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
12
+ const { style = {}, allowFontScaling = false, selectable, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'user-select': userSelect, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
13
13
  const layoutRef = useRef({});
14
14
  const { normalStyle, hasVarDec, varContextRef } = useTransformStyle(style, {
15
15
  enableVar,
@@ -19,22 +19,23 @@ const _Text = forwardRef((props, ref) => {
19
19
  parentHeight
20
20
  });
21
21
  const nodeRef = useRef(null);
22
- useNodesRef(props, ref, nodeRef);
22
+ useNodesRef(props, ref, nodeRef, {
23
+ style: normalStyle
24
+ });
23
25
  const innerProps = useInnerProps(props, {
24
26
  ref: nodeRef,
25
27
  style: normalStyle,
26
- selectable: !!selectable || !!userSelect
28
+ selectable: !!selectable || !!userSelect,
29
+ allowFontScaling
27
30
  }, [
28
31
  'user-select'
29
32
  ], {
30
33
  layoutRef
31
34
  });
32
- return (<Text {...innerProps}>
33
- {wrapChildren(props, {
34
- hasVarDec,
35
- varContext: varContextRef.current
36
- })}
37
- </Text>);
35
+ return createElement(Text, innerProps, wrapChildren(props, {
36
+ hasVarDec,
37
+ varContext: varContextRef.current
38
+ }));
38
39
  });
39
40
  _Text.displayName = 'MpxText';
40
41
  export default _Text;
@@ -9,10 +9,10 @@
9
9
  * ✘ show-confirm-bar
10
10
  * ✔ bindlinechange: No `heightRpx` info.
11
11
  */
12
- import { forwardRef } from 'react';
12
+ import { forwardRef, createElement } from 'react';
13
13
  import { Keyboard } from 'react-native';
14
14
  import Input from './mpx-input';
15
- import { omit } from './utils';
15
+ import { omit, extendObject } from './utils';
16
16
  const Textarea = forwardRef((props, ref) => {
17
17
  const restProps = omit(props, [
18
18
  'ref',
@@ -21,7 +21,12 @@ const Textarea = forwardRef((props, ref) => {
21
21
  'multiline',
22
22
  'confirm-hold'
23
23
  ]);
24
- return (<Input ref={ref} multiline confirm-type='next' bindblur={() => Keyboard.dismiss()} {...restProps}/>);
24
+ return createElement(Input, extendObject({
25
+ ref: ref,
26
+ multiline: true,
27
+ confirmType: 'next',
28
+ bindblur: () => Keyboard.dismiss()
29
+ }, restProps));
25
30
  });
26
31
  Textarea.displayName = 'MpxTextarea';
27
32
  export default Textarea;
@@ -5,13 +5,15 @@
5
5
  * ✔ hover-stay-time
6
6
  */
7
7
  import { View, StyleSheet, Image } from 'react-native';
8
- import { useRef, useState, useEffect, forwardRef } from 'react';
8
+ import { useRef, useState, useEffect, forwardRef, createElement } from 'react';
9
9
  import useInnerProps from './getInnerListeners';
10
10
  import Animated from 'react-native-reanimated';
11
11
  import useAnimationHooks from './useAnimationHooks';
12
12
  import useNodesRef from './useNodesRef';
13
- import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout } from './utils';
13
+ import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject, useHoverStyle } from './utils';
14
+ import { error } from '@mpxjs/utils';
14
15
  import LinearGradient from 'react-native-linear-gradient';
16
+ import { GestureDetector } from 'react-native-gesture-handler';
15
17
  const linearMap = new Map([
16
18
  ['top', 0],
17
19
  ['bottom', 180],
@@ -148,10 +150,7 @@ function backgroundPosition(imageProps, preImageInfo, imageSize, layoutInfo) {
148
150
  style[key] = val;
149
151
  }
150
152
  }
151
- imageProps.style = {
152
- ...imageProps.style,
153
- ...style
154
- };
153
+ extendObject(imageProps.style, style);
155
154
  }
156
155
  // background-size 转换
157
156
  function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
@@ -201,7 +200,7 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
201
200
  }
202
201
  else { // 数值类型 ImageStyle
203
202
  // 数值类型设置为 stretch
204
- imageProps.style.resizeMode = 'stretch';
203
+ imageProps.resizeMode = 'stretch';
205
204
  dimensions = {
206
205
  width: isPercent(width) ? width : +width,
207
206
  height: isPercent(height) ? height : +height
@@ -209,15 +208,13 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
209
208
  }
210
209
  }
211
210
  // 样式合并
212
- imageProps.style = {
213
- ...imageProps.style,
214
- ...dimensions
215
- };
211
+ extendObject(imageProps.style, dimensions);
216
212
  }
217
213
  // background-image转换为source
218
214
  function backgroundImage(imageProps, preImageInfo) {
219
- if (preImageInfo.src) {
220
- imageProps.src = preImageInfo.src;
215
+ const src = preImageInfo.src;
216
+ if (src) {
217
+ imageProps.source = { uri: src };
221
218
  }
222
219
  }
223
220
  // 渐变的转换
@@ -241,8 +238,8 @@ function linearGradient(imageProps, preImageInfo, imageSize, layoutInfo) {
241
238
  const imageStyleToProps = (preImageInfo, imageSize, layoutInfo) => {
242
239
  // 初始化
243
240
  const imageProps = {
241
+ resizeMode: 'cover',
244
242
  style: {
245
- resizeMode: 'cover',
246
243
  position: 'absolute'
247
244
  // ...StyleSheet.absoluteFillObject
248
245
  },
@@ -384,10 +381,9 @@ function parseLinearGradient(text) {
384
381
  !isNaN(numberVal) && locations.push(numberVal);
385
382
  return prev;
386
383
  }, { colors: [], locations: [] });
387
- return {
388
- ...linearInfo,
384
+ return extendObject({}, linearInfo, {
389
385
  direction: direction.trim()
390
- };
386
+ });
391
387
  }
392
388
  function parseBgImage(text) {
393
389
  if (!text)
@@ -430,7 +426,23 @@ function preParseImage(imageStyle) {
430
426
  function isDiagonalAngle(linearInfo) {
431
427
  return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction]);
432
428
  }
433
- function wrapImage(imageStyle) {
429
+ function inheritStyle(innerStyle = {}) {
430
+ const { borderWidth, borderRadius } = innerStyle;
431
+ const borderStyles = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'];
432
+ return pickStyle(innerStyle, borderStyles, borderWidth && borderRadius
433
+ ? (key, val) => {
434
+ // 盒子内圆角borderWith与borderRadius的关系
435
+ // 当borderRadius 小于 当borderWith 内边框为直角
436
+ // 当borderRadius 大于等于 当borderWith 内边框为圆角
437
+ if (borderStyles.includes(key)) {
438
+ const borderVal = +val - borderWidth;
439
+ return borderVal > 0 ? borderVal : 0;
440
+ }
441
+ return val;
442
+ }
443
+ : undefined);
444
+ }
445
+ function wrapImage(imageStyle, innerStyle, enableFastImage) {
434
446
  // 预处理数据
435
447
  const preImageInfo = preParseImage(imageStyle);
436
448
  // 预解析
@@ -510,12 +522,12 @@ function wrapImage(imageStyle) {
510
522
  setShow(true);
511
523
  }
512
524
  };
513
- return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
525
+ return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
514
526
  {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
515
- {show && type === 'image' && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
527
+ {show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current), enableFastImage))}
516
528
  </View>;
517
529
  }
518
- function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps }) {
530
+ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }) {
519
531
  const children = wrapChildren(props, {
520
532
  hasVarDec,
521
533
  varContext,
@@ -523,29 +535,24 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
523
535
  textProps
524
536
  });
525
537
  return [
526
- enableBackground ? wrapImage(backgroundStyle) : null,
538
+ enableBackground ? wrapImage(backgroundStyle, innerStyle, enableFastImage) : null,
527
539
  children
528
540
  ];
529
541
  }
530
542
  const _View = forwardRef((viewProps, ref) => {
531
543
  const { textProps, innerProps: props = {} } = splitProps(viewProps);
532
- let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
533
- const [isHover, setIsHover] = useState(false);
544
+ let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-fast-image': enableFastImage, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
534
545
  // 默认样式
535
- const defaultStyle = {
536
- // flex 布局相关的默认样式
537
- ...style.display === 'flex' && {
546
+ const defaultStyle = style.display === 'flex'
547
+ ? {
538
548
  flexDirection: 'row',
539
549
  flexBasis: 'auto',
540
550
  flexShrink: 1,
541
551
  flexWrap: 'nowrap'
542
552
  }
543
- };
544
- const styleObj = {
545
- ...defaultStyle,
546
- ...style,
547
- ...(isHover ? hoverStyle : null)
548
- };
553
+ : {};
554
+ const { isHover, enableHoverStyle, gesture } = useHoverStyle({ hoverStyle, hoverStartTime, hoverStayTime });
555
+ const styleObj = extendObject({}, defaultStyle, style, isHover ? hoverStyle : {});
549
556
  const { normalStyle, hasSelfPercent, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, {
550
557
  enableVar,
551
558
  externalVarContext,
@@ -553,57 +560,33 @@ const _View = forwardRef((viewProps, ref) => {
553
560
  parentWidth,
554
561
  parentHeight
555
562
  });
556
- const { textStyle, backgroundStyle, innerStyle } = splitStyle(normalStyle);
563
+ const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle);
557
564
  enableBackground = enableBackground || !!backgroundStyle;
558
565
  const enableBackgroundRef = useRef(enableBackground);
559
566
  if (enableBackgroundRef.current !== enableBackground) {
560
- throw new Error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.');
567
+ error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.');
561
568
  }
562
569
  const nodeRef = useRef(null);
563
570
  useNodesRef(props, ref, nodeRef, {
564
- defaultStyle
571
+ style: normalStyle
565
572
  });
566
- const dataRef = useRef({});
567
- useEffect(() => {
568
- return () => {
569
- dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
570
- dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer);
571
- };
572
- }, []);
573
- const setStartTimer = () => {
574
- dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
575
- dataRef.current.startTimer = setTimeout(() => {
576
- setIsHover(true);
577
- }, +hoverStartTime);
578
- };
579
- const setStayTimer = () => {
580
- dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer);
581
- dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
582
- dataRef.current.stayTimer = setTimeout(() => {
583
- setIsHover(false);
584
- }, +hoverStayTime);
585
- };
586
- function onTouchStart(e) {
587
- const { bindtouchstart } = props;
588
- bindtouchstart && bindtouchstart(e);
589
- setStartTimer();
590
- }
591
- function onTouchEnd(e) {
592
- const { bindtouchend } = props;
593
- bindtouchend && bindtouchend(e);
594
- setStayTimer();
595
- }
596
573
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
597
- const viewStyle = Object.assign({}, innerStyle, layoutStyle);
598
- const innerProps = useInnerProps(props, {
574
+ const viewStyle = extendObject({}, innerStyle, layoutStyle);
575
+ enableAnimation = enableAnimation || !!animation;
576
+ const enableAnimationRef = useRef(enableAnimation);
577
+ if (enableAnimationRef.current !== enableAnimation) {
578
+ error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.');
579
+ }
580
+ const finalStyle = enableAnimationRef.current
581
+ ? [viewStyle, useAnimationHooks({
582
+ animation,
583
+ style: viewStyle
584
+ })]
585
+ : viewStyle;
586
+ const innerProps = useInnerProps(props, extendObject({
599
587
  ref: nodeRef,
600
- style: viewStyle,
601
- ...layoutProps,
602
- ...(hoverStyle && {
603
- bindtouchstart: onTouchStart,
604
- bindtouchend: onTouchEnd
605
- })
606
- }, [
588
+ style: finalStyle
589
+ }, layoutProps), [
607
590
  'hover-start-time',
608
591
  'hover-stay-time',
609
592
  'hover-style',
@@ -611,32 +594,22 @@ const _View = forwardRef((viewProps, ref) => {
611
594
  ], {
612
595
  layoutRef
613
596
  });
614
- enableAnimation = enableAnimation || !!animation;
615
- const enableAnimationRef = useRef(enableAnimation);
616
- if (enableAnimationRef.current !== enableAnimation) {
617
- throw new Error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.');
618
- }
619
- const finalStyle = enableAnimation
620
- ? useAnimationHooks({
621
- animation,
622
- style: viewStyle
623
- })
624
- : viewStyle;
625
597
  const childNode = wrapWithChildren(props, {
626
598
  hasVarDec,
627
599
  enableBackground: enableBackgroundRef.current,
628
600
  textStyle,
629
601
  backgroundStyle,
630
602
  varContext: varContextRef.current,
631
- textProps
603
+ textProps,
604
+ innerStyle,
605
+ enableFastImage
632
606
  });
633
- return animation?.actions?.length
634
- ? (<Animated.View {...innerProps} style={finalStyle}>
635
- {childNode}
636
- </Animated.View>)
637
- : (<View {...innerProps}>
638
- {childNode}
639
- </View>);
607
+ const BaseComponent = enableAnimation
608
+ ? createElement(Animated.View, extendObject({}, innerProps, { style: finalStyle }), childNode)
609
+ : createElement(View, innerProps, childNode);
610
+ return enableHoverStyle
611
+ ? createElement(GestureDetector, { gesture }, BaseComponent)
612
+ : BaseComponent;
640
613
  });
641
614
  _View.displayName = 'MpxView';
642
615
  export default _View;
@@ -1,15 +1,22 @@
1
- import { forwardRef, useEffect, useRef } from 'react';
2
- import { noop, warn } from '@mpxjs/utils';
1
+ import { forwardRef, useRef, useContext, useMemo, createElement, useCallback, useEffect } from 'react';
2
+ import { warn, getFocusedNavigation, isFunction } from '@mpxjs/utils';
3
3
  import { Portal } from '@ant-design/react-native';
4
4
  import { getCustomEvent } from './getInnerListeners';
5
5
  import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
6
6
  import { WebView } from 'react-native-webview';
7
7
  import useNodesRef from './useNodesRef';
8
+ import { getCurrentPage, extendObject } from './utils';
9
+ import { RouteContext } from './context';
10
+ import { BackHandler } from 'react-native';
8
11
  const _WebView = forwardRef((props, ref) => {
9
- const { src = '', bindmessage = noop, bindload = noop, binderror = noop } = props;
12
+ const { src, bindmessage, bindload, binderror } = props;
13
+ const mpx = global.__mpx;
10
14
  if (props.style) {
11
15
  warn('The web-view component does not support the style prop.');
12
16
  }
17
+ const pageId = useContext(RouteContext);
18
+ const currentPage = useMemo(() => getCurrentPage(pageId), [pageId]);
19
+ const webViewRef = useRef(null);
13
20
  const defaultWebViewStyle = {
14
21
  position: 'absolute',
15
22
  left: 0,
@@ -17,26 +24,36 @@ const _WebView = forwardRef((props, ref) => {
17
24
  top: 0,
18
25
  bottom: 0
19
26
  };
20
- const webViewRef = useRef(null);
21
- useNodesRef(props, ref, webViewRef, {
22
- defaultStyle: defaultWebViewStyle
23
- });
24
- const _messageList = [];
25
- const handleUnload = () => {
26
- // 这里是 WebView 销毁前执行的逻辑
27
- bindmessage(getCustomEvent('messsage', {}, {
28
- detail: {
29
- data: _messageList
30
- },
31
- layoutRef: webViewRef
32
- }));
33
- };
27
+ const canGoBack = useRef(false);
28
+ const onAndroidBackPress = useCallback(() => {
29
+ if (canGoBack.current) {
30
+ webViewRef.current?.goBack();
31
+ return true;
32
+ }
33
+ return false;
34
+ }, [canGoBack]);
35
+ const beforeRemoveHandle = useCallback((e) => {
36
+ if (canGoBack.current) {
37
+ webViewRef.current?.goBack();
38
+ e.preventDefault();
39
+ }
40
+ }, [canGoBack]);
41
+ const navigation = getFocusedNavigation();
42
+ navigation?.addListener('beforeRemove', beforeRemoveHandle);
34
43
  useEffect(() => {
35
- // 组件卸载时执行
36
- return () => {
37
- handleUnload();
38
- };
44
+ if (__mpx_mode__ === 'android') {
45
+ BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress);
46
+ return () => {
47
+ BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress);
48
+ };
49
+ }
39
50
  }, []);
51
+ useNodesRef(props, ref, webViewRef, {
52
+ style: defaultWebViewStyle
53
+ });
54
+ if (!src) {
55
+ return null;
56
+ }
40
57
  const _load = function (res) {
41
58
  const result = {
42
59
  type: 'load',
@@ -57,6 +74,49 @@ const _WebView = forwardRef((props, ref) => {
57
74
  };
58
75
  binderror(result);
59
76
  };
77
+ const injectedJavaScript = `
78
+ if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
79
+ var _documentTitle = document.title;
80
+ window.ReactNativeWebView.postMessage(JSON.stringify({
81
+ type: 'setTitle',
82
+ payload: {
83
+ _documentTitle: _documentTitle
84
+ }
85
+ }))
86
+ Object.defineProperty(document, 'title', {
87
+ set (val) {
88
+ _documentTitle = val
89
+ window.ReactNativeWebView.postMessage(JSON.stringify({
90
+ type: 'setTitle',
91
+ payload: {
92
+ _documentTitle: _documentTitle
93
+ }
94
+ }))
95
+ },
96
+ get () {
97
+ return _documentTitle
98
+ }
99
+ });
100
+ }
101
+ true;
102
+ `;
103
+ const sendMessage = function (params) {
104
+ return `
105
+ window.mpxWebviewMessageCallback(${params})
106
+ true;
107
+ `;
108
+ };
109
+ const _changeUrl = function (navState) {
110
+ if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
111
+ canGoBack.current = navState.canGoBack;
112
+ currentPage.__webViewUrl = navState.url;
113
+ }
114
+ };
115
+ const _onLoadProgress = function (event) {
116
+ if (__mpx_mode__ === 'android') {
117
+ canGoBack.current = event.nativeEvent.canGoBack;
118
+ }
119
+ };
60
120
  const _message = function (res) {
61
121
  let data = {};
62
122
  let asyncCallback;
@@ -67,47 +127,102 @@ const _WebView = forwardRef((props, ref) => {
67
127
  data = JSON.parse(nativeEventData);
68
128
  }
69
129
  }
70
- catch (e) {
71
- data = {};
72
- }
130
+ catch (e) { }
131
+ const args = data.args;
73
132
  const postData = data.payload || {};
74
- switch (data.type) {
133
+ const params = Array.isArray(args) ? args : [postData];
134
+ const type = data.type;
135
+ switch (type) {
136
+ case 'setTitle':
137
+ { // case下不允许直接声明,包个块解决该问题
138
+ const title = postData._documentTitle;
139
+ if (title) {
140
+ navigation && navigation.setOptions({ title });
141
+ }
142
+ }
143
+ break;
75
144
  case 'postMessage':
76
- _messageList.push(postData.data);
145
+ bindmessage && bindmessage(getCustomEvent('messsage', {}, {
146
+ detail: {
147
+ data: params[0]?.data
148
+ }
149
+ }));
77
150
  asyncCallback = Promise.resolve({
78
151
  errMsg: 'invokeWebappApi:ok'
79
152
  });
80
153
  break;
81
154
  case 'navigateTo':
82
- asyncCallback = navObj.navigateTo(postData);
155
+ asyncCallback = navObj.navigateTo(...params);
83
156
  break;
84
157
  case 'navigateBack':
85
- asyncCallback = navObj.navigateBack(postData);
158
+ asyncCallback = navObj.navigateBack(...params);
86
159
  break;
87
160
  case 'redirectTo':
88
- asyncCallback = navObj.redirectTo(postData);
161
+ asyncCallback = navObj.redirectTo(...params);
89
162
  break;
90
163
  case 'switchTab':
91
- asyncCallback = navObj.switchTab(postData);
164
+ asyncCallback = navObj.switchTab(...params);
92
165
  break;
93
166
  case 'reLaunch':
94
- asyncCallback = navObj.reLaunch(postData);
167
+ asyncCallback = navObj.reLaunch(...params);
168
+ break;
169
+ default:
170
+ if (type) {
171
+ const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type];
172
+ if (isFunction(implement)) {
173
+ asyncCallback = Promise.resolve(implement(...params));
174
+ }
175
+ else {
176
+ /* eslint-disable prefer-promise-reject-errors */
177
+ asyncCallback = Promise.reject({
178
+ errMsg: `未在apiImplementations中配置${type}方法`
179
+ });
180
+ }
181
+ }
95
182
  break;
96
183
  }
97
184
  asyncCallback && asyncCallback.then((res) => {
98
185
  if (webViewRef.current?.postMessage) {
99
- const test = JSON.stringify({
100
- type: data.type,
186
+ const result = JSON.stringify({
187
+ type,
101
188
  callbackId: data.callbackId,
102
189
  result: res
103
190
  });
104
- webViewRef.current.postMessage(test);
191
+ webViewRef.current.injectJavaScript(sendMessage(result));
192
+ }
193
+ }).catch((error) => {
194
+ if (webViewRef.current?.postMessage) {
195
+ const result = JSON.stringify({
196
+ type,
197
+ callbackId: data.callbackId,
198
+ error
199
+ });
200
+ webViewRef.current.injectJavaScript(sendMessage(result));
105
201
  }
106
202
  });
107
203
  };
108
- return (<Portal>
109
- <WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} onLoad={_load} onError={_error} onMessage={_message} javaScriptEnabled={true}></WebView>
110
- </Portal>);
204
+ const events = {};
205
+ if (bindload) {
206
+ extendObject(events, {
207
+ onLoad: _load
208
+ });
209
+ }
210
+ if (binderror) {
211
+ extendObject(events, {
212
+ onError: _error
213
+ });
214
+ }
215
+ return createElement(Portal, null, createElement(WebView, extendObject({
216
+ style: defaultWebViewStyle,
217
+ source: { uri: src },
218
+ ref: webViewRef,
219
+ javaScriptEnabled: true,
220
+ onNavigationStateChange: _changeUrl,
221
+ onMessage: _message,
222
+ injectedJavaScript: injectedJavaScript,
223
+ onLoadProgress: _onLoadProgress,
224
+ allowsBackForwardNavigationGestures: true
225
+ }, events)));
111
226
  });
112
227
  _WebView.displayName = 'MpxWebview';
113
228
  export default _WebView;