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 |