Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: third_party/WebKit/Source/core/editing/SelectionController.cpp

Issue 2201853002: Blink handle selection handle visibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: default handle visibility should be false Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698