@@ -1066,7 +1066,8 @@ public static function parse( string $input, int &$offset ): ?self {
10661066 return null ;
10671067 }
10681068
1069- $ selectors = array ( $ selector );
1069+ $ selectors = array ( $ selector );
1070+ $ has_preceding_subclass_selector = null !== $ selector ->subclass_selectors ;
10701071
10711072 $ found_whitespace = self ::parse_whitespace ( $ input , $ updated_offset );
10721073 while ( $ updated_offset < strlen ( $ input ) ) {
@@ -1075,22 +1076,13 @@ public static function parse( string $input, int &$offset ): ?self {
10751076 self ::COMBINATOR_NEXT_SIBLING === $ input [ $ updated_offset ] ||
10761077 self ::COMBINATOR_SUBSEQUENT_SIBLING === $ input [ $ updated_offset ]
10771078 ) {
1078- $ combinator = $ input [ $ updated_offset ];
1079- ++$ updated_offset ;
1080- self ::parse_whitespace ( $ input , $ updated_offset );
1081-
1082- // Failure to find a selector here is a parse error
1083- $ selector = WP_CSS_Selector::parse ( $ input , $ updated_offset );
1084- // Failure to find a selector is a parse error.
1085- if ( null === $ selector ) {
1086- return null ;
1087- }
1088- $ selectors [] = $ combinator ;
1089- $ selectors [] = $ selector ;
1090- } elseif ( ! $ found_whitespace ) {
1091- break ;
1092- } else {
1079+ $ combinator = $ input [ $ updated_offset ];
1080+ ++$ updated_offset ;
1081+ self ::parse_whitespace ( $ input , $ updated_offset );
10931082
1083+ // Failure to find a selector here is a parse error
1084+ $ selector = WP_CSS_Selector::parse ( $ input , $ updated_offset );
1085+ } elseif ( $ found_whitespace ) {
10941086 /*
10951087 * Whitespace is ambiguous, it could be a descendant combinator or
10961088 * insignificant whitespace.
@@ -1099,9 +1091,24 @@ public static function parse( string $input, int &$offset ): ?self {
10991091 if ( null === $ selector ) {
11001092 break ;
11011093 }
1102- $ selectors [] = self ::COMBINATOR_DESCENDANT ;
1103- $ selectors [] = $ selector ;
1094+ $ combinator = self ::COMBINATOR_DESCENDANT ;
1095+ } else {
1096+ break ;
1097+ }
1098+
1099+ if ( null === $ selector ) {
1100+ return null ;
11041101 }
1102+
1103+ // `div > .className` is valid, but `.className > div` is not.
1104+ if ( $ has_preceding_subclass_selector ) {
1105+ throw new Exception ( 'Unsupported non-final subclass selector. ' );
1106+ }
1107+ $ has_preceding_subclass_selector = null !== $ selector ->subclass_selectors ;
1108+
1109+ $ selectors [] = $ combinator ;
1110+ $ selectors [] = $ selector ;
1111+
11051112 $ found_whitespace = self ::parse_whitespace ( $ input , $ updated_offset );
11061113 }
11071114 $ offset = $ updated_offset ;
0 commit comments