| 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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 return previousVisuallyDistinctCandidateAlgorithm<EditingStrategy>(position)
; | 441 return previousVisuallyDistinctCandidateAlgorithm<EditingStrategy>(position)
; |
| 442 } | 442 } |
| 443 | 443 |
| 444 PositionInComposedTree previousVisuallyDistinctCandidate(const PositionInCompose
dTree& position) | 444 PositionInComposedTree previousVisuallyDistinctCandidate(const PositionInCompose
dTree& position) |
| 445 { | 445 { |
| 446 return previousVisuallyDistinctCandidateAlgorithm<EditingInComposedTreeStrat
egy>(position); | 446 return previousVisuallyDistinctCandidateAlgorithm<EditingInComposedTreeStrat
egy>(position); |
| 447 } | 447 } |
| 448 | 448 |
| 449 VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position&
position, ContainerNode* highestRoot) | 449 VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position&
position, ContainerNode* highestRoot) |
| 450 { | 450 { |
| 451 return VisiblePosition(firstEditablePositionAfterPositionInRoot(position, hi
ghestRoot)); | 451 return createVisiblePosition(firstEditablePositionAfterPositionInRoot(positi
on, highestRoot)); |
| 452 } | 452 } |
| 453 | 453 |
| 454 template <typename Strategy> | 454 template <typename Strategy> |
| 455 PositionAlgorithm<Strategy> firstEditablePositionAfterPositionInRootAlgorithm(co
nst PositionAlgorithm<Strategy>& position, Node* highestRoot) | 455 PositionAlgorithm<Strategy> firstEditablePositionAfterPositionInRootAlgorithm(co
nst PositionAlgorithm<Strategy>& position, Node* highestRoot) |
| 456 { | 456 { |
| 457 // position falls before highestRoot. | 457 // position falls before highestRoot. |
| 458 if (position.compareTo(PositionAlgorithm<Strategy>::firstPositionInNode(high
estRoot)) == -1 && highestRoot->hasEditableStyle()) | 458 if (position.compareTo(PositionAlgorithm<Strategy>::firstPositionInNode(high
estRoot)) == -1 && highestRoot->hasEditableStyle()) |
| 459 return PositionAlgorithm<Strategy>::firstPositionInNode(highestRoot); | 459 return PositionAlgorithm<Strategy>::firstPositionInNode(highestRoot); |
| 460 | 460 |
| 461 PositionAlgorithm<Strategy> editablePosition = position; | 461 PositionAlgorithm<Strategy> editablePosition = position; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 482 return firstEditablePositionAfterPositionInRootAlgorithm<EditingStrategy>(po
sition, highestRoot); | 482 return firstEditablePositionAfterPositionInRootAlgorithm<EditingStrategy>(po
sition, highestRoot); |
| 483 } | 483 } |
| 484 | 484 |
| 485 PositionInComposedTree firstEditablePositionAfterPositionInRoot(const PositionIn
ComposedTree& position, Node* highestRoot) | 485 PositionInComposedTree firstEditablePositionAfterPositionInRoot(const PositionIn
ComposedTree& position, Node* highestRoot) |
| 486 { | 486 { |
| 487 return firstEditablePositionAfterPositionInRootAlgorithm<EditingInComposedTr
eeStrategy>(position, highestRoot); | 487 return firstEditablePositionAfterPositionInRootAlgorithm<EditingInComposedTr
eeStrategy>(position, highestRoot); |
| 488 } | 488 } |
| 489 | 489 |
| 490 VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position&
position, ContainerNode* highestRoot) | 490 VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position&
position, ContainerNode* highestRoot) |
| 491 { | 491 { |
| 492 return VisiblePosition(lastEditablePositionBeforePositionInRoot(position, hi
ghestRoot)); | 492 return createVisiblePosition(lastEditablePositionBeforePositionInRoot(positi
on, highestRoot)); |
| 493 } | 493 } |
| 494 | 494 |
| 495 template <typename Strategy> | 495 template <typename Strategy> |
| 496 PositionAlgorithm<Strategy> lastEditablePositionBeforePositionInRootAlgorithm(co
nst PositionAlgorithm<Strategy>& position, Node* highestRoot) | 496 PositionAlgorithm<Strategy> lastEditablePositionBeforePositionInRootAlgorithm(co
nst PositionAlgorithm<Strategy>& position, Node* highestRoot) |
| 497 { | 497 { |
| 498 // When position falls after highestRoot, the result is easy to compute. | 498 // When position falls after highestRoot, the result is easy to compute. |
| 499 if (position.compareTo(PositionAlgorithm<Strategy>::lastPositionInNode(highe
stRoot)) == 1) | 499 if (position.compareTo(PositionAlgorithm<Strategy>::lastPositionInNode(highe
stRoot)) == 1) |
| 500 return PositionAlgorithm<Strategy>::lastPositionInNode(highestRoot); | 500 return PositionAlgorithm<Strategy>::lastPositionInNode(highestRoot); |
| 501 | 501 |
| 502 PositionAlgorithm<Strategy> editablePosition = position; | 502 PositionAlgorithm<Strategy> editablePosition = position; |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 | 796 |
| 797 return false; | 797 return false; |
| 798 } | 798 } |
| 799 | 799 |
| 800 static HTMLElement* firstInSpecialElement(const Position& pos) | 800 static HTMLElement* firstInSpecialElement(const Position& pos) |
| 801 { | 801 { |
| 802 Element* rootEditableElement = pos.computeContainerNode()->rootEditableEleme
nt(); | 802 Element* rootEditableElement = pos.computeContainerNode()->rootEditableEleme
nt(); |
| 803 for (Node* n = pos.anchorNode(); n && n->rootEditableElement() == rootEditab
leElement; n = n->parentNode()) { | 803 for (Node* n = pos.anchorNode(); n && n->rootEditableElement() == rootEditab
leElement; n = n->parentNode()) { |
| 804 if (isSpecialHTMLElement(*n)) { | 804 if (isSpecialHTMLElement(*n)) { |
| 805 HTMLElement* specialElement = toHTMLElement(n); | 805 HTMLElement* specialElement = toHTMLElement(n); |
| 806 VisiblePosition vPos = VisiblePosition(pos); | 806 VisiblePosition vPos = createVisiblePosition(pos); |
| 807 VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBe
foreNode(specialElement)); | 807 VisiblePosition firstInElement = createVisiblePosition(firstPosition
InOrBeforeNode(specialElement)); |
| 808 if (isRenderedTableElement(specialElement) && vPos.deepEquivalent()
== nextPositionOf(firstInElement).deepEquivalent()) | 808 if (isRenderedTableElement(specialElement) && vPos.deepEquivalent()
== nextPositionOf(firstInElement).deepEquivalent()) |
| 809 return specialElement; | 809 return specialElement; |
| 810 if (vPos.deepEquivalent() == firstInElement.deepEquivalent()) | 810 if (vPos.deepEquivalent() == firstInElement.deepEquivalent()) |
| 811 return specialElement; | 811 return specialElement; |
| 812 } | 812 } |
| 813 } | 813 } |
| 814 return 0; | 814 return 0; |
| 815 } | 815 } |
| 816 | 816 |
| 817 static HTMLElement* lastInSpecialElement(const Position& pos) | 817 static HTMLElement* lastInSpecialElement(const Position& pos) |
| 818 { | 818 { |
| 819 Element* rootEditableElement = pos.computeContainerNode()->rootEditableEleme
nt(); | 819 Element* rootEditableElement = pos.computeContainerNode()->rootEditableEleme
nt(); |
| 820 for (Node* n = pos.anchorNode(); n && n->rootEditableElement() == rootEditab
leElement; n = n->parentNode()) { | 820 for (Node* n = pos.anchorNode(); n && n->rootEditableElement() == rootEditab
leElement; n = n->parentNode()) { |
| 821 if (isSpecialHTMLElement(*n)) { | 821 if (isSpecialHTMLElement(*n)) { |
| 822 HTMLElement* specialElement = toHTMLElement(n); | 822 HTMLElement* specialElement = toHTMLElement(n); |
| 823 VisiblePosition vPos = VisiblePosition(pos); | 823 VisiblePosition vPos = createVisiblePosition(pos); |
| 824 VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfte
rNode(specialElement)); | 824 VisiblePosition lastInElement = createVisiblePosition(lastPositionIn
OrAfterNode(specialElement)); |
| 825 if (isRenderedTableElement(specialElement) && vPos.deepEquivalent()
== previousPositionOf(lastInElement).deepEquivalent()) | 825 if (isRenderedTableElement(specialElement) && vPos.deepEquivalent()
== previousPositionOf(lastInElement).deepEquivalent()) |
| 826 return specialElement; | 826 return specialElement; |
| 827 if (vPos.deepEquivalent() == lastInElement.deepEquivalent()) | 827 if (vPos.deepEquivalent() == lastInElement.deepEquivalent()) |
| 828 return specialElement; | 828 return specialElement; |
| 829 } | 829 } |
| 830 } | 830 } |
| 831 return 0; | 831 return 0; |
| 832 } | 832 } |
| 833 | 833 |
| 834 Position positionBeforeContainingSpecialElement(const Position& pos, HTMLElement
** containingSpecialElement) | 834 Position positionBeforeContainingSpecialElement(const Position& pos, HTMLElement
** containingSpecialElement) |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 return node; | 919 return node; |
| 920 node = nextNodeConsideringAtomicNodes(*node); | 920 node = nextNodeConsideringAtomicNodes(*node); |
| 921 } | 921 } |
| 922 return nullptr; | 922 return nullptr; |
| 923 } | 923 } |
| 924 | 924 |
| 925 // Returns the visible position at the beginning of a node | 925 // Returns the visible position at the beginning of a node |
| 926 VisiblePosition visiblePositionBeforeNode(Node& node) | 926 VisiblePosition visiblePositionBeforeNode(Node& node) |
| 927 { | 927 { |
| 928 if (node.hasChildren()) | 928 if (node.hasChildren()) |
| 929 return VisiblePosition(firstPositionInOrBeforeNode(&node)); | 929 return createVisiblePosition(firstPositionInOrBeforeNode(&node)); |
| 930 ASSERT(node.parentNode()); | 930 ASSERT(node.parentNode()); |
| 931 ASSERT(!node.parentNode()->isShadowRoot()); | 931 ASSERT(!node.parentNode()->isShadowRoot()); |
| 932 return VisiblePosition(positionInParentBeforeNode(node)); | 932 return createVisiblePosition(positionInParentBeforeNode(node)); |
| 933 } | 933 } |
| 934 | 934 |
| 935 // Returns the visible position at the ending of a node | 935 // Returns the visible position at the ending of a node |
| 936 VisiblePosition visiblePositionAfterNode(Node& node) | 936 VisiblePosition visiblePositionAfterNode(Node& node) |
| 937 { | 937 { |
| 938 if (node.hasChildren()) | 938 if (node.hasChildren()) |
| 939 return VisiblePosition(lastPositionInOrAfterNode(&node)); | 939 return createVisiblePosition(lastPositionInOrAfterNode(&node)); |
| 940 ASSERT(node.parentNode()); | 940 ASSERT(node.parentNode()); |
| 941 ASSERT(!node.parentNode()->isShadowRoot()); | 941 ASSERT(!node.parentNode()->isShadowRoot()); |
| 942 return VisiblePosition(positionInParentAfterNode(node)); | 942 return createVisiblePosition(positionInParentAfterNode(node)); |
| 943 } | 943 } |
| 944 | 944 |
| 945 bool isHTMLListElement(Node* n) | 945 bool isHTMLListElement(Node* n) |
| 946 { | 946 { |
| 947 return (n && (isHTMLUListElement(*n) || isHTMLOListElement(*n) || isHTMLDLis
tElement(*n))); | 947 return (n && (isHTMLUListElement(*n) || isHTMLOListElement(*n) || isHTMLDLis
tElement(*n))); |
| 948 } | 948 } |
| 949 | 949 |
| 950 bool isListItem(const Node* n) | 950 bool isListItem(const Node* n) |
| 951 { | 951 { |
| 952 return n && n->layoutObject() && n->layoutObject()->isListItem(); | 952 return n && n->layoutObject() && n->layoutObject()->isListItem(); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 } | 1111 } |
| 1112 | 1112 |
| 1113 // FIXME: This method should not need to call isStartOfParagraph/isEndOfParagrap
h | 1113 // FIXME: This method should not need to call isStartOfParagraph/isEndOfParagrap
h |
| 1114 Node* enclosingEmptyListItem(const VisiblePosition& visiblePos) | 1114 Node* enclosingEmptyListItem(const VisiblePosition& visiblePos) |
| 1115 { | 1115 { |
| 1116 // Check that position is on a line by itself inside a list item | 1116 // Check that position is on a line by itself inside a list item |
| 1117 Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().anchorN
ode()); | 1117 Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().anchorN
ode()); |
| 1118 if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(v
isiblePos)) | 1118 if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(v
isiblePos)) |
| 1119 return 0; | 1119 return 0; |
| 1120 | 1120 |
| 1121 VisiblePosition firstInListChild(firstPositionInOrBeforeNode(listChildNode))
; | 1121 VisiblePosition firstInListChild = createVisiblePosition(firstPositionInOrBe
foreNode(listChildNode)); |
| 1122 VisiblePosition lastInListChild(lastPositionInOrAfterNode(listChildNode)); | 1122 VisiblePosition lastInListChild = createVisiblePosition(lastPositionInOrAfte
rNode(listChildNode)); |
| 1123 | 1123 |
| 1124 if (firstInListChild.deepEquivalent() != visiblePos.deepEquivalent() || last
InListChild.deepEquivalent() != visiblePos.deepEquivalent()) | 1124 if (firstInListChild.deepEquivalent() != visiblePos.deepEquivalent() || last
InListChild.deepEquivalent() != visiblePos.deepEquivalent()) |
| 1125 return 0; | 1125 return 0; |
| 1126 | 1126 |
| 1127 return listChildNode; | 1127 return listChildNode; |
| 1128 } | 1128 } |
| 1129 | 1129 |
| 1130 HTMLElement* outermostEnclosingList(Node* node, HTMLElement* rootList) | 1130 HTMLElement* outermostEnclosingList(Node* node, HTMLElement* rootList) |
| 1131 { | 1131 { |
| 1132 HTMLElement* list = enclosingList(node); | 1132 HTMLElement* list = enclosingList(node); |
| 1133 if (!list) | 1133 if (!list) |
| 1134 return 0; | 1134 return 0; |
| 1135 | 1135 |
| 1136 while (HTMLElement* nextList = enclosingList(list)) { | 1136 while (HTMLElement* nextList = enclosingList(list)) { |
| 1137 if (nextList == rootList) | 1137 if (nextList == rootList) |
| 1138 break; | 1138 break; |
| 1139 list = nextList; | 1139 list = nextList; |
| 1140 } | 1140 } |
| 1141 | 1141 |
| 1142 return list; | 1142 return list; |
| 1143 } | 1143 } |
| 1144 | 1144 |
| 1145 // Determines whether two positions are visibly next to each other (first then s
econd) | 1145 // Determines whether two positions are visibly next to each other (first then s
econd) |
| 1146 // while ignoring whitespaces and unrendered nodes | 1146 // while ignoring whitespaces and unrendered nodes |
| 1147 static bool isVisiblyAdjacent(const Position& first, const Position& second) | 1147 static bool isVisiblyAdjacent(const Position& first, const Position& second) |
| 1148 { | 1148 { |
| 1149 return VisiblePosition(first).deepEquivalent() == VisiblePosition(mostBackwa
rdCaretPosition(second)).deepEquivalent(); | 1149 return createVisiblePosition(first).deepEquivalent() == createVisiblePositio
n(mostBackwardCaretPosition(second)).deepEquivalent(); |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 bool canMergeLists(Element* firstList, Element* secondList) | 1152 bool canMergeLists(Element* firstList, Element* secondList) |
| 1153 { | 1153 { |
| 1154 if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList-
>isHTMLElement()) | 1154 if (!firstList || !secondList || !firstList->isHTMLElement() || !secondList-
>isHTMLElement()) |
| 1155 return false; | 1155 return false; |
| 1156 | 1156 |
| 1157 return firstList->hasTagName(secondList->tagQName()) // make sure the list t
ypes match (ol vs. ul) | 1157 return firstList->hasTagName(secondList->tagQName()) // make sure the list t
ypes match (ol vs. ul) |
| 1158 && firstList->hasEditableStyle() && secondList->hasEditableStyle() // both l
ists are editable | 1158 && firstList->hasEditableStyle() && secondList->hasEditableStyle() // both l
ists are editable |
| 1159 && firstList->rootEditableElement() == secondList->rootEditableElement() //
don't cross editing boundaries | 1159 && firstList->rootEditableElement() == secondList->rootEditableElement() //
don't cross editing boundaries |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 } | 1309 } |
| 1310 | 1310 |
| 1311 // return first preceding DOM position rendered at a different location, or "thi
s" | 1311 // return first preceding DOM position rendered at a different location, or "thi
s" |
| 1312 static Position previousCharacterPosition(const Position& position, TextAffinity
affinity) | 1312 static Position previousCharacterPosition(const Position& position, TextAffinity
affinity) |
| 1313 { | 1313 { |
| 1314 if (position.isNull()) | 1314 if (position.isNull()) |
| 1315 return Position(); | 1315 return Position(); |
| 1316 | 1316 |
| 1317 Element* fromRootEditableElement = position.anchorNode()->rootEditableElemen
t(); | 1317 Element* fromRootEditableElement = position.anchorNode()->rootEditableElemen
t(); |
| 1318 | 1318 |
| 1319 bool atStartOfLine = isStartOfLine(VisiblePosition(position, affinity)); | 1319 bool atStartOfLine = isStartOfLine(createVisiblePosition(position, affinity)
); |
| 1320 bool rendered = isVisuallyEquivalentCandidate(position); | 1320 bool rendered = isVisuallyEquivalentCandidate(position); |
| 1321 | 1321 |
| 1322 Position currentPos = position; | 1322 Position currentPos = position; |
| 1323 while (!currentPos.atStartOfTree()) { | 1323 while (!currentPos.atStartOfTree()) { |
| 1324 // TODO(yosin) When we use |previousCharacterPosition()| other than | 1324 // TODO(yosin) When we use |previousCharacterPosition()| other than |
| 1325 // finding leading whitespace, we should use |Character| instead of | 1325 // finding leading whitespace, we should use |Character| instead of |
| 1326 // |CodePoint|. | 1326 // |CodePoint|. |
| 1327 currentPos = previousPositionOf(currentPos, PositionMoveType::CodePoint)
; | 1327 currentPos = previousPositionOf(currentPos, PositionMoveType::CodePoint)
; |
| 1328 | 1328 |
| 1329 if (currentPos.anchorNode()->rootEditableElement() != fromRootEditableEl
ement) | 1329 if (currentPos.anchorNode()->rootEditableElement() != fromRootEditableEl
ement) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 return Position(); | 1362 return Position(); |
| 1363 } | 1363 } |
| 1364 | 1364 |
| 1365 // This assumes that it starts in editable content. | 1365 // This assumes that it starts in editable content. |
| 1366 Position trailingWhitespacePosition(const Position& position, TextAffinity, Whit
espacePositionOption option) | 1366 Position trailingWhitespacePosition(const Position& position, TextAffinity, Whit
espacePositionOption option) |
| 1367 { | 1367 { |
| 1368 ASSERT(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)); | 1368 ASSERT(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)); |
| 1369 if (position.isNull()) | 1369 if (position.isNull()) |
| 1370 return Position(); | 1370 return Position(); |
| 1371 | 1371 |
| 1372 VisiblePosition visiblePosition(position); | 1372 VisiblePosition visiblePosition = createVisiblePosition(position); |
| 1373 UChar characterAfterVisiblePosition = characterAfter(visiblePosition); | 1373 UChar characterAfterVisiblePosition = characterAfter(visiblePosition); |
| 1374 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNewlin
e(characterAfterVisiblePosition) || characterAfterVisiblePosition == noBreakSpac
eCharacter) : isCollapsibleWhitespace(characterAfterVisiblePosition); | 1374 bool isSpace = option == ConsiderNonCollapsibleWhitespace ? (isSpaceOrNewlin
e(characterAfterVisiblePosition) || characterAfterVisiblePosition == noBreakSpac
eCharacter) : isCollapsibleWhitespace(characterAfterVisiblePosition); |
| 1375 // The space must not be in another paragraph and it must be editable. | 1375 // The space must not be in another paragraph and it must be editable. |
| 1376 if (isSpace && !isEndOfParagraph(visiblePosition) && nextPositionOf(visibleP
osition, CannotCrossEditingBoundary).isNotNull()) | 1376 if (isSpace && !isEndOfParagraph(visiblePosition) && nextPositionOf(visibleP
osition, CannotCrossEditingBoundary).isNotNull()) |
| 1377 return position; | 1377 return position; |
| 1378 return Position(); | 1378 return Position(); |
| 1379 } | 1379 } |
| 1380 | 1380 |
| 1381 unsigned numEnclosingMailBlockquotes(const Position& p) | 1381 unsigned numEnclosingMailBlockquotes(const Position& p) |
| 1382 { | 1382 { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope) | 1561 VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope) |
| 1562 { | 1562 { |
| 1563 if (!scope) | 1563 if (!scope) |
| 1564 return VisiblePosition(); | 1564 return VisiblePosition(); |
| 1565 EphemeralRange range = PlainTextRange(index).createRangeForSelection(*scope)
; | 1565 EphemeralRange range = PlainTextRange(index).createRangeForSelection(*scope)
; |
| 1566 // Check for an invalid index. Certain editing operations invalidate indices | 1566 // Check for an invalid index. Certain editing operations invalidate indices |
| 1567 // because of problems with | 1567 // because of problems with |
| 1568 // TextIteratorEmitsCharactersBetweenAllVisiblePositions. | 1568 // TextIteratorEmitsCharactersBetweenAllVisiblePositions. |
| 1569 if (range.isNull()) | 1569 if (range.isNull()) |
| 1570 return VisiblePosition(); | 1570 return VisiblePosition(); |
| 1571 return VisiblePosition(range.startPosition()); | 1571 return createVisiblePosition(range.startPosition()); |
| 1572 } | 1572 } |
| 1573 | 1573 |
| 1574 // Determines whether a node is inside a range or visibly starts and ends at the
boundaries of the range. | 1574 // Determines whether a node is inside a range or visibly starts and ends at the
boundaries of the range. |
| 1575 // Call this function to determine whether a node is visibly fit inside selected
Range | 1575 // Call this function to determine whether a node is visibly fit inside selected
Range |
| 1576 bool isNodeVisiblyContainedWithin(Node& node, const Range& selectedRange) | 1576 bool isNodeVisiblyContainedWithin(Node& node, const Range& selectedRange) |
| 1577 { | 1577 { |
| 1578 if (selectedRange.isNodeFullyContained(node)) | 1578 if (selectedRange.isNodeFullyContained(node)) |
| 1579 return true; | 1579 return true; |
| 1580 | 1580 |
| 1581 bool startIsVisuallySame = visiblePositionBeforeNode(node).deepEquivalent()
== VisiblePosition(selectedRange.startPosition()).deepEquivalent(); | 1581 bool startIsVisuallySame = visiblePositionBeforeNode(node).deepEquivalent()
== createVisiblePosition(selectedRange.startPosition()).deepEquivalent(); |
| 1582 if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node),
selectedRange.endPosition()) < 0) | 1582 if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node),
selectedRange.endPosition()) < 0) |
| 1583 return true; | 1583 return true; |
| 1584 | 1584 |
| 1585 bool endIsVisuallySame = visiblePositionAfterNode(node).deepEquivalent() ==
VisiblePosition(selectedRange.endPosition()).deepEquivalent(); | 1585 bool endIsVisuallySame = visiblePositionAfterNode(node).deepEquivalent() ==
createVisiblePosition(selectedRange.endPosition()).deepEquivalent(); |
| 1586 if (endIsVisuallySame && comparePositions(selectedRange.startPosition(), pos
itionInParentBeforeNode(node)) < 0) | 1586 if (endIsVisuallySame && comparePositions(selectedRange.startPosition(), pos
itionInParentBeforeNode(node)) < 0) |
| 1587 return true; | 1587 return true; |
| 1588 | 1588 |
| 1589 return startIsVisuallySame && endIsVisuallySame; | 1589 return startIsVisuallySame && endIsVisuallySame; |
| 1590 } | 1590 } |
| 1591 | 1591 |
| 1592 bool isRenderedAsNonInlineTableImageOrHR(const Node* node) | 1592 bool isRenderedAsNonInlineTableImageOrHR(const Node* node) |
| 1593 { | 1593 { |
| 1594 if (!node) | 1594 if (!node) |
| 1595 return false; | 1595 return false; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1635 return node.isElementNode() && layoutObject && layoutObject->isLayoutBlockFl
ow(); | 1635 return node.isElementNode() && layoutObject && layoutObject->isLayoutBlockFl
ow(); |
| 1636 } | 1636 } |
| 1637 | 1637 |
| 1638 Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selec
tion) | 1638 Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selec
tion) |
| 1639 { | 1639 { |
| 1640 // This function is used by range style computations to avoid bugs like: | 1640 // This function is used by range style computations to avoid bugs like: |
| 1641 // <rdar://problem/4017641> REGRESSION (Mail): you can only bold/unbold a se
lection starting from end of line once | 1641 // <rdar://problem/4017641> REGRESSION (Mail): you can only bold/unbold a se
lection starting from end of line once |
| 1642 // It is important to skip certain irrelevant content at the start of the se
lection, so we do not wind up | 1642 // It is important to skip certain irrelevant content at the start of the se
lection, so we do not wind up |
| 1643 // with a spurious "mixed" style. | 1643 // with a spurious "mixed" style. |
| 1644 | 1644 |
| 1645 VisiblePosition visiblePosition(selection.start()); | 1645 VisiblePosition visiblePosition = createVisiblePosition(selection.start()); |
| 1646 if (visiblePosition.isNull()) | 1646 if (visiblePosition.isNull()) |
| 1647 return Position(); | 1647 return Position(); |
| 1648 | 1648 |
| 1649 // if the selection is a caret, just return the position, since the style | 1649 // if the selection is a caret, just return the position, since the style |
| 1650 // behind us is relevant | 1650 // behind us is relevant |
| 1651 if (selection.isCaret()) | 1651 if (selection.isCaret()) |
| 1652 return visiblePosition.deepEquivalent(); | 1652 return visiblePosition.deepEquivalent(); |
| 1653 | 1653 |
| 1654 // if the selection starts just before a paragraph break, skip over it | 1654 // if the selection starts just before a paragraph break, skip over it |
| 1655 if (isEndOfParagraph(visiblePosition)) | 1655 if (isEndOfParagraph(visiblePosition)) |
| 1656 return mostForwardCaretPosition(nextPositionOf(visiblePosition).deepEqui
valent()); | 1656 return mostForwardCaretPosition(nextPositionOf(visiblePosition).deepEqui
valent()); |
| 1657 | 1657 |
| 1658 // otherwise, make sure to be at the start of the first selected node, | 1658 // otherwise, make sure to be at the start of the first selected node, |
| 1659 // instead of possibly at the end of the last node before the selection | 1659 // instead of possibly at the end of the last node before the selection |
| 1660 return mostForwardCaretPosition(visiblePosition.deepEquivalent()); | 1660 return mostForwardCaretPosition(visiblePosition.deepEquivalent()); |
| 1661 } | 1661 } |
| 1662 | 1662 |
| 1663 } // namespace blink | 1663 } // namespace blink |
| OLD | NEW |