Merge pull request #2627 from lydell/css-numbers

Normalize numbers in CSS like JS
master
Simon Lydell 2017-08-22 19:05:08 +02:00 committed by GitHub
commit 854bb3ccc5
12 changed files with 262 additions and 34 deletions

View File

@ -32,7 +32,7 @@
"postcss-media-query-parser": "0.2.3",
"postcss-scss": "1.0.0",
"postcss-selector-parser": "2.2.3",
"postcss-values-parser": "git://github.com/shellscape/postcss-values-parser.git#5e351360479116f3fe309602cdd15b0a233bc29f",
"postcss-values-parser": "git://github.com/lydell/postcss-values-parser.git#af2c80b2bb558a6e7d61540d97f068f9fa162b38",
"strip-bom": "3.0.0",
"typescript": "2.5.0-dev.20170617",
"typescript-eslint-parser": "git://github.com/eslint/typescript-eslint-parser.git#01c34f44e7bb3b8a1ec3d28433a6e0c9b2901d3c"

View File

@ -104,6 +104,16 @@ function massageAST(ast) {
delete newObj.quoted;
}
if (
(ast.type === "media-value" || ast.type === "value-number") &&
newObj.value
) {
newObj.value = newObj.value.replace(/[\d.eE+-]+/g, match => {
const num = Number(match);
return isNaN(num) ? match : num;
});
}
// (TypeScript) Ignore `static` in `constructor(static p) {}`
// and `export` in `constructor(export p) {}`
if (

View File

@ -179,7 +179,7 @@ function genericPrint(path, options, print) {
return concat([n.value, " "]);
}
case "media-value": {
return adjustStrings(n.value, options);
return adjustNumbers(adjustStrings(n.value, options));
}
case "media-keyword": {
return n.value;
@ -337,7 +337,7 @@ function genericPrint(path, options, print) {
return n.value;
}
case "value-number": {
return concat([n.value, n.unit]);
return concat([printNumber(n.value), n.unit]);
}
case "value-operator": {
return n.value;
@ -419,6 +419,11 @@ function printValue(value) {
}
const STRING_REGEX = /(['"])(?:(?!\1)[^\\]|\\[\s\S])*\1/g;
const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g;
const STRING_OR_NUMBER_REGEX = RegExp(
`${STRING_REGEX.source}|(${NUMBER_REGEX.source})`,
"g"
);
function adjustStrings(value, options) {
return value.replace(STRING_REGEX, match => util.printString(match, options));
@ -431,4 +436,20 @@ function quoteAttributeValue(value, options) {
: quote + value + quote;
}
function adjustNumbers(value) {
return value.replace(
STRING_OR_NUMBER_REGEX,
(match, quote, number) => (number ? printNumber(number) : match)
);
}
function printNumber(rawNumber) {
return (
util
.printNumber(rawNumber)
// Remove trailing `.0`.
.replace(/\.0(?=$|e)/, "")
);
}
module.exports = genericPrint;

View File

@ -1159,7 +1159,7 @@ function genericPrintNoParens(path, options, print, args) {
case "RegExpLiteral": // Babel 6 Literal split
return printRegex(n);
case "NumericLiteral": // Babel 6 Literal split
return printNumber(n.extra.raw);
return util.printNumber(n.extra.raw);
case "BooleanLiteral": // Babel 6 Literal split
case "StringLiteral": // Babel 6 Literal split
case "Literal": {
@ -1167,7 +1167,7 @@ function genericPrintNoParens(path, options, print, args) {
return printRegex(n.regex);
}
if (typeof n.value === "number") {
return printNumber(n.raw);
return util.printNumber(n.raw);
}
if (typeof n.value !== "string") {
return "" + n.value;
@ -2239,9 +2239,9 @@ function genericPrintNoParens(path, options, print, args) {
assert.strictEqual(typeof n.value, "number");
if (n.extra != null) {
return printNumber(n.extra.raw);
return util.printNumber(n.extra.raw);
}
return printNumber(n.raw);
return util.printNumber(n.raw);
case "StringTypeAnnotation":
return "string";
@ -4336,23 +4336,6 @@ function printRegex(node) {
return `/${node.pattern}/${flags}`;
}
function printNumber(rawNumber) {
return (
rawNumber
.toLowerCase()
// Remove unnecessary plus and zeroes from scientific notation.
.replace(/^([\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3")
// Remove unnecessary scientific notation (1e0).
.replace(/^([\d.]+)e[+-]?0+$/, "$1")
// Make sure numbers always start with a digit.
.replace(/^\./, "0.")
// Remove extraneous trailing decimal zeroes.
.replace(/(\.\d+?)0+(?=e|$)/, "$1")
// Remove trailing dot.
.replace(/\.(?=e|$)/, "")
);
}
function isLastStatement(path) {
const parent = path.getParentNode();
if (!parent) {

View File

@ -567,6 +567,23 @@ function makeString(rawContent, enclosingQuote, unescapeUnnecessaryEscapes) {
return enclosingQuote + newContent + enclosingQuote;
}
function printNumber(rawNumber) {
return (
rawNumber
.toLowerCase()
// Remove unnecessary plus and zeroes from scientific notation.
.replace(/^([\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3")
// Remove unnecessary scientific notation (1e0).
.replace(/^([\d.]+)e[+-]?0+$/, "$1")
// Make sure numbers always start with a digit.
.replace(/^\./, "0.")
// Remove extraneous trailing decimal zeroes.
.replace(/(\.\d+?)0+(?=e|$)/, "$1")
// Remove trailing dot.
.replace(/\.(?=e|$)/, "")
);
}
module.exports = {
getPrecedence,
shouldFlatten,
@ -593,5 +610,6 @@ module.exports = {
isBlockComment,
hasClosureCompilerTypeCastComment,
getAlignmentSize,
printString
printString,
printNumber
};

View File

@ -10,11 +10,11 @@ exports[`if-else.css 1`] = `
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@if $media == phonePortrait {
$k: .15625;
$k: 0.15625;
} @else if $media == phoneLandscape {
$k: .08803;
$k: 0.08803;
} @else if $media == tabletPortrait {
$k: .065106;
$k: 0.065106;
}
`;

View File

@ -0,0 +1,132 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`numbers.css 1`] = `
@supports (margin: .5px ".30px" 1E+2px) {
a {
a: 0;
a: 1;
a: 0.1;
a: 1.1;
a: .1;
a: 1.;
a: 1e1;
a: 1e+1;
a: 1e-1;
a: 1.e1;
a: .1e1;
a: 1.1e1;
a: 1.1e0010;
a: .1e+0010;
a: .1e-0010;
a: 1E1;
a: 1E+1;
a: 1E-1;
a: 1.E1;
a: .1E1;
a: 1.1E1;
a: 1.1E0010;
a: .1E+0010;
a: .1E-0010;
a: 0.5e0;
a: 0.5e00;
a: 0.5e+0;
a: 0.5e+00;
a: 0.5e-0;
a: 0.5e-00;
a: 1;
a: 1.00500;
a: 1.0;
a: 1.5;
a: 1.50;
a: 0.00500;
a: 0.0;
a: 0.0000;
a: 500600.001230045000;
a: 1.00500e60;
a: 1.0e60;
a: 0.00500e60;
a: 0.0e60;
a: 0.0000e60;
a: .0e60;
a: 0.e60;
a: 0e60;
a: 500600.001230045000e60;
a: 10;
a: 9700;
a: 10e100;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@supports (margin: 0.5px ".30px" 1e2px) {
a {
a: 0;
a: 1;
a: 0.1;
a: 1.1;
a: 0.1;
a: 1;
a: 1e1;
a: 1e1;
a: 1e-1;
a: 1e1;
a: 0.1e1;
a: 1.1e1;
a: 1.1e10;
a: 0.1e10;
a: 0.1e-10;
a: 1e1;
a: 1e1;
a: 1e-1;
a: 1e1;
a: 0.1e1;
a: 1.1e1;
a: 1.1e10;
a: 0.1e10;
a: 0.1e-10;
a: 0.5;
a: 0.5;
a: 0.5;
a: 0.5;
a: 0.5;
a: 0.5;
a: 1;
a: 1.005;
a: 1;
a: 1.5;
a: 1.5;
a: 0.005;
a: 0;
a: 0;
a: 500600.001230045;
a: 1.005e60;
a: 1e60;
a: 0.005e60;
a: 0e60;
a: 0e60;
a: 0e60;
a: 0e60;
a: 0e60;
a: 500600.001230045e60;
a: 10;
a: 9700;
a: 10e100;
}
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,63 @@
@supports (margin: .5px ".30px" 1E+2px) {
a {
a: 0;
a: 1;
a: 0.1;
a: 1.1;
a: .1;
a: 1.;
a: 1e1;
a: 1e+1;
a: 1e-1;
a: 1.e1;
a: .1e1;
a: 1.1e1;
a: 1.1e0010;
a: .1e+0010;
a: .1e-0010;
a: 1E1;
a: 1E+1;
a: 1E-1;
a: 1.E1;
a: .1E1;
a: 1.1E1;
a: 1.1E0010;
a: .1E+0010;
a: .1E-0010;
a: 0.5e0;
a: 0.5e00;
a: 0.5e+0;
a: 0.5e+00;
a: 0.5e-0;
a: 0.5e-00;
a: 1;
a: 1.00500;
a: 1.0;
a: 1.5;
a: 1.50;
a: 0.00500;
a: 0.0;
a: 0.0000;
a: 500600.001230045000;
a: 1.00500e60;
a: 1.0e60;
a: 0.00500e60;
a: 0.0e60;
a: 0.0000e60;
a: .0e60;
a: 0.e60;
a: 0e60;
a: 500600.001230045000e60;
a: 10;
a: 9700;
a: 10e100;
}
}

View File

@ -100,7 +100,7 @@ table {
filter: blur(4px);
}
.sepia {
filter: sepia(.8);
filter: sepia(0.8);
}
`;

View File

@ -12,8 +12,8 @@ exports[`values.css 1`] = `
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.class {
background: linear-gradient(to bottom right, white, hsla(0, 0%, 100%, .8));
border: 1px solid rgba(0, 0, 0, .3);
background: linear-gradient(to bottom right, white, hsla(0, 0%, 100%, 0.8));
border: 1px solid rgba(0, 0, 0, 0.3);
font-family: Arial, sans-serif;
color: rgba(0, 0, 0, 1);
margin: 0 20px 0 -24px;

View File

@ -2998,9 +2998,9 @@ postcss-selector-parser@2.2.3:
indexes-of "^1.0.1"
uniq "^1.0.1"
"postcss-values-parser@git://github.com/shellscape/postcss-values-parser.git#5e351360479116f3fe309602cdd15b0a233bc29f":
version "1.2.2"
resolved "git://github.com/shellscape/postcss-values-parser.git#5e351360479116f3fe309602cdd15b0a233bc29f"
"postcss-values-parser@git://github.com/lydell/postcss-values-parser.git#af2c80b2bb558a6e7d61540d97f068f9fa162b38":
version "1.3.0"
resolved "git://github.com/lydell/postcss-values-parser.git#af2c80b2bb558a6e7d61540d97f068f9fa162b38"
dependencies:
flatten "^1.0.2"
indexes-of "^1.0.1"