| 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 |