diff --git a/packages/less/src/less/parser/parser.js b/packages/less/src/less/parser/parser.js index b87b4d762..9c6e50e2e 100644 --- a/packages/less/src/less/parser/parser.js +++ b/packages/less/src/less/parser/parser.js @@ -5,7 +5,6 @@ import getParserInput from './parser-input'; import * as utils from '../utils'; import functionRegistry from '../functions/function-registry'; import { ContainerSyntaxOptions, MediaSyntaxOptions } from '../tree/atrule-syntax'; -import Selector from '../tree/selector'; import Anonymous from '../tree/anonymous'; // @@ -1314,27 +1313,25 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) { if (!e) { parserInput.save(); if (parserInput.$char('(')) { - if ((v = this.selector(false))) { - let selectors = []; - while (parserInput.$char(',')) { - selectors.push(v); - selectors.push(new Anonymous(',')); - v = this.selector(false); - } - selectors.push(v); - + let vSelectors = []; + while ((v = this.selector(false)) && parserInput.$char(',')) { + vSelectors.push(v); + vSelectors.push(new Anonymous(',')); + } + vSelectors.push(v); + + if (v) { if (parserInput.$char(')')) { - if (selectors.length > 1) { - e = new (tree.Paren)(new Selector(selectors)); + if (vSelectors.length === 1) { + e = new (tree.Paren)(vSelectors[0]); } else { - e = new(tree.Paren)(v); + e = new (tree.ListParen)(vSelectors); } - parserInput.forget(); } else { parserInput.restore('Missing closing \')\''); } } else { - parserInput.restore('Missing closing \')\''); + parserInput.restore('Could not find valid selector'); } } else { parserInput.forget(); diff --git a/packages/less/src/less/tree/index.js b/packages/less/src/less/tree/index.js index 1d4fbfdd7..74b89d6da 100644 --- a/packages/less/src/less/tree/index.js +++ b/packages/less/src/less/tree/index.js @@ -38,6 +38,7 @@ import NamespaceValue from './namespace-value'; // mixins import MixinCall from './mixin-call'; import MixinDefinition from './mixin-definition'; +import ListParen from './list-paren'; export default { Node, Color, AtRule, DetachedRuleset, Operation, @@ -47,7 +48,7 @@ export default { Comment, Anonymous, Value, JavaScript, Assignment, Condition, Paren, Media, Container, QueryInParens, UnicodeDescriptor, Negative, Extend, VariableCall, - NamespaceValue, + NamespaceValue, ListParen, mixin: { Call: MixinCall, Definition: MixinDefinition diff --git a/packages/less/src/less/tree/list-paren.js b/packages/less/src/less/tree/list-paren.js new file mode 100644 index 000000000..5600cc3ef --- /dev/null +++ b/packages/less/src/less/tree/list-paren.js @@ -0,0 +1,21 @@ +import Node from './node'; + +const ListParen = function(node) { + this.value = node; +}; + +ListParen.prototype = Object.assign(new Node(), { + type: 'ListParen', + + genCSS(context, output) { + output.add('('); + this.value.forEach(val => val.genCSS(context, output)); + output.add(')'); + }, + + eval(context) { + return new ListParen(this.value.map(val => val.eval(context))); + } +}); + +export default ListParen; diff --git a/packages/test-data/css/_main/selectors.css b/packages/test-data/css/_main/selectors.css index 92c8b824f..164abfb48 100644 --- a/packages/test-data/css/_main/selectors.css +++ b/packages/test-data/css/_main/selectors.css @@ -189,3 +189,24 @@ a:is(.b, :is(.c)) { a:is(.b, :is(.c), :has(div)) { color: red; } +@-moz-document domain("example.com") { + :is( + [a1], + [a2] + ):is( [a3], [a4]:not( :is([a5],[a6])):is( [a7]:not(:is([a8],[a9])), [b1]:not(:is([b2],[b3]))):is( + [b4],[b5] + ), [b6], [b7]) { + color: red; + } +} +@-moz-document domain("example.com") { + :is([foo], [bar], [baz]) { + color: red; + } +} +:is(.color-1, .focus-color-1:focus, .hover-color-1:hover) { + color: red !important; +} +:is(.color-2, .focus-color-2:focus, .hover-color-2:hover) { + color: green !important; +} diff --git a/packages/test-data/less/_main/selectors.less b/packages/test-data/less/_main/selectors.less index c976380a8..055cdb1b2 100644 --- a/packages/test-data/less/_main/selectors.less +++ b/packages/test-data/less/_main/selectors.less @@ -208,3 +208,39 @@ a:is(.b, :is(.c)) { a:is(.b, :is(.c), :has(div)) { color: red; } + +@-moz-document domain("example.com") { + :is( + [a1], + [a2] + ):is( + [a3], + [a4]:not( + :is([a5],[a6]) + ):is( + [a7]:not(:is([a8],[a9])), + [b1]:not(:is([b2],[b3])) + ):is( + [b4],[b5] + ), + [b6], + [b7] + ) { + color: red; } + +} + +@-moz-document domain("example.com") { + :is([foo], [bar] /* :is(a, b) */, [baz]) { + color: red; } +} + +@color: red green; + +each(@color, { + :is(.color-@{key}, + .focus-color-@{key}:focus, + .hover-color-@{key}:hover) { + color: @value !important; + } +});