blob: 2de1350464da201e0e96b5ba33cb906f99c4b825 [file] [log] [blame]
Jack Franklina5fd0a42022-12-09 11:30:24 +00001'use strict';
2const valueParser = require('postcss-value-parser');
3const minifyWeight = require('./lib/minify-weight');
4const minifyFamily = require('./lib/minify-family');
5const minifyFont = require('./lib/minify-font');
6
7/**
8 * @param {string} value
9 * @return {boolean}
10 */
11function hasVariableFunction(value) {
12 const lowerCasedValue = value.toLowerCase();
13
14 return lowerCasedValue.includes('var(') || lowerCasedValue.includes('env(');
15}
16
17/**
18 * @param {string} prop
19 * @param {string} value
20 * @param {Options} opts
21 * @return {string}
22 */
23function transform(prop, value, opts) {
24 let lowerCasedProp = prop.toLowerCase();
25
26 if (lowerCasedProp === 'font-weight' && !hasVariableFunction(value)) {
27 return minifyWeight(value);
28 } else if (lowerCasedProp === 'font-family' && !hasVariableFunction(value)) {
29 const tree = valueParser(value);
30
31 tree.nodes = minifyFamily(tree.nodes, opts);
32
33 return tree.toString();
34 } else if (lowerCasedProp === 'font') {
35 const tree = valueParser(value);
36
37 tree.nodes = minifyFont(tree.nodes, opts);
38
39 return tree.toString();
40 }
41
42 return value;
43}
44
45/** @typedef {{removeAfterKeyword?: boolean, removeDuplicates?: boolean, removeQuotes?: boolean}} Options */
46
47/**
48 * @type {import('postcss').PluginCreator<Options>}
49 * @param {Options} opts
50 * @return {import('postcss').Plugin}
51 */
52function pluginCreator(opts) {
53 opts = Object.assign(
54 {},
55 {
56 removeAfterKeyword: false,
57 removeDuplicates: true,
58 removeQuotes: true,
59 },
60 opts
61 );
62
63 return {
64 postcssPlugin: 'postcss-minify-font-values',
65 prepare() {
66 const cache = new Map();
67 return {
68 OnceExit(css) {
69 css.walkDecls(/font/i, (decl) => {
70 const value = decl.value;
71
72 if (!value) {
73 return;
74 }
75
76 const prop = decl.prop;
77
78 const cacheKey = `${prop}|${value}`;
79
80 if (cache.has(cacheKey)) {
81 decl.value = cache.get(cacheKey);
82
83 return;
84 }
85
86 const newValue = transform(prop, value, opts);
87
88 decl.value = newValue;
89 cache.set(cacheKey, newValue);
90 });
91 },
92 };
93 },
94 };
95}
96
97pluginCreator.postcss = true;
98module.exports = pluginCreator;