Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Side by Side Diff: Source/core/editing/VisibleUnits.cpp

Issue 1326313002: Introduce composed tree version of leftPositionOf() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-09-09T12:49:11 Add a comment about DOM version of leftPositoin() for composed tree Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/editing/VisibleUnits.h ('k') | Source/core/editing/VisibleUnitsTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/editing/VisibleUnits.h ('k') | Source/core/editing/VisibleUnitsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698