Skip to content

Commit

Permalink
feat(css_formatter): support for pseudo selectors (#1291)
Browse files Browse the repository at this point in the history
  • Loading branch information
faultyserver authored Dec 22, 2023
1 parent 934fa66 commit bf1c3eb
Show file tree
Hide file tree
Showing 51 changed files with 1,243 additions and 81 deletions.
9 changes: 6 additions & 3 deletions crates/biome_css_formatter/src/css/auxiliary/nth_offset.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::prelude::*;
use biome_css_syntax::CssNthOffset;
use biome_rowan::AstNode;
use biome_css_syntax::{CssNthOffset, CssNthOffsetFields};
use biome_formatter::write;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssNthOffset;
impl FormatNodeRule<CssNthOffset> for FormatCssNthOffset {
fn fmt_fields(&self, node: &CssNthOffset, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssNthOffsetFields { sign, value } = node.as_fields();

write!(f, [sign.format(), space(), value.format()])
}
}
11 changes: 10 additions & 1 deletion crates/biome_css_formatter/src/css/auxiliary/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ impl FormatNodeRule<CssRule> for FormatCssRule {
fn fmt_fields(&self, node: &CssRule, f: &mut CssFormatter) -> FormatResult<()> {
let CssRuleFields { prelude, block } = node.as_fields();

write!(f, [group(&prelude.format()), space(), &block?.format()])
write!(
f,
[
// The selector list gets expanded so that every selector
// appears on its own line, no matter how long they are.
group(&prelude.format()).should_expand(true),
space(),
&block?.format()
]
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ pub(crate) struct FormatCssCompoundSelectorList;
impl FormatRule<CssCompoundSelectorList> for FormatCssCompoundSelectorList {
type Context = CssFormatContext;
fn fmt(&self, node: &CssCompoundSelectorList, f: &mut CssFormatter) -> FormatResult<()> {
f.join().entries(node.iter().formatted()).finish()
let mut joiner = f.join_nodes_with_soft_line();

for (rule, formatted) in node.elements().zip(node.format_separated(",")) {
// Each selector gets `indent` added in case it breaks over multiple
// lines. The break is added here rather than in each selector both
// for simplicity and to avoid recursively adding indents when
// selectors are nested within other rules. The group is then added
// around the indent to ensure that it tries using a flat layout
// first and only expands when the single selector can't fit the line.
//
// For example, a selector like `div span a` is structured like
// `[div, [span, [a]]]`, so `a` would end up double-indented if it
// was handled by the selector rather than here.
joiner.entry(rule.node()?.syntax(), &group(&indent(&formatted)));
}

joiner.finish()
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoValueList;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoValueList;
impl FormatRule<CssPseudoValueList> for FormatCssPseudoValueList {
type Context = CssFormatContext;
fn fmt(&self, node: &CssPseudoValueList, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let mut joiner = f.join_nodes_with_soft_line();

for (rule, formatted) in node.elements().zip(node.format_separated(",")) {
joiner.entry(rule.node()?.syntax(), &formatted);
}

joiner.finish()
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
use crate::prelude::*;
use biome_css_syntax::CssRelativeSelectorList;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssRelativeSelectorList;
impl FormatRule<CssRelativeSelectorList> for FormatCssRelativeSelectorList {
type Context = CssFormatContext;
fn fmt(&self, node: &CssRelativeSelectorList, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let mut joiner = f.join_nodes_with_soft_line();

for (rule, formatted) in node.elements().zip(node.format_separated(",")) {
// Each selector gets `indent` added in case it breaks over multiple
// lines. The break is added here rather than in each selector both
// for simplicity and to avoid recursively adding indents when
// selectors are nested within other rules. The group is then added
// around the indent to ensure that it tries using a flat layout
// first and only expands when the single selector can't fit the line.
//
// For example, a selector like `div span a` is structured like
// `[div, [span, [a]]]`, so `a` would end up double-indented if it
// was handled by the selector rather than here.
joiner.entry(rule.node()?.syntax(), &group(&indent(&formatted)));
}

joiner.finish()
}
}
3 changes: 2 additions & 1 deletion crates/biome_css_formatter/src/css/lists/selector_list.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::prelude::*;
use biome_css_syntax::CssSelectorList;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssSelectorList;
impl FormatRule<CssSelectorList> for FormatCssSelectorList {
type Context = CssFormatContext;
fn fmt(&self, node: &CssSelectorList, f: &mut CssFormatter) -> FormatResult<()> {
let mut joiner = f.join_nodes_with_hardline();
let mut joiner = f.join_nodes_with_soft_line();

for (rule, formatted) in node.elements().zip(node.format_separated(",")) {
// Each selector gets `indent` added in case it breaks over multiple
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassFunctionCompoundSelectorList;
use biome_rowan::AstNode;
use biome_css_syntax::{
CssPseudoClassFunctionCompoundSelectorList, CssPseudoClassFunctionCompoundSelectorListFields,
};
use biome_formatter::{format_args, write};

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassFunctionCompoundSelectorList;
impl FormatNodeRule<CssPseudoClassFunctionCompoundSelectorList>
Expand All @@ -11,6 +14,23 @@ impl FormatNodeRule<CssPseudoClassFunctionCompoundSelectorList>
node: &CssPseudoClassFunctionCompoundSelectorList,
f: &mut CssFormatter,
) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassFunctionCompoundSelectorListFields {
name,
l_paren_token,
compound_selector_list,
r_paren_token,
} = node.as_fields();

write!(
f,
[
name.format(),
group(&format_args![
l_paren_token.format(),
soft_block_indent(&compound_selector_list.format()),
r_paren_token.format()
])
]
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassFunctionIdentifier;
use biome_rowan::AstNode;
use biome_css_syntax::{CssPseudoClassFunctionIdentifier, CssPseudoClassFunctionIdentifierFields};
use biome_formatter::{format_args, write};

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassFunctionIdentifier;
impl FormatNodeRule<CssPseudoClassFunctionIdentifier> for FormatCssPseudoClassFunctionIdentifier {
Expand All @@ -9,6 +10,23 @@ impl FormatNodeRule<CssPseudoClassFunctionIdentifier> for FormatCssPseudoClassFu
node: &CssPseudoClassFunctionIdentifier,
f: &mut CssFormatter,
) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassFunctionIdentifierFields {
name_token,
l_paren_token,
ident,
r_paren_token,
} = node.as_fields();

write!(
f,
[
name_token.format(),
group(&format_args![
l_paren_token.format(),
soft_block_indent(&ident.format()),
r_paren_token.format()
])
]
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassFunctionNth;
use biome_rowan::AstNode;
use biome_css_syntax::{CssPseudoClassFunctionNth, CssPseudoClassFunctionNthFields};
use biome_formatter::{format_args, write};

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassFunctionNth;
impl FormatNodeRule<CssPseudoClassFunctionNth> for FormatCssPseudoClassFunctionNth {
Expand All @@ -9,6 +10,23 @@ impl FormatNodeRule<CssPseudoClassFunctionNth> for FormatCssPseudoClassFunctionN
node: &CssPseudoClassFunctionNth,
f: &mut CssFormatter,
) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassFunctionNthFields {
name,
l_paren_token,
selector,
r_paren_token,
} = node.as_fields();

write!(
f,
[
name.format(),
group(&format_args![
l_paren_token.format(),
soft_block_indent(&selector.format()),
r_paren_token.format()
])
]
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassFunctionRelativeSelectorList;
use biome_rowan::AstNode;
use biome_css_syntax::{
CssPseudoClassFunctionRelativeSelectorList, CssPseudoClassFunctionRelativeSelectorListFields,
};
use biome_formatter::{format_args, write};

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassFunctionRelativeSelectorList;
impl FormatNodeRule<CssPseudoClassFunctionRelativeSelectorList>
Expand All @@ -11,6 +14,23 @@ impl FormatNodeRule<CssPseudoClassFunctionRelativeSelectorList>
node: &CssPseudoClassFunctionRelativeSelectorList,
f: &mut CssFormatter,
) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassFunctionRelativeSelectorListFields {
name_token,
l_paren_token,
relative_selector_list,
r_paren_token,
} = node.as_fields();

write!(
f,
[
name_token.format(),
group(&format_args![
l_paren_token.format(),
soft_block_indent(&relative_selector_list.format()),
r_paren_token.format()
])
]
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassFunctionSelectorList;
use biome_rowan::AstNode;
use biome_css_syntax::{
CssPseudoClassFunctionSelectorList, CssPseudoClassFunctionSelectorListFields,
};
use biome_formatter::{format_args, write};

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassFunctionSelectorList;
impl FormatNodeRule<CssPseudoClassFunctionSelectorList>
Expand All @@ -11,6 +14,23 @@ impl FormatNodeRule<CssPseudoClassFunctionSelectorList>
node: &CssPseudoClassFunctionSelectorList,
f: &mut CssFormatter,
) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassFunctionSelectorListFields {
name,
l_paren_token,
selector_list,
r_paren_token,
} = node.as_fields();

write!(
f,
[
name.format(),
group(&format_args![
l_paren_token.format(),
soft_block_indent(&selector_list.format()),
r_paren_token.format()
])
]
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassFunctionValueList;
use biome_rowan::AstNode;
use biome_css_syntax::{CssPseudoClassFunctionValueList, CssPseudoClassFunctionValueListFields};
use biome_formatter::{format_args, write};

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassFunctionValueList;
impl FormatNodeRule<CssPseudoClassFunctionValueList> for FormatCssPseudoClassFunctionValueList {
Expand All @@ -9,6 +10,23 @@ impl FormatNodeRule<CssPseudoClassFunctionValueList> for FormatCssPseudoClassFun
node: &CssPseudoClassFunctionValueList,
f: &mut CssFormatter,
) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassFunctionValueListFields {
name_token,
l_paren_token,
value_list,
r_paren_token,
} = node.as_fields();

write!(
f,
[
name_token.format(),
group(&format_args![
l_paren_token.format(),
soft_block_indent(&value_list.format()),
r_paren_token.format()
])
]
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassIdentifier;
use biome_rowan::AstNode;
use biome_css_syntax::{CssPseudoClassIdentifier, CssPseudoClassIdentifierFields};
use biome_formatter::write;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassIdentifier;
impl FormatNodeRule<CssPseudoClassIdentifier> for FormatCssPseudoClassIdentifier {
Expand All @@ -9,6 +10,8 @@ impl FormatNodeRule<CssPseudoClassIdentifier> for FormatCssPseudoClassIdentifier
node: &CssPseudoClassIdentifier,
f: &mut CssFormatter,
) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassIdentifierFields { name } = node.as_fields();

write!(f, [name.format()])
}
}
20 changes: 17 additions & 3 deletions crates/biome_css_formatter/src/css/pseudo/pseudo_class_nth.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
use crate::prelude::*;
use biome_css_syntax::CssPseudoClassNth;
use biome_rowan::AstNode;
use biome_css_syntax::{CssPseudoClassNth, CssPseudoClassNthFields};
use biome_formatter::write;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssPseudoClassNth;
impl FormatNodeRule<CssPseudoClassNth> for FormatCssPseudoClassNth {
fn fmt_fields(&self, node: &CssPseudoClassNth, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
let CssPseudoClassNthFields {
sign,
value,
symbol_token,
offset,
} = node.as_fields();

write!(f, [sign.format(), value.format(), symbol_token.format(),])?;

if offset.is_some() {
write!(f, [soft_line_break_or_space(), offset.format()])?;
}

Ok(())
}
}
Loading

0 comments on commit bf1c3eb

Please sign in to comment.