Forked from victor-homyakov/detect-unused-css-selectors.js
Created
April 20, 2020 11:24
-
-
Save haalogen/760b6b9c96ad5cc9c0e1b809838c98fc to your computer and use it in GitHub Desktop.
Revisions
-
victor-homyakov revised this gist
Apr 20, 2020 . 1 changed file with 5 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -37,13 +37,16 @@ if (unused.length !== window.selectorStats.unused.length) { message.push(unused.length + ' unused'); } window.selectorStats.unused = unused; if (added.length > 0) { message.push(added.length + ' added'); window.selectorStats.added = added; } if (removed.length > 0) { message.push(removed.length + ' removed', removed); window.selectorStats.removed = removed; } if (message.length > 0) { console.log('Selectors: ' + message.join(', ')); } -
victor-homyakov revised this gist
Apr 17, 2020 . 1 changed file with 8 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ /* eslint-disable no-var,no-console */ // detect unused CSS selectors (function() { var parsedRules = parseCssRules(); @@ -48,14 +49,14 @@ } }, 1000); function parseCssRules() { var styleSheets = document.styleSheets, parsedRules = { fontFaces: [], keyframes: [], media: [], style: [], support: [], unknown: [] }; @@ -82,6 +83,9 @@ parsedRules.style.push(rule.selectorText); // rule.cssText break; case 'CSSSupportsRule': parsedRules.support.push(rule.conditionText); break; default: parsedRules.unknown.push(rule); } @@ -94,7 +98,7 @@ function detectDuplicateSelectors(parsedRules) { var seenSelectors = {}, duplicatedSelectors = [], duplicatedSequence = []; parsedRules.style.forEach(function(selector) { if (selector in seenSelectors) { @@ -103,7 +107,7 @@ } else { seenSelectors[selector] = true; if (duplicatedSequence.length > 5) { console.warn('Duplicated sequence of selectors:', duplicatedSequence); } duplicatedSequence = []; } @@ -119,6 +123,7 @@ .filter(function(selector) { return !( selector === 'html' || selector.includes(':hover') || selector.includes('::after') || selector.includes('::before') ); -
victor-homyakov revised this gist
Feb 18, 2018 . 1 changed file with 53 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,33 +4,47 @@ console.log('Parsed CSS rules:', parsedRules); detectDuplicateSelectors(parsedRules); var selectorsToTrack = getSelectorsToTrack(parsedRules); window.selectorStats = { unused: [], added: [], removed: [] }; console.log('Tracking style usage (inspect window.selectorStats for details)...'); setInterval(function() { var newSelectors = getSelectorsToTrack(parseCssRules()); // Calculation order for removed/added/unused is significant var removed = Object.keys(selectorsToTrack) .filter(selector => newSelectors[selector] === undefined); var added = Object.keys(newSelectors) .filter(selector => { if (selectorsToTrack[selector] === undefined) { selectorsToTrack[selector] = 0; return true; } return false; }); var unused = Object.keys(selectorsToTrack) .filter(selector => { if (document.querySelector(selector)) { selectorsToTrack[selector]++; } return selectorsToTrack[selector] === 0; }); var message = []; if (unused.length !== window.selectorStats.unused.length) { message.push(unused.length + ' unused'); } if (added.length > 0) { message.push(added.length + ' added'); } if (removed.length > 0) { message.push(removed.length + ' removed'); } window.selectorStats = { unused: unused, added: added, removed: removed }; if (message.length > 0) { console.log('Selectors: ' + message.join(', ')); } }, 1000); @@ -99,4 +113,19 @@ console.log('List of all duplicated selectors:', duplicatedSelectors); } } function getSelectorsToTrack(parsedRules) { return parsedRules.style .filter(function(selector) { return !( selector === 'html' || selector.includes('::after') || selector.includes('::before') ); }) .reduce(function(selectors, selector) { selectors[selector] = 0; return selectors; }, {}); } }()); -
victor-homyakov revised this gist
Feb 16, 2018 . 1 changed file with 81 additions and 82 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,103 +1,102 @@ // detect unused CSS selectors (function() { var parsedRules = parseCssRules(); console.log('Parsed CSS rules:', parsedRules); detectDuplicateSelectors(parsedRules); var selectorsToTrack = parsedRules.style .filter(function(selector) { return !( selector === 'html' || selector.includes('::after') || selector.includes('::before') ); }) .reduce(function(selectors, selector) { selectors[selector] = 0; return selectors; }, {}); window.unusedSelectors = []; setInterval(function() { unusedSelectors = []; Object.keys(selectorsToTrack).forEach(function(selector) { if (document.querySelector(selector)) { selectorsToTrack[selector]++; } if (selectorsToTrack[selector] === 0) { unusedSelectors.push(selector); } }); if (unusedSelectors.length > 0) { console.log(unusedSelectors.length + ' unused selectors (inspect window.unusedSelectors for details)'); } }, 1000); function parseCssRules() { var styleSheets = document.styleSheets, parsedRules = { fontFaces: [], keyframes: [], media: [], style: [], unknown: [] }; for (var i = 0; i < styleSheets.length; i++) { var styleSheet = styleSheets[i]; var rules = styleSheet.cssRules; // styleSheet.rules for (var j = 0; j < rules.length; j++) { var rule = rules[j]; var ruleClass = Object.prototype.toString.call(rule).replace(/\[object (.+)]/, '$1'); switch (ruleClass) { case 'CSSFontFaceRule': parsedRules.fontFaces.push(rule.cssText); break; case 'CSSKeyframesRule': parsedRules.keyframes.push(rule.cssText); break; case 'CSSMediaRule': // if (rule.conditionText) parsedRules.media.push(rule.conditionText); break; case 'CSSStyleRule': // if (rule.selectorText) parsedRules.style.push(rule.selectorText); // rule.cssText break; default: parsedRules.unknown.push(rule); } } } return parsedRules; } function detectDuplicateSelectors(parsedRules) { var seenSelectors = {}, duplicatedSelectors = [], duplicatedSequence = [] parsedRules.style.forEach(function(selector) { if (selector in seenSelectors) { duplicatedSelectors.push(selector); duplicatedSequence.push(selector); } else { seenSelectors[selector] = true; if (duplicatedSequence.length > 5) { console.warn('Duplicated sequence of selectors:', duplicatedSequence) } duplicatedSequence = []; } }); if (duplicatedSelectors.length > 0) { console.log('List of all duplicated selectors:', duplicatedSelectors); } } }()); -
victor-homyakov created this gist
Feb 15, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,103 @@ // detect unused CSS selectors (function() { var styleSheets = document.styleSheets, parsedRules = { fontFaces: [], keyframes: [], media: [], style: [], unknown: [] }; for (var i = 0; i < styleSheets.length; i++) { var styleSheet = styleSheets[i]; var rules = styleSheet.cssRules; // styleSheet.rules for (var j = 0; j < rules.length; j++) { var rule = rules[j]; var ruleClass = Object.prototype.toString.call(rule).replace(/\[object (.+)]/, '$1'); switch (ruleClass) { case 'CSSFontFaceRule': parsedRules.fontFaces.push(rule.cssText); break; case 'CSSKeyframesRule': parsedRules.keyframes.push(rule.cssText); break; case 'CSSMediaRule': // if (rule.conditionText) parsedRules.media.push(rule.conditionText); break; case 'CSSStyleRule': // if (rule.selectorText) parsedRules.style.push(rule.selectorText); // rule.cssText break; default: parsedRules.unknown.push(rule); } /* if (rule.selectorText) { parsedRules.style.push(rule.selectorText); // if (document.querySelector(rule.selectorText)) { // parsedRules.style.push(rule.selectorText); // } else { // parsedRules.unusedStyle.push(rule.selectorText); // } } else if (rule.conditionText) { parsedRules.media.push(rule.conditionText); } else if (rule instanceof window.CSSFontFaceRule) { parsedRules.fontFaces.push(rule.cssText); } else if (rule instanceof window.CSSKeyframesRule) { parsedRules.keyframes.push(rule.cssText); } else { parsedRules.unknown.push(rule); } */ } } console.log('Parsed CSS rules:', parsedRules); window.unusedSelectors = []; var selectors = {}, duplicatedSelectors = [], duplicatedSequence = []; parsedRules.style.forEach(function(selector) { if (selector in selectors) { duplicatedSelectors.push(selector); duplicatedSequence.push(selector); } else { selectors[selector] = 0; if (duplicatedSequence.length > 5) { console.warn('Duplicated sequence of selectors:', duplicatedSequence) } duplicatedSequence = []; } }); if (duplicatedSelectors.length > 0) { console.log('List of all duplicated selectors:', duplicatedSelectors); } setInterval(function() { unusedSelectors = []; Object.keys(selectors).forEach(function(selector) { if (selector === 'html' || selector.includes('::after') || selector.includes('::before') || document.querySelector(selector)) { selectors[selector]++; } if (!selectors[selector]) { unusedSelectors.push(selector); } }); if (unusedSelectors.length > 0) { console.log(unusedSelectors.length + ' unused selectors'); } }, 1000); }());