diff --git a/includes/common.inc b/includes/common.inc
index 6dbb9a2..76e3c87 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -4003,6 +4003,9 @@ function drupal_region_class($region) {
  *     a JavaScript file. Defaults to TRUE.
  *   - preprocess: If TRUE and JavaScript aggregation is enabled, the script
  *     file will be aggregated. Defaults to TRUE.
+ *   - browsers: An array containing information specifying which browsers
+ *     should load the JavaScript item. See
+ *     drupal_pre_render_conditional_comments() for details.
  *
  * @return
  *   The current array of JavaScript files, settings, and in-line code,
@@ -4051,6 +4054,7 @@ function drupal_add_js($data = NULL, $options = NULL) {
           'group' => JS_LIBRARY,
           'every_page' => TRUE,
           'weight' => 0,
+          'browsers' => array(),
         ),
         'misc/drupal.js' => array(
           'data' => 'misc/drupal.js',
@@ -4062,6 +4066,7 @@ function drupal_add_js($data = NULL, $options = NULL) {
           'preprocess' => TRUE,
           'cache' => TRUE,
           'defer' => FALSE,
+          'browsers' => array(),
         ),
       );
       // Register all required libraries.
@@ -4110,6 +4115,7 @@ function drupal_js_defaults($data = NULL) {
     'preprocess' => TRUE,
     'version' => NULL,
     'data' => $data,
+    'browsers' => array(),
   );
 }
 
@@ -4214,6 +4220,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
 
   // Loop through the JavaScript to construct the rendered output.
   $element = array(
+    '#type' => 'html_tag',
     '#tag' => 'script',
     '#value' => '',
     '#attributes' => array(
@@ -4222,59 +4229,63 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
   );
   foreach ($items as $item) {
     $query_string =  empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
+    $js_element = $element;
+    $js_element['#browsers'] = isset($item['browsers']) ? $item['browsers'] : array();
 
     switch ($item['type']) {
       case 'setting':
-        $js_element = $element;
         $js_element['#value_prefix'] = $embed_prefix;
         $js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");";
         $js_element['#value_suffix'] = $embed_suffix;
-        $output .= theme('html_tag', array('element' => $js_element));
+        $output .= drupal_render($js_element);
         break;
 
       case 'inline':
-        $js_element = $element;
         if ($item['defer']) {
           $js_element['#attributes']['defer'] = 'defer';
         }
         $js_element['#value_prefix'] = $embed_prefix;
         $js_element['#value'] = $item['data'];
         $js_element['#value_suffix'] = $embed_suffix;
-        $processed[$index++] = theme('html_tag', array('element' => $js_element));
+        $processed[$index++] = drupal_render($js_element);
         break;
 
       case 'file':
-        $js_element = $element;
         if (!$item['preprocess'] || !$preprocess_js) {
           if ($item['defer']) {
             $js_element['#attributes']['defer'] = 'defer';
           }
           $query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
           $js_element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
-          $processed[$index++] = theme('html_tag', array('element' => $js_element));
+          $processed[$index++] = drupal_render($js_element);
         }
         else {
           // By increasing the index for each aggregated file, we maintain
           // the relative ordering of JS by weight. We also set the key such
-          // that groups are split by items sharing the same 'group' value and
-          // 'every_page' flag. While this potentially results in more aggregate
-          // files, it helps make each one more reusable across a site visit,
-          // leading to better front-end performance of a website as a whole.
-          // See drupal_add_js() for details.
-          $key = 'aggregate_' . $item['group'] . '_' . $item['every_page'] . '_' . $index;
+          // that groups are split by items sharing the same 'group' and
+          // 'browsers' values and 'every_page' flag. While this potentially
+          // results in more aggregate files, it helps make each one more
+          // reusable across a site visit, leading to better front-end
+          // performance of a website as a whole. See drupal_add_js() for
+          // details.
+          // 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($js_element['#browsers']);
+          $key = 'aggregate_' . $item['group'] . '_' . serialize($js_element['#browsers']) . '_' . $item['every_page'] . '_' . $index;
           $processed[$key] = '';
           $files[$key][$item['data']] = $item;
         }
         break;
 
       case 'external':
-        $js_element = $element;
         // Preprocessing for external JavaScript files is ignored.
         if ($item['defer']) {
           $js_element['#attributes']['defer'] = 'defer';
         }
         $js_element['#attributes']['src'] = $item['data'];
-        $processed[$index++] = theme('html_tag', array('element' => $js_element));
+        $processed[$index++] = drupal_render($js_element);
         break;
     }
   }
@@ -4289,7 +4300,11 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
         $preprocess_file = file_create_url($uri);
         $js_element = $element;
         $js_element['#attributes']['src'] = $preprocess_file;
-        $processed[$key] = theme('html_tag', array('element' => $js_element));
+        // All items in the group are guaranteed to have the same value for
+        // 'browsers', so we can just use the current one.
+        $item = current($file_set);
+        $js_element['#browsers'] = isset($item['browsers']) ? $item['browsers'] : array();
+        $processed[$key] = drupal_render($js_element);
       }
     }
   }
