Bug 1460509 - part 36: Make HTMLEditRules::RemoveBlockStyle() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato
MozReview-Commit-ID: KDfxeD9k0UN
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -8044,58 +8044,62 @@ HTMLEditRules::MakeBlockquote(nsTArray<O
*curBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
-/**
- * RemoveBlockStyle() makes the nodes have no special block type.
- */
nsresult
HTMLEditRules::RemoveBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
{
MOZ_ASSERT(IsEditorDataAvailable());
// Intent of this routine is to be used for converting to/from headers,
// paragraphs, pre, and address. Those blocks that pretty much just contain
// inline things...
nsCOMPtr<Element> curBlock;
nsCOMPtr<nsIContent> firstNode, lastNode;
for (auto& curNode : aNodeArray) {
- // If curNode is a address, p, header, address, or pre, remove it
+ // If curNode is an <address>, <p>, <hn>, or <pre>, remove it.
if (HTMLEditUtils::IsFormatNode(curNode)) {
// Process any partial progress saved
if (curBlock) {
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
firstNode = lastNode = curBlock = nullptr;
}
if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// Remove current block
nsresult rv =
HTMLEditorRef().RemoveBlockContainerWithTransaction(
*curNode->AsElement());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- } else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table,
- nsGkAtoms::tr,
- nsGkAtoms::tbody,
- nsGkAtoms::td,
- nsGkAtoms::li,
- nsGkAtoms::blockquote,
- nsGkAtoms::div) ||
- HTMLEditUtils::IsList(curNode)) {
+ continue;
+ }
+
+ // XXX How about, <th>, <thead>, <tfoot>, <dt>, <dl>?
+ if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table,
+ nsGkAtoms::tr,
+ nsGkAtoms::tbody,
+ nsGkAtoms::td,
+ nsGkAtoms::li,
+ nsGkAtoms::blockquote,
+ nsGkAtoms::div) ||
+ HTMLEditUtils::IsList(curNode)) {
// Process any partial progress saved
if (curBlock) {
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
firstNode = lastNode = curBlock = nullptr;
}
@@ -8104,17 +8108,20 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
}
// Recursion time
nsTArray<OwningNonNull<nsINode>> childArray;
GetChildNodesForOperation(*curNode, childArray);
nsresult rv = RemoveBlockStyle(childArray);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- } else if (IsInlineNode(curNode)) {
+ continue;
+ }
+
+ if (IsInlineNode(curNode)) {
if (curBlock) {
// If so, is this node a descendant?
if (EditorUtils::IsDescendantOf(*curNode, *curBlock)) {
// Then we don't need to do anything different for this node
lastNode = curNode->AsContent();
continue;
}
// Otherwise, we have progressed beyond end of curBlock, so let's
@@ -8130,24 +8137,28 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
curBlock = HTMLEditorRef().GetBlockNodeParent(curNode);
if (!curBlock || !HTMLEditUtils::IsFormatNode(curBlock) ||
!HTMLEditorRef().IsEditable(curBlock)) {
// Not a block kind that we care about.
curBlock = nullptr;
} else {
firstNode = lastNode = curNode->AsContent();
}
- } else if (curBlock) {
+ continue;
+ }
+
+ if (curBlock) {
// Some node that is already sans block style. Skip over it and process
// any partial progress saved.
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
firstNode = lastNode = curBlock = nullptr;
+ continue;
}
}
// Process any partial progress saved
if (curBlock) {
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -482,16 +482,25 @@ protected:
/**
* GetHiestInlineParent() returns the highest inline node parent between
* aNode and the editing host. Even if the editing host is an inline
* element, this method never returns the editing host as the result.
*/
nsIContent* GetHighestInlineParent(nsINode& aNode);
void MakeTransitionList(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
nsTArray<bool>& aTransitionArray);
+
+ /**
+ * RemoveBlockStyle() removes all format blocks, table related element,
+ * etc in aNodeArray.
+ * If aNodeArray has a format node, it will be removed and its contents
+ * will be moved to where it was.
+ * If aNodeArray has a table related element, <li>, <blockquote> or <div>,
+ * it will removed and its contents will be moved to where it was.
+ */
nsresult RemoveBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray);
/**
* ApplyBlockStyle() formats all nodes in aNodeArray with block elements
* whose name is aBlockTag.
* If aNodeArray has an inline element, a block element is created and the
* inline element and following inline elements are moved into the new block
* element.