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 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 | 238 |
239 ContainerNode* parent = refNode->nonShadowBoundaryParentNode(); | 239 ContainerNode* parent = refNode->nonShadowBoundaryParentNode(); |
240 if (!parent) | 240 if (!parent) |
241 return; | 241 return; |
242 | 242 |
243 parent->insertBefore(node, refNode); | 243 parent->insertBefore(node, refNode); |
244 } | 244 } |
245 | 245 |
246 PassRefPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* ro
otEditableElement) | 246 PassRefPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* ro
otEditableElement) |
247 { | 247 { |
248 RefPtr<Element> holder = createDefaultParagraphElement(m_document.get()); | 248 ASSERT(m_document); |
| 249 RefPtr<Element> holder = createDefaultParagraphElement(*m_document.get()); |
249 | 250 |
250 holder->appendChild(m_fragment); | 251 holder->appendChild(m_fragment); |
251 rootEditableElement->appendChild(holder.get()); | 252 rootEditableElement->appendChild(holder.get()); |
252 m_document->updateLayoutIgnorePendingStylesheets(); | 253 m_document->updateLayoutIgnorePendingStylesheets(); |
253 | 254 |
254 return holder.release(); | 255 return holder.release(); |
255 } | 256 } |
256 | 257 |
257 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element*
holder) | 258 void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element*
holder) |
258 { | 259 { |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 // include the what was the start of the selection that was pasted into, so
that we preserve that paragraph's | 812 // include the what was the start of the selection that was pasted into, so
that we preserve that paragraph's |
812 // block styles. | 813 // block styles. |
813 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC
ontent) && !isStartOfParagraph(startOfInsertedContent)); | 814 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC
ontent) && !isStartOfParagraph(startOfInsertedContent)); |
814 | 815 |
815 VisiblePosition destination = mergeForward ? endOfInsertedContent.next() : e
ndOfInsertedContent; | 816 VisiblePosition destination = mergeForward ? endOfInsertedContent.next() : e
ndOfInsertedContent; |
816 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end
OfInsertedContent) : endOfInsertedContent.next(); | 817 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end
OfInsertedContent) : endOfInsertedContent.next(); |
817 | 818 |
818 // Merging forward could result in deleting the destination anchor node. | 819 // Merging forward could result in deleting the destination anchor node. |
819 // To avoid this, we add a placeholder node before the start of the paragrap
h. | 820 // To avoid this, we add a placeholder node before the start of the paragrap
h. |
820 if (endOfParagraph(startOfParagraphToMove) == destination) { | 821 if (endOfParagraph(startOfParagraphToMove) == destination) { |
821 RefPtr<Node> placeholder = createBreakElement(&document()); | 822 RefPtr<Node> placeholder = createBreakElement(document()); |
822 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().de
precatedNode()); | 823 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().de
precatedNode()); |
823 destination = VisiblePosition(positionBeforeNode(placeholder.get())); | 824 destination = VisiblePosition(positionBeforeNode(placeholder.get())); |
824 } | 825 } |
825 | 826 |
826 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); | 827 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove)
, destination); |
827 | 828 |
828 // Merging forward will remove m_endOfInsertedContent from the document. | 829 // Merging forward will remove m_endOfInsertedContent from the document. |
829 if (mergeForward) { | 830 if (mergeForward) { |
830 if (m_startOfInsertedContent.isOrphan()) | 831 if (m_startOfInsertedContent.isOrphan()) |
831 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); | 832 m_startOfInsertedContent = endingSelection().visibleStart().deepEqui
valent(); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 | 1109 |
1109 // Mutation events (bug 20161) may have already removed the inserted content | 1110 // Mutation events (bug 20161) may have already removed the inserted content |
1110 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()
->inDocument()) | 1111 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()
->inDocument()) |
1111 return; | 1112 return; |
1112 | 1113 |
1113 VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(inserte
dNodes.firstNodeInserted()); | 1114 VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(inserte
dNodes.firstNodeInserted()); |
1114 | 1115 |
1115 // We inserted before the startBlock to prevent nesting, and the content bef
ore the startBlock wasn't in its own block and | 1116 // We inserted before the startBlock to prevent nesting, and the content bef
ore the startBlock wasn't in its own block and |
1116 // didn't have a br after it, so the inserted content ended up in the same p
aragraph. | 1117 // didn't have a br after it, so the inserted content ended up in the same p
aragraph. |
1117 if (startBlock && insertionPos.deprecatedNode() == startBlock->parentNode()
&& (unsigned)insertionPos.deprecatedEditingOffset() < startBlock->nodeIndex() &&
!isStartOfParagraph(startOfInsertedContent)) | 1118 if (startBlock && insertionPos.deprecatedNode() == startBlock->parentNode()
&& (unsigned)insertionPos.deprecatedEditingOffset() < startBlock->nodeIndex() &&
!isStartOfParagraph(startOfInsertedContent)) |
1118 insertNodeAt(createBreakElement(&document()).get(), startOfInsertedConte
nt.deepEquivalent()); | 1119 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten
t.deepEquivalent()); |
1119 | 1120 |
1120 if (endBR && (plainTextFragment || shouldRemoveEndBR(endBR, originalVisPosBe
foreEndBR))) { | 1121 if (endBR && (plainTextFragment || shouldRemoveEndBR(endBR, originalVisPosBe
foreEndBR))) { |
1121 RefPtr<Node> parent = endBR->parentNode(); | 1122 RefPtr<Node> parent = endBR->parentNode(); |
1122 insertedNodes.willRemoveNode(endBR); | 1123 insertedNodes.willRemoveNode(endBR); |
1123 removeNode(endBR); | 1124 removeNode(endBR); |
1124 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { | 1125 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { |
1125 insertedNodes.willRemoveNode(nodeToRemove); | 1126 insertedNodes.willRemoveNode(nodeToRemove); |
1126 removeNode(nodeToRemove); | 1127 removeNode(nodeToRemove); |
1127 } | 1128 } |
1128 } | 1129 } |
(...skipping 14 matching lines...) Expand all Loading... |
1143 m_shouldMergeEnd = shouldMergeEnd(selectionEndWasEndOfParagraph); | 1144 m_shouldMergeEnd = shouldMergeEnd(selectionEndWasEndOfParagraph); |
1144 | 1145 |
1145 if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasIntercha
ngeNewlineAtStart(), startIsInsideMailBlockquote)) { | 1146 if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasIntercha
ngeNewlineAtStart(), startIsInsideMailBlockquote)) { |
1146 VisiblePosition startOfParagraphToMove = positionAtStartOfInsertedConten
t(); | 1147 VisiblePosition startOfParagraphToMove = positionAtStartOfInsertedConten
t(); |
1147 VisiblePosition destination = startOfParagraphToMove.previous(); | 1148 VisiblePosition destination = startOfParagraphToMove.previous(); |
1148 // We need to handle the case where we need to merge the end | 1149 // We need to handle the case where we need to merge the end |
1149 // but our destination node is inside an inline that is the last in the
block. | 1150 // but our destination node is inside an inline that is the last in the
block. |
1150 // We insert a placeholder before the newly inserted content to avoid be
ing merged into the inline. | 1151 // We insert a placeholder before the newly inserted content to avoid be
ing merged into the inline. |
1151 Node* destinationNode = destination.deepEquivalent().deprecatedNode(); | 1152 Node* destinationNode = destination.deepEquivalent().deprecatedNode(); |
1152 if (m_shouldMergeEnd && destinationNode != enclosingInline(destinationNo
de) && enclosingInline(destinationNode)->nextSibling()) | 1153 if (m_shouldMergeEnd && destinationNode != enclosingInline(destinationNo
de) && enclosingInline(destinationNode)->nextSibling()) |
1153 insertNodeBefore(createBreakElement(&document()), refNode.get()); | 1154 insertNodeBefore(createBreakElement(document()), refNode.get()); |
1154 | 1155 |
1155 // Merging the the first paragraph of inserted content with the content
that came | 1156 // Merging the the first paragraph of inserted content with the content
that came |
1156 // before the selection that was pasted into would also move content aft
er | 1157 // before the selection that was pasted into would also move content aft
er |
1157 // the selection that was pasted into if: only one paragraph was being p
asted, | 1158 // the selection that was pasted into if: only one paragraph was being p
asted, |
1158 // and it was not wrapped in a block, the selection that was pasted into
ended | 1159 // and it was not wrapped in a block, the selection that was pasted into
ended |
1159 // at the end of a block and the next paragraph didn't start at the star
t of a block. | 1160 // at the end of a block and the next paragraph didn't start at the star
t of a block. |
1160 // Insert a line break just after the inserted content to separate it fr
om what | 1161 // Insert a line break just after the inserted content to separate it fr
om what |
1161 // comes after and prevent that from happening. | 1162 // comes after and prevent that from happening. |
1162 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); | 1163 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); |
1163 if (startOfParagraph(endOfInsertedContent) == startOfParagraphToMove) { | 1164 if (startOfParagraph(endOfInsertedContent) == startOfParagraphToMove) { |
1164 insertNodeAt(createBreakElement(&document()).get(), endOfInsertedCon
tent.deepEquivalent()); | 1165 insertNodeAt(createBreakElement(document()).get(), endOfInsertedCont
ent.deepEquivalent()); |
1165 // Mutation events (bug 22634) triggered by inserting the <br> might
have removed the content we're about to move | 1166 // Mutation events (bug 22634) triggered by inserting the <br> might
have removed the content we're about to move |
1166 if (!startOfParagraphToMove.deepEquivalent().anchorNode()->inDocumen
t()) | 1167 if (!startOfParagraphToMove.deepEquivalent().anchorNode()->inDocumen
t()) |
1167 return; | 1168 return; |
1168 } | 1169 } |
1169 | 1170 |
1170 // FIXME: Maintain positions for the start and end of inserted content i
nstead of keeping nodes. The nodes are | 1171 // FIXME: Maintain positions for the start and end of inserted content i
nstead of keeping nodes. The nodes are |
1171 // only ever used to create positions where inserted content starts/ends
. | 1172 // only ever used to create positions where inserted content starts/ends
. |
1172 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToM
ove), destination); | 1173 moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToM
ove), destination); |
1173 m_startOfInsertedContent = endingSelection().visibleStart().deepEquivale
nt().downstream(); | 1174 m_startOfInsertedContent = endingSelection().visibleStart().deepEquivale
nt().downstream(); |
1174 if (m_endOfInsertedContent.isOrphan()) | 1175 if (m_endOfInsertedContent.isOrphan()) |
1175 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivale
nt().upstream(); | 1176 m_endOfInsertedContent = endingSelection().visibleEnd().deepEquivale
nt().upstream(); |
1176 } | 1177 } |
1177 | 1178 |
1178 Position lastPositionToSelect; | 1179 Position lastPositionToSelect; |
1179 if (fragment.hasInterchangeNewlineAtEnd()) { | 1180 if (fragment.hasInterchangeNewlineAtEnd()) { |
1180 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); | 1181 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); |
1181 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound
ary); | 1182 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound
ary); |
1182 | 1183 |
1183 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont
ent) || next.isNull()) { | 1184 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont
ent) || next.isNull()) { |
1184 if (!isStartOfParagraph(endOfInsertedContent)) { | 1185 if (!isStartOfParagraph(endOfInsertedContent)) { |
1185 setEndingSelection(endOfInsertedContent); | 1186 setEndingSelection(endOfInsertedContent); |
1186 Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEq
uivalent().deprecatedNode()); | 1187 Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEq
uivalent().deprecatedNode()); |
1187 if (isListItem(enclosingNode)) { | 1188 if (isListItem(enclosingNode)) { |
1188 RefPtr<Node> newListItem = createListItemElement(&document()
); | 1189 RefPtr<Node> newListItem = createListItemElement(document())
; |
1189 insertNodeAfter(newListItem, enclosingNode); | 1190 insertNodeAfter(newListItem, enclosingNode); |
1190 setEndingSelection(VisiblePosition(firstPositionInNode(newLi
stItem.get()))); | 1191 setEndingSelection(VisiblePosition(firstPositionInNode(newLi
stItem.get()))); |
1191 } else { | 1192 } else { |
1192 // Use a default paragraph element (a plain div) for the emp
ty paragraph, using the last paragraph | 1193 // Use a default paragraph element (a plain div) for the emp
ty paragraph, using the last paragraph |
1193 // block's style seems to annoy users. | 1194 // block's style seems to annoy users. |
1194 insertParagraphSeparator(true, !startIsInsideMailBlockquote
&& highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), | 1195 insertParagraphSeparator(true, !startIsInsideMailBlockquote
&& highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), |
1195 isMailBlockquote, CannotCrossEditingBoundary, insertedNo
des.firstNodeInserted()->parentNode())); | 1196 isMailBlockquote, CannotCrossEditingBoundary, insertedNo
des.firstNodeInserted()->parentNode())); |
1196 } | 1197 } |
1197 | 1198 |
1198 // Select up to the paragraph separator that was added. | 1199 // Select up to the paragraph separator that was added. |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); | 1487 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); |
1487 | 1488 |
1488 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
d); | 1489 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en
d); |
1489 | 1490 |
1490 setEndingSelection(selectionAfterReplace); | 1491 setEndingSelection(selectionAfterReplace); |
1491 | 1492 |
1492 return true; | 1493 return true; |
1493 } | 1494 } |
1494 | 1495 |
1495 } // namespace WebCore | 1496 } // namespace WebCore |
OLD | NEW |