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

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

Issue 2759943004: CANCELLED Merge SelectionAdjuster into VisibleSelection part 2 (Closed)
Patch Set: Rebased Created 3 years, 9 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 Apple Computer, Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 12 matching lines...) Expand all
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/VisibleSelection.h" 26 #include "core/editing/VisibleSelection.h"
27 27
28 #include "bindings/core/v8/ExceptionState.h" 28 #include "bindings/core/v8/ExceptionState.h"
29 #include "core/dom/Document.h" 29 #include "core/dom/Document.h"
30 #include "core/dom/Element.h" 30 #include "core/dom/Element.h"
31 #include "core/dom/Range.h" 31 #include "core/dom/Range.h"
32 #include "core/editing/EditingUtilities.h" 32 #include "core/editing/EditingUtilities.h"
33 #include "core/editing/SelectionAdjuster.h"
34 #include "core/editing/iterators/CharacterIterator.h" 33 #include "core/editing/iterators/CharacterIterator.h"
35 #include "platform/geometry/LayoutPoint.h" 34 #include "platform/geometry/LayoutPoint.h"
36 #include "wtf/Assertions.h" 35 #include "wtf/Assertions.h"
37 #include "wtf/text/CString.h" 36 #include "wtf/text/CString.h"
38 #include "wtf/text/CharacterNames.h" 37 #include "wtf/text/CharacterNames.h"
39 #include "wtf/text/StringBuilder.h" 38 #include "wtf/text/StringBuilder.h"
40 39
41 namespace blink { 40 namespace blink {
42 41
42 namespace {
43
44 enum class AdjustDirection { kAdjustNone, kAdjustStart, kAdjustEnd };
45
46 Node* enclosingShadowHost(Node* node) {
47 for (Node* runner = node; runner;
48 runner = FlatTreeTraversal::parent(*runner)) {
49 if (isShadowHost(runner))
50 return runner;
51 }
52 return nullptr;
53 }
54
55 bool isEnclosedBy(const PositionInFlatTree& position, const Node& node) {
56 DCHECK(position.isNotNull());
57 Node* anchorNode = position.anchorNode();
58 if (anchorNode == node)
59 return !position.isAfterAnchor() && !position.isBeforeAnchor();
60
61 return FlatTreeTraversal::isDescendantOf(*anchorNode, node);
62 }
63
64 bool isSelectionBoundary(const Node& node) {
65 return isHTMLTextAreaElement(node) || isHTMLInputElement(node) ||
66 isHTMLSelectElement(node);
67 }
68
69 Node* enclosingShadowHostForStart(const PositionInFlatTree& position) {
70 Node* node = position.nodeAsRangeFirstNode();
71 if (!node)
72 return nullptr;
73 Node* shadowHost = enclosingShadowHost(node);
74 if (!shadowHost)
75 return nullptr;
76 if (!isEnclosedBy(position, *shadowHost))
77 return nullptr;
78 return isSelectionBoundary(*shadowHost) ? shadowHost : nullptr;
79 }
80
81 Node* enclosingShadowHostForEnd(const PositionInFlatTree& position) {
82 Node* node = position.nodeAsRangeLastNode();
83 if (!node)
84 return nullptr;
85 Node* shadowHost = enclosingShadowHost(node);
86 if (!shadowHost)
87 return nullptr;
88 if (!isEnclosedBy(position, *shadowHost))
89 return nullptr;
90 return isSelectionBoundary(*shadowHost) ? shadowHost : nullptr;
91 }
92
93 PositionInFlatTree adjustPositionInFlatTreeForStart(
94 const PositionInFlatTree& position,
95 Node* shadowHost) {
96 if (isEnclosedBy(position, *shadowHost)) {
97 if (position.isBeforeChildren())
98 return PositionInFlatTree::beforeNode(shadowHost);
99 return PositionInFlatTree::afterNode(shadowHost);
100 }
101
102 // We use |firstChild|'s after instead of beforeAllChildren for backward
103 // compatibility. The positions are same but the anchors would be different,
104 // and selection painting uses anchor nodes.
105 if (Node* firstChild = FlatTreeTraversal::firstChild(*shadowHost))
106 return PositionInFlatTree::beforeNode(firstChild);
107 return PositionInFlatTree();
108 }
109
110 Position adjustPositionForEnd(const Position& currentPosition,
111 Node* startContainerNode) {
112 TreeScope& treeScope = startContainerNode->treeScope();
113
114 DCHECK(currentPosition.computeContainerNode()->treeScope() != treeScope);
115
116 if (Node* ancestor = treeScope.ancestorInThisScope(
117 currentPosition.computeContainerNode())) {
118 if (ancestor->contains(startContainerNode))
119 return Position::afterNode(ancestor);
120 return Position::beforeNode(ancestor);
121 }
122
123 if (Node* lastChild = treeScope.rootNode().lastChild())
124 return Position::afterNode(lastChild);
125
126 return Position();
127 }
128
129 PositionInFlatTree adjustPositionInFlatTreeForEnd(
130 const PositionInFlatTree& position,
131 Node* shadowHost) {
132 if (isEnclosedBy(position, *shadowHost)) {
133 if (position.isAfterChildren())
134 return PositionInFlatTree::afterNode(shadowHost);
135 return PositionInFlatTree::beforeNode(shadowHost);
136 }
137
138 // We use |lastChild|'s after instead of afterAllChildren for backward
139 // compatibility. The positions are same but the anchors would be different,
140 // and selection painting uses anchor nodes.
141 if (Node* lastChild = FlatTreeTraversal::lastChild(*shadowHost))
142 return PositionInFlatTree::afterNode(lastChild);
143 return PositionInFlatTree();
144 }
145
146 Position adjustPositionForStart(const Position& currentPosition,
147 Node* endContainerNode) {
148 TreeScope& treeScope = endContainerNode->treeScope();
149
150 DCHECK(currentPosition.computeContainerNode()->treeScope() != treeScope);
151
152 if (Node* ancestor = treeScope.ancestorInThisScope(
153 currentPosition.computeContainerNode())) {
154 if (ancestor->contains(endContainerNode))
155 return Position::beforeNode(ancestor);
156 return Position::afterNode(ancestor);
157 }
158
159 if (Node* firstChild = treeScope.rootNode().firstChild())
160 return Position::beforeNode(firstChild);
161
162 return Position();
163 }
164
165 std::pair<AdjustDirection, Position> adjustmentToAvoidCrossingShadowBoundaries(
166 const VisibleSelection& selection) {
167 // Note: |m_selectionType| isn't computed yet.
168 DCHECK(selection.base().isNotNull());
169 DCHECK(selection.extent().isNotNull());
170 DCHECK(selection.start().isNotNull());
171 DCHECK(selection.end().isNotNull());
172
173 // TODO(hajimehoshi): Checking treeScope is wrong when a node is
174 // distributed, but we leave it as it is for backward compatibility.
175 if (selection.start().anchorNode()->treeScope() ==
176 selection.end().anchorNode()->treeScope())
177 return std::make_pair(AdjustDirection::kAdjustNone, Position());
178
179 if (selection.isBaseFirst()) {
180 const Position& newEnd = adjustPositionForEnd(
181 selection.end(), selection.start().computeContainerNode());
182 return std::make_pair(AdjustDirection::kAdjustEnd, newEnd);
183 }
184
185 const Position& newStart = adjustPositionForStart(
186 selection.start(), selection.end().computeContainerNode());
187 return std::make_pair(AdjustDirection::kAdjustStart, newStart);
188 }
189
190 // This function is called twice. The first is called when |m_start| and |m_end|
191 // or |m_extent| are same, and the second when |m_start| and |m_end| are changed
192 // after downstream/upstream.
193 std::pair<AdjustDirection, PositionInFlatTree>
194 adjustmentToAvoidCrossingShadowBoundaries(
195 const VisibleSelectionInFlatTree& selection) {
196 Node* const shadowHostStart = enclosingShadowHostForStart(selection.start());
197 Node* const shadowHostEnd = enclosingShadowHostForEnd(selection.end());
198 if (shadowHostStart == shadowHostEnd)
199 return std::make_pair(AdjustDirection::kAdjustNone, PositionInFlatTree());
200
201 if (selection.isBaseFirst()) {
202 Node* const shadowHost = shadowHostStart ? shadowHostStart : shadowHostEnd;
203 const PositionInFlatTree& newEnd =
204 adjustPositionInFlatTreeForEnd(selection.end(), shadowHost);
205 return std::make_pair(AdjustDirection::kAdjustEnd, newEnd);
206 }
207 Node* const shadowHost = shadowHostEnd ? shadowHostEnd : shadowHostStart;
208 const PositionInFlatTree& newStart =
209 adjustPositionInFlatTreeForStart(selection.start(), shadowHost);
210 return std::make_pair(AdjustDirection::kAdjustStart, newStart);
211 }
212
213 } // namespace
214
43 template <typename Strategy> 215 template <typename Strategy>
44 VisibleSelectionTemplate<Strategy>::VisibleSelectionTemplate() 216 VisibleSelectionTemplate<Strategy>::VisibleSelectionTemplate()
45 : m_affinity(TextAffinity::Downstream), 217 : m_affinity(TextAffinity::Downstream),
46 m_selectionType(NoSelection), 218 m_selectionType(NoSelection),
47 m_baseIsFirst(true), 219 m_baseIsFirst(true),
48 m_isDirectional(false), 220 m_isDirectional(false),
49 m_granularity(CharacterGranularity), 221 m_granularity(CharacterGranularity),
50 m_hasTrailingWhitespace(false) {} 222 m_hasTrailingWhitespace(false) {}
51 223
52 template <typename Strategy> 224 template <typename Strategy>
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 980
809 void showTree(const blink::VisibleSelectionInFlatTree& sel) { 981 void showTree(const blink::VisibleSelectionInFlatTree& sel) {
810 sel.showTreeForThis(); 982 sel.showTreeForThis();
811 } 983 }
812 984
813 void showTree(const blink::VisibleSelectionInFlatTree* sel) { 985 void showTree(const blink::VisibleSelectionInFlatTree* sel) {
814 if (sel) 986 if (sel)
815 sel->showTreeForThis(); 987 sel->showTreeForThis();
816 } 988 }
817 #endif 989 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698