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

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

Issue 1675163002: Rename ComposedTree to FlatTree (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: wip Created 4 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, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 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
(...skipping 15 matching lines...) Expand all
26 #include "core/editing/SelectionAdjuster.h" 26 #include "core/editing/SelectionAdjuster.h"
27 27
28 #include "core/editing/EditingUtilities.h" 28 #include "core/editing/EditingUtilities.h"
29 29
30 namespace blink { 30 namespace blink {
31 31
32 namespace { 32 namespace {
33 33
34 Node* enclosingShadowHost(Node* node) 34 Node* enclosingShadowHost(Node* node)
35 { 35 {
36 for (Node* runner = node; runner; runner = ComposedTreeTraversal::parent(*ru nner)) { 36 for (Node* runner = node; runner; runner = FlatTreeTraversal::parent(*runner )) {
37 if (isShadowHost(runner)) 37 if (isShadowHost(runner))
38 return runner; 38 return runner;
39 } 39 }
40 return nullptr; 40 return nullptr;
41 } 41 }
42 42
43 bool isEnclosedBy(const PositionInComposedTree& position, const Node& node) 43 bool isEnclosedBy(const PositionInFlatTree& position, const Node& node)
44 { 44 {
45 ASSERT(position.isNotNull()); 45 ASSERT(position.isNotNull());
46 Node* anchorNode = position.anchorNode(); 46 Node* anchorNode = position.anchorNode();
47 if (anchorNode == node) 47 if (anchorNode == node)
48 return !position.isAfterAnchor() && !position.isBeforeAnchor(); 48 return !position.isAfterAnchor() && !position.isBeforeAnchor();
49 49
50 return ComposedTreeTraversal::isDescendantOf(*anchorNode, node); 50 return FlatTreeTraversal::isDescendantOf(*anchorNode, node);
51 } 51 }
52 52
53 bool isSelectionBoundary(const Node& node) 53 bool isSelectionBoundary(const Node& node)
54 { 54 {
55 return isHTMLTextAreaElement(node) || isHTMLInputElement(node) || isHTMLSele ctElement(node); 55 return isHTMLTextAreaElement(node) || isHTMLInputElement(node) || isHTMLSele ctElement(node);
56 } 56 }
57 57
58 Node* enclosingShadowHostForStart(const PositionInComposedTree& position) 58 Node* enclosingShadowHostForStart(const PositionInFlatTree& position)
59 { 59 {
60 Node* node = position.nodeAsRangeFirstNode(); 60 Node* node = position.nodeAsRangeFirstNode();
61 if (!node) 61 if (!node)
62 return nullptr; 62 return nullptr;
63 Node* shadowHost = enclosingShadowHost(node); 63 Node* shadowHost = enclosingShadowHost(node);
64 if (!shadowHost) 64 if (!shadowHost)
65 return nullptr; 65 return nullptr;
66 if (!isEnclosedBy(position, *shadowHost)) 66 if (!isEnclosedBy(position, *shadowHost))
67 return nullptr; 67 return nullptr;
68 return isSelectionBoundary(*shadowHost) ? shadowHost : nullptr; 68 return isSelectionBoundary(*shadowHost) ? shadowHost : nullptr;
69 } 69 }
70 70
71 Node* enclosingShadowHostForEnd(const PositionInComposedTree& position) 71 Node* enclosingShadowHostForEnd(const PositionInFlatTree& position)
72 { 72 {
73 Node* node = position.nodeAsRangeLastNode(); 73 Node* node = position.nodeAsRangeLastNode();
74 if (!node) 74 if (!node)
75 return nullptr; 75 return nullptr;
76 Node* shadowHost = enclosingShadowHost(node); 76 Node* shadowHost = enclosingShadowHost(node);
77 if (!shadowHost) 77 if (!shadowHost)
78 return nullptr; 78 return nullptr;
79 if (!isEnclosedBy(position, *shadowHost)) 79 if (!isEnclosedBy(position, *shadowHost))
80 return nullptr; 80 return nullptr;
81 return isSelectionBoundary(*shadowHost) ? shadowHost : nullptr; 81 return isSelectionBoundary(*shadowHost) ? shadowHost : nullptr;
82 } 82 }
83 83
84 PositionInComposedTree adjustPositionInComposedTreeForStart(const PositionInComp osedTree& position, Node* shadowHost) 84 PositionInFlatTree adjustPositionInFlatTreeForStart(const PositionInFlatTree& po sition, Node* shadowHost)
85 { 85 {
86 if (isEnclosedBy(position, *shadowHost)) { 86 if (isEnclosedBy(position, *shadowHost)) {
87 if (position.isBeforeChildren()) 87 if (position.isBeforeChildren())
88 return PositionInComposedTree::beforeNode(shadowHost); 88 return PositionInFlatTree::beforeNode(shadowHost);
89 return PositionInComposedTree::afterNode(shadowHost); 89 return PositionInFlatTree::afterNode(shadowHost);
90 } 90 }
91 91
92 // We use |firstChild|'s after instead of beforeAllChildren for backward 92 // We use |firstChild|'s after instead of beforeAllChildren for backward
93 // compatibility. The positions are same but the anchors would be different, 93 // compatibility. The positions are same but the anchors would be different,
94 // and selection painting uses anchor nodes. 94 // and selection painting uses anchor nodes.
95 if (Node* firstChild = ComposedTreeTraversal::firstChild(*shadowHost)) 95 if (Node* firstChild = FlatTreeTraversal::firstChild(*shadowHost))
96 return PositionInComposedTree::beforeNode(firstChild); 96 return PositionInFlatTree::beforeNode(firstChild);
97 return PositionInComposedTree(); 97 return PositionInFlatTree();
98 } 98 }
99 99
100 Position adjustPositionForEnd(const Position& currentPosition, Node* startContai nerNode) 100 Position adjustPositionForEnd(const Position& currentPosition, Node* startContai nerNode)
101 { 101 {
102 TreeScope& treeScope = startContainerNode->treeScope(); 102 TreeScope& treeScope = startContainerNode->treeScope();
103 103
104 ASSERT(currentPosition.computeContainerNode()->treeScope() != treeScope); 104 ASSERT(currentPosition.computeContainerNode()->treeScope() != treeScope);
105 105
106 if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.computeCo ntainerNode())) { 106 if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.computeCo ntainerNode())) {
107 if (ancestor->contains(startContainerNode)) 107 if (ancestor->contains(startContainerNode))
108 return positionAfterNode(ancestor); 108 return positionAfterNode(ancestor);
109 return positionBeforeNode(ancestor); 109 return positionBeforeNode(ancestor);
110 } 110 }
111 111
112 if (Node* lastChild = treeScope.rootNode().lastChild()) 112 if (Node* lastChild = treeScope.rootNode().lastChild())
113 return positionAfterNode(lastChild); 113 return positionAfterNode(lastChild);
114 114
115 return Position(); 115 return Position();
116 } 116 }
117 117
118 PositionInComposedTree adjustPositionInComposedTreeForEnd(const PositionInCompos edTree& position, Node* shadowHost) 118 PositionInFlatTree adjustPositionInFlatTreeForEnd(const PositionInFlatTree& posi tion, Node* shadowHost)
119 { 119 {
120 if (isEnclosedBy(position, *shadowHost)) { 120 if (isEnclosedBy(position, *shadowHost)) {
121 if (position.isAfterChildren()) 121 if (position.isAfterChildren())
122 return PositionInComposedTree::afterNode(shadowHost); 122 return PositionInFlatTree::afterNode(shadowHost);
123 return PositionInComposedTree::beforeNode(shadowHost); 123 return PositionInFlatTree::beforeNode(shadowHost);
124 } 124 }
125 125
126 // We use |lastChild|'s after instead of afterAllChildren for backward 126 // We use |lastChild|'s after instead of afterAllChildren for backward
127 // compatibility. The positions are same but the anchors would be different, 127 // compatibility. The positions are same but the anchors would be different,
128 // and selection painting uses anchor nodes. 128 // and selection painting uses anchor nodes.
129 if (Node* lastChild = ComposedTreeTraversal::lastChild(*shadowHost)) 129 if (Node* lastChild = FlatTreeTraversal::lastChild(*shadowHost))
130 return PositionInComposedTree::afterNode(lastChild); 130 return PositionInFlatTree::afterNode(lastChild);
131 return PositionInComposedTree(); 131 return PositionInFlatTree();
132 } 132 }
133 133
134 Position adjustPositionForStart(const Position& currentPosition, Node* endContai nerNode) 134 Position adjustPositionForStart(const Position& currentPosition, Node* endContai nerNode)
135 { 135 {
136 TreeScope& treeScope = endContainerNode->treeScope(); 136 TreeScope& treeScope = endContainerNode->treeScope();
137 137
138 ASSERT(currentPosition.computeContainerNode()->treeScope() != treeScope); 138 ASSERT(currentPosition.computeContainerNode()->treeScope() != treeScope);
139 139
140 if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.computeCo ntainerNode())) { 140 if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.computeCo ntainerNode())) {
141 if (ancestor->contains(endContainerNode)) 141 if (ancestor->contains(endContainerNode))
142 return positionBeforeNode(ancestor); 142 return positionBeforeNode(ancestor);
143 return positionAfterNode(ancestor); 143 return positionAfterNode(ancestor);
144 } 144 }
145 145
146 if (Node* firstChild = treeScope.rootNode().firstChild()) 146 if (Node* firstChild = treeScope.rootNode().firstChild())
147 return positionBeforeNode(firstChild); 147 return positionBeforeNode(firstChild);
148 148
149 return Position(); 149 return Position();
150 } 150 }
151 151
152 } // namespace 152 } // namespace
153 153
154 // Updates |selectionInComposedTree| to match with |selection|. 154 // Updates |selectionInFlatTree| to match with |selection|.
155 void SelectionAdjuster::adjustSelectionInComposedTree(VisibleSelectionInComposed Tree* selectionInComposedTree, const VisibleSelection& selection) 155 void SelectionAdjuster::adjustSelectionInFlatTree(VisibleSelectionInFlatTree* se lectionInFlatTree, const VisibleSelection& selection)
156 { 156 {
157 if (selection.isNone()) { 157 if (selection.isNone()) {
158 *selectionInComposedTree = VisibleSelectionInComposedTree(); 158 *selectionInFlatTree = VisibleSelectionInFlatTree();
159 return; 159 return;
160 } 160 }
161 161
162 const PositionInComposedTree& base = toPositionInComposedTree(selection.base ()); 162 const PositionInFlatTree& base = toPositionInFlatTree(selection.base());
163 const PositionInComposedTree& extent = toPositionInComposedTree(selection.ex tent()); 163 const PositionInFlatTree& extent = toPositionInFlatTree(selection.extent());
164 const PositionInComposedTree& position1 = toPositionInComposedTree(selection .start()); 164 const PositionInFlatTree& position1 = toPositionInFlatTree(selection.start() );
165 const PositionInComposedTree& position2 = toPositionInComposedTree(selection .end()); 165 const PositionInFlatTree& position2 = toPositionInFlatTree(selection.end());
166 position1.anchorNode()->updateDistribution(); 166 position1.anchorNode()->updateDistribution();
167 position2.anchorNode()->updateDistribution(); 167 position2.anchorNode()->updateDistribution();
168 selectionInComposedTree->m_base = base; 168 selectionInFlatTree->m_base = base;
169 selectionInComposedTree->m_extent = extent; 169 selectionInFlatTree->m_extent = extent;
170 selectionInComposedTree->m_affinity = selection.m_affinity; 170 selectionInFlatTree->m_affinity = selection.m_affinity;
171 selectionInComposedTree->m_isDirectional = selection.m_isDirectional; 171 selectionInFlatTree->m_isDirectional = selection.m_isDirectional;
172 selectionInComposedTree->m_granularity = selection.m_granularity; 172 selectionInFlatTree->m_granularity = selection.m_granularity;
173 selectionInComposedTree->m_hasTrailingWhitespace = selection.m_hasTrailingWh itespace; 173 selectionInFlatTree->m_hasTrailingWhitespace = selection.m_hasTrailingWhites pace;
174 selectionInComposedTree->m_baseIsFirst = base.isNull() || base.compareTo(ext ent) <= 0; 174 selectionInFlatTree->m_baseIsFirst = base.isNull() || base.compareTo(extent) <= 0;
175 if (position1.compareTo(position2) <= 0) { 175 if (position1.compareTo(position2) <= 0) {
176 selectionInComposedTree->m_start = position1; 176 selectionInFlatTree->m_start = position1;
177 selectionInComposedTree->m_end = position2; 177 selectionInFlatTree->m_end = position2;
178 } else { 178 } else {
179 selectionInComposedTree->m_start = position2; 179 selectionInFlatTree->m_start = position2;
180 selectionInComposedTree->m_end = position1; 180 selectionInFlatTree->m_end = position1;
181 } 181 }
182 selectionInComposedTree->updateSelectionType(); 182 selectionInFlatTree->updateSelectionType();
183 selectionInComposedTree->didChange(); 183 selectionInFlatTree->didChange();
184 } 184 }
185 185
186 static bool isCrossingShadowBoundaries(const VisibleSelectionInComposedTree& sel ection) 186 static bool isCrossingShadowBoundaries(const VisibleSelectionInFlatTree& selecti on)
187 { 187 {
188 if (!selection.isRange()) 188 if (!selection.isRange())
189 return false; 189 return false;
190 TreeScope& treeScope = selection.base().anchorNode()->treeScope(); 190 TreeScope& treeScope = selection.base().anchorNode()->treeScope();
191 return selection.extent().anchorNode()->treeScope() != treeScope 191 return selection.extent().anchorNode()->treeScope() != treeScope
192 || selection.start().anchorNode()->treeScope() != treeScope 192 || selection.start().anchorNode()->treeScope() != treeScope
193 || selection.end().anchorNode()->treeScope() != treeScope; 193 || selection.end().anchorNode()->treeScope() != treeScope;
194 } 194 }
195 195
196 void SelectionAdjuster::adjustSelectionInDOMTree(VisibleSelection* selection, co nst VisibleSelectionInComposedTree& selectionInComposedTree) 196 void SelectionAdjuster::adjustSelectionInDOMTree(VisibleSelection* selection, co nst VisibleSelectionInFlatTree& selectionInFlatTree)
197 { 197 {
198 if (selectionInComposedTree.isNone()) { 198 if (selectionInFlatTree.isNone()) {
199 *selection = VisibleSelection(); 199 *selection = VisibleSelection();
200 return; 200 return;
201 } 201 }
202 202
203 const Position& base = toPositionInDOMTree(selectionInComposedTree.base()); 203 const Position& base = toPositionInDOMTree(selectionInFlatTree.base());
204 const Position& extent = toPositionInDOMTree(selectionInComposedTree.extent( )); 204 const Position& extent = toPositionInDOMTree(selectionInFlatTree.extent());
205 205
206 if (isCrossingShadowBoundaries(selectionInComposedTree)) { 206 if (isCrossingShadowBoundaries(selectionInFlatTree)) {
207 *selection = VisibleSelection(base, extent); 207 *selection = VisibleSelection(base, extent);
208 return; 208 return;
209 } 209 }
210 210
211 const Position& position1 = toPositionInDOMTree(selectionInComposedTree.star t()); 211 const Position& position1 = toPositionInDOMTree(selectionInFlatTree.start()) ;
212 const Position& position2 = toPositionInDOMTree(selectionInComposedTree.end( )); 212 const Position& position2 = toPositionInDOMTree(selectionInFlatTree.end());
213 selection->m_base = base; 213 selection->m_base = base;
214 selection->m_extent = extent; 214 selection->m_extent = extent;
215 selection->m_affinity = selectionInComposedTree.m_affinity; 215 selection->m_affinity = selectionInFlatTree.m_affinity;
216 selection->m_isDirectional = selectionInComposedTree.m_isDirectional; 216 selection->m_isDirectional = selectionInFlatTree.m_isDirectional;
217 selection->m_granularity = selectionInComposedTree.m_granularity; 217 selection->m_granularity = selectionInFlatTree.m_granularity;
218 selection->m_hasTrailingWhitespace = selectionInComposedTree.m_hasTrailingWh itespace; 218 selection->m_hasTrailingWhitespace = selectionInFlatTree.m_hasTrailingWhites pace;
219 selection->m_baseIsFirst = base.isNull() || base.compareTo(extent) <= 0; 219 selection->m_baseIsFirst = base.isNull() || base.compareTo(extent) <= 0;
220 if (position1.compareTo(position2) <= 0) { 220 if (position1.compareTo(position2) <= 0) {
221 selection->m_start = position1; 221 selection->m_start = position1;
222 selection->m_end = position2; 222 selection->m_end = position2;
223 } else { 223 } else {
224 selection->m_start = position2; 224 selection->m_start = position2;
225 selection->m_end = position1; 225 selection->m_end = position1;
226 } 226 }
227 selection->updateSelectionType(); 227 selection->updateSelectionType();
228 selection->didChange(); 228 selection->didChange();
(...skipping 20 matching lines...) Expand all
249 } 249 }
250 250
251 const Position& newStart = adjustPositionForStart(selection->start(), select ion->end().computeContainerNode()); 251 const Position& newStart = adjustPositionForStart(selection->start(), select ion->end().computeContainerNode());
252 selection->m_extent = newStart; 252 selection->m_extent = newStart;
253 selection->m_start = newStart; 253 selection->m_start = newStart;
254 } 254 }
255 255
256 // This function is called twice. The first is called when |m_start| and |m_end| 256 // This function is called twice. The first is called when |m_start| and |m_end|
257 // or |m_extent| are same, and the second when |m_start| and |m_end| are changed 257 // or |m_extent| are same, and the second when |m_start| and |m_end| are changed
258 // after downstream/upstream. 258 // after downstream/upstream.
259 void SelectionAdjuster::adjustSelectionToAvoidCrossingShadowBoundaries(VisibleSe lectionInComposedTree* selection) 259 void SelectionAdjuster::adjustSelectionToAvoidCrossingShadowBoundaries(VisibleSe lectionInFlatTree* selection)
260 { 260 {
261 Node* const shadowHostStart = enclosingShadowHostForStart(selection->start() ); 261 Node* const shadowHostStart = enclosingShadowHostForStart(selection->start() );
262 Node* const shadowHostEnd = enclosingShadowHostForEnd(selection->end()); 262 Node* const shadowHostEnd = enclosingShadowHostForEnd(selection->end());
263 if (shadowHostStart == shadowHostEnd) 263 if (shadowHostStart == shadowHostEnd)
264 return; 264 return;
265 265
266 if (selection->isBaseFirst()) { 266 if (selection->isBaseFirst()) {
267 Node* const shadowHost = shadowHostStart ? shadowHostStart : shadowHostE nd; 267 Node* const shadowHost = shadowHostStart ? shadowHostStart : shadowHostE nd;
268 const PositionInComposedTree& newEnd = adjustPositionInComposedTreeForEn d(selection->end(), shadowHost); 268 const PositionInFlatTree& newEnd = adjustPositionInFlatTreeForEnd(select ion->end(), shadowHost);
269 selection->m_extent = newEnd; 269 selection->m_extent = newEnd;
270 selection->m_end = newEnd; 270 selection->m_end = newEnd;
271 return; 271 return;
272 } 272 }
273 Node* const shadowHost = shadowHostEnd ? shadowHostEnd : shadowHostStart; 273 Node* const shadowHost = shadowHostEnd ? shadowHostEnd : shadowHostStart;
274 const PositionInComposedTree& newStart = adjustPositionInComposedTreeForStar t(selection->start(), shadowHost); 274 const PositionInFlatTree& newStart = adjustPositionInFlatTreeForStart(select ion->start(), shadowHost);
275 selection->m_extent = newStart; 275 selection->m_extent = newStart;
276 selection->m_start = newStart; 276 selection->m_start = newStart;
277 } 277 }
278 278
279 } // namespace blink 279 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698