@@ -530,6 +530,34 @@ protected function mediaParent($scope)
530530 return $ scope ;
531531 }
532532
533+ /**
534+ * Compile keyframe block
535+ *
536+ * @param \stdClass $block
537+ * @param array $selectors
538+ */
539+ protected function compileKeyframeBlock ($ block , $ selectors )
540+ {
541+ $ env = $ this ->pushEnv ($ block );
542+
543+ $ envs = $ this ->compactEnv ($ env );
544+
545+ $ this ->env = $ this ->extractEnv (array_filter ($ envs , function ($ e ) {
546+ return ! isset ($ e ->block ->selectors );
547+ }));
548+
549+ $ this ->scope = $ this ->makeOutputBlock ($ block ->type , $ selectors );
550+ $ this ->scope ->depth = 1 ;
551+ $ this ->scope ->parent ->children [] = $ this ->scope ;
552+
553+ $ this ->compileChildren ($ block ->children , $ this ->scope );
554+
555+ $ this ->scope = $ this ->scope ->parent ;
556+ $ this ->env = $ this ->extractEnv ($ envs );
557+
558+ $ this ->popEnv ();
559+ }
560+
533561 /**
534562 * Compile nested block
535563 *
@@ -1049,7 +1077,11 @@ protected function compileChild($child, $out)
10491077 $ s .= ' ' . $ this ->compileValue ($ directive ->value );
10501078 }
10511079
1052- $ this ->compileNestedBlock ($ directive , array ($ s ));
1080+ if ($ directive ->name === 'keyframes ' || substr ($ directive ->name , -10 ) === '-keyframes ' ) {
1081+ $ this ->compileKeyframeBlock ($ directive , array ($ s ));
1082+ } else {
1083+ $ this ->compileNestedBlock ($ directive , array ($ s ));
1084+ }
10531085 break ;
10541086
10551087 case 'media ' :
@@ -2245,7 +2277,7 @@ protected function extractInterpolation($list)
22452277 foreach ($ items as $ i => $ item ) {
22462278 if ($ item [0 ] === 'interpolate ' ) {
22472279 $ before = array ('list ' , $ list [1 ], array_slice ($ items , 0 , $ i ));
2248- $ after = array ('list ' , $ list [1 ], array_slice ($ items , $ i + 1 ));
2280+ $ after = array ('list ' , $ list [1 ], array_slice ($ items , $ i + 1 ));
22492281
22502282 return array ('interpolated ' , $ item , $ before , $ after );
22512283 }
@@ -2263,16 +2295,15 @@ protected function extractInterpolation($list)
22632295 */
22642296 protected function multiplySelectors ($ env )
22652297 {
2266- for ($ envs = array (); $ env ; $ env = $ env ->parent ) {
2267- if (count ($ env ->selectors )) {
2268- $ envs [] = $ env ;
2269- }
2270- }
2271-
2272- $ selectors = array ();
2298+ $ envs = $ this ->compactEnv ($ env );
2299+ $ selectors = array ();
22732300 $ parentSelectors = array (array ());
22742301
22752302 while ($ env = array_pop ($ envs )) {
2303+ if (empty ($ env ->selectors )) {
2304+ continue ;
2305+ }
2306+
22762307 $ selectors = array ();
22772308
22782309 foreach ($ env ->selectors as $ selector ) {
@@ -2366,6 +2397,39 @@ protected function multiplyMedia($env, $childQueries = null)
23662397 return $ this ->multiplyMedia ($ env ->parent , $ childQueries );
23672398 }
23682399
2400+ /**
2401+ * Convert env linked list to stack
2402+ *
2403+ * @param \stdClass $env
2404+ *
2405+ * @return array
2406+ */
2407+ private function compactEnv ($ env )
2408+ {
2409+ for ($ envs = array (); $ env ; $ env = $ env ->parent ) {
2410+ $ envs [] = $ env ;
2411+ }
2412+
2413+ return $ envs ;
2414+ }
2415+
2416+ /**
2417+ * Convert env stack to singly linked list
2418+ *
2419+ * @param array $envs
2420+ *
2421+ * @return \stdClass
2422+ */
2423+ private function extractEnv ($ envs )
2424+ {
2425+ for ($ env = null ; $ e = array_pop ($ envs );) {
2426+ $ e ->parent = $ env ;
2427+ $ env = $ e ;
2428+ }
2429+
2430+ return $ env ;
2431+ }
2432+
23692433 /**
23702434 * Push environment
23712435 *
0 commit comments