Bug 1133155 - Selection Handler closes leaving handles on screen, r=margaret

This commit is contained in:
Mark Capella 2015-03-05 01:33:36 -05:00
Родитель 9695fdaeea
Коммит 0ba329fe26
1 изменённых файлов: 43 добавлений и 4 удалений

Просмотреть файл

@ -44,6 +44,7 @@ var SelectionHandler = {
_focusIsRTL: false,
_activeType: 0, // TYPE_NONE
_selectionPrivate: null, // private selection reference
_selectionID: 0, // Unique Selection ID
_draggingHandles: false, // True while user drags text selection handles
@ -118,9 +119,12 @@ var SelectionHandler = {
}
switch (aTopic) {
// Update handle/caret position on page reflow (keyboard open/close,
// dynamic DOM changes, orientation updates, etc).
// Update selectionListener and handle/caret positions, on page reflow
// (keyboard open/close, dynamic DOM changes, orientation updates, etc).
case "TextSelection:LayerReflow": {
if (this._activeType == this.TYPE_SELECTION) {
this._updateSelectionListener();
}
if (this._activeType != this.TYPE_NONE) {
this._positionHandlesOnChange();
}
@ -290,6 +294,41 @@ var SelectionHandler = {
};
},
/**
* Add a selection listener to monitor for external selection changes.
*/
_addSelectionListener: function(selection) {
this._selectionPrivate = selection.QueryInterface(Ci.nsISelectionPrivate);
this._selectionPrivate.addSelectionListener(this);
},
/**
* The nsISelection object for an editable can change during DOM mutations,
* causing us to stop receiving selectionChange notifications.
*
* We can detect that after a layer-reflow event, and dynamically update the
* listener.
*/
_updateSelectionListener: function() {
if (!(this._targetElement instanceof Ci.nsIDOMNSEditableElement)) {
return;
}
let selection = this._getSelection();
if (this._selectionPrivate != selection.QueryInterface(Ci.nsISelectionPrivate)) {
this._removeSelectionListener();
this._addSelectionListener(selection);
}
},
/**
* Remove the selection listener.
*/
_removeSelectionListener: function() {
this._selectionPrivate.removeSelectionListener(this);
this._selectionPrivate = null;
},
/**
* Observe and react to programmatic SelectionChange notifications.
*/
@ -359,7 +398,7 @@ var SelectionHandler = {
}
// Add a listener to end the selection if it's removed programatically
selection.QueryInterface(Ci.nsISelectionPrivate).addSelectionListener(this);
this._addSelectionListener(selection);
this._activeType = this.TYPE_SELECTION;
// Figure out the distance between the selection and the click
@ -1074,7 +1113,7 @@ var SelectionHandler = {
let selection = this._getSelection();
if (selection) {
// Remove our listener before we clear the selection
selection.QueryInterface(Ci.nsISelectionPrivate).removeSelectionListener(this);
this._removeSelectionListener();
// Remove the selection. For editables, we clear selection without losing
// element focus. For non-editables, just clear all.