fontmin-spider
Version:
Analyze which fonts are used on the page and eliminate the ones that are not used to get a smaller font file
114 lines (113 loc) • 5.13 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseSelector = exports.parseUseFamily = exports.getUseFamily = void 0;
const node_fs_1 = require("node:fs");
const postcss_1 = __importDefault(require("postcss"));
const _1 = require(".");
/**
* Get font used
* @param { Tkv } declaredFamilyMap Mapping of used fonts
* @param { string | Buffer } content css file content
*/
function getUseFamily(declaredFamilyMap, content) {
let family = '';
(0, postcss_1.default)({
postcssPlugin: 'fontmin-spider-get-use-family',
Once(root) {
root.walkDecls(/^(font-family|font)$/, (decl) => {
family = decl.value;
if (decl.prop === 'font') {
const font = Object.entries(declaredFamilyMap).find(([k]) => family.match(new RegExp(k)));
if (font)
family = font[0];
}
family = family.split(',').find((item) => declaredFamilyMap[(0, _1.getQuoteless)(item.trim())]) || '';
family = (0, _1.getQuoteless)(family);
});
}
}).process(content).css;
return family;
}
exports.getUseFamily = getUseFamily;
/**
* Parsing the fonts used
* @param { string } basePath You can think of it as the root of the website
* @param { Tkv } declaredFamilyMap Mapping of used fonts
* @param { string | Buffer } content css file content
* @param { string } importPath css file path
*/
function parseUseFamily(basePath, declaredFamilyMap, content, importPath) {
(0, postcss_1.default)({
postcssPlugin: 'fontmin-spider-parse-use-family',
Once(root) {
root.walkAtRules('font-face', (rule) => {
let tmpFontName = '';
let tmpSourcePath = '';
rule.walkDecls(/font-family|src/, (decl) => {
if (decl.value && decl.value.includes('url(')) {
(0, _1.getUrls)(decl.value).forEach((meta) => {
const sourcePath = (0, _1.removeParam)(meta.value);
const filePath = (0, _1.getAbsolutePath)(basePath, importPath, sourcePath);
if ((0, node_fs_1.existsSync)(filePath) && (0, node_fs_1.statSync)(filePath).isFile()) {
tmpSourcePath = filePath;
}
});
}
else {
tmpFontName = (0, _1.getQuoteless)(decl.value);
}
});
if (tmpFontName && tmpSourcePath) {
declaredFamilyMap[tmpFontName] = {};
declaredFamilyMap[tmpFontName].selector = [];
declaredFamilyMap[tmpFontName].path = tmpSourcePath;
declaredFamilyMap[tmpFontName].chars = '';
}
});
}
}).process(content).css;
}
exports.parseUseFamily = parseUseFamily;
/**
* Parse the selector that uses fonts
* @param { Tkv } declaredFamilyMap Mapping of used fonts
* @param { string | Buffer } content css file content
*/
function parseSelector(declaredFamilyMap, content) {
(0, postcss_1.default)({
postcssPlugin: 'fontmin-spider-family-parse',
Once(root) {
const reg = /:?:(active|hover|focus|before|after)/g;
root.walkDecls(/^(font-family|font)$/, (decl) => {
var _a;
let content = '';
let family = decl.value;
let selector = decl.parent && decl.parent.selector;
if (!selector)
return;
if (reg.test(selector)) {
const value = (_a = decl.parent) === null || _a === void 0 ? void 0 : _a.nodes.find((node) => node.prop === 'content');
if (value)
content = (0, _1.getQuoteless)(value.value);
}
selector = selector.replace(reg, '').replace(/\r?\n/g, '');
if (decl.prop === 'font') {
const font = Object.entries(declaredFamilyMap).find(([k]) => family.match(new RegExp(k)));
if (font)
family = font[0];
}
family = family.split(',').find((item) => declaredFamilyMap[(0, _1.getQuoteless)(item.trim())]) || '';
family = (0, _1.getQuoteless)(family);
if (selector && declaredFamilyMap[family]) {
if (!declaredFamilyMap[family].selector.includes(selector))
declaredFamilyMap[family].selector.push(selector);
declaredFamilyMap[family].chars += content;
}
});
}
}).process(content).css;
}
exports.parseSelector = parseSelector;