| 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 |