? sites/default/files
? sites/default/private
? sites/default/settings.php
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.553
diff -u -p -r1.553 theme.inc
--- includes/theme.inc	20 Nov 2009 04:29:42 -0000	1.553
+++ includes/theme.inc	25 Nov 2009 08:45:32 -0000
@@ -1659,6 +1659,11 @@ function theme_table($variables) {
     $attributes['class'][] = 'sticky-enabled';
   }
 
+  // Attach tablefilter behavior, if required.
+  if (is_array($attributes['class']) && in_array('tablefilter', $attributes['class'])) {
+    drupal_add_js('misc/tablefilter.js');
+  }
+
   $output = '<table' . drupal_attributes($attributes) . ">\n";
 
   if (isset($caption)) {
Index: misc/tablefilter.js
===================================================================
RCS file: misc/tablefilter.js
diff -N misc/tablefilter.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ misc/tablefilter.js	25 Nov 2009 08:45:32 -0000
@@ -0,0 +1,180 @@
+// $Id$
+
+(function($) {
+
+// Create an object on which each instance of the tableFilter object will be applied to.
+Drupal.tablefilters = {};
+
+/**
+ * The tableFilter object.
+ */
+Drupal.tableFilter = function(container, settings) {
+  // Create a reference and define it's variables.
+  var ref = this;
+  ref.settings = settings;
+  ref.container = (container[0].tagName.toLowerCase() == 'form' ? container.children('div') : container);
+  ref.textfield;
+
+  /**
+   * Initializes the tablefilter behavior.
+   */
+  ref.init = function() {
+    ref.createTextfield();
+    ref.attachEventListeners();
+  };
+
+  /**
+   * Creates an input textfield inside the container.
+   */
+  ref.createTextfield = function() {
+    var wrapper = $('<div />').addClass('form-item form-type-textfield form-item-tablefilter').prependTo(ref.container);
+    var label = $('<label />').attr('for', 'edit-' + ref.settings.id).text(ref.settings.label).appendTo(wrapper);
+    ref.textfield = $('<input type="text" />').attr({
+      'maxlength': 128,
+      'name': ref.settings.id,
+      'id': 'edit-' + ref.settings.id,
+      'size': 30,
+      'value': ''
+    }).addClass('tablefilter-textfield form-text').appendTo(wrapper);
+    description = $('<div />').addClass('description').text(ref.settings.description).appendTo(wrapper);
+
+    if (ref.textfield[0]) {
+      ref.textfield[0].type = 'search';
+      ref.textfield.attr('results', 5);
+    };
+  };
+
+  /**
+   * Attaches all event listeners to the relevant DOM elements.
+   */
+  ref.attachEventListeners = function() {
+    ref.textfield.bind('click keyup', function() {
+      ref.filter(ref.container, $.trim(ref.textfield.val().toLowerCase()));
+    });
+  };
+
+  /**
+   * Adds a DOM element after the textfield element and displays a 'no results' message.
+   */
+  ref.addPlaceholder = function() {
+    if (!ref.container.find('.tablefilter-no-results').length)
+      ref.textfield.closest('.form-item').after($('<p class="tablefilter-no-results"></p>').text(ref.settings.empty));
+  };
+
+  /**
+   * Removes the 'no results' message.
+   */
+  ref.removePlaceholder = function() {
+    ref.container.find('.tablefilter-no-results').remove();
+  };
+
+  /**
+   * FIlteres all affected table rows for the given string.
+   * All table row containing the string will stay visible, while other rows are hidden.
+   */
+  ref.filter = function(container, string) {
+
+    // Keep track of whether or not we'll find any results.
+    var results = false;
+
+    // Walk through each tbody inside the container element.
+    container.find('tbody').each(function() {
+      var num_trs = $('tr', this).size();
+      var zebra = 'even';
+
+      // Walk through each tr inside the current tbody element.
+      $(this).find('tr').each(function() {
+        str_exists = false;
+  
+        // Walk through each td inside the current tr element.
+        $(this).find('td').each(function() {
+          // Check whether or not the string exists in the current td.
+          if ($(this).text().toLowerCase().indexOf(string) > -1) {
+            // The string is found.
+            str_exists = true;
+            results = true;
+          };
+        });
+         // If the variable string_exists returns true, the string exists in the current tr.
+        if (!str_exists) {
+          num_trs--;
+          $(this).removeClass('tablefilter-match').addClass('tablefilter-irrelevant').hide();
+        }
+        else {
+          num_trs++;
+          zebra = (zebra == 'odd' ? 'even' : 'odd');
+          $(this).removeClass('tablefilter-irrelevant odd even').addClass('tablefilter-match ' + (zebra)).show();
+        };
+      });
+      // If the matched tr's equals 0, hide it's parent container.
+      if (num_trs == 0) {
+        $(this).parents('table, .tablefilter-group').hide();
+      }
+      else {
+        $(this).parents('table, .tablefilter-group').show();
+      };
+    });
+
+    // If any results are found, remove the 'no results' message.
+    // Otherwise dipslay the 'no results message.
+    if (results) {
+      ref.removePlaceholder();
+    }
+    else {
+      ref.addPlaceholder();
+    };
+
+    // Allow other scripts to interact with this event.
+    container.trigger('tablefilter');
+  };
+
+  // Return the reference object.
+  return ref;
+};
+
+/**
+ * Attaches the tablefilter bahavior to Drupal behaviours.
+ */
+Drupal.behaviors.tablefilter = {
+  attach: function(context) {
+
+    // Avoid the behavior being attached more than once to this dom element.
+    $('.tablefilter', context).once('tablefilter-processed', function() {
+
+      // Create a unique idetifier for the new tablefilter instance.
+      window.table_filter_index = (window.table_filter_index == undefined ?  0 : window.table_filter_index + 1);
+
+      // Specify which element is the container of the table(s) on which to applie the behavior.
+      // This can either be the parent element of an table or a parent element with classname 'tablefilter-container'.
+      var container = ($(this).parents('.tablefilter-container').size() > 0 ? $(this).parents('.tablefilter-container') : $(this).parent());
+
+      // If the container hasn't got an ID, create one
+      if (!container.attr('id')) {
+        container.attr('id', 'tablefilter-' + window.table_filter_index);
+      };
+
+      // Create a default setting object.
+      var settings = {
+        'label': Drupal.t('Filter'),
+        'description': Drupal.t('Enter text to filter the table below.'),
+        'empty': Drupal.t('There were no results.'),
+        'id': container.attr('id')
+      };
+
+      // Allow other scripts to overwrite the settings object.
+      if (Drupal.settings && Drupal.settings.tablefilter && Drupal.settings.tablefilter[settings.id]) {
+        for (var i in Drupal.settings.tablefilter[settings.id]) {
+          settings[i] = Drupal.settings.tablefilter[settings.id][i];
+        };
+      };
+
+      // Create a new instance of the tableFilter object and initialize the instance.
+      if (!Drupal.tablefilters[settings.id]) {
+        Drupal.tablefilters[settings.id] =  new Drupal.tableFilter(container, settings);
+        Drupal.tablefilters[settings.id].init();
+      };
+    });
+  }
+};
+
+})(jQuery);
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.227
diff -u -p -r1.227 system.admin.inc
--- modules/system/system.admin.inc	22 Nov 2009 18:42:55 -0000	1.227
+++ modules/system/system.admin.inc	25 Nov 2009 08:45:33 -0000
@@ -776,6 +776,7 @@ function system_modules($form, $form_sta
       '#title' => t($package),
       '#collapsible' => TRUE,
       '#theme' => 'system_modules_fieldset',
+      '#attributes' => array('class' => array('tablefilter-group')),
       '#header' => array(
         array('data' => t('Enabled'), 'class' => array('checkbox')),
         t('Name'),
@@ -791,7 +792,15 @@ function system_modules($form, $form_sta
     '#value' => t('Save configuration'),
   );
   $form['#action'] = url('admin/config/modules/list/confirm');
-
+  $form['#attributes']['class'] = 'tablefilter-container';
+  $form['#attached'] = array(
+    'js' => array(
+      array(
+        'data' => array('tablefilter' => array('system-modules' => array('label' => t('Filter modules'), 'description' => t('Enter the name of a module to filter the list.')))),
+        'type' => 'setting'
+      ),
+    ),
+  );
   return $form;
 }
 
@@ -2347,7 +2356,7 @@ function theme_system_modules_fieldset($
     $rows[] = $row;
   }
 
-  return theme('table', array('header' => $form['#header'], 'rows' => $rows));
+  return theme('table', array('header' => $form['#header'], 'rows' => $rows, 'attributes' => array('class' => array('tablefilter'))));
 }
 
 /**
