Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(colors): convert rgba/hsla to rgb/hsl if opacity is >= 1 #1083

Merged
merged 1 commit into from Nov 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 18 additions & 8 deletions lib/optimizer/level-1/optimize.js
Expand Up @@ -89,16 +89,25 @@ function optimizeBorderRadius(property) {
}
}

/**
* @param {string} name
* @param {string} value
* @param {Object} compatibility
* @return {string}
*/
function optimizeColors(name, value, compatibility) {
if (value.indexOf('#') === -1 && value.indexOf('rgb') == -1 && value.indexOf('hsl') == -1) {
if (!value.match(/#|rgb|hsl/gi)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this change may lead to a slight performance degradation, but let's merge it and fix if needed.

return shortenHex(value);
}

value = value
.replace(/rgb\((\-?\d+),(\-?\d+),(\-?\d+)\)/g, function (match, red, green, blue) {
.replace(/(rgb|hsl)a?\((\-?\d+),(\-?\d+\%?),(\-?\d+\%?),(0*[1-9]+[0-9]*(.?\d*)?)\)/gi, function (match, colorFn, p1, p2, p3, alpha) {
return (parseInt(alpha, 10) >= 1 ? colorFn + '(' + [p1,p2,p3].join(',') + ')' : match);
})
.replace(/rgb\((\-?\d+),(\-?\d+),(\-?\d+)\)/gi, function (match, red, green, blue) {
return shortenRgb(red, green, blue);
})
.replace(/hsl\((-?\d+),(-?\d+)%?,(-?\d+)%?\)/g, function (match, hue, saturation, lightness) {
.replace(/hsl\((-?\d+),(-?\d+)%?,(-?\d+)%?\)/gi, function (match, hue, saturation, lightness) {
return shortenHsl(hue, saturation, lightness);
})
.replace(/(^|[^='"])#([0-9a-f]{6})/gi, function (match, prefix, color, at, inputValue) {
Expand All @@ -115,12 +124,13 @@ function optimizeColors(name, value, compatibility) {
.replace(/(^|[^='"])#([0-9a-f]{3})/gi, function (match, prefix, color) {
return prefix + '#' + color.toLowerCase();
})
.replace(/(rgb|rgba|hsl|hsla)\(([^\)]+)\)/g, function (match, colorFunction, colorDef) {
.replace(/(rgb|rgba|hsl|hsla)\(([^\)]+)\)/gi, function (match, colorFunction, colorDef) {
var tokens = colorDef.split(',');
var applies = (colorFunction == 'hsl' && tokens.length == 3) ||
(colorFunction == 'hsla' && tokens.length == 4) ||
(colorFunction == 'rgb' && tokens.length == 3 && colorDef.indexOf('%') > 0) ||
(colorFunction == 'rgba' && tokens.length == 4 && colorDef.indexOf('%') > 0);
var colorFnLowercase = colorFunction && colorFunction.toLowerCase();
var applies = (colorFnLowercase == 'hsl' && tokens.length == 3) ||
(colorFnLowercase == 'hsla' && tokens.length == 4) ||
(colorFnLowercase == 'rgb' && tokens.length === 3 && colorDef.indexOf('%') > 0) ||
(colorFnLowercase == 'rgba' && tokens.length == 4 && colorDef.indexOf('%') > 0);

if (!applies) {
return match;
Expand Down
4 changes: 2 additions & 2 deletions lib/optimizer/validator.js
Expand Up @@ -6,11 +6,11 @@ var functionAnyRegexStr = '(' + variableRegexStr + '|' + functionNoVendorRegexSt
var calcRegex = new RegExp('^(\\-moz\\-|\\-webkit\\-)?calc\\([^\\)]+\\)$', 'i');
var decimalRegex = /[0-9]/;
var functionAnyRegex = new RegExp('^' + functionAnyRegexStr + '$', 'i');
var hslColorRegex = /^hsl\(\s{0,31}[\-\.]?\d+\s{0,31},\s{0,31}\.?\d+%\s{0,31},\s{0,31}\.?\d+%\s{0,31}\)|hsla\(\s{0,31}[\-\.]?\d+\s{0,31},\s{0,31}\.?\d+%\s{0,31},\s{0,31}\.?\d+%\s{0,31},\s{0,31}\.?\d+\s{0,31}\)$/;
var hslColorRegex = /^hsl\(\s{0,31}[\-\.]?\d+\s{0,31},\s{0,31}\.?\d+%\s{0,31},\s{0,31}\.?\d+%\s{0,31}\)|hsla\(\s{0,31}[\-\.]?\d+\s{0,31},\s{0,31}\.?\d+%\s{0,31},\s{0,31}\.?\d+%\s{0,31},\s{0,31}\.?\d+\s{0,31}\)$/i;
var identifierRegex = /^(\-[a-z0-9_][a-z0-9\-_]*|[a-z][a-z0-9\-_]*)$/i;
var namedEntityRegex = /^[a-z]+$/i;
var prefixRegex = /^-([a-z0-9]|-)*$/i;
var rgbColorRegex = /^rgb\(\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31}\)|rgba\(\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\.\d]+\s{0,31}\)$/;
var rgbColorRegex = /^rgb\(\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31}\)|rgba\(\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\.\d]+\s{0,31}\)$/i;
var timingFunctionRegex = /^(cubic\-bezier|steps)\([^\)]+\)$/;
var validTimeUnits = ['ms', 's'];
var urlRegex = /^url\([\s\S]+\)$/i;
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/big-min.css
Expand Up @@ -189,7 +189,7 @@ body{font-size:13px;line-height:140%;color:#16212c;background:#e9edf0}
.global{width:1000px;margin:0 auto;padding:20px 0 10px;background:#fff}
.lmd-header{position:relative;z-index:15}
.lmd-header #header{margin-bottom:16px}
.deroule_edito,.deroule_fleuve,.ombre_section,.une_edito{-webkit-box-shadow:0 6px 6px -6px rgba(202,205,209,1);-moz-box-shadow:0 6px 6px -6px rgba(202,205,209,1);box-shadow:0 6px 6px -6px rgba(202,205,209,1);padding-top:0;margin-bottom:16px;margin-top:16px;overflow:hidden}
.deroule_edito,.deroule_fleuve,.ombre_section,.une_edito{-webkit-box-shadow:0 6px 6px -6px #cacdd1;-moz-box-shadow:0 6px 6px -6px #cacdd1;box-shadow:0 6px 6px -6px #cacdd1;padding-top:0;margin-bottom:16px;margin-top:16px;overflow:hidden}
a{color:#036;text-decoration:none;cursor:pointer}
.bg_fonce a{opacity:.85}
.obf{cursor:pointer;color:#036}
Expand Down
16 changes: 10 additions & 6 deletions test/integration-test.js
Expand Up @@ -158,9 +158,13 @@ vows.describe('integration tests')
'a{text-shadow:rgb(255,0,1) 1px 1px}',
'a{text-shadow:#ff0001 1px 1px}'
],
'after rgba': [
'after rgba #1': [
'a{text-shadow:rgba(255,0,0,.1) 0 1px}',
'a{text-shadow:rgba(255,0,0,.1) 0 1px}'
],
'after rgba #2': [
'a{text-shadow:rgba(255,0,0,1) 0 1px}',
'a{text-shadow:rgba(255,0,0,1) 0 1px}'
'a{text-shadow:red 0 1px}'
],
'after hsl': [
'a{text-shadow:hsl(240,100%,40%) -1px 1px}',
Expand Down Expand Up @@ -215,8 +219,8 @@ vows.describe('integration tests')
'a{text-shadow:#ff0001 1px 1px}'
],
'after rgba': [
'a{text-shadow:rgba(255,0,0,1) 0 1px}',
'a{text-shadow:rgba(255,0,0,1) 0 1px}'
'a{text-shadow:rgba(255,0,0,.1) 0 1px}',
'a{text-shadow:rgba(255,0,0,.1) 0 1px}'
],
'after hsl': [
'a{text-shadow:hsl(240,100%,40%) -1px 1px}',
Expand Down Expand Up @@ -695,8 +699,8 @@ vows.describe('integration tests')
'a{-webkit-box-shadow:0 0;-moz-box-shadow:0 0}'
],
'zero as .0 #1': [
'a{color:rgba(0,0,.0,1)}',
'a{color:rgba(0,0,0,1)}'
'a{color:rgba(0,0,.0,.1)}',
'a{color:rgba(0,0,0,.1)}'
],
'zero as .0 #2': [
'body{margin:.0}',
Expand Down