зеркало из https://github.com/mozilla/gecko-dev.git
Bug 765057 - (Part 2) Reverse handles if the start handle goes past the end of the selection and vice versa. r=mbrubeck
This commit is contained in:
Родитель
b01bec2a6c
Коммит
d1bab9d6c6
|
@ -1500,25 +1500,48 @@ var SelectionHandler = {
|
||||||
this._end.style.top = aY + this.cache.offset.y + "px";
|
this._end.style.top = aY + this.cache.offset.y + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
//XXX bug 765057: Reverse text selection handles if necessary
|
|
||||||
|
|
||||||
// Send mouse events to the top-level window
|
// Send mouse events to the top-level window
|
||||||
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
|
||||||
if (aIsStartHandle) {
|
// If we're moving the start handle, we need to re-position the carat
|
||||||
// If we're moving the start handle, we need to re-position the caret using a fake mouse click
|
if (aIsStartHandle)
|
||||||
let start = this._start.getBoundingClientRect();
|
this._sendStartMouseEvents(cwu);
|
||||||
cwu.sendMouseEventToWindow("mousedown", start.right - this.HANDLE_PADDING, start.top - this.HANDLE_VERTICAL_MARGIN, 0, 0, 0, true);
|
|
||||||
cwu.sendMouseEventToWindow("mouseup", start.right - this.HANDLE_PADDING, start.top - this.HANDLE_VERTICAL_MARGIN, 0, 0, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send a shift+click to select text between the carat at the start and an end point
|
// We always need to fire events for the end to move the selection
|
||||||
|
this._sendEndMouseEvents(cwu);
|
||||||
|
|
||||||
|
// Update the cached selection area after firing the mouse events
|
||||||
|
let selectionReversed = this.updateCacheForSelection(aIsStartHandle);
|
||||||
|
|
||||||
|
// Reverse the handles if necessary
|
||||||
|
if (selectionReversed) {
|
||||||
|
let oldStart = this._start;
|
||||||
|
let oldEnd = this._end;
|
||||||
|
|
||||||
|
oldStart.setAttribute("anonid", "selection-handle-end");
|
||||||
|
oldEnd.setAttribute("anonid", "selection-handle-start");
|
||||||
|
|
||||||
|
this._start = oldEnd;
|
||||||
|
this._end = oldStart;
|
||||||
|
|
||||||
|
// Re-send mouse events to update the selection corresponding to the new handles
|
||||||
|
this._sendStartMouseEvents(cwu);
|
||||||
|
this._sendEndMouseEvents(cwu);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Positions the caret using a fake mouse click
|
||||||
|
_sendStartMouseEvents: function sh_sendStartMouseEvents(cwu) {
|
||||||
|
let start = this._start.getBoundingClientRect();
|
||||||
|
cwu.sendMouseEventToWindow("mousedown", start.right - this.HANDLE_PADDING, start.top - this.HANDLE_VERTICAL_MARGIN, 0, 0, 0, true);
|
||||||
|
cwu.sendMouseEventToWindow("mouseup", start.right - this.HANDLE_PADDING, start.top - this.HANDLE_VERTICAL_MARGIN, 0, 0, 0, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Selects text between the carat at the start and an end point using a fake shift+click
|
||||||
|
_sendEndMouseEvents: function sh_sendEndMouseEvents(cwu) {
|
||||||
let end = this._end.getBoundingClientRect();
|
let end = this._end.getBoundingClientRect();
|
||||||
cwu.sendMouseEventToWindow("mousedown", end.left + this.HANDLE_PADDING, end.top - this.HANDLE_VERTICAL_MARGIN, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
|
cwu.sendMouseEventToWindow("mousedown", end.left + this.HANDLE_PADDING, end.top - this.HANDLE_VERTICAL_MARGIN, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
|
||||||
cwu.sendMouseEventToWindow("mouseup", end.left + this.HANDLE_PADDING, end.top - this.HANDLE_VERTICAL_MARGIN, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
|
cwu.sendMouseEventToWindow("mouseup", end.left + this.HANDLE_PADDING, end.top - this.HANDLE_VERTICAL_MARGIN, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
|
||||||
|
|
||||||
// Update the cached selection area
|
|
||||||
this.updateCacheForSelection();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// aX/aY are in top-level window browser coordinates
|
// aX/aY are in top-level window browser coordinates
|
||||||
|
@ -1554,14 +1577,27 @@ var SelectionHandler = {
|
||||||
this.cache = null;
|
this.cache = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateCacheForSelection: function sh_updateCacheForSelection() {
|
// Returns true if the selection has been reversed. Takes optional aIsStartHandle
|
||||||
|
// param to decide whether the selection has been reversed.
|
||||||
|
updateCacheForSelection: function sh_updateCacheForSelection(aIsStartHandle) {
|
||||||
let range = this._view.getSelection().getRangeAt(0);
|
let range = this._view.getSelection().getRangeAt(0);
|
||||||
|
this.cache.rect = range.getBoundingClientRect();
|
||||||
|
|
||||||
let rects = range.getClientRects();
|
let rects = range.getClientRects();
|
||||||
this.cache.start = { x: rects[0].left, y: rects[0].bottom };
|
let start = { x: rects[0].left, y: rects[0].bottom };
|
||||||
this.cache.end = { x: rects[rects.length - 1].right, y: rects[rects.length - 1].bottom };
|
let end = { x: rects[rects.length - 1].right, y: rects[rects.length - 1].bottom };
|
||||||
|
|
||||||
this.cache.rect = range.getBoundingClientRect();
|
let selectionReversed = false;
|
||||||
|
if (this.cache.start) {
|
||||||
|
// If the end moved past the old end, but we're dragging the start handle, then that handle should become the end handle (and vice versa)
|
||||||
|
selectionReversed = (aIsStartHandle && (end.y > this.cache.end.y || (end.y == this.cache.end.y && end.x > this.cache.end.x))) ||
|
||||||
|
(!aIsStartHandle && (start.y < this.cache.start.y || (start.y == this.cache.start.y && start.x < this.cache.start.x)));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cache.start = start;
|
||||||
|
this.cache.end = end;
|
||||||
|
|
||||||
|
return selectionReversed;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateCacheOffset: function sh_updateCacheOffset() {
|
updateCacheOffset: function sh_updateCacheOffset() {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче