You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							94 lines
						
					
					
						
							3.8 KiB
						
					
					
				
			
		
		
	
	
							94 lines
						
					
					
						
							3.8 KiB
						
					
					
				| 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;
 | |
|         }
 | |
|     }
 | |
| };
 |