OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 static PositionInComposedTreeWithAffinity honorEditingBoundaryAtOrBeforeOf(const
PositionInComposedTreeWithAffinity& pos, const PositionInComposedTree& anchor) | 201 static PositionInComposedTreeWithAffinity honorEditingBoundaryAtOrBeforeOf(const
PositionInComposedTreeWithAffinity& pos, const PositionInComposedTree& anchor) |
202 { | 202 { |
203 return honorEditingBoundaryAtOrBeforeAlgorithm(pos, anchor); | 203 return honorEditingBoundaryAtOrBeforeAlgorithm(pos, anchor); |
204 } | 204 } |
205 | 205 |
206 static VisiblePosition honorEditingBoundaryAtOrBefore(const VisiblePosition& pos
, const Position& anchor) | 206 static VisiblePosition honorEditingBoundaryAtOrBefore(const VisiblePosition& pos
, const Position& anchor) |
207 { | 207 { |
208 return createVisiblePosition(honorEditingBoundaryAtOrBeforeOf(pos.toPosition
WithAffinity(), anchor)); | 208 return createVisiblePosition(honorEditingBoundaryAtOrBeforeOf(pos.toPosition
WithAffinity(), anchor)); |
209 } | 209 } |
210 | 210 |
211 static VisiblePosition honorEditingBoundaryAtOrAfter(const VisiblePosition& pos,
const Position& anchor) | 211 template <typename Strategy> |
| 212 static VisiblePositionTemplate<Strategy> honorEditingBoundaryAtOrAfter(const Vis
iblePositionTemplate<Strategy>& pos, const PositionAlgorithm<Strategy>& anchor) |
212 { | 213 { |
213 if (pos.isNull()) | 214 if (pos.isNull()) |
214 return pos; | 215 return pos; |
215 | 216 |
216 ContainerNode* highestRoot = highestEditableRoot(anchor); | 217 ContainerNode* highestRoot = highestEditableRoot(anchor); |
217 | 218 |
218 // Return empty position if |pos| is not somewhere inside the editable | 219 // Return empty position if |pos| is not somewhere inside the editable |
219 // region // containing this position | 220 // region containing this position |
220 if (highestRoot && !pos.deepEquivalent().anchorNode()->isDescendantOf(highes
tRoot)) | 221 if (highestRoot && !pos.deepEquivalent().anchorNode()->isDescendantOf(highes
tRoot)) |
221 return VisiblePosition(); | 222 return VisiblePositionTemplate<Strategy>(); |
222 | 223 |
223 // Return |pos| itself if the two are from the very same editable region, or | 224 // Return |pos| itself if the two are from the very same editable region, or |
224 // both are non-editable | 225 // both are non-editable |
225 // TODO(yosin) In the non-editable case, just because the new position is | 226 // TODO(yosin) In the non-editable case, just because the new position is |
226 // non-editable doesn't mean movement to it is allowed. | 227 // non-editable doesn't mean movement to it is allowed. |
227 // |VisibleSelection::adjustForEditableContent()| has this problem too. | 228 // |VisibleSelection::adjustForEditableContent()| has this problem too. |
228 if (highestEditableRoot(pos.deepEquivalent()) == highestRoot) | 229 if (highestEditableRoot(pos.deepEquivalent()) == highestRoot) |
229 return pos; | 230 return pos; |
230 | 231 |
231 // Return empty position if this position is non-editable, but |pos| is | 232 // Return empty position if this position is non-editable, but |pos| is |
232 // editable | 233 // editable. |
233 // TODO(yosin) Move to the next non-editable region. | 234 // TODO(yosin) Move to the next non-editable region. |
234 if (!highestRoot) | 235 if (!highestRoot) |
235 return VisiblePosition(); | 236 return VisiblePositionTemplate<Strategy>(); |
236 | 237 |
237 // Return the next position after |pos| that is in the same editable region | 238 // Return the next position after |pos| that is in the same editable region |
238 // as this position | 239 // as this position |
239 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
highestRoot); | 240 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
highestRoot); |
240 } | 241 } |
241 | 242 |
242 static Node* previousLeafWithSameEditability(Node* node, EditableType editableTy
pe) | 243 static Node* previousLeafWithSameEditability(Node* node, EditableType editableTy
pe) |
243 { | 244 { |
244 bool editable = node->hasEditableStyle(editableType); | 245 bool editable = node->hasEditableStyle(editableType); |
245 node = previousAtomicLeafNode(*node); | 246 node = previousAtomicLeafNode(*node); |
(...skipping 2273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2519 IntRect absoluteCaretBoundsOf(const VisiblePosition& visiblePosition) | 2520 IntRect absoluteCaretBoundsOf(const VisiblePosition& visiblePosition) |
2520 { | 2521 { |
2521 return absoluteCaretBoundsOfAlgorithm<EditingStrategy>(visiblePosition); | 2522 return absoluteCaretBoundsOfAlgorithm<EditingStrategy>(visiblePosition); |
2522 } | 2523 } |
2523 | 2524 |
2524 IntRect absoluteCaretBoundsOf(const VisiblePositionInComposedTree& visiblePositi
on) | 2525 IntRect absoluteCaretBoundsOf(const VisiblePositionInComposedTree& visiblePositi
on) |
2525 { | 2526 { |
2526 return absoluteCaretBoundsOfAlgorithm<EditingInComposedTreeStrategy>(visible
Position); | 2527 return absoluteCaretBoundsOfAlgorithm<EditingInComposedTreeStrategy>(visible
Position); |
2527 } | 2528 } |
2528 | 2529 |
2529 static VisiblePosition skipToEndOfEditingBoundary(const VisiblePosition& pos, co
nst Position& anchor) | 2530 template <typename Strategy> |
| 2531 static VisiblePositionTemplate<Strategy> skipToEndOfEditingBoundary(const Visibl
ePositionTemplate<Strategy>& pos, const PositionAlgorithm<Strategy>& anchor) |
2530 { | 2532 { |
2531 if (pos.isNull()) | 2533 if (pos.isNull()) |
2532 return pos; | 2534 return pos; |
2533 | 2535 |
2534 ContainerNode* highestRoot = highestEditableRoot(anchor); | 2536 ContainerNode* highestRoot = highestEditableRoot(anchor); |
2535 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); | 2537 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
2536 | 2538 |
2537 // Return |pos| itself if the two are from the very same editable region, or | 2539 // Return |pos| itself if the two are from the very same editable region, |
2538 // both are non-editable. | 2540 // or both are non-editable. |
2539 if (highestRootOfPos == highestRoot) | 2541 if (highestRootOfPos == highestRoot) |
2540 return pos; | 2542 return pos; |
2541 | 2543 |
2542 // If this is not editable but |pos| has an editable root, skip to the end | 2544 // If this is not editable but |pos| has an editable root, skip to the end |
2543 if (!highestRoot && highestRootOfPos) | 2545 if (!highestRoot && highestRootOfPos) |
2544 return createVisiblePosition(Position(highestRootOfPos, PositionAnchorTy
pe::AfterAnchor).parentAnchoredEquivalent()); | 2546 return createVisiblePosition(PositionAlgorithm<Strategy>(highestRootOfPo
s, PositionAnchorType::AfterAnchor).parentAnchoredEquivalent()); |
2545 | 2547 |
2546 // That must mean that |pos| is not editable. Return the next position after | 2548 // That must mean that |pos| is not editable. Return the next position after |
2547 // |pos| that is in the same editable region as this position | 2549 // |pos| that is in the same editable region as this position |
2548 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
highestRoot); | 2550 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
highestRoot); |
2549 } | 2551 } |
2550 | 2552 |
2551 template <typename Strategy> | 2553 template <typename Strategy> |
2552 static UChar32 characterAfterAlgorithm(const VisiblePositionTemplate<Strategy>&
visiblePosition) | 2554 static UChar32 characterAfterAlgorithm(const VisiblePositionTemplate<Strategy>&
visiblePosition) |
2553 { | 2555 { |
2554 // We canonicalize to the first of two equivalent candidates, but the second | 2556 // We canonicalize to the first of two equivalent candidates, but the second |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2906 // TODO(yosin) Why can't we move left from the last position in a tree? | 2908 // TODO(yosin) Why can't we move left from the last position in a tree? |
2907 if (pos.atStartOfTree() || pos.atEndOfTree()) | 2909 if (pos.atStartOfTree() || pos.atEndOfTree()) |
2908 return VisiblePosition(); | 2910 return VisiblePosition(); |
2909 | 2911 |
2910 VisiblePosition right = createVisiblePosition(pos); | 2912 VisiblePosition right = createVisiblePosition(pos); |
2911 ASSERT(right.deepEquivalent() != visiblePosition.deepEquivalent()); | 2913 ASSERT(right.deepEquivalent() != visiblePosition.deepEquivalent()); |
2912 | 2914 |
2913 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? honorEditi
ngBoundaryAtOrAfter(right, visiblePosition.deepEquivalent()) : honorEditingBound
aryAtOrBefore(right, visiblePosition.deepEquivalent()); | 2915 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? honorEditi
ngBoundaryAtOrAfter(right, visiblePosition.deepEquivalent()) : honorEditingBound
aryAtOrBefore(right, visiblePosition.deepEquivalent()); |
2914 } | 2916 } |
2915 | 2917 |
2916 VisiblePosition nextPositionOf(const VisiblePosition& visiblePosition, EditingBo
undaryCrossingRule rule) | 2918 template <typename Strategy> |
| 2919 static VisiblePositionTemplate<Strategy> nextPositionOfAlgorithm(const VisiblePo
sitionTemplate<Strategy>& visiblePosition, EditingBoundaryCrossingRule rule) |
2917 { | 2920 { |
2918 VisiblePosition next = createVisiblePosition(nextVisuallyDistinctCandidate(v
isiblePosition.deepEquivalent()), visiblePosition.affinity()); | 2921 const VisiblePositionTemplate<Strategy> next = createVisiblePosition(nextVis
uallyDistinctCandidate(visiblePosition.deepEquivalent()), visiblePosition.affini
ty()); |
2919 | 2922 |
2920 switch (rule) { | 2923 switch (rule) { |
2921 case CanCrossEditingBoundary: | 2924 case CanCrossEditingBoundary: |
2922 return next; | 2925 return next; |
2923 case CannotCrossEditingBoundary: | 2926 case CannotCrossEditingBoundary: |
2924 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalen
t()); | 2927 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalen
t()); |
2925 case CanSkipOverEditingBoundary: | 2928 case CanSkipOverEditingBoundary: |
2926 return skipToEndOfEditingBoundary(next, visiblePosition.deepEquivalent()
); | 2929 return skipToEndOfEditingBoundary(next, visiblePosition.deepEquivalent()
); |
2927 } | 2930 } |
2928 ASSERT_NOT_REACHED(); | 2931 ASSERT_NOT_REACHED(); |
2929 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalent())
; | 2932 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalent())
; |
2930 } | 2933 } |
2931 | 2934 |
| 2935 VisiblePosition nextPositionOf(const VisiblePosition& visiblePosition, EditingBo
undaryCrossingRule rule) |
| 2936 { |
| 2937 return nextPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); |
| 2938 } |
| 2939 |
| 2940 VisiblePositionInComposedTree nextPositionOf(const VisiblePositionInComposedTree
& visiblePosition, EditingBoundaryCrossingRule rule) |
| 2941 { |
| 2942 return nextPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePositio
n, rule); |
| 2943 } |
| 2944 |
2932 static VisiblePosition skipToStartOfEditingBoundary(const VisiblePosition& pos,
const Position& anchor) | 2945 static VisiblePosition skipToStartOfEditingBoundary(const VisiblePosition& pos,
const Position& anchor) |
2933 { | 2946 { |
2934 if (pos.isNull()) | 2947 if (pos.isNull()) |
2935 return pos; | 2948 return pos; |
2936 | 2949 |
2937 ContainerNode* highestRoot = highestEditableRoot(anchor); | 2950 ContainerNode* highestRoot = highestEditableRoot(anchor); |
2938 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); | 2951 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
2939 | 2952 |
2940 // Return |pos| itself if the two are from the very same editable region, or | 2953 // Return |pos| itself if the two are from the very same editable region, or |
2941 // both are non-editable. | 2954 // both are non-editable. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2979 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); | 2992 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); |
2980 case CanSkipOverEditingBoundary: | 2993 case CanSkipOverEditingBoundary: |
2981 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); | 2994 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); |
2982 } | 2995 } |
2983 | 2996 |
2984 ASSERT_NOT_REACHED(); | 2997 ASSERT_NOT_REACHED(); |
2985 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); | 2998 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); |
2986 } | 2999 } |
2987 | 3000 |
2988 } // namespace blink | 3001 } // namespace blink |
OLD | NEW |