From aee81cb8243dad6f9f0e8123c4ea8da7448e1853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sun, 27 Mar 2016 21:24:27 +0300 Subject: [PATCH] Change the way offenders are displayed for some CSS related rules --- front/src/views/rule.html | 90 +++++++----- lib/metadata/policies.js | 301 +++++++++++++++++--------------------- lib/offendersHelpers.js | 21 +++ 3 files changed, 213 insertions(+), 199 deletions(-) diff --git a/front/src/views/rule.html b/front/src/views/rule.html index d6a83e8..eb14e77 100644 --- a/front/src/views/rule.html +++ b/front/src/views/rule.html @@ -30,7 +30,7 @@

This rule reached the abnormality threshold, which means there is a real problem you should care about.

-

+

@@ -106,20 +106,14 @@
{{offender.color1}}
{{offender.color2}}
-
- {{offender.query}} for - -
-
{{offender.error}} (Check on the W3C validator)
-
- - {{offender.css}} +
+ {{offender.css}}
@@ -127,32 +121,6 @@ {{offender.rule}} (x{{offender.occurrences}})
-
- Property {{offender.property}} duplicated in {{offender.rule}} { } - -
- -
- {{offender.css}} { } - -
- -
- {{offender.rule}} {{ '{' + offender.property}}: expression({{offender.expression}})} - -
- -
- {{offender.rule}} {{ '{' + offender.property}}: {{offender.value}} !important} - -
- -
- {{offender.browser}} fix: - - -
-
{{offender.property}} {{offender.message}}
@@ -195,7 +163,57 @@
-
+
+

+ + in + + inline CSS +

+ +
+
+
+ + {{offender.css}} + @ {{offender.line}}:{{offender.column}} +
+ +
+ {{offender.query}} for + @ {{offender.line}}:{{offender.column}} +
+ +
+ Property {{offender.property}} duplicated in {{offender.rule}} { } + @ {{offender.line}}:{{offender.column}} +
+ +
+ {{offender.css}} { } + @ {{offender.line}}:{{offender.column}} +
+ +
+ {{offender.rule}} {{ '{' + offender.property}}: expression({{offender.expression}})} + @ {{offender.line}}:{{offender.column}} +
+ +
+ {{offender.rule}} {{ '{' + offender.property}}: {{offender.value}} !important} + @ {{offender.line}}:{{offender.column}} +
+ +
+ {{offender.browser}} fix: + + @ {{offender.line}}:{{offender.column}} +
+
+
+
+ +
diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index 40a1b38..fdd0881 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -462,19 +462,18 @@ var policies = { "cssComplexSelectors": { "tool": "phantomas", "label": "Complex selectors", - "message": "

Complex selectors are CSS selectors with 4 or more expressions, like \"#header ul li .foo\".

They are adding more work for the browser, and this could be avoided by simplifying selectors.

", + "message": "

Complex selectors are CSS selectors with 4 or more expressions, like \"#header ul li .foo\".

They are adding more work for the browser, and this could be avoided by simplifying selectors. The B.E.M. methodology is an useful way to simplify your CSS.

", "isOkThreshold": 0, "isBadThreshold": 600, "isAbnormalThreshold": 2000, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - return splittedOffender; - }) - }; + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + return splittedOffender; + }); + + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssComplexSelectorsByAttribute": { @@ -486,16 +485,13 @@ var policies = { "isAbnormalThreshold": 150, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + splittedOffender.bolded = splittedOffender.css.replace(/(\[[^ ]+[~\|\^\$\*]=["']?[^"'\]]+["']?\])/g, '$1'); + return splittedOffender; + }); - splittedOffender.bolded = splittedOffender.css.replace(/(\[[^ ]+[~\|\^\$\*]="[^"]+"\])/g, '$1'); - - return splittedOffender; - }) - }; + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssColors": { @@ -590,10 +586,7 @@ var policies = { "isAbnormalThreshold": 1000, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders - }; + return offendersHelpers.orderByFile(offenders); } }, "cssImports": { @@ -652,29 +645,28 @@ var policies = { "isAbnormalThreshold": 120, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - var parts = /^([^{]+) {([^ ]+): (.+)}$/.exec(splittedOffender.css); - - if (!parts) { - debug('cssDuplicatedProperties offenders transform function error with "%s"', offender); - return { - parseError: offender - }; - } + var parts = /^([^{]+) {([^ ]+): (.+)}$/.exec(splittedOffender.css); + if (!parts) { + debug('cssDuplicatedProperties offenders transform function error with "%s"', offender); return { - property: parts[2], - rule: parts[1], - file: splittedOffender.file, - line: splittedOffender.line, - column: splittedOffender.column + parseError: offender }; - }) - }; + } + + return { + property: parts[2], + rule: parts[1], + file: splittedOffender.file, + line: splittedOffender.line, + column: splittedOffender.column + }; + }); + + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssEmptyRules": { @@ -686,14 +678,8 @@ var policies = { "isAbnormalThreshold": 100, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - - return splittedOffender; - }) - }; + var parsedOffenders = offenders.map(offendersHelpers.cssOffenderPattern); + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssExpressions": { @@ -705,30 +691,29 @@ var policies = { "isAbnormalThreshold": 20, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - var parts = /^(.*) {([^ ]+): expression\((.*)\)}$/.exec(splittedOffender.css); - - if (!parts) { - debug('cssExpressions offenders transform function error with "%s"', offender); - return { - parseError: offender - }; - } + var parts = /^(.*) {([^ ]+): expression\((.*)\)}$/.exec(splittedOffender.css); + if (!parts) { + debug('cssExpressions offenders transform function error with "%s"', offender); return { - rule: parts[1], - property: parts[2], - expression: parts[3], - file: splittedOffender.file, - line: splittedOffender.line, - column: splittedOffender.column + parseError: offender }; - }) - }; + } + + return { + rule: parts[1], + property: parts[2], + expression: parts[3], + file: splittedOffender.file, + line: splittedOffender.line, + column: splittedOffender.column + }; + }); + + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssImportants": { @@ -740,30 +725,29 @@ var policies = { "isAbnormalThreshold": 200, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - var parts = /^(.*) {([^ ]+): (.*) ?\!important}$/.exec(splittedOffender.css); - - if (!parts) { - debug('cssImportants offenders transform function error with "%s"', offender); - return { - parseError: offender - }; - } + var parts = /^(.*) {([^ ]+): (.*) ?\!important}$/.exec(splittedOffender.css); + if (!parts) { + debug('cssImportants offenders transform function error with "%s"', offender); return { - rule: parts[1], - property: parts[2], - value: parts[3], - file: splittedOffender.file, - line: splittedOffender.line, - column: splittedOffender.column + parseError: offender }; - }) - }; + } + + return { + rule: parts[1], + property: parts[2], + value: parts[3], + file: splittedOffender.file, + line: splittedOffender.line, + column: splittedOffender.column + }; + }); + + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssOldIEFixes": { @@ -775,52 +759,51 @@ var policies = { "isAbnormalThreshold": 300, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - var parts = /^([^{]*)( {([^ ]+): (.*)})?$/.exec(splittedOffender.css); + var parts = /^([^{]*)( {([^ ]+): (.*)})?$/.exec(splittedOffender.css); - if (!parts) { - debug('cssOldIEFixes offenders transform function error with "%s"', offender); - return { - parseError: offender - }; - } + if (!parts) { + debug('cssOldIEFixes offenders transform function error with "%s"', offender); + return { + parseError: offender + }; + } - var rule = parts[1]; - var property = parts[3]; - var value = parts[4]; - var browser = null; + var rule = parts[1]; + var property = parts[3]; + var value = parts[4]; + var browser = null; - if (rule.indexOf('* html') === 0) { - rule = rule.replace(/^\* html/, '* html'); - browser = 'IE6'; - } else if (rule.indexOf('html>body') === 0) { - rule = rule.replace(/^html>body/, 'html>body'); - browser = 'IE6'; - } else if (property.indexOf('*') === 0) { - property = '' + property + ''; - browser = 'IE7'; - } else if (value.match(/\!ie$/)) { - value = value.replace(/\!ie$/, '!ie'); - browser = 'IE7'; - } else if (property === '-ms-filter') { - property = '-ms-filter'; - browser = 'IE9'; - } else if (value.indexOf('progid:DXImageTransform.Microsoft') >= 0) { - value = value.replace(/progid:DXImageTransform\.Microsoft/, 'progid:DXImageTransform.Microsoft'); - browser = 'IE9'; - } + if (rule.indexOf('* html') === 0) { + rule = rule.replace(/^\* html/, '* html'); + browser = 'IE6'; + } else if (rule.indexOf('html>body') === 0) { + rule = rule.replace(/^html>body/, 'html>body'); + browser = 'IE6'; + } else if (property.indexOf('*') === 0) { + property = '' + property + ''; + browser = 'IE7'; + } else if (value.match(/\!ie$/)) { + value = value.replace(/\!ie$/, '!ie'); + browser = 'IE7'; + } else if (property === '-ms-filter') { + property = '-ms-filter'; + browser = 'IE9'; + } else if (value.indexOf('progid:DXImageTransform.Microsoft') >= 0) { + value = value.replace(/progid:DXImageTransform\.Microsoft/, 'progid:DXImageTransform.Microsoft'); + browser = 'IE9'; + } - var propertyAndValue = (property && value) ? ' {' + property + ': ' + value + '}' : ''; - splittedOffender.bolded = rule + propertyAndValue; - splittedOffender.browser = browser; + var propertyAndValue = (property && value) ? ' {' + property + ': ' + value + '}' : ''; + splittedOffender.bolded = rule + propertyAndValue; + splittedOffender.browser = browser; - return splittedOffender; - }) - }; + return splittedOffender; + }); + + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssOldPropertyPrefixes": { @@ -885,13 +868,9 @@ var policies = { "isAbnormalThreshold": 150, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - return splittedOffender; - }) - }; + var parsedOffenders = offenders.map(offendersHelpers.cssOffenderPattern); + + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssRedundantBodySelectors": { @@ -903,16 +882,13 @@ var policies = { "isAbnormalThreshold": 200, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + splittedOffender.bolded = splittedOffender.css.replace(/body/, 'body'); + return splittedOffender; + }); - splittedOffender.bolded = splittedOffender.css.replace(/body/, 'body'); - - return splittedOffender; - }) - }; + return offendersHelpers.orderByFile(parsedOffenders); } }, "cssRedundantChildNodesSelectors": { @@ -924,29 +900,28 @@ var policies = { "isAbnormalThreshold": 200, "hasOffenders": true, "offendersTransformFn": function(offenders) { - return { - count: offenders.length, - list: offenders.map(function(offender) { - var splittedOffender = offendersHelpers.cssOffenderPattern(offender); + var parsedOffenders = offenders.map(function(offender) { + var splittedOffender = offendersHelpers.cssOffenderPattern(offender); - var rule = splittedOffender.css || ''; - var redundanters = [ - ['ul', 'li'], - ['ol', 'li'], - ['select', 'option'], - ['table', 'tr'], - ['table', 'th'], - ]; + var rule = splittedOffender.css || ''; + var redundanters = [ + ['ul', 'li'], + ['ol', 'li'], + ['select', 'option'], + ['table', 'tr'], + ['table', 'th'], + ]; - redundanters.forEach(function(couple) { - rule = rule.replace(new RegExp('(^| |>)' + couple[0] + '([^ >]*)?([ >]| > )' + couple[1] + '([^\\w-]|$)', 'g'), '$1' + couple[0] + '$2$3' + couple[1] + '$4'); - }); + redundanters.forEach(function(couple) { + rule = rule.replace(new RegExp('(^| |>)' + couple[0] + '([^ >]*)?([ >]| > )' + couple[1] + '([^\\w-]|$)', 'g'), '$1' + couple[0] + '$2$3' + couple[1] + '$4'); + }); - splittedOffender.bolded = rule; + splittedOffender.bolded = rule; - return splittedOffender; - }) - }; + return splittedOffender; + }); + + return offendersHelpers.orderByFile(parsedOffenders); } }, "totalWeight": { diff --git a/lib/offendersHelpers.js b/lib/offendersHelpers.js index 24fc5dc..69e7b1b 100644 --- a/lib/offendersHelpers.js +++ b/lib/offendersHelpers.js @@ -185,6 +185,27 @@ var OffendersHelpers = function() { } }; + this.orderByFile = function(offenders) { + var byFile = {}; + + offenders.forEach(function(offender) { + var file = offender.file || 'Inline CSS'; + delete offender.file; + + if (!byFile[file]) { + byFile[file] = { + count: 0, + offenders: [] + }; + } + + byFile[file].count ++; + byFile[file].offenders.push(offender); + }); + + return {byFile: byFile}; + }; + }; module.exports = new OffendersHelpers(); \ No newline at end of file