| 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 |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 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/PositionIterator.h" | 26 #include "core/editing/PositionIterator.h" |
| 27 | 27 |
| 28 #include "core/editing/EditingUtilities.h" |
| 29 |
| 28 namespace blink { | 30 namespace blink { |
| 29 | 31 |
| 32 namespace { |
| 33 |
| 34 // TODO(editing-dev): We should replace usages of |hasChildren()| in |
| 35 // |PositionIterator| to |shouldTraverseChildren()|. |
| 36 template <typename Strategy> |
| 37 bool shouldTraverseChildren(const Node& node) { |
| 38 return Strategy::hasChildren(node) && !isUserSelectContain(node); |
| 39 } |
| 40 |
| 41 // TODO(editing-dev): We should replace usages of |parent()| in |
| 42 // |PositionIterator| to |selectableParentOf()|. |
| 43 template <typename Strategy> |
| 44 ContainerNode* selectableParentOf(const Node& node) { |
| 45 ContainerNode* const parent = Strategy::parent(node); |
| 46 return parent && !isUserSelectContain(*parent) ? parent : nullptr; |
| 47 } |
| 48 |
| 49 } // namespace |
| 50 |
| 30 static const int kInvalidOffset = -1; | 51 static const int kInvalidOffset = -1; |
| 31 | 52 |
| 32 template <typename Strategy> | 53 template <typename Strategy> |
| 33 PositionIteratorAlgorithm<Strategy>::PositionIteratorAlgorithm( | 54 PositionIteratorAlgorithm<Strategy>::PositionIteratorAlgorithm( |
| 34 Node* anchorNode, | 55 Node* anchorNode, |
| 35 int offsetInAnchor) | 56 int offsetInAnchor) |
| 36 : m_anchorNode(anchorNode), | 57 : m_anchorNode(anchorNode), |
| 37 m_nodeAfterPositionInAnchor( | 58 m_nodeAfterPositionInAnchor( |
| 38 Strategy::childAt(*anchorNode, offsetInAnchor)), | 59 Strategy::childAt(*anchorNode, offsetInAnchor)), |
| 39 m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : offsetInAnchor), | 60 m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : offsetInAnchor), |
| 40 m_depthToAnchorNode(0), | 61 m_depthToAnchorNode(0), |
| 41 m_domTreeVersion(anchorNode->document().domTreeVersion()) { | 62 m_domTreeVersion(anchorNode->document().domTreeVersion()) { |
| 42 for (Node* node = Strategy::parent(*anchorNode); node; | 63 for (Node* node = selectableParentOf<Strategy>(*anchorNode); node; |
| 43 node = Strategy::parent(*node)) { | 64 node = selectableParentOf<Strategy>(*node)) { |
| 44 // Each m_offsetsInAnchorNode[offset] should be an index of node in | 65 // Each m_offsetsInAnchorNode[offset] should be an index of node in |
| 45 // parent, but delay to calculate the index until it is needed for | 66 // parent, but delay to calculate the index until it is needed for |
| 46 // performance. | 67 // performance. |
| 47 m_offsetsInAnchorNode.push_back(kInvalidOffset); | 68 m_offsetsInAnchorNode.push_back(kInvalidOffset); |
| 48 ++m_depthToAnchorNode; | 69 ++m_depthToAnchorNode; |
| 49 } | 70 } |
| 50 if (m_nodeAfterPositionInAnchor) | 71 if (m_nodeAfterPositionInAnchor) |
| 51 m_offsetsInAnchorNode.push_back(offsetInAnchor); | 72 m_offsetsInAnchorNode.push_back(offsetInAnchor); |
| 52 } | 73 } |
| 53 template <typename Strategy> | 74 template <typename Strategy> |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 if (m_nodeAfterPositionInAnchor) { | 122 if (m_nodeAfterPositionInAnchor) { |
| 102 // For example, position is before E, F. | 123 // For example, position is before E, F. |
| 103 DCHECK_EQ(Strategy::parent(*m_nodeAfterPositionInAnchor), m_anchorNode); | 124 DCHECK_EQ(Strategy::parent(*m_nodeAfterPositionInAnchor), m_anchorNode); |
| 104 DCHECK_NE(m_offsetsInAnchorNode[m_depthToAnchorNode], kInvalidOffset); | 125 DCHECK_NE(m_offsetsInAnchorNode[m_depthToAnchorNode], kInvalidOffset); |
| 105 // TODO(yoichio): This should be equivalent to | 126 // TODO(yoichio): This should be equivalent to |
| 106 // PositionTemplate<Strategy>(m_anchorNode, | 127 // PositionTemplate<Strategy>(m_anchorNode, |
| 107 // PositionAnchorType::BeforeAnchor); | 128 // PositionAnchorType::BeforeAnchor); |
| 108 return PositionTemplate<Strategy>( | 129 return PositionTemplate<Strategy>( |
| 109 m_anchorNode, m_offsetsInAnchorNode[m_depthToAnchorNode]); | 130 m_anchorNode, m_offsetsInAnchorNode[m_depthToAnchorNode]); |
| 110 } | 131 } |
| 111 if (Strategy::hasChildren(*m_anchorNode)) | 132 if (shouldTraverseChildren<Strategy>(*m_anchorNode)) |
| 112 // For example, position is the end of B. | 133 // For example, position is the end of B. |
| 113 return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNode); | 134 return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNode); |
| 114 if (m_anchorNode->isTextNode()) | 135 if (m_anchorNode->isTextNode()) |
| 115 return PositionTemplate<Strategy>(m_anchorNode, m_offsetInAnchor); | 136 return PositionTemplate<Strategy>(m_anchorNode, m_offsetInAnchor); |
| 116 if (m_offsetInAnchor) | 137 if (m_offsetInAnchor) |
| 117 // For example, position is after G. | 138 // For example, position is after G. |
| 118 return PositionTemplate<Strategy>(m_anchorNode, | 139 return PositionTemplate<Strategy>(m_anchorNode, |
| 119 PositionAnchorType::AfterAnchor); | 140 PositionAnchorType::AfterAnchor); |
| 120 // For example, position is before G. | 141 // For example, position is before G. |
| 121 return PositionTemplate<Strategy>(m_anchorNode, | 142 return PositionTemplate<Strategy>(m_anchorNode, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 140 // +-H | 161 // +-H |
| 141 // Let |anchor| as |m_anchorNode| and | 162 // Let |anchor| as |m_anchorNode| and |
| 142 // |child| as |m_nodeAfterPositionInAnchor|. | 163 // |child| as |m_nodeAfterPositionInAnchor|. |
| 143 if (m_nodeAfterPositionInAnchor) { | 164 if (m_nodeAfterPositionInAnchor) { |
| 144 // Case #1: Move to position before the first child of | 165 // Case #1: Move to position before the first child of |
| 145 // |m_nodeAfterPositionInAnchor|. | 166 // |m_nodeAfterPositionInAnchor|. |
| 146 // This is a point just before |child|. | 167 // This is a point just before |child|. |
| 147 // Let |anchor| is A and |child| is B, | 168 // Let |anchor| is A and |child| is B, |
| 148 // then next |anchor| is B and |child| is E. | 169 // then next |anchor| is B and |child| is E. |
| 149 m_anchorNode = m_nodeAfterPositionInAnchor; | 170 m_anchorNode = m_nodeAfterPositionInAnchor; |
| 150 m_nodeAfterPositionInAnchor = Strategy::firstChild(*m_anchorNode); | 171 m_nodeAfterPositionInAnchor = |
| 172 shouldTraverseChildren<Strategy>(*m_anchorNode) |
| 173 ? Strategy::firstChild(*m_anchorNode) |
| 174 : nullptr; |
| 151 m_offsetInAnchor = 0; | 175 m_offsetInAnchor = 0; |
| 152 // Increment depth intializing with 0. | 176 // Increment depth intializing with 0. |
| 153 ++m_depthToAnchorNode; | 177 ++m_depthToAnchorNode; |
| 154 if (m_depthToAnchorNode == m_offsetsInAnchorNode.size()) | 178 if (m_depthToAnchorNode == m_offsetsInAnchorNode.size()) |
| 155 m_offsetsInAnchorNode.push_back(0); | 179 m_offsetsInAnchorNode.push_back(0); |
| 156 else | 180 else |
| 157 m_offsetsInAnchorNode[m_depthToAnchorNode] = 0; | 181 m_offsetsInAnchorNode[m_depthToAnchorNode] = 0; |
| 158 return; | 182 return; |
| 159 } | 183 } |
| 160 | 184 |
| 161 if (m_anchorNode->layoutObject() && !Strategy::hasChildren(*m_anchorNode) && | 185 if (m_anchorNode->layoutObject() && |
| 186 !shouldTraverseChildren<Strategy>(*m_anchorNode) && |
| 162 m_offsetInAnchor < Strategy::lastOffsetForEditing(m_anchorNode)) { | 187 m_offsetInAnchor < Strategy::lastOffsetForEditing(m_anchorNode)) { |
| 163 // Case #2. This is the next of Case #1 or #2 itself. | 188 // Case #2. This is the next of Case #1 or #2 itself. |
| 164 // Position is (|anchor|, |m_offsetInAchor|). | 189 // Position is (|anchor|, |m_offsetInAchor|). |
| 165 // In this case |anchor| is a leaf(E,F,C,G or H) and | 190 // In this case |anchor| is a leaf(E,F,C,G or H) and |
| 166 // |m_offsetInAnchor| is not on the end of |anchor|. | 191 // |m_offsetInAnchor| is not on the end of |anchor|. |
| 167 // Then just increment |m_offsetInAnchor|. | 192 // Then just increment |m_offsetInAnchor|. |
| 168 m_offsetInAnchor = nextGraphemeBoundaryOf(m_anchorNode, m_offsetInAnchor); | 193 m_offsetInAnchor = nextGraphemeBoundaryOf(m_anchorNode, m_offsetInAnchor); |
| 169 } else { | 194 } else { |
| 170 // Case #3. This is the next of Case #2 or #3. | 195 // Case #3. This is the next of Case #2 or #3. |
| 171 // Position is the end of |anchor|. | 196 // Position is the end of |anchor|. |
| 172 // 3-a. If |anchor| has next sibling (let E), | 197 // 3-a. If |anchor| has next sibling (let E), |
| 173 // next |anchor| is B and |child| is F (next is Case #1.) | 198 // next |anchor| is B and |child| is F (next is Case #1.) |
| 174 // 3-b. If |anchor| doesn't have next sibling (let F), | 199 // 3-b. If |anchor| doesn't have next sibling (let F), |
| 175 // next |anchor| is B and |child| is null. (next is Case #3.) | 200 // next |anchor| is B and |child| is null. (next is Case #3.) |
| 176 m_nodeAfterPositionInAnchor = m_anchorNode; | 201 m_nodeAfterPositionInAnchor = m_anchorNode; |
| 177 m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); | 202 m_anchorNode = selectableParentOf<Strategy>(*m_nodeAfterPositionInAnchor); |
| 178 if (!m_anchorNode) | 203 if (!m_anchorNode) |
| 179 return; | 204 return; |
| 180 DCHECK_GT(m_depthToAnchorNode, 0u); | 205 DCHECK_GT(m_depthToAnchorNode, 0u); |
| 181 --m_depthToAnchorNode; | 206 --m_depthToAnchorNode; |
| 182 // Increment offset of |child| or initialize if it have never been | 207 // Increment offset of |child| or initialize if it have never been |
| 183 // used. | 208 // used. |
| 184 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) | 209 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) |
| 185 m_offsetsInAnchorNode[m_depthToAnchorNode] = | 210 m_offsetsInAnchorNode[m_depthToAnchorNode] = |
| 186 Strategy::index(*m_nodeAfterPositionInAnchor) + 1; | 211 Strategy::index(*m_nodeAfterPositionInAnchor) + 1; |
| 187 else | 212 else |
| (...skipping 24 matching lines...) Expand all Loading... |
| 212 // |child| as |m_nodeAfterPositionInAnchor|. | 237 // |child| as |m_nodeAfterPositionInAnchor|. |
| 213 // decrement() is complex but logically reverse of increment(), of course:) | 238 // decrement() is complex but logically reverse of increment(), of course:) |
| 214 if (m_nodeAfterPositionInAnchor) { | 239 if (m_nodeAfterPositionInAnchor) { |
| 215 m_anchorNode = Strategy::previousSibling(*m_nodeAfterPositionInAnchor); | 240 m_anchorNode = Strategy::previousSibling(*m_nodeAfterPositionInAnchor); |
| 216 if (m_anchorNode) { | 241 if (m_anchorNode) { |
| 217 // Case #1-a. This is a revese of increment()::Case#3-a. | 242 // Case #1-a. This is a revese of increment()::Case#3-a. |
| 218 // |child| has a previous sibling. | 243 // |child| has a previous sibling. |
| 219 // Let |anchor| is B and |child| is F, | 244 // Let |anchor| is B and |child| is F, |
| 220 // next |anchor| is E and |child| is null. | 245 // next |anchor| is E and |child| is null. |
| 221 m_nodeAfterPositionInAnchor = nullptr; | 246 m_nodeAfterPositionInAnchor = nullptr; |
| 222 m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode) | 247 m_offsetInAnchor = shouldTraverseChildren<Strategy>(*m_anchorNode) |
| 223 ? 0 | 248 ? 0 |
| 224 : Strategy::lastOffsetForEditing(m_anchorNode); | 249 : Strategy::lastOffsetForEditing(m_anchorNode); |
| 225 // Decrement offset of |child| or initialize if it have never been | 250 // Decrement offset of |child| or initialize if it have never been |
| 226 // used. | 251 // used. |
| 227 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) | 252 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) |
| 228 m_offsetsInAnchorNode[m_depthToAnchorNode] = | 253 m_offsetsInAnchorNode[m_depthToAnchorNode] = |
| 229 Strategy::index(*m_nodeAfterPositionInAnchor); | 254 Strategy::index(*m_nodeAfterPositionInAnchor); |
| 230 else | 255 else |
| 231 --m_offsetsInAnchorNode[m_depthToAnchorNode]; | 256 --m_offsetsInAnchorNode[m_depthToAnchorNode]; |
| 232 DCHECK_GE(m_offsetsInAnchorNode[m_depthToAnchorNode], 0); | 257 DCHECK_GE(m_offsetsInAnchorNode[m_depthToAnchorNode], 0); |
| 233 // Increment depth intializing with last offset. | 258 // Increment depth intializing with last offset. |
| 234 ++m_depthToAnchorNode; | 259 ++m_depthToAnchorNode; |
| 235 if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) | 260 if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) |
| 236 m_offsetsInAnchorNode.push_back(m_offsetInAnchor); | 261 m_offsetsInAnchorNode.push_back(m_offsetInAnchor); |
| 237 else | 262 else |
| 238 m_offsetsInAnchorNode[m_depthToAnchorNode] = m_offsetInAnchor; | 263 m_offsetsInAnchorNode[m_depthToAnchorNode] = m_offsetInAnchor; |
| 239 return; | 264 return; |
| 240 } else { | 265 } else { |
| 241 // Case #1-b. This is a revese of increment()::Case#1. | 266 // Case #1-b. This is a revese of increment()::Case#1. |
| 242 // |child| doesn't have a previous sibling. | 267 // |child| doesn't have a previous sibling. |
| 243 // Let |anchor| is B and |child| is E, | 268 // Let |anchor| is B and |child| is E, |
| 244 // next |anchor| is A and |child| is B. | 269 // next |anchor| is A and |child| is B. |
| 245 m_nodeAfterPositionInAnchor = | 270 m_nodeAfterPositionInAnchor = |
| 246 Strategy::parent(*m_nodeAfterPositionInAnchor); | 271 Strategy::parent(*m_nodeAfterPositionInAnchor); |
| 247 m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); | 272 m_anchorNode = selectableParentOf<Strategy>(*m_nodeAfterPositionInAnchor); |
| 248 if (!m_anchorNode) | 273 if (!m_anchorNode) |
| 249 return; | 274 return; |
| 250 m_offsetInAnchor = 0; | 275 m_offsetInAnchor = 0; |
| 251 // Decrement depth and intialize if needs. | 276 // Decrement depth and intialize if needs. |
| 252 DCHECK_GT(m_depthToAnchorNode, 0u); | 277 DCHECK_GT(m_depthToAnchorNode, 0u); |
| 253 --m_depthToAnchorNode; | 278 --m_depthToAnchorNode; |
| 254 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) | 279 if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) |
| 255 m_offsetsInAnchorNode[m_depthToAnchorNode] = | 280 m_offsetsInAnchorNode[m_depthToAnchorNode] = |
| 256 Strategy::index(*m_nodeAfterPositionInAnchor); | 281 Strategy::index(*m_nodeAfterPositionInAnchor); |
| 257 } | 282 } |
| 258 return; | 283 return; |
| 259 } | 284 } |
| 260 | 285 |
| 261 if (Strategy::hasChildren(*m_anchorNode)) { | 286 if (shouldTraverseChildren<Strategy>(*m_anchorNode)) { |
| 262 // Case #2. This is a reverse of increment()::Case3-b. | 287 // Case #2. This is a reverse of increment()::Case3-b. |
| 263 // Let |anchor| is B, next |anchor| is F. | 288 // Let |anchor| is B, next |anchor| is F. |
| 264 m_anchorNode = Strategy::lastChild(*m_anchorNode); | 289 m_anchorNode = Strategy::lastChild(*m_anchorNode); |
| 265 m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode) | 290 m_offsetInAnchor = shouldTraverseChildren<Strategy>(*m_anchorNode) |
| 266 ? 0 | 291 ? 0 |
| 267 : Strategy::lastOffsetForEditing(m_anchorNode); | 292 : Strategy::lastOffsetForEditing(m_anchorNode); |
| 268 // Decrement depth initializing with -1 because | 293 // Decrement depth initializing with -1 because |
| 269 // |m_nodeAfterPositionInAnchor| is null so still unneeded. | 294 // |m_nodeAfterPositionInAnchor| is null so still unneeded. |
| 270 if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) | 295 if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) |
| 271 m_offsetsInAnchorNode.push_back(kInvalidOffset); | 296 m_offsetsInAnchorNode.push_back(kInvalidOffset); |
| 272 else | 297 else |
| 273 m_offsetsInAnchorNode[m_depthToAnchorNode] = kInvalidOffset; | 298 m_offsetsInAnchorNode[m_depthToAnchorNode] = kInvalidOffset; |
| 274 ++m_depthToAnchorNode; | 299 ++m_depthToAnchorNode; |
| 275 return; | 300 return; |
| 276 } | 301 } |
| 277 | |
| 278 if (m_offsetInAnchor && m_anchorNode->layoutObject()) { | 302 if (m_offsetInAnchor && m_anchorNode->layoutObject()) { |
| 279 // Case #3-a. This is a reverse of increment()::Case#2. | 303 // Case #3-a. This is a reverse of increment()::Case#2. |
| 280 // In this case |anchor| is a leaf(E,F,C,G or H) and | 304 // In this case |anchor| is a leaf(E,F,C,G or H) and |
| 281 // |m_offsetInAnchor| is not on the beginning of |anchor|. | 305 // |m_offsetInAnchor| is not on the beginning of |anchor|. |
| 282 // Then just decrement |m_offsetInAnchor|. | 306 // Then just decrement |m_offsetInAnchor|. |
| 283 m_offsetInAnchor = | 307 m_offsetInAnchor = |
| 284 previousGraphemeBoundaryOf(m_anchorNode, m_offsetInAnchor); | 308 previousGraphemeBoundaryOf(m_anchorNode, m_offsetInAnchor); |
| 285 return; | 309 return; |
| 286 } | 310 } |
| 287 // Case #3-b. This is a reverse of increment()::Case#1. | 311 // Case #3-b. This is a reverse of increment()::Case#1. |
| 288 // In this case |anchor| is a leaf(E,F,C,G or H) and | 312 // In this case |anchor| is a leaf(E,F,C,G or H) and |
| 289 // |m_offsetInAnchor| is on the beginning of |anchor|. | 313 // |m_offsetInAnchor| is on the beginning of |anchor|. |
| 290 // Let |anchor| is E, | 314 // Let |anchor| is E, |
| 291 // next |anchor| is B and |child| is E. | 315 // next |anchor| is B and |child| is E. |
| 292 m_nodeAfterPositionInAnchor = m_anchorNode; | 316 m_nodeAfterPositionInAnchor = m_anchorNode; |
| 293 m_anchorNode = Strategy::parent(*m_anchorNode); | 317 m_anchorNode = selectableParentOf<Strategy>(*m_anchorNode); |
| 294 if (!m_anchorNode) | 318 if (!m_anchorNode) |
| 295 return; | 319 return; |
| 296 DCHECK_GT(m_depthToAnchorNode, 0u); | 320 DCHECK_GT(m_depthToAnchorNode, 0u); |
| 297 --m_depthToAnchorNode; | 321 --m_depthToAnchorNode; |
| 298 if (m_offsetsInAnchorNode[m_depthToAnchorNode] != kInvalidOffset) | 322 if (m_offsetsInAnchorNode[m_depthToAnchorNode] != kInvalidOffset) |
| 299 return; | 323 return; |
| 300 m_offsetsInAnchorNode[m_depthToAnchorNode] = | 324 m_offsetsInAnchorNode[m_depthToAnchorNode] = |
| 301 Strategy::index(*m_nodeAfterPositionInAnchor); | 325 Strategy::index(*m_nodeAfterPositionInAnchor); |
| 302 } | 326 } |
| 303 | 327 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 return false; | 368 return false; |
| 345 return Strategy::hasChildren(*m_anchorNode) || | 369 return Strategy::hasChildren(*m_anchorNode) || |
| 346 m_offsetInAnchor >= Strategy::lastOffsetForEditing(m_anchorNode); | 370 m_offsetInAnchor >= Strategy::lastOffsetForEditing(m_anchorNode); |
| 347 } | 371 } |
| 348 | 372 |
| 349 template class CORE_TEMPLATE_EXPORT PositionIteratorAlgorithm<EditingStrategy>; | 373 template class CORE_TEMPLATE_EXPORT PositionIteratorAlgorithm<EditingStrategy>; |
| 350 template class CORE_TEMPLATE_EXPORT | 374 template class CORE_TEMPLATE_EXPORT |
| 351 PositionIteratorAlgorithm<EditingInFlatTreeStrategy>; | 375 PositionIteratorAlgorithm<EditingInFlatTreeStrategy>; |
| 352 | 376 |
| 353 } // namespace blink | 377 } // namespace blink |
| OLD | NEW |