|
@@ -38,7 +38,7 @@ var policies = {
|
|
|
"isAbnormalThreshold": 10,
|
|
|
"offendersTransformFn": function(offenders) {
|
|
|
return offenders.map(function(offender) {
|
|
|
- var parts = /^(.*): ?(\d) ?occurrences$/.exec(offender);
|
|
|
+ var parts = /^(.*): ?(\d+) ?occurrences$/.exec(offender);
|
|
|
|
|
|
if (!parts) {
|
|
|
debug('DOMidDuplicated offenders transform function error with "%s"', offender);
|
|
@@ -107,7 +107,7 @@ var policies = {
|
|
|
"takeOffendersFrom": "DOMqueriesDuplicated",
|
|
|
"offendersTransformFn": function(offenders) {
|
|
|
return offenders.map(function(offender) {
|
|
|
- var parts = /^.* "(.*)" ?with ?(.*) ?\(in ?context ?(.*)\): ?(.*)\s?queries$/.exec(offender);
|
|
|
+ var parts = /^[^"]* ?"(.*)" ?with ?(.*) ?\(in ?context ?(.*)\): ?(.*)\s?queries$/.exec(offender);
|
|
|
|
|
|
if (!parts) {
|
|
|
debug('DOMqueriesAvoidable offenders transform function error with "%s"', offender);
|
|
@@ -265,7 +265,34 @@ var policies = {
|
|
|
"message": "<p>Yellow Lab Tools failed to parse a CSS file. I doubt the problem comes from the css parser.</p><p>Maybe a <a href=\"http://jigsaw.w3.org/css-validator\" target=\"_blank\">CSS validator</a> can help you.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 1,
|
|
|
- "isAbnormalThreshold": 1
|
|
|
+ "isAbnormalThreshold": 1,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var parts = /^(([^ \(]*|<inline CSS>) ?)?(?:\((((?! @ ).)*)( @ (\d+):(\d+))?\))?$/.exec(offender);
|
|
|
+
|
|
|
+ if (!parts) {
|
|
|
+ debug('cssParsingErrors offenders transform function error with "%s"', offender);
|
|
|
+ return offender;
|
|
|
+ }
|
|
|
+
|
|
|
+ var html = (parts[3]) ? parts[3] : '';
|
|
|
+
|
|
|
+ if (parts[2]) {
|
|
|
+ html += (parts[2] === '<inline CSS>') ? ' <inline CSS>' : ' ' + offendersHelpers.urlToLink(parts[2]);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (parts[5]) {
|
|
|
+ html += ' @ ' + parts[6] + ':' + parts[7];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (parts[2] && parts[2] !== '<inline CSS>') {
|
|
|
+ var w3cDirectUrl = 'http://jigsaw.w3.org/css-validator/validator?uri=' + encodeURIComponent(parts[2]) + '&profile=css3&usermedium=all&warning=no';
|
|
|
+ html += ' (<a href="' + w3cDirectUrl + '" target="_blank">Check on the W3C validator</a>)';
|
|
|
+ }
|
|
|
+
|
|
|
+ return html;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssRules": {
|
|
|
"tool": "phantomas",
|
|
@@ -281,7 +308,14 @@ var policies = {
|
|
|
"message": "<p>Complex selectors are CSS selectors with 4 or more expressions, like \"#header ul li .foo\".</p><p>They are adding more work for the browser, and this could be avoided by simplifying selectors.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 500,
|
|
|
- "isAbnormalThreshold": 2000
|
|
|
+ "isAbnormalThreshold": 2000,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ return '<b>' + splittedOffender.offender + '</b> @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssComplexSelectorsByAttribute": {
|
|
|
"tool": "phantomas",
|
|
@@ -289,7 +323,16 @@ var policies = {
|
|
|
"message": "<p>Complex attributes selectors are one of these:<ul><li>.foo[type*=bar] (contains bar)</li><li>.foo[type^=bar] (starts with bar)</li><li>.foo[type|=bar] (starts with bar or bar-)</li><li>.foo[type$=bar] (ends with bar)</li><li>.foo[type~=bar baz] (bar or baz)</li></ul></p><p>Their matching process needs more CPU and it has a cost on performances.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 50,
|
|
|
- "isAbnormalThreshold": 100
|
|
|
+ "isAbnormalThreshold": 100,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ var boldedOffender = splittedOffender.offender.replace(/(\[[^ ]+[~\|\^\$\*]="[^"]+"\])/g, '<b>$1</b>');
|
|
|
+
|
|
|
+ return boldedOffender + ' @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssImports": {
|
|
|
"tool": "phantomas",
|
|
@@ -297,7 +340,14 @@ var policies = {
|
|
|
"message": "<p>It’s bad for performance to use @import because CSS files don't get downloaded in parallel.</p><p>You should use <link rel='stylesheet' href='a.css'> instead.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 1,
|
|
|
- "isAbnormalThreshold": 1
|
|
|
+ "isAbnormalThreshold": 1,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ return '<b>' + splittedOffender.offender + '</b> @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssDuplicatedSelectors": {
|
|
|
"tool": "phantomas",
|
|
@@ -305,7 +355,19 @@ var policies = {
|
|
|
"message": "<p>This is when two or more selectors are strictly identical and should be merged.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 40,
|
|
|
- "isAbnormalThreshold": 80
|
|
|
+ "isAbnormalThreshold": 80,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var parts = /^(.*) \((\d+) times\)$/.exec(offender);
|
|
|
+
|
|
|
+ if (!parts) {
|
|
|
+ debug('cssDuplicatedSelectors offenders transform function error with "%s"', offender);
|
|
|
+ return offender;
|
|
|
+ }
|
|
|
+
|
|
|
+ return parts[1] + ' (<b>x' + parts[2] + '</b>)';
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssDuplicatedProperties": {
|
|
|
"tool": "phantomas",
|
|
@@ -313,7 +375,21 @@ var policies = {
|
|
|
"message": "<p>This is the number of property definitions duplicated within a selector.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 50,
|
|
|
- "isAbnormalThreshold": 100
|
|
|
+ "isAbnormalThreshold": 100,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ var parts = /^([^{]+) {([^ ]+): (.+)}$/.exec(splittedOffender.offender);
|
|
|
+
|
|
|
+ if (!parts) {
|
|
|
+ debug('cssDuplicatedProperties offenders transform function error with "%s"', offender);
|
|
|
+ return offender;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 'Property <b>' + parts[2] + '</b> duplicated in <b>' + parts[1] + ' { }</b> @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssEmptyRules": {
|
|
|
"tool": "phantomas",
|
|
@@ -321,7 +397,13 @@ var policies = {
|
|
|
"message": "<p>Very easy to fix: remove all empty rules.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 40,
|
|
|
- "isAbnormalThreshold": 100
|
|
|
+ "isAbnormalThreshold": 100,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+ return '<b>' + splittedOffender.offender + ' { }</b> @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssExpressions": {
|
|
|
"tool": "phantomas",
|
|
@@ -329,7 +411,21 @@ var policies = {
|
|
|
"message": "<p>Such as: expression( document.body.clientWidth > 600 ? \"600px\" : \"auto\" )</p><p>This is a bad practice as it slows down browsers. There are some simpler CSS3 methods for doing this.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 1,
|
|
|
- "isAbnormalThreshold": 20
|
|
|
+ "isAbnormalThreshold": 20,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ var parts = /^(.*) {([^ ]+): expression\((.*)\)}$/.exec(splittedOffender.offender);
|
|
|
+
|
|
|
+ if (!parts) {
|
|
|
+ debug('cssExpressions offenders transform function error with "%s"', offender);
|
|
|
+ return offender;
|
|
|
+ }
|
|
|
+
|
|
|
+ return parts[1] + ' {' + parts[2] + ': <b>expression(</b>' + parts[3] + '<b>)</b>} @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssImportants": {
|
|
|
"tool": "phantomas",
|
|
@@ -337,7 +433,21 @@ var policies = {
|
|
|
"message": "<p>It can be useful, but only as a last resort. It is a bad practice because it overrides the normal cascading logic. The more you use !important, the more you need it again to over-override. This conducts to a poor maintainability.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 50,
|
|
|
- "isAbnormalThreshold": 150
|
|
|
+ "isAbnormalThreshold": 150,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ var parts = /^(.*) {([^ ]+): (.*) ?\!important}$/.exec(splittedOffender.offender);
|
|
|
+
|
|
|
+ if (!parts) {
|
|
|
+ debug('cssImportants offenders transform function error with "%s"', offender);
|
|
|
+ return offender;
|
|
|
+ }
|
|
|
+
|
|
|
+ return parts[1] + ' {' + parts[2] + ': ' + parts[3] + ' <b>!important</b>} @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssOldIEFixes": {
|
|
|
"tool": "phantomas",
|
|
@@ -345,7 +455,49 @@ var policies = {
|
|
|
"message": "<p>What browser do you need to support? Once you've got the answer, take a look at these old rules that pollute your CSS code and remove them.</p><p>IE6:<ul><li>* html</li><li>html > body (everything but IE6)</li></ul><p><p>IE7:<ul><li><b>*</b>height: 123px;</li><li>height: 123px <b>!ie</b>;</li></ul><p><p>IE9:<ul><li>-ms-filter</li><li>progid:DXImageTransform.Microsoft</li></ul></p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 50,
|
|
|
- "isAbnormalThreshold": 300
|
|
|
+ "isAbnormalThreshold": 300,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ var parts = /^([^{]*)( {([^ ]+): (.*)})?$/.exec(splittedOffender.offender);
|
|
|
+
|
|
|
+ if (!parts) {
|
|
|
+ debug('cssOldIEFixes offenders transform function error with "%s"', offender);
|
|
|
+ return offender;
|
|
|
+ }
|
|
|
+
|
|
|
+ var rule = parts[1];
|
|
|
+ var property = parts[3];
|
|
|
+ var value = parts[4];
|
|
|
+ var browser = null;
|
|
|
+
|
|
|
+ if (rule.indexOf('* html') === 0) {
|
|
|
+ rule = rule.replace(/^\* html/, '<b>* html</b>');
|
|
|
+ browser = 'IE6';
|
|
|
+ } else if (rule.indexOf('html>body') === 0) {
|
|
|
+ rule = rule.replace(/^html>body/, '<b>html>body</b>');
|
|
|
+ browser = 'IE6';
|
|
|
+ } else if (property.indexOf('*') === 0) {
|
|
|
+ property = '<b>' + property + '</b>';
|
|
|
+ browser = 'IE7';
|
|
|
+ } else if (value.match(/\!ie$/)) {
|
|
|
+ value = value.replace(/\!ie$/, '<b>!ie</b>');
|
|
|
+ browser = 'IE7';
|
|
|
+ } else if (property === '-ms-filter') {
|
|
|
+ property = '<b>-ms-filter</b>';
|
|
|
+ browser = 'IE9';
|
|
|
+ } else if (value.indexOf('progid:DXImageTransform.Microsoft') === 0) {
|
|
|
+ value = value.replace(/^progid:DXImageTransform\.Microsoft/, '<b>progid:DXImageTransform.Microsoft</b>');
|
|
|
+ browser = 'IE9';
|
|
|
+ }
|
|
|
+
|
|
|
+ browser = browser ? '<b>' + browser + ' fix:</b> ' : '';
|
|
|
+ var propertyAndValue = (property && value) ? ' {' + property + ': ' + value + '}' : '';
|
|
|
+
|
|
|
+ return browser + rule + propertyAndValue + ' @ ' + splittedOffender.line + ':' + splittedOffender.character;
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssOldPropertyPrefixes": {
|
|
|
"tool": "phantomas",
|
|
@@ -353,7 +505,21 @@ var policies = {
|
|
|
"message": "<p>Many property prefixes such as -moz- or -webkit- are not needed anymore, or by very few people. You can remove them or replace them with the non-prefixed version. This will help reducing your stylesheets weight.</p>",
|
|
|
"isOkThreshold": 0,
|
|
|
"isBadThreshold": 50,
|
|
|
- "isAbnormalThreshold": 300
|
|
|
+ "isAbnormalThreshold": 300,
|
|
|
+ "offendersTransformFn": function(offenders) {
|
|
|
+ return offenders.map(function(offender) {
|
|
|
+ var splittedOffender = offendersHelpers.cssOffenderPattern(offender);
|
|
|
+
|
|
|
+ var parts = /^([^{]*)(?: { ([^ ]+): (.*) }) \/\/ (.*)$/.exec(splittedOffender.offender);
|
|
|
+
|
|
|
+ if (!parts) {
|
|
|
+ debug('cssOldPropertyPrefixes offenders transform function error with "%s"', offender);
|
|
|
+ return offender;
|
|
|
+ }
|
|
|
+
|
|
|
+ return '<div>' + parts[1] + ' {<b>' + parts[2] + '</b>: ' + parts[3] + '} @ ' + splittedOffender.line + ':' + splittedOffender.character + '</div><div><b>' + parts[4] + '</b></div>';
|
|
|
+ });
|
|
|
+ }
|
|
|
},
|
|
|
"cssUniversalSelectors": {
|
|
|
"tool": "phantomas",
|