From 2431015afa1c2454e27907cfefaface19ce1393d Mon Sep 17 00:00:00 2001 From: Lei Chen Date: Thu, 23 Dec 2021 23:53:41 +0800 Subject: [PATCH] feat: add support for case-insensitive attribute selectors (#3673) * feat: add support for case-insensitive attribute selectors --- packages/less/src/less/parser/parser.js | 10 +++++++++- packages/less/src/less/tree/attribute.js | 15 ++++++++++++--- packages/test-data/css/_main/selectors.css | 15 +++++++++++++++ packages/test-data/less/_main/selectors.less | 17 +++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/packages/less/src/less/parser/parser.js b/packages/less/src/less/parser/parser.js index 41b7d01a5..c7a65cb07 100644 --- a/packages/less/src/less/parser/parser.js +++ b/packages/less/src/less/parser/parser.js @@ -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-]|\\.)+/); @@ -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); }, // diff --git a/packages/less/src/less/tree/attribute.js b/packages/less/src/less/tree/attribute.js index cc78b4b22..0fa07eaba 100644 --- a/packages/less/src/less/tree/attribute.js +++ b/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) { @@ -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}]`; } }); diff --git a/packages/test-data/css/_main/selectors.css b/packages/test-data/css/_main/selectors.css index 10716d45c..9e0a31579 100644 --- a/packages/test-data/css/_main/selectors.css +++ b/packages/test-data/css/_main/selectors.css @@ -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 diff --git a/packages/test-data/less/_main/selectors.less b/packages/test-data/less/_main/selectors.less index 005524cc5..8f8bc6f1a 100644 --- a/packages/test-data/less/_main/selectors.less +++ b/packages/test-data/less/_main/selectors.less @@ -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