Implements hook_advagg_modify_css_pre_render_alter().
Related topics
File
-
advagg_mod/
advagg_mod.module, line 905
Code
function advagg_mod_advagg_modify_css_pre_render_alter(&$children, &$elements) {
// Skip if there is no css.
if (empty($children)) {
return;
}
if (!module_exists('advagg') || !advagg_enabled()) {
return;
}
// Return early if this setting is disabled.
list(, , , , , , , , , , $css_defer) = advagg_mod_get_lists(array(), $elements['#items']);
if (empty($css_defer)) {
return;
}
$critical_css = FALSE;
// Only check for the critical-css key if configured to do so.
if (variable_get('advagg_mod_css_defer_visibility', ADVAGG_MOD_VISIBILITY_LISTED) == ADVAGG_MOD_VISIBILITY_FILE_CONTROLLED) {
foreach ($elements['#items'] as $item) {
if ($item['type'] === 'inline' && !empty($item['critical-css'])) {
$critical_css = TRUE;
break;
}
}
// Return early if there's no critical css for the path and deferring is
// file controlled.
if (!$critical_css) {
return;
}
}
if (!$critical_css) {
// Return early if we're in a page that is not specified in the settings for
// specific pages.
if (!advagg_mod_css_defer_page()) {
return;
}
// Return early if we're in the admin theme and this setting is disabled.
$css_defer_admin = variable_get('advagg_mod_css_defer_admin', ADVAGG_MOD_CSS_DEFER_ADMIN);
if (empty($css_defer_admin) && path_is_admin(current_path())) {
return;
}
}
// Modify css.
static $added;
advagg_mod_add_loadcss_js_lib(array(), $elements['#items']);
// Wrap CSS in noscript tags.
$defer_skip_first_file = variable_get('advagg_mod_css_defer_skip_first_file', ADVAGG_MOD_CSS_DEFER_SKIP_FIRST_FILE);
$options = array(
'type' => 'inline',
'scope' => $css_defer >= 5 ? 'footer' : 'header',
'scope_lock' => TRUE,
'group' => $css_defer == 1 ? JS_LIBRARY - 1 : JS_DEFAULT,
'weight' => $css_defer == 1 ? -50000 : 0,
'movable' => $css_defer == 1 ? FALSE : TRUE,
);
// Get the key of the last css file that will use loadcss.
$last_key = NULL;
foreach ($children as $children_key => $values) {
// Do not count inline styles.
if ($values['#tag'] === 'style' || empty($values['#attributes']['href'])) {
continue;
}
// Only use if no browser conditionals.
if (isset($values['#browsers']['!IE']) && $values['#browsers']['!IE'] === TRUE && isset($values['#browsers']['IE']) && $values['#browsers']['IE'] === TRUE && isset($values['#attributes']['media']) && $values['#attributes']['media'] !== 'print' && $values['#attributes']['media'] !== 'none') {
$last_key = $children_key;
}
}
// If all css uses a browser conditional, then use the last one to release.
if ($last_key === NULL) {
$last_key = $children_key;
}
$preload_array = array();
foreach ($children as $children_key => &$values) {
// Do not defer inline styles.
if ($values['#tag'] === 'style' || empty($values['#attributes']['href'])) {
continue;
}
if (empty($preload_array) && $defer_skip_first_file == 2) {
$preload_array[] = array();
continue;
}
// If this is the last CSS file release the hold on jquery.ready.
$onload_extra = '';
if ($last_key === $children_key) {
// Run holdready once it is defined.
$holdready_script = 'window.advagg_mod_loadcss = function() {if (window.jQuery) {if (jQuery.isFunction(jQuery.holdReady)){jQuery.holdReady(false);}} else {setTimeout(advagg_mod_loadcss, 100);}};';
$onload_extra = "{$holdready_script}setTimeout(advagg_mod_loadcss, 200);";
$GLOBALS['advagg_mod_loadcss_jquery_holdready'] = TRUE;
}
$id = "advagg_loadcss_{$children_key}";
if ($css_defer == 4) {
$copy = $values;
$copy['#attributes']['rel'] = 'preload';
$copy['#attributes']['as'] = 'style';
$copy['#attributes']['onload'] = "{$onload_extra}this.onload=null;this.rel='stylesheet'";
$preload_array[$children_key] = $copy;
}
else {
// Add browsers to the js options.
if (isset($values['#browsers'])) {
$options['browsers'] = $values['#browsers'];
}
// Create loadCSS wrapper code.
$inline = "loadCSS(\"{$values['#attributes']['href']}\", document.getElementById(\"{$id}\")";
if ($values['#attributes']['media'] !== 'all') {
$inline .= ", \"{$values['#attributes']['media']}\"";
}
if (!empty($values['#attributes']['crossorigin'])) {
$inline .= ", \"{$values['#attributes']['crossorigin']}\"";
}
$inline .= ')';
// Create onloadCSS wrapper code.
if (!empty($values['#attributes']['onloadCSS'])) {
$inline = "onloadCSS({$inline}, function() {{$onload_extra}{$values['#attributes']['onloadCSS']}});";
}
elseif (!empty($onload_extra)) {
$inline = "onloadCSS({$inline}, function() {{$onload_extra}});";
}
// Make code work if loader code is below loadcss calls.
$matches[2] = $matches[0] = $inline;
$inline = advagg_mod_wrap_inline_js($matches, "window.loadCSS", 40);
// Add in script tags to load css via js.
if (!isset($added[$values['#attributes']['href']])) {
drupal_add_js($inline, $options);
$added[$values['#attributes']['href']] = TRUE;
}
}
// Wrap current css in noscript tags.
$values['#prefix'] = "<noscript id=\"{$id}\">\n";
$values['#suffix'] = '</noscript>';
// Reset for next item in loop.
if (isset($options['browsers'])) {
unset($options['browsers']);
}
}
unset($values);
// Add in the element after the noscript element keeping the css order.
$new_elements = array();
foreach ($elements as $elements_key => $elements_value) {
// Build old array.
if (is_numeric($elements_key)) {
$new_elements[] = $elements_value;
}
else {
$new_elements[$elements_key] = $elements_value;
}
// Splice in new data.
if (isset($preload_array[$elements_key])) {
$new_elements[] = $preload_array[$elements_key];
}
}
$elements = $new_elements;
unset($new_elements);
}