@mpxjs/webpack-plugin 2.9.58 → 2.9.62

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 (109) hide show
  1. package/lib/config.js +1 -3
  2. package/lib/platform/style/wx/index.js +374 -239
  3. package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
  4. package/lib/platform/template/wx/component-config/checkbox.js +8 -0
  5. package/lib/platform/template/wx/component-config/cover-image.js +15 -0
  6. package/lib/platform/template/wx/component-config/cover-view.js +9 -0
  7. package/lib/platform/template/wx/component-config/form.js +13 -1
  8. package/lib/platform/template/wx/component-config/icon.js +8 -0
  9. package/lib/platform/template/wx/component-config/index.js +5 -1
  10. package/lib/platform/template/wx/component-config/label.js +15 -0
  11. package/lib/platform/template/wx/component-config/movable-area.js +18 -1
  12. package/lib/platform/template/wx/component-config/movable-view.js +18 -1
  13. package/lib/platform/template/wx/component-config/navigator.js +8 -0
  14. package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
  15. package/lib/platform/template/wx/component-config/picker-view.js +18 -2
  16. package/lib/platform/template/wx/component-config/picker.js +14 -1
  17. package/lib/platform/template/wx/component-config/radio-group.js +8 -0
  18. package/lib/platform/template/wx/component-config/radio.js +8 -0
  19. package/lib/platform/template/wx/component-config/root-portal.js +15 -0
  20. package/lib/platform/template/wx/component-config/switch.js +8 -0
  21. package/lib/platform/template/wx/component-config/unsupported.js +1 -3
  22. package/lib/react/processScript.js +7 -1
  23. package/lib/react/style-helper.js +10 -1
  24. package/lib/runtime/components/react/context.ts +38 -0
  25. package/lib/runtime/components/react/dist/context.js +7 -0
  26. package/lib/runtime/components/react/dist/getInnerListeners.js +24 -13
  27. package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
  28. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
  29. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
  30. package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
  31. package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
  32. package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
  33. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
  34. package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
  35. package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
  36. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
  37. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
  38. package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
  39. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
  40. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
  42. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
  43. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  44. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
  45. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
  46. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  47. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
  48. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
  49. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
  50. package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
  51. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
  52. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
  53. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
  54. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
  56. package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
  57. package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
  58. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  59. package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
  60. package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
  61. package/lib/runtime/components/react/dist/types/common.js +1 -0
  62. package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
  63. package/lib/runtime/components/react/dist/utils.js +83 -15
  64. package/lib/runtime/components/react/getInnerListeners.ts +27 -15
  65. package/lib/runtime/components/react/mpx-button.tsx +87 -67
  66. package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
  67. package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
  68. package/lib/runtime/components/react/mpx-form.tsx +89 -0
  69. package/lib/runtime/components/react/mpx-icon.tsx +103 -0
  70. package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
  71. package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
  72. package/lib/runtime/components/react/mpx-input.tsx +54 -26
  73. package/lib/runtime/components/react/mpx-label.tsx +115 -0
  74. package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
  75. package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
  76. package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
  77. package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
  78. package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
  79. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
  80. package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
  81. package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
  82. package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
  83. package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
  84. package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
  85. package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
  86. package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
  87. package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
  88. package/lib/runtime/components/react/mpx-radio.tsx +246 -0
  89. package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
  90. package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
  91. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
  92. package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
  93. package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
  94. package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
  95. package/lib/runtime/components/react/mpx-switch.tsx +127 -0
  96. package/lib/runtime/components/react/mpx-text.tsx +52 -68
  97. package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
  98. package/lib/runtime/components/react/mpx-view.tsx +374 -141
  99. package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
  100. package/lib/runtime/components/react/types/common.ts +12 -0
  101. package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
  102. package/lib/runtime/components/react/types/global.d.ts +4 -0
  103. package/lib/runtime/components/react/useNodesRef.ts +3 -8
  104. package/lib/runtime/components/react/utils.ts +94 -16
  105. package/lib/runtime/optionProcessor.js +19 -17
  106. package/lib/template-compiler/compiler.js +73 -44
  107. package/lib/template-compiler/gen-node-react.js +7 -7
  108. package/lib/utils/shallow-stringify.js +1 -1
  109. package/package.json +6 -3
@@ -1,4 +1,4 @@
1
- import { forwardRef, JSX, useRef, useEffect } from 'react'
1
+ import { forwardRef, JSX, useEffect } from 'react'
2
2
  // @ts-ignore
3
3
  import { noop } from '@mpxjs/utils'
4
4
  import { Portal } from '@ant-design/react-native'
@@ -7,7 +7,6 @@ import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab }
7
7
  // @ts-ignore
8
8
  import { WebView } from 'react-native-webview'
9
9
  import useNodesRef, { HandlerRef } from './useNodesRef'
10
- import { StyleSheet } from 'react-native'
11
10
 
12
11
  type OnMessageCallbackEvent = {
13
12
  detail: {
@@ -55,21 +54,19 @@ interface FormRef {
55
54
  const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element => {
56
55
  const { src, bindmessage = noop, bindload = noop, binderror = noop } = props
57
56
 
58
- const defaultWebViewStyle = [
59
- {
60
- position: 'absolute',
61
- left: 0,
62
- right: 0,
63
- top: 0,
64
- bottom: 0
65
- }
66
- ]
57
+ const defaultWebViewStyle = {
58
+ position: 'absolute',
59
+ left: 0,
60
+ right: 0,
61
+ top: 0,
62
+ bottom: 0
63
+ }
64
+
67
65
  const { nodeRef: webViewRef } = useNodesRef<WebView, WebViewProps>(props, ref, {
68
- defaultStyle: StyleSheet.flatten([
69
- ...defaultWebViewStyle
70
- ])
66
+ defaultStyle: defaultWebViewStyle
71
67
  })
72
- const _messageList:any[] = []
68
+
69
+ const _messageList: any[] = []
73
70
  const handleUnload = () => {
74
71
  // 这里是 WebView 销毁前执行的逻辑
75
72
  bindmessage(getCustomEvent('messsage', {}, {
@@ -86,7 +83,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
86
83
  handleUnload()
87
84
  }
88
85
  }, [])
89
- const _load = function(res:LoadRes) {
86
+ const _load = function (res: LoadRes) {
90
87
  const result = {
91
88
  type: 'load',
92
89
  timeStamp: res.timeStamp,
@@ -96,7 +93,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
96
93
  }
97
94
  bindload(result)
98
95
  }
99
- const _error = function(res:LoadRes) {
96
+ const _error = function (res: LoadRes) {
100
97
  const result = {
101
98
  type: 'error',
102
99
  timeStamp: res.timeStamp,
@@ -106,7 +103,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
106
103
  }
107
104
  binderror(result)
108
105
  }
109
- const _message = function(res:LoadRes) {
106
+ const _message = function (res: LoadRes) {
110
107
  let data: MessageData
111
108
  let asyncCallback
112
109
  const navObj = promisify({ redirectTo, navigateTo, navigateBack, reLaunch, switchTab })
@@ -116,7 +113,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
116
113
  } catch (e) {
117
114
  data = {}
118
115
  }
119
- const postData:PayloadData = data.payload || {}
116
+ const postData: PayloadData = data.payload || {}
120
117
  switch (data.type) {
121
118
  case 'postMessage':
122
119
  _messageList.push(postData.data)
@@ -152,16 +149,15 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
152
149
  }
153
150
  })
154
151
  }
155
- // @ts-ignore
156
- return(<Portal>
152
+ return (<Portal>
157
153
  <WebView
158
- style={[ ...defaultWebViewStyle ]}
159
- source={{ uri: src }}
160
- ref={webViewRef}
161
- onLoad={_load}
162
- onError={_error}
163
- onMessage={_message}
164
- javaScriptEnabled={true}
154
+ style={defaultWebViewStyle}
155
+ source={{ uri: src }}
156
+ ref={webViewRef}
157
+ onLoad={_load}
158
+ onError={_error}
159
+ onMessage={_message}
160
+ javaScriptEnabled={true}
165
161
  ></WebView>
166
162
  </Portal>)
167
163
  })
@@ -0,0 +1,12 @@
1
+ import { ViewStyle, ImageResizeMode} from 'react-native'
2
+
3
+ type NumberVal = number | `${number}%`
4
+ type backgroundPositionList = [ 'left'| 'right', NumberVal, 'top' | 'bottom', NumberVal ] | []
5
+
6
+ export type ExtendedViewStyle = ViewStyle & {
7
+ backgroundImage?: string
8
+ backgroundSize?: Array<ImageResizeMode | string> | ImageResizeMode | string
9
+ borderRadius?: string | number
10
+ backgroundPosition?: backgroundPositionList
11
+ [key: string]: any
12
+ }
@@ -49,7 +49,8 @@ interface InnerRef {
49
49
  }
50
50
  interface UseInnerPropsConfig {
51
51
  layoutRef: LayoutRef;
52
- disableTouch?: boolean
52
+ disableTouch?: boolean;
53
+ disableTap?: boolean
53
54
  }
54
55
  interface DataSetType {
55
56
  [key: string]: string;
@@ -12,4 +12,8 @@ declare module 'react-native-svg/css' {
12
12
  }
13
13
 
14
14
  export const WithLocalSvg: React.ComponentType<WithLocalSvgProps>
15
+ }
16
+
17
+ declare module '@mpxjs/utils' {
18
+ export function isEmptyObject(obj: Record<string, any>): boolean;
15
19
  }
@@ -1,4 +1,4 @@
1
- import { useRef, useEffect, useImperativeHandle, RefObject, ForwardedRef } from 'react'
1
+ import { useRef, useImperativeHandle, RefObject, ForwardedRef } from 'react'
2
2
 
3
3
 
4
4
  type Obj = Record<string, any>
@@ -13,14 +13,9 @@ export type HandlerRef<T, P> = {
13
13
 
14
14
  export default function useNodesRef<T, P>(props: P, ref: ForwardedRef<HandlerRef<T, P>>, instance:Obj = {} ) {
15
15
  const nodeRef = useRef<T>(null)
16
- const _props = useRef<P | null>(props)
16
+ const _props = useRef<P | null>(null)
17
+ _props.current = props
17
18
 
18
- useEffect(() => {
19
- _props.current = props
20
- return () => {
21
- _props.current = null // 组件销毁,清空 _props 依赖数据
22
- }
23
- }, [props])
24
19
  useImperativeHandle(ref, () => {
25
20
  return {
26
21
  getNodeInstance () {
@@ -1,9 +1,20 @@
1
- import { useEffect, useRef, Children, ReactNode, FunctionComponent, isValidElement } from 'react'
2
- import { StyleProp, StyleSheet, TextStyle, ViewStyle } from 'react-native'
1
+ import { useEffect, useRef, ReactNode, FunctionComponent, isValidElement } from 'react'
2
+ import { ExtendedViewStyle } from './types/common'
3
+ import { TextStyle } from 'react-native'
4
+
5
+ type GroupData = Record<string, Record<string, any>>
3
6
 
4
7
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
5
8
 
6
- export const PERCENT_REGX = /^\s*-?\d+(\.\d+)?%\s*$/
9
+ export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
10
+
11
+ export const IMAGE_STYLE_REGEX = /^background(Image|Size|Repeat|Position)$/
12
+
13
+ export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/
14
+
15
+ export const DEFAULT_STYLE = {
16
+ fontSize: 16
17
+ }
7
18
 
8
19
  const URL_REGEX = /url\(["']?(.*?)["']?\)/
9
20
 
@@ -16,18 +27,6 @@ export function omit<T, K extends string>(obj: T, fields: K[]): Omit<T, K> {
16
27
  return shallowCopy
17
28
  }
18
29
 
19
- /**
20
- * 从 style 中提取 TextStyle
21
- * @param style
22
- * @returns
23
- */
24
- export const extractTextStyle = (style: StyleProp<ViewStyle & TextStyle>): TextStyle => {
25
- return Object.entries(StyleSheet.flatten(style)).reduce((textStyle, [key, value]) => {
26
- TEXT_STYLE_REGEX.test(key) && Object.assign(textStyle, { [key]: value })
27
- return textStyle
28
- }, {})
29
- }
30
-
31
30
  /**
32
31
  * 用法等同于 useEffect,但是会忽略首次执行,只在依赖更新时执行
33
32
  */
@@ -87,6 +86,85 @@ export const isText = (ele: ReactNode) => {
87
86
  return false
88
87
  }
89
88
 
89
+ export const isEmbedded = (ele: ReactNode) => {
90
+ if (isValidElement(ele)) {
91
+ const displayName = (ele.type as FunctionComponent)?.displayName
92
+ return displayName && ['mpx-checkbox', 'mpx-radio', 'mpx-switch'].includes(displayName)
93
+ }
94
+ return false
95
+ }
96
+
90
97
  export function every(children: ReactNode, callback: (children: ReactNode) => boolean ) {
91
- return Children.toArray(children).every((child) => callback(child as ReactNode))
98
+ const childrenArray = Array.isArray(children) ? children : [children];
99
+ return childrenArray.every((child) => callback(child as ReactNode))
100
+ }
101
+
102
+ export function groupBy(obj: Record<string, any>, callback: (key: string, val: string) => string, group:GroupData = {}):GroupData {
103
+ let groupKey = ''
104
+ for (let key in obj) {
105
+ if (obj.hasOwnProperty(key)) { // 确保处理对象自身的属性
106
+ let val: string = obj[key] as string
107
+ groupKey = callback(key, val)
108
+ if (!group[groupKey]) {
109
+ group[groupKey] = {}
110
+ }
111
+ group[groupKey][key] = val
112
+ }
113
+ }
114
+ return group
115
+ }
116
+
117
+ export const normalizeStyle = (style: ExtendedViewStyle = {}) => {
118
+ const { borderRadius } = style
119
+ if (borderRadius && PERCENT_REGEX.test(borderRadius as string)) {
120
+ style.borderTopLeftRadius = borderRadius
121
+ style.borderBottomLeftRadius = borderRadius
122
+ style.borderBottomRightRadius = borderRadius
123
+ style.borderTopRightRadius = borderRadius
124
+ delete style.borderRadius
125
+ }
126
+ ['backgroundSize', 'backgroundPosition'].forEach(name => {
127
+ if (style[name] && typeof style[name] === 'string') {
128
+ if (style[name].trim()) {
129
+ style[name] = style[name].split(' ')
130
+ }
131
+ }
132
+ })
133
+ return style
134
+ }
135
+
136
+ export function splitStyle<T extends Record<string, any>>(styles: T) {
137
+ return groupBy(styles, (key) => {
138
+ if (TEXT_STYLE_REGEX.test(key)) {
139
+ return 'textStyle'
140
+ } else if (IMAGE_STYLE_REGEX.test(key)) {
141
+ return 'imageStyle'
142
+ } else {
143
+ return 'innerStyle'
144
+ }
145
+ }, {})
146
+ }
147
+
148
+ export function splitProps<T extends Record<string, any>>(props: T) {
149
+ return groupBy(props, (key) => {
150
+ if (TEXT_PROPS_REGEX.test(key)) {
151
+ return 'textProps'
152
+ } else {
153
+ return 'innerProps'
154
+ }
155
+ }, {})
156
+ }
157
+
158
+ export const throwReactWarning = (message: string) => {
159
+ setTimeout(() => {
160
+ console.warn(message)
161
+ }, 0)
162
+ }
163
+
164
+ export const transformTextStyle = (styleObj: TextStyle) => {
165
+ let { lineHeight } = styleObj
166
+ if (typeof lineHeight === 'string' && PERCENT_REGEX.test(lineHeight)) {
167
+ lineHeight = (parseFloat(lineHeight) / 100) * (styleObj.fontSize || DEFAULT_STYLE.fontSize)
168
+ styleObj.lineHeight = lineHeight
169
+ }
92
170
  }
@@ -81,23 +81,25 @@ registered in parent context!`)
81
81
  transitionName: ''
82
82
  }
83
83
  }
84
- option.watch = {
85
- $route: {
86
- handler () {
87
- const actionType = global.__mpxRouter.currentActionType
84
+ if (!global.__mpx.config.webConfig.disablePageTransition) {
85
+ option.watch = {
86
+ $route: {
87
+ handler () {
88
+ const actionType = global.__mpxRouter.currentActionType
88
89
 
89
- switch (actionType) {
90
- case 'to':
91
- this.transitionName = 'mpx-slide-left'
92
- break
93
- case 'back':
94
- this.transitionName = 'mpx-slide-right'
95
- break
96
- default:
97
- this.transitionName = ''
98
- }
99
- },
100
- immediate: true
90
+ switch (actionType) {
91
+ case 'to':
92
+ this.transitionName = 'mpx-slide-left'
93
+ break
94
+ case 'back':
95
+ this.transitionName = 'mpx-slide-right'
96
+ break
97
+ default:
98
+ this.transitionName = ''
99
+ }
100
+ },
101
+ immediate: true
102
+ }
101
103
  }
102
104
  }
103
105
  }
@@ -161,7 +163,7 @@ function createApp ({ componentsMap, Vue, pagesMap, firstPage, VueRouter, App, t
161
163
  redirect: '/' + firstPage
162
164
  })
163
165
  }
164
- const webRouteConfig = global.__mpx.config.webRouteConfig
166
+ const webRouteConfig = global.__mpx.config.webConfig.routeConfig || global.__mpx.config.webRouteConfig
165
167
  global.__mpxRouter = option.router = new VueRouter({
166
168
  ...webRouteConfig,
167
169
  routes: routes
@@ -990,7 +990,7 @@ function processComponentIs (el, options) {
990
990
  const eventIdentifier = '__mpx_event__'
991
991
 
992
992
  function parseFuncStr (str, extraStr = '') {
993
- const funcRE = /^([^()]+)(\((.*)\))?/
993
+ const funcRE = /^(.*{{.+}}[^()]*|[^()]+)(\((.*)\))?/
994
994
  const match = funcRE.exec(str)
995
995
  if (match) {
996
996
  const funcName = parseMustacheWithContext(match[1]).result
@@ -1052,7 +1052,7 @@ function stringifyWithResolveComputed (modelValue) {
1052
1052
  return result.join('+')
1053
1053
  }
1054
1054
 
1055
- function processStyleReact (el) {
1055
+ function processStyleReact (el, options) {
1056
1056
  // process class/wx:class/style/wx:style/wx:show for react native
1057
1057
  const dynamicClass = getAndRemoveAttr(el, config[mode].directive.dynamicClass).val
1058
1058
  let staticClass = getAndRemoveAttr(el, 'class').val || ''
@@ -1088,10 +1088,24 @@ function processStyleReact (el) {
1088
1088
  const staticClassExp = parseMustacheWithContext(staticHoverClass).result
1089
1089
  addAttrs(el, [{
1090
1090
  name: 'hoverStyle',
1091
- // runtime helper
1092
1091
  value: `{{this.__getStyle(${staticClassExp})}}`
1093
1092
  }])
1094
1093
  }
1094
+
1095
+ // 处理externalClasses,将其转换为style作为props传递
1096
+ if (options.externalClasses) {
1097
+ options.externalClasses.forEach((className) => {
1098
+ let externalClass = getAndRemoveAttr(el, className).val || ''
1099
+ externalClass = externalClass.replace(/\s+/g, ' ')
1100
+ if (externalClass) {
1101
+ const externalClassExp = parseMustacheWithContext(externalClass).result
1102
+ addAttrs(el, [{
1103
+ name: className,
1104
+ value: `{{this.__getStyle(${externalClassExp})}}`
1105
+ }])
1106
+ }
1107
+ })
1108
+ }
1095
1109
  }
1096
1110
 
1097
1111
  function getModelConfig (el, match) {
@@ -2427,12 +2441,26 @@ function isValidModeP (i) {
2427
2441
 
2428
2442
  const wrapRE = /^\((.*)\)$/
2429
2443
 
2430
- function processAtMode (el) {
2431
- // 父节点的atMode匹配状态不应该影响子节点,atMode的影响范围应该限制在当前节点本身
2432
- // if (el.parent && el.parent._atModeStatus) {
2433
- // el._atModeStatus = el.parent._atModeStatus
2434
- // }
2444
+ // MATCH: mode 与 env 都匹配,节点/属性保留,但不做跨平台转换
2445
+ // IMPLICITMATCH: mode 与 env 匹配,节点/属性保留,属于隐式匹配,做跨平台转换
2446
+ // MISMATCH: mode env不匹配,节点/属性直接删除
2447
+ const statusEnum = {
2448
+ MISMATCH: 1,
2449
+ IMPLICITMATCH: 2,
2450
+ MATCH: 3
2451
+ }
2452
+
2453
+ // 父节点的atMode匹配状态不应该影响子节点,atMode的影响范围应该限制在当前节点本身
2454
+ function setModeStatus (target, status) {
2455
+ // 高优status才可以覆盖低优status,status枚举值代表优先级
2456
+ if (!target._matchStatus) {
2457
+ target._matchStatus = status
2458
+ } else if (status > target._matchStatus) {
2459
+ target._matchStatus = status
2460
+ }
2461
+ }
2435
2462
 
2463
+ function processAtMode (el) {
2436
2464
  const attrsListClone = cloneAttrsList(el.attrsList)
2437
2465
  attrsListClone.forEach(item => {
2438
2466
  const attrName = item.name || ''
@@ -2469,40 +2497,41 @@ function processAtMode (el) {
2469
2497
  const attrValue = getAndRemoveAttr(el, attrName).val
2470
2498
  const replacedAttrName = attrArr.join('@')
2471
2499
  const processedAttr = { name: replacedAttrName, value: attrValue }
2472
-
2500
+ const target = replacedAttrName ? processedAttr : el
2501
+ // 循环 conditionMap
2502
+ // 判断 env 是否匹配
2503
+ // 判断 mode 是否匹配
2504
+ // 额外处理attr value 场景
2473
2505
  for (let [defineMode, defineEnvArr] of conditionMap.entries()) {
2474
2506
  const isImplicitMode = defineMode[0] === '_'
2475
2507
  if (isImplicitMode) defineMode = defineMode.slice(1)
2476
- if (defineMode === 'noMode' || defineMode === mode) {
2477
- // 命中 env 规则(没有定义env 或者定义的envArr包含当前env)
2478
- if (!defineEnvArr.length || defineEnvArr.includes(env)) {
2479
- if (!replacedAttrName) {
2480
- if (defineMode === 'noMode' || isImplicitMode) {
2481
- // 若defineMode 为 noMode 或 implicitMode,则 element 都需要进行规则转换
2482
- } else {
2483
- el._atModeStatus = 'match'
2484
- }
2485
- } else {
2486
- if (defineMode === 'noMode' || isImplicitMode) {
2487
- // 若defineMode 为 noMode 或 implicitMode,则直接将 attr 挂载回 el,进行规则转换
2488
- addAttrs(el, [processedAttr])
2489
- } else {
2490
- // 如果命中了指定的mode,且当前 mode 不为 noMode 或 implicitMode,则把不需要转换的 attrs 暂存在 noTransAttrs 上,等规则转换后再挂载回去
2491
- el.noTransAttrs ? el.noTransAttrs.push(processedAttr) : el.noTransAttrs = [processedAttr]
2492
- }
2493
- }
2494
- // 命中mode,命中env,完成匹配,直接退出
2508
+
2509
+ const isNoMode = defineMode === 'noMode'
2510
+ const isMatchMode = isNoMode || defineMode === mode
2511
+ const isMatchEnv = !defineEnvArr.length || defineEnvArr.includes(env)
2512
+ let matchStatus = statusEnum.MISMATCH
2513
+ // 是否为针对于节点的条件判断,否为节点属性
2514
+ if (isMatchMode && isMatchEnv) {
2515
+ // mpxTagName 特殊标签,需要做转换保留处理
2516
+ matchStatus = (isNoMode || isImplicitMode || replacedAttrName === 'mpxTagName') ? statusEnum.IMPLICITMATCH : statusEnum.MATCH
2517
+ }
2518
+ setModeStatus(target, matchStatus)
2519
+ }
2520
+ // 解析处理attr._matchStatus
2521
+ if (replacedAttrName) {
2522
+ switch (processedAttr._matchStatus) {
2523
+ // IMPLICITMATCH保留属性并进行平台转换
2524
+ case statusEnum.IMPLICITMATCH:
2525
+ addAttrs(el, [processedAttr])
2495
2526
  break
2496
- } else if (!replacedAttrName) {
2497
- // 命中mode规则,没有命中当前env规则,设置为 'mismatch'
2498
- el._atModeStatus = 'mismatch'
2499
- }
2500
- } else if (!replacedAttrName) {
2501
- // 没有命中当前mode规则,设置为 'mismatch'
2502
- el._atModeStatus = 'mismatch'
2503
- } else {
2504
- // 如果没命中指定的mode,则该属性删除
2527
+ // MATCH保留属性并跳过平台转换
2528
+ case statusEnum.MATCH:
2529
+ el.noTransAttrs ? el.noTransAttrs.push(processedAttr) : el.noTransAttrs = [processedAttr]
2530
+ break
2531
+ default:
2532
+ // MISMATCH丢弃属性
2505
2533
  }
2534
+ delete processedAttr._matchStatus
2506
2535
  }
2507
2536
  }
2508
2537
  })
@@ -2550,15 +2579,17 @@ function processMpxTagName (el) {
2550
2579
  function processElement (el, root, options, meta) {
2551
2580
  processAtMode(el)
2552
2581
  // 如果已经标记了这个元素要被清除,直接return跳过后续处理步骤
2553
- if (el._atModeStatus === 'mismatch') {
2582
+ if (el._matchStatus === statusEnum.MISMATCH) {
2554
2583
  return
2555
2584
  }
2556
2585
 
2586
+ processMpxTagName(el)
2587
+
2557
2588
  if (runtimeCompile && options.dynamicTemplateRuleRunner) {
2558
2589
  options.dynamicTemplateRuleRunner(el, options, config[mode])
2559
2590
  }
2560
2591
 
2561
- if (rulesRunner && el._atModeStatus !== 'match') {
2592
+ if (rulesRunner && el._matchStatus !== statusEnum.MATCH) {
2562
2593
  currentEl = el
2563
2594
  rulesRunner(el)
2564
2595
  }
@@ -2567,8 +2598,6 @@ function processElement (el, root, options, meta) {
2567
2598
 
2568
2599
  processDuplicateAttrsList(el)
2569
2600
 
2570
- processMpxTagName(el)
2571
-
2572
2601
  processInjectWxs(el, meta, options)
2573
2602
 
2574
2603
  const transAli = mode === 'ali' && srcMode === 'wx'
@@ -2590,7 +2619,7 @@ function processElement (el, root, options, meta) {
2590
2619
  processIf(el)
2591
2620
  processFor(el)
2592
2621
  processRefReact(el, meta)
2593
- processStyleReact(el)
2622
+ processStyleReact(el, options)
2594
2623
  processEventReact(el)
2595
2624
  processComponentIs(el, options)
2596
2625
  processSlotReact(el)
@@ -2670,8 +2699,8 @@ function collectDynamicInfo (el, options, meta) {
2670
2699
  }
2671
2700
 
2672
2701
  function postProcessAtMode (el) {
2673
- if (el._atModeStatus === 'mismatch') {
2674
- removeNode(el, true)
2702
+ if (el._matchStatus === statusEnum.MISMATCH) {
2703
+ removeNode(el)
2675
2704
  }
2676
2705
  }
2677
2706
 
@@ -61,7 +61,7 @@ function genNode (node) {
61
61
  } else {
62
62
  exp += `createElement(${`getComponent(${node.is || s(node.tag)})`}`
63
63
  if (node.isRoot) {
64
- exp += `, Object.assign({}, rootProps, {style: [${attrExpMap.style}, rootProps.style]})`
64
+ exp += `, Object.assign({}, rootProps, {style: Object.assign({}, ${attrExpMap.style}, rootProps.style)})`
65
65
  } else if (node.attrsList.length) {
66
66
  const attrs = []
67
67
  node.attrsList && node.attrsList.forEach(({ name, value }) => {
@@ -75,17 +75,17 @@ function genNode (node) {
75
75
 
76
76
  if (!node.unary && node.children.length) {
77
77
  exp += ','
78
- node.children.forEach(function (child, index) {
79
- exp += `${index === 0 ? '' : ','}${genNode(child)}`
80
- })
78
+ exp += node.children.map((child) => {
79
+ return genNode(child)
80
+ }).filter(fragment => fragment).join(',')
81
81
  }
82
82
  exp += ')'
83
83
  }
84
84
  }
85
85
  } else {
86
- node.children.forEach(function (child, index) {
87
- exp += `${index === 0 ? '' : ','}${genNode(child)}`
88
- })
86
+ exp += node.children.map((child) => {
87
+ return genNode(child)
88
+ }).filter(fragment => fragment).join(',')
89
89
  }
90
90
  }
91
91
  }
@@ -6,7 +6,7 @@ module.exports = function shallowStringify (obj, isTemplateExp) {
6
6
  if (hasOwn(obj, key)) {
7
7
  let value = obj[key]
8
8
  if (Array.isArray(value)) {
9
- value = `[${value.join(',')}]`
9
+ value = `[${value.map((item) => typeof item === 'object' ? shallowStringify(item, isTemplateExp) : item).join(',')}]`
10
10
  } else if (typeof value === 'object') {
11
11
  value = shallowStringify(value, isTemplateExp)
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.9.58",
3
+ "version": "2.9.62",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -28,6 +28,7 @@
28
28
  "@better-scroll/wheel": "^2.5.1",
29
29
  "@better-scroll/zoom": "^2.5.1",
30
30
  "@mpxjs/template-engine": "^2.8.7",
31
+ "@mpxjs/utils": "^2.9.59",
31
32
  "acorn": "^8.11.3",
32
33
  "acorn-walk": "^7.2.0",
33
34
  "async": "^2.6.0",
@@ -41,7 +42,7 @@
41
42
  "html-minifier": "^3.5.8",
42
43
  "icss-utils": "^2.1.0",
43
44
  "json5": "^2.1.3",
44
- "loader-utils": "^2.0.2",
45
+ "loader-utils": "^2.0.0",
45
46
  "lodash": "^4.17.15",
46
47
  "lodash.camelcase": "^4.3.0",
47
48
  "lru-cache": "^4.1.2",
@@ -81,14 +82,16 @@
81
82
  },
82
83
  "devDependencies": {
83
84
  "@ant-design/react-native": "^5.2.2",
85
+ "@mpxjs/api-proxy": "^2.9.62",
84
86
  "@types/babel-traverse": "^6.25.4",
85
87
  "@types/babel-types": "^7.0.4",
86
88
  "@types/react": "^18.2.79",
87
89
  "react-native": "^0.74.5",
90
+ "react-native-gesture-handler": "^2.18.1",
88
91
  "rimraf": "^6.0.1"
89
92
  },
90
93
  "engines": {
91
94
  "node": ">=14.14.0"
92
95
  },
93
- "gitHead": "49fe4c4bc46ff4bf87cd8adde37981d4b4134aa7"
96
+ "gitHead": "c31a343e7ef2c1c1585002752d8c50f016a858ae"
94
97
  }