| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #include "core/dom/AXObjectCache.h" | 32 #include "core/dom/AXObjectCache.h" |
| 33 #include "core/dom/CharacterData.h" | 33 #include "core/dom/CharacterData.h" |
| 34 #include "core/dom/Document.h" | 34 #include "core/dom/Document.h" |
| 35 #include "core/dom/Element.h" | 35 #include "core/dom/Element.h" |
| 36 #include "core/dom/ElementTraversal.h" | 36 #include "core/dom/ElementTraversal.h" |
| 37 #include "core/dom/NodeTraversal.h" | 37 #include "core/dom/NodeTraversal.h" |
| 38 #include "core/dom/Text.h" | 38 #include "core/dom/Text.h" |
| 39 #include "core/editing/CaretBase.h" | 39 #include "core/editing/CaretBase.h" |
| 40 #include "core/editing/EditingUtilities.h" | 40 #include "core/editing/EditingUtilities.h" |
| 41 #include "core/editing/Editor.h" | 41 #include "core/editing/Editor.h" |
| 42 #include "core/editing/FrameCaret.h" |
| 42 #include "core/editing/GranularityStrategy.h" | 43 #include "core/editing/GranularityStrategy.h" |
| 43 #include "core/editing/InputMethodController.h" | 44 #include "core/editing/InputMethodController.h" |
| 44 #include "core/editing/PendingSelection.h" | 45 #include "core/editing/PendingSelection.h" |
| 45 #include "core/editing/RenderedPosition.h" | 46 #include "core/editing/RenderedPosition.h" |
| 46 #include "core/editing/SelectionController.h" | 47 #include "core/editing/SelectionController.h" |
| 47 #include "core/editing/SelectionEditor.h" | 48 #include "core/editing/SelectionEditor.h" |
| 48 #include "core/editing/SelectionModifier.h" | 49 #include "core/editing/SelectionModifier.h" |
| 49 #include "core/editing/TextAffinity.h" | 50 #include "core/editing/TextAffinity.h" |
| 50 #include "core/editing/VisibleUnits.h" | 51 #include "core/editing/VisibleUnits.h" |
| 51 #include "core/editing/commands/TypingCommand.h" | 52 #include "core/editing/commands/TypingCommand.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 { | 92 { |
| 92 return frame->editor().behavior().shouldConsiderSelectionAsDirectional(); | 93 return frame->editor().behavior().shouldConsiderSelectionAsDirectional(); |
| 93 } | 94 } |
| 94 | 95 |
| 95 FrameSelection::FrameSelection(LocalFrame* frame) | 96 FrameSelection::FrameSelection(LocalFrame* frame) |
| 96 : m_frame(frame) | 97 : m_frame(frame) |
| 97 , m_pendingSelection(PendingSelection::create(*this)) | 98 , m_pendingSelection(PendingSelection::create(*this)) |
| 98 , m_selectionEditor(SelectionEditor::create(*this)) | 99 , m_selectionEditor(SelectionEditor::create(*this)) |
| 99 , m_granularity(CharacterGranularity) | 100 , m_granularity(CharacterGranularity) |
| 100 , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation()) | 101 , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation()) |
| 101 , m_previousCaretVisibility(CaretVisibility::Hidden) | |
| 102 , m_caretBlinkTimer(this, &FrameSelection::caretBlinkTimerFired) | |
| 103 , m_caretRectDirty(true) | |
| 104 , m_shouldPaintCaret(true) | |
| 105 , m_isCaretBlinkingSuspended(false) | |
| 106 , m_focused(frame->page() && frame->page()->focusController().focusedFrame()
== frame) | 102 , m_focused(frame->page() && frame->page()->focusController().focusedFrame()
== frame) |
| 107 , m_shouldShowBlockCursor(false) | 103 , m_shouldShowBlockCursor(false) |
| 108 , m_caretBase(adoptPtr(new CaretBase)) | 104 , m_frameCaret(new FrameCaret(frame)) |
| 109 { | 105 { |
| 110 DCHECK(frame); | 106 DCHECK(frame); |
| 111 if (shouldAlwaysUseDirectionalSelection(m_frame)) | 107 if (shouldAlwaysUseDirectionalSelection(m_frame)) |
| 112 m_selectionEditor->setIsDirectional(true); | 108 m_selectionEditor->setIsDirectional(true); |
| 113 } | 109 } |
| 114 | 110 |
| 115 FrameSelection::~FrameSelection() | 111 FrameSelection::~FrameSelection() |
| 116 { | 112 { |
| 117 } | 113 } |
| 118 | 114 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 334 |
| 339 m_selectionEditor->setVisibleSelection(s, options); | 335 m_selectionEditor->setVisibleSelection(s, options); |
| 340 setCaretRectNeedsUpdate(); | 336 setCaretRectNeedsUpdate(); |
| 341 | 337 |
| 342 if (!s.isNone() && !(options & DoNotSetFocus)) | 338 if (!s.isNone() && !(options & DoNotSetFocus)) |
| 343 setFocusedNodeIfNeeded(); | 339 setFocusedNodeIfNeeded(); |
| 344 | 340 |
| 345 if (!(options & DoNotUpdateAppearance)) { | 341 if (!(options & DoNotUpdateAppearance)) { |
| 346 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr
olling-contents.html | 342 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr
olling-contents.html |
| 347 DisableCompositingQueryAsserts disabler; | 343 DisableCompositingQueryAsserts disabler; |
| 348 stopCaretBlinkTimer(); | 344 m_frameCaret->stopCaretBlinkTimer(); |
| 349 updateAppearance(); | 345 updateAppearance(); |
| 350 } | 346 } |
| 351 | 347 |
| 352 // Always clear the x position used for vertical arrow navigation. | 348 // Always clear the x position used for vertical arrow navigation. |
| 353 // It will be restored by the vertical arrow navigation code if necessary. | 349 // It will be restored by the vertical arrow navigation code if necessary. |
| 354 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); | 350 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); |
| 355 // This may dispatch a synchronous focus-related events. | 351 // This may dispatch a synchronous focus-related events. |
| 356 selectFrameElementInParentIfFullySelected(); | 352 selectFrameElementInParentIfFullySelected(); |
| 357 notifyLayoutObjectOfSelectionChange(userTriggered); | 353 notifyLayoutObjectOfSelectionChange(userTriggered); |
| 358 // If the selections are same in the DOM tree but not in the flat tree, | 354 // If the selections are same in the DOM tree but not in the flat tree, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 if (position.anchorNode() == node) | 396 if (position.anchorNode() == node) |
| 401 return true; | 397 return true; |
| 402 | 398 |
| 403 if (!node.isElementNode()) | 399 if (!node.isElementNode()) |
| 404 return false; | 400 return false; |
| 405 | 401 |
| 406 Element& element = toElement(node); | 402 Element& element = toElement(node); |
| 407 return element.isShadowIncludingInclusiveAncestorOf(position.anchorNode()); | 403 return element.isShadowIncludingInclusiveAncestorOf(position.anchorNode()); |
| 408 } | 404 } |
| 409 | 405 |
| 406 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 407 void FrameCaret::nodeWillBeRemoved(Node& node) |
| 408 { |
| 409 if (node != m_previousCaretNode) |
| 410 return; |
| 411 // Hits in ManualTests/caret-paint-after-last-text-is-removed.html |
| 412 DisableCompositingQueryAsserts disabler; |
| 413 invalidateLocalCaretRect(m_previousCaretNode.get(), m_previousCaretRect); |
| 414 m_previousCaretNode = nullptr; |
| 415 m_previousCaretRect = LayoutRect(); |
| 416 m_previousCaretVisibility = CaretVisibility::Hidden; |
| 417 } |
| 418 |
| 410 void FrameSelection::nodeWillBeRemoved(Node& node) | 419 void FrameSelection::nodeWillBeRemoved(Node& node) |
| 411 { | 420 { |
| 412 // There can't be a selection inside a fragment, so if a fragment's node is
being removed, | 421 // There can't be a selection inside a fragment, so if a fragment's node is
being removed, |
| 413 // the selection in the document that created the fragment needs no adjustme
nt. | 422 // the selection in the document that created the fragment needs no adjustme
nt. |
| 414 if (isNone() || !node.inActiveDocument()) | 423 if (isNone() || !node.inActiveDocument()) |
| 415 return; | 424 return; |
| 416 | 425 |
| 417 respondToNodeModification(node, removingNodeRemovesPosition(node, selection(
).base()), removingNodeRemovesPosition(node, selection().extent()), | 426 respondToNodeModification(node, removingNodeRemovesPosition(node, selection(
).base()), removingNodeRemovesPosition(node, selection().extent()), |
| 418 removingNodeRemovesPosition(node, selection().start()), removingNodeRemo
vesPosition(node, selection().end())); | 427 removingNodeRemovesPosition(node, selection().start()), removingNodeRemo
vesPosition(node, selection().end())); |
| 419 | 428 |
| 420 if (node == m_previousCaretNode) { | 429 m_frameCaret->nodeWillBeRemoved(node); |
| 421 // Hits in ManualTests/caret-paint-after-last-text-is-removed.html | |
| 422 DisableCompositingQueryAsserts disabler; | |
| 423 m_caretBase->invalidateLocalCaretRect(m_previousCaretNode.get(), m_previ
ousCaretRect); | |
| 424 m_previousCaretNode = nullptr; | |
| 425 m_previousCaretRect = LayoutRect(); | |
| 426 m_previousCaretVisibility = CaretVisibility::Hidden; | |
| 427 } | |
| 428 } | 430 } |
| 429 | 431 |
| 430 static bool intersectsNode(const VisibleSelection& selection, Node* node) | 432 static bool intersectsNode(const VisibleSelection& selection, Node* node) |
| 431 { | 433 { |
| 432 if (selection.isNone()) | 434 if (selection.isNone()) |
| 433 return false; | 435 return false; |
| 434 Position start = selection.start().parentAnchoredEquivalent(); | 436 Position start = selection.start().parentAnchoredEquivalent(); |
| 435 Position end = selection.end().parentAnchoredEquivalent(); | 437 Position end = selection.end().parentAnchoredEquivalent(); |
| 436 TrackExceptionState exceptionState; | 438 TrackExceptionState exceptionState; |
| 437 // TODO(yosin) We should avoid to use |Range::intersectsNode()|. | 439 // TODO(yosin) We should avoid to use |Range::intersectsNode()|. |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 | 635 |
| 634 const SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTri
ggered; | 636 const SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTri
ggered; |
| 635 setSelection(selectionModifier.selection(), options); | 637 setSelection(selectionModifier.selection(), options); |
| 636 | 638 |
| 637 if (granularity == LineGranularity || granularity == ParagraphGranularity) | 639 if (granularity == LineGranularity || granularity == ParagraphGranularity) |
| 638 m_xPosForVerticalArrowNavigation = selectionModifier.xPosForVerticalArro
wNavigation(); | 640 m_xPosForVerticalArrowNavigation = selectionModifier.xPosForVerticalArro
wNavigation(); |
| 639 | 641 |
| 640 if (userTriggered == UserTriggered) | 642 if (userTriggered == UserTriggered) |
| 641 m_granularity = CharacterGranularity; | 643 m_granularity = CharacterGranularity; |
| 642 | 644 |
| 643 setCaretRectNeedsUpdate(); | 645 m_frameCaret->setCaretRectNeedsUpdate(); |
| 644 | 646 |
| 645 return true; | 647 return true; |
| 646 } | 648 } |
| 647 | 649 |
| 648 bool FrameSelection::modify(EAlteration alter, unsigned verticalDistance, Vertic
alDirection direction, EUserTriggered userTriggered, CursorAlignOnScroll align) | 650 bool FrameSelection::modify(EAlteration alter, unsigned verticalDistance, Vertic
alDirection direction, EUserTriggered userTriggered, CursorAlignOnScroll align) |
| 649 { | 651 { |
| 650 SelectionModifier selectionModifier(*frame(), selection()); | 652 SelectionModifier selectionModifier(*frame(), selection()); |
| 651 if (!selectionModifier.modifyWithPageGranularity(alter, verticalDistance, di
rection)) | 653 if (!selectionModifier.modifyWithPageGranularity(alter, verticalDistance, di
rection)) |
| 652 return false; | 654 return false; |
| 653 | 655 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 664 } | 666 } |
| 665 | 667 |
| 666 void FrameSelection::clear() | 668 void FrameSelection::clear() |
| 667 { | 669 { |
| 668 m_granularity = CharacterGranularity; | 670 m_granularity = CharacterGranularity; |
| 669 if (m_granularityStrategy) | 671 if (m_granularityStrategy) |
| 670 m_granularityStrategy->Clear(); | 672 m_granularityStrategy->Clear(); |
| 671 setSelection(VisibleSelection()); | 673 setSelection(VisibleSelection()); |
| 672 } | 674 } |
| 673 | 675 |
| 676 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 677 void FrameCaret::prepareForDestruction() |
| 678 { |
| 679 m_caretBlinkTimer.stop(); |
| 680 m_previousCaretNode.clear(); |
| 681 } |
| 682 |
| 674 void FrameSelection::prepareForDestruction() | 683 void FrameSelection::prepareForDestruction() |
| 675 { | 684 { |
| 676 m_originalBase = VisiblePosition(); | 685 m_originalBase = VisiblePosition(); |
| 677 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); | 686 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); |
| 678 m_granularity = CharacterGranularity; | 687 m_granularity = CharacterGranularity; |
| 679 | 688 |
| 680 m_caretBlinkTimer.stop(); | |
| 681 | |
| 682 LayoutViewItem view = m_frame->contentLayoutItem(); | 689 LayoutViewItem view = m_frame->contentLayoutItem(); |
| 683 if (!view.isNull()) | 690 if (!view.isNull()) |
| 684 view.clearSelection(); | 691 view.clearSelection(); |
| 685 | 692 |
| 686 setSelection(VisibleSelection(), CloseTyping | ClearTypingStyle | DoNotUpdat
eAppearance); | 693 setSelection(VisibleSelection(), CloseTyping | ClearTypingStyle | DoNotUpdat
eAppearance); |
| 687 m_selectionEditor->dispose(); | 694 m_selectionEditor->dispose(); |
| 688 m_previousCaretNode.clear(); | 695 m_frameCaret->prepareForDestruction(); |
| 689 } | 696 } |
| 690 | 697 |
| 691 void FrameSelection::setBase(const VisiblePosition &pos, EUserTriggered userTrig
gered) | 698 void FrameSelection::setBase(const VisiblePosition &pos, EUserTriggered userTrig
gered) |
| 692 { | 699 { |
| 693 const bool selectionHasDirection = true; | 700 const bool selectionHasDirection = true; |
| 694 setSelection(VisibleSelection(pos.deepEquivalent(), selection().extent(), po
s.affinity(), selectionHasDirection), CloseTyping | ClearTypingStyle | userTrigg
ered); | 701 setSelection(VisibleSelection(pos.deepEquivalent(), selection().extent(), po
s.affinity(), selectionHasDirection), CloseTyping | ClearTypingStyle | userTrigg
ered); |
| 695 } | 702 } |
| 696 | 703 |
| 697 void FrameSelection::setExtent(const VisiblePosition &pos, EUserTriggered userTr
iggered) | 704 void FrameSelection::setExtent(const VisiblePosition &pos, EUserTriggered userTr
iggered) |
| 698 { | 705 { |
| 699 const bool selectionHasDirection = true; | 706 const bool selectionHasDirection = true; |
| 700 setSelection(VisibleSelection(selection().base(), pos.deepEquivalent(), pos.
affinity(), selectionHasDirection), CloseTyping | ClearTypingStyle | userTrigger
ed); | 707 setSelection(VisibleSelection(selection().base(), pos.deepEquivalent(), pos.
affinity(), selectionHasDirection), CloseTyping | ClearTypingStyle | userTrigger
ed); |
| 701 } | 708 } |
| 702 | 709 |
| 703 static bool isTextFormControl(const VisibleSelection& selection) | 710 static bool isTextFormControl(const VisibleSelection& selection) |
| 704 { | 711 { |
| 705 return enclosingTextFormControl(selection.start()); | 712 return enclosingTextFormControl(selection.start()); |
| 706 } | 713 } |
| 707 | 714 |
| 708 LayoutBlock* FrameSelection::caretLayoutObject() const | 715 LayoutBlock* FrameSelection::caretLayoutObject() const |
| 709 { | 716 { |
| 710 DCHECK(selection().isValidFor(*m_frame->document())); | 717 DCHECK(selection().isValidFor(*m_frame->document())); |
| 711 if (!isCaret()) | 718 if (!isCaret()) |
| 712 return nullptr; | 719 return nullptr; |
| 713 return CaretBase::caretLayoutObject(selection().start().anchorNode()); | 720 return CaretBase::caretLayoutObject(selection().start().anchorNode()); |
| 714 } | 721 } |
| 715 | 722 |
| 723 // TODO(yoichio): All of functionality should be in FrameCaret. |
| 724 // FrameCaret should have PositionWithAffnity and FrameSelection set in |
| 725 // setSelecitonAlgorithm. |
| 716 IntRect FrameSelection::absoluteCaretBounds() | 726 IntRect FrameSelection::absoluteCaretBounds() |
| 717 { | 727 { |
| 718 DCHECK(selection().isValidFor(*m_frame->document())); | 728 DCHECK(selection().isValidFor(*m_frame->document())); |
| 719 DCHECK_NE(m_frame->document()->lifecycle().state(), DocumentLifecycle::InPai
ntInvalidation); | 729 DCHECK_NE(m_frame->document()->lifecycle().state(), DocumentLifecycle::InPai
ntInvalidation); |
| 720 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 730 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 721 if (!isCaret()) { | 731 if (!isCaret()) { |
| 722 m_caretBase->clearCaretRect(); | 732 m_frameCaret->clearCaretRect(); |
| 723 } else { | 733 } else { |
| 724 if (isTextFormControl(selection())) | 734 if (isTextFormControl(selection())) |
| 725 m_caretBase->updateCaretRect(PositionWithAffinity(isVisuallyEquivale
ntCandidate(selection().start()) ? selection().start() : Position(), selection()
.affinity())); | 735 m_frameCaret->updateCaretRect(PositionWithAffinity(isVisuallyEquival
entCandidate(selection().start()) ? selection().start() : Position(), selection(
).affinity())); |
| 726 else | 736 else |
| 727 m_caretBase->updateCaretRect(createVisiblePosition(selection().start
(), selection().affinity())); | 737 m_frameCaret->updateCaretRect(createVisiblePosition(selection().star
t(), selection().affinity())); |
| 728 } | 738 } |
| 729 return m_caretBase->absoluteBoundsForLocalRect(selection().start().anchorNod
e(), m_caretBase->localCaretRectWithoutUpdate()); | 739 return m_frameCaret->absoluteBoundsForLocalRect(selection().start().anchorNo
de(), m_frameCaret->localCaretRectWithoutUpdate()); |
| 730 } | 740 } |
| 731 | 741 |
| 732 void FrameSelection::invalidateCaretRect() | 742 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 743 void FrameCaret::invalidateCaretRect(const VisibleSelection& selection) |
| 733 { | 744 { |
| 734 if (!m_caretRectDirty) | 745 if (!m_caretRectDirty) |
| 735 return; | 746 return; |
| 736 m_caretRectDirty = false; | 747 m_caretRectDirty = false; |
| 737 | 748 |
| 738 DCHECK(selection().isValidFor(*m_frame->document())); | 749 DCHECK(selection.isValidFor(*m_frame->document())); |
| 739 LayoutObject* layoutObject = nullptr; | 750 LayoutObject* layoutObject = nullptr; |
| 740 LayoutRect newRect; | 751 LayoutRect newRect; |
| 741 if (selection().isCaret()) | 752 if (selection.isCaret()) |
| 742 newRect = localCaretRectOfPosition(PositionWithAffinity(selection().star
t(), selection().affinity()), layoutObject); | 753 newRect = localCaretRectOfPosition(PositionWithAffinity(selection.start(
), selection.affinity()), layoutObject); |
| 743 Node* newNode = layoutObject ? layoutObject->node() : nullptr; | 754 Node* newNode = layoutObject ? layoutObject->node() : nullptr; |
| 744 | 755 |
| 745 if (!m_caretBlinkTimer.isActive() | 756 if (!m_caretBlinkTimer.isActive() |
| 746 && newNode == m_previousCaretNode | 757 && newNode == m_previousCaretNode |
| 747 && newRect == m_previousCaretRect | 758 && newRect == m_previousCaretRect |
| 748 && m_caretBase->getCaretVisibility() == m_previousCaretVisibility) | 759 && getCaretVisibility() == m_previousCaretVisibility) |
| 749 return; | 760 return; |
| 750 | 761 |
| 751 LayoutViewItem view = m_frame->document()->layoutViewItem(); | 762 LayoutViewItem view = m_frame->document()->layoutViewItem(); |
| 752 if (m_previousCaretNode && (m_caretBase->shouldRepaintCaret(*m_previousCaret
Node) || m_caretBase->shouldRepaintCaret(view))) | 763 if (m_previousCaretNode && (shouldRepaintCaret(*m_previousCaretNode) || shou
ldRepaintCaret(view))) |
| 753 m_caretBase->invalidateLocalCaretRect(m_previousCaretNode.get(), m_previ
ousCaretRect); | 764 invalidateLocalCaretRect(m_previousCaretNode.get(), m_previousCaretRect)
; |
| 754 if (newNode && (m_caretBase->shouldRepaintCaret(*newNode) || m_caretBase->sh
ouldRepaintCaret(view))) | 765 if (newNode && (shouldRepaintCaret(*newNode) || shouldRepaintCaret(view))) |
| 755 m_caretBase->invalidateLocalCaretRect(newNode, newRect); | 766 invalidateLocalCaretRect(newNode, newRect); |
| 756 m_previousCaretNode = newNode; | 767 m_previousCaretNode = newNode; |
| 757 m_previousCaretRect = newRect; | 768 m_previousCaretRect = newRect; |
| 758 m_previousCaretVisibility = m_caretBase->getCaretVisibility(); | 769 m_previousCaretVisibility = getCaretVisibility(); |
| 770 } |
| 771 |
| 772 void FrameSelection::invalidateCaretRect() |
| 773 { |
| 774 m_frameCaret->invalidateCaretRect(selection()); |
| 775 } |
| 776 |
| 777 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 778 void FrameCaret::dataWillChange(const CharacterData& node) |
| 779 { |
| 780 if (node == m_previousCaretNode) { |
| 781 // This invalidation is eager, and intentionally uses stale state. |
| 782 DisableCompositingQueryAsserts disabler; |
| 783 invalidateLocalCaretRect(m_previousCaretNode.get(), m_previousCaretRect)
; |
| 784 } |
| 759 } | 785 } |
| 760 | 786 |
| 761 void FrameSelection::dataWillChange(const CharacterData& node) | 787 void FrameSelection::dataWillChange(const CharacterData& node) |
| 762 { | 788 { |
| 763 if (node == m_previousCaretNode) { | 789 m_frameCaret->dataWillChange(node); |
| 764 // This invalidation is eager, and intentionally uses stale state. | 790 } |
| 765 DisableCompositingQueryAsserts disabler; | 791 |
| 766 m_caretBase->invalidateLocalCaretRect(m_previousCaretNode.get(), m_previ
ousCaretRect); | 792 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 793 void FrameCaret::paintCaret(GraphicsContext& context, const LayoutPoint& paintOf
fset, const VisibleSelection& selection) |
| 794 { |
| 795 if (selection.isCaret() && m_shouldPaintCaret) { |
| 796 updateCaretRect(PositionWithAffinity(selection.start(), selection.affini
ty())); |
| 797 CaretBase::paintCaret(selection.start().anchorNode(), context, paintOffs
et); |
| 767 } | 798 } |
| 768 } | 799 } |
| 769 | 800 |
| 770 void FrameSelection::paintCaret(GraphicsContext& context, const LayoutPoint& pai
ntOffset) | 801 void FrameSelection::paintCaret(GraphicsContext& context, const LayoutPoint& pai
ntOffset) |
| 771 { | 802 { |
| 772 if (selection().isCaret() && m_shouldPaintCaret) { | 803 m_frameCaret->paintCaret(context, paintOffset, selection()); |
| 773 m_caretBase->updateCaretRect(PositionWithAffinity(selection().start(), s
election().affinity())); | |
| 774 m_caretBase->paintCaret(selection().start().anchorNode(), context, paint
Offset); | |
| 775 } | |
| 776 } | 804 } |
| 777 | 805 |
| 778 bool FrameSelection::contains(const LayoutPoint& point) | 806 bool FrameSelection::contains(const LayoutPoint& point) |
| 779 { | 807 { |
| 780 Document* document = m_frame->document(); | 808 Document* document = m_frame->document(); |
| 781 if (document->layoutViewItem().isNull()) | 809 if (document->layoutViewItem().isNull()) |
| 782 return false; | 810 return false; |
| 783 | 811 |
| 784 // Treat a collapsed selection like no selection. | 812 // Treat a collapsed selection like no selection. |
| 785 const VisibleSelectionInFlatTree& visibleSelection = this->visibleSelection<
EditingInFlatTreeStrategy>(); | 813 const VisibleSelectionInFlatTree& visibleSelection = this->visibleSelection<
EditingInFlatTreeStrategy>(); |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 bool FrameSelection::isAppearanceDirty() const | 1067 bool FrameSelection::isAppearanceDirty() const |
| 1040 { | 1068 { |
| 1041 return m_pendingSelection->hasPendingSelection(); | 1069 return m_pendingSelection->hasPendingSelection(); |
| 1042 } | 1070 } |
| 1043 | 1071 |
| 1044 void FrameSelection::commitAppearanceIfNeeded(LayoutView& layoutView) | 1072 void FrameSelection::commitAppearanceIfNeeded(LayoutView& layoutView) |
| 1045 { | 1073 { |
| 1046 return m_pendingSelection->commit(layoutView); | 1074 return m_pendingSelection->commit(layoutView); |
| 1047 } | 1075 } |
| 1048 | 1076 |
| 1077 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 1078 void FrameCaret::startBlinkCaret() |
| 1079 { |
| 1080 // Start blinking with a black caret. Be sure not to restart if we're |
| 1081 // already blinking in the right location. |
| 1082 if (m_caretBlinkTimer.isActive()) |
| 1083 return; |
| 1084 |
| 1085 if (double blinkInterval = LayoutTheme::theme().caretBlinkInterval()) |
| 1086 m_caretBlinkTimer.startRepeating(blinkInterval, BLINK_FROM_HERE); |
| 1087 |
| 1088 m_shouldPaintCaret = true; |
| 1089 setCaretRectNeedsUpdate(); |
| 1090 |
| 1091 } |
| 1092 |
| 1093 // TODO(yoichio): All of functionality should be in FrameCaret. |
| 1094 // FrameCaret should have PositionWithAffnity and FrameSelection set in |
| 1095 // setSelecitonAlgorithm. |
| 1049 void FrameSelection::updateAppearance() | 1096 void FrameSelection::updateAppearance() |
| 1050 { | 1097 { |
| 1051 // Paint a block cursor instead of a caret in overtype mode unless the caret
is at the end of a line (in this case | 1098 // Paint a block cursor instead of a caret in overtype mode unless the caret
is at the end of a line (in this case |
| 1052 // the FrameSelection will paint a blinking caret as usual). | 1099 // the FrameSelection will paint a blinking caret as usual). |
| 1053 bool paintBlockCursor = m_shouldShowBlockCursor && selection().isCaret() &&
!isLogicalEndOfLine(selection().visibleEnd()); | 1100 bool paintBlockCursor = m_shouldShowBlockCursor && selection().isCaret() &&
!isLogicalEndOfLine(selection().visibleEnd()); |
| 1054 | 1101 |
| 1055 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); | 1102 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); |
| 1056 | 1103 |
| 1057 // If the caret moved, stop the blink timer so we can restart with a | 1104 // If the caret moved, stop the blink timer so we can restart with a |
| 1058 // black caret in the new location. | 1105 // black caret in the new location. |
| 1059 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) | 1106 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) |
| 1060 stopCaretBlinkTimer(); | 1107 m_frameCaret->stopCaretBlinkTimer(); |
| 1061 | 1108 |
| 1062 // Start blinking with a black caret. Be sure not to restart if we're | 1109 // Start blinking with a black caret. Be sure not to restart if we're |
| 1063 // already blinking in the right location. | 1110 // already blinking in the right location. |
| 1064 if (shouldBlink && !m_caretBlinkTimer.isActive()) { | 1111 if (shouldBlink) |
| 1065 if (double blinkInterval = LayoutTheme::theme().caretBlinkInterval()) | 1112 m_frameCaret->startBlinkCaret(); |
| 1066 m_caretBlinkTimer.startRepeating(blinkInterval, BLINK_FROM_HERE); | |
| 1067 | |
| 1068 m_shouldPaintCaret = true; | |
| 1069 setCaretRectNeedsUpdate(); | |
| 1070 } | |
| 1071 | 1113 |
| 1072 if (m_frame->contentLayoutItem().isNull()) | 1114 if (m_frame->contentLayoutItem().isNull()) |
| 1073 return; | 1115 return; |
| 1074 m_pendingSelection->setHasPendingSelection(); | 1116 m_pendingSelection->setHasPendingSelection(); |
| 1075 } | 1117 } |
| 1076 | 1118 |
| 1119 // TODO(yoichio): All of functionality should be in FrameCaret. |
| 1120 // FrameCaret should have PositionWithAffnity and FrameSelection set in |
| 1121 // setSelecitonAlgorithm. |
| 1077 void FrameSelection::setCaretVisibility(CaretVisibility visibility) | 1122 void FrameSelection::setCaretVisibility(CaretVisibility visibility) |
| 1078 { | 1123 { |
| 1079 if (m_caretBase->getCaretVisibility() == visibility) | 1124 if (m_frameCaret->getCaretVisibility() == visibility) |
| 1080 return; | 1125 return; |
| 1081 | 1126 |
| 1082 m_caretBase->setCaretVisibility(visibility); | 1127 m_frameCaret->setCaretVisibility(visibility); |
| 1083 | 1128 |
| 1084 updateAppearance(); | 1129 updateAppearance(); |
| 1085 } | 1130 } |
| 1086 | 1131 |
| 1087 bool FrameSelection::shouldBlinkCaret() const | 1132 bool FrameSelection::shouldBlinkCaret() const |
| 1088 { | 1133 { |
| 1089 if (!m_caretBase->caretIsVisible() || !isCaret()) | 1134 if (!m_frameCaret->caretIsVisible() || !isCaret()) |
| 1090 return false; | 1135 return false; |
| 1091 | 1136 |
| 1092 if (m_frame->settings() && m_frame->settings()->caretBrowsingEnabled()) | 1137 if (m_frame->settings() && m_frame->settings()->caretBrowsingEnabled()) |
| 1093 return false; | 1138 return false; |
| 1094 | 1139 |
| 1095 Element* root = rootEditableElement(); | 1140 Element* root = rootEditableElement(); |
| 1096 if (!root) | 1141 if (!root) |
| 1097 return false; | 1142 return false; |
| 1098 | 1143 |
| 1099 Element* focusedElement = root->document().focusedElement(); | 1144 Element* focusedElement = root->document().focusedElement(); |
| 1100 if (!focusedElement) | 1145 if (!focusedElement) |
| 1101 return false; | 1146 return false; |
| 1102 | 1147 |
| 1103 return focusedElement->isShadowIncludingInclusiveAncestorOf(selection().star
t().anchorNode()); | 1148 return focusedElement->isShadowIncludingInclusiveAncestorOf(selection().star
t().anchorNode()); |
| 1104 } | 1149 } |
| 1105 | 1150 |
| 1106 void FrameSelection::caretBlinkTimerFired(Timer<FrameSelection>*) | 1151 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 1152 void FrameCaret::caretBlinkTimerFired(Timer<FrameCaret>*) |
| 1107 { | 1153 { |
| 1108 DCHECK(m_caretBase->caretIsVisible()); | 1154 DCHECK(caretIsVisible()); |
| 1109 DCHECK(isCaret()); | |
| 1110 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) | 1155 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) |
| 1111 return; | 1156 return; |
| 1112 m_shouldPaintCaret = !m_shouldPaintCaret; | 1157 m_shouldPaintCaret = !m_shouldPaintCaret; |
| 1113 setCaretRectNeedsUpdate(); | 1158 setCaretRectNeedsUpdate(); |
| 1114 } | 1159 } |
| 1115 | 1160 |
| 1116 void FrameSelection::stopCaretBlinkTimer() | 1161 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 1162 void FrameCaret::stopCaretBlinkTimer() |
| 1117 { | 1163 { |
| 1118 if (m_caretBlinkTimer.isActive() || m_shouldPaintCaret) | 1164 if (m_caretBlinkTimer.isActive() || m_shouldPaintCaret) |
| 1119 setCaretRectNeedsUpdate(); | 1165 setCaretRectNeedsUpdate(); |
| 1120 m_shouldPaintCaret = false; | 1166 m_shouldPaintCaret = false; |
| 1121 m_caretBlinkTimer.stop(); | 1167 m_caretBlinkTimer.stop(); |
| 1122 } | 1168 } |
| 1123 | 1169 |
| 1124 void FrameSelection::notifyLayoutObjectOfSelectionChange(EUserTriggered userTrig
gered) | 1170 void FrameSelection::notifyLayoutObjectOfSelectionChange(EUserTriggered userTrig
gered) |
| 1125 { | 1171 { |
| 1126 if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start
())) | 1172 if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start
())) |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 | 1403 |
| 1358 #endif | 1404 #endif |
| 1359 | 1405 |
| 1360 DEFINE_TRACE(FrameSelection) | 1406 DEFINE_TRACE(FrameSelection) |
| 1361 { | 1407 { |
| 1362 visitor->trace(m_frame); | 1408 visitor->trace(m_frame); |
| 1363 visitor->trace(m_pendingSelection); | 1409 visitor->trace(m_pendingSelection); |
| 1364 visitor->trace(m_selectionEditor); | 1410 visitor->trace(m_selectionEditor); |
| 1365 visitor->trace(m_originalBase); | 1411 visitor->trace(m_originalBase); |
| 1366 visitor->trace(m_originalBaseInFlatTree); | 1412 visitor->trace(m_originalBaseInFlatTree); |
| 1367 visitor->trace(m_previousCaretNode); | |
| 1368 visitor->trace(m_typingStyle); | 1413 visitor->trace(m_typingStyle); |
| 1414 visitor->trace(m_frameCaret); |
| 1369 } | 1415 } |
| 1370 | 1416 |
| 1371 void FrameSelection::setCaretRectNeedsUpdate() | 1417 // TODO(yoiciho): We should move this function to FrameCaret.cpp |
| 1418 void FrameCaret::setCaretRectNeedsUpdate() |
| 1372 { | 1419 { |
| 1373 if (m_caretRectDirty) | 1420 if (m_caretRectDirty) |
| 1374 return; | 1421 return; |
| 1375 m_caretRectDirty = true; | 1422 m_caretRectDirty = true; |
| 1376 | 1423 |
| 1377 scheduleVisualUpdate(); | 1424 if (Page* page = m_frame->page()) |
| 1425 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); |
| 1378 } | 1426 } |
| 1379 | 1427 |
| 1380 void FrameSelection::scheduleVisualUpdate() const | 1428 void FrameSelection::scheduleVisualUpdate() const |
| 1381 { | 1429 { |
| 1382 if (Page* page = m_frame->page()) | 1430 if (Page* page = m_frame->page()) |
| 1383 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); | 1431 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); |
| 1384 } | 1432 } |
| 1385 | 1433 |
| 1386 bool FrameSelection::selectWordAroundPosition(const VisiblePosition& position) | 1434 bool FrameSelection::selectWordAroundPosition(const VisiblePosition& position) |
| 1387 { | 1435 { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1446 void FrameSelection::updateIfNeeded() | 1494 void FrameSelection::updateIfNeeded() |
| 1447 { | 1495 { |
| 1448 m_selectionEditor->updateIfNeeded(); | 1496 m_selectionEditor->updateIfNeeded(); |
| 1449 } | 1497 } |
| 1450 | 1498 |
| 1451 void FrameSelection::setCaretVisible(bool caretIsVisible) | 1499 void FrameSelection::setCaretVisible(bool caretIsVisible) |
| 1452 { | 1500 { |
| 1453 setCaretVisibility(caretIsVisible ? CaretVisibility::Visible : CaretVisibili
ty::Hidden); | 1501 setCaretVisibility(caretIsVisible ? CaretVisibility::Visible : CaretVisibili
ty::Hidden); |
| 1454 } | 1502 } |
| 1455 | 1503 |
| 1504 bool FrameSelection::shouldPaintCaretForTesting() const |
| 1505 { |
| 1506 return m_frameCaret->shouldPaintCaretForTesting(); |
| 1507 } |
| 1508 |
| 1509 bool FrameSelection::isPreviousCaretDirtyForTesting() const |
| 1510 { |
| 1511 return m_frameCaret->isPreviousCaretDirtyForTesting(); |
| 1512 } |
| 1513 |
| 1514 bool FrameSelection::isCaretBoundsDirty() const |
| 1515 { |
| 1516 return m_frameCaret->isCaretBoundsDirty(); |
| 1517 } |
| 1518 |
| 1519 void FrameSelection::setCaretRectNeedsUpdate() |
| 1520 { |
| 1521 m_frameCaret->setCaretRectNeedsUpdate(); |
| 1522 } |
| 1523 |
| 1524 void FrameSelection::setCaretBlinkingSuspended(bool suspended) |
| 1525 { |
| 1526 m_frameCaret->setCaretBlinkingSuspended(suspended); |
| 1527 } |
| 1528 |
| 1529 bool FrameSelection::isCaretBlinkingSuspended() const |
| 1530 { |
| 1531 return m_frameCaret->isCaretBlinkingSuspended(); |
| 1532 } |
| 1533 |
| 1456 } // namespace blink | 1534 } // namespace blink |
| 1457 | 1535 |
| 1458 #ifndef NDEBUG | 1536 #ifndef NDEBUG |
| 1459 | 1537 |
| 1460 void showTree(const blink::FrameSelection& sel) | 1538 void showTree(const blink::FrameSelection& sel) |
| 1461 { | 1539 { |
| 1462 sel.showTreeForThis(); | 1540 sel.showTreeForThis(); |
| 1463 } | 1541 } |
| 1464 | 1542 |
| 1465 void showTree(const blink::FrameSelection* sel) | 1543 void showTree(const blink::FrameSelection* sel) |
| 1466 { | 1544 { |
| 1467 if (sel) | 1545 if (sel) |
| 1468 sel->showTreeForThis(); | 1546 sel->showTreeForThis(); |
| 1469 else | 1547 else |
| 1470 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n"); | 1548 fprintf(stderr, "Cannot showTree for (nil) FrameSelection.\n"); |
| 1471 } | 1549 } |
| 1472 | 1550 |
| 1473 #endif | 1551 #endif |
| OLD | NEW |