Chromium Code Reviews| 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() || !event.event().fromTouch()) |
| 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(event.event().fromTouch()); | |
|
aelias_OOO_until_Jul13
2016/08/08 21:30:51
The changes in this file are intentionally changin
| |
| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) | 454 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) |
| 444 return false; | 455 return false; |
| 445 | 456 |
| 446 VisibleSelectionInFlatTree newSelection; | 457 VisibleSelectionInFlatTree newSelection; |
| 447 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(event. hitTestResult()); | 458 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(event. hitTestResult()); |
| 448 if (pos.isNotNull()) { | 459 if (pos.isNotNull()) { |
| 449 newSelection = VisibleSelectionInFlatTree(pos); | 460 newSelection = VisibleSelectionInFlatTree(pos); |
| 450 newSelection.expandUsingGranularity(ParagraphGranularity); | 461 newSelection.expandUsingGranularity(ParagraphGranularity); |
| 451 } | 462 } |
| 452 | 463 |
| 464 newSelection.setIsHandleVisible(event.event().fromTouch()); | |
| 465 | |
| 453 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); | 466 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); |
| 454 } | 467 } |
| 455 | 468 |
| 456 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul ts& event) | 469 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul ts& event) |
| 457 { | 470 { |
| 458 // If we got the event back, that must mean it wasn't prevented, | 471 // If we got the event back, that must mean it wasn't prevented, |
| 459 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. | 472 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. |
| 460 m_mouseDownMayStartSelect = (canMouseDownStartSelect(event.innerNode()) || i sLinkSelection(event)) | 473 m_mouseDownMayStartSelect = (canMouseDownStartSelect(event.innerNode()) || i sLinkSelection(event)) |
| 461 && !event.scrollbar(); | 474 && !event.scrollbar(); |
| 462 m_mouseDownWasSingleClickInSelection = false; | 475 m_mouseDownWasSingleClickInSelection = false; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 return false; | 590 return false; |
| 578 if (hitTestResult.isLiveLink()) | 591 if (hitTestResult.isLiveLink()) |
| 579 return false; | 592 return false; |
| 580 | 593 |
| 581 Node* innerNode = hitTestResult.innerNode(); | 594 Node* innerNode = hitTestResult.innerNode(); |
| 582 innerNode->document().updateStyleAndLayoutTree(); | 595 innerNode->document().updateStyleAndLayoutTree(); |
| 583 bool innerNodeIsSelectable = innerNode && (hasEditableStyle(*innerNode) || i nnerNode->canStartSelection()); | 596 bool innerNodeIsSelectable = innerNode && (hasEditableStyle(*innerNode) || i nnerNode->canStartSelection()); |
| 584 if (!innerNodeIsSelectable) | 597 if (!innerNodeIsSelectable) |
| 585 return false; | 598 return false; |
| 586 | 599 |
| 600 // If longpress occurs inside of a selection that doesn't have handles | |
| 601 // then we want to show the handes on the entire selection. | |
| 602 if (FrameView* view = m_frame->view()) { | |
| 603 LayoutPoint vPoint = view->rootFrameToContents(gestureEvent.position()); | |
| 604 VisibleSelectionInFlatTree newSelection = selection().visibleSelection<E ditingInFlatTreeStrategy>(); | |
| 605 if (selection().contains(vPoint) && !newSelection.isHandleVisible()) { | |
|
aelias_OOO_until_Jul13
2016/08/08 21:30:51
FrameSelection::contains() performs another hit te
amaralp
2016/10/14 00:53:07
Done.
| |
| 606 newSelection.setIsHandleVisible(true); | |
| 607 selection().setNonDirectionalSelectionIfNeeded(newSelection, selecti on().granularity()); | |
| 608 return true; | |
| 609 } | |
| 610 } | |
| 611 | |
| 587 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace:: DontAppend, SelectInputEventType::Touch); | 612 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace:: DontAppend, SelectInputEventType::Touch); |
| 588 if (!selection().isAvailable()) { | 613 if (!selection().isAvailable()) { |
| 589 // "editing/selection/longpress-selection-in-iframe-removed-crash.html" | 614 // "editing/selection/longpress-selection-in-iframe-removed-crash.html" |
| 590 // reach here. | 615 // reach here. |
| 591 return false; | 616 return false; |
| 592 } | 617 } |
| 593 return selection().isRange(); | 618 return selection().isRange(); |
| 594 } | 619 } |
| 595 | 620 |
| 596 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult s& mev, const LayoutPoint& position) | 621 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(); | 697 return event.event().altKey() && event.isOverLink(); |
| 673 } | 698 } |
| 674 | 699 |
| 675 bool isExtendingSelection(const MouseEventWithHitTestResults& event) | 700 bool isExtendingSelection(const MouseEventWithHitTestResults& event) |
| 676 { | 701 { |
| 677 bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult(). image(); | 702 bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult(). image(); |
| 678 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; | 703 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; |
| 679 } | 704 } |
| 680 | 705 |
| 681 } // namespace blink | 706 } // namespace blink |
| OLD | NEW |