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

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

Issue 2901263002: Introduce SelectionPaintRange in LayoutSelection (Closed)
Patch Set: Introduce IsNull() 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
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 14 matching lines...) Expand all
25 #include "core/editing/EditingUtilities.h" 25 #include "core/editing/EditingUtilities.h"
26 #include "core/editing/FrameSelection.h" 26 #include "core/editing/FrameSelection.h"
27 #include "core/editing/VisiblePosition.h" 27 #include "core/editing/VisiblePosition.h"
28 #include "core/editing/VisibleUnits.h" 28 #include "core/editing/VisibleUnits.h"
29 #include "core/html/TextControlElement.h" 29 #include "core/html/TextControlElement.h"
30 #include "core/layout/LayoutView.h" 30 #include "core/layout/LayoutView.h"
31 #include "core/paint/PaintLayer.h" 31 #include "core/paint/PaintLayer.h"
32 32
33 namespace blink { 33 namespace blink {
34 34
35 SelectionPaintRange::SelectionPaintRange(LayoutObject* start_layout_object,
36 int start_offset,
37 LayoutObject* end_layout_object,
38 int end_offset)
39 : start_layout_object_(start_layout_object),
40 start_offset_(start_offset),
41 end_layout_object_(end_layout_object),
42 end_offset_(end_offset) {
43 DCHECK(start_layout_object_);
44 DCHECK(end_layout_object_);
45 if (start_layout_object_ == end_layout_object_)
yosin_UTC9 2017/05/25 04:29:15 nit: early-return style is better.
yoichio 2017/05/25 08:29:03 Done.
46 DCHECK_LT(start_offset_, end_offset_);
47 }
48
49 bool SelectionPaintRange::operator==(const SelectionPaintRange& other) const {
50 return start_layout_object_ == other.start_layout_object_ &&
51 start_offset_ == other.start_offset_ &&
52 end_layout_object_ == other.end_layout_object_ &&
53 end_offset_ == other.end_offset_;
54 }
55
56 LayoutObject* SelectionPaintRange::StartLayoutObject() const {
57 DCHECK(!IsNull());
58 return start_layout_object_;
59 }
60
61 int SelectionPaintRange::StartOffset() const {
62 DCHECK(!IsNull());
63 return start_offset_;
64 }
65
66 LayoutObject* SelectionPaintRange::EndLayoutObject() const {
67 DCHECK(!IsNull());
68 return end_layout_object_;
69 }
70
71 int SelectionPaintRange::EndOffset() const {
72 DCHECK(!IsNull());
73 return end_offset_;
74 }
75
35 LayoutSelection::LayoutSelection(FrameSelection& frame_selection) 76 LayoutSelection::LayoutSelection(FrameSelection& frame_selection)
36 : frame_selection_(&frame_selection), 77 : frame_selection_(&frame_selection),
37 has_pending_selection_(false), 78 has_pending_selection_(false),
38 selection_start_(nullptr), 79 paint_range_(SelectionPaintRange()) {}
39 selection_end_(nullptr),
40 selection_start_pos_(-1),
41 selection_end_pos_(-1) {}
42 80
43 SelectionInFlatTree LayoutSelection::CalcVisibleSelection( 81 SelectionInFlatTree LayoutSelection::CalcVisibleSelection(
44 const VisibleSelectionInFlatTree& original_selection) const { 82 const VisibleSelectionInFlatTree& original_selection) const {
45 const PositionInFlatTree& start = original_selection.Start(); 83 const PositionInFlatTree& start = original_selection.Start();
46 const PositionInFlatTree& end = original_selection.end(); 84 const PositionInFlatTree& end = original_selection.end();
47 SelectionType selection_type = original_selection.GetSelectionType(); 85 SelectionType selection_type = original_selection.GetSelectionType();
48 const TextAffinity affinity = original_selection.Affinity(); 86 const TextAffinity affinity = original_selection.Affinity();
49 87
50 bool paint_block_cursor = 88 bool paint_block_cursor =
51 frame_selection_->ShouldShowBlockCursor() && 89 frame_selection_->ShouldShowBlockCursor() &&
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 SelectedMap(SelectedMap&& other) { 155 SelectedMap(SelectedMap&& other) {
118 object_map = std::move(other.object_map); 156 object_map = std::move(other.object_map);
119 block_map = std::move(other.block_map); 157 block_map = std::move(other.block_map);
120 } 158 }
121 159
122 private: 160 private:
123 DISALLOW_COPY_AND_ASSIGN(SelectedMap); 161 DISALLOW_COPY_AND_ASSIGN(SelectedMap);
124 }; 162 };
125 163
126 static SelectedMap CollectSelectedMap( 164 static SelectedMap CollectSelectedMap(
127 LayoutObject* selection_start, 165 const SelectionPaintRange& range,
128 LayoutObject* selection_end,
129 int selection_end_pos,
130 LayoutSelection::SelectionPaintInvalidationMode 166 LayoutSelection::SelectionPaintInvalidationMode
131 block_paint_invalidation_mode) { 167 block_paint_invalidation_mode) {
168 DCHECK(!range.IsNull());
132 SelectedMap selected_map; 169 SelectedMap selected_map;
133 170
134 LayoutObject* const stop = 171 LayoutObject* const stop =
135 LayoutObjectAfterPosition(selection_end, selection_end_pos); 172 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset());
136 for (LayoutObject* runner = selection_start; runner && (runner != stop); 173 for (LayoutObject* runner = range.StartLayoutObject();
137 runner = runner->NextInPreOrder()) { 174 runner && (runner != stop); runner = runner->NextInPreOrder()) {
138 if (!runner->CanBeSelectionLeaf() && runner != selection_start && 175 if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() &&
139 runner != selection_end) 176 runner != range.EndLayoutObject())
140 continue; 177 continue;
141 if (runner->GetSelectionState() == SelectionNone) 178 if (runner->GetSelectionState() == SelectionNone)
142 continue; 179 continue;
143 180
144 // Blocks are responsible for painting line gaps and margin gaps. They 181 // Blocks are responsible for painting line gaps and margin gaps. They
145 // must be examined as well. 182 // must be examined as well.
146 selected_map.object_map.Set(runner, runner->GetSelectionState()); 183 selected_map.object_map.Set(runner, runner->GetSelectionState());
147 if (block_paint_invalidation_mode == 184 if (block_paint_invalidation_mode ==
148 LayoutSelection::kPaintInvalidationNewXOROld) { 185 LayoutSelection::kPaintInvalidationNewXOROld) {
149 LayoutBlock* containing_block = runner->ContainingBlock(); 186 LayoutBlock* containing_block = runner->ContainingBlock();
150 while (containing_block && !containing_block->IsLayoutView()) { 187 while (containing_block && !containing_block->IsLayoutView()) {
151 SelectedBlockMap::AddResult result = selected_map.block_map.insert( 188 SelectedBlockMap::AddResult result = selected_map.block_map.insert(
152 containing_block, containing_block->GetSelectionState()); 189 containing_block, containing_block->GetSelectionState());
153 if (!result.is_new_entry) 190 if (!result.is_new_entry)
154 break; 191 break;
155 containing_block = containing_block->ContainingBlock(); 192 containing_block = containing_block->ContainingBlock();
156 } 193 }
157 } 194 }
158 } 195 }
159 return selected_map; 196 return selected_map;
160 } 197 }
161 198
162 // Update the selection status of all LayoutObjects between |start| and |end|. 199 // Update the selection status of all LayoutObjects between |start| and |end|.
163 static void SetSelectionState(LayoutObject* start, 200 static void SetSelectionState(const SelectionPaintRange& range) {
164 LayoutObject* end, 201 DCHECK(!range.IsNull());
165 int end_pos) { 202 if (range.StartLayoutObject() == range.EndLayoutObject()) {
166 if (start && start == end) { 203 range.StartLayoutObject()->SetSelectionStateIfNeeded(SelectionBoth);
167 start->SetSelectionStateIfNeeded(SelectionBoth);
168 } else { 204 } else {
169 if (start) 205 range.StartLayoutObject()->SetSelectionStateIfNeeded(SelectionStart);
170 start->SetSelectionStateIfNeeded(SelectionStart); 206 range.EndLayoutObject()->SetSelectionStateIfNeeded(SelectionEnd);
171 if (end)
172 end->SetSelectionStateIfNeeded(SelectionEnd);
173 } 207 }
174 208
175 LayoutObject* const stop = LayoutObjectAfterPosition(end, end_pos); 209 LayoutObject* const stop =
176 for (LayoutObject* runner = start; runner && runner != stop; 210 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset());
177 runner = runner->NextInPreOrder()) { 211 for (LayoutObject* runner = range.StartLayoutObject();
178 if (runner != start && runner != end && runner->CanBeSelectionLeaf()) 212 runner && runner != stop; runner = runner->NextInPreOrder()) {
213 if (runner != range.StartLayoutObject() &&
yosin_UTC9 2017/05/25 04:29:16 We have a pattern her: L213 runner != range.start
yoichio 2017/05/25 08:29:03 Acknowledged.
yosin_UTC9 2017/05/25 09:40:31 What do you mean "Acknowledged"? I would like to i
214 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf())
179 runner->SetSelectionStateIfNeeded(SelectionInside); 215 runner->SetSelectionStateIfNeeded(SelectionInside);
180 } 216 }
181 } 217 }
182 218
183 void LayoutSelection::SetSelection( 219 void LayoutSelection::SetSelection(
184 LayoutObject* start, 220 const SelectionPaintRange& new_range,
185 int start_pos,
186 LayoutObject* end,
187 int end_pos,
188 SelectionPaintInvalidationMode block_paint_invalidation_mode) { 221 SelectionPaintInvalidationMode block_paint_invalidation_mode) {
189 DCHECK(start); 222 DCHECK(!new_range.IsNull());
190 DCHECK(end);
191 223
192 // Just return if the selection hasn't changed. 224 // Just return if the selection hasn't changed.
193 if (selection_start_ == start && selection_start_pos_ == start_pos && 225 if (paint_range_ == new_range)
194 selection_end_ == end && selection_end_pos_ == end_pos)
195 return; 226 return;
196 227
197 DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView()); 228 DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView());
198 DCHECK(!frame_selection_->GetDocument().NeedsLayoutTreeUpdate()); 229 DCHECK(!frame_selection_->GetDocument().NeedsLayoutTreeUpdate());
199 230
200 SelectedMap old_selected_map = 231 SelectedMap old_selected_map =
201 CollectSelectedMap(selection_start_, selection_end_, selection_end_pos_, 232 CollectSelectedMap(paint_range_, block_paint_invalidation_mode);
202 block_paint_invalidation_mode);
203 233
204 // Now clear the selection. 234 // Now clear the selection.
205 for (auto layout_object : old_selected_map.object_map.Keys()) 235 for (auto layout_object : old_selected_map.object_map.Keys())
206 layout_object->SetSelectionStateIfNeeded(SelectionNone); 236 layout_object->SetSelectionStateIfNeeded(SelectionNone);
207 237
208 SetSelectionState(start, end, end_pos); 238 SetSelectionState(new_range);
209 239
210 // Now that the selection state has been updated for the new objects, walk 240 // Now that the selection state has been updated for the new objects, walk
211 // them again and put them in the new objects list. 241 // them again and put them in the new objects list.
212 // TODO(editing-dev): |new_selected_map| doesn't really need to store the 242 // TODO(editing-dev): |new_selected_map| doesn't really need to store the
213 // SelectionState, it's just more convenient to have it use the same data 243 // SelectionState, it's just more convenient to have it use the same data
214 // structure as |old_selected_map|. 244 // structure as |old_selected_map|.
215 SelectedMap new_selected_map = 245 SelectedMap new_selected_map =
216 CollectSelectedMap(start, end, end_pos, kPaintInvalidationNewXOROld); 246 CollectSelectedMap(new_range, kPaintInvalidationNewXOROld);
217 247
218 // Have any of the old selected objects changed compared to the new selection? 248 // Have any of the old selected objects changed compared to the new selection?
219 for (const auto& pair : old_selected_map.object_map) { 249 for (const auto& pair : old_selected_map.object_map) {
220 LayoutObject* obj = pair.key; 250 LayoutObject* obj = pair.key;
221 SelectionState new_selection_state = obj->GetSelectionState(); 251 SelectionState new_selection_state = obj->GetSelectionState();
222 SelectionState old_selection_state = pair.value; 252 SelectionState old_selection_state = pair.value;
223 if (new_selection_state != old_selection_state || 253 if (new_selection_state != old_selection_state ||
224 (start == obj && start_pos != selection_start_pos_) || 254 (new_range.StartLayoutObject() == obj &&
225 (end == obj && end_pos != selection_end_pos_)) { 255 new_range.StartOffset() != paint_range_.StartOffset()) ||
256 (new_range.EndLayoutObject() == obj &&
257 new_range.EndOffset() != paint_range_.EndOffset())) {
226 obj->SetShouldInvalidateSelection(); 258 obj->SetShouldInvalidateSelection();
227 new_selected_map.object_map.erase(obj); 259 new_selected_map.object_map.erase(obj);
228 } 260 }
229 } 261 }
230 262
231 // Any new objects that remain were not found in the old objects dict, and so 263 // Any new objects that remain were not found in the old objects dict, and so
232 // they need to be updated. 264 // they need to be updated.
233 for (auto layout_object : new_selected_map.object_map.Keys()) 265 for (auto layout_object : new_selected_map.object_map.Keys())
234 layout_object->SetShouldInvalidateSelection(); 266 layout_object->SetShouldInvalidateSelection();
235 267
236 // Have any of the old blocks changed? 268 // Have any of the old blocks changed?
237 for (const auto& pair : old_selected_map.block_map) { 269 for (const auto& pair : old_selected_map.block_map) {
238 LayoutBlock* block = pair.key; 270 LayoutBlock* block = pair.key;
239 SelectionState new_selection_state = block->GetSelectionState(); 271 SelectionState new_selection_state = block->GetSelectionState();
240 SelectionState old_selection_state = pair.value; 272 SelectionState old_selection_state = pair.value;
241 if (new_selection_state != old_selection_state) { 273 if (new_selection_state != old_selection_state) {
242 block->SetShouldInvalidateSelection(); 274 block->SetShouldInvalidateSelection();
243 new_selected_map.block_map.erase(block); 275 new_selected_map.block_map.erase(block);
244 } 276 }
245 } 277 }
246 278
247 // Any new blocks that remain were not found in the old blocks dict, and so 279 // Any new blocks that remain were not found in the old blocks dict, and so
248 // they need to be updated. 280 // they need to be updated.
249 for (auto layout_object : new_selected_map.block_map.Keys()) 281 for (auto layout_object : new_selected_map.block_map.Keys())
250 layout_object->SetShouldInvalidateSelection(); 282 layout_object->SetShouldInvalidateSelection();
251 283
252 // set selection start and end 284 paint_range_ = new_range;
253 selection_start_ = start;
254 selection_start_pos_ = start_pos;
255 selection_end_ = end;
256 selection_end_pos_ = end_pos;
257 } 285 }
258 286
259 std::pair<int, int> LayoutSelection::SelectionStartEnd() { 287 std::pair<int, int> LayoutSelection::SelectionStartEnd() {
260 Commit(); 288 Commit();
261 return std::make_pair(selection_start_pos_, selection_end_pos_); 289 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset());
262 } 290 }
263 291
264 void LayoutSelection::ClearSelection() { 292 void LayoutSelection::ClearSelection() {
265 // For querying Layer::compositingState() 293 // For querying Layer::compositingState()
266 // This is correct, since destroying layout objects needs to cause eager paint 294 // This is correct, since destroying layout objects needs to cause eager paint
267 // invalidations. 295 // invalidations.
268 DisableCompositingQueryAsserts disabler; 296 DisableCompositingQueryAsserts disabler;
269 297
270 // Just return if the selection hasn't changed. 298 // Just return if the selection is already empty.
271 if (!selection_start_) { 299 if (paint_range_.IsNull())
272 DCHECK_EQ(selection_end_, nullptr);
273 DCHECK_EQ(selection_start_pos_, -1);
274 DCHECK_EQ(selection_end_pos_, -1);
275 return; 300 return;
276 }
277 301
278 const SelectedMap& old_selected_map = 302 const SelectedMap& old_selected_map =
279 CollectSelectedMap(selection_start_, selection_end_, selection_end_pos_, 303 CollectSelectedMap(paint_range_, kPaintInvalidationNewMinusOld);
280 kPaintInvalidationNewMinusOld);
281 // Clear SelectionState and invalidation. 304 // Clear SelectionState and invalidation.
282 for (auto layout_object : old_selected_map.object_map.Keys()) { 305 for (auto layout_object : old_selected_map.object_map.Keys()) {
283 const SelectionState old_state = layout_object->GetSelectionState(); 306 const SelectionState old_state = layout_object->GetSelectionState();
284 layout_object->SetSelectionStateIfNeeded(SelectionNone); 307 layout_object->SetSelectionStateIfNeeded(SelectionNone);
285 if (layout_object->GetSelectionState() == old_state) 308 if (layout_object->GetSelectionState() == old_state)
286 continue; 309 continue;
287 layout_object->SetShouldInvalidateSelection(); 310 layout_object->SetShouldInvalidateSelection();
288 } 311 }
289 312
290 // Reset selection start and end. 313 // Reset selection.
291 selection_start_ = nullptr; 314 paint_range_ = SelectionPaintRange();
292 selection_start_pos_ = -1;
293 selection_end_ = nullptr;
294 selection_end_pos_ = -1;
295 } 315 }
296 316
297 void LayoutSelection::Commit() { 317 void LayoutSelection::Commit() {
298 if (!HasPendingSelection()) 318 if (!HasPendingSelection())
299 return; 319 return;
300 has_pending_selection_ = false; 320 has_pending_selection_ = false;
301 321
302 const VisibleSelectionInFlatTree& original_selection = 322 const VisibleSelectionInFlatTree& original_selection =
303 frame_selection_->ComputeVisibleSelectionInFlatTree(); 323 frame_selection_->ComputeVisibleSelectionInFlatTree();
304 324
(...skipping 30 matching lines...) Expand all
335 if (start_pos.IsNull() || end_pos.IsNull() || 355 if (start_pos.IsNull() || end_pos.IsNull() ||
336 selection.VisibleStart().DeepEquivalent() == 356 selection.VisibleStart().DeepEquivalent() ==
337 selection.VisibleEnd().DeepEquivalent()) 357 selection.VisibleEnd().DeepEquivalent())
338 return; 358 return;
339 DCHECK_LE(start_pos, end_pos); 359 DCHECK_LE(start_pos, end_pos);
340 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); 360 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject();
341 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); 361 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject();
342 if (!start_layout_object || !end_layout_object) 362 if (!start_layout_object || !end_layout_object)
343 return; 363 return;
344 DCHECK(start_layout_object->View() == end_layout_object->View()); 364 DCHECK(start_layout_object->View() == end_layout_object->View());
345 SetSelection(start_layout_object, start_pos.ComputeEditingOffset(), 365 SetSelection(
346 end_layout_object, end_pos.ComputeEditingOffset()); 366 SelectionPaintRange(start_layout_object, start_pos.ComputeEditingOffset(),
367 end_layout_object, end_pos.ComputeEditingOffset()));
347 } 368 }
348 369
349 void LayoutSelection::OnDocumentShutdown() { 370 void LayoutSelection::OnDocumentShutdown() {
350 has_pending_selection_ = false; 371 has_pending_selection_ = false;
351 selection_start_ = nullptr; 372 paint_range_ = SelectionPaintRange();
352 selection_end_ = nullptr;
353 selection_start_pos_ = -1;
354 selection_end_pos_ = -1;
355 } 373 }
356 374
357 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { 375 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) {
358 if (!object->IsRooted()) 376 if (!object->IsRooted())
359 return LayoutRect(); 377 return LayoutRect();
360 378
361 if (!object->CanUpdateSelectionOnRootLineBoxes()) 379 if (!object->CanUpdateSelectionOnRootLineBoxes())
362 return LayoutRect(); 380 return LayoutRect();
363 381
364 return object->SelectionRectInViewCoordinates(); 382 return object->SelectionRectInViewCoordinates();
365 } 383 }
366 384
367 IntRect LayoutSelection::SelectionBounds() { 385 IntRect LayoutSelection::SelectionBounds() {
368 // Now create a single bounding box rect that encloses the whole selection. 386 // Now create a single bounding box rect that encloses the whole selection.
369 LayoutRect sel_rect; 387 LayoutRect sel_rect;
370 388
371 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet; 389 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet;
372 VisitedContainingBlockSet visited_containing_blocks; 390 VisitedContainingBlockSet visited_containing_blocks;
373 391
374 Commit(); 392 Commit();
375 LayoutObject* os = selection_start_; 393 LayoutObject* os = paint_range_.StartLayoutObject();
376 LayoutObject* stop = 394 LayoutObject* stop = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(),
377 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); 395 paint_range_.EndOffset());
378 while (os && os != stop) { 396 while (os && os != stop) {
yosin_UTC9 2017/05/25 04:29:16 Note: We can rewrite this while-statement to for-s
yoichio 2017/05/25 08:29:03 Acknowledged.
yosin_UTC9 2017/05/25 09:40:31 Since introducing iterator is big. We should do in
379 if ((os->CanBeSelectionLeaf() || os == selection_start_ || 397 if ((os->CanBeSelectionLeaf() || os == paint_range_.StartLayoutObject() ||
380 os == selection_end_) && 398 os == paint_range_.EndLayoutObject()) &&
381 os->GetSelectionState() != SelectionNone) { 399 os->GetSelectionState() != SelectionNone) {
382 // Blocks are responsible for painting line gaps and margin gaps. They 400 // Blocks are responsible for painting line gaps and margin gaps. They
383 // must be examined as well. 401 // must be examined as well.
384 sel_rect.Unite(SelectionRectForLayoutObject(os)); 402 sel_rect.Unite(SelectionRectForLayoutObject(os));
385 const LayoutBlock* cb = os->ContainingBlock(); 403 const LayoutBlock* cb = os->ContainingBlock();
386 while (cb && !cb->IsLayoutView()) { 404 while (cb && !cb->IsLayoutView()) {
387 sel_rect.Unite(SelectionRectForLayoutObject(cb)); 405 sel_rect.Unite(SelectionRectForLayoutObject(cb));
388 VisitedContainingBlockSet::AddResult add_result = 406 VisitedContainingBlockSet::AddResult add_result =
389 visited_containing_blocks.insert(cb); 407 visited_containing_blocks.insert(cb);
390 if (!add_result.is_new_entry) 408 if (!add_result.is_new_entry)
391 break; 409 break;
392 cb = cb->ContainingBlock(); 410 cb = cb->ContainingBlock();
393 } 411 }
394 } 412 }
395 413
396 os = os->NextInPreOrder(); 414 os = os->NextInPreOrder();
397 } 415 }
398 416
399 return PixelSnappedIntRect(sel_rect); 417 return PixelSnappedIntRect(sel_rect);
400 } 418 }
401 419
402 void LayoutSelection::InvalidatePaintForSelection() { 420 void LayoutSelection::InvalidatePaintForSelection() {
403 LayoutObject* end = 421 LayoutObject* end = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(),
404 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); 422 paint_range_.EndOffset());
405 for (LayoutObject* o = selection_start_; o && o != end; 423 for (LayoutObject* o = paint_range_.StartLayoutObject(); o && o != end;
406 o = o->NextInPreOrder()) { 424 o = o->NextInPreOrder()) {
407 if (!o->CanBeSelectionLeaf() && o != selection_start_ && 425 if (!o->CanBeSelectionLeaf() && o != paint_range_.StartLayoutObject() &&
408 o != selection_end_) 426 o != paint_range_.EndLayoutObject())
409 continue; 427 continue;
410 if (o->GetSelectionState() == SelectionNone) 428 if (o->GetSelectionState() == SelectionNone)
411 continue; 429 continue;
412 430
413 o->SetShouldInvalidateSelection(); 431 o->SetShouldInvalidateSelection();
414 } 432 }
415 } 433 }
416 434
417 DEFINE_TRACE(LayoutSelection) { 435 DEFINE_TRACE(LayoutSelection) {
418 visitor->Trace(frame_selection_); 436 visitor->Trace(frame_selection_);
419 } 437 }
420 438
421 } // namespace blink 439 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698