You are here

public function JSqueeze::squeeze in Advanced CSS/JS Aggregation 7.2

Same name and namespace in other branches
  1. 8.4 advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::squeeze()
  2. 8.2 advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::squeeze()
  3. 8.3 advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::squeeze()

Squeezes a JavaScript source code.

Set $singleLine to false if you want optional semi-colons to be replaced by line feeds.

Set $keepImportantComments to false if you want /*! comments to be removed.

$specialVarRx defines the regular expression of special variables names for global vars, methods, properties and in string substitution. Set it to false if you don't want any.

If the analysed javascript source contains a single line comment like this one, then the directive will overwrite $specialVarRx:

// jsqueeze.specialVarRx = your_special_var_regexp_here

Only the first directive is parsed, others are ignored. It is not possible to redefine $specialVarRx in the middle of the javascript source.

Example: $parser = new JSqueeze; $squeezed_js = $parser->squeeze($fat_js);

File

advagg_js_compress/jsqueeze.inc, line 129

Class

JSqueeze

Namespace

Patchwork

Code

public function squeeze($code, $singleLine = true, $keepImportantComments = true, $specialVarRx = false) {
  $code = trim($code);
  if ('' === $code) {
    return '';
  }
  $this->argFreq = array(
    -1 => 0,
  );
  $this->specialVarRx = $specialVarRx;
  $this->keepImportantComments = !!$keepImportantComments;
  if (preg_match("#//[ \t]*jsqueeze\\.specialVarRx[ \t]*=[ \t]*([\"']?)(.*)\\1#i", $code, $key)) {
    if (!$key[1]) {
      $key[2] = trim($key[2]);
      $key[1] = strtolower($key[2]);
      $key[1] = $key[1] && $key[1] != 'false' && $key[1] != 'none' && $key[1] != 'off';
    }
    $this->specialVarRx = $key[1] ? $key[2] : false;
  }

  // Remove capturing parentheses
  $this->specialVarRx && ($this->specialVarRx = preg_replace('/(?<!\\\\)((?:\\\\\\\\)*)\\((?!\\?)/', '(?:', $this->specialVarRx));
  false !== strpos($code, "\r") && ($code = strtr(str_replace("\r\n", "\n", $code), "\r", "\n"));
  false !== strpos($code, "…") && ($code = str_replace("…", "\n", $code));

  // Next Line
  false !== strpos($code, "
") && ($code = str_replace("
", "\n", $code));

  // Line Separator
  false !== strpos($code, "
") && ($code = str_replace("
", "\n", $code));

  // Paragraph Separator
  list($code, $this->strings) = $this
    ->extractStrings($code);
  list($code, $this->closures) = $this
    ->extractClosures($code);
  $key = "//''\"\"#0'";

  // This crap has a wonderful property: it can not happen in any valid javascript, even in strings
  $this->closures[$key] =& $code;
  $tree = array(
    $key => array(
      'parent' => false,
    ),
  );
  $this
    ->makeVars($code, $tree[$key], $key);
  $this
    ->renameVars($tree[$key], true);
  $code = substr($tree[$key]['code'], 1);
  $code = preg_replace("'\\breturn !'", 'return!', $code);
  $code = preg_replace("'\\}(?=(else|while)[^\$.a-zA-Z0-9_])'", "}\r", $code);

  // preg_replace is much more efficient than str_replace here
  // because we don't need to scan the entire code each time for every replacement
  $code = preg_replace_callback('#//\'\'""\\d++(?:/?+\'|\\])#', array(
    $this,
    'restoreString',
  ), $code);
  if ($singleLine) {
    $code = strtr($code, "\n", ';');
  }
  else {
    $code = str_replace("\n", ";\n", $code);
  }
  false !== strpos($code, "\r") && ($code = strtr(trim($code), "\r", "\n"));

  // Cleanup memory
  $this->charFreq = array_fill(0, 256, 0);
  $this->strings = $this->closures = $this->argFreq = array();
  $this->str0 = $this->str1 = '';
  return $code;
}