|
"use strict"; |
|
Object.defineProperty(exports, "__esModule", { |
|
value: true |
|
}); |
|
function _export(target, all) { |
|
for(var name in all)Object.defineProperty(target, name, { |
|
enumerable: true, |
|
get: all[name] |
|
}); |
|
} |
|
_export(exports, { |
|
formatVariantSelector: function() { |
|
return formatVariantSelector; |
|
}, |
|
eliminateIrrelevantSelectors: function() { |
|
return eliminateIrrelevantSelectors; |
|
}, |
|
finalizeSelector: function() { |
|
return finalizeSelector; |
|
}, |
|
handleMergePseudo: function() { |
|
return handleMergePseudo; |
|
} |
|
}); |
|
const _postcssselectorparser = _interop_require_default(require("postcss-selector-parser")); |
|
const _unesc = _interop_require_default(require("postcss-selector-parser/dist/util/unesc")); |
|
const _escapeClassName = _interop_require_default(require("../util/escapeClassName")); |
|
const _prefixSelector = _interop_require_default(require("../util/prefixSelector")); |
|
const _pseudoElements = require("./pseudoElements"); |
|
const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly"); |
|
function _interop_require_default(obj) { |
|
return obj && obj.__esModule ? obj : { |
|
default: obj |
|
}; |
|
} |
|
let MERGE = ":merge"; |
|
function formatVariantSelector(formats, { context , candidate }) { |
|
var _context_tailwindConfig_prefix; |
|
let prefix = (_context_tailwindConfig_prefix = context === null || context === void 0 ? void 0 : context.tailwindConfig.prefix) !== null && _context_tailwindConfig_prefix !== void 0 ? _context_tailwindConfig_prefix : ""; |
|
|
|
let parsedFormats = formats.map((format)=>{ |
|
let ast = (0, _postcssselectorparser.default)().astSync(format.format); |
|
return { |
|
...format, |
|
ast: format.respectPrefix ? (0, _prefixSelector.default)(prefix, ast) : ast |
|
}; |
|
}); |
|
|
|
let formatAst = _postcssselectorparser.default.root({ |
|
nodes: [ |
|
_postcssselectorparser.default.selector({ |
|
nodes: [ |
|
_postcssselectorparser.default.className({ |
|
value: (0, _escapeClassName.default)(candidate) |
|
}) |
|
] |
|
}) |
|
] |
|
}); |
|
|
|
for (let { ast } of parsedFormats){ |
|
[formatAst, ast] = handleMergePseudo(formatAst, ast); |
|
|
|
ast.walkNesting((nesting)=>nesting.replaceWith(...formatAst.nodes[0].nodes)); |
|
|
|
formatAst = ast; |
|
} |
|
return formatAst; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function simpleSelectorForNode(node) { |
|
let nodes = []; |
|
|
|
while(node.prev() && node.prev().type !== "combinator"){ |
|
node = node.prev(); |
|
} |
|
|
|
while(node && node.type !== "combinator"){ |
|
nodes.push(node); |
|
node = node.next(); |
|
} |
|
return nodes; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function resortSelector(sel) { |
|
sel.sort((a, b)=>{ |
|
if (a.type === "tag" && b.type === "class") { |
|
return -1; |
|
} else if (a.type === "class" && b.type === "tag") { |
|
return 1; |
|
} else if (a.type === "class" && b.type === "pseudo" && b.value.startsWith("::")) { |
|
return -1; |
|
} else if (a.type === "pseudo" && a.value.startsWith("::") && b.type === "class") { |
|
return 1; |
|
} |
|
return sel.index(a) - sel.index(b); |
|
}); |
|
return sel; |
|
} |
|
function eliminateIrrelevantSelectors(sel, base) { |
|
let hasClassesMatchingCandidate = false; |
|
sel.walk((child)=>{ |
|
if (child.type === "class" && child.value === base) { |
|
hasClassesMatchingCandidate = true; |
|
return false |
|
; |
|
} |
|
}); |
|
if (!hasClassesMatchingCandidate) { |
|
sel.remove(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
function finalizeSelector(current, formats, { context , candidate , base }) { |
|
var _context_tailwindConfig; |
|
var _context_tailwindConfig_separator; |
|
let separator = (_context_tailwindConfig_separator = context === null || context === void 0 ? void 0 : (_context_tailwindConfig = context.tailwindConfig) === null || _context_tailwindConfig === void 0 ? void 0 : _context_tailwindConfig.separator) !== null && _context_tailwindConfig_separator !== void 0 ? _context_tailwindConfig_separator : ":"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
base = base !== null && base !== void 0 ? base : (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(candidate, separator).pop(); |
|
|
|
let selector = (0, _postcssselectorparser.default)().astSync(current); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
selector.walkClasses((node)=>{ |
|
if (node.raws && node.value.includes(base)) { |
|
node.raws.value = (0, _escapeClassName.default)((0, _unesc.default)(node.raws.value)); |
|
} |
|
}); |
|
|
|
selector.each((sel)=>eliminateIrrelevantSelectors(sel, base)); |
|
|
|
|
|
|
|
if (selector.length === 0) { |
|
return null; |
|
} |
|
|
|
|
|
let formatAst = Array.isArray(formats) ? formatVariantSelector(formats, { |
|
context, |
|
candidate |
|
}) : formats; |
|
if (formatAst === null) { |
|
return selector.toString(); |
|
} |
|
let simpleStart = _postcssselectorparser.default.comment({ |
|
value: "/*__simple__*/" |
|
}); |
|
let simpleEnd = _postcssselectorparser.default.comment({ |
|
value: "/*__simple__*/" |
|
}); |
|
|
|
|
|
selector.walkClasses((node)=>{ |
|
if (node.value !== base) { |
|
return; |
|
} |
|
let parent = node.parent; |
|
let formatNodes = formatAst.nodes[0].nodes; |
|
|
|
if (parent.nodes.length === 1) { |
|
node.replaceWith(...formatNodes); |
|
return; |
|
} |
|
let simpleSelector = simpleSelectorForNode(node); |
|
parent.insertBefore(simpleSelector[0], simpleStart); |
|
parent.insertAfter(simpleSelector[simpleSelector.length - 1], simpleEnd); |
|
for (let child of formatNodes){ |
|
parent.insertBefore(simpleSelector[0], child.clone()); |
|
} |
|
node.remove(); |
|
|
|
simpleSelector = simpleSelectorForNode(simpleStart); |
|
let firstNode = parent.index(simpleStart); |
|
parent.nodes.splice(firstNode, simpleSelector.length, ...resortSelector(_postcssselectorparser.default.selector({ |
|
nodes: simpleSelector |
|
})).nodes); |
|
simpleStart.remove(); |
|
simpleEnd.remove(); |
|
}); |
|
|
|
selector.walkPseudos((p)=>{ |
|
if (p.value === MERGE) { |
|
p.replaceWith(p.nodes); |
|
} |
|
}); |
|
|
|
selector.each((sel)=>(0, _pseudoElements.movePseudos)(sel)); |
|
return selector.toString(); |
|
} |
|
function handleMergePseudo(selector, format) { |
|
let merges = []; |
|
|
|
selector.walkPseudos((pseudo)=>{ |
|
if (pseudo.value === MERGE) { |
|
merges.push({ |
|
pseudo, |
|
value: pseudo.nodes[0].toString() |
|
}); |
|
} |
|
}); |
|
|
|
format.walkPseudos((pseudo)=>{ |
|
if (pseudo.value !== MERGE) { |
|
return; |
|
} |
|
let value = pseudo.nodes[0].toString(); |
|
|
|
let existing = merges.find((merge)=>merge.value === value); |
|
|
|
if (!existing) { |
|
return; |
|
} |
|
|
|
let attachments = []; |
|
let next = pseudo.next(); |
|
while(next && next.type !== "combinator"){ |
|
attachments.push(next); |
|
next = next.next(); |
|
} |
|
let combinator = next; |
|
existing.pseudo.parent.insertAfter(existing.pseudo, _postcssselectorparser.default.selector({ |
|
nodes: attachments.map((node)=>node.clone()) |
|
})); |
|
pseudo.remove(); |
|
attachments.forEach((node)=>node.remove()); |
|
|
|
|
|
|
|
if (combinator && combinator.type === "combinator") { |
|
combinator.remove(); |
|
} |
|
}); |
|
return [ |
|
selector, |
|
format |
|
]; |
|
} |
|
|