astro-ghostcms/.pnpm-store/v3/files/14/defcb70f3b266df8e90ad58d42e...

196 lines
7.3 KiB
Plaintext

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const core = require('@unocss/core');
const cssTree = require('css-tree');
const ruleUtils = require('@unocss/rule-utils');
function handleThemeFn({ code, uno, options }, node) {
const { throwOnMissing = true } = options;
const offset = node.value.loc.start.offset;
const str = code.original.slice(offset, node.value.loc.end.offset);
code.overwrite(offset, node.value.loc.end.offset, ruleUtils.transformThemeFn(str, uno.config.theme, throwOnMissing));
}
const screenRuleRE = /(@screen) (.+) /g;
function handleScreen({ code, uno }, node) {
let breakpointName = "";
let prefix = "";
if (node.name === "screen" && node.prelude?.type === "Raw")
breakpointName = node.prelude.value.trim();
if (!breakpointName)
return;
const match = breakpointName.match(/^(?:(lt|at)-)?(\w+)$/);
if (match) {
prefix = match[1];
breakpointName = match[2];
}
const resolveBreakpoints = () => {
let breakpoints;
if (uno.userConfig && uno.userConfig.theme)
breakpoints = uno.userConfig.theme.breakpoints;
if (!breakpoints)
breakpoints = uno.config.theme.breakpoints;
return breakpoints ? Object.entries(breakpoints).sort((a, b) => Number.parseInt(a[1].replace(/[a-z]+/gi, "")) - Number.parseInt(b[1].replace(/[a-z]+/gi, ""))).map(([point, size]) => ({ point, size })) : void 0;
};
const variantEntries = (resolveBreakpoints() ?? []).map(({ point, size }, idx) => [point, size, idx]);
const generateMediaQuery = (breakpointName2, prefix2) => {
const [, size, idx] = variantEntries.find((i) => i[0] === breakpointName2);
if (prefix2) {
if (prefix2 === "lt")
return `@media (max-width: ${calcMaxWidthBySize(size)})`;
else if (prefix2 === "at")
return `@media (min-width: ${size})${variantEntries[idx + 1] ? ` and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})` : ""}`;
else
throw new Error(`breakpoint variant not supported: ${prefix2}`);
}
return `@media (min-width: ${size})`;
};
if (!variantEntries.find((i) => i[0] === breakpointName))
throw new Error(`breakpoint ${breakpointName} not found`);
const offset = node.loc.start.offset;
const str = code.original.slice(offset, node.loc.end.offset);
const matches = Array.from(str.matchAll(screenRuleRE));
if (!matches.length)
return;
for (const match2 of matches) {
code.overwrite(
offset + match2.index,
offset + match2.index + match2[0].length,
`${generateMediaQuery(breakpointName, prefix)} `
);
}
}
function calcMaxWidthBySize(size) {
const value = size.match(/^-?[0-9]+\.?[0-9]*/)?.[0] || "";
const unit = size.slice(value.length);
const maxWidth = Number.parseFloat(value) - 0.1;
return Number.isNaN(maxWidth) ? size : `${maxWidth}${unit}`;
}
async function handleApply(ctx, node) {
const { code, uno, options, filename, offset } = ctx;
const calcOffset = (pos) => offset ? pos + offset : pos;
await Promise.all(
node.block.children.map(async (childNode) => {
if (childNode.type === "Raw")
return transformDirectives(code, uno, options, filename, childNode.value, calcOffset(childNode.loc.start.offset));
await parseApply(ctx, node, childNode);
}).toArray()
);
}
async function parseApply({ code, uno, offset, applyVariable }, node, childNode) {
const calcOffset = (pos) => offset ? pos + offset : pos;
let body;
if (childNode.type === "Atrule" && childNode.name === "apply" && childNode.prelude && childNode.prelude.type === "Raw") {
body = childNode.prelude.value.trim();
} else if (childNode.type === "Declaration" && applyVariable.includes(childNode.property) && childNode.value.type === "Raw") {
body = childNode.value.value.trim();
if (body.match(/^(['"]).*\1$/))
body = body.slice(1, -1);
}
if (!body)
return;
const classNames = core.expandVariantGroup(body).split(/\s+/g).map((className) => className.trim().replace(/\\/, ""));
const utils = (await Promise.all(
classNames.map((i) => uno.parseToken(i, "-"))
)).filter(core.notNull).flat().sort((a, b) => a[0] - b[0]).sort((a, b) => (a[3] ? uno.parentOrders.get(a[3]) ?? 0 : 0) - (b[3] ? uno.parentOrders.get(b[3]) ?? 0 : 0)).reduce((acc, item) => {
const target = acc.find((i) => i[1] === item[1] && i[3] === item[3]);
if (target)
target[2] += item[2];
else
acc.push([...item]);
return acc;
}, []);
if (!utils.length)
return;
for (const i of utils) {
const [, _selector, body2, parent] = i;
const selector = _selector?.replace(core.regexScopePlaceholder, " ") || _selector;
if (parent || selector && selector !== ".\\-") {
let newSelector = cssTree.generate(node.prelude);
if (selector && selector !== ".\\-") {
const selectorAST = cssTree.parse(selector, {
context: "selector"
});
const prelude = cssTree.clone(node.prelude);
prelude.children.forEach((child) => {
const parentSelectorAst = cssTree.clone(selectorAST);
parentSelectorAst.children.forEach((i2) => {
if (i2.type === "ClassSelector" && i2.name === "\\-")
Object.assign(i2, cssTree.clone(child));
});
Object.assign(child, parentSelectorAst);
});
newSelector = cssTree.generate(prelude);
}
let css = `${newSelector}{${body2}}`;
if (parent)
css = `${parent}{${css}}`;
code.appendLeft(calcOffset(node.loc.end.offset), css);
} else {
code.appendRight(calcOffset(childNode.loc.end.offset), body2);
}
}
code.remove(
calcOffset(childNode.loc.start.offset),
calcOffset(childNode.loc.end.offset)
);
}
function transformerDirectives(options = {}) {
return {
name: "@unocss/transformer-directives",
enforce: options?.enforce,
idFilter: (id) => !!id.match(core.cssIdRE),
transform: (code, id, ctx) => {
return transformDirectives(code, ctx.uno, options, id);
}
};
}
async function transformDirectives(code, uno, options, filename, originalCode, offset) {
let { applyVariable } = options;
const varStyle = options.varStyle;
if (applyVariable === void 0) {
if (varStyle !== void 0)
applyVariable = varStyle ? [`${varStyle}apply`] : [];
applyVariable = ["--at-apply", "--uno-apply", "--uno"];
}
applyVariable = core.toArray(applyVariable || []);
const hasApply = code.original.includes("@apply") || applyVariable.some((s) => code.original.includes(s));
const hasScreen = code.original.includes("@screen");
const hasThemeFn = ruleUtils.hasThemeFn(code.original);
if (!hasApply && !hasThemeFn && !hasScreen)
return;
const ast = cssTree.parse(originalCode || code.original, {
parseAtrulePrelude: false,
positions: true,
filename
});
if (ast.type !== "StyleSheet")
return;
const stack = [];
const ctx = {
options,
applyVariable,
uno,
code,
filename,
offset
};
const processNode = async (node, _item, _list) => {
if (hasScreen && node.type === "Atrule")
handleScreen(ctx, node);
if (hasThemeFn && node.type === "Declaration")
handleThemeFn(ctx, node);
if (hasApply && node.type === "Rule")
await handleApply(ctx, node);
};
cssTree.walk(ast, (...args) => stack.push(processNode(...args)));
await Promise.all(stack);
}
exports.default = transformerDirectives;
exports.transformDirectives = transformDirectives;