diff --git a/core/includes/common.inc b/core/includes/common.inc
index 14154af..db567a0 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2998,18 +2998,6 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) {
   // Sort CSS items, so that they appear in the correct order.
   uasort($css, 'drupal_sort_css_js');
 
-  // Provide the page with information about the individual CSS files used,
-  // information not otherwise available when CSS aggregation is enabled. The
-  // setting is attached later in this function, but is set here, so that CSS
-  // files removed below are still considered "used" and prevented from being
-  // added in a later AJAX request.
-  // Skip if no files were added to the page or jQuery.extend() will overwrite
-  // the Drupal.settings.ajaxPageState.css object with an empty array.
-  if (!empty($css)) {
-    // Cast the array to an object to be on the safe side even if not empty.
-    $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1);
-  }
-
   // Remove the overridden CSS files. Later CSS files override former ones.
   $previous_item = array();
   foreach ($css as $key => $item) {
@@ -3224,6 +3212,12 @@ function drupal_aggregate_css(&$css_groups) {
       case 'file':
         if ($group['preprocess'] && $preprocess_css) {
           $css_groups[$key]['data'] = drupal_build_css_cache($group['items']);
+          // Build a list of all the CSS files of the group.
+          $files = array();
+          foreach ($group['items'] as $item) {
+            $files[] = $item['data'];
+          }
+          $css_groups[$key]['files'] = $files;
         }
         break;
       // Aggregate all inline CSS content into the group's data property.
@@ -3353,6 +3347,7 @@ function drupal_pre_render_styles($elements) {
           $element = $link_element_defaults;
           $element['#attributes']['href'] = file_create_url($group['data']);
           $element['#attributes']['media'] = $group['media'];
+          $element['#attributes']['data-css-files'] = implode(',', $group['files']);
           $element['#browsers'] = $group['browsers'];
           $elements[] = $element;
         }
@@ -3360,6 +3355,7 @@ function drupal_pre_render_styles($elements) {
         // into as few STYLE tags as possible.
         elseif ($group['preprocess']) {
           $import = array();
+          $files = array();
           foreach ($group['items'] as $item) {
             // A theme's .info file may have an entry for a file that doesn't
             // exist as a way of overriding a module or base theme CSS file from
@@ -3378,6 +3374,7 @@ function drupal_pre_render_styles($elements) {
               // @import statement, so we instead specify the media for the
               // group on the STYLE tag.
               $import[] = '@import url("' . check_plain(file_create_url($item['data']) . '?' . $query_string) . '");';
+              $files[] = $item['data'];
             }
           }
           // In addition to IE's limit of 31 total CSS inclusion tags, it also
@@ -3385,9 +3382,12 @@ function drupal_pre_render_styles($elements) {
           while (!empty($import)) {
             $import_batch = array_slice($import, 0, 31);
             $import = array_slice($import, 31);
+            $files_batch = array_slice($files, 0, 31);
+            $files = array_slice($files, 31);
             $element = $style_element_defaults;
             $element['#value'] = implode("\n", $import_batch);
             $element['#attributes']['media'] = $group['media'];
+            $element['#attributes']['data-css-files'] = implode(',', $files_batch);
             $element['#browsers'] = $group['browsers'];
             $elements[] = $element;
           }
@@ -3410,6 +3410,7 @@ function drupal_pre_render_styles($elements) {
             $query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
             $element['#attributes']['href'] = file_create_url($item['data']) . $query_string_separator . $query_string;
             $element['#attributes']['media'] = $item['media'];
+            $element['#attributes']['data-css-files'] = $item['data'];
             $element['#browsers'] = $group['browsers'];
             $elements[] = $element;
           }
@@ -4218,22 +4219,6 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
   // Sort the JavaScript so that it appears in the correct order.
   uasort($items, 'drupal_sort_css_js');
 
-  // Provide the page with information about the individual JavaScript files
-  // used, information not otherwise available when aggregation is enabled.
-  $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
-  unset($setting['ajaxPageState']['js']['settings']);
-  drupal_add_js($setting, 'setting');
-
-  // If we're outputting the header scope, then this might be the final time
-  // that drupal_get_js() is running, so add the setting to this output as well
-  // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
-  // because drupal_get_js() was intentionally passed a $javascript argument
-  // stripped of settings, potentially in order to override how settings get
-  // output, so in this case, do not add the setting to this output.
-  if ($scope == 'header' && isset($items['settings'])) {
-    $items['settings']['data'][] = $setting;
-  }
-
   // Render the HTML needed to load the JavaScript.
   $elements = array(
     '#type' => 'scripts',
@@ -4312,6 +4297,7 @@ function drupal_pre_render_scripts($elements) {
     if ($group['type'] == 'file' && isset($group['data'])) {
       $element = $element_defaults;
       $element['#attributes']['src'] = file_create_url($group['data']);
+      $element['#attributes']['data-js-files'] = implode(',', $group['files']);
       $element['#browsers'] = $group['browsers'];
       $elements[] = $element;
     }
@@ -4344,6 +4330,7 @@ function drupal_pre_render_scripts($elements) {
             $query_string = empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
             $query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
             $element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
+            $element['#attributes']['data-js-files'] = $item['data'];
             break;
 
           case 'external':
@@ -4474,6 +4461,12 @@ function drupal_aggregate_js(&$js_groups) {
     foreach ($js_groups as $key => $group) {
       if ($group['type'] == 'file' && $group['preprocess']) {
         $js_groups[$key]['data'] = drupal_build_js_cache($group['items']);
+        // Build a list of all the JS files of the group.
+        $files = array();
+        foreach ($group['items'] as $item) {
+          $files[] = $item['data'];
+        }
+        $js_groups[$key]['files'] = $files;
       }
     }
   }
diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index d599799..48ca980 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -290,6 +290,17 @@ Drupal.ajax.prototype.beforeSerialize = function (element, options) {
     options.data['ajax_html_ids[]'].push(this.id);
   });
 
+  // Helper function to split a list of filenames and add them to the proper
+  // ajax_page_state value.
+  function addFiles (type, files) {
+    if (files) {
+      files = files.split(',');
+      for (var i = 0, il = files.length; i < il; i += 1) {
+        options.data['ajax_page_state[' + type + '][' + files[i] + ']'] = 1;
+      }
+    }
+  }
+
   // Allow Drupal to return new JavaScript and CSS files to load without
   // returning the ones already loaded.
   // @see ajax_base_page_theme()
@@ -297,11 +308,33 @@ Drupal.ajax.prototype.beforeSerialize = function (element, options) {
   // @see drupal_get_js()
   options.data['ajax_page_state[theme]'] = Drupal.settings.ajaxPageState.theme;
   options.data['ajax_page_state[theme_token]'] = Drupal.settings.ajaxPageState.theme_token;
-  for (var key in Drupal.settings.ajaxPageState.css) {
-    options.data['ajax_page_state[css][' + key + ']'] = 1;
-  }
-  for (var key in Drupal.settings.ajaxPageState.js) {
-    options.data['ajax_page_state[js][' + key + ']'] = 1;
+  $('[data-css-files]').each(function () {
+    addFiles('css', $(this).attr('data-css-files'));
+  });
+  $('[data-js-files]').each(function () {
+    addFiles('js', $(this).attr('data-css-files'));
+  });
+  // We need to get the values that are inside conditional comments.
+  var child, text, cssMatch, jsMatch;
+  var dataCSSFiles = /data-css-files="([^"]+)"/gi;
+  var dataJSFiles = /data-js-files="([^"]+)"/gi;
+  var childNodes = $('head')[0].childNodes;
+  for (var i = 0, il = childNodes.length; i < il; i += 1) {
+    child = childNodes[i];
+    text = child.textContent;
+    // Filter comment nodes.
+    if (child.nodeType === 8) {
+      if (dataCSSFiles.test(text)) {
+        while ((cssMatch = dataCSSFiles.exec(text)) !== null) {
+          addFiles('css', cssMatch[1]);
+        }
+      }
+      if (dataJSFiles.test(text)) {
+        while ((jsMatch = dataJSFiles.exec(text)) !== null) {
+          addFiles('js', jsMatch[1]);
+        }
+      }
+    }
   }
 };
 
