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
24 changes: 14 additions & 10 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ export function unquote(str: string): string {
return str.replaceAll(UNQUOTE_RE, EMPTY_STRING)
}

/** Lowercases a CSS identifier, except a custom-ident starting with `--`,
* which must keep its case as written. */
function print_identifier(name: string): string {
return name.startsWith('--') ? name : name.toLowerCase()
}

function print_string(str: string | number | null, quote?: '"' | "'"): string {
str = str?.toString() || ''
let inner = unquote(str)
Expand Down Expand Up @@ -124,7 +130,7 @@ function print_list(nodes: CSSNode[], optional_space = SPACE): string {
let parts = []
for (let node of nodes) {
if (is_function(node)) {
let fn = node.name.toLowerCase()
let fn = print_identifier(node.name)
parts.push(fn, OPEN_PARENTHESES, print_list(node.children, optional_space), CLOSE_PARENTHESES)
} else if (is_dimension(node)) {
parts.push(node.value, node.unit?.toLowerCase())
Expand Down Expand Up @@ -183,9 +189,7 @@ export function format_declaration(
value += SPACE
}

if (!property.startsWith('--')) {
property = property.toLowerCase()
}
property = print_identifier(property)
return property + COLON + optional_space + value + important
}

Expand Down Expand Up @@ -233,7 +237,7 @@ function print_combinator(node: Combinator, optional_space: string, is_first: bo

/** Prints an attribute selector, e.g. `[href^="https://" i]`. */
function print_attribute_selector(node: AttributeSelector): string {
let parts = [OPEN_BRACKET, node.name.toLowerCase()]
let parts = [OPEN_BRACKET, print_identifier(node.name)]

if (node.attr_operator) {
parts.push(node.attr_operator)
Expand All @@ -256,7 +260,7 @@ function print_pseudo_selector(
optional_space = SPACE,
): string {
let parts = [COLON]
let name = node.name.toLowerCase()
let name = print_identifier(node.name)

// Legacy pseudo-elements or actual pseudo-elements use double colon
if (name === 'before' || name === 'after' || is_pseudo_element_selector(node)) {
Expand Down Expand Up @@ -293,12 +297,12 @@ function print_selector_component(
}

if (is_type_selector(node)) {
let prefix = node.namespace === null ? '' : node.namespace.toLowerCase() + '|'
return prefix + node.name.toLowerCase()
let prefix = node.namespace === null ? '' : print_identifier(node.namespace) + '|'
return prefix + print_identifier(node.name)
}

if (is_universal_selector(node)) {
let prefix = node.namespace === null ? '' : node.namespace.toLowerCase() + '|'
let prefix = node.namespace === null ? '' : print_identifier(node.namespace) + '|'
return prefix + '*'
}

Expand Down Expand Up @@ -588,7 +592,7 @@ export function format(
}

function print_atrule(node: Atrule): string {
let name = '@' + node.name!.toLowerCase()
let name = '@' + print_identifier(node.name!)
if (node.prelude) {
name += SPACE + format_atrule_prelude(node.prelude.text, { minify })
}
Expand Down
12 changes: 12 additions & 0 deletions test/selectors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ test('forces attribute selectors to have quoted values', () => {
expect(actual).toEqual(expected)
})

test('lowercases attribute selector names', () => {
let actual = format(`[HREF] {}`)
let expected = `[href] {}`
expect(actual).toEqual(expected)
})

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Add another test to prove that attribute selector's value remains intact in terms of quoting.

test('lowercases attribute selector name but keeps the value as-is', () => {
let actual = format(`[HREF=Some-Value] {}`)
let expected = `[href="Some-Value"] {}`
expect(actual).toEqual(expected)
})

test('adds a space before attribute selector flags', () => {
let actual = format(`
[title="foo" i],
Expand Down
8 changes: 8 additions & 0 deletions test/values.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ test('lowercases CSS functions', () => {
expect(actual).toEqual(expected)
})

test('preserves casing of a custom function name', () => {
let actual = format(`a { width: --myFunc(1px); }`)
let expected = `a {
width: --myFunc(1px);
}`
expect(actual).toEqual(expected)
})

test('relative colors', () => {
let actual = format(`a {
color: rgb( from red 0 0 255);
Expand Down
Loading