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. 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |