@@ -123,26 +123,28 @@ class _CssShim {
123123 List <_Rule > cssToRules (String css) =>
124124 new _Parser (css).parse ();
125125
126- String scopeRules (List <_Rule > rules) {
127- final scopedRules = [];
126+ String scopeRules (List <_Rule > rules, {bool emitMode: false }) {
127+ if (emitMode) {
128+ return rules.map (ruleToString).join ("\n " );
129+ }
128130
131+ final scopedRules = [];
129132 var prevRule;
130133 rules.forEach ((rule) {
131134 if (prevRule != null && prevRule.selectorText == POLYFILL_NON_STRICT ) {
132- scopedRules.add (scopeNonStrictMode (rule));
133-
135+ scopedRules.add (scopeNonStrictMode (rule, emitMode));
134136 } else if (prevRule != null && prevRule.selectorText == POLYFILL_UNSCOPED_NEXT_SELECTOR ) {
135137 final content = extractContent (prevRule);
136138 scopedRules.add (ruleToString (new _Rule (content, body: rule.body)));
137139
138140 } else if (prevRule != null && prevRule.selectorText == POLYFILL_NEXT_SELECTOR ) {
139141 final content = extractContent (prevRule);
140- scopedRules.add (scopeStrictMode (new _Rule (content, body: rule.body)));
142+ scopedRules.add (scopeStrictMode (new _Rule (content, body: rule.body), false ));
141143
142144 } else if (rule.selectorText != POLYFILL_NON_STRICT &&
143145 rule.selectorText != POLYFILL_UNSCOPED_NEXT_SELECTOR &&
144146 rule.selectorText != POLYFILL_NEXT_SELECTOR ) {
145- scopedRules.add (scopeStrictMode (rule));
147+ scopedRules.add (scopeStrictMode (rule, false ));
146148 }
147149
148150 prevRule = rule;
@@ -159,19 +161,22 @@ class _CssShim {
159161 return "${rule .selectorText } ${rule .body }" ;
160162 }
161163
162- String scopeStrictMode (_Rule rule) {
164+ String scopeStrictMode (_Rule rule, bool emitMode ) {
163165 if (rule.hasNestedRules) {
164- final selector = rule.selectorText;
165- final rules = scopeRules (rule.rules);
166- return '$selector {\n $rules \n }' ;
166+ final rules = scopeRules (rule.rules, emitMode: rule.selectorText.contains ("keyframes" ));
167+ return "${rule .selectorText } {\n $rules \n }" ;
167168 } else {
168169 final scopedSelector = scopeSelector (rule.selectorText, strict: true );
169170 final scopedBody = cssText (rule);
170171 return "$scopedSelector $scopedBody " ;
171172 }
172173 }
173174
174- String scopeNonStrictMode (_Rule rule) {
175+ String scopeNonStrictMode (_Rule rule, bool emitMode) {
176+ if (rule.hasNestedRules && rule.selectorText == "keyframes" ) {
177+ final rules = scopeRules (rule.rules, emitMode: true );
178+ return '${rule .selectorText } {\n $rules \n }' ;
179+ }
175180 final scopedBody = cssText (rule);
176181 final scopedSelector = scopeSelector (rule.selectorText, strict: false );
177182 return "${scopedSelector } $scopedBody " ;
@@ -281,7 +286,7 @@ class _Lexer {
281286 advance ();
282287 return new _Token ("}" , "rparen" );
283288 }
284- if (isMedia (peek)) return scanMedia ();
289+ if (isDeclaration (peek)) return scanDeclaration ();
285290 if (isSelector (peek)) return scanSelector ();
286291 if (isBodyStart (peek)) return scanBody ();
287292
@@ -291,7 +296,7 @@ class _Lexer {
291296 bool isSelector (int v) => ! isBodyStart (v) && v != $EOF ;
292297 bool isBodyStart (int v) => v == $LBRACE ;
293298 bool isBodyEnd (int v) => v == $RBRACE ;
294- bool isMedia (int v) => v == 64 ; //@ = 64
299+ bool isDeclaration (int v) => v == 64 ; //@ = 64
295300
296301 void skipWhitespace () {
297302 while (isWhitespace (peek)) {
@@ -321,7 +326,7 @@ class _Lexer {
321326 return new _Token (string, "body" );
322327 }
323328
324- _Token scanMedia () {
329+ _Token scanDeclaration () {
325330 int start = index;
326331 advance ();
327332
@@ -330,7 +335,10 @@ class _Lexer {
330335
331336 advance (); //skip {
332337
333- return new _Token (string, "media" );
338+ // we assume that declaration cannot start with media and contain keyframes.
339+ String type = string.contains ("keyframes" ) ? "keyframes" :
340+ (string.startsWith ("@media" ) ? "media" : string);
341+ return new _Token (string, type);
334342 }
335343
336344 void advance () {
@@ -370,8 +378,8 @@ class _Parser {
370378
371379 _Rule parseRule () {
372380 try {
373- if (next.type == "media" ) {
374- return parseMedia ();
381+ if (next.type == "media" || next.type == "keyframes" ) {
382+ return parseMedia (next.type );
375383 } else {
376384 return parseCssRule ();
377385 }
@@ -380,8 +388,8 @@ class _Parser {
380388 }
381389 }
382390
383- _Rule parseMedia () {
384- advance ("media" );
391+ _Rule parseMedia (type ) {
392+ advance (type );
385393 final media = current.string;
386394
387395 final rules = [];
0 commit comments