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

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

Issue 1317053004: Make VisiblePosition constructor private (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-09-01T18:48:19 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
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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 192 }
193 return 0; 193 return 0;
194 } 194 }
195 195
196 // FIXME: consolidate with code in previousLinePosition. 196 // FIXME: consolidate with code in previousLinePosition.
197 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible Position& visiblePosition, EditableType editableType) 197 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible Position& visiblePosition, EditableType editableType)
198 { 198 {
199 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent(), editableType); 199 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent(), editableType);
200 Node* previousNode = previousLeafWithSameEditability(node, editableType); 200 Node* previousNode = previousLeafWithSameEditability(node, editableType);
201 201
202 while (previousNode && (!previousNode->layoutObject() || inSameLine(VisibleP osition(firstPositionInOrBeforeNode(previousNode)), visiblePosition))) 202 while (previousNode && (!previousNode->layoutObject() || inSameLine(createVi siblePosition(firstPositionInOrBeforeNode(previousNode)), visiblePosition)))
203 previousNode = previousLeafWithSameEditability(previousNode, editableTyp e); 203 previousNode = previousLeafWithSameEditability(previousNode, editableTyp e);
204 204
205 while (previousNode && !previousNode->isShadowRoot()) { 205 while (previousNode && !previousNode->isShadowRoot()) {
206 if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode), edita bleType) != highestRoot) 206 if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode), edita bleType) != highestRoot)
207 break; 207 break;
208 208
209 Position pos = isHTMLBRElement(*previousNode) ? positionBeforeNode(previ ousNode) : 209 Position pos = isHTMLBRElement(*previousNode) ? positionBeforeNode(previ ousNode) :
210 Position::editingPositionOf(previousNode, caretMaxOffset(previousNod e)); 210 Position::editingPositionOf(previousNode, caretMaxOffset(previousNod e));
211 211
212 if (isVisuallyEquivalentCandidate(pos)) 212 if (isVisuallyEquivalentCandidate(pos))
213 return pos; 213 return pos;
214 214
215 previousNode = previousLeafWithSameEditability(previousNode, editableTyp e); 215 previousNode = previousLeafWithSameEditability(previousNode, editableTyp e);
216 } 216 }
217 return Position(); 217 return Position();
218 } 218 }
219 219
220 static Position nextRootInlineBoxCandidatePosition(Node* node, const VisiblePosi tion& visiblePosition, EditableType editableType) 220 static Position nextRootInlineBoxCandidatePosition(Node* node, const VisiblePosi tion& visiblePosition, EditableType editableType)
221 { 221 {
222 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent(), editableType); 222 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent(), editableType);
223 Node* nextNode = nextLeafWithSameEditability(node, editableType); 223 Node* nextNode = nextLeafWithSameEditability(node, editableType);
224 while (nextNode && (!nextNode->layoutObject() || inSameLine(VisiblePosition( firstPositionInOrBeforeNode(nextNode)), visiblePosition))) 224 while (nextNode && (!nextNode->layoutObject() || inSameLine(createVisiblePos ition(firstPositionInOrBeforeNode(nextNode)), visiblePosition)))
225 nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable); 225 nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable);
226 226
227 while (nextNode && !nextNode->isShadowRoot()) { 227 while (nextNode && !nextNode->isShadowRoot()) {
228 if (highestEditableRoot(firstPositionInOrBeforeNode(nextNode), editableT ype) != highestRoot) 228 if (highestEditableRoot(firstPositionInOrBeforeNode(nextNode), editableT ype) != highestRoot)
229 break; 229 break;
230 230
231 Position pos; 231 Position pos;
232 pos = Position::editingPositionOf(nextNode, caretMinOffset(nextNode)); 232 pos = Position::editingPositionOf(nextNode, caretMinOffset(nextNode));
233 233
234 if (isVisuallyEquivalentCandidate(pos)) 234 if (isVisuallyEquivalentCandidate(pos))
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 it.advance(); 642 it.advance();
643 } 643 }
644 if (needMoreContext) { 644 if (needMoreContext) {
645 // The last search returned the beginning of the buffer and asked for mo re context, 645 // The last search returned the beginning of the buffer and asked for mo re context,
646 // but there is no earlier text. Force a search with what's available. 646 // but there is no earlier text. Force a search with what's available.
647 next = searchFunction(string.data(), string.size(), string.size() - suff ixLength, DontHaveMoreContext, needMoreContext); 647 next = searchFunction(string.data(), string.size(), string.size() - suff ixLength, DontHaveMoreContext, needMoreContext);
648 ASSERT(!needMoreContext); 648 ASSERT(!needMoreContext);
649 } 649 }
650 650
651 if (!next) 651 if (!next)
652 return VisiblePosition(it.atEnd() ? it.startPosition() : pos); 652 return createVisiblePosition(it.atEnd() ? it.startPosition() : pos);
653 653
654 Node* node = it.startContainer(); 654 Node* node = it.startContainer();
655 if (node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffset ()) { 655 if (node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffset ()) {
656 // The next variable contains a usable index into a text node 656 // The next variable contains a usable index into a text node
657 return VisiblePosition(Position(node, next)); 657 return createVisiblePosition(Position(node, next));
658 } 658 }
659 659
660 // Use the character iterator to translate the next value into a DOM positio n. 660 // Use the character iterator to translate the next value into a DOM positio n.
661 BackwardsCharacterIterator charIt(start, end); 661 BackwardsCharacterIterator charIt(start, end);
662 charIt.advance(string.size() - suffixLength - next); 662 charIt.advance(string.size() - suffixLength - next);
663 // FIXME: charIt can get out of shadow host. 663 // FIXME: charIt can get out of shadow host.
664 return VisiblePosition(charIt.endPosition()); 664 return createVisiblePosition(charIt.endPosition());
665 } 665 }
666 666
667 static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc tion searchFunction) 667 static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc tion searchFunction)
668 { 668 {
669 Position pos = c.deepEquivalent(); 669 Position pos = c.deepEquivalent();
670 Node* boundary = parentEditingBoundary(pos); 670 Node* boundary = parentEditingBoundary(pos);
671 if (!boundary) 671 if (!boundary)
672 return VisiblePosition(); 672 return VisiblePosition();
673 673
674 Document& d = boundary->document(); 674 Document& d = boundary->document();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 if (it.atEnd() && next == string.size()) { 727 if (it.atEnd() && next == string.size()) {
728 pos = it.startPositionInCurrentContainer(); 728 pos = it.startPositionInCurrentContainer();
729 } else if (next != invalidOffset && next != prefixLength) { 729 } else if (next != invalidOffset && next != prefixLength) {
730 // Use the character iterator to translate the next value into a DOM pos ition. 730 // Use the character iterator to translate the next value into a DOM pos ition.
731 CharacterIterator charIt(searchStart, searchEnd, TextIteratorEmitsCharac tersBetweenAllVisiblePositions); 731 CharacterIterator charIt(searchStart, searchEnd, TextIteratorEmitsCharac tersBetweenAllVisiblePositions);
732 charIt.advance(next - prefixLength - 1); 732 charIt.advance(next - prefixLength - 1);
733 pos = charIt.endPosition(); 733 pos = charIt.endPosition();
734 734
735 if (charIt.characterAt(0) == '\n') { 735 if (charIt.characterAt(0) == '\n') {
736 // FIXME: workaround for collapsed range (where only start position is correct) emitted for some emitted newlines (see rdar://5192593) 736 // FIXME: workaround for collapsed range (where only start position is correct) emitted for some emitted newlines (see rdar://5192593)
737 VisiblePosition visPos = VisiblePosition(pos); 737 VisiblePosition visPos = createVisiblePosition(pos);
738 if (visPos.deepEquivalent() == VisiblePosition(charIt.startPosition( )).deepEquivalent()) { 738 if (visPos.deepEquivalent() == createVisiblePosition(charIt.startPos ition()).deepEquivalent()) {
739 charIt.advance(1); 739 charIt.advance(1);
740 pos = charIt.startPosition(); 740 pos = charIt.startPosition();
741 } 741 }
742 } 742 }
743 } 743 }
744 744
745 // generate VisiblePosition, use TextAffinity::Upstream affinity if possible 745 // generate VisiblePosition, use TextAffinity::Upstream affinity if possible
746 return VisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE); 746 return createVisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE);
747 } 747 }
748 748
749 // --------- 749 // ---------
750 750
751 static unsigned startWordBoundary(const UChar* characters, unsigned length, unsi gned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMor eContext) 751 static unsigned startWordBoundary(const UChar* characters, unsigned length, unsi gned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMor eContext)
752 { 752 {
753 ASSERT(offset); 753 ASSERT(offset);
754 if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset )) { 754 if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset )) {
755 needMoreContext = true; 755 needMoreContext = true;
756 return 0; 756 return 0;
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 } else if (endBox->isInlineTextBox() && endNode->isTextNode()) { 965 } else if (endBox->isInlineTextBox() && endNode->isTextNode()) {
966 InlineTextBox* endTextBox = toInlineTextBox(endBox); 966 InlineTextBox* endTextBox = toInlineTextBox(endBox);
967 int endOffset = endTextBox->start(); 967 int endOffset = endTextBox->start();
968 if (!endTextBox->isLineBreak()) 968 if (!endTextBox->isLineBreak())
969 endOffset += endTextBox->len(); 969 endOffset += endTextBox->len();
970 pos = Position(toText(endNode), endOffset); 970 pos = Position(toText(endNode), endOffset);
971 } else { 971 } else {
972 pos = positionAfterNode(endNode); 972 pos = positionAfterNode(endNode);
973 } 973 }
974 974
975 return VisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE); 975 return createVisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE);
976 } 976 }
977 977
978 static bool inSameLogicalLine(const VisiblePosition& a, const VisiblePosition& b ) 978 static bool inSameLogicalLine(const VisiblePosition& a, const VisiblePosition& b )
979 { 979 {
980 return a.isNotNull() && logicalStartOfLine(a).deepEquivalent() == logicalSta rtOfLine(b).deepEquivalent(); 980 return a.isNotNull() && logicalStartOfLine(a).deepEquivalent() == logicalSta rtOfLine(b).deepEquivalent();
981 } 981 }
982 982
983 static VisiblePosition endOfLine(const VisiblePosition& c, LineEndpointComputati onMode mode) 983 static VisiblePosition endOfLine(const VisiblePosition& c, LineEndpointComputati onMode mode)
984 { 984 {
985 // TODO: this is the current behavior that might need to be fixed. 985 // TODO: this is the current behavior that might need to be fixed.
986 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail. 986 // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail.
987 VisiblePosition visPos = endPositionForLine(c, mode); 987 VisiblePosition visPos = endPositionForLine(c, mode);
988 988
989 if (mode == UseLogicalOrdering) { 989 if (mode == UseLogicalOrdering) {
990 // Make sure the end of line is at the same line as the given input posi tion. For a wrapping line, the logical end 990 // Make sure the end of line is at the same line as the given input posi tion. For a wrapping line, the logical end
991 // position for the not-last-2-lines might incorrectly hand back the log ical beginning of the next line. 991 // position for the not-last-2-lines might incorrectly hand back the log ical beginning of the next line.
992 // For example, <div contenteditable dir="rtl" style="line-break:before- white-space">abcdefg abcdefg abcdefg 992 // For example, <div contenteditable dir="rtl" style="line-break:before- white-space">abcdefg abcdefg abcdefg
993 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abc defg abcdefg </div> 993 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abc defg abcdefg </div>
994 // In this case, use the previous position of the computed logical end p osition. 994 // In this case, use the previous position of the computed logical end p osition.
995 if (!inSameLogicalLine(c, visPos)) 995 if (!inSameLogicalLine(c, visPos))
996 visPos = previousPositionOf(visPos); 996 visPos = previousPositionOf(visPos);
997 997
998 if (ContainerNode* editableRoot = highestEditableRoot(c.deepEquivalent() )) { 998 if (ContainerNode* editableRoot = highestEditableRoot(c.deepEquivalent() )) {
999 if (!editableRoot->contains(visPos.deepEquivalent().computeContainer Node())) 999 if (!editableRoot->contains(visPos.deepEquivalent().computeContainer Node()))
1000 return VisiblePosition(lastPositionInNode(editableRoot)); 1000 return createVisiblePosition(lastPositionInNode(editableRoot));
1001 } 1001 }
1002 1002
1003 return honorEditingBoundaryAtOrAfter(visPos, c.deepEquivalent()); 1003 return honorEditingBoundaryAtOrAfter(visPos, c.deepEquivalent());
1004 } 1004 }
1005 1005
1006 // Make sure the end of line is at the same line as the given input position . Else use the previous position to 1006 // Make sure the end of line is at the same line as the given input position . Else use the previous position to
1007 // obtain end of line. This condition happens when the input position is bef ore the space character at the end 1007 // obtain end of line. This condition happens when the input position is bef ore the space character at the end
1008 // of a soft-wrapped non-editable line. In this scenario, endPositionForLine would incorrectly hand back a position 1008 // of a soft-wrapped non-editable line. In this scenario, endPositionForLine would incorrectly hand back a position
1009 // in the next line instead. This fix is to account for the discrepancy betw een lines with webkit-line-break:after-white-space style 1009 // in the next line instead. This fix is to account for the discrepancy betw een lines with webkit-line-break:after-white-space style
1010 // versus lines without that style, which would break before a space by defa ult. 1010 // versus lines without that style, which would break before a space by defa ult.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 root = box->root().prevRootBox(); 1108 root = box->root().prevRootBox();
1109 // We want to skip zero height boxes. 1109 // We want to skip zero height boxes.
1110 // This could happen in case it is a TrailingFloatsRootInlineBox. 1110 // This could happen in case it is a TrailingFloatsRootInlineBox.
1111 if (!root || !root->logicalHeight() || !root->firstLeafChild()) 1111 if (!root || !root->logicalHeight() || !root->firstLeafChild())
1112 root = 0; 1112 root = 0;
1113 } 1113 }
1114 1114
1115 if (!root) { 1115 if (!root) {
1116 Position position = previousRootInlineBoxCandidatePosition(node, visible Position, editableType); 1116 Position position = previousRootInlineBoxCandidatePosition(node, visible Position, editableType);
1117 if (position.isNotNull()) { 1117 if (position.isNotNull()) {
1118 RenderedPosition renderedPosition((VisiblePosition(position))); 1118 RenderedPosition renderedPosition((createVisiblePosition(position))) ;
1119 root = renderedPosition.rootBox(); 1119 root = renderedPosition.rootBox();
1120 if (!root) 1120 if (!root)
1121 return VisiblePosition(position); 1121 return createVisiblePosition(position);
1122 } 1122 }
1123 } 1123 }
1124 1124
1125 if (root) { 1125 if (root) {
1126 // FIXME: Can be wrong for multi-column layout and with transforms. 1126 // FIXME: Can be wrong for multi-column layout and with transforms.
1127 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock( root, lineDirectionPoint); 1127 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock( root, lineDirectionPoint);
1128 LayoutObject& layoutObject = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->layoutObject(); 1128 LayoutObject& layoutObject = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->layoutObject();
1129 Node* node = layoutObject.node(); 1129 Node* node = layoutObject.node();
1130 if (node && editingIgnoresContent(node)) 1130 if (node && editingIgnoresContent(node))
1131 return VisiblePosition(positionInParentBeforeNode(*node)); 1131 return createVisiblePosition(positionInParentBeforeNode(*node));
1132 return createVisiblePosition(layoutObject.positionForPoint(pointInLine)) ; 1132 return createVisiblePosition(layoutObject.positionForPoint(pointInLine)) ;
1133 } 1133 }
1134 1134
1135 // Could not find a previous line. This means we must already be on the firs t line. 1135 // Could not find a previous line. This means we must already be on the firs t line.
1136 // Move to the start of the content in this block, which effectively moves u s 1136 // Move to the start of the content in this block, which effectively moves u s
1137 // to the start of the line we're on. 1137 // to the start of the line we're on.
1138 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit ableElement(editableType) : node->document().documentElement(); 1138 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit ableElement(editableType) : node->document().documentElement();
1139 if (!rootElement) 1139 if (!rootElement)
1140 return VisiblePosition(); 1140 return VisiblePosition();
1141 return VisiblePosition(firstPositionInNode(rootElement)); 1141 return createVisiblePosition(firstPositionInNode(rootElement));
1142 } 1142 }
1143 1143
1144 VisiblePosition nextLinePosition(const VisiblePosition& visiblePosition, LayoutU nit lineDirectionPoint, EditableType editableType) 1144 VisiblePosition nextLinePosition(const VisiblePosition& visiblePosition, LayoutU nit lineDirectionPoint, EditableType editableType)
1145 { 1145 {
1146 Position p = visiblePosition.deepEquivalent(); 1146 Position p = visiblePosition.deepEquivalent();
1147 Node* node = p.anchorNode(); 1147 Node* node = p.anchorNode();
1148 1148
1149 if (!node) 1149 if (!node)
1150 return VisiblePosition(); 1150 return VisiblePosition();
1151 1151
(...skipping 12 matching lines...) Expand all
1164 if (!root || !root->logicalHeight() || !root->firstLeafChild()) 1164 if (!root || !root->logicalHeight() || !root->firstLeafChild())
1165 root = 0; 1165 root = 0;
1166 } 1166 }
1167 1167
1168 if (!root) { 1168 if (!root) {
1169 // FIXME: We need do the same in previousLinePosition. 1169 // FIXME: We need do the same in previousLinePosition.
1170 Node* child = NodeTraversal::childAt(*node, p.computeEditingOffset()); 1170 Node* child = NodeTraversal::childAt(*node, p.computeEditingOffset());
1171 node = child ? child : &NodeTraversal::lastWithinOrSelf(*node); 1171 node = child ? child : &NodeTraversal::lastWithinOrSelf(*node);
1172 Position position = nextRootInlineBoxCandidatePosition(node, visiblePosi tion, editableType); 1172 Position position = nextRootInlineBoxCandidatePosition(node, visiblePosi tion, editableType);
1173 if (position.isNotNull()) { 1173 if (position.isNotNull()) {
1174 RenderedPosition renderedPosition((VisiblePosition(position))); 1174 RenderedPosition renderedPosition((createVisiblePosition(position))) ;
1175 root = renderedPosition.rootBox(); 1175 root = renderedPosition.rootBox();
1176 if (!root) 1176 if (!root)
1177 return VisiblePosition(position); 1177 return createVisiblePosition(position);
1178 } 1178 }
1179 } 1179 }
1180 1180
1181 if (root) { 1181 if (root) {
1182 // FIXME: Can be wrong for multi-column layout and with transforms. 1182 // FIXME: Can be wrong for multi-column layout and with transforms.
1183 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock( root, lineDirectionPoint); 1183 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock( root, lineDirectionPoint);
1184 LayoutObject& layoutObject = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->layoutObject(); 1184 LayoutObject& layoutObject = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->layoutObject();
1185 Node* node = layoutObject.node(); 1185 Node* node = layoutObject.node();
1186 if (node && editingIgnoresContent(node)) 1186 if (node && editingIgnoresContent(node))
1187 return VisiblePosition(positionInParentBeforeNode(*node)); 1187 return createVisiblePosition(positionInParentBeforeNode(*node));
1188 return createVisiblePosition(layoutObject.positionForPoint(pointInLine)) ; 1188 return createVisiblePosition(layoutObject.positionForPoint(pointInLine)) ;
1189 } 1189 }
1190 1190
1191 // Could not find a next line. This means we must already be on the last lin e. 1191 // Could not find a next line. This means we must already be on the last lin e.
1192 // Move to the end of the content in this block, which effectively moves us 1192 // Move to the end of the content in this block, which effectively moves us
1193 // to the end of the line we're on. 1193 // to the end of the line we're on.
1194 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit ableElement(editableType) : node->document().documentElement(); 1194 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit ableElement(editableType) : node->document().documentElement();
1195 if (!rootElement) 1195 if (!rootElement)
1196 return VisiblePosition(); 1196 return VisiblePosition();
1197 return VisiblePosition(lastPositionInNode(rootElement)); 1197 return createVisiblePosition(lastPositionInNode(rootElement));
1198 } 1198 }
1199 1199
1200 // --------- 1200 // ---------
1201 1201
1202 static unsigned startSentenceBoundary(const UChar* characters, unsigned length, unsigned, BoundarySearchContextAvailability, bool&) 1202 static unsigned startSentenceBoundary(const UChar* characters, unsigned length, unsigned, BoundarySearchContextAvailability, bool&)
1203 { 1203 {
1204 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); 1204 TextBreakIterator* iterator = sentenceBreakIterator(characters, length);
1205 // FIXME: The following function can return -1; we don't handle that. 1205 // FIXME: The following function can return -1; we don't handle that.
1206 return iterator->preceding(length); 1206 return iterator->preceding(length);
1207 } 1207 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 1253
1254 VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi ngRule boundaryCrossingRule) 1254 VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi ngRule boundaryCrossingRule)
1255 { 1255 {
1256 Position p = c.deepEquivalent(); 1256 Position p = c.deepEquivalent();
1257 Node* startNode = p.anchorNode(); 1257 Node* startNode = p.anchorNode();
1258 1258
1259 if (!startNode) 1259 if (!startNode)
1260 return VisiblePosition(); 1260 return VisiblePosition();
1261 1261
1262 if (isRenderedAsNonInlineTableImageOrHR(startNode)) 1262 if (isRenderedAsNonInlineTableImageOrHR(startNode))
1263 return VisiblePosition(positionBeforeNode(startNode)); 1263 return createVisiblePosition(positionBeforeNode(startNode));
1264 1264
1265 Element* startBlock = enclosingBlock(startNode); 1265 Element* startBlock = enclosingBlock(startNode);
1266 1266
1267 Node* node = startNode; 1267 Node* node = startNode;
1268 ContainerNode* highestRoot = highestEditableRoot(p); 1268 ContainerNode* highestRoot = highestEditableRoot(p);
1269 int offset = p.computeEditingOffset(); 1269 int offset = p.computeEditingOffset();
1270 PositionAnchorType type = p.anchorType(); 1270 PositionAnchorType type = p.anchorType();
1271 1271
1272 Node* n = startNode; 1272 Node* n = startNode;
1273 bool startNodeIsEditable = startNode->hasEditableStyle(); 1273 bool startNodeIsEditable = startNode->hasEditableStyle();
(...skipping 24 matching lines...) Expand all
1298 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); 1298 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode());
1299 type = PositionAnchorType::OffsetInAnchor; 1299 type = PositionAnchorType::OffsetInAnchor;
1300 if (style.preserveNewline()) { 1300 if (style.preserveNewline()) {
1301 LayoutText* text = toLayoutText(r); 1301 LayoutText* text = toLayoutText(r);
1302 int i = text->textLength(); 1302 int i = text->textLength();
1303 int o = offset; 1303 int o = offset;
1304 if (n == startNode && o < i) 1304 if (n == startNode && o < i)
1305 i = max(0, o); 1305 i = max(0, o);
1306 while (--i >= 0) { 1306 while (--i >= 0) {
1307 if ((*text)[i] == '\n') 1307 if ((*text)[i] == '\n')
1308 return VisiblePosition(Position(toText(n), i + 1)); 1308 return createVisiblePosition(Position(toText(n), i + 1)) ;
1309 } 1309 }
1310 } 1310 }
1311 node = n; 1311 node = n;
1312 offset = 0; 1312 offset = 0;
1313 n = NodeTraversal::previousPostOrder(*n, startBlock); 1313 n = NodeTraversal::previousPostOrder(*n, startBlock);
1314 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) { 1314 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) {
1315 node = n; 1315 node = n;
1316 type = PositionAnchorType::BeforeAnchor; 1316 type = PositionAnchorType::BeforeAnchor;
1317 n = n->previousSibling() ? n->previousSibling() : NodeTraversal::pre viousPostOrder(*n, startBlock); 1317 n = n->previousSibling() ? n->previousSibling() : NodeTraversal::pre viousPostOrder(*n, startBlock);
1318 } else { 1318 } else {
1319 n = NodeTraversal::previousPostOrder(*n, startBlock); 1319 n = NodeTraversal::previousPostOrder(*n, startBlock);
1320 } 1320 }
1321 } 1321 }
1322 1322
1323 if (type == PositionAnchorType::OffsetInAnchor) 1323 if (type == PositionAnchorType::OffsetInAnchor)
1324 return VisiblePosition(Position(node, offset)); 1324 return createVisiblePosition(Position(node, offset));
1325 1325
1326 return VisiblePosition(Position(node, type)); 1326 return createVisiblePosition(Position(node, type));
1327 } 1327 }
1328 1328
1329 VisiblePosition endOfParagraph(const VisiblePosition& c, EditingBoundaryCrossing Rule boundaryCrossingRule) 1329 VisiblePosition endOfParagraph(const VisiblePosition& c, EditingBoundaryCrossing Rule boundaryCrossingRule)
1330 { 1330 {
1331 if (c.isNull()) 1331 if (c.isNull())
1332 return VisiblePosition(); 1332 return VisiblePosition();
1333 1333
1334 Position p = c.deepEquivalent(); 1334 Position p = c.deepEquivalent();
1335 Node* startNode = p.anchorNode(); 1335 Node* startNode = p.anchorNode();
1336 1336
1337 if (isRenderedAsNonInlineTableImageOrHR(startNode)) 1337 if (isRenderedAsNonInlineTableImageOrHR(startNode))
1338 return VisiblePosition(positionAfterNode(startNode)); 1338 return createVisiblePosition(positionAfterNode(startNode));
1339 1339
1340 Element* startBlock = enclosingBlock(startNode); 1340 Element* startBlock = enclosingBlock(startNode);
1341 Element* stayInsideBlock = startBlock; 1341 Element* stayInsideBlock = startBlock;
1342 1342
1343 Node* node = startNode; 1343 Node* node = startNode;
1344 ContainerNode* highestRoot = highestEditableRoot(p); 1344 ContainerNode* highestRoot = highestEditableRoot(p);
1345 int offset = p.computeEditingOffset(); 1345 int offset = p.computeEditingOffset();
1346 PositionAnchorType type = p.anchorType(); 1346 PositionAnchorType type = p.anchorType();
1347 1347
1348 Node* n = startNode; 1348 Node* n = startNode;
(...skipping 25 matching lines...) Expand all
1374 // FIXME: We avoid returning a position where the layoutObject can't acc ept the caret. 1374 // FIXME: We avoid returning a position where the layoutObject can't acc ept the caret.
1375 if (r->isText() && toLayoutText(r)->resolvedTextLength()) { 1375 if (r->isText() && toLayoutText(r)->resolvedTextLength()) {
1376 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); 1376 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode());
1377 int length = toLayoutText(r)->textLength(); 1377 int length = toLayoutText(r)->textLength();
1378 type = PositionAnchorType::OffsetInAnchor; 1378 type = PositionAnchorType::OffsetInAnchor;
1379 if (style.preserveNewline()) { 1379 if (style.preserveNewline()) {
1380 LayoutText* text = toLayoutText(r); 1380 LayoutText* text = toLayoutText(r);
1381 int o = n == startNode ? offset : 0; 1381 int o = n == startNode ? offset : 0;
1382 for (int i = o; i < length; ++i) { 1382 for (int i = o; i < length; ++i) {
1383 if ((*text)[i] == '\n') 1383 if ((*text)[i] == '\n')
1384 return VisiblePosition(Position(toText(n), i)); 1384 return createVisiblePosition(Position(toText(n), i));
1385 } 1385 }
1386 } 1386 }
1387 node = n; 1387 node = n;
1388 offset = r->caretMaxOffset(); 1388 offset = r->caretMaxOffset();
1389 n = NodeTraversal::next(*n, stayInsideBlock); 1389 n = NodeTraversal::next(*n, stayInsideBlock);
1390 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) { 1390 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) {
1391 node = n; 1391 node = n;
1392 type = PositionAnchorType::AfterAnchor; 1392 type = PositionAnchorType::AfterAnchor;
1393 n = NodeTraversal::nextSkippingChildren(*n, stayInsideBlock); 1393 n = NodeTraversal::nextSkippingChildren(*n, stayInsideBlock);
1394 } else { 1394 } else {
1395 n = NodeTraversal::next(*n, stayInsideBlock); 1395 n = NodeTraversal::next(*n, stayInsideBlock);
1396 } 1396 }
1397 } 1397 }
1398 1398
1399 if (type == PositionAnchorType::OffsetInAnchor) 1399 if (type == PositionAnchorType::OffsetInAnchor)
1400 return VisiblePosition(Position(node, offset)); 1400 return createVisiblePosition(Position(node, offset));
1401 1401
1402 return VisiblePosition(Position(node, type)); 1402 return createVisiblePosition(Position(node, type));
1403 } 1403 }
1404 1404
1405 // FIXME: isStartOfParagraph(startOfNextParagraph(pos)) is not always true 1405 // FIXME: isStartOfParagraph(startOfNextParagraph(pos)) is not always true
1406 VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition) 1406 VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition)
1407 { 1407 {
1408 VisiblePosition paragraphEnd(endOfParagraph(visiblePosition, CanSkipOverEdit ingBoundary)); 1408 VisiblePosition paragraphEnd(endOfParagraph(visiblePosition, CanSkipOverEdit ingBoundary));
1409 VisiblePosition afterParagraphEnd(nextPositionOf(paragraphEnd, CannotCrossEd itingBoundary)); 1409 VisiblePosition afterParagraphEnd(nextPositionOf(paragraphEnd, CannotCrossEd itingBoundary));
1410 // The position after the last position in the last cell of a table 1410 // The position after the last position in the last cell of a table
1411 // is not the start of the next paragraph. 1411 // is not the start of the next paragraph.
1412 if (isFirstPositionAfterTable(afterParagraphEnd)) 1412 if (isFirstPositionAfterTable(afterParagraphEnd))
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 } while (inSameParagraph(p, pos)); 1452 } while (inSameParagraph(p, pos));
1453 return pos; 1453 return pos;
1454 } 1454 }
1455 1455
1456 // --------- 1456 // ---------
1457 1457
1458 VisiblePosition startOfBlock(const VisiblePosition& visiblePosition, EditingBoun daryCrossingRule rule) 1458 VisiblePosition startOfBlock(const VisiblePosition& visiblePosition, EditingBoun daryCrossingRule rule)
1459 { 1459 {
1460 Position position = visiblePosition.deepEquivalent(); 1460 Position position = visiblePosition.deepEquivalent();
1461 Element* startBlock = position.computeContainerNode() ? enclosingBlock(posit ion.computeContainerNode(), rule) : 0; 1461 Element* startBlock = position.computeContainerNode() ? enclosingBlock(posit ion.computeContainerNode(), rule) : 0;
1462 return startBlock ? VisiblePosition(firstPositionInNode(startBlock)) : Visib lePosition(); 1462 return startBlock ? createVisiblePosition(firstPositionInNode(startBlock)) : VisiblePosition();
1463 } 1463 }
1464 1464
1465 VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBounda ryCrossingRule rule) 1465 VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBounda ryCrossingRule rule)
1466 { 1466 {
1467 Position position = visiblePosition.deepEquivalent(); 1467 Position position = visiblePosition.deepEquivalent();
1468 Element* endBlock = position.computeContainerNode() ? enclosingBlock(positio n.computeContainerNode(), rule) : 0; 1468 Element* endBlock = position.computeContainerNode() ? enclosingBlock(positio n.computeContainerNode(), rule) : 0;
1469 return endBlock ? VisiblePosition(lastPositionInNode(endBlock)) : VisiblePos ition(); 1469 return endBlock ? createVisiblePosition(lastPositionInNode(endBlock)) : Visi blePosition();
1470 } 1470 }
1471 1471
1472 bool inSameBlock(const VisiblePosition& a, const VisiblePosition& b) 1472 bool inSameBlock(const VisiblePosition& a, const VisiblePosition& b)
1473 { 1473 {
1474 return !a.isNull() && enclosingBlock(a.deepEquivalent().computeContainerNode ()) == enclosingBlock(b.deepEquivalent().computeContainerNode()); 1474 return !a.isNull() && enclosingBlock(a.deepEquivalent().computeContainerNode ()) == enclosingBlock(b.deepEquivalent().computeContainerNode());
1475 } 1475 }
1476 1476
1477 bool isStartOfBlock(const VisiblePosition& pos) 1477 bool isStartOfBlock(const VisiblePosition& pos)
1478 { 1478 {
1479 return pos.isNotNull() && pos.deepEquivalent() == startOfBlock(pos, CanCross EditingBoundary).deepEquivalent(); 1479 return pos.isNotNull() && pos.deepEquivalent() == startOfBlock(pos, CanCross EditingBoundary).deepEquivalent();
1480 } 1480 }
1481 1481
1482 bool isEndOfBlock(const VisiblePosition& pos) 1482 bool isEndOfBlock(const VisiblePosition& pos)
1483 { 1483 {
1484 return pos.isNotNull() && pos.deepEquivalent() == endOfBlock(pos, CanCrossEd itingBoundary).deepEquivalent(); 1484 return pos.isNotNull() && pos.deepEquivalent() == endOfBlock(pos, CanCrossEd itingBoundary).deepEquivalent();
1485 } 1485 }
1486 1486
1487 // --------- 1487 // ---------
1488 1488
1489 VisiblePosition startOfDocument(const Node* node) 1489 VisiblePosition startOfDocument(const Node* node)
1490 { 1490 {
1491 if (!node || !node->document().documentElement()) 1491 if (!node || !node->document().documentElement())
1492 return VisiblePosition(); 1492 return VisiblePosition();
1493 1493
1494 return VisiblePosition(firstPositionInNode(node->document().documentElement( ))); 1494 return createVisiblePosition(firstPositionInNode(node->document().documentEl ement()));
1495 } 1495 }
1496 1496
1497 VisiblePosition startOfDocument(const VisiblePosition& c) 1497 VisiblePosition startOfDocument(const VisiblePosition& c)
1498 { 1498 {
1499 return startOfDocument(c.deepEquivalent().anchorNode()); 1499 return startOfDocument(c.deepEquivalent().anchorNode());
1500 } 1500 }
1501 1501
1502 VisiblePosition endOfDocument(const Node* node) 1502 VisiblePosition endOfDocument(const Node* node)
1503 { 1503 {
1504 if (!node || !node->document().documentElement()) 1504 if (!node || !node->document().documentElement())
1505 return VisiblePosition(); 1505 return VisiblePosition();
1506 1506
1507 Element* doc = node->document().documentElement(); 1507 Element* doc = node->document().documentElement();
1508 return VisiblePosition(lastPositionInNode(doc)); 1508 return createVisiblePosition(lastPositionInNode(doc));
1509 } 1509 }
1510 1510
1511 VisiblePosition endOfDocument(const VisiblePosition& c) 1511 VisiblePosition endOfDocument(const VisiblePosition& c)
1512 { 1512 {
1513 return endOfDocument(c.deepEquivalent().anchorNode()); 1513 return endOfDocument(c.deepEquivalent().anchorNode());
1514 } 1514 }
1515 1515
1516 bool isStartOfDocument(const VisiblePosition& p) 1516 bool isStartOfDocument(const VisiblePosition& p)
1517 { 1517 {
1518 return p.isNotNull() && previousPositionOf(p, CanCrossEditingBoundary).isNul l(); 1518 return p.isNotNull() && previousPositionOf(p, CanCrossEditingBoundary).isNul l();
1519 } 1519 }
1520 1520
1521 bool isEndOfDocument(const VisiblePosition& p) 1521 bool isEndOfDocument(const VisiblePosition& p)
1522 { 1522 {
1523 return p.isNotNull() && nextPositionOf(p, CanCrossEditingBoundary).isNull(); 1523 return p.isNotNull() && nextPositionOf(p, CanCrossEditingBoundary).isNull();
1524 } 1524 }
1525 1525
1526 // --------- 1526 // ---------
1527 1527
1528 VisiblePosition startOfEditableContent(const VisiblePosition& visiblePosition) 1528 VisiblePosition startOfEditableContent(const VisiblePosition& visiblePosition)
1529 { 1529 {
1530 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent()); 1530 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent());
1531 if (!highestRoot) 1531 if (!highestRoot)
1532 return VisiblePosition(); 1532 return VisiblePosition();
1533 1533
1534 return VisiblePosition(firstPositionInNode(highestRoot)); 1534 return createVisiblePosition(firstPositionInNode(highestRoot));
1535 } 1535 }
1536 1536
1537 VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition) 1537 VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition)
1538 { 1538 {
1539 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent()); 1539 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival ent());
1540 if (!highestRoot) 1540 if (!highestRoot)
1541 return VisiblePosition(); 1541 return VisiblePosition();
1542 1542
1543 return VisiblePosition(lastPositionInNode(highestRoot)); 1543 return createVisiblePosition(lastPositionInNode(highestRoot));
1544 } 1544 }
1545 1545
1546 bool isEndOfEditableOrNonEditableContent(const VisiblePosition& p) 1546 bool isEndOfEditableOrNonEditableContent(const VisiblePosition& p)
1547 { 1547 {
1548 return p.isNotNull() && nextPositionOf(p).isNull(); 1548 return p.isNotNull() && nextPositionOf(p).isNull();
1549 } 1549 }
1550 1550
1551 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc tion) 1551 VisiblePosition leftBoundaryOfLine(const VisiblePosition& c, TextDirection direc tion)
1552 { 1552 {
1553 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); 1553 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 int caretOffset = position.computeEditingOffset(); 1623 int caretOffset = position.computeEditingOffset();
1624 Node* const anchorNode = position.anchorNode(); 1624 Node* const anchorNode = position.anchorNode();
1625 LayoutObject* layoutObject = anchorNode->isShadowRoot() ? toShadowRoot(ancho rNode)->host()->layoutObject() : anchorNode->layoutObject(); 1625 LayoutObject* layoutObject = anchorNode->isShadowRoot() ? toShadowRoot(ancho rNode)->host()->layoutObject() : anchorNode->layoutObject();
1626 1626
1627 if (!layoutObject->isText()) { 1627 if (!layoutObject->isText()) {
1628 inlineBox = 0; 1628 inlineBox = 0;
1629 if (canHaveChildrenForEditing(anchorNode) && layoutObject->isLayoutBlock Flow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { 1629 if (canHaveChildrenForEditing(anchorNode) && layoutObject->isLayoutBlock Flow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) {
1630 // Try a visually equivalent position with possibly opposite 1630 // Try a visually equivalent position with possibly opposite
1631 // editability. This helps in case |this| is in an editable block 1631 // editability. This helps in case |this| is in an editable block
1632 // but surrounded by non-editable positions. It acts to negate the 1632 // but surrounded by non-editable positions. It acts to negate the
1633 // logic at the beginning of LayoutObject::createVisiblePosition(). 1633 // logic at the beginning of LayoutObject::VisiblePosition().
tkent 2015/09/01 23:21:17 LayoutObject has neither createVisiblePosition nor
yosin_UTC9 2015/09/02 03:46:20 Good catch. It should be |LayoutObject::createPosi
1634 PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBo undaries(position); 1634 PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBo undaries(position);
1635 if (equivalent == position) { 1635 if (equivalent == position) {
1636 equivalent = upstreamIgnoringEditingBoundaries(position); 1636 equivalent = upstreamIgnoringEditingBoundaries(position);
1637 if (equivalent == position || downstreamIgnoringEditingBoundarie s(equivalent) == position) 1637 if (equivalent == position || downstreamIgnoringEditingBoundarie s(equivalent) == position)
1638 return InlineBoxPosition(inlineBox, caretOffset); 1638 return InlineBoxPosition(inlineBox, caretOffset);
1639 } 1639 }
1640 1640
1641 return computeInlineBoxPosition(equivalent, TextAffinity::Upstream, primaryDirection); 1641 return computeInlineBoxPosition(equivalent, TextAffinity::Upstream, primaryDirection);
1642 } 1642 }
1643 if (layoutObject->isBox()) { 1643 if (layoutObject->isBox()) {
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 ContainerNode* highestRoot = highestEditableRoot(anchor); 2445 ContainerNode* highestRoot = highestEditableRoot(anchor);
2446 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); 2446 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent());
2447 2447
2448 // Return |pos| itself if the two are from the very same editable region, or 2448 // Return |pos| itself if the two are from the very same editable region, or
2449 // both are non-editable. 2449 // both are non-editable.
2450 if (highestRootOfPos == highestRoot) 2450 if (highestRootOfPos == highestRoot)
2451 return pos; 2451 return pos;
2452 2452
2453 // If this is not editable but |pos| has an editable root, skip to the end 2453 // If this is not editable but |pos| has an editable root, skip to the end
2454 if (!highestRoot && highestRootOfPos) 2454 if (!highestRoot && highestRootOfPos)
2455 return VisiblePosition(Position(highestRootOfPos, PositionAnchorType::Af terAnchor).parentAnchoredEquivalent()); 2455 return createVisiblePosition(Position(highestRootOfPos, PositionAnchorTy pe::AfterAnchor).parentAnchoredEquivalent());
2456 2456
2457 // That must mean that |pos| is not editable. Return the next position after 2457 // That must mean that |pos| is not editable. Return the next position after
2458 // |pos| that is in the same editable region as this position 2458 // |pos| that is in the same editable region as this position
2459 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot); 2459 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
2460 } 2460 }
2461 2461
2462 UChar32 characterAfter(const VisiblePosition& visiblePosition) 2462 UChar32 characterAfter(const VisiblePosition& visiblePosition)
2463 { 2463 {
2464 // We canonicalize to the first of two equivalent candidates, but the second 2464 // We canonicalize to the first of two equivalent candidates, but the second
2465 // of the two candidates is the one that will be inside the text node 2465 // of the two candidates is the one that will be inside the text node
(...skipping 13 matching lines...) Expand all
2479 return textNode->data().characterStartingAt(offset); 2479 return textNode->data().characterStartingAt(offset);
2480 } 2480 }
2481 2481
2482 UChar32 characterBefore(const VisiblePosition& visiblePosition) 2482 UChar32 characterBefore(const VisiblePosition& visiblePosition)
2483 { 2483 {
2484 return characterAfter(previousPositionOf(visiblePosition)); 2484 return characterAfter(previousPositionOf(visiblePosition));
2485 } 2485 }
2486 2486
2487 VisiblePosition nextPositionOf(const VisiblePosition& visiblePosition, EditingBo undaryCrossingRule rule) 2487 VisiblePosition nextPositionOf(const VisiblePosition& visiblePosition, EditingBo undaryCrossingRule rule)
2488 { 2488 {
2489 VisiblePosition next(nextVisuallyDistinctCandidate(visiblePosition.deepEquiv alent()), visiblePosition.affinity()); 2489 VisiblePosition next = createVisiblePosition(nextVisuallyDistinctCandidate(v isiblePosition.deepEquivalent()), visiblePosition.affinity());
2490 2490
2491 switch (rule) { 2491 switch (rule) {
2492 case CanCrossEditingBoundary: 2492 case CanCrossEditingBoundary:
2493 return next; 2493 return next;
2494 case CannotCrossEditingBoundary: 2494 case CannotCrossEditingBoundary:
2495 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalen t()); 2495 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalen t());
2496 case CanSkipOverEditingBoundary: 2496 case CanSkipOverEditingBoundary:
2497 return skipToEndOfEditingBoundary(next, visiblePosition.deepEquivalent() ); 2497 return skipToEndOfEditingBoundary(next, visiblePosition.deepEquivalent() );
2498 } 2498 }
2499 ASSERT_NOT_REACHED(); 2499 ASSERT_NOT_REACHED();
2500 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalent()) ; 2500 return honorEditingBoundaryAtOrAfter(next, visiblePosition.deepEquivalent()) ;
2501 } 2501 }
2502 2502
2503 static VisiblePosition skipToStartOfEditingBoundary(const VisiblePosition& pos, const Position& anchor) 2503 static VisiblePosition skipToStartOfEditingBoundary(const VisiblePosition& pos, const Position& anchor)
2504 { 2504 {
2505 if (pos.isNull()) 2505 if (pos.isNull())
2506 return pos; 2506 return pos;
2507 2507
2508 ContainerNode* highestRoot = highestEditableRoot(anchor); 2508 ContainerNode* highestRoot = highestEditableRoot(anchor);
2509 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); 2509 ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent());
2510 2510
2511 // Return |pos| itself if the two are from the very same editable region, or 2511 // Return |pos| itself if the two are from the very same editable region, or
2512 // both are non-editable. 2512 // both are non-editable.
2513 if (highestRootOfPos == highestRoot) 2513 if (highestRootOfPos == highestRoot)
2514 return pos; 2514 return pos;
2515 2515
2516 // If this is not editable but |pos| has an editable root, skip to the start 2516 // If this is not editable but |pos| has an editable root, skip to the start
2517 if (!highestRoot && highestRootOfPos) 2517 if (!highestRoot && highestRootOfPos)
2518 return VisiblePosition(previousVisuallyDistinctCandidate(Position(highes tRootOfPos, PositionAnchorType::BeforeAnchor).parentAnchoredEquivalent())); 2518 return createVisiblePosition(previousVisuallyDistinctCandidate(Position( highestRootOfPos, PositionAnchorType::BeforeAnchor).parentAnchoredEquivalent())) ;
2519 2519
2520 // That must mean that |pos| is not editable. Return the last position 2520 // That must mean that |pos| is not editable. Return the last position
2521 // before |pos| that is in the same editable region as this position 2521 // before |pos| that is in the same editable region as this position
2522 return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot); 2522 return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
2523 } 2523 }
2524 2524
2525 VisiblePosition previousPositionOf(const VisiblePosition& visiblePosition, Editi ngBoundaryCrossingRule rule) 2525 VisiblePosition previousPositionOf(const VisiblePosition& visiblePosition, Editi ngBoundaryCrossingRule rule)
2526 { 2526 {
2527 Position pos = previousVisuallyDistinctCandidate(visiblePosition.deepEquival ent()); 2527 Position pos = previousVisuallyDistinctCandidate(visiblePosition.deepEquival ent());
2528 2528
2529 // return null visible position if there is no previous visible position 2529 // return null visible position if there is no previous visible position
2530 if (pos.atStartOfTree()) 2530 if (pos.atStartOfTree())
2531 return VisiblePosition(); 2531 return VisiblePosition();
2532 2532
2533 VisiblePosition prev = VisiblePosition(pos); 2533 VisiblePosition prev = createVisiblePosition(pos);
2534 ASSERT(prev.deepEquivalent() != visiblePosition.deepEquivalent()); 2534 ASSERT(prev.deepEquivalent() != visiblePosition.deepEquivalent());
2535 2535
2536 #if ENABLE(ASSERT) 2536 #if ENABLE(ASSERT)
2537 // we should always be able to make the affinity |TextAffinity::Downstream|, 2537 // we should always be able to make the affinity |TextAffinity::Downstream|,
2538 // because going previous from an |TextAffinity::Upstream| position can 2538 // because going previous from an |TextAffinity::Upstream| position can
2539 // never yield another |TextAffinity::Upstream position| (unless line wrap 2539 // never yield another |TextAffinity::Upstream position| (unless line wrap
2540 // length is 0!). 2540 // length is 0!).
2541 if (prev.isNotNull() && visiblePosition.affinity() == TextAffinity::Upstream ) { 2541 if (prev.isNotNull() && visiblePosition.affinity() == TextAffinity::Upstream ) {
2542 ASSERT(inSameLine(PositionWithAffinity(prev.deepEquivalent()), PositionW ithAffinity(prev.deepEquivalent(), TextAffinity::Upstream))); 2542 ASSERT(inSameLine(PositionWithAffinity(prev.deepEquivalent()), PositionW ithAffinity(prev.deepEquivalent(), TextAffinity::Upstream)));
2543 } 2543 }
2544 #endif 2544 #endif
2545 2545
2546 switch (rule) { 2546 switch (rule) {
2547 case CanCrossEditingBoundary: 2547 case CanCrossEditingBoundary:
2548 return prev; 2548 return prev;
2549 case CannotCrossEditingBoundary: 2549 case CannotCrossEditingBoundary:
2550 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale nt()); 2550 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivale nt());
2551 case CanSkipOverEditingBoundary: 2551 case CanSkipOverEditingBoundary:
2552 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent ()); 2552 return skipToStartOfEditingBoundary(prev, visiblePosition.deepEquivalent ());
2553 } 2553 }
2554 2554
2555 ASSERT_NOT_REACHED(); 2555 ASSERT_NOT_REACHED();
2556 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent() ); 2556 return honorEditingBoundaryAtOrBefore(prev, visiblePosition.deepEquivalent() );
2557 } 2557 }
2558 2558
2559 } // namespace blink 2559 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/VisibleSelection.cpp ('k') | Source/core/editing/commands/ApplyBlockElementCommand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698