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 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 return adjacentCharacterPosition; | 427 return adjacentCharacterPosition; |
428 | 428 |
429 current = adjacentCharacterPosition; | 429 current = adjacentCharacterPosition; |
430 } | 430 } |
431 return VisiblePosition(); | 431 return VisiblePosition(); |
432 } | 432 } |
433 | 433 |
434 VisiblePosition leftWordPosition(const VisiblePosition& visiblePosition, bool sk
ipsSpaceWhenMovingRight) | 434 VisiblePosition leftWordPosition(const VisiblePosition& visiblePosition, bool sk
ipsSpaceWhenMovingRight) |
435 { | 435 { |
436 VisiblePosition leftWordBreak = visualWordPosition(visiblePosition, MoveLeft
, skipsSpaceWhenMovingRight); | 436 VisiblePosition leftWordBreak = visualWordPosition(visiblePosition, MoveLeft
, skipsSpaceWhenMovingRight); |
437 leftWordBreak = visiblePosition.honorEditingBoundaryAtOrBefore(leftWordBreak
); | 437 leftWordBreak = honorEditingBoundaryAtOrBefore(leftWordBreak, visiblePositio
n.deepEquivalent()); |
438 | 438 |
439 // FIXME: How should we handle a non-editable position? | 439 // FIXME: How should we handle a non-editable position? |
440 if (leftWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquival
ent())) { | 440 if (leftWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquival
ent())) { |
441 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition
.deepEquivalent()); | 441 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition
.deepEquivalent()); |
442 leftWordBreak = blockDirection == LTR ? startOfEditableContent(visiblePo
sition) : endOfEditableContent(visiblePosition); | 442 leftWordBreak = blockDirection == LTR ? startOfEditableContent(visiblePo
sition) : endOfEditableContent(visiblePosition); |
443 } | 443 } |
444 return leftWordBreak; | 444 return leftWordBreak; |
445 } | 445 } |
446 | 446 |
447 VisiblePosition rightWordPosition(const VisiblePosition& visiblePosition, bool s
kipsSpaceWhenMovingRight) | 447 VisiblePosition rightWordPosition(const VisiblePosition& visiblePosition, bool s
kipsSpaceWhenMovingRight) |
448 { | 448 { |
449 VisiblePosition rightWordBreak = visualWordPosition(visiblePosition, MoveRig
ht, skipsSpaceWhenMovingRight); | 449 VisiblePosition rightWordBreak = visualWordPosition(visiblePosition, MoveRig
ht, skipsSpaceWhenMovingRight); |
450 rightWordBreak = visiblePosition.honorEditingBoundaryAtOrBefore(rightWordBre
ak); | 450 rightWordBreak = honorEditingBoundaryAtOrBefore(rightWordBreak, visiblePosit
ion.deepEquivalent()); |
451 | 451 |
452 // FIXME: How should we handle a non-editable position? | 452 // FIXME: How should we handle a non-editable position? |
453 if (rightWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquiva
lent())) { | 453 if (rightWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquiva
lent())) { |
454 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition
.deepEquivalent()); | 454 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition
.deepEquivalent()); |
455 rightWordBreak = blockDirection == LTR ? endOfEditableContent(visiblePos
ition) : startOfEditableContent(visiblePosition); | 455 rightWordBreak = blockDirection == LTR ? endOfEditableContent(visiblePos
ition) : startOfEditableContent(visiblePosition); |
456 } | 456 } |
457 return rightWordBreak; | 457 return rightWordBreak; |
458 } | 458 } |
459 | 459 |
460 template <typename Strategy> | 460 template <typename Strategy> |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 needMoreContext = true; | 713 needMoreContext = true; |
714 return 0; | 714 return 0; |
715 } | 715 } |
716 needMoreContext = false; | 716 needMoreContext = false; |
717 return findNextWordFromIndex(characters, length, offset, false); | 717 return findNextWordFromIndex(characters, length, offset, false); |
718 } | 718 } |
719 | 719 |
720 VisiblePosition previousWordPosition(const VisiblePosition& c) | 720 VisiblePosition previousWordPosition(const VisiblePosition& c) |
721 { | 721 { |
722 VisiblePosition prev = previousBoundary(c, previousWordPositionBoundary); | 722 VisiblePosition prev = previousBoundary(c, previousWordPositionBoundary); |
723 return c.honorEditingBoundaryAtOrBefore(prev); | 723 return honorEditingBoundaryAtOrBefore(prev, c.deepEquivalent()); |
724 } | 724 } |
725 | 725 |
726 static unsigned nextWordPositionBoundary(const UChar* characters, unsigned lengt
h, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool&
needMoreContext) | 726 static unsigned nextWordPositionBoundary(const UChar* characters, unsigned lengt
h, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool&
needMoreContext) |
727 { | 727 { |
728 if (mayHaveMoreContext && endOfFirstWordBoundaryContext(characters + offset,
length - offset) == static_cast<int>(length - offset)) { | 728 if (mayHaveMoreContext && endOfFirstWordBoundaryContext(characters + offset,
length - offset) == static_cast<int>(length - offset)) { |
729 needMoreContext = true; | 729 needMoreContext = true; |
730 return length; | 730 return length; |
731 } | 731 } |
732 needMoreContext = false; | 732 needMoreContext = false; |
733 return findNextWordFromIndex(characters, length, offset, true); | 733 return findNextWordFromIndex(characters, length, offset, true); |
734 } | 734 } |
735 | 735 |
736 VisiblePosition nextWordPosition(const VisiblePosition& c) | 736 VisiblePosition nextWordPosition(const VisiblePosition& c) |
737 { | 737 { |
738 VisiblePosition next = nextBoundary(c, nextWordPositionBoundary); | 738 VisiblePosition next = nextBoundary(c, nextWordPositionBoundary); |
739 return c.honorEditingBoundaryAtOrAfter(next); | 739 return honorEditingBoundaryAtOrAfter(next, c.deepEquivalent()); |
740 } | 740 } |
741 | 741 |
742 // --------- | 742 // --------- |
743 | 743 |
744 enum LineEndpointComputationMode { UseLogicalOrdering, UseInlineBoxOrdering }; | 744 enum LineEndpointComputationMode { UseLogicalOrdering, UseInlineBoxOrdering }; |
745 template <typename Strategy> | 745 template <typename Strategy> |
746 static PositionWithAffinityTemplate<Strategy> startPositionForLine(const Positio
nWithAffinityTemplate<Strategy>& c, LineEndpointComputationMode mode) | 746 static PositionWithAffinityTemplate<Strategy> startPositionForLine(const Positio
nWithAffinityTemplate<Strategy>& c, LineEndpointComputationMode mode) |
747 { | 747 { |
748 if (c.isNull()) | 748 if (c.isNull()) |
749 return PositionWithAffinityTemplate<Strategy>(); | 749 return PositionWithAffinityTemplate<Strategy>(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abc
defg abcdefg </div> | 893 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abc
defg abcdefg </div> |
894 // In this case, use the previous position of the computed logical end p
osition. | 894 // In this case, use the previous position of the computed logical end p
osition. |
895 if (!inSameLogicalLine(c, visPos)) | 895 if (!inSameLogicalLine(c, visPos)) |
896 visPos = previousPositionOf(visPos); | 896 visPos = previousPositionOf(visPos); |
897 | 897 |
898 if (ContainerNode* editableRoot = highestEditableRoot(c.deepEquivalent()
)) { | 898 if (ContainerNode* editableRoot = highestEditableRoot(c.deepEquivalent()
)) { |
899 if (!editableRoot->contains(visPos.deepEquivalent().computeContainer
Node())) | 899 if (!editableRoot->contains(visPos.deepEquivalent().computeContainer
Node())) |
900 return VisiblePosition(lastPositionInNode(editableRoot)); | 900 return VisiblePosition(lastPositionInNode(editableRoot)); |
901 } | 901 } |
902 | 902 |
903 return c.honorEditingBoundaryAtOrAfter(visPos); | 903 return honorEditingBoundaryAtOrAfter(visPos, c.deepEquivalent()); |
904 } | 904 } |
905 | 905 |
906 // Make sure the end of line is at the same line as the given input position
. Else use the previous position to | 906 // Make sure the end of line is at the same line as the given input position
. Else use the previous position to |
907 // obtain end of line. This condition happens when the input position is bef
ore the space character at the end | 907 // obtain end of line. This condition happens when the input position is bef
ore the space character at the end |
908 // of a soft-wrapped non-editable line. In this scenario, endPositionForLine
would incorrectly hand back a position | 908 // of a soft-wrapped non-editable line. In this scenario, endPositionForLine
would incorrectly hand back a position |
909 // in the next line instead. This fix is to account for the discrepancy betw
een lines with webkit-line-break:after-white-space style | 909 // in the next line instead. This fix is to account for the discrepancy betw
een lines with webkit-line-break:after-white-space style |
910 // versus lines without that style, which would break before a space by defa
ult. | 910 // versus lines without that style, which would break before a space by defa
ult. |
911 if (!inSameLine(c, visPos)) { | 911 if (!inSameLine(c, visPos)) { |
912 visPos = previousPositionOf(c); | 912 visPos = previousPositionOf(c); |
913 if (visPos.isNull()) | 913 if (visPos.isNull()) |
914 return VisiblePosition(); | 914 return VisiblePosition(); |
915 visPos = endPositionForLine(visPos, UseInlineBoxOrdering); | 915 visPos = endPositionForLine(visPos, UseInlineBoxOrdering); |
916 } | 916 } |
917 | 917 |
918 return c.honorEditingBoundaryAtOrAfter(visPos); | 918 return honorEditingBoundaryAtOrAfter(visPos, c.deepEquivalent()); |
919 } | 919 } |
920 | 920 |
921 // FIXME: Rename this function to reflect the fact it ignores bidi levels. | 921 // FIXME: Rename this function to reflect the fact it ignores bidi levels. |
922 VisiblePosition endOfLine(const VisiblePosition& currentPosition) | 922 VisiblePosition endOfLine(const VisiblePosition& currentPosition) |
923 { | 923 { |
924 return endOfLine(currentPosition, UseInlineBoxOrdering); | 924 return endOfLine(currentPosition, UseInlineBoxOrdering); |
925 } | 925 } |
926 | 926 |
927 VisiblePosition logicalEndOfLine(const VisiblePosition& currentPosition) | 927 VisiblePosition logicalEndOfLine(const VisiblePosition& currentPosition) |
928 { | 928 { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 { | 1127 { |
1128 // FIXME: This is identical to startSentenceBoundary. I'm pretty sure that's
not right. | 1128 // FIXME: This is identical to startSentenceBoundary. I'm pretty sure that's
not right. |
1129 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); | 1129 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); |
1130 // FIXME: The following function can return -1; we don't handle that. | 1130 // FIXME: The following function can return -1; we don't handle that. |
1131 return iterator->preceding(length); | 1131 return iterator->preceding(length); |
1132 } | 1132 } |
1133 | 1133 |
1134 VisiblePosition previousSentencePosition(const VisiblePosition& c) | 1134 VisiblePosition previousSentencePosition(const VisiblePosition& c) |
1135 { | 1135 { |
1136 VisiblePosition prev = previousBoundary(c, previousSentencePositionBoundary)
; | 1136 VisiblePosition prev = previousBoundary(c, previousSentencePositionBoundary)
; |
1137 return c.honorEditingBoundaryAtOrBefore(prev); | 1137 return honorEditingBoundaryAtOrBefore(prev, c.deepEquivalent()); |
1138 } | 1138 } |
1139 | 1139 |
1140 static unsigned nextSentencePositionBoundary(const UChar* characters, unsigned l
ength, unsigned, BoundarySearchContextAvailability, bool&) | 1140 static unsigned nextSentencePositionBoundary(const UChar* characters, unsigned l
ength, unsigned, BoundarySearchContextAvailability, bool&) |
1141 { | 1141 { |
1142 // FIXME: This is identical to endSentenceBoundary. This isn't right, it nee
ds to | 1142 // FIXME: This is identical to endSentenceBoundary. This isn't right, it nee
ds to |
1143 // move to the equivlant position in the following sentence. | 1143 // move to the equivlant position in the following sentence. |
1144 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); | 1144 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); |
1145 return iterator->following(0); | 1145 return iterator->following(0); |
1146 } | 1146 } |
1147 | 1147 |
1148 VisiblePosition nextSentencePosition(const VisiblePosition& c) | 1148 VisiblePosition nextSentencePosition(const VisiblePosition& c) |
1149 { | 1149 { |
1150 VisiblePosition next = nextBoundary(c, nextSentencePositionBoundary); | 1150 VisiblePosition next = nextBoundary(c, nextSentencePositionBoundary); |
1151 return c.honorEditingBoundaryAtOrAfter(next); | 1151 return honorEditingBoundaryAtOrAfter(next, c.deepEquivalent()); |
1152 } | 1152 } |
1153 | 1153 |
1154 VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi
ngRule boundaryCrossingRule) | 1154 VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi
ngRule boundaryCrossingRule) |
1155 { | 1155 { |
1156 Position p = c.deepEquivalent(); | 1156 Position p = c.deepEquivalent(); |
1157 Node* startNode = p.anchorNode(); | 1157 Node* startNode = p.anchorNode(); |
1158 | 1158 |
1159 if (!startNode) | 1159 if (!startNode) |
1160 return VisiblePosition(); | 1160 return VisiblePosition(); |
1161 | 1161 |
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2331 { | 2331 { |
2332 return isVisuallyEquivalentCandidateAlgorithm<EditingStrategy>(position); | 2332 return isVisuallyEquivalentCandidateAlgorithm<EditingStrategy>(position); |
2333 } | 2333 } |
2334 | 2334 |
2335 bool isVisuallyEquivalentCandidate(const PositionInComposedTree& position) | 2335 bool isVisuallyEquivalentCandidate(const PositionInComposedTree& position) |
2336 { | 2336 { |
2337 return isVisuallyEquivalentCandidateAlgorithm<EditingInComposedTreeStrategy>
(position); | 2337 return isVisuallyEquivalentCandidateAlgorithm<EditingInComposedTreeStrategy>
(position); |
2338 } | 2338 } |
2339 | 2339 |
2340 } // namespace blink | 2340 } // namespace blink |
OLD | NEW |