Bug 1304073 - don't hide the modal highlight dimmed background upon a mouse click under certain conditions. r?jaws draft
authorMike de Boer <mdeboer@mozilla.com>
Thu, 29 Sep 2016 15:37:39 +0200
changeset 419018 8747e80f436a06d38c9ef0ae994c38d2cd92302f
parent 419017 dc21ccd6a304df32cdec43a71f01bdf80288ee98
child 532468 a403417341d04275f9fc4af6f4f2599e176d2cd1
push id30819
push usermdeboer@mozilla.com
push dateThu, 29 Sep 2016 13:38:05 +0000
reviewersjaws
bugs1304073
milestone52.0a1
Bug 1304073 - don't hide the modal highlight dimmed background upon a mouse click under certain conditions. r?jaws We'll ignore mouse events with the following properties: 1) a modifier key was pressed during the click, 2) an anchor element was clicked, 3) the 'selectstart' event fired earlier, indicating a text selection action 4) 'relatedTarget' is set, indicating a drag action or touch event. MozReview-Commit-ID: 2hIBgcVXzp
toolkit/modules/FinderHighlighter.jsm
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -311,28 +311,33 @@ FinderHighlighter.prototype = {
    * @param {nsIDOMWindow} window    The dimmed background will overlay this window.
    *                                 Optional, defaults to the finder window.
    * @param {nsIDOMRange}  skipRange A range that should not be removed from the
    *                                 find selection.
    * @param {nsIDOMEvent}  event     When called from an event handler, this will
    *                                 be the triggering event.
    */
   hide(window = null, skipRange = null, event = null) {
-    // Do not hide on anything but a left-click.
-    if (event && event.type == "click" && event.button !== 0)
-      return;
-
     try {
       window = (window || this.finder._getWindow()).top;
     } catch (ex) {
       Cu.reportError(ex);
       return;
     }
     let dict = this.getForWindow(window);
 
+    let isBusySelecting = dict.busySelecting;
+    dict.busySelecting = false;
+    // Do not hide on anything but a left-click.
+    if (event && event.type == "click" && (event.button !== 0 || event.altKey ||
+        event.ctrlKey || event.metaKey || event.shiftKey || event.relatedTarget ||
+        isBusySelecting || (event.target.localName == "a" && event.target.href))) {
+      return;
+    }
+
     this._clearSelection(this.finder._getSelectionController(window), skipRange);
     for (let frame of dict.frames.keys())
       this._clearSelection(this.finder._getSelectionController(frame), skipRange);
 
     // Next, check our editor cache, for editors belonging to this
     // document
     if (this._editors) {
       let doc = window.document;
@@ -1183,23 +1188,25 @@ FinderHighlighter.prototype = {
     if (dict.highlightListeners)
       return;
 
     window = window.top;
     dict.highlightListeners = [
       this._scheduleRepaintOfMask.bind(this, window, { contentChanged: true }),
       this._scheduleRepaintOfMask.bind(this, window, { updateAllRanges: true }),
       this._scheduleRepaintOfMask.bind(this, window, { scrollOnly: true }),
-      this.hide.bind(this, window, null)
+      this.hide.bind(this, window, null),
+      () => dict.busySelecting = true
     ];
     let target = this.iterator._getDocShell(window).chromeEventHandler;
     target.addEventListener("MozAfterPaint", dict.highlightListeners[0]);
     target.addEventListener("resize", dict.highlightListeners[1]);
     target.addEventListener("scroll", dict.highlightListeners[2]);
     target.addEventListener("click", dict.highlightListeners[3]);
+    target.addEventListener("selectstart", dict.highlightListeners[4]);
   },
 
   /**
    * Remove event listeners from content.
    *
    * @param {nsIDOMWindow} window
    */
   _removeModalHighlightListeners(window) {
@@ -1208,16 +1215,17 @@ FinderHighlighter.prototype = {
     if (!dict.highlightListeners)
       return;
 
     let target = this.iterator._getDocShell(window).chromeEventHandler;
     target.removeEventListener("MozAfterPaint", dict.highlightListeners[0]);
     target.removeEventListener("resize", dict.highlightListeners[1]);
     target.removeEventListener("scroll", dict.highlightListeners[2]);
     target.removeEventListener("click", dict.highlightListeners[3]);
+    target.removeEventListener("selectstart", dict.highlightListeners[4]);
 
     dict.highlightListeners = null;
   },
 
   /**
    * For a given node returns its editable parent or null if there is none.
    * It's enough to check if node is a text node and its parent's parent is
    * instance of nsIDOMNSEditableElement.