From dd7e0d7d2b41bf5a177e20ec084245034ee4133c Mon Sep 17 00:00:00 2001 From: Puneet Dixit <236133619+puneetdixit200@users.noreply.github.com> Date: Thu, 21 May 2026 20:38:01 +0530 Subject: [PATCH] Preserve container feature function spacing Signed-off-by: Puneet Dixit <236133619+puneetdixit200@users.noreply.github.com> --- packages/less/lib/less/parser/parser.js | 23 +++++++-- .../tests-unit/container/container.css | 40 ++++++++++++++++ .../tests-unit/container/container.less | 48 +++++++++++++++++++ 3 files changed, 107 insertions(+), 4 deletions(-) diff --git a/packages/less/lib/less/parser/parser.js b/packages/less/lib/less/parser/parser.js index 6a439fb89..1bd114192 100644 --- a/packages/less/lib/less/parser/parser.js +++ b/packages/less/lib/less/parser/parser.js @@ -1878,7 +1878,7 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) { parserInput.save(); do { parserInput.save(); - if (parserInput.$re(/^[0-9a-z-]*\s+\(/)) { + if (parserInput.$re(/^(?:--|-?(?:[_a-zA-Z0-9]|[^\0-\x7F]|\\[0-9a-fA-F]{1,6}\s?|\\[^\n\r\f0-9a-fA-F]))(?:[-_a-zA-Z0-9]|[^\0-\x7F]|\\[0-9a-fA-F]{1,6}\s?|\\[^\n\r\f0-9a-fA-F])*\s+\(/)) { spacing = true; } parserInput.restore(); @@ -1920,7 +1920,11 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) { } if (closed) { if (p && !e) { - nodes.push(new (tree.Paren)(new (tree.QueryInParens)(p.op, p.lvalue, p.rvalue, rangeP ? rangeP.op : null, rangeP ? rangeP.rvalue : null, p._index))); + const paren = new (tree.Paren)(new (tree.QueryInParens)(p.op, p.lvalue, p.rvalue, rangeP ? rangeP.op : null, rangeP ? rangeP.rvalue : null, p._index)); + if (!spacing) { + paren.noSpacing = true; + } + nodes.push(paren); e = p; } else if (p && e) { nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i + currentIndex, fileInfo, true))); @@ -1929,7 +1933,11 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) { } spacing = false; } else if (e) { - nodes.push(new(tree.Paren)(e)); + const paren = new(tree.Paren)(e); + if (!spacing) { + paren.noSpacing = true; + } + nodes.push(paren); spacing = false; } else { error('badly formed media feature definition'); @@ -1942,7 +1950,14 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) { parserInput.forget(); if (nodes.length > 0) { - return new(tree.Expression)(nodes); + const expression = new(tree.Expression)(nodes); + if (nodes.length === 2 + && (nodes[0].type === 'Keyword' || nodes[0].type === 'Variable') + && nodes[1].type === 'Paren' + && nodes[1].noSpacing) { + expression.noSpacing = true; + } + return expression; } }, diff --git a/packages/test-data/tests-unit/container/container.css b/packages/test-data/tests-unit/container/container.css index dd9673c7e..70fb096f8 100644 --- a/packages/test-data/tests-unit/container/container.css +++ b/packages/test-data/tests-unit/container/container.css @@ -130,6 +130,41 @@ margin: 0.5em 0 0 0; } } +@container card (width > 400px), style(--responsive: true), scroll-state(stuck: top) { + h2 { + font-size: 1.5em; + } +} +@container style(--theme) { + .style-query { + color: red; + } +} +@container style((--theme: one) or (--theme: two)) { + .style-query-list { + color: blue; + } +} +@container contactBody (min-width: 1300px) { + .named-container { + width: 25%; + } +} +@container _body (min-width: 1300px) { + .underscored-container { + width: 25%; + } +} +@container --body (min-width: 1300px) { + .custom-ident-container { + width: 25%; + } +} +@container contact\.body (min-width: 1300px) { + .escaped-container { + width: 25%; + } +} @container (width < 500px) or (height < 500px) and (orientation: portrait) { .card-content p { padding: 0; @@ -268,6 +303,11 @@ font-size: 75%; } } +@container sidebar (min-width: 400px), scroll-state(stuck: top) { + #sticky-child { + font-size: 80%; + } +} @container foo (min-width: 400px) { #sticky-child { font-size: 75%; diff --git a/packages/test-data/tests-unit/container/container.less b/packages/test-data/tests-unit/container/container.less index 013a9e243..9d1dcd714 100644 --- a/packages/test-data/tests-unit/container/container.less +++ b/packages/test-data/tests-unit/container/container.less @@ -159,6 +159,48 @@ } } +@container card (width > 400px), style(--responsive: true), scroll-state(stuck: top) { + h2 { + font-size: 1.5em; + } +} + +@container style(--theme) { + .style-query { + color: red; + } +} + +@container style((--theme: one) or (--theme: two)) { + .style-query-list { + color: blue; + } +} + +@container contactBody (min-width: 1300px) { + .named-container { + width: 25%; + } +} + +@container _body (min-width: 1300px) { + .underscored-container { + width: 25%; + } +} + +@container --body (min-width: 1300px) { + .custom-ident-container { + width: 25%; + } +} + +@container contact\.body (min-width: 1300px) { + .escaped-container { + width: 25%; + } +} + @container ( width < 500px ) or (height<500px) and (orientation: portrait) { .card-content p { padding: 0; @@ -319,6 +361,12 @@ } } +@container sidebar (min-width: 400px), scroll-state(stuck: top) { + #sticky-child { + font-size: 80%; + } +} + @varfoo: foo; @threshold: 400px; @container @varfoo (min-width: @threshold) {