1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", {
|
3 | value: true
|
4 | });
|
5 | function _export(target, all) {
|
6 | for(var name in all)Object.defineProperty(target, name, {
|
7 | enumerable: true,
|
8 | get: all[name]
|
9 | });
|
10 | }
|
11 | _export(exports, {
|
12 | selectorFunctions: ()=>selectorFunctions,
|
13 | formatVariantSelector: ()=>formatVariantSelector,
|
14 | finalizeSelector: ()=>finalizeSelector
|
15 | });
|
16 | const _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
|
17 | const _unesc = _interopRequireDefault(require("postcss-selector-parser/dist/util/unesc"));
|
18 | const _escapeClassName = _interopRequireDefault(require("../util/escapeClassName"));
|
19 | const _prefixSelector = _interopRequireDefault(require("../util/prefixSelector"));
|
20 | function _interopRequireDefault(obj) {
|
21 | return obj && obj.__esModule ? obj : {
|
22 | default: obj
|
23 | };
|
24 | }
|
25 | var ref;
|
26 | let MERGE = ":merge";
|
27 | let PARENT = "&";
|
28 | let selectorFunctions = new Set([
|
29 | MERGE
|
30 | ]);
|
31 | function formatVariantSelector(current, ...others) {
|
32 | for (let other of others){
|
33 | let incomingValue = resolveFunctionArgument(other, MERGE);
|
34 | if (incomingValue !== null) {
|
35 | let existingValue = resolveFunctionArgument(current, MERGE, incomingValue);
|
36 | if (existingValue !== null) {
|
37 | let existingTarget = `${MERGE}(${incomingValue})`;
|
38 | let splitIdx = other.indexOf(existingTarget);
|
39 | let addition = other.slice(splitIdx + existingTarget.length).split(" ")[0];
|
40 | current = current.replace(existingTarget, existingTarget + addition);
|
41 | continue;
|
42 | }
|
43 | }
|
44 | current = other.replace(PARENT, current);
|
45 | }
|
46 | return current;
|
47 | }
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 | function simpleSelectorForNode(node) {
|
57 | let nodes = [];
|
58 |
|
59 | while(node.prev() && node.prev().type !== "combinator"){
|
60 | node = node.prev();
|
61 | }
|
62 |
|
63 | while(node && node.type !== "combinator"){
|
64 | nodes.push(node);
|
65 | node = node.next();
|
66 | }
|
67 | return nodes;
|
68 | }
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | function resortSelector(sel) {
|
76 | sel.sort((a, b)=>{
|
77 | if (a.type === "tag" && b.type === "class") {
|
78 | return -1;
|
79 | } else if (a.type === "class" && b.type === "tag") {
|
80 | return 1;
|
81 | } else if (a.type === "class" && b.type === "pseudo" && b.value.startsWith("::")) {
|
82 | return -1;
|
83 | } else if (a.type === "pseudo" && a.value.startsWith("::") && b.type === "class") {
|
84 | return 1;
|
85 | }
|
86 | return sel.index(a) - sel.index(b);
|
87 | });
|
88 | return sel;
|
89 | }
|
90 | function eliminateIrrelevantSelectors(sel, base) {
|
91 | let hasClassesMatchingCandidate = false;
|
92 | sel.walk((child)=>{
|
93 | if (child.type === "class" && child.value === base) {
|
94 | hasClassesMatchingCandidate = true;
|
95 | return false
|
96 | ;
|
97 | }
|
98 | });
|
99 | if (!hasClassesMatchingCandidate) {
|
100 | sel.remove();
|
101 | }
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | }
|
109 | var ref1;
|
110 | function finalizeSelector(format, { selector , candidate , context , isArbitraryVariant , // Split by the separator, but ignore the separator inside square brackets:
|
111 | //
|
112 | // E.g.: dark:lg:hover:[paint-order:markers]
|
113 | // ┬ ┬ ┬ ┬
|
114 | // │ │ │ ╰── We will not split here
|
115 | // ╰──┴─────┴─────────────── We will split here
|
116 | //
|
117 | base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === void 0 ? void 0 : (ref = context.tailwindConfig) === null || ref === void 0 ? void 0 : ref.separator) !== null && ref1 !== void 0 ? ref1 : ":"}(?![^[]*\\])`)).pop() }) {
|
118 | var ref2;
|
119 | let ast = (0, _postcssSelectorParser.default)().astSync(selector);
|
120 |
|
121 | if ((context === null || context === void 0 ? void 0 : (ref2 = context.tailwindConfig) === null || ref2 === void 0 ? void 0 : ref2.prefix) && !isArbitraryVariant) {
|
122 | format = (0, _prefixSelector.default)(context.tailwindConfig.prefix, format);
|
123 | }
|
124 | format = format.replace(PARENT, `.${(0, _escapeClassName.default)(candidate)}`);
|
125 | let formatAst = (0, _postcssSelectorParser.default)().astSync(format);
|
126 |
|
127 |
|
128 |
|
129 | ast.each((sel)=>eliminateIrrelevantSelectors(sel, base));
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | ast.walkClasses((node)=>{
|
142 | if (node.raws && node.value.includes(base)) {
|
143 | node.raws.value = (0, _escapeClassName.default)((0, _unesc.default)(node.raws.value));
|
144 | }
|
145 | });
|
146 | let simpleStart = _postcssSelectorParser.default.comment({
|
147 | value: "/*__simple__*/"
|
148 | });
|
149 | let simpleEnd = _postcssSelectorParser.default.comment({
|
150 | value: "/*__simple__*/"
|
151 | });
|
152 |
|
153 |
|
154 | ast.walkClasses((node)=>{
|
155 | if (node.value !== base) {
|
156 | return;
|
157 | }
|
158 | let parent = node.parent;
|
159 | let formatNodes = formatAst.nodes[0].nodes;
|
160 |
|
161 | if (parent.nodes.length === 1) {
|
162 | node.replaceWith(...formatNodes);
|
163 | return;
|
164 | }
|
165 | let simpleSelector = simpleSelectorForNode(node);
|
166 | parent.insertBefore(simpleSelector[0], simpleStart);
|
167 | parent.insertAfter(simpleSelector[simpleSelector.length - 1], simpleEnd);
|
168 | for (let child of formatNodes){
|
169 | parent.insertBefore(simpleSelector[0], child);
|
170 | }
|
171 | node.remove();
|
172 |
|
173 | simpleSelector = simpleSelectorForNode(simpleStart);
|
174 | let firstNode = parent.index(simpleStart);
|
175 | parent.nodes.splice(firstNode, simpleSelector.length, ...resortSelector(_postcssSelectorParser.default.selector({
|
176 | nodes: simpleSelector
|
177 | })).nodes);
|
178 | simpleStart.remove();
|
179 | simpleEnd.remove();
|
180 | });
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 | function collectPseudoElements(selector) {
|
191 | let nodes = [];
|
192 | for (let node of selector.nodes){
|
193 | if (isPseudoElement(node)) {
|
194 | nodes.push(node);
|
195 | selector.removeChild(node);
|
196 | }
|
197 | if (node === null || node === void 0 ? void 0 : node.nodes) {
|
198 | nodes.push(...collectPseudoElements(node));
|
199 | }
|
200 | }
|
201 | return nodes;
|
202 | }
|
203 |
|
204 | ast.each((selector)=>{
|
205 | selector.walkPseudos((p)=>{
|
206 | if (selectorFunctions.has(p.value)) {
|
207 | p.replaceWith(p.nodes);
|
208 | }
|
209 | });
|
210 | let pseudoElements = collectPseudoElements(selector);
|
211 | if (pseudoElements.length > 0) {
|
212 | selector.nodes.push(pseudoElements.sort(sortSelector));
|
213 | }
|
214 | });
|
215 | return ast.toString();
|
216 | }
|
217 |
|
218 |
|
219 |
|
220 |
|
221 | let pseudoElementsBC = [
|
222 | ":before",
|
223 | ":after",
|
224 | ":first-line",
|
225 | ":first-letter"
|
226 | ];
|
227 |
|
228 | let pseudoElementExceptions = [
|
229 | "::file-selector-button"
|
230 | ];
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 | function sortSelector(a, z) {
|
242 |
|
243 |
|
244 | if (a.type !== "pseudo" && z.type !== "pseudo") {
|
245 | return 0;
|
246 | }
|
247 |
|
248 |
|
249 | if (a.type === "combinator" ^ z.type === "combinator") {
|
250 | return 0;
|
251 | }
|
252 |
|
253 |
|
254 | if (a.type === "pseudo" ^ z.type === "pseudo") {
|
255 | return (a.type === "pseudo") - (z.type === "pseudo");
|
256 | }
|
257 |
|
258 |
|
259 | return isPseudoElement(a) - isPseudoElement(z);
|
260 | }
|
261 | function isPseudoElement(node) {
|
262 | if (node.type !== "pseudo") return false;
|
263 | if (pseudoElementExceptions.includes(node.value)) return false;
|
264 | return node.value.startsWith("::") || pseudoElementsBC.includes(node.value);
|
265 | }
|
266 | function resolveFunctionArgument(haystack, needle, arg) {
|
267 | let startIdx = haystack.indexOf(arg ? `${needle}(${arg})` : needle);
|
268 | if (startIdx === -1) return null;
|
269 |
|
270 | startIdx += needle.length + 1;
|
271 | let target = "";
|
272 | let count = 0;
|
273 | for (let char of haystack.slice(startIdx)){
|
274 | if (char !== "(" && char !== ")") {
|
275 | target += char;
|
276 | } else if (char === "(") {
|
277 | target += char;
|
278 | count++;
|
279 | } else if (char === ")") {
|
280 | if (--count < 0) break;
|
281 | target += char;
|
282 | }
|
283 | }
|
284 | return target;
|
285 | }
|