Bug 879887 - Use caretPositionFromPoint when adjusting selection in text inputs. r=mbrubeck
authorJim Mathies <jmathies@mozilla.com>
Mon, 17 Jun 2013 07:46:52 -0500
changeset 146785 6bb17ac2733d626658550d18e00872637145c325
parent 146784 bc16dc2a866f73abcbe2826ce04b5e8a25fef260
child 146786 186cf0ac8efc35da85252dcb93d21432db4ace09
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs879887
milestone24.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 879887 - Use caretPositionFromPoint when adjusting selection in text inputs. r=mbrubeck
browser/metro/base/content/contenthandlers/SelectionHandler.js
--- a/browser/metro/base/content/contenthandlers/SelectionHandler.js
+++ b/browser/metro/base/content/contenthandlers/SelectionHandler.js
@@ -659,18 +659,17 @@ var SelectionHandler = {
 
     // Adjust our y position up such that we are sending coordinates on
     // the text line vs. below it where the monocle is positioned.
     let halfLineHeight = this._queryHalfLineHeight(aMarker, selection);
     clientPoint.yPos -= halfLineHeight;
 
     // Modify selection based on monocle movement
     if (this._targetIsEditable) {
-      this._adjustEditableSelection(aMarker, clientPoint,
-                                    halfLineHeight, aEndOfSelection);
+      this._adjustEditableSelection(aMarker, clientPoint, aEndOfSelection);
     } else {
       this._adjustSelection(aMarker, clientPoint, aEndOfSelection);
     }
   },
 
   /*
    * _handleSelectionPoint helper methods
    */
@@ -678,24 +677,22 @@ var SelectionHandler = {
   /*
    * _adjustEditableSelection
    *
    * Based on a monocle marker and position, adds or subtracts from the
    * existing selection in editable controls. Handles auto-scroll as well.
    *
    * @param the marker currently being manipulated
    * @param aAdjustedClientPoint client point adjusted for line height.
-   * @param aHalfLineHeight half line height in pixels
    * @param aEndOfSelection indicates if this is the end of a selection
    * move, in which case we may want to snap to the end of a word or
    * sentence.
    */
   _adjustEditableSelection: function _adjustEditableSelection(aMarker,
                                                               aAdjustedClientPoint,
-                                                              aHalfLineHeight,
                                                               aEndOfSelection) {
     // Test to see if we need to handle auto-scroll in cases where the
     // monocle is outside the bounds of the control. This also handles
     // adjusting selection if out-of-bounds is true.
     let result = this.updateTextEditSelection(aAdjustedClientPoint);
 
     // If result.trigger is true, the monocle is outside the bounds of the
     // control.
@@ -710,24 +707,31 @@ var SelectionHandler = {
       this._setContinuousSelection();
 
       // Update the other monocle's position if we've dragged off to one side
       this._updateSelectionUI("update", result.start, result.end);
     } else {
       // If we aren't out-of-bounds, clear the scroll timer if it exists.
       this._clearTimers();
 
-      // Restrict the client point to the interior of the control. Prevents
-      // _adjustSelection from accidentally selecting content outside the
-      // control.
+      // Restrict the client point to the interior of the control.
       let constrainedPoint =
-        this._constrainPointWithinControl(aAdjustedClientPoint, aHalfLineHeight);
+        this._constrainPointWithinControl(aAdjustedClientPoint);
 
       // Add or subtract selection
-      this._adjustSelection(aMarker, constrainedPoint, aEndOfSelection);
+      let cp = this._contentWindow.document.caretPositionFromPoint(constrainedPoint.xPos,
+                                                                   constrainedPoint.yPos);
+      if (cp.offsetNode != this._targetElement) {
+        return;
+      }
+      if (aMarker == "start") {
+        this._targetElement.selectionStart = cp.offset;
+      } else {
+        this._targetElement.selectionEnd = cp.offset;
+      }
     }
   },
 
   /*
    * _adjustSelection
    *
    * Based on a monocle marker and position, adds or subtracts from the
    * existing selection.
@@ -809,30 +813,29 @@ var SelectionHandler = {
   _freeRangeList: function _restoreRangeList() {
     this._rangeBackup = null;
   },
 
   /*
    * Constrains a selection point within a text input control bounds.
    *
    * @param aPoint - client coordinate point
-   * @param aHalfLineHeight - half the line height at the point
    * @return new constrained point struct
    */
-  _constrainPointWithinControl: function _cpwc(aPoint, aHalfLineHeight) {
+  _constrainPointWithinControl: function _cpwc(aPoint) {
     let bounds = this._getTargetBrowserRect();
     let point = { xPos: aPoint.xPos, yPos: aPoint.yPos };
     if (point.xPos <= bounds.left)
       point.xPos = bounds.left + 2;
     if (point.xPos >= bounds.right)
       point.xPos = bounds.right - 2;
-    if (point.yPos <= (bounds.top + aHalfLineHeight))
-      point.yPos = (bounds.top + aHalfLineHeight);
-    if (point.yPos >= (bounds.bottom - aHalfLineHeight))
-      point.yPos = (bounds.bottom - aHalfLineHeight);
+    if (point.yPos <= bounds.top)
+      point.yPos = bounds.top + 2;
+    if (point.yPos >= bounds.bottom)
+      point.yPos = bounds.bottom - 2;
     return point;
   },
 
   /*
    * _pointOrientationToRect(aPoint, aRect)
    *
    * Returns a table representing which sides of target aPoint is offset
    * from: { left: offset, top: offset, right: offset, bottom: offset }