diff --git a/Recipe.min.js b/Recipe.min.js index e96e982..73db83a 100644 --- a/Recipe.min.js +++ b/Recipe.min.js @@ -824,84 +824,36 @@ void function() { try { atrulesUsage[selectorText] = Object.create(null); atrulesUsage[selectorText] = {"count": 1, "props": {}, - "nested": {}, "conditions": {}} } else { var count = atrulesUsage[selectorText].count; - count = count++; + atrulesUsage[selectorText].count = count + 1; } var selectedAtruleUsage = atrulesUsage[selectorText]; if(rule.cssRules) { CSSUsage.PropertyValuesAnalyzer.anaylzeStyleOfRulePropCount(rule, selectedAtruleUsage); - processNestedRules(rule, selectedAtruleUsage.nested); } processConditionText(rule.conditionText, selectedAtruleUsage.conditions); } - /** - * Analyzes the given @atrules, such as @supports, and counts the usage of the nested rules - * according to their type. NOTE: must pass in the current usage of nested rules for the - * given @atrule. - */ - function processNestedRules(rule, nestedRulesUsage) { - // find the rule count for nested rules - for(let index in rule.cssRules) { - let ruleBody = rule.cssRules[index]; - - if(!ruleBody.cssText) { - continue; - } - - var nestRuleSelector; - - if(isRuleAnAtRule(ruleBody)) { - nestRuleSelector = '@atrule:' + ruleBody.type; - - } else if(ruleBody.style) { - if(ruleBody.selectorText) { - try { - var selectorText = CSSUsage.PropertyValuesAnalyzer.cleanSelectorText(ruleBody.selectorText); - var matchedElements = [].slice.call(document.querySelectorAll(selectorText)); - - if(matchedElements.length == 0) { - continue; - } - - var cleanedSelector = CSSUsage.PropertyValuesAnalyzer.generalizedSelectorsOf(selectorText); - nestRuleSelector = cleanedSelector[0]; // only passed in one selector to a function that returns many - } catch (ex) { - continue; - } - } - } - - if(nestRuleSelector) { - if(!nestedRulesUsage[nestRuleSelector]) { - nestedRulesUsage[nestRuleSelector] = Object.create(null); - nestedRulesUsage[nestRuleSelector] = {"count": 1} - } else { - var nestedCount = nestedRulesUsage[nestRuleSelector].count; - nestedCount = nestedCount++; - } - } - } - } - /** * This processes the usage of conditions of conditional @atrules like @media. * Requires the condition of the rule to process and the current recorded usage * of the @atrule in question. */ function processConditionText(conditionText, selectedAtruleConditionalUsage) { + // replace numeric specific information from condition statements + conditionText = conditionText.replace(/[0-9]+.*[0-9]+/g, ''); + if(!selectedAtruleConditionalUsage[conditionText]) { selectedAtruleConditionalUsage[conditionText] = Object.create(null); selectedAtruleConditionalUsage[conditionText] = {"count": 1} } else { var count = selectedAtruleConditionalUsage[conditionText].count; - count = count++; + selectedAtruleConditionalUsage[conditionText].count = count + 1; } } @@ -920,7 +872,7 @@ void function() { try { "props": {}} } else { var count = atrulesUsage[selectorText].count; - count = count++; + atrulesUsage[selectorText].count = count + 1; } // @keyframes rule type is 7 @@ -928,40 +880,10 @@ void function() { try { processKeyframeAtRules(rule); } else if(CSSUsageResults.rules[selectorText].props) { atrulesUsage[selectorText].props = CSSUsageResults.rules[selectorText].props; - } - - if(rule.pseudoClass) { - processPseudoClassesOfAtrules(rule); + delete atrulesUsage[selectorText].props.values; } } - - /** - * If an atrule as has a pseudo class such as @page, process the pseudo class and - * add it to the atrule usage. - */ - function processPseudoClassesOfAtrules(rule) { - var selectorText = '@atrule:' + rule.type; - var selectorAtruleUsage = CSSUsageResults.atrules[selectorText]; - - if(!selectorAtruleUsage["pseudos"]) { - selectorAtruleUsage["pseudos"] = Object.create(null); - selectorAtruleUsage["pseudos"] = {}; - } - - var pseudosUsageForSelector = selectorAtruleUsage["pseudos"]; - let pseudoClass = rule.pseudoClass; - - if(!pseudosUsageForSelector[pseudoClass]) { - pseudosUsageForSelector[pseudoClass] = Object.create(null); - pseudosUsageForSelector[pseudoClass] = {"count": 1}; - } else { - var pseudoCount = pseudosUsageForSelector[pseudoClass].count; - pseudoCount = pseudoCount++; - } - } - - /** * Processes on @keyframe to add the appropriate props from the frame and a counter of which * frames are used throughout the document. @@ -980,18 +902,23 @@ void function() { try { * WARN: tightly coupled with previous processing of rules. */ atrulesUsageForSelector.props = CSSUsageResults.rules["@atrule:8"].props; + delete atrulesUsageForSelector.props.values; for(let index in rule.cssRules) { let keyframe = rule.cssRules[index]; var atrulesUsageForKeyframeOfSelector = atrulesUsageForSelector.keyframes; - if(keyframe.keyText) { - if(!atrulesUsageForKeyframeOfSelector[keyframe.keyText]) { - atrulesUsageForKeyframeOfSelector[keyframe.keyText] = {"count": 1}; - } else { - var keyframeCount = atrulesUsageForKeyframeOfSelector[keyframe.keyText].count; - keyframeCount = keyframeCount++; - } + if(!keyframe.keyText) { + continue; + } + + var frame = keyframe.keyText; + + if(!atrulesUsageForKeyframeOfSelector[frame]) { + atrulesUsageForKeyframeOfSelector[frame] = { "count" : 1 }; + } else { + var keyframeCount = atrulesUsageForKeyframeOfSelector[frame].count; + atrulesUsageForKeyframeOfSelector[frame].count = keyframeCount + 1; } } } @@ -1505,6 +1432,20 @@ void function() { try { continue; } + if(ruleBody.selector) { + try { + var selectorText = CssPropertyValuesAnalyzer.cleanSelectorText(ruleBody.selectorText); + var matchedElements = [].slice.call(document.querySelectorAll(selectorText)); + + if (matchedElements.length == 0) { + continue; + } + } catch (ex) { + console.warn(ex.stack||("Invalid selector: "+selectorText+" -- via "+ruleBody.selectorText)); + continue; + } + } + let cssText = ' ' + style.cssText.toLowerCase(); for (var i = style.length; i--;) { @@ -1532,7 +1473,7 @@ void function() { try { propsForSelectedAtrule[normalizedKey] = {"count": 1}; } else { var propCount = propsForSelectedAtrule[normalizedKey].count; - propCount = propCount++; + propsForSelectedAtrule[normalizedKey].count = propCount + 1; } } } @@ -1812,7 +1753,7 @@ void function() { try { CSSUsageResults.usages = results; deleteDuplicatedAtRules(); // TODO: issue #52 - + if(window.debugCSSUsage) if(window.debugCSSUsage) console.log(CSSUsageResults.usages); } @@ -1830,6 +1771,8 @@ void function() { try { delete cssUsageRules[key]; } } + + delete CSSUsageResults.atrules["@atrule:8"]; // delete duplicated data from atrule:7, keyframe } }(); diff --git a/cssUsage.src.js b/cssUsage.src.js index 3746fe2..000bc3d 100644 --- a/cssUsage.src.js +++ b/cssUsage.src.js @@ -824,84 +824,36 @@ void function() { try { atrulesUsage[selectorText] = Object.create(null); atrulesUsage[selectorText] = {"count": 1, "props": {}, - "nested": {}, "conditions": {}} } else { var count = atrulesUsage[selectorText].count; - count = count++; + atrulesUsage[selectorText].count = count + 1; } var selectedAtruleUsage = atrulesUsage[selectorText]; if(rule.cssRules) { CSSUsage.PropertyValuesAnalyzer.anaylzeStyleOfRulePropCount(rule, selectedAtruleUsage); - processNestedRules(rule, selectedAtruleUsage.nested); } processConditionText(rule.conditionText, selectedAtruleUsage.conditions); } - /** - * Analyzes the given @atrules, such as @supports, and counts the usage of the nested rules - * according to their type. NOTE: must pass in the current usage of nested rules for the - * given @atrule. - */ - function processNestedRules(rule, nestedRulesUsage) { - // find the rule count for nested rules - for(let index in rule.cssRules) { - let ruleBody = rule.cssRules[index]; - - if(!ruleBody.cssText) { - continue; - } - - var nestRuleSelector; - - if(isRuleAnAtRule(ruleBody)) { - nestRuleSelector = '@atrule:' + ruleBody.type; - - } else if(ruleBody.style) { - if(ruleBody.selectorText) { - try { - var selectorText = CSSUsage.PropertyValuesAnalyzer.cleanSelectorText(ruleBody.selectorText); - var matchedElements = [].slice.call(document.querySelectorAll(selectorText)); - - if(matchedElements.length == 0) { - continue; - } - - var cleanedSelector = CSSUsage.PropertyValuesAnalyzer.generalizedSelectorsOf(selectorText); - nestRuleSelector = cleanedSelector[0]; // only passed in one selector to a function that returns many - } catch (ex) { - continue; - } - } - } - - if(nestRuleSelector) { - if(!nestedRulesUsage[nestRuleSelector]) { - nestedRulesUsage[nestRuleSelector] = Object.create(null); - nestedRulesUsage[nestRuleSelector] = {"count": 1} - } else { - var nestedCount = nestedRulesUsage[nestRuleSelector].count; - nestedCount = nestedCount++; - } - } - } - } - /** * This processes the usage of conditions of conditional @atrules like @media. * Requires the condition of the rule to process and the current recorded usage * of the @atrule in question. */ function processConditionText(conditionText, selectedAtruleConditionalUsage) { + // replace numeric specific information from condition statements + conditionText = conditionText.replace(/[0-9]+.*[0-9]+/g, ''); + if(!selectedAtruleConditionalUsage[conditionText]) { selectedAtruleConditionalUsage[conditionText] = Object.create(null); selectedAtruleConditionalUsage[conditionText] = {"count": 1} } else { var count = selectedAtruleConditionalUsage[conditionText].count; - count = count++; + selectedAtruleConditionalUsage[conditionText].count = count + 1; } } @@ -920,7 +872,7 @@ void function() { try { "props": {}} } else { var count = atrulesUsage[selectorText].count; - count = count++; + atrulesUsage[selectorText].count = count + 1; } // @keyframes rule type is 7 @@ -928,40 +880,10 @@ void function() { try { processKeyframeAtRules(rule); } else if(CSSUsageResults.rules[selectorText].props) { atrulesUsage[selectorText].props = CSSUsageResults.rules[selectorText].props; - } - - if(rule.pseudoClass) { - processPseudoClassesOfAtrules(rule); + delete atrulesUsage[selectorText].props.values; } } - - /** - * If an atrule as has a pseudo class such as @page, process the pseudo class and - * add it to the atrule usage. - */ - function processPseudoClassesOfAtrules(rule) { - var selectorText = '@atrule:' + rule.type; - var selectorAtruleUsage = CSSUsageResults.atrules[selectorText]; - - if(!selectorAtruleUsage["pseudos"]) { - selectorAtruleUsage["pseudos"] = Object.create(null); - selectorAtruleUsage["pseudos"] = {}; - } - - var pseudosUsageForSelector = selectorAtruleUsage["pseudos"]; - let pseudoClass = rule.pseudoClass; - - if(!pseudosUsageForSelector[pseudoClass]) { - pseudosUsageForSelector[pseudoClass] = Object.create(null); - pseudosUsageForSelector[pseudoClass] = {"count": 1}; - } else { - var pseudoCount = pseudosUsageForSelector[pseudoClass].count; - pseudoCount = pseudoCount++; - } - } - - /** * Processes on @keyframe to add the appropriate props from the frame and a counter of which * frames are used throughout the document. @@ -980,18 +902,23 @@ void function() { try { * WARN: tightly coupled with previous processing of rules. */ atrulesUsageForSelector.props = CSSUsageResults.rules["@atrule:8"].props; + delete atrulesUsageForSelector.props.values; for(let index in rule.cssRules) { let keyframe = rule.cssRules[index]; var atrulesUsageForKeyframeOfSelector = atrulesUsageForSelector.keyframes; - if(keyframe.keyText) { - if(!atrulesUsageForKeyframeOfSelector[keyframe.keyText]) { - atrulesUsageForKeyframeOfSelector[keyframe.keyText] = {"count": 1}; - } else { - var keyframeCount = atrulesUsageForKeyframeOfSelector[keyframe.keyText].count; - keyframeCount = keyframeCount++; - } + if(!keyframe.keyText) { + continue; + } + + var frame = keyframe.keyText; + + if(!atrulesUsageForKeyframeOfSelector[frame]) { + atrulesUsageForKeyframeOfSelector[frame] = { "count" : 1 }; + } else { + var keyframeCount = atrulesUsageForKeyframeOfSelector[frame].count; + atrulesUsageForKeyframeOfSelector[frame].count = keyframeCount + 1; } } } @@ -1505,6 +1432,20 @@ void function() { try { continue; } + if(ruleBody.selector) { + try { + var selectorText = CssPropertyValuesAnalyzer.cleanSelectorText(ruleBody.selectorText); + var matchedElements = [].slice.call(document.querySelectorAll(selectorText)); + + if (matchedElements.length == 0) { + continue; + } + } catch (ex) { + console.warn(ex.stack||("Invalid selector: "+selectorText+" -- via "+ruleBody.selectorText)); + continue; + } + } + let cssText = ' ' + style.cssText.toLowerCase(); for (var i = style.length; i--;) { @@ -1532,7 +1473,7 @@ void function() { try { propsForSelectedAtrule[normalizedKey] = {"count": 1}; } else { var propCount = propsForSelectedAtrule[normalizedKey].count; - propCount = propCount++; + propsForSelectedAtrule[normalizedKey].count = propCount + 1; } } } @@ -1812,7 +1753,7 @@ void function() { try { CSSUsageResults.usages = results; deleteDuplicatedAtRules(); // TODO: issue #52 - + if(window.debugCSSUsage) if(window.debugCSSUsage) console.log(CSSUsageResults.usages); } @@ -1830,6 +1771,8 @@ void function() { try { delete cssUsageRules[key]; } } + + delete CSSUsageResults.atrules["@atrule:8"]; // delete duplicated data from atrule:7, keyframe } }(); diff --git a/src/cssUsage.js b/src/cssUsage.js index 82926f6..b8700c3 100644 --- a/src/cssUsage.js +++ b/src/cssUsage.js @@ -327,84 +327,36 @@ void function() { try { atrulesUsage[selectorText] = Object.create(null); atrulesUsage[selectorText] = {"count": 1, "props": {}, - "nested": {}, "conditions": {}} } else { var count = atrulesUsage[selectorText].count; - count = count++; + atrulesUsage[selectorText].count = count + 1; } var selectedAtruleUsage = atrulesUsage[selectorText]; if(rule.cssRules) { CSSUsage.PropertyValuesAnalyzer.anaylzeStyleOfRulePropCount(rule, selectedAtruleUsage); - processNestedRules(rule, selectedAtruleUsage.nested); } processConditionText(rule.conditionText, selectedAtruleUsage.conditions); } - /** - * Analyzes the given @atrules, such as @supports, and counts the usage of the nested rules - * according to their type. NOTE: must pass in the current usage of nested rules for the - * given @atrule. - */ - function processNestedRules(rule, nestedRulesUsage) { - // find the rule count for nested rules - for(let index in rule.cssRules) { - let ruleBody = rule.cssRules[index]; - - if(!ruleBody.cssText) { - continue; - } - - var nestRuleSelector; - - if(isRuleAnAtRule(ruleBody)) { - nestRuleSelector = '@atrule:' + ruleBody.type; - - } else if(ruleBody.style) { - if(ruleBody.selectorText) { - try { - var selectorText = CSSUsage.PropertyValuesAnalyzer.cleanSelectorText(ruleBody.selectorText); - var matchedElements = [].slice.call(document.querySelectorAll(selectorText)); - - if(matchedElements.length == 0) { - continue; - } - - var cleanedSelector = CSSUsage.PropertyValuesAnalyzer.generalizedSelectorsOf(selectorText); - nestRuleSelector = cleanedSelector[0]; // only passed in one selector to a function that returns many - } catch (ex) { - continue; - } - } - } - - if(nestRuleSelector) { - if(!nestedRulesUsage[nestRuleSelector]) { - nestedRulesUsage[nestRuleSelector] = Object.create(null); - nestedRulesUsage[nestRuleSelector] = {"count": 1} - } else { - var nestedCount = nestedRulesUsage[nestRuleSelector].count; - nestedCount = nestedCount++; - } - } - } - } - /** * This processes the usage of conditions of conditional @atrules like @media. * Requires the condition of the rule to process and the current recorded usage * of the @atrule in question. */ function processConditionText(conditionText, selectedAtruleConditionalUsage) { + // replace numeric specific information from condition statements + conditionText = conditionText.replace(/[0-9]+.*[0-9]+/g, ''); + if(!selectedAtruleConditionalUsage[conditionText]) { selectedAtruleConditionalUsage[conditionText] = Object.create(null); selectedAtruleConditionalUsage[conditionText] = {"count": 1} } else { var count = selectedAtruleConditionalUsage[conditionText].count; - count = count++; + selectedAtruleConditionalUsage[conditionText].count = count + 1; } } @@ -423,7 +375,7 @@ void function() { try { "props": {}} } else { var count = atrulesUsage[selectorText].count; - count = count++; + atrulesUsage[selectorText].count = count + 1; } // @keyframes rule type is 7 @@ -431,40 +383,10 @@ void function() { try { processKeyframeAtRules(rule); } else if(CSSUsageResults.rules[selectorText].props) { atrulesUsage[selectorText].props = CSSUsageResults.rules[selectorText].props; - } - - if(rule.pseudoClass) { - processPseudoClassesOfAtrules(rule); + delete atrulesUsage[selectorText].props.values; } } - - /** - * If an atrule as has a pseudo class such as @page, process the pseudo class and - * add it to the atrule usage. - */ - function processPseudoClassesOfAtrules(rule) { - var selectorText = '@atrule:' + rule.type; - var selectorAtruleUsage = CSSUsageResults.atrules[selectorText]; - - if(!selectorAtruleUsage["pseudos"]) { - selectorAtruleUsage["pseudos"] = Object.create(null); - selectorAtruleUsage["pseudos"] = {}; - } - - var pseudosUsageForSelector = selectorAtruleUsage["pseudos"]; - let pseudoClass = rule.pseudoClass; - - if(!pseudosUsageForSelector[pseudoClass]) { - pseudosUsageForSelector[pseudoClass] = Object.create(null); - pseudosUsageForSelector[pseudoClass] = {"count": 1}; - } else { - var pseudoCount = pseudosUsageForSelector[pseudoClass].count; - pseudoCount = pseudoCount++; - } - } - - /** * Processes on @keyframe to add the appropriate props from the frame and a counter of which * frames are used throughout the document. @@ -483,18 +405,23 @@ void function() { try { * WARN: tightly coupled with previous processing of rules. */ atrulesUsageForSelector.props = CSSUsageResults.rules["@atrule:8"].props; + delete atrulesUsageForSelector.props.values; for(let index in rule.cssRules) { let keyframe = rule.cssRules[index]; var atrulesUsageForKeyframeOfSelector = atrulesUsageForSelector.keyframes; - if(keyframe.keyText) { - if(!atrulesUsageForKeyframeOfSelector[keyframe.keyText]) { - atrulesUsageForKeyframeOfSelector[keyframe.keyText] = {"count": 1}; - } else { - var keyframeCount = atrulesUsageForKeyframeOfSelector[keyframe.keyText].count; - keyframeCount = keyframeCount++; - } + if(!keyframe.keyText) { + continue; + } + + var frame = keyframe.keyText; + + if(!atrulesUsageForKeyframeOfSelector[frame]) { + atrulesUsageForKeyframeOfSelector[frame] = { "count" : 1 }; + } else { + var keyframeCount = atrulesUsageForKeyframeOfSelector[frame].count; + atrulesUsageForKeyframeOfSelector[frame].count = keyframeCount + 1; } } } @@ -1008,6 +935,20 @@ void function() { try { continue; } + if(ruleBody.selector) { + try { + var selectorText = CssPropertyValuesAnalyzer.cleanSelectorText(ruleBody.selectorText); + var matchedElements = [].slice.call(document.querySelectorAll(selectorText)); + + if (matchedElements.length == 0) { + continue; + } + } catch (ex) { + console.warn(ex.stack||("Invalid selector: "+selectorText+" -- via "+ruleBody.selectorText)); + continue; + } + } + let cssText = ' ' + style.cssText.toLowerCase(); for (var i = style.length; i--;) { @@ -1035,7 +976,7 @@ void function() { try { propsForSelectedAtrule[normalizedKey] = {"count": 1}; } else { var propCount = propsForSelectedAtrule[normalizedKey].count; - propCount = propCount++; + propsForSelectedAtrule[normalizedKey].count = propCount + 1; } } } @@ -1315,7 +1256,7 @@ void function() { try { CSSUsageResults.usages = results; deleteDuplicatedAtRules(); // TODO: issue #52 - + if(window.debugCSSUsage) if(window.debugCSSUsage) console.log(CSSUsageResults.usages); } @@ -1333,6 +1274,8 @@ void function() { try { delete cssUsageRules[key]; } } + + delete CSSUsageResults.atrules["@atrule:8"]; // delete duplicated data from atrule:7, keyframe } }(); diff --git a/tests/test-page-atrules/styles.css b/tests/test-page-atrules/styles.css index 268bd10..372df4e 100644 --- a/tests/test-page-atrules/styles.css +++ b/tests/test-page-atrules/styles.css @@ -77,6 +77,9 @@ h2 { } @media screen and (min-width:480px) { + p { + background-color: whitesmoke; + } body{ background-color:#6aa6cc;