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

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

Issue 1416843004: [Editing][BugFix] Fix if condition in ReplaceSelectionCommand (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2526
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « third_party/WebKit/LayoutTests/editing/execCommand/replace-crossing-mailblockquote-crash.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 901 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 } 912 }
913 913
914 static inline HTMLElement* elementToSplitToAvoidPastingIntoInlineElementsWithSty le(const Position& insertionPos) 914 static inline HTMLElement* elementToSplitToAvoidPastingIntoInlineElementsWithSty le(const Position& insertionPos)
915 { 915 {
916 Element* containingBlock = enclosingBlock(insertionPos.computeContainerNode( )); 916 Element* containingBlock = enclosingBlock(insertionPos.computeContainerNode( ));
917 return toHTMLElement(highestEnclosingNodeOfType(insertionPos, isInlineHTMLEl ementWithStyle, CannotCrossEditingBoundary, containingBlock)); 917 return toHTMLElement(highestEnclosingNodeOfType(insertionPos, isInlineHTMLEl ementWithStyle, CannotCrossEditingBoundary, containingBlock));
918 } 918 }
919 919
920 void ReplaceSelectionCommand::doApply() 920 void ReplaceSelectionCommand::doApply()
921 { 921 {
922 VisibleSelection selection = endingSelection(); 922 const VisibleSelection selection = endingSelection();
923 ASSERT(selection.isCaretOrRange()); 923 ASSERT(selection.isCaretOrRange());
924 ASSERT(selection.start().anchorNode()); 924 ASSERT(selection.start().anchorNode());
925 if (!selection.isNonOrphanedCaretOrRange() || !selection.start().anchorNode( )) 925 if (!selection.isNonOrphanedCaretOrRange() || !selection.start().anchorNode( ))
926 return; 926 return;
927 927
928 if (!selection.rootEditableElement()) 928 if (!selection.rootEditableElement())
929 return; 929 return;
930 930
931 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio n); 931 ReplacementFragment fragment(&document(), m_documentFragment.get(), selectio n);
932 if (performTrivialReplace(fragment)) 932 if (performTrivialReplace(fragment))
933 return; 933 return;
934 934
935 // We can skip matching the style if the selection is plain text. 935 // We can skip matching the style if the selection is plain text.
936 if ((selection.start().anchorNode()->layoutObject() && selection.start().anc horNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY) 936 if ((selection.start().anchorNode()->layoutObject() && selection.start().anc horNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY)
937 && (selection.end().anchorNode()->layoutObject() && selection.end().anch orNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY)) 937 && (selection.end().anchorNode()->layoutObject() && selection.end().anch orNode()->layoutObject()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY))
938 m_matchStyle = false; 938 m_matchStyle = false;
939 939
940 if (m_matchStyle) { 940 if (m_matchStyle) {
941 m_insertionStyle = EditingStyle::create(selection.start()); 941 m_insertionStyle = EditingStyle::create(selection.start());
942 m_insertionStyle->mergeTypingStyle(&document()); 942 m_insertionStyle->mergeTypingStyle(&document());
943 } 943 }
944 944
945 VisiblePosition visibleStart = selection.visibleStart(); 945 const VisiblePosition visibleStart = selection.visibleStart();
946 VisiblePosition visibleEnd = selection.visibleEnd(); 946 const VisiblePosition visibleEnd = selection.visibleEnd();
947 947
948 bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); 948 const bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd);
949 bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); 949 const bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleSta rt);
950 950
951 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui valent().anchorNode()); 951 Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEqui valent().anchorNode());
952 952
953 Position insertionPos = selection.start(); 953 const bool startIsInsideMailBlockquote = enclosingNodeOfType(selection.start (), isMailHTMLBlockquoteElement, CanCrossEditingBoundary);
954 bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailH TMLBlockquoteElement, CanCrossEditingBoundary); 954 const bool selectionIsPlainText = !selection.isContentRichlyEditable();
955 bool selectionIsPlainText = !selection.isContentRichlyEditable();
956 Element* currentRoot = selection.rootEditableElement(); 955 Element* currentRoot = selection.rootEditableElement();
957 956
958 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && ! startIsInsideMailBlockquote) 957 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && ! startIsInsideMailBlockquote)
959 || enclosingBlockOfVisibleStart == currentRoot 958 || enclosingBlockOfVisibleStart == currentRoot
960 || isListItem(enclosingBlockOfVisibleStart) 959 || isListItem(enclosingBlockOfVisibleStart)
961 || selectionIsPlainText) { 960 || selectionIsPlainText) {
962 m_preventNesting = false; 961 m_preventNesting = false;
963 } 962 }
964 963
965 if (selection.isRange()) { 964 if (selection.isRange()) {
966 // 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
967 // spans multiple blocks, not merging may leave an empty line. 966 // spans multiple blocks, not merging may leave an empty line.
968 // 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
969 // will leave hanging block(s). 968 // will leave hanging block(s).
970 // 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
971 // that case specially to prevent nesting. 970 // that case specially to prevent nesting.
972 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara graph(visibleEnd) || isStartOfBlock(visibleStart); 971 bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfPara graph(visibleEnd) || isStartOfBlock(visibleStart);
973 // 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
974 // selection and pasting it on top of itself. 973 // selection and pasting it on top of itself.
975 deleteSelection(false, mergeBlocksAfterDelete, false); 974 deleteSelection(false, mergeBlocksAfterDelete, false);
976 visibleStart = endingSelection().visibleStart();
977 if (fragment.hasInterchangeNewlineAtStart()) { 975 if (fragment.hasInterchangeNewlineAtStart()) {
978 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta rt)) { 976 VisiblePosition startAfterDelete = endingSelection().visibleStart();
979 if (!isEndOfEditableOrNonEditableContent(visibleStart)) 977 if (isEndOfParagraph(startAfterDelete) && !isStartOfParagraph(startA fterDelete) && !isEndOfEditableOrNonEditableContent(startAfterDelete))
980 setEndingSelection(nextPositionOf(visibleStart)); 978 setEndingSelection(nextPositionOf(startAfterDelete));
981 } else { 979 else
982 insertParagraphSeparator(); 980 insertParagraphSeparator();
983 }
984 } 981 }
985 insertionPos = endingSelection().start();
986 } else { 982 } else {
987 ASSERT(selection.isCaret()); 983 ASSERT(selection.isCaret());
988 if (fragment.hasInterchangeNewlineAtStart()) { 984 if (fragment.hasInterchangeNewlineAtStart()) {
989 VisiblePosition next = nextPositionOf(visibleStart, CannotCrossEditi ngBoundary); 985 const VisiblePosition next = nextPositionOf(visibleStart, CannotCros sEditingBoundary);
990 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta rt) && next.isNotNull()) { 986 if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleSta rt) && next.isNotNull())
991 setEndingSelection(next); 987 setEndingSelection(next);
992 } else { 988 else
993 insertParagraphSeparator(); 989 insertParagraphSeparator();
994 visibleStart = endingSelection().visibleStart();
995 }
996 } 990 }
997 // We split the current paragraph in two to avoid nesting the blocks fro m the fragment inside the current block. 991 // We split the current paragraph in two to avoid nesting the blocks fro m the fragment inside the current block.
998 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di v>x^x</div>, where ^ is the caret. 992 // For example paste <div>foo</div><div>bar</div><div>baz</div> into <di v>x^x</div>, where ^ is the caret.
999 // As long as the div styles are the same, visually you'd expect: <div> xbar</div><div>bar</div><div>bazx</div>, 993 // As long as the div styles are the same, visually you'd expect: <div> xbar</div><div>bar</div><div>bazx</div>,
1000 // not <div>xbar<div>bar</div><div>bazx</div></div>. 994 // not <div>xbar<div>bar</div><div>bazx</div></div>.
1001 // Don't do this if the selection started in a Mail blockquote. 995 // Don't do this if the selection started in a Mail blockquote.
1002 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap h(visibleStart) && !isStartOfParagraph(visibleStart)) { 996 if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagrap h(endingSelection().visibleStart()) && !isStartOfParagraph(endingSelection().vis ibleStart())) {
1003 insertParagraphSeparator(); 997 insertParagraphSeparator();
1004 setEndingSelection(previousPositionOf(endingSelection().visibleStart ())); 998 setEndingSelection(previousPositionOf(endingSelection().visibleStart ()));
1005 } 999 }
1006 insertionPos = endingSelection().start();
1007 } 1000 }
1008 1001
1002 Position insertionPos = endingSelection().start();
1009 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break 1003 // We don't want any of the pasted content to end up nested in a Mail blockq uote, so first break
1010 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case 1004 // out of any surrounding Mail blockquotes. Unless we're inserting in a tabl e, in which case
1011 // breaking the blockquote will prevent the content from actually being inse rted in the table. 1005 // breaking the blockquote will prevent the content from actually being inse rted in the table.
1012 if (startIsInsideMailBlockquote && m_preventNesting && !(enclosingNodeOfType (insertionPos, &isTableStructureNode))) { 1006 if (enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, CanCrossE ditingBoundary) && m_preventNesting && !(enclosingNodeOfType(insertionPos, &isTa bleStructureNode))) {
1013 applyCommandToComposite(BreakBlockquoteCommand::create(document())); 1007 applyCommandToComposite(BreakBlockquoteCommand::create(document()));
1014 // This will leave a br between the split. 1008 // This will leave a br between the split.
1015 Node* br = endingSelection().start().anchorNode(); 1009 Node* br = endingSelection().start().anchorNode();
1016 ASSERT(isHTMLBRElement(br)); 1010 ASSERT(isHTMLBRElement(br));
1017 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder). 1011 // Insert content between the two blockquotes, but remove the br (since it was just a placeholder).
1018 insertionPos = positionInParentBeforeNode(*br); 1012 insertionPos = positionInParentBeforeNode(*br);
1019 removeNode(br); 1013 removeNode(br);
1020 } 1014 }
1021 1015
1022 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world. 1016 // Inserting content could cause whitespace to collapse, e.g. inserting <div >foo</div> into hello^ world.
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 DEFINE_TRACE(ReplaceSelectionCommand) 1543 DEFINE_TRACE(ReplaceSelectionCommand)
1550 { 1544 {
1551 visitor->trace(m_startOfInsertedContent); 1545 visitor->trace(m_startOfInsertedContent);
1552 visitor->trace(m_endOfInsertedContent); 1546 visitor->trace(m_endOfInsertedContent);
1553 visitor->trace(m_insertionStyle); 1547 visitor->trace(m_insertionStyle);
1554 visitor->trace(m_documentFragment); 1548 visitor->trace(m_documentFragment);
1555 CompositeEditCommand::trace(visitor); 1549 CompositeEditCommand::trace(visitor);
1556 } 1550 }
1557 1551
1558 } // namespace blink 1552 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/editing/execCommand/replace-crossing-mailblockquote-crash.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698