Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" | |
| 28 #include "core/frame/FrameView.h" | 29 #include "core/frame/FrameView.h" |
| 29 #include "core/frame/LocalFrame.h" | 30 #include "core/frame/LocalFrame.h" |
| 30 #include "core/frame/Settings.h" | 31 #include "core/frame/Settings.h" |
| 31 #include "core/html/HTMLIFrameElement.h" | 32 #include "core/html/HTMLIFrameElement.h" |
| 32 #include "core/layout/HitTestResult.h" | 33 #include "core/layout/HitTestResult.h" |
| 33 #include "core/layout/LayoutGeometryMap.h" | 34 #include "core/layout/LayoutGeometryMap.h" |
| 34 #include "core/layout/LayoutPart.h" | 35 #include "core/layout/LayoutPart.h" |
| 35 #include "core/layout/ViewFragmentationContext.h" | 36 #include "core/layout/ViewFragmentationContext.h" |
| 36 #include "core/layout/api/LayoutAPIShim.h" | 37 #include "core/layout/api/LayoutAPIShim.h" |
| 37 #include "core/layout/api/LayoutPartItem.h" | 38 #include "core/layout/api/LayoutPartItem.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 private: | 81 private: |
| 81 double start_; | 82 double start_; |
| 82 bool allows_child_frame_content_; | 83 bool allows_child_frame_content_; |
| 83 }; | 84 }; |
| 84 | 85 |
| 85 } // namespace | 86 } // namespace |
| 86 | 87 |
| 87 LayoutView::LayoutView(Document* document) | 88 LayoutView::LayoutView(Document* document) |
| 88 : LayoutBlockFlow(document), | 89 : LayoutBlockFlow(document), |
| 89 frame_view_(document->View()), | 90 frame_view_(document->View()), |
| 90 selection_start_(nullptr), | |
| 91 selection_end_(nullptr), | |
| 92 selection_start_pos_(-1), | |
| 93 selection_end_pos_(-1), | |
| 94 layout_state_(nullptr), | 91 layout_state_(nullptr), |
| 95 layout_quote_head_(nullptr), | 92 layout_quote_head_(nullptr), |
| 96 layout_counter_count_(0), | 93 layout_counter_count_(0), |
| 97 hit_test_count_(0), | 94 hit_test_count_(0), |
| 98 hit_test_cache_hits_(0), | 95 hit_test_cache_hits_(0), |
| 99 hit_test_cache_(HitTestCache::Create()) { | 96 hit_test_cache_(HitTestCache::Create()) { |
| 100 // init LayoutObject attributes | 97 // init LayoutObject attributes |
| 101 SetInline(false); | 98 SetInline(false); |
| 102 | 99 |
| 103 min_preferred_logical_width_ = LayoutUnit(); | 100 min_preferred_logical_width_ = LayoutUnit(); |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { | 622 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { |
| 626 if (!object->IsRooted()) | 623 if (!object->IsRooted()) |
| 627 return LayoutRect(); | 624 return LayoutRect(); |
| 628 | 625 |
| 629 if (!object->CanUpdateSelectionOnRootLineBoxes()) | 626 if (!object->CanUpdateSelectionOnRootLineBoxes()) |
| 630 return LayoutRect(); | 627 return LayoutRect(); |
| 631 | 628 |
| 632 return object->SelectionRectInViewCoordinates(); | 629 return object->SelectionRectInViewCoordinates(); |
| 633 } | 630 } |
| 634 | 631 |
| 635 IntRect LayoutView::SelectionBounds() { | 632 // TODO(yoichio): Move this to LayoutSelection. |
| 633 IntRect LayoutSelection::SelectionBounds() { | |
| 636 // Now create a single bounding box rect that encloses the whole selection. | 634 // Now create a single bounding box rect that encloses the whole selection. |
| 637 LayoutRect sel_rect; | 635 LayoutRect sel_rect; |
| 638 | 636 |
| 639 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet; | 637 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet; |
| 640 VisitedContainingBlockSet visited_containing_blocks; | 638 VisitedContainingBlockSet visited_containing_blocks; |
| 641 | 639 |
| 642 CommitPendingSelection(); | 640 Commit(*frame_selection_->GetDocument().GetLayoutView()); |
| 643 LayoutObject* os = selection_start_; | 641 LayoutObject* os = selection_start_; |
| 644 LayoutObject* stop = | 642 LayoutObject* stop = |
| 645 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); | 643 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); |
| 646 while (os && os != stop) { | 644 while (os && os != stop) { |
| 647 if ((os->CanBeSelectionLeaf() || os == selection_start_ || | 645 if ((os->CanBeSelectionLeaf() || os == selection_start_ || |
| 648 os == selection_end_) && | 646 os == selection_end_) && |
| 649 os->GetSelectionState() != SelectionNone) { | 647 os->GetSelectionState() != SelectionNone) { |
| 650 // Blocks are responsible for painting line gaps and margin gaps. They | 648 // Blocks are responsible for painting line gaps and margin gaps. They |
| 651 // must be examined as well. | 649 // must be examined as well. |
| 652 sel_rect.Unite(SelectionRectForLayoutObject(os)); | 650 sel_rect.Unite(SelectionRectForLayoutObject(os)); |
| 653 const LayoutBlock* cb = os->ContainingBlock(); | 651 const LayoutBlock* cb = os->ContainingBlock(); |
| 654 while (cb && !cb->IsLayoutView()) { | 652 while (cb && !cb->IsLayoutView()) { |
| 655 sel_rect.Unite(SelectionRectForLayoutObject(cb)); | 653 sel_rect.Unite(SelectionRectForLayoutObject(cb)); |
| 656 VisitedContainingBlockSet::AddResult add_result = | 654 VisitedContainingBlockSet::AddResult add_result = |
| 657 visited_containing_blocks.insert(cb); | 655 visited_containing_blocks.insert(cb); |
| 658 if (!add_result.is_new_entry) | 656 if (!add_result.is_new_entry) |
| 659 break; | 657 break; |
| 660 cb = cb->ContainingBlock(); | 658 cb = cb->ContainingBlock(); |
| 661 } | 659 } |
| 662 } | 660 } |
| 663 | 661 |
| 664 os = os->NextInPreOrder(); | 662 os = os->NextInPreOrder(); |
| 665 } | 663 } |
| 666 | 664 |
| 667 return PixelSnappedIntRect(sel_rect); | 665 return PixelSnappedIntRect(sel_rect); |
| 668 } | 666 } |
| 669 | 667 |
| 670 void LayoutView::InvalidatePaintForSelection() { | 668 // TODO(yoichio): Move this to LayoutSelection. |
| 669 void LayoutSelection::InvalidatePaintForSelection() { | |
| 671 LayoutObject* end = | 670 LayoutObject* end = |
| 672 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); | 671 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); |
| 673 for (LayoutObject* o = selection_start_; o && o != end; | 672 for (LayoutObject* o = selection_start_; o && o != end; |
| 674 o = o->NextInPreOrder()) { | 673 o = o->NextInPreOrder()) { |
| 675 if (!o->CanBeSelectionLeaf() && o != selection_start_ && | 674 if (!o->CanBeSelectionLeaf() && o != selection_start_ && |
| 676 o != selection_end_) | 675 o != selection_end_) |
| 677 continue; | 676 continue; |
| 678 if (o->GetSelectionState() == SelectionNone) | 677 if (o->GetSelectionState() == SelectionNone) |
| 679 continue; | 678 continue; |
| 680 | 679 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 700 exploring_backwards = !next && (next != stop); | 699 exploring_backwards = !next && (next != stop); |
| 701 if (exploring_backwards) { | 700 if (exploring_backwards) { |
| 702 next = stop->PreviousInPreOrder(); | 701 next = stop->PreviousInPreOrder(); |
| 703 continue_exploring = next && !next->IsLayoutView(); | 702 continue_exploring = next && !next->IsLayoutView(); |
| 704 } | 703 } |
| 705 } | 704 } |
| 706 | 705 |
| 707 return next; | 706 return next; |
| 708 } | 707 } |
| 709 | 708 |
| 710 void LayoutView::SetSelection( | 709 // TODO(yoichio): Move this to LayoutSelection. |
| 710 void LayoutSelection::SetSelection( | |
| 711 LayoutObject* start, | 711 LayoutObject* start, |
| 712 int start_pos, | 712 int start_pos, |
| 713 LayoutObject* end, | 713 LayoutObject* end, |
| 714 int end_pos, | 714 int end_pos, |
| 715 SelectionPaintInvalidationMode block_paint_invalidation_mode) { | 715 SelectionPaintInvalidationMode block_paint_invalidation_mode) { |
| 716 // This code makes no assumptions as to if the layout tree is up to date or | 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 | 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. | 718 // (intentionally) without updating the layout tree as it doesn't care. |
| 719 // Other callers may want to force recalc style before calling this. | 719 // Other callers may want to force recalc style before calling this. |
| 720 | 720 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 if (!result.is_new_entry) | 830 if (!result.is_new_entry) |
| 831 break; | 831 break; |
| 832 cb = cb->ContainingBlock(); | 832 cb = cb->ContainingBlock(); |
| 833 } | 833 } |
| 834 } | 834 } |
| 835 | 835 |
| 836 o = GetNextOrPrevLayoutObjectBasedOnDirection(o, stop, continue_exploring, | 836 o = GetNextOrPrevLayoutObjectBasedOnDirection(o, stop, continue_exploring, |
| 837 exploring_backwards); | 837 exploring_backwards); |
| 838 } | 838 } |
| 839 | 839 |
| 840 if (!frame_view_) | 840 if (!frame_selection_->GetDocument().GetLayoutView()->GetFrameView()) |
|
dcheng
2017/04/12 07:20:50
Nit: add a TODO to try DCHECKing this, just in cas
yoichio
2017/04/12 08:12:19
Done.
| |
| 841 return; | 841 return; |
| 842 | 842 |
| 843 // Have any of the old selected objects changed compared to the new selection? | 843 // Have any of the old selected objects changed compared to the new selection? |
| 844 for (SelectedObjectMap::iterator i = old_selected_objects.begin(); | 844 for (SelectedObjectMap::iterator i = old_selected_objects.begin(); |
| 845 i != old_objects_end; ++i) { | 845 i != old_objects_end; ++i) { |
| 846 LayoutObject* obj = i->key; | 846 LayoutObject* obj = i->key; |
| 847 SelectionState new_selection_state = obj->GetSelectionState(); | 847 SelectionState new_selection_state = obj->GetSelectionState(); |
| 848 SelectionState old_selection_state = i->value; | 848 SelectionState old_selection_state = i->value; |
| 849 if (new_selection_state != old_selection_state || | 849 if (new_selection_state != old_selection_state || |
| 850 (selection_start_ == obj && old_start_pos != selection_start_pos_) || | 850 (selection_start_ == obj && old_start_pos != selection_start_pos_) || |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 875 } | 875 } |
| 876 | 876 |
| 877 // Any new blocks that remain were not found in the old blocks dict, and so | 877 // Any new blocks that remain were not found in the old blocks dict, and so |
| 878 // they need to be updated. | 878 // they need to be updated. |
| 879 SelectedBlockMap::iterator new_blocks_end = new_selected_blocks.end(); | 879 SelectedBlockMap::iterator new_blocks_end = new_selected_blocks.end(); |
| 880 for (SelectedBlockMap::iterator i = new_selected_blocks.begin(); | 880 for (SelectedBlockMap::iterator i = new_selected_blocks.begin(); |
| 881 i != new_blocks_end; ++i) | 881 i != new_blocks_end; ++i) |
| 882 i->key->SetShouldInvalidateSelection(); | 882 i->key->SetShouldInvalidateSelection(); |
| 883 } | 883 } |
| 884 | 884 |
| 885 void LayoutView::ClearSelection() { | 885 // TODO(yoichio): Move this to LayoutSelection. |
| 886 void LayoutSelection::ClearSelection() { | |
| 886 // For querying Layer::compositingState() | 887 // For querying Layer::compositingState() |
| 887 // This is correct, since destroying layout objects needs to cause eager paint | 888 // This is correct, since destroying layout objects needs to cause eager paint |
| 888 // invalidations. | 889 // invalidations. |
| 889 DisableCompositingQueryAsserts disabler; | 890 DisableCompositingQueryAsserts disabler; |
| 890 | 891 |
| 891 SetSelection(0, -1, 0, -1, kPaintInvalidationNewMinusOld); | 892 SetSelection(0, -1, 0, -1, kPaintInvalidationNewMinusOld); |
| 892 } | 893 } |
| 893 | 894 |
| 895 void LayoutView::ClearSelection() { | |
| 896 frame_view_->GetFrame().Selection().ClearLayoutSelection(); | |
| 897 } | |
| 898 | |
| 894 bool LayoutView::HasPendingSelection() const { | 899 bool LayoutView::HasPendingSelection() const { |
| 895 return frame_view_->GetFrame().Selection().IsAppearanceDirty(); | 900 return frame_view_->GetFrame().Selection().IsAppearanceDirty(); |
| 896 } | 901 } |
| 897 | 902 |
| 898 void LayoutView::CommitPendingSelection() { | 903 void LayoutView::CommitPendingSelection() { |
| 899 TRACE_EVENT0("blink", "LayoutView::commitPendingSelection"); | 904 TRACE_EVENT0("blink", "LayoutView::commitPendingSelection"); |
| 900 frame_view_->GetFrame().Selection().CommitAppearanceIfNeeded(*this); | 905 frame_view_->GetFrame().Selection().CommitAppearanceIfNeeded(*this); |
| 901 } | 906 } |
| 902 | 907 |
| 903 void LayoutView::SelectionStartEnd(int& start_pos, int& end_pos) { | 908 void LayoutView::SelectionStartEnd(int& start_pos, int& end_pos) { |
| 904 CommitPendingSelection(); | 909 frame_view_->GetFrame().Selection().LayoutSelectionStartEnd(start_pos, |
| 910 end_pos); | |
| 911 } | |
| 912 | |
| 913 // TODO(yoichio): Move this to LayoutSelection. | |
| 914 void LayoutSelection::SelectionStartEnd(int& start_pos, int& end_pos) { | |
| 915 Commit(*frame_selection_->GetDocument().GetLayoutView()); | |
| 905 start_pos = selection_start_pos_; | 916 start_pos = selection_start_pos_; |
| 906 end_pos = selection_end_pos_; | 917 end_pos = selection_end_pos_; |
| 907 } | 918 } |
| 908 | 919 |
| 909 bool LayoutView::ShouldUsePrintingLayout() const { | 920 bool LayoutView::ShouldUsePrintingLayout() const { |
| 910 if (!GetDocument().Printing() || !frame_view_) | 921 if (!GetDocument().Printing() || !frame_view_) |
| 911 return false; | 922 return false; |
| 912 return frame_view_->GetFrame().ShouldUsePrintingLayout(); | 923 return frame_view_->GetFrame().ShouldUsePrintingLayout(); |
| 913 } | 924 } |
| 914 | 925 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1101 // Frame scroll corner is painted using LayoutView as the display item client. | 1112 // Frame scroll corner is painted using LayoutView as the display item client. |
| 1102 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && | 1113 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
| 1103 (GetFrameView()->HorizontalScrollbar() || | 1114 (GetFrameView()->HorizontalScrollbar() || |
| 1104 GetFrameView()->VerticalScrollbar())) | 1115 GetFrameView()->VerticalScrollbar())) |
| 1105 return false; | 1116 return false; |
| 1106 | 1117 |
| 1107 return LayoutBlockFlow::PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); | 1118 return LayoutBlockFlow::PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); |
| 1108 } | 1119 } |
| 1109 | 1120 |
| 1110 } // namespace blink | 1121 } // namespace blink |
| OLD | NEW |