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 |