Skip to content

Commit 2431015

Browse files
authored
feat: add support for case-insensitive attribute selectors (#3673)
* feat: add support for case-insensitive attribute selectors
1 parent ee9e13b commit 2431015

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

packages/less/src/less/parser/parser.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,11 @@ const Parser = function Parser(context, imports, fileInfo) {
14051405
let key;
14061406
let val;
14071407
let op;
1408+
//
1409+
// case-insensitive flag
1410+
// e.g. [attr operator value i]
1411+
//
1412+
let cif;
14081413

14091414
if (!(key = entities.variableCurly())) {
14101415
key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
@@ -1413,11 +1418,14 @@ const Parser = function Parser(context, imports, fileInfo) {
14131418
op = parserInput.$re(/^[|~*$^]?=/);
14141419
if (op) {
14151420
val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly();
1421+
if (val) {
1422+
cif = parserInput.$re(/^[iIsS]/);
1423+
}
14161424
}
14171425

14181426
expectChar(']');
14191427

1420-
return new(tree.Attribute)(key, op, val);
1428+
return new(tree.Attribute)(key, op, val, cif);
14211429
},
14221430

14231431
//

packages/less/src/less/tree/attribute.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import Node from './node';
22

3-
const Attribute = function(key, op, value) {
3+
const Attribute = function(key, op, value, cif) {
44
this.key = key;
55
this.op = op;
66
this.value = value;
7+
this.cif = cif;
78
}
89

910
Attribute.prototype = Object.assign(new Node(), {
1011
type: 'Attribute',
1112

1213
eval(context) {
13-
return new Attribute(this.key.eval ? this.key.eval(context) : this.key,
14-
this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);
14+
return new Attribute(
15+
this.key.eval ? this.key.eval(context) : this.key,
16+
this.op,
17+
(this.value && this.value.eval) ? this.value.eval(context) : this.value,
18+
this.cif
19+
);
1520
},
1621

1722
genCSS(context, output) {
@@ -26,6 +31,10 @@ Attribute.prototype = Object.assign(new Node(), {
2631
value += (this.value.toCSS ? this.value.toCSS(context) : this.value);
2732
}
2833

34+
if (this.cif) {
35+
value = value + " " + this.cif;
36+
}
37+
2938
return `[${value}]`;
3039
}
3140
});

packages/test-data/css/_main/selectors.css

+15
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,21 @@ p a span {
143143
[p] {
144144
attributes: yes;
145145
}
146+
/**
147+
* https://www.w3.org/TR/selectors-4/#attribute-case
148+
*/
149+
a[href*="insensitive" i] {
150+
color: cyan;
151+
}
152+
a[href*="cAsE" s] {
153+
color: pink;
154+
}
155+
a[href*="less" I] {
156+
background-color: silver;
157+
}
158+
a[href*="less" S] {
159+
background-color: red;
160+
}
146161
/*
147162
Large comment means chunk will be emitted after } which means chunk will begin with whitespace...
148163
blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank

packages/test-data/less/_main/selectors.less

+17
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,23 @@ a {
147147
attributes: yes;
148148
}
149149

150+
/**
151+
* https://www.w3.org/TR/selectors-4/#attribute-case
152+
*/
153+
@pattern: less;
154+
a[href*="insensitive" i] {
155+
color: cyan;
156+
}
157+
a[href*="cAsE" s] {
158+
color: pink;
159+
}
160+
a[href*="@{pattern}" I] {
161+
background-color: silver;
162+
}
163+
a[href*="@{pattern}" S] {
164+
background-color: red;
165+
}
166+
150167
/*
151168
Large comment means chunk will be emitted after } which means chunk will begin with whitespace...
152169
blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank

0 commit comments

Comments
 (0)