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

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

Issue 2921863002: Introduce range-based for loop in LayoutSelection. (Closed)
Patch Set: update 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
« no previous file with comments | « third_party/WebKit/Source/core/editing/LayoutSelection.h ('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. 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_)
86 return;
87 stop_ = range->EndLayoutObject()->NextInPreOrderAfterChildren();
88 }
89
90 LayoutObject* SelectionPaintRange::Iterator::operator*() const {
91 DCHECK(current_);
92 return current_;
93 }
94
95 SelectionPaintRange::Iterator& SelectionPaintRange::Iterator::operator++() {
96 DCHECK(current_);
97 for (current_ = current_->NextInPreOrder(); current_ && current_ != stop_;
98 current_ = current_->NextInPreOrder()) {
99 if (current_ == included_end_ || current_->CanBeSelectionLeaf())
100 return *this;
101 }
102
103 current_ = nullptr;
104 return *this;
105 }
106
77 LayoutSelection::LayoutSelection(FrameSelection& frame_selection) 107 LayoutSelection::LayoutSelection(FrameSelection& frame_selection)
78 : frame_selection_(&frame_selection), 108 : frame_selection_(&frame_selection),
79 has_pending_selection_(false), 109 has_pending_selection_(false),
80 paint_range_(SelectionPaintRange()) {} 110 paint_range_(SelectionPaintRange()) {}
81 111
82 static SelectionInFlatTree CalcSelection( 112 static SelectionInFlatTree CalcSelection(
83 const VisibleSelectionInFlatTree& original_selection, 113 const VisibleSelectionInFlatTree& original_selection,
84 bool should_show_blok_cursor) { 114 bool should_show_blok_cursor) {
85 const PositionInFlatTree& start = original_selection.Start(); 115 const PositionInFlatTree& start = original_selection.Start();
86 const PositionInFlatTree& end = original_selection.End(); 116 const PositionInFlatTree& end = original_selection.End();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 ? TextAffinity::kUpstream 154 ? TextAffinity::kUpstream
125 : affinity); 155 : affinity);
126 if (visible_end.IsNull()) 156 if (visible_end.IsNull())
127 return SelectionInFlatTree(); 157 return SelectionInFlatTree();
128 SelectionInFlatTree::Builder builder; 158 SelectionInFlatTree::Builder builder;
129 builder.Collapse(visible_start.ToPositionWithAffinity()); 159 builder.Collapse(visible_start.ToPositionWithAffinity());
130 builder.Extend(visible_end.DeepEquivalent()); 160 builder.Extend(visible_end.DeepEquivalent());
131 return builder.Build(); 161 return builder.Build();
132 } 162 }
133 163
134 static LayoutObject* LayoutObjectAfterPosition(LayoutObject* object,
135 unsigned offset) {
136 if (!object)
137 return nullptr;
138 164
139 LayoutObject* child = object->ChildAt(offset);
140 return child ? child : object->NextInPreOrderAfterChildren();
141 }
142 165
143 // Objects each have a single selection rect to examine. 166 // Objects each have a single selection rect to examine.
144 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>; 167 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>;
145 // Blocks contain selected objects and fill gaps between them, either on the 168 // Blocks contain selected objects and fill gaps between them, either on the
146 // left, right, or in between lines and blocks. 169 // left, right, or in between lines and blocks.
147 // In order to get the visual rect right, we have to examine left, middle, and 170 // In order to get the visual rect right, we have to examine left, middle, and
148 // right rects individually, since otherwise the union of those rects might 171 // right rects individually, since otherwise the union of those rects might
149 // remain the same even when changes have occurred. 172 // remain the same even when changes have occurred.
150 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>; 173 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>;
151 struct SelectedMap { 174 struct SelectedMap {
(...skipping 16 matching lines...) Expand all
168 kNotCollectBlock, 191 kNotCollectBlock,
169 }; 192 };
170 193
171 static SelectedMap CollectSelectedMap(const SelectionPaintRange& range, 194 static SelectedMap CollectSelectedMap(const SelectionPaintRange& range,
172 CollectSelectedMapOption option) { 195 CollectSelectedMapOption option) {
173 if (range.IsNull()) 196 if (range.IsNull())
174 return SelectedMap(); 197 return SelectedMap();
175 198
176 SelectedMap selected_map; 199 SelectedMap selected_map;
177 200
178 LayoutObject* const stop = 201 for (LayoutObject* runner : range) {
179 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset());
180 for (LayoutObject* runner = range.StartLayoutObject();
181 runner && (runner != stop); runner = runner->NextInPreOrder()) {
182 if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() &&
183 runner != range.EndLayoutObject())
184 continue;
185 if (runner->GetSelectionState() == SelectionState::kNone) 202 if (runner->GetSelectionState() == SelectionState::kNone)
186 continue; 203 continue;
187 204
188 // Blocks are responsible for painting line gaps and margin gaps. They 205 // Blocks are responsible for painting line gaps and margin gaps. They
189 // must be examined as well. 206 // must be examined as well.
190 selected_map.object_map.Set(runner, runner->GetSelectionState()); 207 selected_map.object_map.Set(runner, runner->GetSelectionState());
191 if (option == CollectSelectedMapOption::kCollectBlock) { 208 if (option == CollectSelectedMapOption::kCollectBlock) {
192 LayoutBlock* containing_block = runner->ContainingBlock(); 209 LayoutBlock* containing_block = runner->ContainingBlock();
193 while (containing_block && !containing_block->IsLayoutView()) { 210 while (containing_block && !containing_block->IsLayoutView()) {
194 SelectedBlockMap::AddResult result = selected_map.block_map.insert( 211 SelectedBlockMap::AddResult result = selected_map.block_map.insert(
(...skipping 14 matching lines...) Expand all
209 226
210 if (range.StartLayoutObject() == range.EndLayoutObject()) { 227 if (range.StartLayoutObject() == range.EndLayoutObject()) {
211 range.StartLayoutObject()->SetSelectionStateIfNeeded( 228 range.StartLayoutObject()->SetSelectionStateIfNeeded(
212 SelectionState::kStartAndEnd); 229 SelectionState::kStartAndEnd);
213 } else { 230 } else {
214 range.StartLayoutObject()->SetSelectionStateIfNeeded( 231 range.StartLayoutObject()->SetSelectionStateIfNeeded(
215 SelectionState::kStart); 232 SelectionState::kStart);
216 range.EndLayoutObject()->SetSelectionStateIfNeeded(SelectionState::kEnd); 233 range.EndLayoutObject()->SetSelectionStateIfNeeded(SelectionState::kEnd);
217 } 234 }
218 235
219 LayoutObject* const stop = 236 for (LayoutObject* runner : range) {
220 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset());
221 for (LayoutObject* runner = range.StartLayoutObject();
222 runner && runner != stop; runner = runner->NextInPreOrder()) {
223 if (runner != range.StartLayoutObject() && 237 if (runner != range.StartLayoutObject() &&
224 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf()) 238 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf())
225 runner->SetSelectionStateIfNeeded(SelectionState::kInside); 239 runner->SetSelectionStateIfNeeded(SelectionState::kInside);
226 } 240 }
227 } 241 }
228 242
229 // Set SetSelectionState and ShouldInvalidateSelection flag of LayoutObjects 243 // Set SetSelectionState and ShouldInvalidateSelection flag of LayoutObjects
230 // comparing them in |new_range| and |old_range|. 244 // comparing them in |new_range| and |old_range|.
231 static void UpdateLayoutObjectState(const SelectionPaintRange& new_range, 245 static void UpdateLayoutObjectState(const SelectionPaintRange& new_range,
232 const SelectionPaintRange& old_range) { 246 const SelectionPaintRange& old_range) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 // invalidations. 311 // invalidations.
298 DisableCompositingQueryAsserts disabler; 312 DisableCompositingQueryAsserts disabler;
299 313
300 // Just return if the selection is already empty. 314 // Just return if the selection is already empty.
301 if (paint_range_.IsNull()) 315 if (paint_range_.IsNull())
302 return; 316 return;
303 317
304 const SelectedMap& old_selected_map = CollectSelectedMap( 318 const SelectedMap& old_selected_map = CollectSelectedMap(
305 paint_range_, CollectSelectedMapOption::kNotCollectBlock); 319 paint_range_, CollectSelectedMapOption::kNotCollectBlock);
306 // Clear SelectionState and invalidation. 320 // Clear SelectionState and invalidation.
321 // TODO(yoichio): Iterate with *this directrly.
307 for (auto layout_object : old_selected_map.object_map.Keys()) { 322 for (auto layout_object : old_selected_map.object_map.Keys()) {
308 const SelectionState old_state = layout_object->GetSelectionState(); 323 const SelectionState old_state = layout_object->GetSelectionState();
309 layout_object->SetSelectionStateIfNeeded(SelectionState::kNone); 324 layout_object->SetSelectionStateIfNeeded(SelectionState::kNone);
310 if (layout_object->GetSelectionState() == old_state) 325 if (layout_object->GetSelectionState() == old_state)
311 continue; 326 continue;
312 layout_object->SetShouldInvalidateSelection(); 327 layout_object->SetShouldInvalidateSelection();
313 } 328 }
314 329
315 // Reset selection. 330 // Reset selection.
316 paint_range_ = SelectionPaintRange(); 331 paint_range_ = SelectionPaintRange();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 // Now create a single bounding box rect that encloses the whole selection. 418 // Now create a single bounding box rect that encloses the whole selection.
404 LayoutRect sel_rect; 419 LayoutRect sel_rect;
405 420
406 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet; 421 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet;
407 VisitedContainingBlockSet visited_containing_blocks; 422 VisitedContainingBlockSet visited_containing_blocks;
408 423
409 Commit(); 424 Commit();
410 if (paint_range_.IsNull()) 425 if (paint_range_.IsNull())
411 return IntRect(); 426 return IntRect();
412 427
413 LayoutObject* os = paint_range_.StartLayoutObject(); 428 // TODO(yoichio): Use CollectSelectedMap.
414 LayoutObject* stop = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(), 429 for (LayoutObject* runner : paint_range_) {
415 paint_range_.EndOffset()); 430 if (runner->GetSelectionState() == SelectionState::kNone)
416 while (os && os != stop) { 431 continue;
417 if ((os->CanBeSelectionLeaf() || os == paint_range_.StartLayoutObject() || 432
418 os == paint_range_.EndLayoutObject()) && 433 // Blocks are responsible for painting line gaps and margin gaps. They
419 os->GetSelectionState() != SelectionState::kNone) { 434 // must be examined as well.
420 // Blocks are responsible for painting line gaps and margin gaps. They 435 sel_rect.Unite(SelectionRectForLayoutObject(runner));
421 // must be examined as well. 436 const LayoutBlock* cb = runner->ContainingBlock();
422 sel_rect.Unite(SelectionRectForLayoutObject(os)); 437 while (cb && !cb->IsLayoutView()) {
yosin_UTC9 2017/06/12 06:37:36 Let's use for-statement. s/cb/block/ or s/cb/block
yoichio 2017/06/12 06:45:44 I will use CollectSelectedMap and remove these lin
423 const LayoutBlock* cb = os->ContainingBlock(); 438 sel_rect.Unite(SelectionRectForLayoutObject(cb));
424 while (cb && !cb->IsLayoutView()) { 439 VisitedContainingBlockSet::AddResult add_result =
425 sel_rect.Unite(SelectionRectForLayoutObject(cb)); 440 visited_containing_blocks.insert(cb);
426 VisitedContainingBlockSet::AddResult add_result = 441 if (!add_result.is_new_entry)
427 visited_containing_blocks.insert(cb); 442 break;
428 if (!add_result.is_new_entry) 443 cb = cb->ContainingBlock();
429 break;
430 cb = cb->ContainingBlock();
431 }
432 } 444 }
433
434 os = os->NextInPreOrder();
435 } 445 }
436 446
437 return PixelSnappedIntRect(sel_rect); 447 return PixelSnappedIntRect(sel_rect);
438 } 448 }
439 449
440 void LayoutSelection::InvalidatePaintForSelection() { 450 void LayoutSelection::InvalidatePaintForSelection() {
441 if (paint_range_.IsNull()) 451 if (paint_range_.IsNull())
442 return; 452 return;
443 453
444 LayoutObject* end = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(), 454 for (LayoutObject* runner : paint_range_) {
445 paint_range_.EndOffset()); 455 if (runner->GetSelectionState() == SelectionState::kNone)
446 for (LayoutObject* o = paint_range_.StartLayoutObject(); o && o != end;
447 o = o->NextInPreOrder()) {
448 if (!o->CanBeSelectionLeaf() && o != paint_range_.StartLayoutObject() &&
449 o != paint_range_.EndLayoutObject())
450 continue;
451 if (o->GetSelectionState() == SelectionState::kNone)
452 continue; 456 continue;
453 457
454 o->SetShouldInvalidateSelection(); 458 runner->SetShouldInvalidateSelection();
455 } 459 }
456 } 460 }
457 461
458 DEFINE_TRACE(LayoutSelection) { 462 DEFINE_TRACE(LayoutSelection) {
459 visitor->Trace(frame_selection_); 463 visitor->Trace(frame_selection_);
460 } 464 }
461 465
462 } // namespace blink 466 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/LayoutSelection.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698