|
|
@@ -171,63 +171,42 @@ this.fontsMinifier = this.fontsMinifier || (() => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- function getPropertyValue(cssRule, propertyName) {
|
|
|
- const property = cssRule.block.children.filter(node => node.property == propertyName).tail;
|
|
|
- if (property) {
|
|
|
- return cssTree.generate(property.data.value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function getFontFamilyNames(declarations) {
|
|
|
- let fontFamilyName = declarations.children.filter(node => node.property == "font-family").tail;
|
|
|
- let fontFamilyNames = [];
|
|
|
- if (fontFamilyName) {
|
|
|
- let familyName = "";
|
|
|
- fontFamilyName.data.value.children.forEach(node => {
|
|
|
- if (node.type == "Operator" && node.value == "," && familyName) {
|
|
|
- fontFamilyNames.push(getFontFamily(familyName));
|
|
|
- familyName = "";
|
|
|
- } else {
|
|
|
- familyName += cssTree.generate(node);
|
|
|
- }
|
|
|
- });
|
|
|
- if (familyName) {
|
|
|
- fontFamilyNames.push(getFontFamily(familyName));
|
|
|
- }
|
|
|
- }
|
|
|
- const font = declarations.children.filter(node => node.property == "font").tail;
|
|
|
- if (font) {
|
|
|
- for (let node = font.data.value.children.tail; node && node.data.type != "WhiteSpace"; node = node.prev) {
|
|
|
- if (node.data.type == "String" || node.data.type == "Identifier") {
|
|
|
- fontFamilyNames.push(getFontFamily(cssTree.generate(node.data)));
|
|
|
+ function filterUnusedFonts(rules, declaredFonts, unusedFonts, filteredUsedFonts, docContent) {
|
|
|
+ const removedRules = [];
|
|
|
+ for (let rule = rules.head; rule; rule = rule.next) {
|
|
|
+ const ruleData = rule.data;
|
|
|
+ if (ruleData.type == "Atrule" && ruleData.name == "media") {
|
|
|
+ filterUnusedFonts(ruleData.block.children, declaredFonts, unusedFonts, filteredUsedFonts, docContent);
|
|
|
+ } else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
|
|
|
+ const fontFamily = getFontFamily(getPropertyValue(ruleData, "font-family"));
|
|
|
+ if (fontFamily) {
|
|
|
+ const unicodeRange = getPropertyValue(ruleData, "unicode-range");
|
|
|
+ if (unusedFonts.find(fontInfo => fontInfo.fontFamily == fontFamily) || !testUnicodeRange(docContent, unicodeRange) || !testUsedFont(ruleData, fontFamily, declaredFonts, filteredUsedFonts)) {
|
|
|
+ removedRules.push(rule);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return fontFamilyNames;
|
|
|
+ removedRules.forEach(rule => rules.remove(rule));
|
|
|
}
|
|
|
|
|
|
- function getFontsDetails(doc, cssRules, fontsDetails) {
|
|
|
- cssRules.forEach(cssRule => {
|
|
|
- if (cssRule.type == "Atrule" && cssRule.name == "media") {
|
|
|
- getFontsDetails(doc, cssRule.block.children, fontsDetails);
|
|
|
- } else {
|
|
|
- if (cssRule.type == "Atrule" && cssRule.name == "font-face") {
|
|
|
- const fontKey = getFontKey(cssRule);
|
|
|
- let fontInfo = fontsDetails.get(fontKey);
|
|
|
- if (!fontInfo) {
|
|
|
- fontInfo = [];
|
|
|
- fontsDetails.set(fontKey, fontInfo);
|
|
|
- }
|
|
|
- const src = getPropertyValue(cssRule, "src");
|
|
|
- if (src) {
|
|
|
- const fontSources = src.match(REGEXP_URL_FUNCTION);
|
|
|
- if (fontSources) {
|
|
|
- fontSources.forEach(source => fontInfo.unshift(source));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
+ function testUsedFont(rule, familyName, declaredFonts, filteredUsedFonts) {
|
|
|
+ let test;
|
|
|
+ const optionalUsedFonts = filteredUsedFonts && filteredUsedFonts.get(familyName);
|
|
|
+ if (optionalUsedFonts && optionalUsedFonts.length) {
|
|
|
+ const fontStyle = getPropertyValue(rule, "font-style") || "normal";
|
|
|
+ const fontWeight = getFontWeight(getPropertyValue(rule, "font-weight") || "400");
|
|
|
+ const fontVariant = getPropertyValue(rule, "font-variant") || "normal";
|
|
|
+ const declaredFontsWeights = declaredFonts
|
|
|
+ .filter(fontInfo => fontInfo.fontFamily == familyName && fontInfo.fontStyle == fontStyle && testFontVariant(fontInfo, fontVariant))
|
|
|
+ .map(fontInfo => fontInfo.fontWeight)
|
|
|
+ .sort((weight1, weight2) => weight1 - weight2);
|
|
|
+ const usedFontWeights = optionalUsedFonts.map(fontInfo => findFontWeight(fontInfo.fontWeight, declaredFontsWeights));
|
|
|
+ test = usedFontWeights.includes(fontWeight);
|
|
|
+ } else {
|
|
|
+ test = true;
|
|
|
+ }
|
|
|
+ return test;
|
|
|
}
|
|
|
|
|
|
function processFontFaceRules(cssRules, fontsDetails, media, stats) {
|
|
|
@@ -295,42 +274,63 @@ this.fontsMinifier = this.fontsMinifier || (() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- function filterUnusedFonts(rules, declaredFonts, unusedFonts, filteredUsedFonts, docContent) {
|
|
|
- const removedRules = [];
|
|
|
- for (let rule = rules.head; rule; rule = rule.next) {
|
|
|
- const ruleData = rule.data;
|
|
|
- if (ruleData.type == "Atrule" && ruleData.name == "media") {
|
|
|
- filterUnusedFonts(ruleData.block.children, declaredFonts, unusedFonts, filteredUsedFonts, docContent);
|
|
|
- } else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
|
|
|
- const fontFamily = getFontFamily(getPropertyValue(ruleData, "font-family"));
|
|
|
- if (fontFamily) {
|
|
|
- const unicodeRange = getPropertyValue(ruleData, "unicode-range");
|
|
|
- if (unusedFonts.find(fontInfo => fontInfo.fontFamily == fontFamily) || !testUnicodeRange(docContent, unicodeRange) || !testUsedFont(ruleData, fontFamily, declaredFonts, filteredUsedFonts)) {
|
|
|
- removedRules.push(rule);
|
|
|
- }
|
|
|
+ function getPropertyValue(cssRule, propertyName) {
|
|
|
+ const property = cssRule.block.children.filter(node => node.property == propertyName).tail;
|
|
|
+ if (property) {
|
|
|
+ return cssTree.generate(property.data.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function getFontFamilyNames(declarations) {
|
|
|
+ let fontFamilyName = declarations.children.filter(node => node.property == "font-family").tail;
|
|
|
+ let fontFamilyNames = [];
|
|
|
+ if (fontFamilyName) {
|
|
|
+ let familyName = "";
|
|
|
+ fontFamilyName.data.value.children.forEach(node => {
|
|
|
+ if (node.type == "Operator" && node.value == "," && familyName) {
|
|
|
+ fontFamilyNames.push(getFontFamily(familyName));
|
|
|
+ familyName = "";
|
|
|
+ } else {
|
|
|
+ familyName += cssTree.generate(node);
|
|
|
}
|
|
|
+ });
|
|
|
+ if (familyName) {
|
|
|
+ fontFamilyNames.push(getFontFamily(familyName));
|
|
|
}
|
|
|
}
|
|
|
- removedRules.forEach(rule => rules.remove(rule));
|
|
|
+ const font = declarations.children.filter(node => node.property == "font").tail;
|
|
|
+ if (font) {
|
|
|
+ for (let node = font.data.value.children.tail; node && node.data.type != "WhiteSpace"; node = node.prev) {
|
|
|
+ if (node.data.type == "String" || node.data.type == "Identifier") {
|
|
|
+ fontFamilyNames.push(getFontFamily(cssTree.generate(node.data)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fontFamilyNames;
|
|
|
}
|
|
|
|
|
|
- function testUsedFont(rule, familyName, declaredFonts, filteredUsedFonts) {
|
|
|
- let test;
|
|
|
- const optionalUsedFonts = filteredUsedFonts && filteredUsedFonts.get(familyName);
|
|
|
- if (optionalUsedFonts && optionalUsedFonts.length) {
|
|
|
- const fontStyle = getPropertyValue(rule, "font-style") || "normal";
|
|
|
- const fontWeight = getFontWeight(getPropertyValue(rule, "font-weight") || "400");
|
|
|
- const fontVariant = getPropertyValue(rule, "font-variant") || "normal";
|
|
|
- const declaredFontsWeights = declaredFonts
|
|
|
- .filter(fontInfo => fontInfo.fontFamily == familyName && fontInfo.fontStyle == fontStyle && testFontVariant(fontInfo, fontVariant))
|
|
|
- .map(fontInfo => fontInfo.fontWeight)
|
|
|
- .sort((weight1, weight2) => weight1 - weight2);
|
|
|
- const usedFontWeights = optionalUsedFonts.map(fontInfo => findFontWeight(fontInfo.fontWeight, declaredFontsWeights));
|
|
|
- test = usedFontWeights.includes(fontWeight);
|
|
|
- } else {
|
|
|
- test = true;
|
|
|
- }
|
|
|
- return test;
|
|
|
+ function getFontsDetails(doc, cssRules, fontsDetails) {
|
|
|
+ cssRules.forEach(cssRule => {
|
|
|
+ if (cssRule.type == "Atrule" && cssRule.name == "media") {
|
|
|
+ getFontsDetails(doc, cssRule.block.children, fontsDetails);
|
|
|
+ } else {
|
|
|
+ if (cssRule.type == "Atrule" && cssRule.name == "font-face") {
|
|
|
+ const fontKey = getFontKey(cssRule);
|
|
|
+ let fontInfo = fontsDetails.get(fontKey);
|
|
|
+ if (!fontInfo) {
|
|
|
+ fontInfo = [];
|
|
|
+ fontsDetails.set(fontKey, fontInfo);
|
|
|
+ }
|
|
|
+ const src = getPropertyValue(cssRule, "src");
|
|
|
+ if (src) {
|
|
|
+ const fontSources = src.match(REGEXP_URL_FUNCTION);
|
|
|
+ if (fontSources) {
|
|
|
+ fontSources.forEach(source => fontInfo.unshift(source));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
function findFontWeight(fontWeight, fontWeights) {
|