Skip to content

Commit 1e7b003

Browse files
authored
Release v4.2.2 (#4307)
* Release v4.2.2 * Update files for Release/v4.2.2. * chore: update changelog for CI merges * Update CHANGELOG.md for recent CI update merges.
1 parent ab5c82f commit 1e7b003

13 files changed

+224
-93
lines changed

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
## Change Log
22

3+
### v4.2.2 (2025-01-04)
4+
5+
- [#4290](https://github.com/less/less.js/pull/4290) Fix [#4268](https://github.com/less/less.js/issues/4268) nested pseudo-selector parsing (@puckowski)
6+
- [#4291](https://github.com/less/less.js/pull/4291) Enhance Less.js test environment setup (#4291) (@iChenLei)
7+
- [#4295](https://github.com/less/less.js/pull/4295) Fix [#4252](https://github.com/less/less.js/issues/4252) container queries created via mixin evaluating variables incorrectly (@puckowski)
8+
- [#4294](https://github.com/less/less.js/pull/4294) Fix [#3737](https://github.com/less/less.js/issues/3737) allow blank variable declarationd (@puckowski)
9+
- [#4292](https://github.com/less/less.js/pull/4292) Fix [#4258](https://github.com/less/less.js/issues/4258) variable interpolation after math (@puckowski)
10+
- [#4293](https://github.com/less/less.js/pull/4293) Fix [#4264](https://github.com/less/less.js/issues/4264) strip line comment from expression (@puckowski)
11+
- [#4302](https://github.com/less/less.js/pull/4302) Fix [#4301](https://github.com/less/less.js/issues/4301) at-rule declarations missing (@puckowski)
12+
- [#4309](https://github.com/less/less.js/pull/4309) Fix Node 23 CI (#4309) (@iChenLei)
13+
314
### v4.2.1 (2024-09-26)
415

516
- [#4237](https://github.com/less/less.js/pull/4237) Fix [#4235](https://github.com/less/less.js/issues/4235) container style queries extra space resolved (@puckowski)

dist/less.js

+98-38
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
2-
* Less - Leaner CSS v4.2.1
2+
* Less - Leaner CSS v4.2.2
33
* http://lesscss.org
44
*
5-
* Copyright (c) 2009-2024, Alexis Sellier <[email protected]>
5+
* Copyright (c) 2009-2025, Alexis Sellier <[email protected]>
66
* Licensed under the Apache-2.0 License.
77
*
88
* @license Apache-2.0
@@ -3238,6 +3238,34 @@
32383238
queryInParens: true
32393239
};
32403240

3241+
var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
3242+
this.value = value;
3243+
this._index = index;
3244+
this._fileInfo = currentFileInfo;
3245+
this.mapLines = mapLines;
3246+
this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
3247+
this.allowRoot = true;
3248+
this.copyVisibilityInfo(visibilityInfo);
3249+
};
3250+
Anonymous.prototype = Object.assign(new Node(), {
3251+
type: 'Anonymous',
3252+
eval: function () {
3253+
return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
3254+
},
3255+
compare: function (other) {
3256+
return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
3257+
},
3258+
isRulesetLike: function () {
3259+
return this.rulesetLike;
3260+
},
3261+
genCSS: function (context, output) {
3262+
this.nodeVisible = Boolean(this.value);
3263+
if (this.nodeVisible) {
3264+
output.add(this.value, this._fileInfo, this._index, this.mapLines);
3265+
}
3266+
}
3267+
});
3268+
32413269
//
32423270
// less.js - parser
32433271
//
@@ -4402,9 +4430,26 @@
44024430
if (!e) {
44034431
parserInput.save();
44044432
if (parserInput.$char('(')) {
4405-
if ((v = this.selector(false)) && parserInput.$char(')')) {
4406-
e = new (tree.Paren)(v);
4407-
parserInput.forget();
4433+
if ((v = this.selector(false))) {
4434+
var selectors = [];
4435+
while (parserInput.$char(',')) {
4436+
selectors.push(v);
4437+
selectors.push(new Anonymous(','));
4438+
v = this.selector(false);
4439+
}
4440+
selectors.push(v);
4441+
if (parserInput.$char(')')) {
4442+
if (selectors.length > 1) {
4443+
e = new (tree.Paren)(new Selector(selectors));
4444+
}
4445+
else {
4446+
e = new (tree.Paren)(v);
4447+
}
4448+
parserInput.forget();
4449+
}
4450+
else {
4451+
parserInput.restore('Missing closing \')\'');
4452+
}
44084453
}
44094454
else {
44104455
parserInput.restore('Missing closing \')\'');
@@ -4495,6 +4540,9 @@
44954540
error('Extend can only be used at the end of selector');
44964541
}
44974542
c = parserInput.currentChar();
4543+
if (Array.isArray(e)) {
4544+
e.forEach(function (ele) { return elements.push(ele); });
4545+
}
44984546
if (elements) {
44994547
elements.push(e);
45004548
}
@@ -4669,7 +4717,12 @@
46694717
merge = !isVariable && name.length > 1 && name.pop().value;
46704718
// Custom property values get permissive parsing
46714719
if (name[0].value && name[0].value.slice(0, 2) === '--') {
4672-
value = this.permissiveValue(/[;}]/);
4720+
if (parserInput.$char(';')) {
4721+
value = new Anonymous('');
4722+
}
4723+
else {
4724+
value = this.permissiveValue(/[;}]/);
4725+
}
46734726
}
46744727
// Try to store values as anonymous
46754728
// If we need the value later we'll re-parse it in ruleset.parseValue
@@ -4793,7 +4846,9 @@
47934846
}
47944847
// Treat like quoted values, but replace vars like unquoted expressions
47954848
var quote = new tree.Quoted('\'', item, true, index, fileInfo);
4796-
quote.variableRegex = /@([\w-]+)/g;
4849+
if (!item.startsWith('@{')) {
4850+
quote.variableRegex = /@([\w-]+)/g;
4851+
}
47974852
quote.propRegex = /\$([\w-]+)/g;
47984853
result.push(quote);
47994854
}
@@ -5443,7 +5498,7 @@
54435498
var index = parserInput.i;
54445499
do {
54455500
e = this.comment();
5446-
if (e) {
5501+
if (e && !e.isLineComment) {
54475502
entities.push(e);
54485503
continue;
54495504
}
@@ -5704,34 +5759,6 @@
57045759
Keyword.True = new Keyword('true');
57055760
Keyword.False = new Keyword('false');
57065761

5707-
var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
5708-
this.value = value;
5709-
this._index = index;
5710-
this._fileInfo = currentFileInfo;
5711-
this.mapLines = mapLines;
5712-
this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
5713-
this.allowRoot = true;
5714-
this.copyVisibilityInfo(visibilityInfo);
5715-
};
5716-
Anonymous.prototype = Object.assign(new Node(), {
5717-
type: 'Anonymous',
5718-
eval: function () {
5719-
return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
5720-
},
5721-
compare: function (other) {
5722-
return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
5723-
},
5724-
isRulesetLike: function () {
5725-
return this.rulesetLike;
5726-
},
5727-
genCSS: function (context, output) {
5728-
this.nodeVisible = Boolean(this.value);
5729-
if (this.nodeVisible) {
5730-
output.add(this.value, this._fileInfo, this._index, this.mapLines);
5731-
}
5732-
}
5733-
});
5734-
57355762
var MATH$1 = Math$1;
57365763
function evalName(context, name) {
57375764
var value = '';
@@ -7583,6 +7610,10 @@
75837610
var path = context.mediaPath.concat([this]);
75847611
// Extract the media-query conditions separated with `,` (OR).
75857612
for (i = 0; i < path.length; i++) {
7613+
if (path[i].type !== this.type) {
7614+
context.mediaBlocks.splice(i, 1);
7615+
return this;
7616+
}
75867617
value = path[i].features instanceof Value ?
75877618
path[i].features.value : path[i].features;
75887619
path[i] = Array.isArray(value) ? value : [value];
@@ -7978,6 +8009,7 @@
79788009
this.op2 = op2 ? op2.trim() : null;
79798010
this.rvalue = r;
79808011
this._index = i;
8012+
this.mvalues = [];
79818013
};
79828014
QueryInParens.prototype = Object.assign(new Node(), {
79838015
type: 'QueryInParens',
@@ -7990,7 +8022,32 @@
79908022
},
79918023
eval: function (context) {
79928024
this.lvalue = this.lvalue.eval(context);
7993-
this.mvalue = this.mvalue.eval(context);
8025+
var variableDeclaration;
8026+
var rule;
8027+
for (var i_1 = 0; (rule = context.frames[i_1]); i_1++) {
8028+
if (rule.type === 'Ruleset') {
8029+
variableDeclaration = rule.rules.find(function (r) {
8030+
if ((r instanceof Declaration) && r.variable) {
8031+
return true;
8032+
}
8033+
return false;
8034+
});
8035+
if (variableDeclaration) {
8036+
break;
8037+
}
8038+
}
8039+
}
8040+
if (!this.mvalueCopy) {
8041+
this.mvalueCopy = copy(this.mvalue);
8042+
}
8043+
if (variableDeclaration) {
8044+
this.mvalue = this.mvalueCopy;
8045+
this.mvalue = this.mvalue.eval(context);
8046+
this.mvalues.push(this.mvalue);
8047+
}
8048+
else {
8049+
this.mvalue = this.mvalue.eval(context);
8050+
}
79948051
if (this.rvalue) {
79958052
this.rvalue = this.rvalue.eval(context);
79968053
}
@@ -7999,6 +8056,9 @@
79998056
genCSS: function (context, output) {
80008057
this.lvalue.genCSS(context, output);
80018058
output.add(' ' + this.op + ' ');
8059+
if (this.mvalues.length > 0) {
8060+
this.mvalue = this.mvalues.shift();
8061+
}
80028062
this.mvalue.genCSS(context, output);
80038063
if (this.rvalue) {
80048064
output.add(' ' + this.op2 + ' ');
@@ -10792,7 +10852,7 @@
1079210852
return render;
1079310853
}
1079410854

10795-
var version = "4.2.1";
10855+
var version = "4.2.2";
1079610856

1079710857
function parseNodeVersion(version) {
1079810858
var match = version.match(/^v(\d{1,2})\.(\d{1,2})\.(\d{1,2})(?:-([0-9A-Za-z-.]+))?(?:\+([0-9A-Za-z-.]+))?$/); // eslint-disable-line max-len

dist/less.min.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/less.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lerna.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
],
55
"useNx": false,
66
"npmClient": "npm",
7-
"version": "4.2.1"
7+
"version": "4.2.2"
88
}

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@less/root",
33
"private": true,
4-
"version": "4.2.1",
4+
"version": "4.2.2",
55
"description": "Less monorepo",
66
"homepage": "http://lesscss.org",
77
"scripts": {

0 commit comments

Comments
 (0)