Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 60 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ function print_atrule(node, indent_level, css) {
let buffer = indent(indent_level) + '@' + node.name

// @font-face has no prelude
if (node.prelude) {
if (node.prelude !== null) {
buffer += ' ' + substr(node.prelude, css)
}

Expand All @@ -267,7 +267,63 @@ function print_atrule(node, indent_level, css) {
* @returns {string} A formatted Declaration
*/
function print_declaration(node, indent_level, css) {
return indent(indent_level) + node.property + ': ' + substr(node.value, css) + ';'
return indent(indent_level) + node.property.toLowerCase() + ': ' + print_value(node.value, indent_level, css).trim() + ';'
}

/**
* @param {import('css-tree').List} children
* @param {number} indent_level
* @param {string} css
*/
function print_list(children, indent_level, css) {
let buffer = ''

for (let node of children) {
if (node !== children.first && node.type !== 'Operator') {
buffer += ' '
}

if (node.type === 'Identifier') {
// TODO: new CSS keywork NaN should not be lowercased
buffer += node.name.toLowerCase()
} else if (node.type === 'Function') {
buffer += print_function(node, 0, css)
} else if (node.type === 'Dimension') {
buffer += node.value + node.unit.toLowerCase()
} else if (node.type === 'Value') {
// Values can be inside var() as fallback
// var(--prop, VALUE)
buffer += print_value(node, 0, css)
} else {
buffer += print_unknown(node, 0, css)
}
}
return buffer
}

/**
* @param {import('css-tree').Value | import('css-tree').Raw} node
* @param {number} indent_level
* @param {string} css
*/
function print_value(node, indent_level, css) {
if (node.type === 'Raw') {
return print_unknown(node, 0, css)
}

return print_list(node.children, 0, css)
}

/**
* @param {import('css-tree').FunctionNode} node
* @param {number} indent_level
* @param {string} css
*/
function print_function(node, indent_level, css) {
let buffer = node.name.toLowerCase() + '('
buffer += print_list(node.children, 0, css)
buffer += ')'
return buffer
}

/**
Expand Down Expand Up @@ -316,8 +372,8 @@ export function format(css) {
let ast = parse(css, {
positions: true,
parseAtrulePrelude: false,
parseCustomProperty: false,
parseValue: false,
parseCustomProperty: true,
parseValue: true,
})
return print(ast, 0, css)
}
34 changes: 28 additions & 6 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ test('Declarations end with a semicolon (;)', () => {
`)
let expected = `@font-face {
src: url('test');
font-family: Test;
font-family: test;
}

css {
Expand Down Expand Up @@ -277,7 +277,7 @@ test { a: 1}
no-layer-2 {
color: red;
font-size: 1rem;
COLOR: green;
color: green;
}

@layer components, deep;
Expand Down Expand Up @@ -443,7 +443,7 @@ a.b
color: green }
`)
let expected = `a {
background: linear-gradient( red, 10% blue, 20% green,100% yellow);
background: linear-gradient(red, 10% blue, 20% green, 100% yellow);
}

a.b .c .d .e .f {
Expand Down Expand Up @@ -499,32 +499,54 @@ test('formats selectors with Nth', () => {
}
})

test.skip('formats simple value lists', () => {
test('formats simple value lists', () => {
let actual = format(`
a {
transition-property: all,opacity;
transition: all 100ms ease,opacity 10ms 20ms linear;
transition: all 100ms ease;
ANIMATION: COLOR 123MS EASE-OUT;
color: rgb(0,0,0);
color: HSL(0%,10%,50%);
content: 'Test';
background-image: url("EXAMPLE.COM");
}
`)
let expected = `a {
transition-property: all, opacity;
transition: all 100ms ease, opacity 10ms 20ms linear;
transition: all 100ms ease;
animation: color 123ms ease-out;
color: rgb(0, 0, 0);
color: hsl(0%, 10%, 50%);
content: 'Test';
background-image: url("EXAMPLE.COM");
}`
assert.equal(actual, expected)
})

test.skip('formats nested value lists', () => {
test('formats nested value lists', () => {
let actual = format(`
a {
background: red,linear-gradient(to bottom,red 10%,green 50%,blue 100%);
color: var(--test1,var(--test2,green));
}
`)
let expected = `a {
background: red, linear-gradient(to bottom, red 10%, green 50%, blue 100%);
}`
assert.equal(actual, expected)
})

test('formats nested var()', () => {
let actual = format(`
a {
color: var(--test1,var(--test2,green));
color: var(--test3,rgb(0,0,0));
}
`)
let expected = `a {
color: var(--test1, var(--test2, green));
color: var(--test3, rgb(0, 0, 0));
}`
assert.equal(actual, expected)
})
Expand Down