| 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 |