| 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 |
| 3 * reserved. |
| 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 4 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 5 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
| 5 * Copyright (C) 2015 Google Inc. All rights reserved. | 6 * Copyright (C) 2015 Google Inc. All rights reserved. |
| 6 * | 7 * |
| 7 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
| 8 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
| 9 * are met: | 10 * are met: |
| 10 * 1. Redistributions of source code must retain the above copyright | 11 * 1. Redistributions of source code must retain the above copyright |
| 11 * notice, this list of conditions and the following disclaimer. | 12 * notice, this list of conditions and the following disclaimer. |
| 12 * 2. Redistributions in binary form must reproduce the above copyright | 13 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 bool SelectionController::handleMousePressEventSingleClick( | 126 bool SelectionController::handleMousePressEventSingleClick( |
| 126 const MouseEventWithHitTestResults& event) { | 127 const MouseEventWithHitTestResults& event) { |
| 127 TRACE_EVENT0("blink", | 128 TRACE_EVENT0("blink", |
| 128 "SelectionController::handleMousePressEventSingleClick"); | 129 "SelectionController::handleMousePressEventSingleClick"); |
| 129 | 130 |
| 130 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); | 131 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); |
| 131 Node* innerNode = event.innerNode(); | 132 Node* innerNode = event.innerNode(); |
| 132 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) | 133 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) |
| 133 return false; | 134 return false; |
| 134 | 135 |
| 135 // Extend the selection if the Shift key is down, unless the click is in a lin
k or image. | 136 // Extend the selection if the Shift key is down, unless the click is in a |
| 137 // link or image. |
| 136 bool extendSelection = isExtendingSelection(event); | 138 bool extendSelection = isExtendingSelection(event); |
| 137 | 139 |
| 138 // Don't restart the selection when the mouse is pressed on an | 140 // Don't restart the selection when the mouse is pressed on an |
| 139 // existing selection so we can allow for text dragging. | 141 // existing selection so we can allow for text dragging. |
| 140 if (FrameView* view = m_frame->view()) { | 142 if (FrameView* view = m_frame->view()) { |
| 141 LayoutPoint vPoint = view->rootFrameToContents(event.event().position()); | 143 LayoutPoint vPoint = view->rootFrameToContents(event.event().position()); |
| 142 if (!extendSelection && selection().contains(vPoint)) { | 144 if (!extendSelection && selection().contains(vPoint)) { |
| 143 m_mouseDownWasSingleClickInSelection = true; | 145 m_mouseDownWasSingleClickInSelection = true; |
| 144 return false; | 146 return false; |
| 145 } | 147 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 188 |
| 187 if (selection().granularity() != CharacterGranularity) { | 189 if (selection().granularity() != CharacterGranularity) { |
| 188 granularity = selection().granularity(); | 190 granularity = selection().granularity(); |
| 189 newSelection.expandUsingGranularity(selection().granularity()); | 191 newSelection.expandUsingGranularity(selection().granularity()); |
| 190 } | 192 } |
| 191 } else if (m_selectionState != SelectionState::ExtendedSelection) { | 193 } else if (m_selectionState != SelectionState::ExtendedSelection) { |
| 192 newSelection = expandSelectionToRespectUserSelectAll( | 194 newSelection = expandSelectionToRespectUserSelectAll( |
| 193 innerNode, createVisibleSelection(visiblePos)); | 195 innerNode, createVisibleSelection(visiblePos)); |
| 194 } | 196 } |
| 195 | 197 |
| 196 // Updating the selection is considered side-effect of the event and so it doe
sn't impact the handled state. | 198 // Updating the selection is considered side-effect of the event and so it |
| 199 // doesn't impact the handled state. |
| 197 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, | 200 updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, |
| 198 granularity); | 201 granularity); |
| 199 return false; | 202 return false; |
| 200 } | 203 } |
| 201 | 204 |
| 202 void SelectionController::updateSelectionForMouseDrag( | 205 void SelectionController::updateSelectionForMouseDrag( |
| 203 const HitTestResult& hitTestResult, | 206 const HitTestResult& hitTestResult, |
| 204 Node* mousePressNode, | 207 Node* mousePressNode, |
| 205 const LayoutPoint& dragStartPos, | 208 const LayoutPoint& dragStartPos, |
| 206 const IntPoint& lastKnownMousePosition) { | 209 const IntPoint& lastKnownMousePosition) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 218 const PositionWithAffinity& rawTargetPosition = | 221 const PositionWithAffinity& rawTargetPosition = |
| 219 positionRespectingEditingBoundary(selection().selection().start(), | 222 positionRespectingEditingBoundary(selection().selection().start(), |
| 220 hitTestResult.localPoint(), target); | 223 hitTestResult.localPoint(), target); |
| 221 VisiblePositionInFlatTree targetPosition = createVisiblePosition( | 224 VisiblePositionInFlatTree targetPosition = createVisiblePosition( |
| 222 fromPositionInDOMTree<EditingInFlatTreeStrategy>(rawTargetPosition)); | 225 fromPositionInDOMTree<EditingInFlatTreeStrategy>(rawTargetPosition)); |
| 223 // Don't modify the selection if we're not on a node. | 226 // Don't modify the selection if we're not on a node. |
| 224 if (targetPosition.isNull()) | 227 if (targetPosition.isNull()) |
| 225 return; | 228 return; |
| 226 | 229 |
| 227 // Restart the selection if this is the first mouse move. This work is usually | 230 // Restart the selection if this is the first mouse move. This work is usually |
| 228 // done in handleMousePressEvent, but not if the mouse press was on an existin
g selection. | 231 // done in handleMousePressEvent, but not if the mouse press was on an |
| 232 // existing selection. |
| 229 VisibleSelectionInFlatTree newSelection = | 233 VisibleSelectionInFlatTree newSelection = |
| 230 selection().visibleSelection<EditingInFlatTreeStrategy>(); | 234 selection().visibleSelection<EditingInFlatTreeStrategy>(); |
| 231 | 235 |
| 232 // Special case to limit selection to the containing block for SVG text. | 236 // Special case to limit selection to the containing block for SVG text. |
| 233 // FIXME: Isn't there a better non-SVG-specific way to do this? | 237 // FIXME: Isn't there a better non-SVG-specific way to do this? |
| 234 if (Node* selectionBaseNode = newSelection.base().anchorNode()) { | 238 if (Node* selectionBaseNode = newSelection.base().anchorNode()) { |
| 235 if (LayoutObject* selectionBaseLayoutObject = | 239 if (LayoutObject* selectionBaseLayoutObject = |
| 236 selectionBaseNode->layoutObject()) { | 240 selectionBaseNode->layoutObject()) { |
| 237 if (selectionBaseLayoutObject->isSVGText()) { | 241 if (selectionBaseLayoutObject->isSVGText()) { |
| 238 if (target->layoutObject()->containingBlock() != | 242 if (target->layoutObject()->containingBlock() != |
| (...skipping 25 matching lines...) Expand all Loading... |
| 264 EditingInFlatTreeStrategy::rootUserSelectAllForNode(target); | 268 EditingInFlatTreeStrategy::rootUserSelectAllForNode(target); |
| 265 if (rootUserSelectAllForMousePressNode && | 269 if (rootUserSelectAllForMousePressNode && |
| 266 rootUserSelectAllForMousePressNode == rootUserSelectAllForTarget) { | 270 rootUserSelectAllForMousePressNode == rootUserSelectAllForTarget) { |
| 267 newSelection.setBase(mostBackwardCaretPosition( | 271 newSelection.setBase(mostBackwardCaretPosition( |
| 268 PositionInFlatTree::beforeNode(rootUserSelectAllForMousePressNode), | 272 PositionInFlatTree::beforeNode(rootUserSelectAllForMousePressNode), |
| 269 CanCrossEditingBoundary)); | 273 CanCrossEditingBoundary)); |
| 270 newSelection.setExtent(mostForwardCaretPosition( | 274 newSelection.setExtent(mostForwardCaretPosition( |
| 271 PositionInFlatTree::afterNode(rootUserSelectAllForMousePressNode), | 275 PositionInFlatTree::afterNode(rootUserSelectAllForMousePressNode), |
| 272 CanCrossEditingBoundary)); | 276 CanCrossEditingBoundary)); |
| 273 } else { | 277 } else { |
| 274 // Reset base for user select all when base is inside user-select-all area
and extent < base. | 278 // Reset base for user select all when base is inside user-select-all area |
| 279 // and extent < base. |
| 275 if (rootUserSelectAllForMousePressNode) { | 280 if (rootUserSelectAllForMousePressNode) { |
| 276 PositionInFlatTree eventPosition = toPositionInFlatTree( | 281 PositionInFlatTree eventPosition = toPositionInFlatTree( |
| 277 target->layoutObject() | 282 target->layoutObject() |
| 278 ->positionForPoint(hitTestResult.localPoint()) | 283 ->positionForPoint(hitTestResult.localPoint()) |
| 279 .position()); | 284 .position()); |
| 280 PositionInFlatTree dragStartPosition = | 285 PositionInFlatTree dragStartPosition = |
| 281 toPositionInFlatTree(mousePressNode->layoutObject() | 286 toPositionInFlatTree(mousePressNode->layoutObject() |
| 282 ->positionForPoint(dragStartPos) | 287 ->positionForPoint(dragStartPos) |
| 283 .position()); | 288 .position()); |
| 284 if (eventPosition.compareTo(dragStartPosition) < 0) | 289 if (eventPosition.compareTo(dragStartPosition) < 0) |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 handled = true; | 656 handled = true; |
| 652 } | 657 } |
| 653 | 658 |
| 654 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); | 659 selection().notifyLayoutObjectOfSelectionChange(UserTriggered); |
| 655 | 660 |
| 656 selection().selectFrameElementInParentIfFullySelected(); | 661 selection().selectFrameElementInParentIfFullySelected(); |
| 657 | 662 |
| 658 if (event.event().pointerProperties().button == | 663 if (event.event().pointerProperties().button == |
| 659 WebPointerProperties::Button::Middle && | 664 WebPointerProperties::Button::Middle && |
| 660 !event.isOverLink()) { | 665 !event.isOverLink()) { |
| 661 // Ignore handled, since we want to paste to where the caret was placed anyw
ay. | 666 // Ignore handled, since we want to paste to where the caret was placed |
| 667 // anyway. |
| 662 handled = handlePasteGlobalSelection(event.event()) || handled; | 668 handled = handlePasteGlobalSelection(event.event()) || handled; |
| 663 } | 669 } |
| 664 | 670 |
| 665 return handled; | 671 return handled; |
| 666 } | 672 } |
| 667 | 673 |
| 668 bool SelectionController::handlePasteGlobalSelection( | 674 bool SelectionController::handlePasteGlobalSelection( |
| 669 const PlatformMouseEvent& mouseEvent) { | 675 const PlatformMouseEvent& mouseEvent) { |
| 670 // If the event was a middle click, attempt to copy global selection in after | 676 // If the event was a middle click, attempt to copy global selection in after |
| 671 // the newly set caret position. | 677 // the newly set caret position. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 pos.deepEquivalent().parentAnchoredEquivalent()), | 746 pos.deepEquivalent().parentAnchoredEquivalent()), |
| 741 DocumentMarker::MisspellingMarkers()) | 747 DocumentMarker::MisspellingMarkers()) |
| 742 .size() > 0; | 748 .size() > 0; |
| 743 } | 749 } |
| 744 | 750 |
| 745 void SelectionController::sendContextMenuEvent( | 751 void SelectionController::sendContextMenuEvent( |
| 746 const MouseEventWithHitTestResults& mev, | 752 const MouseEventWithHitTestResults& mev, |
| 747 const LayoutPoint& position) { | 753 const LayoutPoint& position) { |
| 748 if (!selection().isAvailable()) | 754 if (!selection().isAvailable()) |
| 749 return; | 755 return; |
| 750 if (selection().contains(position) || mev.scrollbar() | 756 if (selection().contains(position) || mev.scrollbar() || |
| 751 // FIXME: In the editable case, word selection sometimes selects content t
hat isn't underneath the mouse. | 757 // FIXME: In the editable case, word selection sometimes selects content |
| 752 // If the selection is non-editable, we do word selection to make it easie
r to use the contextual menu items | 758 // that isn't underneath the mouse. |
| 753 // available for text selections. But only if we're above text. | 759 // If the selection is non-editable, we do word selection to make it |
| 754 || | 760 // easier to use the contextual menu items available for text selections. |
| 761 // But only if we're above text. |
| 755 !(selection().isContentEditable() || | 762 !(selection().isContentEditable() || |
| 756 (mev.innerNode() && mev.innerNode()->isTextNode()))) | 763 (mev.innerNode() && mev.innerNode()->isTextNode()))) |
| 757 return; | 764 return; |
| 758 | 765 |
| 759 // Context menu events are always allowed to perform a selection. | 766 // Context menu events are always allowed to perform a selection. |
| 760 AutoReset<bool> mouseDownMayStartSelectChange(&m_mouseDownMayStartSelect, | 767 AutoReset<bool> mouseDownMayStartSelectChange(&m_mouseDownMayStartSelect, |
| 761 true); | 768 true); |
| 762 | 769 |
| 763 if (hitTestResultIsMisspelled(mev.hitTestResult())) | 770 if (hitTestResultIsMisspelled(mev.hitTestResult())) |
| 764 return selectClosestMisspellingFromMouseEvent(mev); | 771 return selectClosestMisspellingFromMouseEvent(mev); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 return event.event().altKey() && event.isOverLink(); | 829 return event.event().altKey() && event.isOverLink(); |
| 823 } | 830 } |
| 824 | 831 |
| 825 bool isExtendingSelection(const MouseEventWithHitTestResults& event) { | 832 bool isExtendingSelection(const MouseEventWithHitTestResults& event) { |
| 826 bool isMouseDownOnLinkOrImage = | 833 bool isMouseDownOnLinkOrImage = |
| 827 event.isOverLink() || event.hitTestResult().image(); | 834 event.isOverLink() || event.hitTestResult().image(); |
| 828 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; | 835 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; |
| 829 } | 836 } |
| 830 | 837 |
| 831 } // namespace blink | 838 } // namespace blink |
| OLD | NEW |