-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcodemod-expand-shorthands.js
122 lines (106 loc) · 3.77 KB
/
codemod-expand-shorthands.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const glob = require('fast-glob');
const fs = require('fs');
const is = (thing, line) => thing.test(line);
const get = (regex, line) => line.match(regex);
const PROP = /^([a-z][a-zA-Z0-9]*)(\s+(.+))?$/;
const getProp = line => get(PROP, line);
const isProp = line => is(PROP, line);
const SHORTHAND = {
background: ['backgroundColor', 'backgroundImage', 'backgroundSize'],
border: ['borderWidth', 'borderStyle', 'borderColor'],
borderBottom: ['borderBottomWidth', 'borderBottomStyle', 'borderBottomColor'],
borderTop: ['borderTopWidth', 'borderTopStyle', 'borderTopColor'],
borderRight: ['borderRightWidth', 'borderRightStyle', 'borderRightColor'],
borderLeft: ['borderLeftWidth', 'borderLeftStyle', 'borderLeftColor'],
borderRadius: [
'borderTopLeftRadius',
'borderTopRightRadius',
'borderBottomLeftRadius',
'borderBottomRightRadius',
],
boxShadow: [
'shadowOffsetX',
'shadowOffsetY',
'shadowRadius',
'shadowSpread',
'shadowColor',
],
margin: ['marginTop', 'marginRight', 'marginBottom', 'marginLeft'],
padding: ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'],
textShadow: ['shadowOffsetX', 'shadowOffsetY', 'shadowRadius', 'shadowColor'],
outline: ['outlineWidth', 'outlineStyle', 'outlineColor'],
overflow: ['overflowX', 'overflowY'],
};
const isShorthand = name => name in SHORTHAND;
const getShorthandExpanded = (name, value) => {
const props = SHORTHAND[name];
if (name === 'borderRadius') {
const theValue = value.replace('px', '');
return [
`${props[0]} ${theValue}`,
`${props[1]} ${theValue}`,
`${props[2]} ${theValue}`,
`${props[3]} ${theValue}`,
];
} else if (name.startsWith('border') || name === 'outline') {
const [width, style, ...color] = value.split(' ');
return [
`${props[0]} ${width.replace('px', '')}`,
`${props[1]} ${style}`,
`${props[2]} ${color.join(' ')}`,
];
} else if (name === 'boxShadow') {
const [offsetX, offsetY, blurRadius, spreadRadius, ...color] = value.split(
' '
);
return [
`${props[0]} ${offsetX.replace('px', '')}`,
`${props[1]} ${offsetY.replace('px', '')}`,
`${props[2]} ${blurRadius.replace('px', '')}`,
`${props[3]} ${spreadRadius.replace('px', '')}`,
`${props[4]} ${color.join(' ')}`,
];
} else if (name === 'textShadow') {
const [offsetX, offsetY, blurRadius, ...color] = value.split(' ');
return [
`${props[0]} ${offsetX.replace('px', '')}`,
`${props[1]} ${offsetY.replace('px', '')}`,
`${props[2]} ${blurRadius.replace('px', '')}`,
`${props[3]} ${color.join(' ')}`,
];
} else if (name === 'overflow') {
return [`${props[0]} ${value}`, `${props[1]} ${value}`];
} else if (name === 'padding' || name === 'margin') {
let [top, right, bottom, left] = value.split(' ');
top = top.replace('px', '');
right = right ? right.replace('px', '') : top;
bottom = bottom ? bottom.replace('px', '') : top;
left = left ? left.replace('px', '') : right || top;
return [
`${props[0]} ${top}`,
`${props[1]} ${right}`,
`${props[2]} ${bottom}`,
`${props[3]} ${left}`,
];
}
};
function transform(rtext) {
const text = rtext.replace(/\r\n/g, '\n');
const lines = text.split('\n').map(line => line.trim());
const next = lines.map(line => {
if (!isProp(line)) return line;
const [_, prop, _1, value] = getProp(line);
if (!isShorthand(prop) || value.startsWith('props')) return line;
return getShorthandExpanded(prop, value).join('\n');
});
return next.join('\n');
}
glob(['src/**/*.view'], {
bashNative: ['linux'],
cwd: process.cwd(),
}).then(list => {
list.forEach(file => {
const content = fs.readFileSync(file, 'utf-8');
fs.writeFileSync(file, transform(content));
});
});