@@ -15,6 +15,7 @@ CSSOM.parse = function parse(token) {
1515 "selector" or
1616 "atRule" or
1717 "atBlock" or
18+ "conditionBlock" or
1819 "before-name" or
1920 "name" or
2021 "before-value" or
@@ -34,18 +35,23 @@ CSSOM.parse = function parse(token) {
3435 "importRule-begin" : true ,
3536 "importRule" : true ,
3637 "atBlock" : true ,
38+ "conditionBlock" : true ,
3739 'documentRule-begin' : true
3840 } ;
3941
4042 var styleSheet = new CSSOM . CSSStyleSheet ( ) ;
4143
42- // @type CSSStyleSheet|CSSMediaRule|CSSFontFaceRule|CSSKeyframesRule|CSSDocumentRule
44+ // @type CSSStyleSheet|CSSMediaRule|CSSSupportsRule| CSSFontFaceRule|CSSKeyframesRule|CSSDocumentRule
4345 var currentScope = styleSheet ;
4446
45- // @type CSSMediaRule|CSSKeyframesRule|CSSDocumentRule
47+ // @type CSSMediaRule|CSSSupportsRule| CSSKeyframesRule|CSSDocumentRule
4648 var parentRule ;
4749
48- var name , priority = "" , styleRule , mediaRule , importRule , fontFaceRule , keyframesRule , documentRule , hostRule ;
50+ var ancestorRules = [ ] ;
51+ var hasAncestors = false ;
52+ var prevScope ;
53+
54+ var name , priority = "" , styleRule , mediaRule , supportsRule , importRule , fontFaceRule , keyframesRule , documentRule , hostRule ;
4955
5056 var atKeyframesRegExp = / @ ( - (?: \w + - ) + ) ? k e y f r a m e s / g;
5157
@@ -151,6 +157,13 @@ CSSOM.parse = function parse(token) {
151157 i += "media" . length ;
152158 buffer = "" ;
153159 break ;
160+ } else if ( token . indexOf ( "@supports" , i ) === i ) {
161+ state = "conditionBlock" ;
162+ supportsRule = new CSSOM . CSSSupportsRule ( ) ;
163+ supportsRule . __starts = i ;
164+ i += "supports" . length ;
165+ buffer = "" ;
166+ break ;
154167 } else if ( token . indexOf ( "@host" , i ) === i ) {
155168 state = "hostRule-begin" ;
156169 i += "host" . length ;
@@ -196,17 +209,38 @@ CSSOM.parse = function parse(token) {
196209 state = "before-name" ;
197210 } else if ( state === "atBlock" ) {
198211 mediaRule . media . mediaText = buffer . trim ( ) ;
212+
213+ if ( parentRule ) {
214+ ancestorRules . push ( parentRule ) ;
215+ }
216+
199217 currentScope = parentRule = mediaRule ;
200218 mediaRule . parentStyleSheet = styleSheet ;
201219 buffer = "" ;
202220 state = "before-selector" ;
221+ } else if ( state === "conditionBlock" ) {
222+ supportsRule . conditionText = buffer . trim ( ) ;
223+
224+ if ( parentRule ) {
225+ ancestorRules . push ( parentRule ) ;
226+ }
227+
228+ currentScope = parentRule = supportsRule ;
229+ supportsRule . parentStyleSheet = styleSheet ;
230+ buffer = "" ;
231+ state = "before-selector" ;
203232 } else if ( state === "hostRule-begin" ) {
233+ if ( parentRule ) {
234+ ancestorRules . push ( parentRule ) ;
235+ }
236+
204237 currentScope = parentRule = hostRule ;
205238 hostRule . parentStyleSheet = styleSheet ;
206239 buffer = "" ;
207240 state = "before-selector" ;
208241 } else if ( state === "fontFaceRule-begin" ) {
209242 if ( parentRule ) {
243+ ancestorRules . push ( parentRule ) ;
210244 fontFaceRule . parentRule = parentRule ;
211245 }
212246 fontFaceRule . parentStyleSheet = styleSheet ;
@@ -216,6 +250,7 @@ CSSOM.parse = function parse(token) {
216250 } else if ( state === "keyframesRule-begin" ) {
217251 keyframesRule . name = buffer . trim ( ) ;
218252 if ( parentRule ) {
253+ ancestorRules . push ( parentRule ) ;
219254 keyframesRule . parentRule = parentRule ;
220255 }
221256 keyframesRule . parentStyleSheet = styleSheet ;
@@ -232,6 +267,7 @@ CSSOM.parse = function parse(token) {
232267 // FIXME: what if this '{' is in the url text of the match function?
233268 documentRule . matcher . matcherText = buffer . trim ( ) ;
234269 if ( parentRule ) {
270+ ancestorRules . push ( parentRule ) ;
235271 documentRule . parentRule = parentRule ;
236272 }
237273 currentScope = parentRule = documentRule ;
@@ -345,15 +381,39 @@ CSSOM.parse = function parse(token) {
345381 case "keyframeRule-begin" :
346382 case "before-selector" :
347383 case "selector" :
348- // End of media/document rule.
384+ // End of media/supports/ document rule.
349385 if ( ! parentRule ) {
350386 parseError ( "Unexpected }" ) ;
351387 }
352- currentScope . __ends = i + 1 ;
353- // Nesting rules aren't supported yet
354- styleSheet . cssRules . push ( currentScope ) ;
355- currentScope = styleSheet ;
356- parentRule = null ;
388+
389+ // Handle rules nested in @media or @supports
390+ hasAncestors = ancestorRules . length > 0 ;
391+
392+ while ( ancestorRules . length > 0 ) {
393+ parentRule = ancestorRules . pop ( ) ;
394+
395+ if (
396+ parentRule . constructor . name === "CSSMediaRule"
397+ || parentRule . constructor . name === "CSSSupportsRule"
398+ ) {
399+ prevScope = currentScope ;
400+ currentScope = parentRule ;
401+ currentScope . cssRules . push ( prevScope ) ;
402+ break ;
403+ }
404+
405+ if ( ancestorRules . length === 0 ) {
406+ hasAncestors = false ;
407+ }
408+ }
409+
410+ if ( ! hasAncestors ) {
411+ currentScope . __ends = i + 1 ;
412+ styleSheet . cssRules . push ( currentScope ) ;
413+ currentScope = styleSheet ;
414+ parentRule = null ;
415+ }
416+
357417 buffer = "" ;
358418 state = "before-selector" ;
359419 break ;
@@ -393,6 +453,7 @@ CSSOM.CSSStyleSheet = require("./CSSStyleSheet").CSSStyleSheet;
393453CSSOM . CSSStyleRule = require ( "./CSSStyleRule" ) . CSSStyleRule ;
394454CSSOM . CSSImportRule = require ( "./CSSImportRule" ) . CSSImportRule ;
395455CSSOM . CSSMediaRule = require ( "./CSSMediaRule" ) . CSSMediaRule ;
456+ CSSOM . CSSSupportsRule = require ( "./CSSSupportsRule" ) . CSSSupportsRule ;
396457CSSOM . CSSFontFaceRule = require ( "./CSSFontFaceRule" ) . CSSFontFaceRule ;
397458CSSOM . CSSHostRule = require ( "./CSSHostRule" ) . CSSHostRule ;
398459CSSOM . CSSStyleDeclaration = require ( './CSSStyleDeclaration' ) . CSSStyleDeclaration ;
0 commit comments