Bug 1234186 - Unified autocompletion Visit feature doesn't use https for https-only websites. r=adw
authorMarco Bonardo <mbonardo@mozilla.com>
Tue, 19 Jan 2016 00:39:57 +0100
changeset 303112 55dd1f2654bdf945bdb9300abaac4c0b4ac0abd3
parent 303111 8fc9a5eeede3b4551dbcbf0a77fe40349914c83e
child 303113 bc225865b5e26e77ee247988054e7a60d5bde08e
push id8978
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 14:05:32 +0000
treeherdermozilla-aurora@b9a803752a2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw
bugs1234186
milestone46.0a1
Bug 1234186 - Unified autocompletion Visit feature doesn't use https for https-only websites. r=adw
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/autocomplete/tests/unit/test_finalCompleteValue.js
toolkit/components/autocomplete/tests/unit/test_finalCompleteValue_defaultIndex.js
toolkit/components/autocomplete/tests/unit/xpcshell.ini
--- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
@@ -1374,44 +1374,49 @@ nsAutoCompleteController::EnterMatch(boo
     bool shouldComplete;
     input->GetCompleteDefaultIndex(&shouldComplete);
     bool completeSelection;
     input->GetCompleteSelectedIndex(&completeSelection);
 
     int32_t selectedIndex;
     popup->GetSelectedIndex(&selectedIndex);
     if (selectedIndex >= 0) {
+
+      nsAutoString inputValue;
+      input->GetTextValue(inputValue);
       nsAutoString finalValue;
-      // If completeselectedindex is false or a row was selected from the popup,
-      // enter it into the textbox.
-      if (!completeSelection || aIsPopupSelection) {
+      if (!completeSelection || aIsPopupSelection ||
+          (mDefaultIndexCompleted &&
+           inputValue.Equals(mPlaceholderCompletionString,
+                             nsCaseInsensitiveStringComparator()))) {
+        // We need to fill-in the value if:
+        //  * completeselectedindex is false
+        //  * A row in the popup was confirmed
+        //  * The default index completion was confirmed
         GetResultValueAt(selectedIndex, true, finalValue);
         value = finalValue;
       } else if (mCompletedSelectionIndex != -1) {
         // If completeselectedindex is true, and EnterMatch was not invoked by
         // mouse-clicking a match (for example the user pressed Enter),
         // don't fill in the value as it will have already been filled in as
         // needed, unless the selected match has a final complete value that
         // differs from the user-facing value.
         GetResultValueAt(mCompletedSelectionIndex, true, finalValue);
-        nsAutoString inputValue;
-        input->GetTextValue(inputValue);
         nsAutoString completedValue;
         GetResultValueAt(mCompletedSelectionIndex, false, completedValue);
         if (completedValue.Equals(inputValue) && !finalValue.Equals(inputValue)) {
           value = finalValue;
         }
         // Note that if the user opens the popup, mouses over entries without
         // ever selecting one with the keyboard, and then hits enter, none of
-        // the above cases will be hitt, since mouseover doesn't activate
+        // the above cases will be hit, since mouseover doesn't activate
         // completeselectedindex and thus mCompletedSelectionIndex would be
         // -1.
       }
-    }
-    else if (shouldComplete) {
+    } else if (shouldComplete) {
       // We usually try to preserve the casing of what user has typed, but
       // if he wants to autocomplete, we will replace the value with the
       // actual autocomplete result.
       // The user wants explicitely to use that result, so this ensures
       // association of the result with the autocompleted text.
       nsAutoString defaultIndexValue;
       if (NS_SUCCEEDED(GetFinalDefaultCompleteValue(defaultIndexValue)))
         value = defaultIndexValue;
@@ -1929,22 +1934,27 @@ nsAutoCompleteController::GetResultValue
   result->GetSearchResult(&searchResult);
 
   if (searchResult == nsIAutoCompleteResult::RESULT_FAILURE) {
     if (aGetValue)
       return NS_ERROR_FAILURE;
     result->GetErrorDescription(_retval);
   } else if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
              searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
-    if (aGetFinalValue)
-      result->GetFinalCompleteValueAt(rowIndex, _retval);
-    else if (aGetValue)
+    if (aGetFinalValue) {
+      // Some implementations may miss finalCompleteValue, try to be backwards
+      // compatible.
+      if (NS_FAILED(result->GetFinalCompleteValueAt(rowIndex, _retval))) {
+        result->GetValueAt(rowIndex, _retval);
+      }
+    } else if (aGetValue) {
       result->GetValueAt(rowIndex, _retval);
-    else
+    } else {
       result->GetLabelAt(rowIndex, _retval);
+    }
   }
 
   return NS_OK;
 }
 
 /**
  * Given the index of a row in the autocomplete popup, find the
  * corresponding nsIAutoCompleteSearch index, and sub-index into
--- a/toolkit/components/autocomplete/tests/unit/test_finalCompleteValue.js
+++ b/toolkit/components/autocomplete/tests/unit/test_finalCompleteValue.js
@@ -5,25 +5,23 @@ function AutoCompleteResult(aValues, aFi
 AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
 
 function AutoCompleteInput(aSearches) {
   this.searches = aSearches;
   this.popup.selectedIndex = 0;
 }
 AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
 
-function run_test() {
-  run_next_test();
-}
-
-add_test(function test_handleEnter() {
+add_test(function test_handleEnter_mouse() {
   doSearch("moz", "mozilla.com", "http://www.mozilla.com", function(aController) {
     do_check_eq(aController.input.textValue, "moz");
     do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
-    aController.handleEnter(false);
+    // Keyboard interaction is tested by test_finalCompleteValueSelectedIndex.js
+    // so here just test popup selection.
+    aController.handleEnter(true);
     do_check_eq(aController.input.textValue, "http://www.mozilla.com");
   });
 });
 
 function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteCallback) {
   let search = new AutoCompleteSearchBase(
     "search",
     new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
new file mode 100644
--- /dev/null
+++ b/toolkit/components/autocomplete/tests/unit/test_finalCompleteValue_defaultIndex.js
@@ -0,0 +1,58 @@
+function AutoCompleteResult(aResultValues) {
+  this.defaultIndex = 0;
+  this._values = aResultValues.map(x => x[0]);
+  this._finalCompleteValues = aResultValues.map(x => x[1]);
+}
+AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
+
+function AutoCompleteInput(aSearches) {
+  this.searches = aSearches;
+  this.popup.selectedIndex = 0;
+  this.completeSelectedIndex = true;
+  this.completeDefaultIndex = true;
+}
+AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
+
+add_test(function test_handleEnter() {
+  let results = [
+    ["mozilla.com", "https://www.mozilla.com"],
+    ["gomozilla.org", "http://www.gomozilla.org"],
+  ];
+  doSearch("moz", results, controller => {
+    let input = controller.input;
+    Assert.equal(input.textValue, "mozilla.com");
+    Assert.equal(controller.getFinalCompleteValueAt(0), results[0][1]);
+    Assert.equal(controller.getFinalCompleteValueAt(1), results[1][1]);
+    Assert.equal(input.popup.selectedIndex, 0);
+
+    controller.handleEnter(false);
+    // Verify that the keyboard-selected thing got inserted,
+    // and not the mouse selection:
+    Assert.equal(controller.input.textValue, "https://www.mozilla.com");
+  });
+});
+
+function doSearch(aSearchString, aResults, aOnCompleteCallback) {
+  let search = new AutoCompleteSearchBase(
+    "search",
+    new AutoCompleteResult(aResults)
+  );
+  registerAutoCompleteSearch(search);
+
+  let input = new AutoCompleteInput([ search.name ]);
+  input.textValue = aSearchString;
+  // Needed for defaultIndex completion.
+  input.selectTextRange(aSearchString.length, aSearchString.length);
+
+  let controller = Cc["@mozilla.org/autocomplete/controller;1"].
+                   getService(Ci.nsIAutoCompleteController);
+  controller.input = input;
+  controller.startSearch(aSearchString);
+
+  input.onSearchComplete = function onSearchComplete() {
+    aOnCompleteCallback(controller);
+
+    unregisterAutoCompleteSearch(search);
+    run_next_test();
+  };
+}
--- a/toolkit/components/autocomplete/tests/unit/xpcshell.ini
+++ b/toolkit/components/autocomplete/tests/unit/xpcshell.ini
@@ -9,16 +9,17 @@ skip-if = toolkit == 'gonk'
 [test_440866.js]
 [test_463023.js]
 [test_660156.js]
 [test_autocomplete_multiple.js]
 [test_autofillSelectedPopupIndex.js]
 [test_badDefaultIndex.js]
 [test_completeDefaultIndex_casing.js]
 [test_finalCompleteValue.js]
+[test_finalCompleteValue_defaultIndex.js]
 [test_finalCompleteValue_forceComplete.js]
 [test_finalCompleteValueSelectedIndex.js]
 [test_finalDefaultCompleteValue.js]
 [test_hiddenResult.js]
 [test_immediate_search.js]
 [test_insertMatchAt.js]
 [test_popupSelectionVsDefaultCompleteValue.js]
 [test_previousResult.js]