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

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

Issue 2895193002: Cleanup traversing in LayoutSelection.cpp::CollectSelectedMap() (Closed)
Patch Set: Created 3 years, 7 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 | « no previous file | 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 93
94 static LayoutObject* LayoutObjectAfterPosition(LayoutObject* object, 94 static LayoutObject* LayoutObjectAfterPosition(LayoutObject* object,
95 unsigned offset) { 95 unsigned offset) {
96 if (!object) 96 if (!object)
97 return nullptr; 97 return nullptr;
98 98
99 LayoutObject* child = object->ChildAt(offset); 99 LayoutObject* child = object->ChildAt(offset);
100 return child ? child : object->NextInPreOrderAfterChildren(); 100 return child ? child : object->NextInPreOrderAfterChildren();
101 } 101 }
102 102
103 // When exploring the LayoutTree looking for the nodes involved in the
104 // Selection, sometimes it's required to change the traversing direction because
105 // the "start" position is below the "end" one.
yosin_UTC9 2017/05/23 09:01:36 It seems patch[1] introduce backward traversal to
106 static inline LayoutObject* GetNextOrPrevLayoutObjectBasedOnDirection(
107 const LayoutObject* o,
108 const LayoutObject* stop,
109 bool& continue_exploring,
110 bool& exploring_backwards) {
111 LayoutObject* next;
112 if (exploring_backwards) {
113 next = o->PreviousInPreOrder();
114 continue_exploring = next && !(next)->IsLayoutView();
115 } else {
116 next = o->NextInPreOrder();
117 continue_exploring = next && next != stop;
118 exploring_backwards = !next && (next != stop);
119 if (exploring_backwards) {
120 next = stop->PreviousInPreOrder();
121 continue_exploring = next && !next->IsLayoutView();
122 }
123 }
124
125 return next;
126 }
127
128 // Objects each have a single selection rect to examine. 103 // Objects each have a single selection rect to examine.
129 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>; 104 using SelectedObjectMap = HashMap<LayoutObject*, SelectionState>;
130 // Blocks contain selected objects and fill gaps between them, either on the 105 // Blocks contain selected objects and fill gaps between them, either on the
131 // left, right, or in between lines and blocks. 106 // left, right, or in between lines and blocks.
132 // In order to get the visual rect right, we have to examine left, middle, and 107 // In order to get the visual rect right, we have to examine left, middle, and
133 // right rects individually, since otherwise the union of those rects might 108 // right rects individually, since otherwise the union of those rects might
134 // remain the same even when changes have occurred. 109 // remain the same even when changes have occurred.
135 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>; 110 using SelectedBlockMap = HashMap<LayoutBlock*, SelectionState>;
136 struct SelectedMap { 111 struct SelectedMap {
137 STACK_ALLOCATED(); 112 STACK_ALLOCATED();
(...skipping 10 matching lines...) Expand all
148 DISALLOW_COPY_AND_ASSIGN(SelectedMap); 123 DISALLOW_COPY_AND_ASSIGN(SelectedMap);
149 }; 124 };
150 125
151 static SelectedMap CollectSelectedMap( 126 static SelectedMap CollectSelectedMap(
152 LayoutObject* selection_start, 127 LayoutObject* selection_start,
153 LayoutObject* selection_end, 128 LayoutObject* selection_end,
154 int selection_end_pos, 129 int selection_end_pos,
155 LayoutSelection::SelectionPaintInvalidationMode 130 LayoutSelection::SelectionPaintInvalidationMode
156 block_paint_invalidation_mode) { 131 block_paint_invalidation_mode) {
157 SelectedMap selected_map; 132 SelectedMap selected_map;
158 LayoutObject* runner = selection_start; 133
159 LayoutObject* const stop = 134 LayoutObject* const stop =
160 LayoutObjectAfterPosition(selection_end, selection_end_pos); 135 LayoutObjectAfterPosition(selection_end, selection_end_pos);
161 bool exploring_backwards = false; 136 for (LayoutObject* runner = selection_start; runner && (runner != stop);
162 bool continue_exploring = runner && (runner != stop); 137 runner = runner->NextInPreOrder()) {
163 while (continue_exploring) { 138 if (!runner->CanBeSelectionLeaf() && runner != selection_start &&
164 if ((runner->CanBeSelectionLeaf() || runner == selection_start || 139 runner != selection_end)
165 runner == selection_end) && 140 continue;
166 runner->GetSelectionState() != SelectionNone) { 141 if (runner->GetSelectionState() == SelectionNone)
167 // Blocks are responsible for painting line gaps and margin gaps. They 142 continue;
168 // must be examined as well. 143
169 selected_map.object_map.Set(runner, runner->GetSelectionState()); 144 // Blocks are responsible for painting line gaps and margin gaps. They
170 if (block_paint_invalidation_mode == 145 // must be examined as well.
171 LayoutSelection::kPaintInvalidationNewXOROld) { 146 selected_map.object_map.Set(runner, runner->GetSelectionState());
172 LayoutBlock* containing_block = runner->ContainingBlock(); 147 if (block_paint_invalidation_mode ==
173 while (containing_block && !containing_block->IsLayoutView()) { 148 LayoutSelection::kPaintInvalidationNewXOROld) {
174 SelectedBlockMap::AddResult result = selected_map.block_map.insert( 149 LayoutBlock* containing_block = runner->ContainingBlock();
175 containing_block, containing_block->GetSelectionState()); 150 while (containing_block && !containing_block->IsLayoutView()) {
176 if (!result.is_new_entry) 151 SelectedBlockMap::AddResult result = selected_map.block_map.insert(
177 break; 152 containing_block, containing_block->GetSelectionState());
178 containing_block = containing_block->ContainingBlock(); 153 if (!result.is_new_entry)
179 } 154 break;
155 containing_block = containing_block->ContainingBlock();
180 } 156 }
181 } 157 }
182
183 runner = GetNextOrPrevLayoutObjectBasedOnDirection(
184 runner, stop, continue_exploring, exploring_backwards);
185 } 158 }
186 return selected_map; 159 return selected_map;
187 } 160 }
188 161
189 // Update the selection status of all LayoutObjects between |start| and |end|. 162 // Update the selection status of all LayoutObjects between |start| and |end|.
190 static void SetSelectionState(LayoutObject* start, 163 static void SetSelectionState(LayoutObject* start,
191 LayoutObject* end, 164 LayoutObject* end,
192 int end_pos) { 165 int end_pos) {
193 if (start && start == end) { 166 if (start && start == end) {
194 start->SetSelectionStateIfNeeded(SelectionBoth); 167 start->SetSelectionStateIfNeeded(SelectionBoth);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 if (IsVisuallyEquivalentCandidate(candidate)) 312 if (IsVisuallyEquivalentCandidate(candidate))
340 end_pos = candidate; 313 end_pos = candidate;
341 314
342 // We can get into a state where the selection endpoints map to the same 315 // We can get into a state where the selection endpoints map to the same
343 // |VisiblePosition| when a selection is deleted because we don't yet notify 316 // |VisiblePosition| when a selection is deleted because we don't yet notify
344 // the |FrameSelection| of text removal. 317 // the |FrameSelection| of text removal.
345 if (start_pos.IsNull() || end_pos.IsNull() || 318 if (start_pos.IsNull() || end_pos.IsNull() ||
346 selection.VisibleStart().DeepEquivalent() == 319 selection.VisibleStart().DeepEquivalent() ==
347 selection.VisibleEnd().DeepEquivalent()) 320 selection.VisibleEnd().DeepEquivalent())
348 return; 321 return;
322 DCHECK(start_pos <= end_pos);
yosin_UTC9 2017/05/23 09:01:36 nit: DCHECK_LE(start_pos, end_pos)
349 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); 323 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject();
350 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); 324 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject();
351 if (!start_layout_object || !end_layout_object) 325 if (!start_layout_object || !end_layout_object)
352 return; 326 return;
353 DCHECK(start_layout_object->View() == end_layout_object->View()); 327 DCHECK(start_layout_object->View() == end_layout_object->View());
354 SetSelection(start_layout_object, start_pos.ComputeEditingOffset(), 328 SetSelection(start_layout_object, start_pos.ComputeEditingOffset(),
355 end_layout_object, end_pos.ComputeEditingOffset()); 329 end_layout_object, end_pos.ComputeEditingOffset());
356 } 330 }
357 331
358 void LayoutSelection::OnDocumentShutdown() { 332 void LayoutSelection::OnDocumentShutdown() {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 395
422 o->SetShouldInvalidateSelection(); 396 o->SetShouldInvalidateSelection();
423 } 397 }
424 } 398 }
425 399
426 DEFINE_TRACE(LayoutSelection) { 400 DEFINE_TRACE(LayoutSelection) {
427 visitor->Trace(frame_selection_); 401 visitor->Trace(frame_selection_);
428 } 402 }
429 403
430 } // namespace blink 404 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698