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
--- 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.