-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
99 lines (79 loc) · 2.39 KB
/
Copy pathindex.js
File metadata and controls
99 lines (79 loc) · 2.39 KB
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
'use strict';
var postcss = require('postcss');
/**
* Takes position declaration and expands it
* @param {Object} decl CSS declaration to handle
* @return undefined
*/
var declExpander = function(decl) {
var offsets = ['top', 'right', 'bottom', 'left'],
outputVals = offsets.map(function(){
return 0;
}),
inputVals = [],
position;
// Throw decl values into an array
var re = /(([\+\-]?[0-9\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw)?)|(calc\(([^\)]+)\)|null|false|undefined|auto)/g,
m = void 0;
while ((m = re.exec(decl.value)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
inputVals.push(m[0]);
}
// If there are no additional values on position, exit
if (inputVals.length === 0) {
return;
}
// Strip position from vals and store for safe keeping
position = decl.value.match(/^static|absolute|fixed|relative|sticky|-webkit-sticky|initial|inherit/).toString();
// Transform input values into correct 4 outputs
outputVals = (function(ins) {
switch (ins.length) {
case 1:
return outputVals.map(function() {
return ins[0];
});
case 2:
return outputVals.map(function(v, k) {
return ins[(k + 1) % 2 ? 0 : 1];
});
case 3:
return outputVals.map(function(v, k) {
return ins[k === 3 ? 1 : k];
});
case 4:
return outputVals.map(function(v, k) {
return ins[k];
});
default:
return [];
}
})(inputVals);
if (outputVals.length === 0) {
outputVals = offsets.map(function() {
return 0;
});
}
// Create the position-type declaration
decl.cloneBefore({ prop: 'position', value: position });
// And each position offset
offsets.forEach(function(offset, i){
if (!/null|false|undefined/i.test(outputVals[i])) {
decl.cloneBefore({prop: offset, value: outputVals[i] });
}
});
decl.remove();
};
module.exports = postcss.plugin('postcss-position', function () {
return function(css, result) {
css.walkDecls(function(decl){
if (decl.prop === 'position') {
declExpander(decl);
}
if (decl.prop.match(/^(static|absolute|fixed|relative|sticky|-webkit-sticky|initial|inherit)$/)) {
result.warn('This syntax is no longer supported, use position: type [offsets]; instead', { node: decl });
}
});
};
});