Skip to content

Commit

Permalink
fix(issue:3622) resolve rigid parenthesis parsing
Browse files Browse the repository at this point in the history
* Fix issue less#3622 by resolving rigid parethensis parsing issues.
  • Loading branch information
puckowski committed Dec 10, 2024
1 parent 304c310 commit 639cf28
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 19 deletions.
29 changes: 11 additions & 18 deletions packages/less/src/less/parser/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

//
Expand Down Expand Up @@ -1314,24 +1313,18 @@ 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);

if (parserInput.$char(')')) {
if (selectors.length > 1) {
e = new (tree.Paren)(new Selector(selectors));
} else {
e = new(tree.Paren)(v);
}
parserInput.forget();
let vSelectors = [];
while ((v = this.selector(false)) && parserInput.$char(',')) {
vSelectors.push(v);
vSelectors.push(new Anonymous(','));
}
vSelectors.push(v);

if (v && parserInput.$char(')')) {
if (vSelectors.length === 1) {
e = new (tree.Paren)(vSelectors[0]);
} else {
parserInput.restore('Missing closing \')\'');
e = new (tree.ListParen)(vSelectors);
}
} else {
parserInput.restore('Missing closing \')\'');
Expand Down
3 changes: 2 additions & 1 deletion packages/less/src/less/tree/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
21 changes: 21 additions & 0 deletions packages/less/src/less/tree/list-paren.js
Original file line number Diff line number Diff line change
@@ -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;
21 changes: 21 additions & 0 deletions packages/test-data/css/_main/selectors.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
36 changes: 36 additions & 0 deletions packages/test-data/less/_main/selectors.less
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
});

0 comments on commit 639cf28

Please sign in to comment.