OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 it.advance(); | 512 it.advance(); |
513 } | 513 } |
514 if (needMoreContext) { | 514 if (needMoreContext) { |
515 // The last search returned the beginning of the buffer and asked for mo
re context, | 515 // The last search returned the beginning of the buffer and asked for mo
re context, |
516 // but there is no earlier text. Force a search with what's available. | 516 // but there is no earlier text. Force a search with what's available. |
517 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, DontHaveMoreContext, needMoreContext); | 517 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, DontHaveMoreContext, needMoreContext); |
518 ASSERT(!needMoreContext); | 518 ASSERT(!needMoreContext); |
519 } | 519 } |
520 | 520 |
521 if (!next) | 521 if (!next) |
522 return VisiblePosition(it.atEnd() ? it.startPosition() : pos, DOWNSTREAM
); | 522 return VisiblePosition(it.atEnd() ? it.startPosition() : pos); |
523 | 523 |
524 Node* node = it.startContainer(); | 524 Node* node = it.startContainer(); |
525 if (node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffset
()) { | 525 if (node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffset
()) { |
526 // The next variable contains a usable index into a text node | 526 // The next variable contains a usable index into a text node |
527 return VisiblePosition(Position(node, next), DOWNSTREAM); | 527 return VisiblePosition(Position(node, next)); |
528 } | 528 } |
529 | 529 |
530 // Use the character iterator to translate the next value into a DOM positio
n. | 530 // Use the character iterator to translate the next value into a DOM positio
n. |
531 BackwardsCharacterIterator charIt(start, end); | 531 BackwardsCharacterIterator charIt(start, end); |
532 charIt.advance(string.size() - suffixLength - next); | 532 charIt.advance(string.size() - suffixLength - next); |
533 // FIXME: charIt can get out of shadow host. | 533 // FIXME: charIt can get out of shadow host. |
534 return VisiblePosition(charIt.endPosition(), DOWNSTREAM); | 534 return VisiblePosition(charIt.endPosition()); |
535 } | 535 } |
536 | 536 |
537 static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
tion searchFunction) | 537 static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
tion searchFunction) |
538 { | 538 { |
539 Position pos = c.deepEquivalent(); | 539 Position pos = c.deepEquivalent(); |
540 Node* boundary = pos.parentEditingBoundary(); | 540 Node* boundary = pos.parentEditingBoundary(); |
541 if (!boundary) | 541 if (!boundary) |
542 return VisiblePosition(); | 542 return VisiblePosition(); |
543 | 543 |
544 Document& d = boundary->document(); | 544 Document& d = boundary->document(); |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 return VisiblePosition(positionInParentBeforeNode(*node)); | 1001 return VisiblePosition(positionInParentBeforeNode(*node)); |
1002 return VisiblePosition(layoutObject.positionForPoint(pointInLine)); | 1002 return VisiblePosition(layoutObject.positionForPoint(pointInLine)); |
1003 } | 1003 } |
1004 | 1004 |
1005 // Could not find a previous line. This means we must already be on the firs
t line. | 1005 // Could not find a previous line. This means we must already be on the firs
t line. |
1006 // Move to the start of the content in this block, which effectively moves u
s | 1006 // Move to the start of the content in this block, which effectively moves u
s |
1007 // to the start of the line we're on. | 1007 // to the start of the line we're on. |
1008 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); | 1008 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); |
1009 if (!rootElement) | 1009 if (!rootElement) |
1010 return VisiblePosition(); | 1010 return VisiblePosition(); |
1011 return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM); | 1011 return VisiblePosition(firstPositionInNode(rootElement)); |
1012 } | 1012 } |
1013 | 1013 |
1014 VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, LayoutU
nit lineDirectionPoint, EditableType editableType) | 1014 VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, LayoutU
nit lineDirectionPoint, EditableType editableType) |
1015 { | 1015 { |
1016 Position p = visiblePosition.deepEquivalent(); | 1016 Position p = visiblePosition.deepEquivalent(); |
1017 Node* node = p.anchorNode(); | 1017 Node* node = p.anchorNode(); |
1018 | 1018 |
1019 if (!node) | 1019 if (!node) |
1020 return VisiblePosition(); | 1020 return VisiblePosition(); |
1021 | 1021 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 return VisiblePosition(positionInParentBeforeNode(*node)); | 1057 return VisiblePosition(positionInParentBeforeNode(*node)); |
1058 return VisiblePosition(layoutObject.positionForPoint(pointInLine)); | 1058 return VisiblePosition(layoutObject.positionForPoint(pointInLine)); |
1059 } | 1059 } |
1060 | 1060 |
1061 // Could not find a next line. This means we must already be on the last lin
e. | 1061 // Could not find a next line. This means we must already be on the last lin
e. |
1062 // Move to the end of the content in this block, which effectively moves us | 1062 // Move to the end of the content in this block, which effectively moves us |
1063 // to the end of the line we're on. | 1063 // to the end of the line we're on. |
1064 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); | 1064 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); |
1065 if (!rootElement) | 1065 if (!rootElement) |
1066 return VisiblePosition(); | 1066 return VisiblePosition(); |
1067 return VisiblePosition(lastPositionInNode(rootElement), DOWNSTREAM); | 1067 return VisiblePosition(lastPositionInNode(rootElement)); |
1068 } | 1068 } |
1069 | 1069 |
1070 // --------- | 1070 // --------- |
1071 | 1071 |
1072 static unsigned startSentenceBoundary(const UChar* characters, unsigned length,
unsigned, BoundarySearchContextAvailability, bool&) | 1072 static unsigned startSentenceBoundary(const UChar* characters, unsigned length,
unsigned, BoundarySearchContextAvailability, bool&) |
1073 { | 1073 { |
1074 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); | 1074 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); |
1075 // FIXME: The following function can return -1; we don't handle that. | 1075 // FIXME: The following function can return -1; we don't handle that. |
1076 return iterator->preceding(length); | 1076 return iterator->preceding(length); |
1077 } | 1077 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); | 1168 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); |
1169 type = PositionAnchorType::OffsetInAnchor; | 1169 type = PositionAnchorType::OffsetInAnchor; |
1170 if (style.preserveNewline()) { | 1170 if (style.preserveNewline()) { |
1171 LayoutText* text = toLayoutText(r); | 1171 LayoutText* text = toLayoutText(r); |
1172 int i = text->textLength(); | 1172 int i = text->textLength(); |
1173 int o = offset; | 1173 int o = offset; |
1174 if (n == startNode && o < i) | 1174 if (n == startNode && o < i) |
1175 i = max(0, o); | 1175 i = max(0, o); |
1176 while (--i >= 0) { | 1176 while (--i >= 0) { |
1177 if ((*text)[i] == '\n') | 1177 if ((*text)[i] == '\n') |
1178 return VisiblePosition(Position(toText(n), i + 1), DOWNS
TREAM); | 1178 return VisiblePosition(Position(toText(n), i + 1)); |
1179 } | 1179 } |
1180 } | 1180 } |
1181 node = n; | 1181 node = n; |
1182 offset = 0; | 1182 offset = 0; |
1183 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1183 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1184 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) { | 1184 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) { |
1185 node = n; | 1185 node = n; |
1186 type = PositionAnchorType::BeforeAnchor; | 1186 type = PositionAnchorType::BeforeAnchor; |
1187 n = n->previousSibling() ? n->previousSibling() : NodeTraversal::pre
viousPostOrder(*n, startBlock); | 1187 n = n->previousSibling() ? n->previousSibling() : NodeTraversal::pre
viousPostOrder(*n, startBlock); |
1188 } else { | 1188 } else { |
1189 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1189 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1190 } | 1190 } |
1191 } | 1191 } |
1192 | 1192 |
1193 if (type == PositionAnchorType::OffsetInAnchor) | 1193 if (type == PositionAnchorType::OffsetInAnchor) |
1194 return VisiblePosition(Position(node, offset), DOWNSTREAM); | 1194 return VisiblePosition(Position(node, offset)); |
1195 | 1195 |
1196 return VisiblePosition(Position(node, type), DOWNSTREAM); | 1196 return VisiblePosition(Position(node, type)); |
1197 } | 1197 } |
1198 | 1198 |
1199 VisiblePosition endOfParagraph(const VisiblePosition &c, EditingBoundaryCrossing
Rule boundaryCrossingRule) | 1199 VisiblePosition endOfParagraph(const VisiblePosition &c, EditingBoundaryCrossing
Rule boundaryCrossingRule) |
1200 { | 1200 { |
1201 if (c.isNull()) | 1201 if (c.isNull()) |
1202 return VisiblePosition(); | 1202 return VisiblePosition(); |
1203 | 1203 |
1204 Position p = c.deepEquivalent(); | 1204 Position p = c.deepEquivalent(); |
1205 Node* startNode = p.anchorNode(); | 1205 Node* startNode = p.anchorNode(); |
1206 | 1206 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 // FIXME: We avoid returning a position where the layoutObject can't acc
ept the caret. | 1244 // FIXME: We avoid returning a position where the layoutObject can't acc
ept the caret. |
1245 if (r->isText() && toLayoutText(r)->resolvedTextLength()) { | 1245 if (r->isText() && toLayoutText(r)->resolvedTextLength()) { |
1246 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); | 1246 ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode()); |
1247 int length = toLayoutText(r)->textLength(); | 1247 int length = toLayoutText(r)->textLength(); |
1248 type = PositionAnchorType::OffsetInAnchor; | 1248 type = PositionAnchorType::OffsetInAnchor; |
1249 if (style.preserveNewline()) { | 1249 if (style.preserveNewline()) { |
1250 LayoutText* text = toLayoutText(r); | 1250 LayoutText* text = toLayoutText(r); |
1251 int o = n == startNode ? offset : 0; | 1251 int o = n == startNode ? offset : 0; |
1252 for (int i = o; i < length; ++i) { | 1252 for (int i = o; i < length; ++i) { |
1253 if ((*text)[i] == '\n') | 1253 if ((*text)[i] == '\n') |
1254 return VisiblePosition(Position(toText(n), i), DOWNSTREA
M); | 1254 return VisiblePosition(Position(toText(n), i)); |
1255 } | 1255 } |
1256 } | 1256 } |
1257 node = n; | 1257 node = n; |
1258 offset = r->caretMaxOffset(); | 1258 offset = r->caretMaxOffset(); |
1259 n = NodeTraversal::next(*n, stayInsideBlock); | 1259 n = NodeTraversal::next(*n, stayInsideBlock); |
1260 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) { | 1260 } else if (editingIgnoresContent(n) || isRenderedTableElement(n)) { |
1261 node = n; | 1261 node = n; |
1262 type = PositionAnchorType::AfterAnchor; | 1262 type = PositionAnchorType::AfterAnchor; |
1263 n = NodeTraversal::nextSkippingChildren(*n, stayInsideBlock); | 1263 n = NodeTraversal::nextSkippingChildren(*n, stayInsideBlock); |
1264 } else { | 1264 } else { |
1265 n = NodeTraversal::next(*n, stayInsideBlock); | 1265 n = NodeTraversal::next(*n, stayInsideBlock); |
1266 } | 1266 } |
1267 } | 1267 } |
1268 | 1268 |
1269 if (type == PositionAnchorType::OffsetInAnchor) | 1269 if (type == PositionAnchorType::OffsetInAnchor) |
1270 return VisiblePosition(Position(node, offset), DOWNSTREAM); | 1270 return VisiblePosition(Position(node, offset)); |
1271 | 1271 |
1272 return VisiblePosition(Position(node, type), DOWNSTREAM); | 1272 return VisiblePosition(Position(node, type)); |
1273 } | 1273 } |
1274 | 1274 |
1275 // FIXME: isStartOfParagraph(startOfNextParagraph(pos)) is not always true | 1275 // FIXME: isStartOfParagraph(startOfNextParagraph(pos)) is not always true |
1276 VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition) | 1276 VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition) |
1277 { | 1277 { |
1278 VisiblePosition paragraphEnd(endOfParagraph(visiblePosition, CanSkipOverEdit
ingBoundary)); | 1278 VisiblePosition paragraphEnd(endOfParagraph(visiblePosition, CanSkipOverEdit
ingBoundary)); |
1279 VisiblePosition afterParagraphEnd(paragraphEnd.next(CannotCrossEditingBounda
ry)); | 1279 VisiblePosition afterParagraphEnd(paragraphEnd.next(CannotCrossEditingBounda
ry)); |
1280 // The position after the last position in the last cell of a table | 1280 // The position after the last position in the last cell of a table |
1281 // is not the start of the next paragraph. | 1281 // is not the start of the next paragraph. |
1282 if (isFirstPositionAfterTable(afterParagraphEnd)) | 1282 if (isFirstPositionAfterTable(afterParagraphEnd)) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1354 return pos.isNotNull() && pos.deepEquivalent() == endOfBlock(pos, CanCrossEd
itingBoundary).deepEquivalent(); | 1354 return pos.isNotNull() && pos.deepEquivalent() == endOfBlock(pos, CanCrossEd
itingBoundary).deepEquivalent(); |
1355 } | 1355 } |
1356 | 1356 |
1357 // --------- | 1357 // --------- |
1358 | 1358 |
1359 VisiblePosition startOfDocument(const Node* node) | 1359 VisiblePosition startOfDocument(const Node* node) |
1360 { | 1360 { |
1361 if (!node || !node->document().documentElement()) | 1361 if (!node || !node->document().documentElement()) |
1362 return VisiblePosition(); | 1362 return VisiblePosition(); |
1363 | 1363 |
1364 return VisiblePosition(firstPositionInNode(node->document().documentElement(
)), DOWNSTREAM); | 1364 return VisiblePosition(firstPositionInNode(node->document().documentElement(
))); |
1365 } | 1365 } |
1366 | 1366 |
1367 VisiblePosition startOfDocument(const VisiblePosition &c) | 1367 VisiblePosition startOfDocument(const VisiblePosition &c) |
1368 { | 1368 { |
1369 return startOfDocument(c.deepEquivalent().anchorNode()); | 1369 return startOfDocument(c.deepEquivalent().anchorNode()); |
1370 } | 1370 } |
1371 | 1371 |
1372 VisiblePosition endOfDocument(const Node* node) | 1372 VisiblePosition endOfDocument(const Node* node) |
1373 { | 1373 { |
1374 if (!node || !node->document().documentElement()) | 1374 if (!node || !node->document().documentElement()) |
1375 return VisiblePosition(); | 1375 return VisiblePosition(); |
1376 | 1376 |
1377 Element* doc = node->document().documentElement(); | 1377 Element* doc = node->document().documentElement(); |
1378 return VisiblePosition(lastPositionInNode(doc), DOWNSTREAM); | 1378 return VisiblePosition(lastPositionInNode(doc)); |
1379 } | 1379 } |
1380 | 1380 |
1381 VisiblePosition endOfDocument(const VisiblePosition &c) | 1381 VisiblePosition endOfDocument(const VisiblePosition &c) |
1382 { | 1382 { |
1383 return endOfDocument(c.deepEquivalent().anchorNode()); | 1383 return endOfDocument(c.deepEquivalent().anchorNode()); |
1384 } | 1384 } |
1385 | 1385 |
1386 bool isStartOfDocument(const VisiblePosition &p) | 1386 bool isStartOfDocument(const VisiblePosition &p) |
1387 { | 1387 { |
1388 return p.isNotNull() && p.previous(CanCrossEditingBoundary).isNull(); | 1388 return p.isNotNull() && p.previous(CanCrossEditingBoundary).isNull(); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1595 | 1595 |
1596 if (previousRenderedEditable(position1.anchorNode()) == position2.anchorNode
() | 1596 if (previousRenderedEditable(position1.anchorNode()) == position2.anchorNode
() |
1597 && !renderedOffset1 && renderedOffset2 == caretMaxOffset(position2.ancho
rNode())) { | 1597 && !renderedOffset1 && renderedOffset2 == caretMaxOffset(position2.ancho
rNode())) { |
1598 return false; | 1598 return false; |
1599 } | 1599 } |
1600 | 1600 |
1601 return true; | 1601 return true; |
1602 } | 1602 } |
1603 | 1603 |
1604 } | 1604 } |
OLD | NEW |