OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
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 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 bool isNodeRendered(const Node& node) | 1125 bool isNodeRendered(const Node& node) |
1126 { | 1126 { |
1127 LayoutObject* layoutObject = node.layoutObject(); | 1127 LayoutObject* layoutObject = node.layoutObject(); |
1128 if (!layoutObject) | 1128 if (!layoutObject) |
1129 return false; | 1129 return false; |
1130 | 1130 |
1131 return layoutObject->style()->visibility() == VISIBLE; | 1131 return layoutObject->style()->visibility() == VISIBLE; |
1132 } | 1132 } |
1133 | 1133 |
1134 // return first preceding DOM position rendered at a different location, or "thi
s" | 1134 // return first preceding DOM position rendered at a different location, or "thi
s" |
1135 static Position previousCharacterPosition(const Position& position, EAffinity af
finity) | 1135 static Position previousCharacterPosition(const Position& position, TextAffinity
affinity) |
1136 { | 1136 { |
1137 if (position.isNull()) | 1137 if (position.isNull()) |
1138 return Position(); | 1138 return Position(); |
1139 | 1139 |
1140 Element* fromRootEditableElement = position.anchorNode()->rootEditableElemen
t(); | 1140 Element* fromRootEditableElement = position.anchorNode()->rootEditableElemen
t(); |
1141 | 1141 |
1142 bool atStartOfLine = isStartOfLine(VisiblePosition(position, affinity)); | 1142 bool atStartOfLine = isStartOfLine(VisiblePosition(position, affinity)); |
1143 bool rendered = position.isCandidate(); | 1143 bool rendered = position.isCandidate(); |
1144 | 1144 |
1145 Position currentPos = position; | 1145 Position currentPos = position; |
1146 while (!currentPos.atStartOfTree()) { | 1146 while (!currentPos.atStartOfTree()) { |
1147 currentPos = currentPos.previous(); | 1147 currentPos = currentPos.previous(); |
1148 | 1148 |
1149 if (currentPos.anchorNode()->rootEditableElement() != fromRootEditableEl
ement) | 1149 if (currentPos.anchorNode()->rootEditableElement() != fromRootEditableEl
ement) |
1150 return position; | 1150 return position; |
1151 | 1151 |
1152 if (atStartOfLine || !rendered) { | 1152 if (atStartOfLine || !rendered) { |
1153 if (currentPos.isCandidate()) | 1153 if (currentPos.isCandidate()) |
1154 return currentPos; | 1154 return currentPos; |
1155 } else if (rendersInDifferentPosition(position, currentPos)) { | 1155 } else if (rendersInDifferentPosition(position, currentPos)) { |
1156 return currentPos; | 1156 return currentPos; |
1157 } | 1157 } |
1158 } | 1158 } |
1159 | 1159 |
1160 return position; | 1160 return position; |
1161 } | 1161 } |
1162 | 1162 |
1163 // This assumes that it starts in editable content. | 1163 // This assumes that it starts in editable content. |
1164 Position leadingWhitespacePosition(const Position& position, EAffinity affinity,
WhitespacePositionOption option) | 1164 Position leadingWhitespacePosition(const Position& position, TextAffinity affini
ty, WhitespacePositionOption option) |
1165 { | 1165 { |
1166 ASSERT(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)); | 1166 ASSERT(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)); |
1167 if (position.isNull()) | 1167 if (position.isNull()) |
1168 return Position(); | 1168 return Position(); |
1169 | 1169 |
1170 if (isHTMLBRElement(*position.upstream().anchorNode())) | 1170 if (isHTMLBRElement(*position.upstream().anchorNode())) |
1171 return Position(); | 1171 return Position(); |
1172 | 1172 |
1173 Position prev = previousCharacterPosition(position, affinity); | 1173 Position prev = previousCharacterPosition(position, affinity); |
1174 if (prev != position && inSameContainingBlockFlowElement(prev.anchorNode(),
position.anchorNode()) && prev.anchorNode()->isTextNode()) { | 1174 if (prev != position && inSameContainingBlockFlowElement(prev.anchorNode(),
position.anchorNode()) && prev.anchorNode()->isTextNode()) { |
1175 String string = toText(prev.anchorNode())->data(); | 1175 String string = toText(prev.anchorNode())->data(); |
1176 UChar previousCharacter = string[prev.computeOffsetInContainerNode()]; | 1176 UChar previousCharacter = string[prev.computeOffsetInContainerNode()]; |
1177 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNe
wline(previousCharacter) || previousCharacter == noBreakSpaceCharacter) : isColl
apsibleWhitespace(previousCharacter); | 1177 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNe
wline(previousCharacter) || previousCharacter == noBreakSpaceCharacter) : isColl
apsibleWhitespace(previousCharacter); |
1178 if (isSpace && isEditablePosition(prev)) | 1178 if (isSpace && isEditablePosition(prev)) |
1179 return prev; | 1179 return prev; |
1180 } | 1180 } |
1181 | 1181 |
1182 return Position(); | 1182 return Position(); |
1183 } | 1183 } |
1184 | 1184 |
1185 // This assumes that it starts in editable content. | 1185 // This assumes that it starts in editable content. |
1186 Position trailingWhitespacePosition(const Position& position, EAffinity, Whitesp
acePositionOption option) | 1186 Position trailingWhitespacePosition(const Position& position, TextAffinity, Whit
espacePositionOption option) |
1187 { | 1187 { |
1188 ASSERT(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)); | 1188 ASSERT(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)); |
1189 if (position.isNull()) | 1189 if (position.isNull()) |
1190 return Position(); | 1190 return Position(); |
1191 | 1191 |
1192 VisiblePosition visiblePosition(position); | 1192 VisiblePosition visiblePosition(position); |
1193 UChar characterAfterVisiblePosition = visiblePosition.characterAfter(); | 1193 UChar characterAfterVisiblePosition = visiblePosition.characterAfter(); |
1194 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNewlin
e(characterAfterVisiblePosition) || characterAfterVisiblePosition == noBreakSpac
eCharacter) : isCollapsibleWhitespace(characterAfterVisiblePosition); | 1194 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNewlin
e(characterAfterVisiblePosition) || characterAfterVisiblePosition == noBreakSpac
eCharacter) : isCollapsibleWhitespace(characterAfterVisiblePosition); |
1195 // The space must not be in another paragraph and it must be editable. | 1195 // The space must not be in another paragraph and it must be editable. |
1196 if (isSpace && !isEndOfParagraph(visiblePosition) && visiblePosition.next(Ca
nnotCrossEditingBoundary).isNotNull()) | 1196 if (isSpace && !isEndOfParagraph(visiblePosition) && visiblePosition.next(Ca
nnotCrossEditingBoundary).isNotNull()) |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 // if the selection starts just before a paragraph break, skip over it | 1434 // if the selection starts just before a paragraph break, skip over it |
1435 if (isEndOfParagraph(visiblePosition)) | 1435 if (isEndOfParagraph(visiblePosition)) |
1436 return visiblePosition.next().deepEquivalent().downstream(); | 1436 return visiblePosition.next().deepEquivalent().downstream(); |
1437 | 1437 |
1438 // otherwise, make sure to be at the start of the first selected node, | 1438 // otherwise, make sure to be at the start of the first selected node, |
1439 // instead of possibly at the end of the last node before the selection | 1439 // instead of possibly at the end of the last node before the selection |
1440 return visiblePosition.deepEquivalent().downstream(); | 1440 return visiblePosition.deepEquivalent().downstream(); |
1441 } | 1441 } |
1442 | 1442 |
1443 } // namespace blink | 1443 } // namespace blink |
OLD | NEW |