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

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 (140) hide show
  1. package/lib/index.js +13 -8
  2. package/lib/platform/json/wx/index.js +21 -8
  3. package/lib/platform/style/wx/index.js +35 -38
  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/rich-text.js +8 -0
  9. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  10. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  11. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  12. package/lib/react/processStyles.js +14 -4
  13. package/lib/react/processTemplate.js +3 -0
  14. package/lib/resolver/AddModePlugin.js +8 -8
  15. package/lib/runtime/components/react/context.ts +6 -0
  16. package/lib/runtime/components/react/dist/context.js +2 -0
  17. package/lib/runtime/components/react/dist/event.config.js +24 -24
  18. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -174
  19. package/lib/runtime/components/react/dist/mpx-button.jsx +77 -49
  20. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  21. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  22. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  23. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  24. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  25. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  26. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  27. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
  28. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  29. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  30. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  31. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  32. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  33. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  34. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  35. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  36. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  37. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +13 -13
  38. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  39. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  40. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  41. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  42. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  43. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  44. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  45. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  46. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +160 -88
  47. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
  48. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  49. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  50. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  51. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  52. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  53. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +47 -41
  54. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -2
  56. package/lib/runtime/components/react/dist/mpx-swiper.jsx +606 -0
  57. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  58. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  59. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  60. package/lib/runtime/components/react/dist/mpx-view.jsx +65 -61
  61. package/lib/runtime/components/react/dist/mpx-web-view.jsx +112 -35
  62. package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
  63. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  64. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  65. package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
  66. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -9
  67. package/lib/runtime/components/react/dist/utils.jsx +70 -23
  68. package/lib/runtime/components/react/event.config.ts +25 -26
  69. package/lib/runtime/components/react/getInnerListeners.ts +237 -199
  70. package/lib/runtime/components/react/mpx-button.tsx +104 -57
  71. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  72. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  73. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  74. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  75. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  76. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  77. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  78. package/lib/runtime/components/react/mpx-canvas/index.tsx +296 -0
  79. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  80. package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
  81. package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
  82. package/lib/runtime/components/react/mpx-form.tsx +25 -28
  83. package/lib/runtime/components/react/mpx-icon.tsx +12 -17
  84. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  85. package/lib/runtime/components/react/mpx-input.tsx +77 -57
  86. package/lib/runtime/components/react/mpx-label.tsx +26 -27
  87. package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
  88. package/lib/runtime/components/react/mpx-movable-view.tsx +21 -25
  89. package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
  90. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  91. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  92. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  93. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  94. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  95. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  96. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  97. package/lib/runtime/components/react/mpx-picker-view-column.tsx +236 -104
  98. package/lib/runtime/components/react/mpx-picker-view.tsx +132 -122
  99. package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
  100. package/lib/runtime/components/react/mpx-radio.tsx +45 -54
  101. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  102. package/lib/runtime/components/react/mpx-rich-text/index.tsx +121 -0
  103. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  104. package/lib/runtime/components/react/mpx-scroll-view.tsx +72 -71
  105. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  106. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
  107. package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
  108. package/lib/runtime/components/react/mpx-switch.tsx +29 -23
  109. package/lib/runtime/components/react/mpx-text.tsx +14 -18
  110. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  111. package/lib/runtime/components/react/mpx-view.tsx +92 -76
  112. package/lib/runtime/components/react/mpx-web-view.tsx +116 -54
  113. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  114. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  115. package/lib/runtime/components/react/types/common.ts +2 -0
  116. package/lib/runtime/components/react/types/global.d.ts +5 -17
  117. package/lib/runtime/components/react/useAnimationHooks.ts +36 -11
  118. package/lib/runtime/components/react/utils.tsx +99 -28
  119. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  120. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  121. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  122. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  123. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  124. package/lib/runtime/optionProcessor.js +7 -38
  125. package/lib/runtime/utils.js +2 -0
  126. package/lib/style-compiler/plugins/scope-id.js +30 -2
  127. package/lib/template-compiler/bind-this.js +7 -2
  128. package/lib/template-compiler/compiler.js +79 -47
  129. package/lib/template-compiler/gen-node-react.js +3 -3
  130. package/lib/utils/pre-process-json.js +9 -5
  131. package/package.json +6 -4
  132. package/LICENSE +0 -433
  133. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  134. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  135. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  136. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  137. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  138. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  139. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  140. 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,12 +5,13 @@
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 } from './utils';
14
+ import { error } from '@mpxjs/utils';
14
15
  import LinearGradient from 'react-native-linear-gradient';
15
16
  const linearMap = new Map([
16
17
  ['top', 0],
@@ -148,10 +149,7 @@ function backgroundPosition(imageProps, preImageInfo, imageSize, layoutInfo) {
148
149
  style[key] = val;
149
150
  }
150
151
  }
151
- imageProps.style = {
152
- ...imageProps.style,
153
- ...style
154
- };
152
+ extendObject(imageProps.style, style);
155
153
  }
156
154
  // background-size 转换
157
155
  function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
@@ -201,7 +199,7 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
201
199
  }
202
200
  else { // 数值类型 ImageStyle
203
201
  // 数值类型设置为 stretch
204
- imageProps.style.resizeMode = 'stretch';
202
+ imageProps.resizeMode = 'stretch';
205
203
  dimensions = {
206
204
  width: isPercent(width) ? width : +width,
207
205
  height: isPercent(height) ? height : +height
@@ -209,15 +207,13 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
209
207
  }
210
208
  }
211
209
  // 样式合并
212
- imageProps.style = {
213
- ...imageProps.style,
214
- ...dimensions
215
- };
210
+ extendObject(imageProps.style, dimensions);
216
211
  }
217
212
  // background-image转换为source
218
213
  function backgroundImage(imageProps, preImageInfo) {
219
- if (preImageInfo.src) {
220
- imageProps.src = preImageInfo.src;
214
+ const src = preImageInfo.src;
215
+ if (src) {
216
+ imageProps.source = { uri: src };
221
217
  }
222
218
  }
223
219
  // 渐变的转换
@@ -241,8 +237,8 @@ function linearGradient(imageProps, preImageInfo, imageSize, layoutInfo) {
241
237
  const imageStyleToProps = (preImageInfo, imageSize, layoutInfo) => {
242
238
  // 初始化
243
239
  const imageProps = {
240
+ resizeMode: 'cover',
244
241
  style: {
245
- resizeMode: 'cover',
246
242
  position: 'absolute'
247
243
  // ...StyleSheet.absoluteFillObject
248
244
  },
@@ -384,10 +380,9 @@ function parseLinearGradient(text) {
384
380
  !isNaN(numberVal) && locations.push(numberVal);
385
381
  return prev;
386
382
  }, { colors: [], locations: [] });
387
- return {
388
- ...linearInfo,
383
+ return extendObject({}, linearInfo, {
389
384
  direction: direction.trim()
390
- };
385
+ });
391
386
  }
392
387
  function parseBgImage(text) {
393
388
  if (!text)
@@ -430,7 +425,23 @@ function preParseImage(imageStyle) {
430
425
  function isDiagonalAngle(linearInfo) {
431
426
  return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction]);
432
427
  }
433
- function wrapImage(imageStyle) {
428
+ function inheritStyle(innerStyle = {}) {
429
+ const { borderWidth, borderRadius } = innerStyle;
430
+ const borderStyles = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'];
431
+ return pickStyle(innerStyle, borderStyles, borderWidth && borderRadius
432
+ ? (key, val) => {
433
+ // 盒子内圆角borderWith与borderRadius的关系
434
+ // 当borderRadius 小于 当borderWith 内边框为直角
435
+ // 当borderRadius 大于等于 当borderWith 内边框为圆角
436
+ if (borderStyles.includes(key)) {
437
+ const borderVal = +val - borderWidth;
438
+ return borderVal > 0 ? borderVal : 0;
439
+ }
440
+ return val;
441
+ }
442
+ : undefined);
443
+ }
444
+ function wrapImage(imageStyle, innerStyle, enableFastImage) {
434
445
  // 预处理数据
435
446
  const preImageInfo = preParseImage(imageStyle);
436
447
  // 预解析
@@ -510,12 +521,12 @@ function wrapImage(imageStyle) {
510
521
  setShow(true);
511
522
  }
512
523
  };
513
- return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
524
+ return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
514
525
  {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
515
- {show && type === 'image' && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
526
+ {show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current), enableFastImage))}
516
527
  </View>;
517
528
  }
518
- function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps }) {
529
+ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }) {
519
530
  const children = wrapChildren(props, {
520
531
  hasVarDec,
521
532
  varContext,
@@ -523,29 +534,24 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
523
534
  textProps
524
535
  });
525
536
  return [
526
- enableBackground ? wrapImage(backgroundStyle) : null,
537
+ enableBackground ? wrapImage(backgroundStyle, innerStyle, enableFastImage) : null,
527
538
  children
528
539
  ];
529
540
  }
530
541
  const _View = forwardRef((viewProps, ref) => {
531
542
  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;
543
+ 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;
533
544
  const [isHover, setIsHover] = useState(false);
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 styleObj = extendObject({}, defaultStyle, style, isHover ? hoverStyle : {});
549
555
  const { normalStyle, hasSelfPercent, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, {
550
556
  enableVar,
551
557
  externalVarContext,
@@ -553,15 +559,15 @@ const _View = forwardRef((viewProps, ref) => {
553
559
  parentWidth,
554
560
  parentHeight
555
561
  });
556
- const { textStyle, backgroundStyle, innerStyle } = splitStyle(normalStyle);
562
+ const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle);
557
563
  enableBackground = enableBackground || !!backgroundStyle;
558
564
  const enableBackgroundRef = useRef(enableBackground);
559
565
  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.');
566
+ error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.');
561
567
  }
562
568
  const nodeRef = useRef(null);
563
569
  useNodesRef(props, ref, nodeRef, {
564
- defaultStyle
570
+ style: normalStyle
565
571
  });
566
572
  const dataRef = useRef({});
567
573
  useEffect(() => {
@@ -594,16 +600,27 @@ const _View = forwardRef((viewProps, ref) => {
594
600
  setStayTimer();
595
601
  }
596
602
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
597
- const viewStyle = Object.assign({}, innerStyle, layoutStyle);
598
- const innerProps = useInnerProps(props, {
603
+ const viewStyle = extendObject({}, innerStyle, layoutStyle);
604
+ enableAnimation = enableAnimation || !!animation;
605
+ const enableAnimationRef = useRef(enableAnimation);
606
+ if (enableAnimationRef.current !== enableAnimation) {
607
+ error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.');
608
+ }
609
+ const finalStyle = enableAnimationRef.current
610
+ ? [viewStyle, useAnimationHooks({
611
+ animation,
612
+ style: viewStyle
613
+ })]
614
+ : viewStyle;
615
+ const innerProps = useInnerProps(props, extendObject({
599
616
  ref: nodeRef,
600
- style: viewStyle,
601
- ...layoutProps,
602
- ...(hoverStyle && {
617
+ style: finalStyle
618
+ }, layoutProps, hoverStyle
619
+ ? {
603
620
  bindtouchstart: onTouchStart,
604
621
  bindtouchend: onTouchEnd
605
- })
606
- }, [
622
+ }
623
+ : {}), [
607
624
  'hover-start-time',
608
625
  'hover-stay-time',
609
626
  'hover-style',
@@ -611,32 +628,19 @@ const _View = forwardRef((viewProps, ref) => {
611
628
  ], {
612
629
  layoutRef
613
630
  });
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
631
  const childNode = wrapWithChildren(props, {
626
632
  hasVarDec,
627
633
  enableBackground: enableBackgroundRef.current,
628
634
  textStyle,
629
635
  backgroundStyle,
630
636
  varContext: varContextRef.current,
631
- textProps
637
+ textProps,
638
+ innerStyle,
639
+ enableFastImage
632
640
  });
633
- return animation?.actions?.length
634
- ? (<Animated.View {...innerProps} style={finalStyle}>
635
- {childNode}
636
- </Animated.View>)
637
- : (<View {...innerProps}>
638
- {childNode}
639
- </View>);
641
+ return enableAnimation
642
+ ? createElement(Animated.View, innerProps, childNode)
643
+ : createElement(View, innerProps, childNode);
640
644
  });
641
645
  _View.displayName = 'MpxView';
642
646
  export default _View;
@@ -1,15 +1,21 @@
1
- import { forwardRef, useEffect, useRef } from 'react';
2
- import { noop, warn } from '@mpxjs/utils';
1
+ import { forwardRef, useRef, useContext, useMemo, createElement } 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';
8
10
  const _WebView = forwardRef((props, ref) => {
9
- const { src = '', bindmessage = noop, bindload = noop, binderror = noop } = props;
11
+ const { src, bindmessage, bindload, binderror } = props;
12
+ const mpx = global.__mpx;
10
13
  if (props.style) {
11
14
  warn('The web-view component does not support the style prop.');
12
15
  }
16
+ const pageId = useContext(RouteContext);
17
+ const currentPage = useMemo(() => getCurrentPage(pageId), [pageId]);
18
+ const webViewRef = useRef(null);
13
19
  const defaultWebViewStyle = {
14
20
  position: 'absolute',
15
21
  left: 0,
@@ -17,26 +23,12 @@ const _WebView = forwardRef((props, ref) => {
17
23
  top: 0,
18
24
  bottom: 0
19
25
  };
20
- const webViewRef = useRef(null);
21
26
  useNodesRef(props, ref, webViewRef, {
22
- defaultStyle: defaultWebViewStyle
27
+ style: defaultWebViewStyle
23
28
  });
24
- const _messageList = [];
25
- const handleUnload = () => {
26
- // 这里是 WebView 销毁前执行的逻辑
27
- bindmessage(getCustomEvent('messsage', {}, {
28
- detail: {
29
- data: _messageList
30
- },
31
- layoutRef: webViewRef
32
- }));
33
- };
34
- useEffect(() => {
35
- // 组件卸载时执行
36
- return () => {
37
- handleUnload();
38
- };
39
- }, []);
29
+ if (!src) {
30
+ return null;
31
+ }
40
32
  const _load = function (res) {
41
33
  const result = {
42
34
  type: 'load',
@@ -57,6 +49,36 @@ const _WebView = forwardRef((props, ref) => {
57
49
  };
58
50
  binderror(result);
59
51
  };
52
+ const injectedJavaScript = `
53
+ if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
54
+ var _documentTitle = document.title;
55
+ window.ReactNativeWebView.postMessage(JSON.stringify({
56
+ type: 'setTitle',
57
+ payload: {
58
+ _documentTitle: _documentTitle
59
+ }
60
+ }))
61
+ Object.defineProperty(document, 'title', {
62
+ set (val) {
63
+ _documentTitle = val
64
+ window.ReactNativeWebView.postMessage(JSON.stringify({
65
+ type: 'setTitle',
66
+ payload: {
67
+ _documentTitle: _documentTitle
68
+ }
69
+ }))
70
+ },
71
+ get () {
72
+ return _documentTitle
73
+ }
74
+ });
75
+ }
76
+ `;
77
+ const _changeUrl = function (navState) {
78
+ if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
79
+ currentPage.__webViewUrl = navState.url;
80
+ }
81
+ };
60
82
  const _message = function (res) {
61
83
  let data = {};
62
84
  let asyncCallback;
@@ -67,47 +89,102 @@ const _WebView = forwardRef((props, ref) => {
67
89
  data = JSON.parse(nativeEventData);
68
90
  }
69
91
  }
70
- catch (e) {
71
- data = {};
72
- }
92
+ catch (e) { }
93
+ const args = data.args;
73
94
  const postData = data.payload || {};
74
- switch (data.type) {
95
+ const params = Array.isArray(args) ? args : [postData];
96
+ const type = data.type;
97
+ switch (type) {
98
+ case 'setTitle':
99
+ { // case下不允许直接声明,包个块解决该问题
100
+ const title = postData._documentTitle;
101
+ if (title) {
102
+ const navigation = getFocusedNavigation();
103
+ navigation && navigation.setOptions({ title });
104
+ }
105
+ }
106
+ break;
75
107
  case 'postMessage':
76
- _messageList.push(postData.data);
108
+ bindmessage && bindmessage(getCustomEvent('messsage', {}, {
109
+ detail: {
110
+ data: params[0]?.data
111
+ }
112
+ }));
77
113
  asyncCallback = Promise.resolve({
78
114
  errMsg: 'invokeWebappApi:ok'
79
115
  });
80
116
  break;
81
117
  case 'navigateTo':
82
- asyncCallback = navObj.navigateTo(postData);
118
+ asyncCallback = navObj.navigateTo(...params);
83
119
  break;
84
120
  case 'navigateBack':
85
- asyncCallback = navObj.navigateBack(postData);
121
+ asyncCallback = navObj.navigateBack(...params);
86
122
  break;
87
123
  case 'redirectTo':
88
- asyncCallback = navObj.redirectTo(postData);
124
+ asyncCallback = navObj.redirectTo(...params);
89
125
  break;
90
126
  case 'switchTab':
91
- asyncCallback = navObj.switchTab(postData);
127
+ asyncCallback = navObj.switchTab(...params);
92
128
  break;
93
129
  case 'reLaunch':
94
- asyncCallback = navObj.reLaunch(postData);
130
+ asyncCallback = navObj.reLaunch(...params);
131
+ break;
132
+ default:
133
+ if (type) {
134
+ const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type];
135
+ if (isFunction(implement)) {
136
+ asyncCallback = Promise.resolve(implement(...params));
137
+ }
138
+ else {
139
+ /* eslint-disable prefer-promise-reject-errors */
140
+ asyncCallback = Promise.reject({
141
+ errMsg: `未在apiImplementations中配置${type}方法`
142
+ });
143
+ }
144
+ }
95
145
  break;
96
146
  }
97
147
  asyncCallback && asyncCallback.then((res) => {
98
148
  if (webViewRef.current?.postMessage) {
99
149
  const test = JSON.stringify({
100
- type: data.type,
150
+ type,
101
151
  callbackId: data.callbackId,
102
152
  result: res
103
153
  });
104
154
  webViewRef.current.postMessage(test);
105
155
  }
156
+ }).catch((error) => {
157
+ if (webViewRef.current?.postMessage) {
158
+ const test = JSON.stringify({
159
+ type,
160
+ callbackId: data.callbackId,
161
+ error
162
+ });
163
+ webViewRef.current.postMessage(test);
164
+ }
106
165
  });
107
166
  };
108
- return (<Portal>
109
- <WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} onLoad={_load} onError={_error} onMessage={_message} javaScriptEnabled={true}></WebView>
110
- </Portal>);
167
+ const events = {};
168
+ if (bindload) {
169
+ extendObject(events, {
170
+ onLoad: _load
171
+ });
172
+ }
173
+ if (binderror) {
174
+ extendObject(events, {
175
+ onError: _error
176
+ });
177
+ }
178
+ extendObject(events, {
179
+ onMessage: _message
180
+ });
181
+ return createElement(Portal, null, createElement(WebView, extendObject({
182
+ style: defaultWebViewStyle,
183
+ source: { uri: src },
184
+ ref: webViewRef,
185
+ javaScriptEnabled: true,
186
+ onNavigationStateChange: _changeUrl
187
+ }, events)));
111
188
  });
112
189
  _WebView.displayName = 'MpxWebview';
113
190
  export default _WebView;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Borrowed from open-source code: https://github.com/quidone/react-native-wheel-picker
3
+ * Special thanks to the authors for their contribution to the open-source community.
4
+ */
5
+ export const degToRad = (deg) => (Math.PI * deg) / 180;
6
+ // Calculates the height of the element after rotating it relative to the user's screen.
7
+ const calcHeight = (degree, itemHeight) => itemHeight * Math.cos(degToRad(degree));
8
+ export const calcPickerHeight = (faces, itemHeight) => {
9
+ if (faces.length === 7) {
10
+ return itemHeight * 5;
11
+ }
12
+ return faces.reduce((r, v) => r + calcHeight(Math.abs(v.deg), itemHeight), 0);
13
+ };
14
+ export const createFaces = (itemHeight, visibleCount) => {
15
+ // e.g [30, 60, 90]
16
+ const getDegreesRelativeCenter = () => {
17
+ const maxStep = Math.trunc((visibleCount + 2) / 2); // + 2 because there are 2 more faces at 90 degrees
18
+ const stepDegree = 90 / maxStep;
19
+ const result = [];
20
+ for (let i = 1; i <= maxStep; i++) {
21
+ result.push(i * stepDegree);
22
+ }
23
+ return result;
24
+ };
25
+ const getScreenHeightsAndOffsets = (degrees) => {
26
+ const screenHeights = degrees.map((deg) => calcHeight(deg, itemHeight));
27
+ const freeSpaces = screenHeights.map((screenHeight) => itemHeight - screenHeight);
28
+ const offsets = freeSpaces.map((freeSpace, index) => {
29
+ let offset = freeSpace / 2;
30
+ for (let i = 0; i < index; i++) {
31
+ offset += freeSpaces[i];
32
+ }
33
+ if (index === 0) {
34
+ offset *= 0.6;
35
+ }
36
+ return offset;
37
+ });
38
+ return [screenHeights, offsets];
39
+ };
40
+ const getOpacity = (index) => {
41
+ const map = {
42
+ 0: 0,
43
+ 1: 0.8,
44
+ 2: 0.9 // 0.35
45
+ // 3: 0.45, // 0.45
46
+ // 4: 0.5 // 0.5
47
+ };
48
+ return map[index] ?? Math.min(1, map[2] + index * 0.05);
49
+ };
50
+ const degrees = getDegreesRelativeCenter();
51
+ const [screenHeight, offsets] = getScreenHeightsAndOffsets(degrees);
52
+ const scales = [1, 0.925, 0.8];
53
+ return [
54
+ // top items
55
+ ...degrees
56
+ .map((degree, index) => {
57
+ return {
58
+ index: -1 * (index + 1),
59
+ deg: degree,
60
+ opacity: getOpacity(degrees.length - 1 - index),
61
+ offsetY: -1 * offsets[index],
62
+ scale: scales[index],
63
+ screenHeight: screenHeight[index]
64
+ };
65
+ })
66
+ .reverse(),
67
+ // center item
68
+ { index: 0, deg: 0, opacity: 1, offsetY: 0, scale: 1.031, screenHeight: itemHeight },
69
+ // bottom items
70
+ ...degrees.map((degree, index) => {
71
+ return {
72
+ index: index + 1,
73
+ deg: -1 * degree,
74
+ opacity: getOpacity(degrees.length - 1 - index),
75
+ offsetY: offsets[index],
76
+ scale: scales[index],
77
+ screenHeight: screenHeight[index]
78
+ };
79
+ })
80
+ ];
81
+ };
@@ -0,0 +1,9 @@
1
+ import { createContext, useContext } from 'react';
2
+ export const PickerViewColumnAnimationContext = createContext(undefined);
3
+ export const usePickerViewColumnAnimationContext = () => {
4
+ const value = useContext(PickerViewColumnAnimationContext);
5
+ if (value === undefined) {
6
+ throw new Error('usePickerViewColumnAnimationContext must be called from within PickerViewColumnAnimationContext.Provider!');
7
+ }
8
+ return value;
9
+ };
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { StyleSheet, View } from 'react-native';
3
+ import LinearGradient from 'react-native-linear-gradient';
4
+ const _PickerViewMask = ({ itemHeight, maskContainerStyle }) => {
5
+ return (<View style={[styles.overlayContainer, maskContainerStyle]} pointerEvents={'none'}>
6
+ <LinearGradient colors={['rgba(255,255,255,1)', 'rgba(255,255,255,0.5)']} style={{ flex: 1 }}/>
7
+ <View style={{ height: itemHeight }}/>
8
+ <LinearGradient colors={['rgba(255,255,255,0.5)', 'rgba(255,255,255,1)']} style={{ flex: 1 }}/>
9
+ </View>);
10
+ };
11
+ const styles = StyleSheet.create({
12
+ overlayContainer: {
13
+ ...StyleSheet.absoluteFillObject,
14
+ zIndex: 100
15
+ }
16
+ });
17
+ _PickerViewMask.displayName = 'MpxPickerViewMask';
18
+ export default _PickerViewMask;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { StyleSheet, View } from 'react-native';
3
+ const _PickerViewOverlay = ({ itemHeight, overlayItemStyle, overlayContainerStyle }) => {
4
+ return (<View style={[styles.overlayContainer, overlayContainerStyle]} pointerEvents={'none'}>
5
+ <View style={[styles.selection, { height: itemHeight }, overlayItemStyle]}/>
6
+ </View>);
7
+ };
8
+ const styles = StyleSheet.create({
9
+ overlayContainer: {
10
+ ...StyleSheet.absoluteFillObject,
11
+ justifyContent: 'center',
12
+ alignItems: 'center',
13
+ zIndex: 200
14
+ },
15
+ selection: {
16
+ borderTopWidth: 1,
17
+ borderBottomWidth: 1,
18
+ borderColor: 'rgba(0, 0, 0, 0.05)',
19
+ alignSelf: 'stretch'
20
+ }
21
+ });
22
+ _PickerViewOverlay.displayName = 'MpxPickerViewOverlay';
23
+ export default _PickerViewOverlay;