private function _prefix_keyframe(css_group $keyframe, $apply_list) { $prefixes = array(3 => "@-ms-keyframes", 2 => "@-o-keyframes", 0 => "@-moz-keyframes", 1 => "@-webkit-keyframes"); foreach ($prefixes as $id => $value) { if (isset($apply_list[$id]) && $apply_list[$id]) { $new_name = str_replace('@keyframes', $prefixes[$id], $keyframe->name); //Check if keyframe with prefix exists $found = false; foreach ($keyframe->siblings('css_group') as $sibling) { if ($sibling->name == $new_name) { $found = true; } } if (!$found) { //Create new keyframe only with prefix for the current vendor $new_keyframe = $keyframe->make_clone(); $new_keyframe->name = $new_name; $keyframe->insert_after($new_keyframe); $this->_add_prefixes($new_keyframe, array($id => true), true, true); } } } }
/** * Clean a CSS file * * @param css_group $css_doc CSS file to clean * * @return css_group */ public function clean(css_group $css_doc) { //Find tokens $project_tokens = $this->_find_tokens(); //Clean selectors $removed = 0; $selector_usage = array(); foreach ($css_doc->find_all('css_group') as $group) { /* @var $group css_group */ if (!$group->name || stripos($group->name, '@') !== false) { continue; //Ignore @media, @keyframes and future especial groups } $current_selectors = $group->selectors(); $valid_selectors = array(); foreach ($current_selectors as $selector) { $include = true; //Remove pseudo-class $clean_selector = preg_replace('/\\:.*/', '', $selector); //Look for selector tokens in the token list foreach ($this->_get_tokens($clean_selector) as $token) { if (!isset($project_tokens[$token])) { //Remove current selector $include = false; } } if ($include) { $valid_selectors[] = $selector; if ($this->report_path) { $count = 0; foreach ($this->_get_tokens($clean_selector) as $token) { $count += $project_tokens[$token]; } $selector_usage[$clean_selector] = isset($selector_usage[$clean_selector]) ? $selector_usage[$clean_selector] + $count : $count; } } } //Set cleaned selectors, or remove entire group if empty if (empty($valid_selectors)) { $group->remove(); } else { $group->selectors($valid_selectors); } if ($this->verbose) { $dif = array_diff($current_selectors, $valid_selectors); if (!empty($dif)) { $removed += count($dif); $dif = implode(', ', $dif); echo "Removed {$dif}\n"; } } } //Create report if ($this->report_path) { asort($selector_usage); $lines = array('Selector usage report. Generated on ' . date('r'), ''); foreach ($selector_usage as $selector => $freq) { $lines[] = "{$selector} found {$freq} references"; } file_put_contents($this->report_path, implode(PHP_EOL, $lines)); } if ($this->verbose) { echo "\nClean done, removed {$removed} unused selectors\n"; } return $css_doc; }
/** * @see http://net.tutsplus.com/tutorials/html-css-techniques/quick-tip-how-to-target-ie6-ie7-and-ie8-uniquely-with-4-characters/ */ protected function _remove_ie_hacks(css_group $document) { foreach ($document->find_all('css_property') as $property) { $is_hack = in_array($property->name, array('filter', '-ms-filter')) || in_array($property->name[0], array('*', '_')) || stripos($property->value, 'expression') === 0 || substr($property->value, -2) === '\\9'; //IE8 Hack if ($is_hack) { $property->remove(); } } }