| 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 reserv
ed. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 | 745 |
| 746 void LayoutView::setSelection(const FrameSelection& selection) | 746 void LayoutView::setSelection(const FrameSelection& selection) |
| 747 { | 747 { |
| 748 // No need to create a pending clearSelection() to be executed in PendingSel
ection::commit() | 748 // No need to create a pending clearSelection() to be executed in PendingSel
ection::commit() |
| 749 // if there's no selection, since it's no-op. This is a frequent code path w
orth to optimize. | 749 // if there's no selection, since it's no-op. This is a frequent code path w
orth to optimize. |
| 750 if (selection.isNone() && !m_selectionStart && !m_selectionEnd && !hasPendin
gSelection()) | 750 if (selection.isNone() && !m_selectionStart && !m_selectionEnd && !hasPendin
gSelection()) |
| 751 return; | 751 return; |
| 752 m_pendingSelection->setSelection(selection); | 752 m_pendingSelection->setSelection(selection); |
| 753 } | 753 } |
| 754 | 754 |
| 755 void LayoutView::commitPendingSelection() | 755 template <typename Strategy> |
| 756 void LayoutView::commitPendingSelectionAlgorithm() |
| 756 { | 757 { |
| 758 using PositionType = typename Strategy::PositionType; |
| 759 |
| 757 if (!hasPendingSelection()) | 760 if (!hasPendingSelection()) |
| 758 return; | 761 return; |
| 759 ASSERT(!needsLayout()); | 762 ASSERT(!needsLayout()); |
| 760 | 763 |
| 761 // Skip if pending VisibilePositions became invalid before we reach here. | 764 // Skip if pending VisibilePositions became invalid before we reach here. |
| 762 if (!m_pendingSelection->isInDocument(document())) { | 765 if (!m_pendingSelection->isInDocument(document())) { |
| 763 m_pendingSelection->clear(); | 766 m_pendingSelection->clear(); |
| 764 return; | 767 return; |
| 765 } | 768 } |
| 766 | 769 |
| 767 // Construct a new VisibleSolution, since m_selection is not necessarily val
id, and the following steps | 770 // Construct a new VisibleSolution, since m_selection is not necessarily val
id, and the following steps |
| 768 // assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69
563> and <rdar://problem/10232866>. | 771 // assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69
563> and <rdar://problem/10232866>. |
| 769 VisibleSelection selection = m_pendingSelection->calcVisibleSelection(); | 772 VisibleSelection selection = m_pendingSelection->calcVisibleSelection(); |
| 770 m_pendingSelection->clear(); | 773 m_pendingSelection->clear(); |
| 771 | 774 |
| 772 if (!selection.isRange()) { | 775 if (!selection.isRange()) { |
| 773 clearSelection(); | 776 clearSelection(); |
| 774 return; | 777 return; |
| 775 } | 778 } |
| 776 | 779 |
| 777 // Use the rightmost candidate for the start of the selection, and the leftm
ost candidate for the end of the selection. | 780 // Use the rightmost candidate for the start of the selection, and the leftm
ost candidate for the end of the selection. |
| 778 // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', an
d that 'bar' is selected. If we pass [foo, 3] | 781 // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', an
d that 'bar' is selected. If we pass [foo, 3] |
| 779 // as the start of the selection, the selection painting code will think tha
t content on the line containing 'foo' is selected | 782 // as the start of the selection, the selection painting code will think tha
t content on the line containing 'foo' is selected |
| 780 // and will fill the gap before 'bar'. | 783 // and will fill the gap before 'bar'. |
| 781 Position startPos = selection.start(); | 784 PositionType startPos = Strategy::selectionStart(selection); |
| 782 Position candidate = startPos.downstream(); | 785 PositionType candidate = startPos.downstream(); |
| 783 if (candidate.isCandidate()) | 786 if (candidate.isCandidate()) |
| 784 startPos = candidate; | 787 startPos = candidate; |
| 785 Position endPos = selection.end(); | 788 PositionType endPos = Strategy::selectionEnd(selection); |
| 786 candidate = endPos.upstream(); | 789 candidate = endPos.upstream(); |
| 787 if (candidate.isCandidate()) | 790 if (candidate.isCandidate()) |
| 788 endPos = candidate; | 791 endPos = candidate; |
| 789 | 792 |
| 790 // We can get into a state where the selection endpoints map to the same Vis
iblePosition when a selection is deleted | 793 // We can get into a state where the selection endpoints map to the same Vis
iblePosition when a selection is deleted |
| 791 // because we don't yet notify the FrameSelection of text removal. | 794 // because we don't yet notify the FrameSelection of text removal. |
| 792 if (startPos.isNull() || endPos.isNull() || selection.visibleStart() == sele
ction.visibleEnd()) | 795 if (startPos.isNull() || endPos.isNull() || Strategy::selectionVisibleStart(
selection) == Strategy::selectionVisibleEnd(selection)) |
| 793 return; | 796 return; |
| 794 LayoutObject* startLayoutObject = startPos.anchorNode()->layoutObject(); | 797 LayoutObject* startLayoutObject = startPos.anchorNode()->layoutObject(); |
| 795 LayoutObject* endLayoutObject = endPos.anchorNode()->layoutObject(); | 798 LayoutObject* endLayoutObject = endPos.anchorNode()->layoutObject(); |
| 796 if (!startLayoutObject || !endLayoutObject) | 799 if (!startLayoutObject || !endLayoutObject) |
| 797 return; | 800 return; |
| 798 ASSERT(startLayoutObject->view() == this && endLayoutObject->view() == this)
; | 801 ASSERT(startLayoutObject->view() == this && endLayoutObject->view() == this)
; |
| 799 setSelection(startLayoutObject, startPos.deprecatedEditingOffset(), endLayou
tObject, endPos.deprecatedEditingOffset()); | 802 setSelection(startLayoutObject, startPos.deprecatedEditingOffset(), endLayou
tObject, endPos.deprecatedEditingOffset()); |
| 800 } | 803 } |
| 801 | 804 |
| 805 void LayoutView::commitPendingSelection() |
| 806 { |
| 807 commitPendingSelectionAlgorithm<VisibleSelection::InDOMTree>(); |
| 808 } |
| 809 |
| 802 LayoutObject* LayoutView::selectionStart() | 810 LayoutObject* LayoutView::selectionStart() |
| 803 { | 811 { |
| 804 commitPendingSelection(); | 812 commitPendingSelection(); |
| 805 return m_selectionStart; | 813 return m_selectionStart; |
| 806 } | 814 } |
| 807 | 815 |
| 808 LayoutObject* LayoutView::selectionEnd() | 816 LayoutObject* LayoutView::selectionEnd() |
| 809 { | 817 { |
| 810 commitPendingSelection(); | 818 commitPendingSelection(); |
| 811 return m_selectionEnd; | 819 return m_selectionEnd; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 return viewHeight(IncludeScrollbars) / scale; | 970 return viewHeight(IncludeScrollbars) / scale; |
| 963 } | 971 } |
| 964 | 972 |
| 965 void LayoutView::willBeDestroyed() | 973 void LayoutView::willBeDestroyed() |
| 966 { | 974 { |
| 967 LayoutBlockFlow::willBeDestroyed(); | 975 LayoutBlockFlow::willBeDestroyed(); |
| 968 m_compositor.clear(); | 976 m_compositor.clear(); |
| 969 } | 977 } |
| 970 | 978 |
| 971 } // namespace blink | 979 } // namespace blink |
| OLD | NEW |