@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,15 +4,16 @@
4
4
  * ✔ hover-start-time
5
5
  * ✔ hover-stay-time
6
6
  */
7
- import { View, TextStyle, NativeSyntheticEvent, ViewProps, ImageStyle, ImageResizeMode, StyleSheet, Image, LayoutChangeEvent, Text } from 'react-native'
8
- import { useRef, useState, useEffect, forwardRef, ReactNode, JSX, Children, cloneElement } from 'react'
7
+ import { View, TextStyle, NativeSyntheticEvent, ViewProps, ImageStyle, StyleSheet, Image, LayoutChangeEvent } from 'react-native'
8
+ import { useRef, useState, useEffect, forwardRef, ReactNode, JSX, 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 type { AnimationProp } from './useAnimationHooks'
13
13
  import { ExtendedViewStyle } from './types/common'
14
14
  import useNodesRef, { HandlerRef } from './useNodesRef'
15
- import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout } from './utils'
15
+ import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject } from './utils'
16
+ import { error } from '@mpxjs/utils'
16
17
  import LinearGradient from 'react-native-linear-gradient'
17
18
 
18
19
  export interface _ViewProps extends ViewProps {
@@ -24,6 +25,7 @@ export interface _ViewProps extends ViewProps {
24
25
  'hover-stay-time'?: number
25
26
  'enable-background'?: boolean
26
27
  'enable-var'?: boolean
28
+ 'enable-fast-image'?: boolean
27
29
  'external-var-context'?: Record<string, any>
28
30
  'parent-font-size'?: number
29
31
  'parent-width'?: number
@@ -76,9 +78,11 @@ type PreImageInfo = {
76
78
  type ImageProps = {
77
79
  style: ImageStyle,
78
80
  src?: string,
81
+ source?: {uri: string },
79
82
  colors: Array<string>,
80
83
  locations?: Array<number>
81
84
  angle?: number
85
+ resizeMode?: 'cover' | 'stretch'
82
86
  }
83
87
 
84
88
  const linearMap = new Map([
@@ -233,10 +237,7 @@ function backgroundPosition (imageProps: ImageProps, preImageInfo: PreImageInfo,
233
237
  }
234
238
  }
235
239
 
236
- imageProps.style = {
237
- ...imageProps.style as ImageStyle,
238
- ...style
239
- }
240
+ extendObject(imageProps.style, style)
240
241
  }
241
242
 
242
243
  // background-size 转换
@@ -280,24 +281,23 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
280
281
  if (!dimensions) return
281
282
  } else { // 数值类型 ImageStyle
282
283
  // 数值类型设置为 stretch
283
- (imageProps.style as ImageStyle).resizeMode = 'stretch'
284
+ imageProps.resizeMode = 'stretch'
284
285
  dimensions = {
285
286
  width: isPercent(width) ? width : +width,
286
287
  height: isPercent(height) ? height : +height
287
288
  } as { width: NumberVal, height: NumberVal }
288
289
  }
289
290
  }
291
+
290
292
  // 样式合并
291
- imageProps.style = {
292
- ...imageProps.style as ImageStyle,
293
- ...dimensions
294
- }
293
+ extendObject(imageProps.style, dimensions)
295
294
  }
296
295
 
297
296
  // background-image转换为source
298
297
  function backgroundImage (imageProps: ImageProps, preImageInfo: PreImageInfo) {
299
- if (preImageInfo.src) {
300
- imageProps.src = preImageInfo.src
298
+ const src = preImageInfo.src
299
+ if (src) {
300
+ imageProps.source = { uri: src }
301
301
  }
302
302
  }
303
303
 
@@ -326,8 +326,8 @@ function linearGradient (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
326
326
  const imageStyleToProps = (preImageInfo: PreImageInfo, imageSize: Size, layoutInfo: Size) => {
327
327
  // 初始化
328
328
  const imageProps: ImageProps = {
329
+ resizeMode: 'cover',
329
330
  style: {
330
- resizeMode: 'cover' as ImageResizeMode,
331
331
  position: 'absolute'
332
332
  // ...StyleSheet.absoluteFillObject
333
333
  },
@@ -476,10 +476,9 @@ function parseLinearGradient (text: string): LinearInfo | undefined {
476
476
  return prev
477
477
  }, { colors: [], locations: [] })
478
478
 
479
- return {
480
- ...linearInfo,
479
+ return extendObject({}, linearInfo, {
481
480
  direction: direction.trim()
482
- }
481
+ })
483
482
  }
484
483
 
485
484
  function parseBgImage (text: string): {
@@ -533,7 +532,26 @@ function isDiagonalAngle (linearInfo?: LinearInfo): boolean {
533
532
  return !!(linearInfo?.direction && diagonalAngleMap[linearInfo.direction])
534
533
  }
535
534
 
536
- function wrapImage (imageStyle?: ExtendedViewStyle) {
535
+ function inheritStyle (innerStyle: ExtendedViewStyle = {}) {
536
+ const { borderWidth, borderRadius } = innerStyle
537
+ const borderStyles = ['borderRadius', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius']
538
+ return pickStyle(innerStyle,
539
+ borderStyles,
540
+ borderWidth && borderRadius
541
+ ? (key, val) => {
542
+ // 盒子内圆角borderWith与borderRadius的关系
543
+ // 当borderRadius 小于 当borderWith 内边框为直角
544
+ // 当borderRadius 大于等于 当borderWith 内边框为圆角
545
+ if (borderStyles.includes(key)) {
546
+ const borderVal = +val - borderWidth
547
+ return borderVal > 0 ? borderVal : 0
548
+ }
549
+ return val
550
+ }
551
+ : undefined)
552
+ }
553
+
554
+ function wrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<string, any>, enableFastImage?: boolean) {
537
555
  // 预处理数据
538
556
  const preImageInfo: PreImageInfo = preParseImage(imageStyle)
539
557
  // 预解析
@@ -616,9 +634,9 @@ function wrapImage (imageStyle?: ExtendedViewStyle) {
616
634
  }
617
635
  }
618
636
 
619
- return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
637
+ return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
620
638
  {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} /> }
621
- {show && type === 'image' && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
639
+ {show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size), enableFastImage))}
622
640
  </View>
623
641
  }
624
642
 
@@ -629,9 +647,11 @@ interface WrapChildrenConfig {
629
647
  backgroundStyle?: ExtendedViewStyle
630
648
  varContext?: Record<string, any>
631
649
  textProps?: Record<string, any>
650
+ innerStyle?: Record<string, any>
651
+ enableFastImage?: boolean
632
652
  }
633
653
 
634
- function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps }: WrapChildrenConfig) {
654
+ function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }: WrapChildrenConfig) {
635
655
  const children = wrapChildren(props, {
636
656
  hasVarDec,
637
657
  varContext,
@@ -640,7 +660,7 @@ function wrapWithChildren (props: _ViewProps, { hasVarDec, enableBackground, tex
640
660
  })
641
661
 
642
662
  return [
643
- enableBackground ? wrapImage(backgroundStyle) : null,
663
+ enableBackground ? wrapImage(backgroundStyle, innerStyle, enableFastImage) : null,
644
664
  children
645
665
  ]
646
666
  }
@@ -655,6 +675,7 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
655
675
  'enable-var': enableVar,
656
676
  'external-var-context': externalVarContext,
657
677
  'enable-background': enableBackground,
678
+ 'enable-fast-image': enableFastImage,
658
679
  'enable-animation': enableAnimation,
659
680
  'parent-font-size': parentFontSize,
660
681
  'parent-width': parentWidth,
@@ -665,21 +686,16 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
665
686
  const [isHover, setIsHover] = useState(false)
666
687
 
667
688
  // 默认样式
668
- const defaultStyle: ExtendedViewStyle = {
669
- // flex 布局相关的默认样式
670
- ...style.display === 'flex' && {
671
- flexDirection: 'row',
672
- flexBasis: 'auto',
673
- flexShrink: 1,
674
- flexWrap: 'nowrap'
675
- }
676
- }
689
+ const defaultStyle: ExtendedViewStyle = style.display === 'flex'
690
+ ? {
691
+ flexDirection: 'row',
692
+ flexBasis: 'auto',
693
+ flexShrink: 1,
694
+ flexWrap: 'nowrap'
695
+ }
696
+ : {}
677
697
 
678
- const styleObj: ExtendedViewStyle = {
679
- ...defaultStyle,
680
- ...style,
681
- ...(isHover ? hoverStyle : null)
682
- }
698
+ const styleObj: ExtendedViewStyle = extendObject({}, defaultStyle, style, isHover ? hoverStyle as ExtendedViewStyle : {})
683
699
 
684
700
  const {
685
701
  normalStyle,
@@ -696,17 +712,17 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
696
712
  parentHeight
697
713
  })
698
714
 
699
- const { textStyle, backgroundStyle, innerStyle } = splitStyle(normalStyle)
715
+ const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle)
700
716
 
701
717
  enableBackground = enableBackground || !!backgroundStyle
702
718
  const enableBackgroundRef = useRef(enableBackground)
703
719
  if (enableBackgroundRef.current !== enableBackground) {
704
- throw new Error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.')
720
+ error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.')
705
721
  }
706
722
 
707
723
  const nodeRef = useRef(null)
708
724
  useNodesRef<View, _ViewProps>(props, ref, nodeRef, {
709
- defaultStyle
725
+ style: normalStyle
710
726
  })
711
727
 
712
728
  const dataRef = useRef<{
@@ -754,55 +770,55 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
754
770
  layoutProps
755
771
  } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
756
772
 
757
- const viewStyle = Object.assign({}, innerStyle, layoutStyle)
758
- const innerProps = useInnerProps(props, {
759
- ref: nodeRef,
760
- style: viewStyle,
761
- ...layoutProps,
762
- ...(hoverStyle && {
763
- bindtouchstart: onTouchStart,
764
- bindtouchend: onTouchEnd
765
- })
766
- }, [
767
- 'hover-start-time',
768
- 'hover-stay-time',
769
- 'hover-style',
770
- 'hover-class'
771
- ], {
772
- layoutRef
773
- })
773
+ const viewStyle = extendObject({}, innerStyle, layoutStyle)
774
774
 
775
775
  enableAnimation = enableAnimation || !!animation
776
776
  const enableAnimationRef = useRef(enableAnimation)
777
777
  if (enableAnimationRef.current !== enableAnimation) {
778
- throw new Error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.')
778
+ error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.')
779
779
  }
780
- const finalStyle = enableAnimation
781
- ? useAnimationHooks({
782
- animation,
783
- style: viewStyle
784
- })
780
+ const finalStyle = enableAnimationRef.current
781
+ ? [viewStyle, useAnimationHooks({
782
+ animation,
783
+ style: viewStyle
784
+ })]
785
785
  : viewStyle
786
+ const innerProps = useInnerProps(
787
+ props,
788
+ extendObject({
789
+ ref: nodeRef,
790
+ style: finalStyle
791
+ },
792
+ layoutProps,
793
+ hoverStyle
794
+ ? {
795
+ bindtouchstart: onTouchStart,
796
+ bindtouchend: onTouchEnd
797
+ }
798
+ : {}
799
+ ), [
800
+ 'hover-start-time',
801
+ 'hover-stay-time',
802
+ 'hover-style',
803
+ 'hover-class'
804
+ ], {
805
+ layoutRef
806
+ })
807
+
786
808
  const childNode = wrapWithChildren(props, {
787
809
  hasVarDec,
788
810
  enableBackground: enableBackgroundRef.current,
789
811
  textStyle,
790
812
  backgroundStyle,
791
813
  varContext: varContextRef.current,
792
- textProps
814
+ textProps,
815
+ innerStyle,
816
+ enableFastImage
793
817
  })
794
- return animation?.actions?.length
795
- ? (<Animated.View
796
- {...innerProps}
797
- style={finalStyle}
798
- >
799
- {childNode}
800
- </Animated.View>)
801
- : (<View
802
- {...innerProps}
803
- >
804
- {childNode}
805
- </View>)
818
+
819
+ return enableAnimation
820
+ ? createElement(Animated.View, innerProps, childNode)
821
+ : createElement(View, innerProps, childNode)
806
822
  })
807
823
 
808
824
  _View.displayName = 'MpxView'
@@ -1,11 +1,13 @@
1
- import { forwardRef, JSX, useEffect, useRef } from 'react'
2
- import { noop, warn } from '@mpxjs/utils'
1
+ import { forwardRef, JSX, 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, { HandlerRef } from './useNodesRef'
8
- import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent } from 'react-native-webview/lib/WebViewTypes'
8
+ import { getCurrentPage, extendObject } from './utils'
9
+ import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent, WebViewNavigation } from 'react-native-webview/lib/WebViewTypes'
10
+ import { RouteContext } from './context'
9
11
 
10
12
  type OnMessageCallbackEvent = {
11
13
  detail: {
@@ -28,29 +30,25 @@ interface WebViewProps {
28
30
  }
29
31
 
30
32
  interface PayloadData {
31
- data?: Record<string, any>
33
+ [x: string]: any
32
34
  }
33
35
 
34
36
  type MessageData = {
35
37
  payload?: PayloadData,
38
+ args?: Array<any>,
36
39
  type?: string,
37
40
  callbackId?: number
38
41
  }
39
42
 
40
- interface NativeEvent {
41
- url: string,
42
- data: string
43
- }
44
-
45
- interface FormRef {
46
- postMessage: (value: any) => void;
47
- }
48
-
49
- const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element => {
50
- const { src = '', bindmessage = noop, bindload = noop, binderror = noop } = props
43
+ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element | null => {
44
+ const { src, bindmessage, bindload, binderror } = props
45
+ const mpx = global.__mpx
51
46
  if (props.style) {
52
47
  warn('The web-view component does not support the style prop.')
53
48
  }
49
+ const pageId = useContext(RouteContext)
50
+ const currentPage = useMemo(() => getCurrentPage(pageId), [pageId])
51
+ const webViewRef = useRef<WebView>(null)
54
52
  const defaultWebViewStyle = {
55
53
  position: 'absolute' as 'absolute' | 'relative' | 'static',
56
54
  left: 0 as number,
@@ -59,28 +57,14 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
59
57
  bottom: 0 as number
60
58
  }
61
59
 
62
- const webViewRef = useRef<WebView>(null)
63
60
  useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
64
- defaultStyle: defaultWebViewStyle
61
+ style: defaultWebViewStyle
65
62
  })
66
63
 
67
- const _messageList: any[] = []
68
- const handleUnload = () => {
69
- // 这里是 WebView 销毁前执行的逻辑
70
- bindmessage(getCustomEvent('messsage', {}, {
71
- detail: {
72
- data: _messageList
73
- },
74
- layoutRef: webViewRef
75
- }))
64
+ if (!src) {
65
+ return null
76
66
  }
77
67
 
78
- useEffect(() => {
79
- // 组件卸载时执行
80
- return () => {
81
- handleUnload()
82
- }
83
- }, [])
84
68
  const _load = function (res: WebViewNavigationEvent) {
85
69
  const result = {
86
70
  type: 'load',
@@ -101,6 +85,36 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
101
85
  }
102
86
  binderror(result)
103
87
  }
88
+ const injectedJavaScript = `
89
+ if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
90
+ var _documentTitle = document.title;
91
+ window.ReactNativeWebView.postMessage(JSON.stringify({
92
+ type: 'setTitle',
93
+ payload: {
94
+ _documentTitle: _documentTitle
95
+ }
96
+ }))
97
+ Object.defineProperty(document, 'title', {
98
+ set (val) {
99
+ _documentTitle = val
100
+ window.ReactNativeWebView.postMessage(JSON.stringify({
101
+ type: 'setTitle',
102
+ payload: {
103
+ _documentTitle: _documentTitle
104
+ }
105
+ }))
106
+ },
107
+ get () {
108
+ return _documentTitle
109
+ }
110
+ });
111
+ }
112
+ `
113
+ const _changeUrl = function (navState: WebViewNavigation) {
114
+ if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
115
+ currentPage.__webViewUrl = navState.url
116
+ }
117
+ }
104
118
  const _message = function (res: WebViewMessageEvent) {
105
119
  let data: MessageData = {}
106
120
  let asyncCallback
@@ -110,56 +124,104 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
110
124
  if (typeof nativeEventData === 'string') {
111
125
  data = JSON.parse(nativeEventData)
112
126
  }
113
- } catch (e) {
114
- data = {}
115
- }
127
+ } catch (e) {}
128
+ const args = data.args
116
129
  const postData: PayloadData = data.payload || {}
117
- switch (data.type) {
130
+ const params = Array.isArray(args) ? args : [postData]
131
+ const type = data.type
132
+ switch (type) {
133
+ case 'setTitle':
134
+ { // case下不允许直接声明,包个块解决该问题
135
+ const title = postData._documentTitle
136
+ if (title) {
137
+ const navigation = getFocusedNavigation()
138
+ navigation && navigation.setOptions({ title })
139
+ }
140
+ }
141
+ break
118
142
  case 'postMessage':
119
- _messageList.push(postData.data)
143
+ bindmessage && bindmessage(getCustomEvent('messsage', {}, { // RN组件销毁顺序与小程序不一致,所以改成和支付宝消息一致
144
+ detail: {
145
+ data: params[0]?.data
146
+ }
147
+ }))
120
148
  asyncCallback = Promise.resolve({
121
149
  errMsg: 'invokeWebappApi:ok'
122
150
  })
123
151
  break
124
152
  case 'navigateTo':
125
- asyncCallback = navObj.navigateTo(postData)
153
+ asyncCallback = navObj.navigateTo(...params)
126
154
  break
127
155
  case 'navigateBack':
128
- asyncCallback = navObj.navigateBack(postData)
156
+ asyncCallback = navObj.navigateBack(...params)
129
157
  break
130
158
  case 'redirectTo':
131
- asyncCallback = navObj.redirectTo(postData)
159
+ asyncCallback = navObj.redirectTo(...params)
132
160
  break
133
161
  case 'switchTab':
134
- asyncCallback = navObj.switchTab(postData)
162
+ asyncCallback = navObj.switchTab(...params)
135
163
  break
136
164
  case 'reLaunch':
137
- asyncCallback = navObj.reLaunch(postData)
165
+ asyncCallback = navObj.reLaunch(...params)
166
+ break
167
+ default:
168
+ if (type) {
169
+ const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type]
170
+ if (isFunction(implement)) {
171
+ asyncCallback = Promise.resolve(implement(...params))
172
+ } else {
173
+ /* eslint-disable prefer-promise-reject-errors */
174
+ asyncCallback = Promise.reject({
175
+ errMsg: `未在apiImplementations中配置${type}方法`
176
+ })
177
+ }
178
+ }
138
179
  break
139
180
  }
140
181
 
141
182
  asyncCallback && asyncCallback.then((res: any) => {
142
183
  if (webViewRef.current?.postMessage) {
143
184
  const test = JSON.stringify({
144
- type: data.type,
185
+ type,
145
186
  callbackId: data.callbackId,
146
187
  result: res
147
188
  })
148
189
  webViewRef.current.postMessage(test)
149
190
  }
191
+ }).catch((error: any) => {
192
+ if (webViewRef.current?.postMessage) {
193
+ const test = JSON.stringify({
194
+ type,
195
+ callbackId: data.callbackId,
196
+ error
197
+ })
198
+ webViewRef.current.postMessage(test)
199
+ }
150
200
  })
151
201
  }
152
- return (<Portal>
153
- <WebView
154
- style={defaultWebViewStyle}
155
- source={{ uri: src }}
156
- ref={webViewRef}
157
- onLoad={_load}
158
- onError={_error}
159
- onMessage={_message}
160
- javaScriptEnabled={true}
161
- ></WebView>
162
- </Portal>)
202
+ const events = {}
203
+
204
+ if (bindload) {
205
+ extendObject(events, {
206
+ onLoad: _load
207
+ })
208
+ }
209
+ if (binderror) {
210
+ extendObject(events, {
211
+ onError: _error
212
+ })
213
+ }
214
+ extendObject(events, {
215
+ onMessage: _message
216
+ })
217
+
218
+ return createElement(Portal, null, createElement(WebView, extendObject({
219
+ style: defaultWebViewStyle,
220
+ source: { uri: src },
221
+ ref: webViewRef,
222
+ javaScriptEnabled: true,
223
+ onNavigationStateChange: _changeUrl
224
+ }, events)))
163
225
  })
164
226
 
165
227
  _WebView.displayName = 'MpxWebview'
@@ -0,0 +1,104 @@
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
+
6
+ export type Faces = {
7
+ index: number
8
+ deg: number
9
+ offsetY: number
10
+ opacity: number
11
+ screenHeight: number
12
+ }
13
+
14
+ export const degToRad = (deg: number) => (Math.PI * deg) / 180
15
+
16
+ // Calculates the height of the element after rotating it relative to the user's screen.
17
+ const calcHeight = (degree: number, itemHeight: number) =>
18
+ itemHeight * Math.cos(degToRad(degree))
19
+
20
+ export const calcPickerHeight = (faces: Faces[], itemHeight: number) => {
21
+ if (faces.length === 7) {
22
+ return itemHeight * 5
23
+ }
24
+ return faces.reduce((r, v) => r + calcHeight(Math.abs(v.deg), itemHeight), 0)
25
+ }
26
+
27
+ export const createFaces = (
28
+ itemHeight: number,
29
+ visibleCount: number
30
+ ): Faces[] => {
31
+ // e.g [30, 60, 90]
32
+ const getDegreesRelativeCenter = () => {
33
+ const maxStep = Math.trunc((visibleCount + 2) / 2) // + 2 because there are 2 more faces at 90 degrees
34
+ const stepDegree = 90 / maxStep
35
+
36
+ const result = []
37
+ for (let i = 1; i <= maxStep; i++) {
38
+ result.push(i * stepDegree)
39
+ }
40
+ return result
41
+ }
42
+
43
+ const getScreenHeightsAndOffsets = <T extends readonly number[]>(
44
+ degrees: T
45
+ ): [T, T] => {
46
+ const screenHeights = degrees.map((deg) =>
47
+ calcHeight(deg, itemHeight)
48
+ ) as unknown as T
49
+ const freeSpaces = screenHeights.map(
50
+ (screenHeight) => itemHeight - screenHeight
51
+ )
52
+ const offsets = freeSpaces.map((freeSpace, index) => {
53
+ let offset = freeSpace / 2
54
+ for (let i = 0; i < index; i++) {
55
+ offset += freeSpaces[i]
56
+ }
57
+ return offset
58
+ }) as unknown as T
59
+ return [screenHeights, offsets]
60
+ }
61
+
62
+ const getOpacity = (index: number) => {
63
+ const map: Record<number, number> = {
64
+ 0: 0,
65
+ 1: 0.2,
66
+ 2: 0.35,
67
+ 3: 0.45,
68
+ 4: 0.5
69
+ }
70
+ return map[index] ?? Math.min(1, map[4] + index * 0.5)
71
+ }
72
+
73
+ const degrees = getDegreesRelativeCenter()
74
+ const [screenHeight, offsets] = getScreenHeightsAndOffsets(degrees)
75
+
76
+ return [
77
+ // top items
78
+ ...degrees
79
+ .map<Faces>((degree, index) => {
80
+ return {
81
+ index: -1 * (index + 1),
82
+ deg: degree,
83
+ opacity: getOpacity(degrees.length - 1 - index),
84
+ offsetY: -1 * offsets[index],
85
+ screenHeight: screenHeight[index]
86
+ }
87
+ })
88
+ .reverse(),
89
+
90
+ // center item
91
+ { index: 0, deg: 0, opacity: 1, offsetY: 0, screenHeight: itemHeight },
92
+
93
+ // bottom items
94
+ ...degrees.map<Faces>((degree, index) => {
95
+ return {
96
+ index: index + 1,
97
+ deg: -1 * degree,
98
+ opacity: getOpacity(degrees.length - 1 - index),
99
+ offsetY: offsets[index],
100
+ screenHeight: screenHeight[index]
101
+ }
102
+ })
103
+ ]
104
+ }