File
-
advagg_css_compress/
css-compressor-3.x/ src/ lib/ Compress.inc
View source
<?php
/**
* CSS Compressor [VERSION]
* [DATE]
* Corey Hart @ http://www.codenothing.com
*/
class CSSCompression_Compress {
/**
* Trim Patterns
*
* @param (array) options: Reference to options
* @param (array) stats: Reference to stats
* @param (regex) rsemicolon: Checks for semicolon without an escape '\' character before it
* @param (regex) rcolon: Checks for colon without an escape '\' character before it
* @param (regex) rspace: Checks for space without an escape '\' character before it
*/
private $options = array();
private $stats = array();
private $rsemicolon = "/(?<!\\\\);/";
private $rcolon = "/(?<!\\\\):/";
private $rspace = "/(?<!\\\\)\\s/";
/**
* Other inner classes that get used within compression
*
* @class Control: Compression Controller
* @class Trim: Trim Instance
* @class Setup: Setup Instance
* @class Format: Formatting Instance
* @class Combine: Combine Instance
* @class Cleanup: Cleanup Instance
* @class Organize: Organize Instance
* @class Selectors: Selectors Instance
* @param (array) others: List of above classes for copying
*/
private $Control;
private $Trim;
private $Setup;
private $Format;
private $Combine;
private $Cleanup;
private $Organize;
private $Selectors;
private $others = array(
'Trim',
'Setup',
'Format',
'Combine',
'Cleanup',
'Organize',
'Selectors',
);
/**
* Stash a reference to the controller on each instantiation
*
* @param (class) control: CSSCompression Controller
*/
public function __construct(CSSCompression_Control $control) {
$this->Control = $control;
$this->options =& $control->Option->options;
$this->stats =& $control->stats;
foreach ($this->others as $class) {
$this->{$class} = $control->{$class};
}
}
/**
* Centralized function to run css compression.
*
* @param (string) css: Stylesheet to compresss
*/
public function compress($css) {
$setup = $this->setup($css);
$setup = $this->rulesets($setup);
$css = $this->readability($setup);
// Attach plea to top of page with unknown blocks
if ($this->options['add-unknown'] && count($setup['unknown'])) {
$css = "/*\nThere are unknown blocks in the sheet, please please please open an issue with your sheet attached to it:\n" . "https://github.com/codenothing/css-compressor/issues\n" . "Thank You --\n\n" . implode("\n", $setup['unknown']) . "\n*/\n" . $css;
}
// Mark final file size
$this->stats['after']['size'] = strlen($css = trim($css));
// Return compressed css
return $css;
}
/**
* Runs css through initial setup handlers
*
* @param (string) css: Sheet to compress
*/
private function setup($css) {
// Initial stats
$this->stats['before']['time'] = microtime(true);
$this->stats['before']['size'] = strlen($css);
// Initial trimming
$css = $this->Trim
->trim($css);
// Do a little tokenizing, compress each property individually
$setup = $this->Setup
->setup($css);
// Mark number of selectors pre-combine
$this->stats['before']['selectors'] = count($setup['selectors']);
return $setup;
}
/**
* Focus compressions on each rule set
*
* @param (array) setup: Array containing selectors and rule sets
*/
private function rulesets($setup) {
// Do selector specific compressions
$this->Selectors
->selectors($setup['selectors']);
// Look at each group of properties as a whole, and compress/combine similiar definitions
$this->Combine
->combine($setup['selectors'], $setup['details']);
// If order isn't important, run comination functions before and after compressions to catch all instances
// Be sure to prune before hand for higher chance of matching
if ($this->options['organize']) {
$this->Cleanup
->cleanup($setup['selectors'], $setup['details']);
$this->Organize
->organize($setup['selectors'], $setup['details']);
$this->Combine
->combine($setup['selectors'], $setup['details']);
}
// Do final maintenace work, remove injected property/values
$this->Cleanup
->cleanup($setup['selectors'], $setup['details']);
// Run final counters before full cleanup
$this->finalCount($setup['selectors'], $setup['details']);
return $setup;
}
/**
* Runs final counts on selectors and props
*
* @param (array) selectors: Selector rules
* @param (array) details: Rule sets
*/
private function finalCount($selectors, $details) {
// Selectors and props
$this->stats['after']['selectors'] = count($selectors);
foreach ($details as $item) {
$props = preg_split($this->rsemicolon, $item);
// Make sure count is true
foreach ($props as $k => $v) {
if (!isset($v) || $v == '') {
unset($props[$k]);
}
}
$this->stats['after']['props'] += count($props);
}
// Final count for stats
$this->stats['after']['time'] = microtime(true);
}
/**
* Formats the compressed rule sets into a stylesheet
*
* @param (array) setup: Array containing selectors and rule sets
*/
private function readability($setup) {
// Format css to users preference
$css = $this->Format
->readability($this->options['readability'], $setup['selectors'], $setup['details']);
// Intros
foreach ($setup as $value) {
if ($value && is_string($value)) {
$css = $value . $css;
}
}
// Remove escapables
$css = $this->Cleanup
->removeInjections($css);
return $css;
}
/**
* Access to private methods for testing
*
* @param (string) method: Method to be called
* @param (array) args: Array of paramters to be passed in
*/
public function access($method, $args) {
if (method_exists($this, $method)) {
return call_user_func_array(array(
$this,
$method,
), $args);
}
else {
throw new CSSCompression_Exception("Unknown method in Compress Class - " . $method);
}
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
CSSCompression_Compress | CSS Compressor [VERSION] [DATE] Corey Hart @ http://www.codenothing.com |