OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 DCHECK(m_extent.isNotNull()); | 554 DCHECK(m_extent.isNotNull()); |
555 | 555 |
556 m_start = m_baseIsFirst ? m_base : m_extent; | 556 m_start = m_baseIsFirst ? m_base : m_extent; |
557 | 557 |
558 switch (granularity) { | 558 switch (granularity) { |
559 case CharacterGranularity: | 559 case CharacterGranularity: |
560 // Don't do any expansion. | 560 // Don't do any expansion. |
561 break; | 561 break; |
562 case WordGranularity: { | 562 case WordGranularity: { |
563 // General case: Select the word the caret is positioned inside of. | 563 // General case: Select the word the caret is positioned inside of. |
564 // If the caret is on the word boundary, select the word according to |wor
dSide|. | 564 // If the caret is on the word boundary, select the word according to |
565 // Edge case: If the caret is after the last word in a soft-wrapped line o
r the last word in | 565 // |wordSide|. |
566 // the document, select that last word (LeftWordIfOnBoundary). | 566 // Edge case: If the caret is after the last word in a soft-wrapped line |
567 // Edge case: If the caret is after the last word in a paragraph, select f
rom the the end of the | 567 // or the last word in the document, select that last word |
568 // last word to the line break (also RightWordIfOnBoundary); | 568 // (LeftWordIfOnBoundary). |
| 569 // Edge case: If the caret is after the last word in a paragraph, select |
| 570 // from the the end of the last word to the line break (also |
| 571 // RightWordIfOnBoundary); |
569 const VisiblePositionTemplate<Strategy> visibleStart = | 572 const VisiblePositionTemplate<Strategy> visibleStart = |
570 createVisiblePosition(m_start, m_affinity); | 573 createVisiblePosition(m_start, m_affinity); |
571 EWordSide side = RightWordIfOnBoundary; | 574 EWordSide side = RightWordIfOnBoundary; |
572 if (isEndOfEditableOrNonEditableContent(visibleStart) || | 575 if (isEndOfEditableOrNonEditableContent(visibleStart) || |
573 (isEndOfLine(visibleStart) && !isStartOfLine(visibleStart) && | 576 (isEndOfLine(visibleStart) && !isStartOfLine(visibleStart) && |
574 !isEndOfParagraph(visibleStart))) | 577 !isEndOfParagraph(visibleStart))) |
575 side = LeftWordIfOnBoundary; | 578 side = LeftWordIfOnBoundary; |
576 m_start = startOfWord(visibleStart, side).deepEquivalent(); | 579 m_start = startOfWord(visibleStart, side).deepEquivalent(); |
577 break; | 580 break; |
578 } | 581 } |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 if (m_base.isNull() || m_start.isNull() || m_end.isNull()) | 867 if (m_base.isNull() || m_start.isNull() || m_end.isNull()) |
865 return; | 868 return; |
866 | 869 |
867 ContainerNode* baseRoot = highestEditableRoot(m_base); | 870 ContainerNode* baseRoot = highestEditableRoot(m_base); |
868 ContainerNode* startRoot = highestEditableRoot(m_start); | 871 ContainerNode* startRoot = highestEditableRoot(m_start); |
869 ContainerNode* endRoot = highestEditableRoot(m_end); | 872 ContainerNode* endRoot = highestEditableRoot(m_end); |
870 | 873 |
871 Element* baseEditableAncestor = | 874 Element* baseEditableAncestor = |
872 lowestEditableAncestor(m_base.computeContainerNode()); | 875 lowestEditableAncestor(m_base.computeContainerNode()); |
873 | 876 |
874 // The base, start and end are all in the same region. No adjustment necessar
y. | 877 // The base, start and end are all in the same region. No adjustment |
| 878 // necessary. |
875 if (baseRoot == startRoot && baseRoot == endRoot) | 879 if (baseRoot == startRoot && baseRoot == endRoot) |
876 return; | 880 return; |
877 | 881 |
878 // The selection is based in editable content. | 882 // The selection is based in editable content. |
879 if (baseRoot) { | 883 if (baseRoot) { |
880 // If the start is outside the base's editable root, cap it at the start of
that root. | 884 // If the start is outside the base's editable root, cap it at the start of |
881 // If the start is in non-editable content that is inside the base's editabl
e root, put it | 885 // that root. |
882 // at the first editable position after start inside the base's editable roo
t. | 886 // If the start is in non-editable content that is inside the base's |
| 887 // editable root, put it at the first editable position after start inside |
| 888 // the base's editable root. |
883 if (startRoot != baseRoot) { | 889 if (startRoot != baseRoot) { |
884 const VisiblePositionTemplate<Strategy> first = | 890 const VisiblePositionTemplate<Strategy> first = |
885 firstEditableVisiblePositionAfterPositionInRoot(m_start, *baseRoot); | 891 firstEditableVisiblePositionAfterPositionInRoot(m_start, *baseRoot); |
886 m_start = first.deepEquivalent(); | 892 m_start = first.deepEquivalent(); |
887 if (m_start.isNull()) { | 893 if (m_start.isNull()) { |
888 NOTREACHED(); | 894 NOTREACHED(); |
889 m_start = m_end; | 895 m_start = m_end; |
890 } | 896 } |
891 } | 897 } |
892 // If the end is outside the base's editable root, cap it at the end of that
root. | 898 // If the end is outside the base's editable root, cap it at the end of that |
893 // If the end is in non-editable content that is inside the base's root, put
it | 899 // root. |
894 // at the last editable position before the end inside the base's root. | 900 // If the end is in non-editable content that is inside the base's root, put |
| 901 // it at the last editable position before the end inside the base's root. |
895 if (endRoot != baseRoot) { | 902 if (endRoot != baseRoot) { |
896 const VisiblePositionTemplate<Strategy> last = | 903 const VisiblePositionTemplate<Strategy> last = |
897 lastEditableVisiblePositionBeforePositionInRoot(m_end, *baseRoot); | 904 lastEditableVisiblePositionBeforePositionInRoot(m_end, *baseRoot); |
898 m_end = last.deepEquivalent(); | 905 m_end = last.deepEquivalent(); |
899 if (m_end.isNull()) | 906 if (m_end.isNull()) |
900 m_end = m_start; | 907 m_end = m_start; |
901 } | 908 } |
902 // The selection is based in non-editable content. | 909 // The selection is based in non-editable content. |
903 } else { | 910 } else { |
904 // FIXME: Non-editable pieces inside editable content should be atomic, in t
he same way that editable | 911 // FIXME: Non-editable pieces inside editable content should be atomic, in |
905 // pieces in non-editable content are atomic. | 912 // the same way that editable pieces in non-editable content are atomic. |
906 | 913 |
907 // The selection ends in editable content or non-editable content inside a d
ifferent editable ancestor, | 914 // The selection ends in editable content or non-editable content inside a |
908 // move backward until non-editable content inside the same lowest editable
ancestor is reached. | 915 // different editable ancestor, move backward until non-editable content |
| 916 // inside the same lowest editable ancestor is reached. |
909 Element* endEditableAncestor = | 917 Element* endEditableAncestor = |
910 lowestEditableAncestor(m_end.computeContainerNode()); | 918 lowestEditableAncestor(m_end.computeContainerNode()); |
911 if (endRoot || endEditableAncestor != baseEditableAncestor) { | 919 if (endRoot || endEditableAncestor != baseEditableAncestor) { |
912 PositionTemplate<Strategy> p = previousVisuallyDistinctCandidate(m_end); | 920 PositionTemplate<Strategy> p = previousVisuallyDistinctCandidate(m_end); |
913 Element* shadowAncestor = endRoot ? endRoot->ownerShadowHost() : nullptr; | 921 Element* shadowAncestor = endRoot ? endRoot->ownerShadowHost() : nullptr; |
914 if (p.isNull() && shadowAncestor) | 922 if (p.isNull() && shadowAncestor) |
915 p = PositionTemplate<Strategy>::afterNode(shadowAncestor); | 923 p = PositionTemplate<Strategy>::afterNode(shadowAncestor); |
916 while (p.isNotNull() && | 924 while (p.isNotNull() && |
917 !(lowestEditableAncestor(p.computeContainerNode()) == | 925 !(lowestEditableAncestor(p.computeContainerNode()) == |
918 baseEditableAncestor && | 926 baseEditableAncestor && |
(...skipping 15 matching lines...) Expand all Loading... |
934 // programmer error in the editing code. Happy debugging! | 942 // programmer error in the editing code. Happy debugging! |
935 NOTREACHED(); | 943 NOTREACHED(); |
936 m_base = PositionTemplate<Strategy>(); | 944 m_base = PositionTemplate<Strategy>(); |
937 m_extent = PositionTemplate<Strategy>(); | 945 m_extent = PositionTemplate<Strategy>(); |
938 validate(); | 946 validate(); |
939 return; | 947 return; |
940 } | 948 } |
941 m_end = previous.deepEquivalent(); | 949 m_end = previous.deepEquivalent(); |
942 } | 950 } |
943 | 951 |
944 // The selection starts in editable content or non-editable content inside a
different editable ancestor, | 952 // The selection starts in editable content or non-editable content inside a |
945 // move forward until non-editable content inside the same lowest editable a
ncestor is reached. | 953 // different editable ancestor, move forward until non-editable content |
| 954 // inside the same lowest editable ancestor is reached. |
946 Element* startEditableAncestor = | 955 Element* startEditableAncestor = |
947 lowestEditableAncestor(m_start.computeContainerNode()); | 956 lowestEditableAncestor(m_start.computeContainerNode()); |
948 if (startRoot || startEditableAncestor != baseEditableAncestor) { | 957 if (startRoot || startEditableAncestor != baseEditableAncestor) { |
949 PositionTemplate<Strategy> p = nextVisuallyDistinctCandidate(m_start); | 958 PositionTemplate<Strategy> p = nextVisuallyDistinctCandidate(m_start); |
950 Element* shadowAncestor = | 959 Element* shadowAncestor = |
951 startRoot ? startRoot->ownerShadowHost() : nullptr; | 960 startRoot ? startRoot->ownerShadowHost() : nullptr; |
952 if (p.isNull() && shadowAncestor) | 961 if (p.isNull() && shadowAncestor) |
953 p = PositionTemplate<Strategy>::beforeNode(shadowAncestor); | 962 p = PositionTemplate<Strategy>::beforeNode(shadowAncestor); |
954 while (p.isNotNull() && | 963 while (p.isNotNull() && |
955 !(lowestEditableAncestor(p.computeContainerNode()) == | 964 !(lowestEditableAncestor(p.computeContainerNode()) == |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 | 1131 |
1123 void showTree(const blink::VisibleSelectionInFlatTree& sel) { | 1132 void showTree(const blink::VisibleSelectionInFlatTree& sel) { |
1124 sel.showTreeForThis(); | 1133 sel.showTreeForThis(); |
1125 } | 1134 } |
1126 | 1135 |
1127 void showTree(const blink::VisibleSelectionInFlatTree* sel) { | 1136 void showTree(const blink::VisibleSelectionInFlatTree* sel) { |
1128 if (sel) | 1137 if (sel) |
1129 sel->showTreeForThis(); | 1138 sel->showTreeForThis(); |
1130 } | 1139 } |
1131 #endif | 1140 #endif |
OLD | NEW |