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 2764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2775 VisiblePosition leftPositionOf(const VisiblePosition& visiblePosition) | 2775 VisiblePosition leftPositionOf(const VisiblePosition& visiblePosition) |
2776 { | 2776 { |
2777 return leftPositionOfAlgorithm<EditingStrategy>(visiblePosition); | 2777 return leftPositionOfAlgorithm<EditingStrategy>(visiblePosition); |
2778 } | 2778 } |
2779 | 2779 |
2780 VisiblePositionInComposedTree leftPositionOf(const VisiblePositionInComposedTree
& visiblePosition) | 2780 VisiblePositionInComposedTree leftPositionOf(const VisiblePositionInComposedTree
& visiblePosition) |
2781 { | 2781 { |
2782 return leftPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePositio
n); | 2782 return leftPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePositio
n); |
2783 } | 2783 } |
2784 | 2784 |
2785 static Position rightVisuallyDistinctCandidate(const VisiblePosition& visiblePos
ition) | 2785 template <typename Strategy> |
| 2786 static PositionAlgorithm<Strategy> rightVisuallyDistinctCandidate(const VisibleP
ositionTemplate<Strategy>& visiblePosition) |
2786 { | 2787 { |
2787 const Position deepPosition = visiblePosition.deepEquivalent(); | 2788 const PositionAlgorithm<Strategy> deepPosition = visiblePosition.deepEquival
ent(); |
2788 Position p = deepPosition; | 2789 PositionAlgorithm<Strategy> p = deepPosition; |
2789 if (p.isNull()) | 2790 if (p.isNull()) |
2790 return Position(); | 2791 return PositionAlgorithm<Strategy>(); |
2791 | 2792 |
2792 Position downstreamStart = mostForwardCaretPosition(p); | 2793 const PositionAlgorithm<Strategy> downstreamStart = mostForwardCaretPosition
(p); |
2793 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); | 2794 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); |
2794 const TextAffinity affinity = visiblePosition.affinity(); | 2795 const TextAffinity affinity = visiblePosition.affinity(); |
2795 | 2796 |
2796 while (true) { | 2797 while (true) { |
2797 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, affinity, pr
imaryDirection); | 2798 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, affinity, pr
imaryDirection); |
2798 InlineBox* box = boxPosition.inlineBox; | 2799 InlineBox* box = boxPosition.inlineBox; |
2799 int offset = boxPosition.offsetInBox; | 2800 int offset = boxPosition.offsetInBox; |
2800 if (!box) | 2801 if (!box) |
2801 return primaryDirection == LTR ? nextVisuallyDistinctCandidate(deepP
osition) : previousVisuallyDistinctCandidate(deepPosition); | 2802 return primaryDirection == LTR ? nextVisuallyDistinctCandidate(deepP
osition) : previousVisuallyDistinctCandidate(deepPosition); |
2802 | 2803 |
(...skipping 17 matching lines...) Expand all Loading... |
2820 int caretMinOffset = box->caretMinOffset(); | 2821 int caretMinOffset = box->caretMinOffset(); |
2821 int caretMaxOffset = box->caretMaxOffset(); | 2822 int caretMaxOffset = box->caretMaxOffset(); |
2822 | 2823 |
2823 if (offset > caretMinOffset && offset < caretMaxOffset) | 2824 if (offset > caretMinOffset && offset < caretMaxOffset) |
2824 break; | 2825 break; |
2825 | 2826 |
2826 if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset
< caretMinOffset) { | 2827 if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset
< caretMinOffset) { |
2827 // Overshot to the right. | 2828 // Overshot to the right. |
2828 InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); | 2829 InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); |
2829 if (!nextBox) { | 2830 if (!nextBox) { |
2830 Position positionOnRight = primaryDirection == LTR ? nextVis
uallyDistinctCandidate(deepPosition) : previousVisuallyDistinctCandidate(deepPos
ition); | 2831 PositionAlgorithm<Strategy> positionOnRight = primaryDirecti
on == LTR ? nextVisuallyDistinctCandidate(deepPosition) : previousVisuallyDistin
ctCandidate(deepPosition); |
2831 if (positionOnRight.isNull()) | 2832 if (positionOnRight.isNull()) |
2832 return Position(); | 2833 return PositionAlgorithm<Strategy>(); |
2833 | 2834 |
2834 InlineBox* boxOnRight = computeInlineBoxPosition(positionOnR
ight, affinity, primaryDirection).inlineBox; | 2835 InlineBox* boxOnRight = computeInlineBoxPosition(positionOnR
ight, affinity, primaryDirection).inlineBox; |
2835 if (boxOnRight && boxOnRight->root() == box->root()) | 2836 if (boxOnRight && boxOnRight->root() == box->root()) |
2836 return Position(); | 2837 return PositionAlgorithm<Strategy>(); |
2837 return positionOnRight; | 2838 return positionOnRight; |
2838 } | 2839 } |
2839 | 2840 |
2840 // Reposition at the other logical position corresponding to our | 2841 // Reposition at the other logical position corresponding to our |
2841 // edge's visual position and go for another round. | 2842 // edge's visual position and go for another round. |
2842 box = nextBox; | 2843 box = nextBox; |
2843 layoutObject = &box->layoutObject(); | 2844 layoutObject = &box->layoutObject(); |
2844 offset = nextBox->caretLeftmostOffset(); | 2845 offset = nextBox->caretLeftmostOffset(); |
2845 continue; | 2846 continue; |
2846 } | 2847 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 | 2895 |
2895 if (box->bidiLevel() > level) { | 2896 if (box->bidiLevel() > level) { |
2896 do { | 2897 do { |
2897 nextBox = nextBox->nextLeafChild(); | 2898 nextBox = nextBox->nextLeafChild(); |
2898 } while (nextBox && nextBox->bidiLevel() > level); | 2899 } while (nextBox && nextBox->bidiLevel() > level); |
2899 | 2900 |
2900 if (!nextBox || nextBox->bidiLevel() < level) | 2901 if (!nextBox || nextBox->bidiLevel() < level) |
2901 continue; | 2902 continue; |
2902 } | 2903 } |
2903 } else { | 2904 } else { |
2904 // Trailing edge of a secondary run. Set to the leading edge of | 2905 // Trailing edge of a secondary run. Set to the leading edge of
the entire run. |
2905 // the entire run. | |
2906 while (true) { | 2906 while (true) { |
2907 while (InlineBox* prevBox = box->prevLeafChild()) { | 2907 while (InlineBox* prevBox = box->prevLeafChild()) { |
2908 if (prevBox->bidiLevel() < level) | 2908 if (prevBox->bidiLevel() < level) |
2909 break; | 2909 break; |
2910 box = prevBox; | 2910 box = prevBox; |
2911 } | 2911 } |
2912 if (box->bidiLevel() == level) | 2912 if (box->bidiLevel() == level) |
2913 break; | 2913 break; |
2914 level = box->bidiLevel(); | 2914 level = box->bidiLevel(); |
2915 while (InlineBox* nextBox = box->nextLeafChild()) { | 2915 while (InlineBox* nextBox = box->nextLeafChild()) { |
2916 if (nextBox->bidiLevel() < level) | 2916 if (nextBox->bidiLevel() < level) |
2917 break; | 2917 break; |
2918 box = nextBox; | 2918 box = nextBox; |
2919 } | 2919 } |
2920 if (box->bidiLevel() == level) | 2920 if (box->bidiLevel() == level) |
2921 break; | 2921 break; |
2922 level = box->bidiLevel(); | 2922 level = box->bidiLevel(); |
2923 } | 2923 } |
2924 layoutObject = &box->layoutObject(); | 2924 layoutObject = &box->layoutObject(); |
2925 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->
caretMinOffset(); | 2925 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->
caretMinOffset(); |
2926 } | 2926 } |
2927 break; | 2927 break; |
2928 } | 2928 } |
2929 | 2929 |
2930 p = Position::editingPositionOf(layoutObject->node(), offset); | 2930 p = PositionAlgorithm<Strategy>::editingPositionOf(layoutObject->node(),
offset); |
2931 | 2931 |
2932 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) | 2932 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) |
2933 return p; | 2933 return p; |
2934 | 2934 |
2935 ASSERT(p != deepPosition); | 2935 ASSERT(p != deepPosition); |
2936 } | 2936 } |
2937 } | 2937 } |
2938 | 2938 |
2939 VisiblePosition rightPositionOf(const VisiblePosition& visiblePosition) | 2939 template <typename Strategy> |
| 2940 static VisiblePositionTemplate<Strategy> rightPositionOfAlgorithm(const VisibleP
ositionTemplate<Strategy>& visiblePosition) |
2940 { | 2941 { |
2941 const Position pos = rightVisuallyDistinctCandidate(visiblePosition); | 2942 const PositionAlgorithm<Strategy> pos = rightVisuallyDistinctCandidate(visib
lePosition); |
2942 // TODO(yosin) Why can't we move left from the last position in a tree? | 2943 // FIXME: Why can't we move left from the last position in a tree? |
2943 if (pos.atStartOfTree() || pos.atEndOfTree()) | 2944 if (pos.atStartOfTree() || pos.atEndOfTree()) |
2944 return VisiblePosition(); | 2945 return VisiblePositionTemplate<Strategy>(); |
2945 | 2946 |
2946 VisiblePosition right = createVisiblePosition(pos); | 2947 const VisiblePositionTemplate<Strategy> right = createVisiblePosition(pos); |
2947 ASSERT(right.deepEquivalent() != visiblePosition.deepEquivalent()); | 2948 ASSERT(right.deepEquivalent() != visiblePosition.deepEquivalent()); |
2948 | 2949 |
2949 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? honorEditi
ngBoundaryAtOrAfter(right, visiblePosition.deepEquivalent()) : honorEditingBound
aryAtOrBefore(right, visiblePosition.deepEquivalent()); | 2950 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? honorEditi
ngBoundaryAtOrAfter(right, visiblePosition.deepEquivalent()) : honorEditingBound
aryAtOrBefore(right, visiblePosition.deepEquivalent()); |
2950 } | 2951 } |
2951 | 2952 |
| 2953 VisiblePosition rightPositionOf(const VisiblePosition& visiblePosition) |
| 2954 { |
| 2955 return rightPositionOfAlgorithm<EditingStrategy>(visiblePosition); |
| 2956 } |
| 2957 |
| 2958 VisiblePositionInComposedTree rightPositionOf(const VisiblePositionInComposedTre
e& visiblePosition) |
| 2959 { |
| 2960 return rightPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePositi
on); |
| 2961 } |
| 2962 |
2952 template <typename Strategy> | 2963 template <typename Strategy> |
2953 static VisiblePositionTemplate<Strategy> nextPositionOfAlgorithm(const VisiblePo
sitionTemplate<Strategy>& visiblePosition, EditingBoundaryCrossingRule rule) | 2964 static VisiblePositionTemplate<Strategy> nextPositionOfAlgorithm(const VisiblePo
sitionTemplate<Strategy>& visiblePosition, EditingBoundaryCrossingRule rule) |
2954 { | 2965 { |
2955 const VisiblePositionTemplate<Strategy> next = createVisiblePosition(nextVis
uallyDistinctCandidate(visiblePosition.deepEquivalent()), visiblePosition.affini
ty()); | 2966 const VisiblePositionTemplate<Strategy> next = createVisiblePosition(nextVis
uallyDistinctCandidate(visiblePosition.deepEquivalent()), visiblePosition.affini
ty()); |
2956 | 2967 |
2957 switch (rule) { | 2968 switch (rule) { |
2958 case CanCrossEditingBoundary: | 2969 case CanCrossEditingBoundary: |
2959 return next; | 2970 return next; |
2960 case CannotCrossEditingBoundary: | 2971 case CannotCrossEditingBoundary: |
2961 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalen
t()); | 2972 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalen
t()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3026 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); | 3037 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); |
3027 case CanSkipOverEditingBoundary: | 3038 case CanSkipOverEditingBoundary: |
3028 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); | 3039 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); |
3029 } | 3040 } |
3030 | 3041 |
3031 ASSERT_NOT_REACHED(); | 3042 ASSERT_NOT_REACHED(); |
3032 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); | 3043 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); |
3033 } | 3044 } |
3034 | 3045 |
3035 } // namespace blink | 3046 } // namespace blink |
OLD | NEW |