Bug 1460509 - part 63: Make HTMLEditRules::RemovePartOfBlock() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato
And this patch renames it to SplitRangeOffFromBlockAndRemoveMiddleContainer()
for making the name explain what it does.
MozReview-Commit-ID: 546dnCeoGOV
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -5372,40 +5372,42 @@ HTMLEditRules::WillOutdent(bool* aCancel
SelectionRef().Collapse(atRememberedRightBQ, error);
NS_WARNING_ASSERTION(!error.Failed(),
"Failed to collapse selection after the right <blockquote>");
}
}
return NS_OK;
}
-/**
- * RemovePartOfBlock() splits aBlock and move aStartChild to aEndChild out of
- * aBlock.
- */
-nsresult
-HTMLEditRules::RemovePartOfBlock(Element& aBlock,
- nsIContent& aStartChild,
- nsIContent& aEndChild)
+SplitRangeOffFromNodeResult
+HTMLEditRules::SplitRangeOffFromBlockAndRemoveMiddleContainer(
+ Element& aBlockElement,
+ nsIContent& aStartOfRange,
+ nsIContent& aEndOfRange)
{
MOZ_ASSERT(IsEditorDataAvailable());
SplitRangeOffFromNodeResult splitResult =
- SplitRangeOffFromBlock(aBlock, aStartChild, aEndChild);
+ SplitRangeOffFromBlock(aBlockElement, aStartOfRange, aEndOfRange);
if (NS_WARN_IF(splitResult.Rv() == NS_ERROR_EDITOR_DESTROYED)) {
- return NS_ERROR_EDITOR_DESTROYED;
+ return splitResult;
}
NS_WARNING_ASSERTION(splitResult.Succeeded(),
"Failed to split the range off from the block element");
- // Get rid of part of blockquote we are outdenting
- nsresult rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(aBlock);
+ nsresult rv =
+ HTMLEditorRef().RemoveBlockContainerWithTransaction(aBlockElement);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED);
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- return NS_OK;
+ return SplitRangeOffFromNodeResult(rv);
+ }
+ return SplitRangeOffFromNodeResult(splitResult.GetLeftContent(),
+ nullptr,
+ splitResult.GetRightContent());
}
SplitRangeOffFromNodeResult
HTMLEditRules::SplitRangeOffFromBlock(Element& aBlockElement,
nsIContent& aStartOfMiddleElement,
nsIContent& aEndOfMiddleElement)
{
MOZ_ASSERT(IsEditorDataAvailable());
@@ -8445,19 +8447,21 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
// inline things...
nsCOMPtr<Element> curBlock;
nsCOMPtr<nsIContent> firstNode, lastNode;
for (auto& curNode : aNodeArray) {
// 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;
+ SplitRangeOffFromNodeResult removeMiddleContainerResult =
+ SplitRangeOffFromBlockAndRemoveMiddleContainer(*curBlock,
+ *firstNode, *lastNode);
+ if (NS_WARN_IF(removeMiddleContainerResult.Failed())) {
+ return removeMiddleContainerResult.Rv();
}
firstNode = lastNode = curBlock = nullptr;
}
if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// Remove current block
nsresult rv =
@@ -8478,19 +8482,21 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
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;
+ SplitRangeOffFromNodeResult removeMiddleContainerResult =
+ SplitRangeOffFromBlockAndRemoveMiddleContainer(*curBlock,
+ *firstNode, *lastNode);
+ if (NS_WARN_IF(removeMiddleContainerResult.Failed())) {
+ return removeMiddleContainerResult.Rv();
}
firstNode = lastNode = curBlock = nullptr;
}
if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// Recursion time
nsTArray<OwningNonNull<nsINode>> childArray;
@@ -8508,19 +8514,21 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
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
// handle it now. We need to remove the portion of curBlock that
// contains [firstNode - lastNode].
- nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
+ SplitRangeOffFromNodeResult removeMiddleContainerResult =
+ SplitRangeOffFromBlockAndRemoveMiddleContainer(*curBlock,
+ *firstNode, *lastNode);
+ if (NS_WARN_IF(removeMiddleContainerResult.Failed())) {
+ return removeMiddleContainerResult.Rv();
}
firstNode = lastNode = curBlock = nullptr;
// Fall out and handle curNode
}
curBlock = HTMLEditorRef().GetBlockNodeParent(curNode);
if (!curBlock || !HTMLEditUtils::IsFormatNode(curBlock) ||
!HTMLEditorRef().IsEditable(curBlock)) {
// Not a block kind that we care about.
@@ -8529,29 +8537,33 @@ HTMLEditRules::RemoveBlockStyle(nsTArray
firstNode = lastNode = curNode->AsContent();
}
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;
+ SplitRangeOffFromNodeResult removeMiddleContainerResult =
+ SplitRangeOffFromBlockAndRemoveMiddleContainer(*curBlock,
+ *firstNode, *lastNode);
+ if (NS_WARN_IF(removeMiddleContainerResult.Failed())) {
+ return removeMiddleContainerResult.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;
+ SplitRangeOffFromNodeResult removeMiddleContainerResult =
+ SplitRangeOffFromBlockAndRemoveMiddleContainer(*curBlock,
+ *firstNode, *lastNode);
+ if (NS_WARN_IF(removeMiddleContainerResult.Failed())) {
+ return removeMiddleContainerResult.Rv();
}
firstNode = lastNode = curBlock = nullptr;
}
return NS_OK;
}
nsresult
HTMLEditRules::ApplyBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -524,18 +524,37 @@ protected:
/**
* Called after handling edit action. This may adjust Selection, remove
* unnecessary empty nodes, create <br> elements if needed, etc.
*/
MOZ_MUST_USE nsresult
AfterEditInner(EditAction action, nsIEditor::EDirection aDirection);
- nsresult RemovePartOfBlock(Element& aBlock, nsIContent& aStartChild,
- nsIContent& aEndChild);
+ /**
+ * SplitRangeOffFromBlockAndRemoveMiddleContainer() splits the nodes
+ * between aStartOfRange and aEndOfRange, then, removes the middle element
+ * and moves its content to where the middle element was.
+ *
+ * @param aBlockElement The node which will be split.
+ * @param aStartOfRange The first node which will be unwrapped
+ * from aBlockElement.
+ * @param aEndOfRange The last node which will be unwrapped from
+ * aBlockElement.
+ * @return The left content is new created left
+ * element of aBlockElement.
+ * The right content is split element,
+ * i.e., must be aBlockElement.
+ * The middle content is nullptr since
+ * removing it is the job of this method.
+ */
+ MOZ_MUST_USE SplitRangeOffFromNodeResult
+ SplitRangeOffFromBlockAndRemoveMiddleContainer(Element& aBlockElement,
+ nsIContent& aStartOfRange,
+ nsIContent& aEndOfRange);
/**
* SplitRangeOffFromBlock() splits aBlock at two points, before aStartChild
* and after aEndChild. If they are very start or very end of aBlcok, this
* won't create empty block.
*
* @param aBlockElement A block element which will be split.
* @param aStartOfMiddleElement Start node of middle block element.