Bug 855417 - don't display caret monocle if there is no selection in focused inputs. r=ally
authorJim Mathies <jmathies@mozilla.com>
Fri, 05 Apr 2013 05:33:40 -0500
changeset 127775 842c175f344c4df1f33c9852a12134d4fa6d64e0
parent 127774 59e4c48fa13fe08e73903fac1ec6e3d40d7e33a8
child 127776 a5aa2d31e8e9a9ef9dd4b0eb60690452fd0ad351
push id24512
push userryanvm@gmail.com
push dateFri, 05 Apr 2013 20:13:49 +0000
treeherdermozilla-central@139b6ba547fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersally
bugs855417
milestone23.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 855417 - don't display caret monocle if there is no selection in focused inputs. r=ally
browser/metro/base/content/contenthandlers/SelectionHandler.js
browser/metro/base/content/helperui/SelectionHelperUI.js
--- a/browser/metro/base/content/contenthandlers/SelectionHandler.js
+++ b/browser/metro/base/content/contenthandlers/SelectionHandler.js
@@ -520,17 +520,17 @@ var SelectionHandler = {
   /*
    * _updateUIMarkerRects(aSelection)
    *
    * Extracts the rects of the current selection, clips them to any text
    * input bounds, and stores them in the cache table we send over to
    * SelectionHelperUI.
    */
   _updateUIMarkerRects: function _updateUIMarkerRects(aSelection) {
-    this._cache = this._extractClientRectFromRange(aSelection.getRangeAt(0));
+    this._cache = this._extractUIRects(aSelection.getRangeAt(0));
     if (this. _debugOptions.dumpRanges)  {
        Util.dumpLn("start:", "(" + this._cache.start.xPos + "," +
                    this._cache.start.yPos + ")");
        Util.dumpLn("end:", "(" + this._cache.end.xPos + "," +
                    this._cache.end.yPos + ")");
        Util.dumpLn("caret:", "(" + this._cache.caret.xPos + "," +
                    this._cache.caret.yPos + ")");
     }
@@ -1130,66 +1130,68 @@ var SelectionHandler = {
     }
   },
 
   /*
    * Utilities
    */
 
   /*
-   * Returns data on the position of a selection using the relative
-   * coordinates in a range extracted from any sub frames. If aRange
-   * is in the root frame offset should be zero. 
+   * _extractUIRects - Extracts selection and target element information
+   * used by SelectionHelperUI. Returns client relative coordinates.
+   *
+   * @return table containing various ui rects and information
    */
-  _extractClientRectFromRange: function _extractClientRectFromRange(aRange) {
-    let cache = {
+  _extractUIRects: function _extractUIRects(aRange) {
+    let seldata = {
       start: {}, end: {}, caret: {},
       selection: { left: 0, top: 0, right: 0, bottom: 0 },
       element: { left: 0, top: 0, right: 0, bottom: 0 }
     };
 
     // When in an iframe, aRange coordinates are relative to the frame origin.
     let rects = aRange.getClientRects();
 
-    let startSet = false;
-    for (let idx = 0; idx < rects.length; idx++) {
-      if (this. _debugOptions.dumpRanges) Util.dumpDOMRect(idx, rects[idx]);
-      if (!startSet && !Util.isEmptyDOMRect(rects[idx])) {
-        cache.start.xPos = rects[idx].left + this._contentOffset.x;
-        cache.start.yPos = rects[idx].bottom + this._contentOffset.y;
-        cache.caret = cache.start;
-        startSet = true;
-        if (this. _debugOptions.dumpRanges) Util.dumpLn("start set");
+    if (rects && rects.length) {
+      let startSet = false;
+      for (let idx = 0; idx < rects.length; idx++) {
+        if (this. _debugOptions.dumpRanges) Util.dumpDOMRect(idx, rects[idx]);
+        if (!startSet && !Util.isEmptyDOMRect(rects[idx])) {
+          seldata.start.xPos = rects[idx].left + this._contentOffset.x;
+          seldata.start.yPos = rects[idx].bottom + this._contentOffset.y;
+          seldata.caret = seldata.start;
+          startSet = true;
+          if (this. _debugOptions.dumpRanges) Util.dumpLn("start set");
+        }
+        if (!Util.isEmptyDOMRect(rects[idx])) {
+          seldata.end.xPos = rects[idx].right + this._contentOffset.x;
+          seldata.end.yPos = rects[idx].bottom + this._contentOffset.y;
+          if (this. _debugOptions.dumpRanges) Util.dumpLn("end set");
+        }
       }
-      if (!Util.isEmptyDOMRect(rects[idx])) {
-        cache.end.xPos = rects[idx].right + this._contentOffset.x;
-        cache.end.yPos = rects[idx].bottom + this._contentOffset.y;
-        if (this. _debugOptions.dumpRanges) Util.dumpLn("end set");
-      }
+
+      // Store the client rect of selection
+      let r = aRange.getBoundingClientRect();
+      seldata.selection.left = r.left + this._contentOffset.x;
+      seldata.selection.top = r.top + this._contentOffset.y;
+      seldata.selection.right = r.right + this._contentOffset.x;
+      seldata.selection.bottom = r.bottom + this._contentOffset.y;
     }
 
-    // Store the client rect of selection
-    let r = aRange.getBoundingClientRect();
-    cache.selection.left = r.left + this._contentOffset.x;
-    cache.selection.top = r.top + this._contentOffset.y;
-    cache.selection.right = r.right + this._contentOffset.x;
-    cache.selection.bottom = r.bottom + this._contentOffset.y;
-
     // Store the client rect of target element
     r = this._getTargetClientRect();
-    cache.element.left = r.left + this._contentOffset.x;
-    cache.element.top = r.top + this._contentOffset.y;
-    cache.element.right = r.right + this._contentOffset.x;
-    cache.element.bottom = r.bottom + this._contentOffset.y;
+    seldata.element.left = r.left + this._contentOffset.x;
+    seldata.element.top = r.top + this._contentOffset.y;
+    seldata.element.right = r.right + this._contentOffset.x;
+    seldata.element.bottom = r.bottom + this._contentOffset.y;
 
-    if (!rects.length) {
-      Util.dumpLn("no rects in selection range. unexpected.");
-    }
+    // If we don't have a range we can attach to let SelectionHelperUI know.
+    seldata.selectionRangeFound = !!rects.length;
 
-    return cache;
+    return seldata;
   },
 
   _getTargetClientRect: function _getTargetClientRect() {
     return this._targetElement.getBoundingClientRect();
   },
 
    /*
     * Translate a top level client point to frame relative client point.
--- a/browser/metro/base/content/helperui/SelectionHelperUI.js
+++ b/browser/metro/base/content/helperui/SelectionHelperUI.js
@@ -765,18 +765,26 @@ var SelectionHelperUI = {
       this.startMark.position(json.start.xPos, json.start.yPos);
       this.startMark.show();
     }
     if (json.updateEnd) {
       this.endMark.position(json.end.xPos, json.end.yPos);
       this.endMark.show();
     }
     if (json.updateCaret) {
-      this.caretMark.position(json.caret.xPos, json.caret.yPos);
-      this.caretMark.show();
+      // If selectionRangeFound is set SelectionHelper found a range we can
+      // attach to. If not, there's no text in the control, and hence no caret
+      // position information we can use.
+      if (json.selectionRangeFound) {
+        this.caretMark.position(json.caret.xPos, json.caret.yPos);
+        this.caretMark.show();
+      } else {
+        // Don't display anything, just shutdown.
+        this.closeEditSession();
+      }
     }
     this._activeSelectionRect = json.selection;
     this._targetElementRect = json.element;
     this._targetIsEditable = json.targetIsEditable;
   },
 
   _onSelectionFail: function _onSelectionFail() {
     Util.dumpLn("failed to get a selection.");