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

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: removed ESTABLISHED/DISSOLVED Created 4 years, 1 month 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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 157
158 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); 158 DCHECK(!m_frame->document()->needsLayoutTreeUpdate());
159 Node* innerNode = event.innerNode(); 159 Node* innerNode = event.innerNode();
160 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect)) 160 if (!(innerNode && innerNode->layoutObject() && m_mouseDownMayStartSelect))
161 return false; 161 return false;
162 162
163 // Extend the selection if the Shift key is down, unless the click is in a 163 // Extend the selection if the Shift key is down, unless the click is in a
164 // link or image. 164 // link or image.
165 bool extendSelection = isExtendingSelection(event); 165 bool extendSelection = isExtendingSelection(event);
166 166
167 // Don't restart the selection when the mouse is pressed on an
168 // existing selection so we can allow for text dragging.
169 if (FrameView* view = m_frame->view()) {
170 LayoutPoint vPoint = view->rootFrameToContents(event.event().position());
171 if (!extendSelection && selection().contains(vPoint)) {
172 m_mouseDownWasSingleClickInSelection = true;
173 return false;
174 }
175 }
176
177 const VisiblePositionInFlatTree& visibleHitPos = 167 const VisiblePositionInFlatTree& visibleHitPos =
178 visiblePositionOfHitTestResult(event.hitTestResult()); 168 visiblePositionOfHitTestResult(event.hitTestResult());
179 const VisiblePositionInFlatTree& visiblePos = 169 const VisiblePositionInFlatTree& visiblePos =
180 visibleHitPos.isNull() 170 visibleHitPos.isNull()
181 ? createVisiblePosition( 171 ? createVisiblePosition(
182 PositionInFlatTree::firstPositionInOrBeforeNode(innerNode)) 172 PositionInFlatTree::firstPositionInOrBeforeNode(innerNode))
183 : visibleHitPos; 173 : visibleHitPos;
184 const VisibleSelectionInFlatTree& selection = 174 const VisibleSelectionInFlatTree& selection =
185 this->selection().visibleSelection<EditingInFlatTreeStrategy>(); 175 this->selection().visibleSelection<EditingInFlatTreeStrategy>();
186 176
177 // Don't restart the selection when the mouse is pressed on an
178 // existing selection so we can allow for text dragging.
179 if (!extendSelection && this->selection().contains(event.hitTestResult())) {
180 m_mouseDownWasSingleClickInSelection = true;
181 if (!event.event().fromTouch())
182 return false;
183
184 if (!this->selection().isHandleVisible()) {
185 updateSelectionForMouseDownDispatchingSelectStart(
186 innerNode, selection, CharacterGranularity,
187 HandleVisibility::Visible);
188 return false;
189 }
190 }
191
187 if (extendSelection && !selection.isNone()) { 192 if (extendSelection && !selection.isNone()) {
188 // Note: "fast/events/shift-click-user-select-none.html" makes 193 // Note: "fast/events/shift-click-user-select-none.html" makes
189 // |pos.isNull()| true. 194 // |pos.isNull()| true.
190 const PositionInFlatTree& pos = adjustPositionRespectUserSelectAll( 195 const PositionInFlatTree& pos = adjustPositionRespectUserSelectAll(
191 innerNode, selection.start(), selection.end(), 196 innerNode, selection.start(), selection.end(),
192 visiblePos.deepEquivalent()); 197 visiblePos.deepEquivalent());
193 SelectionInFlatTree::Builder builder; 198 SelectionInFlatTree::Builder builder;
194 builder.setGranularity(this->selection().granularity()); 199 builder.setGranularity(this->selection().granularity());
195 if (m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()) { 200 if (m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()) {
196 builder.setBaseAndExtent(selection.base(), pos); 201 builder.setBaseAndExtent(selection.base(), pos);
197 } else if (pos.isNull()) { 202 } else if (pos.isNull()) {
198 builder.setBaseAndExtent(selection.base(), selection.extent()); 203 builder.setBaseAndExtent(selection.base(), selection.extent());
199 } else { 204 } else {
200 // Shift+Click deselects when selection was created right-to-left 205 // Shift+Click deselects when selection was created right-to-left
201 const PositionInFlatTree& start = selection.start(); 206 const PositionInFlatTree& start = selection.start();
202 const PositionInFlatTree& end = selection.end(); 207 const PositionInFlatTree& end = selection.end();
203 const int distanceToStart = textDistance(start, pos); 208 const int distanceToStart = textDistance(start, pos);
204 const int distanceToEnd = textDistance(pos, end); 209 const int distanceToEnd = textDistance(pos, end);
205 builder.setBaseAndExtent(distanceToStart <= distanceToEnd ? end : start, 210 builder.setBaseAndExtent(distanceToStart <= distanceToEnd ? end : start,
206 pos); 211 pos);
207 } 212 }
208 213
209 updateSelectionForMouseDownDispatchingSelectStart( 214 updateSelectionForMouseDownDispatchingSelectStart(
210 innerNode, createVisibleSelection(builder.build()), 215 innerNode, createVisibleSelection(builder.build()),
211 this->selection().granularity()); 216 this->selection().granularity(), HandleVisibility::NotVisible);
212 return false; 217 return false;
213 } 218 }
214 219
215 if (m_selectionState == SelectionState::ExtendedSelection) { 220 if (m_selectionState == SelectionState::ExtendedSelection) {
216 updateSelectionForMouseDownDispatchingSelectStart(innerNode, selection, 221 updateSelectionForMouseDownDispatchingSelectStart(
217 CharacterGranularity); 222 innerNode, selection, CharacterGranularity,
223 HandleVisibility::NotVisible);
218 return false; 224 return false;
219 } 225 }
220 226
221 if (visiblePos.isNull()) { 227 if (visiblePos.isNull()) {
222 updateSelectionForMouseDownDispatchingSelectStart( 228 updateSelectionForMouseDownDispatchingSelectStart(
223 innerNode, VisibleSelectionInFlatTree(), CharacterGranularity); 229 innerNode, VisibleSelectionInFlatTree(), CharacterGranularity,
230 HandleVisibility::NotVisible);
224 return false; 231 return false;
225 } 232 }
226 233
234 bool isHandleVisible = false;
235 if (hasEditableStyle(*innerNode)) {
236 const bool isTextBoxEmpty =
237 createVisibleSelection(SelectionInFlatTree::Builder()
238 .selectAllChildren(*innerNode)
239 .build())
240 .isCaret();
241 const bool notLeftClick = event.event().pointerProperties().button !=
242 WebPointerProperties::Button::Left;
243 if (!isTextBoxEmpty || notLeftClick)
244 isHandleVisible = event.event().fromTouch();
245 }
246
227 updateSelectionForMouseDownDispatchingSelectStart( 247 updateSelectionForMouseDownDispatchingSelectStart(
228 innerNode, 248 innerNode,
229 expandSelectionToRespectUserSelectAll( 249 expandSelectionToRespectUserSelectAll(
230 innerNode, createVisibleSelection( 250 innerNode, createVisibleSelection(
231 SelectionInFlatTree::Builder() 251 SelectionInFlatTree::Builder()
232 .collapse(visiblePos.toPositionWithAffinity()) 252 .collapse(visiblePos.toPositionWithAffinity())
233 .build())), 253 .build())),
234 CharacterGranularity); 254 CharacterGranularity, isHandleVisible ? HandleVisibility::Visible
255 : HandleVisibility::NotVisible);
235 return false; 256 return false;
236 } 257 }
237 258
238 void SelectionController::updateSelectionForMouseDrag( 259 void SelectionController::updateSelectionForMouseDrag(
239 const HitTestResult& hitTestResult, 260 const HitTestResult& hitTestResult,
240 Node* mousePressNode, 261 Node* mousePressNode,
241 const LayoutPoint& dragStartPos, 262 const LayoutPoint& dragStartPos,
242 const IntPoint& lastKnownMousePosition) { 263 const IntPoint& lastKnownMousePosition) {
243 if (!m_mouseDownMayStartSelect) 264 if (!m_mouseDownMayStartSelect)
244 return; 265 return;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 // |newSelection|. 375 // |newSelection|.
355 if (selection().granularity() != CharacterGranularity) { 376 if (selection().granularity() != CharacterGranularity) {
356 newSelection = createVisibleSelection( 377 newSelection = createVisibleSelection(
357 SelectionInFlatTree::Builder() 378 SelectionInFlatTree::Builder()
358 .setBaseAndExtent(newSelection.base(), newSelection.extent()) 379 .setBaseAndExtent(newSelection.base(), newSelection.extent())
359 .setGranularity(selection().granularity()) 380 .setGranularity(selection().granularity())
360 .build()); 381 .build());
361 } 382 }
362 383
363 setNonDirectionalSelectionIfNeeded(newSelection, selection().granularity(), 384 setNonDirectionalSelectionIfNeeded(newSelection, selection().granularity(),
364 AdjustEndpointsAtBidiBoundary); 385 AdjustEndpointsAtBidiBoundary,
386 HandleVisibility::NotVisible);
365 } 387 }
366 388
367 bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart( 389 bool SelectionController::updateSelectionForMouseDownDispatchingSelectStart(
368 Node* targetNode, 390 Node* targetNode,
369 const VisibleSelectionInFlatTree& selection, 391 const VisibleSelectionInFlatTree& selection,
370 TextGranularity granularity) { 392 TextGranularity granularity,
393 HandleVisibility handleVisibility) {
371 if (targetNode && targetNode->layoutObject() && 394 if (targetNode && targetNode->layoutObject() &&
372 !targetNode->layoutObject()->isSelectable()) 395 !targetNode->layoutObject()->isSelectable())
373 return false; 396 return false;
374 397
375 if (dispatchSelectStart(targetNode) != DispatchEventResult::NotCanceled) 398 if (dispatchSelectStart(targetNode) != DispatchEventResult::NotCanceled)
376 return false; 399 return false;
377 400
378 // |dispatchSelectStart()| can change document hosted by |m_frame|. 401 // |dispatchSelectStart()| can change document hosted by |m_frame|.
379 if (!this->selection().isAvailable()) 402 if (!this->selection().isAvailable())
380 return false; 403 return false;
381 404
382 if (!selection.isValidFor(this->selection().document())) 405 if (!selection.isValidFor(this->selection().document()))
383 return false; 406 return false;
384 407
385 if (selection.isRange()) { 408 if (selection.isRange()) {
386 m_selectionState = SelectionState::ExtendedSelection; 409 m_selectionState = SelectionState::ExtendedSelection;
387 } else { 410 } else {
388 granularity = CharacterGranularity; 411 granularity = CharacterGranularity;
389 m_selectionState = SelectionState::PlacedCaret; 412 m_selectionState = SelectionState::PlacedCaret;
390 } 413 }
391 414
392 setNonDirectionalSelectionIfNeeded(selection, granularity, 415 setNonDirectionalSelectionIfNeeded(selection, granularity,
393 DoNotAdjustEndpoints); 416 DoNotAdjustEndpoints, handleVisibility);
394 417
395 return true; 418 return true;
396 } 419 }
397 420
398 void SelectionController::selectClosestWordFromHitTestResult( 421 void SelectionController::selectClosestWordFromHitTestResult(
399 const HitTestResult& result, 422 const HitTestResult& result,
400 AppendTrailingWhitespace appendTrailingWhitespace, 423 AppendTrailingWhitespace appendTrailingWhitespace,
401 SelectInputEventType selectInputEventType) { 424 SelectInputEventType selectInputEventType) {
402 Node* innerNode = result.innerNode(); 425 Node* innerNode = result.innerNode();
403 VisibleSelectionInFlatTree newSelection; 426 VisibleSelectionInFlatTree newSelection;
(...skipping 13 matching lines...) Expand all
417 const VisiblePositionInFlatTree& pos = 440 const VisiblePositionInFlatTree& pos =
418 visiblePositionOfHitTestResult(adjustedHitTestResult); 441 visiblePositionOfHitTestResult(adjustedHitTestResult);
419 if (pos.isNotNull()) { 442 if (pos.isNotNull()) {
420 newSelection = 443 newSelection =
421 createVisibleSelection(SelectionInFlatTree::Builder() 444 createVisibleSelection(SelectionInFlatTree::Builder()
422 .collapse(pos.toPositionWithAffinity()) 445 .collapse(pos.toPositionWithAffinity())
423 .setGranularity(WordGranularity) 446 .setGranularity(WordGranularity)
424 .build()); 447 .build());
425 } 448 }
426 449
450 HandleVisibility visibility = HandleVisibility::NotVisible;
427 if (selectInputEventType == SelectInputEventType::Touch) { 451 if (selectInputEventType == SelectInputEventType::Touch) {
428 // If node doesn't have text except space, tab or line break, do not 452 // If node doesn't have text except space, tab or line break, do not
429 // select that 'empty' area. 453 // select that 'empty' area.
430 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end()); 454 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end());
431 const String& str = 455 const String& str =
432 plainText(range, hasEditableStyle(*innerNode) 456 plainText(range, hasEditableStyle(*innerNode)
433 ? TextIteratorEmitsObjectReplacementCharacter 457 ? TextIteratorEmitsObjectReplacementCharacter
434 : TextIteratorDefaultBehavior); 458 : TextIteratorDefaultBehavior);
435 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) 459 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace())
436 return; 460 return;
437 461
438 if (newSelection.rootEditableElement() && 462 if (newSelection.rootEditableElement() &&
439 pos.deepEquivalent() == 463 pos.deepEquivalent() ==
440 VisiblePositionInFlatTree::lastPositionInNode( 464 VisiblePositionInFlatTree::lastPositionInNode(
441 newSelection.rootEditableElement()) 465 newSelection.rootEditableElement())
442 .deepEquivalent()) 466 .deepEquivalent())
443 return; 467 return;
468 visibility = HandleVisibility::Visible;
444 } 469 }
445 470
446 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend) 471 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend)
447 newSelection.appendTrailingWhitespace(); 472 newSelection.appendTrailingWhitespace();
448 473
449 updateSelectionForMouseDownDispatchingSelectStart( 474 updateSelectionForMouseDownDispatchingSelectStart(
450 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 475 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
451 WordGranularity); 476 WordGranularity, visibility);
452 } 477 }
453 478
454 void SelectionController::selectClosestMisspellingFromHitTestResult( 479 void SelectionController::selectClosestMisspellingFromHitTestResult(
455 const HitTestResult& result, 480 const HitTestResult& result,
456 AppendTrailingWhitespace appendTrailingWhitespace) { 481 AppendTrailingWhitespace appendTrailingWhitespace) {
457 Node* innerNode = result.innerNode(); 482 Node* innerNode = result.innerNode();
458 VisibleSelectionInFlatTree newSelection; 483 VisibleSelectionInFlatTree newSelection;
459 484
460 if (!innerNode || !innerNode->layoutObject()) 485 if (!innerNode || !innerNode->layoutObject())
461 return; 486 return;
(...skipping 13 matching lines...) Expand all
475 newSelection = createVisibleSelection( 500 newSelection = createVisibleSelection(
476 SelectionInFlatTree::Builder().collapse(start).extend(end).build()); 501 SelectionInFlatTree::Builder().collapse(start).extend(end).build());
477 } 502 }
478 } 503 }
479 504
480 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend) 505 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend)
481 newSelection.appendTrailingWhitespace(); 506 newSelection.appendTrailingWhitespace();
482 507
483 updateSelectionForMouseDownDispatchingSelectStart( 508 updateSelectionForMouseDownDispatchingSelectStart(
484 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 509 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
485 WordGranularity); 510 WordGranularity, HandleVisibility::NotVisible);
486 } 511 }
487 512
488 void SelectionController::selectClosestWordFromMouseEvent( 513 void SelectionController::selectClosestWordFromMouseEvent(
489 const MouseEventWithHitTestResults& result) { 514 const MouseEventWithHitTestResults& result) {
490 if (!m_mouseDownMayStartSelect) 515 if (!m_mouseDownMayStartSelect)
491 return; 516 return;
492 517
493 AppendTrailingWhitespace appendTrailingWhitespace = 518 AppendTrailingWhitespace appendTrailingWhitespace =
494 (result.event().clickCount() == 2 && 519 (result.event().clickCount() == 2 &&
495 m_frame->editor().isSelectTrailingWhitespaceEnabled()) 520 m_frame->editor().isSelectTrailingWhitespaceEnabled())
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 const VisiblePositionInFlatTree pos = 557 const VisiblePositionInFlatTree pos =
533 visiblePositionOfHitTestResult(result.hitTestResult()); 558 visiblePositionOfHitTestResult(result.hitTestResult());
534 if (pos.isNotNull() && 559 if (pos.isNotNull() &&
535 pos.deepEquivalent().anchorNode()->isDescendantOf(URLElement)) { 560 pos.deepEquivalent().anchorNode()->isDescendantOf(URLElement)) {
536 newSelection = createVisibleSelection( 561 newSelection = createVisibleSelection(
537 SelectionInFlatTree::Builder().selectAllChildren(*URLElement).build()); 562 SelectionInFlatTree::Builder().selectAllChildren(*URLElement).build());
538 } 563 }
539 564
540 updateSelectionForMouseDownDispatchingSelectStart( 565 updateSelectionForMouseDownDispatchingSelectStart(
541 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 566 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
542 WordGranularity); 567 WordGranularity, HandleVisibility::NotVisible);
543 } 568 }
544 569
545 // TODO(xiaochengh): We should not use reference to return value. 570 // TODO(xiaochengh): We should not use reference to return value.
546 static void adjustEndpointsAtBidiBoundary( 571 static void adjustEndpointsAtBidiBoundary(
547 VisiblePositionInFlatTree& visibleBase, 572 VisiblePositionInFlatTree& visibleBase,
548 VisiblePositionInFlatTree& visibleExtent) { 573 VisiblePositionInFlatTree& visibleExtent) {
549 DCHECK(visibleBase.isValid()); 574 DCHECK(visibleBase.isValid());
550 DCHECK(visibleExtent.isValid()); 575 DCHECK(visibleExtent.isValid());
551 576
552 RenderedPosition base(visibleBase); 577 RenderedPosition base(visibleBase);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) { 615 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) {
591 visibleExtent = createVisiblePosition( 616 visibleExtent = createVisiblePosition(
592 toPositionInFlatTree(extent.positionAtRightBoundaryOfBiDiRun())); 617 toPositionInFlatTree(extent.positionAtRightBoundaryOfBiDiRun()));
593 return; 618 return;
594 } 619 }
595 } 620 }
596 621
597 void SelectionController::setNonDirectionalSelectionIfNeeded( 622 void SelectionController::setNonDirectionalSelectionIfNeeded(
598 const VisibleSelectionInFlatTree& passedNewSelection, 623 const VisibleSelectionInFlatTree& passedNewSelection,
599 TextGranularity granularity, 624 TextGranularity granularity,
600 EndPointsAdjustmentMode endpointsAdjustmentMode) { 625 EndPointsAdjustmentMode endpointsAdjustmentMode,
626 HandleVisibility handleVisibility) {
601 VisibleSelectionInFlatTree newSelection = passedNewSelection; 627 VisibleSelectionInFlatTree newSelection = passedNewSelection;
602 bool isDirectional = 628 bool isDirectional =
603 m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() || 629 m_frame->editor().behavior().shouldConsiderSelectionAsDirectional() ||
604 newSelection.isDirectional(); 630 newSelection.isDirectional();
605 631
606 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 632 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
607 // needs to be audited. See http://crbug.com/590369 for more details. 633 // needs to be audited. See http://crbug.com/590369 for more details.
608 document().updateStyleAndLayoutIgnorePendingStylesheets(); 634 document().updateStyleAndLayoutIgnorePendingStylesheets();
609 635
610 const PositionInFlatTree& basePosition = 636 const PositionInFlatTree& basePosition =
(...skipping 18 matching lines...) Expand all
629 newSelection.setExtent(newExtent); 655 newSelection.setExtent(newExtent);
630 } else if (originalBase.isNotNull()) { 656 } else if (originalBase.isNotNull()) {
631 if (selection().visibleSelection<EditingInFlatTreeStrategy>().base() == 657 if (selection().visibleSelection<EditingInFlatTreeStrategy>().base() ==
632 newSelection.base()) 658 newSelection.base())
633 newSelection.setBase(originalBase); 659 newSelection.setBase(originalBase);
634 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); 660 m_originalBaseInFlatTree = VisiblePositionInFlatTree();
635 } 661 }
636 662
637 // Adjusting base and extent will make newSelection always directional 663 // Adjusting base and extent will make newSelection always directional
638 newSelection.setIsDirectional(isDirectional); 664 newSelection.setIsDirectional(isDirectional);
639 if (selection().visibleSelection<EditingInFlatTreeStrategy>() == newSelection) 665 const bool isHandleVisible = handleVisibility == HandleVisibility::Visible;
666 if (selection().visibleSelection<EditingInFlatTreeStrategy>() ==
667 newSelection &&
668 selection().isHandleVisible() == isHandleVisible)
640 return; 669 return;
641 670
642 const FrameSelection::SetSelectionOptions options = 671 FrameSelection::SetSelectionOptions options =
643 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle; 672 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle;
673 if (isHandleVisible)
674 options |= FrameSelection::HandleVisible;
644 selection().setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded, 675 selection().setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
645 granularity); 676 granularity);
646 } 677 }
647 678
648 bool SelectionController::handleMousePressEventDoubleClick( 679 bool SelectionController::handleMousePressEventDoubleClick(
649 const MouseEventWithHitTestResults& event) { 680 const MouseEventWithHitTestResults& event) {
650 TRACE_EVENT0("blink", 681 TRACE_EVENT0("blink",
651 "SelectionController::handleMousePressEventDoubleClick"); 682 "SelectionController::handleMousePressEventDoubleClick");
652 683
653 if (!selection().isAvailable()) 684 if (!selection().isAvailable())
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 const VisiblePositionInFlatTree& pos = 729 const VisiblePositionInFlatTree& pos =
699 visiblePositionOfHitTestResult(event.hitTestResult()); 730 visiblePositionOfHitTestResult(event.hitTestResult());
700 if (pos.isNotNull()) { 731 if (pos.isNotNull()) {
701 newSelection = 732 newSelection =
702 createVisibleSelection(SelectionInFlatTree::Builder() 733 createVisibleSelection(SelectionInFlatTree::Builder()
703 .collapse(pos.toPositionWithAffinity()) 734 .collapse(pos.toPositionWithAffinity())
704 .setGranularity(ParagraphGranularity) 735 .setGranularity(ParagraphGranularity)
705 .build()); 736 .build());
706 } 737 }
707 738
739 bool isHandleVisible = event.event().fromTouch() && newSelection.isRange();
740
708 return updateSelectionForMouseDownDispatchingSelectStart( 741 return updateSelectionForMouseDownDispatchingSelectStart(
709 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), 742 innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection),
710 ParagraphGranularity); 743 ParagraphGranularity, isHandleVisible ? HandleVisibility::Visible
744 : HandleVisibility::NotVisible);
711 } 745 }
712 746
713 void SelectionController::handleMousePressEvent( 747 void SelectionController::handleMousePressEvent(
714 const MouseEventWithHitTestResults& event) { 748 const MouseEventWithHitTestResults& event) {
715 // If we got the event back, that must mean it wasn't prevented, 749 // If we got the event back, that must mean it wasn't prevented,
716 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. 750 // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
717 m_mouseDownMayStartSelect = 751 m_mouseDownMayStartSelect =
718 (canMouseDownStartSelect(event.innerNode()) || isLinkSelection(event)) && 752 (canMouseDownStartSelect(event.innerNode()) || isLinkSelection(event)) &&
719 !event.scrollbar(); 753 !event.scrollbar();
720 m_mouseDownWasSingleClickInSelection = false; 754 m_mouseDownWasSingleClickInSelection = false;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 pos.deepEquivalent().parentAnchoredEquivalent()), 936 pos.deepEquivalent().parentAnchoredEquivalent()),
903 DocumentMarker::MisspellingMarkers()) 937 DocumentMarker::MisspellingMarkers())
904 .size() > 0; 938 .size() > 0;
905 } 939 }
906 940
907 void SelectionController::sendContextMenuEvent( 941 void SelectionController::sendContextMenuEvent(
908 const MouseEventWithHitTestResults& mev, 942 const MouseEventWithHitTestResults& mev,
909 const LayoutPoint& position) { 943 const LayoutPoint& position) {
910 if (!selection().isAvailable()) 944 if (!selection().isAvailable())
911 return; 945 return;
912 if (selection().contains(position) || mev.scrollbar() || 946 if (selection().contains(mev.hitTestResult()) || mev.scrollbar() ||
913 // FIXME: In the editable case, word selection sometimes selects content 947 // FIXME: In the editable case, word selection sometimes selects content
914 // that isn't underneath the mouse. 948 // that isn't underneath the mouse.
915 // If the selection is non-editable, we do word selection to make it 949 // If the selection is non-editable, we do word selection to make it
916 // easier to use the contextual menu items available for text selections. 950 // easier to use the contextual menu items available for text selections.
917 // But only if we're above text. 951 // But only if we're above text.
918 !(selection().isContentEditable() || 952 !(selection().isContentEditable() ||
919 (mev.innerNode() && mev.innerNode()->isTextNode()))) 953 (mev.innerNode() && mev.innerNode()->isTextNode())))
920 return; 954 return;
921 955
922 // Context menu events are always allowed to perform a selection. 956 // Context menu events are always allowed to perform a selection.
923 AutoReset<bool> mouseDownMayStartSelectChange(&m_mouseDownMayStartSelect, 957 AutoReset<bool> mouseDownMayStartSelectChange(&m_mouseDownMayStartSelect,
924 true); 958 true);
925 959
926 if (hitTestResultIsMisspelled(mev.hitTestResult())) 960 if (hitTestResultIsMisspelled(mev.hitTestResult()))
927 return selectClosestMisspellingFromMouseEvent(mev); 961 return selectClosestMisspellingFromMouseEvent(mev);
928 962
929 if (!m_frame->editor().behavior().shouldSelectOnContextualMenuClick()) 963 if (!m_frame->editor().behavior().shouldSelectOnContextualMenuClick())
930 return; 964 return;
931 965
932 selectClosestWordOrLinkFromMouseEvent(mev); 966 selectClosestWordOrLinkFromMouseEvent(mev);
933 } 967 }
934 968
935 void SelectionController::passMousePressEventToSubframe( 969 void SelectionController::passMousePressEventToSubframe(
936 const MouseEventWithHitTestResults& mev) { 970 const MouseEventWithHitTestResults& mev) {
937 // If we're clicking into a frame that is selected, the frame will appear 971 // If we're clicking into a frame that is selected, the frame will appear
938 // greyed out even though we're clicking on the selection. This looks 972 // greyed out even though we're clicking on the selection. This looks
939 // really strange (having the whole frame be greyed out), so we deselect the 973 // really strange (having the whole frame be greyed out), so we deselect the
940 // selection. 974 // selection.
941 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); 975 if (!selection().contains(mev.hitTestResult()))
942 if (!selection().contains(p))
943 return; 976 return;
944 977
945 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 978 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
946 // needs to be audited. See http://crbug.com/590369 for more details. 979 // needs to be audited. See http://crbug.com/590369 for more details.
947 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); 980 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
948 981
949 const VisiblePositionInFlatTree& visiblePos = 982 const VisiblePositionInFlatTree& visiblePos =
950 visiblePositionOfHitTestResult(mev.hitTestResult()); 983 visiblePositionOfHitTestResult(mev.hitTestResult());
951 if (visiblePos.isNull()) { 984 if (visiblePos.isNull()) {
952 selection().setSelection(VisibleSelectionInFlatTree()); 985 selection().setSelection(VisibleSelectionInFlatTree());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 return event.event().altKey() && event.isOverLink(); 1023 return event.event().altKey() && event.isOverLink();
991 } 1024 }
992 1025
993 bool isExtendingSelection(const MouseEventWithHitTestResults& event) { 1026 bool isExtendingSelection(const MouseEventWithHitTestResults& event) {
994 bool isMouseDownOnLinkOrImage = 1027 bool isMouseDownOnLinkOrImage =
995 event.isOverLink() || event.hitTestResult().image(); 1028 event.isOverLink() || event.hitTestResult().image();
996 return event.event().shiftKey() && !isMouseDownOnLinkOrImage; 1029 return event.event().shiftKey() && !isMouseDownOnLinkOrImage;
997 } 1030 }
998 1031
999 } // namespace blink 1032 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698