-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtidy-function.js
95 lines (83 loc) · 2.93 KB
/
tidy-function.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
const postcss = require('postcss');
const cleanClone = require('./lib/cleanClone');
const detectCalcWrapper = require('./lib/detectCalcWrapper');
const hasComment = require('./lib/hasComment');
/**
* Pattern to match `tidy-*` functions in declaration values.
*
* @type {RegExp}
*/
const FUNCTION_REGEX = /tidy-(span|offset)(-full)?\(([\d.-]+)\)/;
/**
* Replace `tidy-[span|offset]()` and `tidy-[span|offset]-full()` functions.
*
* @see https://github.com/goodguyry/postcss-tidy-columns#span-function
* @see https://github.com/goodguyry/postcss-tidy-columns#offset-function
*
* @param {Object} declaration The current CSS declaration.
* @param {Object} Tidy An instance of the Tidy class.
*/
function tidyFunction(declaration, tidy) {
// Parse the tidy-* function matches.
const tidyMatches = detectCalcWrapper(declaration.value);
if (0 < tidyMatches.length) {
const { columns, columns: { options } } = tidy;
/**
* Find all matches in the declaration value.
*
* @param {String} acc The accumulator, based on declaration.value
* @param {String} tidyMatch The full tidy function match(es).
*
* @return {String} The replacement value for the declaration.
*/
const replaceWithValue = tidyMatches.reduce((acc, tidyMatch) => {
const { match: tidyFunctionMatch, isNested } = tidyMatch;
// Conditionally suppress 'calc' in the output.
columns.suppressCalc = isNested;
/**
* match: The full function expression.
* slug: One of either `span` or `offset`.
* modifier: One of either `undefined` or `-full`.
* value: The function's argument.
*/
const [match, slug, modifier, value] = tidyFunctionMatch.match(FUNCTION_REGEX);
/**
* Get the span or offset `calc()` value(s).
* Use the object's `isNested` value to suppress the `calc` from the output.
*
* fluid: calc() function based on 100vw base.
* full: calc() function based on `siteMax` base.
*/
const { fluid, full } = ('span' === slug)
? columns.spanCalc(value)
: columns.offsetCalc(value);
return ('-full' === modifier)
// tidy-[span|offset]-full()
? acc.replace(match, full)
// tidy-[span|offset] ()
: acc.replace(match, fluid);
}, 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() }));
}
// Replace declaration(s) with cloned and updated declarations.
declaration.replaceWith(cleanClone(
declaration,
{
prop: declaration.prop,
value: replaceWithValue,
},
));
// Reset suppress 'calc' to default.
columns.suppressCalc = false;
}
}
module.exports = {
tidyFunction,
FUNCTION_REGEX,
};