Bug 1435711 - Remove controller support for tree autocomplete. r=paolo draft
authorMarco Bonardo <mbonardo@mozilla.com>
Sat, 17 Feb 2018 18:11:13 +0100
changeset 757280 de12aff76f538ab58b804792d6aaf8e126bfa79a
parent 756852 ad133cd410a719c0b67e61b8d3b1c77a32fd80a9
push id99739
push usermak77@bonardo.net
push dateTue, 20 Feb 2018 16:20:06 +0000
reviewerspaolo
bugs1435711
milestone60.0a1
Bug 1435711 - Remove controller support for tree autocomplete. r=paolo MozReview-Commit-ID: 5NJu2ILBP5h
browser/base/content/urlbarBindings.xml
browser/components/search/content/search.xml
browser/components/search/test/browser_searchbar_keyboard_navigation.js
browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/autocomplete/nsAutoCompleteController.h
toolkit/content/widgets/autocomplete.xml
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1820,18 +1820,17 @@ file, You can obtain one at http://mozil
       <method name="onPopupClick">
         <parameter name="aEvent"/>
         <body><![CDATA[
           if (aEvent.button == 2) {
             // Ignore right-clicks.
             return;
           }
           // Otherwise "call super" -- do what autocomplete-base-popup does.
-          let controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
-          controller.handleEnter(true, aEvent);
+          this.input.controller.handleEnter(true, aEvent);
         ]]></body>
       </method>
 
       <method name="enableOneOffSearches">
         <parameter name="enable"/>
         <body><![CDATA[
           this._oneOffSearchesEnabled = enable;
           if (enable) {
@@ -2043,17 +2042,16 @@ file, You can obtain one at http://mozil
             this.margins = undefined;
             needsHandleOverUnderflow = true;
           }
 
           // Now that the margins have been set, start adding items (via
           // _invalidate).
           this.mInput = aInput;
           aInput.controller.setInitiallySelectedIndex(this._isFirstResultHeuristic ? 0 : -1);
-          this.view = aInput.controller.QueryInterface(Components.interfaces.nsITreeView);
           this._invalidate();
 
           try {
             let whichNotification = aInput.whichSearchSuggestionsNotification;
             if (whichNotification != "none") {
               // Update the impressions count on real popupshown, since there's
               // no guarantee openPopup will be respected by the platform.
               // Though, we must ensure the handled event is the expected one.
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -954,43 +954,41 @@
 
       <method name="onPopupClick">
         <parameter name="aEvent"/>
         <body><![CDATA[
           // Ignore all right-clicks
           if (aEvent.button == 2)
             return;
 
-          var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
-
           var searchBar = BrowserSearch.searchBar;
           var popupForSearchBar = searchBar && searchBar.textbox == this.mInput;
           if (popupForSearchBar) {
             searchBar.telemetrySearchDetails = {
               index: this.selectedIndex,
               kind: "mouse"
             };
           }
 
           // Check for unmodified left-click, and use default behavior
           if (aEvent.button == 0 && !aEvent.shiftKey && !aEvent.ctrlKey &&
               !aEvent.altKey && !aEvent.metaKey) {
-            controller.handleEnter(true, aEvent);
+            this.input.controller.handleEnter(true, aEvent);
             return;
           }
 
           // Check for middle-click or modified clicks on the search bar
           if (popupForSearchBar) {
             BrowserUsageTelemetry.recordSearchbarSelectedResultMethod(
               aEvent,
               this.selectedIndex
             );
 
             // Handle search bar popup clicks
-            var search = controller.getValueAt(this.selectedIndex);
+            var search = this.input.controller.getValueAt(this.selectedIndex);
 
             // open the search results according to the clicking subtlety
             var where = whereToOpenLink(aEvent, false, true);
             let params = {};
 
             // But open ctrl/cmd clicks on autocomplete items in a new background tab.
             let modifier = AppConstants.platform == "macosx" ?
                            aEvent.metaKey :
@@ -998,17 +996,17 @@
             if (where == "tab" && (aEvent instanceof MouseEvent) &&
                 (aEvent.button == 1 || modifier))
               params.inBackground = true;
 
             // leave the popup open for background tab loads
             if (!(where == "tab" && params.inBackground)) {
               // close the autocomplete popup and revert the entered search term
               this.closePopup();
-              controller.handleEscape();
+              this.input.controller.handleEscape();
             }
 
             searchBar.doSearch(search, where, null, params);
             if (where == "tab" && params.inBackground)
               searchBar.focus();
             else
               searchBar.value = search;
           }
--- a/browser/components/search/test/browser_searchbar_keyboard_navigation.js
+++ b/browser/components/search/test/browser_searchbar_keyboard_navigation.js
@@ -74,17 +74,17 @@ add_task(async function init() {
 add_task(async function test_arrows() {
   let promise = promiseEvent(searchPopup, "popupshown");
   info("Opening search panel");
   searchbar.focus();
   await promise;
   is(textbox.mController.searchString, kUserValue, "The search string should be 'foo'");
 
   // Check the initial state of the panel before sending keyboard events.
-  is(searchPopup.view.rowCount, kValues.length, "There should be 3 suggestions");
+  is(searchPopup.matchCount, kValues.length, "There should be 3 suggestions");
   is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
 
   // The tests will be less meaningful if the first, second, last, and
   // before-last one-off buttons aren't different. We should always have more
   // than 4 default engines, but it's safer to check this assumption.
   let oneOffs = getOneOffs();
   ok(oneOffs.length >= 4, "we have at least 4 one-off buttons displayed");
 
--- a/browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js
+++ b/browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js
@@ -78,17 +78,17 @@ add_task(async function test_arrows() {
   await promise;
 info("textbox.mController.searchString = " + textbox.mController.searchString);
   is(textbox.mController.searchString, "", "The search string should be empty");
 
   // Check the initial state of the panel before sending keyboard events.
   is(searchPopup.getAttribute("showonlysettings"), "true", "Should show the small popup");
   // Having suggestions populated (but hidden) is important, because if there
   // are none we can't ensure the keyboard events don't reach them.
-  is(searchPopup.view.rowCount, kValues.length, "There should be 3 suggestions");
+  is(searchPopup.matchCount, kValues.length, "There should be 3 suggestions");
   is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
 
   // The tests will be less meaningful if the first, second, last, and
   // before-last one-off buttons aren't different. We should always have more
   // than 4 default engines, but it's safer to check this assumption.
   let oneOffs = getOneOffs();
   ok(oneOffs.length >= 4, "we have at least 4 one-off buttons displayed");
 
--- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
@@ -9,18 +9,16 @@
 #include "nsAutoPtr.h"
 #include "nsNetCID.h"
 #include "nsIIOService.h"
 #include "nsToolkitCompsCID.h"
 #include "nsIServiceManager.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsITreeBoxObject.h"
-#include "nsITreeColumns.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/Unused.h"
 #include "mozilla/dom/KeyboardEventBinding.h"
 
 static const char *kAutoCompleteSearchCID = "@mozilla.org/autocomplete/search;1?name=";
 
@@ -30,39 +28,38 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsAutoCom
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAutoCompleteController)
   tmp->SetInput(nullptr);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAutoCompleteController)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInput)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearches)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResults)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResultCache)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAutoCompleteController)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAutoCompleteController)
 NS_INTERFACE_TABLE_HEAD(nsAutoCompleteController)
   NS_INTERFACE_TABLE(nsAutoCompleteController, nsIAutoCompleteController,
-                     nsIAutoCompleteObserver, nsITimerCallback, nsITreeView,
-                     nsINamed)
+                     nsIAutoCompleteObserver, nsITimerCallback, nsINamed)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsAutoCompleteController)
 NS_INTERFACE_MAP_END
 
 nsAutoCompleteController::nsAutoCompleteController() :
   mDefaultIndexCompleted(false),
   mPopupClosedByCompositionStart(false),
   mProhibitAutoFill(false),
   mUserClearedAutoFill(false),
   mClearingAutoFillSearchesAgain(false),
   mCompositionState(eCompositionState_None),
   mSearchStatus(nsAutoCompleteController::STATUS_NONE),
-  mRowCount(0),
+  mMatchCount(0),
   mSearchesOngoing(0),
   mSearchesFailed(0),
-  mDelayedRowCountDelta(0),
   mImmediateSearchesCount(0),
   mCompletedSelectionIndex(-1)
 {
 }
 
 nsAutoCompleteController::~nsAutoCompleteController()
 {
   SetInput(nullptr);
@@ -88,17 +85,17 @@ nsAutoCompleteController::GetSearchStatu
 {
   *aSearchStatus = mSearchStatus;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetMatchCount(uint32_t *aMatchCount)
 {
-  *aMatchCount = mRowCount;
+  *aMatchCount = mMatchCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetInput(nsIAutoCompleteInput **aInput)
 {
   *aInput = mInput;
   NS_IF_ADDREF(*aInput);
@@ -146,19 +143,16 @@ nsAutoCompleteController::SetInput(nsIAu
   }
   nsCOMPtr<nsIAutoCompleteInput> input(mInput);
 
   // Reset the current search string.
   nsAutoString value;
   input->GetTextValue(value);
   SetSearchStringInternal(value);
 
-  // Clear out this reference in case the new input's popup has no tree
-  mTree = nullptr;
-
   // Since the controller can be used as a service it's important to reset this.
   mClearingAutoFillSearchesAgain = false;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::ResetInternalState()
@@ -172,18 +166,17 @@ nsAutoCompleteController::ResetInternalS
     Unused << ClearResults();
     SetSearchStringInternal(value);
   }
 
   mPlaceholderCompletionString.Truncate();
   mDefaultIndexCompleted = false;
   mProhibitAutoFill = false;
   mSearchStatus = nsIAutoCompleteController::STATUS_NONE;
-  mRowCount = 0;
-  mDelayedRowCountDelta = 0;
+  mMatchCount = 0;
   mCompletedSelectionIndex = -1;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::StartSearch(const nsAString &aSearchString)
 {
@@ -530,17 +523,17 @@ nsAutoCompleteController::HandleKeyNavig
       }
 #endif
       if (*_retval) {
         nsAutoString oldSearchString;
         // Open the popup if there has been a previous search, or else kick off a new search
         if (!mResults.IsEmpty() &&
             NS_SUCCEEDED(mResults[0]->GetSearchString(oldSearchString)) &&
             oldSearchString.Equals(mSearchString, nsCaseInsensitiveStringComparator())) {
-          if (mRowCount) {
+          if (mMatchCount) {
             OpenPopup();
           }
         } else {
           // Stop all searches in case they are async.
           StopSearch();
 
           if (!mInput) {
             // StopSearch() can call PostSearchCleanup() which might result
@@ -571,17 +564,17 @@ nsAutoCompleteController::HandleKeyNavig
     bool isOpen = false;
     input->GetPopupOpen(&isOpen);
 
     // If minresultsforpopup > 1 and there's less matches than the minimum
     // required, the popup is not open, but the search suggestion is showing
     // inline, so we should proceed as if we had the popup.
     uint32_t minResultsForPopup;
     input->GetMinResultsForPopup(&minResultsForPopup);
-    if (isOpen || (mRowCount > 0 && mRowCount < minResultsForPopup)) {
+    if (isOpen || (mMatchCount > 0 && mMatchCount < minResultsForPopup)) {
       // For completeSelectedIndex autocomplete fields, if the popup shouldn't
       // close when the caret is moved, don't adjust the text value or caret
       // position.
       if (isOpen) {
         bool noRollup;
         input->GetNoRollupOnCaretMove(&noRollup);
         if (noRollup) {
           bool completeSelection;
@@ -653,65 +646,61 @@ nsAutoCompleteController::HandleDelete(b
 {
   *_retval = false;
   if (!mInput)
     return NS_OK;
 
   nsCOMPtr<nsIAutoCompleteInput> input(mInput);
   bool isOpen = false;
   input->GetPopupOpen(&isOpen);
-  if (!isOpen || mRowCount == 0) {
+  if (!isOpen || mMatchCount == 0) {
     // Nothing left to delete, proceed as normal
     bool unused = false;
     HandleText(&unused);
     return NS_OK;
   }
 
   nsCOMPtr<nsIAutoCompletePopup> popup;
   input->GetPopup(getter_AddRefs(popup));
 
-  int32_t index, searchIndex, rowIndex;
+  int32_t index, searchIndex, matchIndex;
   popup->GetSelectedIndex(&index);
   if (index == -1) {
-    // No row is selected in the list
+    // No match is selected in the list
     bool unused = false;
     HandleText(&unused);
     return NS_OK;
   }
 
-  RowIndexToSearch(index, &searchIndex, &rowIndex);
-  NS_ENSURE_TRUE(searchIndex >= 0 && rowIndex >= 0, NS_ERROR_FAILURE);
+  MatchIndexToSearch(index, &searchIndex, &matchIndex);
+  NS_ENSURE_TRUE(searchIndex >= 0 && matchIndex >= 0, NS_ERROR_FAILURE);
 
   nsIAutoCompleteResult *result = mResults.SafeObjectAt(searchIndex);
   NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
 
   nsAutoString search;
   input->GetSearchParam(search);
 
-  // Clear the row in our result and in the DB.
-  result->RemoveValueAt(rowIndex, true);
-  --mRowCount;
+  // Clear the match in our result and in the DB.
+  result->RemoveValueAt(matchIndex, true);
+  --mMatchCount;
 
   // We removed it, so make sure we cancel the event that triggered this call.
   *_retval = true;
 
   // Unselect the current item.
   popup->SetSelectedIndex(-1);
 
-  // Tell the tree that the row count changed.
-  if (mTree)
-    mTree->RowCountChanged(mRowCount, -1);
+  // Adjust index, if needed.
+  MOZ_ASSERT(index >= 0); // We verified this above, after MatchIndexToSearch.
+  if (static_cast<uint32_t>(index) >= mMatchCount)
+    index = mMatchCount - 1;
 
-  // Adjust index, if needed.
-  MOZ_ASSERT(index >= 0); // We verified this above, after RowIndexToSearch.
-  if (static_cast<uint32_t>(index) >= mRowCount)
-    index = mRowCount - 1;
-
-  if (mRowCount > 0) {
-    // There are still rows in the popup, select the current index again.
+  if (mMatchCount > 0) {
+    // There are still matches in the popup, select the current index again.
     popup->SetSelectedIndex(index);
 
     // Complete to the new current value.
     bool shouldComplete = false;
     input->GetCompleteDefaultIndex(&shouldComplete);
     if (shouldComplete) {
       nsAutoString value;
       if (NS_SUCCEEDED(GetResultValueAt(index, false, value))) {
@@ -732,21 +721,21 @@ nsAutoCompleteController::HandleDelete(b
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 nsAutoCompleteController::GetResultAt(int32_t aIndex, nsIAutoCompleteResult** aResult,
-                                      int32_t* aRowIndex)
+                                      int32_t* aMatchIndex)
 {
   int32_t searchIndex;
-  RowIndexToSearch(aIndex, &searchIndex, aRowIndex);
-  NS_ENSURE_TRUE(searchIndex >= 0 && *aRowIndex >= 0, NS_ERROR_FAILURE);
+  MatchIndexToSearch(aIndex, &searchIndex, aMatchIndex);
+  NS_ENSURE_TRUE(searchIndex >= 0 && *aMatchIndex >= 0, NS_ERROR_FAILURE);
 
   *aResult = mResults.SafeObjectAt(searchIndex);
   NS_ENSURE_TRUE(*aResult, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetValueAt(int32_t aIndex, nsAString & _retval)
@@ -762,111 +751,97 @@ nsAutoCompleteController::GetLabelAt(int
   GetResultLabelAt(aIndex, _retval);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetCommentAt(int32_t aIndex, nsAString & _retval)
 {
-  int32_t rowIndex;
+  int32_t matchIndex;
   nsIAutoCompleteResult* result;
-  nsresult rv = GetResultAt(aIndex, &result, &rowIndex);
+  nsresult rv = GetResultAt(aIndex, &result, &matchIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return result->GetCommentAt(rowIndex, _retval);
+  return result->GetCommentAt(matchIndex, _retval);
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetStyleAt(int32_t aIndex, nsAString & _retval)
 {
-  int32_t rowIndex;
+  int32_t matchIndex;
   nsIAutoCompleteResult* result;
-  nsresult rv = GetResultAt(aIndex, &result, &rowIndex);
+  nsresult rv = GetResultAt(aIndex, &result, &matchIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return result->GetStyleAt(rowIndex, _retval);
+  return result->GetStyleAt(matchIndex, _retval);
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetImageAt(int32_t aIndex, nsAString & _retval)
 {
-  int32_t rowIndex;
+  int32_t matchIndex;
   nsIAutoCompleteResult* result;
-  nsresult rv = GetResultAt(aIndex, &result, &rowIndex);
+  nsresult rv = GetResultAt(aIndex, &result, &matchIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return result->GetImageAt(rowIndex, _retval);
+  return result->GetImageAt(matchIndex, _retval);
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetFinalCompleteValueAt(int32_t aIndex,
                                                   nsAString & _retval)
 {
-  int32_t rowIndex;
+  int32_t matchIndex;
   nsIAutoCompleteResult* result;
-  nsresult rv = GetResultAt(aIndex, &result, &rowIndex);
+  nsresult rv = GetResultAt(aIndex, &result, &matchIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return result->GetFinalCompleteValueAt(rowIndex, _retval);
+  return result->GetFinalCompleteValueAt(matchIndex, _retval);
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::SetSearchString(const nsAString &aSearchString)
 {
   SetSearchStringInternal(aSearchString);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAutoCompleteController::GetSearchString(nsAString &aSearchString)
 {
   aSearchString = mSearchString;
   return NS_OK;
 }
 
-void
-nsAutoCompleteController::HandleSearchResult(nsIAutoCompleteSearch *aSearch,
-                                             nsIAutoCompleteResult *aResult)
-{
-  // Look up the index of the search which is returning.
-  for (uint32_t i = 0; i < mSearches.Length(); ++i) {
-    if (mSearches[i] == aSearch) {
-      ProcessResult(i, aResult);
-    }
-  }
-}
-
-
 ////////////////////////////////////////////////////////////////////////
 //// nsIAutoCompleteObserver
 
 NS_IMETHODIMP
 nsAutoCompleteController::OnSearchResult(nsIAutoCompleteSearch *aSearch, nsIAutoCompleteResult* aResult)
 {
   MOZ_ASSERT(mSearchesOngoing > 0 && mSearches.Contains(aSearch));
 
-  // Update the tree if necessary.
-  if (mTree && mDelayedRowCountDelta != 0) {
-    mTree->RowCountChanged(0, mDelayedRowCountDelta);
-    mDelayedRowCountDelta = 0;
-  }
-
   uint16_t result = 0;
   if (aResult) {
     aResult->GetSearchResult(&result);
   }
 
   // If our results are incremental, the search is still ongoing.
   if (result != nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING &&
       result != nsIAutoCompleteResult::RESULT_NOMATCH_ONGOING) {
     --mSearchesOngoing;
   }
 
-  HandleSearchResult(aSearch, aResult);
+  // Look up the index of the search which is returning.
+  for (uint32_t i = 0; i < mSearches.Length(); ++i) {
+    if (mSearches[i] == aSearch) {
+      ProcessResult(i, aResult);
+    }
+  }
 
   if (mSearchesOngoing == 0) {
     // If this is the last search to return, cleanup.
     PostSearchCleanup();
   }
 
   return NS_OK;
 }
@@ -897,249 +872,25 @@ nsAutoCompleteController::Notify(nsITime
 NS_IMETHODIMP
 nsAutoCompleteController::GetName(nsACString& aName)
 {
   aName.AssignLiteral("nsAutoCompleteController");
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////
-// nsITreeView
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetRowCount(int32_t *aRowCount)
-{
-  *aRowCount = mRowCount;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetRowProperties(int32_t index, nsAString& aProps)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetCellProperties(int32_t row, nsITreeColumn* col,
-                                            nsAString& aProps)
-{
-  if (row >= 0) {
-    GetStyleAt(row, aProps);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetColumnProperties(nsITreeColumn* col, nsAString& aProps)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetImageSrc(int32_t row, nsITreeColumn* col, nsAString& _retval)
-{
-  const char16_t* colID;
-  col->GetIdConst(&colID);
-
-  if (NS_LITERAL_STRING("treecolAutoCompleteValue").Equals(colID))
-    return GetImageAt(row, _retval);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetCellValue(int32_t row, nsITreeColumn* col, nsAString& _retval)
-{
-  NS_NOTREACHED("all of our cells are text");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetCellText(int32_t row, nsITreeColumn* col, nsAString& _retval)
-{
-  const char16_t* colID;
-  col->GetIdConst(&colID);
-
-  if (NS_LITERAL_STRING("treecolAutoCompleteValue").Equals(colID))
-    GetValueAt(row, _retval);
-  else if (NS_LITERAL_STRING("treecolAutoCompleteComment").Equals(colID))
-    GetCommentAt(row, _retval);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::IsContainer(int32_t index, bool *_retval)
-{
-  *_retval = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::IsContainerOpen(int32_t index, bool *_retval)
-{
-  NS_NOTREACHED("no container cells");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::IsContainerEmpty(int32_t index, bool *_retval)
-{
-  NS_NOTREACHED("no container cells");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetLevel(int32_t index, int32_t *_retval)
-{
-  *_retval = 0;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetParentIndex(int32_t rowIndex, int32_t *_retval)
-{
-  *_retval = -1;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::HasNextSibling(int32_t rowIndex, int32_t afterIndex, bool *_retval)
-{
-  *_retval = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::ToggleOpenState(int32_t index)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::SetTree(nsITreeBoxObject *tree)
-{
-  mTree = tree;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::GetSelection(nsITreeSelection * *aSelection)
-{
-  *aSelection = mSelection;
-  NS_IF_ADDREF(*aSelection);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsAutoCompleteController::SetSelection(nsITreeSelection * aSelection)
-{
-  mSelection = aSelection;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::SelectionChanged()
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::SetCellValue(int32_t row, nsITreeColumn* col, const nsAString& value)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::SetCellText(int32_t row, nsITreeColumn* col, const nsAString& value)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::CycleHeader(nsITreeColumn* col)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::CycleCell(int32_t row, nsITreeColumn* col)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::IsEditable(int32_t row, nsITreeColumn* col, bool *_retval)
-{
-  *_retval = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::IsSelectable(int32_t row, nsITreeColumn* col, bool *_retval)
-{
-  *_retval = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::IsSeparator(int32_t index, bool *_retval)
-{
-  *_retval = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::IsSorted(bool *_retval)
-{
-  *_retval = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::CanDrop(int32_t index, int32_t orientation,
-                                  nsIDOMDataTransfer* dataTransfer, bool *_retval)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::Drop(int32_t row, int32_t orientation, nsIDOMDataTransfer* dataTransfer)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::PerformAction(const char16_t *action)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::PerformActionOnRow(const char16_t *action, int32_t row)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAutoCompleteController::PerformActionOnCell(const char16_t* action, int32_t row, nsITreeColumn* col)
-{
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////
 //// nsAutoCompleteController
 
 nsresult
 nsAutoCompleteController::OpenPopup()
 {
   uint32_t minResults;
   mInput->GetMinResultsForPopup(&minResults);
 
-  if (mRowCount >= minResults) {
+  if (mMatchCount >= minResults) {
     return mInput->SetPopupOpen(true);
   }
 
   return NS_OK;
 }
 
 nsresult
 nsAutoCompleteController::ClosePopup()
@@ -1171,19 +922,16 @@ nsAutoCompleteController::BeforeSearches
   mDefaultIndexCompleted = false;
 
   // ClearResults will clear the mResults array, but we should pass the previous
   // result to each search to allow reusing it.  So we temporarily cache the
   // current results until AfterSearches().
   if (!mResultCache.AppendObjects(mResults)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
-  // The rowCountChanged notification is sent later, when the first result
-  // from the search arrives, to avoid flickering in the tree contents.
-  mDelayedRowCountDelta = 0;
   ClearResults(true);
   mSearchesOngoing = mSearches.Length();
   mSearchesFailed = 0;
 
   // notify the input that the search is beginning
   mInput->OnSearchBegin();
 
   return NS_OK;
@@ -1457,26 +1205,17 @@ nsAutoCompleteController::EnterMatch(boo
     int32_t selectedIndex;
     popup->GetSelectedIndex(&selectedIndex);
     if (selectedIndex >= 0) {
       nsAutoString inputValue;
       input->GetTextValue(inputValue);
       if (aIsPopupSelection || !completeSelection) {
         // We need to fill-in the value if:
         //  * completeselectedindex is false
-        //  * A row in the popup was confirmed
-        //
-        // TODO: This is not totally correct, cause it will also confirm
-        // a result selected with a simple mouseover, that could also have
-        // happened accidentally, maybe touching a touchpad.
-        // The reason is that autocomplete.xml sets selectedIndex on mousemove
-        // making impossible, in the !completeSelection case, to distinguish if
-        // the user wanted to confirm autoFill or the popup entry.
-        // The solution may be to change autocomplete.xml to set selectedIndex
-        // only on popupClick, but that requires changing the selection behavior.
+        //  * A match in the popup was confirmed
         GetResultValueAt(selectedIndex, true, value);
       } else if (mDefaultIndexCompleted &&
                  inputValue.Equals(mPlaceholderCompletionString,
                                    nsCaseInsensitiveStringComparator())) {
         // We also need to fill-in the value if the default index completion was
         // confirmed, though we cannot use the selectedIndex cause the selection
         // may have been changed by the mouse in the meanwhile.
         GetFinalDefaultCompleteValue(value);
@@ -1486,21 +1225,16 @@ nsAutoCompleteController::EnterMatch(boo
         // 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.
         nsAutoString finalValue;
         GetResultValueAt(mCompletedSelectionIndex, true, finalValue);
         if (!inputValue.Equals(finalValue)) {
           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 hit, since mouseover doesn't activate
-        // completeselectedindex and thus mCompletedSelectionIndex would be
-        // -1.
       }
     } 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;
@@ -1660,46 +1394,39 @@ nsAutoCompleteController::ProcessResult(
     }
   }
   // When found the result should have the same index as the search.
   MOZ_ASSERT_IF(mResults.IndexOf(aResult) != -1,
                 mResults.IndexOf(aResult) == aSearchIndex);
   MOZ_ASSERT(mResults.Count() >= aSearchIndex + 1,
              "aSearchIndex should always be valid for mResults");
 
-  uint32_t oldRowCount = mRowCount;
+  uint32_t oldMatchCount = mMatchCount;
   // If the search failed, increase the match count to include the error
   // description.
   if (searchResult == nsIAutoCompleteResult::RESULT_FAILURE) {
     nsAutoString error;
     aResult->GetErrorDescription(error);
     if (!error.IsEmpty()) {
-      ++mRowCount;
-      if (mTree) {
-        mTree->RowCountChanged(oldRowCount, 1);
-      }
+      ++mMatchCount;
     }
   } else if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
              searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
     // Increase the match count for all matches in this result.
     uint32_t totalMatchCount = 0;
     for (uint32_t i = 0; i < mResults.Length(); i++) {
       nsIAutoCompleteResult* result = mResults.SafeObjectAt(i);
       if (result) {
         uint32_t matchCount = 0;
         result->GetMatchCount(&matchCount);
         totalMatchCount += matchCount;
       }
     }
-    uint32_t delta = totalMatchCount - oldRowCount;
-
-    mRowCount += delta;
-    if (mTree) {
-      mTree->RowCountChanged(oldRowCount, delta);
-    }
+    uint32_t delta = totalMatchCount - oldMatchCount;
+    mMatchCount += delta;
   }
 
   // Try to autocomplete the default index for this search.
   // Do this before invalidating so the binding knows about it.
   CompleteDefaultIndex(aSearchIndex);
 
   // Refresh the popup view to display the new search results
   nsCOMPtr<nsIAutoCompletePopup> popup;
@@ -1708,17 +1435,17 @@ nsAutoCompleteController::ProcessResult(
   popup->Invalidate(nsIAutoCompletePopup::INVALIDATE_REASON_NEW_RESULT);
 
   uint32_t minResults;
   input->GetMinResultsForPopup(&minResults);
 
   // Make sure the popup is open, if necessary, since we now have at least one
   // search result ready to display. Don't force the popup closed if we might
   // get results in the future to avoid unnecessarily canceling searches.
-  if (mRowCount || !minResults) {
+  if (mMatchCount || !minResults) {
     OpenPopup();
   } else if (mSearchesOngoing == 0) {
     ClosePopup();
   }
 
   return NS_OK;
 }
 
@@ -1726,25 +1453,19 @@ nsresult
 nsAutoCompleteController::PostSearchCleanup()
 {
   NS_ENSURE_STATE(mInput);
   nsCOMPtr<nsIAutoCompleteInput> input(mInput);
 
   uint32_t minResults;
   input->GetMinResultsForPopup(&minResults);
 
-  // Apply a pending rowCountChanged.
-  if (mTree && mDelayedRowCountDelta != 0) {
-    mTree->RowCountChanged(0, mDelayedRowCountDelta);
-    // mDelayedRowCountDelta will be reset by the next search.
-  }
-
-  if (mRowCount || minResults == 0) {
+  if (mMatchCount || minResults == 0) {
     OpenPopup();
-    if (mRowCount)
+    if (mMatchCount)
       mSearchStatus = nsIAutoCompleteController::STATUS_COMPLETE_MATCH;
     else
       mSearchStatus = nsIAutoCompleteController::STATUS_COMPLETE_NO_MATCH;
   } else {
     mSearchStatus = nsIAutoCompleteController::STATUS_COMPLETE_NO_MATCH;
     ClosePopup();
   }
 
@@ -1752,36 +1473,25 @@ nsAutoCompleteController::PostSearchClea
   input->OnSearchComplete();
 
   return NS_OK;
 }
 
 nsresult
 nsAutoCompleteController::ClearResults(bool aIsSearching)
 {
-  int32_t oldRowCount = mRowCount;
-  mRowCount = 0;
+  int32_t oldMatchCount = mMatchCount;
+  mMatchCount = 0;
   mResults.Clear();
-  if (oldRowCount != 0) {
-    if (mTree) {
-      if (aIsSearching) {
-        // Delay the notification, so the tree provides a smoother transition to
-        // the new result. It will be handled as soon as we add the first result.
-        mDelayedRowCountDelta = -oldRowCount;
-      } else {
-        // Notify immediately.
-        mTree->RowCountChanged(0, -oldRowCount);
-      }
-    } else if (mInput) {
+  if (oldMatchCount != 0) {
+    if (mInput) {
       nsCOMPtr<nsIAutoCompletePopup> popup;
       mInput->GetPopup(getter_AddRefs(popup));
       NS_ENSURE_TRUE(popup != nullptr, NS_ERROR_FAILURE);
-      // if we had a tree, RowCountChanged() would have cleared the selection
-      // when the selected row was removed.  But since we don't have a tree,
-      // we need to clear the selection manually.
+      // Clear the selection.
       popup->SetSelectedIndex(-1);
     }
   }
   return NS_OK;
 }
 
 nsresult
 nsAutoCompleteController::CompleteDefaultIndex(int32_t aResultIndex)
@@ -2017,92 +1727,92 @@ nsAutoCompleteController::GetResultValue
 }
 
 nsresult
 nsAutoCompleteController::GetResultValueLabelAt(int32_t aIndex,
                                                 bool aGetFinalValue,
                                                 bool aGetValue,
                                                 nsAString & _retval)
 {
-  NS_ENSURE_TRUE(aIndex >= 0 && static_cast<uint32_t>(aIndex) < mRowCount, NS_ERROR_ILLEGAL_VALUE);
+  NS_ENSURE_TRUE(aIndex >= 0 && static_cast<uint32_t>(aIndex) < mMatchCount, NS_ERROR_ILLEGAL_VALUE);
 
-  int32_t rowIndex;
+  int32_t matchIndex;
   nsIAutoCompleteResult *result;
-  nsresult rv = GetResultAt(aIndex, &result, &rowIndex);
+  nsresult rv = GetResultAt(aIndex, &result, &matchIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint16_t searchResult;
   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) {
       // Some implementations may miss finalCompleteValue, try to be backwards
       // compatible.
-      if (NS_FAILED(result->GetFinalCompleteValueAt(rowIndex, _retval))) {
-        result->GetValueAt(rowIndex, _retval);
+      if (NS_FAILED(result->GetFinalCompleteValueAt(matchIndex, _retval))) {
+        result->GetValueAt(matchIndex, _retval);
       }
     } else if (aGetValue) {
-      result->GetValueAt(rowIndex, _retval);
+      result->GetValueAt(matchIndex, _retval);
     } else {
-      result->GetLabelAt(rowIndex, _retval);
+      result->GetLabelAt(matchIndex, _retval);
     }
   }
 
   return NS_OK;
 }
 
 /**
- * Given the index of a row in the autocomplete popup, find the
+ * Given the index of a match in the autocomplete popup, find the
  * corresponding nsIAutoCompleteSearch index, and sub-index into
  * the search's results list.
  */
 nsresult
-nsAutoCompleteController::RowIndexToSearch(int32_t aRowIndex, int32_t *aSearchIndex, int32_t *aItemIndex)
+nsAutoCompleteController::MatchIndexToSearch(int32_t aMatchIndex, int32_t *aSearchIndex, int32_t *aItemIndex)
 {
   *aSearchIndex = -1;
   *aItemIndex = -1;
 
   uint32_t index = 0;
 
   // Move index through the results of each registered nsIAutoCompleteSearch
-  // until we find the given row
+  // until we find the given match
   for (uint32_t i = 0; i < mSearches.Length(); ++i) {
     nsIAutoCompleteResult *result = mResults.SafeObjectAt(i);
     if (!result)
       continue;
 
-    uint32_t rowCount = 0;
+    uint32_t matchCount = 0;
 
     uint16_t searchResult;
     result->GetSearchResult(&searchResult);
 
     // Find out how many results were provided by the
     // current nsIAutoCompleteSearch.
     if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
         searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
-      result->GetMatchCount(&rowCount);
+      result->GetMatchCount(&matchCount);
     }
 
-    // If the given row index is within the results range
+    // If the given match index is within the results range
     // of the current nsIAutoCompleteSearch then return the
     // search index and sub-index into the results array
-    if ((rowCount != 0) && (index + rowCount-1 >= (uint32_t) aRowIndex)) {
+    if ((matchCount != 0) && (index + matchCount-1 >= (uint32_t) aMatchIndex)) {
       *aSearchIndex = i;
-      *aItemIndex = aRowIndex - index;
+      *aItemIndex = aMatchIndex - index;
       return NS_OK;
     }
 
     // Advance the popup table index cursor past the
     // results of the current search.
-    index += rowCount;
+    index += matchCount;
   }
 
   return NS_OK;
 }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteController)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteSimpleResult)
 
--- a/toolkit/components/autocomplete/nsAutoCompleteController.h
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.h
@@ -9,36 +9,32 @@
 
 #include "nsCOMPtr.h"
 #include "nsIAutoCompleteInput.h"
 #include "nsIAutoCompletePopup.h"
 #include "nsIAutoCompleteResult.h"
 #include "nsIAutoCompleteSearch.h"
 #include "nsINamed.h"
 #include "nsString.h"
-#include "nsITreeView.h"
-#include "nsITreeSelection.h"
 #include "nsITimer.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsAutoCompleteController final : public nsIAutoCompleteController,
                                        public nsIAutoCompleteObserver,
                                        public nsITimerCallback,
-                                       public nsITreeView,
                                        public nsINamed
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsAutoCompleteController,
                                            nsIAutoCompleteController)
   NS_DECL_NSIAUTOCOMPLETECONTROLLER
   NS_DECL_NSIAUTOCOMPLETEOBSERVER
-  NS_DECL_NSITREEVIEW
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSINAMED
 
   nsAutoCompleteController();
 
 protected:
   virtual ~nsAutoCompleteController();
 
@@ -63,37 +59,34 @@ protected:
   nsresult StartSearch(uint16_t aSearchType);
 
   nsresult BeforeSearches();
   nsresult StartSearches();
   void AfterSearches();
   nsresult ClearSearchTimer();
   void MaybeCompletePlaceholder();
 
-  void HandleSearchResult(nsIAutoCompleteSearch *aSearch,
-                          nsIAutoCompleteResult *aResult);
   nsresult ProcessResult(int32_t aSearchIndex, nsIAutoCompleteResult *aResult);
   nsresult PostSearchCleanup();
 
   nsresult EnterMatch(bool aIsPopupSelection,
                       nsIDOMEvent *aEvent);
   nsresult RevertTextValue();
 
   nsresult CompleteDefaultIndex(int32_t aResultIndex);
   nsresult CompleteValue(nsString &aValue);
 
   nsresult GetResultAt(int32_t aIndex, nsIAutoCompleteResult** aResult,
-                       int32_t* aRowIndex);
+                       int32_t* aMatchIndex);
   nsresult GetResultValueAt(int32_t aIndex, bool aGetFinalValue,
                             nsAString & _retval);
   nsresult GetResultLabelAt(int32_t aIndex, nsAString & _retval);
 private:
   nsresult GetResultValueLabelAt(int32_t aIndex, bool aGetFinalValue,
                                  bool aGetValue, nsAString & _retval);
-protected:
 
   /**
    * Gets and validates the defaultComplete result and the relative
    * defaultIndex value.
    *
    * @param aResultIndex
    *        Index of the defaultComplete result to be used.  Pass -1 to search
    *        for the first result providing a valid defaultIndex.
@@ -129,34 +122,32 @@ protected:
    *
    * @param _retval
    *        The value to be completed.
    */
   nsresult GetFinalDefaultCompleteValue(nsAString &_retval);
 
   nsresult ClearResults(bool aIsSearching = false);
 
-  nsresult RowIndexToSearch(int32_t aRowIndex,
-                            int32_t *aSearchIndex, int32_t *aItemIndex);
+  nsresult MatchIndexToSearch(int32_t aMatchIndex,
+                              int32_t *aSearchIndex, int32_t *aItemIndex);
 
   // members //////////////////////////////////////////
 
   nsCOMPtr<nsIAutoCompleteInput> mInput;
 
   nsCOMArray<nsIAutoCompleteSearch> mSearches;
   // This is used as a sparse array, always use SafeObjectAt to access it.
   nsCOMArray<nsIAutoCompleteResult> mResults;
   // Temporarily keeps the results alive while invoking startSearch() for each
   // search.  This is needed to allow the searches to reuse the previous result,
   // since otherwise the first search clears mResults.
   nsCOMArray<nsIAutoCompleteResult> mResultCache;
 
   nsCOMPtr<nsITimer> mTimer;
-  nsCOMPtr<nsITreeSelection> mSelection;
-  nsCOMPtr<nsITreeBoxObject> mTree;
 
   // mSearchString stores value which is the original value of the input or
   // typed by the user.  When user is choosing an item from the popup, this
   // is NOT modified by the item because this is used for reverting the input
   // value when user cancels choosing an item from the popup.
   // This should be set through only SetSearchStringInternal().
   nsString mSearchString;
   nsString mPlaceholderCompletionString;
@@ -182,20 +173,19 @@ protected:
 
   enum CompositionState {
     eCompositionState_None,
     eCompositionState_Composing,
     eCompositionState_Committing
   };
   CompositionState mCompositionState;
   uint16_t mSearchStatus;
-  uint32_t mRowCount;
+  uint32_t mMatchCount;
   uint32_t mSearchesOngoing;
   uint32_t mSearchesFailed;
-  int32_t mDelayedRowCountDelta;
   uint32_t mImmediateSearchesCount;
   // The index of the match on the popup that was selected using the keyboard,
   // if the completeselectedindex attribute is set.
   // This is used to distinguish that selection (which would have been put in
   // the input on being selected) from a moused-over selectedIndex value. This
   // distinction is used to prevent mouse moves from inadvertently changing
   // what happens once the user hits Enter on the keyboard.
   // See bug 1043584 for more details.
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -734,18 +734,17 @@
 
           return aIndex;
         ]]></body>
       </method>
 
       <method name="onPopupClick">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
-          controller.handleEnter(true, aEvent);
+          this.input.controller.handleEnter(true, aEvent);
         ]]></body>
       </method>
 
       <property name="selectedIndex"
                 onget="return this.richlistbox.selectedIndex;">
         <setter>
           <![CDATA[
           this.richlistbox.selectedIndex = val;
@@ -1159,18 +1158,17 @@
           }
       ]]>
       </handler>
 
       <handler event="popuphiding"><![CDATA[
         var isListActive = true;
         if (this.selectedIndex == -1)
           isListActive = false;
-        var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
-        controller.stopSearch();
+        this.input.controller.stopSearch();
 
         this.removeAttribute("autocompleteinput");
         this.mPopupOpen = false;
 
         // Reset the maxRows property to the cached "normal" value (if there's
         // any), and reset normalMaxRows so that we can detect whether it was set
         // by the input when the popupshowing handler runs.