-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtidy-var.js
80 lines (70 loc) · 2.36 KB
/
tidy-var.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
/* eslint-disable no-param-reassign */
const postcss = require('postcss');
const cleanClone = require('./lib/cleanClone');
const hasComment = require('./lib/hasComment');
/**
* Matches tidy-var() functions.
*
* @type {RegExp}
*/
const VAR_FUNCTION_REGEX = /tidy-var\(["']?(columns|edge|gap|siteMax)["']?\)/i;
/**
* Replace `tidy-var()` functions within property values.
*
* @see https://github.com/goodguyry/postcss-tidy-columns#var-function
*
* @param {Object} declaration The current CSS declaration.
* @param {Object} Tidy An instance of the Tidy class.
*/
function tidyVar(declaration, tidy) {
const globalRegExp = new RegExp(VAR_FUNCTION_REGEX, 'g');
const localRegExp = new RegExp(VAR_FUNCTION_REGEX);
if (localRegExp.test(declaration.value)) {
const { columns, columns: { options } } = tidy;
const fullMatch = declaration.value.match(globalRegExp);
/**
* Find all matches in the declaration value.
*
* @param {String} acc The accumulator, based on declaration.value
* @param {String} varMatch The full tidy function match(es)
*
* @return {String} The replacement value for the declaration
*/
const replaceWithValue = fullMatch.reduce((acc, varMatch) => {
/**
* match: The full function expression.
* value: The function's argument.
*/
const [match, value] = varMatch.match(localRegExp);
// Replace the tidy-var() function with the real option value.
if (Object.keys(columns.options).includes(value)) {
return acc.replace(match, columns.options[value]);
}
// There's no corresponding option value.
return acc;
}, declaration.value);
// Save the original declaration in a comment for debugging.
if (
options.debug
&& undefined !== declaration.parent
&& !hasComment(declaration)
) {
declaration.cloneBefore(postcss.comment({ text: declaration.toString() }));
}
// Clone after so the new declaration can be walked again.
// This avoids a situation where another Tidy property or function is within this declaration.
declaration.cloneAfter(cleanClone(
declaration,
{
prop: declaration.prop,
value: replaceWithValue,
},
));
// Remove the original declaration.
declaration.remove();
}
}
module.exports = {
tidyVar,
VAR_FUNCTION_REGEX,
};