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