Bug 1558248 - Don't clear the completion text when it starts with the typed letters. r=fvsch.
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Sun, 07 Jul 2019 10:38:08 +0000
changeset 544413 d6cfc645e0c0a4da20eb79e7b9c2653ef323b94e
parent 544412 6a41c590899802f9636815ad69b14d67318582cf
child 544414 1a5bc9c6cfcd134a813cbf269b0b11a02ddd22a7
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfvsch
bugs1558248, 1491776
milestone69.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 1558248 - Don't clear the completion text when it starts with the typed letters. r=fvsch. We were clearing the completion text all the time to prevent a visual glitch while typing (See Bug 1491776). But since we are now waiting for 75ms before calling the autocomplete function (which triggers the autocompletion text update), we have a flash of the completion text, which isn't ideal. In this patch, we check if the typed letters match the begining of the completion text, and if they do, we don't clear the completion text. In the same time, we set the completion text in absolute position so it doesn't jump when the new letter is added in the CodeMirror document. Finally, we change how the Editor pipe events from CodeMirror to include parameters, so we can use them in JsTerm. Differential Revision: https://phabricator.services.mozilla.com/D36163
devtools/client/shared/sourceeditor/editor.js
devtools/client/themes/webconsole.css
devtools/client/webconsole/components/Input/JSTerm.js
--- a/devtools/client/shared/sourceeditor/editor.js
+++ b/devtools/client/shared/sourceeditor/editor.js
@@ -424,17 +424,17 @@ Editor.prototype = {
     const pipedEvents = [
       "beforeChange",
       "changes",
       "cursorActivity",
       "focus",
       "scroll",
     ];
     for (const eventName of pipedEvents) {
-      cm.on(eventName, () => this.emit(eventName));
+      cm.on(eventName, (...args) => this.emit(eventName, ...args));
     }
 
     cm.on("change", () => {
       this.emit("change");
       if (!this._lastDirty) {
         this._lastDirty = true;
         this.emit("dirty-change");
       }
--- a/devtools/client/themes/webconsole.css
+++ b/devtools/client/themes/webconsole.css
@@ -536,16 +536,24 @@ textarea.jsterm-input-node:focus {
 
 .jsterm-cm .jsterm-input-container > .CodeMirror-focused {
   fill: var(--theme-icon-checked-color);
 }
 
 .jsterm-cm .cm-auto-complete-shadow-text::after {
   content: attr(title);
   color: var(--theme-comment);
+  /* This is important for the completion text not to move while the user is typing */
+  /* See Bugs 1491776 & 1558248 */
+  position: absolute;
+}
+
+.jsterm-cm .CodeMirror-hscrollbar {
+  /* We never want to see the horizontal scrollbar */
+  display: none !important;
 }
 
 /* Security styles */
 
 .stacktrace {
   display: none;
   overflow-y: auto;
   margin-block-start: 5px;
--- a/devtools/client/webconsole/components/Input/JSTerm.js
+++ b/devtools/client/webconsole/components/Input/JSTerm.js
@@ -900,20 +900,32 @@ class JSTerm extends Component {
     }
     return this.editor.getSelection();
   }
 
   /**
    * Even handler for the "beforeChange" event fired by codeMirror. This event is fired
    * when codeMirror is about to make a change to its DOM representation.
    */
-  _onBeforeChange() {
-    // clear the completionText before the change is done to prevent a visual glitch.
-    // See Bug 1491776.
-    this.setAutoCompletionText("");
+  _onBeforeChange(cm, change) {
+    // If the user did not type a character that matches the completion text, then we
+    // clear it before the change is done to prevent a visual glitch.
+    // See Bugs 1491776 & 1558248.
+    const { from, to, origin, text } = change;
+    const completionText = this.getAutoCompletionText();
+
+    const addedCharacterMatchCompletion =
+      from.line === to.line &&
+      from.ch === to.ch &&
+      origin === "+input" &&
+      completionText.startsWith(text.join(""));
+
+    if (!completionText || change.canceled || !addedCharacterMatchCompletion) {
+      this.setAutoCompletionText("");
+    }
   }
 
   /**
    * The inputNode "input" and "keyup" event handler.
    * @private
    */
   _inputEventHandler() {
     const value = this._getValue();