Bug 1600680 - Fix race issue in autocompletion + Enter. r=Honza.
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Thu, 19 Dec 2019 11:19:55 +0000
changeset 507847 e823e110d07bb828fff8540c693f7dd840b247f3
parent 507846 57904839c03789c8fc238cc93916dee1c8c8f272
child 507848 ccb4dd2108ce9785954406227de1cac8de75eccd
push id36932
push useraciure@mozilla.com
push dateThu, 19 Dec 2019 21:52:02 +0000
treeherdermozilla-central@8e1b11b00157 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersHonza
bugs1600680
milestone73.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 1600680 - Fix race issue in autocompletion + Enter. r=Honza. This ensures the selected item of the autocomplete popup is updated, so if the user accepts the completion it will retrieve the right text. Differential Revision: https://phabricator.services.mozilla.com/D57342
devtools/client/webconsole/components/Input/JSTerm.js
devtools/client/webconsole/test/browser/browser_jsterm_autocomplete_race_on_enter.js
--- a/devtools/client/webconsole/components/Input/JSTerm.js
+++ b/devtools/client/webconsole/components/Input/JSTerm.js
@@ -727,16 +727,28 @@ class JSTerm extends Component {
     const addedCharacterMatchCompletion =
       isAddedText && completionText.startsWith(addedText);
 
     const addedCharacterMatchPopupItem =
       isAddedText &&
       this.autocompletePopup.items.some(({ preLabel, label }) =>
         label.startsWith(preLabel + addedText)
       );
+    const nextSelectedAutocompleteItemIndex =
+      addedCharacterMatchPopupItem &&
+      this.autocompletePopup.items.findIndex(({ preLabel, label }) =>
+        label.startsWith(preLabel + addedText)
+      );
+
+    if (addedCharacterMatchPopupItem) {
+      this.autocompletePopup.selectItemAtIndex(
+        nextSelectedAutocompleteItemIndex,
+        { preventSelectCallback: true }
+      );
+    }
 
     if (!completionText || change.canceled || !addedCharacterMatchCompletion) {
       this.setAutoCompletionText("");
     }
 
     if (!addedCharacterMatchCompletion && !addedCharacterMatchPopupItem) {
       this.autocompletePopup.hidePopup();
     } else if (
--- a/devtools/client/webconsole/test/browser/browser_jsterm_autocomplete_race_on_enter.js
+++ b/devtools/client/webconsole/test/browser/browser_jsterm_autocomplete_race_on_enter.js
@@ -111,17 +111,17 @@ add_task(async function() {
   await waitForTime(5);
   EventUtils.synthesizeKey("KEY_Enter");
   await onPopupClosed;
   is(getInputValue(hud), "[].some", "the input has the expected value");
 
   setInputValue(hud, "");
 
   info(
-    "Hitting Enter quicly after a letter that should close the popup evaluates the expression"
+    "Hitting Enter quickly after a letter that should close the popup evaluates the expression"
   );
   onPopupOpened = autocompletePopup.once("popup-opened");
   await setInputValueForAutocompletion(hud, "var docx = 1; doc");
   await onPopupOpened;
   checkInputCompletionValue(hud, "ument", "completeNode has expected value");
 
   info(`Quickly type "x" and "Enter"`);
   onPopupClosed = autocompletePopup.once("popup-closed");
@@ -130,9 +130,24 @@ add_task(async function() {
   await waitForTime(5);
   EventUtils.synthesizeKey("KEY_Enter");
   await Promise.all[(onPopupClosed, onMessage)];
   is(
     getInputValue(hud),
     "",
     "the input is empty and the expression was evaluated"
   );
+
+  info(
+    "Hitting Enter quickly after a letter that will make the expression exactly match another item than the selected one"
+  );
+  onPopupOpened = autocompletePopup.once("popup-opened");
+  await setInputValueForAutocompletion(hud, "cons");
+  await onPopupOpened;
+  checkInputCompletionValue(hud, "ole", "completeNode has expected value");
+  info(`Quickly type "t" and "Enter"`);
+  onPopupClosed = autocompletePopup.once("popup-closed");
+  EventUtils.synthesizeKey("t");
+  await waitForTime(5);
+  EventUtils.synthesizeKey("KEY_Enter");
+  await onPopupClosed;
+  is(getInputValue(hud), "const", "the input has the expected item");
 });