@mpxjs/webpack-plugin 2.9.59 → 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/platform/style/wx/index.js +314 -254
- 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 +2 -0
- 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 +22 -11
- 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 +82 -14
- package/lib/runtime/components/react/getInnerListeners.ts +25 -13
- 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 +373 -140
- 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 +93 -15
- package/lib/runtime/optionProcessor.js +19 -17
- package/lib/template-compiler/compiler.js +56 -41
- package/lib/template-compiler/gen-node-react.js +7 -7
- 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,148 +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-
|
|
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]
|
|
37
71
|
}
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return false
|
|
49
|
-
}
|
|
50
|
-
if (isIllegalValue({ prop, value })) {
|
|
51
|
-
unsupportedValueError({ prop, value })
|
|
52
|
-
return false
|
|
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
|
|
102
|
+
}
|
|
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
|
+
}
|
|
108
|
+
return true
|
|
81
109
|
}
|
|
82
|
-
|
|
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
|
+
}
|
|
83
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
|
let propsIdx = 0
|
|
157
|
-
|
|
158
|
-
while (idx < values.length
|
|
158
|
+
const diff = values.length - props.length
|
|
159
|
+
while (idx < values.length) {
|
|
159
160
|
const prop = props[propsIdx]
|
|
160
|
-
|
|
161
|
-
|
|
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
|
+
}
|
|
162
165
|
const value = values[idx]
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
+
}
|
|
171
185
|
} else if (prop.includes('.')) {
|
|
172
186
|
// 多个属性值的prop
|
|
173
187
|
const [main, sub] = prop.split('.')
|
|
@@ -196,30 +210,10 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
196
210
|
}
|
|
197
211
|
return cssMap
|
|
198
212
|
}
|
|
199
|
-
const getAbbreviation = ({ prop, value }) => {
|
|
200
|
-
const keyMap = AbbreviationMap[prop]
|
|
201
|
-
return formatAbbreviation({ prop, value, keyMap })
|
|
202
|
-
}
|
|
203
|
-
// 简写过滤安卓不支持的类型
|
|
204
|
-
const getAbbreviationAndroid = ({ prop, value }, { mode }) => {
|
|
205
|
-
const cssMap = getAbbreviation({ prop, value })
|
|
206
|
-
// android 不支持的 shadowOffset shadowOpacity shadowRadius textDecorationStyle 和 textDecorationStyle
|
|
207
|
-
return cssMap.filter(({ prop }) => { // 不支持的 prop 提示 & 过滤不支持的 prop
|
|
208
|
-
const dashProp = hump2dash(prop)
|
|
209
|
-
if (unsupportedPropMode.android.test(dashProp)) {
|
|
210
|
-
unsupportedPropError({ prop: dashProp, mode })
|
|
211
|
-
return false
|
|
212
|
-
}
|
|
213
|
-
return true
|
|
214
|
-
})
|
|
215
|
-
}
|
|
216
213
|
|
|
214
|
+
// margin padding
|
|
217
215
|
const formatMargins = ({ prop, value }) => {
|
|
218
216
|
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
219
|
-
// validate
|
|
220
|
-
for (let i = 0; i < values.length; i++) {
|
|
221
|
-
verifyValues({ prop, value: values[i], valueType: ValueType.number })
|
|
222
|
-
}
|
|
223
217
|
// format
|
|
224
218
|
let suffix = []
|
|
225
219
|
switch (values.length) {
|
|
@@ -235,55 +229,38 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
235
229
|
break
|
|
236
230
|
}
|
|
237
231
|
return values.map((value, index) => {
|
|
232
|
+
const newProp = `${prop}${suffix[index] || ''}`
|
|
233
|
+
// validate
|
|
234
|
+
verifyValues({ prop: hump2dash(newProp), value }, false)
|
|
238
235
|
return {
|
|
239
|
-
prop:
|
|
236
|
+
prop: newProp,
|
|
240
237
|
value: value
|
|
241
238
|
}
|
|
242
239
|
})
|
|
243
240
|
}
|
|
244
241
|
|
|
242
|
+
// line-height
|
|
245
243
|
const formatLineHeight = ({ prop, value }) => {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
return {
|
|
244
|
+
return verifyValues({ prop, value }) && ({
|
|
249
245
|
prop,
|
|
250
246
|
value: /^\s*-?\d+(\.\d+)?\s*$/.test(value) ? `${Math.round(value * 100)}%` : value
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const getFontVariant = ({ prop, value }) => {
|
|
255
|
-
if (/^(font-variant-caps|font-variant-numeric|font-variant-east-asian|font-variant-alternates|font-variant-ligatures)$/.test(prop)) {
|
|
256
|
-
error(`Property [${prop}] is not supported in React Native environment, please replace [font-variant]!`)
|
|
257
|
-
}
|
|
258
|
-
prop = 'font-variant'
|
|
259
|
-
// 校验枚举值
|
|
260
|
-
if (isIllegalValue({ prop, value })) {
|
|
261
|
-
unsupportedValueError({ prop, value })
|
|
262
|
-
return false
|
|
263
|
-
}
|
|
264
|
-
return {
|
|
265
|
-
prop,
|
|
266
|
-
value
|
|
267
|
-
}
|
|
247
|
+
})
|
|
268
248
|
}
|
|
269
249
|
|
|
270
|
-
// background
|
|
250
|
+
// background 相关属性的转换 Todo
|
|
251
|
+
// 仅支持以下属性,不支持其他背景相关的属性
|
|
252
|
+
// /^((?!(-color)).)*background((?!(-color)).)*$/ 包含background且不包含background-color
|
|
271
253
|
const checkBackgroundImage = ({ prop, value }, { mode }) => {
|
|
272
254
|
const bgPropMap = {
|
|
273
255
|
image: 'background-image',
|
|
274
256
|
color: 'background-color',
|
|
275
257
|
size: 'background-size',
|
|
276
258
|
repeat: 'background-repeat',
|
|
277
|
-
|
|
259
|
+
position: 'background-position',
|
|
278
260
|
all: 'background'
|
|
279
261
|
}
|
|
280
262
|
const urlExp = /url\(["']?(.*?)["']?\)/
|
|
281
263
|
switch (prop) {
|
|
282
|
-
case bgPropMap.color: {
|
|
283
|
-
// background-color 背景色校验一下颜色值
|
|
284
|
-
verifyValues({ prop, value, valueType: ValueType.color })
|
|
285
|
-
return { prop, value }
|
|
286
|
-
}
|
|
287
264
|
case bgPropMap.image: {
|
|
288
265
|
// background-image 仅支持背景图
|
|
289
266
|
const imgUrl = value.match(urlExp)?.[0]
|
|
@@ -308,23 +285,26 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
308
285
|
}
|
|
309
286
|
const values = []
|
|
310
287
|
value.trim().split(/\s(?![^()]*\))/).forEach(item => {
|
|
311
|
-
if (
|
|
288
|
+
if (verifyValues({ prop, value: item })) {
|
|
312
289
|
// 支持 number 值 / container cover auto 枚举
|
|
313
290
|
values.push(item)
|
|
314
|
-
} else {
|
|
315
|
-
error(`background size value[${value}] does not support in React Native ${mode} environment!`)
|
|
316
291
|
}
|
|
317
292
|
})
|
|
318
293
|
// value 无有效值时返回false
|
|
319
294
|
return values.length === 0 ? false : { prop, value: values }
|
|
320
295
|
}
|
|
321
|
-
case bgPropMap.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
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 }
|
|
328
308
|
}
|
|
329
309
|
case bgPropMap.all: {
|
|
330
310
|
// background: 仅支持 background-image & background-color & background-repeat
|
|
@@ -336,14 +316,11 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
336
316
|
error(`<linear-gradient()> is not supported in React Native ${mode} environment!`)
|
|
337
317
|
} else if (url) {
|
|
338
318
|
bgMap.push({ prop: bgPropMap.image, value: url })
|
|
339
|
-
} else if (
|
|
319
|
+
} else if (verifyValues({ prop: bgPropMap.color, value: item }, false)) {
|
|
340
320
|
bgMap.push({ prop: bgPropMap.color, value: item })
|
|
341
|
-
} else if (
|
|
321
|
+
} else if (verifyValues({ prop: bgPropMap.repeat, value: item }, false)) {
|
|
342
322
|
bgMap.push({ prop: bgPropMap.repeat, value: item })
|
|
343
323
|
}
|
|
344
|
-
// else if (SUPPORTED_PROP_VAL_ARR[bgPropMap.size].includes(item)) {
|
|
345
|
-
// bgMap.push({ prop: bgPropMap.size, value: item })
|
|
346
|
-
// }
|
|
347
324
|
})
|
|
348
325
|
return bgMap.length ? bgMap : false
|
|
349
326
|
}
|
|
@@ -352,23 +329,30 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
352
329
|
return false
|
|
353
330
|
}
|
|
354
331
|
|
|
355
|
-
|
|
332
|
+
// border-radius 缩写转换
|
|
333
|
+
const getBorderRadius = ({ prop, value }, { mode }) => {
|
|
356
334
|
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
357
335
|
if (values.length === 1) {
|
|
358
|
-
verifyValues({ prop, value,
|
|
336
|
+
verifyValues({ prop, value }, false)
|
|
359
337
|
return { prop, value }
|
|
360
338
|
} else {
|
|
361
|
-
|
|
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 })
|
|
362
345
|
}
|
|
363
346
|
}
|
|
364
347
|
|
|
348
|
+
// transform 转换
|
|
365
349
|
const formatTransform = ({ prop, value }, { mode }) => {
|
|
366
350
|
if (Array.isArray(value)) return { prop, value }
|
|
367
351
|
const values = value.trim().split(/\s(?![^()]*\))/)
|
|
368
352
|
const transform = []
|
|
369
353
|
values.forEach(item => {
|
|
370
354
|
const match = item.match(/([/\w]+)\(([^)]+)\)/)
|
|
371
|
-
if (match.length >= 3) {
|
|
355
|
+
if (match && match.length >= 3) {
|
|
372
356
|
let key = match[1]
|
|
373
357
|
const val = match[2]
|
|
374
358
|
switch (key) {
|
|
@@ -382,6 +366,7 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
382
366
|
case 'rotate':
|
|
383
367
|
case 'skewX':
|
|
384
368
|
case 'skewY':
|
|
369
|
+
case 'perspective':
|
|
385
370
|
// 单个值处理
|
|
386
371
|
transform.push({ [key]: val })
|
|
387
372
|
break
|
|
@@ -395,19 +380,19 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
395
380
|
case 'rotate3d': // x y z angle
|
|
396
381
|
case 'translate3d': // x y 支持 z不支持
|
|
397
382
|
case 'scale3d': // x y 支持 z不支持
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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
|
+
}
|
|
411
396
|
case 'translateZ':
|
|
412
397
|
case 'scaleZ':
|
|
413
398
|
default:
|
|
@@ -425,47 +410,113 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
425
410
|
}
|
|
426
411
|
}
|
|
427
412
|
|
|
428
|
-
const
|
|
413
|
+
const isNumber = (value) => {
|
|
414
|
+
return !isNaN(+value)
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const getIntegersFlex = ({ prop, value }) => {
|
|
418
|
+
if (isNumber(value) && value >= 0) {
|
|
419
|
+
return { prop, value }
|
|
420
|
+
} else {
|
|
421
|
+
error(`The value of ${prop} accepts any floating point value >= 0.`)
|
|
422
|
+
return false
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
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 {
|
|
429
513
|
supportedModes: ['ios', 'android'],
|
|
430
514
|
rules: [
|
|
431
515
|
{ // 背景相关属性的处理
|
|
432
|
-
test: /^(background|background-image|background-
|
|
516
|
+
test: /^(background|background-image|background-size|background-position)$/,
|
|
433
517
|
ios: checkBackgroundImage,
|
|
434
518
|
android: checkBackgroundImage
|
|
435
519
|
},
|
|
436
|
-
{ // RN 不支持的 CSS property
|
|
437
|
-
test: unsupportedPropExp,
|
|
438
|
-
ios: delRule,
|
|
439
|
-
android: delRule
|
|
440
|
-
},
|
|
441
|
-
{ // React Native android 不支持的 CSS property
|
|
442
|
-
test: unsupportedPropMode.android,
|
|
443
|
-
android: delRule
|
|
444
|
-
},
|
|
445
|
-
{ // React Native ios 不支持的 CSS property
|
|
446
|
-
test: unsupportedPropMode.ios,
|
|
447
|
-
ios: delRule
|
|
448
|
-
},
|
|
449
|
-
{ // RN 支持的 CSS property value
|
|
450
|
-
test: propValExp,
|
|
451
|
-
ios: delRule,
|
|
452
|
-
android: delRule
|
|
453
|
-
},
|
|
454
|
-
{
|
|
455
|
-
test: 'box-shadow',
|
|
456
|
-
ios: getAbbreviation,
|
|
457
|
-
android: getAbbreviationAndroid
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
test: 'text-decoration',
|
|
461
|
-
ios: getAbbreviation,
|
|
462
|
-
android: getAbbreviationAndroid
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
test: /^(font-variant|font-variant-caps|font-variant-numeric|font-variant-east-asian|font-variant-alternates|font-variant-ligatures)$/,
|
|
466
|
-
ios: getFontVariant,
|
|
467
|
-
android: getFontVariant
|
|
468
|
-
},
|
|
469
520
|
{
|
|
470
521
|
test: 'border-radius',
|
|
471
522
|
ios: getBorderRadius,
|
|
@@ -476,12 +527,6 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
476
527
|
ios: formatMargins,
|
|
477
528
|
android: formatMargins
|
|
478
529
|
},
|
|
479
|
-
// 通用的简写格式匹配
|
|
480
|
-
{
|
|
481
|
-
test: new RegExp('^(' + Object.keys(AbbreviationMap).join('|') + ')$'),
|
|
482
|
-
ios: getAbbreviation,
|
|
483
|
-
android: getAbbreviation
|
|
484
|
-
},
|
|
485
530
|
{ // line-height 换算
|
|
486
531
|
test: 'line-height',
|
|
487
532
|
ios: formatLineHeight,
|
|
@@ -492,18 +537,33 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
492
537
|
ios: formatTransform,
|
|
493
538
|
android: formatTransform
|
|
494
539
|
},
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
540
|
+
{
|
|
541
|
+
test: 'flex',
|
|
542
|
+
ios: formatFlex,
|
|
543
|
+
android: formatFlex
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
test: 'font-family',
|
|
547
|
+
ios: formatFontFamily,
|
|
548
|
+
android: formatFontFamily
|
|
500
549
|
},
|
|
501
|
-
{
|
|
502
|
-
test:
|
|
503
|
-
ios:
|
|
504
|
-
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
|
|
505
566
|
}
|
|
506
567
|
]
|
|
507
568
|
}
|
|
508
|
-
return spec
|
|
509
569
|
}
|