Add support for import at-rule layer functionality (#4340)

* fix(issue#4242): add support for layer at-rule

* Add support for layer at-rule.
* Add tests for layer at-rule.

* feat: add support for layer import syntax

* Add support for layer import at-rule syntax. See: https://developer.mozilla.org/en-US/docs/Web/CSS/@import

* chore: cleanup layer import solution

* Cleanup layer import at-rule solution before merge.

* fix(issue#4242): fix for media query list

* Add fix for media query list parsing in import.
* Add test for import with media query list syntax.
This commit is contained in:
Daniel Puckowski
2025-05-29 23:14:40 -04:00
committed by GitHub
parent 36626c8853
commit 67404cd50c
8 changed files with 83 additions and 1 deletions

View File

@@ -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;
},

View File

@@ -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 [];
}
}

View File

@@ -1,3 +1,8 @@
@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-4.css") layer(print) print, (max-width: 600px);
@import url("/import/layer-import-5.css") layer(features) supports(display: grid);
@layer {
.main::before {
color: #f00;

View File

@@ -0,0 +1,5 @@
.sub-rule {
ul {
color: white;
}
}

View File

@@ -0,0 +1,5 @@
.sub-rule {
ul {
color: white;
}
}

View File

@@ -0,0 +1,5 @@
.sub-rule {
ul {
color: white;
}
}

View File

@@ -10,6 +10,12 @@
@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-4.css") layer(print) print, (max-width: 600px);
@import url("/import/layer-import-5.css") layer(features) supports(display: grid);
@layer-name: primevue;
@layer @layer-name {