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