| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 , m_offsetInAnchor(0) | 60 , m_offsetInAnchor(0) |
| 61 , m_depthToAnchorNode(0) | 61 , m_depthToAnchorNode(0) |
| 62 , m_domTreeVersion(0) | 62 , m_domTreeVersion(0) |
| 63 { | 63 { |
| 64 } | 64 } |
| 65 | 65 |
| 66 template <typename Strategy> | 66 template <typename Strategy> |
| 67 PositionTemplate<Strategy> PositionIteratorAlgorithm<Strategy>::deprecatedComput
ePosition() const | 67 PositionTemplate<Strategy> PositionIteratorAlgorithm<Strategy>::deprecatedComput
ePosition() const |
| 68 { | 68 { |
| 69 // TODO(yoichio): Share code to check domTreeVersion with EphemeralRange. | 69 // TODO(yoichio): Share code to check domTreeVersion with EphemeralRange. |
| 70 ASSERT(isValid()); | 70 DCHECK(isValid()); |
| 71 if (m_nodeAfterPositionInAnchor) { | 71 if (m_nodeAfterPositionInAnchor) { |
| 72 ASSERT(Strategy::parent(*m_nodeAfterPositionInAnchor) == m_anchorNode); | 72 DCHECK_EQ(Strategy::parent(*m_nodeAfterPositionInAnchor), m_anchorNode); |
| 73 ASSERT(m_offsetsInAnchorNode[m_depthToAnchorNode] != kInvalidOffset); | 73 DCHECK_NE(m_offsetsInAnchorNode[m_depthToAnchorNode], kInvalidOffset); |
| 74 // FIXME: This check is inadaquete because any ancestor could be ignored
by editing | 74 // FIXME: This check is inadaquete because any ancestor could be ignored
by editing |
| 75 if (Strategy::editingIgnoresContent(Strategy::parent(*m_nodeAfterPositio
nInAnchor))) | 75 if (Strategy::editingIgnoresContent(Strategy::parent(*m_nodeAfterPositio
nInAnchor))) |
| 76 return PositionTemplate<Strategy>::beforeNode(m_anchorNode); | 76 return PositionTemplate<Strategy>::beforeNode(m_anchorNode); |
| 77 return PositionTemplate<Strategy>(m_anchorNode, m_offsetsInAnchorNode[m_
depthToAnchorNode]); | 77 return PositionTemplate<Strategy>(m_anchorNode, m_offsetsInAnchorNode[m_
depthToAnchorNode]); |
| 78 } | 78 } |
| 79 if (Strategy::hasChildren(*m_anchorNode)) | 79 if (Strategy::hasChildren(*m_anchorNode)) |
| 80 return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNod
e); | 80 return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNod
e); |
| 81 return PositionTemplate<Strategy>::editingPositionOf(m_anchorNode, m_offsetI
nAnchor); | 81 return PositionTemplate<Strategy>::editingPositionOf(m_anchorNode, m_offsetI
nAnchor); |
| 82 } | 82 } |
| 83 | 83 |
| 84 template <typename Strategy> | 84 template <typename Strategy> |
| 85 PositionTemplate<Strategy> PositionIteratorAlgorithm<Strategy>::computePosition(
) const | 85 PositionTemplate<Strategy> PositionIteratorAlgorithm<Strategy>::computePosition(
) const |
| 86 { | 86 { |
| 87 ASSERT(isValid()); | 87 DCHECK(isValid()); |
| 88 // Assume that we have the following DOM tree: | 88 // Assume that we have the following DOM tree: |
| 89 // A | 89 // A |
| 90 // |-B | 90 // |-B |
| 91 // | |-E | 91 // | |-E |
| 92 // | +-F | 92 // | +-F |
| 93 // | | 93 // | |
| 94 // |-C | 94 // |-C |
| 95 // +-D | 95 // +-D |
| 96 // |-G | 96 // |-G |
| 97 // +-H | 97 // +-H |
| 98 if (m_nodeAfterPositionInAnchor) { | 98 if (m_nodeAfterPositionInAnchor) { |
| 99 // For example, position is before E, F. | 99 // For example, position is before E, F. |
| 100 ASSERT(Strategy::parent(*m_nodeAfterPositionInAnchor) == m_anchorNode); | 100 DCHECK_EQ(Strategy::parent(*m_nodeAfterPositionInAnchor), m_anchorNode); |
| 101 ASSERT(m_offsetsInAnchorNode[m_depthToAnchorNode] != kInvalidOffset); | 101 DCHECK_NE(m_offsetsInAnchorNode[m_depthToAnchorNode], kInvalidOffset); |
| 102 // TODO(yoichio): This should be equivalent to | 102 // TODO(yoichio): This should be equivalent to |
| 103 // PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::BeforeAn
chor); | 103 // PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::BeforeAn
chor); |
| 104 return PositionTemplate<Strategy>(m_anchorNode, m_offsetsInAnchorNode[m_
depthToAnchorNode]); | 104 return PositionTemplate<Strategy>(m_anchorNode, m_offsetsInAnchorNode[m_
depthToAnchorNode]); |
| 105 } | 105 } |
| 106 if (Strategy::hasChildren(*m_anchorNode)) | 106 if (Strategy::hasChildren(*m_anchorNode)) |
| 107 // For example, position is the end of B. | 107 // For example, position is the end of B. |
| 108 return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNod
e); | 108 return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNod
e); |
| 109 if (m_anchorNode->isTextNode()) | 109 if (m_anchorNode->isTextNode()) |
| 110 return PositionTemplate<Strategy>(m_anchorNode, m_offsetInAnchor); | 110 return PositionTemplate<Strategy>(m_anchorNode, m_offsetInAnchor); |
| 111 if (m_offsetInAnchor) | 111 if (m_offsetInAnchor) |
| 112 // For example, position is after G. | 112 // For example, position is after G. |
| 113 return PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::Afte
rAnchor); | 113 return PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::Afte
rAnchor); |
| 114 // For example, position is before G. | 114 // For example, position is before G. |
| 115 return PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::BeforeAn
chor); | 115 return PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::BeforeAn
chor); |
| 116 } | 116 } |
| 117 | 117 |
| 118 template <typename Strategy> | 118 template <typename Strategy> |
| 119 void PositionIteratorAlgorithm<Strategy>::increment() | 119 void PositionIteratorAlgorithm<Strategy>::increment() |
| 120 { | 120 { |
| 121 ASSERT(isValid()); | 121 DCHECK(isValid()); |
| 122 if (!m_anchorNode) | 122 if (!m_anchorNode) |
| 123 return; | 123 return; |
| 124 | 124 |
| 125 // Assume that we have the following DOM tree: | 125 // Assume that we have the following DOM tree: |
| 126 // A | 126 // A |
| 127 // |-B | 127 // |-B |
| 128 // | |-E | 128 // | |-E |
| 129 // | +-F | 129 // | +-F |
| 130 // | | 130 // | |
| 131 // |-C | 131 // |-C |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 // Case #3. This is the next of Case #2 or #3. | 163 // Case #3. This is the next of Case #2 or #3. |
| 164 // Position is the end of |anchor|. | 164 // Position is the end of |anchor|. |
| 165 // 3-a. If |anchor| has next sibling (let E), | 165 // 3-a. If |anchor| has next sibling (let E), |
| 166 // next |anchor| is B and |child| is F (next is Case #1.) | 166 // next |anchor| is B and |child| is F (next is Case #1.) |
| 167 // 3-b. If |anchor| doesn't have next sibling (let F), | 167 // 3-b. If |anchor| doesn't have next sibling (let F), |
| 168 // next |anchor| is B and |child| is null. (next is Case #3.) | 168 // next |anchor| is B and |child| is null. (next is Case #3.) |
| 169 m_nodeAfterPositionInAnchor = m_anchorNode; | 169 m_nodeAfterPositionInAnchor = m_anchorNode; |
| 170 m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); | 170 m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); |
| 171 if (!m_anchorNode) | 171 if (!m_anchorNode) |
| 172 return; | 172 return; |
| 173 ASSERT(m_depthToAnchorNode > 0); | 173 DCHECK_GT(m_depthToAnchorNode, 0u); |
| 174 --m_depthToAnchorNode; | 174 --m_depthToAnchorNode; |
| 175 // Increment offset of |child| or initialize if it have never been | 175 // Increment offset of |child| or initialize if it have never been |
| 176 // used. | 176 // used. |
| 177 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) | 177 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) |
| 178 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_node
AfterPositionInAnchor) + 1; | 178 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_node
AfterPositionInAnchor) + 1; |
| 179 else | 179 else |
| 180 ++m_offsetsInAnchorNode[m_depthToAnchorNode]; | 180 ++m_offsetsInAnchorNode[m_depthToAnchorNode]; |
| 181 m_nodeAfterPositionInAnchor = Strategy::nextSibling(*m_nodeAfterPosition
InAnchor); | 181 m_nodeAfterPositionInAnchor = Strategy::nextSibling(*m_nodeAfterPosition
InAnchor); |
| 182 m_offsetInAnchor = 0; | 182 m_offsetInAnchor = 0; |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 | 185 |
| 186 template <typename Strategy> | 186 template <typename Strategy> |
| 187 void PositionIteratorAlgorithm<Strategy>::decrement() | 187 void PositionIteratorAlgorithm<Strategy>::decrement() |
| 188 { | 188 { |
| 189 ASSERT(isValid()); | 189 DCHECK(isValid()); |
| 190 if (!m_anchorNode) | 190 if (!m_anchorNode) |
| 191 return; | 191 return; |
| 192 | 192 |
| 193 // Assume that we have the following DOM tree: | 193 // Assume that we have the following DOM tree: |
| 194 // A | 194 // A |
| 195 // |-B | 195 // |-B |
| 196 // | |-E | 196 // | |-E |
| 197 // | +-F | 197 // | +-F |
| 198 // | | 198 // | |
| 199 // |-C | 199 // |-C |
| (...skipping 11 matching lines...) Expand all Loading... |
| 211 // Let |anchor| is B and |child| is F, | 211 // Let |anchor| is B and |child| is F, |
| 212 // next |anchor| is E and |child| is null. | 212 // next |anchor| is E and |child| is null. |
| 213 m_nodeAfterPositionInAnchor = nullptr; | 213 m_nodeAfterPositionInAnchor = nullptr; |
| 214 m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode) ? 0 : Strate
gy::lastOffsetForEditing(m_anchorNode); | 214 m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode) ? 0 : Strate
gy::lastOffsetForEditing(m_anchorNode); |
| 215 // Decrement offset of |child| or initialize if it have never been | 215 // Decrement offset of |child| or initialize if it have never been |
| 216 // used. | 216 // used. |
| 217 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) | 217 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) |
| 218 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_
nodeAfterPositionInAnchor); | 218 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_
nodeAfterPositionInAnchor); |
| 219 else | 219 else |
| 220 --m_offsetsInAnchorNode[m_depthToAnchorNode]; | 220 --m_offsetsInAnchorNode[m_depthToAnchorNode]; |
| 221 ASSERT(m_offsetsInAnchorNode[m_depthToAnchorNode] >= 0); | 221 DCHECK_GE(m_offsetsInAnchorNode[m_depthToAnchorNode], 0); |
| 222 // Increment depth intializing with last offset. | 222 // Increment depth intializing with last offset. |
| 223 ++m_depthToAnchorNode; | 223 ++m_depthToAnchorNode; |
| 224 if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) | 224 if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) |
| 225 m_offsetsInAnchorNode.append(m_offsetInAnchor); | 225 m_offsetsInAnchorNode.append(m_offsetInAnchor); |
| 226 else | 226 else |
| 227 m_offsetsInAnchorNode[m_depthToAnchorNode] = m_offsetInAnchor; | 227 m_offsetsInAnchorNode[m_depthToAnchorNode] = m_offsetInAnchor; |
| 228 return; | 228 return; |
| 229 } else { | 229 } else { |
| 230 // Case #1-b. This is a revese of increment()::Case#1. | 230 // Case #1-b. This is a revese of increment()::Case#1. |
| 231 // |child| doesn't have a previous sibling. | 231 // |child| doesn't have a previous sibling. |
| 232 // Let |anchor| is B and |child| is E, | 232 // Let |anchor| is B and |child| is E, |
| 233 // next |anchor| is A and |child| is B. | 233 // next |anchor| is A and |child| is B. |
| 234 m_nodeAfterPositionInAnchor = Strategy::parent(*m_nodeAfterPositionI
nAnchor); | 234 m_nodeAfterPositionInAnchor = Strategy::parent(*m_nodeAfterPositionI
nAnchor); |
| 235 m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); | 235 m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); |
| 236 if (!m_anchorNode) | 236 if (!m_anchorNode) |
| 237 return; | 237 return; |
| 238 m_offsetInAnchor = 0; | 238 m_offsetInAnchor = 0; |
| 239 // Decrement depth and intialize if needs. | 239 // Decrement depth and intialize if needs. |
| 240 ASSERT(m_depthToAnchorNode > 0); | 240 DCHECK_GT(m_depthToAnchorNode, 0u); |
| 241 --m_depthToAnchorNode; | 241 --m_depthToAnchorNode; |
| 242 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) | 242 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) |
| 243 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_
nodeAfterPositionInAnchor); | 243 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_
nodeAfterPositionInAnchor); |
| 244 } | 244 } |
| 245 return; | 245 return; |
| 246 } | 246 } |
| 247 | 247 |
| 248 if (Strategy::hasChildren(*m_anchorNode)) { | 248 if (Strategy::hasChildren(*m_anchorNode)) { |
| 249 // Case #2. This is a reverse of increment()::Case3-b. | 249 // Case #2. This is a reverse of increment()::Case3-b. |
| 250 // Let |anchor| is B, next |anchor| is F. | 250 // Let |anchor| is B, next |anchor| is F. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 269 } else { | 269 } else { |
| 270 // Case #3-b. This is a reverse of increment()::Case#1. | 270 // Case #3-b. This is a reverse of increment()::Case#1. |
| 271 // In this case |anchor| is a leaf(E,F,C,G or H) and | 271 // In this case |anchor| is a leaf(E,F,C,G or H) and |
| 272 // |m_offsetInAnchor| is on the beginning of |anchor|. | 272 // |m_offsetInAnchor| is on the beginning of |anchor|. |
| 273 // Let |anchor| is E, | 273 // Let |anchor| is E, |
| 274 // next |anchor| is B and |child| is E. | 274 // next |anchor| is B and |child| is E. |
| 275 m_nodeAfterPositionInAnchor = m_anchorNode; | 275 m_nodeAfterPositionInAnchor = m_anchorNode; |
| 276 m_anchorNode = Strategy::parent(*m_anchorNode); | 276 m_anchorNode = Strategy::parent(*m_anchorNode); |
| 277 if (!m_anchorNode) | 277 if (!m_anchorNode) |
| 278 return; | 278 return; |
| 279 ASSERT(m_depthToAnchorNode > 0); | 279 DCHECK_GT(m_depthToAnchorNode, 0u); |
| 280 --m_depthToAnchorNode; | 280 --m_depthToAnchorNode; |
| 281 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) | 281 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) |
| 282 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_
nodeAfterPositionInAnchor); | 282 m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_
nodeAfterPositionInAnchor); |
| 283 } | 283 } |
| 284 } | 284 } |
| 285 } | 285 } |
| 286 | 286 |
| 287 template <typename Strategy> | 287 template <typename Strategy> |
| 288 bool PositionIteratorAlgorithm<Strategy>::atStart() const | 288 bool PositionIteratorAlgorithm<Strategy>::atStart() const |
| 289 { | 289 { |
| 290 ASSERT(isValid()); | 290 DCHECK(isValid()); |
| 291 if (!m_anchorNode) | 291 if (!m_anchorNode) |
| 292 return true; | 292 return true; |
| 293 if (Strategy::parent(*m_anchorNode)) | 293 if (Strategy::parent(*m_anchorNode)) |
| 294 return false; | 294 return false; |
| 295 return (!Strategy::hasChildren(*m_anchorNode) && !m_offsetInAnchor) || (m_no
deAfterPositionInAnchor && !Strategy::previousSibling(*m_nodeAfterPositionInAnch
or)); | 295 return (!Strategy::hasChildren(*m_anchorNode) && !m_offsetInAnchor) || (m_no
deAfterPositionInAnchor && !Strategy::previousSibling(*m_nodeAfterPositionInAnch
or)); |
| 296 } | 296 } |
| 297 | 297 |
| 298 template <typename Strategy> | 298 template <typename Strategy> |
| 299 bool PositionIteratorAlgorithm<Strategy>::atEnd() const | 299 bool PositionIteratorAlgorithm<Strategy>::atEnd() const |
| 300 { | 300 { |
| 301 ASSERT(isValid()); | 301 DCHECK(isValid()); |
| 302 if (!m_anchorNode) | 302 if (!m_anchorNode) |
| 303 return true; | 303 return true; |
| 304 if (m_nodeAfterPositionInAnchor) | 304 if (m_nodeAfterPositionInAnchor) |
| 305 return false; | 305 return false; |
| 306 return !Strategy::parent(*m_anchorNode) && (Strategy::hasChildren(*m_anchorN
ode) || m_offsetInAnchor >= Strategy::lastOffsetForEditing(m_anchorNode)); | 306 return !Strategy::parent(*m_anchorNode) && (Strategy::hasChildren(*m_anchorN
ode) || m_offsetInAnchor >= Strategy::lastOffsetForEditing(m_anchorNode)); |
| 307 } | 307 } |
| 308 | 308 |
| 309 template <typename Strategy> | 309 template <typename Strategy> |
| 310 bool PositionIteratorAlgorithm<Strategy>::atStartOfNode() const | 310 bool PositionIteratorAlgorithm<Strategy>::atStartOfNode() const |
| 311 { | 311 { |
| 312 ASSERT(isValid()); | 312 DCHECK(isValid()); |
| 313 if (!m_anchorNode) | 313 if (!m_anchorNode) |
| 314 return true; | 314 return true; |
| 315 if (!m_nodeAfterPositionInAnchor) | 315 if (!m_nodeAfterPositionInAnchor) |
| 316 return !Strategy::hasChildren(*m_anchorNode) && !m_offsetInAnchor; | 316 return !Strategy::hasChildren(*m_anchorNode) && !m_offsetInAnchor; |
| 317 return !Strategy::previousSibling(*m_nodeAfterPositionInAnchor); | 317 return !Strategy::previousSibling(*m_nodeAfterPositionInAnchor); |
| 318 } | 318 } |
| 319 | 319 |
| 320 template <typename Strategy> | 320 template <typename Strategy> |
| 321 bool PositionIteratorAlgorithm<Strategy>::atEndOfNode() const | 321 bool PositionIteratorAlgorithm<Strategy>::atEndOfNode() const |
| 322 { | 322 { |
| 323 ASSERT(isValid()); | 323 DCHECK(isValid()); |
| 324 if (!m_anchorNode) | 324 if (!m_anchorNode) |
| 325 return true; | 325 return true; |
| 326 if (m_nodeAfterPositionInAnchor) | 326 if (m_nodeAfterPositionInAnchor) |
| 327 return false; | 327 return false; |
| 328 return Strategy::hasChildren(*m_anchorNode) || m_offsetInAnchor >= Strategy:
:lastOffsetForEditing(m_anchorNode); | 328 return Strategy::hasChildren(*m_anchorNode) || m_offsetInAnchor >= Strategy:
:lastOffsetForEditing(m_anchorNode); |
| 329 } | 329 } |
| 330 | 330 |
| 331 template class PositionIteratorAlgorithm<EditingStrategy>; | 331 template class PositionIteratorAlgorithm<EditingStrategy>; |
| 332 template class PositionIteratorAlgorithm<EditingInFlatTreeStrategy>; | 332 template class PositionIteratorAlgorithm<EditingInFlatTreeStrategy>; |
| 333 | 333 |
| 334 } // namespace blink | 334 } // namespace blink |
| OLD | NEW |