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

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

Issue 2691243002: Revert of Make FrameSelection to hold non-canonicalized positions (Closed)
Patch Set: Created 3 years, 10 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) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/editing/SelectionEditor.h" 26 #include "core/editing/SelectionEditor.h"
27 27
28 #include "core/dom/NodeWithIndex.h"
29 #include "core/dom/Text.h"
30 #include "core/editing/EditingUtilities.h" 28 #include "core/editing/EditingUtilities.h"
31 #include "core/editing/Editor.h" 29 #include "core/editing/Editor.h"
32 #include "core/editing/SelectionAdjuster.h" 30 #include "core/editing/SelectionAdjuster.h"
33 #include "core/frame/LocalFrame.h" 31 #include "core/frame/LocalFrame.h"
34 32
35 namespace blink { 33 namespace blink {
36 34
37 SelectionEditor::SelectionEditor(LocalFrame& frame) : m_frame(frame) { 35 SelectionEditor::SelectionEditor(LocalFrame& frame)
36 : m_frame(frame), m_observingVisibleSelection(false) {
38 clearVisibleSelection(); 37 clearVisibleSelection();
39 } 38 }
40 39
41 SelectionEditor::~SelectionEditor() {} 40 SelectionEditor::~SelectionEditor() {}
42 41
43 void SelectionEditor::assertSelectionValid() const {
44 #if DCHECK_IS_ON()
45 // Since We don't track dom tree version during attribute changes, we can't
46 // use it for validity of |m_selection|.
47 const_cast<SelectionEditor*>(this)->m_selection.m_domTreeVersion =
48 document().domTreeVersion();
49 #endif
50 m_selection.assertValidFor(document());
51 }
52
53 void SelectionEditor::clearVisibleSelection() { 42 void SelectionEditor::clearVisibleSelection() {
54 m_selection = SelectionInDOMTree(); 43 m_selection = VisibleSelection();
55 m_cachedVisibleSelectionInDOMTree = VisibleSelection(); 44 m_selectionInFlatTree = VisibleSelectionInFlatTree();
56 m_cachedVisibleSelectionInFlatTree = VisibleSelectionInFlatTree();
57 m_cacheIsDirty = false;
58 if (!shouldAlwaysUseDirectionalSelection()) 45 if (!shouldAlwaysUseDirectionalSelection())
59 return; 46 return;
60 m_selection.m_isDirectional = true; 47 m_selection.setIsDirectional(true);
48 m_selectionInFlatTree.setIsDirectional(true);
61 } 49 }
62 50
63 void SelectionEditor::dispose() { 51 void SelectionEditor::dispose() {
64 resetLogicalRange(); 52 resetLogicalRange();
65 clearDocumentCachedRange(); 53 clearDocumentCachedRange();
66 clearVisibleSelection(); 54 clearVisibleSelection();
67 } 55 }
68 56
69 Document& SelectionEditor::document() const { 57 const Document& SelectionEditor::document() const {
70 DCHECK(lifecycleContext()); 58 DCHECK(m_document);
71 return *lifecycleContext(); 59 return *m_document;
72 } 60 }
73 61
74 template <> 62 template <>
75 const VisibleSelection& SelectionEditor::visibleSelection<EditingStrategy>() 63 const VisibleSelection& SelectionEditor::visibleSelection<EditingStrategy>()
76 const { 64 const {
77 return computeVisibleSelectionInDOMTree(); 65 DCHECK_EQ(frame()->document(), document());
66 DCHECK_EQ(frame(), document().frame());
67 if (m_selection.isNone())
68 return m_selection;
69 DCHECK_EQ(m_selection.base().document(), document());
70 return m_selection;
78 } 71 }
79 72
80 template <> 73 template <>
81 const VisibleSelectionInFlatTree& 74 const VisibleSelectionInFlatTree&
82 SelectionEditor::visibleSelection<EditingInFlatTreeStrategy>() const { 75 SelectionEditor::visibleSelection<EditingInFlatTreeStrategy>() const {
83 return computeVisibleSelectionInFlatTree(); 76 DCHECK_EQ(frame()->document(), document());
77 DCHECK_EQ(frame(), document().frame());
78 if (m_selectionInFlatTree.isNone())
79 return m_selectionInFlatTree;
80 DCHECK_EQ(m_selectionInFlatTree.base().document(), document());
81 return m_selectionInFlatTree;
84 } 82 }
85 83
86 const VisibleSelection& SelectionEditor::computeVisibleSelectionInDOMTree() 84 void SelectionEditor::setVisibleSelection(
87 const { 85 const VisibleSelection& newSelection,
88 DCHECK_EQ(frame()->document(), document()); 86 FrameSelection::SetSelectionOptions options) {
89 DCHECK_EQ(frame(), document().frame()); 87 DCHECK(newSelection.isValidFor(document())) << newSelection;
90 updateCachedVisibleSelectionIfNeeded(); 88 resetLogicalRange();
91 if (m_cachedVisibleSelectionInDOMTree.isNone()) 89 clearDocumentCachedRange();
92 return m_cachedVisibleSelectionInDOMTree; 90
93 DCHECK_EQ(m_cachedVisibleSelectionInDOMTree.base().document(), document()); 91 m_selection = newSelection;
94 return m_cachedVisibleSelectionInDOMTree; 92 if (options & FrameSelection::DoNotAdjustInFlatTree) {
93 m_selectionInFlatTree.setWithoutValidation(
94 toPositionInFlatTree(m_selection.base()),
95 toPositionInFlatTree(m_selection.extent()));
96 return;
97 }
98
99 SelectionAdjuster::adjustSelectionInFlatTree(&m_selectionInFlatTree,
100 m_selection);
95 } 101 }
96 102
97 const VisibleSelectionInFlatTree& 103 void SelectionEditor::setVisibleSelection(
98 SelectionEditor::computeVisibleSelectionInFlatTree() const { 104 const VisibleSelectionInFlatTree& newSelection,
99 DCHECK_EQ(frame()->document(), document()); 105 FrameSelection::SetSelectionOptions options) {
100 DCHECK_EQ(frame(), document().frame()); 106 DCHECK(newSelection.isValidFor(document())) << newSelection;
101 updateCachedVisibleSelectionIfNeeded(); 107 DCHECK(!(options & FrameSelection::DoNotAdjustInFlatTree));
102 if (m_cachedVisibleSelectionInFlatTree.isNone()) 108 resetLogicalRange();
103 return m_cachedVisibleSelectionInFlatTree; 109 clearDocumentCachedRange();
104 DCHECK_EQ(m_cachedVisibleSelectionInFlatTree.base().document(), document()); 110
105 return m_cachedVisibleSelectionInFlatTree; 111 m_selectionInFlatTree = newSelection;
112 SelectionAdjuster::adjustSelectionInDOMTree(&m_selection,
113 m_selectionInFlatTree);
106 } 114 }
107 115
108 const SelectionInDOMTree& SelectionEditor::selectionInDOMTree() const { 116 void SelectionEditor::setWithoutValidation(const Position& base,
109 assertSelectionValid(); 117 const Position& extent) {
110 return m_selection; 118 resetLogicalRange();
111 } 119 if (base.isNotNull())
120 DCHECK_EQ(base.document(), document());
121 if (extent.isNotNull())
122 DCHECK_EQ(extent.document(), document());
123 clearDocumentCachedRange();
112 124
113 bool SelectionEditor::hasEditableStyle() const { 125 m_selection.setWithoutValidation(base, extent);
114 return computeVisibleSelectionInDOMTree().hasEditableStyle(); 126 m_selectionInFlatTree.setWithoutValidation(toPositionInFlatTree(base),
115 } 127 toPositionInFlatTree(extent));
116
117 bool SelectionEditor::isContentEditable() const {
118 return computeVisibleSelectionInDOMTree().isContentEditable();
119 }
120
121 bool SelectionEditor::isContentRichlyEditable() const {
122 return computeVisibleSelectionInDOMTree().isContentRichlyEditable();
123 }
124
125 void SelectionEditor::markCacheDirty() {
126 m_cachedVisibleSelectionInFlatTree = VisibleSelectionInFlatTree();
127 m_cachedVisibleSelectionInDOMTree = VisibleSelection();
128 m_cacheIsDirty = true;
129 }
130
131 void SelectionEditor::setSelection(const SelectionInDOMTree& newSelection) {
132 newSelection.assertValidFor(document());
133 if (m_selection == newSelection)
134 return;
135 resetLogicalRange();
136 clearDocumentCachedRange();
137 markCacheDirty();
138 m_selection = newSelection;
139 }
140
141 void SelectionEditor::didChangeChildren(const ContainerNode&) {
142 markCacheDirty();
143 didFinishDOMMutation();
144 }
145
146 void SelectionEditor::didFinishTextChange(const Position& newBase,
147 const Position& newExtent) {
148 if (newBase == m_selection.m_base && newExtent == m_selection.m_extent) {
149 didFinishDOMMutation();
150 return;
151 }
152 m_selection.m_base = newBase;
153 m_selection.m_extent = newExtent;
154 markCacheDirty();
155 didFinishDOMMutation();
156 }
157
158 void SelectionEditor::didFinishDOMMutation() {
159 assertSelectionValid();
160 } 128 }
161 129
162 void SelectionEditor::documentAttached(Document* document) { 130 void SelectionEditor::documentAttached(Document* document) {
163 DCHECK(document); 131 DCHECK(document);
164 DCHECK(!lifecycleContext()) << lifecycleContext(); 132 DCHECK(!m_document) << m_document;
165 m_styleVersion = static_cast<uint64_t>(-1); 133 m_document = document;
166 clearVisibleSelection();
167 setContext(document);
168 } 134 }
169 135
170 void SelectionEditor::contextDestroyed(Document*) { 136 void SelectionEditor::documentDetached(const Document& document) {
137 DCHECK_EQ(m_document, &document);
171 dispose(); 138 dispose();
172 m_styleVersion = static_cast<uint64_t>(-1); 139 m_document = nullptr;
173 m_selection = SelectionInDOMTree();
174 m_cachedVisibleSelectionInDOMTree = VisibleSelection();
175 m_cachedVisibleSelectionInFlatTree = VisibleSelectionInFlatTree();
176 m_cacheIsDirty = false;
177 } 140 }
178 141
179 void SelectionEditor::resetLogicalRange() { 142 void SelectionEditor::resetLogicalRange() {
180 // Non-collapsed ranges are not allowed to start at the end of a line that 143 // Non-collapsed ranges are not allowed to start at the end of a line that
181 // is wrapped, they start at the beginning of the next line instead 144 // is wrapped, they start at the beginning of the next line instead
182 if (!m_logicalRange) 145 if (!m_logicalRange)
183 return; 146 return;
184 m_logicalRange->dispose(); 147 m_logicalRange->dispose();
185 m_logicalRange = nullptr; 148 m_logicalRange = nullptr;
186 } 149 }
187 150
188 void SelectionEditor::setLogicalRange(Range* range) { 151 void SelectionEditor::setLogicalRange(Range* range) {
189 DCHECK_EQ(range->ownerDocument(), document()); 152 DCHECK_EQ(range->ownerDocument(), document());
190 DCHECK(!m_logicalRange) << "A logical range should be one."; 153 DCHECK(!m_logicalRange) << "A logical range should be one.";
191 m_logicalRange = range; 154 m_logicalRange = range;
192 } 155 }
193 156
194 Range* SelectionEditor::firstRange() const { 157 Range* SelectionEditor::firstRange() const {
195 if (m_logicalRange) 158 if (m_logicalRange)
196 return m_logicalRange->cloneRange(); 159 return m_logicalRange->cloneRange();
197 return firstRangeOf(computeVisibleSelectionInDOMTree()); 160 return firstRangeOf(m_selection);
198 } 161 }
199 162
200 bool SelectionEditor::shouldAlwaysUseDirectionalSelection() const { 163 bool SelectionEditor::shouldAlwaysUseDirectionalSelection() const {
201 return frame()->editor().behavior().shouldConsiderSelectionAsDirectional(); 164 return frame()->editor().behavior().shouldConsiderSelectionAsDirectional();
202 } 165 }
203 166
204 void SelectionEditor::updateIfNeeded() { 167 void SelectionEditor::updateIfNeeded() {
205 // TODO(yosin): We should unify |SelectionEditor::updateIfNeeded()| and 168 DCHECK(m_selection.isValidFor(document())) << m_selection;
206 // |updateCachedVisibleSelectionIfNeeded()| 169 DCHECK(m_selectionInFlatTree.isValidFor(document())) << m_selection;
207 updateCachedVisibleSelectionIfNeeded(); 170 m_selection.updateIfNeeded();
208 } 171 m_selectionInFlatTree.updateIfNeeded();
209
210 bool SelectionEditor::needsUpdateVisibleSelection() const {
211 return m_cacheIsDirty || m_styleVersion != document().styleVersion();
212 }
213
214 void SelectionEditor::updateCachedVisibleSelectionIfNeeded() const {
215 // Note: Since we |FrameCaret::updateApperance()| is called from
216 // |FrameView::performPostLayoutTasks()|, we check lifecycle against
217 // |AfterPerformLayout| instead of |LayoutClean|.
218 DCHECK_GE(document().lifecycle().state(),
219 DocumentLifecycle::AfterPerformLayout);
220 assertSelectionValid();
221 if (!needsUpdateVisibleSelection())
222 return;
223
224 m_cachedVisibleSelectionInDOMTree = createVisibleSelection(m_selection);
225 m_cachedVisibleSelectionInFlatTree = createVisibleSelection(
226 SelectionInFlatTree::Builder()
227 .setBaseAndExtent(toPositionInFlatTree(m_selection.base()),
228 toPositionInFlatTree(m_selection.extent()))
229 .setAffinity(m_selection.affinity())
230 .setHasTrailingWhitespace(m_selection.hasTrailingWhitespace())
231 .setGranularity(m_selection.granularity())
232 .setIsDirectional(m_selection.isDirectional())
233 .build());
234 m_styleVersion = document().styleVersion();
235 m_cacheIsDirty = false;
236 } 172 }
237 173
238 void SelectionEditor::cacheRangeOfDocument(Range* range) { 174 void SelectionEditor::cacheRangeOfDocument(Range* range) {
239 m_cachedRange = range; 175 m_cachedRange = range;
240 } 176 }
241 177
242 Range* SelectionEditor::documentCachedRange() const { 178 Range* SelectionEditor::documentCachedRange() const {
243 return m_cachedRange; 179 return m_cachedRange;
244 } 180 }
245 181
246 void SelectionEditor::clearDocumentCachedRange() { 182 void SelectionEditor::clearDocumentCachedRange() {
247 m_cachedRange = nullptr; 183 m_cachedRange = nullptr;
248 } 184 }
249 185
250 DEFINE_TRACE(SelectionEditor) { 186 DEFINE_TRACE(SelectionEditor) {
187 visitor->trace(m_document);
251 visitor->trace(m_frame); 188 visitor->trace(m_frame);
252 visitor->trace(m_selection); 189 visitor->trace(m_selection);
253 visitor->trace(m_cachedVisibleSelectionInDOMTree); 190 visitor->trace(m_selectionInFlatTree);
254 visitor->trace(m_cachedVisibleSelectionInFlatTree);
255 visitor->trace(m_logicalRange); 191 visitor->trace(m_logicalRange);
256 visitor->trace(m_cachedRange); 192 visitor->trace(m_cachedRange);
257 SynchronousMutationObserver::trace(visitor);
258 } 193 }
259 194
260 } // namespace blink 195 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/SelectionEditor.h ('k') | third_party/WebKit/Source/core/editing/VisibleSelection.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698