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

Side by Side Diff: Source/core/editing/ReplaceSelectionCommand.cpp

Issue 1245843003: [CodeHealth] Use Position::anchorNode instead of deprecatedNode. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 5 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 DEFINE_STATIC_LOCAL(String, convertedSpaceSpanClassString, (AppleConvertedSp ace)); 115 DEFINE_STATIC_LOCAL(String, convertedSpaceSpanClassString, (AppleConvertedSp ace));
116 if (!node->isHTMLElement() || toHTMLElement(node)->getAttribute(classAttr) ! = convertedSpaceSpanClassString) 116 if (!node->isHTMLElement() || toHTMLElement(node)->getAttribute(classAttr) ! = convertedSpaceSpanClassString)
117 return false; 117 return false;
118 UseCounter::count(node->document(), UseCounter::EditingAppleConvertedSpace); 118 UseCounter::count(node->document(), UseCounter::EditingAppleConvertedSpace);
119 return true; 119 return true;
120 } 120 }
121 121
122 static Position positionAvoidingPrecedingNodes(Position pos) 122 static Position positionAvoidingPrecedingNodes(Position pos)
123 { 123 {
124 // If we're already on a break, it's probably a placeholder and we shouldn't change our position. 124 // If we're already on a break, it's probably a placeholder and we shouldn't change our position.
125 if (editingIgnoresContent(pos.deprecatedNode())) 125 if (editingIgnoresContent(pos.anchorNode()))
126 return pos; 126 return pos;
127 127
128 // We also stop when changing block flow elements because even though the vi sual position is the 128 // We also stop when changing block flow elements because even though the vi sual position is the
129 // same. E.g., 129 // same. E.g.,
130 // <div>foo^</div>^ 130 // <div>foo^</div>^
131 // The two positions above are the same visual position, but we want to stay in the same block. 131 // The two positions above are the same visual position, but we want to stay in the same block.
132 Element* enclosingBlockElement = enclosingBlock(pos.containerNode()); 132 Element* enclosingBlockElement = enclosingBlock(pos.containerNode());
133 for (Position nextPosition = pos; nextPosition.containerNode() != enclosingB lockElement; pos = nextPosition) { 133 for (Position nextPosition = pos; nextPosition.containerNode() != enclosingB lockElement; pos = nextPosition) {
134 if (lineBreakExistsAtPosition(pos)) 134 if (lineBreakExistsAtPosition(pos))
135 break; 135 break;
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 // For a successful merge, we still need to make sure that the inserted cont ent starts with the beginning of a paragraph. 408 // For a successful merge, we still need to make sure that the inserted cont ent starts with the beginning of a paragraph.
409 // And we should only merge here if the selection start was inside a mail bl ockquote. This prevents against removing a 409 // And we should only merge here if the selection start was inside a mail bl ockquote. This prevents against removing a
410 // blockquote from newly pasted quoted content that was pasted into an unquo ted position. If that unquoted position happens 410 // blockquote from newly pasted quoted content that was pasted into an unquo ted position. If that unquoted position happens
411 // to be right after another blockquote, we don't want to merge and risk str ipping a valid block (and newline) from the pasted content. 411 // to be right after another blockquote, we don't want to merge and risk str ipping a valid block (and newline) from the pasted content.
412 if (isStartOfParagraph(startOfInsertedContent) && selectionStartWasInsideMai lBlockquote && hasMatchingQuoteLevel(prev, positionAtEndOfInsertedContent())) 412 if (isStartOfParagraph(startOfInsertedContent) && selectionStartWasInsideMai lBlockquote && hasMatchingQuoteLevel(prev, positionAtEndOfInsertedContent()))
413 return true; 413 return true;
414 414
415 return !selectionStartWasStartOfParagraph 415 return !selectionStartWasStartOfParagraph
416 && !fragmentHasInterchangeNewlineAtStart 416 && !fragmentHasInterchangeNewlineAtStart
417 && isStartOfParagraph(startOfInsertedContent) 417 && isStartOfParagraph(startOfInsertedContent)
418 && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().deprecatedN ode()) 418 && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().anchorNode( ))
419 && shouldMerge(startOfInsertedContent, prev); 419 && shouldMerge(startOfInsertedContent, prev);
420 } 420 }
421 421
422 bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph) 422 bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph)
423 { 423 {
424 VisiblePosition endOfInsertedContent(positionAtEndOfInsertedContent()); 424 VisiblePosition endOfInsertedContent(positionAtEndOfInsertedContent());
425 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBoundary) ; 425 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBoundary) ;
426 if (next.isNull()) 426 if (next.isNull())
427 return false; 427 return false;
428 428
429 return !selectionEndWasEndOfParagraph 429 return !selectionEndWasEndOfParagraph
430 && isEndOfParagraph(endOfInsertedContent) 430 && isEndOfParagraph(endOfInsertedContent)
431 && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().deprecatedNod e()) 431 && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().anchorNode())
432 && shouldMerge(endOfInsertedContent, next); 432 && shouldMerge(endOfInsertedContent, next);
433 } 433 }
434 434
435 static bool isMailPasteAsQuotationHTMLBlockQuoteElement(const Node* node) 435 static bool isMailPasteAsQuotationHTMLBlockQuoteElement(const Node* node)
436 { 436 {
437 if (!node || !node->isHTMLElement()) 437 if (!node || !node->isHTMLElement())
438 return false; 438 return false;
439 const HTMLElement& element = toHTMLElement(*node); 439 const HTMLElement& element = toHTMLElement(*node);
440 if (!element.hasTagName(blockquoteTag) || element.getAttribute(classAttr) != ApplePasteAsQuotation) 440 if (!element.hasTagName(blockquoteTag) || element.getAttribute(classAttr) != ApplePasteAsQuotation)
441 return false; 441 return false;
(...skipping 18 matching lines...) Expand all
460 static bool haveSameTagName(Element* a, Element* b) 460 static bool haveSameTagName(Element* a, Element* b)
461 { 461 {
462 return a && b && a->tagName() == b->tagName(); 462 return a && b && a->tagName() == b->tagName();
463 } 463 }
464 464
465 bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const V isiblePosition& destination) 465 bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const V isiblePosition& destination)
466 { 466 {
467 if (source.isNull() || destination.isNull()) 467 if (source.isNull() || destination.isNull())
468 return false; 468 return false;
469 469
470 Node* sourceNode = source.deepEquivalent().deprecatedNode(); 470 Node* sourceNode = source.deepEquivalent().anchorNode();
471 Node* destinationNode = destination.deepEquivalent().deprecatedNode(); 471 Node* destinationNode = destination.deepEquivalent().anchorNode();
472 Element* sourceBlock = enclosingBlock(sourceNode); 472 Element* sourceBlock = enclosingBlock(sourceNode);
473 Element* destinationBlock = enclosingBlock(destinationNode); 473 Element* destinationBlock = enclosingBlock(destinationNode);
474 return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotation HTMLBlockQuoteElement) 474 return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotation HTMLBlockQuoteElement)
475 && sourceBlock && (!sourceBlock->hasTagName(blockquoteTag) || isMailHTML BlockquoteElement(sourceBlock)) 475 && sourceBlock && (!sourceBlock->hasTagName(blockquoteTag) || isMailHTML BlockquoteElement(sourceBlock))
476 && enclosingListChild(sourceBlock) == enclosingListChild(destinationNode ) 476 && enclosingListChild(sourceBlock) == enclosingListChild(destinationNode )
477 && enclosingTableCell(source.deepEquivalent()) == enclosingTableCell(des tination.deepEquivalent()) 477 && enclosingTableCell(source.deepEquivalent()) == enclosingTableCell(des tination.deepEquivalent())
478 && (!isHTMLHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, de stinationBlock)) 478 && (!isHTMLHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, de stinationBlock))
479 // Don't merge to or from a position before or after a block because it would 479 // Don't merge to or from a position before or after a block because it would
480 // be a no-op and cause infinite recursion. 480 // be a no-op and cause infinite recursion.
481 && !isBlock(sourceNode) && !isBlock(destinationNode); 481 && !isBlock(sourceNode) && !isBlock(destinationNode);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 // block styles. 842 // block styles.
843 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC ontent) && !isStartOfParagraph(startOfInsertedContent)); 843 bool mergeForward = !(inSameParagraph(startOfInsertedContent, endOfInsertedC ontent) && !isStartOfParagraph(startOfInsertedContent));
844 844
845 VisiblePosition destination = mergeForward ? endOfInsertedContent.next() : e ndOfInsertedContent; 845 VisiblePosition destination = mergeForward ? endOfInsertedContent.next() : e ndOfInsertedContent;
846 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end OfInsertedContent) : endOfInsertedContent.next(); 846 VisiblePosition startOfParagraphToMove = mergeForward ? startOfParagraph(end OfInsertedContent) : endOfInsertedContent.next();
847 847
848 // Merging forward could result in deleting the destination anchor node. 848 // Merging forward could result in deleting the destination anchor node.
849 // To avoid this, we add a placeholder node before the start of the paragrap h. 849 // To avoid this, we add a placeholder node before the start of the paragrap h.
850 if (endOfParagraph(startOfParagraphToMove) == destination) { 850 if (endOfParagraph(startOfParagraphToMove) == destination) {
851 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBreakElement(docum ent()); 851 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBreakElement(docum ent());
852 insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().de precatedNode()); 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( );
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 static inline HTMLElement* elementToSplitToAvoidPastingIntoInlineElementsWithSty le(const Position& insertionPos) 913 static inline HTMLElement* elementToSplitToAvoidPastingIntoInlineElementsWithSty le(const Position& insertionPos)
914 { 914 {
915 Element* containingBlock = enclosingBlock(insertionPos.containerNode()); 915 Element* containingBlock = enclosingBlock(insertionPos.containerNode());
916 return toHTMLElement(highestEnclosingNodeOfType(insertionPos, isInlineHTMLEl ementWithStyle, CannotCrossEditingBoundary, containingBlock)); 916 return toHTMLElement(highestEnclosingNodeOfType(insertionPos, isInlineHTMLEl ementWithStyle, CannotCrossEditingBoundary, containingBlock));
917 } 917 }
918 918
919 void ReplaceSelectionCommand::doApply() 919 void ReplaceSelectionCommand::doApply()
920 { 920 {
921 VisibleSelection selection = endingSelection(); 921 VisibleSelection selection = endingSelection();
922 ASSERT(selection.isCaretOrRange()); 922 ASSERT(selection.isCaretOrRange());
923 ASSERT(selection.start().deprecatedNode()); 923 ASSERT(selection.start().anchorNode());
924 if (!selection.isNonOrphanedCaretOrRange() || !selection.start().deprecatedN ode()) 924 if (!selection.isNonOrphanedCaretOrRange() || !selection.start().anchorNode( ))
925 return; 925 return;
926 926
927 if (!selection.rootEditableElement()) 927 if (!selection.rootEditableElement())
928 return; 928 return;
929 929
930 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio n); 930 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio n);
931 if (performTrivialReplace(fragment)) 931 if (performTrivialReplace(fragment))
932 return; 932 return;
933 933
934 // We can skip matching the style if the selection is plain text. 934 // We can skip matching the style if the selection is plain text.
935 if ((selection.start().deprecatedNode()->layoutObject() && selection.start() .deprecatedNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT _ONLY) 935 if ((selection.start().anchorNode()->layoutObject() && selection.start().anc horNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY)
936 && (selection.end().deprecatedNode()->layoutObject() && selection.end(). deprecatedNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ ONLY)) 936 && (selection.end().anchorNode()->layoutObject() && selection.end().anch orNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY))
937 m_matchStyle = false; 937 m_matchStyle = false;
938 938
939 if (m_matchStyle) { 939 if (m_matchStyle) {
940 m_insertionStyle = EditingStyle::create(selection.start()); 940 m_insertionStyle = EditingStyle::create(selection.start());
941 m_insertionStyle->mergeTypingStyle(&document()); 941 m_insertionStyle->mergeTypingStyle(&document());
942 } 942 }
943 943
944 VisiblePosition visibleStart = selection.visibleStart(); 944 VisiblePosition visibleStart = selection.visibleStart();
945 VisiblePosition visibleEnd = selection.visibleEnd(); 945 VisiblePosition visibleEnd = selection.visibleEnd();
946 946
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().deprecatedNode()); 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 || isListItem(enclosingBlock OfVisibleStart) || selectionIsPlainText)
959 m_preventNesting = false; 959 m_preventNesting = false;
960 960
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 } 1000 }
1001 insertionPos = endingSelection().start(); 1001 insertionPos = endingSelection().start();
1002 } 1002 }
1003 1003
1004 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break 1004 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break
1005 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case 1005 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case
1006 // breaking the blockquote will prevent the content from actually being inse rted in the table. 1006 // breaking the blockquote will prevent the content from actually being inse rted in the table.
1007 if (startIsInsideMailBlockquote && m_preventNesting && !(enclosingNodeOfType (insertionPos, &isTableStructureNode))) { 1007 if (startIsInsideMailBlockquote && m_preventNesting && !(enclosingNodeOfType (insertionPos, &isTableStructureNode))) {
1008 applyCommandToComposite(BreakBlockquoteCommand::create(document())); 1008 applyCommandToComposite(BreakBlockquoteCommand::create(document()));
1009 // This will leave a br between the split. 1009 // This will leave a br between the split.
1010 Node* br = endingSelection().start().deprecatedNode(); 1010 Node* br = endingSelection().start().anchorNode();
1011 ASSERT(isHTMLBRElement(br)); 1011 ASSERT(isHTMLBRElement(br));
1012 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder). 1012 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder).
1013 insertionPos = positionInParentBeforeNode(*br); 1013 insertionPos = positionInParentBeforeNode(*br);
1014 removeNode(br); 1014 removeNode(br);
1015 } 1015 }
1016 1016
1017 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world. 1017 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world.
1018 prepareWhitespaceAtPositionForSplit(insertionPos); 1018 prepareWhitespaceAtPositionForSplit(insertionPos);
1019 1019
1020 // If the downstream node has been removed there's no point in continuing. 1020 // If the downstream node has been removed there's no point in continuing.
1021 if (!insertionPos.downstream().deprecatedNode()) 1021 if (!insertionPos.downstream().anchorNode())
1022 return; 1022 return;
1023 1023
1024 // NOTE: This would be an incorrect usage of downstream() if downstream() we re changed to mean the last position after 1024 // 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 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
1026 // away, there are positions after the br which map to the same visible posi tion as [br, 0]). 1026 // away, there are positions after the br which map to the same visible posi tion as [br, 0]).
1027 HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().deprecated Node()) ? toHTMLBRElement(insertionPos.downstream().deprecatedNode()) : 0; 1027 HTMLBRElement* endBR = isHTMLBRElement(*insertionPos.downstream().anchorNode ()) ? toHTMLBRElement(insertionPos.downstream().anchorNode()) : 0;
1028 VisiblePosition originalVisPosBeforeEndBR; 1028 VisiblePosition originalVisPosBeforeEndBR;
1029 if (endBR) 1029 if (endBR)
1030 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D OWNSTREAM).previous(); 1030 originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), D OWNSTREAM).previous();
1031 1031
1032 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in sertionPos.deprecatedNode()); 1032 RefPtrWillBeRawPtr<Element> enclosingBlockOfInsertionPos = enclosingBlock(in sertionPos.anchorNode());
1033 1033
1034 // Adjust insertionPos to prevent nesting. 1034 // Adjust insertionPos to prevent nesting.
1035 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above. 1035 // If the start was in a Mail blockquote, we will have already handled adjus ting insertionPos above.
1036 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) { 1036 if (m_preventNesting && enclosingBlockOfInsertionPos && !isTableCell(enclosi ngBlockOfInsertionPos.get()) && !startIsInsideMailBlockquote) {
1037 ASSERT(enclosingBlockOfInsertionPos != currentRoot); 1037 ASSERT(enclosingBlockOfInsertionPos != currentRoot);
1038 VisiblePosition visibleInsertionPos(insertionPos); 1038 VisiblePosition visibleInsertionPos(insertionPos);
1039 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti onPos) && fragment.hasInterchangeNewlineAtEnd())) 1039 if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInserti onPos) && fragment.hasInterchangeNewlineAtEnd()))
1040 insertionPos = positionInParentAfterNode(*enclosingBlockOfInsertionP os); 1040 insertionPos = positionInParentAfterNode(*enclosingBlockOfInsertionP os);
1041 else if (isStartOfBlock(visibleInsertionPos)) 1041 else if (isStartOfBlock(visibleInsertionPos))
1042 insertionPos = positionInParentBeforeNode(*enclosingBlockOfInsertion Pos); 1042 insertionPos = positionInParentBeforeNode(*enclosingBlockOfInsertion Pos);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 // 5) Add spaces for smart replace. 1102 // 5) Add spaces for smart replace.
1103 // 6) Select the replacement if requested, and match style if requested. 1103 // 6) Select the replacement if requested, and match style if requested.
1104 1104
1105 InsertedNodes insertedNodes; 1105 InsertedNodes insertedNodes;
1106 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild(); 1106 RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild();
1107 ASSERT(refNode); 1107 ASSERT(refNode);
1108 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling(); 1108 RefPtrWillBeRawPtr<Node> node = refNode->nextSibling();
1109 1109
1110 fragment.removeNode(refNode); 1110 fragment.removeNode(refNode);
1111 1111
1112 Element* blockStart = enclosingBlock(insertionPos.deprecatedNode()); 1112 Element* blockStart = enclosingBlock(insertionPos.anchorNode());
1113 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo de.get()) && isHTMLListElement(refNode->firstChild()))) 1113 if ((isHTMLListElement(refNode.get()) || (isLegacyAppleHTMLSpanElement(refNo de.get()) && isHTMLListElement(refNode->firstChild())))
1114 && blockStart && blockStart->layoutObject()->isListItem()) 1114 && blockStart && blockStart->layoutObject()->isListItem())
1115 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes); 1115 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes);
1116 else { 1116 else {
1117 insertNodeAt(refNode, insertionPos); 1117 insertNodeAt(refNode, insertionPos);
1118 insertedNodes.respondToNodeInsertion(*refNode); 1118 insertedNodes.respondToNodeInsertion(*refNode);
1119 } 1119 }
1120 1120
1121 // Mutation events (bug 22634) may have already removed the inserted content 1121 // Mutation events (bug 22634) may have already removed the inserted content
1122 if (!refNode->inDocument()) 1122 if (!refNode->inDocument())
(...skipping 28 matching lines...) Expand all
1151 1151
1152 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse rtionPos| 1152 // Scripts specified in javascript protocol may remove |enclosingBlockOfInse rtionPos|
1153 // during insertion, e.g. <iframe src="javascript:..."> 1153 // during insertion, e.g. <iframe src="javascript:...">
1154 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->inDocumen t()) 1154 if (enclosingBlockOfInsertionPos && !enclosingBlockOfInsertionPos->inDocumen t())
1155 enclosingBlockOfInsertionPos = nullptr; 1155 enclosingBlockOfInsertionPos = nullptr;
1156 1156
1157 VisiblePosition startOfInsertedContent(firstPositionInOrBeforeNode(insertedN odes.firstNodeInserted())); 1157 VisiblePosition startOfInsertedContent(firstPositionInOrBeforeNode(insertedN odes.firstNodeInserted()));
1158 1158
1159 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd 1159 // We inserted before the enclosingBlockOfInsertionPos to prevent nesting, a nd the content before the enclosingBlockOfInsertionPos wasn't in its own block a nd
1160 // didn't have a br after it, so the inserted content ended up in the same p aragraph. 1160 // didn't have a br after it, so the inserted content ended up in the same p aragraph.
1161 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.deprecatedNode() == enclosingBlockOfInsertionPos->parentNode() && (unsi gned)insertionPos.deprecatedEditingOffset() < enclosingBlockOfInsertionPos->node Index() && !isStartOfParagraph(startOfInsertedContent)) 1161 if (!startOfInsertedContent.isNull() && enclosingBlockOfInsertionPos && inse rtionPos.anchorNode() == enclosingBlockOfInsertionPos->parentNode() && (unsigned )insertionPos.deprecatedEditingOffset() < enclosingBlockOfInsertionPos->nodeInde x() && !isStartOfParagraph(startOfInsertedContent))
1162 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent()); 1162 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent());
1163 1163
1164 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) { 1164 if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosB eforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)) )) {
1165 RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode(); 1165 RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode();
1166 insertedNodes.willRemoveNode(*endBR); 1166 insertedNodes.willRemoveNode(*endBR);
1167 removeNode(endBR); 1167 removeNode(endBR);
1168 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { 1168 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) {
1169 insertedNodes.willRemoveNode(*nodeToRemove); 1169 insertedNodes.willRemoveNode(*nodeToRemove);
1170 removeNode(nodeToRemove); 1170 removeNode(nodeToRemove);
1171 } 1171 }
(...skipping 13 matching lines...) Expand all
1185 // Determine whether or not we should merge the end of inserted content with what's after it before we do 1185 // Determine whether or not we should merge the end of inserted content with what's after it before we do
1186 // the start merge so that the start merge doesn't effect our decision. 1186 // the start merge so that the start merge doesn't effect our decision.
1187 m_shouldMergeEnd = shouldMergeEnd(selectionEndWasEndOfParagraph); 1187 m_shouldMergeEnd = shouldMergeEnd(selectionEndWasEndOfParagraph);
1188 1188
1189 if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasIntercha ngeNewlineAtStart(), startIsInsideMailBlockquote)) { 1189 if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasIntercha ngeNewlineAtStart(), startIsInsideMailBlockquote)) {
1190 VisiblePosition startOfParagraphToMove = positionAtStartOfInsertedConten t(); 1190 VisiblePosition startOfParagraphToMove = positionAtStartOfInsertedConten t();
1191 VisiblePosition destination = startOfParagraphToMove.previous(); 1191 VisiblePosition destination = startOfParagraphToMove.previous();
1192 // We need to handle the case where we need to merge the end 1192 // We need to handle the case where we need to merge the end
1193 // but our destination node is inside an inline that is the last in the block. 1193 // but our destination node is inside an inline that is the last in the block.
1194 // We insert a placeholder before the newly inserted content to avoid be ing merged into the inline. 1194 // We insert a placeholder before the newly inserted content to avoid be ing merged into the inline.
1195 Node* destinationNode = destination.deepEquivalent().deprecatedNode(); 1195 Node* destinationNode = destination.deepEquivalent().anchorNode();
1196 if (m_shouldMergeEnd && destinationNode != enclosingInline(destinationNo de) && enclosingInline(destinationNode)->nextSibling()) 1196 if (m_shouldMergeEnd && destinationNode != enclosingInline(destinationNo de) && enclosingInline(destinationNode)->nextSibling())
1197 insertNodeBefore(createBreakElement(document()), refNode.get()); 1197 insertNodeBefore(createBreakElement(document()), refNode.get());
1198 1198
1199 // Merging the the first paragraph of inserted content with the content that came 1199 // Merging the the first paragraph of inserted content with the content that came
1200 // before the selection that was pasted into would also move content aft er 1200 // before the selection that was pasted into would also move content aft er
1201 // the selection that was pasted into if: only one paragraph was being p asted, 1201 // the selection that was pasted into if: only one paragraph was being p asted,
1202 // and it was not wrapped in a block, the selection that was pasted into ended 1202 // and it was not wrapped in a block, the selection that was pasted into ended
1203 // at the end of a block and the next paragraph didn't start at the star t of a block. 1203 // at the end of a block and the next paragraph didn't start at the star t of a block.
1204 // Insert a line break just after the inserted content to separate it fr om what 1204 // Insert a line break just after the inserted content to separate it fr om what
1205 // comes after and prevent that from happening. 1205 // comes after and prevent that from happening.
(...skipping 14 matching lines...) Expand all
1220 } 1220 }
1221 1221
1222 Position lastPositionToSelect; 1222 Position lastPositionToSelect;
1223 if (fragment.hasInterchangeNewlineAtEnd()) { 1223 if (fragment.hasInterchangeNewlineAtEnd()) {
1224 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent(); 1224 VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
1225 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound ary); 1225 VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBound ary);
1226 1226
1227 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) { 1227 if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedCont ent) || next.isNull()) {
1228 if (!isStartOfParagraph(endOfInsertedContent)) { 1228 if (!isStartOfParagraph(endOfInsertedContent)) {
1229 setEndingSelection(endOfInsertedContent); 1229 setEndingSelection(endOfInsertedContent);
1230 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().deprecatedNode()); 1230 Element* enclosingBlockElement = enclosingBlock(endOfInsertedCon tent.deepEquivalent().anchorNode());
1231 if (isListItem(enclosingBlockElement)) { 1231 if (isListItem(enclosingBlockElement)) {
1232 RefPtrWillBeRawPtr<HTMLLIElement> newListItem = createListIt emElement(document()); 1232 RefPtrWillBeRawPtr<HTMLLIElement> newListItem = createListIt emElement(document());
1233 insertNodeAfter(newListItem, enclosingBlockElement); 1233 insertNodeAfter(newListItem, enclosingBlockElement);
1234 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get()))); 1234 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get())));
1235 } else { 1235 } else {
1236 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph 1236 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph
1237 // block's style seems to annoy users. 1237 // block's style seems to annoy users.
1238 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), 1238 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),
1239 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode())); 1239 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode()));
1240 } 1240 }
1241 1241
1242 // Select up to the paragraph separator that was added. 1242 // Select up to the paragraph separator that was added.
1243 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent(); 1243 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent();
1244 updateNodesInserted(lastPositionToSelect.deprecatedNode()); 1244 updateNodesInserted(lastPositionToSelect.anchorNode());
1245 } 1245 }
1246 } else { 1246 } else {
1247 // Select up to the beginning of the next paragraph. 1247 // Select up to the beginning of the next paragraph.
1248 lastPositionToSelect = next.deepEquivalent().downstream(); 1248 lastPositionToSelect = next.deepEquivalent().downstream();
1249 } 1249 }
1250 } else { 1250 } else {
1251 mergeEndIfNeeded(); 1251 mergeEndIfNeeded();
1252 } 1252 }
1253 1253
1254 if (HTMLQuoteElement* mailBlockquote = toHTMLQuoteElement(enclosingNodeOfTyp e(positionAtStartOfInsertedContent().deepEquivalent(), isMailPasteAsQuotationHTM LBlockQuoteElement))) 1254 if (HTMLQuoteElement* mailBlockquote = toHTMLQuoteElement(enclosingNodeOfTyp e(positionAtStartOfInsertedContent().deepEquivalent(), isMailPasteAsQuotationHTM LBlockQuoteElement)))
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 1460
1461 bool isStart = isStartOfParagraph(VisiblePosition(insertPos)); 1461 bool isStart = isStartOfParagraph(VisiblePosition(insertPos));
1462 bool isEnd = isEndOfParagraph(VisiblePosition(insertPos)); 1462 bool isEnd = isEndOfParagraph(VisiblePosition(insertPos));
1463 bool isMiddle = !isStart && !isEnd; 1463 bool isMiddle = !isStart && !isEnd;
1464 Node* lastNode = insertionBlock; 1464 Node* lastNode = insertionBlock;
1465 1465
1466 // If we're in the middle of a list item, we should split it into two separa te 1466 // If we're in the middle of a list item, we should split it into two separa te
1467 // list items and insert these nodes between them. 1467 // list items and insert these nodes between them.
1468 if (isMiddle) { 1468 if (isMiddle) {
1469 int textNodeOffset = insertPos.offsetInContainerNode(); 1469 int textNodeOffset = insertPos.offsetInContainerNode();
1470 if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0) 1470 if (insertPos.anchorNode()->isTextNode() && textNodeOffset > 0)
1471 splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset); 1471 splitTextNode(toText(insertPos.anchorNode()), textNodeOffset);
1472 splitTreeToNode(insertPos.deprecatedNode(), lastNode, true); 1472 splitTreeToNode(insertPos.anchorNode(), lastNode, true);
1473 } 1473 }
1474 1474
1475 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) { 1475 while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) {
1476 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); 1476 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION);
1477 if (isStart || isMiddle) { 1477 if (isStart || isMiddle) {
1478 insertNodeBefore(listItem, lastNode); 1478 insertNodeBefore(listItem, lastNode);
1479 insertedNodes.respondToNodeInsertion(*listItem); 1479 insertedNodes.respondToNodeInsertion(*listItem);
1480 } else if (isEnd) { 1480 } else if (isEnd) {
1481 insertNodeAfter(listItem, lastNode); 1481 insertNodeAfter(listItem, lastNode);
1482 insertedNodes.respondToNodeInsertion(*listItem); 1482 insertedNodes.respondToNodeInsertion(*listItem);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 DEFINE_TRACE(ReplaceSelectionCommand) 1542 DEFINE_TRACE(ReplaceSelectionCommand)
1543 { 1543 {
1544 visitor->trace(m_startOfInsertedContent); 1544 visitor->trace(m_startOfInsertedContent);
1545 visitor->trace(m_endOfInsertedContent); 1545 visitor->trace(m_endOfInsertedContent);
1546 visitor->trace(m_insertionStyle); 1546 visitor->trace(m_insertionStyle);
1547 visitor->trace(m_documentFragment); 1547 visitor->trace(m_documentFragment);
1548 CompositeEditCommand::trace(visitor); 1548 CompositeEditCommand::trace(visitor);
1549 } 1549 }
1550 1550
1551 } // namespace blink 1551 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/InsertParagraphSeparatorCommand.cpp ('k') | Source/core/editing/SelectionController.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698