OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 4 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
5 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 5 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
6 * Copyright (C) 2015 Google Inc. All rights reserved. | 6 * Copyright (C) 2015 Google Inc. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "core/editing/EditingUtilities.h" | 34 #include "core/editing/EditingUtilities.h" |
35 #include "core/editing/Editor.h" | 35 #include "core/editing/Editor.h" |
36 #include "core/editing/FrameSelection.h" | 36 #include "core/editing/FrameSelection.h" |
37 #include "core/editing/RenderedPosition.h" | 37 #include "core/editing/RenderedPosition.h" |
38 #include "core/editing/iterators/TextIterator.h" | 38 #include "core/editing/iterators/TextIterator.h" |
39 #include "core/editing/markers/DocumentMarkerController.h" | 39 #include "core/editing/markers/DocumentMarkerController.h" |
40 #include "core/events/Event.h" | 40 #include "core/events/Event.h" |
41 #include "core/frame/LocalFrame.h" | 41 #include "core/frame/LocalFrame.h" |
42 #include "core/frame/LocalFrameView.h" | 42 #include "core/frame/LocalFrameView.h" |
43 #include "core/frame/Settings.h" | 43 #include "core/frame/Settings.h" |
| 44 #include "core/input/EventHandler.h" |
44 #include "core/layout/LayoutView.h" | 45 #include "core/layout/LayoutView.h" |
45 #include "core/layout/api/LayoutViewItem.h" | 46 #include "core/layout/api/LayoutViewItem.h" |
46 #include "core/page/FocusController.h" | 47 #include "core/page/FocusController.h" |
47 #include "core/page/Page.h" | 48 #include "core/page/Page.h" |
48 #include "platform/RuntimeEnabledFeatures.h" | 49 #include "platform/RuntimeEnabledFeatures.h" |
49 #include "platform/wtf/AutoReset.h" | 50 #include "platform/wtf/AutoReset.h" |
| 51 #include "public/web/WebMenuSourceType.h" |
50 | 52 |
51 namespace blink { | 53 namespace blink { |
52 SelectionController* SelectionController::Create(LocalFrame& frame) { | 54 SelectionController* SelectionController::Create(LocalFrame& frame) { |
53 return new SelectionController(frame); | 55 return new SelectionController(frame); |
54 } | 56 } |
55 | 57 |
56 SelectionController::SelectionController(LocalFrame& frame) | 58 SelectionController::SelectionController(LocalFrame& frame) |
57 : frame_(&frame), | 59 : frame_(&frame), |
58 mouse_down_may_start_select_(false), | 60 mouse_down_may_start_select_(false), |
59 mouse_down_was_single_click_in_selection_(false), | 61 mouse_down_was_single_click_in_selection_(false), |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 // existing selection so we can allow for text dragging. | 186 // existing selection so we can allow for text dragging. |
185 if (LocalFrameView* view = frame_->View()) { | 187 if (LocalFrameView* view = frame_->View()) { |
186 const LayoutPoint v_point = view->RootFrameToContents( | 188 const LayoutPoint v_point = view->RootFrameToContents( |
187 FlooredIntPoint(event.Event().PositionInRootFrame())); | 189 FlooredIntPoint(event.Event().PositionInRootFrame())); |
188 if (!extend_selection && this->Selection().Contains(v_point)) { | 190 if (!extend_selection && this->Selection().Contains(v_point)) { |
189 mouse_down_was_single_click_in_selection_ = true; | 191 mouse_down_was_single_click_in_selection_ = true; |
190 if (!event.Event().FromTouch()) | 192 if (!event.Event().FromTouch()) |
191 return false; | 193 return false; |
192 | 194 |
193 if (!this->Selection().IsHandleVisible()) { | 195 if (!this->Selection().IsHandleVisible()) { |
194 UpdateSelectionForMouseDownDispatchingSelectStart( | 196 const bool did_select = |
195 inner_node, selection, kCharacterGranularity, | 197 UpdateSelectionForMouseDownDispatchingSelectStart( |
196 HandleVisibility::kVisible); | 198 inner_node, selection, kCharacterGranularity, |
| 199 HandleVisibility::kVisible); |
| 200 if (did_select) { |
| 201 frame_->GetEventHandler().ShowNonLocatedContextMenu(nullptr, |
| 202 kMenuSourceTouch); |
| 203 } |
197 return false; | 204 return false; |
198 } | 205 } |
199 } | 206 } |
200 } | 207 } |
201 | 208 |
202 if (extend_selection && !selection.IsNone()) { | 209 if (extend_selection && !selection.IsNone()) { |
203 // Note: "fast/events/shift-click-user-select-none.html" makes | 210 // Note: "fast/events/shift-click-user-select-none.html" makes |
204 // |pos.isNull()| true. | 211 // |pos.isNull()| true. |
205 const PositionInFlatTree& pos = AdjustPositionRespectUserSelectAll( | 212 const PositionInFlatTree& pos = AdjustPositionRespectUserSelectAll( |
206 inner_node, selection.Start(), selection.end(), | 213 inner_node, selection.Start(), selection.end(), |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 | 551 |
545 if (append_trailing_whitespace == AppendTrailingWhitespace::kShouldAppend) | 552 if (append_trailing_whitespace == AppendTrailingWhitespace::kShouldAppend) |
546 new_selection.AppendTrailingWhitespace(); | 553 new_selection.AppendTrailingWhitespace(); |
547 | 554 |
548 UpdateSelectionForMouseDownDispatchingSelectStart( | 555 UpdateSelectionForMouseDownDispatchingSelectStart( |
549 inner_node, | 556 inner_node, |
550 ExpandSelectionToRespectUserSelectAll(inner_node, new_selection), | 557 ExpandSelectionToRespectUserSelectAll(inner_node, new_selection), |
551 kWordGranularity, HandleVisibility::kNotVisible); | 558 kWordGranularity, HandleVisibility::kNotVisible); |
552 } | 559 } |
553 | 560 |
554 void SelectionController::SelectClosestWordFromMouseEvent( | 561 bool SelectionController::SelectClosestWordFromMouseEvent( |
555 const MouseEventWithHitTestResults& result) { | 562 const MouseEventWithHitTestResults& result) { |
556 if (!mouse_down_may_start_select_) | 563 if (!mouse_down_may_start_select_) |
557 return; | 564 return false; |
558 | 565 |
559 AppendTrailingWhitespace append_trailing_whitespace = | 566 AppendTrailingWhitespace append_trailing_whitespace = |
560 (result.Event().click_count == 2 && | 567 (result.Event().click_count == 2 && |
561 frame_->GetEditor().IsSelectTrailingWhitespaceEnabled()) | 568 frame_->GetEditor().IsSelectTrailingWhitespaceEnabled()) |
562 ? AppendTrailingWhitespace::kShouldAppend | 569 ? AppendTrailingWhitespace::kShouldAppend |
563 : AppendTrailingWhitespace::kDontAppend; | 570 : AppendTrailingWhitespace::kDontAppend; |
564 | 571 |
565 DCHECK(!frame_->GetDocument()->NeedsLayoutTreeUpdate()); | 572 DCHECK(!frame_->GetDocument()->NeedsLayoutTreeUpdate()); |
566 | 573 |
567 SelectClosestWordFromHitTestResult( | 574 return SelectClosestWordFromHitTestResult( |
568 result.GetHitTestResult(), append_trailing_whitespace, | 575 result.GetHitTestResult(), append_trailing_whitespace, |
569 result.Event().FromTouch() ? SelectInputEventType::kTouch | 576 result.Event().FromTouch() ? SelectInputEventType::kTouch |
570 : SelectInputEventType::kMouse); | 577 : SelectInputEventType::kMouse); |
571 } | 578 } |
572 | 579 |
573 void SelectionController::SelectClosestMisspellingFromMouseEvent( | 580 void SelectionController::SelectClosestMisspellingFromMouseEvent( |
574 const MouseEventWithHitTestResults& result) { | 581 const MouseEventWithHitTestResults& result) { |
575 if (!mouse_down_may_start_select_) | 582 if (!mouse_down_may_start_select_) |
576 return; | 583 return; |
577 | 584 |
578 SelectClosestMisspellingFromHitTestResult( | 585 SelectClosestMisspellingFromHitTestResult( |
579 result.GetHitTestResult(), | 586 result.GetHitTestResult(), |
580 (result.Event().click_count == 2 && | 587 (result.Event().click_count == 2 && |
581 frame_->GetEditor().IsSelectTrailingWhitespaceEnabled()) | 588 frame_->GetEditor().IsSelectTrailingWhitespaceEnabled()) |
582 ? AppendTrailingWhitespace::kShouldAppend | 589 ? AppendTrailingWhitespace::kShouldAppend |
583 : AppendTrailingWhitespace::kDontAppend); | 590 : AppendTrailingWhitespace::kDontAppend); |
584 } | 591 } |
585 | 592 |
586 void SelectionController::SelectClosestWordOrLinkFromMouseEvent( | 593 void SelectionController::SelectClosestWordOrLinkFromMouseEvent( |
587 const MouseEventWithHitTestResults& result) { | 594 const MouseEventWithHitTestResults& result) { |
588 if (!result.GetHitTestResult().IsLiveLink()) | 595 if (!result.GetHitTestResult().IsLiveLink()) { |
589 return SelectClosestWordFromMouseEvent(result); | 596 SelectClosestWordFromMouseEvent(result); |
| 597 return; |
| 598 } |
590 | 599 |
591 Node* inner_node = result.InnerNode(); | 600 Node* inner_node = result.InnerNode(); |
592 | 601 |
593 if (!inner_node || !inner_node->GetLayoutObject() || | 602 if (!inner_node || !inner_node->GetLayoutObject() || |
594 !mouse_down_may_start_select_) | 603 !mouse_down_may_start_select_) |
595 return; | 604 return; |
596 | 605 |
597 VisibleSelectionInFlatTree new_selection; | 606 VisibleSelectionInFlatTree new_selection; |
598 Element* url_element = result.GetHitTestResult().URLElement(); | 607 Element* url_element = result.GetHitTestResult().URLElement(); |
599 const VisiblePositionInFlatTree pos = | 608 const VisiblePositionInFlatTree pos = |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 return false; | 773 return false; |
765 | 774 |
766 if (Selection().ComputeVisibleSelectionInDOMTreeDeprecated().IsRange()) { | 775 if (Selection().ComputeVisibleSelectionInDOMTreeDeprecated().IsRange()) { |
767 // A double-click when range is already selected | 776 // A double-click when range is already selected |
768 // should not change the selection. So, do not call | 777 // should not change the selection. So, do not call |
769 // selectClosestWordFromMouseEvent, but do set | 778 // selectClosestWordFromMouseEvent, but do set |
770 // m_beganSelectingText to prevent handleMouseReleaseEvent | 779 // m_beganSelectingText to prevent handleMouseReleaseEvent |
771 // from setting caret selection. | 780 // from setting caret selection. |
772 selection_state_ = SelectionState::kExtendedSelection; | 781 selection_state_ = SelectionState::kExtendedSelection; |
773 } else { | 782 } else { |
774 SelectClosestWordFromMouseEvent(event); | 783 const bool did_select = SelectClosestWordFromMouseEvent(event); |
| 784 if (did_select && Selection().IsHandleVisible()) { |
| 785 frame_->GetEventHandler().ShowNonLocatedContextMenu(nullptr, |
| 786 kMenuSourceTouch); |
| 787 } |
775 } | 788 } |
776 return true; | 789 return true; |
777 } | 790 } |
778 | 791 |
779 bool SelectionController::HandleTripleClick( | 792 bool SelectionController::HandleTripleClick( |
780 const MouseEventWithHitTestResults& event) { | 793 const MouseEventWithHitTestResults& event) { |
781 TRACE_EVENT0("blink", | 794 TRACE_EVENT0("blink", |
782 "SelectionController::handleMousePressEventTripleClick"); | 795 "SelectionController::handleMousePressEventTripleClick"); |
783 | 796 |
784 if (!Selection().IsAvailable()) { | 797 if (!Selection().IsAvailable()) { |
(...skipping 19 matching lines...) Expand all Loading... |
804 new_selection = | 817 new_selection = |
805 CreateVisibleSelection(SelectionInFlatTree::Builder() | 818 CreateVisibleSelection(SelectionInFlatTree::Builder() |
806 .Collapse(pos.ToPositionWithAffinity()) | 819 .Collapse(pos.ToPositionWithAffinity()) |
807 .SetGranularity(kParagraphGranularity) | 820 .SetGranularity(kParagraphGranularity) |
808 .Build()); | 821 .Build()); |
809 } | 822 } |
810 | 823 |
811 const bool is_handle_visible = | 824 const bool is_handle_visible = |
812 event.Event().FromTouch() && new_selection.IsRange(); | 825 event.Event().FromTouch() && new_selection.IsRange(); |
813 | 826 |
814 return UpdateSelectionForMouseDownDispatchingSelectStart( | 827 const bool did_select = UpdateSelectionForMouseDownDispatchingSelectStart( |
815 inner_node, | 828 inner_node, |
816 ExpandSelectionToRespectUserSelectAll(inner_node, new_selection), | 829 ExpandSelectionToRespectUserSelectAll(inner_node, new_selection), |
817 kParagraphGranularity, | 830 kParagraphGranularity, |
818 is_handle_visible ? HandleVisibility::kVisible | 831 is_handle_visible ? HandleVisibility::kVisible |
819 : HandleVisibility::kNotVisible); | 832 : HandleVisibility::kNotVisible); |
| 833 if (!did_select) |
| 834 return false; |
| 835 |
| 836 if (Selection().IsHandleVisible()) { |
| 837 frame_->GetEventHandler().ShowNonLocatedContextMenu(nullptr, |
| 838 kMenuSourceTouch); |
| 839 } |
| 840 return true; |
820 } | 841 } |
821 | 842 |
822 bool SelectionController::HandleMousePressEvent( | 843 bool SelectionController::HandleMousePressEvent( |
823 const MouseEventWithHitTestResults& event) { | 844 const MouseEventWithHitTestResults& event) { |
824 TRACE_EVENT0("blink", "SelectionController::handleMousePressEvent"); | 845 TRACE_EVENT0("blink", "SelectionController::handleMousePressEvent"); |
825 | 846 |
826 // If we got the event back, that must mean it wasn't prevented, | 847 // If we got the event back, that must mean it wasn't prevented, |
827 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. | 848 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. |
828 mouse_down_may_start_select_ = | 849 mouse_down_may_start_select_ = |
829 (CanMouseDownStartSelect(event.InnerNode()) || IsLinkSelection(event)) && | 850 (CanMouseDownStartSelect(event.InnerNode()) || IsLinkSelection(event)) && |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 | 1163 |
1143 bool IsExtendingSelection(const MouseEventWithHitTestResults& event) { | 1164 bool IsExtendingSelection(const MouseEventWithHitTestResults& event) { |
1144 bool is_mouse_down_on_link_or_image = | 1165 bool is_mouse_down_on_link_or_image = |
1145 event.IsOverLink() || event.GetHitTestResult().GetImage(); | 1166 event.IsOverLink() || event.GetHitTestResult().GetImage(); |
1146 return (event.Event().GetModifiers() & WebInputEvent::Modifiers::kShiftKey) != | 1167 return (event.Event().GetModifiers() & WebInputEvent::Modifiers::kShiftKey) != |
1147 0 && | 1168 0 && |
1148 !is_mouse_down_on_link_or_image; | 1169 !is_mouse_down_on_link_or_image; |
1149 } | 1170 } |
1150 | 1171 |
1151 } // namespace blink | 1172 } // namespace blink |
OLD | NEW |