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

Side by Side Diff: third_party/WebKit/Source/core/editing/LayoutSelection.cpp

Issue 2921863002: Introduce range-based for loop in LayoutSelection. (Closed)
Patch Set: Created 3 years, 6 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
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. All rights 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
4 * reserved. 4 * 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 *
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 LayoutObject* SelectionPaintRange::EndLayoutObject() const { 67 LayoutObject* SelectionPaintRange::EndLayoutObject() const {
68 DCHECK(!IsNull()); 68 DCHECK(!IsNull());
69 return end_layout_object_; 69 return end_layout_object_;
70 } 70 }
71 71
72 int SelectionPaintRange::EndOffset() const { 72 int SelectionPaintRange::EndOffset() const {
73 DCHECK(!IsNull()); 73 DCHECK(!IsNull());
74 return end_offset_; 74 return end_offset_;
75 } 75 }
76 76
77 SelectionPaintRange::Iterator::Iterator(const SelectionPaintRange* range) {
78 if (!range) {
79 current_ = nullptr;
80 return;
81 }
82 current_ = range->StartLayoutObject();
83 included_end_ = range->EndLayoutObject();
84 stop_ = range->EndLayoutObject()->ChildAt(range->EndOffset());
85 if (!stop_)
yosin_UTC9 2017/06/02 08:35:44 nit: prefer early-retrun if (stop_) return; sto
yoichio 2017/06/12 06:12:51 Done.
86 stop_ = range->EndLayoutObject()->NextInPreOrderAfterChildren();
87 }
88
89 SelectionPaintRange::Iterator& SelectionPaintRange::Iterator::operator++() {
90 DCHECK(current_);
91 current_ = current_->NextInPreOrder();
yosin_UTC9 2017/06/02 08:35:44 Let's use for-statement for(current_ = current_->
yoichio 2017/06/12 06:12:51 Done.
92 while (current_ && current_ != stop_) {
93 if (current_ == included_end_ || current_->CanBeSelectionLeaf())
94 return *this;
95 current_ = current_->NextInPreOrder();
96 }
97
98 current_ = nullptr;
99 return *this;
100 }
101
77 LayoutSelection::LayoutSelection(FrameSelection& frame_selection) 102 LayoutSelection::LayoutSelection(FrameSelection& frame_selection)
78 : frame_selection_(&frame_selection), 103 : frame_selection_(&frame_selection),
79 has_pending_selection_(false), 104 has_pending_selection_(false),
80 paint_range_(SelectionPaintRange()) {} 105 paint_range_(SelectionPaintRange()) {}
81 106
82 SelectionInFlatTree LayoutSelection::CalcVisibleSelection( 107 SelectionInFlatTree LayoutSelection::CalcVisibleSelection(
83 const VisibleSelectionInFlatTree& original_selection) const { 108 const VisibleSelectionInFlatTree& original_selection) const {
84 const PositionInFlatTree& start = original_selection.Start(); 109 const PositionInFlatTree& start = original_selection.Start();
85 const PositionInFlatTree& end = original_selection.end(); 110 const PositionInFlatTree& end = original_selection.end();
86 SelectionType selection_type = original_selection.GetSelectionType(); 111 SelectionType selection_type = original_selection.GetSelectionType();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 ? TextAffinity::kUpstream 148 ? TextAffinity::kUpstream
124 : affinity); 149 : affinity);
125 if (visible_end.IsNull()) 150 if (visible_end.IsNull())
126 return SelectionInFlatTree(); 151 return SelectionInFlatTree();
127 SelectionInFlatTree::Builder builder; 152 SelectionInFlatTree::Builder builder;
128 builder.Collapse(visible_start.ToPositionWithAffinity()); 153 builder.Collapse(visible_start.ToPositionWithAffinity());
129 builder.Extend(visible_end.DeepEquivalent()); 154 builder.Extend(visible_end.DeepEquivalent());
130 return builder.Build(); 155 return builder.Build();
131 } 156 }
132 157
133 static LayoutObject* LayoutObjectAfterPosition(LayoutObject* object,
134 unsigned offset) {
135 if (!object)
136 return nullptr;
137 158
138 LayoutObject* child = object->ChildAt(offset);
139 return child ? child : object->NextInPreOrderAfterChildren();
140 }
141 159
142 // Objects each have a single selection rect to examine. 160 // Objects each have a single selection rect to examine.
143 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>; 161 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>;
144 // Blocks contain selected objects and fill gaps between them, either on the 162 // Blocks contain selected objects and fill gaps between them, either on the
145 // left, right, or in between lines and blocks. 163 // left, right, or in between lines and blocks.
146 // In order to get the visual rect right, we have to examine left, middle, and 164 // In order to get the visual rect right, we have to examine left, middle, and
147 // right rects individually, since otherwise the union of those rects might 165 // right rects individually, since otherwise the union of those rects might
148 // remain the same even when changes have occurred. 166 // remain the same even when changes have occurred.
149 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>; 167 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>;
150 struct SelectedMap { 168 struct SelectedMap {
(...skipping 16 matching lines...) Expand all
167 kNotCollectBlock, 185 kNotCollectBlock,
168 }; 186 };
169 187
170 static SelectedMap CollectSelectedMap(const SelectionPaintRange& range, 188 static SelectedMap CollectSelectedMap(const SelectionPaintRange& range,
171 CollectSelectedMapOption option) { 189 CollectSelectedMapOption option) {
172 if (range.IsNull()) 190 if (range.IsNull())
173 return SelectedMap(); 191 return SelectedMap();
174 192
175 SelectedMap selected_map; 193 SelectedMap selected_map;
176 194
177 LayoutObject* const stop = 195 for (LayoutObject* runner : range) {
178 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset());
179 for (LayoutObject* runner = range.StartLayoutObject();
180 runner && (runner != stop); runner = runner->NextInPreOrder()) {
181 if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() &&
182 runner != range.EndLayoutObject())
183 continue;
184 if (runner->GetSelectionState() == SelectionState::kNone) 196 if (runner->GetSelectionState() == SelectionState::kNone)
185 continue; 197 continue;
186 198
187 // Blocks are responsible for painting line gaps and margin gaps. They 199 // Blocks are responsible for painting line gaps and margin gaps. They
188 // must be examined as well. 200 // must be examined as well.
189 selected_map.object_map.Set(runner, runner->GetSelectionState()); 201 selected_map.object_map.Set(runner, runner->GetSelectionState());
190 if (option == CollectSelectedMapOption::kCollectBlock) { 202 if (option == CollectSelectedMapOption::kCollectBlock) {
191 LayoutBlock* containing_block = runner->ContainingBlock(); 203 LayoutBlock* containing_block = runner->ContainingBlock();
192 while (containing_block && !containing_block->IsLayoutView()) { 204 while (containing_block && !containing_block->IsLayoutView()) {
193 SelectedBlockMap::AddResult result = selected_map.block_map.insert( 205 SelectedBlockMap::AddResult result = selected_map.block_map.insert(
(...skipping 14 matching lines...) Expand all
208 220
209 if (range.StartLayoutObject() == range.EndLayoutObject()) { 221 if (range.StartLayoutObject() == range.EndLayoutObject()) {
210 range.StartLayoutObject()->SetSelectionStateIfNeeded( 222 range.StartLayoutObject()->SetSelectionStateIfNeeded(
211 SelectionState::kStartAndEnd); 223 SelectionState::kStartAndEnd);
212 } else { 224 } else {
213 range.StartLayoutObject()->SetSelectionStateIfNeeded( 225 range.StartLayoutObject()->SetSelectionStateIfNeeded(
214 SelectionState::kStart); 226 SelectionState::kStart);
215 range.EndLayoutObject()->SetSelectionStateIfNeeded(SelectionState::kEnd); 227 range.EndLayoutObject()->SetSelectionStateIfNeeded(SelectionState::kEnd);
216 } 228 }
217 229
218 LayoutObject* const stop = 230 for (LayoutObject* runner : range) {
219 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset());
220 for (LayoutObject* runner = range.StartLayoutObject();
221 runner && runner != stop; runner = runner->NextInPreOrder()) {
222 if (runner != range.StartLayoutObject() && 231 if (runner != range.StartLayoutObject() &&
223 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf()) 232 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf())
224 runner->SetSelectionStateIfNeeded(SelectionState::kInside); 233 runner->SetSelectionStateIfNeeded(SelectionState::kInside);
225 } 234 }
226 } 235 }
227 236
228 // Set SetSelectionState and ShouldInvalidateSelection flag of LayoutObjects 237 // Set SetSelectionState and ShouldInvalidateSelection flag of LayoutObjects
229 // comparing them in |new_range| and |old_range|. 238 // comparing them in |new_range| and |old_range|.
230 static void UpdateLayoutObjectState(const SelectionPaintRange& new_range, 239 static void UpdateLayoutObjectState(const SelectionPaintRange& new_range,
231 const SelectionPaintRange& old_range) { 240 const SelectionPaintRange& old_range) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 // Now create a single bounding box rect that encloses the whole selection. 401 // Now create a single bounding box rect that encloses the whole selection.
393 LayoutRect sel_rect; 402 LayoutRect sel_rect;
394 403
395 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet; 404 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet;
396 VisitedContainingBlockSet visited_containing_blocks; 405 VisitedContainingBlockSet visited_containing_blocks;
397 406
398 Commit(); 407 Commit();
399 if (paint_range_.IsNull()) 408 if (paint_range_.IsNull())
400 return IntRect(); 409 return IntRect();
401 410
402 LayoutObject* os = paint_range_.StartLayoutObject(); 411 for (LayoutObject* runner : paint_range_) {
403 LayoutObject* stop = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(), 412 if (runner->GetSelectionState() == SelectionState::kNone)
404 paint_range_.EndOffset()); 413 continue;
405 while (os && os != stop) { 414
406 if ((os->CanBeSelectionLeaf() || os == paint_range_.StartLayoutObject() || 415 // Blocks are responsible for painting line gaps and margin gaps. They
407 os == paint_range_.EndLayoutObject()) && 416 // must be examined as well.
408 os->GetSelectionState() != SelectionState::kNone) { 417 sel_rect.Unite(SelectionRectForLayoutObject(runner));
409 // Blocks are responsible for painting line gaps and margin gaps. They 418 const LayoutBlock* cb = runner->ContainingBlock();
yosin_UTC9 2017/06/02 08:35:44 Let't use for-statement for (const LayoutBlock* c
yoichio 2017/06/12 06:12:51 I will use CollectSelectedMap and remove these lin
410 // must be examined as well. 419 while (cb && !cb->IsLayoutView()) {
411 sel_rect.Unite(SelectionRectForLayoutObject(os)); 420 sel_rect.Unite(SelectionRectForLayoutObject(cb));
412 const LayoutBlock* cb = os->ContainingBlock(); 421 VisitedContainingBlockSet::AddResult add_result =
413 while (cb && !cb->IsLayoutView()) { 422 visited_containing_blocks.insert(cb);
414 sel_rect.Unite(SelectionRectForLayoutObject(cb)); 423 if (!add_result.is_new_entry)
415 VisitedContainingBlockSet::AddResult add_result = 424 break;
416 visited_containing_blocks.insert(cb); 425 cb = cb->ContainingBlock();
417 if (!add_result.is_new_entry)
418 break;
419 cb = cb->ContainingBlock();
420 }
421 } 426 }
422
423 os = os->NextInPreOrder();
424 } 427 }
425 428
426 return PixelSnappedIntRect(sel_rect); 429 return PixelSnappedIntRect(sel_rect);
427 } 430 }
428 431
429 void LayoutSelection::InvalidatePaintForSelection() { 432 void LayoutSelection::InvalidatePaintForSelection() {
430 if (paint_range_.IsNull()) 433 if (paint_range_.IsNull())
431 return; 434 return;
432 435
433 LayoutObject* end = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(), 436 for (LayoutObject* runner : paint_range_) {
434 paint_range_.EndOffset()); 437 if (runner->GetSelectionState() == SelectionState::kNone)
435 for (LayoutObject* o = paint_range_.StartLayoutObject(); o && o != end;
436 o = o->NextInPreOrder()) {
437 if (!o->CanBeSelectionLeaf() && o != paint_range_.StartLayoutObject() &&
438 o != paint_range_.EndLayoutObject())
439 continue;
440 if (o->GetSelectionState() == SelectionState::kNone)
441 continue; 438 continue;
442 439
443 o->SetShouldInvalidateSelection(); 440 runner->SetShouldInvalidateSelection();
444 } 441 }
445 } 442 }
446 443
447 DEFINE_TRACE(LayoutSelection) { 444 DEFINE_TRACE(LayoutSelection) {
448 visitor->Trace(frame_selection_); 445 visitor->Trace(frame_selection_);
449 } 446 }
450 447
451 } // namespace blink 448 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698