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 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); | 345 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection
ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); |
346 } | 346 } |
347 | 347 |
348 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) | 348 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi
tTestResults& result) |
349 { | 349 { |
350 if (!m_mouseDownMayStartSelect) | 350 if (!m_mouseDownMayStartSelect) |
351 return; | 351 return; |
352 | 352 |
353 AppendTrailingWhitespace appendTrailingWhitespace = (result.event().clickCou
nt() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrai
lingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend; | 353 AppendTrailingWhitespace appendTrailingWhitespace = (result.event().clickCou
nt() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrai
lingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend; |
354 | 354 |
355 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 355 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
356 return selectClosestWordFromHitTestResult<EditingInComposedTreeStrategy>
(result.hitTestResult(), appendTrailingWhitespace); | 356 return selectClosestWordFromHitTestResult<EditingInFlatTreeStrategy>(res
ult.hitTestResult(), appendTrailingWhitespace); |
357 selectClosestWordFromHitTestResult<EditingStrategy>(result.hitTestResult(),
appendTrailingWhitespace); | 357 selectClosestWordFromHitTestResult<EditingStrategy>(result.hitTestResult(),
appendTrailingWhitespace); |
358 } | 358 } |
359 | 359 |
360 template <typename Strategy> | 360 template <typename Strategy> |
361 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven
tWithHitTestResults& result) | 361 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven
tWithHitTestResults& result) |
362 { | 362 { |
363 if (!m_mouseDownMayStartSelect) | 363 if (!m_mouseDownMayStartSelect) |
364 return; | 364 return; |
365 | 365 |
366 selectClosestMisspellingFromHitTestResult<Strategy>(result.hitTestResult(), | 366 selectClosestMisspellingFromHitTestResult<Strategy>(result.hitTestResult(), |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 if (pos.isNotNull()) { | 431 if (pos.isNotNull()) { |
432 newSelection = VisibleSelectionTemplate<Strategy>(pos); | 432 newSelection = VisibleSelectionTemplate<Strategy>(pos); |
433 newSelection.expandUsingGranularity(ParagraphGranularity); | 433 newSelection.expandUsingGranularity(ParagraphGranularity); |
434 } | 434 } |
435 | 435 |
436 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); | 436 return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSe
lectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity); |
437 } | 437 } |
438 | 438 |
439 bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithH
itTestResults& event) | 439 bool SelectionController::handleMousePressEventTripleClick(const MouseEventWithH
itTestResults& event) |
440 { | 440 { |
441 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 441 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
442 return handleMousePressEventTripleClickAlgorithm<EditingInComposedTreeSt
rategy>(event); | 442 return handleMousePressEventTripleClickAlgorithm<EditingInFlatTreeStrate
gy>(event); |
443 return handleMousePressEventTripleClickAlgorithm<EditingStrategy>(event); | 443 return handleMousePressEventTripleClickAlgorithm<EditingStrategy>(event); |
444 } | 444 } |
445 | 445 |
446 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH
itTestResults& event) | 446 bool SelectionController::handleMousePressEventSingleClick(const MouseEventWithH
itTestResults& event) |
447 { | 447 { |
448 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 448 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
449 return handleMousePressEventSingleClickAlgorithm<EditingInComposedTreeSt
rategy>(event); | 449 return handleMousePressEventSingleClickAlgorithm<EditingInFlatTreeStrate
gy>(event); |
450 return handleMousePressEventSingleClickAlgorithm<EditingStrategy>(event); | 450 return handleMousePressEventSingleClickAlgorithm<EditingStrategy>(event); |
451 } | 451 } |
452 | 452 |
453 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul
ts& event) | 453 void SelectionController::handleMousePressEvent(const MouseEventWithHitTestResul
ts& event) |
454 { | 454 { |
455 // If we got the event back, that must mean it wasn't prevented, | 455 // If we got the event back, that must mean it wasn't prevented, |
456 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. | 456 // so it's allowed to start a drag or selection if it wasn't in a scrollbar. |
457 m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !e
vent.scrollbar(); | 457 m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !e
vent.scrollbar(); |
458 m_mouseDownWasSingleClickInSelection = false; | 458 m_mouseDownWasSingleClickInSelection = false; |
459 // Avoid double-tap touch gesture confusion by restricting multi-click side | 459 // Avoid double-tap touch gesture confusion by restricting multi-click side |
(...skipping 23 matching lines...) Expand all Loading... |
483 return; | 483 return; |
484 | 484 |
485 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H
itTestRequest::Move); | 485 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | H
itTestRequest::Move); |
486 HitTestResult result(request, view->rootFrameToContents(lastKnownMousePositi
on)); | 486 HitTestResult result(request, view->rootFrameToContents(lastKnownMousePositi
on)); |
487 layoutObject->hitTest(result); | 487 layoutObject->hitTest(result); |
488 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownM
ousePosition); | 488 updateSelectionForMouseDrag(result, mousePressNode, dragStartPos, lastKnownM
ousePosition); |
489 } | 489 } |
490 | 490 |
491 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) | 491 void SelectionController::updateSelectionForMouseDrag(const HitTestResult& hitTe
stResult, Node* mousePressNode, const LayoutPoint& dragStartPos, const IntPoint&
lastKnownMousePosition) |
492 { | 492 { |
493 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 493 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
494 return updateSelectionForMouseDragAlgorithm<EditingInComposedTreeStrateg
y>(hitTestResult, mousePressNode, dragStartPos, lastKnownMousePosition); | 494 return updateSelectionForMouseDragAlgorithm<EditingInFlatTreeStrategy>(h
itTestResult, mousePressNode, dragStartPos, lastKnownMousePosition); |
495 updateSelectionForMouseDragAlgorithm<EditingStrategy>(hitTestResult, mousePr
essNode, dragStartPos, lastKnownMousePosition); | 495 updateSelectionForMouseDragAlgorithm<EditingStrategy>(hitTestResult, mousePr
essNode, dragStartPos, lastKnownMousePosition); |
496 } | 496 } |
497 | 497 |
498 template <typename Strategy> | 498 template <typename Strategy> |
499 bool SelectionController::handleMouseReleaseEventAlgorithm(const MouseEventWithH
itTestResults& event, const LayoutPoint& dragStartPos) | 499 bool SelectionController::handleMouseReleaseEventAlgorithm(const MouseEventWithH
itTestResults& event, const LayoutPoint& dragStartPos) |
500 { | 500 { |
501 bool handled = false; | 501 bool handled = false; |
502 m_mouseDownMayStartSelect = false; | 502 m_mouseDownMayStartSelect = false; |
503 // Clear the selection if the mouse didn't move after the last mouse | 503 // Clear the selection if the mouse didn't move after the last mouse |
504 // press and it's not a context menu click. We do this so when clicking | 504 // press and it's not a context menu click. We do this so when clicking |
(...skipping 23 matching lines...) Expand all Loading... |
528 if (event.event().button() == MiddleButton && !event.isOverLink()) { | 528 if (event.event().button() == MiddleButton && !event.isOverLink()) { |
529 // Ignore handled, since we want to paste to where the caret was placed
anyway. | 529 // Ignore handled, since we want to paste to where the caret was placed
anyway. |
530 handled = handlePasteGlobalSelection(event.event()) || handled; | 530 handled = handlePasteGlobalSelection(event.event()) || handled; |
531 } | 531 } |
532 | 532 |
533 return handled; | 533 return handled; |
534 } | 534 } |
535 | 535 |
536 bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes
ults& event, const LayoutPoint& dragStartPos) | 536 bool SelectionController::handleMouseReleaseEvent(const MouseEventWithHitTestRes
ults& event, const LayoutPoint& dragStartPos) |
537 { | 537 { |
538 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 538 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
539 return handleMouseReleaseEventAlgorithm<EditingInComposedTreeStrategy>(e
vent, dragStartPos); | 539 return handleMouseReleaseEventAlgorithm<EditingInFlatTreeStrategy>(event
, dragStartPos); |
540 return handleMouseReleaseEventAlgorithm<EditingStrategy>(event, dragStartPos
); | 540 return handleMouseReleaseEventAlgorithm<EditingStrategy>(event, dragStartPos
); |
541 } | 541 } |
542 | 542 |
543 bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& m
ouseEvent) | 543 bool SelectionController::handlePasteGlobalSelection(const PlatformMouseEvent& m
ouseEvent) |
544 { | 544 { |
545 // If the event was a middle click, attempt to copy global selection in afte
r | 545 // If the event was a middle click, attempt to copy global selection in afte
r |
546 // the newly set caret position. | 546 // the newly set caret position. |
547 // | 547 // |
548 // This code is called from either the mouse up or mouse down handling. Ther
e | 548 // This code is called from either the mouse up or mouse down handling. Ther
e |
549 // is some debate about when the global selection is pasted: | 549 // is some debate about when the global selection is pasted: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 #endif | 585 #endif |
586 if (!innerNodeIsSelectable) | 586 if (!innerNodeIsSelectable) |
587 return false; | 587 return false; |
588 | 588 |
589 selectClosestWordFromHitTestResult<Strategy>(hitTestResult, AppendTrailingWh
itespace::DontAppend); | 589 selectClosestWordFromHitTestResult<Strategy>(hitTestResult, AppendTrailingWh
itespace::DontAppend); |
590 return selection().isRange(); | 590 return selection().isRange(); |
591 } | 591 } |
592 | 592 |
593 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges
tureEvent, const HitTestResult& hitTestResult) | 593 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges
tureEvent, const HitTestResult& hitTestResult) |
594 { | 594 { |
595 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 595 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
596 return handleGestureLongPressAlgorithm<EditingInComposedTreeStrategy>(ge
stureEvent, hitTestResult); | 596 return handleGestureLongPressAlgorithm<EditingInFlatTreeStrategy>(gestur
eEvent, hitTestResult); |
597 return handleGestureLongPressAlgorithm<EditingStrategy>(gestureEvent, hitTes
tResult); | 597 return handleGestureLongPressAlgorithm<EditingStrategy>(gestureEvent, hitTes
tResult); |
598 } | 598 } |
599 | 599 |
600 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) | 600 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult
s& mev, const LayoutPoint& position) |
601 { | 601 { |
602 if (selection().contains(position) | 602 if (selection().contains(position) |
603 || mev.scrollbar() | 603 || mev.scrollbar() |
604 // FIXME: In the editable case, word selection sometimes selects content
that isn't underneath the mouse. | 604 // FIXME: In the editable case, word selection sometimes selects content
that isn't underneath the mouse. |
605 // If the selection is non-editable, we do word selection to make it eas
ier to use the contextual menu items | 605 // If the selection is non-editable, we do word selection to make it eas
ier to use the contextual menu items |
606 // available for text selections. But only if we're above text. | 606 // available for text selections. But only if we're above text. |
607 || !(selection().isContentEditable() || (mev.innerNode() && mev.innerNod
e()->isTextNode()))) | 607 || !(selection().isContentEditable() || (mev.innerNode() && mev.innerNod
e()->isTextNode()))) |
608 return; | 608 return; |
609 | 609 |
610 m_mouseDownMayStartSelect = true; // context menu events are always allowed
to perform a selection | 610 m_mouseDownMayStartSelect = true; // context menu events are always allowed
to perform a selection |
611 | 611 |
612 if (mev.hitTestResult().isMisspelled()) { | 612 if (mev.hitTestResult().isMisspelled()) { |
613 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 613 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
614 return selectClosestMisspellingFromMouseEvent<EditingInComposedTreeS
trategy>(mev); | 614 return selectClosestMisspellingFromMouseEvent<EditingInFlatTreeStrat
egy>(mev); |
615 return selectClosestMisspellingFromMouseEvent<EditingStrategy>(mev); | 615 return selectClosestMisspellingFromMouseEvent<EditingStrategy>(mev); |
616 } | 616 } |
617 | 617 |
618 if (!m_frame->editor().behavior().shouldSelectOnContextualMenuClick()) | 618 if (!m_frame->editor().behavior().shouldSelectOnContextualMenuClick()) |
619 return; | 619 return; |
620 | 620 |
621 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 621 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
622 return selectClosestWordOrLinkFromMouseEvent<EditingInComposedTreeStrate
gy>(mev); | 622 return selectClosestWordOrLinkFromMouseEvent<EditingInFlatTreeStrategy>(
mev); |
623 selectClosestWordOrLinkFromMouseEvent<EditingStrategy>(mev); | 623 selectClosestWordOrLinkFromMouseEvent<EditingStrategy>(mev); |
624 } | 624 } |
625 | 625 |
626 template <typename Strategy> | 626 template <typename Strategy> |
627 void SelectionController::passMousePressEventToSubframeAlgorithm(const MouseEven
tWithHitTestResults& mev) | 627 void SelectionController::passMousePressEventToSubframeAlgorithm(const MouseEven
tWithHitTestResults& mev) |
628 { | 628 { |
629 // If we're clicking into a frame that is selected, the frame will appear | 629 // If we're clicking into a frame that is selected, the frame will appear |
630 // greyed out even though we're clicking on the selection. This looks | 630 // greyed out even though we're clicking on the selection. This looks |
631 // really strange (having the whole frame be greyed out), so we deselect the | 631 // really strange (having the whole frame be greyed out), so we deselect the |
632 // selection. | 632 // selection. |
633 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); | 633 IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position()); |
634 if (!selection().contains(p)) | 634 if (!selection().contains(p)) |
635 return; | 635 return; |
636 | 636 |
637 const VisiblePositionTemplate<Strategy> visiblePos = createVisiblePosition( | 637 const VisiblePositionTemplate<Strategy> visiblePos = createVisiblePosition( |
638 fromPositionInDOMTree<Strategy>(mev.innerNode()->layoutObject()->positio
nForPoint(mev.localPoint()))); | 638 fromPositionInDOMTree<Strategy>(mev.innerNode()->layoutObject()->positio
nForPoint(mev.localPoint()))); |
639 VisibleSelectionTemplate<Strategy> newSelection(visiblePos); | 639 VisibleSelectionTemplate<Strategy> newSelection(visiblePos); |
640 selection().setSelection(newSelection); | 640 selection().setSelection(newSelection); |
641 } | 641 } |
642 | 642 |
643 void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitT
estResults& mev) | 643 void SelectionController::passMousePressEventToSubframe(const MouseEventWithHitT
estResults& mev) |
644 { | 644 { |
645 if (RuntimeEnabledFeatures::selectionForComposedTreeEnabled()) | 645 if (RuntimeEnabledFeatures::selectionForFlatTreeEnabled()) |
646 return passMousePressEventToSubframeAlgorithm<EditingInComposedTreeStrat
egy>(mev); | 646 return passMousePressEventToSubframeAlgorithm<EditingInFlatTreeStrategy>
(mev); |
647 passMousePressEventToSubframeAlgorithm<EditingStrategy>(mev); | 647 passMousePressEventToSubframeAlgorithm<EditingStrategy>(mev); |
648 } | 648 } |
649 | 649 |
650 void SelectionController::initializeSelectionState() | 650 void SelectionController::initializeSelectionState() |
651 { | 651 { |
652 m_selectionState = SelectionState::HaveNotStartedSelection; | 652 m_selectionState = SelectionState::HaveNotStartedSelection; |
653 } | 653 } |
654 | 654 |
655 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect) | 655 void SelectionController::setMouseDownMayStartSelect(bool mayStartSelect) |
656 { | 656 { |
(...skipping 19 matching lines...) Expand all Loading... |
676 else | 676 else |
677 m_selectionState = SelectionState::HaveNotStartedSelection; | 677 m_selectionState = SelectionState::HaveNotStartedSelection; |
678 } | 678 } |
679 | 679 |
680 FrameSelection& SelectionController::selection() const | 680 FrameSelection& SelectionController::selection() const |
681 { | 681 { |
682 return m_frame->selection(); | 682 return m_frame->selection(); |
683 } | 683 } |
684 | 684 |
685 } // namespace blink | 685 } // namespace blink |
OLD | NEW |