| 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; | 
|         } | 
|     } | 
| }; |