You are here

public function JsMinifier::minifyJsmin in Advanced CSS/JS Aggregation 8.3

Same name and namespace in other branches
  1. 8.4 advagg_js_minify/src/Asset/JsMinifier.php \Drupal\advagg_js_minify\Asset\JsMinifier::minifyJsmin()

Minify a JS string using jsmin.

Parameters

string $contents: JavaScript string.

string $path: The original file path.

File

advagg_js_minify/src/Asset/JsMinifier.php, line 125

Class

JsMinifier
Optimizes a JavaScript asset.

Namespace

Drupal\advagg_js_minify\Asset

Code

public function minifyJsmin(&$contents, $path) {

  // Do not use jsmin() if the function can not be called.
  if (!function_exists('jsmin')) {
    $this->logger
      ->notice($this
      ->t('The jsmin function does not exist. Using JSqueeze.'), []);
    $contents = $this
      ->minifyJsqueeze($contents);
    return;
  }

  // Jsmin doesn't handle multi-byte characters before version 2, fall back to
  // different minifier if jsmin version < 2 and $contents contains multi-
  // byte characters.
  if (version_compare(phpversion('jsmin'), '2.0.0', '<') && $this
    ->stringContainsMultibyteCharacters($contents)) {
    $this->logger
      ->notice('The currently installed jsmin version does not handle multibyte characters, you may consider to upgrade the jsmin extension. Using JSqueeze fallback.', []);
    $contents = $this
      ->minifyJsqueeze($contents);
    return;
  }

  // Jsmin may have errors (incorrectly determining EOLs) with mixed tabs
  // and spaces. An example: jQuery.Cycle 3.0.3 - http://jquery.malsup.com/
  $contents = str_replace("\t", " ", $contents);
  $minified = jsmin($contents);

  // Check for JSMin errors.
  $error = jsmin_last_error_msg();
  if ($error != 'No error') {
    $this->logger
      ->warning('JSMin had an error processing, using JSqueeze fallback. Error details: ' . $error, []);
    $contents = $this
      ->minifyJsqueeze($contents);
    return;
  }

  // Under some unknown/rare circumstances, JSMin can add up to 5
  // extraneous/wrong chars at the end of the string. Check and remove if
  // necessary. The chars unfortunately vary in number and specific chars.
  // Hence this is a poor quality check but often works.
  if (ctype_cntrl(substr(trim($minified), -1)) || strpbrk(substr(trim($minified), -1), ';})') === FALSE) {
    $this->logger
      ->notice($this
      ->t('JSMin had a possible error minifying: @file, correcting.', [
      '@file' => $path,
    ]));
    if (strrpos(substr($minified, -10), ';')) {
      $contents = substr($minified, 0, strrpos($minified, ';'));
    }
  }
  else {
    $contents = $minified;
  }
  $semicolons = substr_count($contents, ';', strlen($contents) - 5);
  if ($semicolons > 2) {
    $start = substr($contents, 0, -5);
    $contents = $start . preg_replace("/([;)}]*)([\\w]*)([;)}]*)/", "\$1\$3", substr($contents, -5));
    $this->logger
      ->notice($this
      ->t('JSMin had an error minifying file: @file, attempting to correct.', [
      '@file' => $path,
    ]));
  }
}