OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 */ | 25 */ |
26 | 26 |
27 #include "config.h" | 27 #include "config.h" |
28 #include "core/editing/ReplaceSelectionCommand.h" | 28 #include "core/editing/commands/ReplaceSelectionCommand.h" |
29 | 29 |
30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
31 #include "core/CSSPropertyNames.h" | 31 #include "core/CSSPropertyNames.h" |
32 #include "core/HTMLNames.h" | 32 #include "core/HTMLNames.h" |
33 #include "core/InputTypeNames.h" | 33 #include "core/InputTypeNames.h" |
34 #include "core/css/CSSStyleDeclaration.h" | 34 #include "core/css/CSSStyleDeclaration.h" |
35 #include "core/css/StylePropertySet.h" | 35 #include "core/css/StylePropertySet.h" |
36 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
37 #include "core/dom/DocumentFragment.h" | 37 #include "core/dom/DocumentFragment.h" |
38 #include "core/dom/Element.h" | 38 #include "core/dom/Element.h" |
39 #include "core/dom/Text.h" | 39 #include "core/dom/Text.h" |
40 #include "core/editing/ApplyStyleCommand.h" | |
41 #include "core/editing/BreakBlockquoteCommand.h" | |
42 #include "core/editing/EditingUtilities.h" | 40 #include "core/editing/EditingUtilities.h" |
43 #include "core/editing/FrameSelection.h" | 41 #include "core/editing/FrameSelection.h" |
44 #include "core/editing/SimplifyMarkupCommand.h" | |
45 #include "core/editing/SmartReplace.h" | |
46 #include "core/editing/VisibleUnits.h" | 42 #include "core/editing/VisibleUnits.h" |
| 43 #include "core/editing/commands/ApplyStyleCommand.h" |
| 44 #include "core/editing/commands/BreakBlockquoteCommand.h" |
| 45 #include "core/editing/commands/SimplifyMarkupCommand.h" |
| 46 #include "core/editing/commands/SmartReplace.h" |
47 #include "core/editing/iterators/TextIterator.h" | 47 #include "core/editing/iterators/TextIterator.h" |
48 #include "core/editing/serializers/HTMLInterchange.h" | 48 #include "core/editing/serializers/HTMLInterchange.h" |
49 #include "core/editing/serializers/Serialization.h" | 49 #include "core/editing/serializers/Serialization.h" |
50 #include "core/events/BeforeTextInsertedEvent.h" | 50 #include "core/events/BeforeTextInsertedEvent.h" |
51 #include "core/frame/LocalFrame.h" | 51 #include "core/frame/LocalFrame.h" |
52 #include "core/frame/UseCounter.h" | 52 #include "core/frame/UseCounter.h" |
53 #include "core/html/HTMLBRElement.h" | 53 #include "core/html/HTMLBRElement.h" |
54 #include "core/html/HTMLElement.h" | 54 #include "core/html/HTMLElement.h" |
55 #include "core/html/HTMLInputElement.h" | 55 #include "core/html/HTMLInputElement.h" |
56 #include "core/html/HTMLLIElement.h" | 56 #include "core/html/HTMLLIElement.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 139 |
140 if (nextPosition == pos | 140 if (nextPosition == pos |
141 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement | 141 || enclosingBlock(nextPosition.computeContainerNode()) != enclosingB
lockElement |
142 || VisiblePosition(pos).deepEquivalent() != VisiblePosition(nextPosi
tion).deepEquivalent()) | 142 || VisiblePosition(pos).deepEquivalent() != VisiblePosition(nextPosi
tion).deepEquivalent()) |
143 break; | 143 break; |
144 } | 144 } |
145 return pos; | 145 return pos; |
146 } | 146 } |
147 | 147 |
148 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) | 148 ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
ragment, const VisibleSelection& selection) |
149 : m_document(document), | 149 : m_document(document) |
150 m_fragment(fragment), | 150 , m_fragment(fragment) |
151 m_hasInterchangeNewlineAtStart(false), | 151 , m_hasInterchangeNewlineAtStart(false) |
152 m_hasInterchangeNewlineAtEnd(false) | 152 , m_hasInterchangeNewlineAtEnd(false) |
153 { | 153 { |
154 if (!m_document) | 154 if (!m_document) |
155 return; | 155 return; |
156 if (!m_fragment || !m_fragment->hasChildren()) | 156 if (!m_fragment || !m_fragment->hasChildren()) |
157 return; | 157 return; |
158 | 158 |
159 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement(); | 159 RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement(); |
160 ASSERT(editableRoot); | 160 ASSERT(editableRoot); |
161 if (!editableRoot) | 161 if (!editableRoot) |
162 return; | 162 return; |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an
chorNode()); | 852 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().an
chorNode()); |
853 destination = VisiblePosition(positionBeforeNode(placeholder.get())); | 853 destination = VisiblePosition(positionBeforeNode(placeholder.get())); |
854 } | 854 } |
855 | 855 |
856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); | 856 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); |
857 | 857 |
858 // Merging forward will remove m_endOfInsertedContent from the document. | 858 // Merging forward will remove m_endOfInsertedContent from the document. |
859 if (mergeForward) { | 859 if (mergeForward) { |
860 if (m_startOfInsertedContent.isOrphan()) | 860 if (m_startOfInsertedContent.isOrphan()) |
861 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); | 861 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); |
862 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent(
); | 862 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivalent()
; |
863 // If we merged text nodes, m_endOfInsertedContent could be null. If thi
s is the case, we use m_startOfInsertedContent. | 863 // If we merged text nodes, m_endOfInsertedContent could be null. If thi
s is the case, we use m_startOfInsertedContent. |
864 if (m_endOfInsertedContent.isNull()) | 864 if (m_endOfInsertedContent.isNull()) |
865 m_endOfInsertedContent = m_startOfInsertedContent; | 865 m_endOfInsertedContent = m_startOfInsertedContent; |
866 } | 866 } |
867 } | 867 } |
868 | 868 |
869 static Node* enclosingInline(Node* node) | 869 static Node* enclosingInline(Node* node) |
870 { | 870 { |
871 while (ContainerNode* parent = node->parentNode()) { | 871 while (ContainerNode* parent = node->parentNode()) { |
872 if (isBlockFlowElement(*parent) || isHTMLBodyElement(*parent)) | 872 if (isBlockFlowElement(*parent) || isHTMLBodyElement(*parent)) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); | 947 bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); |
948 bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); | 948 bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); |
949 | 949 |
950 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui
valent().anchorNode()); | 950 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui
valent().anchorNode()); |
951 | 951 |
952 Position insertionPos = selection.start(); | 952 Position insertionPos = selection.start(); |
953 bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailH
TMLBlockquoteElement, CanCrossEditingBoundary); | 953 bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailH
TMLBlockquoteElement, CanCrossEditingBoundary); |
954 bool selectionIsPlainText = !selection.isContentRichlyEditable(); | 954 bool selectionIsPlainText = !selection.isContentRichlyEditable(); |
955 Element* currentRoot = selection.rootEditableElement(); | 955 Element* currentRoot = selection.rootEditableElement(); |
956 | 956 |
957 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !
startIsInsideMailBlockquote) || | 957 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !
startIsInsideMailBlockquote) |
958 enclosingBlockOfVisibleStart == currentRoot || isListItem(enclosingBlock
OfVisibleStart) || selectionIsPlainText) | 958 || enclosingBlockOfVisibleStart == currentRoot |
| 959 || isListItem(enclosingBlockOfVisibleStart) |
| 960 || selectionIsPlainText) { |
959 m_preventNesting = false; | 961 m_preventNesting = false; |
| 962 } |
960 | 963 |
961 if (selection.isRange()) { | 964 if (selection.isRange()) { |
962 // When the end of the selection being pasted into is at the end of a pa
ragraph, and that selection | 965 // When the end of the selection being pasted into is at the end of a pa
ragraph, and that selection |
963 // spans multiple blocks, not merging may leave an empty line. | 966 // spans multiple blocks, not merging may leave an empty line. |
964 // When the start of the selection being pasted into is at the start of
a block, not merging | 967 // When the start of the selection being pasted into is at the start of
a block, not merging |
965 // will leave hanging block(s). | 968 // will leave hanging block(s). |
966 // Merge blocks if the start of the selection was in a Mail blockquote,
since we handle | 969 // Merge blocks if the start of the selection was in a Mail blockquote,
since we handle |
967 // that case specially to prevent nesting. | 970 // that case specially to prevent nesting. |
968 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara
graph(visibleEnd) || isStartOfBlock(visibleStart); | 971 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara
graph(visibleEnd) || isStartOfBlock(visibleStart); |
969 // FIXME: We should only expand to include fully selected special elemen
ts if we are copying a | 972 // FIXME: We should only expand to include fully selected special elemen
ts if we are copying a |
970 // selection and pasting it on top of itself. | 973 // selection and pasting it on top of itself. |
971 deleteSelection(false, mergeBlocksAfterDelete, false); | 974 deleteSelection(false, mergeBlocksAfterDelete, false); |
972 visibleStart = endingSelection().visibleStart(); | 975 visibleStart = endingSelection().visibleStart(); |
973 if (fragment.hasInterchangeNewlineAtStart()) { | 976 if (fragment.hasInterchangeNewlineAtStart()) { |
974 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt)) { | 977 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt)) { |
975 if (!isEndOfEditableOrNonEditableContent(visibleStart)) | 978 if (!isEndOfEditableOrNonEditableContent(visibleStart)) |
976 setEndingSelection(visibleStart.next()); | 979 setEndingSelection(visibleStart.next()); |
977 } else | 980 } else { |
978 insertParagraphSeparator(); | 981 insertParagraphSeparator(); |
| 982 } |
979 } | 983 } |
980 insertionPos = endingSelection().start(); | 984 insertionPos = endingSelection().start(); |
981 } else { | 985 } else { |
982 ASSERT(selection.isCaret()); | 986 ASSERT(selection.isCaret()); |
983 if (fragment.hasInterchangeNewlineAtStart()) { | 987 if (fragment.hasInterchangeNewlineAtStart()) { |
984 VisiblePosition next = visibleStart.next(CannotCrossEditingBoundary)
; | 988 VisiblePosition next = visibleStart.next(CannotCrossEditingBoundary)
; |
985 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt) && next.isNotNull()) | 989 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta
rt) && next.isNotNull()) { |
986 setEndingSelection(next); | 990 setEndingSelection(next); |
987 else { | 991 } else { |
988 insertParagraphSeparator(); | 992 insertParagraphSeparator(); |
989 visibleStart = endingSelection().visibleStart(); | 993 visibleStart = endingSelection().visibleStart(); |
990 } | 994 } |
991 } | 995 } |
992 // We split the current paragraph in two to avoid nesting the blocks fro
m the fragment inside the current block. | 996 // We split the current paragraph in two to avoid nesting the blocks fro
m the fragment inside the current block. |
993 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di
v>x^x</div>, where ^ is the caret. | 997 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di
v>x^x</div>, where ^ is the caret. |
994 // As long as the div styles are the same, visually you'd expect: <div>
xbar</div><div>bar</div><div>bazx</div>, | 998 // As long as the div styles are the same, visually you'd expect: <div>
xbar</div><div>bar</div><div>bazx</div>, |
995 // not <div>xbar<div>bar</div><div>bazx</div></div>. | 999 // not <div>xbar<div>bar</div><div>bazx</div></div>. |
996 // Don't do this if the selection started in a Mail blockquote. | 1000 // Don't do this if the selection started in a Mail blockquote. |
997 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap
h(visibleStart) && !isStartOfParagraph(visibleStart)) { | 1001 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap
h(visibleStart) && !isStartOfParagraph(visibleStart)) { |
(...skipping 14 matching lines...) Expand all Loading... |
1012 // Insert content between the two blockquotes, but remove the br (since
it was just a placeholder). | 1016 // Insert content between the two blockquotes, but remove the br (since
it was just a placeholder). |
1013 insertionPos = positionInParentBeforeNode(*br); | 1017 insertionPos = positionInParentBeforeNode(*br); |
1014 removeNode(br); | 1018 removeNode(br); |
1015 } | 1019 } |
1016 | 1020 |
1017 // Inserting content could cause whitespace to collapse, e.g. inserting <div
>foo</div> into hello^ world. | 1021 // Inserting content could cause whitespace to collapse, e.g. inserting <div
>foo</div> into hello^ world. |
1018 prepareWhitespaceAtPositionForSplit(insertionPos); | 1022 prepareWhitespaceAtPositionForSplit(insertionPos); |
1019 | 1023 |
1020 // If the downstream node has been removed there's no point in continuing. | 1024 // If the downstream node has been removed there's no point in continuing. |
1021 if (!insertionPos.downstream().anchorNode()) | 1025 if (!insertionPos.downstream().anchorNode()) |
1022 return; | 1026 return; |
1023 | 1027 |
1024 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after | 1028 // NOTE: This would be an incorrect usage of downstream() if downstream() we
re changed to mean the last position after |
1025 // p that maps to the same visible position as p (since in the case where a
br is at the end of a block and collapsed | 1029 // p that maps to the same visible position as p (since in the case where a
br is at the end of a block and collapsed |
1026 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). | 1030 // away, there are positions after the br which map to the same visible posi
tion as [br, 0]). |
1027 HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().anchorNode
()) ? toHTMLBRElement(insertionPos.downstream().anchorNode()) : 0; | 1031 HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().anchorNode
()) ? toHTMLBRElement(insertionPos.downstream().anchorNode()) : 0; |
1028 VisiblePosition originalVisPosBeforeEndBR; | 1032 VisiblePosition originalVisPosBeforeEndBR; |
1029 if (endBR) | 1033 if (endBR) |
1030 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D
OWNSTREAM).previous(); | 1034 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D
OWNSTREAM).previous(); |
1031 | 1035 |
1032 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in
sertionPos.anchorNode()); | 1036 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in
sertionPos.anchorNode()); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 | 1108 |
1105 InsertedNodes insertedNodes; | 1109 InsertedNodes insertedNodes; |
1106 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); | 1110 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); |
1107 ASSERT(refNode); | 1111 ASSERT(refNode); |
1108 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); | 1112 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); |
1109 | 1113 |
1110 fragment.removeNode(refNode); | 1114 fragment.removeNode(refNode); |
1111 | 1115 |
1112 Element* blockStart = enclosingBlock(insertionPos.anchorNode()); | 1116 Element* blockStart = enclosingBlock(insertionPos.anchorNode()); |
1113 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo
de.get()) && isHTMLListElement(refNode->firstChild()))) | 1117 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo
de.get()) && isHTMLListElement(refNode->firstChild()))) |
1114 && blockStart && blockStart->layoutObject()->isListItem()) | 1118 && blockStart && blockStart->layoutObject()->isListItem()) { |
1115 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio
nPos, insertedNodes); | 1119 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio
nPos, insertedNodes); |
1116 else { | 1120 } else { |
1117 insertNodeAt(refNode, insertionPos); | 1121 insertNodeAt(refNode, insertionPos); |
1118 insertedNodes.respondToNodeInsertion(*refNode); | 1122 insertedNodes.respondToNodeInsertion(*refNode); |
1119 } | 1123 } |
1120 | 1124 |
1121 // Mutation events (bug 22634) may have already removed the inserted content | 1125 // Mutation events (bug 22634) may have already removed the inserted content |
1122 if (!refNode->inDocument()) | 1126 if (!refNode->inDocument()) |
1123 return; | 1127 return; |
1124 | 1128 |
1125 bool plainTextFragment = isPlainTextMarkup(refNode.get()); | 1129 bool plainTextFragment = isPlainTextMarkup(refNode.get()); |
1126 | 1130 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 | 1373 |
1370 if (m_matchStyle) { | 1374 if (m_matchStyle) { |
1371 ASSERT(m_insertionStyle); | 1375 ASSERT(m_insertionStyle); |
1372 applyStyle(m_insertionStyle.get(), start, end); | 1376 applyStyle(m_insertionStyle.get(), start, end); |
1373 } | 1377 } |
1374 | 1378 |
1375 if (lastPositionToSelect.isNotNull()) | 1379 if (lastPositionToSelect.isNotNull()) |
1376 end = lastPositionToSelect; | 1380 end = lastPositionToSelect; |
1377 | 1381 |
1378 mergeTextNodesAroundPosition(start, end); | 1382 mergeTextNodesAroundPosition(start, end); |
1379 } else if (lastPositionToSelect.isNotNull()) | 1383 } else if (lastPositionToSelect.isNotNull()) { |
1380 start = end = lastPositionToSelect; | 1384 start = end = lastPositionToSelect; |
1381 else | 1385 } else { |
1382 return; | 1386 return; |
| 1387 } |
1383 | 1388 |
1384 if (m_selectReplacement) | 1389 if (m_selectReplacement) |
1385 setEndingSelection(VisibleSelection(start, end, SEL_DEFAULT_AFFINITY, en
dingSelection().isDirectional())); | 1390 setEndingSelection(VisibleSelection(start, end, SEL_DEFAULT_AFFINITY, en
dingSelection().isDirectional())); |
1386 else | 1391 else |
1387 setEndingSelection(VisibleSelection(end, SEL_DEFAULT_AFFINITY, endingSel
ection().isDirectional())); | 1392 setEndingSelection(VisibleSelection(end, SEL_DEFAULT_AFFINITY, endingSel
ection().isDirectional())); |
1388 } | 1393 } |
1389 | 1394 |
1390 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P
osition& positionOnlyToBeUpdated) | 1395 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P
osition& positionOnlyToBeUpdated) |
1391 { | 1396 { |
1392 bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); | 1397 bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); |
1393 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff
setInAnchor(); | 1398 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff
setInAnchor(); |
1394 RefPtrWillBeRawPtr<Text> text = nullptr; | 1399 RefPtrWillBeRawPtr<Text> text = nullptr; |
1395 if (positionIsOffsetInAnchor && position.computeContainerNode() && position.
computeContainerNode()->isTextNode()) | 1400 if (positionIsOffsetInAnchor && position.computeContainerNode() && position.
computeContainerNode()->isTextNode()) { |
1396 text = toText(position.computeContainerNode()); | 1401 text = toText(position.computeContainerNode()); |
1397 else { | 1402 } else { |
1398 Node* before = position.computeNodeBeforePosition(); | 1403 Node* before = position.computeNodeBeforePosition(); |
1399 if (before && before->isTextNode()) | 1404 if (before && before->isTextNode()) { |
1400 text = toText(before); | 1405 text = toText(before); |
1401 else { | 1406 } else { |
1402 Node* after = position.computeNodeAfterPosition(); | 1407 Node* after = position.computeNodeAfterPosition(); |
1403 if (after && after->isTextNode()) | 1408 if (after && after->isTextNode()) |
1404 text = toText(after); | 1409 text = toText(after); |
1405 } | 1410 } |
1406 } | 1411 } |
1407 if (!text) | 1412 if (!text) |
1408 return; | 1413 return; |
1409 | 1414 |
1410 if (text->previousSibling() && text->previousSibling()->isTextNode()) { | 1415 if (text->previousSibling() && text->previousSibling()->isTextNode()) { |
1411 RefPtrWillBeRawPtr<Text> previous = toText(text->previousSibling()); | 1416 RefPtrWillBeRawPtr<Text> previous = toText(text->previousSibling()); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1474 | 1479 |
1475 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) { | 1480 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) { |
1476 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); | 1481 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); |
1477 if (isStart || isMiddle) { | 1482 if (isStart || isMiddle) { |
1478 insertNodeBefore(listItem, lastNode); | 1483 insertNodeBefore(listItem, lastNode); |
1479 insertedNodes.respondToNodeInsertion(*listItem); | 1484 insertedNodes.respondToNodeInsertion(*listItem); |
1480 } else if (isEnd) { | 1485 } else if (isEnd) { |
1481 insertNodeAfter(listItem, lastNode); | 1486 insertNodeAfter(listItem, lastNode); |
1482 insertedNodes.respondToNodeInsertion(*listItem); | 1487 insertedNodes.respondToNodeInsertion(*listItem); |
1483 lastNode = listItem.get(); | 1488 lastNode = listItem.get(); |
1484 } else | 1489 } else { |
1485 ASSERT_NOT_REACHED(); | 1490 ASSERT_NOT_REACHED(); |
| 1491 } |
1486 } | 1492 } |
1487 if (isStart || isMiddle) { | 1493 if (isStart || isMiddle) { |
1488 if (Node* node = lastNode->previousSibling()) | 1494 if (Node* node = lastNode->previousSibling()) |
1489 return node; | 1495 return node; |
1490 } | 1496 } |
1491 return lastNode; | 1497 return lastNode; |
1492 } | 1498 } |
1493 | 1499 |
1494 void ReplaceSelectionCommand::updateNodesInserted(Node *node) | 1500 void ReplaceSelectionCommand::updateNodesInserted(Node *node) |
1495 { | 1501 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 DEFINE_TRACE(ReplaceSelectionCommand) | 1548 DEFINE_TRACE(ReplaceSelectionCommand) |
1543 { | 1549 { |
1544 visitor->trace(m_startOfInsertedContent); | 1550 visitor->trace(m_startOfInsertedContent); |
1545 visitor->trace(m_endOfInsertedContent); | 1551 visitor->trace(m_endOfInsertedContent); |
1546 visitor->trace(m_insertionStyle); | 1552 visitor->trace(m_insertionStyle); |
1547 visitor->trace(m_documentFragment); | 1553 visitor->trace(m_documentFragment); |
1548 CompositeEditCommand::trace(visitor); | 1554 CompositeEditCommand::trace(visitor); |
1549 } | 1555 } |
1550 | 1556 |
1551 } // namespace blink | 1557 } // namespace blink |
OLD | NEW |