Bug 1051187 - "Match case" button does not refresh the number of occurences. r=mikedeboer
authorTomasz Kołodziejski <tkolodziejski@mozilla.com>
Thu, 02 Oct 2014 17:23:00 +0200
changeset 208928 d5a592a6504455c58e4e769ac5f6f2d6d6b2bc04
parent 208927 76e64cc73ccf87031cdbfe5d91f8821de073487f
child 208929 8c0ced0c0ab1c1737acad57713369407884ea3a0
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmikedeboer
bugs1051187
milestone35.0a1
Bug 1051187 - "Match case" button does not refresh the number of occurences. r=mikedeboer
toolkit/content/tests/chrome/findbar_events_window.xul
toolkit/content/tests/chrome/findbar_window.xul
toolkit/content/widgets/findbar.xml
--- a/toolkit/content/tests/chrome/findbar_events_window.xul
+++ b/toolkit/content/tests/chrome/findbar_events_window.xul
@@ -16,17 +16,17 @@
   <script type="application/javascript"><![CDATA[
     const Ci = Components.interfaces;
     const Cc = Components.classes;
     const Cr = Components.results;
 
     var gFindBar = null;
     var gBrowser;
 
-    var imports = ["SimpleTest", "ok"];
+    var imports = ["SimpleTest", "ok", "is"];
     for each (var name in imports) {
       window[name] = window.opener.wrappedJSObject[name];
     }
 
     function finish() {
       window.close();
       SimpleTest.finish();
     }
@@ -66,31 +66,38 @@
       gFindBar.open();
       gFindBar.onFindCommand();
       nextTest();
     }
 
     function checkSelection(done) {
       SimpleTest.executeSoon(function() {
         var selected = gBrowser.contentWindow.getSelection();
-        ok(selected == "", "No text is selected");
+        is(selected, "", "No text is selected");
 
         var controller = gFindBar.browser.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                  .getInterface(Ci.nsISelectionDisplay)
                                  .QueryInterface(Ci.nsISelectionController);
         var selection = controller.getSelection(controller.SELECTION_FIND);
-        ok(selection.rangeCount == 0, "No text is highlighted");
+        is(selection.rangeCount, 0, "No text is highlighted");
         done();
       });
     }
 
+    function once(node, eventName, callback) {
+      node.addEventListener(eventName, function clb(e) {
+        node.removeEventListener(eventName, clb);
+        callback(e);
+      })
+    }
+
     function testFind(done) {
-      var findTriggered = false;
+      var eventTriggered = false;
       var query = "t";
-      gFindBar.addEventListener("find", function(e) {
+      once(gFindBar, "find", function(e) {
         eventTriggered = true;
         ok(e.detail.query === query, "find event query should match '" + query + "'");
         e.preventDefault();
         // Since we're preventing the default make sure nothing was selected.
         checkSelection(done);
       });
 
       // Put some text in the find box.
@@ -98,44 +105,48 @@
       event.initKeyEvent("keypress", true, true, null, false, false,
                          false, false, 0, query.charCodeAt(0));
       gFindBar._findField.inputField.dispatchEvent(event);
       ok(eventTriggered, "find event should be triggered");
     }
 
     function testFindAgain(done) {
       var eventTriggered = false;
-      gFindBar.addEventListener("findagain", function(e) {
+      once(gFindBar, "findagain", function(e) {
         eventTriggered = true;
         e.preventDefault();
         // Since we're preventing the default make sure nothing was selected.
         checkSelection(done);
       });
 
       gFindBar.onFindAgainCommand();
       ok(eventTriggered, "findagain event should be triggered");
     }
 
     function testCaseSensitivity() {
       var eventTriggered = false;
-      gFindBar.addEventListener("findcasesensitivitychange", function(e) {
+      once(gFindBar, "findcasesensitivitychange", function(e) {
         eventTriggered = true;
         ok(e.detail.caseSensitive, "find should be case sensitive");
       });
 
       var matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
       matchCaseCheckbox.click();
       ok(eventTriggered, "findcasesensitivitychange should be triggered");
+
+      // Changing case sensitivity does the search so clear the selected text
+      // before the next test.
+      gBrowser.contentWindow.getSelection().removeAllRanges();
     }
 
     function testHighlight(done) {
       // Update the find state so the highlight button is clickable.
       gFindBar.updateControlState(Ci.nsITypeAheadFind.FIND_FOUND, false);
       var eventTriggered = false;
-      gFindBar.addEventListener("findhighlightallchange", function(e) {
+      once(gFindBar, "findhighlightallchange", function(e) {
         eventTriggered = true;
         ok(e.detail.highlightAll, "find event should have highlight all set");
         e.preventDefault();
         // Since we're preventing the default make sure nothing was highlighted.
         SimpleTest.executeSoon(function() {
           checkSelection(done);
         });
       });
--- a/toolkit/content/tests/chrome/findbar_window.xul
+++ b/toolkit/content/tests/chrome/findbar_window.xul
@@ -17,16 +17,19 @@
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"/>
 
   <script type="application/javascript"><![CDATA[
     const Ci = Components.interfaces;
     const Cc = Components.classes;
     const Cr = Components.results;
+    const Cu = Components.utils;
+    const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
+    var { Promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
 
     const SAMPLE_URL = "http://www.mozilla.org/";
     const SAMPLE_TEXT = "Some text in a text field.";
     const SEARCH_TEXT = "Text Test";
 
     var gFindBar = null;
     var gBrowser;
 
@@ -50,16 +53,19 @@
       },
 
       onBeforeLinkTraversal: function() { }
     };
 
     function ok(condition, message) {
       window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
     }
+    function is(a, b, message) {
+      window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
+    }
     function finish() {
       window.close();
       window.opener.wrappedJSObject.SimpleTest.finish();
     }
 
     function onLoad() {
       window.QueryInterface(Ci.nsIInterfaceRequestor)
             .getInterface(Ci.nsIWebNavigation)
@@ -78,46 +84,46 @@
       setTimeout(_delayedOnLoad, 1000);
     }
 
     function _delayedOnPageShow() {
       // setTimeout to the test runs after painting suppression ends
       setTimeout(onPageShow, 0);
     }
 
-    function onPageShow() {
+    let onPageShow = Task.async(function* () {
       testNormalFind();
       gFindBar.close();
       ok(gFindBar.hidden, "Failed to close findbar after testNormalFind");
       testNormalFindWithComposition();
       gFindBar.close();
       ok(gFindBar.hidden, "findbar should be hidden after testNormalFindWithComposition");
       testAutoCaseSensitivityUI();
       testQuickFindText();
       gFindBar.close();
       ok(gFindBar.hidden, "Failed to close findbar after testQuickFindText");
       testFindWithHighlight();
       gFindBar.close();
       ok(gFindBar.hidden, "Failed to close findbar after testFindWithHighlight");
       testFindbarSelection();
       testDrop();
       testQuickFindLink();
-      if (gHasFindClipboard)
-        testStatusText(afterStatusText);
-      else
-        afterStatusText();
-
-      function afterStatusText() {
-        testFindCountUI(function() {
-          gFindBar.close();
-          ok(gFindBar.hidden, "Failed to close findbar after testFindCountUI");
-          testQuickFindClose();
-        });
+      if (gHasFindClipboard) {
+        yield testStatusText();
       }
-    }
+      yield testFindCountUI();
+      gFindBar.close();
+      ok(gFindBar.hidden, "Failed to close findbar after testFindCountUI");
+      yield testFindAfterCaseChanged();
+      gFindBar.close();
+      yield testFailedStringReset();
+      gFindBar.close();
+      yield testQuickFindClose();
+      finish();
+    });
 
     function testFindbarSelection() {
       function checkFindbarState(aTestName, aExpSelection) {
         document.getElementById("cmd_find").doCommand();
         ok(!gFindBar.hidden, "testFindbarSelection: failed to open findbar: " + aTestName);
         ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
            "testFindbarSelection: find field is not focused: " + aTestName);
         if (!gHasFindClipboard) {
@@ -153,36 +159,40 @@
     }
 
     function testDrop()
     {
       gFindBar.open();
       // use an dummy image to start the drag so it doesn't get interrupted by a selection
       var img = gBrowser.contentDocument.getElementById("img");
       synthesizeDrop(img, gFindBar._findField, [[ {type: "text/plain", data: "Rabbits" } ]], "copy", window);
-      window.opener.wrappedJSObject.SimpleTest.is(gFindBar._findField.inputField.value, "Rabbits", "drop on findbar");
+      is(gFindBar._findField.inputField.value, "Rabbits", "drop on findbar");
       gFindBar.close();
     }
 
     function testQuickFindClose() {
+      let deferred = Promise.defer();
       var _isClosedCallback = function() {
         ok(gFindBar.hidden,
            "_isClosedCallback: Failed to auto-close quick find bar after " +
            gFindBar._quickFindTimeoutLength + "ms");
-        finish();
+        deferred.resolve();
       };
       setTimeout(_isClosedCallback, gFindBar._quickFindTimeoutLength + 100);
+      return deferred.promise;
     }
 
-    function testStatusText(aCallback) {
+    function testStatusText() {
+      let deferred = Promise.defer();
       var _delayedCheckStatusText = function() {
         ok(gStatusText == SAMPLE_URL, "testStatusText: Failed to set status text of found link");
-        aCallback();
+        deferred.resolve();
       };
       setTimeout(_delayedCheckStatusText, 100);
+      return deferred.promise;
     }
 
     function enterStringIntoFindField(aString) {
       for (var i=0; i < aString.length; i++) {
         var event = document.createEvent("KeyEvents");
         event.initKeyEvent("keypress", true, true, null, false, false,
                            false, false, 0, aString.charCodeAt(i));
         gFindBar._findField.inputField.dispatchEvent(event);
@@ -387,16 +397,18 @@
 
       enterStringIntoFindField(SEARCH_TEXT);
       ok(gBrowser.contentWindow.getSelection() == SEARCH_TEXT,
          "testQuickFindText: failed to find '" + SEARCH_TEXT + "'");
       testClipboardSearchString(SEARCH_TEXT);
     }
 
     function testFindCountUI(callback) {
+      let deferred = Promise.defer();
+
       clearFocus();
       document.getElementById("cmd_find").doCommand();
 
       ok(!gFindBar.hidden, "testFindCountUI: failed to open findbar");
       ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
          "testFindCountUI: find field is not focused");
 
       let matchCase = gFindBar.getElement("find-case-sensitive");
@@ -420,19 +432,19 @@
         text: "texxx",
         current: 0,
         total: 0
       }];
       let regex = /([\d]*)\sof\s([\d]*)/;
       let timeout = gFindBar._matchesCountTimeoutLength + 20;
 
       function assertMatches(aTest, aMatches) {
-        window.opener.wrappedJSObject.SimpleTest.is(aMatches[1], aTest.current,
+        is(aMatches[1], aTest.current,
           "Currently highlighted match should be at " + aTest.current);
-        window.opener.wrappedJSObject.SimpleTest.is(aMatches[2], aTest.total,
+        is(aMatches[2], aTest.total,
           "Total amount of matches should be " + aTest.total);
       }
 
       function* generatorTest() {
         for (let test of tests) {
           gFindBar.clear();
           yield;
           enterStringIntoFindField(test.text);
@@ -449,26 +461,74 @@
               let current = (test.current + i - 1) % test.total + 1;
               assertMatches({
                 current: current,
                 total: test.total
               }, foundMatches.value.match(regex));
             }
           }
         }
-        callback();
+        deferred.resolve();
       }
       let test = generatorTest();
       let resultListener = {
         onMatchesCountResult: function() {
           test.next();
         }
       };
       gFindBar.browser.finder.addResultListener(resultListener);
       test.next();
+      return deferred.promise;
+    }
+
+    // See bug 1051187.
+    function testFindAfterCaseChanged() {
+      let deferred = Promise.defer();
+      document.getElementById("cmd_find").doCommand();
+
+      // Search to set focus on "Text Test" so that searching for "t" selects first
+      // (upper case!) "T".
+      enterStringIntoFindField(SEARCH_TEXT);
+      gFindBar.clear();
+
+      let prefsvc = Cc["@mozilla.org/preferences-service;1"]
+                      .getService(Ci.nsIPrefBranch);
+      prefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 0);
+
+      enterStringIntoFindField("t");
+      is(gBrowser.contentWindow.getSelection(), "T", "First T should be selected.");
+
+      prefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 1);
+      setTimeout(function() {
+        is(gBrowser.contentWindow.getSelection(), "t", "First t should be selected.");
+        deferred.resolve();
+      }, 0);
+      return deferred.promise;
+    }
+
+    // Make sure that _findFailedString is cleared:
+    // 1. Do a search that fails with case sensitivity but matches with no case sensitivity.
+    // 2. Uncheck case sensitivity button to match the string.
+    function testFailedStringReset(aCallback) {
+      let deferred = Promise.defer();
+      document.getElementById("cmd_find").doCommand();
+
+      var prefsvc = Cc["@mozilla.org/preferences-service;1"].
+                    getService(Components.interfaces.nsIPrefBranch);
+      prefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 1);
+
+      enterStringIntoFindField(SEARCH_TEXT.toUpperCase());
+      is(gBrowser.contentWindow.getSelection(), "", "Not found.");
+
+      prefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 0);
+      setTimeout(function() {
+        is(gBrowser.contentWindow.getSelection(), SEARCH_TEXT, "Search text should be selected.");
+        deferred.resolve();
+      }, 0);
+      return deferred.resolve();
     }
 
     function testClipboardSearchString(aExpected) {
       if (!gHasFindClipboard)
         return;
 
       if (!aExpected)
         aExpected = "";
--- a/toolkit/content/widgets/findbar.xml
+++ b/toolkit/content/widgets/findbar.xml
@@ -533,16 +533,18 @@
         -   2 - auto = case sensitive iff match string contains upper case letters
         -   @see _shouldBeCaseSensitive
         -->
       <method name="_setCaseSensitivity">
         <parameter name="aCaseSensitivity"/>
         <body><![CDATA[
           this._typeAheadCaseSensitive = aCaseSensitivity;
           this._updateCaseSensitivity();
+          this._findFailedString = null;
+          this._find();
           if (this.getElement("highlight").checked)
             this._setHighlightTimeout();
 
           this._dispatchFindEvent("casesensitivitychange");
         ]]></body>
       </method>
 
       <field name="_strBundle">null</field>