@@ -93,6 +93,36 @@ def deconstruct_keys(keys)
93
93
end
94
94
end
95
95
96
+ # §15.1 https://www.w3.org/TR/selectors-4/#descendant-combinators
97
+ class DescendantCombinator < Combinator
98
+ TOKEN = WhitespaceToken
99
+ PP_NAME = "descendant-combinator"
100
+ end
101
+
102
+ # §15.2 https://www.w3.org/TR/selectors-4/#child-combinators
103
+ class ChildCombinator < Combinator
104
+ TOKEN = ">"
105
+ PP_NAME = "child-combinator"
106
+ end
107
+
108
+ # §15.3 https://www.w3.org/TR/selectors-4/#adjacent-sibling-combinators
109
+ class NextSiblingCombinator < Combinator
110
+ TOKEN = "+"
111
+ PP_NAME = "next-sibling-combinator"
112
+ end
113
+
114
+ # §15.4 https://www.w3.org/TR/selectors-4/#general-sibling-combinators
115
+ class SubsequentSiblingCombinator < Combinator
116
+ TOKEN = "~"
117
+ PP_NAME = "subsequent-sibling-combinator"
118
+ end
119
+
120
+ # §16.1 https://www.w3.org/TR/selectors-4/#the-column-combinator
121
+ class ColumnSiblingCombinator < Combinator
122
+ TOKEN = [ "|" , "|" ]
123
+ PP_NAME = "column-sibling-combinator"
124
+ end
125
+
96
126
class ComplexSelector < Node
97
127
attr_reader :child_nodes
98
128
@@ -399,16 +429,13 @@ def simple_selector
399
429
400
430
# <combinator> = '>' | '+' | '~' | [ '|' '|' ]
401
431
def combinator
402
- value =
403
- options do
404
- maybe { consume_combinator ( ">" ) } ||
405
- maybe { consume_combinator ( "+" ) } ||
406
- maybe { consume_combinator ( "~" ) } ||
407
- maybe { consume_combinator ( "|" , "|" ) } ||
408
- maybe { consume ( WhitespaceToken ) }
409
- end
410
-
411
- Combinator . new ( value : value )
432
+ options do
433
+ maybe { consume_combinator ( ChildCombinator ) } ||
434
+ maybe { consume_combinator ( NextSiblingCombinator ) } ||
435
+ maybe { consume_combinator ( SubsequentSiblingCombinator ) } ||
436
+ maybe { consume_combinator ( ColumnSiblingCombinator ) } ||
437
+ maybe { consume_combinator ( DescendantCombinator ) }
438
+ end
412
439
end
413
440
414
441
# <type-selector> = <wq-name> | <ns-prefix>? '*'
@@ -551,11 +578,14 @@ def one_or_more
551
578
end
552
579
end
553
580
554
- def consume_combinator ( *values )
555
- consume_whitespace
556
- result = consume ( *values )
557
- consume_whitespace
558
- result
581
+ def consume_combinator ( combinator_class )
582
+ eat_whitespace = ( combinator_class ::TOKEN != WhitespaceToken )
583
+
584
+ consume_whitespace if eat_whitespace
585
+ result = consume ( *combinator_class ::TOKEN )
586
+ consume_whitespace if eat_whitespace
587
+
588
+ combinator_class . new ( value : result )
559
589
end
560
590
561
591
def consume ( *values )
0 commit comments