UNPKG

5.31 kBJavaScriptView Raw
1"use strict";
2
3function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
4
5function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _defaults(subClass, superClass); }
6
7var _require = require('postcss'),
8 list = _require.list;
9
10var OldSelector = require('./old-selector');
11
12var Prefixer = require('./prefixer');
13
14var Browsers = require('./browsers');
15
16var utils = require('./utils');
17
18var Selector =
19/*#__PURE__*/
20function (_Prefixer) {
21 _inheritsLoose(Selector, _Prefixer);
22
23 function Selector(name, prefixes, all) {
24 var _this;
25
26 _this = _Prefixer.call(this, name, prefixes, all) || this;
27 _this.regexpCache = {};
28 return _this;
29 }
30 /**
31 * Is rule selectors need to be prefixed
32 */
33
34
35 var _proto = Selector.prototype;
36
37 _proto.check = function check(rule) {
38 if (rule.selector.includes(this.name)) {
39 return !!rule.selector.match(this.regexp());
40 }
41
42 return false;
43 }
44 /**
45 * Return prefixed version of selector
46 */
47 ;
48
49 _proto.prefixed = function prefixed(prefix) {
50 return this.name.replace(/^([^\w]*)/, "$1" + prefix);
51 }
52 /**
53 * Lazy loadRegExp for name
54 */
55 ;
56
57 _proto.regexp = function regexp(prefix) {
58 if (this.regexpCache[prefix]) {
59 return this.regexpCache[prefix];
60 }
61
62 var name = prefix ? this.prefixed(prefix) : this.name;
63 this.regexpCache[prefix] = new RegExp("(^|[^:\"'=])" + utils.escapeRegexp(name), 'gi');
64 return this.regexpCache[prefix];
65 }
66 /**
67 * All possible prefixes
68 */
69 ;
70
71 _proto.possible = function possible() {
72 return Browsers.prefixes();
73 }
74 /**
75 * Return all possible selector prefixes
76 */
77 ;
78
79 _proto.prefixeds = function prefixeds(rule) {
80 var _this2 = this;
81
82 if (rule._autoprefixerPrefixeds) {
83 if (rule._autoprefixerPrefixeds[this.name]) {
84 return rule._autoprefixerPrefixeds;
85 }
86 } else {
87 rule._autoprefixerPrefixeds = {};
88 }
89
90 var prefixeds = {};
91
92 if (rule.selector.includes(',')) {
93 var ruleParts = list.comma(rule.selector);
94 var toProcess = ruleParts.filter(function (el) {
95 return el.includes(_this2.name);
96 });
97
98 var _loop = function _loop() {
99 if (_isArray) {
100 if (_i >= _iterator.length) return "break";
101 _ref = _iterator[_i++];
102 } else {
103 _i = _iterator.next();
104 if (_i.done) return "break";
105 _ref = _i.value;
106 }
107
108 var prefix = _ref;
109 prefixeds[prefix] = toProcess.map(function (el) {
110 return _this2.replace(el, prefix);
111 }).join(', ');
112 };
113
114 for (var _iterator = this.possible(), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
115 var _ref;
116
117 var _ret = _loop();
118
119 if (_ret === "break") break;
120 }
121 } else {
122 for (var _iterator2 = this.possible(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
123 var _ref2;
124
125 if (_isArray2) {
126 if (_i2 >= _iterator2.length) break;
127 _ref2 = _iterator2[_i2++];
128 } else {
129 _i2 = _iterator2.next();
130 if (_i2.done) break;
131 _ref2 = _i2.value;
132 }
133
134 var prefix = _ref2;
135 prefixeds[prefix] = this.replace(rule.selector, prefix);
136 }
137 }
138
139 rule._autoprefixerPrefixeds[this.name] = prefixeds;
140 return rule._autoprefixerPrefixeds;
141 }
142 /**
143 * Is rule already prefixed before
144 */
145 ;
146
147 _proto.already = function already(rule, prefixeds, prefix) {
148 var index = rule.parent.index(rule) - 1;
149
150 while (index >= 0) {
151 var before = rule.parent.nodes[index];
152
153 if (before.type !== 'rule') {
154 return false;
155 }
156
157 var some = false;
158
159 for (var key in prefixeds[this.name]) {
160 var prefixed = prefixeds[this.name][key];
161
162 if (before.selector === prefixed) {
163 if (prefix === key) {
164 return true;
165 } else {
166 some = true;
167 break;
168 }
169 }
170 }
171
172 if (!some) {
173 return false;
174 }
175
176 index -= 1;
177 }
178
179 return false;
180 }
181 /**
182 * Replace selectors by prefixed one
183 */
184 ;
185
186 _proto.replace = function replace(selector, prefix) {
187 return selector.replace(this.regexp(), "$1" + this.prefixed(prefix));
188 }
189 /**
190 * Clone and add prefixes for at-rule
191 */
192 ;
193
194 _proto.add = function add(rule, prefix) {
195 var prefixeds = this.prefixeds(rule);
196
197 if (this.already(rule, prefixeds, prefix)) {
198 return;
199 }
200
201 var cloned = this.clone(rule, {
202 selector: prefixeds[this.name][prefix]
203 });
204 rule.parent.insertBefore(rule, cloned);
205 }
206 /**
207 * Return function to fast find prefixed selector
208 */
209 ;
210
211 _proto.old = function old(prefix) {
212 return new OldSelector(this, prefix);
213 };
214
215 return Selector;
216}(Prefixer);
217
218module.exports = Selector;
\No newline at end of file