diff --git a/core/includes/common.inc b/core/includes/common.inc index 6c489b2..a86a690 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -4225,6 +4225,14 @@ function drupal_pre_render_scripts($elements) { $element = $element_defaults; $element['#attributes']['src'] = file_create_url($group['data']); $element['#browsers'] = $group['browsers']; + + if (!empty($group['async'])) { + $element['#attributes']['async'] = 'async'; + } + if (!empty($group['defer'])) { + $element['#attributes']['defer'] = 'defer'; + } + $elements[] = $element; } // For non-file types, and non-aggregated files, add a script element per @@ -4293,11 +4301,6 @@ function drupal_pre_render_scripts($elements) { * if their 'preprocess' flag is TRUE. Items of the 'inline', 'settings', or * 'external' type are not groupable. * - * This function also ensures that the process of grouping items does not change - * their relative order. This requirement may result in multiple groups for the - * same type and browsers, if needed to accommodate other items in - * between. - * * @param $javascript * An array of JavaScript items, as returned by drupal_add_js(), but after * alteration performed by drupal_get_js(). @@ -4315,48 +4318,47 @@ function drupal_group_js($javascript) { $groups = array(); // If a group can contain multiple items, we track the information that must // be the same for each item in the group, so that when we iterate the next - // item, we can determine if it can be put into the current group, or if a - // new group needs to be made for it. - $current_group_keys = NULL; - $index = -1; + // item, we can determine if it can be put into an existing group. + $index = FALSE; foreach ($javascript as $item) { - // The browsers for which the JavaScript item needs to be loaded is part of - // the information that determines when a new group is needed, but the order - // of keys in the array doesn't matter, and we don't want a new group if all - // that's different is that order. - ksort($item['browsers']); - switch ($item['type']) { case 'file': // Group file items if their 'preprocess' flag is TRUE. - // Help ensure maximum reuse of aggregate files by only grouping - // together items that share the same 'group' value and 'every_page' - // flag. See drupal_add_js() for details about that. - $group_keys = $item['preprocess'] ? array($item['type'], $item['group'], $item['every_page'], $item['browsers']) : FALSE; + if ($item['preprocess']) { + $group_keys = array( + $item['type'], + $item['group'], + $item['every_page'], + $item['browsers'], + $item['async'], + $item['defer'], + ); + $index = md5(serialize($group_keys)); + } + else { + $index = FALSE; + } break; case 'external': case 'setting': case 'inline': // Do not group external, settings, and inline items. - $group_keys = FALSE; + $index = FALSE; break; } - // If the group keys don't match the most recent group we're working with, - // then a new group must be made. - if ($group_keys !== $current_group_keys) { - $index++; + // If the group index is new, then create a new group. + if (!isset($groups[$index])) { // Initialize the new group with the same properties as the first item // being placed into it. The item's 'data' and 'weight' properties are // unique to the item and should not be carried over to the group. $groups[$index] = $item; unset($groups[$index]['data'], $groups[$index]['weight']); $groups[$index]['items'] = array(); - $current_group_keys = $group_keys ? $group_keys : NULL; } - // Add the item to the current group. + // Add the item to its group. $groups[$index]['items'][] = $item; }