Index: third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp |
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp |
index cd8700f785f2f72e0c3f849ff87bd83f2883257e..da914f134bd834f66c6b1ef75cd16f597d7eba7d 100644 |
--- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp |
+++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp |
@@ -300,7 +300,7 @@ void DeleteSelectionCommand::saveTypingStyleState() |
m_deleteIntoBlockquoteStyle = nullptr; |
} |
-bool DeleteSelectionCommand::handleSpecialCaseBRDelete() |
+bool DeleteSelectionCommand::handleSpecialCaseBRDelete(EditingState* editingState) |
{ |
Node* nodeAfterUpstreamStart = m_upstreamStart.computeNodeAfterPosition(); |
Node* nodeAfterDownstreamStart = m_downstreamStart.computeNodeAfterPosition(); |
@@ -315,7 +315,7 @@ bool DeleteSelectionCommand::handleSpecialCaseBRDelete() |
bool downstreamStartIsBR = isHTMLBRElement(*nodeAfterDownstreamStart); |
bool isBROnLineByItself = upstreamStartIsBR && downstreamStartIsBR && nodeAfterDownstreamStart == nodeAfterUpstreamEnd; |
if (isBROnLineByItself) { |
- removeNode(nodeAfterDownstreamStart); |
+ removeNode(nodeAfterDownstreamStart, editingState); |
return true; |
} |
@@ -431,7 +431,7 @@ void DeleteSelectionCommand::deleteTextFromNode(PassRefPtrWillBeRawPtr<Text> nod |
CompositeEditCommand::deleteTextFromNode(node, offset, count); |
} |
-void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss() |
+void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(EditingState* editingState) |
{ |
RefPtrWillBeRawPtr<Range> range = createRange(m_selectionToDelete.toNormalizedEphemeralRange()); |
RefPtrWillBeRawPtr<Node> node = range->firstNode(); |
@@ -441,8 +441,12 @@ void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPr |
nextNode = NodeTraversal::nextSkippingChildren(*node); |
RefPtrWillBeRawPtr<Element> rootEditableElement = node->rootEditableElement(); |
if (rootEditableElement.get()) { |
- removeNode(node); |
- appendNode(node, rootEditableElement); |
+ removeNode(node, editingState); |
+ if (editingState->isAborted()) |
+ return; |
+ appendNode(node, rootEditableElement, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
} |
node = nextNode; |
@@ -458,7 +462,9 @@ void DeleteSelectionCommand::handleGeneralDelete(EditingState* editingState) |
Node* startNode = m_upstreamStart.anchorNode(); |
ASSERT(startNode); |
- makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(); |
+ makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(editingState); |
+ if (editingState->isAborted()) |
+ return; |
// Never remove the start block unless it's a table, in which case we won't merge content in. |
if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChildrenForEditing(startNode) && !isHTMLTableElement(*startNode)) { |
@@ -490,7 +496,9 @@ void DeleteSelectionCommand::handleGeneralDelete(EditingState* editingState) |
Text* text = toText(startNode); |
deleteTextFromNode(text, startOffset, m_downstreamEnd.computeOffsetInContainerNode() - startOffset); |
} else { |
- removeChildrenInRange(startNode, startOffset, m_downstreamEnd.computeEditingOffset()); |
+ removeChildrenInRange(startNode, startOffset, m_downstreamEnd.computeEditingOffset(), editingState); |
+ if (editingState->isAborted()) |
+ return; |
m_endingPosition = m_upstreamStart; |
} |
} |
@@ -573,7 +581,9 @@ void DeleteSelectionCommand::handleGeneralDelete(EditingState* editingState) |
if (n) |
offset = n->nodeIndex() + 1; |
} |
- removeChildrenInRange(m_downstreamEnd.anchorNode(), offset, m_downstreamEnd.computeEditingOffset()); |
+ removeChildrenInRange(m_downstreamEnd.anchorNode(), offset, m_downstreamEnd.computeEditingOffset(), editingState); |
+ if (editingState->isAborted()) |
+ return; |
m_downstreamEnd = Position::editingPositionOf(m_downstreamEnd.anchorNode(), offset); |
} |
} |
@@ -601,12 +611,14 @@ void DeleteSelectionCommand::fixupWhitespace() |
// If a selection starts in one block and ends in another, we have to merge to bring content before the |
// start together with content after the end. |
-void DeleteSelectionCommand::mergeParagraphs() |
+void DeleteSelectionCommand::mergeParagraphs(EditingState* editingState) |
{ |
if (!m_mergeBlocksAfterDelete) { |
if (m_pruneStartBlockIfNecessary) { |
// We aren't going to merge into the start block, so remove it if it's empty. |
- prune(m_startBlock); |
+ prune(m_startBlock, editingState); |
+ if (editingState->isAborted()) |
+ return; |
// Removing the start block during a deletion is usually an indication that we need |
// a placeholder, but not in this case. |
m_needPlaceholder = false; |
@@ -636,13 +648,15 @@ void DeleteSelectionCommand::mergeParagraphs() |
// move, so just remove it. |
Element* endBlock = enclosingBlock(m_downstreamEnd.anchorNode()); |
if (!endBlock || !endBlock->contains(startOfParagraphToMove.deepEquivalent().anchorNode()) || !startOfParagraphToMove.deepEquivalent().anchorNode()) { |
- removeNode(enclosingBlock(m_downstreamEnd.anchorNode())); |
+ removeNode(enclosingBlock(m_downstreamEnd.anchorNode()), editingState); |
return; |
} |
// We need to merge into m_upstreamStart's block, but it's been emptied out and collapsed by deletion. |
if (!mergeDestination.deepEquivalent().anchorNode() || (!mergeDestination.deepEquivalent().anchorNode()->isDescendantOf(enclosingBlock(m_upstreamStart.computeContainerNode())) && (!mergeDestination.deepEquivalent().anchorNode()->hasChildren() || !m_upstreamStart.computeContainerNode()->hasChildren())) || (m_startsAtEmptyLine && mergeDestination.deepEquivalent() != startOfParagraphToMove.deepEquivalent())) { |
- insertNodeAt(HTMLBRElement::create(document()).get(), m_upstreamStart); |
+ insertNodeAt(HTMLBRElement::create(document()).get(), m_upstreamStart, editingState); |
+ if (editingState->isAborted()) |
+ return; |
mergeDestination = createVisiblePosition(m_upstreamStart); |
} |
@@ -660,7 +674,9 @@ void DeleteSelectionCommand::mergeParagraphs() |
if (listItemInFirstParagraph && listItemInSecondParagraph |
&& listItemInFirstParagraph->parentElement() != listItemInSecondParagraph->parentElement() |
&& canMergeLists(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement())) { |
- mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement()); |
+ mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement(), editingState); |
+ if (editingState->isAborted()) |
+ return; |
m_endingPosition = mergeDestination.deepEquivalent(); |
return; |
} |
@@ -669,7 +685,9 @@ void DeleteSelectionCommand::mergeParagraphs() |
// FIXME: Consider RTL. |
if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && absoluteCaretBoundsOf(startOfParagraphToMove).x() > absoluteCaretBoundsOf(mergeDestination).x()) { |
if (isHTMLBRElement(*mostForwardCaretPosition(mergeDestination.deepEquivalent()).anchorNode())) { |
- removeNodeAndPruneAncestors(mostForwardCaretPosition(mergeDestination.deepEquivalent()).anchorNode()); |
+ removeNodeAndPruneAncestors(mostForwardCaretPosition(mergeDestination.deepEquivalent()).anchorNode(), editingState); |
+ if (editingState->isAborted()) |
+ return; |
m_endingPosition = startOfParagraphToMove.deepEquivalent(); |
return; |
} |
@@ -687,13 +705,15 @@ void DeleteSelectionCommand::mergeParagraphs() |
// removals that it does cause the insertion of *another* placeholder. |
bool needPlaceholder = m_needPlaceholder; |
bool paragraphToMergeIsEmpty = startOfParagraphToMove.deepEquivalent() == endOfParagraphToMove.deepEquivalent(); |
- moveParagraph(startOfParagraphToMove, endOfParagraphToMove, mergeDestination, ASSERT_NO_EDITING_ABORT, false, !paragraphToMergeIsEmpty); |
+ moveParagraph(startOfParagraphToMove, endOfParagraphToMove, mergeDestination, editingState, false, !paragraphToMergeIsEmpty); |
+ if (editingState->isAborted()) |
+ return; |
m_needPlaceholder = needPlaceholder; |
// The endingPosition was likely clobbered by the move, so recompute it (moveParagraph selects the moved paragraph). |
m_endingPosition = endingSelection().start(); |
} |
-void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows() |
+void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows(EditingState* editingState) |
{ |
if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_startTableRow) { |
Node* row = m_endTableRow->previousSibling(); |
@@ -703,7 +723,9 @@ void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows() |
// Use a raw removeNode, instead of DeleteSelectionCommand's, |
// because that won't remove rows, it only empties them in |
// preparation for this function. |
- CompositeEditCommand::removeNode(row); |
+ CompositeEditCommand::removeNode(row, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
row = previousRow.get(); |
} |
@@ -714,8 +736,11 @@ void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows() |
Node* row = m_startTableRow->nextSibling(); |
while (row && row != m_endTableRow) { |
RefPtrWillBeRawPtr<Node> nextRow = row->nextSibling(); |
- if (isTableRowEmpty(row)) |
- CompositeEditCommand::removeNode(row); |
+ if (isTableRowEmpty(row)) { |
+ CompositeEditCommand::removeNode(row, editingState); |
+ if (editingState->isAborted()) |
+ return; |
+ } |
row = nextRow.get(); |
} |
} |
@@ -729,7 +754,9 @@ void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows() |
// fully selected, even if it is empty. We'll need to start |
// adjusting the selection endpoints during deletion to know |
// whether or not m_endTableRow was fully selected here. |
- CompositeEditCommand::removeNode(m_endTableRow.get()); |
+ CompositeEditCommand::removeNode(m_endTableRow.get(), editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
} |
} |
@@ -842,7 +869,10 @@ void DeleteSelectionCommand::doApply(EditingState* editingState) |
// deleting just a BR is handled specially, at least because we do not |
// want to replace it with a placeholder BR! |
- if (handleSpecialCaseBRDelete()) { |
+ bool brResult = handleSpecialCaseBRDelete(editingState); |
+ if (editingState->isAborted()) |
+ return; |
+ if (brResult) { |
calculateTypingStyleAfterDelete(); |
setEndingSelection(VisibleSelection(m_endingPosition, affinity, endingSelection().isDirectional())); |
clearTransientState(); |
@@ -856,9 +886,13 @@ void DeleteSelectionCommand::doApply(EditingState* editingState) |
fixupWhitespace(); |
- mergeParagraphs(); |
+ mergeParagraphs(editingState); |
+ if (editingState->isAborted()) |
+ return; |
- removePreviouslySelectedEmptyTableRows(); |
+ removePreviouslySelectedEmptyTableRows(editingState); |
+ if (editingState->isAborted()) |
+ return; |
if (!m_needPlaceholder && rootWillStayOpenWithoutPlaceholder) { |
VisiblePosition visualEnding = createVisiblePosition(m_endingPosition); |