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

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

Issue 1878473002: ASSERT -> DCHECK in core/editing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Output info for some DCHECKs, add TODOs. Created 4 years, 8 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
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 #include "platform/heap/Handle.h" 66 #include "platform/heap/Handle.h"
67 #include "platform/text/TextBoundaries.h" 67 #include "platform/text/TextBoundaries.h"
68 68
69 namespace blink { 69 namespace blink {
70 70
71 template <typename PositionType> 71 template <typename PositionType>
72 static PositionType canonicalizeCandidate(const PositionType& candidate) 72 static PositionType canonicalizeCandidate(const PositionType& candidate)
73 { 73 {
74 if (candidate.isNull()) 74 if (candidate.isNull())
75 return PositionType(); 75 return PositionType();
76 ASSERT(isVisuallyEquivalentCandidate(candidate)); 76 DCHECK(isVisuallyEquivalentCandidate(candidate));
77 PositionType upstream = mostBackwardCaretPosition(candidate); 77 PositionType upstream = mostBackwardCaretPosition(candidate);
78 if (isVisuallyEquivalentCandidate(upstream)) 78 if (isVisuallyEquivalentCandidate(upstream))
79 return upstream; 79 return upstream;
80 return candidate; 80 return candidate;
81 } 81 }
82 82
83 template <typename PositionType> 83 template <typename PositionType>
84 static PositionType canonicalPosition(const PositionType& passedPosition) 84 static PositionType canonicalPosition(const PositionType& passedPosition)
85 { 85 {
86 // Sometimes updating selection positions can be extremely expensive and 86 // Sometimes updating selection positions can be extremely expensive and
87 // occur frequently. Often calling preventDefault on mousedown events can 87 // occur frequently. Often calling preventDefault on mousedown events can
88 // avoid doing unnecessary text selection work. http://crbug.com/472258. 88 // avoid doing unnecessary text selection work. http://crbug.com/472258.
89 TRACE_EVENT0("input", "VisibleUnits::canonicalPosition"); 89 TRACE_EVENT0("input", "VisibleUnits::canonicalPosition");
90 90
91 // The updateLayout call below can do so much that even the position passed 91 // The updateLayout call below can do so much that even the position passed
92 // in to us might get changed as a side effect. Specifically, there are code 92 // in to us might get changed as a side effect. Specifically, there are code
93 // paths that pass selection endpoints, and updateLayout can change the 93 // paths that pass selection endpoints, and updateLayout can change the
94 // selection. 94 // selection.
95 PositionType position = passedPosition; 95 PositionType position = passedPosition;
96 96
97 // FIXME (9535): Canonicalizing to the leftmost candidate means that if 97 // FIXME (9535): Canonicalizing to the leftmost candidate means that if
98 // we're at a line wrap, we will ask layoutObjects to paint downstream 98 // we're at a line wrap, we will ask layoutObjects to paint downstream
99 // carets for other layoutObjects. To fix this, we need to either a) add 99 // carets for other layoutObjects. To fix this, we need to either a) add
100 // code to all paintCarets to pass the responsibility off to the appropriate 100 // code to all paintCarets to pass the responsibility off to the appropriate
101 // layoutObject for VisiblePosition's like these, or b) canonicalize to the 101 // layoutObject for VisiblePosition's like these, or b) canonicalize to the
102 // rightmost candidate unless the affinity is upstream. 102 // rightmost candidate unless the affinity is upstream.
103 if (position.isNull()) 103 if (position.isNull())
104 return PositionType(); 104 return PositionType();
105 105
106 ASSERT(position.document()); 106 DCHECK(position.document());
107 position.document()->updateLayoutIgnorePendingStylesheets(); 107 position.document()->updateLayoutIgnorePendingStylesheets();
108 108
109 Node* node = position.computeContainerNode(); 109 Node* node = position.computeContainerNode();
110 110
111 PositionType candidate = mostBackwardCaretPosition(position); 111 PositionType candidate = mostBackwardCaretPosition(position);
112 if (isVisuallyEquivalentCandidate(candidate)) 112 if (isVisuallyEquivalentCandidate(candidate))
113 return candidate; 113 return candidate;
114 candidate = mostForwardCaretPosition(position); 114 candidate = mostForwardCaretPosition(position);
115 if (isVisuallyEquivalentCandidate(candidate)) 115 if (isVisuallyEquivalentCandidate(candidate))
116 return candidate; 116 return candidate;
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 next = 0; 718 next = 0;
719 } 719 }
720 it.advance(); 720 it.advance();
721 } 721 }
722 if (needMoreContext) { 722 if (needMoreContext) {
723 // The last search returned the beginning of the buffer and asked for 723 // The last search returned the beginning of the buffer and asked for
724 // more context, but there is no earlier text. Force a search with 724 // more context, but there is no earlier text. Force a search with
725 // what's available. 725 // what's available.
726 // TODO(xiaochengh): Do we have to search the whole string? 726 // TODO(xiaochengh): Do we have to search the whole string?
727 next = searchFunction(string.data(), string.size(), string.size() - suff ixLength, DontHaveMoreContext, needMoreContext); 727 next = searchFunction(string.data(), string.size(), string.size() - suff ixLength, DontHaveMoreContext, needMoreContext);
728 ASSERT(!needMoreContext); 728 DCHECK(!needMoreContext);
729 } 729 }
730 730
731 if (!next) 731 if (!next)
732 return createVisiblePosition(it.atEnd() ? it.startPosition() : pos); 732 return createVisiblePosition(it.atEnd() ? it.startPosition() : pos);
733 733
734 Node* node = it.startContainer(); 734 Node* node = it.startContainer();
735 int boundaryOffset = remainingLength + next; 735 int boundaryOffset = remainingLength + next;
736 if (node->isTextNode() && boundaryOffset <= node->maxCharacterOffset()) { 736 if (node->isTextNode() && boundaryOffset <= node->maxCharacterOffset()) {
737 // The next variable contains a usable index into a text node 737 // The next variable contains a usable index into a text node
738 return createVisiblePosition(PositionTemplate<Strategy>(node, boundaryOf fset)); 738 return createVisiblePosition(PositionTemplate<Strategy>(node, boundaryOf fset));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 next = string.size(); 812 next = string.size();
813 } 813 }
814 it.advance(); 814 it.advance();
815 } 815 }
816 if (needMoreContext) { 816 if (needMoreContext) {
817 // The last search returned the end of the buffer and asked for more 817 // The last search returned the end of the buffer and asked for more
818 // context, but there is no further text. Force a search with what's 818 // context, but there is no further text. Force a search with what's
819 // available. 819 // available.
820 // TODO(xiaochengh): Do we still have to search the whole string? 820 // TODO(xiaochengh): Do we still have to search the whole string?
821 next = searchFunction(string.data(), string.size(), prefixLength, DontHa veMoreContext, needMoreContext); 821 next = searchFunction(string.data(), string.size(), prefixLength, DontHa veMoreContext, needMoreContext);
822 ASSERT(!needMoreContext); 822 DCHECK(!needMoreContext);
823 } 823 }
824 824
825 if (it.atEnd() && next == string.size()) { 825 if (it.atEnd() && next == string.size()) {
826 pos = it.startPositionInCurrentContainer(); 826 pos = it.startPositionInCurrentContainer();
827 } else if (next != invalidOffset && next != prefixLength) { 827 } else if (next != invalidOffset && next != prefixLength) {
828 // Use the character iterator to translate the next value into a DOM 828 // Use the character iterator to translate the next value into a DOM
829 // position. 829 // position.
830 CharacterIteratorAlgorithm<Strategy> charIt(searchStart, searchEnd, Text IteratorEmitsCharactersBetweenAllVisiblePositions); 830 CharacterIteratorAlgorithm<Strategy> charIt(searchStart, searchEnd, Text IteratorEmitsCharactersBetweenAllVisiblePositions);
831 charIt.advance(next - prefixLength - 1); 831 charIt.advance(next - prefixLength - 1);
832 pos = charIt.endPosition(); 832 pos = charIt.endPosition();
(...skipping 12 matching lines...) Expand all
845 845
846 // generate VisiblePosition, use TextAffinity::Upstream affinity if possible 846 // generate VisiblePosition, use TextAffinity::Upstream affinity if possible
847 return createVisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE); 847 return createVisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE);
848 } 848 }
849 849
850 // --------- 850 // ---------
851 851
852 static unsigned startWordBoundary(const UChar* characters, unsigned length, unsi gned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMor eContext) 852 static unsigned startWordBoundary(const UChar* characters, unsigned length, unsi gned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMor eContext)
853 { 853 {
854 TRACE_EVENT0("blink", "startWordBoundary"); 854 TRACE_EVENT0("blink", "startWordBoundary");
855 ASSERT(offset); 855 DCHECK(offset);
856 if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset )) { 856 if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset )) {
857 needMoreContext = true; 857 needMoreContext = true;
858 return 0; 858 return 0;
859 } 859 }
860 needMoreContext = false; 860 needMoreContext = false;
861 int start, end; 861 int start, end;
862 U16_BACK_1(characters, 0, offset); 862 U16_BACK_1(characters, 0, offset);
863 findWordBoundary(characters, length, offset, &start, &end); 863 findWordBoundary(characters, length, offset, &start, &end);
864 return start; 864 return start;
865 } 865 }
(...skipping 21 matching lines...) Expand all
887 return startOfWordAlgorithm<EditingStrategy>(c, side); 887 return startOfWordAlgorithm<EditingStrategy>(c, side);
888 } 888 }
889 889
890 VisiblePositionInFlatTree startOfWord(const VisiblePositionInFlatTree& c, EWordS ide side) 890 VisiblePositionInFlatTree startOfWord(const VisiblePositionInFlatTree& c, EWordS ide side)
891 { 891 {
892 return startOfWordAlgorithm<EditingInFlatTreeStrategy>(c, side); 892 return startOfWordAlgorithm<EditingInFlatTreeStrategy>(c, side);
893 } 893 }
894 894
895 static unsigned endWordBoundary(const UChar* characters, unsigned length, unsign ed offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreC ontext) 895 static unsigned endWordBoundary(const UChar* characters, unsigned length, unsign ed offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreC ontext)
896 { 896 {
897 ASSERT(offset <= length); 897 DCHECK_LE(offset, length);
898 if (mayHaveMoreContext && endOfFirstWordBoundaryContext(characters + offset, length - offset) == static_cast<int>(length - offset)) { 898 if (mayHaveMoreContext && endOfFirstWordBoundaryContext(characters + offset, length - offset) == static_cast<int>(length - offset)) {
899 needMoreContext = true; 899 needMoreContext = true;
900 return length; 900 return length;
901 } 901 }
902 needMoreContext = false; 902 needMoreContext = false;
903 return findWordEndBoundary(characters, length, offset); 903 return findWordEndBoundary(characters, length, offset);
904 } 904 }
905 905
906 template <typename Strategy> 906 template <typename Strategy>
907 static VisiblePositionTemplate<Strategy> endOfWordAlgorithm(const VisiblePositio nTemplate<Strategy>& c, EWordSide side) 907 static VisiblePositionTemplate<Strategy> endOfWordAlgorithm(const VisiblePositio nTemplate<Strategy>& c, EWordSide side)
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 return isLogicalEndOfLineAlgorithm<EditingStrategy>(p); 1275 return isLogicalEndOfLineAlgorithm<EditingStrategy>(p);
1276 } 1276 }
1277 1277
1278 bool isLogicalEndOfLine(const VisiblePositionInFlatTree& p) 1278 bool isLogicalEndOfLine(const VisiblePositionInFlatTree& p)
1279 { 1279 {
1280 return isLogicalEndOfLineAlgorithm<EditingInFlatTreeStrategy>(p); 1280 return isLogicalEndOfLineAlgorithm<EditingInFlatTreeStrategy>(p);
1281 } 1281 }
1282 1282
1283 static inline LayoutPoint absoluteLineDirectionPointToLocalPointInBlock(RootInli neBox* root, LayoutUnit lineDirectionPoint) 1283 static inline LayoutPoint absoluteLineDirectionPointToLocalPointInBlock(RootInli neBox* root, LayoutUnit lineDirectionPoint)
1284 { 1284 {
1285 ASSERT(root); 1285 DCHECK(root);
1286 LineLayoutBlockFlow containingBlock = root->block(); 1286 LineLayoutBlockFlow containingBlock = root->block();
1287 FloatPoint absoluteBlockPoint = containingBlock.localToAbsolute(FloatPoint() ); 1287 FloatPoint absoluteBlockPoint = containingBlock.localToAbsolute(FloatPoint() );
1288 if (containingBlock.hasOverflowClip()) 1288 if (containingBlock.hasOverflowClip())
1289 absoluteBlockPoint -= FloatSize(containingBlock.scrolledContentOffset()) ; 1289 absoluteBlockPoint -= FloatSize(containingBlock.scrolledContentOffset()) ;
1290 1290
1291 if (root->block().isHorizontalWritingMode()) 1291 if (root->block().isHorizontalWritingMode())
1292 return LayoutPoint(LayoutUnit(lineDirectionPoint - absoluteBlockPoint.x( )), root->blockDirectionPointInLine()); 1292 return LayoutPoint(LayoutUnit(lineDirectionPoint - absoluteBlockPoint.x( )), root->blockDirectionPointInLine());
1293 1293
1294 return LayoutPoint(root->blockDirectionPointInLine(), LayoutUnit(lineDirecti onPoint - absoluteBlockPoint.y())); 1294 return LayoutPoint(root->blockDirectionPointInLine(), LayoutUnit(lineDirecti onPoint - absoluteBlockPoint.y()));
1295 } 1295 }
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 // appeared in layout tree. 2209 // appeared in layout tree.
2210 // 2210 //
2211 // When |Text| node contains only first-letter characters and whitespaces, e.g. 2211 // When |Text| node contains only first-letter characters and whitespaces, e.g.
2212 // "B\n", associated |LayoutTextFragment| is first-letter part instead of 2212 // "B\n", associated |LayoutTextFragment| is first-letter part instead of
2213 // remaining part. 2213 // remaining part.
2214 // 2214 //
2215 // Punctuation characters are considered as first-letter. For "(1)ab", 2215 // Punctuation characters are considered as first-letter. For "(1)ab",
2216 // "(1)" are first-letter part and "ab" are remaining part. 2216 // "(1)" are first-letter part and "ab" are remaining part.
2217 LayoutObject* associatedLayoutObjectOf(const Node& node, int offsetInNode) 2217 LayoutObject* associatedLayoutObjectOf(const Node& node, int offsetInNode)
2218 { 2218 {
2219 ASSERT(offsetInNode >= 0); 2219 DCHECK_GE(offsetInNode, 0);
2220 LayoutObject* layoutObject = node.layoutObject(); 2220 LayoutObject* layoutObject = node.layoutObject();
2221 if (!node.isTextNode() || !layoutObject || !toLayoutText(layoutObject)->isTe xtFragment()) 2221 if (!node.isTextNode() || !layoutObject || !toLayoutText(layoutObject)->isTe xtFragment())
2222 return layoutObject; 2222 return layoutObject;
2223 LayoutTextFragment* layoutTextFragment = toLayoutTextFragment(layoutObject); 2223 LayoutTextFragment* layoutTextFragment = toLayoutTextFragment(layoutObject);
2224 if (!layoutTextFragment->isRemainingTextLayoutObject()) { 2224 if (!layoutTextFragment->isRemainingTextLayoutObject()) {
2225 ASSERT(static_cast<unsigned>(offsetInNode) <= layoutTextFragment->start( ) + layoutTextFragment->fragmentLength()); 2225 DCHECK_LE(static_cast<unsigned>(offsetInNode), layoutTextFragment->start () + layoutTextFragment->fragmentLength());
2226 return layoutTextFragment; 2226 return layoutTextFragment;
2227 } 2227 }
2228 if (layoutTextFragment->fragmentLength() && static_cast<unsigned>(offsetInNo de) >= layoutTextFragment->start()) 2228 if (layoutTextFragment->fragmentLength() && static_cast<unsigned>(offsetInNo de) >= layoutTextFragment->start())
2229 return layoutObject; 2229 return layoutObject;
2230 LayoutObject* firstLetterLayoutObject = layoutTextFragment->firstLetterPseud oElement()->layoutObject(); 2230 LayoutObject* firstLetterLayoutObject = layoutTextFragment->firstLetterPseud oElement()->layoutObject();
2231 // TODO(yosin): We're not sure when |firstLetterLayoutObject| has 2231 // TODO(yosin): We're not sure when |firstLetterLayoutObject| has
2232 // multiple child layout object. 2232 // multiple child layout object.
2233 ASSERT(firstLetterLayoutObject->slowFirstChild() == firstLetterLayoutObject- >slowLastChild()); 2233 DCHECK_EQ(firstLetterLayoutObject->slowFirstChild(), firstLetterLayoutObject ->slowLastChild());
2234 return firstLetterLayoutObject->slowFirstChild(); 2234 return firstLetterLayoutObject->slowFirstChild();
2235 } 2235 }
2236 2236
2237 int caretMinOffset(const Node* node) 2237 int caretMinOffset(const Node* node)
2238 { 2238 {
2239 LayoutObject* layoutObject = associatedLayoutObjectOf(*node, 0); 2239 LayoutObject* layoutObject = associatedLayoutObjectOf(*node, 0);
2240 return layoutObject ? layoutObject->caretMinOffset() : 0; 2240 return layoutObject ? layoutObject->caretMinOffset() : 0;
2241 } 2241 }
2242 2242
2243 int caretMaxOffset(const Node* n) 2243 int caretMaxOffset(const Node* n)
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2418 2418
2419 // return current position if it is in laid out text 2419 // return current position if it is in laid out text
2420 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) { 2420 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) {
2421 LayoutText* const textLayoutObject = toLayoutText(layoutObject); 2421 LayoutText* const textLayoutObject = toLayoutText(layoutObject);
2422 const unsigned textStartOffset = textLayoutObject->textStartOffset() ; 2422 const unsigned textStartOffset = textLayoutObject->textStartOffset() ;
2423 if (currentNode != startNode) { 2423 if (currentNode != startNode) {
2424 // This assertion fires in layout tests in the case-transform.ht ml test because 2424 // This assertion fires in layout tests in the case-transform.ht ml test because
2425 // of a mix-up between offsets in the text in the DOM tree with text in the 2425 // of a mix-up between offsets in the text in the DOM tree with text in the
2426 // layout tree which can have a different length due to case tra nsformation. 2426 // layout tree which can have a different length due to case tra nsformation.
2427 // Until we resolve that, disable this so we can run the layout tests! 2427 // Until we resolve that, disable this so we can run the layout tests!
2428 // ASSERT(currentOffset >= layoutObject->caretMaxOffset()); 2428 // DCHECK_GE(currentOffset, layoutObject->caretMaxOffset());
2429 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMaxOffset() + textStartOffset); 2429 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMaxOffset() + textStartOffset);
2430 } 2430 }
2431 2431
2432 // Map offset in DOM node to offset in InlineBox. 2432 // Map offset in DOM node to offset in InlineBox.
2433 ASSERT(currentPos.offsetInLeafNode() >= static_cast<int>(textStartOf fset)); 2433 DCHECK_GE(currentPos.offsetInLeafNode(), static_cast<int>(textStartO ffset));
2434 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar tOffset; 2434 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar tOffset;
2435 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); 2435 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox();
2436 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) { 2436 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) {
2437 if (textOffset == box->start()) { 2437 if (textOffset == box->start()) {
2438 if (textLayoutObject->isTextFragment() && toLayoutTextFragme nt(layoutObject)->isRemainingTextLayoutObject()) { 2438 if (textLayoutObject->isTextFragment() && toLayoutTextFragme nt(layoutObject)->isRemainingTextLayoutObject()) {
2439 // |currentPos| is at start of remaining text of 2439 // |currentPos| is at start of remaining text of
2440 // |Text| node with :first-letter. 2440 // |Text| node with :first-letter.
2441 ASSERT(currentPos.offsetInLeafNode() >= 1); 2441 DCHECK_GE(currentPos.offsetInLeafNode(), 1);
2442 LayoutObject* firstLetterLayoutObject = toLayoutTextFrag ment(layoutObject)->firstLetterPseudoElement()->layoutObject(); 2442 LayoutObject* firstLetterLayoutObject = toLayoutTextFrag ment(layoutObject)->firstLetterPseudoElement()->layoutObject();
2443 if (firstLetterLayoutObject && firstLetterLayoutObject-> style()->visibility() == VISIBLE) 2443 if (firstLetterLayoutObject && firstLetterLayoutObject-> style()->visibility() == VISIBLE)
2444 return currentPos.computePosition(); 2444 return currentPos.computePosition();
2445 } 2445 }
2446 continue; 2446 continue;
2447 } 2447 }
2448 if (textOffset <= box->start() + box->len()) { 2448 if (textOffset <= box->start() + box->len()) {
2449 if (textOffset > box->start()) 2449 if (textOffset > box->start())
2450 return currentPos.computePosition(); 2450 return currentPos.computePosition();
2451 continue; 2451 continue;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset()) 2560 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset())
2561 return PositionTemplate<Strategy>::editingPositionOf(currentNode , layoutObject->caretMinOffset()); 2561 return PositionTemplate<Strategy>::editingPositionOf(currentNode , layoutObject->caretMinOffset());
2562 continue; 2562 continue;
2563 } 2563 }
2564 2564
2565 // return current position if it is in laid out text 2565 // return current position if it is in laid out text
2566 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) { 2566 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) {
2567 LayoutText* const textLayoutObject = toLayoutText(layoutObject); 2567 LayoutText* const textLayoutObject = toLayoutText(layoutObject);
2568 const unsigned textStartOffset = textLayoutObject->textStartOffset() ; 2568 const unsigned textStartOffset = textLayoutObject->textStartOffset() ;
2569 if (currentNode != startNode) { 2569 if (currentNode != startNode) {
2570 ASSERT(currentPos.atStartOfNode()); 2570 DCHECK(currentPos.atStartOfNode());
2571 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMinOffset() + textStartOffset); 2571 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMinOffset() + textStartOffset);
2572 } 2572 }
2573 2573
2574 // Map offset in DOM node to offset in InlineBox. 2574 // Map offset in DOM node to offset in InlineBox.
2575 ASSERT(currentPos.offsetInLeafNode() >= static_cast<int>(textStartOf fset)); 2575 DCHECK_GE(currentPos.offsetInLeafNode(), static_cast<int>(textStartO ffset));
2576 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar tOffset; 2576 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar tOffset;
2577 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); 2577 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox();
2578 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) { 2578 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) {
2579 if (textOffset <= box->end()) { 2579 if (textOffset <= box->end()) {
2580 if (textOffset >= box->start()) 2580 if (textOffset >= box->start())
2581 return currentPos.computePosition(); 2581 return currentPos.computePosition();
2582 continue; 2582 continue;
2583 } 2583 }
2584 2584
2585 if (box == lastTextBox || textOffset != box->start() + box->len( )) 2585 if (box == lastTextBox || textOffset != box->start() + box->len( ))
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2758 // or both are non-editable. 2758 // or both are non-editable.
2759 if (highestRootOfPos == highestRoot) 2759 if (highestRootOfPos == highestRoot)
2760 return pos; 2760 return pos;
2761 2761
2762 // If this is not editable but |pos| has an editable root, skip to the end 2762 // If this is not editable but |pos| has an editable root, skip to the end
2763 if (!highestRoot && highestRootOfPos) 2763 if (!highestRoot && highestRootOfPos)
2764 return createVisiblePosition(PositionTemplate<Strategy>(highestRootOfPos , PositionAnchorType::AfterAnchor).parentAnchoredEquivalent()); 2764 return createVisiblePosition(PositionTemplate<Strategy>(highestRootOfPos , PositionAnchorType::AfterAnchor).parentAnchoredEquivalent());
2765 2765
2766 // That must mean that |pos| is not editable. Return the next position after 2766 // That must mean that |pos| is not editable. Return the next position after
2767 // |pos| that is in the same editable region as this position 2767 // |pos| that is in the same editable region as this position
2768 ASSERT(highestRoot); 2768 DCHECK(highestRoot);
2769 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), *highestRoot); 2769 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), *highestRoot);
2770 } 2770 }
2771 2771
2772 template <typename Strategy> 2772 template <typename Strategy>
2773 static UChar32 characterAfterAlgorithm(const VisiblePositionTemplate<Strategy>& visiblePosition) 2773 static UChar32 characterAfterAlgorithm(const VisiblePositionTemplate<Strategy>& visiblePosition)
2774 { 2774 {
2775 // We canonicalize to the first of two equivalent candidates, but the second 2775 // We canonicalize to the first of two equivalent candidates, but the second
2776 // of the two candidates is the one that will be inside the text node 2776 // of the two candidates is the one that will be inside the text node
2777 // containing the character after this visible position. 2777 // containing the character after this visible position.
2778 const PositionTemplate<Strategy> pos = mostForwardCaretPosition(visiblePosit ion.deepEquivalent()); 2778 const PositionTemplate<Strategy> pos = mostForwardCaretPosition(visiblePosit ion.deepEquivalent());
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2874 } 2874 }
2875 2875
2876 // Reposition at the other logical position corresponding to our 2876 // Reposition at the other logical position corresponding to our
2877 // edge's visual position and go for another round. 2877 // edge's visual position and go for another round.
2878 box = prevBox; 2878 box = prevBox;
2879 lineLayoutItem = box->getLineLayoutItem(); 2879 lineLayoutItem = box->getLineLayoutItem();
2880 offset = prevBox->caretRightmostOffset(); 2880 offset = prevBox->caretRightmostOffset();
2881 continue; 2881 continue;
2882 } 2882 }
2883 2883
2884 ASSERT(offset == box->caretLeftmostOffset()); 2884 DCHECK_EQ(offset, box->caretLeftmostOffset());
2885 2885
2886 unsigned char level = box->bidiLevel(); 2886 unsigned char level = box->bidiLevel();
2887 InlineBox* prevBox = box->prevLeafChild(); 2887 InlineBox* prevBox = box->prevLeafChild();
2888 2888
2889 if (box->direction() == primaryDirection) { 2889 if (box->direction() == primaryDirection) {
2890 if (!prevBox) { 2890 if (!prevBox) {
2891 InlineBox* logicalStart = 0; 2891 InlineBox* logicalStart = 0;
2892 if (primaryDirection == LTR ? box->root().getLogicalStartBox WithNode(logicalStart) : box->root().getLogicalEndBoxWithNode(logicalStart)) { 2892 if (primaryDirection == LTR ? box->root().getLogicalStartBox WithNode(logicalStart) : box->root().getLogicalEndBoxWithNode(logicalStart)) {
2893 box = logicalStart; 2893 box = logicalStart;
2894 lineLayoutItem = box->getLineLayoutItem(); 2894 lineLayoutItem = box->getLineLayoutItem();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2957 offset = primaryDirection == LTR ? box->caretMinOffset() : box-> caretMaxOffset(); 2957 offset = primaryDirection == LTR ? box->caretMinOffset() : box-> caretMaxOffset();
2958 } 2958 }
2959 break; 2959 break;
2960 } 2960 }
2961 2961
2962 p = PositionTemplate<Strategy>::editingPositionOf(lineLayoutItem.node(), offset); 2962 p = PositionTemplate<Strategy>::editingPositionOf(lineLayoutItem.node(), offset);
2963 2963
2964 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) != downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) 2964 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
2965 return p; 2965 return p;
2966 2966
2967 ASSERT(p != deepPosition); 2967 DCHECK_NE(p, deepPosition);
2968 } 2968 }
2969 } 2969 }
2970 2970
2971 template <typename Strategy> 2971 template <typename Strategy>
2972 VisiblePositionTemplate<Strategy> leftPositionOfAlgorithm(const VisiblePositionT emplate<Strategy>& visiblePosition) 2972 VisiblePositionTemplate<Strategy> leftPositionOfAlgorithm(const VisiblePositionT emplate<Strategy>& visiblePosition)
2973 { 2973 {
2974 const PositionTemplate<Strategy> pos = leftVisuallyDistinctCandidate(visible Position); 2974 const PositionTemplate<Strategy> pos = leftVisuallyDistinctCandidate(visible Position);
2975 // TODO(yosin) Why can't we move left from the last position in a tree? 2975 // TODO(yosin) Why can't we move left from the last position in a tree?
2976 if (pos.atStartOfTree() || pos.atEndOfTree()) 2976 if (pos.atStartOfTree() || pos.atEndOfTree())
2977 return VisiblePositionTemplate<Strategy>(); 2977 return VisiblePositionTemplate<Strategy>();
2978 2978
2979 const VisiblePositionTemplate<Strategy> left = createVisiblePosition(pos); 2979 const VisiblePositionTemplate<Strategy> left = createVisiblePosition(pos);
2980 ASSERT(left.deepEquivalent() != visiblePosition.deepEquivalent()); 2980 DCHECK_NE(left.deepEquivalent(), visiblePosition.deepEquivalent());
2981 2981
2982 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? honorEditin gBoundaryAtOrBefore(left, visiblePosition.deepEquivalent()) : honorEditingBounda ryAtOrAfter(left, visiblePosition.deepEquivalent()); 2982 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? honorEditin gBoundaryAtOrBefore(left, visiblePosition.deepEquivalent()) : honorEditingBounda ryAtOrAfter(left, visiblePosition.deepEquivalent());
2983 } 2983 }
2984 2984
2985 VisiblePosition leftPositionOf(const VisiblePosition& visiblePosition) 2985 VisiblePosition leftPositionOf(const VisiblePosition& visiblePosition)
2986 { 2986 {
2987 return leftPositionOfAlgorithm<EditingStrategy>(visiblePosition); 2987 return leftPositionOfAlgorithm<EditingStrategy>(visiblePosition);
2988 } 2988 }
2989 2989
2990 VisiblePositionInFlatTree leftPositionOf(const VisiblePositionInFlatTree& visibl ePosition) 2990 VisiblePositionInFlatTree leftPositionOf(const VisiblePositionInFlatTree& visibl ePosition)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3049 } 3049 }
3050 3050
3051 // Reposition at the other logical position corresponding to our 3051 // Reposition at the other logical position corresponding to our
3052 // edge's visual position and go for another round. 3052 // edge's visual position and go for another round.
3053 box = nextBox; 3053 box = nextBox;
3054 layoutObject = LineLayoutAPIShim::layoutObjectFrom(box->getLineL ayoutItem()); 3054 layoutObject = LineLayoutAPIShim::layoutObjectFrom(box->getLineL ayoutItem());
3055 offset = nextBox->caretLeftmostOffset(); 3055 offset = nextBox->caretLeftmostOffset();
3056 continue; 3056 continue;
3057 } 3057 }
3058 3058
3059 ASSERT(offset == box->caretRightmostOffset()); 3059 DCHECK_EQ(offset, box->caretRightmostOffset());
3060 3060
3061 unsigned char level = box->bidiLevel(); 3061 unsigned char level = box->bidiLevel();
3062 InlineBox* nextBox = box->nextLeafChild(); 3062 InlineBox* nextBox = box->nextLeafChild();
3063 3063
3064 if (box->direction() == primaryDirection) { 3064 if (box->direction() == primaryDirection) {
3065 if (!nextBox) { 3065 if (!nextBox) {
3066 InlineBox* logicalEnd = 0; 3066 InlineBox* logicalEnd = 0;
3067 if (primaryDirection == LTR ? box->root().getLogicalEndBoxWi thNode(logicalEnd) : box->root().getLogicalStartBoxWithNode(logicalEnd)) { 3067 if (primaryDirection == LTR ? box->root().getLogicalEndBoxWi thNode(logicalEnd) : box->root().getLogicalStartBoxWithNode(logicalEnd)) {
3068 box = logicalEnd; 3068 box = logicalEnd;
3069 layoutObject = LineLayoutAPIShim::layoutObjectFrom(box-> getLineLayoutItem()); 3069 layoutObject = LineLayoutAPIShim::layoutObjectFrom(box-> getLineLayoutItem());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3135 offset = primaryDirection == LTR ? box->caretMaxOffset() : box-> caretMinOffset(); 3135 offset = primaryDirection == LTR ? box->caretMaxOffset() : box-> caretMinOffset();
3136 } 3136 }
3137 break; 3137 break;
3138 } 3138 }
3139 3139
3140 p = PositionTemplate<Strategy>::editingPositionOf(layoutObject->node(), offset); 3140 p = PositionTemplate<Strategy>::editingPositionOf(layoutObject->node(), offset);
3141 3141
3142 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) != downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) 3142 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
3143 return p; 3143 return p;
3144 3144
3145 ASSERT(p != deepPosition); 3145 DCHECK_NE(p, deepPosition);
3146 } 3146 }
3147 } 3147 }
3148 3148
3149 template <typename Strategy> 3149 template <typename Strategy>
3150 static VisiblePositionTemplate<Strategy> rightPositionOfAlgorithm(const VisibleP ositionTemplate<Strategy>& visiblePosition) 3150 static VisiblePositionTemplate<Strategy> rightPositionOfAlgorithm(const VisibleP ositionTemplate<Strategy>& visiblePosition)
3151 { 3151 {
3152 const PositionTemplate<Strategy> pos = rightVisuallyDistinctCandidate(visibl ePosition); 3152 const PositionTemplate<Strategy> pos = rightVisuallyDistinctCandidate(visibl ePosition);
3153 // FIXME: Why can't we move left from the last position in a tree? 3153 // FIXME: Why can't we move left from the last position in a tree?
3154 if (pos.atStartOfTree() || pos.atEndOfTree()) 3154 if (pos.atStartOfTree() || pos.atEndOfTree())
3155 return VisiblePositionTemplate<Strategy>(); 3155 return VisiblePositionTemplate<Strategy>();
3156 3156
3157 const VisiblePositionTemplate<Strategy> right = createVisiblePosition(pos); 3157 const VisiblePositionTemplate<Strategy> right = createVisiblePosition(pos);
3158 ASSERT(right.deepEquivalent() != visiblePosition.deepEquivalent()); 3158 DCHECK_NE(right.deepEquivalent(), visiblePosition.deepEquivalent());
3159 3159
3160 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? honorEditi ngBoundaryAtOrAfter(right, visiblePosition.deepEquivalent()) : honorEditingBound aryAtOrBefore(right, visiblePosition.deepEquivalent()); 3160 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? honorEditi ngBoundaryAtOrAfter(right, visiblePosition.deepEquivalent()) : honorEditingBound aryAtOrBefore(right, visiblePosition.deepEquivalent());
3161 } 3161 }
3162 3162
3163 VisiblePosition rightPositionOf(const VisiblePosition& visiblePosition) 3163 VisiblePosition rightPositionOf(const VisiblePosition& visiblePosition)
3164 { 3164 {
3165 return rightPositionOfAlgorithm<EditingStrategy>(visiblePosition); 3165 return rightPositionOfAlgorithm<EditingStrategy>(visiblePosition);
3166 } 3166 }
3167 3167
3168 VisiblePositionInFlatTree rightPositionOf(const VisiblePositionInFlatTree& visib lePosition) 3168 VisiblePositionInFlatTree rightPositionOf(const VisiblePositionInFlatTree& visib lePosition)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3210 // both are non-editable. 3210 // both are non-editable.
3211 if (highestRootOfPos == highestRoot) 3211 if (highestRootOfPos == highestRoot)
3212 return pos; 3212 return pos;
3213 3213
3214 // If this is not editable but |pos| has an editable root, skip to the start 3214 // If this is not editable but |pos| has an editable root, skip to the start
3215 if (!highestRoot && highestRootOfPos) 3215 if (!highestRoot && highestRootOfPos)
3216 return createVisiblePosition(previousVisuallyDistinctCandidate(PositionT emplate<Strategy>(highestRootOfPos, PositionAnchorType::BeforeAnchor).parentAnch oredEquivalent())); 3216 return createVisiblePosition(previousVisuallyDistinctCandidate(PositionT emplate<Strategy>(highestRootOfPos, PositionAnchorType::BeforeAnchor).parentAnch oredEquivalent()));
3217 3217
3218 // That must mean that |pos| is not editable. Return the last position 3218 // That must mean that |pos| is not editable. Return the last position
3219 // before |pos| that is in the same editable region as this position 3219 // before |pos| that is in the same editable region as this position
3220 ASSERT(highestRoot); 3220 DCHECK(highestRoot);
3221 return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), *highestRoot); 3221 return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), *highestRoot);
3222 } 3222 }
3223 3223
3224 template <typename Strategy> 3224 template <typename Strategy>
3225 static VisiblePositionTemplate<Strategy> previousPositionOfAlgorithm(const Visib lePositionTemplate<Strategy>& visiblePosition, EditingBoundaryCrossingRule rule) 3225 static VisiblePositionTemplate<Strategy> previousPositionOfAlgorithm(const Visib lePositionTemplate<Strategy>& visiblePosition, EditingBoundaryCrossingRule rule)
3226 { 3226 {
3227 const PositionTemplate<Strategy> pos = previousVisuallyDistinctCandidate(vis iblePosition.deepEquivalent()); 3227 const PositionTemplate<Strategy> pos = previousVisuallyDistinctCandidate(vis iblePosition.deepEquivalent());
3228 3228
3229 // return null visible position if there is no previous visible position 3229 // return null visible position if there is no previous visible position
3230 if (pos.atStartOfTree()) 3230 if (pos.atStartOfTree())
3231 return VisiblePositionTemplate<Strategy>(); 3231 return VisiblePositionTemplate<Strategy>();
3232 3232
3233 // we should always be able to make the affinity |TextAffinity::Downstream|, 3233 // we should always be able to make the affinity |TextAffinity::Downstream|,
3234 // because going previous from an |TextAffinity::Upstream| position can 3234 // because going previous from an |TextAffinity::Upstream| position can
3235 // never yield another |TextAffinity::Upstream position| (unless line wrap 3235 // never yield another |TextAffinity::Upstream position| (unless line wrap
3236 // length is 0!). 3236 // length is 0!).
3237 const VisiblePositionTemplate<Strategy> prev = createVisiblePosition(pos); 3237 const VisiblePositionTemplate<Strategy> prev = createVisiblePosition(pos);
3238 ASSERT(prev.deepEquivalent() != visiblePosition.deepEquivalent()); 3238 DCHECK_NE(prev.deepEquivalent(), visiblePosition.deepEquivalent());
3239 3239
3240 switch (rule) { 3240 switch (rule) {
3241 case CanCrossEditingBoundary: 3241 case CanCrossEditingBoundary:
3242 return prev; 3242 return prev;
3243 case CannotCrossEditingBoundary: 3243 case CannotCrossEditingBoundary:
3244 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale nt()); 3244 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale nt());
3245 case CanSkipOverEditingBoundary: 3245 case CanSkipOverEditingBoundary:
3246 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent ()); 3246 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent ());
3247 } 3247 }
3248 3248
3249 ASSERT_NOT_REACHED(); 3249 ASSERT_NOT_REACHED();
3250 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent() ); 3250 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent() );
3251 } 3251 }
3252 3252
3253 VisiblePosition previousPositionOf(const VisiblePosition& visiblePosition, Editi ngBoundaryCrossingRule rule) 3253 VisiblePosition previousPositionOf(const VisiblePosition& visiblePosition, Editi ngBoundaryCrossingRule rule)
3254 { 3254 {
3255 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); 3255 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule);
3256 } 3256 }
3257 3257
3258 VisiblePositionInFlatTree previousPositionOf(const VisiblePositionInFlatTree& vi siblePosition, EditingBoundaryCrossingRule rule) 3258 VisiblePositionInFlatTree previousPositionOf(const VisiblePositionInFlatTree& vi siblePosition, EditingBoundaryCrossingRule rule)
3259 { 3259 {
3260 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>(visiblePositio n, rule); 3260 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>(visiblePositio n, rule);
3261 } 3261 }
3262 3262
3263 } // namespace blink 3263 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698