@mpxjs/webpack-plugin 2.9.67 → 2.9.70-alpha.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 (161) hide show
  1. package/README.md +1 -1
  2. package/lib/config.js +14 -0
  3. package/lib/dependencies/AddEntryDependency.js +24 -0
  4. package/lib/dependencies/ResolveDependency.js +5 -0
  5. package/lib/index.js +51 -15
  6. package/lib/json-compiler/helper.js +3 -3
  7. package/lib/loader.js +53 -0
  8. package/lib/platform/template/wx/component-config/button.js +14 -2
  9. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  10. package/lib/platform/template/wx/component-config/image.js +4 -0
  11. package/lib/platform/template/wx/component-config/input.js +5 -1
  12. package/lib/platform/template/wx/component-config/rich-text.js +4 -0
  13. package/lib/platform/template/wx/component-config/scroll-view.js +4 -0
  14. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  15. package/lib/platform/template/wx/component-config/switch.js +4 -0
  16. package/lib/platform/template/wx/component-config/text.js +4 -0
  17. package/lib/platform/template/wx/component-config/textarea.js +6 -1
  18. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  19. package/lib/platform/template/wx/component-config/view.js +4 -0
  20. package/lib/platform/template/wx/index.js +127 -1
  21. package/lib/react/processStyles.js +14 -4
  22. package/lib/react/processTemplate.js +3 -0
  23. package/lib/resolve-loader.js +4 -1
  24. package/lib/resolver/AddModePlugin.js +8 -8
  25. package/lib/runtime/components/react/context.ts +6 -0
  26. package/lib/runtime/components/react/dist/context.js +2 -0
  27. package/lib/runtime/components/react/dist/event.config.js +24 -24
  28. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -174
  29. package/lib/runtime/components/react/dist/mpx-button.jsx +77 -49
  30. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  31. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  32. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  33. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  34. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  35. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  36. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  37. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
  38. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  39. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  40. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  41. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  42. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  43. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  44. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  45. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  46. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  47. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +13 -13
  48. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  49. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  50. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  51. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  52. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  53. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  54. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  55. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  56. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +160 -88
  57. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
  58. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  59. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  60. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  61. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  62. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  63. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +47 -41
  64. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  65. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -2
  66. package/lib/runtime/components/react/dist/mpx-swiper.jsx +606 -0
  67. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  68. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  69. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  70. package/lib/runtime/components/react/dist/mpx-view.jsx +65 -61
  71. package/lib/runtime/components/react/dist/mpx-web-view.jsx +112 -35
  72. package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
  73. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  74. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  75. package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
  76. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -9
  77. package/lib/runtime/components/react/dist/utils.jsx +70 -23
  78. package/lib/runtime/components/react/getInnerListeners.ts +36 -43
  79. package/lib/runtime/components/react/mpx-button.tsx +95 -43
  80. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  81. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  82. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  83. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  84. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  85. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  86. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  87. package/lib/runtime/components/react/mpx-canvas/index.tsx +302 -0
  88. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  89. package/lib/runtime/components/react/mpx-checkbox-group.tsx +13 -12
  90. package/lib/runtime/components/react/mpx-checkbox.tsx +28 -28
  91. package/lib/runtime/components/react/mpx-form.tsx +10 -8
  92. package/lib/runtime/components/react/mpx-icon.tsx +10 -15
  93. package/lib/runtime/components/react/mpx-image.tsx +396 -0
  94. package/lib/runtime/components/react/mpx-input.tsx +61 -33
  95. package/lib/runtime/components/react/mpx-label.tsx +14 -13
  96. package/lib/runtime/components/react/mpx-movable-area.tsx +8 -7
  97. package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
  98. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  99. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  100. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  101. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  102. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  103. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  104. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  105. package/lib/runtime/components/react/mpx-picker-view-column.tsx +236 -104
  106. package/lib/runtime/components/react/mpx-picker-view.tsx +132 -122
  107. package/lib/runtime/components/react/mpx-radio-group.tsx +11 -12
  108. package/lib/runtime/components/react/mpx-radio.tsx +26 -29
  109. package/lib/runtime/components/react/mpx-scroll-view.tsx +32 -30
  110. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  111. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
  112. package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
  113. package/lib/runtime/components/react/mpx-switch.tsx +10 -8
  114. package/lib/runtime/components/react/mpx-text.tsx +6 -2
  115. package/lib/runtime/components/react/mpx-view.tsx +81 -59
  116. package/lib/runtime/components/react/mpx-web-view.tsx +46 -19
  117. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  118. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  119. package/lib/runtime/components/react/types/common.ts +2 -0
  120. package/lib/runtime/components/react/types/global.d.ts +3 -16
  121. package/lib/runtime/components/react/utils.tsx +98 -27
  122. package/lib/runtime/components/tenon/getInnerListeners.js +334 -0
  123. package/lib/runtime/components/tenon/tenon-button.vue +309 -0
  124. package/lib/runtime/components/tenon/tenon-image.vue +66 -0
  125. package/lib/runtime/components/tenon/tenon-input.vue +171 -0
  126. package/lib/runtime/components/tenon/tenon-rich-text.vue +26 -0
  127. package/lib/runtime/components/tenon/tenon-scroll-view.vue +127 -0
  128. package/lib/runtime/components/tenon/tenon-switch.vue +96 -0
  129. package/lib/runtime/components/tenon/tenon-text.vue +70 -0
  130. package/lib/runtime/components/tenon/tenon-textarea.vue +86 -0
  131. package/lib/runtime/components/tenon/tenon-view.vue +93 -0
  132. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  133. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  134. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  135. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  136. package/lib/runtime/components/web/mpx-web-view.vue +162 -162
  137. package/lib/runtime/optionProcessor.js +7 -16
  138. package/lib/runtime/optionProcessor.tenon.js +84 -0
  139. package/lib/runtime/utils.js +2 -0
  140. package/lib/style-compiler/index.js +1 -1
  141. package/lib/style-compiler/plugins/hm.js +20 -0
  142. package/lib/template-compiler/bind-this.js +7 -2
  143. package/lib/template-compiler/compiler.js +70 -42
  144. package/lib/template-compiler/gen-node-react.js +3 -3
  145. package/lib/tenon/index.js +117 -0
  146. package/lib/tenon/processJSON.js +352 -0
  147. package/lib/tenon/processScript.js +203 -0
  148. package/lib/tenon/processStyles.js +21 -0
  149. package/lib/tenon/processTemplate.js +126 -0
  150. package/lib/tenon/script-helper.js +223 -0
  151. package/lib/utils/env.js +6 -1
  152. package/lib/utils/get-relative-path.js +25 -0
  153. package/package.json +9 -4
  154. package/LICENSE +0 -433
  155. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  156. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  157. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  158. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  159. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  160. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  161. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
@@ -1,16 +1,18 @@
1
- import { useEffect, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
- import { LayoutChangeEvent, TextStyle } from 'react-native'
3
- import { isObject, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
1
+ import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
+ import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
3
+ import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
4
4
  import { VarContext } from './context'
5
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
6
6
  import { initialWindowMetrics } from 'react-native-safe-area-context'
7
- import type { ExtendedFunctionComponent } from './types/common'
7
+ import FastImage, { FastImageProps } from '@d11/react-native-fast-image'
8
+ import type { AnyFunc, ExtendedFunctionComponent } from './types/common'
8
9
 
9
10
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
10
11
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
11
12
  export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/
13
+ export const SVG_REGEXP = /https?:\/\/.*\.(?:svg)/i
12
14
  export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/
13
- export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/
15
+ export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines|allowFontScaling/
14
16
  export const DEFAULT_FONT_SIZE = 16
15
17
  export const HIDDEN_STYLE = {
16
18
  opacity: 0
@@ -30,10 +32,7 @@ const safeAreaInsetMap: Record<string, 'top' | 'right' | 'bottom' | 'left'> = {
30
32
 
31
33
  function getSafeAreaInset (name: string) {
32
34
  const navigation = getFocusedNavigation()
33
- const insets = {
34
- ...initialWindowMetrics?.insets,
35
- ...navigation?.insets
36
- }
35
+ const insets = extendObject({}, initialWindowMetrics?.insets, navigation?.insets)
37
36
  return insets[safeAreaInsetMap[name]]
38
37
  }
39
38
 
@@ -78,7 +77,7 @@ export const parseInlineStyle = (inlineStyle = ''): Record<string, string> => {
78
77
  const [k, v, ...rest] = style.split(':')
79
78
  if (rest.length || !v || !k) return styleObj
80
79
  const key = k.trim().replace(/-./g, c => c.substring(1).toUpperCase())
81
- return Object.assign(styleObj, { [key]: v.trim() })
80
+ return Object.assign(styleObj, { [key]: global.__formatValue(v.trim()) })
82
81
  }, {})
83
82
  }
84
83
 
@@ -89,25 +88,18 @@ export const parseUrl = (cssUrl = '') => {
89
88
  }
90
89
 
91
90
  export const getRestProps = (transferProps: any = {}, originProps: any = {}, deletePropsKey: any = []) => {
92
- return {
93
- ...transferProps,
94
- ...omit(originProps, deletePropsKey)
95
- }
91
+ return extendObject(
92
+ {},
93
+ transferProps,
94
+ omit(originProps, deletePropsKey)
95
+ )
96
96
  }
97
97
 
98
98
  export function isText (ele: ReactNode): ele is ReactElement {
99
99
  if (isValidElement(ele)) {
100
100
  const displayName = (ele.type as ExtendedFunctionComponent)?.displayName
101
101
  const isCustomText = (ele.type as ExtendedFunctionComponent)?.isCustomText
102
- return displayName === 'MpxText' || displayName === 'Text' || !!isCustomText
103
- }
104
- return false
105
- }
106
-
107
- export function isEmbedded (ele: ReactNode): ele is ReactElement {
108
- if (isValidElement(ele)) {
109
- const displayName = (ele.type as ExtendedFunctionComponent)?.displayName || ''
110
- return ['mpx-checkbox', 'mpx-radio', 'mpx-switch'].includes(displayName)
102
+ return displayName === 'MpxText' || displayName === 'MpxSimpleText' || displayName === 'Text' || !!isCustomText
111
103
  }
112
104
  return false
113
105
  }
@@ -275,6 +267,15 @@ function transformCalc (styleObj: Record<string, any>, calcKeyPaths: Array<Array
275
267
  })
276
268
  }
277
269
 
270
+ const stringifyProps = ['fontWeight']
271
+ function transformStringify (styleObj: Record<string, any>) {
272
+ stringifyProps.forEach((prop) => {
273
+ if (isNumber(styleObj[prop])) {
274
+ styleObj[prop] = '' + styleObj[prop]
275
+ }
276
+ })
277
+ }
278
+
278
279
  interface TransformStyleConfig {
279
280
  enableVar?: boolean
280
281
  externalVarContext?: Record<string, any>
@@ -385,6 +386,8 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
385
386
  }
386
387
  }
387
388
  })
389
+ // transform number enum stringify
390
+ transformStringify(normalStyle)
388
391
 
389
392
  return {
390
393
  normalStyle,
@@ -513,8 +516,8 @@ export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varC
513
516
  if (textStyle || textProps) {
514
517
  children = Children.map(children, (child) => {
515
518
  if (isText(child)) {
516
- const style = { ...textStyle, ...child.props.style }
517
- return cloneElement(child, { ...textProps, style })
519
+ const style = extendObject({}, textStyle, child.props.style)
520
+ return cloneElement(child, extendObject({}, textProps, { style }))
518
521
  }
519
522
  return child
520
523
  })
@@ -525,9 +528,52 @@ export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varC
525
528
  return children
526
529
  }
527
530
 
531
+ export const debounce = <T extends AnyFunc> (
532
+ func: T,
533
+ delay: number
534
+ ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
535
+ let timer: any
536
+ const wrapper = (...args: ReadonlyArray<any>) => {
537
+ clearTimeout(timer)
538
+ timer = setTimeout(() => {
539
+ func(...args)
540
+ }, delay)
541
+ }
542
+ wrapper.clear = () => {
543
+ clearTimeout(timer)
544
+ }
545
+ return wrapper
546
+ }
547
+
548
+ export const useDebounceCallback = <T extends AnyFunc> (
549
+ func: T,
550
+ delay: number
551
+ ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
552
+ const debounced = useMemo(() => debounce(func, delay), [func])
553
+ return debounced
554
+ }
555
+
556
+ export const useStableCallback = <T extends AnyFunc | null | undefined> (
557
+ callback: T
558
+ ): T extends AnyFunc ? T : () => void => {
559
+ const ref = useRef<T>(callback)
560
+ ref.current = callback
561
+ return useCallback<any>(
562
+ (...args: any[]) => ref.current?.(...args),
563
+ []
564
+ )
565
+ }
566
+
567
+ export const usePrevious = <T, > (value: T): T | undefined => {
568
+ const ref = useRef<T | undefined>(undefined)
569
+ const prev = ref.current
570
+ ref.current = value
571
+ return prev
572
+ }
573
+
528
574
  export interface GestureHandler {
529
- nodeRefs?: Array<{ getNodeInstance: () => { nodeRef: unknown } }>;
530
- current?: unknown;
575
+ nodeRefs?: Array<{ getNodeInstance: () => { nodeRef: unknown } }>
576
+ current?: unknown
531
577
  }
532
578
 
533
579
  export function flatGesture (gestures: Array<GestureHandler> = []) {
@@ -539,3 +585,28 @@ export function flatGesture (gestures: Array<GestureHandler> = []) {
539
585
  return gesture?.current ? [gesture] : []
540
586
  })) || []
541
587
  }
588
+
589
+ export const extendObject = Object.assign
590
+
591
+ export function getCurrentPage (pageId: number | null) {
592
+ if (!global.getCurrentPages) return
593
+ const pages = global.getCurrentPages()
594
+ return pages.find((page: any) => isFunction(page.getPageId) && page.getPageId() === pageId)
595
+ }
596
+
597
+ export function renderImage (
598
+ imageProps: ImageProps | FastImageProps,
599
+ enableFastImage = false
600
+ ) {
601
+ const Component: React.ComponentType<ImageProps | FastImageProps> = enableFastImage ? FastImage : Image
602
+ return <Component {...imageProps} />
603
+ }
604
+
605
+ export function pickStyle (styleObj: Record<string, any> = {}, pickedKeys: Array<string>, callback?: (key: string, val: number | string) => number | string) {
606
+ return pickedKeys.reduce<Record<string, any>>((acc, key) => {
607
+ if (key in styleObj) {
608
+ acc[key] = callback ? callback(key, styleObj[key]) : styleObj[key]
609
+ }
610
+ return acc
611
+ }, {})
612
+ }
@@ -0,0 +1,334 @@
1
+ import { isEmptyObject } from '../../utils'
2
+
3
+ const tapEvents = [
4
+ 'onTouchstart',
5
+ 'onTouchmove',
6
+ 'onTouchcancel',
7
+ 'onTouchend',
8
+ 'onLongtap'
9
+ ]
10
+
11
+ function createTouch (context, hasLongTap, __mpxTapInfo) {
12
+ return ({
13
+ onTouch (e) {
14
+ // 用touch模拟longtap
15
+ switch (e.state) {
16
+ case 1:
17
+ context.$emit('touchstart', e)
18
+ __mpxTapInfo.detail = {
19
+ x: e.position.x,
20
+ y: e.position.y
21
+ }
22
+ __mpxTapInfo.startTimer = null
23
+
24
+ if (hasLongTap) {
25
+ __mpxTapInfo.startTimer = setTimeout(() => {
26
+ if (hasLongTap) {
27
+ const re = inheritEvent(
28
+ 'longtap',
29
+ e,
30
+ __mpxTapInfo.detail
31
+ )
32
+ context.$emit('longtap', re)
33
+ __mpxTapInfo.startTimer = null
34
+ }
35
+ }, 350)
36
+ }
37
+
38
+ break
39
+ case 2:
40
+ context.$emit('touchmove', e)
41
+ if (
42
+ Math.abs(e.position.x - __mpxTapInfo.detail.x) > 1 ||
43
+ Math.abs(e.position.y - __mpxTapInfo.detail.y) > 1
44
+ ) {
45
+ __mpxTapInfo.startTimer &&
46
+ clearTimeout(__mpxTapInfo.startTimer)
47
+ __mpxTapInfo.startTimer = null
48
+ }
49
+ break
50
+ case 3:
51
+ context.$emit('touchend', e)
52
+ __mpxTapInfo.startTimer &&
53
+ clearTimeout(__mpxTapInfo.startTimer)
54
+ __mpxTapInfo.startTimer = null
55
+ break
56
+ case 4:
57
+ context.$emit('touchcancel', e)
58
+ break
59
+ }
60
+ }
61
+ })
62
+ }
63
+
64
+ function processOriginEvent (listeners, context, _input) {
65
+ // 给event添加_originEvent属性
66
+ const ignoreEvents = ['onTap', 'onFocus', 'onChange', 'onBlur', 'onConfirm', 'onInput']
67
+ Object.keys(listeners).forEach((key) => {
68
+ if (!ignoreEvents.includes(key)) {
69
+ const listener = listeners[key]
70
+ listeners[key] = function (e) {
71
+ if (e) {
72
+ e._originEvent = { ...e }
73
+ }
74
+ listener.call(this, e)
75
+ }
76
+ }
77
+ })
78
+
79
+ // 处理input输入框事件
80
+ if (listeners.onInput && _input) {
81
+ delete listeners.onInput
82
+ listeners.onInput = function (e) {
83
+ let _type
84
+ const { state } = e || {}
85
+ if (state === 1) {
86
+ _type = 'focus'
87
+ } else if (state === 2) {
88
+ _type = 'focus'
89
+ } else if (state === 3) {
90
+ _type = 'blur'
91
+ } else {
92
+ _type = 'confirm'
93
+ }
94
+ context.$emit(_type, { ...e, detail: e })
95
+ }
96
+ }
97
+ }
98
+
99
+ function processModel (listeners, context, _input = false) {
100
+ // 该函数只有wx:model的情况下才调用,而且默认e.detail.value有值
101
+ // 该函数必须在产生merge前执行
102
+ // todo 此处对于$attrs的访问会导致父组件更新时子组件必然更新,暂时用短路效应避免影响,待优化
103
+ // todo 访问$listeners也会导致上述现象,但是为了事件代理还必须访问$listeners,待后续思考处理
104
+ const modelEvent = context.$attrs.mpxModelEvent
105
+ const modelEventId = context.$attrs.mpxModelEventId
106
+ if (modelEvent && modelEventId) {
107
+ // 对于modelEvent,内部获得时间后向外部转发,触发外部listener的同时转发为mpxModel事件
108
+
109
+ const listener = listeners.onInput
110
+
111
+ listeners.onInput = function (e) {
112
+ Hummer.notifyCenter.triggerEvent(modelEventId, {
113
+ detail: e
114
+ })
115
+ context.$emit('mpxModel', {
116
+ detail: e
117
+ })
118
+ listener && listener.call(this, e)
119
+ }
120
+ // 内部listener不需要mpxModel
121
+ delete listeners.mpxModel
122
+ }
123
+ }
124
+
125
+ function mergeListeners (listeners, otherListeners, options = {}, context, __mpxTapInfo) {
126
+ if (!otherListeners) {
127
+ return
128
+ }
129
+ // "onTouchstart",
130
+ // "onTouchmove",
131
+ // "onTouchcancel",
132
+ // "onTouchend",
133
+ // "onLongtap",
134
+
135
+ // 都依赖touch事件 如果listener没有touch事件 如果是force需要强行添加一个touch事件 longTap需要根据context
136
+ // 特殊处理
137
+ const listenerMap = {}
138
+ tapEvents.forEach((eventName) => {
139
+ if (listeners[eventName]) {
140
+ listenerMap[eventName] = true
141
+ delete listeners[eventName]
142
+ }
143
+ })
144
+ // const otherListenerKeys = Object.keys(otherListeners)
145
+ // for (let key of otherListenerKeys) {
146
+
147
+ // }
148
+
149
+ Object.keys(otherListeners).forEach((key) => {
150
+ const listener = otherListeners[key]
151
+ let rawListener
152
+ if (tapEvents.includes(key)) {
153
+ // 判断onTouch是否存在 若存在 则直接处理
154
+ rawListener = listeners.onTouch
155
+
156
+ if (!rawListener && !options.force) {
157
+ return
158
+ } else if (!rawListener && options.force) {
159
+ // 创建一个touh事件 并赋值
160
+ listeners.onTouch = createTouch(context, listenerMap.onLongtap, __mpxTapInfo).onTouch
161
+ rawListener = listeners.onTouch
162
+ }
163
+ // 事件处理 onTouchstart 1 onTouchmove 2 onTouchend 3 onTouchcancel 4
164
+ listeners.onTouch = function (e) {
165
+ // const thatKey = key
166
+ let timer = null
167
+ if (key === 'onLongtap') {
168
+ if (e.state === 1) {
169
+ // start
170
+ timer = setTimeout(
171
+ () => {
172
+ listener.call(this, e)
173
+ },
174
+ options.before ? 340 : 360
175
+ )
176
+ } else if (e.state === 3) {
177
+ timer && clearTimeout(timer)
178
+ timer = null
179
+ }
180
+ } else {
181
+ if (options.before) {
182
+ if (key === 'onTouchstart' && e.state === 1) {
183
+ listener.call(this, e)
184
+ } else if (key === 'onTouchmove' && e.state === 2) {
185
+ listener.call(this, e)
186
+ } else if (key === 'onTouchend' && e.state === 3) {
187
+ listener.call(this, e)
188
+ } else if (key === 'onTouchcancel' && e.state === 4) {
189
+ listener.call(this, e)
190
+ }
191
+ rawListener.call(this, e)
192
+ } else {
193
+ rawListener.call(this, e)
194
+ if (key === 'onTouchstart' && e.state === 1) {
195
+ listener.call(this, e)
196
+ } else if (key === 'onTouchmove' && e.state === 2) {
197
+ listener.call(this, e)
198
+ } else if (key === 'onTouchend' && e.state === 3) {
199
+ listener.call(this, e)
200
+ } else if (key === 'onTouchcancel' && e.state === 4) {
201
+ listener.call(this, e)
202
+ }
203
+ }
204
+ }
205
+ }
206
+ } else {
207
+ rawListener = listeners[key]
208
+ if (!rawListener) {
209
+ if (options.force) {
210
+ listeners[key] = listener
211
+ }
212
+ } else {
213
+ listeners[key] = function (e) {
214
+ if (options.before) {
215
+ listener.call(this, e)
216
+ rawListener.call(this, e)
217
+ } else {
218
+ rawListener.call(this, e)
219
+ listener.call(this, e)
220
+ }
221
+ }
222
+ }
223
+ }
224
+ })
225
+ }
226
+ // 没有tap 用touch模拟 touchstart touchmove touchcancel touchend tap longpress langtap
227
+ function processTouchAndLtap (listeners, context, __mpxTapInfo) {
228
+ const listenerMap = {}
229
+ tapEvents.forEach((eventName) => {
230
+ if (listeners[eventName]) {
231
+ listenerMap[eventName] = true
232
+ delete listeners[eventName]
233
+ }
234
+ })
235
+ if (isEmptyObject(listenerMap)) return
236
+ const events = createTouch(context, listenerMap.onLongtap, __mpxTapInfo)
237
+ mergeListeners(
238
+ listeners,
239
+ events,
240
+ {
241
+ force: true
242
+ },
243
+ context,
244
+ __mpxTapInfo
245
+ )
246
+ }
247
+
248
+ export function extendEvent (e, extendObj = {}) {
249
+ Object.keys(extendObj).forEach((key) => {
250
+ Object.defineProperty(e, key, {
251
+ value: extendObj[key],
252
+ enumerable: true,
253
+ configurable: true,
254
+ writable: true
255
+ })
256
+ })
257
+ }
258
+
259
+ export function inheritEvent (type, oe, detail = {}) {
260
+ detail = Object.assign({}, oe.detail, detail)
261
+ const ne = getCustomEvent(type, detail)
262
+ extendEvent(ne, {
263
+ timeStamp: oe.timeStamp,
264
+ target: oe.target,
265
+ currentTarget: oe.currentTarget,
266
+ stopPropagation: oe.stopPropagation.bind(oe),
267
+ preventDefault: oe.preventDefault.bind(oe)
268
+ })
269
+ return ne
270
+ }
271
+
272
+ export function getCustomEvent (type, detail = {}, target = null) {
273
+ return {
274
+ type,
275
+ detail,
276
+ target,
277
+ timeStamp: new Date().valueOf()
278
+ }
279
+ }
280
+
281
+ function noop () {}
282
+
283
+ function getListeners (context) {
284
+ const attrs = context.$attrs
285
+ const listeners = {}
286
+ Object.keys(attrs).forEach((v) => {
287
+ if (/^on[A-Z]/.test(v)) {
288
+ listeners[v] = attrs[v]
289
+ }
290
+ })
291
+ return listeners
292
+ }
293
+
294
+ export default function getInnerListeners (context, options = {}) {
295
+ let {
296
+ mergeBefore = {},
297
+ mergeAfter = {},
298
+ defaultListeners = [],
299
+ ignoredListeners = [],
300
+ _input = false
301
+ } = options
302
+ const __mpxTapInfo = {}
303
+ // 从attrs里面拿到以on开头的所有绑定的事件
304
+ const listeners = Object.assign({}, getListeners(context))
305
+
306
+ defaultListeners.forEach((key) => {
307
+ if (!listeners[key]) listeners[key] = noop
308
+ })
309
+ const mergeBeforeOptions = {
310
+ before: true
311
+ }
312
+ const mergeAfterOptions = {
313
+ before: false
314
+ }
315
+
316
+ if (mergeBefore.listeners) {
317
+ mergeBeforeOptions.force = mergeBefore.force
318
+ mergeBefore = mergeBefore.listeners
319
+ }
320
+
321
+ if (mergeAfter.listeners) {
322
+ mergeAfterOptions.force = mergeAfter.force
323
+ mergeAfter = mergeAfter.listeners
324
+ }
325
+ processOriginEvent(listeners, context, _input)
326
+ processModel(listeners, context, _input)
327
+ processTouchAndLtap(listeners, context, __mpxTapInfo)
328
+ mergeListeners(listeners, mergeBefore, mergeBeforeOptions, context, __mpxTapInfo)
329
+ mergeListeners(listeners, mergeAfter, mergeAfterOptions, context, __mpxTapInfo)
330
+ ignoredListeners.forEach((key) => {
331
+ delete listeners[key]
332
+ })
333
+ return listeners
334
+ }