94 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var hasOwnProperty = Object.prototype.hasOwnProperty;
 | 
						|
var walk = require('css-tree').walk;
 | 
						|
var { hasNoChildren } = require('./utils');
 | 
						|
 | 
						|
function cleanUnused(selectorList, usageData) {
 | 
						|
    selectorList.children.each(function(selector, item, list) {
 | 
						|
        var shouldRemove = false;
 | 
						|
 | 
						|
        walk(selector, function(node) {
 | 
						|
            // ignore nodes in nested selectors
 | 
						|
            if (this.selector === null || this.selector === selectorList) {
 | 
						|
                switch (node.type) {
 | 
						|
                    case 'SelectorList':
 | 
						|
                        // TODO: remove toLowerCase when pseudo selectors will be normalized
 | 
						|
                        // ignore selectors inside :not()
 | 
						|
                        if (this.function === null || this.function.name.toLowerCase() !== 'not') {
 | 
						|
                            if (cleanUnused(node, usageData)) {
 | 
						|
                                shouldRemove = true;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case 'ClassSelector':
 | 
						|
                        if (usageData.whitelist !== null &&
 | 
						|
                            usageData.whitelist.classes !== null &&
 | 
						|
                            !hasOwnProperty.call(usageData.whitelist.classes, node.name)) {
 | 
						|
                            shouldRemove = true;
 | 
						|
                        }
 | 
						|
                        if (usageData.blacklist !== null &&
 | 
						|
                            usageData.blacklist.classes !== null &&
 | 
						|
                            hasOwnProperty.call(usageData.blacklist.classes, node.name)) {
 | 
						|
                            shouldRemove = true;
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case 'IdSelector':
 | 
						|
                        if (usageData.whitelist !== null &&
 | 
						|
                            usageData.whitelist.ids !== null &&
 | 
						|
                            !hasOwnProperty.call(usageData.whitelist.ids, node.name)) {
 | 
						|
                            shouldRemove = true;
 | 
						|
                        }
 | 
						|
                        if (usageData.blacklist !== null &&
 | 
						|
                            usageData.blacklist.ids !== null &&
 | 
						|
                            hasOwnProperty.call(usageData.blacklist.ids, node.name)) {
 | 
						|
                            shouldRemove = true;
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case 'TypeSelector':
 | 
						|
                        // TODO: remove toLowerCase when type selectors will be normalized
 | 
						|
                        // ignore universal selectors
 | 
						|
                        if (node.name.charAt(node.name.length - 1) !== '*') {
 | 
						|
                            if (usageData.whitelist !== null &&
 | 
						|
                                usageData.whitelist.tags !== null &&
 | 
						|
                                !hasOwnProperty.call(usageData.whitelist.tags, node.name.toLowerCase())) {
 | 
						|
                                shouldRemove = true;
 | 
						|
                            }
 | 
						|
                            if (usageData.blacklist !== null &&
 | 
						|
                                usageData.blacklist.tags !== null &&
 | 
						|
                                hasOwnProperty.call(usageData.blacklist.tags, node.name.toLowerCase())) {
 | 
						|
                                shouldRemove = true;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        });
 | 
						|
 | 
						|
        if (shouldRemove) {
 | 
						|
            list.remove(item);
 | 
						|
        }
 | 
						|
    });
 | 
						|
 | 
						|
    return selectorList.children.isEmpty();
 | 
						|
}
 | 
						|
 | 
						|
module.exports = function cleanRule(node, item, list, options) {
 | 
						|
    if (hasNoChildren(node.prelude) || hasNoChildren(node.block)) {
 | 
						|
        list.remove(item);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    var usageData = options.usage;
 | 
						|
 | 
						|
    if (usageData && (usageData.whitelist !== null || usageData.blacklist !== null)) {
 | 
						|
        cleanUnused(node.prelude, usageData);
 | 
						|
 | 
						|
        if (hasNoChildren(node.prelude)) {
 | 
						|
            list.remove(item);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
    }
 | 
						|
};
 |