From 538ce6d20904e15456a2e67368901a0e8137447f Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Wed, 1 Nov 2017 15:21:59 -0200 Subject: [PATCH] Preserve line breaks in css grid declaration --- src/printer-postcss.js | 30 ++- .../css_grid/__snapshots__/jsfmt.spec.js.snap | 234 ++++++++++++++++++ tests/css_grid/grid.css | 114 +++++++++ tests/css_grid/jsfmt.spec.js | 1 + 4 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 tests/css_grid/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/css_grid/grid.css create mode 100644 tests/css_grid/jsfmt.spec.js diff --git a/src/printer-postcss.js b/src/printer-postcss.js index 4b9a77ab..f29b5e36 100644 --- a/src/printer-postcss.js +++ b/src/printer-postcss.js @@ -283,8 +283,22 @@ function genericPrint(path, options, print) { return path.call(print, "group"); } case "value-comma_group": { + const parent = path.getParentNode(); + let declParent; + let i = 0; + do { + declParent = path.getParentNode(i++); + } while (declParent && declParent.type !== "css-decl"); + + const declParentProp = declParent.prop.toLowerCase(); + const isGridValue = + parent.type === "value-value" && + (declParentProp === "grid" || + declParentProp.startsWith("grid-template")); + const printed = path.map(print, "groups"); const parts = []; + let didBreak = false; for (let i = 0; i < n.groups.length; ++i) { parts.push(printed[i]); if ( @@ -292,7 +306,17 @@ function genericPrint(path, options, print) { n.groups[i + 1].raws && n.groups[i + 1].raws.before !== "" ) { - if ( + if (isGridValue) { + if ( + n.groups[i].source.start.line !== + n.groups[i + 1].source.start.line + ) { + parts.push(hardline); + didBreak = true; + } else { + parts.push(" "); + } + } else if ( n.groups[i + 1].type === "value-operator" && ["+", "-", "/", "*", "%"].indexOf(n.groups[i + 1].value) !== -1 ) { @@ -303,6 +327,10 @@ function genericPrint(path, options, print) { } } + if (didBreak) { + parts.unshift(hardline); + } + return group(indent(fill(parts))); } case "value-paren_group": { diff --git a/tests/css_grid/__snapshots__/jsfmt.spec.js.snap b/tests/css_grid/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 00000000..138fddc7 --- /dev/null +++ b/tests/css_grid/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,234 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`grid.css 1`] = ` +/* quotes */ +div { + grid-template-areas: + 'header header' + 'main sidebar' + 'footer footer'; +} + +/* numbers */ +div { + grid-template-columns: + [full-start] minmax(1.50em, 1fr) + [main-start] minmax(.40ch, 75ch) + [main-end] minmax(1em, 1.000fr) + [full-end]; +} + +/* casing */ +div { + GRID: + [top] 1fr + [middle] 1fr + bottom; + + grid-TEMPLATE: + "a a a" 200px + "b b b" 200px + / 200px 200px auto; +} + +/* break before first line if there are any breaks */ +div { + grid-template-columns: + 1fr 100px 3em; + grid: [wide-start] "header header header" 200px [wide-end] + "footer footer footer" 25px + / auto 50px auto; +} + +/** + * https://github.com/prettier/prettier/issues/2703#issuecomment-341188126 + */ +.container { + display: grid; + + /* basic template rows/columns */ + grid-template-columns: 1fr 100px 3em; + grid-template-rows: 1fr 100px 3em; + /* template rows/columns with named grid lines */ + grid-template-columns: + [wide-start] 1fr + [main-start] 500px + [main-end] 1fr + [wide-end]; + grid-template-rows: + [top] 1fr + [middle] 1fr + [bottom]; + /* template rows/columns with functions */ + grid-template-columns: minmax(1em, 1fr) minmax(1em, 80ch) minmax(1em, 1fr); + /* getting really busy with named lines + functions */ + grid-template-columns: + [full-start] minmax(1em, 1fr) + [main-start] minmax(1em, 80ch) + [main-end] minmax(1em, 1fr) + [full-end]; + + grid-template-areas: + "header header header" + "main main sidebar" + "main main sidebar2" + "footer footer footer"; + + /* Shorthand for grid-template-rows, grid-template-columns, and grid-template + areas. In one. This can get really crazy. */ + grid-template: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + + /* The. Worst. This one is shorthand for like everything here smashed into one. But rarely will you actually specify EVERYTHING. */ + grid: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + /* simpler use case: */ + grid: 200px auto / 1fr auto 1fr; + + /* Okay, the the worst of it. The simpler syntaxes: */ + + grid-row-gap: 2em; + grid-column-gap: 1em; + /* shorthand for grid-row-gap + grid-column-gap: */ + grid-gap: 2em 1em; + + grid-auto-columns: 1fr; + grid-auto-rows: 1fr; +} + +.container > .item { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: -2; + grid-row-end: -1; + + /* shorthands for the above: */ + grid-column: 1 / 2; + grid-column: main; + grid-row: -2 / span 1; + grid-row: footer; + + grid-area: main; + grid-area: 1 / main-start / 3 / main-end; +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/* quotes */ +div { + grid-template-areas: + "header header" + "main sidebar" + "footer footer"; +} + +/* numbers */ +div { + grid-template-columns: + [full-start] minmax(1.5em, 1fr) + [main-start] minmax(0.4ch, 75ch) + [main-end] minmax(1em, 1fr) + [full-end]; +} + +/* casing */ +div { + grid: + [top] 1fr + [middle] 1fr + bottom; + + grid-template: + "a a a" 200px + "b b b" 200px + / 200px 200px auto; +} + +/* break before first line if there are any breaks */ +div { + grid-template-columns: 1fr 100px 3em; + grid: + [wide-start] "header header header" 200px [wide-end] + "footer footer footer" 25px + / auto 50px auto; +} + +/** + * https://github.com/prettier/prettier/issues/2703#issuecomment-341188126 + */ +.container { + display: grid; + + /* basic template rows/columns */ + grid-template-columns: 1fr 100px 3em; + grid-template-rows: 1fr 100px 3em; + /* template rows/columns with named grid lines */ + grid-template-columns: + [wide-start] 1fr + [main-start] 500px + [main-end] 1fr + [wide-end]; + grid-template-rows: + [top] 1fr + [middle] 1fr + [bottom]; + /* template rows/columns with functions */ + grid-template-columns: minmax(1em, 1fr) minmax(1em, 80ch) minmax(1em, 1fr); + /* getting really busy with named lines + functions */ + grid-template-columns: + [full-start] minmax(1em, 1fr) + [main-start] minmax(1em, 80ch) + [main-end] minmax(1em, 1fr) + [full-end]; + + grid-template-areas: + "header header header" + "main main sidebar" + "main main sidebar2" + "footer footer footer"; + + /* Shorthand for grid-template-rows, grid-template-columns, and grid-template + areas. In one. This can get really crazy. */ + grid-template: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + + /* The. Worst. This one is shorthand for like everything here smashed into one. But rarely will you actually specify EVERYTHING. */ + grid: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + /* simpler use case: */ + grid: 200px auto / 1fr auto 1fr; + + /* Okay, the the worst of it. The simpler syntaxes: */ + + grid-row-gap: 2em; + grid-column-gap: 1em; + /* shorthand for grid-row-gap + grid-column-gap: */ + grid-gap: 2em 1em; + + grid-auto-columns: 1fr; + grid-auto-rows: 1fr; +} + +.container > .item { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: -2; + grid-row-end: -1; + + /* shorthands for the above: */ + grid-column: 1 / 2; + grid-column: main; + grid-row: -2 / span 1; + grid-row: footer; + + grid-area: main; + grid-area: 1 / main-start / 3 / main-end; +} + +`; diff --git a/tests/css_grid/grid.css b/tests/css_grid/grid.css new file mode 100644 index 00000000..b8cdb7ba --- /dev/null +++ b/tests/css_grid/grid.css @@ -0,0 +1,114 @@ +/* quotes */ +div { + grid-template-areas: + 'header header' + 'main sidebar' + 'footer footer'; +} + +/* numbers */ +div { + grid-template-columns: + [full-start] minmax(1.50em, 1fr) + [main-start] minmax(.40ch, 75ch) + [main-end] minmax(1em, 1.000fr) + [full-end]; +} + +/* casing */ +div { + GRID: + [top] 1fr + [middle] 1fr + bottom; + + grid-TEMPLATE: + "a a a" 200px + "b b b" 200px + / 200px 200px auto; +} + +/* break before first line if there are any breaks */ +div { + grid-template-columns: + 1fr 100px 3em; + grid: [wide-start] "header header header" 200px [wide-end] + "footer footer footer" 25px + / auto 50px auto; +} + +/** + * https://github.com/prettier/prettier/issues/2703#issuecomment-341188126 + */ +.container { + display: grid; + + /* basic template rows/columns */ + grid-template-columns: 1fr 100px 3em; + grid-template-rows: 1fr 100px 3em; + /* template rows/columns with named grid lines */ + grid-template-columns: + [wide-start] 1fr + [main-start] 500px + [main-end] 1fr + [wide-end]; + grid-template-rows: + [top] 1fr + [middle] 1fr + [bottom]; + /* template rows/columns with functions */ + grid-template-columns: minmax(1em, 1fr) minmax(1em, 80ch) minmax(1em, 1fr); + /* getting really busy with named lines + functions */ + grid-template-columns: + [full-start] minmax(1em, 1fr) + [main-start] minmax(1em, 80ch) + [main-end] minmax(1em, 1fr) + [full-end]; + + grid-template-areas: + "header header header" + "main main sidebar" + "main main sidebar2" + "footer footer footer"; + + /* Shorthand for grid-template-rows, grid-template-columns, and grid-template + areas. In one. This can get really crazy. */ + grid-template: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + + /* The. Worst. This one is shorthand for like everything here smashed into one. But rarely will you actually specify EVERYTHING. */ + grid: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + /* simpler use case: */ + grid: 200px auto / 1fr auto 1fr; + + /* Okay, the the worst of it. The simpler syntaxes: */ + + grid-row-gap: 2em; + grid-column-gap: 1em; + /* shorthand for grid-row-gap + grid-column-gap: */ + grid-gap: 2em 1em; + + grid-auto-columns: 1fr; + grid-auto-rows: 1fr; +} + +.container > .item { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: -2; + grid-row-end: -1; + + /* shorthands for the above: */ + grid-column: 1 / 2; + grid-column: main; + grid-row: -2 / span 1; + grid-row: footer; + + grid-area: main; + grid-area: 1 / main-start / 3 / main-end; +} diff --git a/tests/css_grid/jsfmt.spec.js b/tests/css_grid/jsfmt.spec.js new file mode 100644 index 00000000..5f2741d5 --- /dev/null +++ b/tests/css_grid/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, { parser: "css" });