@mpxjs/webpack-plugin 2.9.57 → 2.9.59
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.
- package/lib/config.js +1 -3
- package/lib/platform/style/wx/index.js +110 -15
- package/lib/platform/template/wx/component-config/web-view.js +8 -0
- package/lib/react/index.js +0 -1
- package/lib/react/processScript.js +5 -1
- package/lib/react/processStyles.js +14 -3
- package/lib/react/style-helper.js +16 -11
- package/lib/runtime/components/react/dist/getInnerListeners.js +2 -2
- package/lib/runtime/components/react/dist/mpx-text.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-view.jsx +5 -5
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +115 -0
- package/lib/runtime/components/react/dist/utils.js +1 -1
- package/lib/runtime/components/react/getInnerListeners.ts +2 -2
- package/lib/runtime/components/react/mpx-text.tsx +2 -2
- package/lib/runtime/components/react/mpx-view.tsx +6 -6
- package/lib/runtime/components/react/mpx-web-view.tsx +171 -0
- package/lib/runtime/components/react/utils.ts +1 -1
- package/lib/runtime/transRpxStyle.js +1 -1
- package/lib/style-compiler/plugins/rpx.js +2 -2
- package/lib/style-compiler/plugins/vw.js +2 -2
- package/lib/template-compiler/compiler.js +57 -24
- package/lib/utils/shallow-stringify.js +1 -1
- package/package.json +3 -2
package/lib/config.js
CHANGED
|
@@ -60,7 +60,7 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
60
60
|
default: 'default' // 不校验
|
|
61
61
|
}
|
|
62
62
|
// number 类型支持的单位(包含auto)
|
|
63
|
-
const numberRegExp = /^\s*((
|
|
63
|
+
const numberRegExp = /^\s*((-?\d+(\.\d+)?)(rpx|px|%)?)|(auto)\s*$/
|
|
64
64
|
// RN 不支持的颜色格式
|
|
65
65
|
const colorRegExp = /^\s*(lab|lch|oklab|oklch|color-mix|color|hwb|lch|light-dark).*$/
|
|
66
66
|
|
|
@@ -101,6 +101,26 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
101
101
|
borderStyle: ValueType.default,
|
|
102
102
|
borderColor: ValueType.color
|
|
103
103
|
},
|
|
104
|
+
'border-left': { // 仅支持 width | style | color 这种排序
|
|
105
|
+
borderLeftWidth: ValueType.number,
|
|
106
|
+
borderLeftStyle: ValueType.default,
|
|
107
|
+
borderLeftColor: ValueType.color
|
|
108
|
+
},
|
|
109
|
+
'border-right': { // 仅支持 width | style | color 这种排序
|
|
110
|
+
borderRightWidth: ValueType.number,
|
|
111
|
+
borderRightStyle: ValueType.default,
|
|
112
|
+
borderRightColor: ValueType.color
|
|
113
|
+
},
|
|
114
|
+
'border-top': { // 仅支持 width | style | color 这种排序
|
|
115
|
+
borderTopWidth: ValueType.number,
|
|
116
|
+
borderTopStyle: ValueType.default,
|
|
117
|
+
borderTopColor: ValueType.color
|
|
118
|
+
},
|
|
119
|
+
'border-bottom': { // 仅支持 width | style | color 这种排序
|
|
120
|
+
borderBottomWidth: ValueType.number,
|
|
121
|
+
borderBottomStyle: ValueType.default,
|
|
122
|
+
borderBottomColor: ValueType.color
|
|
123
|
+
},
|
|
104
124
|
'box-shadow': { // 仅支持 offset-x | offset-y | blur-radius | color 排序
|
|
105
125
|
'shadowOffset.width': ValueType.number,
|
|
106
126
|
'shadowOffset.height': ValueType.number,
|
|
@@ -133,17 +153,21 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
133
153
|
const cssMap = []
|
|
134
154
|
const props = Object.getOwnPropertyNames(keyMap)
|
|
135
155
|
let idx = 0
|
|
156
|
+
let propsIdx = 0
|
|
136
157
|
// 按值的个数循环赋值
|
|
137
|
-
while (idx < values.length
|
|
138
|
-
const prop = props[
|
|
158
|
+
while (idx < values.length || propsIdx < props.length) {
|
|
159
|
+
const prop = props[propsIdx]
|
|
139
160
|
const valueType = keyMap[prop]
|
|
140
161
|
const dashProp = hump2dash(prop)
|
|
141
|
-
// 校验 value 类型
|
|
142
|
-
verifyValues({ prop, value: values[idx], valueType })
|
|
143
162
|
const value = values[idx]
|
|
144
163
|
if (isIllegalValue({ prop: dashProp, value })) {
|
|
145
|
-
//
|
|
164
|
+
// 过滤 rn prop 不支持 value
|
|
146
165
|
unsupportedValueError({ prop: dashProp, value })
|
|
166
|
+
idx += 1
|
|
167
|
+
propsIdx += 1
|
|
168
|
+
} else if (!verifyValues({ prop, value, valueType })) {
|
|
169
|
+
// 校验 value 类型,类型不符则匹配下一个value
|
|
170
|
+
idx += 1
|
|
147
171
|
} else if (prop.includes('.')) {
|
|
148
172
|
// 多个属性值的prop
|
|
149
173
|
const [main, sub] = prop.split('.')
|
|
@@ -158,14 +182,17 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
158
182
|
}
|
|
159
183
|
})
|
|
160
184
|
}
|
|
185
|
+
idx += 1
|
|
186
|
+
propsIdx += 1
|
|
161
187
|
} else {
|
|
162
188
|
// 单个值的属性
|
|
163
189
|
cssMap.push({
|
|
164
190
|
prop,
|
|
165
191
|
value
|
|
166
192
|
})
|
|
193
|
+
idx += 1
|
|
194
|
+
propsIdx += 1
|
|
167
195
|
}
|
|
168
|
-
idx += 1
|
|
169
196
|
}
|
|
170
197
|
return cssMap
|
|
171
198
|
}
|
|
@@ -220,7 +247,7 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
220
247
|
|
|
221
248
|
return {
|
|
222
249
|
prop,
|
|
223
|
-
value:
|
|
250
|
+
value: /^\s*-?\d+(\.\d+)?\s*$/.test(value) ? `${Math.round(value * 100)}%` : value
|
|
224
251
|
}
|
|
225
252
|
}
|
|
226
253
|
|
|
@@ -335,11 +362,74 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
335
362
|
}
|
|
336
363
|
}
|
|
337
364
|
|
|
365
|
+
const formatTransform = ({ prop, value }, { mode }) => {
|
|
366
|
+
if (Array.isArray(value)) return { prop, value }
|
|
367
|
+
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
368
|
+
const transform = []
|
|
369
|
+
values.forEach(item => {
|
|
370
|
+
const match = item.match(/([/\w]+)\(([^)]+)\)/)
|
|
371
|
+
if (match.length >= 3) {
|
|
372
|
+
let key = match[1]
|
|
373
|
+
const val = match[2]
|
|
374
|
+
switch (key) {
|
|
375
|
+
case 'translateX':
|
|
376
|
+
case 'translateY':
|
|
377
|
+
case 'scaleX':
|
|
378
|
+
case 'scaleY':
|
|
379
|
+
case 'rotateX':
|
|
380
|
+
case 'rotateY':
|
|
381
|
+
case 'rotateZ':
|
|
382
|
+
case 'rotate':
|
|
383
|
+
case 'skewX':
|
|
384
|
+
case 'skewY':
|
|
385
|
+
// 单个值处理
|
|
386
|
+
transform.push({ [key]: val })
|
|
387
|
+
break
|
|
388
|
+
case 'matrix':
|
|
389
|
+
case 'matrix3d':
|
|
390
|
+
transform.push({ [key]: val.split(',').map(val => +val) })
|
|
391
|
+
break
|
|
392
|
+
case 'translate':
|
|
393
|
+
case 'scale':
|
|
394
|
+
case 'skew':
|
|
395
|
+
case 'rotate3d': // x y z angle
|
|
396
|
+
case 'translate3d': // x y 支持 z不支持
|
|
397
|
+
case 'scale3d': // x y 支持 z不支持
|
|
398
|
+
{
|
|
399
|
+
// 2 个以上的值处理
|
|
400
|
+
key = key.replace('3d', '')
|
|
401
|
+
const vals = val.split(',').splice(0, key === 'rotate' ? 4 : 3)
|
|
402
|
+
const xyz = ['X', 'Y', 'Z']
|
|
403
|
+
transform.push(...vals.map((v, index) => {
|
|
404
|
+
if (key !== 'rotate' && index > 1) {
|
|
405
|
+
unsupportedPropError({ prop: `${key}Z`, mode })
|
|
406
|
+
}
|
|
407
|
+
return { [`${key}${xyz[index] || ''}`]: v.trim() }
|
|
408
|
+
}))
|
|
409
|
+
break
|
|
410
|
+
}
|
|
411
|
+
case 'translateZ':
|
|
412
|
+
case 'scaleZ':
|
|
413
|
+
default:
|
|
414
|
+
// 不支持的属性处理
|
|
415
|
+
unsupportedPropError({ prop: key, mode })
|
|
416
|
+
break
|
|
417
|
+
}
|
|
418
|
+
} else {
|
|
419
|
+
error(`Property [${prop}] is invalid, please check the value!`)
|
|
420
|
+
}
|
|
421
|
+
})
|
|
422
|
+
return {
|
|
423
|
+
prop,
|
|
424
|
+
value: transform
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
338
428
|
const spec = {
|
|
339
429
|
supportedModes: ['ios', 'android'],
|
|
340
430
|
rules: [
|
|
341
431
|
{ // 背景相关属性的处理
|
|
342
|
-
test:
|
|
432
|
+
test: /^(background|background-image|background-color|background-size|background-repeat|background-position)$/,
|
|
343
433
|
ios: checkBackgroundImage,
|
|
344
434
|
android: checkBackgroundImage
|
|
345
435
|
},
|
|
@@ -372,7 +462,7 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
372
462
|
android: getAbbreviationAndroid
|
|
373
463
|
},
|
|
374
464
|
{
|
|
375
|
-
test:
|
|
465
|
+
test: /^(font-variant|font-variant-caps|font-variant-numeric|font-variant-east-asian|font-variant-alternates|font-variant-ligatures)$/,
|
|
376
466
|
ios: getFontVariant,
|
|
377
467
|
android: getFontVariant
|
|
378
468
|
},
|
|
@@ -382,7 +472,7 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
382
472
|
android: getBorderRadius
|
|
383
473
|
},
|
|
384
474
|
{ // margin padding 内外边距的处理
|
|
385
|
-
test:
|
|
475
|
+
test: /^(margin|padding)$/,
|
|
386
476
|
ios: formatMargins,
|
|
387
477
|
android: formatMargins
|
|
388
478
|
},
|
|
@@ -397,14 +487,19 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
397
487
|
ios: formatLineHeight,
|
|
398
488
|
android: formatLineHeight
|
|
399
489
|
},
|
|
490
|
+
{
|
|
491
|
+
test: 'transform',
|
|
492
|
+
ios: formatTransform,
|
|
493
|
+
android: formatTransform
|
|
494
|
+
},
|
|
400
495
|
// 值类型校验放到最后
|
|
401
|
-
{ // color 颜色值校验
|
|
402
|
-
test:
|
|
496
|
+
{ // color 颜色值校验 color xx-color 等
|
|
497
|
+
test: /^(color|(.+-color))$/,
|
|
403
498
|
ios: checkCommonValue(ValueType.color),
|
|
404
499
|
android: checkCommonValue(ValueType.color)
|
|
405
500
|
},
|
|
406
|
-
{ // number 值校验
|
|
407
|
-
test:
|
|
501
|
+
{ // number 值校验 // width height xx-left xx-top 等
|
|
502
|
+
test: /^((width|height)|(.+-(left|right|top|bottom|radius|spacing|size)))$/,
|
|
408
503
|
ios: checkCommonValue(ValueType.number),
|
|
409
504
|
android: checkCommonValue(ValueType.number)
|
|
410
505
|
}
|
|
@@ -6,6 +6,14 @@ module.exports = function () {
|
|
|
6
6
|
web (tag, { el }) {
|
|
7
7
|
el.isBuiltIn = true
|
|
8
8
|
return 'mpx-web-view'
|
|
9
|
+
},
|
|
10
|
+
ios (tag, { el }) {
|
|
11
|
+
el.isBuiltIn = true
|
|
12
|
+
return 'mpx-web-view'
|
|
13
|
+
},
|
|
14
|
+
android (tag, { el }) {
|
|
15
|
+
el.isBuiltIn = true
|
|
16
|
+
return 'mpx-web-view'
|
|
9
17
|
}
|
|
10
18
|
}
|
|
11
19
|
}
|
package/lib/react/index.js
CHANGED
|
@@ -27,12 +27,16 @@ import { getComponent } from ${stringifyRequest(loaderContext, optionProcessorPa
|
|
|
27
27
|
import { NavigationContainer, createNavigationContainerRef, StackActions } from '@react-navigation/native'
|
|
28
28
|
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
|
29
29
|
import { Provider } from '@ant-design/react-native'
|
|
30
|
+
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
31
|
+
|
|
30
32
|
global.__navigationHelper = {
|
|
31
33
|
NavigationContainer: NavigationContainer,
|
|
32
34
|
createNavigationContainerRef: createNavigationContainerRef,
|
|
33
35
|
createNativeStackNavigator: createNativeStackNavigator,
|
|
34
36
|
StackActions: StackActions,
|
|
35
|
-
Provider: Provider
|
|
37
|
+
Provider: Provider,
|
|
38
|
+
SafeAreaProvider: SafeAreaProvider,
|
|
39
|
+
useSafeAreaInsets: useSafeAreaInsets
|
|
36
40
|
}\n`
|
|
37
41
|
const { pagesMap, firstPage } = buildPagesMap({
|
|
38
42
|
localPagesMap,
|
|
@@ -5,7 +5,6 @@ const shallowStringify = require('../utils/shallow-stringify')
|
|
|
5
5
|
|
|
6
6
|
module.exports = function (styles, {
|
|
7
7
|
loaderContext,
|
|
8
|
-
srcMode,
|
|
9
8
|
ctorType,
|
|
10
9
|
autoScope,
|
|
11
10
|
moduleId
|
|
@@ -14,7 +13,17 @@ module.exports = function (styles, {
|
|
|
14
13
|
let content = ''
|
|
15
14
|
let output = '/* styles */\n'
|
|
16
15
|
if (styles.length) {
|
|
17
|
-
const
|
|
16
|
+
const warn = (msg) => {
|
|
17
|
+
loaderContext.emitWarning(
|
|
18
|
+
new Error('[style compiler][' + loaderContext.resource + ']: ' + msg)
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
const error = (msg) => {
|
|
22
|
+
loaderContext.emitError(
|
|
23
|
+
new Error('[style compiler][' + loaderContext.resource + ']: ' + msg)
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
const { mode, srcMode } = loaderContext.getMpx()
|
|
18
27
|
async.eachOfSeries(styles, (style, i, callback) => {
|
|
19
28
|
const scoped = style.scoped || autoScope
|
|
20
29
|
const extraOptions = {
|
|
@@ -41,7 +50,9 @@ module.exports = function (styles, {
|
|
|
41
50
|
content,
|
|
42
51
|
filename: loaderContext.resourcePath,
|
|
43
52
|
mode,
|
|
44
|
-
srcMode
|
|
53
|
+
srcMode,
|
|
54
|
+
warn,
|
|
55
|
+
error
|
|
45
56
|
})
|
|
46
57
|
if (ctorType === 'app') {
|
|
47
58
|
output += `global.__getAppClassMap = function() {
|
|
@@ -2,10 +2,10 @@ const postcss = require('postcss')
|
|
|
2
2
|
const selectorParser = require('postcss-selector-parser')
|
|
3
3
|
const getRulesRunner = require('../platform/index')
|
|
4
4
|
const dash2hump = require('../utils/hump-dash').dash2hump
|
|
5
|
-
const rpxRegExp = /^\s*(
|
|
6
|
-
const pxRegExp = /^\s*(
|
|
5
|
+
const rpxRegExp = /^\s*(-?\d+(\.\d+)?)rpx\s*$/
|
|
6
|
+
const pxRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
|
|
7
7
|
const cssPrefixExp = /^-(webkit|moz|ms|o)-/
|
|
8
|
-
function getClassMap ({ content, filename, mode, srcMode }) {
|
|
8
|
+
function getClassMap ({ content, filename, mode, srcMode, warn, error }) {
|
|
9
9
|
const classMap = {}
|
|
10
10
|
|
|
11
11
|
const root = postcss.parse(content, {
|
|
@@ -30,12 +30,8 @@ function getClassMap ({ content, filename, mode, srcMode }) {
|
|
|
30
30
|
srcMode,
|
|
31
31
|
type: 'style',
|
|
32
32
|
testKey: 'prop',
|
|
33
|
-
warn
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
error: (msg) => {
|
|
37
|
-
console.error('[style compiler error]: ' + msg)
|
|
38
|
-
}
|
|
33
|
+
warn,
|
|
34
|
+
error
|
|
39
35
|
})
|
|
40
36
|
|
|
41
37
|
root.walkRules(rule => {
|
|
@@ -51,7 +47,16 @@ function getClassMap ({ content, filename, mode, srcMode }) {
|
|
|
51
47
|
prop = dash2hump(item.prop)
|
|
52
48
|
value = item.value
|
|
53
49
|
if (Array.isArray(value)) {
|
|
54
|
-
value = value.map(
|
|
50
|
+
value = value.map(val => {
|
|
51
|
+
if (typeof val === 'object') {
|
|
52
|
+
for (const key in val) {
|
|
53
|
+
val[key] = formatValue(val[key])
|
|
54
|
+
}
|
|
55
|
+
return val
|
|
56
|
+
} else {
|
|
57
|
+
return formatValue(val)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
55
60
|
} else if (typeof value === 'object') {
|
|
56
61
|
for (const key in value) {
|
|
57
62
|
value[key] = formatValue(value[key])
|
|
@@ -70,7 +75,7 @@ function getClassMap ({ content, filename, mode, srcMode }) {
|
|
|
70
75
|
if (selector.nodes.length === 1 && selector.nodes[0].type === 'class') {
|
|
71
76
|
classMapKeys.push(selector.nodes[0].value)
|
|
72
77
|
} else {
|
|
73
|
-
|
|
78
|
+
error('Only single class selector is supported in react native mode temporarily.')
|
|
74
79
|
}
|
|
75
80
|
})
|
|
76
81
|
}).processSync(rule.selector)
|
|
@@ -10,8 +10,8 @@ const getTouchEvent = (type, event, props, config) => {
|
|
|
10
10
|
...event,
|
|
11
11
|
type,
|
|
12
12
|
timeStamp: timestamp,
|
|
13
|
-
|
|
14
|
-
...(event.
|
|
13
|
+
currentTarget: {
|
|
14
|
+
...(event.currentTarget || {}),
|
|
15
15
|
id: id || '',
|
|
16
16
|
dataset: getDataSet(props),
|
|
17
17
|
offsetLeft: layoutRef?.current?.offsetLeft || 0,
|
|
@@ -8,13 +8,13 @@ import { useRef, useEffect, forwardRef } from 'react';
|
|
|
8
8
|
import useInnerProps from './getInnerListeners';
|
|
9
9
|
// @ts-ignore
|
|
10
10
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
11
|
-
import {
|
|
11
|
+
import { PERCENT_REGEX } from './utils';
|
|
12
12
|
const DEFAULT_STYLE = {
|
|
13
13
|
fontSize: 16
|
|
14
14
|
};
|
|
15
15
|
const transformStyle = (styleObj) => {
|
|
16
16
|
let { lineHeight } = styleObj;
|
|
17
|
-
if (typeof lineHeight === 'string' &&
|
|
17
|
+
if (typeof lineHeight === 'string' && PERCENT_REGEX.test(lineHeight)) {
|
|
18
18
|
lineHeight = (parseFloat(lineHeight) / 100) * (styleObj.fontSize || DEFAULT_STYLE.fontSize);
|
|
19
19
|
styleObj.lineHeight = lineHeight;
|
|
20
20
|
}
|
|
@@ -10,7 +10,7 @@ import { useRef, useState, useEffect, forwardRef } from 'react';
|
|
|
10
10
|
import useInnerProps from './getInnerListeners';
|
|
11
11
|
// @ts-ignore
|
|
12
12
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
13
|
-
import { parseUrl, TEXT_STYLE_REGEX,
|
|
13
|
+
import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGEX, isText } from './utils';
|
|
14
14
|
const IMAGE_STYLE_REGEX = /^background(Image|Size|Repeat|Position)$/;
|
|
15
15
|
function groupBy(style, callback, group = {}) {
|
|
16
16
|
let groupKey = '';
|
|
@@ -33,7 +33,7 @@ const applyHandlers = (handlers, args) => {
|
|
|
33
33
|
};
|
|
34
34
|
const checkNeedLayout = (style) => {
|
|
35
35
|
const [width, height] = style.sizeList;
|
|
36
|
-
return (
|
|
36
|
+
return (PERCENT_REGEX.test(`${height}`) && width === 'auto') || (PERCENT_REGEX.test(`${width}`) && height === 'auto');
|
|
37
37
|
};
|
|
38
38
|
/**
|
|
39
39
|
* h - 用户设置的高度
|
|
@@ -42,7 +42,7 @@ const checkNeedLayout = (style) => {
|
|
|
42
42
|
* **/
|
|
43
43
|
function calculateSize(h, lh, ratio) {
|
|
44
44
|
let height, width;
|
|
45
|
-
if (
|
|
45
|
+
if (PERCENT_REGEX.test(`${h}`)) { // auto px/rpx
|
|
46
46
|
if (!lh)
|
|
47
47
|
return null;
|
|
48
48
|
height = (parseFloat(`${h}`) / 100) * lh;
|
|
@@ -97,8 +97,8 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
|
97
97
|
else { // 数值类型 ImageStyle
|
|
98
98
|
// 数值类型设置为 stretch
|
|
99
99
|
imageProps.style.resizeMode = 'stretch';
|
|
100
|
-
newWidth =
|
|
101
|
-
newHeight =
|
|
100
|
+
newWidth = PERCENT_REGEX.test(`${width}`) ? width : +width;
|
|
101
|
+
newHeight = PERCENT_REGEX.test(`${width}`) ? height : +height;
|
|
102
102
|
}
|
|
103
103
|
// 样式合并
|
|
104
104
|
imageProps.style = {
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { forwardRef, useEffect } from 'react';
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import { noop } from '@mpxjs/utils';
|
|
4
|
+
import { Portal } from '@ant-design/react-native';
|
|
5
|
+
import { getCustomEvent } from './getInnerListeners';
|
|
6
|
+
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
import { WebView } from 'react-native-webview';
|
|
9
|
+
import useNodesRef from './useNodesRef';
|
|
10
|
+
import { StyleSheet } from 'react-native';
|
|
11
|
+
const _WebView = forwardRef((props, ref) => {
|
|
12
|
+
const { src, bindmessage = noop, bindload = noop, binderror = noop } = props;
|
|
13
|
+
const defaultWebViewStyle = [
|
|
14
|
+
{
|
|
15
|
+
position: 'absolute',
|
|
16
|
+
left: 0,
|
|
17
|
+
right: 0,
|
|
18
|
+
top: 0,
|
|
19
|
+
bottom: 0
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
const { nodeRef: webViewRef } = useNodesRef(props, ref, {
|
|
23
|
+
defaultStyle: StyleSheet.flatten([
|
|
24
|
+
...defaultWebViewStyle
|
|
25
|
+
])
|
|
26
|
+
});
|
|
27
|
+
const _messageList = [];
|
|
28
|
+
const handleUnload = () => {
|
|
29
|
+
// 这里是 WebView 销毁前执行的逻辑
|
|
30
|
+
bindmessage(getCustomEvent('messsage', {}, {
|
|
31
|
+
detail: {
|
|
32
|
+
data: _messageList
|
|
33
|
+
},
|
|
34
|
+
layoutRef: webViewRef
|
|
35
|
+
}));
|
|
36
|
+
};
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
// 组件卸载时执行
|
|
39
|
+
return () => {
|
|
40
|
+
handleUnload();
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
43
|
+
const _load = function (res) {
|
|
44
|
+
const result = {
|
|
45
|
+
type: 'load',
|
|
46
|
+
timeStamp: res.timeStamp,
|
|
47
|
+
detail: {
|
|
48
|
+
src: res.nativeEvent?.url
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
bindload(result);
|
|
52
|
+
};
|
|
53
|
+
const _error = function (res) {
|
|
54
|
+
const result = {
|
|
55
|
+
type: 'error',
|
|
56
|
+
timeStamp: res.timeStamp,
|
|
57
|
+
detail: {
|
|
58
|
+
src: ''
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
binderror(result);
|
|
62
|
+
};
|
|
63
|
+
const _message = function (res) {
|
|
64
|
+
let data;
|
|
65
|
+
let asyncCallback;
|
|
66
|
+
const navObj = promisify({ redirectTo, navigateTo, navigateBack, reLaunch, switchTab });
|
|
67
|
+
try {
|
|
68
|
+
const nativeEventData = res.nativeEvent?.data;
|
|
69
|
+
data = JSON.parse(nativeEventData);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
data = {};
|
|
73
|
+
}
|
|
74
|
+
const postData = data.payload || {};
|
|
75
|
+
switch (data.type) {
|
|
76
|
+
case 'postMessage':
|
|
77
|
+
_messageList.push(postData.data);
|
|
78
|
+
asyncCallback = Promise.resolve({
|
|
79
|
+
errMsg: 'invokeWebappApi:ok'
|
|
80
|
+
});
|
|
81
|
+
break;
|
|
82
|
+
case 'navigateTo':
|
|
83
|
+
asyncCallback = navObj.navigateTo(postData);
|
|
84
|
+
break;
|
|
85
|
+
case 'navigateBack':
|
|
86
|
+
asyncCallback = navObj.navigateBack(postData);
|
|
87
|
+
break;
|
|
88
|
+
case 'redirectTo':
|
|
89
|
+
asyncCallback = navObj.redirectTo(postData);
|
|
90
|
+
break;
|
|
91
|
+
case 'switchTab':
|
|
92
|
+
asyncCallback = navObj.switchTab(postData);
|
|
93
|
+
break;
|
|
94
|
+
case 'reLaunch':
|
|
95
|
+
asyncCallback = navObj.reLaunch(postData);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
asyncCallback && asyncCallback.then((res) => {
|
|
99
|
+
if (webViewRef.current?.postMessage) {
|
|
100
|
+
const test = JSON.stringify({
|
|
101
|
+
type: data.type,
|
|
102
|
+
callbackId: data.callbackId,
|
|
103
|
+
result: res
|
|
104
|
+
});
|
|
105
|
+
webViewRef.current.postMessage(test);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
return (<Portal>
|
|
111
|
+
<WebView style={[...defaultWebViewStyle]} source={{ uri: src }} ref={webViewRef} onLoad={_load} onError={_error} onMessage={_message} javaScriptEnabled={true}></WebView>
|
|
112
|
+
</Portal>);
|
|
113
|
+
});
|
|
114
|
+
_WebView.displayName = 'mpx-web-view';
|
|
115
|
+
export default _WebView;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef, Children, isValidElement } from 'react';
|
|
2
2
|
import { StyleSheet } from 'react-native';
|
|
3
3
|
export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/;
|
|
4
|
-
export const
|
|
4
|
+
export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/;
|
|
5
5
|
const URL_REGEX = /url\(["']?(.*?)["']?\)/;
|
|
6
6
|
export function omit(obj, fields) {
|
|
7
7
|
const shallowCopy = Object.assign({}, obj);
|
|
@@ -33,8 +33,8 @@ const getTouchEvent = (
|
|
|
33
33
|
...event,
|
|
34
34
|
type,
|
|
35
35
|
timeStamp: timestamp,
|
|
36
|
-
|
|
37
|
-
...(event.
|
|
36
|
+
currentTarget: {
|
|
37
|
+
...(event.currentTarget || {}),
|
|
38
38
|
id: id || '',
|
|
39
39
|
dataset: getDataSet(props),
|
|
40
40
|
offsetLeft: layoutRef?.current?.offsetLeft || 0,
|
|
@@ -9,7 +9,7 @@ import { useRef, useEffect, forwardRef, ReactNode, ForwardedRef, JSX } from 'rea
|
|
|
9
9
|
import useInnerProps from './getInnerListeners'
|
|
10
10
|
// @ts-ignore
|
|
11
11
|
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
|
|
12
|
-
import {
|
|
12
|
+
import { PERCENT_REGEX } from './utils'
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
interface _TextProps extends TextProps {
|
|
@@ -28,7 +28,7 @@ const DEFAULT_STYLE = {
|
|
|
28
28
|
|
|
29
29
|
const transformStyle = (styleObj: TextStyle) => {
|
|
30
30
|
let { lineHeight } = styleObj
|
|
31
|
-
if (typeof lineHeight === 'string' &&
|
|
31
|
+
if (typeof lineHeight === 'string' && PERCENT_REGEX.test(lineHeight)) {
|
|
32
32
|
lineHeight = (parseFloat(lineHeight)/100) * (styleObj.fontSize || DEFAULT_STYLE.fontSize)
|
|
33
33
|
styleObj.lineHeight = lineHeight
|
|
34
34
|
}
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* ✔ hover-stay-time
|
|
6
6
|
*/
|
|
7
7
|
import { View, Text, StyleProp, TextStyle, ViewStyle, NativeSyntheticEvent, ViewProps, ImageStyle, ImageResizeMode, StyleSheet, Image, LayoutChangeEvent } from 'react-native'
|
|
8
|
-
import { useRef, useState, useEffect, forwardRef,
|
|
8
|
+
import { useRef, useState, useEffect, forwardRef, ReactNode, JSX } from 'react'
|
|
9
9
|
// @ts-ignore
|
|
10
10
|
import useInnerProps from './getInnerListeners'
|
|
11
11
|
// @ts-ignore
|
|
12
12
|
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
|
|
13
13
|
|
|
14
|
-
import { parseUrl, TEXT_STYLE_REGEX,
|
|
14
|
+
import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGEX, isText} from './utils'
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
type ExtendedViewStyle = ViewStyle & {
|
|
@@ -79,7 +79,7 @@ const applyHandlers = (handlers: Handler[] , args: any [] ) => {
|
|
|
79
79
|
|
|
80
80
|
const checkNeedLayout = (style: PreImageInfo) => {
|
|
81
81
|
const [width, height] = style.sizeList
|
|
82
|
-
return (
|
|
82
|
+
return (PERCENT_REGEX.test(`${height}`) && width === 'auto') || (PERCENT_REGEX.test(`${width}`) && height === 'auto')
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
@@ -89,7 +89,7 @@ const checkNeedLayout = (style: PreImageInfo) => {
|
|
|
89
89
|
* **/
|
|
90
90
|
function calculateSize(h: number, lh: number, ratio: number) {
|
|
91
91
|
let height, width
|
|
92
|
-
if (
|
|
92
|
+
if (PERCENT_REGEX.test(`${h}`)) { // auto px/rpx
|
|
93
93
|
if (!lh) return null
|
|
94
94
|
height = (parseFloat(`${h}`) / 100) * lh
|
|
95
95
|
width = height * ratio
|
|
@@ -136,8 +136,8 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
|
|
|
136
136
|
} else { // 数值类型 ImageStyle
|
|
137
137
|
// 数值类型设置为 stretch
|
|
138
138
|
(imageProps.style as ImageStyle).resizeMode = 'stretch'
|
|
139
|
-
newWidth =
|
|
140
|
-
newHeight =
|
|
139
|
+
newWidth = PERCENT_REGEX.test(`${width}`) ? width : +width! as DimensionValue
|
|
140
|
+
newHeight = PERCENT_REGEX.test(`${width}`) ? height : +height! as DimensionValue
|
|
141
141
|
}
|
|
142
142
|
// 样式合并
|
|
143
143
|
imageProps.style = {
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { forwardRef, JSX, useRef, useEffect } from 'react'
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import { noop } from '@mpxjs/utils'
|
|
4
|
+
import { Portal } from '@ant-design/react-native'
|
|
5
|
+
import { getCustomEvent } from './getInnerListeners'
|
|
6
|
+
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
import { WebView } from 'react-native-webview'
|
|
9
|
+
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
10
|
+
import { StyleSheet } from 'react-native'
|
|
11
|
+
|
|
12
|
+
type OnMessageCallbackEvent = {
|
|
13
|
+
detail: {
|
|
14
|
+
data: any[]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type CommonCallbackEvent = {
|
|
19
|
+
detail: {
|
|
20
|
+
src?: string
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface WebViewProps {
|
|
25
|
+
src: string
|
|
26
|
+
bindmessage?: (event: OnMessageCallbackEvent) => void
|
|
27
|
+
bindload?: (event: CommonCallbackEvent) => void
|
|
28
|
+
binderror?: (event: CommonCallbackEvent) => void
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface PayloadData {
|
|
32
|
+
data?: Record<string, any>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type MessageData = {
|
|
36
|
+
payload?: PayloadData,
|
|
37
|
+
type?: string,
|
|
38
|
+
callbackId?: number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface NativeEvent {
|
|
42
|
+
url: string,
|
|
43
|
+
data: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface LoadRes {
|
|
47
|
+
timeStamp: string,
|
|
48
|
+
nativeEvent: NativeEvent
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface FormRef {
|
|
52
|
+
postMessage: (value: any) => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element => {
|
|
56
|
+
const { src, bindmessage = noop, bindload = noop, binderror = noop } = props
|
|
57
|
+
|
|
58
|
+
const defaultWebViewStyle = [
|
|
59
|
+
{
|
|
60
|
+
position: 'absolute',
|
|
61
|
+
left: 0,
|
|
62
|
+
right: 0,
|
|
63
|
+
top: 0,
|
|
64
|
+
bottom: 0
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
const { nodeRef: webViewRef } = useNodesRef<WebView, WebViewProps>(props, ref, {
|
|
68
|
+
defaultStyle: StyleSheet.flatten([
|
|
69
|
+
...defaultWebViewStyle
|
|
70
|
+
])
|
|
71
|
+
})
|
|
72
|
+
const _messageList:any[] = []
|
|
73
|
+
const handleUnload = () => {
|
|
74
|
+
// 这里是 WebView 销毁前执行的逻辑
|
|
75
|
+
bindmessage(getCustomEvent('messsage', {}, {
|
|
76
|
+
detail: {
|
|
77
|
+
data: _messageList
|
|
78
|
+
},
|
|
79
|
+
layoutRef: webViewRef
|
|
80
|
+
}))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
// 组件卸载时执行
|
|
85
|
+
return () => {
|
|
86
|
+
handleUnload()
|
|
87
|
+
}
|
|
88
|
+
}, [])
|
|
89
|
+
const _load = function(res:LoadRes) {
|
|
90
|
+
const result = {
|
|
91
|
+
type: 'load',
|
|
92
|
+
timeStamp: res.timeStamp,
|
|
93
|
+
detail: {
|
|
94
|
+
src: res.nativeEvent?.url
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
bindload(result)
|
|
98
|
+
}
|
|
99
|
+
const _error = function(res:LoadRes) {
|
|
100
|
+
const result = {
|
|
101
|
+
type: 'error',
|
|
102
|
+
timeStamp: res.timeStamp,
|
|
103
|
+
detail: {
|
|
104
|
+
src: ''
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
binderror(result)
|
|
108
|
+
}
|
|
109
|
+
const _message = function(res:LoadRes) {
|
|
110
|
+
let data: MessageData
|
|
111
|
+
let asyncCallback
|
|
112
|
+
const navObj = promisify({ redirectTo, navigateTo, navigateBack, reLaunch, switchTab })
|
|
113
|
+
try {
|
|
114
|
+
const nativeEventData = res.nativeEvent?.data
|
|
115
|
+
data = JSON.parse(nativeEventData)
|
|
116
|
+
} catch (e) {
|
|
117
|
+
data = {}
|
|
118
|
+
}
|
|
119
|
+
const postData:PayloadData = data.payload || {}
|
|
120
|
+
switch (data.type) {
|
|
121
|
+
case 'postMessage':
|
|
122
|
+
_messageList.push(postData.data)
|
|
123
|
+
asyncCallback = Promise.resolve({
|
|
124
|
+
errMsg: 'invokeWebappApi:ok'
|
|
125
|
+
})
|
|
126
|
+
break
|
|
127
|
+
case 'navigateTo':
|
|
128
|
+
asyncCallback = navObj.navigateTo(postData)
|
|
129
|
+
break
|
|
130
|
+
case 'navigateBack':
|
|
131
|
+
asyncCallback = navObj.navigateBack(postData)
|
|
132
|
+
break
|
|
133
|
+
case 'redirectTo':
|
|
134
|
+
asyncCallback = navObj.redirectTo(postData)
|
|
135
|
+
break
|
|
136
|
+
case 'switchTab':
|
|
137
|
+
asyncCallback = navObj.switchTab(postData)
|
|
138
|
+
break
|
|
139
|
+
case 'reLaunch':
|
|
140
|
+
asyncCallback = navObj.reLaunch(postData)
|
|
141
|
+
break
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
asyncCallback && asyncCallback.then((res: any) => {
|
|
145
|
+
if (webViewRef.current?.postMessage) {
|
|
146
|
+
const test = JSON.stringify({
|
|
147
|
+
type: data.type,
|
|
148
|
+
callbackId: data.callbackId,
|
|
149
|
+
result: res
|
|
150
|
+
})
|
|
151
|
+
webViewRef.current.postMessage(test)
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
return(<Portal>
|
|
157
|
+
<WebView
|
|
158
|
+
style={[ ...defaultWebViewStyle ]}
|
|
159
|
+
source={{ uri: src }}
|
|
160
|
+
ref={webViewRef}
|
|
161
|
+
onLoad={_load}
|
|
162
|
+
onError={_error}
|
|
163
|
+
onMessage={_message}
|
|
164
|
+
javaScriptEnabled={true}
|
|
165
|
+
></WebView>
|
|
166
|
+
</Portal>)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
_WebView.displayName = 'mpx-web-view'
|
|
170
|
+
|
|
171
|
+
export default _WebView
|
|
@@ -3,7 +3,7 @@ import { StyleProp, StyleSheet, TextStyle, ViewStyle } from 'react-native'
|
|
|
3
3
|
|
|
4
4
|
export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
|
|
7
7
|
|
|
8
8
|
const URL_REGEX = /url\(["']?(.*?)["']?\)/
|
|
9
9
|
|
|
@@ -5,7 +5,7 @@ module.exports = function (style) {
|
|
|
5
5
|
}
|
|
6
6
|
const transRpxFn = global.__mpxTransRpxFn || defaultTransRpxFn
|
|
7
7
|
const parsedStyleObj = {}
|
|
8
|
-
const rpxRegExpG = /\b(
|
|
8
|
+
const rpxRegExpG = /\b(-?\d+(\.\d+)?)rpx\b/g
|
|
9
9
|
const parseStyleText = (cssText) => {
|
|
10
10
|
const listDelimiter = /;(?![^(]*\))/g
|
|
11
11
|
const propertyDelimiter = /:(.+)/
|
|
@@ -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) {
|
|
@@ -1121,12 +1135,12 @@ function getModelConfig (el, match) {
|
|
|
1121
1135
|
}
|
|
1122
1136
|
}
|
|
1123
1137
|
|
|
1124
|
-
function processEventReact (el
|
|
1138
|
+
function processEventReact (el) {
|
|
1125
1139
|
const eventConfigMap = {}
|
|
1126
1140
|
el.attrsList.forEach(function ({ name, value }) {
|
|
1127
1141
|
const parsedEvent = config[mode].event.parseEvent(name)
|
|
1128
1142
|
if (parsedEvent) {
|
|
1129
|
-
const type = parsedEvent.eventName
|
|
1143
|
+
const type = config[mode].event.getEvent(parsedEvent.eventName, parsedEvent.prefix)
|
|
1130
1144
|
const parsedFunc = parseFuncStr(value)
|
|
1131
1145
|
if (parsedFunc) {
|
|
1132
1146
|
if (!eventConfigMap[type]) {
|
|
@@ -1153,12 +1167,14 @@ function processEventReact (el, options, meta) {
|
|
|
1153
1167
|
// } else {
|
|
1154
1168
|
// stringifiedModelValue = stringify(modelValue)
|
|
1155
1169
|
// }
|
|
1156
|
-
|
|
1157
|
-
|
|
1170
|
+
// todo 未来可能需要支持类似modelEventPrefix这样的配置来声明model事件的绑定方式
|
|
1171
|
+
const modelEventType = config[mode].event.getEvent(modelEvent)
|
|
1172
|
+
if (!eventConfigMap[modelEventType]) {
|
|
1173
|
+
eventConfigMap[modelEventType] = {
|
|
1158
1174
|
configs: []
|
|
1159
1175
|
}
|
|
1160
1176
|
}
|
|
1161
|
-
eventConfigMap[
|
|
1177
|
+
eventConfigMap[modelEventType].configs.unshift({
|
|
1162
1178
|
hasArgs: true,
|
|
1163
1179
|
expStr: `[${stringify('__model')},${stringifiedModelValue},${stringify(eventIdentifier)},${stringify(modelValuePathArr)}${modelFilter ? `,${stringify(modelFilter)}` : ''}]`
|
|
1164
1180
|
})
|
|
@@ -1172,11 +1188,8 @@ function processEventReact (el, options, meta) {
|
|
|
1172
1188
|
}
|
|
1173
1189
|
|
|
1174
1190
|
// let wrapper
|
|
1175
|
-
|
|
1176
1191
|
for (const type in eventConfigMap) {
|
|
1177
1192
|
let { configs } = eventConfigMap[type]
|
|
1178
|
-
|
|
1179
|
-
let resultName
|
|
1180
1193
|
configs.forEach(({ name }) => {
|
|
1181
1194
|
if (name) {
|
|
1182
1195
|
// 清空原始事件绑定
|
|
@@ -1184,21 +1197,15 @@ function processEventReact (el, options, meta) {
|
|
|
1184
1197
|
do {
|
|
1185
1198
|
has = getAndRemoveAttr(el, name).has
|
|
1186
1199
|
} while (has)
|
|
1187
|
-
|
|
1188
|
-
if (!resultName) {
|
|
1189
|
-
// 清除修饰符
|
|
1190
|
-
resultName = name.replace(/\..*/, '')
|
|
1191
|
-
}
|
|
1192
1200
|
}
|
|
1193
1201
|
})
|
|
1194
1202
|
configs = configs.map((item) => {
|
|
1195
1203
|
return item.expStr
|
|
1196
1204
|
})
|
|
1197
|
-
const name = resultName || config[mode].event.getEvent(type)
|
|
1198
1205
|
const value = `{{(e)=>this.__invoke(e, [${configs}])}}`
|
|
1199
1206
|
addAttrs(el, [
|
|
1200
1207
|
{
|
|
1201
|
-
name,
|
|
1208
|
+
name: type,
|
|
1202
1209
|
value
|
|
1203
1210
|
}
|
|
1204
1211
|
])
|
|
@@ -1698,23 +1705,49 @@ function processFor (el) {
|
|
|
1698
1705
|
}
|
|
1699
1706
|
|
|
1700
1707
|
function processRefReact (el, meta) {
|
|
1701
|
-
const val = getAndRemoveAttr(el, config[mode].directive.ref)
|
|
1708
|
+
const { val, has } = getAndRemoveAttr(el, config[mode].directive.ref)
|
|
1709
|
+
|
|
1702
1710
|
// rn中只有内建组件能被作为node ref处理
|
|
1703
1711
|
const type = el.isBuiltIn ? 'node' : 'component'
|
|
1704
|
-
if (
|
|
1712
|
+
if (has) {
|
|
1705
1713
|
if (!meta.refs) {
|
|
1706
1714
|
meta.refs = []
|
|
1707
1715
|
}
|
|
1708
1716
|
const all = !!forScopes.length
|
|
1709
|
-
|
|
1717
|
+
const refConf = {
|
|
1710
1718
|
key: val,
|
|
1711
1719
|
all,
|
|
1712
1720
|
type
|
|
1713
|
-
}
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
if (!val) {
|
|
1724
|
+
refConf.key = `ref_rn_${++refId}`
|
|
1725
|
+
refConf.sKeys = []
|
|
1726
|
+
const rawId = el.attrsMap.id
|
|
1727
|
+
const rawClass = el.attrsMap.class
|
|
1728
|
+
const rawDynamicClass = el.attrsMap[config[mode].directive.dynamicClass]
|
|
1729
|
+
|
|
1730
|
+
meta.computed = meta.computed || []
|
|
1731
|
+
if (rawId) {
|
|
1732
|
+
const staticId = parseMustacheWithContext(rawId).result
|
|
1733
|
+
const computedIdKey = `_ri${refId}`
|
|
1734
|
+
refConf.sKeys.push({ key: computedIdKey, prefix: '#' })
|
|
1735
|
+
meta.computed.push(`${computedIdKey}() {\n return ${staticId}}`)
|
|
1736
|
+
}
|
|
1737
|
+
if (rawClass || rawDynamicClass) {
|
|
1738
|
+
const staticClass = parseMustacheWithContext(rawClass).result
|
|
1739
|
+
const dynamicClass = parseMustacheWithContext(rawDynamicClass).result
|
|
1740
|
+
const computedClassKey = `_rc${refId}`
|
|
1741
|
+
refConf.sKeys.push({ key: computedClassKey, prefix: '.' })
|
|
1742
|
+
meta.computed.push(`${computedClassKey}() {\n return this.__getClass(${staticClass}, ${dynamicClass})}`)
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
meta.refs.push(refConf)
|
|
1714
1747
|
|
|
1715
1748
|
addAttrs(el, [{
|
|
1716
1749
|
name: 'ref',
|
|
1717
|
-
value: `{{ this.__getRefVal('${
|
|
1750
|
+
value: `{{ this.__getRefVal('${refConf.key}') }}`
|
|
1718
1751
|
}])
|
|
1719
1752
|
}
|
|
1720
1753
|
}
|
|
@@ -2571,8 +2604,8 @@ function processElement (el, root, options, meta) {
|
|
|
2571
2604
|
processIf(el)
|
|
2572
2605
|
processFor(el)
|
|
2573
2606
|
processRefReact(el, meta)
|
|
2574
|
-
processStyleReact(el)
|
|
2575
|
-
processEventReact(el
|
|
2607
|
+
processStyleReact(el, options)
|
|
2608
|
+
processEventReact(el)
|
|
2576
2609
|
processComponentIs(el, options)
|
|
2577
2610
|
processSlotReact(el)
|
|
2578
2611
|
processAttrs(el, options)
|
|
@@ -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.
|
|
3
|
+
"version": "2.9.59",
|
|
4
4
|
"description": "mpx compile core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mpx"
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"build": "rimraf ./lib/runtime/components/react/dist && tsc"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
+
"@ant-design/react-native": "^5.2.2",
|
|
83
84
|
"@types/babel-traverse": "^6.25.4",
|
|
84
85
|
"@types/babel-types": "^7.0.4",
|
|
85
86
|
"@types/react": "^18.2.79",
|
|
@@ -89,5 +90,5 @@
|
|
|
89
90
|
"engines": {
|
|
90
91
|
"node": ">=14.14.0"
|
|
91
92
|
},
|
|
92
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "aa001c11cc7b21772fc6f9f5bcdd13118fc6d67c"
|
|
93
94
|
}
|