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 27 matching lines...) Expand all Loading... |
38 force_hide_(false), | 38 force_hide_(false), |
39 selection_start_(nullptr), | 39 selection_start_(nullptr), |
40 selection_end_(nullptr), | 40 selection_end_(nullptr), |
41 selection_start_pos_(-1), | 41 selection_start_pos_(-1), |
42 selection_end_pos_(-1) {} | 42 selection_end_pos_(-1) {} |
43 | 43 |
44 const VisibleSelection& LayoutSelection::GetVisibleSelection() const { | 44 const VisibleSelection& LayoutSelection::GetVisibleSelection() const { |
45 return frame_selection_->ComputeVisibleSelectionInDOMTree(); | 45 return frame_selection_->ComputeVisibleSelectionInDOMTree(); |
46 } | 46 } |
47 | 47 |
48 static bool IsSelectionInDocument( | |
49 const VisibleSelectionInFlatTree& visible_selection, | |
50 const Document& document) { | |
51 const PositionInFlatTree& start = visible_selection.Start(); | |
52 if (start.IsNotNull() && | |
53 (!start.IsConnected() || start.GetDocument() != document)) | |
54 return false; | |
55 const PositionInFlatTree& end = visible_selection.end(); | |
56 if (end.IsNotNull() && (!end.IsConnected() || end.GetDocument() != document)) | |
57 return false; | |
58 const PositionInFlatTree extent = visible_selection.Extent(); | |
59 if (extent.IsNotNull() && | |
60 (!extent.IsConnected() || extent.GetDocument() != document)) | |
61 return false; | |
62 return true; | |
63 } | |
64 | |
65 SelectionInFlatTree LayoutSelection::CalcVisibleSelection( | 48 SelectionInFlatTree LayoutSelection::CalcVisibleSelection( |
66 const VisibleSelectionInFlatTree& original_selection) const { | 49 const VisibleSelectionInFlatTree& original_selection) const { |
67 const PositionInFlatTree& start = original_selection.Start(); | 50 const PositionInFlatTree& start = original_selection.Start(); |
68 const PositionInFlatTree& end = original_selection.end(); | 51 const PositionInFlatTree& end = original_selection.end(); |
69 SelectionType selection_type = original_selection.GetSelectionType(); | 52 SelectionType selection_type = original_selection.GetSelectionType(); |
70 const TextAffinity affinity = original_selection.Affinity(); | 53 const TextAffinity affinity = original_selection.Affinity(); |
71 | 54 |
72 bool paint_block_cursor = | 55 bool paint_block_cursor = |
73 frame_selection_->ShouldShowBlockCursor() && | 56 frame_selection_->ShouldShowBlockCursor() && |
74 selection_type == SelectionType::kCaretSelection && | 57 selection_type == SelectionType::kCaretSelection && |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 | 300 |
318 // Any new blocks that remain were not found in the old blocks dict, and so | 301 // Any new blocks that remain were not found in the old blocks dict, and so |
319 // they need to be updated. | 302 // they need to be updated. |
320 SelectedBlockMap::iterator new_blocks_end = new_selected_blocks.end(); | 303 SelectedBlockMap::iterator new_blocks_end = new_selected_blocks.end(); |
321 for (SelectedBlockMap::iterator i = new_selected_blocks.begin(); | 304 for (SelectedBlockMap::iterator i = new_selected_blocks.begin(); |
322 i != new_blocks_end; ++i) | 305 i != new_blocks_end; ++i) |
323 i->key->SetShouldInvalidateSelection(); | 306 i->key->SetShouldInvalidateSelection(); |
324 } | 307 } |
325 | 308 |
326 void LayoutSelection::SelectionStartEnd(int& start_pos, int& end_pos) { | 309 void LayoutSelection::SelectionStartEnd(int& start_pos, int& end_pos) { |
327 Commit(*frame_selection_->GetDocument().GetLayoutView()); | 310 Commit(); |
328 start_pos = selection_start_pos_; | 311 start_pos = selection_start_pos_; |
329 end_pos = selection_end_pos_; | 312 end_pos = selection_end_pos_; |
330 } | 313 } |
331 | 314 |
332 void LayoutSelection::ClearSelection() { | 315 void LayoutSelection::ClearSelection() { |
333 // For querying Layer::compositingState() | 316 // For querying Layer::compositingState() |
334 // This is correct, since destroying layout objects needs to cause eager paint | 317 // This is correct, since destroying layout objects needs to cause eager paint |
335 // invalidations. | 318 // invalidations. |
336 DisableCompositingQueryAsserts disabler; | 319 DisableCompositingQueryAsserts disabler; |
337 | 320 |
338 SetSelection(0, -1, 0, -1, kPaintInvalidationNewMinusOld); | 321 SetSelection(0, -1, 0, -1, kPaintInvalidationNewMinusOld); |
339 } | 322 } |
340 | 323 |
341 void LayoutSelection::SetHasPendingSelection(PaintHint hint) { | 324 void LayoutSelection::SetHasPendingSelection(PaintHint hint) { |
342 has_pending_selection_ = true; | 325 has_pending_selection_ = true; |
343 if (hint == PaintHint::kHide) | 326 if (hint == PaintHint::kHide) |
344 force_hide_ = true; | 327 force_hide_ = true; |
345 else if (hint == PaintHint::kPaint) | 328 else if (hint == PaintHint::kPaint) |
346 force_hide_ = false; | 329 force_hide_ = false; |
347 } | 330 } |
348 | 331 |
349 void LayoutSelection::Commit(LayoutView& layout_view) { | 332 void LayoutSelection::Commit() { |
350 if (!HasPendingSelection()) | 333 if (!HasPendingSelection()) |
351 return; | 334 return; |
352 DCHECK(!layout_view.NeedsLayout()); | |
353 has_pending_selection_ = false; | 335 has_pending_selection_ = false; |
354 | 336 |
355 const VisibleSelectionInFlatTree& original_selection = | 337 const VisibleSelectionInFlatTree& original_selection = |
356 frame_selection_->ComputeVisibleSelectionInFlatTree(); | 338 frame_selection_->ComputeVisibleSelectionInFlatTree(); |
357 | 339 |
358 // Skip if pending VisibilePositions became invalid before we reach here. | |
359 if (!IsSelectionInDocument(original_selection, layout_view.GetDocument())) | |
360 return; | |
361 | |
362 // Construct a new VisibleSolution, since visibleSelection() is not | 340 // Construct a new VisibleSolution, since visibleSelection() is not |
363 // necessarily valid, and the following steps assume a valid selection. See | 341 // necessarily valid, and the following steps assume a valid selection. See |
364 // <https://bugs.webkit.org/show_bug.cgi?id=69563> and | 342 // <https://bugs.webkit.org/show_bug.cgi?id=69563> and |
365 // <rdar://problem/10232866>. | 343 // <rdar://problem/10232866>. |
366 const VisibleSelectionInFlatTree& selection = | 344 const VisibleSelectionInFlatTree& selection = |
367 CreateVisibleSelection(CalcVisibleSelection(original_selection)); | 345 CreateVisibleSelection(CalcVisibleSelection(original_selection)); |
368 | 346 |
369 if (!selection.IsRange() || force_hide_) { | 347 if (!selection.IsRange() || force_hide_) { |
370 ClearSelection(); | 348 ClearSelection(); |
371 return; | 349 return; |
(...skipping 18 matching lines...) Expand all Loading... |
390 // |VisiblePosition| when a selection is deleted because we don't yet notify | 368 // |VisiblePosition| when a selection is deleted because we don't yet notify |
391 // the |FrameSelection| of text removal. | 369 // the |FrameSelection| of text removal. |
392 if (start_pos.IsNull() || end_pos.IsNull() || | 370 if (start_pos.IsNull() || end_pos.IsNull() || |
393 selection.VisibleStart().DeepEquivalent() == | 371 selection.VisibleStart().DeepEquivalent() == |
394 selection.VisibleEnd().DeepEquivalent()) | 372 selection.VisibleEnd().DeepEquivalent()) |
395 return; | 373 return; |
396 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); | 374 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); |
397 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); | 375 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); |
398 if (!start_layout_object || !end_layout_object) | 376 if (!start_layout_object || !end_layout_object) |
399 return; | 377 return; |
400 DCHECK(layout_view == start_layout_object->View()); | 378 DCHECK(start_layout_object->View() == end_layout_object->View()); |
401 DCHECK(layout_view == end_layout_object->View()); | |
402 SetSelection(start_layout_object, start_pos.ComputeEditingOffset(), | 379 SetSelection(start_layout_object, start_pos.ComputeEditingOffset(), |
403 end_layout_object, end_pos.ComputeEditingOffset()); | 380 end_layout_object, end_pos.ComputeEditingOffset()); |
404 } | 381 } |
405 | 382 |
406 void LayoutSelection::OnDocumentShutdown() { | 383 void LayoutSelection::OnDocumentShutdown() { |
407 has_pending_selection_ = false; | 384 has_pending_selection_ = false; |
408 force_hide_ = false; | 385 force_hide_ = false; |
409 selection_start_ = nullptr; | 386 selection_start_ = nullptr; |
410 selection_end_ = nullptr; | 387 selection_end_ = nullptr; |
411 selection_start_pos_ = -1; | 388 selection_start_pos_ = -1; |
(...skipping 10 matching lines...) Expand all Loading... |
422 return object->SelectionRectInViewCoordinates(); | 399 return object->SelectionRectInViewCoordinates(); |
423 } | 400 } |
424 | 401 |
425 IntRect LayoutSelection::SelectionBounds() { | 402 IntRect LayoutSelection::SelectionBounds() { |
426 // Now create a single bounding box rect that encloses the whole selection. | 403 // Now create a single bounding box rect that encloses the whole selection. |
427 LayoutRect sel_rect; | 404 LayoutRect sel_rect; |
428 | 405 |
429 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet; | 406 typedef HashSet<const LayoutBlock*> VisitedContainingBlockSet; |
430 VisitedContainingBlockSet visited_containing_blocks; | 407 VisitedContainingBlockSet visited_containing_blocks; |
431 | 408 |
432 Commit(*frame_selection_->GetDocument().GetLayoutView()); | 409 Commit(); |
433 LayoutObject* os = selection_start_; | 410 LayoutObject* os = selection_start_; |
434 LayoutObject* stop = | 411 LayoutObject* stop = |
435 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); | 412 LayoutObjectAfterPosition(selection_end_, selection_end_pos_); |
436 while (os && os != stop) { | 413 while (os && os != stop) { |
437 if ((os->CanBeSelectionLeaf() || os == selection_start_ || | 414 if ((os->CanBeSelectionLeaf() || os == selection_start_ || |
438 os == selection_end_) && | 415 os == selection_end_) && |
439 os->GetSelectionState() != SelectionNone) { | 416 os->GetSelectionState() != SelectionNone) { |
440 // Blocks are responsible for painting line gaps and margin gaps. They | 417 // Blocks are responsible for painting line gaps and margin gaps. They |
441 // must be examined as well. | 418 // must be examined as well. |
442 sel_rect.Unite(SelectionRectForLayoutObject(os)); | 419 sel_rect.Unite(SelectionRectForLayoutObject(os)); |
(...skipping 27 matching lines...) Expand all Loading... |
470 | 447 |
471 o->SetShouldInvalidateSelection(); | 448 o->SetShouldInvalidateSelection(); |
472 } | 449 } |
473 } | 450 } |
474 | 451 |
475 DEFINE_TRACE(LayoutSelection) { | 452 DEFINE_TRACE(LayoutSelection) { |
476 visitor->Trace(frame_selection_); | 453 visitor->Trace(frame_selection_); |
477 } | 454 } |
478 | 455 |
479 } // namespace blink | 456 } // namespace blink |
OLD | NEW |