Bug 1540037 - part 13: Move EditorBase::MoveChildren() to HTMLEditor r=m_kato

And this patch renames it to `MoveChildrenBetween()` for avoiding overload.

Differential Revision: https://phabricator.services.mozilla.com/D72845
This commit is contained in:
Masayuki Nakano 2020-04-30 16:24:20 +00:00
parent a1a7ac61e5
commit 481f9750ed
4 changed files with 98 additions and 100 deletions

View File

@ -1722,73 +1722,6 @@ nsresult EditorBase::MoveNodeWithTransaction(
return rv;
}
void EditorBase::MoveChildren(nsIContent& aFirstChild, nsIContent& aLastChild,
const EditorRawDOMPoint& aPointToInsert,
ErrorResult& aError) {
nsCOMPtr<nsINode> oldContainer = aFirstChild.GetParentNode();
if (NS_WARN_IF(oldContainer != aLastChild.GetParentNode()) ||
NS_WARN_IF(!aPointToInsert.IsSet()) ||
NS_WARN_IF(!aPointToInsert.CanContainerHaveChildren())) {
aError.Throw(NS_ERROR_INVALID_ARG);
return;
}
// First, store all children which should be moved to the new container.
AutoTArray<nsCOMPtr<nsIContent>, 10> children;
for (nsIContent* child = &aFirstChild; child;
child = child->GetNextSibling()) {
children.AppendElement(child);
if (child == &aLastChild) {
break;
}
}
if (NS_WARN_IF(children.LastElement() != &aLastChild)) {
aError.Throw(NS_ERROR_INVALID_ARG);
return;
}
nsCOMPtr<nsINode> newContainer = aPointToInsert.GetContainer();
nsCOMPtr<nsIContent> nextNode = aPointToInsert.GetChild();
for (size_t i = children.Length(); i > 0; --i) {
nsCOMPtr<nsIContent>& child = children[i - 1];
if (child->GetParentNode() != oldContainer) {
// If the child has been moved to different container, we shouldn't
// touch it.
continue;
}
oldContainer->RemoveChild(*child, aError);
if (aError.Failed()) {
NS_WARNING("nsINode::RemoveChild() failed");
return;
}
if (nextNode) {
// If we're not appending the children to the new container, we should
// check if referring next node of insertion point is still in the new
// container.
EditorRawDOMPoint pointToInsert(nextNode);
if (NS_WARN_IF(!pointToInsert.IsSet()) ||
NS_WARN_IF(pointToInsert.GetContainer() != newContainer)) {
// The next node of insertion point has been moved by mutation observer.
// Let's stop moving the remaining nodes.
// XXX Or should we move remaining children after the last moved child?
aError.Throw(NS_ERROR_FAILURE);
return;
}
}
newContainer->InsertBefore(*child, nextNode, aError);
if (aError.Failed()) {
NS_WARNING("nsINode::InsertBefore() failed");
return;
}
// If the child was inserted or appended properly, the following children
// should be inserted before it. Otherwise, keep using current position.
if (child->GetParentNode() == newContainer) {
nextNode = child;
}
}
}
NS_IMETHODIMP EditorBase::AddEditorObserver(nsIEditorObserver* aObserver) {
// we don't keep ownership of the observers. They must
// remove themselves as observers before they are destroyed.

View File

@ -1476,29 +1476,6 @@ class EditorBase : public nsIEditor,
return MoveNodeWithTransaction(aContent, pointToInsert);
}
/**
* MoveChildren() moves all children between aFirstChild and aLastChild to
* before aPointToInsert.GetChild().
* If some children are moved to different container while this method
* moves other children, they are just ignored.
* If the child node referred by aPointToInsert is moved to different
* container while this method moves children, returns error.
*
* @param aFirstChild The first child which should be moved to
* aPointToInsert.
* @param aLastChild The last child which should be moved. This
* must be a sibling of aFirstChild and it should
* be positioned after aFirstChild in the DOM tree
* order.
* @param aPointToInsert The insertion point. The container must not
* be a data node like a text node.
* @param aError The result. If this succeeds to move children,
* returns NS_OK. Otherwise, an error.
*/
void MoveChildren(nsIContent& aFirstChild, nsIContent& aLastChild,
const EditorRawDOMPoint& aPointToInsert,
ErrorResult& aError);
/**
* CloneAttributeWithTransaction() copies aAttribute of aSourceElement to
* aDestElement. If aSourceElement doesn't have aAttribute, this removes

View File

@ -4297,8 +4297,77 @@ void HTMLEditor::MoveAllChildren(nsINode& aContainer,
aError.Throw(NS_ERROR_FAILURE);
return;
}
MoveChildren(*firstChild, *lastChild, aPointToInsert, aError);
NS_WARNING_ASSERTION(!aError.Failed(), "EditorBase::MoveChildren() failed");
MoveChildrenBetween(*firstChild, *lastChild, aPointToInsert, aError);
NS_WARNING_ASSERTION(!aError.Failed(),
"HTMLEditor::MoveChildrenBetween() failed");
}
void HTMLEditor::MoveChildrenBetween(nsIContent& aFirstChild,
nsIContent& aLastChild,
const EditorRawDOMPoint& aPointToInsert,
ErrorResult& aError) {
nsCOMPtr<nsINode> oldContainer = aFirstChild.GetParentNode();
if (NS_WARN_IF(oldContainer != aLastChild.GetParentNode()) ||
NS_WARN_IF(!aPointToInsert.IsSet()) ||
NS_WARN_IF(!aPointToInsert.CanContainerHaveChildren())) {
aError.Throw(NS_ERROR_INVALID_ARG);
return;
}
// First, store all children which should be moved to the new container.
AutoTArray<nsCOMPtr<nsIContent>, 10> children;
for (nsIContent* child = &aFirstChild; child;
child = child->GetNextSibling()) {
children.AppendElement(child);
if (child == &aLastChild) {
break;
}
}
if (NS_WARN_IF(children.LastElement() != &aLastChild)) {
aError.Throw(NS_ERROR_INVALID_ARG);
return;
}
nsCOMPtr<nsINode> newContainer = aPointToInsert.GetContainer();
nsCOMPtr<nsIContent> nextNode = aPointToInsert.GetChild();
for (size_t i = children.Length(); i > 0; --i) {
nsCOMPtr<nsIContent>& child = children[i - 1];
if (child->GetParentNode() != oldContainer) {
// If the child has been moved to different container, we shouldn't
// touch it.
continue;
}
oldContainer->RemoveChild(*child, aError);
if (aError.Failed()) {
NS_WARNING("nsINode::RemoveChild() failed");
return;
}
if (nextNode) {
// If we're not appending the children to the new container, we should
// check if referring next node of insertion point is still in the new
// container.
EditorRawDOMPoint pointToInsert(nextNode);
if (NS_WARN_IF(!pointToInsert.IsSet()) ||
NS_WARN_IF(pointToInsert.GetContainer() != newContainer)) {
// The next node of insertion point has been moved by mutation observer.
// Let's stop moving the remaining nodes.
// XXX Or should we move remaining children after the last moved child?
aError.Throw(NS_ERROR_FAILURE);
return;
}
}
newContainer->InsertBefore(*child, nextNode, aError);
if (aError.Failed()) {
NS_WARNING("nsINode::InsertBefore() failed");
return;
}
// If the child was inserted or appended properly, the following children
// should be inserted before it. Otherwise, keep using current position.
if (child->GetParentNode() == newContainer) {
nextNode = child;
}
}
}
void HTMLEditor::MovePreviousSiblings(nsIContent& aChild,
@ -4321,8 +4390,9 @@ void HTMLEditor::MovePreviousSiblings(nsIContent& aChild,
aError.Throw(NS_ERROR_FAILURE);
return;
}
MoveChildren(*firstChild, *lastChild, aPointToInsert, aError);
NS_WARNING_ASSERTION(!aError.Failed(), "EditorBase::MoveChildren() failed");
MoveChildrenBetween(*firstChild, *lastChild, aPointToInsert, aError);
NS_WARNING_ASSERTION(!aError.Failed(),
"HTMLEditor::MoveChildrenBetween() failed");
}
nsresult HTMLEditor::DeleteElementsExceptTableRelatedElements(nsINode& aNode) {

View File

@ -2185,13 +2185,10 @@ class HTMLEditor final : public TextEditor,
[[nodiscard]] MOZ_CAN_RUN_SCRIPT MoveNodeResult
MoveChildren(Element& aElement, const EditorDOMPoint& aPointToInsert);
using EditorBase::MoveChildren;
/**
* MoveAllChildren() moves all children of aContainer to before
* aPointToInsert.GetChild().
* See explanation of EditorBase::MoveChildren() for the detail of the
* behavior.
* See explanation of MoveChildrenBetween() for the detail of the behavior.
*
* @param aContainer The container node whose all children should
* be moved.
@ -2204,11 +2201,32 @@ class HTMLEditor final : public TextEditor,
const EditorRawDOMPoint& aPointToInsert,
ErrorResult& aError);
/**
* MoveChildrenBetween() moves all children between aFirstChild and aLastChild
* to before aPointToInsert.GetChild(). If some children are moved to
* different container while this method moves other children, they are just
* ignored. If the child node referred by aPointToInsert is moved to different
* container while this method moves children, returns error.
*
* @param aFirstChild The first child which should be moved to
* aPointToInsert.
* @param aLastChild The last child which should be moved. This
* must be a sibling of aFirstChild and it should
* be positioned after aFirstChild in the DOM tree
* order.
* @param aPointToInsert The insertion point. The container must not
* be a data node like a text node.
* @param aError The result. If this succeeds to move children,
* returns NS_OK. Otherwise, an error.
*/
void MoveChildrenBetween(nsIContent& aFirstChild, nsIContent& aLastChild,
const EditorRawDOMPoint& aPointToInsert,
ErrorResult& aError);
/**
* MovePreviousSiblings() moves all siblings before aChild (i.e., aChild
* won't be moved) to before aPointToInsert.GetChild().
* See explanation of EditorBase::MoveChildren() for the detail of the
* behavior.
* See explanation of MoveChildrenBetween() for the detail of the behavior.
*
* @param aChild The node which is next sibling of the last
* node to be moved.