Bug 1467537 - The delete trigger on moz_updateoriginsinsert_temp is recalculating the whole table every time. r=adw draft
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 08 Jun 2018 11:31:13 +0200
changeset 806337 9a7e13cc62dfe0ae95210e7a75068d07a0b7c275
parent 805282 d8a7dd15c9664dda6dafc8fb1e7dee53b5b2e9b5
push id112865
push usermak77@bonardo.net
push dateSat, 09 Jun 2018 08:13:25 +0000
reviewersadw
bugs1467537
milestone62.0a1
Bug 1467537 - The delete trigger on moz_updateoriginsinsert_temp is recalculating the whole table every time. r=adw The trigger is missing a WHERE clause, and as such it ends up doing a lot more work than necessary. The nsAutoCompleteController changes cover a bug where VK_RIGHT autofills when it's not necessary, and by doing that it will move the caret to an unexpected position (far right) even if it didn't actually complete some preselected text. MozReview-Commit-ID: 1mVbxCdqVSr
browser/base/content/test/urlbar/browser_autocomplete_cursor.js
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/places/nsPlacesTriggers.h
--- a/browser/base/content/test/urlbar/browser_autocomplete_cursor.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_cursor.js
@@ -1,14 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 add_task(async function() {
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
   await promiseAutocompleteResultPopup("www.mozilla.org");
+  await waitForAutocompleteResultAt(0);
 
   gURLBar.selectTextRange(4, 4);
 
   is(gURLBar.popup.state, "open", "Popup should be open");
   is(gURLBar.popup.richlistbox.selectedIndex, 0, "Should have selected something");
 
   EventUtils.synthesizeKey("KEY_ArrowRight");
   await promisePopupHidden(gURLBar.popup);
--- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
@@ -569,42 +569,40 @@ nsAutoCompleteController::HandleKeyNavig
     // 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 || (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.
+      bool completeSelection;
+      input->GetCompleteSelectedIndex(&completeSelection);
       if (isOpen) {
         bool noRollup;
         input->GetNoRollupOnCaretMove(&noRollup);
         if (noRollup) {
-          bool completeSelection;
-          input->GetCompleteSelectedIndex(&completeSelection);
           if (completeSelection) {
             return NS_OK;
           }
         }
       }
 
+      int32_t selectionEnd;
+      input->GetSelectionEnd(&selectionEnd);
+      int32_t selectionStart;
+      input->GetSelectionStart(&selectionStart);
+      bool shouldCompleteSelection =
+        (uint32_t)selectionEnd == mPlaceholderCompletionString.Length() &&
+        selectionStart < selectionEnd;
       int32_t selectedIndex;
       popup->GetSelectedIndex(&selectedIndex);
-      bool shouldComplete;
-      input->GetCompleteDefaultIndex(&shouldComplete);
-      if (selectedIndex >= 0) {
-        // The pop-up is open and has a selection, take its value
-        nsAutoString value;
-        if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, false, value))) {
-          SetValueOfInputTo(
-            value, nsIAutoCompleteInput::TEXTVALUE_REASON_COMPLETESELECTED);
-          input->SelectTextRange(value.Length(), value.Length());
-        }
-      }
-      else if (shouldComplete) {
+      bool completeDefaultIndex;
+      input->GetCompleteDefaultIndex(&completeDefaultIndex);
+      if (completeDefaultIndex && shouldCompleteSelection) {
         // 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. Note that the autocomplete input can also
         // be showing e.g. "bar >> foo bar" if the search matched "bar", a
         // word not at the start of the full value "foo bar".
         // The user wants explicitely to use that result, so this ensures
         // association of the result with the autocompleted text.
         nsAutoString value;
@@ -620,16 +618,25 @@ nsAutoCompleteController::HandleKeyNavig
           }
 
           if (value.Equals(suggestedValue, nsCaseInsensitiveStringComparator())) {
             SetValueOfInputTo(
               value, nsIAutoCompleteInput::TEXTVALUE_REASON_COMPLETEDEFAULT);
             input->SelectTextRange(value.Length(), value.Length());
           }
         }
+      } else if (!completeDefaultIndex && !completeSelection &&
+                 selectedIndex >= 0) {
+        // The pop-up is open and has a selection, take its value
+        nsAutoString value;
+        if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, false, value))) {
+          SetValueOfInputTo(
+            value, nsIAutoCompleteInput::TEXTVALUE_REASON_COMPLETESELECTED);
+          input->SelectTextRange(value.Length(), value.Length());
+        }
       }
 
       // Close the pop-up even if nothing was selected
       ClearSearchTimer();
       ClosePopup();
     }
     // Update last-searched string to the current input, since the input may
     // have changed.  Without this, subsequent backspaces look like text
--- a/toolkit/components/places/nsPlacesTriggers.h
+++ b/toolkit/components/places/nsPlacesTriggers.h
@@ -139,17 +139,18 @@
       "FROM moz_origins " \
       "WHERE prefix = OLD.prefix AND host = OLD.host " \
     ") " \
     "WHERE id = OLD.place_id; " \
     "UPDATE moz_origins SET frecency = ( " \
       "SELECT IFNULL(MAX(frecency), 0) " \
       "FROM moz_places " \
       "WHERE moz_places.origin_id = moz_origins.id " \
-    "); " \
+    ") " \
+    "WHERE prefix = OLD.prefix AND host = OLD.host; " \
   "END" \
 )
 
 // See CREATE_PLACES_AFTERINSERT_TRIGGER. This is the trigger that we want
 // to ensure gets run for each origin that we delete from moz_places.
 #define CREATE_UPDATEORIGINSDELETE_AFTERDELETE_TRIGGER NS_LITERAL_CSTRING( \
   "CREATE TEMP TRIGGER moz_updateoriginsdelete_afterdelete_trigger " \
   "AFTER DELETE ON moz_updateoriginsdelete_temp FOR EACH ROW " \