Bug 767065 - Add a listsener to get rid of text selection handles if the selection is programatically collapsed. r=mbrubeck
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Tue, 26 Jun 2012 14:39:47 -0700
changeset 97726 d095c0213dc851d396d792b38299abe5500103fb
parent 97725 cd3101aa036056c84585a97ce02d5b3948361bde
child 97727 1496916570c62fc5487071cad9ab098f01a945b3
push id22993
push useremorley@mozilla.com
push dateWed, 27 Jun 2012 10:31:27 +0000
treeherdermozilla-central@1a56f1f011c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs767065
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 767065 - Add a listsener to get rid of text selection handles if the selection is programatically collapsed. r=mbrubeck
mobile/android/chrome/content/browser.js
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1410,16 +1410,22 @@ var SelectionHandler = {
 
   observe: function sh_observe(aSubject, aTopic, aData) {
     let data = JSON.parse(aData);
 
     if (this._active)
       this.endSelection(data.x, data.y);
   },
 
+  notifySelectionChanged: function sh_notifySelectionChanged(aDoc, aSel, aReason) {
+    // If the selection was removed, call endSelection() to clean up
+    if (aSel == "" && aReason == Ci.nsISelectionListener.NO_REASON)
+      this.endSelection();
+  },
+
   // aX/aY are in top-level window browser coordinates
   startSelection: function sh_startSelection(aElement, aX, aY) {
     // Clear out any existing selection
     if (this._active)
       this.endSelection();
 
     // Get the element's view
     this._view = aElement.ownerDocument.defaultView;
@@ -1455,16 +1461,19 @@ var SelectionHandler = {
     }
 
     // If there isn't an appropriate selection, bail
     if (!selection.rangeCount || !selection.getRangeAt(0) || !selection.toString().trim().length) {
       selection.collapseToStart();
       return;
     }
 
+    // Add a listener to end the selection if it's removed programatically
+    selection.QueryInterface(Ci.nsISelectionPrivate).addSelectionListener(this);
+
     // Initialize the cache
     this.cache = {};
     this.updateCacheForSelection();
 
     this.showHandles();
     this._active = true;
   },
 
@@ -1570,24 +1579,29 @@ var SelectionHandler = {
       return;
 
     cwu.sendMouseEventToWindow("mousedown", x, y, 0, 0, useShift ? Ci.nsIDOMNSEvent.SHIFT_MASK : 0, true);
     cwu.sendMouseEventToWindow("mouseup", x, y, 0, 0, useShift ? Ci.nsIDOMNSEvent.SHIFT_MASK : 0, true);
   },
 
   // aX/aY are in top-level window browser coordinates
   endSelection: function sh_endSelection(aX, aY) {
+    if (!this._active)
+      return;
+
+    this._active = false;
     this.hideHandles();
 
     let selectedText = "";
     if (this._view) {
       let selection = this._view.getSelection();
       if (selection) {
         selectedText = selection.toString().trim();
         selection.removeAllRanges();
+        selection.QueryInterface(Ci.nsISelectionPrivate).removeSelectionListener(this);
       }
     }
 
     // Only try copying text if there's text to copy!
     if (arguments.length == 2 && selectedText.length) {
       let contentWindow = BrowserApp.selectedBrowser.contentWindow;
       let element = ElementTouchHelper.elementFromPoint(contentWindow, aX, aY);
       if (!element)
@@ -1606,17 +1620,16 @@ var SelectionHandler = {
           NativeWindow.toast.show(Strings.browser.GetStringFromName("selectionHelper.textCopied"), "short");
         }
       }
     }
 
     this._isRTL = false;
     this._view = null;
     this.cache = null;
-    this._active = false;
   },
 
   _getViewOffset: function sh_getViewOffset() {
     let offset = { x: 0, y: 0 };
     let win = this._view;
 
     // Recursively look through frames to compute the total position offset.
     while (win.frameElement) {