| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. |
| 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
| 5 * Copyright (C) 2015 Google Inc. All rights reserved. | 5 * Copyright (C) 2015 Google Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
| 8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
| 9 * are met: | 9 * are met: |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventSingleClick
"); | 125 TRACE_EVENT0("blink", "SelectionController::handleMousePressEventSingleClick
"); |
| 126 | 126 |
| 127 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 127 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 128 Node* innerNode = event.innerNode(); | 128 Node* innerNode = event.innerNode(); |
| 129 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) | 129 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) |
| 130 return false; | 130 return false; |
| 131 | 131 |
| 132 // Extend the selection if the Shift key is down, unless the click is in a l
ink or image. | 132 // Extend the selection if the Shift key is down, unless the click is in a l
ink or image. |
| 133 bool extendSelection = isExtendingSelection(event); | 133 bool extendSelection = isExtendingSelection(event); |
| 134 | 134 |
| 135 VisibleSelectionInFlatTree newSelection = selection().visibleSelection<Editi
ngInFlatTreeStrategy>(); |
| 136 |
| 135 // Don't restart the selection when the mouse is pressed on an | 137 // Don't restart the selection when the mouse is pressed on an |
| 136 // existing selection so we can allow for text dragging. | 138 // existing selection so we can allow for text dragging. |
| 137 if (FrameView* view = m_frame->view()) { | 139 if (FrameView* view = m_frame->view()) { |
| 138 LayoutPoint vPoint = view->rootFrameToContents(event.event().position())
; | 140 LayoutPoint vPoint = view->rootFrameToContents(event.event().position())
; |
| 139 if (!extendSelection && selection().contains(vPoint)) { | 141 if (!extendSelection && selection().contains(vPoint)) { |
| 140 m_mouseDownWasSingleClickInSelection = true; | 142 m_mouseDownWasSingleClickInSelection = true; |
| 141 return false; | 143 if (newSelection.isHandleVisible()) |
| 144 return false; |
| 142 } | 145 } |
| 143 } | 146 } |
| 144 | 147 |
| 145 VisiblePositionInFlatTree visiblePos = visiblePositionOfHitTestResult(event.
hitTestResult()); | 148 VisiblePositionInFlatTree visiblePos = visiblePositionOfHitTestResult(event.
hitTestResult()); |
| 146 if (visiblePos.isNull()) | 149 if (visiblePos.isNull()) |
| 147 visiblePos = createVisiblePosition(PositionInFlatTree::firstPositionInOr
BeforeNode(innerNode)); | 150 visiblePos = createVisiblePosition(PositionInFlatTree::firstPositionInOr
BeforeNode(innerNode)); |
| 148 PositionInFlatTree pos = visiblePos.deepEquivalent(); | 151 PositionInFlatTree pos = visiblePos.deepEquivalent(); |
| 149 | 152 |
| 150 VisibleSelectionInFlatTree newSelection = selection().visibleSelection<Editi
ngInFlatTreeStrategy>(); | |
| 151 TextGranularity granularity = CharacterGranularity; | 153 TextGranularity granularity = CharacterGranularity; |
| 152 | 154 |
| 153 if (extendSelection && !newSelection.isNone()) { | 155 if (mouseDownWasSingleClickInSelection()) { |
| 156 newSelection.setIsHandleVisible(true); |
| 157 } else if (extendSelection && !newSelection.isNone()) { |
| 154 const VisibleSelectionInFlatTree selectionInUserSelectAll(expandSelectio
nToRespectUserSelectAll(innerNode, VisibleSelectionInFlatTree(createVisiblePosit
ion(pos)))); | 158 const VisibleSelectionInFlatTree selectionInUserSelectAll(expandSelectio
nToRespectUserSelectAll(innerNode, VisibleSelectionInFlatTree(createVisiblePosit
ion(pos)))); |
| 155 if (selectionInUserSelectAll.isRange()) { | 159 if (selectionInUserSelectAll.isRange()) { |
| 156 if (selectionInUserSelectAll.start().compareTo(newSelection.start())
< 0) | 160 if (selectionInUserSelectAll.start().compareTo(newSelection.start())
< 0) |
| 157 pos = selectionInUserSelectAll.start(); | 161 pos = selectionInUserSelectAll.start(); |
| 158 else if (newSelection.end().compareTo(selectionInUserSelectAll.end()
) < 0) | 162 else if (newSelection.end().compareTo(selectionInUserSelectAll.end()
) < 0) |
| 159 pos = selectionInUserSelectAll.end(); | 163 pos = selectionInUserSelectAll.end(); |
| 160 } | 164 } |
| 161 | 165 |
| 162 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { | 166 if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()
) { |
| 163 if (pos.isNotNull()) { | 167 if (pos.isNotNull()) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 175 } else { | 179 } else { |
| 176 newSelection.setExtent(pos); | 180 newSelection.setExtent(pos); |
| 177 } | 181 } |
| 178 | 182 |
| 179 if (selection().granularity() != CharacterGranularity) { | 183 if (selection().granularity() != CharacterGranularity) { |
| 180 granularity = selection().granularity(); | 184 granularity = selection().granularity(); |
| 181 newSelection.expandUsingGranularity(selection().granularity()); | 185 newSelection.expandUsingGranularity(selection().granularity()); |
| 182 } | 186 } |
| 183 } else if (m_selectionState != SelectionState::ExtendedSelection) { | 187 } else if (m_selectionState != SelectionState::ExtendedSelection) { |
| 184 newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleS
electionInFlatTree(visiblePos)); | 188 newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleS
electionInFlatTree(visiblePos)); |
| 189 if (newSelection.isContentEditable()) { |
| 190 bool isTextBoxEmpty = VisibleSelection::selectionFromContentsOfNode(
innerNode).isCaret(); |
| 191 bool isRightClick = event.event().button() == RightButton; |
| 192 if (!isTextBoxEmpty || isRightClick) |
| 193 newSelection.setIsHandleVisible(true); |
| 194 } |
| 185 } | 195 } |
| 186 | 196 |
| 187 // Updating the selection is considered side-effect of the event and so it d
oesn't impact the handled state. | 197 // Updating the selection is considered side-effect of the event and so it d
oesn't impact the handled state. |
| 188 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g
ranularity); | 198 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, g
ranularity); |
| 189 return false; | 199 return false; |
| 190 } | 200 } |
| 191 | 201 |
| 192 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) | 202 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) |
| 193 { | 203 { |
| 194 if (!m_mouseDownMayStartSelect) | 204 if (!m_mouseDownMayStartSelect) |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 if (selectInputEventType == SelectInputEventType::Touch) { | 328 if (selectInputEventType == SelectInputEventType::Touch) { |
| 319 // If node doesn't have text except space, tab or line break, do not | 329 // If node doesn't have text except space, tab or line break, do not |
| 320 // select that 'empty' area. | 330 // select that 'empty' area. |
| 321 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end())
; | 331 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end())
; |
| 322 const String& str = plainText(range, hasEditableStyle(*innerNode) ? Text
IteratorEmitsObjectReplacementCharacter : TextIteratorDefaultBehavior); | 332 const String& str = plainText(range, hasEditableStyle(*innerNode) ? Text
IteratorEmitsObjectReplacementCharacter : TextIteratorDefaultBehavior); |
| 323 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) | 333 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) |
| 324 return; | 334 return; |
| 325 | 335 |
| 326 if (newSelection.rootEditableElement() && pos.deepEquivalent() == Visibl
ePositionInFlatTree::lastPositionInNode(newSelection.rootEditableElement()).deep
Equivalent()) | 336 if (newSelection.rootEditableElement() && pos.deepEquivalent() == Visibl
ePositionInFlatTree::lastPositionInNode(newSelection.rootEditableElement()).deep
Equivalent()) |
| 327 return; | 337 return; |
| 338 newSelection.setIsHandleVisible(true); |
| 328 } | 339 } |
| 329 | 340 |
| 330 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) | 341 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne
wSelection.isRange()) |
| 331 newSelection.appendTrailingWhitespace(); | 342 newSelection.appendTrailingWhitespace(); |
| 332 | 343 |
| 333 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 344 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
| 334 } | 345 } |
| 335 | 346 |
| 336 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) | 347 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes
tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) |
| 337 { | 348 { |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 return false; | 588 return false; |
| 578 if (hitTestResult.isLiveLink()) | 589 if (hitTestResult.isLiveLink()) |
| 579 return false; | 590 return false; |
| 580 | 591 |
| 581 Node* innerNode = hitTestResult.innerNode(); | 592 Node* innerNode = hitTestResult.innerNode(); |
| 582 innerNode->document().updateStyleAndLayoutTree(); | 593 innerNode->document().updateStyleAndLayoutTree(); |
| 583 bool innerNodeIsSelectable = innerNode && (hasEditableStyle(*innerNode) || i
nnerNode->canStartSelection()); | 594 bool innerNodeIsSelectable = innerNode && (hasEditableStyle(*innerNode) || i
nnerNode->canStartSelection()); |
| 584 if (!innerNodeIsSelectable) | 595 if (!innerNodeIsSelectable) |
| 585 return false; | 596 return false; |
| 586 | 597 |
| 598 // If longpress occurs inside of a selection that doesn't have handles |
| 599 // then we want to show the handes on the entire selection. |
| 600 if (FrameView* view = m_frame->view()) { |
| 601 LayoutPoint vPoint = view->rootFrameToContents(gestureEvent.position()); |
| 602 VisibleSelectionInFlatTree newSelection = selection().visibleSelection<E
ditingInFlatTreeStrategy>(); |
| 603 if (selection().contains(vPoint) && !newSelection.isHandleVisible()) { |
| 604 newSelection.setIsHandleVisible(true); |
| 605 selection().setNonDirectionalSelectionIfNeeded(newSelection, selecti
on().granularity()); |
| 606 return true; |
| 607 } |
| 608 } |
| 609 |
| 587 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace::
DontAppend, SelectInputEventType::Touch); | 610 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace::
DontAppend, SelectInputEventType::Touch); |
| 588 if (!selection().isAvailable()) { | 611 if (!selection().isAvailable()) { |
| 589 // "editing/selection/longpress-selection-in-iframe-removed-crash.html" | 612 // "editing/selection/longpress-selection-in-iframe-removed-crash.html" |
| 590 // reach here. | 613 // reach here. |
| 591 return false; | 614 return false; |
| 592 } | 615 } |
| 593 return selection().isRange(); | 616 return selection().isRange(); |
| 594 } | 617 } |
| 595 | 618 |
| 596 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) | 619 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 return event.event().altKey() && event.isOverLink(); | 695 return event.event().altKey() && event.isOverLink(); |
| 673 } | 696 } |
| 674 | 697 |
| 675 bool isExtendingSelection(const MouseEventWithHitTestResults& event) | 698 bool isExtendingSelection(const MouseEventWithHitTestResults& event) |
| 676 { | 699 { |
| 677 bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult().
image(); | 700 bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult().
image(); |
| 678 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; | 701 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; |
| 679 } | 702 } |
| 680 | 703 |
| 681 } // namespace blink | 704 } // namespace blink |
| OLD | NEW |