%PDF- %PDF-
Direktori : /var/www/cwg/wp-content/themes/cwg/node_modules/tailwindcss/lib/jit/lib/ |
Current File : //var/www/cwg/wp-content/themes/cwg/node_modules/tailwindcss/lib/jit/lib/expandApplyAtRules.js |
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = expandApplyAtRules; var _postcss = _interopRequireDefault(require("postcss")); var _generateRules = require("./generateRules"); var _bigSign = _interopRequireDefault(require("../../util/bigSign")); var _escapeClassName = _interopRequireDefault(require("../../util/escapeClassName")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function buildApplyCache(applyCandidates, context) { for (let candidate of applyCandidates) { if (context.notClassCache.has(candidate) || context.applyClassCache.has(candidate)) { continue; } if (context.classCache.has(candidate)) { context.applyClassCache.set(candidate, context.classCache.get(candidate).map(([meta, rule]) => [meta, rule.clone()])); continue; } let matches = Array.from((0, _generateRules.resolveMatches)(candidate, context)); if (matches.length === 0) { context.notClassCache.add(candidate); continue; } context.applyClassCache.set(candidate, matches); } return context.applyClassCache; } function extractApplyCandidates(params) { let candidates = params.split(/[\s\t\n]+/g); if (candidates[candidates.length - 1] === '!important') { return [candidates.slice(0, -1), true]; } return [candidates, false]; } function partitionApplyParents(root) { let applyParents = new Set(); root.walkAtRules('apply', rule => { applyParents.add(rule.parent); }); for (let rule of applyParents) { let nodeGroups = []; let lastGroup = []; for (let node of rule.nodes) { if (node.type === 'atrule' && node.name === 'apply') { if (lastGroup.length > 0) { nodeGroups.push(lastGroup); lastGroup = []; } nodeGroups.push([node]); } else { lastGroup.push(node); } } if (lastGroup.length > 0) { nodeGroups.push(lastGroup); } if (nodeGroups.length === 1) { continue; } for (let group of [...nodeGroups].reverse()) { let newParent = rule.clone({ nodes: [] }); newParent.append(group); rule.after(newParent); } rule.remove(); } } function processApply(root, context) { let applyCandidates = new Set(); // Collect all @apply rules and candidates let applies = []; root.walkAtRules('apply', rule => { let [candidates] = extractApplyCandidates(rule.params); for (let util of candidates) { applyCandidates.add(util); } applies.push(rule); }); // Start the @apply process if we have rules with @apply in them if (applies.length > 0) { // Fill up some caches! let applyClassCache = buildApplyCache(applyCandidates, context); /** * When we have an apply like this: * * .abc { * @apply hover:font-bold; * } * * What we essentially will do is resolve to this: * * .abc { * @apply .hover\:font-bold:hover { * font-weight: 500; * } * } * * Notice that the to-be-applied class is `.hover\:font-bold:hover` and that the utility candidate was `hover:font-bold`. * What happens in this function is that we prepend a `.` and escape the candidate. * This will result in `.hover\:font-bold` * Which means that we can replace `.hover\:font-bold` with `.abc` in `.hover\:font-bold:hover` resulting in `.abc:hover` */ // TODO: Should we use postcss-selector-parser for this instead? function replaceSelector(selector, utilitySelectors, candidate) { let needle = `.${(0, _escapeClassName.default)(candidate)}`; let utilitySelectorsList = utilitySelectors.split(/\s*,\s*/g); return selector.split(/\s*,\s*/g).map(s => { let replaced = []; for (let utilitySelector of utilitySelectorsList) { let replacedSelector = utilitySelector.replace(needle, s); if (replacedSelector === utilitySelector) { continue; } replaced.push(replacedSelector); } return replaced.join(', '); }).join(', '); } let perParentApplies = new Map(); // Collect all apply candidates and their rules for (let apply of applies) { let candidates = perParentApplies.get(apply.parent) || []; perParentApplies.set(apply.parent, candidates); let [applyCandidates, important] = extractApplyCandidates(apply.params); if (apply.parent.type === 'atrule') { if (apply.parent.name === 'screen') { const screenType = apply.parent.params; throw apply.error(`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${applyCandidates.map(c => `${screenType}:${c}`).join(' ')} instead.`); } throw apply.error(`@apply is not supported within nested at-rules like @${apply.parent.name}. You can fix this by un-nesting @${apply.parent.name}.`); } for (let applyCandidate of applyCandidates) { if (!applyClassCache.has(applyCandidate)) { throw apply.error(`The \`${applyCandidate}\` class does not exist. If \`${applyCandidate}\` is a custom class, make sure it is defined within a \`@layer\` directive.`); } let rules = applyClassCache.get(applyCandidate); candidates.push([applyCandidate, important, rules]); } } for (const [parent, candidates] of perParentApplies) { let siblings = []; for (let [applyCandidate, important, rules] of candidates) { for (let [meta, node] of rules) { let root = _postcss.default.root({ nodes: [node.clone()] }); let canRewriteSelector = node.type !== 'atrule' || node.type === 'atrule' && node.name !== 'keyframes'; if (canRewriteSelector) { root.walkRules(rule => { rule.selector = replaceSelector(parent.selector, rule.selector, applyCandidate); rule.walkDecls(d => { d.important = meta.important || important; }); }); } siblings.push([meta, root.nodes[0]]); } } // Inject the rules, sorted, correctly let nodes = siblings.sort(([a], [z]) => (0, _bigSign.default)(a.sort - z.sort)).map(s => s[1]); // console.log(parent) // `parent` refers to the node at `.abc` in: .abc { @apply mt-2 } parent.after(nodes); } for (let apply of applies) { // If there are left-over declarations, just remove the @apply if (apply.parent.nodes.length > 1) { apply.remove(); } else { // The node is empty, drop the full node apply.parent.remove(); } } // Do it again, in case we have other `@apply` rules processApply(root, context); } } function expandApplyAtRules(context) { return root => { partitionApplyParents(root); processApply(root, context); }; }