Skip to content

Commit 9d345ff

Browse files
authored
Release v4.4.1 (#4351)
* Update files for Release/v4.4.1
1 parent 6e0095d commit 9d345ff

File tree

10 files changed

+208
-81
lines changed

10 files changed

+208
-81
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## Change Log
22

3+
### v4.4.1 (2025-07-25)
4+
5+
- [#4342](https://github.com/less/less.js/pull/4342) Add support for CSS scroll state container queries (@puckowski)
6+
- [#4349](https://github.com/less/less.js/pull/4349) Fix [#4348](https://github.com/less/less.js/issues/4348) parse layer nesting syntax (@puckowski)
7+
38
### v4.4.0 (2025-05-31)
49

510
- [#4337](https://github.com/less/less.js/pull/4337) Add support for layer at-rule (@puckowski)

dist/less.js

Lines changed: 97 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Less - Leaner CSS v4.4.0
2+
* Less - Leaner CSS v4.4.1
33
* http://lesscss.org
44
*
55
* Copyright (c) 2009-2025, Alexis Sellier <[email protected]>
@@ -908,7 +908,11 @@
908908
output.add(')');
909909
},
910910
eval: function (context) {
911-
return new Paren(this.value.eval(context));
911+
var paren = new Paren(this.value.eval(context));
912+
if (this.noSpacing) {
913+
paren.noSpacing = true;
914+
}
915+
return paren;
912916
}
913917
});
914918

@@ -5010,8 +5014,14 @@
50105014
var e;
50115015
var p;
50125016
var rangeP;
5017+
var spacing = false;
50135018
parserInput.save();
50145019
do {
5020+
parserInput.save();
5021+
if (parserInput.$re(/^[0-9a-z-]*\s+\(/)) {
5022+
spacing = true;
5023+
}
5024+
parserInput.restore();
50155025
e = entities.declarationCall.bind(this)() || entities.keyword() || entities.variable() || entities.mixinLookup();
50165026
if (e) {
50175027
nodes.push(e);
@@ -5039,9 +5049,14 @@
50395049
}
50405050
else if (p && e) {
50415051
nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i + currentIndex, fileInfo, true)));
5052+
if (!spacing) {
5053+
nodes[nodes.length - 1].noSpacing = true;
5054+
}
5055+
spacing = false;
50425056
}
50435057
else if (e) {
50445058
nodes.push(new (tree.Paren)(e));
5059+
spacing = false;
50455060
}
50465061
else {
50475062
error('badly formed media feature definition');
@@ -5163,6 +5178,48 @@
51635178
return null;
51645179
}
51655180
},
5181+
atruleUnknown: function (value, name, hasBlock) {
5182+
value = this.permissiveValue(/^[{;]/);
5183+
hasBlock = (parserInput.currentChar() === '{');
5184+
if (!value) {
5185+
if (!hasBlock && parserInput.currentChar() !== ';') {
5186+
error(''.concat(name, ' rule is missing block or ending semi-colon'));
5187+
}
5188+
}
5189+
else if (!value.value) {
5190+
value = null;
5191+
}
5192+
return [value, hasBlock];
5193+
},
5194+
atruleBlock: function (rules, value, isRooted, isKeywordList) {
5195+
rules = this.blockRuleset();
5196+
parserInput.save();
5197+
if (!rules && !isRooted) {
5198+
value = this.entity();
5199+
rules = this.blockRuleset();
5200+
}
5201+
if (!rules && !isRooted) {
5202+
parserInput.restore();
5203+
var e = [];
5204+
value = this.entity();
5205+
while (parserInput.$char(',')) {
5206+
e.push(value);
5207+
value = this.entity();
5208+
}
5209+
if (value && e.length > 0) {
5210+
e.push(value);
5211+
value = e;
5212+
isKeywordList = true;
5213+
}
5214+
else {
5215+
rules = this.blockRuleset();
5216+
}
5217+
}
5218+
else {
5219+
parserInput.forget();
5220+
}
5221+
return [rules, value, isKeywordList];
5222+
},
51665223
//
51675224
// A CSS AtRule
51685225
//
@@ -5238,43 +5295,27 @@
52385295
}
52395296
}
52405297
else if (hasUnknown) {
5241-
value = this.permissiveValue(/^[{;]/);
5242-
hasBlock = (parserInput.currentChar() === '{');
5243-
if (!value) {
5244-
if (!hasBlock && parserInput.currentChar() !== ';') {
5245-
error("".concat(name, " rule is missing block or ending semi-colon"));
5246-
}
5247-
}
5248-
else if (!value.value) {
5249-
value = null;
5250-
}
5298+
var unknownPackage = this.atruleUnknown(value, name, hasBlock);
5299+
value = unknownPackage[0];
5300+
hasBlock = unknownPackage[1];
52515301
}
52525302
if (hasBlock) {
5253-
rules = this.blockRuleset();
5254-
parserInput.save();
5255-
if (!rules && !isRooted) {
5256-
value = this.entity();
5257-
rules = this.blockRuleset();
5258-
}
5259-
if (!rules && !isRooted) {
5303+
var blockPackage = this.atruleBlock(rules, value, isRooted, isKeywordList);
5304+
rules = blockPackage[0];
5305+
value = blockPackage[1];
5306+
isKeywordList = blockPackage[2];
5307+
if (!rules && !hasUnknown) {
52605308
parserInput.restore();
5261-
var e = [];
5262-
value = this.entity();
5263-
while (parserInput.$char(',')) {
5264-
e.push(value);
5265-
value = this.entity();
5309+
name = parserInput.$re(/^@[a-z-]+/);
5310+
var unknownPackage = this.atruleUnknown(value, name, hasBlock);
5311+
value = unknownPackage[0];
5312+
hasBlock = unknownPackage[1];
5313+
if (hasBlock) {
5314+
blockPackage = this.atruleBlock(rules, value, isRooted, isKeywordList);
5315+
rules = blockPackage[0];
5316+
value = blockPackage[1];
5317+
isKeywordList = blockPackage[2];
52665318
}
5267-
if (value && e.length > 0) {
5268-
e.push(value);
5269-
value = e;
5270-
isKeywordList = true;
5271-
}
5272-
else {
5273-
rules = this.blockRuleset();
5274-
}
5275-
}
5276-
else {
5277-
parserInput.forget();
52785319
}
52795320
}
52805321
if (rules || isKeywordList || (!hasBlock && value && parserInput.$char(';'))) {
@@ -7119,7 +7160,26 @@
71197160
this.rules = visitor.visitArray(this.rules);
71207161
}
71217162
},
7163+
evalFunction: function () {
7164+
if (!this.features || !Array.isArray(this.features.value) || this.features.value.length < 1) {
7165+
return;
7166+
}
7167+
var exprValues = this.features.value;
7168+
var expr, paren;
7169+
for (var index = 0; index < exprValues.length; ++index) {
7170+
expr = exprValues[index];
7171+
if (expr.type === 'Keyword' && index + 1 < exprValues.length) {
7172+
paren = exprValues[index + 1];
7173+
if (paren.type === 'Paren' && paren.noSpacing) {
7174+
exprValues[index] = new Expression([expr, paren]);
7175+
exprValues.splice(index + 1, 1);
7176+
exprValues[index].noSpacing = true;
7177+
}
7178+
}
7179+
}
7180+
},
71227181
evalTop: function (context) {
7182+
this.evalFunction();
71237183
var result = this;
71247184
// Render all dependent Media blocks.
71257185
if (context.mediaBlocks.length > 1) {
@@ -7134,6 +7194,7 @@
71347194
return result;
71357195
},
71367196
evalNested: function (context) {
7197+
this.evalFunction();
71377198
var i;
71387199
var value;
71397200
var path = context.mediaPath.concat([this]);
@@ -11128,7 +11189,7 @@
1112811189
return render;
1112911190
}
1113011191

11131-
var version = "4.4.0";
11192+
var version = "4.4.1";
1113211193

1113311194
function parseNodeVersion(version) {
1113411195
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

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/less.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

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

0 commit comments

Comments
 (0)