@@ -4,6 +4,7 @@ const path = require("path")
44
55// internal tooling
66const joinMedia = require ( "./lib/join-media" )
7+ const joinLayer = require ( "./lib/join-layer" )
78const resolveId = require ( "./lib/resolve-id" )
89const loadContent = require ( "./lib/load-content" )
910const processContent = require ( "./lib/process-content" )
@@ -46,11 +47,13 @@ function AtImport(options) {
4647 throw new Error ( "plugins option must be an array" )
4748 }
4849
49- return parseStyles ( result , styles , options , state , [ ] ) . then ( bundle => {
50- applyRaws ( bundle )
51- applyMedia ( bundle )
52- applyStyles ( bundle , styles )
53- } )
50+ return parseStyles ( result , styles , options , state , [ ] , [ ] ) . then (
51+ bundle => {
52+ applyRaws ( bundle )
53+ applyMedia ( bundle )
54+ applyStyles ( bundle , styles )
55+ }
56+ )
5457
5558 function applyRaws ( bundle ) {
5659 bundle . forEach ( ( stmt , index ) => {
@@ -68,21 +71,60 @@ function AtImport(options) {
6871
6972 function applyMedia ( bundle ) {
7073 bundle . forEach ( stmt => {
71- if ( ! stmt . media . length || stmt . type === "charset" ) return
74+ if (
75+ ( ! stmt . media . length && ! stmt . layer . length ) ||
76+ stmt . type === "charset"
77+ ) {
78+ return
79+ }
80+
7281 if ( stmt . type === "import" ) {
7382 stmt . node . params = `${ stmt . fullUri } ${ stmt . media . join ( ", " ) } `
74- } else if ( stmt . type === "media" )
83+ } else if ( stmt . type === "media" ) {
7584 stmt . node . params = stmt . media . join ( ", " )
76- else {
85+ } else {
7786 const { nodes } = stmt
7887 const { parent } = nodes [ 0 ]
79- const mediaNode = atRule ( {
80- name : "media" ,
81- params : stmt . media . join ( ", " ) ,
82- source : parent . source ,
83- } )
8488
85- parent . insertBefore ( nodes [ 0 ] , mediaNode )
89+ let outerAtRule
90+ let innerAtRule
91+ if ( stmt . media . length && stmt . layer . length ) {
92+ const mediaNode = atRule ( {
93+ name : "media" ,
94+ params : stmt . media . join ( ", " ) ,
95+ source : parent . source ,
96+ } )
97+
98+ const layerNode = atRule ( {
99+ name : "layer" ,
100+ params : stmt . layer . filter ( layer => layer !== "" ) . join ( "." ) ,
101+ source : parent . source ,
102+ } )
103+
104+ mediaNode . append ( layerNode )
105+ innerAtRule = layerNode
106+ outerAtRule = mediaNode
107+ } else if ( stmt . media . length ) {
108+ const mediaNode = atRule ( {
109+ name : "media" ,
110+ params : stmt . media . join ( ", " ) ,
111+ source : parent . source ,
112+ } )
113+
114+ innerAtRule = mediaNode
115+ outerAtRule = mediaNode
116+ } else if ( stmt . layer . length ) {
117+ const layerNode = atRule ( {
118+ name : "layer" ,
119+ params : stmt . layer . filter ( layer => layer !== "" ) . join ( "." ) ,
120+ source : parent . source ,
121+ } )
122+
123+ innerAtRule = layerNode
124+ outerAtRule = layerNode
125+ }
126+
127+ parent . insertBefore ( nodes [ 0 ] , outerAtRule )
86128
87129 // remove nodes
88130 nodes . forEach ( node => {
@@ -92,11 +134,11 @@ function AtImport(options) {
92134 // better output
93135 nodes [ 0 ] . raws . before = nodes [ 0 ] . raws . before || "\n"
94136
95- // wrap new rules with media query
96- mediaNode . append ( nodes )
137+ // wrap new rules with media query and/or layer at rule
138+ innerAtRule . append ( nodes )
97139
98140 stmt . type = "media"
99- stmt . node = mediaNode
141+ stmt . node = outerAtRule
100142 delete stmt . nodes
101143 }
102144 } )
@@ -119,7 +161,7 @@ function AtImport(options) {
119161 } )
120162 }
121163
122- function parseStyles ( result , styles , options , state , media ) {
164+ function parseStyles ( result , styles , options , state , media , layer ) {
123165 const statements = parseStatements ( result , styles )
124166
125167 return Promise . resolve ( statements )
@@ -128,6 +170,7 @@ function AtImport(options) {
128170 return stmts . reduce ( ( promise , stmt ) => {
129171 return promise . then ( ( ) => {
130172 stmt . media = joinMedia ( media , stmt . media || [ ] )
173+ stmt . layer = joinLayer ( layer , stmt . layer || [ ] )
131174
132175 // skip protocol base uri (protocol://url) or protocol-relative
133176 if (
@@ -239,7 +282,7 @@ function AtImport(options) {
239282
240283 function loadImportContent ( result , stmt , filename , options , state ) {
241284 const atRule = stmt . node
242- const { media } = stmt
285+ const { media, layer } = stmt
243286 if ( options . skipDuplicates ) {
244287 // skip files already imported at the same scope
245288 if (
@@ -287,7 +330,7 @@ function AtImport(options) {
287330 }
288331
289332 // recursion: import @import from imported file
290- return parseStyles ( result , styles , options , state , media )
333+ return parseStyles ( result , styles , options , state , media , layer )
291334 } )
292335 }
293336 )
0 commit comments