diff --git a/advagg.admin.inc b/advagg.admin.inc index e1e3bd4..c49f5dc 100644 --- a/advagg.admin.inc +++ b/advagg.admin.inc @@ -50,6 +50,12 @@ function advagg_admin_settings_form($form, $form_state) { '#default_value' => variable_get('advagg_combine_css_media', ADVAGG_COMBINE_CSS_MEDIA), '#description' => t('Use cores grouping logic needs to be unchecked in order for this to work. Also noted is that due to an issue with IE9, compatibility mode is forced off if this is enabled.'), ); + $form['css']['advagg_ie_css_selector_limiter'] = array( + '#type' => 'checkbox', + '#title' => t('Prevent more than 4095 CSS selectors in an aggregated CSS file'), + '#default_value' => variable_get('advagg_ie_css_selector_limiter', ADVAGG_IE_CSS_SELECTOR_LIMITER), + '#description' => t('Internet Explorer before version 10; IE9, IE8, IE7, & IE6 all have 4095 as the limit for the maximum number of css selectors that can be in a file. Enabling this will prevent CSS aggregates from being created that exceed this limit. More info.', array('@link' => 'http://blogs.msdn.com/b/ieinternals/archive/2011/05/14/10164546.aspx')), + ); // Clear the cache bins on submit. $form['#submit'][] = 'advagg_admin_settings_form_submit'; diff --git a/advagg.inc b/advagg.inc index 033fda8..41c372b 100644 --- a/advagg.inc +++ b/advagg.inc @@ -351,8 +351,17 @@ function advagg_get_info_on_file($filename, $bypass_cache = FALSE) { // Get the file contents $file_contents = file_get_contents($filename); - // Get the number of lines. - $linecount = substr_count($file_contents, "\n"); + + $ext = pathinfo($filename, PATHINFO_EXTENSION); + if ($ext == 'css') { + // Get the number of selectors. + // http://stackoverflow.com/questions/12567000/regex-matching-for-counting-css-selectors/12567381#12567381 + $linecount = preg_match_all('/\{.+?\}|,/s', $file_contents, $matched); + } + else { + // Get the number of lines. + $linecount = substr_count($file_contents, "\n"); + } // Build meta data array and set cache. $filename_hashes[$cache_id] = array_merge($filename_hashes[$cache_id], array( @@ -362,6 +371,7 @@ function advagg_get_info_on_file($filename, $bypass_cache = FALSE) { 'content_hash' => drupal_hash_base64($file_contents), 'linecount' => $linecount, 'data' => $filename, + 'fileext' => $ext, )); if (!$bypass_cache) { cache_set($cache_id, $filename_hashes[$cache_id], 'cache_advagg_info', CACHE_PERMANENT); @@ -433,6 +443,7 @@ function advagg_generate_groups($files_to_aggregate) { $cache = ''; $scope = ''; $browsers = array(); + $selector_count = 0; foreach ($files_to_aggregate as $data) { foreach ($data as $values) { @@ -442,6 +453,18 @@ function advagg_generate_groups($files_to_aggregate) { // Check to see if media, browsers, defer, async, cache, or scope has changed // from the previous run of this loop. $changed = FALSE; + if (variable_get('advagg_ie_css_selector_limiter', ADVAGG_IE_CSS_SELECTOR_LIMITER)) { + $file_info += advagg_get_info_on_file($file_info['data']); + // Prevent CSS rules exceding 4095 due to limits with IE9 and below. + $ext = isset($file_info['fileext']) ? $file_info['fileext'] : pathinfo($file_info['data'], PATHINFO_EXTENSION); + if ($ext == 'css') { + $selector_count += $file_info['linecount']; + if ($selector_count > 4095) { + $changed = TRUE; + $selector_count = $file_info['linecount']; + } + } + } if (isset($file_info['media'])) { if (variable_get('advagg_combine_css_media', ADVAGG_COMBINE_CSS_MEDIA)) { $file_info['media_query'] = $file_info['media']; diff --git a/advagg.module b/advagg.module index b7e4396..04222b5 100644 --- a/advagg.module +++ b/advagg.module @@ -47,6 +47,11 @@ define('ADVAGG_USE_HTTPRL', TRUE); define('ADVAGG_COMBINE_CSS_MEDIA', FALSE); /** + * Prevent more than 4095 css selector rules inside of a CSS aggregate. + */ +define('ADVAGG_IE_CSS_SELECTOR_LIMITER', TRUE); + +/** * Default location of AdvAgg configuration items. */ define('ADVAGG_ADMIN_CONFIG_ROOT_PATH', 'admin/config/development/performance'); @@ -870,6 +875,7 @@ function advagg_current_hooks_hash_array() { 'is_https' => $GLOBALS['is_https'], 'advagg_global_counter' => advagg_get_global_counter(), 'base_path' => $GLOBALS['base_path'], + 'advagg_ie_css_selector_limiter' => variable_get('advagg_ie_css_selector_limiter', ADVAGG_IE_CSS_SELECTOR_LIMITER), ), 'hooks' => advagg_hooks_implemented(FALSE), );