From 0663b5353cc88a94b1b927b6ea5b6aca727dcc35 Mon Sep 17 00:00:00 2001 From: Sam Hemelryk Date: Thu, 31 May 2012 16:41:20 +1200 Subject: [PATCH] MDL-33468 css_optimiser: Added support for prioritising reset rules --- lib/csslib.php | 69 ++++++++++++++++++++++++++++++++++++++++++++-- lib/tests/cssslib_test.php | 4 +++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/lib/csslib.php b/lib/csslib.php index 159b7188701..5118529707c 100644 --- a/lib/csslib.php +++ b/lib/csslib.php @@ -643,8 +643,9 @@ class css_optimiser { // continue 3: The for loop continue 3; } - - $currentselector->add($buffer); + if ($buffer !== '') { + $currentselector->add($buffer); + } $currentrule->add_selector($currentselector); $currentselector = css_selector::init(); $currentprocess = self::PROCESSING_STYLES; @@ -765,6 +766,7 @@ class css_optimiser { $css .= implode("\n", $imports); $css .= "\n\n"; } + foreach ($medias as $media) { $media->organise_rules_by_selectors(); $this->optimisedrules += $media->count_rules(); @@ -772,6 +774,15 @@ class css_optimiser { if ($media->has_errors()) { $this->errors += $media->get_errors(); } + if (in_array('all', $media->get_types())) { + $resetrules = $media->get_reset_rules(true); + if (!empty($resetrules)) { + $css .= css_writer::media('all', $resetrules); + } + } + } + + foreach ($medias as $media) { $css .= $media->out(); } @@ -1269,6 +1280,12 @@ class css_selector { protected $count = 0; /** + * Is null if there are no selector, true if all selectors are basic and false otherwise. + * @var bool|null + */ + protected $isbasic = null; + + /** * Initialises a new CSS selector * @return css_selector */ @@ -1292,6 +1309,13 @@ class css_selector { if (strpos($selector, '.') !== 0 && strpos($selector, '#') !== 0) { $count ++; } + if ($this->isbasic !== false) { + if ($count > 1) { + $this->isbasic = false; + } else { + $this->isbasic = (preg_match('#^[a-z]+(:[a-zA-Z]+)?$#', $selector))?true:false; + } + } $this->count = $count; $this->selectors[] = $selector; } @@ -1310,6 +1334,14 @@ class css_selector { public function out() { return css_writer::selector($this->selectors); } + + /** + * Returns true is all of the selectors act only upon basic elements (no classes/ids) + * @return bool + */ + public function is_basic() { + return ($this->isbasic === true); + } } /** @@ -1574,6 +1606,22 @@ class css_rule { } return $css." has the following errors:\n".join("\n", $errors); } + + /** + * Returns true if this rule could be considered a reset rule. + * + * A reset rule is a rule that acts upon an HTML element and does not include any other parts to its selector. + * + * @return bool + */ + public function is_reset_rule() { + foreach ($this->selectors as $selector) { + if (!$selector->is_basic()) { + return false; + } + } + return true; + } } abstract class css_rule_collection { @@ -1732,6 +1780,23 @@ class css_media extends css_rule_collection { public function get_types() { return $this->types; } + + /** + * Returns all of the reset rules known by this media set. + * @return array + */ + public function get_reset_rules($remove = false) { + $resetrules = array(); + foreach ($this->rules as $key => $rule) { + if ($rule->is_reset_rule()) { + $resetrules[] = clone $rule; + if ($remove) { + unset($this->rules[$key]); + } + } + } + return $resetrules; + } } /** diff --git a/lib/tests/cssslib_test.php b/lib/tests/cssslib_test.php index 5c6d90bec07..bc8024ffe74 100644 --- a/lib/tests/cssslib_test.php +++ b/lib/tests/cssslib_test.php @@ -132,6 +132,10 @@ class css_optimiser_testcase extends advanced_testcase { $cssin = '.test {background: #123456 url(data:image/gif;base64,AAAA) no-repeat top left;}'; $cssout = '.test{background:#123456 url(data:image/gif;base64,AAAA) no-repeat top left;}'; $this->assertEquals($cssout, $optimiser->process($cssin)); + + $cssin = '#custommenu {background-image:none;background-position:right center;background-repeat:no-repeat;};'; + $cssout = '#custommenu {background-image:none;background-position:right center;background-repeat:no-repeat;};'; + $this->assertEquals($cssout, $optimiser->process($cssin)); } /** -- 2.11.4.GIT