| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 { | 155 { |
| 156 return canonicalPosition(position); | 156 return canonicalPosition(position); |
| 157 } | 157 } |
| 158 | 158 |
| 159 PositionInComposedTree canonicalPositionOf(const PositionInComposedTree& positio
n) | 159 PositionInComposedTree canonicalPositionOf(const PositionInComposedTree& positio
n) |
| 160 { | 160 { |
| 161 return canonicalPosition(position); | 161 return canonicalPosition(position); |
| 162 } | 162 } |
| 163 | 163 |
| 164 template <typename Strategy> | 164 template <typename Strategy> |
| 165 static PositionWithAffinityTemplate<Strategy> honorEditingBoundaryAtOrBeforeAlgo
rithm(const PositionWithAffinityTemplate<Strategy>& pos, const PositionAlgorithm
<Strategy>& anchor) | 165 static PositionWithAffinityTemplate<Strategy> honorEditingBoundaryAtOrBefore(con
st PositionWithAffinityTemplate<Strategy>& pos, const PositionAlgorithm<Strategy
>& anchor) |
| 166 { | 166 { |
| 167 if (pos.isNull()) | 167 if (pos.isNull()) |
| 168 return pos; | 168 return pos; |
| 169 | 169 |
| 170 ContainerNode* highestRoot = highestEditableRoot(anchor); | 170 ContainerNode* highestRoot = highestEditableRoot(anchor); |
| 171 | 171 |
| 172 // Return empty position if |pos| is not somewhere inside the editable | 172 // Return empty position if |pos| is not somewhere inside the editable |
| 173 // region containing this position | 173 // region containing this position |
| 174 if (highestRoot && !pos.position().anchorNode()->isDescendantOf(highestRoot)
) | 174 if (highestRoot && !pos.position().anchorNode()->isDescendantOf(highestRoot)
) |
| 175 return PositionWithAffinityTemplate<Strategy>(); | 175 return PositionWithAffinityTemplate<Strategy>(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 186 // editable. | 186 // editable. |
| 187 // TODO(yosin) Move to the previous non-editable region. | 187 // TODO(yosin) Move to the previous non-editable region. |
| 188 if (!highestRoot) | 188 if (!highestRoot) |
| 189 return PositionWithAffinityTemplate<Strategy>(); | 189 return PositionWithAffinityTemplate<Strategy>(); |
| 190 | 190 |
| 191 // Return the last position before |pos| that is in the same editable region | 191 // Return the last position before |pos| that is in the same editable region |
| 192 // as this position | 192 // as this position |
| 193 return lastEditablePositionBeforePositionInRoot(pos.position(), highestRoot)
; | 193 return lastEditablePositionBeforePositionInRoot(pos.position(), highestRoot)
; |
| 194 } | 194 } |
| 195 | 195 |
| 196 static PositionWithAffinity honorEditingBoundaryAtOrBeforeOf(const PositionWithA
ffinity& pos, const Position& anchor) | 196 template <typename Strategy> |
| 197 static VisiblePositionTemplate<Strategy> honorEditingBoundaryAtOrBefore(const Vi
siblePositionTemplate<Strategy>& pos, const PositionAlgorithm<Strategy>& anchor) |
| 197 { | 198 { |
| 198 return honorEditingBoundaryAtOrBeforeAlgorithm(pos, anchor); | 199 return createVisiblePosition(honorEditingBoundaryAtOrBefore(pos.toPositionWi
thAffinity(), anchor)); |
| 199 } | |
| 200 | |
| 201 static PositionInComposedTreeWithAffinity honorEditingBoundaryAtOrBeforeOf(const
PositionInComposedTreeWithAffinity& pos, const PositionInComposedTree& anchor) | |
| 202 { | |
| 203 return honorEditingBoundaryAtOrBeforeAlgorithm(pos, anchor); | |
| 204 } | |
| 205 | |
| 206 static VisiblePosition honorEditingBoundaryAtOrBefore(const VisiblePosition& pos
, const Position& anchor) | |
| 207 { | |
| 208 return createVisiblePosition(honorEditingBoundaryAtOrBeforeOf(pos.toPosition
WithAffinity(), anchor)); | |
| 209 } | 200 } |
| 210 | 201 |
| 211 template <typename Strategy> | 202 template <typename Strategy> |
| 212 static VisiblePositionTemplate<Strategy> honorEditingBoundaryAtOrAfter(const Vis
iblePositionTemplate<Strategy>& pos, const PositionAlgorithm<Strategy>& anchor) | 203 static VisiblePositionTemplate<Strategy> honorEditingBoundaryAtOrAfter(const Vis
iblePositionTemplate<Strategy>& pos, const PositionAlgorithm<Strategy>& anchor) |
| 213 { | 204 { |
| 214 if (pos.isNull()) | 205 if (pos.isNull()) |
| 215 return pos; | 206 return pos; |
| 216 | 207 |
| 217 ContainerNode* highestRoot = highestEditableRoot(anchor); | 208 ContainerNode* highestRoot = highestEditableRoot(anchor); |
| 218 | 209 |
| (...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. | 945 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. |
| 955 PositionWithAffinityTemplate<Strategy> visPos = startPositionForLine(c, mode
); | 946 PositionWithAffinityTemplate<Strategy> visPos = startPositionForLine(c, mode
); |
| 956 | 947 |
| 957 if (mode == UseLogicalOrdering) { | 948 if (mode == UseLogicalOrdering) { |
| 958 if (ContainerNode* editableRoot = highestEditableRoot(c.position())) { | 949 if (ContainerNode* editableRoot = highestEditableRoot(c.position())) { |
| 959 if (!editableRoot->contains(visPos.position().computeContainerNode()
)) | 950 if (!editableRoot->contains(visPos.position().computeContainerNode()
)) |
| 960 return PositionWithAffinityTemplate<Strategy>(PositionAlgorithm<
Strategy>::firstPositionInNode(editableRoot)); | 951 return PositionWithAffinityTemplate<Strategy>(PositionAlgorithm<
Strategy>::firstPositionInNode(editableRoot)); |
| 961 } | 952 } |
| 962 } | 953 } |
| 963 | 954 |
| 964 return honorEditingBoundaryAtOrBeforeOf(visPos, c.position()); | 955 return honorEditingBoundaryAtOrBefore(visPos, c.position()); |
| 965 } | 956 } |
| 966 | 957 |
| 967 static PositionWithAffinity startOfLine(const PositionWithAffinity& currentPosit
ion) | 958 static PositionWithAffinity startOfLine(const PositionWithAffinity& currentPosit
ion) |
| 968 { | 959 { |
| 969 return startOfLine(currentPosition, UseInlineBoxOrdering); | 960 return startOfLine(currentPosition, UseInlineBoxOrdering); |
| 970 } | 961 } |
| 971 | 962 |
| 972 static PositionInComposedTreeWithAffinity startOfLine(const PositionInComposedTr
eeWithAffinity& currentPosition) | 963 static PositionInComposedTreeWithAffinity startOfLine(const PositionInComposedTr
eeWithAffinity& currentPosition) |
| 973 { | 964 { |
| 974 return startOfLine(currentPosition, UseInlineBoxOrdering); | 965 return startOfLine(currentPosition, UseInlineBoxOrdering); |
| (...skipping 1615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2590 UChar32 characterAfter(const VisiblePositionInComposedTree& visiblePosition) | 2581 UChar32 characterAfter(const VisiblePositionInComposedTree& visiblePosition) |
| 2591 { | 2582 { |
| 2592 return characterAfterAlgorithm<EditingInComposedTreeStrategy>(visiblePositio
n); | 2583 return characterAfterAlgorithm<EditingInComposedTreeStrategy>(visiblePositio
n); |
| 2593 } | 2584 } |
| 2594 | 2585 |
| 2595 UChar32 characterBefore(const VisiblePosition& visiblePosition) | 2586 UChar32 characterBefore(const VisiblePosition& visiblePosition) |
| 2596 { | 2587 { |
| 2597 return characterAfter(previousPositionOf(visiblePosition)); | 2588 return characterAfter(previousPositionOf(visiblePosition)); |
| 2598 } | 2589 } |
| 2599 | 2590 |
| 2600 static Position leftVisuallyDistinctCandidate(const VisiblePosition& visiblePosi
tion) | 2591 template <typename Strategy> |
| 2592 static PositionAlgorithm<Strategy> leftVisuallyDistinctCandidate(const VisiblePo
sitionTemplate<Strategy>& visiblePosition) |
| 2601 { | 2593 { |
| 2602 const Position deepPosition = visiblePosition.deepEquivalent(); | 2594 const PositionAlgorithm<Strategy> deepPosition = visiblePosition.deepEquival
ent(); |
| 2603 Position p = deepPosition; | 2595 PositionAlgorithm<Strategy> p = deepPosition; |
| 2596 |
| 2604 if (p.isNull()) | 2597 if (p.isNull()) |
| 2605 return Position(); | 2598 return PositionAlgorithm<Strategy>(); |
| 2606 | 2599 |
| 2607 Position downstreamStart = mostForwardCaretPosition(p); | 2600 const PositionAlgorithm<Strategy> downstreamStart = mostForwardCaretPosition
(p); |
| 2608 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); | 2601 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); |
| 2609 const TextAffinity affinity = visiblePosition.affinity(); | 2602 const TextAffinity affinity = visiblePosition.affinity(); |
| 2610 | 2603 |
| 2611 while (true) { | 2604 while (true) { |
| 2612 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, affinity, pr
imaryDirection); | 2605 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, affinity, pr
imaryDirection); |
| 2613 InlineBox* box = boxPosition.inlineBox; | 2606 InlineBox* box = boxPosition.inlineBox; |
| 2614 int offset = boxPosition.offsetInBox; | 2607 int offset = boxPosition.offsetInBox; |
| 2615 if (!box) | 2608 if (!box) |
| 2616 return primaryDirection == LTR ? previousVisuallyDistinctCandidate(d
eepPosition) : nextVisuallyDistinctCandidate(deepPosition); | 2609 return primaryDirection == LTR ? previousVisuallyDistinctCandidate(d
eepPosition) : nextVisuallyDistinctCandidate(deepPosition); |
| 2617 | 2610 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2635 int caretMinOffset = box->caretMinOffset(); | 2628 int caretMinOffset = box->caretMinOffset(); |
| 2636 int caretMaxOffset = box->caretMaxOffset(); | 2629 int caretMaxOffset = box->caretMaxOffset(); |
| 2637 | 2630 |
| 2638 if (offset > caretMinOffset && offset < caretMaxOffset) | 2631 if (offset > caretMinOffset && offset < caretMaxOffset) |
| 2639 break; | 2632 break; |
| 2640 | 2633 |
| 2641 if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset
> caretMaxOffset) { | 2634 if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset
> caretMaxOffset) { |
| 2642 // Overshot to the left. | 2635 // Overshot to the left. |
| 2643 InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); | 2636 InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); |
| 2644 if (!prevBox) { | 2637 if (!prevBox) { |
| 2645 Position positionOnLeft = primaryDirection == LTR ? previous
VisuallyDistinctCandidate(deepPosition) : nextVisuallyDistinctCandidate(deepPosi
tion); | 2638 PositionAlgorithm<Strategy> positionOnLeft = primaryDirectio
n == LTR ? previousVisuallyDistinctCandidate(visiblePosition.deepEquivalent()) :
nextVisuallyDistinctCandidate(visiblePosition.deepEquivalent()); |
| 2646 if (positionOnLeft.isNull()) | 2639 if (positionOnLeft.isNull()) |
| 2647 return Position(); | 2640 return PositionAlgorithm<Strategy>(); |
| 2648 | 2641 |
| 2649 InlineBox* boxOnLeft = computeInlineBoxPosition(positionOnLe
ft, affinity, primaryDirection).inlineBox; | 2642 InlineBox* boxOnLeft = computeInlineBoxPosition(positionOnLe
ft, affinity, primaryDirection).inlineBox; |
| 2650 if (boxOnLeft && boxOnLeft->root() == box->root()) | 2643 if (boxOnLeft && boxOnLeft->root() == box->root()) |
| 2651 return Position(); | 2644 return PositionAlgorithm<Strategy>(); |
| 2652 return positionOnLeft; | 2645 return positionOnLeft; |
| 2653 } | 2646 } |
| 2654 | 2647 |
| 2655 // Reposition at the other logical position corresponding to our | 2648 // Reposition at the other logical position corresponding to our |
| 2656 // edge's visual position and go for another round. | 2649 // edge's visual position and go for another round. |
| 2657 box = prevBox; | 2650 box = prevBox; |
| 2658 layoutObject = &box->layoutObject(); | 2651 layoutObject = &box->layoutObject(); |
| 2659 offset = prevBox->caretRightmostOffset(); | 2652 offset = prevBox->caretRightmostOffset(); |
| 2660 continue; | 2653 continue; |
| 2661 } | 2654 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2705 offset = box->caretRightmostOffset(); | 2698 offset = box->caretRightmostOffset(); |
| 2706 if (box->bidiLevel() > level) { | 2699 if (box->bidiLevel() > level) { |
| 2707 do { | 2700 do { |
| 2708 prevBox = prevBox->prevLeafChild(); | 2701 prevBox = prevBox->prevLeafChild(); |
| 2709 } while (prevBox && prevBox->bidiLevel() > level); | 2702 } while (prevBox && prevBox->bidiLevel() > level); |
| 2710 | 2703 |
| 2711 if (!prevBox || prevBox->bidiLevel() < level) | 2704 if (!prevBox || prevBox->bidiLevel() < level) |
| 2712 continue; | 2705 continue; |
| 2713 } | 2706 } |
| 2714 } else { | 2707 } else { |
| 2715 // Trailing edge of a secondary run. Set to the leading edge of
the entire run. | 2708 // Trailing edge of a secondary run. Set to the leading edge of |
| 2709 // the entire run. |
| 2716 while (true) { | 2710 while (true) { |
| 2717 while (InlineBox* nextBox = box->nextLeafChild()) { | 2711 while (InlineBox* nextBox = box->nextLeafChild()) { |
| 2718 if (nextBox->bidiLevel() < level) | 2712 if (nextBox->bidiLevel() < level) |
| 2719 break; | 2713 break; |
| 2720 box = nextBox; | 2714 box = nextBox; |
| 2721 } | 2715 } |
| 2722 if (box->bidiLevel() == level) | 2716 if (box->bidiLevel() == level) |
| 2723 break; | 2717 break; |
| 2724 level = box->bidiLevel(); | 2718 level = box->bidiLevel(); |
| 2725 while (InlineBox* prevBox = box->prevLeafChild()) { | 2719 while (InlineBox* prevBox = box->prevLeafChild()) { |
| 2726 if (prevBox->bidiLevel() < level) | 2720 if (prevBox->bidiLevel() < level) |
| 2727 break; | 2721 break; |
| 2728 box = prevBox; | 2722 box = prevBox; |
| 2729 } | 2723 } |
| 2730 if (box->bidiLevel() == level) | 2724 if (box->bidiLevel() == level) |
| 2731 break; | 2725 break; |
| 2732 level = box->bidiLevel(); | 2726 level = box->bidiLevel(); |
| 2733 } | 2727 } |
| 2734 layoutObject = &box->layoutObject(); | 2728 layoutObject = &box->layoutObject(); |
| 2735 offset = primaryDirection == LTR ? box->caretMinOffset() : box->
caretMaxOffset(); | 2729 offset = primaryDirection == LTR ? box->caretMinOffset() : box->
caretMaxOffset(); |
| 2736 } | 2730 } |
| 2737 break; | 2731 break; |
| 2738 } | 2732 } |
| 2739 | 2733 |
| 2740 p = Position::editingPositionOf(layoutObject->node(), offset); | 2734 p = PositionAlgorithm<Strategy>::editingPositionOf(layoutObject->node(),
offset); |
| 2741 | 2735 |
| 2742 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) | 2736 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) |
| 2743 return p; | 2737 return p; |
| 2744 | 2738 |
| 2745 ASSERT(p != deepPosition); | 2739 ASSERT(p != deepPosition); |
| 2746 } | 2740 } |
| 2747 } | 2741 } |
| 2748 | 2742 |
| 2749 VisiblePosition leftPositionOf(const VisiblePosition& visiblePosition) | 2743 template <typename Strategy> |
| 2744 VisiblePositionTemplate<Strategy> leftPositionOfAlgorithm(const VisiblePositionT
emplate<Strategy>& visiblePosition) |
| 2750 { | 2745 { |
| 2751 const Position pos = leftVisuallyDistinctCandidate(visiblePosition); | 2746 const PositionAlgorithm<Strategy> pos = leftVisuallyDistinctCandidate(visibl
ePosition); |
| 2752 // TODO(yosin) Why can't we move left from the last position in a tree? | 2747 // TODO(yosin) Why can't we move left from the last position in a tree? |
| 2753 if (pos.atStartOfTree() || pos.atEndOfTree()) | 2748 if (pos.atStartOfTree() || pos.atEndOfTree()) |
| 2754 return VisiblePosition(); | 2749 return VisiblePositionTemplate<Strategy>(); |
| 2755 | 2750 |
| 2756 VisiblePosition left = createVisiblePosition(pos); | 2751 const VisiblePositionTemplate<Strategy> left = createVisiblePosition(pos); |
| 2757 ASSERT(left.deepEquivalent() != visiblePosition.deepEquivalent()); | 2752 ASSERT(left.deepEquivalent() != visiblePosition.deepEquivalent()); |
| 2758 | 2753 |
| 2759 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? honorEditin
gBoundaryAtOrBefore(left, visiblePosition.deepEquivalent()) : honorEditingBounda
ryAtOrAfter(left, visiblePosition.deepEquivalent()); | 2754 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? honorEditin
gBoundaryAtOrBefore(left, visiblePosition.deepEquivalent()) : honorEditingBounda
ryAtOrAfter(left, visiblePosition.deepEquivalent()); |
| 2760 } | 2755 } |
| 2761 | 2756 |
| 2757 VisiblePosition leftPositionOf(const VisiblePosition& visiblePosition) |
| 2758 { |
| 2759 return leftPositionOfAlgorithm<EditingStrategy>(visiblePosition); |
| 2760 } |
| 2761 |
| 2762 VisiblePositionInComposedTree leftPositionOf(const VisiblePositionInComposedTree
& visiblePosition) |
| 2763 { |
| 2764 return leftPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePositio
n); |
| 2765 } |
| 2766 |
| 2762 static Position rightVisuallyDistinctCandidate(const VisiblePosition& visiblePos
ition) | 2767 static Position rightVisuallyDistinctCandidate(const VisiblePosition& visiblePos
ition) |
| 2763 { | 2768 { |
| 2764 const Position deepPosition = visiblePosition.deepEquivalent(); | 2769 const Position deepPosition = visiblePosition.deepEquivalent(); |
| 2765 Position p = deepPosition; | 2770 Position p = deepPosition; |
| 2766 if (p.isNull()) | 2771 if (p.isNull()) |
| 2767 return Position(); | 2772 return Position(); |
| 2768 | 2773 |
| 2769 Position downstreamStart = mostForwardCaretPosition(p); | 2774 Position downstreamStart = mostForwardCaretPosition(p); |
| 2770 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); | 2775 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); |
| 2771 const TextAffinity affinity = visiblePosition.affinity(); | 2776 const TextAffinity affinity = visiblePosition.affinity(); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3003 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); | 3008 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale
nt()); |
| 3004 case CanSkipOverEditingBoundary: | 3009 case CanSkipOverEditingBoundary: |
| 3005 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); | 3010 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent
()); |
| 3006 } | 3011 } |
| 3007 | 3012 |
| 3008 ASSERT_NOT_REACHED(); | 3013 ASSERT_NOT_REACHED(); |
| 3009 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); | 3014 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent()
); |
| 3010 } | 3015 } |
| 3011 | 3016 |
| 3012 } // namespace blink | 3017 } // namespace blink |
| OLD | NEW |