Index: mollom.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.admin.inc,v
retrieving revision 1.1.2.41
diff -u -p -r1.1.2.41 mollom.admin.inc
--- mollom.admin.inc	20 Sep 2010 23:51:30 -0000	1.1.2.41
+++ mollom.admin.inc	21 Sep 2010 02:23:08 -0000
@@ -323,12 +323,27 @@ function mollom_admin_unprotect_form_sub
 function mollom_admin_blacklist_form(&$form_state, $type = 'spam') {
   $form['#tree'] = TRUE;
 
-  // Select options and translation of internal values for rendering.
+  // Translate internal reason values for rendering and select list in form.
   $contexts = array(
     'everything' => t('All fields'),
     'links' => t('Links'),
     'author' => t('Author name'),
   );
+  $matches = array(
+    'contains' => t('contains'),
+    'exact' => t('exact'),
+  );
+
+  $form['filter'] = array(
+    '#prefix' => '<div class="form-wrapper container-inline">',
+    '#suffix' => '</div>',
+  );
+  $form['filter']['text'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Filter'),
+    '#size' => 20,
+    '#id' => 'mollom-blacklist-filter',
+  );
 
   $form['blacklist'] = array();
   // Do not retrieve the current blacklist when submitting the form.
@@ -339,9 +354,15 @@ function mollom_admin_blacklist_form(&$f
         continue;
       }
       $row = array(
-        'context' => array('#value' => check_plain($contexts[$entry['context']])),
-        'text' => array('#value' => check_plain($entry['text'])),
-        'text' => array('#value' => check_plain($entry['text'])),
+        'context' => array(
+          '#value' => check_plain($contexts[$entry['context']]),
+        ),
+        'match' => array(
+          '#value' => check_plain($matches[$entry['match']]),
+        ),
+        'text' => array(
+          '#value' => check_plain($entry['text']),
+        ),
       );
       $query = 'text=' . urlencode($entry['text']) . '&';
       $query .= 'context=' . urlencode($entry['context']) . '&';
@@ -361,6 +382,12 @@ function mollom_admin_blacklist_form(&$f
     '#default_value' => 'everything',
     '#required' => TRUE,
   );
+  $form['entry']['match'] = array(
+    '#type' => 'select',
+    '#options' => $matches,
+    '#default_value' => 'contains',
+    '#required' => TRUE,
+  );
   $form['entry']['text'] = array(
     '#type' => 'textfield',
     '#size' => 40,
@@ -389,6 +416,7 @@ function mollom_admin_blacklist_form_sub
   $data = array(
     'text' => $form_state['values']['entry']['text'],
     'context' => $form_state['values']['entry']['context'],
+    'match' => $form_state['values']['entry']['match'],
     'reason' => $form_state['values']['entry']['reason'],
   );
   $result = mollom('mollom.addBlacklistText', $data);
@@ -396,12 +424,13 @@ function mollom_admin_blacklist_form_sub
   $args = array(
     '@text' => $data['text'],
     '@context' => $data['context'],
+    '@match' => $data['match'],
     '@reason' => $data['reason'],
   );
   if ($result === TRUE) {
     drupal_set_message(t('The entry was added to the blacklist.'));
     _mollom_watchdog(array(
-      'Added @text (@context) to @reason blacklist.' => $args,
+      'Added @text (@context, @match) to @reason blacklist.' => $args,
       'Data:<pre>@data</pre>' => array('@data' => $data),
       'Result:<pre>@result</pre>' => array('@result' => $result),
     ));
@@ -409,7 +438,7 @@ function mollom_admin_blacklist_form_sub
   else {
     drupal_set_message(t('An error occurred upon trying to add the text to the blacklist.'), 'error');
     _mollom_watchdog(array(
-      'Failed to add @text (%context) to @reason blacklist.' => $args,
+      'Failed to add @text (@context, @match) to @reason blacklist.' => $args,
       'Data:<pre>@data</pre>' => array('@data' => $data),
       'Result:<pre>@result</pre>' => array('@result' => $result),
     ), WATCHDOG_ERROR);
@@ -422,6 +451,7 @@ function mollom_admin_blacklist_form_sub
 function theme_mollom_admin_blacklist_form($form) {
   $header = array(
     t('Context'),
+    t('Matches'),
     t('Text'),
     '',
   );
@@ -429,6 +459,7 @@ function theme_mollom_admin_blacklist_fo
 
   $rows[] = array(
     drupal_render($form['entry']['context']),
+    drupal_render($form['entry']['match']),
     drupal_render($form['entry']['text']),
     drupal_render($form['entry']['actions']),
   );
@@ -436,13 +467,19 @@ function theme_mollom_admin_blacklist_fo
   foreach (element_children($form['blacklist']) as $id) {
     $rows[] = array(
       drupal_render($form['blacklist'][$id]['context']),
-      drupal_render($form['blacklist'][$id]['text']),
+      drupal_render($form['blacklist'][$id]['match']),
+      array(
+        'data' => drupal_render($form['blacklist'][$id]['text']),
+        'class' => 'mollom-blacklist-text',
+      ),
       drupal_render($form['blacklist'][$id]['actions']),
     );
   }
 
   // This table is never empty due to the form.
-  $output  = theme('table', $header, $rows);
+  $output = drupal_render($form['filter']);
+  $output .= theme('table', $header, $rows, array('id' => 'mollom-blacklist'));
+  drupal_add_js(drupal_get_path('module', 'mollom') . '/mollom.admin.js');
   $output .= drupal_render($form);
 
   return $output;
Index: mollom.admin.js
===================================================================
RCS file: mollom.admin.js
diff -N mollom.admin.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mollom.admin.js	21 Sep 2010 02:11:40 -0000
@@ -0,0 +1,38 @@
+// $Id: mollom.js,v 1.9 2010/08/04 03:58:46 dries Exp $
+(function ($) {
+
+/**
+ * Filters blacklist entries.
+ */
+Drupal.behaviors.mollomBlacklistFilter = function (context) {
+  // Intentionally wrong indentation for simplified maintenance.
+    var self = this;
+    $('#mollom-blacklist:not(.mollom-processed)', context).addClass('mollom-processed').each(function () {
+      // Prepare a list of all entries to optimize performance. Each key is a
+      // blacklisted text and each value is the corresponding table row.
+      self.$entries = {};
+      $(this).find('.mollom-blacklist-text').each(function () {
+        var $entry = $(this);
+        self.$entries[$entry.text()] = $entry.parent();
+      });
+      // Attach the filter.
+      var $filter = $('#mollom-blacklist-filter', context);
+      $filter.keyup(function () {
+        // Prepare static conditions only once.
+        var searchText = $filter.val();
+        var isEmpty = (searchText.length == 0);
+        // Use a simple for...in loop instead of jQuery.each(), as that saves
+        // thousands of function calls.
+        for (var text in self.$entries) {
+          if (isEmpty || text.indexOf(searchText) != -1) {
+            self.$entries[text].show();
+          }
+          else {
+            self.$entries[text].hide();
+          }
+        }
+      });
+    });
+};
+
+})(jQuery);
