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