diff --git a/packages/less/src/less/parser/parser.js b/packages/less/src/less/parser/parser.js index 53f8a5832..1deb0f765 100644 --- a/packages/less/src/less/parser/parser.js +++ b/packages/less/src/less/parser/parser.js @@ -1884,8 +1884,15 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) { let e; let p; let rangeP; + let spacing = false; parserInput.save(); do { + parserInput.save(); + if (parserInput.$re(/^[0-9a-z-]*\s+\(/)) { + spacing = true; + } + parserInput.restore(); + e = entities.declarationCall.bind(this)() || entities.keyword() || entities.variable() || entities.mixinLookup() if (e) { nodes.push(e); @@ -1911,8 +1918,13 @@ const Parser = function Parser(context, imports, fileInfo, currentIndex) { e = p; } else if (p && e) { nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i + currentIndex, fileInfo, true))); + if (!spacing) { + nodes[nodes.length - 1].noSpacing = true; + } + spacing = false; } else if (e) { nodes.push(new(tree.Paren)(e)); + spacing = false; } else { error('badly formed media feature definition'); } diff --git a/packages/less/src/less/tree/nested-at-rule.js b/packages/less/src/less/tree/nested-at-rule.js index 2846f5ffb..0060755ab 100644 --- a/packages/less/src/less/tree/nested-at-rule.js +++ b/packages/less/src/less/tree/nested-at-rule.js @@ -20,7 +20,32 @@ const NestableAtRulePrototype = { } }, + evalFunction: function () { + if (!this.features || !Array.isArray(this.features.value) || this.features.value.length < 1) { + return; + } + + const exprValues = this.features.value; + let expr, paren; + + for (let index = 0; index < exprValues.length; ++index) { + expr = exprValues[index]; + + if (expr.type === 'Keyword' && index + 1 < exprValues.length) { + paren = exprValues[index + 1]; + + if (paren.type === 'Paren' && paren.noSpacing) { + exprValues[index]= new Expression([expr, paren]); + exprValues.splice(index + 1, 1); + exprValues[index].noSpacing = true; + } + } + } + }, + evalTop(context) { + this.evalFunction(); + let result = this; // Render all dependent Media blocks. @@ -39,6 +64,8 @@ const NestableAtRulePrototype = { }, evalNested(context) { + this.evalFunction(); + let i; let value; const path = context.mediaPath.concat([this]); diff --git a/packages/less/src/less/tree/paren.js b/packages/less/src/less/tree/paren.js index 6e0d889a9..248bfde6c 100644 --- a/packages/less/src/less/tree/paren.js +++ b/packages/less/src/less/tree/paren.js @@ -14,7 +14,13 @@ Paren.prototype = Object.assign(new Node(), { }, eval(context) { - return new Paren(this.value.eval(context)); + const paren = new Paren(this.value.eval(context)); + + if (this.noSpacing) { + paren.noSpacing = true; + } + + return paren; } }); diff --git a/packages/test-data/css/_main/container.css b/packages/test-data/css/_main/container.css index f5a17a602..39aa6af87 100644 --- a/packages/test-data/css/_main/container.css +++ b/packages/test-data/css/_main/container.css @@ -241,3 +241,22 @@ color: purple; } } +#sticky { + position: sticky; + container-type: scroll-state; +} +@container scroll-state(stuck: top) { + #sticky-child { + font-size: 75%; + } +} +@container scroll-state(snapped: x) { + #sticky-child { + font-size: 75%; + } +} +@container scroll-state(scrollable: top) { + #sticky-child { + font-size: 75%; + } +} diff --git a/packages/test-data/less/_main/container.less b/packages/test-data/less/_main/container.less index 73fd17be0..d592eafd4 100644 --- a/packages/test-data/less/_main/container.less +++ b/packages/test-data/less/_main/container.less @@ -289,3 +289,26 @@ color: purple; } } + +#sticky { + position: sticky; + container-type: scroll-state; +} + +@container scroll-state(stuck: top) { + #sticky-child { + font-size: 75%; + } +} + +@container scroll-state(snapped: x) { + #sticky-child { + font-size: 75%; + } +} + +@container scroll-state(scrollable: top) { + #sticky-child { + font-size: 75%; + } +}