diff --git a/editor/libeditor/CSSEditUtils.cpp b/editor/libeditor/CSSEditUtils.cpp index 81880a19a2a38..0e3f366359a87 100644 --- a/editor/libeditor/CSSEditUtils.cpp +++ b/editor/libeditor/CSSEditUtils.cpp @@ -383,8 +383,12 @@ bool CSSEditUtils::IsCSSEditableProperty(nsINode* aNode, nsAtom* aProperty, nsresult CSSEditUtils::SetCSSProperty(Element& aElement, nsAtom& aProperty, const nsAString& aValue, bool aSuppressTxn) { + nsCOMPtr styledElement = do_QueryInterface(&aElement); + if (NS_WARN_IF(!styledElement)) { + return NS_ERROR_INVALID_ARG; + } RefPtr transaction = - ChangeStyleTransaction::Create(aElement, aProperty, aValue); + ChangeStyleTransaction::Create(*styledElement, aProperty, aValue); if (aSuppressTxn) { return transaction->DoTransaction(); } @@ -416,8 +420,12 @@ nsresult CSSEditUtils::SetCSSPropertyPixels(Element& aElement, nsresult CSSEditUtils::RemoveCSSProperty(Element& aElement, nsAtom& aProperty, const nsAString& aValue, bool aSuppressTxn) { + nsCOMPtr styledElement = do_QueryInterface(&aElement); + if (NS_WARN_IF(!styledElement)) { + return NS_ERROR_INVALID_ARG; + } RefPtr transaction = - ChangeStyleTransaction::CreateToRemove(aElement, aProperty, aValue); + ChangeStyleTransaction::CreateToRemove(*styledElement, aProperty, aValue); if (aSuppressTxn) { nsresult rv = transaction->DoTransaction(); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), diff --git a/editor/libeditor/ChangeAttributeTransaction.cpp b/editor/libeditor/ChangeAttributeTransaction.cpp index e442e6ff40500..7c115b579c3a1 100644 --- a/editor/libeditor/ChangeAttributeTransaction.cpp +++ b/editor/libeditor/ChangeAttributeTransaction.cpp @@ -63,36 +63,48 @@ NS_IMETHODIMP ChangeAttributeTransaction::DoTransaction() { // Now set the attribute to the new value if (mRemoveAttribute) { - nsresult rv = mElement->UnsetAttr(kNameSpaceID_None, mAttribute, true); + OwningNonNull element = *mElement; + nsresult rv = element->UnsetAttr(kNameSpaceID_None, mAttribute, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::UnsetAttr() failed"); return rv; } - nsresult rv = mElement->SetAttr(kNameSpaceID_None, mAttribute, mValue, true); + OwningNonNull element = *mElement; + nsresult rv = element->SetAttr(kNameSpaceID_None, mAttribute, mValue, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::SetAttr() failed"); return rv; } NS_IMETHODIMP ChangeAttributeTransaction::UndoTransaction() { + if (NS_WARN_IF(!mElement)) { + return NS_ERROR_NOT_AVAILABLE; + } if (mAttributeWasSet) { + OwningNonNull element = *mElement; nsresult rv = - mElement->SetAttr(kNameSpaceID_None, mAttribute, mUndoValue, true); + element->SetAttr(kNameSpaceID_None, mAttribute, mUndoValue, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::SetAttr() failed"); return rv; } - nsresult rv = mElement->UnsetAttr(kNameSpaceID_None, mAttribute, true); + OwningNonNull element = *mElement; + nsresult rv = element->UnsetAttr(kNameSpaceID_None, mAttribute, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::UnsetAttr() failed"); return rv; } NS_IMETHODIMP ChangeAttributeTransaction::RedoTransaction() { + if (NS_WARN_IF(!mElement)) { + return NS_ERROR_NOT_AVAILABLE; + } if (mRemoveAttribute) { - nsresult rv = mElement->UnsetAttr(kNameSpaceID_None, mAttribute, true); + OwningNonNull element = *mElement; + nsresult rv = element->UnsetAttr(kNameSpaceID_None, mAttribute, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::UnsetAttr() failed"); return rv; } - nsresult rv = mElement->SetAttr(kNameSpaceID_None, mAttribute, mValue, true); + OwningNonNull element = *mElement; + nsresult rv = element->SetAttr(kNameSpaceID_None, mAttribute, mValue, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::SetAttr() failed"); return rv; } diff --git a/editor/libeditor/ChangeStyleTransaction.cpp b/editor/libeditor/ChangeStyleTransaction.cpp index e07dfe2463f0d..9b3672b95428c 100644 --- a/editor/libeditor/ChangeStyleTransaction.cpp +++ b/editor/libeditor/ChangeStyleTransaction.cpp @@ -24,38 +24,40 @@ using namespace dom; // static already_AddRefed ChangeStyleTransaction::Create( - Element& aElement, nsAtom& aProperty, const nsAString& aValue) { + nsStyledElement& aStyledElement, nsAtom& aProperty, + const nsAString& aValue) { RefPtr transaction = - new ChangeStyleTransaction(aElement, aProperty, aValue, false); + new ChangeStyleTransaction(aStyledElement, aProperty, aValue, false); return transaction.forget(); } // static already_AddRefed ChangeStyleTransaction::CreateToRemove( - Element& aElement, nsAtom& aProperty, const nsAString& aValue) { + nsStyledElement& aStyledElement, nsAtom& aProperty, + const nsAString& aValue) { RefPtr transaction = - new ChangeStyleTransaction(aElement, aProperty, aValue, true); + new ChangeStyleTransaction(aStyledElement, aProperty, aValue, true); return transaction.forget(); } -ChangeStyleTransaction::ChangeStyleTransaction(Element& aElement, +ChangeStyleTransaction::ChangeStyleTransaction(nsStyledElement& aStyledElement, nsAtom& aProperty, const nsAString& aValue, bool aRemove) : EditTransactionBase(), - mElement(&aElement), + mStyledElement(&aStyledElement), mProperty(&aProperty), mValue(aValue), - mRemoveProperty(aRemove), mUndoValue(), mRedoValue(), + mRemoveProperty(aRemove), mUndoAttributeWasSet(false), mRedoAttributeWasSet(false) {} #define kNullCh (char16_t('\0')) NS_IMPL_CYCLE_COLLECTION_INHERITED(ChangeStyleTransaction, EditTransactionBase, - mElement) + mStyledElement) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ChangeStyleTransaction) NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) @@ -141,20 +143,20 @@ void ChangeStyleTransaction::RemoveValueFromListOfValues( } NS_IMETHODIMP ChangeStyleTransaction::DoTransaction() { - // TODO: Change mElement to RefPtr. - nsCOMPtr inlineStyles = do_QueryInterface(mElement); - if (NS_WARN_IF(!inlineStyles)) { - return NS_ERROR_INVALID_ARG; + if (NS_WARN_IF(!mStyledElement)) { + return NS_ERROR_NOT_AVAILABLE; } - nsCOMPtr cssDecl = inlineStyles->Style(); + OwningNonNull styledElement = *mStyledElement; + nsCOMPtr cssDecl = styledElement->Style(); // FIXME(bug 1606994): Using atoms forces a string copy here which is not // great. nsAutoCString propertyNameString; mProperty->ToUTF8String(propertyNameString); - mUndoAttributeWasSet = mElement->HasAttr(kNameSpaceID_None, nsGkAtoms::style); + mUndoAttributeWasSet = + mStyledElement->HasAttr(kNameSpaceID_None, nsGkAtoms::style); nsAutoString values; nsresult rv = cssDecl->GetPropertyValue(propertyNameString, values); @@ -221,7 +223,7 @@ NS_IMETHODIMP ChangeStyleTransaction::DoTransaction() { uint32_t length = cssDecl->Length(); if (!length) { nsresult rv = - mElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true); + styledElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true); if (NS_FAILED(rv)) { NS_WARNING("Element::UnsetAttr(nsGkAtoms::style) failed"); return rv; @@ -238,16 +240,18 @@ NS_IMETHODIMP ChangeStyleTransaction::DoTransaction() { nsresult ChangeStyleTransaction::SetStyle(bool aAttributeWasSet, nsAString& aValue) { + if (NS_WARN_IF(!mStyledElement)) { + return NS_ERROR_NOT_AVAILABLE; + } + if (aAttributeWasSet) { + OwningNonNull styledElement = *mStyledElement; + // The style attribute was not empty, let's recreate the declaration nsAutoCString propertyNameString; mProperty->ToUTF8String(propertyNameString); - nsCOMPtr inlineStyles = do_QueryInterface(mElement); - if (NS_WARN_IF(!inlineStyles)) { - return NS_ERROR_INVALID_ARG; - } - nsCOMPtr cssDecl = inlineStyles->Style(); + nsCOMPtr cssDecl = styledElement->Style(); ErrorResult error; if (aValue.IsEmpty()) { @@ -268,7 +272,10 @@ nsresult ChangeStyleTransaction::SetStyle(bool aAttributeWasSet, "nsICSSDeclaration::SetProperty() failed"); return error.StealNSResult(); } - nsresult rv = mElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true); + + OwningNonNull styledElement = *mStyledElement; + nsresult rv = + styledElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::UnsetAttr(nsGkAtoms::style) failed"); return rv; diff --git a/editor/libeditor/ChangeStyleTransaction.h b/editor/libeditor/ChangeStyleTransaction.h index ff926cb2bf384..3883548a74262 100644 --- a/editor/libeditor/ChangeStyleTransaction.h +++ b/editor/libeditor/ChangeStyleTransaction.h @@ -12,6 +12,7 @@ #include "nsString.h" // nsString members class nsAtom; +class nsStyledElement; namespace mozilla { @@ -25,29 +26,31 @@ class Element; */ class ChangeStyleTransaction final : public EditTransactionBase { protected: - ChangeStyleTransaction(dom::Element& aElement, nsAtom& aProperty, + ChangeStyleTransaction(nsStyledElement& aStyledElement, nsAtom& aProperty, const nsAString& aValue, bool aRemove); public: /** * Creates a change style transaction. This never returns nullptr. * - * @param aNode The node whose style attribute will be changed. - * @param aProperty The name of the property to change. - * @param aValue New value for aProperty. + * @param aStyledElement The node whose style attribute will be changed. + * @param aProperty The name of the property to change. + * @param aValue New value for aProperty. */ static already_AddRefed Create( - dom::Element& aElement, nsAtom& aProperty, const nsAString& aValue); + nsStyledElement& aStyledElement, nsAtom& aProperty, + const nsAString& aValue); /** * Creates a change style transaction. This never returns nullptr. * - * @param aNode The node whose style attribute will be changed. - * @param aProperty The name of the property to change. - * @param aValue The value to remove from aProperty. + * @param aStyledElement The node whose style attribute will be changed. + * @param aProperty The name of the property to change. + * @param aValue The value to remove from aProperty. */ static already_AddRefed CreateToRemove( - dom::Element& aElement, nsAtom& aProperty, const nsAString& aValue); + nsStyledElement& aStyledElement, nsAtom& aProperty, + const nsAString& aValue); NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ChangeStyleTransaction, EditTransactionBase) @@ -106,7 +109,7 @@ class ChangeStyleTransaction final : public EditTransactionBase { nsresult SetStyle(bool aAttributeWasSet, nsAString& aValue); // The element to operate upon. - nsCOMPtr mElement; + RefPtr mStyledElement; // The CSS property to change. RefPtr mProperty; @@ -114,13 +117,14 @@ class ChangeStyleTransaction final : public EditTransactionBase { // The value to set the property to (ignored if mRemoveProperty==true). nsString mValue; - // true if the operation is to remove mProperty from mElement. - bool mRemoveProperty; - // The value to set the property to for undo. nsString mUndoValue; // The value to set the property to for redo. nsString mRedoValue; + + // true if the operation is to remove mProperty from mElement. + bool mRemoveProperty; + // True if the style attribute was present and not empty before DoTransaction. bool mUndoAttributeWasSet; // True if the style attribute is present and not empty after DoTransaction. diff --git a/editor/libeditor/CompositionTransaction.cpp b/editor/libeditor/CompositionTransaction.cpp index 79d917b6fec00..e07ebdbe861ea 100644 --- a/editor/libeditor/CompositionTransaction.cpp +++ b/editor/libeditor/CompositionTransaction.cpp @@ -81,44 +81,44 @@ NS_IMPL_RELEASE_INHERITED(CompositionTransaction, EditTransactionBase) MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP CompositionTransaction::DoTransaction() { - if (NS_WARN_IF(!mEditorBase)) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) { + return NS_ERROR_NOT_AVAILABLE; } // Fail before making any changes if there's no selection controller if (NS_WARN_IF(!mEditorBase->GetSelectionController())) { - return NS_ERROR_NOT_INITIALIZED; + return NS_ERROR_NOT_AVAILABLE; } - RefPtr editorBase = mEditorBase; - RefPtr textNode = mTextNode; + OwningNonNull editorBase = *mEditorBase; + OwningNonNull textNode = *mTextNode; // Advance caret: This requires the presentation shell to get the selection. if (mReplaceLength == 0) { ErrorResult error; - editorBase->DoInsertText(*textNode, mOffset, mStringToInsert, error); + editorBase->DoInsertText(textNode, mOffset, mStringToInsert, error); if (error.Failed()) { NS_WARNING("EditorBase::DoInsertText() failed"); return error.StealNSResult(); } - editorBase->RangeUpdaterRef().SelAdjInsertText(*textNode, mOffset, + editorBase->RangeUpdaterRef().SelAdjInsertText(textNode, mOffset, mStringToInsert); } else { uint32_t replaceableLength = textNode->TextLength() - mOffset; ErrorResult error; - editorBase->DoReplaceText(*textNode, mOffset, mReplaceLength, + editorBase->DoReplaceText(textNode, mOffset, mReplaceLength, mStringToInsert, error); if (error.Failed()) { NS_WARNING("EditorBase::DoReplaceText() failed"); return error.StealNSResult(); } DebugOnly rvIgnored = - editorBase->RangeUpdaterRef().SelAdjDeleteText(*textNode, mOffset, + editorBase->RangeUpdaterRef().SelAdjDeleteText(textNode, mOffset, mReplaceLength); NS_WARNING_ASSERTION( NS_SUCCEEDED(rvIgnored), "RangeUpdater::SelAdjDeleteText() failed, but ignored"); - editorBase->RangeUpdaterRef().SelAdjInsertText(*textNode, mOffset, + editorBase->RangeUpdaterRef().SelAdjInsertText(textNode, mOffset, mStringToInsert); // If IME text node is multiple node, ReplaceData doesn't remove all IME @@ -127,19 +127,20 @@ CompositionTransaction::DoTransaction() { // in a text node. if (replaceableLength < mReplaceLength) { int32_t remainLength = mReplaceLength - replaceableLength; - nsCOMPtr node = textNode->GetNextSibling(); IgnoredErrorResult ignoredError; - while (node && node->IsText() && remainLength > 0) { - RefPtr textNode = static_cast(node.get()); + for (nsIContent* nextSibling = textNode->GetNextSibling(); + nextSibling && nextSibling->IsText() && remainLength; + nextSibling = nextSibling->GetNextSibling()) { + OwningNonNull textNode = *static_cast(nextSibling); uint32_t textLength = textNode->TextLength(); - editorBase->DoDeleteText(*textNode, 0, remainLength, ignoredError); + editorBase->DoDeleteText(textNode, 0, remainLength, ignoredError); NS_WARNING_ASSERTION(!ignoredError.Failed(), "EditorBase::DoDeleteText() failed, but ignored"); ignoredError.SuppressException(); - editorBase->RangeUpdaterRef().SelAdjDeleteText(*textNode, 0, + // XXX Needs to check whether the text is deleted as expected. + editorBase->RangeUpdaterRef().SelAdjDeleteText(textNode, 0, remainLength); remainLength -= textLength; - node = node->GetNextSibling(); } } } @@ -153,21 +154,21 @@ CompositionTransaction::DoTransaction() { MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP CompositionTransaction::UndoTransaction() { - if (NS_WARN_IF(!mEditorBase)) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) { + return NS_ERROR_NOT_AVAILABLE; } // Get the selection first so we'll fail before making any changes if we // can't get it RefPtr selection = mEditorBase->GetSelection(); if (NS_WARN_IF(!selection)) { - return NS_ERROR_NOT_INITIALIZED; + return NS_ERROR_NOT_AVAILABLE; } - RefPtr editorBase = mEditorBase; - RefPtr textNode = mTextNode; + OwningNonNull editorBase = *mEditorBase; + OwningNonNull textNode = *mTextNode; ErrorResult error; - editorBase->DoDeleteText(*textNode, mOffset, mStringToInsert.Length(), error); + editorBase->DoDeleteText(textNode, mOffset, mStringToInsert.Length(), error); if (error.Failed()) { NS_WARNING("EditorBase::DoDeleteText() failed"); return error.StealNSResult(); @@ -211,11 +212,14 @@ void CompositionTransaction::MarkFixed() { mFixed = true; } /* ============ private methods ================== */ nsresult CompositionTransaction::SetSelectionForRanges() { - if (NS_WARN_IF(!mEditorBase)) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) { + return NS_ERROR_NOT_AVAILABLE; } - nsresult rv = SetIMESelection(*mEditorBase, mTextNode, mOffset, - mStringToInsert.Length(), mRanges); + OwningNonNull editorBase = *mEditorBase; + OwningNonNull textNode = *mTextNode; + RefPtr ranges = mRanges; + nsresult rv = SetIMESelection(editorBase, textNode, mOffset, + mStringToInsert.Length(), ranges); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "CompositionTransaction::SetIMESelection() failed"); return rv; diff --git a/editor/libeditor/CreateElementTransaction.cpp b/editor/libeditor/CreateElementTransaction.cpp index 9cca32f3c0f25..ea22e05df86ef 100644 --- a/editor/libeditor/CreateElementTransaction.cpp +++ b/editor/libeditor/CreateElementTransaction.cpp @@ -54,11 +54,15 @@ CreateElementTransaction::CreateElementTransaction( : EditTransactionBase(), mEditorBase(&aEditorBase), mTag(&aTag), - mPointToInsert(aPointToInsert) {} + mPointToInsert(aPointToInsert) { + MOZ_ASSERT(!mPointToInsert.IsInDataNode()); + // We only need the child node at inserting new node. + AutoEditorDOMPointOffsetInvalidator lockChild(mPointToInsert); +} NS_IMPL_CYCLE_COLLECTION_INHERITED(CreateElementTransaction, EditTransactionBase, mEditorBase, - mPointToInsert, mNewNode) + mPointToInsert, mNewElement) NS_IMPL_ADDREF_INHERITED(CreateElementTransaction, EditTransactionBase) NS_IMPL_RELEASE_INHERITED(CreateElementTransaction, EditTransactionBase) @@ -72,16 +76,16 @@ CreateElementTransaction::DoTransaction() { return NS_ERROR_NOT_INITIALIZED; } - RefPtr editorBase(mEditorBase); + OwningNonNull editorBase = *mEditorBase; - mNewNode = editorBase->CreateHTMLContent(mTag); - if (!mNewNode) { + mNewElement = editorBase->CreateHTMLContent(mTag); + if (!mNewElement) { NS_WARNING("EditorBase::CreateHTMLContent() failed"); return NS_ERROR_FAILURE; } // Try to insert formatting whitespace for the new node: - OwningNonNull newElement(*mNewNode); + OwningNonNull newElement = *mNewElement; nsresult rv = editorBase->MarkElementDirty(newElement); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return EditorBase::ToGenericNSResult(rv); @@ -108,7 +112,7 @@ CreateElementTransaction::DoTransaction() { return NS_ERROR_FAILURE; } - EditorRawDOMPoint afterNewNode(EditorRawDOMPoint::After(mNewNode)); + EditorRawDOMPoint afterNewNode(EditorRawDOMPoint::After(newElement)); if (NS_WARN_IF(!afterNewNode.IsSet())) { // If mutation observer or mutation event listener moved or removed the // new node, we hit this case. Should we use script blocker while we're @@ -123,56 +127,69 @@ CreateElementTransaction::DoTransaction() { } void CreateElementTransaction::InsertNewNode(ErrorResult& aError) { + MOZ_ASSERT(mNewElement); + MOZ_ASSERT(mPointToInsert.IsSet()); + if (mPointToInsert.IsSetAndValid()) { if (mPointToInsert.IsEndOfContainer()) { - mPointToInsert.GetContainer()->AppendChild(*mNewNode, aError); + OwningNonNull container = *mPointToInsert.GetContainer(); + OwningNonNull newElement = *mNewElement; + container->AppendChild(newElement, aError); NS_WARNING_ASSERTION(!aError.Failed(), "nsINode::AppendChild() failed, but ignored"); return; } - mPointToInsert.GetContainer()->InsertBefore( - *mNewNode, mPointToInsert.GetChild(), aError); + MOZ_ASSERT(mPointToInsert.GetChild()); + OwningNonNull container = *mPointToInsert.GetContainer(); + OwningNonNull child = *mPointToInsert.GetChild(); + OwningNonNull newElement = *mNewElement; + container->InsertBefore(newElement, child, aError); NS_WARNING_ASSERTION(!aError.Failed(), "nsINode::InsertBefore() failed, but ignored"); return; } - if (NS_WARN_IF(mPointToInsert.GetChild() && - mPointToInsert.GetContainer() != - mPointToInsert.GetChild()->GetParentNode())) { + if (NS_WARN_IF(mPointToInsert.GetContainer() != + mPointToInsert.GetChild()->GetParentNode())) { aError.Throw(NS_ERROR_FAILURE); return; } // If mPointToInsert has only offset and it's not valid, we need to treat // it as pointing end of the container. - mPointToInsert.GetContainer()->AppendChild(*mNewNode, aError); + OwningNonNull container = *mPointToInsert.GetContainer(); + OwningNonNull newElement = *mNewElement; + container->AppendChild(newElement, aError); NS_WARNING_ASSERTION(!aError.Failed(), "nsINode::AppendChild() failed, but ignored"); } NS_IMETHODIMP CreateElementTransaction::UndoTransaction() { - if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mPointToInsert.IsSet())) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mPointToInsert.IsSet()) || + NS_WARN_IF(!mNewElement)) { + return NS_ERROR_NOT_AVAILABLE; } + OwningNonNull newElement = *mNewElement; + OwningNonNull containerNode = *mPointToInsert.GetContainer(); ErrorResult error; - mPointToInsert.GetContainer()->RemoveChild(*mNewNode, error); + containerNode->RemoveChild(newElement, error); NS_WARNING_ASSERTION(!error.Failed(), "nsINode::RemoveChild() failed"); return error.StealNSResult(); } NS_IMETHODIMP CreateElementTransaction::RedoTransaction() { - if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mPointToInsert.IsSet())) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mPointToInsert.IsSet()) || + NS_WARN_IF(!mNewElement)) { + return NS_ERROR_NOT_AVAILABLE; } - // First, reset mNewNode so it has no attributes or content - // XXX We never actually did this, we only cleared mNewNode's contents if it - // was a CharacterData node (which it's not, it's an Element) + // First, reset mNewElement so it has no attributes or content + // XXX We never actually did this, we only cleared mNewElement's contents if + // it was a CharacterData node (which it's not, it's an Element) // XXX Don't we need to set selection like DoTransaction()? - // Now, reinsert mNewNode + // Now, reinsert mNewElement ErrorResult error; InsertNewNode(error); NS_WARNING_ASSERTION(!error.Failed(), @@ -180,8 +197,4 @@ NS_IMETHODIMP CreateElementTransaction::RedoTransaction() { return error.StealNSResult(); } -already_AddRefed CreateElementTransaction::GetNewNode() { - return nsCOMPtr(mNewNode).forget(); -} - } // namespace mozilla diff --git a/editor/libeditor/CreateElementTransaction.h b/editor/libeditor/CreateElementTransaction.h index 49b6388cffd3f..629a686426ab4 100644 --- a/editor/libeditor/CreateElementTransaction.h +++ b/editor/libeditor/CreateElementTransaction.h @@ -8,13 +8,12 @@ #include "mozilla/EditorDOMPoint.h" #include "mozilla/EditTransactionBase.h" -#include "nsCOMPtr.h" +#include "mozilla/RefPtr.h" +#include "mozilla/dom/Element.h" #include "nsCycleCollectionParticipant.h" #include "nsISupportsImpl.h" class nsAtom; -class nsIContent; -class nsINode; /** * A transaction that creates a new node in the content tree. @@ -22,9 +21,6 @@ class nsINode; namespace mozilla { class EditorBase; -namespace dom { -class Element; -} // namespace dom class CreateElementTransaction final : public EditTransactionBase { protected: @@ -57,7 +53,7 @@ class CreateElementTransaction final : public EditTransactionBase { NS_IMETHOD RedoTransaction() override; - already_AddRefed GetNewNode(); + dom::Element* GetNewElement() const { return mNewElement; } protected: virtual ~CreateElementTransaction() = default; @@ -77,7 +73,7 @@ class CreateElementTransaction final : public EditTransactionBase { EditorDOMPoint mPointToInsert; // The new node to insert. - nsCOMPtr mNewNode; + RefPtr mNewElement; }; } // namespace mozilla diff --git a/editor/libeditor/DeleteNodeTransaction.cpp b/editor/libeditor/DeleteNodeTransaction.cpp index e7cc4cbfbabee..83ba9dc867ce4 100644 --- a/editor/libeditor/DeleteNodeTransaction.cpp +++ b/editor/libeditor/DeleteNodeTransaction.cpp @@ -14,9 +14,9 @@ namespace mozilla { // static already_AddRefed DeleteNodeTransaction::MaybeCreate( - EditorBase& aEditorBase, nsINode& aNodeToDelete) { + EditorBase& aEditorBase, nsIContent& aContentToDelete) { RefPtr transaction = - new DeleteNodeTransaction(aEditorBase, aNodeToDelete); + new DeleteNodeTransaction(aEditorBase, aContentToDelete); if (NS_WARN_IF(!transaction->CanDoIt())) { return nullptr; } @@ -24,14 +24,14 @@ already_AddRefed DeleteNodeTransaction::MaybeCreate( } DeleteNodeTransaction::DeleteNodeTransaction(EditorBase& aEditorBase, - nsINode& aNodeToDelete) + nsIContent& aContentToDelete) : mEditorBase(&aEditorBase), - mNodeToDelete(&aNodeToDelete), - mParentNode(aNodeToDelete.GetParentNode()) {} + mContentToDelete(&aContentToDelete), + mParentNode(aContentToDelete.GetParentNode()) {} NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteNodeTransaction, EditTransactionBase, - mEditorBase, mNodeToDelete, mParentNode, - mRefNode) + mEditorBase, mContentToDelete, mParentNode, + mRefContent) NS_IMPL_ADDREF_INHERITED(DeleteNodeTransaction, EditTransactionBase) NS_IMPL_RELEASE_INHERITED(DeleteNodeTransaction, EditTransactionBase) @@ -39,8 +39,8 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteNodeTransaction) NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) bool DeleteNodeTransaction::CanDoIt() const { - if (NS_WARN_IF(!mNodeToDelete) || NS_WARN_IF(!mEditorBase) || !mParentNode || - !mEditorBase->IsModifiableNode(*mParentNode)) { + if (NS_WARN_IF(!mContentToDelete) || NS_WARN_IF(!mEditorBase) || + !mParentNode || !mEditorBase->IsModifiableNode(*mParentNode)) { return false; } return true; @@ -51,24 +51,26 @@ NS_IMETHODIMP DeleteNodeTransaction::DoTransaction() { return NS_OK; } - if (!mEditorBase->AsHTMLEditor() && mNodeToDelete->IsText()) { - uint32_t length = mNodeToDelete->AsText()->TextLength(); + if (!mEditorBase->AsHTMLEditor() && mContentToDelete->IsText()) { + uint32_t length = mContentToDelete->AsText()->TextLength(); if (length > 0) { mEditorBase->AsTextEditor()->WillDeleteText(length, 0, length); } } - // Remember which child mNodeToDelete was (by remembering which child was - // next). Note that mRefNode can be nullptr. - mRefNode = mNodeToDelete->GetNextSibling(); + // Remember which child mContentToDelete was (by remembering which child was + // next). Note that mRefContent can be nullptr. + mRefContent = mContentToDelete->GetNextSibling(); // give range updater a chance. SelAdjDeleteNode() needs to be called // *before* we do the action, unlike some of the other RangeItem update // methods. - mEditorBase->RangeUpdaterRef().SelAdjDeleteNode(*mNodeToDelete); + mEditorBase->RangeUpdaterRef().SelAdjDeleteNode(*mContentToDelete); + OwningNonNull parentNode = *mParentNode; + OwningNonNull contentToDelete = *mContentToDelete; ErrorResult error; - mParentNode->RemoveChild(*mNodeToDelete, error); + parentNode->RemoveChild(contentToDelete, error); NS_WARNING_ASSERTION(!error.Failed(), "nsINode::RemoveChild() failed"); return error.StealNSResult(); } @@ -80,17 +82,19 @@ DeleteNodeTransaction::UndoTransaction() { return NS_OK; } ErrorResult error; - RefPtr editorBase = mEditorBase; - nsCOMPtr parent = mParentNode; - nsCOMPtr nodeToDelete = mNodeToDelete; - nsCOMPtr refNode = mRefNode; - parent->InsertBefore(*nodeToDelete, refNode, error); + OwningNonNull editorBase = *mEditorBase; + OwningNonNull parentNode = *mParentNode; + OwningNonNull contentToDelete = *mContentToDelete; + nsCOMPtr refContent = mRefContent; + // XXX Perhaps, we should check `refContent` is a child of `parentNode`, + // and if it's not, we should stop undoing or something. + parentNode->InsertBefore(contentToDelete, refContent, error); if (error.Failed()) { NS_WARNING("nsINode::InsertBefore() failed"); return error.StealNSResult(); } - if (!editorBase->AsHTMLEditor() && nodeToDelete->IsText()) { - uint32_t length = nodeToDelete->AsText()->TextLength(); + if (!editorBase->AsHTMLEditor() && contentToDelete->IsText()) { + uint32_t length = contentToDelete->AsText()->TextLength(); if (length > 0) { nsresult rv = MOZ_KnownLive(editorBase->AsTextEditor()) ->DidInsertText(length, 0, length); @@ -109,17 +113,19 @@ NS_IMETHODIMP DeleteNodeTransaction::RedoTransaction() { return NS_OK; } - if (!mEditorBase->AsHTMLEditor() && mNodeToDelete->IsText()) { - uint32_t length = mNodeToDelete->AsText()->TextLength(); + if (!mEditorBase->AsHTMLEditor() && mContentToDelete->IsText()) { + uint32_t length = mContentToDelete->AsText()->TextLength(); if (length > 0) { mEditorBase->AsTextEditor()->WillDeleteText(length, 0, length); } } - mEditorBase->RangeUpdaterRef().SelAdjDeleteNode(*mNodeToDelete); + mEditorBase->RangeUpdaterRef().SelAdjDeleteNode(*mContentToDelete); + OwningNonNull parentNode = *mParentNode; + OwningNonNull contentToDelete = *mContentToDelete; ErrorResult error; - mParentNode->RemoveChild(*mNodeToDelete, error); + parentNode->RemoveChild(contentToDelete, error); NS_WARNING_ASSERTION(!error.Failed(), "nsINode::RemoveChild() failed"); return error.StealNSResult(); } diff --git a/editor/libeditor/DeleteNodeTransaction.h b/editor/libeditor/DeleteNodeTransaction.h index 18825dcceb5cd..b3299e6de5737 100644 --- a/editor/libeditor/DeleteNodeTransaction.h +++ b/editor/libeditor/DeleteNodeTransaction.h @@ -23,7 +23,7 @@ class EditorBase; */ class DeleteNodeTransaction final : public EditTransactionBase { protected: - DeleteNodeTransaction(EditorBase& aEditorBase, nsINode& aNodeToDelete); + DeleteNodeTransaction(EditorBase& aEditorBase, nsIContent& aContentToDelete); public: /** @@ -31,10 +31,10 @@ class DeleteNodeTransaction final : public EditTransactionBase { * it cannot remove the node from its parent. * * @param aEditorBase The editor. - * @param aNodeToDelete The node to be removed from the DOM tree. + * @param aContentToDelete The node to be removed from the DOM tree. */ static already_AddRefed MaybeCreate( - EditorBase& aEditorBase, nsINode& aNodeToDelete); + EditorBase& aEditorBase, nsIContent& aContentToDelete); /** * CanDoIt() returns true if there are enough members and can modify the @@ -57,13 +57,13 @@ class DeleteNodeTransaction final : public EditTransactionBase { RefPtr mEditorBase; // The element to delete. - nsCOMPtr mNodeToDelete; + nsCOMPtr mContentToDelete; // Parent of node to delete. nsCOMPtr mParentNode; // Next sibling to remember for undo/redo purposes. - nsCOMPtr mRefNode; + nsCOMPtr mRefContent; }; } // namespace mozilla diff --git a/editor/libeditor/DeleteRangeTransaction.cpp b/editor/libeditor/DeleteRangeTransaction.cpp index ab90eaeffd916..9f45ca22c012d 100644 --- a/editor/libeditor/DeleteRangeTransaction.cpp +++ b/editor/libeditor/DeleteRangeTransaction.cpp @@ -130,7 +130,7 @@ nsresult DeleteRangeTransaction::CreateTxnsToDeleteBetween( } // see what kind of node we have - if (RefPtr textNode = Text::FromNode(aStart.Container())) { + if (Text* textNode = Text::FromNode(aStart.Container())) { // if the node is a chardata node, then delete chardata content int32_t numToDel; if (aStart == aEnd) { @@ -193,7 +193,7 @@ nsresult DeleteRangeTransaction::CreateTxnsToDeleteContent( return NS_ERROR_NOT_AVAILABLE; } - RefPtr textNode = Text::FromNode(aPoint.Container()); + Text* textNode = Text::FromNode(aPoint.Container()); if (!textNode) { return NS_OK; } @@ -243,13 +243,13 @@ nsresult DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween( } for (; !subtreeIter.IsDone(); subtreeIter.Next()) { - nsCOMPtr node = subtreeIter.GetCurrentNode(); - if (NS_WARN_IF(!node)) { - return NS_ERROR_NULL_POINTER; + nsINode* node = subtreeIter.GetCurrentNode(); + if (NS_WARN_IF(!node) || NS_WARN_IF(!node->IsContent())) { + return NS_ERROR_FAILURE; } RefPtr deleteNodeTransaction = - DeleteNodeTransaction::MaybeCreate(*mEditorBase, *node); + DeleteNodeTransaction::MaybeCreate(*mEditorBase, *node->AsContent()); // XXX This is odd handling. Even if some nodes in the range are not // editable, editor should append transactions because they could // at undoing/redoing. Additionally, if the transaction needs to diff --git a/editor/libeditor/DeleteTextTransaction.cpp b/editor/libeditor/DeleteTextTransaction.cpp index 6aa7a1680fd9a..58ba7938bb6bb 100644 --- a/editor/libeditor/DeleteTextTransaction.cpp +++ b/editor/libeditor/DeleteTextTransaction.cpp @@ -99,7 +99,7 @@ bool DeleteTextTransaction::CanDoIt() const { MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP DeleteTextTransaction::DoTransaction() { - if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) { + if (NS_WARN_IF(!CanDoIt())) { return NS_ERROR_NOT_AVAILABLE; } @@ -111,16 +111,16 @@ DeleteTextTransaction::DoTransaction() { return error.StealNSResult(); } - RefPtr editorBase = mEditorBase; - RefPtr textNode = mTextNode; - editorBase->DoDeleteText(*textNode, mOffset, mLengthToDelete, error); + OwningNonNull editorBase = *mEditorBase; + OwningNonNull textNode = *mTextNode; + editorBase->DoDeleteText(textNode, mOffset, mLengthToDelete, error); if (error.Failed()) { NS_WARNING("EditorBase::DoDeleteText() failed"); return error.StealNSResult(); } DebugOnly rvIgnored = - editorBase->RangeUpdaterRef().SelAdjDeleteText(*textNode, mOffset, + editorBase->RangeUpdaterRef().SelAdjDeleteText(textNode, mOffset, mLengthToDelete); NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "RangeUpdater::SelAdjDeleteText() failed, but ignored"); @@ -142,8 +142,8 @@ DeleteTextTransaction::DoTransaction() { // it an insertion point or an extended selection? MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP DeleteTextTransaction::UndoTransaction() { - if (NS_WARN_IF(!mTextNode) || NS_WARN_IF(!mEditorBase)) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!CanDoIt())) { + return NS_ERROR_NOT_AVAILABLE; } RefPtr editorBase = mEditorBase; RefPtr textNode = mTextNode; diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 9671a3b32d8a0..37ed6367abe84 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -1447,7 +1447,7 @@ already_AddRefed EditorBase::CreateNodeWithTransaction( NS_SUCCEEDED(rvIgnored), "Rangeupdater::SelAdjCreateNode() failed, but ignored"); } else { - newElement = transaction->GetNewNode(); + newElement = transaction->GetNewElement(); MOZ_ASSERT(newElement); // If we succeeded to create and insert new element, we need to adjust @@ -1667,32 +1667,33 @@ already_AddRefed EditorBase::SplitNodeWithTransaction( NS_WARNING_ASSERTION(!aError.Failed(), "EditorBase::DoTransactionInternal() failed"); - nsCOMPtr newContent = transaction->GetNewNode(); - NS_WARNING_ASSERTION(newContent, "Failed to create a new left node"); + nsCOMPtr newLeftContent = transaction->GetNewLeftContent(); + NS_WARNING_ASSERTION(newLeftContent, "Failed to create a new left node"); - if (newContent) { + if (newLeftContent) { // XXX Some other transactions manage range updater by themselves. // Why doesn't SplitNodeTransaction do it? DebugOnly rvIgnored = RangeUpdaterRef().SelAdjSplitNode( - *aStartOfRightNode.GetContainerAsContent(), *newContent); + *aStartOfRightNode.GetContainerAsContent(), *newLeftContent); NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "RangeUpdater::SelAdjSplitNode() failed, but ignored"); } - if (AsHTMLEditor() && newContent) { + if (AsHTMLEditor() && newLeftContent) { TopLevelEditSubActionDataRef().DidSplitContent( - *this, *aStartOfRightNode.GetContainerAsContent(), *newContent); + *this, *aStartOfRightNode.GetContainerAsContent(), *newLeftContent); } if (mInlineSpellChecker) { RefPtr spellChecker = mInlineSpellChecker; - spellChecker->DidSplitNode(aStartOfRightNode.GetContainer(), newContent); + spellChecker->DidSplitNode(aStartOfRightNode.GetContainer(), + newLeftContent); } if (!mActionListeners.IsEmpty()) { AutoActionListenerArray listeners(mActionListeners); for (auto& listener : listeners) { - DebugOnly rvIgnored = - listener->DidSplitNode(aStartOfRightNode.GetContainer(), newContent); + DebugOnly rvIgnored = listener->DidSplitNode( + aStartOfRightNode.GetContainer(), newLeftContent); NS_WARNING_ASSERTION( NS_SUCCEEDED(rvIgnored), "nsIEditActionListener::DidSplitNode() failed, but ignored"); @@ -1703,7 +1704,7 @@ already_AddRefed EditorBase::SplitNodeWithTransaction( return nullptr; } - return newContent.forget(); + return newLeftContent.forget(); } nsresult EditorBase::JoinNodesWithTransaction(nsINode& aLeftNode, @@ -1736,8 +1737,8 @@ nsresult EditorBase::JoinNodesWithTransaction(nsINode& aLeftNode, *this, *aLeftNode.AsContent(), *aRightNode.AsContent()); } - RefPtr transaction = - JoinNodeTransaction::MaybeCreate(*this, aLeftNode, aRightNode); + RefPtr transaction = JoinNodeTransaction::MaybeCreate( + *this, *aLeftNode.AsContent(), *aRightNode.AsContent()); NS_WARNING_ASSERTION( transaction, "JoinNodeTransaction::MaybeCreate() failed, but ignored"); @@ -1825,7 +1826,7 @@ nsresult EditorBase::DeleteNodeWithTransaction(nsINode& aNode) { // FYI: DeleteNodeTransaction grabs aNode while it's alive. So, it's safe // to refer aNode even after calling DoTransaction(). RefPtr deleteNodeTransaction = - DeleteNodeTransaction::MaybeCreate(*this, aNode); + DeleteNodeTransaction::MaybeCreate(*this, *aNode.AsContent()); NS_WARNING_ASSERTION(deleteNodeTransaction, "DeleteNodeTransaction::MaybeCreate() failed"); nsresult rv; @@ -4797,49 +4798,50 @@ already_AddRefed EditorBase::CreateTxnForDeleteRange( // we're either deleting a node or chardata, need to dig into the next/prev // node to find out - nsCOMPtr selectedNode; + nsCOMPtr selectedContent; if (aAction == ePrevious) { - selectedNode = + selectedContent = GetPreviousEditableNode(EditorRawDOMPoint(node, child, offset)); } else if (aAction == eNext) { - selectedNode = GetNextEditableNode(EditorRawDOMPoint(node, child, offset)); + selectedContent = + GetNextEditableNode(EditorRawDOMPoint(node, child, offset)); } - while (selectedNode && selectedNode->IsCharacterData() && - !selectedNode->Length()) { + while (selectedContent && selectedContent->IsCharacterData() && + !selectedContent->Length()) { // Can't delete an empty chardata node (bug 762183) if (aAction == ePrevious) { - selectedNode = GetPreviousEditableNode(*selectedNode); + selectedContent = GetPreviousEditableNode(*selectedContent); } else if (aAction == eNext) { - selectedNode = GetNextEditableNode(*selectedNode); + selectedContent = GetNextEditableNode(*selectedContent); } } - if (NS_WARN_IF(!selectedNode)) { + if (NS_WARN_IF(!selectedContent)) { return nullptr; } - if (RefPtr selectedNodeAsText = Text::FromNode(selectedNode)) { + if (RefPtr selectedTextNode = Text::FromNode(selectedContent)) { if (NS_WARN_IF(aAction != ePrevious && aAction != eNext)) { return nullptr; } // we are deleting from a chardata node, so do a character deletion uint32_t position = 0; if (aAction == ePrevious) { - position = selectedNode->Length(); + position = selectedTextNode->Length(); } RefPtr deleteTextTransaction; if (aAction == ePrevious) { deleteTextTransaction = DeleteTextTransaction::MaybeCreateForPreviousCharacter( - *this, *selectedNodeAsText, position); + *this, *selectedTextNode, position); NS_WARNING_ASSERTION( deleteTextTransaction, "DeleteTextTransaction::MaybeCreateForPreviousCharacter() failed"); } else { deleteTextTransaction = DeleteTextTransaction::MaybeCreateForNextCharacter( - *this, *selectedNodeAsText, position); + *this, *selectedTextNode, position); NS_WARNING_ASSERTION( deleteTextTransaction, "DeleteTextTransaction::MaybeCreateForNextCharacter() failed"); @@ -4849,16 +4851,18 @@ already_AddRefed EditorBase::CreateTxnForDeleteRange( } *aOffset = deleteTextTransaction->Offset(); *aLength = deleteTextTransaction->LengthToDelete(); - selectedNode.forget(aRemovingNode); + nsCOMPtr removingNode(selectedTextNode); + removingNode.forget(aRemovingNode); return deleteTextTransaction.forget(); } RefPtr deleteNodeTransaction = - DeleteNodeTransaction::MaybeCreate(*this, *selectedNode); + DeleteNodeTransaction::MaybeCreate(*this, *selectedContent); if (NS_WARN_IF(!deleteNodeTransaction)) { return nullptr; } - selectedNode.forget(aRemovingNode); + nsCOMPtr removingNode(selectedContent); + removingNode.forget(aRemovingNode); return deleteNodeTransaction.forget(); } diff --git a/editor/libeditor/InsertNodeTransaction.cpp b/editor/libeditor/InsertNodeTransaction.cpp index e4a7dc8509efb..c9e4cb6f1369e 100644 --- a/editor/libeditor/InsertNodeTransaction.cpp +++ b/editor/libeditor/InsertNodeTransaction.cpp @@ -64,7 +64,7 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP InsertNodeTransaction::DoTransaction() { if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mContentToInsert) || NS_WARN_IF(!mPointToInsert.IsSet())) { - return NS_ERROR_NOT_INITIALIZED; + return NS_ERROR_NOT_AVAILABLE; } if (!mPointToInsert.IsSetAndValid()) { @@ -89,9 +89,9 @@ InsertNodeTransaction::DoTransaction() { } } - RefPtr editorBase = mEditorBase; - nsCOMPtr contentToInsert = mContentToInsert; - nsCOMPtr container = mPointToInsert.GetContainer(); + OwningNonNull editorBase = *mEditorBase; + OwningNonNull contentToInsert = *mContentToInsert; + OwningNonNull container = *mPointToInsert.GetContainer(); nsCOMPtr refChild = mPointToInsert.GetChild(); if (contentToInsert->IsElement()) { nsresult rv = editorBase->MarkElementDirty( @@ -104,7 +104,7 @@ InsertNodeTransaction::DoTransaction() { } ErrorResult error; - container->InsertBefore(*contentToInsert, refChild, error); + container->InsertBefore(contentToInsert, refChild, error); if (error.Failed()) { NS_WARNING("nsINode::InsertBefore() failed"); return error.StealNSResult(); @@ -132,10 +132,10 @@ InsertNodeTransaction::DoTransaction() { } // Place the selection just after the inserted element. - EditorRawDOMPoint afterInsertedNode(mContentToInsert); - DebugOnly advanced = afterInsertedNode.AdvanceOffset(); - NS_WARNING_ASSERTION(advanced, - "Failed to advance offset after the inserted node"); + EditorRawDOMPoint afterInsertedNode( + EditorRawDOMPoint::After(contentToInsert)); + NS_WARNING_ASSERTION(afterInsertedNode.IsSet(), + "Failed to set after the inserted node"); IgnoredErrorResult ignoredError; selection->Collapse(afterInsertedNode, ignoredError); NS_WARNING_ASSERTION(!ignoredError.Failed(), @@ -156,8 +156,10 @@ NS_IMETHODIMP InsertNodeTransaction::UndoTransaction() { } // XXX If the inserted node has been moved to different container node or // just removed from the DOM tree, this always fails. + OwningNonNull container = *mPointToInsert.GetContainer(); + OwningNonNull contentToInsert = *mContentToInsert; ErrorResult error; - mPointToInsert.GetContainer()->RemoveChild(*mContentToInsert, error); + container->RemoveChild(contentToInsert, error); NS_WARNING("nsINode::RemoveChild() failed"); return error.StealNSResult(); } diff --git a/editor/libeditor/InsertTextTransaction.cpp b/editor/libeditor/InsertTextTransaction.cpp index fb86bcfd02413..0c41cceccda20 100644 --- a/editor/libeditor/InsertTextTransaction.cpp +++ b/editor/libeditor/InsertTextTransaction.cpp @@ -51,11 +51,11 @@ InsertTextTransaction::DoTransaction() { return NS_ERROR_NOT_AVAILABLE; } - RefPtr editorBase = mEditorBase; - RefPtr textNode = mTextNode; + OwningNonNull editorBase = *mEditorBase; + OwningNonNull textNode = *mTextNode; ErrorResult error; - editorBase->DoInsertText(*textNode, mOffset, mStringToInsert, error); + editorBase->DoInsertText(textNode, mOffset, mStringToInsert, error); if (error.Failed()) { NS_WARNING("EditorBase::DoInsertText() failed"); return error.StealNSResult(); @@ -76,7 +76,7 @@ InsertTextTransaction::DoTransaction() { } // XXX Other transactions do not do this but its callers do. // Why do this transaction do this by itself? - editorBase->RangeUpdaterRef().SelAdjInsertText(*textNode, mOffset, + editorBase->RangeUpdaterRef().SelAdjInsertText(textNode, mOffset, mStringToInsert); return NS_OK; @@ -87,10 +87,10 @@ InsertTextTransaction::UndoTransaction() { if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) { return NS_ERROR_NOT_INITIALIZED; } - RefPtr editorBase = mEditorBase; - RefPtr textNode = mTextNode; + OwningNonNull editorBase = *mEditorBase; + OwningNonNull textNode = *mTextNode; ErrorResult error; - editorBase->DoDeleteText(*textNode, mOffset, mStringToInsert.Length(), error); + editorBase->DoDeleteText(textNode, mOffset, mStringToInsert.Length(), error); NS_WARNING_ASSERTION(!error.Failed(), "EditorBase::DoDeleteText() failed"); return error.StealNSResult(); } diff --git a/editor/libeditor/JoinNodeTransaction.cpp b/editor/libeditor/JoinNodeTransaction.cpp index 0c9650fc3d6e0..4b82e56c01fd9 100644 --- a/editor/libeditor/JoinNodeTransaction.cpp +++ b/editor/libeditor/JoinNodeTransaction.cpp @@ -19,9 +19,10 @@ using namespace dom; // static already_AddRefed JoinNodeTransaction::MaybeCreate( - EditorBase& aEditorBase, nsINode& aLeftNode, nsINode& aRightNode) { + EditorBase& aEditorBase, nsIContent& aLeftContent, + nsIContent& aRightContent) { RefPtr transaction = - new JoinNodeTransaction(aEditorBase, aLeftNode, aRightNode); + new JoinNodeTransaction(aEditorBase, aLeftContent, aRightContent); if (NS_WARN_IF(!transaction->CanDoIt())) { return nullptr; } @@ -29,56 +30,57 @@ already_AddRefed JoinNodeTransaction::MaybeCreate( } JoinNodeTransaction::JoinNodeTransaction(EditorBase& aEditorBase, - nsINode& aLeftNode, - nsINode& aRightNode) + nsIContent& aLeftContent, + nsIContent& aRightContent) : mEditorBase(&aEditorBase), - mLeftNode(&aLeftNode), - mRightNode(&aRightNode), + mLeftContent(&aLeftContent), + mRightContent(&aRightContent), mOffset(0) {} NS_IMPL_CYCLE_COLLECTION_INHERITED(JoinNodeTransaction, EditTransactionBase, - mEditorBase, mLeftNode, mRightNode, mParent) + mEditorBase, mLeftContent, mRightContent, + mParentNode) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JoinNodeTransaction) NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) bool JoinNodeTransaction::CanDoIt() const { - if (NS_WARN_IF(!mLeftNode) || NS_WARN_IF(!mRightNode) || - NS_WARN_IF(!mEditorBase) || !mLeftNode->GetParentNode()) { + if (NS_WARN_IF(!mLeftContent) || NS_WARN_IF(!mRightContent) || + NS_WARN_IF(!mEditorBase) || !mLeftContent->GetParentNode()) { return false; } - return mEditorBase->IsModifiableNode(*mLeftNode->GetParentNode()); + return mEditorBase->IsModifiableNode(*mLeftContent->GetParentNode()); } // After DoTransaction() and RedoTransaction(), the left node is removed from // the content tree and right node remains. MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP JoinNodeTransaction::DoTransaction() { - if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mLeftNode) || - NS_WARN_IF(!mRightNode)) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mLeftContent) || + NS_WARN_IF(!mRightContent)) { + return NS_ERROR_NOT_AVAILABLE; } // Get the parent node - nsCOMPtr leftNodeParent = mLeftNode->GetParentNode(); - if (NS_WARN_IF(!leftNodeParent)) { - return NS_ERROR_FAILURE; + nsCOMPtr leftContentParent = mLeftContent->GetParentNode(); + if (NS_WARN_IF(!leftContentParent)) { + return NS_ERROR_NOT_AVAILABLE; } - // Verify that mLeftNode and mRightNode have the same parent - if (leftNodeParent != mRightNode->GetParentNode()) { + // Verify that mLeftContent and mRightContent have the same parent + if (leftContentParent != mRightContent->GetParentNode()) { NS_ASSERTION(false, "Nodes do not have same parent"); - return NS_ERROR_INVALID_ARG; + return NS_ERROR_NOT_AVAILABLE; } - // Set this instance's mParent. Other methods will see a non-null mParent - // and know all is well - mParent = leftNodeParent; - mOffset = mLeftNode->Length(); + // Set this instance's mParentNode. Other methods will see a non-null + // mParentNode and know all is well + mParentNode = leftContentParent; + mOffset = mLeftContent->Length(); - RefPtr editorBase = mEditorBase; - nsCOMPtr leftNode = mLeftNode; - nsCOMPtr rightNode = mRightNode; - nsresult rv = editorBase->DoJoinNodes(rightNode, leftNode, leftNodeParent); + OwningNonNull editorBase = *mEditorBase; + OwningNonNull leftNode = *mLeftContent; + OwningNonNull rightNode = *mRightContent; + nsresult rv = editorBase->DoJoinNodes(rightNode, leftNode, leftContentParent); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EditorBase::DoJoinNodes() failed"); return rv; } @@ -87,42 +89,49 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP JoinNodeTransaction::DoTransaction() { // mRight and re-inserted mLeft? MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP JoinNodeTransaction::UndoTransaction() { - if (NS_WARN_IF(!mParent) || NS_WARN_IF(!mLeftNode) || - NS_WARN_IF(!mRightNode) || NS_WARN_IF(!mEditorBase)) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mParentNode) || NS_WARN_IF(!mLeftContent) || + NS_WARN_IF(!mRightContent) || NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_AVAILABLE; } + OwningNonNull leftContent = *mLeftContent; + OwningNonNull rightContent = *mRightContent; + OwningNonNull parentNode = *mParentNode; + // First, massage the existing node so it is in its post-split state ErrorResult error; - if (mRightNode->GetAsText()) { - RefPtr editorBase = mEditorBase; - RefPtr rightNodeAsText = mRightNode->GetAsText(); - editorBase->DoDeleteText(*rightNodeAsText, 0, mOffset, error); + if (Text* rightTextNode = rightContent->GetAsText()) { + OwningNonNull editorBase = *mEditorBase; + editorBase->DoDeleteText(MOZ_KnownLive(*rightTextNode), 0, mOffset, error); if (error.Failed()) { NS_WARNING("EditorBase::DoDeleteText() failed"); return error.StealNSResult(); } } else { - nsCOMPtr child = mRightNode->GetFirstChild(); - for (uint32_t i = 0; i < mOffset; i++) { + AutoTArray, 24> movingChildren; + if (nsIContent* child = mRightContent->GetFirstChild()) { + movingChildren.AppendElement(*child); + for (uint32_t i = 0; i < mOffset; i++) { + child = child->GetNextSibling(); + if (!child) { + break; + } + movingChildren.AppendElement(*child); + } + } + for (OwningNonNull& child : movingChildren) { + leftContent->AppendChild(child, error); if (error.Failed()) { + NS_WARNING("nsINode::AppendChild() failed"); return error.StealNSResult(); } - if (!child) { - return NS_ERROR_NULL_POINTER; - } - nsCOMPtr nextSibling = child->GetNextSibling(); - mLeftNode->AppendChild(*child, error); - NS_WARNING_ASSERTION(!error.Failed(), "nsINode::AppendChild() failed"); - child = nextSibling; } } NS_WARNING_ASSERTION(!error.Failed(), "The previous error was ignored"); // Second, re-insert the left node into the tree - nsCOMPtr refNode = mRightNode; - mParent->InsertBefore(*mLeftNode, refNode, error); + parentNode->InsertBefore(leftContent, rightContent, error); NS_WARNING_ASSERTION(!error.Failed(), "nsINode::InsertBefore() failed"); return error.StealNSResult(); } diff --git a/editor/libeditor/JoinNodeTransaction.h b/editor/libeditor/JoinNodeTransaction.h index d29211731cd0f..a44a9bf8ab8d6 100644 --- a/editor/libeditor/JoinNodeTransaction.h +++ b/editor/libeditor/JoinNodeTransaction.h @@ -12,6 +12,7 @@ #include "nsID.h" // for REFNSIID #include "nscore.h" // for NS_IMETHOD +class nsIContent; class nsINode; namespace mozilla { @@ -26,8 +27,8 @@ class EditorBase; */ class JoinNodeTransaction final : public EditTransactionBase { protected: - JoinNodeTransaction(EditorBase& aEditorBase, nsINode& aLeftNode, - nsINode& aRightNode); + JoinNodeTransaction(EditorBase& aEditorBase, nsIContent& aLeftContent, + nsIContent& aRightContent); public: /** @@ -35,11 +36,12 @@ class JoinNodeTransaction final : public EditTransactionBase { * nodes. * * @param aEditorBase The provider of core editing operations. - * @param aLeftNode The first of two nodes to join. - * @param aRightNode The second of two nodes to join. + * @param aLeftContent The first of two nodes to join. + * @param aRightContent The second of two nodes to join. */ static already_AddRefed MaybeCreate( - EditorBase& aEditorBase, nsINode& aLeftNode, nsINode& aRightNode); + EditorBase& aEditorBase, nsIContent& aLeftContent, + nsIContent& aRightContent); /** * CanDoIt() returns true if there are enough members and can join or @@ -56,18 +58,18 @@ class JoinNodeTransaction final : public EditTransactionBase { protected: RefPtr mEditorBase; - // The nodes to operate upon. After the merge, mRightNode remains and - // mLeftNode is removed from the content tree. - nsCOMPtr mLeftNode; - nsCOMPtr mRightNode; + // The nodes to operate upon. After the merge, mRightContent remains and + // mLeftContent is removed from the content tree. + nsCOMPtr mLeftContent; + nsCOMPtr mRightContent; // The offset into mNode where the children of mElement are split (for // undo). mOffset is the index of the first child in the right node. -1 // means the left node had no children. uint32_t mOffset; - // The parent node containing mLeftNode and mRightNode. - nsCOMPtr mParent; + // The parent node containing mLeftContent and mRightContent. + nsCOMPtr mParentNode; }; } // namespace mozilla diff --git a/editor/libeditor/SplitNodeTransaction.cpp b/editor/libeditor/SplitNodeTransaction.cpp index b4a805478df1f..0463f99535acf 100644 --- a/editor/libeditor/SplitNodeTransaction.cpp +++ b/editor/libeditor/SplitNodeTransaction.cpp @@ -18,32 +18,32 @@ namespace mozilla { using namespace dom; template already_AddRefed SplitNodeTransaction::Create( - EditorBase& aEditorBase, const EditorDOMPoint& aStartOfRightNode); + EditorBase& aEditorBase, const EditorDOMPoint& aStartOfRightContent); template already_AddRefed SplitNodeTransaction::Create( - EditorBase& aEditorBase, const EditorRawDOMPoint& aStartOfRightNode); + EditorBase& aEditorBase, const EditorRawDOMPoint& aStartOfRightContent); // static template already_AddRefed SplitNodeTransaction::Create( EditorBase& aEditorBase, - const EditorDOMPointBase& aStartOfRightNode) { + const EditorDOMPointBase& aStartOfRightContent) { RefPtr transaction = - new SplitNodeTransaction(aEditorBase, aStartOfRightNode); + new SplitNodeTransaction(aEditorBase, aStartOfRightContent); return transaction.forget(); } template SplitNodeTransaction::SplitNodeTransaction( EditorBase& aEditorBase, - const EditorDOMPointBase& aStartOfRightNode) - : mEditorBase(&aEditorBase), mStartOfRightNode(aStartOfRightNode) { - MOZ_DIAGNOSTIC_ASSERT(aStartOfRightNode.IsSet()); - MOZ_DIAGNOSTIC_ASSERT(aStartOfRightNode.GetContainerAsContent()); + const EditorDOMPointBase& aStartOfRightContent) + : mEditorBase(&aEditorBase), mStartOfRightContent(aStartOfRightContent) { + MOZ_DIAGNOSTIC_ASSERT(aStartOfRightContent.IsSet()); + MOZ_DIAGNOSTIC_ASSERT(aStartOfRightContent.GetContainerAsContent()); } NS_IMPL_CYCLE_COLLECTION_INHERITED(SplitNodeTransaction, EditTransactionBase, - mEditorBase, mStartOfRightNode, mParent, - mNewLeftNode) + mEditorBase, mStartOfRightContent, + mContainerParentNode, mNewLeftContent) NS_IMPL_ADDREF_INHERITED(SplitNodeTransaction, EditTransactionBase) NS_IMPL_RELEASE_INHERITED(SplitNodeTransaction, EditTransactionBase) @@ -52,16 +52,16 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP SplitNodeTransaction::DoTransaction() { - if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mStartOfRightNode.IsSet())) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mStartOfRightContent.IsSet())) { + return NS_ERROR_NOT_AVAILABLE; } - MOZ_ASSERT(mStartOfRightNode.IsSetAndValid()); + MOZ_ASSERT(mStartOfRightContent.IsSetAndValid()); // Create a new node ErrorResult error; // Don't use .downcast directly because AsContent has an assertion we want nsCOMPtr cloneOfRightContainer = - mStartOfRightNode.GetContainer()->CloneNode(false, error); + mStartOfRightContent.GetContainer()->CloneNode(false, error); if (error.Failed()) { NS_WARNING("nsINode::CloneNode() failed"); return error.StealNSResult(); @@ -70,11 +70,21 @@ SplitNodeTransaction::DoTransaction() { return NS_ERROR_UNEXPECTED; } - RefPtr editorBase(mEditorBase); + mNewLeftContent = cloneOfRightContainer->AsContent(); + + mContainerParentNode = mStartOfRightContent.GetContainerParent(); + if (!mContainerParentNode) { + NS_WARNING("Right container was an orphan node"); + return NS_ERROR_NOT_AVAILABLE; + } + + OwningNonNull editorBase = *mEditorBase; + OwningNonNull newLeftContent = *mNewLeftContent; + OwningNonNull containerParentNode = *mContainerParentNode; + EditorDOMPoint startOfRightContent(mStartOfRightContent); - mNewLeftNode = cloneOfRightContainer->AsContent(); if (RefPtr startOfRightNode = - mStartOfRightNode.GetContainerAsElement()) { + startOfRightContent.GetContainerAsElement()) { nsresult rv = editorBase->MarkElementDirty(*startOfRightNode); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return EditorBase::ToGenericNSResult(rv); @@ -83,17 +93,8 @@ SplitNodeTransaction::DoTransaction() { "EditorBase::MarkElementDirty() failed, but ignored"); } - // Get the parent node - mParent = mStartOfRightNode.GetContainerParent(); - if (!mParent) { - NS_WARNING("Right container was an orphan node"); - return NS_ERROR_FAILURE; - } - // Insert the new node - nsCOMPtr newLeftNode = mNewLeftNode; - editorBase->DoSplitNode(EditorDOMPoint(mStartOfRightNode), *newLeftNode, - error); + editorBase->DoSplitNode(startOfRightContent, newLeftContent, error); if (error.Failed()) { NS_WARNING("EditorBase::DoSplitNode() failed"); return error.StealNSResult(); @@ -111,7 +112,7 @@ SplitNodeTransaction::DoTransaction() { if (NS_WARN_IF(!selection)) { return NS_ERROR_FAILURE; } - EditorRawDOMPoint atEndOfLeftNode(EditorRawDOMPoint::AtEndOf(mNewLeftNode)); + EditorRawDOMPoint atEndOfLeftNode(EditorRawDOMPoint::AtEndOf(newLeftContent)); selection->Collapse(atEndOfLeftNode, error); NS_WARNING_ASSERTION(!error.Failed(), "Selection::Collapse() failed"); return error.StealNSResult(); @@ -119,19 +120,21 @@ SplitNodeTransaction::DoTransaction() { MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP SplitNodeTransaction::UndoTransaction() { - if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mNewLeftNode) || - NS_WARN_IF(!mParent) || NS_WARN_IF(!mStartOfRightNode.IsSet())) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mNewLeftContent) || + NS_WARN_IF(!mContainerParentNode) || + NS_WARN_IF(!mStartOfRightContent.IsSet())) { + return NS_ERROR_NOT_AVAILABLE; } // This assumes Do inserted the new node in front of the prior existing node // XXX Perhaps, we should reset mStartOfRightNode with current first child // of the right node. - RefPtr editorBase = mEditorBase; - nsCOMPtr container = mStartOfRightNode.GetContainer(); - nsCOMPtr newLeftNode = mNewLeftNode; - nsCOMPtr parent = mParent; - nsresult rv = editorBase->DoJoinNodes(container, newLeftNode, parent); + OwningNonNull editorBase = *mEditorBase; + OwningNonNull containerNode = *mStartOfRightContent.GetContainer(); + OwningNonNull newLeftContent = *mNewLeftContent; + OwningNonNull containerParentNode = *mContainerParentNode; + nsresult rv = editorBase->DoJoinNodes(containerNode, newLeftContent, + containerParentNode); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EditorBase::DoJoinNodes() failed"); return rv; } @@ -142,58 +145,54 @@ SplitNodeTransaction::UndoTransaction() { */ MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP SplitNodeTransaction::RedoTransaction() { - if (NS_WARN_IF(!mNewLeftNode) || NS_WARN_IF(!mParent) || - NS_WARN_IF(!mStartOfRightNode.IsSet()) || NS_WARN_IF(!mEditorBase)) { - return NS_ERROR_NOT_INITIALIZED; + if (NS_WARN_IF(!mNewLeftContent) || NS_WARN_IF(!mContainerParentNode) || + NS_WARN_IF(!mStartOfRightContent.IsSet()) || NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_AVAILABLE; } + OwningNonNull editorBase = *mEditorBase; + OwningNonNull newLeftContent = *mNewLeftContent; + OwningNonNull containerParentNode = *mContainerParentNode; + EditorDOMPoint startOfRightContent(mStartOfRightContent); + // First, massage the existing node so it is in its post-split state ErrorResult error; - if (mStartOfRightNode.IsInTextNode()) { - RefPtr editorBase = mEditorBase; - RefPtr rightNodeAsText = mStartOfRightNode.GetContainerAsText(); - MOZ_DIAGNOSTIC_ASSERT(rightNodeAsText); - editorBase->DoDeleteText(*rightNodeAsText, 0, mStartOfRightNode.Offset(), - error); + if (startOfRightContent.IsInTextNode()) { + Text* rightTextNode = startOfRightContent.ContainerAsText(); + editorBase->DoDeleteText(MOZ_KnownLive(*rightTextNode), 0, + startOfRightContent.Offset(), error); if (error.Failed()) { NS_WARNING("EditorBase::DoDeleteText() failed"); return error.StealNSResult(); } } else { - nsCOMPtr child = - mStartOfRightNode.GetContainer()->GetFirstChild(); - nsCOMPtr nextSibling; - ErrorResult error; - for (uint32_t i = 0; i < mStartOfRightNode.Offset(); i++) { - // XXX This must be bad behavior. Perhaps, we should work with - // mStartOfRightNode::GetChild(). Even if some children - // before the right node have been inserted or removed, we should - // move all children before the right node because user must focus - // on the right node, so, it must be the expected behavior. - if (NS_WARN_IF(!child)) { - return NS_ERROR_NULL_POINTER; - } - nextSibling = child->GetNextSibling(); - mStartOfRightNode.GetContainer()->RemoveChild(*child, error); - if (error.Failed()) { - NS_WARNING("nsINode::RemoveChild() failed"); - return error.StealNSResult(); + AutoTArray, 24> movingChildren; + if (nsIContent* child = + startOfRightContent.GetContainer()->GetFirstChild()) { + movingChildren.AppendElement(*child); + for (uint32_t i = 0; i < startOfRightContent.Offset(); i++) { + child = child->GetNextSibling(); + if (!child) { + break; + } + movingChildren.AppendElement(*child); } - mNewLeftNode->AppendChild(*child, error); + } + ErrorResult error; + for (OwningNonNull& child : movingChildren) { + newLeftContent->AppendChild(child, error); if (error.Failed()) { NS_WARNING("nsINode::AppendChild() failed"); return error.StealNSResult(); } - child = nextSibling; } } MOZ_ASSERT(!error.Failed()); // Second, re-insert the left node into the tree - mParent->InsertBefore(*mNewLeftNode, mStartOfRightNode.GetContainer(), error); + containerParentNode->InsertBefore(newLeftContent, + startOfRightContent.GetContainer(), error); NS_WARNING_ASSERTION(!error.Failed(), "nsINode::InsertBefore() failed"); return error.StealNSResult(); } -nsIContent* SplitNodeTransaction::GetNewNode() { return mNewLeftNode; } - } // namespace mozilla diff --git a/editor/libeditor/SplitNodeTransaction.h b/editor/libeditor/SplitNodeTransaction.h index 80cd5092ac849..079492edcd1de 100644 --- a/editor/libeditor/SplitNodeTransaction.h +++ b/editor/libeditor/SplitNodeTransaction.h @@ -10,12 +10,10 @@ #include "mozilla/EditTransactionBase.h" // for EditTxn, etc. #include "nsCOMPtr.h" // for nsCOMPtr #include "nsCycleCollectionParticipant.h" +#include "nsIContent.h" #include "nsISupportsImpl.h" // for NS_DECL_ISUPPORTS_INHERITED #include "nscore.h" // for NS_IMETHOD -class nsIContent; -class nsINode; - namespace mozilla { class EditorBase; @@ -28,7 +26,7 @@ class SplitNodeTransaction final : public EditTransactionBase { private: template SplitNodeTransaction(EditorBase& aEditorBase, - const EditorDOMPointBase& aStartOfRightNode); + const EditorDOMPointBase& aStartOfRightContent); public: /** @@ -36,16 +34,16 @@ class SplitNodeTransaction final : public EditTransactionBase { * existing node (right node), and split the contents between the same point * in both nodes. * - * @param aEditorBase The provider of core editing operations. - * @param aStartOfRightNode The point to split. Its container will be - * the right node, i.e., become the new node's - * next sibling. And the point will be start - * of the right node. + * @param aEditorBase The provider of core editing operations. + * @param aStartOfRightContent The point to split. Its container will be + * the right node, i.e., become the new node's + * next sibling. And the point will be start + * of the right node. */ template static already_AddRefed Create( EditorBase& aEditorBase, - const EditorDOMPointBase& aStartOfRightNode); + const EditorDOMPointBase& aStartOfRightContent); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SplitNodeTransaction, @@ -55,7 +53,7 @@ class SplitNodeTransaction final : public EditTransactionBase { NS_IMETHOD RedoTransaction() override; - nsIContent* GetNewNode(); + nsIContent* GetNewLeftContent() const { return mNewLeftContent; } protected: virtual ~SplitNodeTransaction() = default; @@ -64,13 +62,13 @@ class SplitNodeTransaction final : public EditTransactionBase { // The container is existing right node (will be split). // The point referring this is start of the right node after it's split. - EditorDOMPoint mStartOfRightNode; + EditorDOMPoint mStartOfRightContent; - // The node we create when splitting mExistingRightNode. - nsCOMPtr mNewLeftNode; + // The node we create when splitting mExistingRightContent. + nsCOMPtr mNewLeftContent; - // The parent shared by mExistingRightNode and mNewLeftNode. - nsCOMPtr mParent; + // The parent shared by mExistingRightContent and mNewLeftContent. + nsCOMPtr mContainerParentNode; }; } // namespace mozilla