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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
var postcss = require('postcss');
// Map new selectors to outputs
var selectors = {
rangeTrack: '::track',
rangeThumb: '::thumb'
};
var pseudos = {
rangeTrack: [
'::-webkit-slider-runnable-track',
'::-moz-range-track',
'::-ms-track'
],
rangeThumb: [
'::-webkit-slider-thumb',
'::-moz-range-thumb',
'::-ms-thumb'
]
};
/**
* Check if selector in array contains any of our psuedo elements
* @param {String} selector string to check for elements
* @return {Boolean} whether it contains pseudo
*/
var containsPseudo = function(selector) {
return selector.match(/::track|::thumb/);
};
/**
* Check if selector in array is free from our psuedo elements
* @param {String} selector string to check for elements
* @return {Boolean} whether it is free from pseudo
*/
var doesntContainPseudo = function(selector) {
return selector.match(/^((?!(::thumb|::track)).)*$/);
};
/**
* Extra processing for new range track rules
* @param {Object} rule CSS rule to process
* @return undefined
*/
var processTracks = function(rule) {
if (rule.selector.indexOf('::-webkit-slider-runnable-track') > -1) {
rule.prepend({ prop: '-webkit-appearance', value: 'none' });
}
if (rule.selector.indexOf('::-moz-range-track') > -1) {
rule.prepend({ prop: '-moz-appearance', value: 'none' });
}
};
/**
* Extra processing for new range thumb rules
* @param {Object} rule CSS rule to process
* @return undefined
*/
var processThumbs = function(rule) {
if (rule.selector.indexOf('::-webkit-slider-thumb') > -1) {
rule.prepend({ prop: '-webkit-appearance', value: 'none' });
}
if (rule.selector.indexOf('::-moz-range-thumb') > -1) {
rule.prepend({ prop: '-moz-appearance', value: 'none' });
}
};
/**
* Expand and process CSS rules
* @param {Object} rule CSS rule to transform
* @return undefined
*/
var ruleHandler = function(rule) {
// Loop over our selectors
Object.keys(selectors).forEach(function(select){
// If the rule doesn't contain our selector, exit
if (rule.selector.indexOf(selectors[select]) === -1){
return;
}
// Expand the pseudo selector
pseudos[select].forEach(function(pseudo){
// Create the new rule
var newRule,
newSelector;
newRule = rule.cloneBefore();
newSelector = newRule.selectors.filter(containsPseudo).map(function(selector){
return selector.replace(selectors[select], pseudo);
}).join(',\n');
newRule.selector = newSelector;
// Do extra processing on the new rules
processTracks(newRule);
processThumbs(newRule);
});
// Add necessary additional base rules
var webkitRule = rule.cloneBefore();
webkitRule.selector = 'input[type="range"]';
webkitRule.removeAll().append({ prop: '-webkit-appearance', value: 'none' });
var mozRule = rule.cloneBefore();
mozRule.selector = 'input[type="range"]::-moz-focus-outer';
mozRule.removeAll().append({ prop: 'border', value: '0' });
// If the rule only contained our elements remove it, else clean it
if (rule.selectors.every(containsPseudo)) {
rule.remove();
} else {
rule.selector = rule.selectors.filter(doesntContainPseudo).join(',\n');
}
});
};
module.exports = postcss.plugin('postcss-input-style', function () {
return function (css) {
css.walkRules(function(rule) {
if (!containsPseudo(rule.selector)) {
return;
}
// Handle dem rules
ruleHandler(rule);
});
};
});
|