@@ -2,6 +2,33 @@ var postcss = require("postcss")
22
33var EXTENSION_RE = / \( \s * ( - - [ \w - ] + ) \s * \) / g
44
5+ /*
6+ * Resolve custom media values.
7+ */
8+ function resolveValue ( value , map , result ) {
9+ if ( ! EXTENSION_RE . test ( value ) ) {
10+ return value
11+ }
12+ return value . replace ( EXTENSION_RE , function ( orig , name ) {
13+ if ( ! map [ name ] ) {
14+ return orig
15+ }
16+
17+ var mq = map [ name ]
18+ if ( mq . resolved ) {
19+ return mq . value
20+ }
21+
22+ if ( mq . deps . indexOf ( name ) !== - 1 ) {
23+ mq . circular = true
24+ return orig
25+ }
26+ mq . deps . push ( name )
27+ mq . value = resolveValue ( mq . value , map , result )
28+ return mq . value
29+ } )
30+ }
31+
532/*
633 * read & replace custom media queries by standard media queries
734 */
@@ -32,7 +59,12 @@ function customMedia(options) {
3259 var params = rule . params . split ( " " )
3360 // @custom -media <extension-name> <media-query-list>;
3461 // map[<extension-name>] = <media-query-list>
35- map [ params . shift ( ) ] = params . join ( " " )
62+ map [ params . shift ( ) ] = {
63+ value : params . join ( " " ) ,
64+ deps : [ ] ,
65+ circular : false ,
66+ resolved : false ,
67+ }
3668
3769 if ( ! preserve ) {
3870 toRemove . push ( rule )
@@ -41,7 +73,17 @@ function customMedia(options) {
4173
4274 // apply js-defined media queries
4375 Object . keys ( extensions ) . forEach ( function ( name ) {
44- map [ name ] = extensions [ name ]
76+ map [ name ] = {
77+ value : extensions [ name ] ,
78+ deps : [ ] ,
79+ circular : false ,
80+ resolved : false ,
81+ }
82+ } )
83+
84+ Object . keys ( map ) . forEach ( function ( name ) {
85+ map [ name ] . value = resolveValue ( map [ name ] . value , map , result )
86+ map [ name ] . resolved = true
4587 } )
4688
4789 // transform custom media query aliases
@@ -52,7 +94,15 @@ function customMedia(options) {
5294
5395 rule . params = rule . params . replace ( EXTENSION_RE , function ( _ , name ) {
5496 if ( map [ name ] ) {
55- return map [ name ]
97+ if ( map [ name ] . circular ) {
98+ result . warn (
99+ "Circular @custom-media definition for '" + name +
100+ "'. The entire rule has been removed from the output." ,
101+ { node : rule }
102+ )
103+ toRemove . push ( rule )
104+ }
105+ return map [ name ] . value
56106 }
57107
58108 result . warn (
@@ -68,10 +118,13 @@ function customMedia(options) {
68118 var names = Object . keys ( map )
69119 if ( names . length ) {
70120 names . forEach ( function ( name ) {
121+ if ( map [ name ] . circular ) {
122+ return
123+ }
71124 var atRule = postcss . atRule ( {
72125 name : "custom-media" ,
73126 afterName : " " ,
74- params : name + " " + map [ name ] ,
127+ params : name + " " + map [ name ] . value ,
75128 } )
76129 styles . append ( atRule )
77130 } )
0 commit comments