Skip to content

Commit

Permalink
Bug 1133155 - Selection Handler closes leaving handles on screen, r=m…
Browse files Browse the repository at this point in the history
…argaret
  • Loading branch information
markcapella committed Mar 5, 2015
1 parent 9695fda commit 0ba329f
Showing 1 changed file with 43 additions and 4 deletions.
47 changes: 43 additions & 4 deletions mobile/android/chrome/content/SelectionHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 0ba329f

Please sign in to comment.