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

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: fixed incorrect rebase Created 3 years, 11 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 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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 160
161 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); 161 DCHECK(!m_frame->document()->needsLayoutTreeUpdate());
162 Node* innerNode = event.innerNode(); 162 Node* innerNode = event.innerNode();
163 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) 163 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
164 return false; 164 return false;
165 165
166 // Extend the selection if the Shift key is down, unless the click is in a 166 // Extend the selection if the Shift key is down, unless the click is in a
167 // link or image. 167 // link or image.
168 bool extendSelection = isExtendingSelection(event); 168 bool extendSelection = isExtendingSelection(event);
169 169
170 // Don't restart the selection when the mouse is pressed on an
171 // existing selection so we can allow for text dragging.
172 if (FrameView* view = m_frame->view()) {
173 LayoutPoint vPoint = view->rootFrameToContents(event.event().position());
174 if (!extendSelection && selection().contains(vPoint)) {
175 m_mouseDownWasSingleClickInSelection = true;
176 return false;
177 }
178 }
179
180 const VisiblePositionInFlatTree& visibleHitPos = 170 const VisiblePositionInFlatTree& visibleHitPos =
181 visiblePositionOfHitTestResult(event.hitTestResult()); 171 visiblePositionOfHitTestResult(event.hitTestResult());
182 const VisiblePositionInFlatTree& visiblePos = 172 const VisiblePositionInFlatTree& visiblePos =
183 visibleHitPos.isNull() 173 visibleHitPos.isNull()
184 ? createVisiblePosition( 174 ? createVisiblePosition(
185 PositionInFlatTree::firstPositionInOrBeforeNode(innerNode)) 175 PositionInFlatTree::firstPositionInOrBeforeNode(innerNode))
186 : visibleHitPos; 176 : visibleHitPos;
187 const VisibleSelectionInFlatTree& selection = 177 const VisibleSelectionInFlatTree& selection =
188 this->selection().visibleSelection<EditingInFlatTreeStrategy>(); 178 this->selection().visibleSelection<EditingInFlatTreeStrategy>();
189 179
180 // Don't restart the selection when the mouse is pressed on an
181 // existing selection so we can allow for text dragging.
182 if (FrameView* view = m_frame->view()) {
183 const LayoutPoint vPoint =
184 view->rootFrameToContents(event.event().position());
185 if (!extendSelection && this->selection().contains(vPoint)) {
186 m_mouseDownWasSingleClickInSelection = true;
187 if (!event.event().fromTouch())
188 return false;
189
190 if (!this->selection().isHandleVisible()) {
191 updateSelectionForMouseDownDispatchingSelectStart(
192 innerNode, selection, CharacterGranularity,
193 HandleVisibility::Visible);
194 return false;
195 }
196 }
197 }
198
190 if (extendSelection && !selection.isNone()) { 199 if (extendSelection && !selection.isNone()) {
191 // Note: "fast/events/shift-click-user-select-none.html" makes 200 // Note: "fast/events/shift-click-user-select-none.html" makes
192 // |pos.isNull()| true. 201 // |pos.isNull()| true.
193 const PositionInFlatTree& pos = adjustPositionRespectUserSelectAll( 202 const PositionInFlatTree& pos = adjustPositionRespectUserSelectAll(
194 innerNode, selection.start(), selection.end(), 203 innerNode, selection.start(), selection.end(),
195 visiblePos.deepEquivalent()); 204 visiblePos.deepEquivalent());
196 SelectionInFlatTree::Builder builder; 205 SelectionInFlatTree::Builder builder;
197 builder.setGranularity(this->selection().granularity()); 206 builder.setGranularity(this->selection().granularity());
198 if (m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()) { 207 if (m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()) {
199 builder.setBaseAndExtent(selection.base(), pos); 208 builder.setBaseAndExtent(selection.base(), pos);
200 } else if (pos.isNull()) { 209 } else if (pos.isNull()) {
201 builder.setBaseAndExtent(selection.base(), selection.extent()); 210 builder.setBaseAndExtent(selection.base(), selection.extent());
202 } else { 211 } else {
203 // Shift+Click deselects when selection was created right-to-left 212 // Shift+Click deselects when selection was created right-to-left
204 const PositionInFlatTree& start = selection.start(); 213 const PositionInFlatTree& start = selection.start();
205 const PositionInFlatTree& end = selection.end(); 214 const PositionInFlatTree& end = selection.end();
206 const int distanceToStart = textDistance(start, pos); 215 const int distanceToStart = textDistance(start, pos);
207 const int distanceToEnd = textDistance(pos, end); 216 const int distanceToEnd = textDistance(pos, end);
208 builder.setBaseAndExtent(distanceToStart <= distanceToEnd ? end : start, 217 builder.setBaseAndExtent(distanceToStart <= distanceToEnd ? end : start,
209 pos); 218 pos);
210 } 219 }
211 220
212 updateSelectionForMouseDownDispatchingSelectStart( 221 updateSelectionForMouseDownDispatchingSelectStart(
213 innerNode, createVisibleSelection(builder.build()), 222 innerNode, createVisibleSelection(builder.build()),
214 this->selection().granularity()); 223 this->selection().granularity(), HandleVisibility::NotVisible);
215 return false; 224 return false;
216 } 225 }
217 226
218 if (m_selectionState == SelectionState::ExtendedSelection) { 227 if (m_selectionState == SelectionState::ExtendedSelection) {
219 updateSelectionForMouseDownDispatchingSelectStart(innerNode, selection, 228 updateSelectionForMouseDownDispatchingSelectStart(
220 CharacterGranularity); 229 innerNode, selection, CharacterGranularity,
230 HandleVisibility::NotVisible);
221 return false; 231 return false;
222 } 232 }
223 233
224 if (visiblePos.isNull()) { 234 if (visiblePos.isNull()) {
225 updateSelectionForMouseDownDispatchingSelectStart( 235 updateSelectionForMouseDownDispatchingSelectStart(
226 innerNode, VisibleSelectionInFlatTree(), CharacterGranularity); 236 innerNode, VisibleSelectionInFlatTree(), CharacterGranularity,
237 HandleVisibility::NotVisible);
227 return false; 238 return false;
228 } 239 }
229 240
241 bool isHandleVisible = false;
242 if (hasEditableStyle(*innerNode)) {
243 const bool isTextBoxEmpty =
244 createVisibleSelection(SelectionInFlatTree::Builder()
245 .selectAllChildren(*innerNode)
246 .build())
247 .isCaret();
248 const bool notLeftClick = event.event().pointerProperties().button !=
249 WebPointerProperties::Button::Left;
250 if (!isTextBoxEmpty || notLeftClick)
251 isHandleVisible = event.event().fromTouch();
252 }
253
230 updateSelectionForMouseDownDispatchingSelectStart( 254 updateSelectionForMouseDownDispatchingSelectStart(
231 innerNode, 255 innerNode,
232 expandSelectionToRespectUserSelectAll( 256 expandSelectionToRespectUserSelectAll(
233 innerNode, createVisibleSelection( 257 innerNode, createVisibleSelection(
234 SelectionInFlatTree::Builder() 258 SelectionInFlatTree::Builder()
235 .collapse(visiblePos.toPositionWithAffinity()) 259 .collapse(visiblePos.toPositionWithAffinity())
236 .build())), 260 .build())),
237 CharacterGranularity); 261 CharacterGranularity, isHandleVisible ? HandleVisibility::Visible
262 : HandleVisibility::NotVisible);
238 return false; 263 return false;
239 } 264 }
240 265
241 void SelectionController::updateSelectionForMouseDrag( 266 void SelectionController::updateSelectionForMouseDrag(
242 const HitTestResult& hitTestResult, 267 const HitTestResult& hitTestResult,
243 Node* mousePressNode, 268 Node* mousePressNode,
244 const LayoutPoint& dragStartPos, 269 const LayoutPoint& dragStartPos,
245 const IntPoint& lastKnownMousePosition) { 270 const IntPoint& lastKnownMousePosition) {
246 if (!m_mouseDownMayStartSelect) 271 if (!m_mouseDownMayStartSelect)
247 return; 272 return;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // |newSelection|. 382 // |newSelection|.
358 if (selection().granularity() != CharacterGranularity) { 383 if (selection().granularity() != CharacterGranularity) {
359 newSelection = createVisibleSelection( 384 newSelection = createVisibleSelection(
360 SelectionInFlatTree::Builder() 385 SelectionInFlatTree::Builder()
361 .setBaseAndExtent(newSelection.base(), newSelection.extent()) 386 .setBaseAndExtent(newSelection.base(), newSelection.extent())
362 .setGranularity(selection().granularity()) 387 .setGranularity(selection().granularity())
363 .build()); 388 .build());
364 } 389 }
365 390
366 setNonDirectionalSelectionIfNeeded(newSelection, selection().granularity(), 391 setNonDirectionalSelectionIfNeeded(newSelection, selection().granularity(),
367 AdjustEndpointsAtBidiBoundary); 392 AdjustEndpointsAtBidiBoundary,
393 HandleVisibility::NotVisible);
368 } 394 }
369 395
370 bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart( 396 bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart(
371 Node* targetNode, 397 Node* targetNode,
372 const VisibleSelectionInFlatTree& selection, 398 const VisibleSelectionInFlatTree& selection,
373 TextGranularity granularity) { 399 TextGranularity granularity,
400 HandleVisibility handleVisibility) {
374 if (targetNode && targetNode->layoutObject() && 401 if (targetNode && targetNode->layoutObject() &&
375 !targetNode->layoutObject()->isSelectable()) 402 !targetNode->layoutObject()->isSelectable())
376 return false; 403 return false;
377 404
378 if (dispatchSelectStart(targetNode) != DispatchEventResult::NotCanceled) 405 if (dispatchSelectStart(targetNode) != DispatchEventResult::NotCanceled)
379 return false; 406 return false;
380 407
381 // |dispatchSelectStart()| can change document hosted by |m_frame|. 408 // |dispatchSelectStart()| can change document hosted by |m_frame|.
382 if (!this->selection().isAvailable()) 409 if (!this->selection().isAvailable())
383 return false; 410 return false;
384 411
385 if (!selection.isValidFor(this->selection().document())) 412 if (!selection.isValidFor(this->selection().document()))
386 return false; 413 return false;
387 414
388 if (selection.isRange()) { 415 if (selection.isRange()) {
389 m_selectionState = SelectionState::ExtendedSelection; 416 m_selectionState = SelectionState::ExtendedSelection;
390 } else { 417 } else {
391 granularity = CharacterGranularity; 418 granularity = CharacterGranularity;
392 m_selectionState = SelectionState::PlacedCaret; 419 m_selectionState = SelectionState::PlacedCaret;
393 } 420 }
394 421
395 setNonDirectionalSelectionIfNeeded(selection, granularity, 422 setNonDirectionalSelectionIfNeeded(selection, granularity,
396 DoNotAdjustEndpoints); 423 DoNotAdjustEndpoints, handleVisibility);
397 424
398 return true; 425 return true;
399 } 426 }
400 427
401 bool SelectionController::selectClosestWordFromHitTestResult( 428 bool SelectionController::selectClosestWordFromHitTestResult(
402 const HitTestResult& result, 429 const HitTestResult& result,
403 AppendTrailingWhitespace appendTrailingWhitespace, 430 AppendTrailingWhitespace appendTrailingWhitespace,
404 SelectInputEventType selectInputEventType) { 431 SelectInputEventType selectInputEventType) {
405 Node* innerNode = result.innerNode(); 432 Node* innerNode = result.innerNode();
406 VisibleSelectionInFlatTree newSelection; 433 VisibleSelectionInFlatTree newSelection;
(...skipping 13 matching lines...) Expand all
420 const VisiblePositionInFlatTree& pos = 447 const VisiblePositionInFlatTree& pos =
421 visiblePositionOfHitTestResult(adjustedHitTestResult); 448 visiblePositionOfHitTestResult(adjustedHitTestResult);
422 if (pos.isNotNull()) { 449 if (pos.isNotNull()) {
423 newSelection = 450 newSelection =
424 createVisibleSelection(SelectionInFlatTree::Builder() 451 createVisibleSelection(SelectionInFlatTree::Builder()
425 .collapse(pos.toPositionWithAffinity()) 452 .collapse(pos.toPositionWithAffinity())
426 .setGranularity(WordGranularity) 453 .setGranularity(WordGranularity)
427 .build()); 454 .build());
428 } 455 }
429 456
457 HandleVisibility visibility = HandleVisibility::NotVisible;
430 if (selectInputEventType == SelectInputEventType::Touch) { 458 if (selectInputEventType == SelectInputEventType::Touch) {
431 // If node doesn't have text except space, tab or line break, do not 459 // If node doesn't have text except space, tab or line break, do not
432 // select that 'empty' area. 460 // select that 'empty' area.
433 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end()); 461 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end());
434 const String& str = 462 const String& str =
435 plainText(range, hasEditableStyle(*innerNode) 463 plainText(range, hasEditableStyle(*innerNode)
436 ? TextIteratorEmitsObjectReplacementCharacter 464 ? TextIteratorEmitsObjectReplacementCharacter
437 : TextIteratorDefaultBehavior); 465 : TextIteratorDefaultBehavior);
438 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) 466 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace())
439 return false; 467 return false;
440 468
441 if (newSelection.rootEditableElement() && 469 if (newSelection.rootEditableElement() &&
442 pos.deepEquivalent() == 470 pos.deepEquivalent() ==
443 VisiblePositionInFlatTree::lastPositionInNode( 471 VisiblePositionInFlatTree::lastPositionInNode(
444 newSelection.rootEditableElement()) 472 newSelection.rootEditableElement())
445 .deepEquivalent()) 473 .deepEquivalent())
446 return false; 474 return false;
475
476 visibility = HandleVisibility::Visible;
447 } 477 }
448 478
449 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend) 479 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend)
450 newSelection.appendTrailingWhitespace(); 480 newSelection.appendTrailingWhitespace();
451 481
452 return updateSelectionForMouseDownDispatchingSelectStart( 482 return updateSelectionForMouseDownDispatchingSelectStart(
453 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 483 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
454 WordGranularity); 484 WordGranularity, visibility);
455 } 485 }
456 486
457 void SelectionController::selectClosestMisspellingFromHitTestResult( 487 void SelectionController::selectClosestMisspellingFromHitTestResult(
458 const HitTestResult& result, 488 const HitTestResult& result,
459 AppendTrailingWhitespace appendTrailingWhitespace) { 489 AppendTrailingWhitespace appendTrailingWhitespace) {
460 Node* innerNode = result.innerNode(); 490 Node* innerNode = result.innerNode();
461 VisibleSelectionInFlatTree newSelection; 491 VisibleSelectionInFlatTree newSelection;
462 492
463 if (!innerNode || !innerNode->layoutObject()) 493 if (!innerNode || !innerNode->layoutObject())
464 return; 494 return;
(...skipping 13 matching lines...) Expand all
478 newSelection = createVisibleSelection( 508 newSelection = createVisibleSelection(
479 SelectionInFlatTree::Builder().collapse(start).extend(end).build()); 509 SelectionInFlatTree::Builder().collapse(start).extend(end).build());
480 } 510 }
481 } 511 }
482 512
483 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend) 513 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend)
484 newSelection.appendTrailingWhitespace(); 514 newSelection.appendTrailingWhitespace();
485 515
486 updateSelectionForMouseDownDispatchingSelectStart( 516 updateSelectionForMouseDownDispatchingSelectStart(
487 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 517 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
488 WordGranularity); 518 WordGranularity, HandleVisibility::NotVisible);
489 } 519 }
490 520
491 void SelectionController::selectClosestWordFromMouseEvent( 521 void SelectionController::selectClosestWordFromMouseEvent(
492 const MouseEventWithHitTestResults& result) { 522 const MouseEventWithHitTestResults& result) {
493 if (!m_mouseDownMayStartSelect) 523 if (!m_mouseDownMayStartSelect)
494 return; 524 return;
495 525
496 AppendTrailingWhitespace appendTrailingWhitespace = 526 AppendTrailingWhitespace appendTrailingWhitespace =
497 (result.event().clickCount() == 2 && 527 (result.event().clickCount() == 2 &&
498 m_frame->editor().isSelectTrailingWhitespaceEnabled()) 528 m_frame->editor().isSelectTrailingWhitespaceEnabled())
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 const VisiblePositionInFlatTree pos = 565 const VisiblePositionInFlatTree pos =
536 visiblePositionOfHitTestResult(result.hitTestResult()); 566 visiblePositionOfHitTestResult(result.hitTestResult());
537 if (pos.isNotNull() && 567 if (pos.isNotNull() &&
538 pos.deepEquivalent().anchorNode()->isDescendantOf(URLElement)) { 568 pos.deepEquivalent().anchorNode()->isDescendantOf(URLElement)) {
539 newSelection = createVisibleSelection( 569 newSelection = createVisibleSelection(
540 SelectionInFlatTree::Builder().selectAllChildren(*URLElement).build()); 570 SelectionInFlatTree::Builder().selectAllChildren(*URLElement).build());
541 } 571 }
542 572
543 updateSelectionForMouseDownDispatchingSelectStart( 573 updateSelectionForMouseDownDispatchingSelectStart(
544 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 574 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
545 WordGranularity); 575 WordGranularity, HandleVisibility::NotVisible);
546 } 576 }
547 577
548 // TODO(xiaochengh): We should not use reference to return value. 578 // TODO(xiaochengh): We should not use reference to return value.
549 static void adjustEndpointsAtBidiBoundary( 579 static void adjustEndpointsAtBidiBoundary(
550 VisiblePositionInFlatTree& visibleBase, 580 VisiblePositionInFlatTree& visibleBase,
551 VisiblePositionInFlatTree& visibleExtent) { 581 VisiblePositionInFlatTree& visibleExtent) {
552 DCHECK(visibleBase.isValid()); 582 DCHECK(visibleBase.isValid());
553 DCHECK(visibleExtent.isValid()); 583 DCHECK(visibleExtent.isValid());
554 584
555 RenderedPosition base(visibleBase); 585 RenderedPosition base(visibleBase);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) { 623 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) {
594 visibleExtent = createVisiblePosition( 624 visibleExtent = createVisiblePosition(
595 toPositionInFlatTree(extent.positionAtRightBoundaryOfBiDiRun())); 625 toPositionInFlatTree(extent.positionAtRightBoundaryOfBiDiRun()));
596 return; 626 return;
597 } 627 }
598 } 628 }
599 629
600 void SelectionController::setNonDirectionalSelectionIfNeeded( 630 void SelectionController::setNonDirectionalSelectionIfNeeded(
601 const VisibleSelectionInFlatTree& passedNewSelection, 631 const VisibleSelectionInFlatTree& passedNewSelection,
602 TextGranularity granularity, 632 TextGranularity granularity,
603 EndPointsAdjustmentMode endpointsAdjustmentMode) { 633 EndPointsAdjustmentMode endpointsAdjustmentMode,
634 HandleVisibility handleVisibility) {
604 VisibleSelectionInFlatTree newSelection = passedNewSelection; 635 VisibleSelectionInFlatTree newSelection = passedNewSelection;
605 bool isDirectional = 636 bool isDirectional =
606 m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() || 637 m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() ||
607 newSelection.isDirectional(); 638 newSelection.isDirectional();
608 639
609 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 640 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
610 // needs to be audited. See http://crbug.com/590369 for more details. 641 // needs to be audited. See http://crbug.com/590369 for more details.
611 document().updateStyleAndLayoutIgnorePendingStylesheets(); 642 document().updateStyleAndLayoutIgnorePendingStylesheets();
612 643
613 const PositionInFlatTree& basePosition = 644 const PositionInFlatTree& basePosition =
(...skipping 19 matching lines...) Expand all
633 newSelection.setExtent(newExtent); 664 newSelection.setExtent(newExtent);
634 } else if (originalBase.isNotNull()) { 665 } else if (originalBase.isNotNull()) {
635 if (selection().visibleSelection<EditingInFlatTreeStrategy>().base() == 666 if (selection().visibleSelection<EditingInFlatTreeStrategy>().base() ==
636 newSelection.base()) 667 newSelection.base())
637 newSelection.setBase(originalBase); 668 newSelection.setBase(originalBase);
638 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); 669 m_originalBaseInFlatTree = VisiblePositionInFlatTree();
639 } 670 }
640 671
641 // Adjusting base and extent will make newSelection always directional 672 // Adjusting base and extent will make newSelection always directional
642 newSelection.setIsDirectional(isDirectional); 673 newSelection.setIsDirectional(isDirectional);
643 if (selection().visibleSelection<EditingInFlatTreeStrategy>() == newSelection) 674 const bool isHandleVisible = handleVisibility == HandleVisibility::Visible;
675 if (selection().visibleSelection<EditingInFlatTreeStrategy>() ==
676 newSelection &&
677 selection().isHandleVisible() == isHandleVisible)
644 return; 678 return;
645 679
646 const FrameSelection::SetSelectionOptions options = 680 const FrameSelection::SetSelectionOptions options =
647 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle; 681 isHandleVisible
682 ? FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle |
683 FrameSelection::HandleVisible
684 : FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle;
685
648 selection().setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded, 686 selection().setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
649 granularity); 687 granularity);
650 } 688 }
651 689
652 void SelectionController::setCaretAtHitTestResult( 690 void SelectionController::setCaretAtHitTestResult(
653 const HitTestResult& hitTestResult) { 691 const HitTestResult& hitTestResult) {
654 Node* innerNode = hitTestResult.innerNode(); 692 Node* innerNode = hitTestResult.innerNode();
655 const VisiblePositionInFlatTree& visibleHitPos = 693 const VisiblePositionInFlatTree& visibleHitPos =
656 visiblePositionOfHitTestResult(hitTestResult); 694 visiblePositionOfHitTestResult(hitTestResult);
657 const VisiblePositionInFlatTree& visiblePos = 695 const VisiblePositionInFlatTree& visiblePos =
658 visibleHitPos.isNull() 696 visibleHitPos.isNull()
659 ? createVisiblePosition( 697 ? createVisiblePosition(
660 PositionInFlatTree::firstPositionInOrBeforeNode(innerNode)) 698 PositionInFlatTree::firstPositionInOrBeforeNode(innerNode))
661 : visibleHitPos; 699 : visibleHitPos;
662 700
663 updateSelectionForMouseDownDispatchingSelectStart( 701 updateSelectionForMouseDownDispatchingSelectStart(
664 innerNode, 702 innerNode,
665 expandSelectionToRespectUserSelectAll( 703 expandSelectionToRespectUserSelectAll(
666 innerNode, createVisibleSelection( 704 innerNode, createVisibleSelection(
667 SelectionInFlatTree::Builder() 705 SelectionInFlatTree::Builder()
668 .collapse(visiblePos.toPositionWithAffinity()) 706 .collapse(visiblePos.toPositionWithAffinity())
669 .build())), 707 .build())),
670 CharacterGranularity); 708 CharacterGranularity, HandleVisibility::Visible);
671 } 709 }
672 710
673 bool SelectionController::handleMousePressEventDoubleClick( 711 bool SelectionController::handleMousePressEventDoubleClick(
674 const MouseEventWithHitTestResults& event) { 712 const MouseEventWithHitTestResults& event) {
675 TRACE_EVENT0("blink", 713 TRACE_EVENT0("blink",
676 "SelectionController::handleMousePressEventDoubleClick"); 714 "SelectionController::handleMousePressEventDoubleClick");
677 715
678 if (!selection().isAvailable()) 716 if (!selection().isAvailable())
679 return false; 717 return false;
680 718
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 const VisiblePositionInFlatTree& pos = 761 const VisiblePositionInFlatTree& pos =
724 visiblePositionOfHitTestResult(event.hitTestResult()); 762 visiblePositionOfHitTestResult(event.hitTestResult());
725 if (pos.isNotNull()) { 763 if (pos.isNotNull()) {
726 newSelection = 764 newSelection =
727 createVisibleSelection(SelectionInFlatTree::Builder() 765 createVisibleSelection(SelectionInFlatTree::Builder()
728 .collapse(pos.toPositionWithAffinity()) 766 .collapse(pos.toPositionWithAffinity())
729 .setGranularity(ParagraphGranularity) 767 .setGranularity(ParagraphGranularity)
730 .build()); 768 .build());
731 } 769 }
732 770
771 const bool isHandleVisible =
772 event.event().fromTouch() && newSelection.isRange();
773
733 return updateSelectionForMouseDownDispatchingSelectStart( 774 return updateSelectionForMouseDownDispatchingSelectStart(
734 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 775 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
735 ParagraphGranularity); 776 ParagraphGranularity, isHandleVisible ? HandleVisibility::Visible
777 : HandleVisibility::NotVisible);
736 } 778 }
737 779
738 void SelectionController::handleMousePressEvent( 780 void SelectionController::handleMousePressEvent(
739 const MouseEventWithHitTestResults& event) { 781 const MouseEventWithHitTestResults& event) {
740 // If we got the event back, that must mean it wasn't prevented, 782 // If we got the event back, that must mean it wasn't prevented,
741 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. 783 // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
742 m_mouseDownMayStartSelect = 784 m_mouseDownMayStartSelect =
743 (canMouseDownStartSelect(event.innerNode()) || isLinkSelection(event)) && 785 (canMouseDownStartSelect(event.innerNode()) || isLinkSelection(event)) &&
744 !event.scrollbar(); 786 !event.scrollbar();
745 m_mouseDownWasSingleClickInSelection = false; 787 m_mouseDownWasSingleClickInSelection = false;
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 return event.event().altKey() && event.isOverLink(); 1060 return event.event().altKey() && event.isOverLink();
1019 } 1061 }
1020 1062
1021 bool isExtendingSelection(const MouseEventWithHitTestResults& event) { 1063 bool isExtendingSelection(const MouseEventWithHitTestResults& event) {
1022 bool isMouseDownOnLinkOrImage = 1064 bool isMouseDownOnLinkOrImage =
1023 event.isOverLink() || event.hitTestResult().image(); 1065 event.isOverLink() || event.hitTestResult().image();
1024 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; 1066 return event.event().shiftKey() && !isMouseDownOnLinkOrImage;
1025 } 1067 }
1026 1068
1027 } // namespace blink 1069 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698