Bug 783110 - Only reset the search box after a New/Edit filter operation in the filter list editor if the touched filter does not match the search term. r=mkmelin, ui-r=bwinton
authoraceman <acelists@atlas.sk>
Mon, 17 Sep 2012 21:03:41 -0400
changeset 13666 0629a3f8aad6ed3e4c7d8153269fe14dcaf0c172
parent 13665 c7cb323988b1b6aaf20062f2dade447374ac11be
child 13667 8f1eedc904bbbb90001e48c0910eab7be7fc0c22
push id762
push userbugzilla@standard8.plus.com
push dateMon, 19 Nov 2012 21:16:42 +0000
treeherdercomm-beta@4a2f61509b17 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, bwinton
bugs783110
Bug 783110 - Only reset the search box after a New/Edit filter operation in the filter list editor if the touched filter does not match the search term. r=mkmelin, ui-r=bwinton
mail/base/content/FilterListDialog.js
--- a/mail/base/content/FilterListDialog.js
+++ b/mail/base/content/FilterListDialog.js
@@ -227,17 +227,17 @@ function onEditFilter()
     return;
 
   let args = {filter: selectedFilter, filterList: gCurrentFilterList};
 
   window.openDialog("chrome://messenger/content/FilterEditor.xul", "FilterEditor", "chrome,modal,titlebar,resizable,centerscreen", args);
 
   if ("refresh" in args && args.refresh) {
     // reset search if edit was okay (name change might lead to hidden entry!)
-    document.getElementById("searchBox").value = "";
+    resetSearchBox(selectedFilter);
     rebuildFilterList();
   }
 }
 
 function onNewFilter(emailAddress)
 {
   let list = document.getElementById("filterList");
   let selectedFilter = currentFilter();
@@ -255,18 +255,18 @@ function onNewFilter(emailAddress)
     }
   }
 
   let args = {filterList: gCurrentFilterList, filterPosition: position};
 
   window.openDialog("chrome://messenger/content/FilterEditor.xul", "FilterEditor", "chrome,modal,titlebar,resizable,centerscreen", args);
 
   if ("refresh" in args && args.refresh) {
-    // On success: reset the search box!
-    document.getElementById("searchBox").value = "";
+    // On success: reset the search box if necessary!
+    resetSearchBox(gCurrentFilterList.getFilterAt(position));
     rebuildFilterList();
 
     // Select the new filter, it is at the position of previous selection.
     list.selectItem(list.getItemAtIndex(position));
   }
 }
 
 /**
@@ -503,28 +503,33 @@ function moveCurrentFilter(motion)
   let filter = currentFilter();
   if (!filter)
     return;
 
   gCurrentFilterList.moveFilter(filter, motion);
   rebuildFilterList();
 }
 
+/**
+ * Redraws the list of filters. Takes the search box value into account.
+ *
+ * This function should perform very fast even in case of high number of filters.
+ * Therefore there are some optimizations (e.g. listelement.children[] instead of
+ * list.getItemAtIndex()), that favour speed vs. semantical perfection.
+ */
 function rebuildFilterList()
 {
-  // This function should perform very fast even in case of high number of filters.
-  // Therefore there are some optimisations (e.g. listelement.children[] instead of
-  // list.getItemAtIndex()), that favour speed vs. semantical perfection.
+  // Get filters that match the search box.
   let aTempFilterList = onFindFilter();
 
   let searchBox = document.getElementById("searchBox");
   let searchBoxFocus = false;
   let activeElement = document.activeElement;
 
-  // Find if the currently focused element is a child inside the searchBox
+  // Find if the currently focused element is a child inside the search box
   // (probably html:input). Traverse up the parents until the first element
   // with an ID is found. If it is not searchBox, return false.
   while (activeElement != null) {
     if (activeElement == searchBox) {
       searchBoxFocus = true;
       break;
     }
     else if (activeElement.id) {
@@ -839,48 +844,75 @@ function getFirstFolder(msgFolder)
       return msgFolder;
   }
   catch (ex) {
     dump(ex + "\n");
   }
   return msgFolder;
 }
 
-
+/**
+ * Decides if the given filter matches the given keyword.
+ *
+ * @param  aFilter   nsIMsgFilter to check
+ * @param  aKeyword  the string to find in the filter name
+ *
+ * @return  True if the filter name contains the searched keyword.
+            Otherwise false. In the future this may be extended to match
+            other filter attributes.
+ */
+function filterSearchMatch(aFilter, aKeyword)
+{
+  return (aFilter.filterName.toLocaleLowerCase().indexOf(aKeyword) != -1)
+}
 
 /**
- * Called when the search button is clicked, this will narrow down the amount
- * of filters displayed in the list, using the search term to filter the names.
+ * Called from rebuildFilterList when the list needs to be redrawn.
+ * @return  Uses the search term in search box, to produce an array of
+ *          row (filter) numbers (indexes) that match the search term.
  */
 function onFindFilter()
 {
   let searchBox = document.getElementById("searchBox");
   let keyWord = searchBox.value.toLocaleLowerCase();
 
   // If searchbox is empty, just return and let rebuildFilterList
   // create an unfiltered list.
   if (!keyWord)
     return null;
 
   // Rematch everything in the list, remove what doesn't match the search box.
   let rows = gCurrentFilterList.filterCount;
   let matchingFilterList = [];
-  let item;
   // Use the full gCurrentFilterList, not the filterList listbox,
   // which may already be filtered.
   for (let i = 0; i < rows; i++) {
-    item = gCurrentFilterList.getFilterAt(i).filterName;
-    if (item.toLocaleLowerCase().indexOf(keyWord) != -1)
+    if (filterSearchMatch(gCurrentFilterList.getFilterAt(i), keyWord))
       matchingFilterList.push(i);
   }
 
   return matchingFilterList;
 }
 
 /**
+ * Clear the search term in the search box if needed.
+ *
+ * @param aFilter  If this nsIMsgFilter matches the search term,
+ *                 do not reset the box. If this is null,
+ *                 reset unconditionally.
+ */
+function resetSearchBox(aFilter)
+{
+  let searchBox = document.getElementById("searchBox");
+  let keyword = searchBox.value.toLocaleLowerCase();
+  if (keyword && (!aFilter || !filterSearchMatch(aFilter, keyword)))
+    searchBox.reset();
+}
+
+/**
  * Display "1 item",  "11 items" or "4 of 10" if list is filtered via search box.
  */
 function updateCountBox()
 {
   let countBox = document.getElementById("countBox");
   let sum = gCurrentFilterList.filterCount;
   let filterList = document.getElementById("filterList");
   let len = filterList.itemCount;