@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.
- package/lib/config.js +1 -3
- package/lib/platform/style/wx/index.js +374 -239
- package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
- package/lib/platform/template/wx/component-config/checkbox.js +8 -0
- package/lib/platform/template/wx/component-config/cover-image.js +15 -0
- package/lib/platform/template/wx/component-config/cover-view.js +9 -0
- package/lib/platform/template/wx/component-config/form.js +13 -1
- package/lib/platform/template/wx/component-config/icon.js +8 -0
- package/lib/platform/template/wx/component-config/index.js +5 -1
- package/lib/platform/template/wx/component-config/label.js +15 -0
- package/lib/platform/template/wx/component-config/movable-area.js +18 -1
- package/lib/platform/template/wx/component-config/movable-view.js +18 -1
- package/lib/platform/template/wx/component-config/navigator.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view.js +18 -2
- package/lib/platform/template/wx/component-config/picker.js +14 -1
- package/lib/platform/template/wx/component-config/radio-group.js +8 -0
- package/lib/platform/template/wx/component-config/radio.js +8 -0
- package/lib/platform/template/wx/component-config/root-portal.js +15 -0
- package/lib/platform/template/wx/component-config/switch.js +8 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -3
- package/lib/react/processScript.js +7 -1
- package/lib/react/style-helper.js +10 -1
- package/lib/runtime/components/react/context.ts +38 -0
- package/lib/runtime/components/react/dist/context.js +7 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +24 -13
- package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
- package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
- package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
- package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
- package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
- package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
- package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
- package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
- package/lib/runtime/components/react/dist/types/common.js +1 -0
- package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
- package/lib/runtime/components/react/dist/utils.js +83 -15
- package/lib/runtime/components/react/getInnerListeners.ts +27 -15
- package/lib/runtime/components/react/mpx-button.tsx +87 -67
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
- package/lib/runtime/components/react/mpx-form.tsx +89 -0
- package/lib/runtime/components/react/mpx-icon.tsx +103 -0
- package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
- package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
- package/lib/runtime/components/react/mpx-input.tsx +54 -26
- package/lib/runtime/components/react/mpx-label.tsx +115 -0
- package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
- package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
- package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
- package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
- package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
- package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
- package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
- package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
- package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
- package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
- package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
- package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-radio.tsx +246 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
- package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
- package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
- package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
- package/lib/runtime/components/react/mpx-switch.tsx +127 -0
- package/lib/runtime/components/react/mpx-text.tsx +52 -68
- package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
- package/lib/runtime/components/react/mpx-view.tsx +374 -141
- package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
- package/lib/runtime/components/react/types/common.ts +12 -0
- package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
- package/lib/runtime/components/react/types/global.d.ts +4 -0
- package/lib/runtime/components/react/useNodesRef.ts +3 -8
- package/lib/runtime/components/react/utils.ts +94 -16
- package/lib/runtime/optionProcessor.js +19 -17
- package/lib/template-compiler/compiler.js +73 -44
- package/lib/template-compiler/gen-node-react.js +7 -7
- package/lib/utils/shallow-stringify.js +1 -1
- package/package.json +6 -3
|
@@ -2,23 +2,45 @@ const { hump2dash } = require('../../../utils/hump-dash')
|
|
|
2
2
|
|
|
3
3
|
module.exports = function getSpec ({ warn, error }) {
|
|
4
4
|
// React Native 双端都不支持的 CSS property
|
|
5
|
-
const unsupportedPropExp = /^(
|
|
5
|
+
const unsupportedPropExp = /^(white-space|text-overflow|animation|transition|font-variant-caps|font-variant-numeric|font-variant-east-asian|font-variant-alternates|font-variant-ligatures|background-position|caret-color)$/
|
|
6
6
|
const unsupportedPropMode = {
|
|
7
7
|
// React Native ios 不支持的 CSS property
|
|
8
8
|
ios: /^(vertical-align)$/,
|
|
9
9
|
// React Native android 不支持的 CSS property
|
|
10
10
|
android: /^(text-decoration-style|text-decoration-color|shadow-offset|shadow-opacity|shadow-radius)$/
|
|
11
11
|
}
|
|
12
|
+
// 不支持的属性提示
|
|
12
13
|
const unsupportedPropError = ({ prop, mode }) => {
|
|
13
14
|
error(`Property [${prop}] is not supported in React Native ${mode} environment!`)
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
+
// prop 校验
|
|
17
|
+
const verifyProps = ({ prop, value }, { mode }, isError = true) => {
|
|
18
|
+
prop = prop.trim()
|
|
19
|
+
const tips = isError ? error : warn
|
|
20
|
+
if (unsupportedPropExp.test(prop) || unsupportedPropMode[mode].test(prop)) {
|
|
21
|
+
tips(`Property [${prop}] is not supported in React Native ${mode} environment!`)
|
|
22
|
+
return false
|
|
23
|
+
}
|
|
24
|
+
return true
|
|
25
|
+
}
|
|
26
|
+
// 值类型
|
|
27
|
+
const ValueType = {
|
|
28
|
+
number: 'number',
|
|
29
|
+
color: 'color',
|
|
30
|
+
enum: 'enum'
|
|
31
|
+
}
|
|
16
32
|
// React 属性支持的枚举值
|
|
17
33
|
const SUPPORTED_PROP_VAL_ARR = {
|
|
34
|
+
'box-sizing': ['border-box'],
|
|
35
|
+
'backface-visibility': ['visible', 'hidden'],
|
|
18
36
|
overflow: ['visible', 'hidden', 'scroll'],
|
|
19
37
|
'border-style': ['solid', 'dotted', 'dashed'],
|
|
38
|
+
'object-fit': ['cover', 'contain', 'fill', 'scale-down'],
|
|
39
|
+
direction: ['inherit', 'ltr', 'rtl'],
|
|
20
40
|
display: ['flex', 'none'],
|
|
21
|
-
'
|
|
41
|
+
'flex-direction': ['row', 'row-reverse', 'column', 'column-reverse'],
|
|
42
|
+
'flex-wrap': ['wrap', 'nowrap', 'wrap-reverse'],
|
|
43
|
+
'pointer-events': ['auto', 'box-none', 'box-only', 'none'],
|
|
22
44
|
'vertical-align': ['auto', 'top', 'bottom', 'center'],
|
|
23
45
|
position: ['relative', 'absolute'],
|
|
24
46
|
'font-variant': ['small-caps', 'oldstyle-nums', 'lining-nums', 'tabular-nums', 'proportional-nums'],
|
|
@@ -26,144 +48,140 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
26
48
|
'font-style': ['normal', 'italic'],
|
|
27
49
|
'font-weight': ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'],
|
|
28
50
|
'text-decoration-line': ['none', 'underline', 'line-through', 'underline line-through'],
|
|
51
|
+
'text-decoration-style': ['solid', 'double', 'dotted', 'dashed'],
|
|
29
52
|
'text-transform': ['none', 'uppercase', 'lowercase', 'capitalize'],
|
|
30
53
|
'user-select': ['auto', 'text', 'none', 'contain', 'all'],
|
|
31
|
-
'align-content': ['flex-start', 'flex-end', 'center', 'stretch', 'space-between', 'space-around'],
|
|
54
|
+
'align-content': ['flex-start', 'flex-end', 'center', 'stretch', 'space-between', 'space-around', 'space-evenly'],
|
|
32
55
|
'align-items': ['flex-start', 'flex-end', 'center', 'stretch', 'baseline'],
|
|
33
56
|
'align-self': ['auto', 'flex-start', 'flex-end', 'center', 'stretch', 'baseline'],
|
|
34
|
-
'justify-content': ['flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'space-evenly'
|
|
35
|
-
'background-size': ['contain', 'cover', 'auto'],
|
|
36
|
-
'background-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
57
|
+
'justify-content': ['flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'space-evenly'],
|
|
58
|
+
'background-size': ['contain', 'cover', 'auto', ValueType.number],
|
|
59
|
+
'background-position': ['left', 'right', 'top', 'bottom', 'center', ValueType.number],
|
|
60
|
+
'background-repeat': ['no-repeat'],
|
|
61
|
+
width: ['auto', ValueType.number],
|
|
62
|
+
height: ['auto', ValueType.number],
|
|
63
|
+
'flex-basis': ['auto', ValueType.number],
|
|
64
|
+
margin: ['auto', ValueType.number],
|
|
65
|
+
'margin-top': ['auto', ValueType.number],
|
|
66
|
+
'margin-left': ['auto', ValueType.number],
|
|
67
|
+
'margin-bottom': ['auto', ValueType.number],
|
|
68
|
+
'margin-right': ['auto', ValueType.number],
|
|
69
|
+
'margin-horizontal': ['auto', ValueType.number],
|
|
70
|
+
'margin-vertical': ['auto', ValueType.number]
|
|
42
71
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return
|
|
72
|
+
// 获取值类型
|
|
73
|
+
const getValueType = (prop) => {
|
|
74
|
+
const propValueTypeRules = [
|
|
75
|
+
// 重要!!优先判断是不是枚举类型
|
|
76
|
+
[ValueType.enum, new RegExp('^(' + Object.keys(SUPPORTED_PROP_VAL_ARR).join('|') + ')$')],
|
|
77
|
+
[ValueType.number, /^((opacity|flex-grow|flex-shrink|gap|left|right|top|bottom)|(.+-(width|height|left|right|top|bottom|radius|spacing|size|gap|index|offset|opacity)))$/],
|
|
78
|
+
[ValueType.color, /^(color|(.+-color))$/]
|
|
79
|
+
]
|
|
80
|
+
for (const rule of propValueTypeRules) {
|
|
81
|
+
if (rule[1].test(prop)) return rule[0]
|
|
53
82
|
}
|
|
54
83
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const verifyValues = ({ prop, value, valueType }) => {
|
|
68
|
-
// 校验 value 枚举 是否支持
|
|
69
|
-
switch (valueType) {
|
|
70
|
-
case ValueType.color: {
|
|
71
|
-
const isNumber = numberRegExp.test(value)
|
|
72
|
-
const isUnsupporttedColor = colorRegExp.test(value)
|
|
73
|
-
isNumber && warn(`Property [${prop}] receives a valid color as value, not a number.`)
|
|
74
|
-
isUnsupporttedColor && warn('React Native\'s supported color format does not contain [lab,lch,oklab,oklch,color-mix,color,hwb,lch,light-dark].')
|
|
75
|
-
return !isNumber && !isUnsupporttedColor
|
|
76
|
-
}
|
|
84
|
+
// 属性值校验
|
|
85
|
+
const verifyValues = ({ prop, value }, isError = true) => {
|
|
86
|
+
prop = prop.trim()
|
|
87
|
+
value = value.trim()
|
|
88
|
+
const type = getValueType(prop)
|
|
89
|
+
const namedColor = ['transparent', 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen']
|
|
90
|
+
const valueExp = {
|
|
91
|
+
number: /^(-?\d+(\.\d+)?)(rpx|px|%)?$/,
|
|
92
|
+
color: new RegExp(('^(' + namedColor.join('|') + ')$') + '|(^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$)|^(rgb|rgba|hsl|hsla|hwb)\\(.+\\)$')
|
|
93
|
+
}
|
|
94
|
+
const tips = isError ? error : warn
|
|
95
|
+
switch (type) {
|
|
77
96
|
case ValueType.number: {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
97
|
+
if (!valueExp.number.test(value)) {
|
|
98
|
+
tips(`The value type of [${prop}] only supports [Number] in React Native environment, eg 10rpx, 10px, 10%, 10, please check again`)
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
return true
|
|
81
102
|
}
|
|
82
|
-
|
|
103
|
+
case ValueType.color: {
|
|
104
|
+
if (!valueExp.color.test(value)) {
|
|
105
|
+
tips(`The value type of [${prop}] only supports [Color] in React Native environment, eg #000, rgba(0,0,0,0), please check again`)
|
|
106
|
+
return false
|
|
107
|
+
}
|
|
83
108
|
return true
|
|
109
|
+
}
|
|
110
|
+
case ValueType.enum: {
|
|
111
|
+
const isIn = SUPPORTED_PROP_VAL_ARR[prop].includes(value)
|
|
112
|
+
const isType = Object.keys(valueExp).some(item => valueExp[item].test(value) && SUPPORTED_PROP_VAL_ARR[prop].includes(ValueType[item]))
|
|
113
|
+
if (!isIn && !isType) {
|
|
114
|
+
tips(`Property [${prop}] only support value [${SUPPORTED_PROP_VAL_ARR[prop]?.join(',')}] in React Native environment, the value [${value}] does not support!`)
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
return true
|
|
118
|
+
}
|
|
84
119
|
}
|
|
120
|
+
return true
|
|
85
121
|
}
|
|
86
|
-
//
|
|
87
|
-
const
|
|
88
|
-
verifyValues({ prop, value,
|
|
122
|
+
// prop & value 校验:过滤的不合法的属性和属性值
|
|
123
|
+
const verification = ({ prop, value }, { mode }) => {
|
|
124
|
+
return verifyProps({ prop, value }, { mode }) && verifyValues({ prop, value }) && ({ prop, value })
|
|
89
125
|
}
|
|
90
126
|
|
|
91
127
|
// 简写转换规则
|
|
92
128
|
const AbbreviationMap = {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
'border-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
},
|
|
124
|
-
'box-shadow': { // 仅支持 offset-x | offset-y | blur-radius | color 排序
|
|
125
|
-
'shadowOffset.width': ValueType.number,
|
|
126
|
-
'shadowOffset.height': ValueType.number,
|
|
127
|
-
shadowRadius: ValueType.number,
|
|
128
|
-
shadowColor: ValueType.color
|
|
129
|
-
},
|
|
130
|
-
'text-decoration': { // 仅支持 text-decoration-line text-decoration-style text-decoration-color 这种格式
|
|
131
|
-
textDecorationLine: ValueType.default,
|
|
132
|
-
textDecorationStyle: ValueType.default,
|
|
133
|
-
textDecorationColor: ValueType.color
|
|
134
|
-
},
|
|
135
|
-
flex: { // /* Three values: flex-grow | flex-shrink | flex-basis */
|
|
136
|
-
flexGrow: ValueType.number,
|
|
137
|
-
flexShrink: ValueType.number,
|
|
138
|
-
flexBasis: ValueType.number
|
|
139
|
-
},
|
|
140
|
-
'flex-flow': { // 仅支持 flex-flow: <'flex-direction'> or flex-flow: <'flex-direction'> and <'flex-wrap'>
|
|
141
|
-
flexDirection: ValueType.default,
|
|
142
|
-
flexWrap: ValueType.default
|
|
143
|
-
},
|
|
144
|
-
'border-radius': {
|
|
145
|
-
borderTopLeftRadius: ValueType.number,
|
|
146
|
-
borderTopRightRadius: ValueType.number,
|
|
147
|
-
borderBottomRightRadius: ValueType.number,
|
|
148
|
-
borderBottomLeftRadius: ValueType.number
|
|
149
|
-
}
|
|
129
|
+
// 仅支持 offset-x | offset-y | blur-radius | color 排序
|
|
130
|
+
'text-shadow': ['textShadowOffset.width', 'textShadowOffset.height', 'textShadowRadius', 'textShadowColor'],
|
|
131
|
+
// 仅支持 width | style | color 这种排序
|
|
132
|
+
border: ['borderWidth', 'borderStyle', 'borderColor'],
|
|
133
|
+
// 仅支持 width | style | color 这种排序
|
|
134
|
+
'border-left': ['borderLeftWidth', 'borderLeftStyle', 'borderLeftColor'],
|
|
135
|
+
// 仅支持 width | style | color 这种排序
|
|
136
|
+
'border-right': ['borderRightWidth', 'borderRightStyle', 'borderRightColor'],
|
|
137
|
+
// 仅支持 width | style | color 这种排序
|
|
138
|
+
'border-top': ['borderTopWidth', 'borderTopStyle', 'borderTopColor'],
|
|
139
|
+
// 仅支持 width | style | color 这种排序
|
|
140
|
+
'border-bottom': ['borderBottomWidth', 'borderBottomStyle', 'borderBottomColor'],
|
|
141
|
+
// 仅支持 offset-x | offset-y | blur-radius | color 排序
|
|
142
|
+
'box-shadow': ['shadowOffset.width', 'shadowOffset.height', 'shadowRadius', 'shadowColor'],
|
|
143
|
+
// 仅支持 text-decoration-line text-decoration-style text-decoration-color 这种格式
|
|
144
|
+
'text-decoration': ['textDecorationLine', 'textDecorationStyle', 'textDecorationColor'],
|
|
145
|
+
// flex-grow | flex-shrink | flex-basis
|
|
146
|
+
flex: ['flexGrow', 'flexShrink', 'flexBasis'],
|
|
147
|
+
// flex-flow: <'flex-direction'> or flex-flow: <'flex-direction'> and <'flex-wrap'>
|
|
148
|
+
'flex-flow': ['flexDirection', 'flexWrap'],
|
|
149
|
+
'border-radius': ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius']
|
|
150
150
|
}
|
|
151
|
-
const formatAbbreviation = ({ value,
|
|
151
|
+
const formatAbbreviation = ({ prop, value }, { mode }) => {
|
|
152
|
+
const original = `${prop}:${value}`
|
|
153
|
+
const props = AbbreviationMap[prop]
|
|
152
154
|
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
153
155
|
const cssMap = []
|
|
154
|
-
const props = Object.getOwnPropertyNames(keyMap)
|
|
155
156
|
let idx = 0
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
let propsIdx = 0
|
|
158
|
+
const diff = values.length - props.length
|
|
159
|
+
while (idx < values.length) {
|
|
160
|
+
const prop = props[propsIdx]
|
|
161
|
+
if (!prop) {
|
|
162
|
+
error(`the value of [${original}] has not enough props to assign in React Native environment, please check again`)
|
|
163
|
+
break
|
|
164
|
+
}
|
|
163
165
|
const value = values[idx]
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
const newProp = hump2dash(prop.replace(/\..+/, ''))
|
|
167
|
+
if (!verifyProps({ prop: newProp, value }, { mode }, diff === 0)) {
|
|
168
|
+
// 有 ios or android 不支持的 prop,跳过 prop
|
|
169
|
+
if (diff === 0) {
|
|
170
|
+
propsIdx++
|
|
171
|
+
idx++
|
|
172
|
+
} else {
|
|
173
|
+
propsIdx++
|
|
174
|
+
}
|
|
175
|
+
} else if (!verifyValues({ prop: newProp, value }, diff === 0)) {
|
|
176
|
+
// 值不合法 跳过 value
|
|
177
|
+
if (diff === 0) {
|
|
178
|
+
propsIdx++
|
|
179
|
+
idx++
|
|
180
|
+
} else if (diff < 0) {
|
|
181
|
+
propsIdx++
|
|
182
|
+
} else {
|
|
183
|
+
idx++
|
|
184
|
+
}
|
|
167
185
|
} else if (prop.includes('.')) {
|
|
168
186
|
// 多个属性值的prop
|
|
169
187
|
const [main, sub] = prop.split('.')
|
|
@@ -178,41 +196,24 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
178
196
|
}
|
|
179
197
|
})
|
|
180
198
|
}
|
|
199
|
+
idx += 1
|
|
200
|
+
propsIdx += 1
|
|
181
201
|
} else {
|
|
182
202
|
// 单个值的属性
|
|
183
203
|
cssMap.push({
|
|
184
204
|
prop,
|
|
185
205
|
value
|
|
186
206
|
})
|
|
207
|
+
idx += 1
|
|
208
|
+
propsIdx += 1
|
|
187
209
|
}
|
|
188
|
-
idx += 1
|
|
189
210
|
}
|
|
190
211
|
return cssMap
|
|
191
212
|
}
|
|
192
|
-
const getAbbreviation = ({ prop, value }) => {
|
|
193
|
-
const keyMap = AbbreviationMap[prop]
|
|
194
|
-
return formatAbbreviation({ prop, value, keyMap })
|
|
195
|
-
}
|
|
196
|
-
// 简写过滤安卓不支持的类型
|
|
197
|
-
const getAbbreviationAndroid = ({ prop, value }, { mode }) => {
|
|
198
|
-
const cssMap = getAbbreviation({ prop, value })
|
|
199
|
-
// android 不支持的 shadowOffset shadowOpacity shadowRadius textDecorationStyle 和 textDecorationStyle
|
|
200
|
-
return cssMap.filter(({ prop }) => { // 不支持的 prop 提示 & 过滤不支持的 prop
|
|
201
|
-
const dashProp = hump2dash(prop)
|
|
202
|
-
if (unsupportedPropMode.android.test(dashProp)) {
|
|
203
|
-
unsupportedPropError({ prop: dashProp, mode })
|
|
204
|
-
return false
|
|
205
|
-
}
|
|
206
|
-
return true
|
|
207
|
-
})
|
|
208
|
-
}
|
|
209
213
|
|
|
214
|
+
// margin padding
|
|
210
215
|
const formatMargins = ({ prop, value }) => {
|
|
211
216
|
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
212
|
-
// validate
|
|
213
|
-
for (let i = 0; i < values.length; i++) {
|
|
214
|
-
verifyValues({ prop, value: values[i], valueType: ValueType.number })
|
|
215
|
-
}
|
|
216
217
|
// format
|
|
217
218
|
let suffix = []
|
|
218
219
|
switch (values.length) {
|
|
@@ -228,55 +229,38 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
228
229
|
break
|
|
229
230
|
}
|
|
230
231
|
return values.map((value, index) => {
|
|
232
|
+
const newProp = `${prop}${suffix[index] || ''}`
|
|
233
|
+
// validate
|
|
234
|
+
verifyValues({ prop: hump2dash(newProp), value }, false)
|
|
231
235
|
return {
|
|
232
|
-
prop:
|
|
236
|
+
prop: newProp,
|
|
233
237
|
value: value
|
|
234
238
|
}
|
|
235
239
|
})
|
|
236
240
|
}
|
|
237
241
|
|
|
242
|
+
// line-height
|
|
238
243
|
const formatLineHeight = ({ prop, value }) => {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return {
|
|
244
|
+
return verifyValues({ prop, value }) && ({
|
|
242
245
|
prop,
|
|
243
246
|
value: /^\s*-?\d+(\.\d+)?\s*$/.test(value) ? `${Math.round(value * 100)}%` : value
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const getFontVariant = ({ prop, value }) => {
|
|
248
|
-
if (/^(font-variant-caps|font-variant-numeric|font-variant-east-asian|font-variant-alternates|font-variant-ligatures)$/.test(prop)) {
|
|
249
|
-
error(`Property [${prop}] is not supported in React Native environment, please replace [font-variant]!`)
|
|
250
|
-
}
|
|
251
|
-
prop = 'font-variant'
|
|
252
|
-
// 校验枚举值
|
|
253
|
-
if (isIllegalValue({ prop, value })) {
|
|
254
|
-
unsupportedValueError({ prop, value })
|
|
255
|
-
return false
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
prop,
|
|
259
|
-
value
|
|
260
|
-
}
|
|
247
|
+
})
|
|
261
248
|
}
|
|
262
249
|
|
|
263
|
-
// background
|
|
250
|
+
// background 相关属性的转换 Todo
|
|
251
|
+
// 仅支持以下属性,不支持其他背景相关的属性
|
|
252
|
+
// /^((?!(-color)).)*background((?!(-color)).)*$/ 包含background且不包含background-color
|
|
264
253
|
const checkBackgroundImage = ({ prop, value }, { mode }) => {
|
|
265
254
|
const bgPropMap = {
|
|
266
255
|
image: 'background-image',
|
|
267
256
|
color: 'background-color',
|
|
268
257
|
size: 'background-size',
|
|
269
258
|
repeat: 'background-repeat',
|
|
270
|
-
|
|
259
|
+
position: 'background-position',
|
|
271
260
|
all: 'background'
|
|
272
261
|
}
|
|
273
262
|
const urlExp = /url\(["']?(.*?)["']?\)/
|
|
274
263
|
switch (prop) {
|
|
275
|
-
case bgPropMap.color: {
|
|
276
|
-
// background-color 背景色校验一下颜色值
|
|
277
|
-
verifyValues({ prop, value, valueType: ValueType.color })
|
|
278
|
-
return { prop, value }
|
|
279
|
-
}
|
|
280
264
|
case bgPropMap.image: {
|
|
281
265
|
// background-image 仅支持背景图
|
|
282
266
|
const imgUrl = value.match(urlExp)?.[0]
|
|
@@ -301,23 +285,26 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
301
285
|
}
|
|
302
286
|
const values = []
|
|
303
287
|
value.trim().split(/\s(?![^()]*\))/).forEach(item => {
|
|
304
|
-
if (
|
|
288
|
+
if (verifyValues({ prop, value: item })) {
|
|
305
289
|
// 支持 number 值 / container cover auto 枚举
|
|
306
290
|
values.push(item)
|
|
307
|
-
} else {
|
|
308
|
-
error(`background size value[${value}] does not support in React Native ${mode} environment!`)
|
|
309
291
|
}
|
|
310
292
|
})
|
|
311
293
|
// value 无有效值时返回false
|
|
312
294
|
return values.length === 0 ? false : { prop, value: values }
|
|
313
295
|
}
|
|
314
|
-
case bgPropMap.
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
296
|
+
case bgPropMap.position: {
|
|
297
|
+
const values = []
|
|
298
|
+
value.trim().split(/\s(?![^()]*\))/).forEach(item => {
|
|
299
|
+
if (verifyValues({ prop, value: item })) {
|
|
300
|
+
// 支持 number 值 / 枚举, center与50%等价
|
|
301
|
+
values.push(item === 'center' ? '50%' : item)
|
|
302
|
+
} else {
|
|
303
|
+
error(`background position value[${value}] does not support in React Native ${mode} environment!`)
|
|
304
|
+
}
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
return { prop, value: values }
|
|
321
308
|
}
|
|
322
309
|
case bgPropMap.all: {
|
|
323
310
|
// background: 仅支持 background-image & background-color & background-repeat
|
|
@@ -329,14 +316,11 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
329
316
|
error(`<linear-gradient()> is not supported in React Native ${mode} environment!`)
|
|
330
317
|
} else if (url) {
|
|
331
318
|
bgMap.push({ prop: bgPropMap.image, value: url })
|
|
332
|
-
} else if (
|
|
319
|
+
} else if (verifyValues({ prop: bgPropMap.color, value: item }, false)) {
|
|
333
320
|
bgMap.push({ prop: bgPropMap.color, value: item })
|
|
334
|
-
} else if (
|
|
321
|
+
} else if (verifyValues({ prop: bgPropMap.repeat, value: item }, false)) {
|
|
335
322
|
bgMap.push({ prop: bgPropMap.repeat, value: item })
|
|
336
323
|
}
|
|
337
|
-
// else if (SUPPORTED_PROP_VAL_ARR[bgPropMap.size].includes(item)) {
|
|
338
|
-
// bgMap.push({ prop: bgPropMap.size, value: item })
|
|
339
|
-
// }
|
|
340
324
|
})
|
|
341
325
|
return bgMap.length ? bgMap : false
|
|
342
326
|
}
|
|
@@ -345,57 +329,194 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
345
329
|
return false
|
|
346
330
|
}
|
|
347
331
|
|
|
348
|
-
|
|
332
|
+
// border-radius 缩写转换
|
|
333
|
+
const getBorderRadius = ({ prop, value }, { mode }) => {
|
|
349
334
|
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
350
335
|
if (values.length === 1) {
|
|
351
|
-
verifyValues({ prop, value,
|
|
336
|
+
verifyValues({ prop, value }, false)
|
|
337
|
+
return { prop, value }
|
|
338
|
+
} else {
|
|
339
|
+
if (values.length === 2) {
|
|
340
|
+
values.push(...values)
|
|
341
|
+
} else if (values.length === 3) {
|
|
342
|
+
values.push(values[1])
|
|
343
|
+
}
|
|
344
|
+
return formatAbbreviation({ prop, value: values.join(' ') }, { mode })
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// transform 转换
|
|
349
|
+
const formatTransform = ({ prop, value }, { mode }) => {
|
|
350
|
+
if (Array.isArray(value)) return { prop, value }
|
|
351
|
+
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
352
|
+
const transform = []
|
|
353
|
+
values.forEach(item => {
|
|
354
|
+
const match = item.match(/([/\w]+)\(([^)]+)\)/)
|
|
355
|
+
if (match && match.length >= 3) {
|
|
356
|
+
let key = match[1]
|
|
357
|
+
const val = match[2]
|
|
358
|
+
switch (key) {
|
|
359
|
+
case 'translateX':
|
|
360
|
+
case 'translateY':
|
|
361
|
+
case 'scaleX':
|
|
362
|
+
case 'scaleY':
|
|
363
|
+
case 'rotateX':
|
|
364
|
+
case 'rotateY':
|
|
365
|
+
case 'rotateZ':
|
|
366
|
+
case 'rotate':
|
|
367
|
+
case 'skewX':
|
|
368
|
+
case 'skewY':
|
|
369
|
+
case 'perspective':
|
|
370
|
+
// 单个值处理
|
|
371
|
+
transform.push({ [key]: val })
|
|
372
|
+
break
|
|
373
|
+
case 'matrix':
|
|
374
|
+
case 'matrix3d':
|
|
375
|
+
transform.push({ [key]: val.split(',').map(val => +val) })
|
|
376
|
+
break
|
|
377
|
+
case 'translate':
|
|
378
|
+
case 'scale':
|
|
379
|
+
case 'skew':
|
|
380
|
+
case 'rotate3d': // x y z angle
|
|
381
|
+
case 'translate3d': // x y 支持 z不支持
|
|
382
|
+
case 'scale3d': // x y 支持 z不支持
|
|
383
|
+
{
|
|
384
|
+
// 2 个以上的值处理
|
|
385
|
+
key = key.replace('3d', '')
|
|
386
|
+
const vals = val.split(',').splice(0, key === 'rotate' ? 4 : 3)
|
|
387
|
+
const xyz = ['X', 'Y', 'Z']
|
|
388
|
+
transform.push(...vals.map((v, index) => {
|
|
389
|
+
if (key !== 'rotate' && index > 1) {
|
|
390
|
+
unsupportedPropError({ prop: `${key}Z`, mode })
|
|
391
|
+
}
|
|
392
|
+
return { [`${key}${xyz[index] || ''}`]: v.trim() }
|
|
393
|
+
}))
|
|
394
|
+
break
|
|
395
|
+
}
|
|
396
|
+
case 'translateZ':
|
|
397
|
+
case 'scaleZ':
|
|
398
|
+
default:
|
|
399
|
+
// 不支持的属性处理
|
|
400
|
+
unsupportedPropError({ prop: key, mode })
|
|
401
|
+
break
|
|
402
|
+
}
|
|
403
|
+
} else {
|
|
404
|
+
error(`Property [${prop}] is invalid, please check the value!`)
|
|
405
|
+
}
|
|
406
|
+
})
|
|
407
|
+
return {
|
|
408
|
+
prop,
|
|
409
|
+
value: transform
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const isNumber = (value) => {
|
|
414
|
+
return !isNaN(+value)
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const getIntegersFlex = ({ prop, value }) => {
|
|
418
|
+
if (isNumber(value) && value >= 0) {
|
|
352
419
|
return { prop, value }
|
|
353
420
|
} else {
|
|
354
|
-
|
|
421
|
+
error(`The value of ${prop} accepts any floating point value >= 0.`)
|
|
422
|
+
return false
|
|
355
423
|
}
|
|
356
424
|
}
|
|
357
425
|
|
|
358
|
-
const
|
|
426
|
+
const formatFlex = ({ prop, value }, { mode }) => {
|
|
427
|
+
let values = value.trim().split(/\s(?![^()]*\))/)
|
|
428
|
+
if (values.length > 3) {
|
|
429
|
+
error('The value of prop [flex] supports up to three values')
|
|
430
|
+
values = values.splice(0, 3)
|
|
431
|
+
}
|
|
432
|
+
const cssMap = []
|
|
433
|
+
const lastOne = values[values.length - 1]
|
|
434
|
+
const isAuto = lastOne === 'auto'
|
|
435
|
+
// 枚举值 none initial
|
|
436
|
+
if (values.includes('initial') || values.includes('none')) {
|
|
437
|
+
// css flex: initial ===> flex: 0 1 ===> rn flex 0 1
|
|
438
|
+
// css flex: none ===> css flex: 0 0 ===> rn flex 0 0
|
|
439
|
+
if (values.length === 1) {
|
|
440
|
+
// 添加 basis 和 shrink
|
|
441
|
+
// value=initial 则 flexShrink=1,其他场景都是0
|
|
442
|
+
cssMap.push(...[{ prop: 'flexGrow', value: 0 }, { prop: 'flexShrink', value: +(values[0] === 'initial') }])
|
|
443
|
+
} else {
|
|
444
|
+
error('When setting the value of flex to none or initial, only one value is supported.')
|
|
445
|
+
}
|
|
446
|
+
return cssMap
|
|
447
|
+
}
|
|
448
|
+
// 最后一个值是flexBasis 的有效值(auto或者有单位百分比、px等)
|
|
449
|
+
// flex 0 1 auto flex auto flex 1 auto flex 1 30px flex 1 10% flex 1 1 auto
|
|
450
|
+
if (!isNumber(lastOne)) {
|
|
451
|
+
// 添加 grow 和 shrink
|
|
452
|
+
// 在设置 flex basis 有效值的场景下,如果没有设置 grow 和 shrink,则默认为1
|
|
453
|
+
// 单值 flex: 1 1 <flex-basis>
|
|
454
|
+
// 双值 flex: <flex-grow> 1 <flex-basis>
|
|
455
|
+
// 三值 flex: <flex-grow> <flex-shrink> <flex-basis>
|
|
456
|
+
for (let i = 0; i < 2; i++) {
|
|
457
|
+
const item = getIntegersFlex({ prop: AbbreviationMap[prop][i], value: isNumber(values[i]) ? values[i] : 1 })
|
|
458
|
+
item && cssMap.push(item)
|
|
459
|
+
}
|
|
460
|
+
if (!isAuto) {
|
|
461
|
+
// 有单位(百分比、px等) 的 value 赋值 flexBasis,auto 不处理
|
|
462
|
+
cssMap.push({
|
|
463
|
+
prop: 'flexBasis',
|
|
464
|
+
value: lastOne
|
|
465
|
+
})
|
|
466
|
+
}
|
|
467
|
+
return cssMap
|
|
468
|
+
}
|
|
469
|
+
// 纯数值:value 按flex-grow flex-shrink flex-basis 顺序赋值
|
|
470
|
+
// 兜底 shrink & basis
|
|
471
|
+
if (values.length === 1) {
|
|
472
|
+
values.push(...[1, 0])
|
|
473
|
+
} else if (values.length === 2) {
|
|
474
|
+
values.push(0)
|
|
475
|
+
}
|
|
476
|
+
// 循环赋值
|
|
477
|
+
for (let i = 0; i < values.length; i++) {
|
|
478
|
+
const item = getIntegersFlex({ prop: AbbreviationMap[prop][i], value: values[i] })
|
|
479
|
+
item && cssMap.push(item)
|
|
480
|
+
}
|
|
481
|
+
return cssMap
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const formatFontFamily = ({ prop, value }) => {
|
|
485
|
+
// 去掉引号 取逗号分隔后的第一个
|
|
486
|
+
const newVal = value.replace(/"|'/g, '').trim()
|
|
487
|
+
const values = newVal.split(',').filter(i => i)
|
|
488
|
+
if (!newVal || !values.length) {
|
|
489
|
+
error(`The value of prop [${prop}: ${value}] is invaild, please check again`)
|
|
490
|
+
return false
|
|
491
|
+
} else if (values.length > 1) {
|
|
492
|
+
warn(`The value of prop [${prop}] only supports one, and the first one is used by default`)
|
|
493
|
+
}
|
|
494
|
+
return { prop, value: values[0].trim() }
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
const formatBoxShadow = ({ prop, value }, { mode }) => {
|
|
498
|
+
value = value.trim()
|
|
499
|
+
if (value === 'none') {
|
|
500
|
+
return false
|
|
501
|
+
}
|
|
502
|
+
const cssMap = formatAbbreviation({ prop, value }, { mode })
|
|
503
|
+
if (mode === 'android') return cssMap
|
|
504
|
+
// ios 阴影需要额外设置 shadowOpacity=1
|
|
505
|
+
cssMap.push({
|
|
506
|
+
prop: 'shadowOpacity',
|
|
507
|
+
value: 1
|
|
508
|
+
})
|
|
509
|
+
return cssMap
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
return {
|
|
359
513
|
supportedModes: ['ios', 'android'],
|
|
360
514
|
rules: [
|
|
361
515
|
{ // 背景相关属性的处理
|
|
362
|
-
test: /^(background|background-image|background-
|
|
516
|
+
test: /^(background|background-image|background-size|background-position)$/,
|
|
363
517
|
ios: checkBackgroundImage,
|
|
364
518
|
android: checkBackgroundImage
|
|
365
519
|
},
|
|
366
|
-
{ // RN 不支持的 CSS property
|
|
367
|
-
test: unsupportedPropExp,
|
|
368
|
-
ios: delRule,
|
|
369
|
-
android: delRule
|
|
370
|
-
},
|
|
371
|
-
{ // React Native android 不支持的 CSS property
|
|
372
|
-
test: unsupportedPropMode.android,
|
|
373
|
-
android: delRule
|
|
374
|
-
},
|
|
375
|
-
{ // React Native ios 不支持的 CSS property
|
|
376
|
-
test: unsupportedPropMode.ios,
|
|
377
|
-
ios: delRule
|
|
378
|
-
},
|
|
379
|
-
{ // RN 支持的 CSS property value
|
|
380
|
-
test: propValExp,
|
|
381
|
-
ios: delRule,
|
|
382
|
-
android: delRule
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
test: 'box-shadow',
|
|
386
|
-
ios: getAbbreviation,
|
|
387
|
-
android: getAbbreviationAndroid
|
|
388
|
-
},
|
|
389
|
-
{
|
|
390
|
-
test: 'text-decoration',
|
|
391
|
-
ios: getAbbreviation,
|
|
392
|
-
android: getAbbreviationAndroid
|
|
393
|
-
},
|
|
394
|
-
{
|
|
395
|
-
test: /^(font-variant|font-variant-caps|font-variant-numeric|font-variant-east-asian|font-variant-alternates|font-variant-ligatures)$/,
|
|
396
|
-
ios: getFontVariant,
|
|
397
|
-
android: getFontVariant
|
|
398
|
-
},
|
|
399
520
|
{
|
|
400
521
|
test: 'border-radius',
|
|
401
522
|
ios: getBorderRadius,
|
|
@@ -406,29 +527,43 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
406
527
|
ios: formatMargins,
|
|
407
528
|
android: formatMargins
|
|
408
529
|
},
|
|
409
|
-
// 通用的简写格式匹配
|
|
410
|
-
{
|
|
411
|
-
test: new RegExp('^(' + Object.keys(AbbreviationMap).join('|') + ')$'),
|
|
412
|
-
ios: getAbbreviation,
|
|
413
|
-
android: getAbbreviation
|
|
414
|
-
},
|
|
415
530
|
{ // line-height 换算
|
|
416
531
|
test: 'line-height',
|
|
417
532
|
ios: formatLineHeight,
|
|
418
533
|
android: formatLineHeight
|
|
419
534
|
},
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
535
|
+
{
|
|
536
|
+
test: 'transform',
|
|
537
|
+
ios: formatTransform,
|
|
538
|
+
android: formatTransform
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
test: 'flex',
|
|
542
|
+
ios: formatFlex,
|
|
543
|
+
android: formatFlex
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
test: 'font-family',
|
|
547
|
+
ios: formatFontFamily,
|
|
548
|
+
android: formatFontFamily
|
|
425
549
|
},
|
|
426
|
-
{
|
|
427
|
-
test:
|
|
428
|
-
ios:
|
|
429
|
-
android:
|
|
550
|
+
{
|
|
551
|
+
test: 'box-shadow',
|
|
552
|
+
ios: formatBoxShadow,
|
|
553
|
+
android: formatBoxShadow
|
|
554
|
+
},
|
|
555
|
+
// 通用的简写格式匹配
|
|
556
|
+
{
|
|
557
|
+
test: new RegExp('^(' + Object.keys(AbbreviationMap).join('|') + ')$'),
|
|
558
|
+
ios: formatAbbreviation,
|
|
559
|
+
android: formatAbbreviation
|
|
560
|
+
},
|
|
561
|
+
// 属性&属性值校验
|
|
562
|
+
{
|
|
563
|
+
test: () => true,
|
|
564
|
+
ios: verification,
|
|
565
|
+
android: verification
|
|
430
566
|
}
|
|
431
567
|
]
|
|
432
568
|
}
|
|
433
|
-
return spec
|
|
434
569
|
}
|