mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
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:
parent
a1a7ac61e5
commit
481f9750ed
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user