all files / src/optimizations/MergeDeclarations/ DeclarationMapper.js

95.79% Statements 91/95
81.25% Branches 13/16
100% Functions 6/6
95.74% Lines 90/94
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168              34× 34× 34× 679× 679× 511× 679× 511× 679×   34× 34× 34× 34× 34× 34× 151×   151× 151× 185×   185×   151× 169× 169× 169× 169×   169×                           169× 169× 255×   169×       34× 34× 34× 34× 169×   169× 169× 255× 255× 255× 255× 255×       83× 83× 83× 83× 224× 224× 224×     224× 224× 224× 224×   83×       172× 172× 172×     172× 172× 172×             34×         396×                         396×     255× 396×   255×     396× 650× 650× 114× 114× 114×     536×         1022×   1022× 511× 511×   1283×    
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = require("@opticss/util");
const propParser = require("css-property-parser");
const specificity = require("specificity");
const typescript_collections_1 = require("typescript-collections");
const Match_1 = require("../../Match");
const cssIntrospection_1 = require("../../util/cssIntrospection");
const shorthandProperties_1 = require("../../util/shorthandProperties");
const OptimizationContext_1 = require("./OptimizationContext");
/**
 * Efficient navigation of the selectors and declarations of a stylesheet
 * and how they intersect at elements.
 */
class DeclarationMapper {
    constructor(pass, analyses, files) {
        this.declarationInfos = new util_1.MultiMap();
        this.contexts = new OptimizationContext_1.OptimizationContexts();
        this.selectorTree = new typescript_collections_1.BSTree((s1, s2) => {
            let cmp = specificity.compare(s1.specificity.specificityArray, s2.specificity.specificityArray);
            if (cmp === 0)
                cmp = compare(s1.fileIndex, s2.fileIndex);
            if (cmp === 0)
                cmp = compare(s1.sourceIndex, s2.sourceIndex);
            return cmp;
        });
        let declSourceIndex = 0;
        let declSourceIndexMap = new Map();
        this.elementDeclarations = new Map();
        files.forEach((file, fileIndex) => {
            let sourceIndex = 0;
            cssIntrospection_1.walkRules(file.content.root, (rule, scope) => {
                let selectors = pass.cache.getParsedSelectors(rule);
                /** all the declarations of this rule after expanding longhand properties. */
                let declarations = new typescript_collections_1.MultiDictionary(undefined, undefined, true);
                rule.walkDecls(decl => {
                    declSourceIndexMap.set(decl, declSourceIndex++);
                    // TODO: normalize values. E.g colors of different formats, etc.
                    declarations.setValue(decl.prop, [decl.value, decl.important, decl]);
                });
                selectors.forEach(selector => {
                    sourceIndex++;
                    let elements = new Array();
                    analyses.forEach(analysis => {
                        elements.splice(elements.length, 0, ...querySelector(analysis, selector));
                    });
                    let selectorInfo = {
                        rule,
                        container: rule.parent,
                        scope,
                        selector,
                        specificity: specificity.calculate(selector.toString())[0],
                        file,
                        fileIndex,
                        sourceIndex,
                        elements,
                        ordinal: -1,
                        declarations,
                        declarationInfos: new typescript_collections_1.MultiDictionary(),
                    };
                    let context = this.contexts.getContext(selectorInfo.rule.root(), selectorInfo.scope, selectorInfo.selector.toContext());
                    for (let prop of declarations.keys()) {
                        context.authoredProps.add(prop);
                    }
                    this.selectorTree.add(selectorInfo);
                });
            });
        });
        let selectorOrdinal = 1;
        let declarationOrdinal = 1;
        let importantDeclInfos = new Array();
        this.selectorTree.inorderTraversal((selectorInfo) => {
            selectorInfo.ordinal = selectorOrdinal++;
            // map properties to selector info
            let context = this.contexts.getContext(selectorInfo.rule.root(), selectorInfo.scope, selectorInfo.selector.toContext());
            for (let prop of selectorInfo.declarations.keys()) {
                let values = selectorInfo.declarations.getValue(prop);
                for (let value of values) {
                    declarationOrdinal++;
                    let [v, important, decl] = value;
                    if (propParser.isShorthandProperty(decl.prop)) {
                        // We only expand shorthand declarations as much as is necessary within the current optimization context
                        // but we need to track declarations globally and against elements according to the fully expanded
                        // values because selectors can conflict across different optimization contexts.
                        let longhandDeclarations = shorthandProperties_1.expandIfNecessary(context.authoredProps, decl.prop, decl.value, pass.actions);
                        let longHandProps = Object.keys(longhandDeclarations);
                        let longHandDeclInfos = new Array();
                        for (let longHandProp of longHandProps) {
                            let declInfo = this.makeDeclInfo(selectorInfo, longHandProp, longhandDeclarations[longHandProp], important, decl, declSourceIndexMap.get(decl), declarationOrdinal);
                            longHandDeclInfos.push(declInfo);
                            Iif (important) {
                                importantDeclInfos.push(declInfo);
                            }
                            selectorInfo.declarationInfos.setValue([prop, v], declInfo);
                            let valueInfo = context.getDeclarationValues(longHandProp);
                            valueInfo.setValue(longhandDeclarations[longHandProp], declInfo);
                            this.addDeclInfoToElements(selectorInfo.elements, longHandProp, declInfo);
                        }
                        this.trackDeclarationInfo(context, longHandDeclInfos);
                    }
                    else {
                        // normal long hand props are just set directly
                        let declInfo = this.makeDeclInfo(selectorInfo, prop, v, important, decl, declSourceIndexMap.get(decl), declarationOrdinal);
                        this.trackDeclarationInfo(context, [declInfo]);
                        Iif (important) {
                            importantDeclInfos.push(declInfo);
                        }
                        let valueInfo = context.getDeclarationValues(prop);
                        valueInfo.setValue(v, declInfo);
                        this.addDeclInfoToElements(selectorInfo.elements, prop, declInfo);
                    }
                }
            }
        });
        // we add the max declaration ordinal to all the important declaration infos
        // this makes those declarations resolve higher than all the non-important values.
        for (let declInfo of importantDeclInfos) {
            declInfo.ordinal = declInfo.ordinal + declarationOrdinal;
        }
    }
    makeDeclInfo(selectorInfo, prop, value, important, decl, sourceOrdinal, ordinal, dupeCount = 0) {
        let declInfo = {
            decl,
            prop,
            value,
            important,
            selectorInfo,
            sourceOrdinal,
            originalSourceOrdinal: sourceOrdinal,
            ordinal,
            originalOrdinal: ordinal,
            dupeCount,
            expanded: false,
        };
        return declInfo;
    }
    trackDeclarationInfo(context, declInfos) {
        for (let info of declInfos) {
            context.declarationInfos.add(info);
        }
        this.declarationInfos.set(declInfos[0].decl, declInfos);
    }
    addDeclInfoToElements(elements, property, declInfo) {
        for (let el of elements) {
            let declarations = this.elementDeclarations.get(el);
            if (!declarations) {
                let newDecls = new typescript_collections_1.MultiDictionary();
                this.elementDeclarations.set(el, newDecls);
                newDecls.setValue(property, declInfo);
            }
            else {
                declarations.setValue(property, declInfo);
            }
        }
    }
}
exports.DeclarationMapper = DeclarationMapper;
function compare(n1, n2) {
    Iif (n1 < n2)
        return -1;
    if (n1 > n2)
        return 1;
    return 0;
}
function querySelector(analysis, selector) {
    return analysis.elements.filter(e => Match_1.matches(Match_1.ElementMatcher.instance.matchSelector(e, selector, true)));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVjbGFyYXRpb25NYXBwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvb3B0aW1pemF0aW9ucy9NZXJnZURlY2xhcmF0aW9ucy9EZWNsYXJhdGlvbk1hcHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLHdDQUF5QztBQUN6QyxrREFBa0Q7QUFFbEQsMkNBQTJDO0FBQzNDLG1FQUFpRTtBQUdqRSx1Q0FBc0Q7QUFHdEQsa0VBQXdEO0FBQ3hELHdFQUV3QztBQUV4QywrREFHK0I7QUFHL0I7OztHQUdHO0FBQ0g7SUFtQkUsWUFDRSxJQUFzQixFQUN0QixRQUFzRCxFQUN0RCxLQUEyQjtRQUczQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxlQUFRLEVBQTBDLENBQUM7UUFDL0UsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLDBDQUFvQixFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLCtCQUFNLENBQWUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDdEQsSUFBSSxHQUFHLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNoRyxJQUFJLEdBQUcsS0FBSyxDQUFDO2dCQUFFLEdBQUcsR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDekQsSUFBSSxHQUFHLEtBQUssQ0FBQztnQkFBRSxHQUFHLEdBQUcsT0FBTyxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzdELE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUM7UUFDeEIsSUFBSSxrQkFBa0IsR0FBRyxJQUFJ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