summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp5
-rw-r--r--third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h2
-rw-r--r--third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp35
-rw-r--r--third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h4
-rw-r--r--third_party/WebKit/Source/core/editing/commands/RemoveNodeCommand.cpp8
-rw-r--r--third_party/WebKit/Source/core/editing/commands/RemoveNodePreservingChildrenCommand.cpp4
-rw-r--r--third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp6
-rw-r--r--third_party/WebKit/Source/core/editing/commands/SimplifyMarkupCommand.cpp4
8 files changed, 45 insertions, 23 deletions
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
index 875db7a..9d9f8b5 100644
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -398,11 +398,12 @@ void CompositeEditCommand::removeChildrenInRange(PassRefPtrWillBeRawPtr<Node> no
removeNode(children[i].release());
}
-void CompositeEditCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+void CompositeEditCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, EditingState* editingState, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
if (!node || !node->nonShadowBoundaryParentNode())
return;
- applyCommandToComposite(RemoveNodeCommand::create(node, shouldAssumeContentIsAlwaysEditable));
+ ASSERT_IN_EDITING_COMMAND(node->document().frame());
+ applyCommandToComposite(RemoveNodeCommand::create(node, shouldAssumeContentIsAlwaysEditable), editingState);
}
void CompositeEditCommand::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node> node, EditingState* editingState, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h
index 3d97058..1a2a929 100644
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.h
@@ -125,7 +125,7 @@ protected:
void removeCSSProperty(PassRefPtrWillBeRawPtr<Element>, CSSPropertyID);
void removeElementAttribute(PassRefPtrWillBeRawPtr<Element>, const QualifiedName& attribute);
void removeChildrenInRange(PassRefPtrWillBeRawPtr<Node>, unsigned from, unsigned to);
- virtual void removeNode(PassRefPtrWillBeRawPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
+ virtual void removeNode(PassRefPtrWillBeRawPtr<Node>, EditingState* = ASSERT_NO_EDITING_ABORT, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
HTMLSpanElement* replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtrWillBeRawPtr<HTMLElement>);
void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node>, EditingState* = ASSERT_NO_EDITING_ABORT, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
void removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<Node>, Node* excludeNode = nullptr);
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
index a62632f..cd8700f 100644
--- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
@@ -338,7 +338,7 @@ static Position firstEditablePositionInNode(Node* node)
return next ? firstPositionInOrBeforeNode(next) : Position();
}
-void DeleteSelectionCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+void DeleteSelectionCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, EditingState* editingState, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
if (!node)
return;
@@ -353,7 +353,9 @@ void DeleteSelectionCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, Shoul
RefPtrWillBeRawPtr<Node> child = node->firstChild();
while (child) {
RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling();
- removeNode(child.get(), shouldAssumeContentIsAlwaysEditable);
+ removeNode(child.get(), editingState, shouldAssumeContentIsAlwaysEditable);
+ if (editingState->isAborted())
+ return;
// Bail if nextChild is no longer node's child.
if (nextChild && nextChild->parentNode() != node)
return;
@@ -372,7 +374,9 @@ void DeleteSelectionCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, Shoul
while (child) {
Node* remove = child;
child = child->nextSibling();
- removeNode(remove, shouldAssumeContentIsAlwaysEditable);
+ removeNode(remove, editingState, shouldAssumeContentIsAlwaysEditable);
+ if (editingState->isAborted())
+ return;
}
// Make sure empty cell has some height, if a placeholder can be inserted.
@@ -402,7 +406,7 @@ void DeleteSelectionCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, Shoul
updatePositionForNodeRemoval(m_leadingWhitespace, *node);
updatePositionForNodeRemoval(m_trailingWhitespace, *node);
- CompositeEditCommand::removeNode(node, shouldAssumeContentIsAlwaysEditable);
+ CompositeEditCommand::removeNode(node, editingState, shouldAssumeContentIsAlwaysEditable);
}
static void updatePositionForTextRemoval(Text* node, int offset, int count, Position& position)
@@ -445,7 +449,7 @@ void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPr
}
}
-void DeleteSelectionCommand::handleGeneralDelete()
+void DeleteSelectionCommand::handleGeneralDelete(EditingState* editingState)
{
if (m_upstreamStart.isNull())
return;
@@ -492,8 +496,11 @@ void DeleteSelectionCommand::handleGeneralDelete()
}
// The selection to delete is all in one node.
- if (!startNode->layoutObject() || (!startOffset && m_downstreamEnd.atLastEditingPositionForNode()))
- removeNode(startNode);
+ if (!startNode->layoutObject() || (!startOffset && m_downstreamEnd.atLastEditingPositionForNode())) {
+ removeNode(startNode, editingState);
+ if (editingState->isAborted())
+ return;
+ }
} else {
bool startNodeWasDescendantOfEndNode = m_upstreamStart.anchorNode()->isDescendantOf(m_downstreamEnd.anchorNode());
// The selection to delete spans more than one node.
@@ -523,12 +530,16 @@ void DeleteSelectionCommand::handleGeneralDelete()
// if we just removed a node from the end container, update end position so the
// check above will work
updatePositionForNodeRemoval(m_downstreamEnd, *node);
- removeNode(node.get());
+ removeNode(node.get(), editingState);
+ if (editingState->isAborted())
+ return;
node = nextNode.get();
} else {
Node& n = NodeTraversal::lastWithinOrSelf(*node);
if (m_downstreamEnd.anchorNode() == n && m_downstreamEnd.computeEditingOffset() >= caretMaxOffset(&n)) {
- removeNode(node.get());
+ removeNode(node.get(), editingState);
+ if (editingState->isAborted())
+ return;
node = nullptr;
} else {
node = NodeTraversal::next(*node);
@@ -539,7 +550,7 @@ void DeleteSelectionCommand::handleGeneralDelete()
if (m_downstreamEnd.anchorNode() != startNode && !m_upstreamStart.anchorNode()->isDescendantOf(m_downstreamEnd.anchorNode()) && m_downstreamEnd.inDocument() && m_downstreamEnd.computeEditingOffset() >= caretMinOffset(m_downstreamEnd.anchorNode())) {
if (m_downstreamEnd.atLastEditingPositionForNode() && !canHaveChildrenForEditing(m_downstreamEnd.anchorNode())) {
// The node itself is fully selected, not just its contents. Delete it.
- removeNode(m_downstreamEnd.anchorNode());
+ removeNode(m_downstreamEnd.anchorNode(), editingState);
} else {
if (m_downstreamEnd.anchorNode()->isTextNode()) {
// in a text node that needs to be trimmed
@@ -839,7 +850,9 @@ void DeleteSelectionCommand::doApply(EditingState* editingState)
return;
}
- handleGeneralDelete();
+ handleGeneralDelete(editingState);
+ if (editingState->isAborted())
+ return;
fixupWhitespace();
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h
index 8bd90bb..6e8ea714 100644
--- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h
+++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.h
@@ -60,14 +60,14 @@ private:
void initializePositionData();
void saveTypingStyleState();
bool handleSpecialCaseBRDelete();
- void handleGeneralDelete();
+ void handleGeneralDelete(EditingState*);
void fixupWhitespace();
void mergeParagraphs();
void removePreviouslySelectedEmptyTableRows();
void calculateTypingStyleAfterDelete();
void clearTransientState();
void makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss();
- void removeNode(PassRefPtrWillBeRawPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable) override;
+ void removeNode(PassRefPtrWillBeRawPtr<Node>, EditingState* = ASSERT_NO_EDITING_ABORT, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable) override;
void deleteTextFromNode(PassRefPtrWillBeRawPtr<Text>, unsigned, unsigned) override;
void removeRedundantBlocks(EditingState*);
diff --git a/third_party/WebKit/Source/core/editing/commands/RemoveNodeCommand.cpp b/third_party/WebKit/Source/core/editing/commands/RemoveNodeCommand.cpp
index a9b8ead..ddc352d 100644
--- a/third_party/WebKit/Source/core/editing/commands/RemoveNodeCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/RemoveNodeCommand.cpp
@@ -27,6 +27,7 @@
#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Node.h"
+#include "core/editing/commands/EditingState.h"
#include "wtf/Assertions.h"
namespace blink {
@@ -40,7 +41,7 @@ RemoveNodeCommand::RemoveNodeCommand(PassRefPtrWillBeRawPtr<Node> node, ShouldAs
ASSERT(m_node->parentNode());
}
-void RemoveNodeCommand::doApply(EditingState*)
+void RemoveNodeCommand::doApply(EditingState* editingState)
{
ContainerNode* parent = m_node->parentNode();
if (!parent || (m_shouldAssumeContentIsAlwaysEditable == DoNotAssumeContentIsAlwaysEditable
@@ -52,6 +53,11 @@ void RemoveNodeCommand::doApply(EditingState*)
m_refChild = m_node->nextSibling();
m_node->remove(IGNORE_EXCEPTION);
+ // Node::remove dispatch synchronous events such as IFRAME unload events,
+ // and event handlers may break the document. We check the document state
+ // here in order to prevent further processing in bad situation.
+ ASSERT_IN_EDITING_COMMAND(m_node->document().frame());
+ ASSERT_IN_EDITING_COMMAND(m_node->document().documentElement());
}
void RemoveNodeCommand::doUnapply()
diff --git a/third_party/WebKit/Source/core/editing/commands/RemoveNodePreservingChildrenCommand.cpp b/third_party/WebKit/Source/core/editing/commands/RemoveNodePreservingChildrenCommand.cpp
index 55fb5d7..4283ee6 100644
--- a/third_party/WebKit/Source/core/editing/commands/RemoveNodePreservingChildrenCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/RemoveNodePreservingChildrenCommand.cpp
@@ -46,11 +46,11 @@ void RemoveNodePreservingChildrenCommand::doApply(EditingState*)
for (auto& currentChild : children) {
RefPtrWillBeRawPtr<Node> child = currentChild.release();
- removeNode(child, m_shouldAssumeContentIsAlwaysEditable);
+ removeNode(child, ASSERT_NO_EDITING_ABORT, m_shouldAssumeContentIsAlwaysEditable);
insertNodeBefore(child.release(), m_node, m_shouldAssumeContentIsAlwaysEditable);
}
}
- removeNode(m_node, m_shouldAssumeContentIsAlwaysEditable);
+ removeNode(m_node, ASSERT_NO_EDITING_ABORT, m_shouldAssumeContentIsAlwaysEditable);
}
DEFINE_TRACE(RemoveNodePreservingChildrenCommand)
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
index aa6415c..9cadc76 100644
--- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -920,7 +920,7 @@ static inline HTMLElement* elementToSplitToAvoidPastingIntoInlineElementsWithSty
return toHTMLElement(highestEnclosingNodeOfType(insertionPos, isInlineHTMLElementWithStyle, CannotCrossEditingBoundary, containingBlock));
}
-void ReplaceSelectionCommand::doApply(EditingState*)
+void ReplaceSelectionCommand::doApply(EditingState* editingState)
{
const VisibleSelection selection = endingSelection();
ASSERT(selection.isCaretOrRange());
@@ -974,7 +974,9 @@ void ReplaceSelectionCommand::doApply(EditingState*)
bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfParagraph(visibleEnd) || isStartOfBlock(visibleStart);
// FIXME: We should only expand to include fully selected special elements if we are copying a
// selection and pasting it on top of itself.
- deleteSelection(ASSERT_NO_EDITING_ABORT, false, mergeBlocksAfterDelete, false);
+ deleteSelection(editingState, false, mergeBlocksAfterDelete, false);
+ if (editingState->isAborted())
+ return;
if (fragment.hasInterchangeNewlineAtStart()) {
VisiblePosition startAfterDelete = endingSelection().visibleStart();
if (isEndOfParagraph(startAfterDelete) && !isStartOfParagraph(startAfterDelete) && !isEndOfEditableOrNonEditableContent(startAfterDelete))
diff --git a/third_party/WebKit/Source/core/editing/commands/SimplifyMarkupCommand.cpp b/third_party/WebKit/Source/core/editing/commands/SimplifyMarkupCommand.cpp
index e7edd8f..538e7e3 100644
--- a/third_party/WebKit/Source/core/editing/commands/SimplifyMarkupCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/SimplifyMarkupCommand.cpp
@@ -113,9 +113,9 @@ int SimplifyMarkupCommand::pruneSubsequentAncestorsToRemove(WillBeHeapVector<Ref
if (pastLastNodeToRemove == startNodeIndex + 1)
return 0;
- removeNode(nodesToRemove[startNodeIndex], AssumeContentIsAlwaysEditable);
+ removeNode(nodesToRemove[startNodeIndex], ASSERT_NO_EDITING_ABORT, AssumeContentIsAlwaysEditable);
insertNodeBefore(nodesToRemove[startNodeIndex], highestAncestorToRemove, AssumeContentIsAlwaysEditable);
- removeNode(highestAncestorToRemove, AssumeContentIsAlwaysEditable);
+ removeNode(highestAncestorToRemove, ASSERT_NO_EDITING_ABORT, AssumeContentIsAlwaysEditable);
return pastLastNodeToRemove - startNodeIndex - 1;
}