Bug 1239992 - Focus input field if text is not selected in webconsole output;r=linclark
authorBrian Grinstead <bgrinstead@mozilla.com>
Wed, 30 Mar 2016 10:10:22 -0700
changeset 290841 e14db462d31d566570e3bece66d5380f7b1ad400
parent 290840 1b9a489995479fb498c61857cc9311d81a88257e
child 290842 09f42355aa061bada9ab92056215d9cdae86a220
push id30127
push userryanvm@gmail.com
push dateThu, 31 Mar 2016 19:47:18 +0000
treeherdermozilla-central@09f42355aa06 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslinclark
bugs1239992
milestone48.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 1239992 - Focus input field if text is not selected in webconsole output;r=linclark MozReview-Commit-ID: 2MsIap7Rj4P
devtools/client/webconsole/test/browser_console_click_focus.js
devtools/client/webconsole/webconsole.js
--- a/devtools/client/webconsole/test/browser_console_click_focus.js
+++ b/devtools/client/webconsole/test/browser_console_click_focus.js
@@ -25,32 +25,34 @@ add_task(function*() {
 
   let msg = [...result.matched][0];
   let outputItem = msg.querySelector(".message-body");
   ok(outputItem, "found a logged message");
 
   let inputNode = hud.jsterm.inputNode;
   ok(inputNode.getAttribute("focused"), "input node is focused, first");
 
-  let lostFocus = () => {
-    inputNode.removeEventListener("blur", lostFocus);
-    info("input node lost focus");
-  };
+  yield waitForBlurredInput(inputNode);
+
+  EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
+  ok(inputNode.getAttribute("focused"), "input node is focused, second time");
 
-  inputNode.addEventListener("blur", lostFocus);
+  yield waitForBlurredInput(inputNode);
 
-  document.getElementById("urlbar").click();
-
-  ok(!inputNode.getAttribute("focused"), "input node is not focused");
+  info("Setting a text selection and making sure a click does not re-focus")
+  let selection = hud.iframeWindow.getSelection();
+  selection.selectAllChildren(outputItem);
 
   EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
-
-  ok(inputNode.getAttribute("focused"), "input node is focused, second time");
-
-  // test click-drags are not focusing the input element.
-  EventUtils.sendMouseEvent({type: "mousedown", clientX: 3, clientY: 4},
-    outputItem);
-  EventUtils.sendMouseEvent({type: "click", clientX: 15, clientY: 5},
-    outputItem);
-
-  todo(!inputNode.getAttribute("focused"), "input node is not focused after drag");
+  ok(!inputNode.getAttribute("focused"), "input node is not focused after drag");
 });
 
+function waitForBlurredInput(inputNode) {
+  return new Promise(resolve => {
+    let lostFocus = () => {
+      inputNode.removeEventListener("blur", lostFocus);
+      ok(!inputNode.getAttribute("focused"), "input node is not focused");
+      resolve();
+    };
+    inputNode.addEventListener("blur", lostFocus);
+    document.getElementById("urlbar").click();
+  });
+}
--- a/devtools/client/webconsole/webconsole.js
+++ b/devtools/client/webconsole/webconsole.js
@@ -569,25 +569,37 @@ WebConsoleFrame.prototype = {
     this.jsterm.on("sidebar-closed", this.resize);
 
     let toolbox = gDevTools.getToolbox(this.owner.target);
     if (toolbox) {
       toolbox.on("webconsole-selected", this._onPanelSelected);
     }
 
     /*
-     * Focus input line whenever the output area is clicked.
-     * Reusing _addMEssageLinkCallback since it correctly filters
-     * drag and select events.
+     * Focus the input line whenever the output area is clicked.
      */
-    this._addFocusCallback(this.outputNode, (evt) => {
-      if ((evt.target.nodeName.toLowerCase() != "a") &&
-          (evt.target.parentNode.nodeName.toLowerCase() != "a")) {
-        this.jsterm.focus();
+    this.outputWrapper.addEventListener("click", (event) => {
+      // Do not focus on middle/right-click or 2+ clicks.
+      if (event.detail !== 1 || event.button !== 0) {
+        return;
       }
+
+      // Do not focus if something is selected
+      let selection = this.window.getSelection();
+      if (selection && !selection.isCollapsed) {
+        return;
+      }
+
+      // Do not focus if a link was clicked
+      if (event.target.nodeName.toLowerCase() === "a" ||
+          event.target.parentNode.nodeName.toLowerCase() === "a") {
+        return;
+      }
+
+      this.jsterm.focus();
     });
 
     // Toggle the timestamp on preference change
     gDevTools.on("pref-changed", this._onToolboxPrefChanged);
     this._onToolboxPrefChanged("pref-changed", {
       pref: PREF_MESSAGE_TIMESTAMP,
       newValue: Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP),
     });
@@ -2631,49 +2643,16 @@ WebConsoleFrame.prototype = {
       }
 
       this._startX = this._startY = undefined;
 
       callback.call(this, event);
     }, false);
   },
 
-  _addFocusCallback: function(node, callback) {
-    node.addEventListener("mousedown", (event) => {
-      this._mousedown = true;
-      this._startX = event.clientX;
-      this._startY = event.clientY;
-    }, false);
-
-    node.addEventListener("click", (event) => {
-      let mousedown = this._mousedown;
-      this._mousedown = false;
-
-      // Do not allow middle/right-click or 2+ clicks.
-      if (event.detail != 1 || event.button != 0) {
-        return;
-      }
-
-      // If this event started with a mousedown event and it ends at a different
-      // location, we consider this text selection.
-      // Add a fuzz modifier of two pixels in any direction to account for
-      // sloppy clicking.
-      if (mousedown &&
-          (Math.abs(event.clientX - this._startX) >= 2) &&
-          (Math.abs(event.clientY - this._startY) >= 1)) {
-        this._startX = this._startY = undefined;
-        return;
-      }
-
-      this._startX = this._startY = undefined;
-
-      callback.call(this, event);
-    }, false);
-  },
-
   /**
    * Handler for the pref-changed event coming from the toolbox.
    * Currently this function only handles the timestamps preferences.
    *
    * @private
    * @param object event
    *        This parameter is a string that holds the event name
    *        pref-changed in this case.