OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007 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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 { | 203 { |
204 // Since enclosingNodeOfType won't search beyond the highest root editable n
ode, | 204 // Since enclosingNodeOfType won't search beyond the highest root editable n
ode, |
205 // this code works even if the closest table cell was outside of the root ed
itable node. | 205 // this code works even if the closest table cell was outside of the root ed
itable node. |
206 Element* enclosingCell = toElement(enclosingNodeOfType(p, &isTableCell)); | 206 Element* enclosingCell = toElement(enclosingNodeOfType(p, &isTableCell)); |
207 if (enclosingCell) | 207 if (enclosingCell) |
208 return enclosingCell; | 208 return enclosingCell; |
209 | 209 |
210 return editableRootForPosition(p); | 210 return editableRootForPosition(p); |
211 } | 211 } |
212 | 212 |
213 Position nextCandidate(const Position& position) | 213 template <typename Strategy> |
| 214 typename Strategy::PositionType nextCandidateAlgorithm(const typename Strategy::
PositionType& position) |
214 { | 215 { |
215 PositionIterator p(position); | 216 using PositionType = typename Strategy::PositionType; |
| 217 typename Strategy::PositionIteratorType p(position); |
216 while (!p.atEnd()) { | 218 while (!p.atEnd()) { |
217 p.increment(); | 219 p.increment(); |
218 if (p.isCandidate()) | 220 if (p.isCandidate()) |
219 return p; | 221 return p; |
220 } | 222 } |
221 return Position(); | 223 return PositionType(); |
| 224 } |
| 225 |
| 226 Position nextCandidate(const Position& position) |
| 227 { |
| 228 return nextCandidateAlgorithm<EditingStrategy>(position); |
222 } | 229 } |
223 | 230 |
224 Position nextVisuallyDistinctCandidate(const Position& position) | 231 Position nextVisuallyDistinctCandidate(const Position& position) |
225 { | 232 { |
226 Position p = position; | 233 Position p = position; |
227 Position downstreamStart = p.downstream(); | 234 Position downstreamStart = p.downstream(); |
228 while (!p.atEndOfTree()) { | 235 while (!p.atEndOfTree()) { |
229 p = p.next(Character); | 236 p = p.next(Character); |
230 if (p.isCandidate() && p.downstream() != downstreamStart) | 237 if (p.isCandidate() && p.downstream() != downstreamStart) |
231 return p; | 238 return p; |
232 } | 239 } |
233 return Position(); | 240 return Position(); |
234 } | 241 } |
235 | 242 |
236 Position previousCandidate(const Position& position) | 243 template <typename Strategy> |
| 244 typename Strategy::PositionType previousCandidateAlgorithm(const typename Strate
gy::PositionType& position) |
237 { | 245 { |
238 PositionIterator p(position); | 246 using PositionType = typename Strategy::PositionType; |
| 247 typename Strategy::PositionIteratorType p(position); |
239 while (!p.atStart()) { | 248 while (!p.atStart()) { |
240 p.decrement(); | 249 p.decrement(); |
241 if (p.isCandidate()) | 250 if (p.isCandidate()) |
242 return p; | 251 return p; |
243 } | 252 } |
244 return Position(); | 253 return PositionType(); |
245 } | 254 } |
246 | 255 |
247 Position previousVisuallyDistinctCandidate(const Position& position) | 256 Position previousCandidate(const Position& position) |
248 { | 257 { |
249 Position p = position; | 258 return previousCandidateAlgorithm<EditingStrategy>(position); |
250 Position downstreamStart = p.downstream(); | 259 } |
| 260 |
| 261 template <typename PositionType> |
| 262 PositionType previousVisuallyDistinctCandidateAlgorithm(const PositionType& posi
tion) |
| 263 { |
| 264 PositionType p = position; |
| 265 PositionType downstreamStart = p.downstream(); |
251 while (!p.atStartOfTree()) { | 266 while (!p.atStartOfTree()) { |
252 p = p.previous(Character); | 267 p = p.previous(Character); |
253 if (p.isCandidate() && p.downstream() != downstreamStart) | 268 if (p.isCandidate() && p.downstream() != downstreamStart) |
254 return p; | 269 return p; |
255 } | 270 } |
256 return Position(); | 271 return PositionType(); |
| 272 } |
| 273 |
| 274 Position previousVisuallyDistinctCandidate(const Position& position) |
| 275 { |
| 276 return previousVisuallyDistinctCandidateAlgorithm<Position>(position); |
257 } | 277 } |
258 | 278 |
259 VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position&
position, ContainerNode* highestRoot) | 279 VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position&
position, ContainerNode* highestRoot) |
260 { | 280 { |
261 // position falls before highestRoot. | 281 // position falls before highestRoot. |
262 if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && hi
ghestRoot->hasEditableStyle()) | 282 if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && hi
ghestRoot->hasEditableStyle()) |
263 return VisiblePosition(firstPositionInNode(highestRoot)); | 283 return VisiblePosition(firstPositionInNode(highestRoot)); |
264 | 284 |
265 Position editablePosition = position; | 285 Position editablePosition = position; |
266 | 286 |
(...skipping 12 matching lines...) Expand all Loading... |
279 return VisiblePosition(); | 299 return VisiblePosition(); |
280 | 300 |
281 return VisiblePosition(editablePosition); | 301 return VisiblePosition(editablePosition); |
282 } | 302 } |
283 | 303 |
284 VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position&
position, ContainerNode* highestRoot) | 304 VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position&
position, ContainerNode* highestRoot) |
285 { | 305 { |
286 return VisiblePosition(lastEditablePositionBeforePositionInRoot(position, hi
ghestRoot)); | 306 return VisiblePosition(lastEditablePositionBeforePositionInRoot(position, hi
ghestRoot)); |
287 } | 307 } |
288 | 308 |
| 309 template <typename PositionType> |
| 310 PositionType lastEditablePositionBeforePositionInRootAlgorithm(const PositionTyp
e& position, Node* highestRoot) |
| 311 { |
| 312 // When position falls after highestRoot, the result is easy to compute. |
| 313 if (position.compareTo(PositionType::lastPositionInNode(highestRoot)) == 1) |
| 314 return PositionType::lastPositionInNode(highestRoot); |
| 315 |
| 316 PositionType editablePosition = position; |
| 317 |
| 318 if (position.deprecatedNode()->treeScope() != highestRoot->treeScope()) { |
| 319 Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(edit
ablePosition.deprecatedNode()); |
| 320 if (!shadowAncestor) |
| 321 return PositionType(); |
| 322 |
| 323 editablePosition = PositionType::firstPositionInOrBeforeNode(shadowAnces
tor); |
| 324 } |
| 325 |
| 326 while (editablePosition.deprecatedNode() && !isEditablePosition(editablePosi
tion) && editablePosition.deprecatedNode()->isDescendantOf(highestRoot)) |
| 327 editablePosition = isAtomicNode(editablePosition.deprecatedNode()) ? Pos
itionType::inParentBeforeNode(*editablePosition.deprecatedNode()) : previousVisu
allyDistinctCandidate(editablePosition); |
| 328 |
| 329 if (editablePosition.deprecatedNode() && editablePosition.deprecatedNode() !
= highestRoot && !editablePosition.deprecatedNode()->isDescendantOf(highestRoot)
) |
| 330 return PositionType(); |
| 331 return editablePosition; |
| 332 } |
| 333 |
289 Position lastEditablePositionBeforePositionInRoot(const Position& position, Node
* highestRoot) | 334 Position lastEditablePositionBeforePositionInRoot(const Position& position, Node
* highestRoot) |
290 { | 335 { |
291 // When position falls after highestRoot, the result is easy to compute. | 336 return lastEditablePositionBeforePositionInRootAlgorithm<Position>(position,
highestRoot); |
292 if (comparePositions(position, lastPositionInNode(highestRoot)) == 1) | |
293 return lastPositionInNode(highestRoot); | |
294 | |
295 Position editablePosition = position; | |
296 | |
297 if (position.deprecatedNode()->treeScope() != highestRoot->treeScope()) { | |
298 Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(edit
ablePosition.deprecatedNode()); | |
299 if (!shadowAncestor) | |
300 return Position(); | |
301 | |
302 editablePosition = firstPositionInOrBeforeNode(shadowAncestor); | |
303 } | |
304 | |
305 while (editablePosition.deprecatedNode() && !isEditablePosition(editablePosi
tion) && editablePosition.deprecatedNode()->isDescendantOf(highestRoot)) | |
306 editablePosition = isAtomicNode(editablePosition.deprecatedNode()) ? pos
itionInParentBeforeNode(*editablePosition.deprecatedNode()) : previousVisuallyDi
stinctCandidate(editablePosition); | |
307 | |
308 if (editablePosition.deprecatedNode() && editablePosition.deprecatedNode() !
= highestRoot && !editablePosition.deprecatedNode()->isDescendantOf(highestRoot)
) | |
309 return Position(); | |
310 return editablePosition; | |
311 } | 337 } |
312 | 338 |
313 // FIXME: The method name, comment, and code say three different things here! | 339 // FIXME: The method name, comment, and code say three different things here! |
314 // Whether or not content before and after this node will collapse onto the same
line as it. | 340 // Whether or not content before and after this node will collapse onto the same
line as it. |
315 bool isBlock(const Node* node) | 341 bool isBlock(const Node* node) |
316 { | 342 { |
317 return node && node->layoutObject() && !node->layoutObject()->isInline() &&
!node->layoutObject()->isRubyText(); | 343 return node && node->layoutObject() && !node->layoutObject()->isInline() &&
!node->layoutObject()->isRubyText(); |
318 } | 344 } |
319 | 345 |
320 bool isInline(const Node* node) | 346 bool isInline(const Node* node) |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1182 // if the selection starts just before a paragraph break, skip over it | 1208 // if the selection starts just before a paragraph break, skip over it |
1183 if (isEndOfParagraph(visiblePosition)) | 1209 if (isEndOfParagraph(visiblePosition)) |
1184 return visiblePosition.next().deepEquivalent().downstream(); | 1210 return visiblePosition.next().deepEquivalent().downstream(); |
1185 | 1211 |
1186 // otherwise, make sure to be at the start of the first selected node, | 1212 // otherwise, make sure to be at the start of the first selected node, |
1187 // instead of possibly at the end of the last node before the selection | 1213 // instead of possibly at the end of the last node before the selection |
1188 return visiblePosition.deepEquivalent().downstream(); | 1214 return visiblePosition.deepEquivalent().downstream(); |
1189 } | 1215 } |
1190 | 1216 |
1191 } // namespace blink | 1217 } // namespace blink |
OLD | NEW |