@@ -2142,19 +2142,19 @@ protected function propertyName(&$out)
21422142 *
21432143 * @return boolean
21442144 */
2145- protected function selectors (&$ out )
2145+ protected function selectors (&$ out, $ subSelector = false )
21462146 {
21472147 $ s = $ this ->count ;
21482148 $ selectors = [];
21492149
2150- while ($ this ->selector ($ sel )) {
2150+ while ($ this ->selector ($ sel, $ subSelector )) {
21512151 $ selectors [] = $ sel ;
21522152
2153- if (! $ this ->matchChar (', ' )) {
2153+ if (! $ this ->matchChar (', ' , true )) {
21542154 break ;
21552155 }
21562156
2157- while ($ this ->matchChar (', ' )) {
2157+ while ($ this ->matchChar (', ' , true )) {
21582158 ; // ignore extra
21592159 }
21602160 }
@@ -2177,23 +2177,23 @@ protected function selectors(&$out)
21772177 *
21782178 * @return boolean
21792179 */
2180- protected function selector (&$ out )
2180+ protected function selector (&$ out, $ subSelector = false )
21812181 {
21822182 $ selector = [];
21832183
21842184 for (;;) {
2185- if ($ this ->match ('[>+~]+ ' , $ m )) {
2185+ if ($ this ->match ('[>+~]+ ' , $ m, true )) {
21862186 $ selector [] = [$ m [0 ]];
21872187 continue ;
21882188 }
21892189
2190- if ($ this ->selectorSingle ($ part )) {
2190+ if ($ this ->selectorSingle ($ part, $ subSelector )) {
21912191 $ selector [] = $ part ;
21922192 $ this ->match ('\s+ ' , $ m );
21932193 continue ;
21942194 }
21952195
2196- if ($ this ->match ('\/[^\/]+\/ ' , $ m )) {
2196+ if ($ this ->match ('\/[^\/]+\/ ' , $ m, true )) {
21972197 $ selector [] = [$ m [0 ]];
21982198 continue ;
21992199 }
@@ -2220,7 +2220,7 @@ protected function selector(&$out)
22202220 *
22212221 * @return boolean
22222222 */
2223- protected function selectorSingle (&$ out )
2223+ protected function selectorSingle (&$ out, $ subSelector = false )
22242224 {
22252225 $ oldWhite = $ this ->eatWhiteDefault ;
22262226 $ this ->eatWhiteDefault = false ;
@@ -2244,6 +2244,11 @@ protected function selectorSingle(&$out)
22442244 break ;
22452245 }
22462246
2247+ // parsing a sub selector in () stop with the closing )
2248+ if ($ subSelector && $ char === ') ' ) {
2249+ break ;
2250+ }
2251+
22472252 //self
22482253 switch ($ char ) {
22492254 case '& ' :
@@ -2307,21 +2312,46 @@ protected function selectorSingle(&$out)
23072312
23082313 $ ss = $ this ->count ;
23092314
2310- if ($ this ->matchChar ('( ' ) &&
2311- ($ this ->openString (') ' , $ str , '( ' ) || true ) &&
2312- $ this ->matchChar (') ' )
2313- ) {
2314- $ parts [] = '( ' ;
2315-
2316- if (! empty ($ str )) {
2317- $ parts [] = $ str ;
2315+ if ($ nameParts === ['not ' ] || $ nameParts === ['is ' ] || $ nameParts === ['has ' ] || $ nameParts === ['where ' ]) {
2316+ if ($ this ->matchChar ('( ' ) &&
2317+ ($ this ->selectors ($ subs , true ) || true ) &&
2318+ $ this ->matchChar (') ' )
2319+ ) {
2320+ $ parts [] = '( ' ;
2321+
2322+ while ($ sub = array_shift ($ subs )) {
2323+ while ($ ps = array_shift ($ sub )) {
2324+ foreach ($ ps as &$ p ) {
2325+ $ parts [] = $ p ;
2326+ }
2327+ if (count ($ sub ) && reset ($ sub )) {
2328+ $ parts [] = ' ' ;
2329+ }
2330+ }
2331+ if (count ($ subs ) && reset ($ subs )) {
2332+ $ parts [] = ', ' ;
2333+ }
2334+ }
2335+ $ parts [] = ') ' ;
2336+ } else {
2337+ $ this ->seek ($ ss );
23182338 }
2319-
2320- $ parts [] = ') ' ;
23212339 } else {
2322- $ this ->seek ($ ss );
2340+ if ($ this ->matchChar ('( ' ) &&
2341+ ($ this ->openString (') ' , $ str , '( ' ) || true ) &&
2342+ $ this ->matchChar (') ' )
2343+ ) {
2344+ $ parts [] = '( ' ;
2345+
2346+ if (! empty ($ str )) {
2347+ $ parts [] = $ str ;
2348+ }
2349+
2350+ $ parts [] = ') ' ;
2351+ } else {
2352+ $ this ->seek ($ ss );
2353+ }
23232354 }
2324-
23252355 continue ;
23262356 }
23272357 }
0 commit comments