OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2008 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 enum PositionMoveType { | 50 enum PositionMoveType { |
51 CodePoint, // Move by a single code point. | 51 CodePoint, // Move by a single code point. |
52 Character, // Move to the next Unicode character break. | 52 Character, // Move to the next Unicode character break. |
53 BackwardDeletion // Subject to platform conventions. | 53 BackwardDeletion // Subject to platform conventions. |
54 }; | 54 }; |
55 | 55 |
56 template <typename Strategy> | 56 template <typename Strategy> |
57 class CORE_TEMPLATE_CLASS_EXPORT PositionAlgorithm { | 57 class CORE_TEMPLATE_CLASS_EXPORT PositionAlgorithm { |
58 DISALLOW_ALLOCATION(); | 58 DISALLOW_ALLOCATION(); |
59 public: | 59 public: |
60 using PositionType = typename Strategy::PositionType; | |
61 using StrategyType = Strategy; | 60 using StrategyType = Strategy; |
62 | 61 |
63 enum AnchorType : unsigned char { | 62 enum AnchorType : unsigned char { |
64 PositionIsOffsetInAnchor, | 63 PositionIsOffsetInAnchor, |
65 PositionIsBeforeAnchor, | 64 PositionIsBeforeAnchor, |
66 PositionIsAfterAnchor, | 65 PositionIsAfterAnchor, |
67 PositionIsBeforeChildren, | 66 PositionIsBeforeChildren, |
68 PositionIsAfterChildren, | 67 PositionIsAfterChildren, |
69 }; | 68 }; |
70 | 69 |
71 PositionAlgorithm() | 70 PositionAlgorithm() |
72 : m_offset(0) | 71 : m_offset(0) |
73 , m_anchorType(PositionIsOffsetInAnchor) | 72 , m_anchorType(PositionIsOffsetInAnchor) |
74 , m_isLegacyEditingPosition(false) | 73 , m_isLegacyEditingPosition(false) |
75 { | 74 { |
76 } | 75 } |
77 | 76 |
78 // For creating legacy editing positions: (Anchor type will be determined fr
om editingIgnoresContent(node)) | 77 // For creating legacy editing positions: (Anchor type will be determined fr
om editingIgnoresContent(node)) |
79 class LegacyEditingOffset { | 78 class LegacyEditingOffset { |
80 public: | 79 public: |
81 int value() const { return m_offset; } | 80 int value() const { return m_offset; } |
82 | 81 |
83 explicit LegacyEditingOffset(int offset) : m_offset(offset) { } | 82 explicit LegacyEditingOffset(int offset) : m_offset(offset) { } |
84 | 83 |
85 private: | 84 private: |
86 int m_offset; | 85 int m_offset; |
87 }; | 86 }; |
88 | 87 |
89 static const TreeScope* commonAncestorTreeScope(const PositionType&, const P
ositionType& b); | 88 static const TreeScope* commonAncestorTreeScope(const PositionAlgorithm<Stra
tegy>&, const PositionAlgorithm<Strategy>& b); |
90 static PositionType createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node>
anchorNode, int offset); | 89 static PositionAlgorithm<Strategy> createLegacyEditingPosition(PassRefPtrWil
lBeRawPtr<Node> anchorNode, int offset); |
91 | 90 |
92 PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffs
et); | 91 PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffs
et); |
93 | 92 |
94 // For creating before/after positions: | 93 // For creating before/after positions: |
95 PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType); | 94 PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType); |
96 | 95 |
97 // For creating offset positions: | 96 // For creating offset positions: |
98 // FIXME: This constructor should eventually go away. See bug 63040. | 97 // FIXME: This constructor should eventually go away. See bug 63040. |
99 PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset); | 98 PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset); |
100 | 99 |
101 PositionAlgorithm(const PositionAlgorithm&); | 100 PositionAlgorithm(const PositionAlgorithm&); |
102 | 101 |
103 AnchorType anchorType() const { return m_anchorType; } | 102 AnchorType anchorType() const { return m_anchorType; } |
104 | 103 |
105 void clear() { m_anchorNode.clear(); m_offset = 0; m_anchorType = PositionIs
OffsetInAnchor; m_isLegacyEditingPosition = false; } | 104 void clear() { m_anchorNode.clear(); m_offset = 0; m_anchorType = PositionIs
OffsetInAnchor; m_isLegacyEditingPosition = false; } |
106 | 105 |
107 // These are always DOM compliant values. Editing positions like [img, 0] (
aka [img, before]) | 106 // These are always DOM compliant values. Editing positions like [img, 0] (
aka [img, before]) |
108 // will return img->parentNode() and img->nodeIndex() from these functions. | 107 // will return img->parentNode() and img->nodeIndex() from these functions. |
109 Node* containerNode() const; // NULL for a before/after position anchored to
a node with no parent | 108 Node* containerNode() const; // NULL for a before/after position anchored to
a node with no parent |
110 Text* containerText() const; | 109 Text* containerText() const; |
111 | 110 |
112 int computeOffsetInContainerNode() const; // O(n) for before/after-anchored
positions, O(1) for parent-anchored positions | 111 int computeOffsetInContainerNode() const; // O(n) for before/after-anchored
positions, O(1) for parent-anchored positions |
113 PositionType parentAnchoredEquivalent() const; // Convenience method for DOM
positions that also fixes up some positions for editing | 112 PositionAlgorithm<Strategy> parentAnchoredEquivalent() const; // Convenience
method for DOM positions that also fixes up some positions for editing |
114 | 113 |
115 // Returns |PositionIsAnchor| type |Position| which is compatible with | 114 // Returns |PositionIsAnchor| type |Position| which is compatible with |
116 // |RangeBoundaryPoint| as safe to pass |Range| constructor. Return value | 115 // |RangeBoundaryPoint| as safe to pass |Range| constructor. Return value |
117 // of this function is different from |parentAnchoredEquivalent()| which | 116 // of this function is different from |parentAnchoredEquivalent()| which |
118 // returns editing specific position. | 117 // returns editing specific position. |
119 PositionType toOffsetInAnchor() const; | 118 PositionAlgorithm<Strategy> toOffsetInAnchor() const; |
120 | 119 |
121 // Inline O(1) access for Positions which callers know to be parent-anchored | 120 // Inline O(1) access for Positions which callers know to be parent-anchored |
122 int offsetInContainerNode() const | 121 int offsetInContainerNode() const |
123 { | 122 { |
124 ASSERT(anchorType() == PositionIsOffsetInAnchor); | 123 ASSERT(anchorType() == PositionIsOffsetInAnchor); |
125 return m_offset; | 124 return m_offset; |
126 } | 125 } |
127 | 126 |
128 // New code should not use this function. | 127 // New code should not use this function. |
129 int deprecatedEditingOffset() const | 128 int deprecatedEditingOffset() const |
(...skipping 13 matching lines...) Expand all Loading... |
143 | 142 |
144 // Similar to |nodeAsRangeLastNode()|, but returns a node in a range. | 143 // Similar to |nodeAsRangeLastNode()|, but returns a node in a range. |
145 Node* nodeAsRangeLastNode() const; | 144 Node* nodeAsRangeLastNode() const; |
146 | 145 |
147 // Returns a node as past last as same as |Range::pastLastNode()|. This | 146 // Returns a node as past last as same as |Range::pastLastNode()|. This |
148 // function is supposed to used in HTML serialization and plain text | 147 // function is supposed to used in HTML serialization and plain text |
149 // iterator. This position must be a |PositionIs::OffsetInAhcor| to | 148 // iterator. This position must be a |PositionIs::OffsetInAhcor| to |
150 // behave as |Range| boundary point. | 149 // behave as |Range| boundary point. |
151 Node* nodeAsRangePastLastNode() const; | 150 Node* nodeAsRangePastLastNode() const; |
152 | 151 |
153 Node* commonAncestorContainer(const PositionType&) const; | 152 Node* commonAncestorContainer(const PositionAlgorithm<Strategy>&) const; |
154 | 153 |
155 Node* anchorNode() const { return m_anchorNode.get(); } | 154 Node* anchorNode() const { return m_anchorNode.get(); } |
156 | 155 |
157 // FIXME: Callers should be moved off of node(), node() is not always the co
ntainer for this position. | 156 // FIXME: Callers should be moved off of node(), node() is not always the co
ntainer for this position. |
158 // For nodes which editingIgnoresContent(node()) returns true, positions lik
e [ignoredNode, 0] | 157 // For nodes which editingIgnoresContent(node()) returns true, positions lik
e [ignoredNode, 0] |
159 // will be treated as before ignoredNode (thus node() is really after the po
sition, not containing it). | 158 // will be treated as before ignoredNode (thus node() is really after the po
sition, not containing it). |
160 Node* deprecatedNode() const { return m_anchorNode.get(); } | 159 Node* deprecatedNode() const { return m_anchorNode.get(); } |
161 | 160 |
162 Document* document() const { return m_anchorNode ? &m_anchorNode->document()
: 0; } | 161 Document* document() const { return m_anchorNode ? &m_anchorNode->document()
: 0; } |
163 bool inDocument() const { return m_anchorNode && m_anchorNode->inDocument();
} | 162 bool inDocument() const { return m_anchorNode && m_anchorNode->inDocument();
} |
(...skipping 11 matching lines...) Expand all Loading... |
175 bool isNull() const { return !m_anchorNode; } | 174 bool isNull() const { return !m_anchorNode; } |
176 bool isNotNull() const { return m_anchorNode; } | 175 bool isNotNull() const { return m_anchorNode; } |
177 bool isOrphan() const { return m_anchorNode && !m_anchorNode->inDocument();
} | 176 bool isOrphan() const { return m_anchorNode && !m_anchorNode->inDocument();
} |
178 | 177 |
179 Element* element() const; | 178 Element* element() const; |
180 PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> ensureComputedStyle() co
nst; | 179 PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> ensureComputedStyle() co
nst; |
181 | 180 |
182 // Move up or down the DOM by one position. | 181 // Move up or down the DOM by one position. |
183 // Offsets are computed using layout text for nodes that have layoutObjects
- but note that even when | 182 // Offsets are computed using layout text for nodes that have layoutObjects
- but note that even when |
184 // using composed characters, the result may be inside a single user-visible
character if a ligature is formed. | 183 // using composed characters, the result may be inside a single user-visible
character if a ligature is formed. |
185 PositionType previous(PositionMoveType = CodePoint) const; | 184 PositionAlgorithm<Strategy> previous(PositionMoveType = CodePoint) const; |
186 PositionType next(PositionMoveType = CodePoint) const; | 185 PositionAlgorithm<Strategy> next(PositionMoveType = CodePoint) const; |
187 static int uncheckedPreviousOffset(const Node*, int current); | 186 static int uncheckedPreviousOffset(const Node*, int current); |
188 static int uncheckedPreviousOffsetForBackwardDeletion(const Node*, int curre
nt); | 187 static int uncheckedPreviousOffsetForBackwardDeletion(const Node*, int curre
nt); |
189 static int uncheckedNextOffset(const Node*, int current); | 188 static int uncheckedNextOffset(const Node*, int current); |
190 | 189 |
191 int compareTo(const PositionType&) const; | 190 int compareTo(const PositionAlgorithm<Strategy>&) const; |
192 | 191 |
193 // These can be either inside or just before/after the node, depending on | 192 // These can be either inside or just before/after the node, depending on |
194 // if the node is ignored by editing or not. | 193 // if the node is ignored by editing or not. |
195 // FIXME: These should go away. They only make sense for legacy positions. | 194 // FIXME: These should go away. They only make sense for legacy positions. |
196 bool atFirstEditingPositionForNode() const; | 195 bool atFirstEditingPositionForNode() const; |
197 bool atLastEditingPositionForNode() const; | 196 bool atLastEditingPositionForNode() const; |
198 | 197 |
199 // Returns true if the visually equivalent positions around have different e
ditability | 198 // Returns true if the visually equivalent positions around have different e
ditability |
200 bool atEditingBoundary() const; | 199 bool atEditingBoundary() const; |
201 Node* parentEditingBoundary() const; | 200 Node* parentEditingBoundary() const; |
202 | 201 |
203 bool atStartOfTree() const; | 202 bool atStartOfTree() const; |
204 bool atEndOfTree() const; | 203 bool atEndOfTree() const; |
205 | 204 |
206 // These return useful visually equivalent positions. | 205 // These return useful visually equivalent positions. |
207 PositionType upstream(EditingBoundaryCrossingRule = CannotCrossEditingBounda
ry) const; | 206 PositionAlgorithm<Strategy> upstream(EditingBoundaryCrossingRule = CannotCro
ssEditingBoundary) const; |
208 PositionType downstream(EditingBoundaryCrossingRule = CannotCrossEditingBoun
dary) const; | 207 PositionAlgorithm<Strategy> downstream(EditingBoundaryCrossingRule = CannotC
rossEditingBoundary) const; |
209 | 208 |
210 bool isCandidate() const; | 209 bool isCandidate() const; |
211 bool inRenderedText() const; | 210 bool inRenderedText() const; |
212 bool isRenderedCharacter() const; | 211 bool isRenderedCharacter() const; |
213 bool rendersInDifferentPosition(const PositionType&) const; | 212 bool rendersInDifferentPosition(const PositionAlgorithm<Strategy>&) const; |
214 | 213 |
215 void getInlineBoxAndOffset(EAffinity, InlineBox*&, int& caretOffset) const; | 214 void getInlineBoxAndOffset(EAffinity, InlineBox*&, int& caretOffset) const; |
216 void getInlineBoxAndOffset(EAffinity, TextDirection primaryDirection, Inline
Box*&, int& caretOffset) const; | 215 void getInlineBoxAndOffset(EAffinity, TextDirection primaryDirection, Inline
Box*&, int& caretOffset) const; |
217 | 216 |
218 TextDirection primaryDirection() const; | 217 TextDirection primaryDirection() const; |
219 | 218 |
220 static bool hasRenderedNonAnonymousDescendantsWithHeight(LayoutObject*); | 219 static bool hasRenderedNonAnonymousDescendantsWithHeight(LayoutObject*); |
221 static bool nodeIsUserSelectNone(Node*); | 220 static bool nodeIsUserSelectNone(Node*); |
222 static bool nodeIsUserSelectAll(const Node*); | 221 static bool nodeIsUserSelectAll(const Node*); |
223 static Node* rootUserSelectAllForNode(Node*); | 222 static Node* rootUserSelectAllForNode(Node*); |
224 static PositionType beforeNode(Node* anchorNode); | 223 static PositionAlgorithm<Strategy> beforeNode(Node* anchorNode); |
225 static PositionType afterNode(Node* anchorNode); | 224 static PositionAlgorithm<Strategy> afterNode(Node* anchorNode); |
226 static PositionType inParentBeforeNode(const Node& anchorNode); | 225 static PositionAlgorithm<Strategy> inParentBeforeNode(const Node& anchorNode
); |
227 static PositionType inParentAfterNode(const Node& anchorNode); | 226 static PositionAlgorithm<Strategy> inParentAfterNode(const Node& anchorNode)
; |
228 static int lastOffsetInNode(Node* anchorNode); | 227 static int lastOffsetInNode(Node* anchorNode); |
229 static PositionType firstPositionInNode(Node* anchorNode); | 228 static PositionAlgorithm<Strategy> firstPositionInNode(Node* anchorNode); |
230 static PositionType lastPositionInNode(Node* anchorNode); | 229 static PositionAlgorithm<Strategy> lastPositionInNode(Node* anchorNode); |
231 static int minOffsetForNode(Node* anchorNode, int offset); | 230 static int minOffsetForNode(Node* anchorNode, int offset); |
232 static bool offsetIsBeforeLastNodeOffset(int offset, Node* anchorNode); | 231 static bool offsetIsBeforeLastNodeOffset(int offset, Node* anchorNode); |
233 static PositionType firstPositionInOrBeforeNode(Node* anchorNode); | 232 static PositionAlgorithm<Strategy> firstPositionInOrBeforeNode(Node* anchorN
ode); |
234 static PositionType lastPositionInOrAfterNode(Node* anchorNode); | 233 static PositionAlgorithm<Strategy> lastPositionInOrAfterNode(Node* anchorNod
e); |
235 | 234 |
236 void debugPosition(const char* msg = "") const; | 235 void debugPosition(const char* msg = "") const; |
237 | 236 |
238 #ifndef NDEBUG | 237 #ifndef NDEBUG |
239 void formatForDebugger(char* buffer, unsigned length) const; | 238 void formatForDebugger(char* buffer, unsigned length) const; |
240 void showAnchorTypeAndOffset() const; | 239 void showAnchorTypeAndOffset() const; |
241 void showTreeForThis() const; | 240 void showTreeForThis() const; |
242 void showTreeForThisInComposedTree() const; | 241 void showTreeForThisInComposedTree() const; |
243 #endif | 242 #endif |
244 | 243 |
(...skipping 18 matching lines...) Expand all Loading... |
263 bool m_isLegacyEditingPosition; | 262 bool m_isLegacyEditingPosition; |
264 }; | 263 }; |
265 | 264 |
266 extern template class CORE_EXTERN_TEMPLATE_EXPORT PositionAlgorithm<EditingStrat
egy>; | 265 extern template class CORE_EXTERN_TEMPLATE_EXPORT PositionAlgorithm<EditingStrat
egy>; |
267 extern template class CORE_EXTERN_TEMPLATE_EXPORT PositionAlgorithm<EditingInCom
posedTreeStrategy>; | 266 extern template class CORE_EXTERN_TEMPLATE_EXPORT PositionAlgorithm<EditingInCom
posedTreeStrategy>; |
268 | 267 |
269 using Position = PositionAlgorithm<EditingStrategy>; | 268 using Position = PositionAlgorithm<EditingStrategy>; |
270 using PositionInComposedTree = PositionAlgorithm<EditingInComposedTreeStrategy>; | 269 using PositionInComposedTree = PositionAlgorithm<EditingInComposedTreeStrategy>; |
271 | 270 |
272 template <typename Strategy> | 271 template <typename Strategy> |
273 typename Strategy::PositionType PositionAlgorithm<Strategy>::createLegacyEditing
Position(PassRefPtrWillBeRawPtr<Node> node, int offset) | 272 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::createLegacyEditingPosi
tion(PassRefPtrWillBeRawPtr<Node> node, int offset) |
274 { | 273 { |
275 return PositionType(node, PositionAlgorithm::LegacyEditingOffset(offset)); | 274 return PositionAlgorithm<Strategy>(node, PositionAlgorithm::LegacyEditingOff
set(offset)); |
276 } | 275 } |
277 | 276 |
278 inline Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node> node, i
nt offset) | 277 inline Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node> node, i
nt offset) |
279 { | 278 { |
280 return Position::createLegacyEditingPosition(node, offset); | 279 return Position::createLegacyEditingPosition(node, offset); |
281 } | 280 } |
282 | 281 |
283 template <typename Strategy> | 282 template <typename Strategy> |
284 bool operator==(const PositionAlgorithm<Strategy>& a, const PositionAlgorithm<St
rategy>& b) | 283 bool operator==(const PositionAlgorithm<Strategy>& a, const PositionAlgorithm<St
rategy>& b) |
285 { | 284 { |
(...skipping 17 matching lines...) Expand all Loading... |
303 bool operator!=(const PositionAlgorithm<Strategy>& a, const PositionAlgorithm<St
rategy>& b) | 302 bool operator!=(const PositionAlgorithm<Strategy>& a, const PositionAlgorithm<St
rategy>& b) |
304 { | 303 { |
305 return !(a == b); | 304 return !(a == b); |
306 } | 305 } |
307 | 306 |
308 // We define position creation functions to make callsites more readable. | 307 // We define position creation functions to make callsites more readable. |
309 // These are inline to prevent ref-churn when returning a Position object. | 308 // These are inline to prevent ref-churn when returning a Position object. |
310 // If we ever add a PassPosition we can make these non-inline. | 309 // If we ever add a PassPosition we can make these non-inline. |
311 | 310 |
312 template <typename Strategy> | 311 template <typename Strategy> |
313 typename Strategy::PositionType PositionAlgorithm<Strategy>::inParentBeforeNode(
const Node& node) | 312 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::inParentBeforeNode(cons
t Node& node) |
314 { | 313 { |
315 // FIXME: This should ASSERT(node.parentNode()) | 314 // FIXME: This should ASSERT(node.parentNode()) |
316 // At least one caller currently hits this ASSERT though, which indicates | 315 // At least one caller currently hits this ASSERT though, which indicates |
317 // that the caller is trying to make a position relative to a disconnected n
ode (which is likely an error) | 316 // that the caller is trying to make a position relative to a disconnected n
ode (which is likely an error) |
318 // Specifically, editing/deleting/delete-ligature-001.html crashes with ASSE
RT(node->parentNode()) | 317 // Specifically, editing/deleting/delete-ligature-001.html crashes with ASSE
RT(node->parentNode()) |
319 return PositionType(Strategy::parent(node), Strategy::index(node)); | 318 return PositionAlgorithm<Strategy>(Strategy::parent(node), Strategy::index(n
ode)); |
320 } | 319 } |
321 | 320 |
322 inline Position positionInParentBeforeNode(const Node& node) | 321 inline Position positionInParentBeforeNode(const Node& node) |
323 { | 322 { |
324 return Position::inParentBeforeNode(node); | 323 return Position::inParentBeforeNode(node); |
325 } | 324 } |
326 | 325 |
327 template <typename Strategy> | 326 template <typename Strategy> |
328 typename Strategy::PositionType PositionAlgorithm<Strategy>::inParentAfterNode(c
onst Node& node) | 327 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::inParentAfterNode(const
Node& node) |
329 { | 328 { |
330 ASSERT(node.parentNode()); | 329 ASSERT(node.parentNode()); |
331 return PositionType(Strategy::parent(node), Strategy::index(node) + 1); | 330 return PositionAlgorithm<Strategy>(Strategy::parent(node), Strategy::index(n
ode) + 1); |
332 } | 331 } |
333 | 332 |
334 inline Position positionInParentAfterNode(const Node& node) | 333 inline Position positionInParentAfterNode(const Node& node) |
335 { | 334 { |
336 return Position::inParentAfterNode(node); | 335 return Position::inParentAfterNode(node); |
337 } | 336 } |
338 | 337 |
339 // positionBeforeNode and positionAfterNode return neighbor-anchored positions,
construction is O(1) | 338 // positionBeforeNode and positionAfterNode return neighbor-anchored positions,
construction is O(1) |
340 template <typename Strategy> | 339 template <typename Strategy> |
341 typename Strategy::PositionType PositionAlgorithm<Strategy>::beforeNode(Node* an
chorNode) | 340 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::beforeNode(Node* anchor
Node) |
342 { | 341 { |
343 ASSERT(anchorNode); | 342 ASSERT(anchorNode); |
344 return PositionType(anchorNode, PositionIsBeforeAnchor); | 343 return PositionAlgorithm<Strategy>(anchorNode, PositionIsBeforeAnchor); |
345 } | 344 } |
346 | 345 |
347 inline Position positionBeforeNode(Node* anchorNode) | 346 inline Position positionBeforeNode(Node* anchorNode) |
348 { | 347 { |
349 return Position::beforeNode(anchorNode); | 348 return Position::beforeNode(anchorNode); |
350 } | 349 } |
351 | 350 |
352 template <typename Strategy> | 351 template <typename Strategy> |
353 typename Strategy::PositionType PositionAlgorithm<Strategy>::afterNode(Node* anc
horNode) | 352 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::afterNode(Node* anchorN
ode) |
354 { | 353 { |
355 ASSERT(anchorNode); | 354 ASSERT(anchorNode); |
356 return PositionType(anchorNode, PositionIsAfterAnchor); | 355 return PositionAlgorithm<Strategy>(anchorNode, PositionIsAfterAnchor); |
357 } | 356 } |
358 | 357 |
359 inline Position positionAfterNode(Node* anchorNode) | 358 inline Position positionAfterNode(Node* anchorNode) |
360 { | 359 { |
361 return Position::afterNode(anchorNode); | 360 return Position::afterNode(anchorNode); |
362 } | 361 } |
363 | 362 |
364 template <typename Strategy> | 363 template <typename Strategy> |
365 int PositionAlgorithm<Strategy>::lastOffsetInNode(Node* node) | 364 int PositionAlgorithm<Strategy>::lastOffsetInNode(Node* node) |
366 { | 365 { |
367 return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast
<int>(Strategy::countChildren(*node)); | 366 return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast
<int>(Strategy::countChildren(*node)); |
368 } | 367 } |
369 | 368 |
370 inline int lastOffsetInNode(Node* node) | 369 inline int lastOffsetInNode(Node* node) |
371 { | 370 { |
372 return Position::lastOffsetInNode(node); | 371 return Position::lastOffsetInNode(node); |
373 } | 372 } |
374 | 373 |
375 // firstPositionInNode and lastPositionInNode return parent-anchored positions,
lastPositionInNode construction is O(n) due to countChildren() | 374 // firstPositionInNode and lastPositionInNode return parent-anchored positions,
lastPositionInNode construction is O(n) due to countChildren() |
376 template <typename Strategy> | 375 template <typename Strategy> |
377 typename Strategy::PositionType PositionAlgorithm<Strategy>::firstPositionInNode
(Node* anchorNode) | 376 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::firstPositionInNode(Nod
e* anchorNode) |
378 { | 377 { |
379 if (anchorNode->isTextNode()) | 378 if (anchorNode->isTextNode()) |
380 return PositionType(anchorNode, 0); | 379 return PositionAlgorithm<Strategy>(anchorNode, 0); |
381 return PositionType(anchorNode, PositionIsBeforeChildren); | 380 return PositionAlgorithm<Strategy>(anchorNode, PositionIsBeforeChildren); |
382 } | 381 } |
383 | 382 |
384 inline Position firstPositionInNode(Node* anchorNode) | 383 inline Position firstPositionInNode(Node* anchorNode) |
385 { | 384 { |
386 return Position::firstPositionInNode(anchorNode); | 385 return Position::firstPositionInNode(anchorNode); |
387 } | 386 } |
388 | 387 |
389 template <typename Strategy> | 388 template <typename Strategy> |
390 typename Strategy::PositionType PositionAlgorithm<Strategy>::lastPositionInNode(
Node* anchorNode) | 389 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::lastPositionInNode(Node
* anchorNode) |
391 { | 390 { |
392 if (anchorNode->isTextNode()) | 391 if (anchorNode->isTextNode()) |
393 return PositionType(anchorNode, lastOffsetInNode(anchorNode)); | 392 return PositionAlgorithm<Strategy>(anchorNode, lastOffsetInNode(anchorNo
de)); |
394 return PositionType(anchorNode, PositionIsAfterChildren); | 393 return PositionAlgorithm<Strategy>(anchorNode, PositionIsAfterChildren); |
395 } | 394 } |
396 | 395 |
397 inline Position lastPositionInNode(Node* anchorNode) | 396 inline Position lastPositionInNode(Node* anchorNode) |
398 { | 397 { |
399 return Position::lastPositionInNode(anchorNode); | 398 return Position::lastPositionInNode(anchorNode); |
400 } | 399 } |
401 | 400 |
402 template <typename Strategy> | 401 template <typename Strategy> |
403 int PositionAlgorithm<Strategy>::minOffsetForNode(Node* anchorNode, int offset) | 402 int PositionAlgorithm<Strategy>::minOffsetForNode(Node* anchorNode, int offset) |
404 { | 403 { |
(...skipping 24 matching lines...) Expand all Loading... |
429 | 428 |
430 return offset < currentOffset; | 429 return offset < currentOffset; |
431 } | 430 } |
432 | 431 |
433 inline bool offsetIsBeforeLastNodeOffset(int offset, Node* anchorNode) | 432 inline bool offsetIsBeforeLastNodeOffset(int offset, Node* anchorNode) |
434 { | 433 { |
435 return Position::offsetIsBeforeLastNodeOffset(offset, anchorNode); | 434 return Position::offsetIsBeforeLastNodeOffset(offset, anchorNode); |
436 } | 435 } |
437 | 436 |
438 template <typename Strategy> | 437 template <typename Strategy> |
439 typename Strategy::PositionType PositionAlgorithm<Strategy>::firstPositionInOrBe
foreNode(Node* node) | 438 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::firstPositionInOrBefore
Node(Node* node) |
440 { | 439 { |
441 if (!node) | 440 if (!node) |
442 return PositionType(); | 441 return PositionAlgorithm<Strategy>(); |
443 return Strategy::editingIgnoresContent(node) ? beforeNode(node) : firstPosit
ionInNode(node); | 442 return Strategy::editingIgnoresContent(node) ? beforeNode(node) : firstPosit
ionInNode(node); |
444 } | 443 } |
445 | 444 |
446 template <typename Strategy> | 445 template <typename Strategy> |
447 typename Strategy::PositionType PositionAlgorithm<Strategy>::lastPositionInOrAft
erNode(Node* node) | 446 PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::lastPositionInOrAfterNo
de(Node* node) |
448 { | 447 { |
449 if (!node) | 448 if (!node) |
450 return PositionType(); | 449 return PositionAlgorithm<Strategy>(); |
451 return Strategy::editingIgnoresContent(node) ? afterNode(node) : lastPositio
nInNode(node); | 450 return Strategy::editingIgnoresContent(node) ? afterNode(node) : lastPositio
nInNode(node); |
452 } | 451 } |
453 | 452 |
454 PositionInComposedTree toPositionInComposedTree(const Position&); | 453 PositionInComposedTree toPositionInComposedTree(const Position&); |
455 Position toPositionInDOMTree(const Position&); | 454 Position toPositionInDOMTree(const Position&); |
456 Position toPositionInDOMTree(const PositionInComposedTree&); | 455 Position toPositionInDOMTree(const PositionInComposedTree&); |
457 | 456 |
458 } // namespace blink | 457 } // namespace blink |
459 | 458 |
460 #ifndef NDEBUG | 459 #ifndef NDEBUG |
461 // Outside the WebCore namespace for ease of invocation from gdb. | 460 // Outside the WebCore namespace for ease of invocation from gdb. |
462 void showTree(const blink::Position&); | 461 void showTree(const blink::Position&); |
463 void showTree(const blink::Position*); | 462 void showTree(const blink::Position*); |
464 #endif | 463 #endif |
465 | 464 |
466 #endif // Position_h | 465 #endif // Position_h |
OLD | NEW |