all files / src/optimizations/ RemoveUnusedStyles.js

100% Statements 27/27
100% Branches 10/10
100% Functions 2/2
100% Lines 26/26
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65                      28× 28×                   34× 34× 34×     34× 63× 63×   63× 166× 3933× 168× 166× 115×   166×             63× 27×       36×            
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Actions_1 = require("../Actions");
const Actions_2 = require("../Actions");
const Match_1 = require("../Match");
const cssIntrospection_1 = require("../util/cssIntrospection");
/**
 * Removed all rules in a single stylesheet that will never match any Selectables
 * discovered during analysis.
 */
class RemoveUnusedStyles {
    /**
     * Create a new instance of this optimizer
     * @param options - The project optimizer's options.
     */
    constructor(_options) {
        this.name = "removeUnusedStyles";
        this.initializers = [];
    }
    /**
     * Provided an OptimizationPass, all TemplateAnalyses, and a ParsedCssFile,
     * remove all unused styles.
     * @param analyses - All TemplateAnalyses found during analysis
     * @param file - The parsed CSS file to optimize.
     */
    optimizeSingleFile(pass, analyses, file) {
        // Fetch the list of all Elements discovered during analysis.
        let elements = analyses.reduce((elements, analysis) => {
            elements.push(...analysis.elements);
            return elements;
        }, new Array());
        // For each rule in the ParsedCSSFile:
        cssIntrospection_1.walkRules(file.content.root, (node) => {
            let parsedSelectors = pass.cache.getParsedSelectors(node);
            let reason = undefined;
            // Check if it matches any element discovered during analysis.
            let found = parsedSelectors.filter((value) => {
                return value.eachCompoundSelector((selector) => {
                    let found = elements.find((element) => Match_1.matches(Match_1.ElementMatcher.instance.matchSelectorComponent(element, selector)));
                    if (!found || selector === value.key) {
                        if (!found) {
                            reason = `no element found that matches ${selector.toString(true)}`;
                        }
                        return !!found;
                    }
                    else {
                        return;
                    }
                });
            });
            // If no elements discovered during Analysis match this style, remove the rule.
            if (found.length === 0) {
                pass.actions.perform(new Actions_1.RemoveRule(node, "removeUnusedStyles", reason, pass.cache));
            }
            // QUESTION: @Chris, what does this do?
            else {
                if (found.length < parsedSelectors.length) {
                    pass.actions.perform(new Actions_2.ChangeSelector(node, found.join(", "), "removeUnusedStyles", reason, pass.cache));
                }
            }
        });
    }
}
exports.RemoveUnusedStyles = RemoveUnusedStyles;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVtb3ZlVW51c2VkU3R5bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL29wdGltaXphdGlvbnMvUmVtb3ZlVW51c2VkU3R5bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBR0Esd0NBQXdDO0FBQ3hDLHdDQUE0QztBQUc1QyxvQ0FBbUQ7QUFHbkQsK0RBQXFEO0FBSXJEOzs7R0FHRztBQUNIO0lBSUU7OztPQUdHO0lBQ0gsWUFBWSxRQUF3QjtRQVBwQyxTQUFJLEdBQUcsb0JBQW9CLENBQUM7UUFDNUIsaUJBQVksR0FBOEIsRUFBRSxDQUFDO0lBTzdDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGtCQUFrQixDQUNoQixJQUFzQixFQUN0QixRQUFzRCxFQUN0RCxJQUFtQjtRQUluQiw2REFBNkQ7UUFDN0QsSUFBSSxRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FDM0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUU7WUFDeEIsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNwQyxPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDLEVBQUUsSUFBSSxLQUFLLEVBQVcsQ0FBQyxDQUFDO1FBRXpCLHNDQUFzQztRQUN0Qyw0QkFBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDckMsSUFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxRCxJQUFJLE1BQU0sR0FBdUIsU0FBUyxDQUFDO1lBRTNDLDhEQUE4RDtZQUM5RCxJQUFJLEtBQUssR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQzNDLE9BQU8sS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7b0JBQzdDLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLGVBQU8sQ0FBQyxzQkFBYyxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNuSCxJQUFJLENBQUMsS0FBSyxJQUFJLFFBQVEsS0FBSyxLQUFLLENBQUMsR0FBRyxFQUFFO3dCQUNwQyxJQUFJLENBQUMsS0FBSyxFQUFFOzRCQUNWLE1BQU0sR0FBRyxpQ0FBaUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO3lCQUNyRTt3QkFDRCxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUM7cUJBQ2hCO3lCQUFNO3dCQUNMLE9BQU87cUJBQ1I7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUVILCtFQUErRTtZQUMvRSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLG9CQUFVLENBQUMsSUFBSSxFQUFFLG9CQUFvQixFQUFFLE1BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzthQUN2RjtZQUVELHVDQUF1QztpQkFDbEM7Z0JBQ0gsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLGVBQWUsQ0FBQyxNQUFNLEVBQUU7b0JBQ3pDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksd0JBQWMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxNQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7aUJBQzdHO2FBQ0Y7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQWhFRCxnREFnRUMifQ==