diff --git a/packages/less/src/less/tree/expression.js b/packages/less/src/less/tree/expression.js index 03b40a1c8..c72f55b5b 100644 --- a/packages/less/src/less/tree/expression.js +++ b/packages/less/src/less/tree/expression.js @@ -20,6 +20,7 @@ Expression.prototype = Object.assign(new Node(), { }, eval(context) { + const noSpacing = this.noSpacing; let returnValue; const mathOn = context.isMathOn(); const inParenthesis = this.parens; @@ -50,6 +51,7 @@ Expression.prototype = Object.assign(new Node(), { && (!(returnValue instanceof Dimension))) { returnValue = new Paren(returnValue); } + returnValue.noSpacing = returnValue.noSpacing || noSpacing; return returnValue; }, diff --git a/packages/less/src/less/tree/import.js b/packages/less/src/less/tree/import.js index abafa3d9f..8c377df87 100644 --- a/packages/less/src/less/tree/import.js +++ b/packages/less/src/less/tree/import.js @@ -6,6 +6,7 @@ import Ruleset from './ruleset'; import Anonymous from './anonymous'; import * as utils from '../utils'; import LessError from '../less-error'; +import Expression from './expression'; // // CSS @import node @@ -157,6 +158,20 @@ Import.prototype = Object.assign(new Node(), { return []; } } + if (this.features) { + let featureValue = this.features.value; + if (Array.isArray(featureValue) && featureValue.length === 1) { + const expr = featureValue[0]; + if (expr.type === 'Expression' && Array.isArray(expr.value) && expr.value.length >= 2) { + featureValue = expr.value; + const isLayer = featureValue[0].type === 'Keyword' && featureValue[0].value === 'layer' + && featureValue[1].type === 'Paren'; + if (isLayer) { + this.css = false; + } + } + } + } if (this.options.inline) { const contents = new Anonymous(this.root, 0, { @@ -165,18 +180,57 @@ Import.prototype = Object.assign(new Node(), { }, true, true); return this.features ? new Media([contents], this.features.value) : [contents]; - } else if (this.css) { + } else if (this.css || this.layerCss) { const newImport = new Import(this.evalPath(context), features, this.options, this._index); + if (this.layerCss) { + newImport.css = this.layerCss; + newImport.path._fileInfo = this._fileInfo; + } if (!newImport.css && this.error) { throw this.error; } return newImport; } else if (this.root) { + if (this.features) { + let featureValue = this.features.value; + if (Array.isArray(featureValue) && featureValue.length === 1) { + const expr = featureValue[0]; + if (expr.type === 'Expression' && Array.isArray(expr.value) && expr.value.length >= 2) { + featureValue = expr.value; + const isLayer = featureValue[0].type === 'Keyword' && featureValue[0].value === 'layer' + && featureValue[1].type === 'Paren'; + if (isLayer) { + this.layerCss = true; + featureValue[0] = new Expression(featureValue.slice(0, 2)); + featureValue.splice(1, 1); + featureValue[0].noSpacing = true; + return this; + } + } + } + } ruleset = new Ruleset(null, utils.copyArray(this.root.rules)); ruleset.evalImports(context); return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; } else { + if (this.features) { + let featureValue = this.features.value; + if (Array.isArray(featureValue) && featureValue.length >= 1) { + featureValue = featureValue[0].value; + if (Array.isArray(featureValue) && featureValue.length >= 2) { + const isLayer = featureValue[0].type === 'Keyword' && featureValue[0].value === 'layer' + && featureValue[1].type === 'Paren'; + if (isLayer) { + this.css = true; + featureValue[0] = new Expression(featureValue.slice(0, 2)); + featureValue.splice(1, 1); + featureValue[0].noSpacing = true; + return this; + } + } + } + } return []; } } diff --git a/packages/test-data/css/_main/layer.css b/packages/test-data/css/_main/layer.css index 97235d750..1b342e996 100644 --- a/packages/test-data/css/_main/layer.css +++ b/packages/test-data/css/_main/layer.css @@ -1,3 +1,7 @@ +@import url("/import/layer-import-2.css") layer(foo); +@import url("/import/layer-import-3.css") layer(responsive) supports(display: flex) screen and (max-width: 768px); +@import url("/import/layer-import-4.css") layer(print) print; +@import url("/import/layer-import-5.css") layer(features) supports(display: grid); @layer { .main::before { color: #f00; diff --git a/packages/test-data/less/_main/import/layer-import-2.css b/packages/test-data/less/_main/import/layer-import-2.css new file mode 100644 index 000000000..f30c9561f --- /dev/null +++ b/packages/test-data/less/_main/import/layer-import-2.css @@ -0,0 +1,5 @@ +.sub-rule { + ul { + color: white; + } +} diff --git a/packages/test-data/less/_main/import/layer-import-3.css b/packages/test-data/less/_main/import/layer-import-3.css new file mode 100644 index 000000000..e69de29bb diff --git a/packages/test-data/less/_main/import/layer-import-4.css b/packages/test-data/less/_main/import/layer-import-4.css new file mode 100644 index 000000000..f30c9561f --- /dev/null +++ b/packages/test-data/less/_main/import/layer-import-4.css @@ -0,0 +1,5 @@ +.sub-rule { + ul { + color: white; + } +} diff --git a/packages/test-data/less/_main/import/layer-import-5.css b/packages/test-data/less/_main/import/layer-import-5.css new file mode 100644 index 000000000..f30c9561f --- /dev/null +++ b/packages/test-data/less/_main/import/layer-import-5.css @@ -0,0 +1,5 @@ +.sub-rule { + ul { + color: white; + } +} diff --git a/packages/test-data/less/_main/layer.less b/packages/test-data/less/_main/layer.less index 00d0aae11..7943da048 100644 --- a/packages/test-data/less/_main/layer.less +++ b/packages/test-data/less/_main/layer.less @@ -10,6 +10,11 @@ @import "./import/layer-import.less"; } +@import url("/import/layer-import-2.css") layer(foo); +@import url("/import/layer-import-3.css") layer(responsive) supports(display: flex) screen and (max-width: 768px); +@import url("/import/layer-import-4.css") layer(print) print; +@import url("/import/layer-import-5.css") layer(features) supports(display: grid); + @layer-name: primevue; @layer @layer-name {