| Index: third_party/WebKit/Source/core/editing/SelectionController.cpp | 
| diff --git a/third_party/WebKit/Source/core/editing/SelectionController.cpp b/third_party/WebKit/Source/core/editing/SelectionController.cpp | 
| index f914c37182f54a58dc10ae16974d1319aab28bab..ede9e1f60755830d568de713344fcaf84f896f10 100644 | 
| --- a/third_party/WebKit/Source/core/editing/SelectionController.cpp | 
| +++ b/third_party/WebKit/Source/core/editing/SelectionController.cpp | 
| @@ -139,12 +139,10 @@ bool SelectionController::handleMousePressEventSingleClick( | 
|  | 
| // Don't restart the selection when the mouse is pressed on an | 
| // existing selection so we can allow for text dragging. | 
| -  if (FrameView* view = m_frame->view()) { | 
| -    LayoutPoint vPoint = view->rootFrameToContents(event.event().position()); | 
| -    if (!extendSelection && selection().contains(vPoint)) { | 
| -      m_mouseDownWasSingleClickInSelection = true; | 
| +  if (!extendSelection && selection().contains(event.hitTestResult())) { | 
| +    m_mouseDownWasSingleClickInSelection = true; | 
| +    if (!event.event().fromTouch()) | 
| return false; | 
| -    } | 
| } | 
|  | 
| VisiblePositionInFlatTree visiblePos = | 
| @@ -157,8 +155,10 @@ bool SelectionController::handleMousePressEventSingleClick( | 
| VisibleSelectionInFlatTree newSelection = | 
| selection().visibleSelection<EditingInFlatTreeStrategy>(); | 
| TextGranularity granularity = CharacterGranularity; | 
| - | 
| -  if (extendSelection && !newSelection.isNone()) { | 
| +  bool isHandleVisible = false; | 
| +  if (mouseDownWasSingleClickInSelection() && !selection().isHandleVisible()) { | 
| +    isHandleVisible = true; | 
| +  } else if (extendSelection && !newSelection.isNone()) { | 
| const VisibleSelectionInFlatTree selectionInUserSelectAll( | 
| expandSelectionToRespectUserSelectAll(innerNode, | 
| createVisibleSelection(pos))); | 
| @@ -193,12 +193,20 @@ bool SelectionController::handleMousePressEventSingleClick( | 
| } else if (m_selectionState != SelectionState::ExtendedSelection) { | 
| newSelection = expandSelectionToRespectUserSelectAll( | 
| innerNode, createVisibleSelection(visiblePos)); | 
| +    if (newSelection.isContentEditable()) { | 
| +      bool isTextBoxEmpty = | 
| +          VisibleSelection::selectionFromContentsOfNode(innerNode).isCaret(); | 
| +      bool notLeftClick = event.event().pointerProperties().button != | 
| +                          WebPointerProperties::Button::Left; | 
| +      if (!isTextBoxEmpty || notLeftClick) | 
| +        isHandleVisible = event.event().fromTouch(); | 
| +    } | 
| } | 
|  | 
| // Updating the selection is considered side-effect of the event and so it | 
| // doesn't impact the handled state. | 
| -  updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, | 
| -                                                    granularity); | 
| +  updateSelectionForMouseDownDispatchingSelectStart( | 
| +      innerNode, newSelection, granularity, isHandleVisible); | 
| return false; | 
| } | 
|  | 
| @@ -326,7 +334,8 @@ void SelectionController::updateSelectionForMouseDrag( | 
| bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart( | 
| Node* targetNode, | 
| const VisibleSelectionInFlatTree& selection, | 
| -    TextGranularity granularity) { | 
| +    TextGranularity granularity, | 
| +    bool isHandleVisible) { | 
| if (targetNode && targetNode->layoutObject() && | 
| !targetNode->layoutObject()->isSelectable()) | 
| return false; | 
| @@ -348,7 +357,9 @@ bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart( | 
| m_selectionState = SelectionState::PlacedCaret; | 
| } | 
|  | 
| -  this->selection().setNonDirectionalSelectionIfNeeded(selection, granularity); | 
| +  this->selection().setNonDirectionalSelectionIfNeeded( | 
| +      selection, granularity, FrameSelection::DoNotAdjustEndpoints, | 
| +      isHandleVisible); | 
|  | 
| return true; | 
| } | 
| @@ -379,6 +390,7 @@ void SelectionController::selectClosestWordFromHitTestResult( | 
| newSelection.expandUsingGranularity(WordGranularity); | 
| } | 
|  | 
| +  bool isHandleVisible = false; | 
| if (selectInputEventType == SelectInputEventType::Touch) { | 
| // If node doesn't have text except space, tab or line break, do not | 
| // select that 'empty' area. | 
| @@ -396,6 +408,7 @@ void SelectionController::selectClosestWordFromHitTestResult( | 
| newSelection.rootEditableElement()) | 
| .deepEquivalent()) | 
| return; | 
| +    isHandleVisible = true; | 
| } | 
|  | 
| if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && | 
| @@ -404,7 +417,7 @@ void SelectionController::selectClosestWordFromHitTestResult( | 
|  | 
| updateSelectionForMouseDownDispatchingSelectStart( | 
| innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), | 
| -      WordGranularity); | 
| +      WordGranularity, isHandleVisible); | 
| } | 
|  | 
| void SelectionController::selectClosestMisspellingFromHitTestResult( | 
| @@ -554,9 +567,11 @@ bool SelectionController::handleMousePressEventTripleClick( | 
| newSelection.expandUsingGranularity(ParagraphGranularity); | 
| } | 
|  | 
| +  bool isHandleVisible = event.event().fromTouch() && newSelection.isRange(); | 
| + | 
| return updateSelectionForMouseDownDispatchingSelectStart( | 
| innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), | 
| -      ParagraphGranularity); | 
| +      ParagraphGranularity, isHandleVisible); | 
| } | 
|  | 
| void SelectionController::handleMousePressEvent( | 
| @@ -750,7 +765,7 @@ void SelectionController::sendContextMenuEvent( | 
| const LayoutPoint& position) { | 
| if (!selection().isAvailable()) | 
| return; | 
| -  if (selection().contains(position) || mev.scrollbar() || | 
| +  if (selection().contains(mev.hitTestResult()) || mev.scrollbar() || | 
| // FIXME: In the editable case, word selection sometimes selects content | 
| // that isn't underneath the mouse. | 
| // If the selection is non-editable, we do word selection to make it | 
| @@ -779,8 +794,7 @@ void SelectionController::passMousePressEventToSubframe( | 
| // greyed out even though we're clicking on the selection.  This looks | 
| // really strange (having the whole frame be greyed out), so we deselect the | 
| // selection. | 
| -  IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); | 
| -  if (!selection().contains(p)) | 
| +  if (!selection().contains(mev.hitTestResult())) | 
| return; | 
|  | 
| // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 
|  |