You are here

function advagg_mod_advagg_modify_js_pre_render_alter in Advanced CSS/JS Aggregation 7.2

Implements hook_advagg_modify_js_pre_render_alter().

Related topics

File

advagg_mod/advagg_mod.module, line 749
Advanced aggregation modifier module.

Code

function advagg_mod_advagg_modify_js_pre_render_alter(&$children, &$elements) {
  if (!module_exists('advagg') || !advagg_enabled()) {
    return;
  }

  // Do not use defer/async shim if JS is inlined.
  if (advagg_mod_inline_page() || advagg_mod_inline_page_js()) {
    return;
  }
  if (variable_get('advagg_mod_js_defer', ADVAGG_MOD_JS_DEFER) || variable_get('advagg_mod_js_async', ADVAGG_MOD_JS_ASYNC)) {

    // Capture all onload code.
    $onload_code = array();
    foreach ($children as $values) {
      if (isset($values['#attributes']['onload'])) {
        $onload_code[$values['#attributes']['src']] = $values['#attributes']['onload'];
      }
    }
    $jquery_rev = strrev('/jquery.js');
    $jquery_min_rev = strrev('/jquery.min.js');
    $ie_fixes = array();
    foreach ($elements['#groups'] as $group) {
      if ($group['type'] !== 'file' || empty($group['defer']) || empty($group['items']['files'])) {
        continue;
      }
      $found = FALSE;
      foreach ($group['items']['files'] as $name => &$values) {

        // Special handling for jQuery.
        if (stripos(strrev($name), $jquery_rev) === 0 || stripos(strrev($name), $jquery_min_rev) === 0) {
          $found = TRUE;
        }
      }
      if ($found) {
        $ie_fixes[] = basename($group['data']);
      }
    }
    foreach ($children as $key => &$values) {
      if (!empty($values['#attributes']['src']) && isset($values['#attributes']['defer']) && empty($values['#browsers'])) {
        $ie_key = array_search(basename($values['#attributes']['src']), $ie_fixes);
        if ($ie_key !== FALSE) {
          unset($ie_fixes[$ie_key]);

          // Not IE supports defer.
          $values['#browsers'] = array(
            'IE' => FALSE,
            '!IE' => TRUE,
          );

          // IE10+ supports defer.
          $copy = $values;
          $copy['#browsers'] = array(
            'IE' => 'gt IE 9',
            '!IE' => FALSE,
          );
          $copy['#attributes']['src'] .= '#ie10+';
          array_splice($children, $key, 0, array(
            $copy,
          ));

          // IE9- does not support defer.
          $copy = $values;
          $copy['#browsers'] = array(
            'IE' => 'lte IE 9',
            '!IE' => FALSE,
          );
          unset($copy['defer']);
          unset($copy['#attributes']['defer']);
          $copy['#attributes']['src'] .= '#ie9-';
          array_splice($children, $key, 0, array(
            $copy,
          ));
        }
      }
    }

    // Count the number of holdReady's there are.
    $holdready_count = array();
    foreach ($children as $key => &$values) {
      if (!empty($values['#attributes']['onload']) && (stripos($values['#attributes']['onload'], 'jQuery.holdReady(true)') !== FALSE || stripos($values['#attributes']['onload'], 'jQuery.holdReady(!0)') !== FALSE)) {

        // Normalize the src attribute.
        $src = $values['#attributes']['src'];
        $pos = strpos($values['#attributes']['src'], '#');
        if ($pos !== FALSE) {
          $src = substr($values['#attributes']['src'], 0, $pos);
        }
        $holdready_count[$src] = TRUE;
        break;
      }
    }
    foreach ($children as $key => &$values) {

      // Core's Drupal.settings. Put inside wrapper if there is an onload call
      // for init_drupal_core_settings. Have to do this here because the
      // settings needed to be rendered.
      if (!empty($values['#value']) && strpos($values['#value'], 'jQuery.extend(Drupal.settings') !== FALSE) {
        $found = FALSE;
        foreach ($onload_code as $src => $code) {
          if (strpos($code, 'init_drupal_core_settings(') !== FALSE) {
            $found = TRUE;
            unset($onload_code[$src]);
            break;
          }
        }
        if ($found) {
          $holdready_string = '';
          if (!empty($holdready_count)) {
            $holdready_string = "\nif(jQuery.isFunction(jQuery.holdReady)){jQuery.holdReady(false);}";
          }
          $values['#value'] = "function init_drupal_core_settings() {{$values['#value']} {$holdready_string}} if(window.jQuery && window.Drupal){init_drupal_core_settings();}";
        }
      }
    }
    unset($values);
  }
  if (variable_get('advagg_mod_js_async_shim', ADVAGG_MOD_JS_ASYNC_SHIM)) {
    foreach ($children as &$values) {
      if (isset($values['#attributes']) && isset($values['#attributes']['async']) && $values['#attributes']['async'] === 'async' && !empty($values['#attributes']['src'])) {
        $source = $values['#attributes']['src'];
        if (strpos($source, 'http://') !== 0 && strpos($source, 'https://') !== 0 && strpos($source, '//') !== 0) {
          $source = url($values['#attributes']['src']);
        }
        $values['#value'] = "(function() {\n  var s = document.createElement('script');\n  s.type = 'text/javascript';\n  s.async = true;\n  s.src = '{$source}';\n  var d = document.getElementsByTagName('script')[0];\n  d.parentNode.insertBefore(s, d);\n})();";
        unset($values['#attributes']['async']);
        unset($values['#attributes']['src']);
      }
    }
    unset($values);
  }
}