@mpxjs/webpack-plugin 2.9.58 → 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 +81 -6
- package/lib/react/processScript.js +5 -1
- package/lib/react/style-helper.js +10 -1
- 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/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/utils.ts +1 -1
- package/lib/template-compiler/compiler.js +17 -3
- package/lib/utils/shallow-stringify.js +1 -1
- package/package.json +2 -2
package/lib/config.js
CHANGED
|
@@ -153,17 +153,21 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
153
153
|
const cssMap = []
|
|
154
154
|
const props = Object.getOwnPropertyNames(keyMap)
|
|
155
155
|
let idx = 0
|
|
156
|
+
let propsIdx = 0
|
|
156
157
|
// 按值的个数循环赋值
|
|
157
|
-
while (idx < values.length
|
|
158
|
-
const prop = props[
|
|
158
|
+
while (idx < values.length || propsIdx < props.length) {
|
|
159
|
+
const prop = props[propsIdx]
|
|
159
160
|
const valueType = keyMap[prop]
|
|
160
161
|
const dashProp = hump2dash(prop)
|
|
161
|
-
// 校验 value 类型
|
|
162
|
-
verifyValues({ prop, value: values[idx], valueType })
|
|
163
162
|
const value = values[idx]
|
|
164
163
|
if (isIllegalValue({ prop: dashProp, value })) {
|
|
165
|
-
//
|
|
164
|
+
// 过滤 rn prop 不支持 value
|
|
166
165
|
unsupportedValueError({ prop: dashProp, value })
|
|
166
|
+
idx += 1
|
|
167
|
+
propsIdx += 1
|
|
168
|
+
} else if (!verifyValues({ prop, value, valueType })) {
|
|
169
|
+
// 校验 value 类型,类型不符则匹配下一个value
|
|
170
|
+
idx += 1
|
|
167
171
|
} else if (prop.includes('.')) {
|
|
168
172
|
// 多个属性值的prop
|
|
169
173
|
const [main, sub] = prop.split('.')
|
|
@@ -178,14 +182,17 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
178
182
|
}
|
|
179
183
|
})
|
|
180
184
|
}
|
|
185
|
+
idx += 1
|
|
186
|
+
propsIdx += 1
|
|
181
187
|
} else {
|
|
182
188
|
// 单个值的属性
|
|
183
189
|
cssMap.push({
|
|
184
190
|
prop,
|
|
185
191
|
value
|
|
186
192
|
})
|
|
193
|
+
idx += 1
|
|
194
|
+
propsIdx += 1
|
|
187
195
|
}
|
|
188
|
-
idx += 1
|
|
189
196
|
}
|
|
190
197
|
return cssMap
|
|
191
198
|
}
|
|
@@ -355,6 +362,69 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
355
362
|
}
|
|
356
363
|
}
|
|
357
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
|
+
|
|
358
428
|
const spec = {
|
|
359
429
|
supportedModes: ['ios', 'android'],
|
|
360
430
|
rules: [
|
|
@@ -417,6 +487,11 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
417
487
|
ios: formatLineHeight,
|
|
418
488
|
android: formatLineHeight
|
|
419
489
|
},
|
|
490
|
+
{
|
|
491
|
+
test: 'transform',
|
|
492
|
+
ios: formatTransform,
|
|
493
|
+
android: formatTransform
|
|
494
|
+
},
|
|
420
495
|
// 值类型校验放到最后
|
|
421
496
|
{ // color 颜色值校验 color xx-color 等
|
|
422
497
|
test: /^(color|(.+-color))$/,
|
|
@@ -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,
|
|
@@ -47,7 +47,16 @@ function getClassMap ({ content, filename, mode, srcMode, warn, error }) {
|
|
|
47
47
|
prop = dash2hump(item.prop)
|
|
48
48
|
value = item.value
|
|
49
49
|
if (Array.isArray(value)) {
|
|
50
|
-
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
|
+
})
|
|
51
60
|
} else if (typeof value === 'object') {
|
|
52
61
|
for (const key in value) {
|
|
53
62
|
value[key] = formatValue(value[key])
|
|
@@ -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 = {
|
|
@@ -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 = {
|
|
@@ -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
|
|
|
@@ -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) {
|
|
@@ -2590,7 +2604,7 @@ function processElement (el, root, options, meta) {
|
|
|
2590
2604
|
processIf(el)
|
|
2591
2605
|
processFor(el)
|
|
2592
2606
|
processRefReact(el, meta)
|
|
2593
|
-
processStyleReact(el)
|
|
2607
|
+
processStyleReact(el, options)
|
|
2594
2608
|
processEventReact(el)
|
|
2595
2609
|
processComponentIs(el, options)
|
|
2596
2610
|
processSlotReact(el)
|
|
@@ -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"
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"engines": {
|
|
91
91
|
"node": ">=14.14.0"
|
|
92
92
|
},
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "aa001c11cc7b21772fc6f9f5bcdd13118fc6d67c"
|
|
94
94
|
}
|