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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutView.cpp

Issue 2813403002: Move LayouetSelection function definition from layout/LayoutView.cpp to editing/LayoutSelection.cpp (Closed)
Patch Set: update Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/editing/LayoutSelection.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details. 14 * Library General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Library General Public License 16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to 17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA. 19 * Boston, MA 02110-1301, USA.
20 */ 20 */
21 21
22 #include "core/layout/LayoutView.h" 22 #include "core/layout/LayoutView.h"
23 23
24 #include <inttypes.h> 24 #include <inttypes.h>
25 #include "core/dom/Document.h" 25 #include "core/dom/Document.h"
26 #include "core/dom/Element.h" 26 #include "core/dom/Element.h"
27 #include "core/editing/FrameSelection.h" 27 #include "core/editing/FrameSelection.h"
28 #include "core/editing/LayoutSelection.h"
29 #include "core/frame/FrameView.h" 28 #include "core/frame/FrameView.h"
30 #include "core/frame/LocalFrame.h" 29 #include "core/frame/LocalFrame.h"
31 #include "core/frame/Settings.h" 30 #include "core/frame/Settings.h"
32 #include "core/html/HTMLIFrameElement.h" 31 #include "core/html/HTMLIFrameElement.h"
33 #include "core/layout/HitTestResult.h" 32 #include "core/layout/HitTestResult.h"
34 #include "core/layout/LayoutGeometryMap.h" 33 #include "core/layout/LayoutGeometryMap.h"
35 #include "core/layout/LayoutPart.h" 34 #include "core/layout/LayoutPart.h"
36 #include "core/layout/ViewFragmentationContext.h" 35 #include "core/layout/ViewFragmentationContext.h"
37 #include "core/layout/api/LayoutAPIShim.h" 36 #include "core/layout/api/LayoutAPIShim.h"
38 #include "core/layout/api/LayoutPartItem.h" 37 #include "core/layout/api/LayoutPartItem.h"
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 rects.push_back( 602 rects.push_back(
604 PixelSnappedIntRect(accumulated_offset, LayoutSize(Layer()->size()))); 603 PixelSnappedIntRect(accumulated_offset, LayoutSize(Layer()->size())));
605 } 604 }
606 605
607 void LayoutView::AbsoluteQuads(Vector<FloatQuad>& quads, 606 void LayoutView::AbsoluteQuads(Vector<FloatQuad>& quads,
608 MapCoordinatesFlags mode) const { 607 MapCoordinatesFlags mode) const {
609 quads.push_back(LocalToAbsoluteQuad( 608 quads.push_back(LocalToAbsoluteQuad(
610 FloatRect(FloatPoint(), FloatSize(Layer()->size())), mode)); 609 FloatRect(FloatPoint(), FloatSize(Layer()->size())), mode));
611 } 610 }
612 611
613 static LayoutObject* LayoutObjectAfterPosition(LayoutObject* object,
614 unsigned offset) {
615 if (!object)
616 return nullptr;
617
618 LayoutObject* child = object->ChildAt(offset);
619 return child ? child : object->NextInPreOrderAfterChildren();
620 }
621
622 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) {
623 if (!object->IsRooted())
624 return LayoutRect();
625
626 if (!object->CanUpdateSelectionOnRootLineBoxes())
627 return LayoutRect();
628
629 return object->SelectionRectInViewCoordinates();
630 }
631
632 // TODO(yoichio): Move this to LayoutSelection.
633 IntRect LayoutSelection::SelectionBounds() {
634 // Now create a single bounding box rect that encloses the whole selection.
635 LayoutRect sel_rect;
636
637 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet;
638 VisitedContainingBlockSet visited_containing_blocks;
639
640 Commit(*frame_selection_->GetDocument().GetLayoutView());
641 LayoutObject* os = selection_start_;
642 LayoutObject* stop =
643 LayoutObjectAfterPosition(selection_end_, selection_end_pos_);
644 while (os && os != stop) {
645 if ((os->CanBeSelectionLeaf() || os == selection_start_ ||
646 os == selection_end_) &&
647 os->GetSelectionState() != SelectionNone) {
648 // Blocks are responsible for painting line gaps and margin gaps. They
649 // must be examined as well.
650 sel_rect.Unite(SelectionRectForLayoutObject(os));
651 const LayoutBlock* cb = os->ContainingBlock();
652 while (cb && !cb->IsLayoutView()) {
653 sel_rect.Unite(SelectionRectForLayoutObject(cb));
654 VisitedContainingBlockSet::AddResult add_result =
655 visited_containing_blocks.insert(cb);
656 if (!add_result.is_new_entry)
657 break;
658 cb = cb->ContainingBlock();
659 }
660 }
661
662 os = os->NextInPreOrder();
663 }
664
665 return PixelSnappedIntRect(sel_rect);
666 }
667
668 // TODO(yoichio): Move this to LayoutSelection.
669 void LayoutSelection::InvalidatePaintForSelection() {
670 LayoutObject* end =
671 LayoutObjectAfterPosition(selection_end_, selection_end_pos_);
672 for (LayoutObject* o = selection_start_; o && o != end;
673 o = o->NextInPreOrder()) {
674 if (!o->CanBeSelectionLeaf() && o != selection_start_ &&
675 o != selection_end_)
676 continue;
677 if (o->GetSelectionState() == SelectionNone)
678 continue;
679
680 o->SetShouldInvalidateSelection();
681 }
682 }
683
684 // When exploring the LayoutTree looking for the nodes involved in the
685 // Selection, sometimes it's required to change the traversing direction because
686 // the "start" position is below the "end" one.
687 static inline LayoutObject* GetNextOrPrevLayoutObjectBasedOnDirection(
688 const LayoutObject* o,
689 const LayoutObject* stop,
690 bool& continue_exploring,
691 bool& exploring_backwards) {
692 LayoutObject* next;
693 if (exploring_backwards) {
694 next = o->PreviousInPreOrder();
695 continue_exploring = next && !(next)->IsLayoutView();
696 } else {
697 next = o->NextInPreOrder();
698 continue_exploring = next && next != stop;
699 exploring_backwards = !next && (next != stop);
700 if (exploring_backwards) {
701 next = stop->PreviousInPreOrder();
702 continue_exploring = next && !next->IsLayoutView();
703 }
704 }
705
706 return next;
707 }
708
709 // TODO(yoichio): Move this to LayoutSelection.
710 void LayoutSelection::SetSelection(
711 LayoutObject* start,
712 int start_pos,
713 LayoutObject* end,
714 int end_pos,
715 SelectionPaintInvalidationMode block_paint_invalidation_mode) {
716 // This code makes no assumptions as to if the layout tree is up to date or
717 // not and will not try to update it. Currently clearSelection calls this
718 // (intentionally) without updating the layout tree as it doesn't care.
719 // Other callers may want to force recalc style before calling this.
720
721 // Make sure both our start and end objects are defined.
722 // Check www.msnbc.com and try clicking around to find the case where this
723 // happened.
724 if ((start && !end) || (end && !start))
725 return;
726
727 // Just return if the selection hasn't changed.
728 if (selection_start_ == start && selection_start_pos_ == start_pos &&
729 selection_end_ == end && selection_end_pos_ == end_pos)
730 return;
731
732 // Record the old selected objects. These will be used later when we compare
733 // against the new selected objects.
734 int old_start_pos = selection_start_pos_;
735 int old_end_pos = selection_end_pos_;
736
737 // Objects each have a single selection rect to examine.
738 typedef HashMap<LayoutObject*, SelectionState> SelectedObjectMap;
739 SelectedObjectMap old_selected_objects;
740 // FIXME: |newSelectedObjects| doesn't really need to store the
741 // SelectionState, it's just more convenient to have it use the same data
742 // structure as |oldSelectedObjects|.
743 SelectedObjectMap new_selected_objects;
744
745 // Blocks contain selected objects and fill gaps between them, either on the
746 // left, right, or in between lines and blocks.
747 // In order to get the visual rect right, we have to examine left, middle, and
748 // right rects individually, since otherwise the union of those rects might
749 // remain the same even when changes have occurred.
750 typedef HashMap<LayoutBlock*, SelectionState> SelectedBlockMap;
751 SelectedBlockMap old_selected_blocks;
752 // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionState,
753 // it's just more convenient to have it use the same data structure as
754 // |oldSelectedBlocks|.
755 SelectedBlockMap new_selected_blocks;
756
757 LayoutObject* os = selection_start_;
758 LayoutObject* stop =
759 LayoutObjectAfterPosition(selection_end_, selection_end_pos_);
760 bool exploring_backwards = false;
761 bool continue_exploring = os && (os != stop);
762 while (continue_exploring) {
763 if ((os->CanBeSelectionLeaf() || os == selection_start_ ||
764 os == selection_end_) &&
765 os->GetSelectionState() != SelectionNone) {
766 // Blocks are responsible for painting line gaps and margin gaps. They
767 // must be examined as well.
768 old_selected_objects.Set(os, os->GetSelectionState());
769 if (block_paint_invalidation_mode == kPaintInvalidationNewXOROld) {
770 LayoutBlock* cb = os->ContainingBlock();
771 while (cb && !cb->IsLayoutView()) {
772 SelectedBlockMap::AddResult result =
773 old_selected_blocks.insert(cb, cb->GetSelectionState());
774 if (!result.is_new_entry)
775 break;
776 cb = cb->ContainingBlock();
777 }
778 }
779 }
780
781 os = GetNextOrPrevLayoutObjectBasedOnDirection(os, stop, continue_exploring,
782 exploring_backwards);
783 }
784
785 // Now clear the selection.
786 SelectedObjectMap::iterator old_objects_end = old_selected_objects.end();
787 for (SelectedObjectMap::iterator i = old_selected_objects.begin();
788 i != old_objects_end; ++i)
789 i->key->SetSelectionStateIfNeeded(SelectionNone);
790
791 // set selection start and end
792 selection_start_ = start;
793 selection_start_pos_ = start_pos;
794 selection_end_ = end;
795 selection_end_pos_ = end_pos;
796
797 // Update the selection status of all objects between m_selectionStart and
798 // m_selectionEnd
799 if (start && start == end) {
800 start->SetSelectionStateIfNeeded(SelectionBoth);
801 } else {
802 if (start)
803 start->SetSelectionStateIfNeeded(SelectionStart);
804 if (end)
805 end->SetSelectionStateIfNeeded(SelectionEnd);
806 }
807
808 LayoutObject* o = start;
809 stop = LayoutObjectAfterPosition(end, end_pos);
810
811 while (o && o != stop) {
812 if (o != start && o != end && o->CanBeSelectionLeaf())
813 o->SetSelectionStateIfNeeded(SelectionInside);
814 o = o->NextInPreOrder();
815 }
816
817 // Now that the selection state has been updated for the new objects, walk
818 // them again and put them in the new objects list.
819 o = start;
820 exploring_backwards = false;
821 continue_exploring = o && (o != stop);
822 while (continue_exploring) {
823 if ((o->CanBeSelectionLeaf() || o == start || o == end) &&
824 o->GetSelectionState() != SelectionNone) {
825 new_selected_objects.Set(o, o->GetSelectionState());
826 LayoutBlock* cb = o->ContainingBlock();
827 while (cb && !cb->IsLayoutView()) {
828 SelectedBlockMap::AddResult result =
829 new_selected_blocks.insert(cb, cb->GetSelectionState());
830 if (!result.is_new_entry)
831 break;
832 cb = cb->ContainingBlock();
833 }
834 }
835
836 o = GetNextOrPrevLayoutObjectBasedOnDirection(o, stop, continue_exploring,
837 exploring_backwards);
838 }
839
840 // TODO(yoichio): DCHECK(frame_selection_->,,,->GetFrameView());
841 if (!frame_selection_->GetDocument().GetLayoutView()->GetFrameView())
842 return;
843
844 // Have any of the old selected objects changed compared to the new selection?
845 for (SelectedObjectMap::iterator i = old_selected_objects.begin();
846 i != old_objects_end; ++i) {
847 LayoutObject* obj = i->key;
848 SelectionState new_selection_state = obj->GetSelectionState();
849 SelectionState old_selection_state = i->value;
850 if (new_selection_state != old_selection_state ||
851 (selection_start_ == obj && old_start_pos != selection_start_pos_) ||
852 (selection_end_ == obj && old_end_pos != selection_end_pos_)) {
853 obj->SetShouldInvalidateSelection();
854 new_selected_objects.erase(obj);
855 }
856 }
857
858 // Any new objects that remain were not found in the old objects dict, and so
859 // they need to be updated.
860 SelectedObjectMap::iterator new_objects_end = new_selected_objects.end();
861 for (SelectedObjectMap::iterator i = new_selected_objects.begin();
862 i != new_objects_end; ++i)
863 i->key->SetShouldInvalidateSelection();
864
865 // Have any of the old blocks changed?
866 SelectedBlockMap::iterator old_blocks_end = old_selected_blocks.end();
867 for (SelectedBlockMap::iterator i = old_selected_blocks.begin();
868 i != old_blocks_end; ++i) {
869 LayoutBlock* block = i->key;
870 SelectionState new_selection_state = block->GetSelectionState();
871 SelectionState old_selection_state = i->value;
872 if (new_selection_state != old_selection_state) {
873 block->SetShouldInvalidateSelection();
874 new_selected_blocks.erase(block);
875 }
876 }
877
878 // Any new blocks that remain were not found in the old blocks dict, and so
879 // they need to be updated.
880 SelectedBlockMap::iterator new_blocks_end = new_selected_blocks.end();
881 for (SelectedBlockMap::iterator i = new_selected_blocks.begin();
882 i != new_blocks_end; ++i)
883 i->key->SetShouldInvalidateSelection();
884 }
885
886 // TODO(yoichio): Move this to LayoutSelection.
887 void LayoutSelection::ClearSelection() {
888 // For querying Layer::compositingState()
889 // This is correct, since destroying layout objects needs to cause eager paint
890 // invalidations.
891 DisableCompositingQueryAsserts disabler;
892
893 SetSelection(0, -1, 0, -1, kPaintInvalidationNewMinusOld);
894 }
895
896 void LayoutView::ClearSelection() { 612 void LayoutView::ClearSelection() {
897 frame_view_->GetFrame().Selection().ClearLayoutSelection(); 613 frame_view_->GetFrame().Selection().ClearLayoutSelection();
898 } 614 }
899 615
900 bool LayoutView::HasPendingSelection() const { 616 bool LayoutView::HasPendingSelection() const {
901 return frame_view_->GetFrame().Selection().IsAppearanceDirty(); 617 return frame_view_->GetFrame().Selection().IsAppearanceDirty();
902 } 618 }
903 619
904 void LayoutView::CommitPendingSelection() { 620 void LayoutView::CommitPendingSelection() {
905 TRACE_EVENT0("blink", "LayoutView::commitPendingSelection"); 621 TRACE_EVENT0("blink", "LayoutView::commitPendingSelection");
906 frame_view_->GetFrame().Selection().CommitAppearanceIfNeeded(*this); 622 frame_view_->GetFrame().Selection().CommitAppearanceIfNeeded(*this);
907 } 623 }
908 624
909 void LayoutView::SelectionStartEnd(int& start_pos, int& end_pos) { 625 void LayoutView::SelectionStartEnd(int& start_pos, int& end_pos) {
910 frame_view_->GetFrame().Selection().LayoutSelectionStartEnd(start_pos, 626 frame_view_->GetFrame().Selection().LayoutSelectionStartEnd(start_pos,
911 end_pos); 627 end_pos);
912 } 628 }
913 629
914 // TODO(yoichio): Move this to LayoutSelection.
915 void LayoutSelection::SelectionStartEnd(int& start_pos, int& end_pos) {
916 Commit(*frame_selection_->GetDocument().GetLayoutView());
917 start_pos = selection_start_pos_;
918 end_pos = selection_end_pos_;
919 }
920
921 bool LayoutView::ShouldUsePrintingLayout() const { 630 bool LayoutView::ShouldUsePrintingLayout() const {
922 if (!GetDocument().Printing() || !frame_view_) 631 if (!GetDocument().Printing() || !frame_view_)
923 return false; 632 return false;
924 return frame_view_->GetFrame().ShouldUsePrintingLayout(); 633 return frame_view_->GetFrame().ShouldUsePrintingLayout();
925 } 634 }
926 635
927 LayoutRect LayoutView::ViewRect() const { 636 LayoutRect LayoutView::ViewRect() const {
928 if (ShouldUsePrintingLayout()) 637 if (ShouldUsePrintingLayout())
929 return LayoutRect(LayoutPoint(), Size()); 638 return LayoutRect(LayoutPoint(), Size());
930 if (frame_view_) 639 if (frame_view_)
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 // Frame scroll corner is painted using LayoutView as the display item client. 822 // Frame scroll corner is painted using LayoutView as the display item client.
1114 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && 823 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() &&
1115 (GetFrameView()->HorizontalScrollbar() || 824 (GetFrameView()->HorizontalScrollbar() ||
1116 GetFrameView()->VerticalScrollbar())) 825 GetFrameView()->VerticalScrollbar()))
1117 return false; 826 return false;
1118 827
1119 return LayoutBlockFlow::PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); 828 return LayoutBlockFlow::PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
1120 } 829 }
1121 830
1122 } // namespace blink 831 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/LayoutSelection.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698