UNPKG

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

118 lines (117 loc) 5.84 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const htmlparser2_1 = require("htmlparser2"); const css_select_1 = __importDefault(require("css-select")); const domutils_1 = require("domutils"); const parse_family_map_1 = require("./utils/parse-family-map"); const utils_1 = require("./utils"); /** * Parsing the fonts used * @param { string } basePath You can think of it as the root of the website * @param { string[] } files Array of html files * @param { Function } filter Execute when all the used fonts are parsed * (the strings are not parsed, you can use the afterFilter method if you need to process the strings) * @param { Function } afterFilter After parsing is complete, execute * @returns { TdeclaredFamilyMap } */ /* eslint-disable max-depth,max-statements */ function parse(basePath, files, filter, afterFilter) { const declaredFamilyMap = {}; const caches = new Map(); const cacheDocment = new Map(); const cacheDocments = new Map(); const getDocument = (file) => (0, htmlparser2_1.parseDocument)((0, node_fs_1.readFileSync)(file).toString()); try { for (const file of files) { const doc = cacheDocment.has(file) ? cacheDocment.get(file) : getDocument(file); const sources = cacheDocments.has(file) ? cacheDocments.get(file) : (0, css_select_1.default)('style,link[href],[style]', doc); cacheDocment.set(file, doc); cacheDocments.set(file, sources); for (const source of sources) { // handler style tags if (source.name === 'style') { const StyleTextContent = (0, domutils_1.textContent)(source); const hash = (0, utils_1.getHash)(StyleTextContent); if (!caches.has(hash)) { caches.set(hash, StyleTextContent); (0, parse_family_map_1.parseUseFamily)(basePath, declaredFamilyMap, StyleTextContent, file); } continue; } // handler link tags const sourcePath = (0, utils_1.removeParam)(source.attribs.href || ''); const sourceAbsolutePath = (0, utils_1.getAbsolutePath)(basePath, file, sourcePath); if ((0, node_path_1.extname)(sourcePath) === '.css' && (0, node_fs_1.existsSync)(sourceAbsolutePath) && (0, node_fs_1.statSync)(sourceAbsolutePath).isFile() && !caches.has(sourceAbsolutePath)) { const data = (0, node_fs_1.readFileSync)(sourceAbsolutePath); caches.set(sourceAbsolutePath, data); (0, parse_family_map_1.parseUseFamily)(basePath, declaredFamilyMap, data, sourceAbsolutePath); continue; } } } // custom filter font filter && filter(declaredFamilyMap); for (const file of files) { const doc = cacheDocment.has(file) ? cacheDocment.get(file) : getDocument(file); const sources = cacheDocments.has(file) ? cacheDocments.get(file) : (0, css_select_1.default)('style,link[href],[style]', doc); for (const source of sources) { // handler style tags if (source.name === 'style') { const StyleTextContent = (0, domutils_1.textContent)(source); (0, parse_family_map_1.parseSelector)(declaredFamilyMap, StyleTextContent); continue; } // handler link tags const sourcePath = (0, utils_1.removeParam)(source.attribs.href || ''); const sourceAbsolutePath = (0, utils_1.getAbsolutePath)(basePath, file, sourcePath); if ((0, node_path_1.extname)(sourcePath) === '.css' && (0, node_fs_1.existsSync)(sourceAbsolutePath) && (0, node_fs_1.statSync)(sourceAbsolutePath).isFile()) { const data = caches.has(sourceAbsolutePath) ? caches.get(sourceAbsolutePath) : (0, node_fs_1.readFileSync)(sourceAbsolutePath); (0, parse_family_map_1.parseSelector)(declaredFamilyMap, data); continue; } const AttrStyleContent = source.attribs.style || ''; if (!AttrStyleContent) continue; const family = (0, parse_family_map_1.getUseFamily)(declaredFamilyMap, AttrStyleContent); if (declaredFamilyMap[family]) { declaredFamilyMap[family].chars += (0, domutils_1.textContent)(source); } } getText(doc, declaredFamilyMap); } // custom filter font afterFilter && afterFilter(declaredFamilyMap); } catch (error) { // eslint-disable-next-line no-console console.error('\x1b[31mfontmin-spider Error:\x1b[39m', error); } return declaredFamilyMap; } exports.default = parse; /* eslint-enable */ function getText(dom, familyMap) { for (const key in familyMap) { const value = familyMap[key]; if (!value) continue; value.selector.map((item) => { const node = (0, css_select_1.default)(item, dom); familyMap[key].chars += (0, domutils_1.textContent)(node); }); } }