You are here

public function CSSmin::run in Advanced CSS/JS Aggregation 7.2

Same name and namespace in other branches
  1. 8.2 advagg_css_minify/yui/CSSMin.inc \CSSmin::run()
  2. 8.3 advagg_css_minify/yui/CSSMin.inc \CSSmin::run()
  3. 6 advagg_css_compress/yui/CSSMin.inc \CSSmin::run()

Minifies a string of CSS

Parameters

string $css:

int|bool $linebreakPos:

Return value

string

File

advagg_css_compress/yui/CSSMin.inc, line 81

Class

CSSmin

Code

public function run($css = '', $linebreakPos = false) {
  if (empty($css)) {
    return '';
  }
  if ($this->raisePhpLimits) {
    $this
      ->doRaisePhpLimits();
  }
  $this->comments = array();
  $this->atRuleBlocks = array();
  $this->preservedTokens = array();

  // process data urls
  $css = $this
    ->processDataUrls($css);

  // process comments
  $css = preg_replace_callback('/(?<!\\\\)\\/\\*(.*?)\\*(?<!\\\\)\\//Ss', array(
    $this,
    'processComments',
  ), $css);

  // process strings so their content doesn't get accidentally minified
  $css = preg_replace_callback('/(?:"(?:[^\\\\"]|\\\\.|\\\\)*")|' . "(?:'(?:[^\\\\']|\\\\.|\\\\)*')/S", array(
    $this,
    'processStrings',
  ), $css);

  // Safe chunking: process at rule blocks so after chunking nothing gets stripped out
  $css = preg_replace_callback('/@(?:document|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?keyframes|media|supports).+?\\}\\s*\\}/si', array(
    $this,
    'processAtRuleBlocks',
  ), $css);

  // Let's divide css code in chunks of {$this->chunkLength} chars aprox.
  // Reason: PHP's PCRE functions like preg_replace have a "backtrack limit"
  // of 100.000 chars by default (php < 5.3.7) so if we're dealing with really
  // long strings and a (sub)pattern matches a number of chars greater than
  // the backtrack limit number (i.e. /(.*)/s) PCRE functions may fail silently
  // returning NULL and $css would be empty.
  $charset = '';
  $charsetRegexp = '/(@charset)( [^;]+;)/i';
  $cssChunks = array();
  $l = strlen($css);

  // if the number of characters is <= {$this->chunkLength}, do not chunk
  if ($l <= $this->chunkLength) {
    $cssChunks[] = $css;
  }
  else {

    // chunk css code securely
    for ($startIndex = 0, $i = $this->chunkLength; $i < $l; $i++) {
      if ($css[$i - 1] === '}' && $i - $startIndex >= $this->chunkLength) {
        $cssChunks[] = $this
          ->strSlice($css, $startIndex, $i);
        $startIndex = $i;

        // Move forward saving iterations when possible!
        if ($startIndex + $this->chunkLength < $l) {
          $i += $this->chunkLength;
        }
      }
    }

    // Final chunk
    $cssChunks[] = $this
      ->strSlice($css, $startIndex);
  }

  // Minify each chunk
  for ($i = 0, $n = count($cssChunks); $i < $n; $i++) {
    $cssChunks[$i] = $this
      ->minify($cssChunks[$i], $linebreakPos);

    // Keep the first @charset at-rule found
    if (empty($charset) && preg_match($charsetRegexp, $cssChunks[$i], $matches)) {
      $charset = strtolower($matches[1]) . $matches[2];
    }

    // Delete all @charset at-rules
    $cssChunks[$i] = preg_replace($charsetRegexp, '', $cssChunks[$i]);
  }

  // Update the first chunk and push the charset to the top of the file.
  $cssChunks[0] = $charset . $cssChunks[0];
  return trim(implode('', $cssChunks));
}