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 232143 d5a592a6504455c58e4e769ac5f6f2d6d6b2bc04
parent 232142 76e64cc73ccf87031cdbfe5d91f8821de073487f
child 232144 8c0ced0c0ab1c1737acad57713369407884ea3a0
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1051187
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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>