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. 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 |