1 |
|
2 | import { list } from 'postcss';
|
3 | import transformNode from './transform-node';
|
4 | import getReplacedString from './get-replaced-string';
|
5 |
|
6 |
|
7 | export default function transformIfAtrule(rule, opts) {
|
8 |
|
9 | const isTruthy = isIfTruthy(rule, opts);
|
10 | const next = rule.next();
|
11 |
|
12 | const transformAndInsertBeforeParent = node => transformNode(node, opts).then(
|
13 | () => node.parent.insertBefore(node, node.nodes)
|
14 | )
|
15 |
|
16 | return ifPromise(
|
17 | opts.transform.includes('@if'),
|
18 | () => ifPromise(
|
19 | isTruthy,
|
20 | () => transformAndInsertBeforeParent(rule)
|
21 | ).then(() => {
|
22 | rule.remove();
|
23 | })
|
24 | ).then(() => ifPromise(
|
25 | opts.transform.includes('@else') && isElseRule(next),
|
26 | () => ifPromise(
|
27 | !isTruthy,
|
28 | () => transformAndInsertBeforeParent(next)
|
29 | ).then(() => {
|
30 | next.remove();
|
31 | })
|
32 | ))
|
33 | }
|
34 |
|
35 | const ifPromise = (condition, trueFunction) => Promise.resolve(condition && trueFunction())
|
36 |
|
37 |
|
38 | const isIfTruthy = (node, opts) => {
|
39 |
|
40 | const params = list.space(node.params);
|
41 | const left = getInterprettedString(getReplacedString(params[0] || '', node, opts));
|
42 | const operator = params[1];
|
43 | const right = getInterprettedString(getReplacedString(params[2] || '', node, opts));
|
44 |
|
45 |
|
46 | const isTruthy = !operator && left ||
|
47 | operator === '==' && left === right ||
|
48 | operator === '!=' && left !== right ||
|
49 | operator === '<' && left < right ||
|
50 | operator === '<=' && left <= right ||
|
51 | operator === '>' && left > right ||
|
52 | operator === '>=' && left >= right;
|
53 |
|
54 | return isTruthy;
|
55 | };
|
56 |
|
57 |
|
58 | const getInterprettedString = value => 'true' === value
|
59 | ? true
|
60 | : 'false' === value
|
61 | ? false
|
62 | : isNaN(value)
|
63 | ? value
|
64 | : Number(value);
|
65 |
|
66 |
|
67 | const isElseRule = node => Object(node) === node && 'atrule' === node.type && 'else' === node.name;
|