Skip to content

Commit 5b84ed8

Browse files
authored
Merge pull request #62 from flavorjones/flavorjones-pseudo-class-functions
Parse pseudo-class function arguments
2 parents f9f7b3e + c689a6c commit 5b84ed8

File tree

4 files changed

+62
-7
lines changed

4 files changed

+62
-7
lines changed

lib/syntax_tree/css/format.rb

+10-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ def visit_pseudo_class_selector(node)
100100
node.value.format(q)
101101
end
102102

103+
# Visit a Selectors::PseudoClassFunction node.
104+
def visit_pseudo_class_function(node)
105+
q.text(node.name)
106+
q.text("(")
107+
q.seplist(node.arguments, -> { q.text(", ") }) do |selector|
108+
selector.format(q)
109+
end
110+
q.text(")")
111+
end
112+
103113
# Visit a Selectors::PseudoElementSelector node.
104114
def visit_pseudo_element_selector(node)
105115
q.text(":")
@@ -137,7 +147,6 @@ def visit_compound_selector(node)
137147
node.child_nodes.each do |node_|
138148
node_.format(q)
139149
end
140-
# TODO: pseudo-elements
141150
end
142151
end
143152

lib/syntax_tree/css/pretty_print.rb

+15-3
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,19 @@ def visit_pseudo_class_function(node)
380380
q.breakable
381381
q.pp(node.name)
382382

383+
q.breakable
384+
q.text("(arguments")
385+
383386
if node.arguments.any?
384-
q.breakable
385-
q.seplist(node.arguments) { |argument| q.pp(argument) }
387+
q.nest(2) do
388+
q.breakable
389+
q.seplist(node.arguments) { |argument| q.pp(argument) }
390+
end
391+
392+
q.breakable("")
386393
end
394+
395+
q.text(")")
387396
end
388397
end
389398

@@ -443,7 +452,10 @@ def visit_complex_selector(node)
443452
def visit_compound_selector(node)
444453
token("compound-selector") do
445454
q.breakable
446-
q.pp(node.type)
455+
token("type") do
456+
q.breakable
457+
q.pp(node.type)
458+
end
447459

448460
q.breakable
449461
q.text("(subclasses")

lib/syntax_tree/css/selectors.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,8 @@ def pseudo_class_selector
533533
PseudoClassSelector.new(value: consume(IdentToken))
534534
in Function
535535
node = consume(Function)
536-
function = PseudoClassFunction.new(name: node.name, arguments: node.value)
536+
arguments = Selectors.new(node.value).parse
537+
function = PseudoClassFunction.new(name: node.name, arguments: arguments)
537538
PseudoClassSelector.new(value: function)
538539
else
539540
raise MissingTokenError, "Expected pseudo class selector to produce something"

test/selectors_test.rb

+35-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class SelectorsTest < Minitest::Spec
8282
end
8383
end
8484

85-
it "parses a compound selector with a pseudo-class" do
85+
it "parses a compound selector with a pseudo-class selector" do
8686
actual = parse_selectors("div.flex:hover")
8787

8888
assert_pattern do
@@ -98,6 +98,33 @@ class SelectorsTest < Minitest::Spec
9898
end
9999
end
100100

101+
it "parses a compound selector with a pseudo-class function" do
102+
actual = parse_selectors(".flex:not(div, span.wide, .hidden)")
103+
104+
assert_pattern do
105+
actual => [
106+
Selectors::CompoundSelector[
107+
type: nil,
108+
subclasses: [
109+
Selectors::ClassSelector[value: { value: "flex" }],
110+
Selectors::PseudoClassSelector[
111+
value: Selectors::PseudoClassFunction[
112+
name: "not",
113+
arguments: [
114+
Selectors::TypeSelector[value: { name: { value: "div" } }],
115+
Selectors::CompoundSelector[
116+
Selectors::TypeSelector[value: { name: { value: "span" } }],
117+
Selectors::ClassSelector[value: { value: "wide" }],
118+
],
119+
],
120+
],
121+
],
122+
],
123+
]
124+
]
125+
end
126+
end
127+
101128
it "parses a compound selector with pseudo-elements and pseudo-classes" do
102129
actual = parse_selectors("div.flex:hover::first-line:last-child:active::first-letter")
103130

@@ -218,7 +245,6 @@ class SelectorsTest < Minitest::Spec
218245
]
219246
end
220247
end
221-
222248
end
223249

224250
describe "formatting" do
@@ -237,6 +263,13 @@ class SelectorsTest < Minitest::Spec
237263
)
238264
end
239265

266+
it "with a pseudo-class function" do
267+
assert_selector_format(
268+
".flex:not(div, span.wide, .hidden)",
269+
".flex:not(div, span.wide, .hidden)",
270+
)
271+
end
272+
240273
it "with class selectors" do
241274
assert_selector_format(
242275
"div.flex.text-xl",

0 commit comments

Comments
 (0)