| 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 |