Index: third_party/WebKit/WebCore/editing/DeleteSelectionCommand.cpp |
=================================================================== |
--- third_party/WebKit/WebCore/editing/DeleteSelectionCommand.cpp (revision 5296) |
+++ third_party/WebKit/WebCore/editing/DeleteSelectionCommand.cpp (working copy) |
@@ -79,6 +79,7 @@ |
m_mergeBlocksAfterDelete(mergeBlocksAfterDelete), |
m_replace(replace), |
m_expandForSpecialElements(expandForSpecialElements), |
+ m_pruneStartBlockIfNecessary(false), |
m_startBlock(0), |
m_endBlock(0), |
m_typingStyle(0), |
@@ -93,6 +94,7 @@ |
m_mergeBlocksAfterDelete(mergeBlocksAfterDelete), |
m_replace(replace), |
m_expandForSpecialElements(expandForSpecialElements), |
+ m_pruneStartBlockIfNecessary(false), |
m_selectionToDelete(selection), |
m_startBlock(0), |
m_endBlock(0), |
@@ -189,6 +191,15 @@ |
m_endingPosition = m_downstreamEnd; |
else |
m_endingPosition = m_downstreamStart; |
+ |
+ // We don't want to merge into a block if it will mean changing the quote level of content after deleting |
+ // selections that contain a whole number paragraphs plus a line break, since it is unclear to most users |
+ // that such a selection actually ends at the start of the next paragraph. This matches TextEdit behavior |
+ // for indented paragraphs. |
+ if (numEnclosingMailBlockquotes(start) != numEnclosingMailBlockquotes(end) && isStartOfParagraph(visibleEnd) && isStartOfParagraph(VisiblePosition(start))) { |
+ m_mergeBlocksAfterDelete = false; |
+ m_pruneStartBlockIfNecessary = true; |
+ } |
// Handle leading and trailing whitespace, as well as smart delete adjustments to the selection |
m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition(m_selectionToDelete.affinity()); |
@@ -510,8 +521,21 @@ |
// start together with content after the end. |
void DeleteSelectionCommand::mergeParagraphs() |
{ |
- if (!m_mergeBlocksAfterDelete) |
+ if (!m_mergeBlocksAfterDelete) { |
+ if (m_pruneStartBlockIfNecessary) { |
+ // Make sure that the ending position isn't inside the block we're about to prune. |
+ m_endingPosition = m_downstreamEnd; |
+ // We aren't going to merge into the start block, so remove it if it's empty. |
+ prune(m_upstreamStart.node()); |
+ // Removing the start block during a deletion is usually an indication that we need |
+ // a placeholder, but not in this case. |
+ m_needPlaceholder = false; |
+ } |
return; |
+ } |
+ |
+ // It shouldn't have been asked to both try and merge content into the start block and prune it. |
+ ASSERT(!m_pruneStartBlockIfNecessary); |
// FIXME: Deletion should adjust selection endpoints as it removes nodes so that we never get into this state (4099839). |
if (!m_downstreamEnd.node()->inDocument() || !m_upstreamStart.node()->inDocument()) |