Implements hook_advagg_modify_js_pre_render_alter().

Related topics

File

advagg_mod/advagg_mod.module, line 749

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);
    }
}