diff --git a/lib/Less/Parser.php b/lib/Less/Parser.php index c4273f67..ba066d04 100644 --- a/lib/Less/Parser.php +++ b/lib/Less/Parser.php @@ -2187,9 +2187,28 @@ private function parseElement() { $this->save(); if ( $this->matchChar( '(' ) ) { $v = $this->parseSelector(); - if ( $v && $this->matchChar( ')' ) ) { - $e = new Less_Tree_Paren( $v ); - $this->forget(); + if ( $v ) { + // Support comma-separated selector lists inside parentheses, + // for pseudo-classes like :is(), :not(), :where(), :has(). + // Backported from Less.js 4.2 (less.js#4290). + $selectors = []; + while ( $this->matchChar( ',' ) ) { + $selectors[] = $v; + $selectors[] = new Less_Tree_Anonymous( ',' ); + $v = $this->parseSelector(); + } + + if ( $v && $this->matchChar( ')' ) ) { + if ( $selectors ) { + $selectors[] = $v; + $e = new Less_Tree_Paren( new Less_Tree_Expression( $selectors, true ) ); + } else { + $e = new Less_Tree_Paren( $v ); + } + $this->forget(); + } else { + $this->restore(); + } } else { $this->restore(); } diff --git a/test/Fixtures/less.php/css/pseudo-selector-list.css b/test/Fixtures/less.php/css/pseudo-selector-list.css new file mode 100644 index 00000000..081c4de4 --- /dev/null +++ b/test/Fixtures/less.php/css/pseudo-selector-list.css @@ -0,0 +1,21 @@ +:not(.active) { + display: none; +} +:not(.a, .b) { + display: block; +} +.form-small:is(.framework-input, .framework-search, select:not([multiple]):not([size])) { + height: 42px; +} +a:is(.b, :is(.c), :has(div)) { + color: red; +} +:where(.x, .y) { + margin: 0; +} +:has(div > .child, span + .sibling) { + border: 1px solid; +} +:is([type="text"], .input-field) { + padding: 4px; +} diff --git a/test/Fixtures/less.php/less/pseudo-selector-list.less b/test/Fixtures/less.php/less/pseudo-selector-list.less new file mode 100644 index 00000000..7393bc3c --- /dev/null +++ b/test/Fixtures/less.php/less/pseudo-selector-list.less @@ -0,0 +1,22 @@ +// https://github.com/wikimedia/less.php/issues/136 +:not(.active) { + display: none; +} +:not(.a, .b) { + display: block; +} +.form-small:is(.framework-input, .framework-search, select:not([multiple]):not([size])) { + height: 42px; +} +a:is(.b, :is(.c), :has(div)) { + color: red; +} +:where(.x, .y) { + margin: 0; +} +:has(div > .child, span + .sibling) { + border: 1px solid; +} +:is([type="text"], .input-field) { + padding: 4px; +}