Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp

Issue 1695153002: Editing: Make the |EditingState*| argument of CompositeEditCommand::removeNode mandatory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ; Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 elements.add(tfootTag.localName()); 626 elements.add(tfootTag.localName());
627 elements.add(thTag.localName()); 627 elements.add(thTag.localName());
628 elements.add(theadTag.localName()); 628 elements.add(theadTag.localName());
629 elements.add(trTag.localName()); 629 elements.add(trTag.localName());
630 elements.add(ulTag.localName()); 630 elements.add(ulTag.localName());
631 elements.add(xmpTag.localName()); 631 elements.add(xmpTag.localName());
632 } 632 }
633 return elements.contains(name); 633 return elements.contains(name);
634 } 634 }
635 635
636 void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild er(const InsertedNodes& insertedNodes) 636 void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild er(const InsertedNodes& insertedNodes, EditingState* editingState)
637 { 637 {
638 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); 638 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
639 RefPtrWillBeRawPtr<Node> next = nullptr; 639 RefPtrWillBeRawPtr<Node> next = nullptr;
640 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) { 640 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
641 next = NodeTraversal::next(*node); 641 next = NodeTraversal::next(*node);
642 642
643 if (!node->isHTMLElement()) 643 if (!node->isHTMLElement())
644 continue; 644 continue;
645 // moveElementOutOfAncestor() in a previous iteration might have failed, 645 // moveElementOutOfAncestor() in a previous iteration might have failed,
646 // and |node| might have been detached from the document tree. 646 // and |node| might have been detached from the document tree.
647 if (!node->inDocument()) 647 if (!node->inDocument())
648 continue; 648 continue;
649 649
650 HTMLElement& element = toHTMLElement(*node); 650 HTMLElement& element = toHTMLElement(*node);
651 if (isProhibitedParagraphChild(element.localName())) { 651 if (isProhibitedParagraphChild(element.localName())) {
652 if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWi thTag(positionInParentBeforeNode(element), pTag))) 652 if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWi thTag(positionInParentBeforeNode(element), pTag))) {
653 moveElementOutOfAncestor(&element, paragraphElement); 653 moveElementOutOfAncestor(&element, paragraphElement, editingStat e);
654 if (editingState->isAborted())
655 return;
656 }
654 } 657 }
655 658
656 if (isHTMLHeaderElement(&element)) { 659 if (isHTMLHeaderElement(&element)) {
657 if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeO fType(positionInParentBeforeNode(element), isHTMLHeaderElement))) 660 if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeO fType(positionInParentBeforeNode(element), isHTMLHeaderElement))) {
658 moveElementOutOfAncestor(&element, headerElement); 661 moveElementOutOfAncestor(&element, headerElement, editingState);
662 if (editingState->isAborted())
663 return;
664 }
659 } 665 }
660 } 666 }
661 } 667 }
662 668
663 void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<El ement> prpElement, PassRefPtrWillBeRawPtr<Element> prpAncestor) 669 void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<El ement> prpElement, PassRefPtrWillBeRawPtr<Element> prpAncestor, EditingState* ed itingState)
664 { 670 {
665 RefPtrWillBeRawPtr<Element> element = prpElement; 671 RefPtrWillBeRawPtr<Element> element = prpElement;
666 RefPtrWillBeRawPtr<Element> ancestor = prpAncestor; 672 RefPtrWillBeRawPtr<Element> ancestor = prpAncestor;
667 673
668 if (!ancestor->parentNode()->hasEditableStyle()) 674 if (!ancestor->parentNode()->hasEditableStyle())
669 return; 675 return;
670 676
671 VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOr AfterNode(element.get())); 677 VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOr AfterNode(element.get()));
672 VisiblePosition lastPositionInParagraph = createVisiblePosition(lastPosition InNode(ancestor.get())); 678 VisiblePosition lastPositionInParagraph = createVisiblePosition(lastPosition InNode(ancestor.get()));
673 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui valent()) { 679 if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEqui valent()) {
674 removeNode(element); 680 removeNode(element, editingState);
681 if (editingState->isAborted())
682 return;
675 if (ancestor->nextSibling()) 683 if (ancestor->nextSibling())
676 insertNodeBefore(element, ancestor->nextSibling()); 684 insertNodeBefore(element, ancestor->nextSibling(), editingState);
677 else 685 else
678 appendNode(element, ancestor->parentNode()); 686 appendNode(element, ancestor->parentNode(), editingState);
687 if (editingState->isAborted())
688 return;
679 } else { 689 } else {
680 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(), ancestor.get(), true); 690 RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(), ancestor.get(), true);
681 removeNode(element); 691 removeNode(element, editingState);
682 insertNodeBefore(element, nodeToSplitTo); 692 if (editingState->isAborted())
693 return;
694 insertNodeBefore(element, nodeToSplitTo, editingState);
695 if (editingState->isAborted())
696 return;
683 } 697 }
684 if (!ancestor->hasChildren()) 698 if (!ancestor->hasChildren())
685 removeNode(ancestor.release()); 699 removeNode(ancestor.release(), editingState);
686 } 700 }
687 701
688 static inline bool nodeHasVisibleLayoutText(Text& text) 702 static inline bool nodeHasVisibleLayoutText(Text& text)
689 { 703 {
690 return text.layoutObject() && text.layoutObject()->resolvedTextLength() > 0; 704 return text.layoutObject() && text.layoutObject()->resolvedTextLength() > 0;
691 } 705 }
692 706
693 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins ertedNodes) 707 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins ertedNodes)
694 { 708 {
695 document().updateLayoutIgnorePendingStylesheets(); 709 document().updateLayoutIgnorePendingStylesheets();
696 710
697 Node* lastLeafInserted = insertedNodes.lastLeafInserted(); 711 Node* lastLeafInserted = insertedNodes.lastLeafInserted();
698 if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleLay outText(toText(*lastLeafInserted)) 712 if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleLay outText(toText(*lastLeafInserted))
699 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted ), selectTag) 713 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted ), selectTag)
700 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted ), scriptTag)) { 714 && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted ), scriptTag)) {
701 insertedNodes.willRemoveNode(*lastLeafInserted); 715 insertedNodes.willRemoveNode(*lastLeafInserted);
702 removeNode(lastLeafInserted); 716 // Removing a Text node won't dispatch synchronous events.
717 removeNode(lastLeafInserted, ASSERT_NO_EDITING_ABORT);
703 } 718 }
704 719
705 // We don't have to make sure that firstNodeInserted isn't inside a select o r script element, because 720 // We don't have to make sure that firstNodeInserted isn't inside a select o r script element, because
706 // it is a top level node in the fragment and the user can't insert into tho se elements. 721 // it is a top level node in the fragment and the user can't insert into tho se elements.
707 Node* firstNodeInserted = insertedNodes.firstNodeInserted(); 722 Node* firstNodeInserted = insertedNodes.firstNodeInserted();
708 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleL ayoutText(toText(*firstNodeInserted))) { 723 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleL ayoutText(toText(*firstNodeInserted))) {
709 insertedNodes.willRemoveNode(*firstNodeInserted); 724 insertedNodes.willRemoveNode(*firstNodeInserted);
710 removeNode(firstNodeInserted); 725 // Removing a Text node won't dispatch synchronous events.
726 removeNode(firstNodeInserted, ASSERT_NO_EDITING_ABORT);
711 } 727 }
712 } 728 }
713 729
714 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const 730 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const
715 { 731 {
716 // FIXME: Why is this hack here? What's special about <select> tags? 732 // FIXME: Why is this hack here? What's special about <select> tags?
717 HTMLSelectElement* enclosingSelect = toHTMLSelectElement(enclosingElementWit hTag(m_endOfInsertedContent, selectTag)); 733 HTMLSelectElement* enclosingSelect = toHTMLSelectElement(enclosingElementWit hTag(m_endOfInsertedContent, selectTag));
718 return createVisiblePosition(enclosingSelect ? lastPositionInOrAfterNode(enc losingSelect) : m_endOfInsertedContent); 734 return createVisiblePosition(enclosingSelect ? lastPositionInOrAfterNode(enc losingSelect) : m_endOfInsertedContent);
719 } 735 }
720 736
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 const VisibleSelection selection = endingSelection(); 941 const VisibleSelection selection = endingSelection();
926 ASSERT(selection.isCaretOrRange()); 942 ASSERT(selection.isCaretOrRange());
927 ASSERT(selection.start().anchorNode()); 943 ASSERT(selection.start().anchorNode());
928 if (!selection.isNonOrphanedCaretOrRange() || !selection.start().anchorNode( )) 944 if (!selection.isNonOrphanedCaretOrRange() || !selection.start().anchorNode( ))
929 return; 945 return;
930 946
931 if (!selection.rootEditableElement()) 947 if (!selection.rootEditableElement())
932 return; 948 return;
933 949
934 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio n); 950 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio n);
935 if (performTrivialReplace(fragment)) 951 bool trivialReplaceResult = performTrivialReplace(fragment, editingState);
952 if (editingState->isAborted())
953 return;
954 if (trivialReplaceResult)
936 return; 955 return;
937 956
938 // We can skip matching the style if the selection is plain text. 957 // We can skip matching the style if the selection is plain text.
939 if ((selection.start().anchorNode()->layoutObject() && selection.start().anc horNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY) 958 if ((selection.start().anchorNode()->layoutObject() && selection.start().anc horNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY)
940 && (selection.end().anchorNode()->layoutObject() && selection.end().anch orNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY)) 959 && (selection.end().anchorNode()->layoutObject() && selection.end().anch orNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY))
941 m_matchStyle = false; 960 m_matchStyle = false;
942 961
943 if (m_matchStyle) { 962 if (m_matchStyle) {
944 m_insertionStyle = EditingStyle::create(selection.start()); 963 m_insertionStyle = EditingStyle::create(selection.start());
945 m_insertionStyle->mergeTypingStyle(&document()); 964 m_insertionStyle->mergeTypingStyle(&document());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break 1027 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break
1009 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case 1028 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case
1010 // breaking the blockquote will prevent the content from actually being inse rted in the table. 1029 // breaking the blockquote will prevent the content from actually being inse rted in the table.
1011 if (enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, CanCrossE ditingBoundary) && m_preventNesting && !(enclosingNodeOfType(insertionPos, &isTa bleStructureNode))) { 1030 if (enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, CanCrossE ditingBoundary) && m_preventNesting && !(enclosingNodeOfType(insertionPos, &isTa bleStructureNode))) {
1012 applyCommandToComposite(BreakBlockquoteCommand::create(document())); 1031 applyCommandToComposite(BreakBlockquoteCommand::create(document()));
1013 // This will leave a br between the split. 1032 // This will leave a br between the split.
1014 Node* br = endingSelection().start().anchorNode(); 1033 Node* br = endingSelection().start().anchorNode();
1015 ASSERT(isHTMLBRElement(br)); 1034 ASSERT(isHTMLBRElement(br));
1016 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder). 1035 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder).
1017 insertionPos = positionInParentBeforeNode(*br); 1036 insertionPos = positionInParentBeforeNode(*br);
1018 removeNode(br); 1037 removeNode(br, editingState);
1038 if (editingState->isAborted())
1039 return;
1019 } 1040 }
1020 1041
1021 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world. 1042 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world.
1022 prepareWhitespaceAtPositionForSplit(insertionPos); 1043 prepareWhitespaceAtPositionForSplit(insertionPos);
1023 1044
1024 // If the downstream node has been removed there's no point in continuing. 1045 // If the downstream node has been removed there's no point in continuing.
1025 if (!mostForwardCaretPosition(insertionPos).anchorNode()) 1046 if (!mostForwardCaretPosition(insertionPos).anchorNode())
1026 return; 1047 return;
1027 1048
1028 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after 1049 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 VisiblePosition startOfInsertedContent = createVisiblePosition(firstPosition InOrBeforeNode(insertedNodes.firstNodeInserted())); 1184 VisiblePosition startOfInsertedContent = createVisiblePosition(firstPosition InOrBeforeNode(insertedNodes.firstNodeInserted()));
1164 1185
1165 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd 1186 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd
1166 // didn't have a br after it, so the inserted content ended up in the same p aragraph. 1187 // didn't have a br after it, so the inserted content ended up in the same p aragraph.
1167 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned )insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex() && !isStartOfParagraph(startOfInsertedContent)) 1188 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned )insertionPos.computeEditingOffset() < enclosingBlockOfInsertionPos->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
1168 insertNodeAt(HTMLBRElement::create(document()).get(), startOfInsertedCon tent.deepEquivalent()); 1189 insertNodeAt(HTMLBRElement::create(document()).get(), startOfInsertedCon tent.deepEquivalent());
1169 1190
1170 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) { 1191 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) {
1171 RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode(); 1192 RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode();
1172 insertedNodes.willRemoveNode(*endBR); 1193 insertedNodes.willRemoveNode(*endBR);
1173 removeNode(endBR); 1194 removeNode(endBR, editingState);
1195 if (editingState->isAborted())
1196 return;
1174 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { 1197 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) {
1175 insertedNodes.willRemoveNode(*nodeToRemove); 1198 insertedNodes.willRemoveNode(*nodeToRemove);
1176 removeNode(nodeToRemove); 1199 removeNode(nodeToRemove, editingState);
1200 if (editingState->isAborted())
1201 return;
1177 } 1202 }
1178 } 1203 }
1179 1204
1180 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); 1205 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes, editingS tate);
1206 if (editingState->isAborted())
1207 return;
1181 1208
1182 removeRedundantStylesAndKeepStyleSpanInline(insertedNodes); 1209 removeRedundantStylesAndKeepStyleSpanInline(insertedNodes);
1183 1210
1184 if (m_sanitizeFragment) 1211 if (m_sanitizeFragment)
1185 applyCommandToComposite(SimplifyMarkupCommand::create(document(), insert edNodes.firstNodeInserted(), insertedNodes.pastLastLeaf())); 1212 applyCommandToComposite(SimplifyMarkupCommand::create(document(), insert edNodes.firstNodeInserted(), insertedNodes.pastLastLeaf()));
1186 1213
1187 // Setup m_startOfInsertedContent and m_endOfInsertedContent. This should be the last two lines of code that access insertedNodes. 1214 // Setup m_startOfInsertedContent and m_endOfInsertedContent. This should be the last two lines of code that access insertedNodes.
1188 m_startOfInsertedContent = firstPositionInOrBeforeNode(insertedNodes.firstNo deInserted()); 1215 m_startOfInsertedContent = firstPositionInOrBeforeNode(insertedNodes.firstNo deInserted());
1189 m_endOfInsertedContent = lastPositionInOrAfterNode(insertedNodes.lastLeafIns erted()); 1216 m_endOfInsertedContent = lastPositionInOrAfterNode(insertedNodes.lastLeafIns erted());
1190 1217
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 removeElementAttribute(mailBlockquote, classAttr); 1288 removeElementAttribute(mailBlockquote, classAttr);
1262 1289
1263 if (shouldPerformSmartReplace()) 1290 if (shouldPerformSmartReplace())
1264 addSpacesForSmartReplace(); 1291 addSpacesForSmartReplace();
1265 1292
1266 // If we are dealing with a fragment created from plain text 1293 // If we are dealing with a fragment created from plain text
1267 // no style matching is necessary. 1294 // no style matching is necessary.
1268 if (plainTextFragment) 1295 if (plainTextFragment)
1269 m_matchStyle = false; 1296 m_matchStyle = false;
1270 1297
1271 completeHTMLReplacement(lastPositionToSelect); 1298 completeHTMLReplacement(lastPositionToSelect, editingState);
1272 } 1299 }
1273 1300
1274 bool ReplaceSelectionCommand::shouldRemoveEndBR(HTMLBRElement* endBR, const Visi blePosition& originalVisPosBeforeEndBR) 1301 bool ReplaceSelectionCommand::shouldRemoveEndBR(HTMLBRElement* endBR, const Visi blePosition& originalVisPosBeforeEndBR)
1275 { 1302 {
1276 if (!endBR || !endBR->inDocument()) 1303 if (!endBR || !endBR->inDocument())
1277 return false; 1304 return false;
1278 1305
1279 VisiblePosition visiblePos = createVisiblePosition(positionBeforeNode(endBR) ); 1306 VisiblePosition visiblePos = createVisiblePosition(positionBeforeNode(endBR) );
1280 1307
1281 // Don't remove the br if nothing was inserted. 1308 // Don't remove the br if nothing was inserted.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 } else { 1382 } else {
1356 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " "); 1383 RefPtrWillBeRawPtr<Text> node = document().createEditingTextNode(col lapseWhiteSpace ? nonBreakingSpaceString() : " ");
1357 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space, 1384 // Don't updateNodesInserted. Doing so would set m_endOfInsertedCont ent to be the node containing the leading space,
1358 // but m_endOfInsertedContent is supposed to mark the end of pasted content. 1385 // but m_endOfInsertedContent is supposed to mark the end of pasted content.
1359 insertNodeBefore(node, startNode); 1386 insertNodeBefore(node, startNode);
1360 m_startOfInsertedContent = firstPositionInNode(node.get()); 1387 m_startOfInsertedContent = firstPositionInNode(node.get());
1361 } 1388 }
1362 } 1389 }
1363 } 1390 }
1364 1391
1365 void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi onToSelect) 1392 void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi onToSelect, EditingState* editingState)
1366 { 1393 {
1367 Position start = positionAtStartOfInsertedContent().deepEquivalent(); 1394 Position start = positionAtStartOfInsertedContent().deepEquivalent();
1368 Position end = positionAtEndOfInsertedContent().deepEquivalent(); 1395 Position end = positionAtEndOfInsertedContent().deepEquivalent();
1369 1396
1370 // Mutation events may have deleted start or end 1397 // Mutation events may have deleted start or end
1371 if (start.isNotNull() && !start.isOrphan() && end.isNotNull() && !end.isOrph an()) { 1398 if (start.isNotNull() && !start.isOrphan() && end.isNotNull() && !end.isOrph an()) {
1372 // FIXME (11475): Remove this and require that the creator of the fragme nt to use nbsps. 1399 // FIXME (11475): Remove this and require that the creator of the fragme nt to use nbsps.
1373 rebalanceWhitespaceAt(start); 1400 rebalanceWhitespaceAt(start);
1374 rebalanceWhitespaceAt(end); 1401 rebalanceWhitespaceAt(end);
1375 1402
1376 if (m_matchStyle) { 1403 if (m_matchStyle) {
1377 ASSERT(m_insertionStyle); 1404 ASSERT(m_insertionStyle);
1378 applyStyle(m_insertionStyle.get(), start, end); 1405 applyStyle(m_insertionStyle.get(), start, end);
1379 } 1406 }
1380 1407
1381 if (lastPositionToSelect.isNotNull()) 1408 if (lastPositionToSelect.isNotNull())
1382 end = lastPositionToSelect; 1409 end = lastPositionToSelect;
1383 1410
1384 mergeTextNodesAroundPosition(start, end); 1411 mergeTextNodesAroundPosition(start, end, editingState);
1412 if (editingState->isAborted())
1413 return;
1385 } else if (lastPositionToSelect.isNotNull()) { 1414 } else if (lastPositionToSelect.isNotNull()) {
1386 start = end = lastPositionToSelect; 1415 start = end = lastPositionToSelect;
1387 } else { 1416 } else {
1388 return; 1417 return;
1389 } 1418 }
1390 1419
1391 m_startOfInsertedRange = start; 1420 m_startOfInsertedRange = start;
1392 m_endOfInsertedRange = end; 1421 m_endOfInsertedRange = end;
1393 1422
1394 if (m_selectReplacement) 1423 if (m_selectReplacement)
1395 setEndingSelection(VisibleSelection(start, end, SelDefaultAffinity, endi ngSelection().isDirectional())); 1424 setEndingSelection(VisibleSelection(start, end, SelDefaultAffinity, endi ngSelection().isDirectional()));
1396 else 1425 else
1397 setEndingSelection(VisibleSelection(end, SelDefaultAffinity, endingSelec tion().isDirectional())); 1426 setEndingSelection(VisibleSelection(end, SelDefaultAffinity, endingSelec tion().isDirectional()));
1398 } 1427 }
1399 1428
1400 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P osition& positionOnlyToBeUpdated) 1429 void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P osition& positionOnlyToBeUpdated, EditingState* editingState)
1401 { 1430 {
1402 bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); 1431 bool positionIsOffsetInAnchor = position.isOffsetInAnchor();
1403 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff setInAnchor(); 1432 bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOff setInAnchor();
1404 RefPtrWillBeRawPtr<Text> text = nullptr; 1433 RefPtrWillBeRawPtr<Text> text = nullptr;
1405 if (positionIsOffsetInAnchor && position.computeContainerNode() && position. computeContainerNode()->isTextNode()) { 1434 if (positionIsOffsetInAnchor && position.computeContainerNode() && position. computeContainerNode()->isTextNode()) {
1406 text = toText(position.computeContainerNode()); 1435 text = toText(position.computeContainerNode());
1407 } else { 1436 } else {
1408 Node* before = position.computeNodeBeforePosition(); 1437 Node* before = position.computeNodeBeforePosition();
1409 if (before && before->isTextNode()) { 1438 if (before && before->isTextNode()) {
1410 text = toText(before); 1439 text = toText(before);
(...skipping 17 matching lines...) Expand all
1428 1457
1429 if (positionOnlyToBeUpdatedIsOffsetInAnchor) { 1458 if (positionOnlyToBeUpdatedIsOffsetInAnchor) {
1430 if (positionOnlyToBeUpdated.computeContainerNode() == text) 1459 if (positionOnlyToBeUpdated.computeContainerNode() == text)
1431 positionOnlyToBeUpdated = Position(text, previous->length() + po sitionOnlyToBeUpdated.offsetInContainerNode()); 1460 positionOnlyToBeUpdated = Position(text, previous->length() + po sitionOnlyToBeUpdated.offsetInContainerNode());
1432 else if (positionOnlyToBeUpdated.computeContainerNode() == previous) 1461 else if (positionOnlyToBeUpdated.computeContainerNode() == previous)
1433 positionOnlyToBeUpdated = Position(text, positionOnlyToBeUpdated .offsetInContainerNode()); 1462 positionOnlyToBeUpdated = Position(text, positionOnlyToBeUpdated .offsetInContainerNode());
1434 } else { 1463 } else {
1435 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous); 1464 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous);
1436 } 1465 }
1437 1466
1438 removeNode(previous); 1467 removeNode(previous, editingState);
1468 if (editingState->isAborted())
1469 return;
1439 } 1470 }
1440 if (text->nextSibling() && text->nextSibling()->isTextNode()) { 1471 if (text->nextSibling() && text->nextSibling()->isTextNode()) {
1441 RefPtrWillBeRawPtr<Text> next = toText(text->nextSibling()); 1472 RefPtrWillBeRawPtr<Text> next = toText(text->nextSibling());
1442 unsigned originalLength = text->length(); 1473 unsigned originalLength = text->length();
1443 insertTextIntoNode(text, originalLength, next->data()); 1474 insertTextIntoNode(text, originalLength, next->data());
1444 1475
1445 if (!positionIsOffsetInAnchor) 1476 if (!positionIsOffsetInAnchor)
1446 updatePositionForNodeRemoval(position, *next); 1477 updatePositionForNodeRemoval(position, *next);
1447 1478
1448 if (positionOnlyToBeUpdatedIsOffsetInAnchor && positionOnlyToBeUpdated.c omputeContainerNode() == next) 1479 if (positionOnlyToBeUpdatedIsOffsetInAnchor && positionOnlyToBeUpdated.c omputeContainerNode() == next)
1449 positionOnlyToBeUpdated = Position(text, originalLength + positionOn lyToBeUpdated.offsetInContainerNode()); 1480 positionOnlyToBeUpdated = Position(text, originalLength + positionOn lyToBeUpdated.offsetInContainerNode());
1450 else 1481 else
1451 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next); 1482 updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next);
1452 1483
1453 removeNode(next); 1484 removeNode(next, editingState);
1485 if (editingState->isAborted())
1486 return;
1454 } 1487 }
1455 } 1488 }
1456 1489
1457 EditAction ReplaceSelectionCommand::editingAction() const 1490 EditAction ReplaceSelectionCommand::editingAction() const
1458 { 1491 {
1459 return m_editAction; 1492 return m_editAction;
1460 } 1493 }
1461 1494
1462 // If the user is inserting a list into an existing list, instead of nesting the list, 1495 // If the user is inserting a list into an existing list, instead of nesting the list,
1463 // we put the list items into the existing list. 1496 // we put the list items into the existing list.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 if (m_startOfInsertedContent.isNull()) 1543 if (m_startOfInsertedContent.isNull())
1511 m_startOfInsertedContent = firstPositionInOrBeforeNode(node); 1544 m_startOfInsertedContent = firstPositionInOrBeforeNode(node);
1512 1545
1513 m_endOfInsertedContent = lastPositionInOrAfterNode(&NodeTraversal::lastWithi nOrSelf(*node)); 1546 m_endOfInsertedContent = lastPositionInOrAfterNode(&NodeTraversal::lastWithi nOrSelf(*node));
1514 } 1547 }
1515 1548
1516 // During simple pastes, where we're just pasting a text node into a run of text , we insert the text node 1549 // During simple pastes, where we're just pasting a text node into a run of text , we insert the text node
1517 // directly into the text node that holds the selection. This is much faster th an the generalized code in 1550 // directly into the text node that holds the selection. This is much faster th an the generalized code in
1518 // ReplaceSelectionCommand, and works around <https://bugs.webkit.org/show_bug.c gi?id=6148> since we don't 1551 // ReplaceSelectionCommand, and works around <https://bugs.webkit.org/show_bug.c gi?id=6148> since we don't
1519 // split text nodes. 1552 // split text nodes.
1520 bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f ragment) 1553 bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f ragment, EditingState* editingState)
1521 { 1554 {
1522 if (!fragment.firstChild() || fragment.firstChild() != fragment.lastChild() || !fragment.firstChild()->isTextNode()) 1555 if (!fragment.firstChild() || fragment.firstChild() != fragment.lastChild() || !fragment.firstChild()->isTextNode())
1523 return false; 1556 return false;
1524 1557
1525 // FIXME: Would be nice to handle smart replace in the fast path. 1558 // FIXME: Would be nice to handle smart replace in the fast path.
1526 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd()) 1559 if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.ha sInterchangeNewlineAtEnd())
1527 return false; 1560 return false;
1528 1561
1529 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined. 1562 // e.g. when "bar" is inserted after "foo" in <div><u>foo</u></div>, "bar" s hould not be underlined.
1530 if (elementToSplitToAvoidPastingIntoInlineElementsWithStyle(endingSelection( ).start())) 1563 if (elementToSplitToAvoidPastingIntoInlineElementsWithStyle(endingSelection( ).start()))
1531 return false; 1564 return false;
1532 1565
1533 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = mostForwardCaretPosition(en dingSelection().end()).anchorNode(); 1566 RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = mostForwardCaretPosition(en dingSelection().end()).anchorNode();
1534 Text* textNode = toText(fragment.firstChild()); 1567 Text* textNode = toText(fragment.firstChild());
1535 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here. 1568 // Our fragment creation code handles tabs, spaces, and newlines, so we don' t have to worry about those here.
1536 1569
1537 Position start = endingSelection().start(); 1570 Position start = endingSelection().start();
1538 Position end = replaceSelectedTextInNode(textNode->data()); 1571 Position end = replaceSelectedTextInNode(textNode->data());
1539 if (end.isNull()) 1572 if (end.isNull())
1540 return false; 1573 return false;
1541 1574
1542 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos) 1575 if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBR Element(*nodeAfterInsertionPos)
1543 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), creat eVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) 1576 && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), creat eVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) {
1544 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); 1577 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get(), editingState);
1578 if (editingState->isAborted())
1579 return false;
1580 }
1545 1581
1546 m_startOfInsertedRange = start; 1582 m_startOfInsertedRange = start;
1547 m_endOfInsertedRange = end; 1583 m_endOfInsertedRange = end;
1548 1584
1549 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d); 1585 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d);
1550 1586
1551 setEndingSelection(selectionAfterReplace); 1587 setEndingSelection(selectionAfterReplace);
1552 1588
1553 return true; 1589 return true;
1554 } 1590 }
(...skipping 13 matching lines...) Expand all
1568 visitor->trace(m_startOfInsertedContent); 1604 visitor->trace(m_startOfInsertedContent);
1569 visitor->trace(m_endOfInsertedContent); 1605 visitor->trace(m_endOfInsertedContent);
1570 visitor->trace(m_insertionStyle); 1606 visitor->trace(m_insertionStyle);
1571 visitor->trace(m_documentFragment); 1607 visitor->trace(m_documentFragment);
1572 visitor->trace(m_startOfInsertedRange); 1608 visitor->trace(m_startOfInsertedRange);
1573 visitor->trace(m_endOfInsertedRange); 1609 visitor->trace(m_endOfInsertedRange);
1574 CompositeEditCommand::trace(visitor); 1610 CompositeEditCommand::trace(visitor);
1575 } 1611 }
1576 1612
1577 } // namespace blink 1613 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698