Index: third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp |
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp |
index eb5383d706d19e09534264c5ed0c7aa97cdb5380..45824f2d01d48b6760203070e9a5664a6d0ceaf4 100644 |
--- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp |
+++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp |
@@ -633,7 +633,7 @@ static bool isProhibitedParagraphChild(const AtomicString& name) |
return elements.contains(name); |
} |
-void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes& insertedNodes) |
+void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes& insertedNodes, EditingState* editingState) |
{ |
RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); |
RefPtrWillBeRawPtr<Node> next = nullptr; |
@@ -649,18 +649,24 @@ void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild |
HTMLElement& element = toHTMLElement(*node); |
if (isProhibitedParagraphChild(element.localName())) { |
- if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWithTag(positionInParentBeforeNode(element), pTag))) |
- moveElementOutOfAncestor(&element, paragraphElement); |
+ if (HTMLElement* paragraphElement = toHTMLElement(enclosingElementWithTag(positionInParentBeforeNode(element), pTag))) { |
+ moveElementOutOfAncestor(&element, paragraphElement, editingState); |
+ if (editingState->isAborted()) |
+ return; |
+ } |
} |
if (isHTMLHeaderElement(&element)) { |
- if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(element), isHTMLHeaderElement))) |
- moveElementOutOfAncestor(&element, headerElement); |
+ if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(element), isHTMLHeaderElement))) { |
+ moveElementOutOfAncestor(&element, headerElement, editingState); |
+ if (editingState->isAborted()) |
+ return; |
+ } |
} |
} |
} |
-void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<Element> prpElement, PassRefPtrWillBeRawPtr<Element> prpAncestor) |
+void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<Element> prpElement, PassRefPtrWillBeRawPtr<Element> prpAncestor, EditingState* editingState) |
{ |
RefPtrWillBeRawPtr<Element> element = prpElement; |
RefPtrWillBeRawPtr<Element> ancestor = prpAncestor; |
@@ -671,18 +677,26 @@ void ReplaceSelectionCommand::moveElementOutOfAncestor(PassRefPtrWillBeRawPtr<El |
VisiblePosition positionAtEndOfNode = createVisiblePosition(lastPositionInOrAfterNode(element.get())); |
VisiblePosition lastPositionInParagraph = createVisiblePosition(lastPositionInNode(ancestor.get())); |
if (positionAtEndOfNode.deepEquivalent() == lastPositionInParagraph.deepEquivalent()) { |
- removeNode(element); |
+ removeNode(element, editingState); |
+ if (editingState->isAborted()) |
+ return; |
if (ancestor->nextSibling()) |
- insertNodeBefore(element, ancestor->nextSibling()); |
+ insertNodeBefore(element, ancestor->nextSibling(), editingState); |
else |
- appendNode(element, ancestor->parentNode()); |
+ appendNode(element, ancestor->parentNode(), editingState); |
+ if (editingState->isAborted()) |
+ return; |
} else { |
RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(element.get(), ancestor.get(), true); |
- removeNode(element); |
- insertNodeBefore(element, nodeToSplitTo); |
+ removeNode(element, editingState); |
+ if (editingState->isAborted()) |
+ return; |
+ insertNodeBefore(element, nodeToSplitTo, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
if (!ancestor->hasChildren()) |
- removeNode(ancestor.release()); |
+ removeNode(ancestor.release(), editingState); |
} |
static inline bool nodeHasVisibleLayoutText(Text& text) |
@@ -699,7 +713,8 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins |
&& !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag) |
&& !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) { |
insertedNodes.willRemoveNode(*lastLeafInserted); |
- removeNode(lastLeafInserted); |
+ // Removing a Text node won't dispatch synchronous events. |
+ removeNode(lastLeafInserted, ASSERT_NO_EDITING_ABORT); |
} |
// We don't have to make sure that firstNodeInserted isn't inside a select or script element, because |
@@ -707,7 +722,8 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins |
Node* firstNodeInserted = insertedNodes.firstNodeInserted(); |
if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleLayoutText(toText(*firstNodeInserted))) { |
insertedNodes.willRemoveNode(*firstNodeInserted); |
- removeNode(firstNodeInserted); |
+ // Removing a Text node won't dispatch synchronous events. |
+ removeNode(firstNodeInserted, ASSERT_NO_EDITING_ABORT); |
} |
} |
@@ -932,7 +948,10 @@ void ReplaceSelectionCommand::doApply(EditingState* editingState) |
return; |
ReplacementFragment fragment(&document(), m_documentFragment.get(), selection); |
- if (performTrivialReplace(fragment)) |
+ bool trivialReplaceResult = performTrivialReplace(fragment, editingState); |
+ if (editingState->isAborted()) |
+ return; |
+ if (trivialReplaceResult) |
return; |
// We can skip matching the style if the selection is plain text. |
@@ -1015,7 +1034,9 @@ void ReplaceSelectionCommand::doApply(EditingState* editingState) |
ASSERT(isHTMLBRElement(br)); |
// Insert content between the two blockquotes, but remove the br (since it was just a placeholder). |
insertionPos = positionInParentBeforeNode(*br); |
- removeNode(br); |
+ removeNode(br, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
// Inserting content could cause whitespace to collapse, e.g. inserting <div>foo</div> into hello^ world. |
@@ -1170,14 +1191,20 @@ void ReplaceSelectionCommand::doApply(EditingState* editingState) |
if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosBeforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)))) { |
RefPtrWillBeRawPtr<ContainerNode> parent = endBR->parentNode(); |
insertedNodes.willRemoveNode(*endBR); |
- removeNode(endBR); |
+ removeNode(endBR, editingState); |
+ if (editingState->isAborted()) |
+ return; |
if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { |
insertedNodes.willRemoveNode(*nodeToRemove); |
- removeNode(nodeToRemove); |
+ removeNode(nodeToRemove, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
} |
- makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); |
+ makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes, editingState); |
+ if (editingState->isAborted()) |
+ return; |
removeRedundantStylesAndKeepStyleSpanInline(insertedNodes); |
@@ -1268,7 +1295,7 @@ void ReplaceSelectionCommand::doApply(EditingState* editingState) |
if (plainTextFragment) |
m_matchStyle = false; |
- completeHTMLReplacement(lastPositionToSelect); |
+ completeHTMLReplacement(lastPositionToSelect, editingState); |
} |
bool ReplaceSelectionCommand::shouldRemoveEndBR(HTMLBRElement* endBR, const VisiblePosition& originalVisPosBeforeEndBR) |
@@ -1362,7 +1389,7 @@ void ReplaceSelectionCommand::addSpacesForSmartReplace() |
} |
} |
-void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositionToSelect) |
+void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositionToSelect, EditingState* editingState) |
{ |
Position start = positionAtStartOfInsertedContent().deepEquivalent(); |
Position end = positionAtEndOfInsertedContent().deepEquivalent(); |
@@ -1381,7 +1408,9 @@ void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi |
if (lastPositionToSelect.isNotNull()) |
end = lastPositionToSelect; |
- mergeTextNodesAroundPosition(start, end); |
+ mergeTextNodesAroundPosition(start, end, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} else if (lastPositionToSelect.isNotNull()) { |
start = end = lastPositionToSelect; |
} else { |
@@ -1397,7 +1426,7 @@ void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi |
setEndingSelection(VisibleSelection(end, SelDefaultAffinity, endingSelection().isDirectional())); |
} |
-void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, Position& positionOnlyToBeUpdated) |
+void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, Position& positionOnlyToBeUpdated, EditingState* editingState) |
{ |
bool positionIsOffsetInAnchor = position.isOffsetInAnchor(); |
bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.isOffsetInAnchor(); |
@@ -1435,7 +1464,9 @@ void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P |
updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous); |
} |
- removeNode(previous); |
+ removeNode(previous, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
if (text->nextSibling() && text->nextSibling()->isTextNode()) { |
RefPtrWillBeRawPtr<Text> next = toText(text->nextSibling()); |
@@ -1450,7 +1481,9 @@ void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P |
else |
updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next); |
- removeNode(next); |
+ removeNode(next, editingState); |
+ if (editingState->isAborted()) |
+ return; |
} |
} |
@@ -1517,7 +1550,7 @@ void ReplaceSelectionCommand::updateNodesInserted(Node *node) |
// directly into the text node that holds the selection. This is much faster than the generalized code in |
// ReplaceSelectionCommand, and works around <https://bugs.webkit.org/show_bug.cgi?id=6148> since we don't |
// split text nodes. |
-bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& fragment) |
+bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& fragment, EditingState* editingState) |
{ |
if (!fragment.firstChild() || fragment.firstChild() != fragment.lastChild() || !fragment.firstChild()->isTextNode()) |
return false; |
@@ -1540,8 +1573,11 @@ bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f |
return false; |
if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBRElement(*nodeAfterInsertionPos) |
- && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), createVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) |
- removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); |
+ && shouldRemoveEndBR(toHTMLBRElement(nodeAfterInsertionPos.get()), createVisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get())))) { |
+ removeNodeAndPruneAncestors(nodeAfterInsertionPos.get(), editingState); |
+ if (editingState->isAborted()) |
+ return false; |
+ } |
m_startOfInsertedRange = start; |
m_endOfInsertedRange = end; |