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 |