Skip to content

Commit

Permalink
feat: add support for case-insensitive attribute selectors (#3673)
Browse files Browse the repository at this point in the history
* feat: add support for case-insensitive attribute selectors
  • Loading branch information
iChenLei committed Dec 23, 2021
1 parent ee9e13b commit 2431015
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
10 changes: 9 additions & 1 deletion packages/less/src/less/parser/parser.js
Expand Up @@ -1405,6 +1405,11 @@ const Parser = function Parser(context, imports, fileInfo) {
let key;
let val;
let op;
//
// case-insensitive flag
// e.g. [attr operator value i]
//
let cif;

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

expectChar(']');

return new(tree.Attribute)(key, op, val);
return new(tree.Attribute)(key, op, val, cif);
},

//
Expand Down
15 changes: 12 additions & 3 deletions packages/less/src/less/tree/attribute.js
@@ -1,17 +1,22 @@
import Node from './node';

const Attribute = function(key, op, value) {
const Attribute = function(key, op, value, cif) {
this.key = key;
this.op = op;
this.value = value;
this.cif = cif;
}

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

eval(context) {
return new Attribute(this.key.eval ? this.key.eval(context) : this.key,
this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);
return new Attribute(
this.key.eval ? this.key.eval(context) : this.key,
this.op,
(this.value && this.value.eval) ? this.value.eval(context) : this.value,
this.cif
);
},

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

if (this.cif) {
value = value + " " + this.cif;
}

return `[${value}]`;
}
});
Expand Down
15 changes: 15 additions & 0 deletions packages/test-data/css/_main/selectors.css
Expand Up @@ -143,6 +143,21 @@ p a span {
[p] {
attributes: yes;
}
/**
* https://www.w3.org/TR/selectors-4/#attribute-case
*/
a[href*="insensitive" i] {
color: cyan;
}
a[href*="cAsE" s] {
color: pink;
}
a[href*="less" I] {
background-color: silver;
}
a[href*="less" S] {
background-color: red;
}
/*
Large comment means chunk will be emitted after } which means chunk will begin with whitespace...
blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank
Expand Down
17 changes: 17 additions & 0 deletions packages/test-data/less/_main/selectors.less
Expand Up @@ -147,6 +147,23 @@ a {
attributes: yes;
}

/**
* https://www.w3.org/TR/selectors-4/#attribute-case
*/
@pattern: less;
a[href*="insensitive" i] {
color: cyan;
}
a[href*="cAsE" s] {
color: pink;
}
a[href*="@{pattern}" I] {
background-color: silver;
}
a[href*="@{pattern}" S] {
background-color: red;
}

/*
Large comment means chunk will be emitted after } which means chunk will begin with whitespace...
blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank
Expand Down

0 comments on commit 2431015

Please sign in to comment.