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(postcss-minify-gradients): handle uppercase #706

Merged
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
92 changes: 91 additions & 1 deletion packages/postcss-minify-gradients/src/__tests__/index.js
Expand Up @@ -60,6 +60,13 @@ test(
'background:repeating-linear-gradient(0deg,#ffe500,#121)'
);

test(
'repeating-linear: should convert "to top" to 0deg (uppercase)',
processCSS,
'background:REPEATING-LINEAR-GRADIENT(TO TOP,#ffe500,#121)',
'background:REPEATING-LINEAR-GRADIENT(0deg,#ffe500,#121)'
);

test(
'repeating-linear: should convert "to right" to 90deg',
processCSS,
Expand Down Expand Up @@ -100,6 +107,13 @@ test(
'background:linear-gradient(45deg,#ffe500 50%,#121 0)'
);

test(
'linear: should reduce length values if they are the same (uppercase)',
processCSS,
'background:LINEAR-GRADIENT(45DEG,#FFE500 50%,#121 50%)',
'background:LINEAR-GRADIENT(45DEG,#FFE500 50%,#121 0)'
);

test(
'linear: should reduce length values if they are less',
processCSS,
Expand Down Expand Up @@ -134,12 +148,18 @@ test(
'BACKGROUND:REPEATING-RADIAL-GRADIENT(#121,#121 5PX,#FFE500 0,#FFE500 10PX)'
);

test(
'repeating-radial: should reduce length values if they are the same (last is zero)',
processCSS,
'BACKGROUND:REPEATING-RADIAL-GRADIENT(#121,#121 5PX,#FFE500 5PX,#FFE500 0)',
'BACKGROUND:REPEATING-RADIAL-GRADIENT(#121,#121 5PX,#FFE500 0,#FFE500 0)'
);

test(
'radial: should correctly account for "at"',
passthroughCSS,
'background:radial-gradient(at 50% 0%,rgba(74,74,74,.15),transparent 40%);'
);

test(
'radial: should correctly account for uppercase "at"',
passthroughCSS,
Expand All @@ -154,6 +174,12 @@ test(
'background:radial-gradient(at 50% 0%,rgba(74,74,74,.15),transparent 40%, red 0);'
);

test(
'radial: should correctly account for "at" (2) (uppercase)',
processCSS,
'background:radial-gradient(AT 50% 0%,RGBA(74,74,74,.15),TRANSPARENT 40%, RED 40%);',
'background:radial-gradient(AT 50% 0%,RGBA(74,74,74,.15),TRANSPARENT 40%, RED 0);'
);

test(
'radial: should correctly account with prefix "-webkit" (1)',
Expand All @@ -162,13 +188,42 @@ test(
'background: -webkit-radial-gradient(50% 26%, circle, #fff, rgba(255, 255, 255, 0) 24%)'
);


test(
'radial: should correctly account with prefix "-webkit" (1) (uppercase)',
processCSS,
'background: -WEBKIT-RADIAL-GRADIENT(50% 26%, circle, #fff, rgba(255, 255, 255, 0) 24%)',
'background: -WEBKIT-RADIAL-GRADIENT(50% 26%, circle, #fff, rgba(255, 255, 255, 0) 24%)'
);

test(
'radial: should correctly account with prefix "-webkit" (1) with px',
processCSS,
'background: -webkit-radial-gradient(50% 26px, circle, #fff, rgba(255, 255, 255, 0) 24%)',
'background: -webkit-radial-gradient(50% 26px, circle, #fff, rgba(255, 255, 255, 0) 24%)'
);

test(
'radial: should correctly account with prefix "-webkit" (1) with px (uppercase)',
processCSS,
'background: -webkit-radial-gradient(50% 26PX, circle, #fff, rgba(255, 255, 255, 0) 24%)',
'background: -webkit-radial-gradient(50% 26PX, circle, #fff, rgba(255, 255, 255, 0) 24%)'
);

test(
'radial: should correctly account with prefix "-webkit" (2)',
processCSS,
'background: -webkit-radial-gradient(center, 30% 30%, white 20%, black 10%)',
'background: -webkit-radial-gradient(center, 30% 30%, white 20%, black 0)'
);

test(
'radial: should correctly account with prefix "-webkit" (2) (uppercase)',
processCSS,
'background: -WEBKIT-RADIAL-GRADIENT(CENTER, 30% 30%, WHITE 20%, BLACK 10%)',
'background: -WEBKIT-RADIAL-GRADIENT(CENTER, 30% 30%, WHITE 20%, BLACK 0)'
);

test(
'radial: should correctly account with prefix "-webkit" (3)',
processCSS,
Expand All @@ -183,20 +238,55 @@ test(
'background: -webkit-radial-gradient(white 50%, black 0)'
);

test(
'radial: should correctly account with prefix "-webkit" (4) (uppercase)',
processCSS,
'background: -WEBKIT-RADIAL-GRADIENT(WHITE 50%, BLACK 40%)',
'background: -WEBKIT-RADIAL-GRADIENT(WHITE 50%, BLACK 0)'
);

test(
'radial: should correctly account with prefix "-webkit" (4) with px (uppercase)',
processCSS,
'background: -WEBKIT-RADIAL-GRADIENT(WHITE 50px, BLACK 400PX)',
'background: -WEBKIT-RADIAL-GRADIENT(WHITE 50px, BLACK 400PX)'
);

test(
'radial: should correctly account with prefix "-webkit" (5)',
processCSS,
'background: -webkit-radial-gradient(white calc(30%), black calc(50%))',
'background: -webkit-radial-gradient(white calc(30%), black calc(50%))'
);

test(
'radial: should correctly account with prefix "-webkit" (5) (calc uppercase)',
processCSS,
'background: -webkit-radial-gradient(white CALC(30%), black calc(50%))',
'background: -webkit-radial-gradient(white CALC(30%), black calc(50%))'
);

test(
'should not mangle floating point numbers',
processCSS,
'background:linear-gradient(#fff,#fff 2em,#ccc 2em,#ccc 2.1em,#fff 2.1em)',
'background:linear-gradient(#fff,#fff 2em,#ccc 0,#ccc 2.1em,#fff 0)'
);

test(
'should not mangle floating point numbers (uppercase)',
processCSS,
'background:LINEAR-GRADIENT(#FFF,#FFF 2EM,#CCC 2EM,#CCC 2.1EM,#FFF 2.1EM)',
'background:LINEAR-GRADIENT(#FFF,#FFF 2EM,#CCC 0,#CCC 2.1EM,#FFF 0)'
);

test(
'should not mangle floating point numbers 1 (uppercase)',
processCSS,
'background:lInEaR-gRaDiEnT(#fFf,#fFf 2Em,#cCc 2eM,#cCc 2.1eM,#fFf 2.1EM)',
'background:lInEaR-gRaDiEnT(#fFf,#fFf 2Em,#cCc 0,#cCc 2.1eM,#fFf 0)'
);

test(
'should not remove the trailing zero if it is the last stop',
passthroughCSS,
Expand Down
53 changes: 46 additions & 7 deletions packages/postcss-minify-gradients/src/index.js
Expand Up @@ -11,91 +11,120 @@ const angles = {
};

function isLessThan (a, b) {
return a.unit === b.unit && parseFloat(a.number) >= parseFloat(b.number);
return a.unit.toLowerCase() === b.unit.toLowerCase() && parseFloat(a.number) >= parseFloat(b.number);
}

function optimise (decl) {
if (!~decl.value.toLowerCase().indexOf('gradient')) {
const value = decl.value;

if (!~value.toLowerCase().indexOf('gradient')) {
return;
}
decl.value = valueParser(decl.value).walk(node => {

decl.value = valueParser(value).walk(node => {
if (node.type !== 'function' || !node.nodes.length) {
return false;
}

const lowerCasedValue = node.value.toLowerCase();

if (
lowerCasedValue === 'linear-gradient' ||
lowerCasedValue === 'repeating-linear-gradient' ||
lowerCasedValue === '-webkit-linear-gradient' ||
lowerCasedValue === '-webkit-repeating-linear-gradient'
) {
let args = getArguments(node);

if (node.nodes[0].value.toLowerCase() === 'to' && args[0].length === 3) {
node.nodes = node.nodes.slice(2);
node.nodes[0].value = angles[node.nodes[0].value.toLowerCase()];
}

let lastStop = null;

args.forEach((arg, index) => {
if (!arg[2]) {
return;
}

let isFinalStop = index === args.length - 1;
let thisStop = unit(arg[2].value);

if (lastStop === null) {
lastStop = thisStop;

if (!isFinalStop && lastStop && lastStop.number === '0' && lastStop.unit.toLowerCase() !== 'deg') {
arg[1].value = arg[2].value = '';
}

return;
}
if (isLessThan(lastStop, thisStop)) {

if (lastStop && thisStop && isLessThan(lastStop, thisStop)) {
arg[2].value = 0;
}

lastStop = thisStop;

if (isFinalStop && arg[2].value === '100%') {
arg[1].value = arg[2].value = '';
}
});

return false;
}

if (
lowerCasedValue === 'radial-gradient' ||
lowerCasedValue === 'repeating-radial-gradient'
) {
let args = getArguments(node);
let lastStop;

const hasAt = args[0].find(n => n.value.toLowerCase() === 'at');

args.forEach((arg, index) => {
if (!arg[2] || !index && hasAt) {
return;
}

let thisStop = unit(arg[2].value);

if (!lastStop) {
lastStop = thisStop;

return;
}
if (isLessThan(lastStop, thisStop)) {

if (lastStop && thisStop && isLessThan(lastStop, thisStop)) {
arg[2].value = 0;
}

lastStop = thisStop;
});

return false;
}

if (
lowerCasedValue === '-webkit-radial-gradient' ||
lowerCasedValue === '-webkit-repeating-radial-gradient'
) {
let args = getArguments(node);
let lastStop;

args.forEach((arg) => {
let color;
let stop;

if (arg[2] !== undefined) {
if (arg[0].type === 'function') {
color = `${arg[0].value}(${stringify(arg[0].nodes)})`;
} else {
color = arg[0].value;
}

if (arg[2].type === 'function') {
stop = `${arg[2].value}(${stringify(arg[2].nodes)})`;
} else {
Expand All @@ -105,25 +134,35 @@ function optimise (decl) {
if (arg[0].type === 'function') {
color = `${arg[0].value}(${stringify(arg[0].nodes)})`;
}

color = arg[0].value;
}

color = color.toLowerCase();

const colorStop = stop || stop === 0 ?
isColorStop(color, stop) :
isColorStop(color, stop.toLowerCase()) :
isColorStop(color);

if (!colorStop || !arg[2]) {
return;
}

let thisStop = unit(arg[2].value);

if (!lastStop) {
lastStop = thisStop;

return;
}
if (isLessThan(lastStop, thisStop)) {

if (lastStop && thisStop && isLessThan(lastStop, thisStop)) {
arg[2].value = 0;
}

lastStop = thisStop;
});

return false;
}
}).toString();
Expand Down