diff --git a/lib/csslib.php b/lib/csslib.php index 27e24c7013e..6ab108a478c 100644 --- a/lib/csslib.php +++ b/lib/csslib.php @@ -566,14 +566,17 @@ class css_optimiser { $currentprocess = self::PROCESSING_SELECTORS; } } - $buffer = ''; - $currentatrule = false; + if ($currentatrule !== 'media') { + $buffer = ''; + $currentatrule = false; + } // continue 1: The switch processing chars // continue 2: The switch processing the state // continue 3: The for loop continue 3; case '{': - if ($currentatrule == 'media' && preg_match('#\s*@media\s*([a-zA-Z0-9]+(\s*,\s*[a-zA-Z0-9]+)*)#', $buffer, $matches)) { + if ($currentatrule == 'media' && preg_match('#\s*@media\s*([a-zA-Z0-9]+(\s*,\s*[a-zA-Z0-9]+)*)\s*{#', $buffer, $matches)) { + // Basic media declaration $mediatypes = str_replace(' ', '', $matches[1]); if (!array_key_exists($mediatypes, $medias)) { $medias[$mediatypes] = new css_media($mediatypes); @@ -581,6 +584,14 @@ class css_optimiser { $currentmedia = $medias[$mediatypes]; $currentprocess = self::PROCESSING_SELECTORS; $buffer = ''; + } else if ($currentatrule == 'media' && preg_match('#\s*@media\s*([^{]+)#', $buffer, $matches)) { + // Advanced media query declaration http://www.w3.org/TR/css3-mediaqueries/ + $mediatypes = $matches[1]; + $hash = md5($mediatypes); + $medias[$hash] = new css_media($mediatypes); + $currentmedia = $medias[$hash]; + $currentprocess = self::PROCESSING_SELECTORS; + $buffer = ''; } else if ($currentatrule == 'keyframes' && preg_match('#@((\-moz\-|\-webkit\-)?keyframes)\s*([^\s]+)#', $buffer, $matches)) { $keyframefor = $matches[1]; $keyframename = $matches[3]; diff --git a/lib/tests/cssslib_test.php b/lib/tests/cssslib_test.php index 278d2866d50..f73ba258012 100644 --- a/lib/tests/cssslib_test.php +++ b/lib/tests/cssslib_test.php @@ -72,6 +72,7 @@ class css_optimiser_testcase extends advanced_testcase { $this->try_invalid_css_handling($optimiser); $this->try_bulk_processing($optimiser); $this->try_break_things($optimiser); + $this->try_media_rules($optimiser); $this->try_keyframe_css_animation($optimiser); } @@ -994,6 +995,39 @@ CSS; @-webkit-keyframes mymove {0%{top:10px;}12%{top:40px;}30%{top:20px;}65%{top:35px;}100%{top:9px;}} CSS; $this->assertEquals($cssout, $optimiser->process($cssin)); + } + public function try_media_rules(css_optimiser $optimiser) { + $cssin = "@media print {\n .test{background-color:#333;}\n}"; + $cssout = "@media print {\n .test{background-color:#333;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = "@media screen and (min-width:30px) {\n #region-main-box{left: 30px;float: left;}\n}"; + $cssout = "@media screen and (min-width:30px) {\n #region-main-box{left:30px;float:left;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = "@media all and (min-width:500px) {\n #region-main-box{left:30px;float:left;}\n}"; + $cssout = "@media all and (min-width:500px) {\n #region-main-box{left:30px;float:left;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = "@media (min-width:500px) {\n #region-main-box{left:30px;float:left;}\n}"; + $cssout = "@media (min-width:500px) {\n #region-main-box{left:30px;float:left;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = "@media screen and (color), projection and (color) {\n #region-main-box{left:30px;float:left;}\n}"; + $cssout = "@media screen and (color),projection and (color) {\n #region-main-box{left:30px;float:left;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = "@media print {\n .test{background-color:#000;}\n}@media print {\n .test{background-color:#FFF;}\n}"; + $cssout = "@media print {\n .test{background-color:#FFF;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = "@media screen and (min-width:30px) {\n #region-main-box{background-color:#000;}\n}\n@media screen and (min-width:30px) {\n #region-main-box{background-color:#FFF;}\n}"; + $cssout = "@media screen and (min-width:30px) {\n #region-main-box{background-color:#FFF;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = "@media screen and (min-width:30px) {\n #region-main-box{background-color:#000;}\n}\n@media screen and (min-width:31px) {\n #region-main-box{background-color:#FFF;}\n}"; + $cssout = "@media screen and (min-width:30px) {\n #region-main-box{background-color:#000;}\n}\n\n@media screen and (min-width:31px) {\n #region-main-box{background-color:#FFF;}\n}"; + $this->assertEquals($cssout, $optimiser->process($cssin)); } } \ No newline at end of file