@mpxjs/webpack-plugin 2.9.69 → 2.9.70

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 (111) hide show
  1. package/lib/parser.js +1 -1
  2. package/lib/platform/json/wx/index.js +21 -8
  3. package/lib/platform/style/wx/index.js +51 -54
  4. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  5. package/lib/platform/template/wx/component-config/index.js +1 -1
  6. package/lib/platform/template/wx/component-config/input.js +1 -1
  7. package/lib/platform/template/wx/component-config/rich-text.js +8 -0
  8. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  9. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  10. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  11. package/lib/react/processTemplate.js +3 -0
  12. package/lib/runtime/components/react/context.ts +4 -0
  13. package/lib/runtime/components/react/dist/context.js +1 -0
  14. package/lib/runtime/components/react/dist/event.config.js +24 -24
  15. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -166
  16. package/lib/runtime/components/react/dist/mpx-button.jsx +35 -42
  17. package/lib/runtime/components/react/dist/mpx-canvas/html.js +2 -4
  18. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +35 -13
  19. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  20. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  21. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  22. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  23. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  24. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  25. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  26. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  27. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +13 -13
  28. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  29. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  30. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  31. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  32. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  33. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  34. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  35. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +3 -1
  36. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +5 -3
  37. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  38. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  39. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  40. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  41. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  42. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +47 -41
  43. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  44. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +4 -2
  45. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -2
  46. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  47. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  48. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  49. package/lib/runtime/components/react/dist/mpx-view.jsx +34 -46
  50. package/lib/runtime/components/react/dist/mpx-web-view.jsx +105 -42
  51. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -10
  52. package/lib/runtime/components/react/dist/utils.jsx +107 -82
  53. package/lib/runtime/components/react/event.config.ts +25 -26
  54. package/lib/runtime/components/react/getInnerListeners.ts +238 -188
  55. package/lib/runtime/components/react/mpx-button.tsx +64 -50
  56. package/lib/runtime/components/react/mpx-canvas/html.ts +2 -4
  57. package/lib/runtime/components/react/mpx-canvas/index.tsx +46 -48
  58. package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
  59. package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
  60. package/lib/runtime/components/react/mpx-form.tsx +25 -28
  61. package/lib/runtime/components/react/mpx-icon.tsx +12 -17
  62. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  63. package/lib/runtime/components/react/mpx-input.tsx +77 -57
  64. package/lib/runtime/components/react/mpx-label.tsx +26 -27
  65. package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
  66. package/lib/runtime/components/react/mpx-movable-view.tsx +21 -25
  67. package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
  68. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  69. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  70. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  71. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  72. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  73. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  74. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  75. package/lib/runtime/components/react/mpx-picker-view-column.tsx +4 -1
  76. package/lib/runtime/components/react/mpx-picker-view.tsx +7 -1
  77. package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
  78. package/lib/runtime/components/react/mpx-radio.tsx +45 -54
  79. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  80. package/lib/runtime/components/react/mpx-rich-text/index.tsx +121 -0
  81. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  82. package/lib/runtime/components/react/mpx-scroll-view.tsx +72 -71
  83. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  84. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
  85. package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
  86. package/lib/runtime/components/react/mpx-switch.tsx +29 -23
  87. package/lib/runtime/components/react/mpx-text.tsx +14 -18
  88. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  89. package/lib/runtime/components/react/mpx-view.tsx +55 -65
  90. package/lib/runtime/components/react/mpx-web-view.tsx +108 -63
  91. package/lib/runtime/components/react/types/global.d.ts +3 -17
  92. package/lib/runtime/components/react/useAnimationHooks.ts +36 -12
  93. package/lib/runtime/components/react/utils.tsx +113 -82
  94. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  95. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  96. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  97. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  98. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  99. package/lib/runtime/optionProcessor.js +7 -38
  100. package/lib/runtime/utils.js +2 -0
  101. package/lib/style-compiler/plugins/scope-id.js +30 -2
  102. package/lib/template-compiler/bind-this.js +7 -2
  103. package/lib/template-compiler/compiler.js +77 -46
  104. package/lib/template-compiler/gen-node-react.js +2 -2
  105. package/lib/utils/pre-process-json.js +9 -5
  106. package/package.json +5 -4
  107. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  108. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  109. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  110. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  111. package/lib/runtime/components/web/event.js +0 -105
@@ -1,11 +1,11 @@
1
- import { forwardRef, JSX, useEffect, useRef, useContext, useMemo } 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 { getCurrentPage } from './utils'
8
+ import { getCurrentPage, extendObject } from './utils'
9
9
  import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent, WebViewNavigation } from 'react-native-webview/lib/WebViewTypes'
10
10
  import { RouteContext } from './context'
11
11
 
@@ -30,32 +30,25 @@ interface WebViewProps {
30
30
  }
31
31
 
32
32
  interface PayloadData {
33
- data?: Record<string, any>
33
+ [x: string]: any
34
34
  }
35
35
 
36
36
  type MessageData = {
37
37
  payload?: PayloadData,
38
+ args?: Array<any>,
38
39
  type?: string,
39
40
  callbackId?: number
40
41
  }
41
42
 
42
- interface NativeEvent {
43
- url: string,
44
- data: string
45
- }
46
-
47
- interface FormRef {
48
- postMessage: (value: any) => void;
49
- }
50
-
51
- const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element => {
52
- 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
53
46
  if (props.style) {
54
47
  warn('The web-view component does not support the style prop.')
55
48
  }
56
49
  const pageId = useContext(RouteContext)
57
50
  const currentPage = useMemo(() => getCurrentPage(pageId), [pageId])
58
-
51
+ const webViewRef = useRef<WebView>(null)
59
52
  const defaultWebViewStyle = {
60
53
  position: 'absolute' as 'absolute' | 'relative' | 'static',
61
54
  left: 0 as number,
@@ -64,34 +57,14 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
64
57
  bottom: 0 as number
65
58
  }
66
59
 
67
- const webViewRef = useRef<WebView>(null)
68
60
  useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
69
- defaultStyle: defaultWebViewStyle
61
+ style: defaultWebViewStyle
70
62
  })
71
63
 
72
- const _messageList = useRef<any[]>([])
73
- const handleUnload = () => {
74
- // 这里是 WebView 销毁前执行的逻辑
75
- bindmessage(getCustomEvent('messsage', {}, {
76
- detail: {
77
- data: _messageList.current
78
- },
79
- layoutRef: webViewRef
80
- }))
64
+ if (!src) {
65
+ return null
81
66
  }
82
67
 
83
- useEffect(() => {
84
- if (currentPage) {
85
- currentPage.__webViewUrl = src
86
- }
87
- }, [src, currentPage])
88
-
89
- useEffect(() => {
90
- // 组件卸载时执行
91
- return () => {
92
- handleUnload()
93
- }
94
- }, [])
95
68
  const _load = function (res: WebViewNavigationEvent) {
96
69
  const result = {
97
70
  type: 'load',
@@ -112,8 +85,33 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
112
85
  }
113
86
  binderror(result)
114
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
+ `
115
113
  const _changeUrl = function (navState: WebViewNavigation) {
116
- if (currentPage) {
114
+ if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
117
115
  currentPage.__webViewUrl = navState.url
118
116
  }
119
117
  }
@@ -126,57 +124,104 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
126
124
  if (typeof nativeEventData === 'string') {
127
125
  data = JSON.parse(nativeEventData)
128
126
  }
129
- } catch (e) {
130
- data = {}
131
- }
127
+ } catch (e) {}
128
+ const args = data.args
132
129
  const postData: PayloadData = data.payload || {}
133
- 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
134
142
  case 'postMessage':
135
- _messageList.current.push(postData.data)
143
+ bindmessage && bindmessage(getCustomEvent('messsage', {}, { // RN组件销毁顺序与小程序不一致,所以改成和支付宝消息一致
144
+ detail: {
145
+ data: params[0]?.data
146
+ }
147
+ }))
136
148
  asyncCallback = Promise.resolve({
137
149
  errMsg: 'invokeWebappApi:ok'
138
150
  })
139
151
  break
140
152
  case 'navigateTo':
141
- asyncCallback = navObj.navigateTo(postData)
153
+ asyncCallback = navObj.navigateTo(...params)
142
154
  break
143
155
  case 'navigateBack':
144
- asyncCallback = navObj.navigateBack(postData)
156
+ asyncCallback = navObj.navigateBack(...params)
145
157
  break
146
158
  case 'redirectTo':
147
- asyncCallback = navObj.redirectTo(postData)
159
+ asyncCallback = navObj.redirectTo(...params)
148
160
  break
149
161
  case 'switchTab':
150
- asyncCallback = navObj.switchTab(postData)
162
+ asyncCallback = navObj.switchTab(...params)
151
163
  break
152
164
  case 'reLaunch':
153
- 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
+ }
154
179
  break
155
180
  }
156
181
 
157
182
  asyncCallback && asyncCallback.then((res: any) => {
158
183
  if (webViewRef.current?.postMessage) {
159
184
  const test = JSON.stringify({
160
- type: data.type,
185
+ type,
161
186
  callbackId: data.callbackId,
162
187
  result: res
163
188
  })
164
189
  webViewRef.current.postMessage(test)
165
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
+ }
166
200
  })
167
201
  }
168
- return (<Portal>
169
- <WebView
170
- style={defaultWebViewStyle}
171
- source={{ uri: src }}
172
- ref={webViewRef}
173
- onLoad={_load}
174
- onError={_error}
175
- onMessage={_message}
176
- onNavigationStateChange={_changeUrl}
177
- javaScriptEnabled={true}
178
- ></WebView>
179
- </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)))
180
225
  })
181
226
 
182
227
  _WebView.displayName = 'MpxWebview'
@@ -1,22 +1,7 @@
1
- declare module 'react-native-svg/css' {
2
- import type { ImageSourcePropType, StyleProp, ImageStyle } from 'react-native'
3
- import type { SvgProps as SvgCssUriProps } from 'react-native-svg'
4
-
5
- export const SvgCssUri: React.ComponentType<SvgCssUriProps & { uri?: string }>
6
-
7
- export interface WithLocalSvgProps {
8
- asset: ImageSourcePropType
9
- style?: StyleProp<ImageStyle>
10
- width?: string | number
11
- height?: string | number
12
- }
13
-
14
- export const WithLocalSvg: React.ComponentType<WithLocalSvgProps>
15
- }
16
-
17
1
  declare module '@mpxjs/utils' {
18
2
  export function isEmptyObject (obj: Object): boolean
19
3
  export function isFunction (fn: unknown): boolean
4
+ export function isNumber (num: unknown): boolean
20
5
  export function hasOwn (obj: Object, key: string): boolean
21
6
  export function noop (...arg: any): void
22
7
  export function diffAndCloneA<A, B> (a: A, b?: B): {
@@ -34,7 +19,8 @@ declare module '@mpxjs/utils' {
34
19
  bottom: number
35
20
  left: number
36
21
  right: number
37
- }
22
+ },
23
+ setOptions: (params: Record<string, any>) => void
38
24
  } | undefined
39
25
  }
40
26
 
@@ -83,12 +83,34 @@ const InitialValue: ExtendedViewStyle = Object.assign({
83
83
  const TransformOrigin = 'transformOrigin'
84
84
  // transform
85
85
  const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
86
+ // 多value解析
87
+ const parseValues = (str: string, char = ' ') => {
88
+ let stack = 0
89
+ let temp = ''
90
+ const result = []
91
+ for (let i = 0; i < str.length; i++) {
92
+ if (str[i] === '(') {
93
+ stack++
94
+ } else if (str[i] === ')') {
95
+ stack--
96
+ }
97
+ // 非括号内 或者 非分隔字符且非空
98
+ if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
99
+ temp += str[i]
100
+ }
101
+ if ((stack === 0 && str[i] === char) || i === str.length - 1) {
102
+ result.push(temp)
103
+ temp = ''
104
+ }
105
+ }
106
+ return result
107
+ }
86
108
  // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
87
109
  const parseTransform = (transformStr: string) => {
88
- const values = transformStr.trim().split(/\s+/)
110
+ const values = parseValues(transformStr)
89
111
  const transform: {[propName: string]: string|number|number[]}[] = []
90
112
  values.forEach(item => {
91
- const match = item.match(/([/\w]+)\(([^)]+)\)/)
113
+ const match = item.match(/([/\w]+)\((.+)\)/)
92
114
  if (match && match.length >= 3) {
93
115
  let key = match[1]
94
116
  const val = match[2]
@@ -109,7 +131,7 @@ const parseTransform = (transformStr: string) => {
109
131
  break
110
132
  case 'matrix':
111
133
  case 'matrix3d':
112
- transform.push({ [key]: val.split(',').map(val => +val) })
134
+ transform.push({ [key]: parseValues(val, ',').map(val => +val) })
113
135
  break
114
136
  case 'translate':
115
137
  case 'scale':
@@ -120,8 +142,8 @@ const parseTransform = (transformStr: string) => {
120
142
  {
121
143
  // 2 个以上的值处理
122
144
  key = key.replace('3d', '')
123
- const vals = val.split(',', key === 'rotate' ? 4 : 3)
124
- // scale(.5) === scaleX(.5) scaleY(.5) 这里处理一下
145
+ const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3)
146
+ // scale(.5) === scaleX(.5) scaleY(.5)
125
147
  if (vals.length === 1 && key === 'scale') {
126
148
  vals.push(vals[0])
127
149
  }
@@ -218,12 +240,14 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
218
240
  }
219
241
  // 添加每个key的多次step动画
220
242
  animatedKeys.forEach(key => {
221
- let toVal = (rules.get(key) || transform.get(key))
243
+ const ruleV = isTransform(key) ? transform.get(key) : rules.get(key)
222
244
  // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
223
- if (toVal === undefined) {
224
- toVal = index > 0 ? lastValueMap[key] : shareValMap[key].value
225
- }
226
- const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
245
+ const toVal = ruleV !== undefined
246
+ ? ruleV
247
+ : index > 0
248
+ ? lastValueMap[key]
249
+ : shareValMap[key].value
250
+ const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
227
251
  needSetCallback = false
228
252
  if (!sequence[key]) {
229
253
  sequence[key] = [animation]
@@ -231,7 +255,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
231
255
  sequence[key].push(animation)
232
256
  }
233
257
  // 更新一下 lastValueMap
234
- lastValueMap[key] = toVal
258
+ lastValueMap[key] = toVal!
235
259
  })
236
260
  // 赋值驱动动画
237
261
  animatedKeys.forEach((key) => {
@@ -327,6 +351,6 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
327
351
  styles[key] = shareValMap[key].value
328
352
  }
329
353
  return styles
330
- }, Object.assign({}, originalStyle) as ExtendedViewStyle)
354
+ }, {} as ExtendedViewStyle)
331
355
  })
332
356
  }