New rule: similar colors
This commit is contained in:
@@ -463,7 +463,7 @@ var policies = {
|
||||
},
|
||||
"cssColors": {
|
||||
"tool": "phantomas",
|
||||
"label": "Different colors",
|
||||
"label": "Colors count",
|
||||
"message": "<p>This is the number of different colors defined in CSS.</p><p>Your CSS project will be easier to maintain if you keep a small color set.</p>",
|
||||
"isOkThreshold": 30,
|
||||
"isBadThreshold": 150,
|
||||
@@ -507,6 +507,21 @@ var policies = {
|
||||
};
|
||||
}
|
||||
},
|
||||
"similarColors": {
|
||||
"tool": "colorDiff",
|
||||
"label": "Similar colors",
|
||||
"message": "<p>This is the list of colors found in the stylesheets, that are very close to each other. The eye can barely see the difference.</p><p>Use this list to reduce the number of colors in your palette, it will be easier to maintain.</p>",
|
||||
"isOkThreshold": 0,
|
||||
"isBadThreshold": 40,
|
||||
"isAbnormalThreshold": 80,
|
||||
"hasOffenders": true,
|
||||
"offendersTransformFn": function(offenders) {
|
||||
return {
|
||||
count: offenders.length,
|
||||
list: offenders
|
||||
};
|
||||
}
|
||||
},
|
||||
"cssImports": {
|
||||
"tool": "phantomas",
|
||||
"label": "Uses of @import",
|
||||
@@ -970,7 +985,7 @@ var policies = {
|
||||
"tool": "phantomas",
|
||||
"label": "Hidden images",
|
||||
"message": "<p>List of all images that have a display:none property, or one of their parents. These images are loaded by the browser even if they're not visible. You might be able to find a way to lazy-load them, only when they get visible.</p><p>Trackers are an exception, you'd better hide them.</p>",
|
||||
"isOkThreshold": 3,
|
||||
"isOkThreshold": 1,
|
||||
"isBadThreshold": 12,
|
||||
"isAbnormalThreshold": 30,
|
||||
"hasOffenders": true
|
||||
|
||||
@@ -70,7 +70,8 @@
|
||||
"cssRules": 2,
|
||||
"cssComplexSelectors": 2,
|
||||
"cssComplexSelectorsByAttribute": 1.5,
|
||||
"cssColors": 0.5
|
||||
"cssColors": 0.5,
|
||||
"similarColors": 0.5
|
||||
}
|
||||
},
|
||||
"badCSS": {
|
||||
|
||||
@@ -3,6 +3,7 @@ var debug = require('debug')('ylt:runner');
|
||||
|
||||
var phantomasWrapper = require('./tools/phantomas/phantomasWrapper');
|
||||
var jsExecutionTransformer = require('./tools/jsExecutionTransformer');
|
||||
var colorDiff = require('./tools/colorDiff');
|
||||
var weightChecker = require('./tools/weightChecker/weightChecker');
|
||||
var rulesChecker = require('./rulesChecker');
|
||||
var scoreCalculator = require('./scoreCalculator');
|
||||
@@ -28,6 +29,9 @@ var Runner = function(params) {
|
||||
// Treat the JS Execution Tree from offenders
|
||||
data = jsExecutionTransformer.transform(data);
|
||||
|
||||
// Compare colors
|
||||
data = colorDiff.compareAllColors(data);
|
||||
|
||||
// Redownload every file
|
||||
return weightChecker.recheckAllFiles(data);
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
var debug = require('debug')('ylt:colorDiff');
|
||||
var diff = require('color-diff');
|
||||
var parse = require('parse-color');
|
||||
|
||||
|
||||
var colorDiff = function() {
|
||||
|
||||
var COLOR_DIFF_THRESHOLD = 0.9;
|
||||
|
||||
this.compareAllColors = function(data) {
|
||||
debug('Starting to compare all colors...');
|
||||
|
||||
var offenders = data.toolsResults.phantomas.offenders.cssColors;
|
||||
var colors = (offenders) ? this.parseAllColors(offenders) : [];
|
||||
var result = [];
|
||||
|
||||
// Compare colors to each other
|
||||
for (var i = 0; i < colors.length - 1 ; i++) {
|
||||
for (var j = i + 1; j < colors.length; j++) {
|
||||
debug('Comparing color %s with color %s', colors[i].original, colors[j].original);
|
||||
if (this.compareTwoColors(colors[i], colors[j])) {
|
||||
debug('Colors are similar!');
|
||||
result.push({
|
||||
color1: colors[i].original,
|
||||
color2: colors[j].original,
|
||||
isDark: (colors[i].Lab.L < 60)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.toolsResults.colorDiff = {
|
||||
metrics: {
|
||||
similarColors: result.length
|
||||
},
|
||||
offenders: {
|
||||
similarColors: result
|
||||
}
|
||||
};
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
this.parseAllColors = function(offenders) {
|
||||
var parsedOffenders = offenders.map(this.parseOffender);
|
||||
var deduplicatedColors = {};
|
||||
|
||||
parsedOffenders.forEach(function(color) {
|
||||
deduplicatedColors[color] = color;
|
||||
});
|
||||
|
||||
return Object.keys(deduplicatedColors).map(this.parseColor);
|
||||
};
|
||||
|
||||
this.parseOffender = function(offender) {
|
||||
var regexResult = /^(.*) \(\d+ times\)$/.exec(offender);
|
||||
return regexResult[1];
|
||||
};
|
||||
|
||||
this.parseColor = function(color) {
|
||||
var colorArray = parse(color).rgba;
|
||||
|
||||
var obj = {
|
||||
R: colorArray[0],
|
||||
G: colorArray[1],
|
||||
B: colorArray[2],
|
||||
A: colorArray[3]
|
||||
};
|
||||
|
||||
obj.Lab = diff.rgb_to_lab(obj);
|
||||
obj.original = color;
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
this.compareTwoColors = function(color1, color2) {
|
||||
if (color1.A !== color2.A) {
|
||||
debug('Comparison not possible, because the alpha channel is different');
|
||||
return false;
|
||||
}
|
||||
|
||||
var delta = diff.diff(color1.Lab, color2.Lab);
|
||||
debug('Delta is %d', delta);
|
||||
|
||||
return delta <= COLOR_DIFF_THRESHOLD;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
module.exports = new colorDiff();
|
||||
Reference in New Issue
Block a user