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

Side by Side Diff: Source/WebCore/editing/DeleteSelectionCommand.cpp

Issue 13954003: Remove mail blockquote special case handling. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. 2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete) 76 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete)
77 , m_needPlaceholder(false) 77 , m_needPlaceholder(false)
78 , m_replace(replace) 78 , m_replace(replace)
79 , m_expandForSpecialElements(expandForSpecialElements) 79 , m_expandForSpecialElements(expandForSpecialElements)
80 , m_pruneStartBlockIfNecessary(false) 80 , m_pruneStartBlockIfNecessary(false)
81 , m_startsAtEmptyLine(false) 81 , m_startsAtEmptyLine(false)
82 , m_sanitizeMarkup(sanitizeMarkup) 82 , m_sanitizeMarkup(sanitizeMarkup)
83 , m_startBlock(0) 83 , m_startBlock(0)
84 , m_endBlock(0) 84 , m_endBlock(0)
85 , m_typingStyle(0) 85 , m_typingStyle(0)
86 , m_deleteIntoBlockquoteStyle(0)
87 { 86 {
88 } 87 }
89 88
90 DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection , bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpe cialElements, bool sanitizeMarkup) 89 DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection , bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpe cialElements, bool sanitizeMarkup)
91 : CompositeEditCommand(selection.start().anchorNode()->document()) 90 : CompositeEditCommand(selection.start().anchorNode()->document())
92 , m_hasSelectionToDelete(true) 91 , m_hasSelectionToDelete(true)
93 , m_smartDelete(smartDelete) 92 , m_smartDelete(smartDelete)
94 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete) 93 , m_mergeBlocksAfterDelete(mergeBlocksAfterDelete)
95 , m_needPlaceholder(false) 94 , m_needPlaceholder(false)
96 , m_replace(replace) 95 , m_replace(replace)
97 , m_expandForSpecialElements(expandForSpecialElements) 96 , m_expandForSpecialElements(expandForSpecialElements)
98 , m_pruneStartBlockIfNecessary(false) 97 , m_pruneStartBlockIfNecessary(false)
99 , m_startsAtEmptyLine(false) 98 , m_startsAtEmptyLine(false)
100 , m_sanitizeMarkup(sanitizeMarkup) 99 , m_sanitizeMarkup(sanitizeMarkup)
101 , m_selectionToDelete(selection) 100 , m_selectionToDelete(selection)
102 , m_startBlock(0) 101 , m_startBlock(0)
103 , m_endBlock(0) 102 , m_endBlock(0)
104 , m_typingStyle(0) 103 , m_typingStyle(0)
105 , m_deleteIntoBlockquoteStyle(0)
106 { 104 {
107 } 105 }
108 106
109 void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end) 107 void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
110 { 108 {
111 Node* startSpecialContainer = 0; 109 Node* startSpecialContainer = 0;
112 Node* endSpecialContainer = 0; 110 Node* endSpecialContainer = 0;
113 111
114 start = m_selectionToDelete.start(); 112 start = m_selectionToDelete.start();
115 end = m_selectionToDelete.end(); 113 end = m_selectionToDelete.end();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 200
203 // Usually the start and the end of the selection to delete are pulled toget her as a result of the deletion. 201 // Usually the start and the end of the selection to delete are pulled toget her as a result of the deletion.
204 // Sometimes they aren't (like when no merge is requested), so we must choos e one position to hold the caret 202 // Sometimes they aren't (like when no merge is requested), so we must choos e one position to hold the caret
205 // and receive the placeholder after deletion. 203 // and receive the placeholder after deletion.
206 VisiblePosition visibleEnd(m_downstreamEnd); 204 VisiblePosition visibleEnd(m_downstreamEnd);
207 if (m_mergeBlocksAfterDelete && !isEndOfParagraph(visibleEnd)) 205 if (m_mergeBlocksAfterDelete && !isEndOfParagraph(visibleEnd))
208 m_endingPosition = m_downstreamEnd; 206 m_endingPosition = m_downstreamEnd;
209 else 207 else
210 m_endingPosition = m_downstreamStart; 208 m_endingPosition = m_downstreamStart;
211 209
212 // We don't want to merge into a block if it will mean changing the quote le vel of content after deleting
213 // selections that contain a whole number paragraphs plus a line break, sinc e it is unclear to most users
214 // that such a selection actually ends at the start of the next paragraph. T his matches TextEdit behavior
215 // for indented paragraphs.
216 // Only apply this rule if the endingSelection is a range selection. If it is a caret, then other operations have created
217 // the selection we're deleting (like the process of creating a selection to delete during a backspace), and the user isn't in the situation described above .
218 if (numEnclosingMailBlockquotes(start) != numEnclosingMailBlockquotes(end)
219 && isStartOfParagraph(visibleEnd) && isStartOfParagraph(VisiblePosit ion(start))
220 && endingSelection().isRange()) {
221 m_mergeBlocksAfterDelete = false;
222 m_pruneStartBlockIfNecessary = true;
223 }
224
225 // Handle leading and trailing whitespace, as well as smart delete adjustmen ts to the selection 210 // Handle leading and trailing whitespace, as well as smart delete adjustmen ts to the selection
226 m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition(m_selectionT oDelete.affinity()); 211 m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition(m_selectionT oDelete.affinity());
227 m_trailingWhitespace = m_downstreamEnd.trailingWhitespacePosition(VP_DEFAULT _AFFINITY); 212 m_trailingWhitespace = m_downstreamEnd.trailingWhitespacePosition(VP_DEFAULT _AFFINITY);
228 213
229 if (m_smartDelete) { 214 if (m_smartDelete) {
230 215
231 // skip smart delete if the selection to delete already starts or ends w ith whitespace 216 // skip smart delete if the selection to delete already starts or ends w ith whitespace
232 Position pos = VisiblePosition(m_upstreamStart, m_selectionToDelete.affi nity()).deepEquivalent(); 217 Position pos = VisiblePosition(m_upstreamStart, m_selectionToDelete.affi nity()).deepEquivalent();
233 bool skipSmartDelete = pos.trailingWhitespacePosition(VP_DEFAULT_AFFINIT Y, true).isNotNull(); 218 bool skipSmartDelete = pos.trailingWhitespacePosition(VP_DEFAULT_AFFINIT Y, true).isNotNull();
234 if (!skipSmartDelete) 219 if (!skipSmartDelete)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 // two positions will be identical). Therefore there is no need to save the 265 // two positions will be identical). Therefore there is no need to save the
281 // typing style at the start of the selection, nor is there a reason to 266 // typing style at the start of the selection, nor is there a reason to
282 // compute the style at the start of the selection after deletion (see the 267 // compute the style at the start of the selection after deletion (see the
283 // early return in calculateTypingStyleAfterDelete). 268 // early return in calculateTypingStyleAfterDelete).
284 if (m_upstreamStart.deprecatedNode() == m_downstreamEnd.deprecatedNode() && m_upstreamStart.deprecatedNode()->isTextNode()) 269 if (m_upstreamStart.deprecatedNode() == m_downstreamEnd.deprecatedNode() && m_upstreamStart.deprecatedNode()->isTextNode())
285 return; 270 return;
286 271
287 // Figure out the typing style in effect before the delete is done. 272 // Figure out the typing style in effect before the delete is done.
288 m_typingStyle = EditingStyle::create(m_selectionToDelete.start()); 273 m_typingStyle = EditingStyle::create(m_selectionToDelete.start());
289 m_typingStyle->removeStyleAddedByNode(enclosingAnchorElement(m_selectionToDe lete.start())); 274 m_typingStyle->removeStyleAddedByNode(enclosingAnchorElement(m_selectionToDe lete.start()));
290
291 // If we're deleting into a Mail blockquote, save the style at end() instead of start()
292 // We'll use this later in computeTypingStyleAfterDelete if we end up outsid e of a Mail blockquote
293 if (enclosingNodeOfType(m_selectionToDelete.start(), isMailBlockquote))
294 m_deleteIntoBlockquoteStyle = EditingStyle::create(m_selectionToDelete.e nd());
295 else
296 m_deleteIntoBlockquoteStyle = 0;
297 } 275 }
298 276
299 bool DeleteSelectionCommand::handleSpecialCaseBRDelete() 277 bool DeleteSelectionCommand::handleSpecialCaseBRDelete()
300 { 278 {
301 Node* nodeAfterUpstreamStart = m_upstreamStart.computeNodeAfterPosition(); 279 Node* nodeAfterUpstreamStart = m_upstreamStart.computeNodeAfterPosition();
302 Node* nodeAfterDownstreamStart = m_downstreamStart.computeNodeAfterPosition( ); 280 Node* nodeAfterDownstreamStart = m_downstreamStart.computeNodeAfterPosition( );
303 // Upstream end will appear before BR due to canonicalization 281 // Upstream end will appear before BR due to canonicalization
304 Node* nodeAfterUpstreamEnd = m_upstreamEnd.computeNodeAfterPosition(); 282 Node* nodeAfterUpstreamEnd = m_upstreamEnd.computeNodeAfterPosition();
305 283
306 if (!nodeAfterUpstreamStart || !nodeAfterDownstreamStart) 284 if (!nodeAfterUpstreamStart || !nodeAfterDownstreamStart)
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 { 680 {
703 if (!m_typingStyle) 681 if (!m_typingStyle)
704 return; 682 return;
705 683
706 // Compute the difference between the style before the delete and the style now 684 // Compute the difference between the style before the delete and the style now
707 // after the delete has been done. Set this style on the frame, so other edi ting 685 // after the delete has been done. Set this style on the frame, so other edi ting
708 // commands being composed with this one will work, and also cache it on the command, 686 // commands being composed with this one will work, and also cache it on the command,
709 // so the Frame::appliedEditing can set it after the whole composite command 687 // so the Frame::appliedEditing can set it after the whole composite command
710 // has completed. 688 // has completed.
711 689
712 // If we deleted into a blockquote, but are now no longer in a blockquote, u se the alternate typing style
713 if (m_deleteIntoBlockquoteStyle && !enclosingNodeOfType(m_endingPosition, is MailBlockquote, CanCrossEditingBoundary))
714 m_typingStyle = m_deleteIntoBlockquoteStyle;
715 m_deleteIntoBlockquoteStyle = 0;
716
717 m_typingStyle->prepareToApplyAt(m_endingPosition); 690 m_typingStyle->prepareToApplyAt(m_endingPosition);
718 if (m_typingStyle->isEmpty()) 691 if (m_typingStyle->isEmpty())
719 m_typingStyle = 0; 692 m_typingStyle = 0;
720 // This is where we've deleted all traces of a style but not a whole paragra ph (that's handled above). 693 // This is where we've deleted all traces of a style but not a whole paragra ph (that's handled above).
721 // In this case if we start typing, the new characters should have the same style as the just deleted ones, 694 // In this case if we start typing, the new characters should have the same style as the just deleted ones,
722 // but, if we change the selection, come back and start typing that style sh ould be lost. Also see 695 // but, if we change the selection, come back and start typing that style sh ould be lost. Also see
723 // preserveTypingStyle() below. 696 // preserveTypingStyle() below.
724 document()->frame()->selection()->setTypingStyle(m_typingStyle); 697 document()->frame()->selection()->setTypingStyle(m_typingStyle);
725 } 698 }
726 699
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 844
872 // Normally deletion doesn't preserve the typing style that was present before i t. For example, 845 // Normally deletion doesn't preserve the typing style that was present before i t. For example,
873 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't 846 // type a character, Bold, then delete the character and start typing. The Bold typing style shouldn't
874 // stick around. Deletion should preserve a typing style that *it* sets, howeve r. 847 // stick around. Deletion should preserve a typing style that *it* sets, howeve r.
875 bool DeleteSelectionCommand::preservesTypingStyle() const 848 bool DeleteSelectionCommand::preservesTypingStyle() const
876 { 849 {
877 return m_typingStyle; 850 return m_typingStyle;
878 } 851 }
879 852
880 } // namespace WebCore 853 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698