diff --git a/editor/libeditor/CompositionTransaction.cpp b/editor/libeditor/CompositionTransaction.cpp index 25938fa608b6..bde53d2e5d65 100644 --- a/editor/libeditor/CompositionTransaction.cpp +++ b/editor/libeditor/CompositionTransaction.cpp @@ -33,7 +33,7 @@ CompositionTransaction::CompositionTransaction( , mReplaceLength(aReplaceLength) , mRanges(aTextRangeArray) , mStringToInsert(aStringToInsert) - , mEditorBase(aEditorBase) + , mEditorBase(&aEditorBase) , mRangeUpdater(aRangeUpdater) , mFixed(false) { @@ -45,6 +45,7 @@ CompositionTransaction::~CompositionTransaction() } NS_IMPL_CYCLE_COLLECTION_INHERITED(CompositionTransaction, EditTransactionBase, + mEditorBase, mTextNode) // mRangeList can't lead to cycles @@ -60,9 +61,13 @@ NS_IMPL_RELEASE_INHERITED(CompositionTransaction, EditTransactionBase) NS_IMETHODIMP CompositionTransaction::DoTransaction() { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_INITIALIZED; + } + // Fail before making any changes if there's no selection controller nsCOMPtr selCon; - mEditorBase.GetSelectionController(getter_AddRefs(selCon)); + mEditorBase->GetSelectionController(getter_AddRefs(selCon)); NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); // Advance caret: This requires the presentation shell to get the selection. @@ -108,9 +113,13 @@ CompositionTransaction::DoTransaction() NS_IMETHODIMP CompositionTransaction::UndoTransaction() { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_INITIALIZED; + } + // Get the selection first so we'll fail before making any changes if we // can't get it - RefPtr selection = mEditorBase.GetSelection(); + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED); nsresult rv = mTextNode->DeleteData(mOffset, mStringToInsert.Length()); @@ -171,7 +180,10 @@ CompositionTransaction::GetTxnDescription(nsAString& aString) nsresult CompositionTransaction::SetSelectionForRanges() { - return SetIMESelection(mEditorBase, mTextNode, mOffset, + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_INITIALIZED; + } + return SetIMESelection(*mEditorBase, mTextNode, mOffset, mStringToInsert.Length(), mRanges); } diff --git a/editor/libeditor/CompositionTransaction.h b/editor/libeditor/CompositionTransaction.h index acb3d8beba71..c2134beddc79 100644 --- a/editor/libeditor/CompositionTransaction.h +++ b/editor/libeditor/CompositionTransaction.h @@ -90,7 +90,7 @@ private: nsString mStringToInsert; // The editor, which is used to get the selection controller. - EditorBase& mEditorBase; + RefPtr mEditorBase; RangeUpdater* mRangeUpdater; diff --git a/editor/libeditor/CreateElementTransaction.cpp b/editor/libeditor/CreateElementTransaction.cpp index 21d4a4288ba8..3206338da9e2 100644 --- a/editor/libeditor/CreateElementTransaction.cpp +++ b/editor/libeditor/CreateElementTransaction.cpp @@ -49,6 +49,7 @@ CreateElementTransaction::~CreateElementTransaction() NS_IMPL_CYCLE_COLLECTION_INHERITED(CreateElementTransaction, EditTransactionBase, + mEditorBase, mParent, mNewNode, mRefNode) @@ -62,7 +63,9 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) NS_IMETHODIMP CreateElementTransaction::DoTransaction() { - MOZ_ASSERT(mEditorBase && mTag && mParent); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTag) || NS_WARN_IF(!mParent)) { + return NS_ERROR_NOT_INITIALIZED; + } mNewNode = mEditorBase->CreateHTMLContent(mTag); NS_ENSURE_STATE(mNewNode); @@ -105,7 +108,9 @@ CreateElementTransaction::DoTransaction() NS_IMETHODIMP CreateElementTransaction::UndoTransaction() { - MOZ_ASSERT(mEditorBase && mParent); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mParent)) { + return NS_ERROR_NOT_INITIALIZED; + } ErrorResult rv; mParent->RemoveChild(*mNewNode, rv); @@ -116,7 +121,9 @@ CreateElementTransaction::UndoTransaction() NS_IMETHODIMP CreateElementTransaction::RedoTransaction() { - MOZ_ASSERT(mEditorBase && mParent); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mParent)) { + return NS_ERROR_NOT_INITIALIZED; + } // First, reset mNewNode so it has no attributes or content // XXX We never actually did this, we only cleared mNewNode's contents if it diff --git a/editor/libeditor/CreateElementTransaction.h b/editor/libeditor/CreateElementTransaction.h index 70fecceaef01..fd5abb8a86d6 100644 --- a/editor/libeditor/CreateElementTransaction.h +++ b/editor/libeditor/CreateElementTransaction.h @@ -57,7 +57,7 @@ protected: virtual ~CreateElementTransaction(); // The document into which the new node will be inserted. - EditorBase* mEditorBase; + RefPtr mEditorBase; // The tag (mapping to object type) for the new element. nsCOMPtr mTag; diff --git a/editor/libeditor/DeleteNodeTransaction.cpp b/editor/libeditor/DeleteNodeTransaction.cpp index b64d49db2326..3692745017d5 100644 --- a/editor/libeditor/DeleteNodeTransaction.cpp +++ b/editor/libeditor/DeleteNodeTransaction.cpp @@ -15,7 +15,7 @@ namespace mozilla { DeleteNodeTransaction::DeleteNodeTransaction(EditorBase& aEditorBase, nsINode& aNodeToDelete, RangeUpdater* aRangeUpdater) - : mEditorBase(aEditorBase) + : mEditorBase(&aEditorBase) , mNodeToDelete(&aNodeToDelete) , mParentNode(aNodeToDelete.GetParentNode()) , mRangeUpdater(aRangeUpdater) @@ -31,6 +31,7 @@ DeleteNodeTransaction::~DeleteNodeTransaction() } NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteNodeTransaction, EditTransactionBase, + mEditorBase, mNodeToDelete, mParentNode, mRefNode) @@ -43,8 +44,8 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) bool DeleteNodeTransaction::CanDoIt() const { - if (NS_WARN_IF(!mNodeToDelete) || !mParentNode || - !mEditorBase.IsModifiableNode(mParentNode)) { + if (NS_WARN_IF(!mNodeToDelete) || NS_WARN_IF(!mEditorBase) || + !mParentNode || !mEditorBase->IsModifiableNode(mParentNode)) { return false; } return true; diff --git a/editor/libeditor/DeleteNodeTransaction.h b/editor/libeditor/DeleteNodeTransaction.h index 8ce97bea64e7..e827249e7ef9 100644 --- a/editor/libeditor/DeleteNodeTransaction.h +++ b/editor/libeditor/DeleteNodeTransaction.h @@ -46,7 +46,7 @@ protected: virtual ~DeleteNodeTransaction(); // The editor for this transaction. - EditorBase& mEditorBase; + RefPtr mEditorBase; // The element to delete. nsCOMPtr mNodeToDelete; diff --git a/editor/libeditor/DeleteRangeTransaction.cpp b/editor/libeditor/DeleteRangeTransaction.cpp index 396e064b6fd7..3ce6f05be812 100644 --- a/editor/libeditor/DeleteRangeTransaction.cpp +++ b/editor/libeditor/DeleteRangeTransaction.cpp @@ -27,7 +27,7 @@ using namespace dom; DeleteRangeTransaction::DeleteRangeTransaction(EditorBase& aEditorBase, nsRange& aRangeToDelete, RangeUpdater* aRangeUpdater) - : mEditorBase(aEditorBase) + : mEditorBase(&aEditorBase) , mRangeToDelete(aRangeToDelete.CloneRange()) , mRangeUpdater(aRangeUpdater) { @@ -35,6 +35,7 @@ DeleteRangeTransaction::DeleteRangeTransaction(EditorBase& aEditorBase, NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteRangeTransaction, EditAggregateTransaction, + mEditorBase, mRangeToDelete) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteRangeTransaction) @@ -43,7 +44,9 @@ NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction) NS_IMETHODIMP DeleteRangeTransaction::DoTransaction() { - MOZ_ASSERT(mRangeToDelete); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mRangeToDelete)) { + return NS_ERROR_NOT_AVAILABLE; + } // build the child transactions nsCOMPtr startParent = mRangeToDelete->GetStartParent(); @@ -77,9 +80,9 @@ DeleteRangeTransaction::DoTransaction() // only set selection to deletion point if editor gives permission bool bAdjustSelection; - mEditorBase.ShouldTxnSetSelection(&bAdjustSelection); + mEditorBase->ShouldTxnSetSelection(&bAdjustSelection); if (bAdjustSelection) { - RefPtr selection = mEditorBase.GetSelection(); + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); rv = selection->Collapse(startParent, startOffset); NS_ENSURE_SUCCESS(rv, rv); @@ -117,6 +120,10 @@ DeleteRangeTransaction::CreateTxnsToDeleteBetween(nsINode* aNode, int32_t aStartOffset, int32_t aEndOffset) { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_AVAILABLE; + } + // see what kind of node we have if (aNode->IsNodeOfType(nsINode::eDATA_NODE)) { // if the node is a chardata node, then delete chardata content @@ -131,7 +138,7 @@ DeleteRangeTransaction::CreateTxnsToDeleteBetween(nsINode* aNode, static_cast(aNode); RefPtr deleteTextTransaction = - new DeleteTextTransaction(mEditorBase, *charDataNode, aStartOffset, + new DeleteTextTransaction(*mEditorBase, *charDataNode, aStartOffset, numToDel, mRangeUpdater); // If the text node isn't editable, it should be never undone/redone. // So, the transaction shouldn't be recorded. @@ -150,7 +157,7 @@ DeleteRangeTransaction::CreateTxnsToDeleteBetween(nsINode* aNode, break; } RefPtr deleteNodeTransaction = - new DeleteNodeTransaction(mEditorBase, *child, mRangeUpdater); + new DeleteNodeTransaction(*mEditorBase, *child, mRangeUpdater); // XXX This is odd handling. Even if some children are not editable, // editor should append transactions because they could be editable // at undoing/redoing. Additionally, if the transaction needs to @@ -169,6 +176,10 @@ DeleteRangeTransaction::CreateTxnsToDeleteContent(nsINode* aNode, int32_t aOffset, nsIEditor::EDirection aAction) { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_AVAILABLE; + } + // see what kind of node we have if (aNode->IsNodeOfType(nsINode::eDATA_NODE)) { // if the node is a chardata node, then delete chardata content @@ -185,7 +196,7 @@ DeleteRangeTransaction::CreateTxnsToDeleteContent(nsINode* aNode, RefPtr dataNode = static_cast(aNode); RefPtr deleteTextTransaction = - new DeleteTextTransaction(mEditorBase, *dataNode, start, numToDelete, + new DeleteTextTransaction(*mEditorBase, *dataNode, start, numToDelete, mRangeUpdater); // If the text node isn't editable, it should be never undone/redone. // So, the transaction shouldn't be recorded. @@ -202,6 +213,10 @@ DeleteRangeTransaction::CreateTxnsToDeleteContent(nsINode* aNode, nsresult DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween() { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_AVAILABLE; + } + nsCOMPtr iter = NS_NewContentSubtreeIterator(); nsresult rv = iter->Init(mRangeToDelete); @@ -214,7 +229,7 @@ DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween() } RefPtr deleteNodeTransaction = - new DeleteNodeTransaction(mEditorBase, *node, mRangeUpdater); + new DeleteNodeTransaction(*mEditorBase, *node, mRangeUpdater); // 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/DeleteRangeTransaction.h b/editor/libeditor/DeleteRangeTransaction.h index 3e7401380f7c..c6db9f3dad22 100644 --- a/editor/libeditor/DeleteRangeTransaction.h +++ b/editor/libeditor/DeleteRangeTransaction.h @@ -61,7 +61,7 @@ protected: nsIEditor::EDirection aAction); // The editor for this transaction. - EditorBase& mEditorBase; + RefPtr mEditorBase; // P1 in the range. RefPtr mRangeToDelete; diff --git a/editor/libeditor/DeleteTextTransaction.cpp b/editor/libeditor/DeleteTextTransaction.cpp index 999372a2319e..2b04e0921ec5 100644 --- a/editor/libeditor/DeleteTextTransaction.cpp +++ b/editor/libeditor/DeleteTextTransaction.cpp @@ -25,7 +25,7 @@ DeleteTextTransaction::DeleteTextTransaction( uint32_t aOffset, uint32_t aNumCharsToDelete, RangeUpdater* aRangeUpdater) - : mEditorBase(aEditorBase) + : mEditorBase(&aEditorBase) , mCharData(&aCharData) , mOffset(aOffset) , mNumCharsToDelete(aNumCharsToDelete) @@ -36,6 +36,7 @@ DeleteTextTransaction::DeleteTextTransaction( } NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteTextTransaction, EditTransactionBase, + mEditorBase, mCharData) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteTextTransaction) @@ -44,16 +45,18 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) bool DeleteTextTransaction::CanDoIt() const { - if (NS_WARN_IF(!mCharData)) { + if (NS_WARN_IF(!mCharData) || NS_WARN_IF(!mEditorBase)) { return false; } - return mEditorBase.IsModifiableNode(mCharData); + return mEditorBase->IsModifiableNode(mCharData); } NS_IMETHODIMP DeleteTextTransaction::DoTransaction() { - MOZ_ASSERT(mCharData); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mCharData)) { + return NS_ERROR_NOT_AVAILABLE; + } // Get the text that we're about to delete nsresult rv = mCharData->SubstringData(mOffset, mNumCharsToDelete, @@ -67,8 +70,8 @@ DeleteTextTransaction::DoTransaction() } // Only set selection to deletion point if editor gives permission - if (mEditorBase.GetShouldTxnSetSelection()) { - RefPtr selection = mEditorBase.GetSelection(); + if (mEditorBase->GetShouldTxnSetSelection()) { + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); rv = selection->Collapse(mCharData, mOffset); NS_ASSERTION(NS_SUCCEEDED(rv), @@ -84,8 +87,9 @@ DeleteTextTransaction::DoTransaction() NS_IMETHODIMP DeleteTextTransaction::UndoTransaction() { - MOZ_ASSERT(mCharData); - + if (NS_WARN_IF(!mCharData)) { + return NS_ERROR_NOT_INITIALIZED; + } return mCharData->InsertData(mOffset, mDeletedText); } diff --git a/editor/libeditor/DeleteTextTransaction.h b/editor/libeditor/DeleteTextTransaction.h index 6536777f2255..b3c292796220 100644 --- a/editor/libeditor/DeleteTextTransaction.h +++ b/editor/libeditor/DeleteTextTransaction.h @@ -57,7 +57,7 @@ public: protected: // The provider of basic editing operations. - EditorBase& mEditorBase; + RefPtr mEditorBase; // The CharacterData node to operate upon. RefPtr mCharData; diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 39f77a398110..ac877476f294 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -465,6 +465,13 @@ EditorBase::PreDestroy(bool aDestroyingFrames) mSpellcheckCheckboxState = eTriUnset; mRootElement = nullptr; + // Transaction may grab this instance. Therefore, they should be released + // here for stopping the circular reference with this instance. + if (mTxnMgr) { + mTxnMgr->Clear(); + mTxnMgr = nullptr; + } + mDidPreDestroy = true; return NS_OK; } diff --git a/editor/libeditor/InsertNodeTransaction.cpp b/editor/libeditor/InsertNodeTransaction.cpp index 6af33b74f77f..6317b8c15cbb 100644 --- a/editor/libeditor/InsertNodeTransaction.cpp +++ b/editor/libeditor/InsertNodeTransaction.cpp @@ -28,7 +28,7 @@ InsertNodeTransaction::InsertNodeTransaction(nsIContent& aNode, : mNode(&aNode) , mParent(&aParent) , mOffset(aOffset) - , mEditorBase(aEditorBase) + , mEditorBase(&aEditorBase) { } @@ -37,6 +37,7 @@ InsertNodeTransaction::~InsertNodeTransaction() } NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertNodeTransaction, EditTransactionBase, + mEditorBase, mNode, mParent) @@ -48,7 +49,9 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) NS_IMETHODIMP InsertNodeTransaction::DoTransaction() { - MOZ_ASSERT(mNode && mParent); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mNode) || NS_WARN_IF(!mParent)) { + return NS_ERROR_NOT_INITIALIZED; + } uint32_t count = mParent->GetChildCount(); if (mOffset > static_cast(count) || mOffset == -1) { @@ -59,15 +62,15 @@ InsertNodeTransaction::DoTransaction() // Note, it's ok for ref to be null. That means append. nsCOMPtr ref = mParent->GetChildAt(mOffset); - mEditorBase.MarkNodeDirty(GetAsDOMNode(mNode)); + mEditorBase->MarkNodeDirty(GetAsDOMNode(mNode)); ErrorResult rv; mParent->InsertBefore(*mNode, ref, rv); NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); // Only set selection to insertion point if editor gives permission - if (mEditorBase.GetShouldTxnSetSelection()) { - RefPtr selection = mEditorBase.GetSelection(); + if (mEditorBase->GetShouldTxnSetSelection()) { + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); // Place the selection just after the inserted element selection->Collapse(mParent, mOffset + 1); @@ -80,8 +83,9 @@ InsertNodeTransaction::DoTransaction() NS_IMETHODIMP InsertNodeTransaction::UndoTransaction() { - MOZ_ASSERT(mNode && mParent); - + if (NS_WARN_IF(!mNode) || NS_WARN_IF(!mParent)) { + return NS_ERROR_NOT_INITIALIZED; + } ErrorResult rv; mParent->RemoveChild(*mNode, rv); return rv.StealNSResult(); diff --git a/editor/libeditor/InsertNodeTransaction.h b/editor/libeditor/InsertNodeTransaction.h index 5af7b8aff511..1b9739d6c022 100644 --- a/editor/libeditor/InsertNodeTransaction.h +++ b/editor/libeditor/InsertNodeTransaction.h @@ -50,7 +50,7 @@ protected: int32_t mOffset; // The editor for this transaction. - EditorBase& mEditorBase; + RefPtr mEditorBase; }; } // namespace mozilla diff --git a/editor/libeditor/InsertTextTransaction.cpp b/editor/libeditor/InsertTextTransaction.cpp index 009b2d023a12..0434b2dd5b3e 100644 --- a/editor/libeditor/InsertTextTransaction.cpp +++ b/editor/libeditor/InsertTextTransaction.cpp @@ -26,7 +26,7 @@ InsertTextTransaction::InsertTextTransaction(Text& aTextNode, : mTextNode(&aTextNode) , mOffset(aOffset) , mStringToInsert(aStringToInsert) - , mEditorBase(aEditorBase) + , mEditorBase(&aEditorBase) , mRangeUpdater(aRangeUpdater) { } @@ -36,6 +36,7 @@ InsertTextTransaction::~InsertTextTransaction() } NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertTextTransaction, EditTransactionBase, + mEditorBase, mTextNode) NS_IMPL_ADDREF_INHERITED(InsertTextTransaction, EditTransactionBase) @@ -50,12 +51,16 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) NS_IMETHODIMP InsertTextTransaction::DoTransaction() { + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) { + return NS_ERROR_NOT_AVAILABLE; + } + nsresult rv = mTextNode->InsertData(mOffset, mStringToInsert); NS_ENSURE_SUCCESS(rv, rv); // Only set selection to insertion point if editor gives permission - if (mEditorBase.GetShouldTxnSetSelection()) { - RefPtr selection = mEditorBase.GetSelection(); + if (mEditorBase->GetShouldTxnSetSelection()) { + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); DebugOnly rv = selection->Collapse(mTextNode, mOffset + mStringToInsert.Length()); diff --git a/editor/libeditor/InsertTextTransaction.h b/editor/libeditor/InsertTextTransaction.h index f97f20e3732f..b6867ad769d3 100644 --- a/editor/libeditor/InsertTextTransaction.h +++ b/editor/libeditor/InsertTextTransaction.h @@ -76,7 +76,7 @@ private: nsString mStringToInsert; // The editor, which we'll need to get the selection. - EditorBase& mEditorBase; + RefPtr mEditorBase; RangeUpdater* mRangeUpdater; }; diff --git a/editor/libeditor/JoinNodeTransaction.cpp b/editor/libeditor/JoinNodeTransaction.cpp index c8e094479b7f..cb222363bee8 100644 --- a/editor/libeditor/JoinNodeTransaction.cpp +++ b/editor/libeditor/JoinNodeTransaction.cpp @@ -21,7 +21,7 @@ using namespace dom; JoinNodeTransaction::JoinNodeTransaction(EditorBase& aEditorBase, nsINode& aLeftNode, nsINode& aRightNode) - : mEditorBase(aEditorBase) + : mEditorBase(&aEditorBase) , mLeftNode(&aLeftNode) , mRightNode(&aRightNode) , mOffset(0) @@ -29,6 +29,7 @@ JoinNodeTransaction::JoinNodeTransaction(EditorBase& aEditorBase, } NS_IMPL_CYCLE_COLLECTION_INHERITED(JoinNodeTransaction, EditTransactionBase, + mEditorBase, mLeftNode, mRightNode, mParent) @@ -41,10 +42,11 @@ JoinNodeTransaction::CanDoIt() const { if (NS_WARN_IF(!mLeftNode) || NS_WARN_IF(!mRightNode) || + NS_WARN_IF(!mEditorBase) || !mLeftNode->GetParentNode()) { return false; } - return mEditorBase.IsModifiableNode(mLeftNode->GetParentNode()); + return mEditorBase->IsModifiableNode(mLeftNode->GetParentNode()); } // After DoTransaction() and RedoTransaction(), the left node is removed from @@ -52,6 +54,12 @@ JoinNodeTransaction::CanDoIt() const NS_IMETHODIMP JoinNodeTransaction::DoTransaction() { + if (NS_WARN_IF(!mEditorBase) || + NS_WARN_IF(!mLeftNode) || + NS_WARN_IF(!mRightNode)) { + return NS_ERROR_NOT_INITIALIZED; + } + // Get the parent node nsCOMPtr leftParent = mLeftNode->GetParentNode(); NS_ENSURE_TRUE(leftParent, NS_ERROR_NULL_POINTER); @@ -67,7 +75,7 @@ JoinNodeTransaction::DoTransaction() mParent = leftParent; mOffset = mLeftNode->Length(); - return mEditorBase.JoinNodesImpl(mRightNode, mLeftNode, mParent); + return mEditorBase->JoinNodesImpl(mRightNode, mLeftNode, mParent); } //XXX: What if instead of split, we just deleted the unneeded children of @@ -75,7 +83,11 @@ JoinNodeTransaction::DoTransaction() NS_IMETHODIMP JoinNodeTransaction::UndoTransaction() { - MOZ_ASSERT(mParent); + if (NS_WARN_IF(!mParent) || + NS_WARN_IF(!mLeftNode) || + NS_WARN_IF(!mRightNode)) { + return NS_ERROR_NOT_INITIALIZED; + } // First, massage the existing node so it is in its post-split state ErrorResult rv; diff --git a/editor/libeditor/JoinNodeTransaction.h b/editor/libeditor/JoinNodeTransaction.h index 543bed6c54e1..79b9fbc6d0e6 100644 --- a/editor/libeditor/JoinNodeTransaction.h +++ b/editor/libeditor/JoinNodeTransaction.h @@ -48,7 +48,7 @@ public: NS_DECL_EDITTRANSACTIONBASE protected: - EditorBase& mEditorBase; + RefPtr mEditorBase; // The nodes to operate upon. After the merge, mRightNode remains and // mLeftNode is removed from the content tree. diff --git a/editor/libeditor/PlaceholderTransaction.cpp b/editor/libeditor/PlaceholderTransaction.cpp index b045e097a6e6..5a76e391af28 100644 --- a/editor/libeditor/PlaceholderTransaction.cpp +++ b/editor/libeditor/PlaceholderTransaction.cpp @@ -25,7 +25,7 @@ PlaceholderTransaction::PlaceholderTransaction( , mCompositionTransaction(nullptr) , mCommitted(false) , mStartSel(Move(aSelState)) - , mEditorBase(aEditorBase) + , mEditorBase(&aEditorBase) { mName = aName; } @@ -41,6 +41,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PlaceholderTransaction, if (tmp->mStartSel) { ImplCycleCollectionUnlink(*tmp->mStartSel); } + NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorBase); NS_IMPL_CYCLE_COLLECTION_UNLINK(mEndSel); NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -49,6 +50,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PlaceholderTransaction, if (tmp->mStartSel) { ImplCycleCollectionTraverse(cb, *tmp->mStartSel, "mStartSel", 0); } + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorBase); NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEndSel); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -69,6 +71,10 @@ PlaceholderTransaction::DoTransaction() NS_IMETHODIMP PlaceholderTransaction::UndoTransaction() { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_INITIALIZED; + } + // Undo transactions. nsresult rv = EditAggregateTransaction::UndoTransaction(); NS_ENSURE_SUCCESS(rv, rv); @@ -76,7 +82,7 @@ PlaceholderTransaction::UndoTransaction() NS_ENSURE_TRUE(mStartSel, NS_ERROR_NULL_POINTER); // now restore selection - RefPtr selection = mEditorBase.GetSelection(); + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); return mStartSel->RestoreSelection(selection); } @@ -84,12 +90,16 @@ PlaceholderTransaction::UndoTransaction() NS_IMETHODIMP PlaceholderTransaction::RedoTransaction() { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_INITIALIZED; + } + // Redo transactions. nsresult rv = EditAggregateTransaction::RedoTransaction(); NS_ENSURE_SUCCESS(rv, rv); // now restore selection - RefPtr selection = mEditorBase.GetSelection(); + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); return mEndSel.RestoreSelection(selection); } @@ -254,7 +264,11 @@ PlaceholderTransaction::Commit() nsresult PlaceholderTransaction::RememberEndingSelection() { - RefPtr selection = mEditorBase.GetSelection(); + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_INITIALIZED; + } + + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); mEndSel.SaveSelection(selection); return NS_OK; diff --git a/editor/libeditor/PlaceholderTransaction.h b/editor/libeditor/PlaceholderTransaction.h index 0bb049a2c7af..7e592cc03842 100644 --- a/editor/libeditor/PlaceholderTransaction.h +++ b/editor/libeditor/PlaceholderTransaction.h @@ -82,7 +82,7 @@ protected: SelectionState mEndSel; // The editor for this transaction. - EditorBase& mEditorBase; + RefPtr mEditorBase; }; } // namespace mozilla diff --git a/editor/libeditor/SplitNodeTransaction.cpp b/editor/libeditor/SplitNodeTransaction.cpp index 113ff7a61194..8965b5399fd3 100644 --- a/editor/libeditor/SplitNodeTransaction.cpp +++ b/editor/libeditor/SplitNodeTransaction.cpp @@ -19,7 +19,7 @@ using namespace dom; SplitNodeTransaction::SplitNodeTransaction(EditorBase& aEditorBase, nsIContent& aNode, int32_t aOffset) - : mEditorBase(aEditorBase) + : mEditorBase(&aEditorBase) , mExistingRightNode(&aNode) , mOffset(aOffset) { @@ -30,6 +30,7 @@ SplitNodeTransaction::~SplitNodeTransaction() } NS_IMPL_CYCLE_COLLECTION_INHERITED(SplitNodeTransaction, EditTransactionBase, + mEditorBase, mParent, mNewLeftNode) @@ -41,6 +42,10 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) NS_IMETHODIMP SplitNodeTransaction::DoTransaction() { + if (NS_WARN_IF(!mEditorBase)) { + return NS_ERROR_NOT_INITIALIZED; + } + // Create a new node ErrorResult rv; // Don't use .downcast directly because AsContent has an assertion we want @@ -48,16 +53,16 @@ SplitNodeTransaction::DoTransaction() NS_ASSERTION(!rv.Failed() && clone, "Could not create clone"); NS_ENSURE_TRUE(!rv.Failed() && clone, rv.StealNSResult()); mNewLeftNode = dont_AddRef(clone.forget().take()->AsContent()); - mEditorBase.MarkNodeDirty(mExistingRightNode->AsDOMNode()); + mEditorBase->MarkNodeDirty(mExistingRightNode->AsDOMNode()); // Get the parent node mParent = mExistingRightNode->GetParentNode(); NS_ENSURE_TRUE(mParent, NS_ERROR_NULL_POINTER); // Insert the new node - rv = mEditorBase.SplitNodeImpl(*mExistingRightNode, mOffset, *mNewLeftNode); - if (mEditorBase.GetShouldTxnSetSelection()) { - RefPtr selection = mEditorBase.GetSelection(); + rv = mEditorBase->SplitNodeImpl(*mExistingRightNode, mOffset, *mNewLeftNode); + if (mEditorBase->GetShouldTxnSetSelection()) { + RefPtr selection = mEditorBase->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); rv = selection->Collapse(mNewLeftNode, mOffset); } @@ -67,10 +72,14 @@ SplitNodeTransaction::DoTransaction() NS_IMETHODIMP SplitNodeTransaction::UndoTransaction() { - MOZ_ASSERT(mNewLeftNode && mParent); + if (NS_WARN_IF(!mEditorBase) || + NS_WARN_IF(!mNewLeftNode) || + NS_WARN_IF(!mParent)) { + return NS_ERROR_NOT_INITIALIZED; + } // This assumes Do inserted the new node in front of the prior existing node - return mEditorBase.JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent); + return mEditorBase->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent); } /* Redo cannot simply resplit the right node, because subsequent transactions @@ -80,7 +89,10 @@ SplitNodeTransaction::UndoTransaction() NS_IMETHODIMP SplitNodeTransaction::RedoTransaction() { - MOZ_ASSERT(mNewLeftNode && mParent); + if (NS_WARN_IF(!mNewLeftNode) || + NS_WARN_IF(!mParent)) { + return NS_ERROR_NOT_INITIALIZED; + } ErrorResult rv; // First, massage the existing node so it is in its post-split state diff --git a/editor/libeditor/SplitNodeTransaction.h b/editor/libeditor/SplitNodeTransaction.h index 36119518bf1b..4c50143ecc43 100644 --- a/editor/libeditor/SplitNodeTransaction.h +++ b/editor/libeditor/SplitNodeTransaction.h @@ -49,7 +49,7 @@ public: protected: virtual ~SplitNodeTransaction(); - EditorBase& mEditorBase; + RefPtr mEditorBase; // The node to operate upon. nsCOMPtr mExistingRightNode; diff --git a/editor/libeditor/StyleSheetTransactions.cpp b/editor/libeditor/StyleSheetTransactions.cpp index b95fed99a591..f07c917e5fa1 100644 --- a/editor/libeditor/StyleSheetTransactions.cpp +++ b/editor/libeditor/StyleSheetTransactions.cpp @@ -44,9 +44,9 @@ RemoveStyleSheet(EditorBase& aEditor, StyleSheet* aSheet) * AddStyleSheetTransaction ******************************************************************************/ -AddStyleSheetTransaction::AddStyleSheetTransaction(EditorBase& aEditor, +AddStyleSheetTransaction::AddStyleSheetTransaction(EditorBase& aEditorBase, StyleSheet* aSheet) - : mEditor(aEditor) + : mEditorBase(&aEditorBase) , mSheet(aSheet) { MOZ_ASSERT(aSheet); @@ -54,6 +54,7 @@ AddStyleSheetTransaction::AddStyleSheetTransaction(EditorBase& aEditor, NS_IMPL_CYCLE_COLLECTION_INHERITED(AddStyleSheetTransaction, EditTransactionBase, + mEditorBase, mSheet) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AddStyleSheetTransaction) @@ -62,18 +63,20 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) NS_IMETHODIMP AddStyleSheetTransaction::DoTransaction() { - NS_ENSURE_TRUE(mSheet, NS_ERROR_NOT_INITIALIZED); - - AddStyleSheet(mEditor, mSheet); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) { + return NS_ERROR_NOT_INITIALIZED; + } + AddStyleSheet(*mEditorBase, mSheet); return NS_OK; } NS_IMETHODIMP AddStyleSheetTransaction::UndoTransaction() { - NS_ENSURE_TRUE(mSheet, NS_ERROR_NOT_INITIALIZED); - - RemoveStyleSheet(mEditor, mSheet); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) { + return NS_ERROR_NOT_INITIALIZED; + } + RemoveStyleSheet(*mEditorBase, mSheet); return NS_OK; } @@ -88,9 +91,10 @@ AddStyleSheetTransaction::GetTxnDescription(nsAString& aString) * RemoveStyleSheetTransaction ******************************************************************************/ -RemoveStyleSheetTransaction::RemoveStyleSheetTransaction(EditorBase& aEditor, - StyleSheet* aSheet) - : mEditor(aEditor) +RemoveStyleSheetTransaction::RemoveStyleSheetTransaction( + EditorBase& aEditorBase, + StyleSheet* aSheet) + : mEditorBase(&aEditorBase) , mSheet(aSheet) { MOZ_ASSERT(aSheet); @@ -98,6 +102,7 @@ RemoveStyleSheetTransaction::RemoveStyleSheetTransaction(EditorBase& aEditor, NS_IMPL_CYCLE_COLLECTION_INHERITED(RemoveStyleSheetTransaction, EditTransactionBase, + mEditorBase, mSheet) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RemoveStyleSheetTransaction) @@ -106,18 +111,20 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) NS_IMETHODIMP RemoveStyleSheetTransaction::DoTransaction() { - NS_ENSURE_TRUE(mSheet, NS_ERROR_NOT_INITIALIZED); - - RemoveStyleSheet(mEditor, mSheet); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) { + return NS_ERROR_NOT_INITIALIZED; + } + RemoveStyleSheet(*mEditorBase, mSheet); return NS_OK; } NS_IMETHODIMP RemoveStyleSheetTransaction::UndoTransaction() { - NS_ENSURE_TRUE(mSheet, NS_ERROR_NOT_INITIALIZED); - - AddStyleSheet(mEditor, mSheet); + if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) { + return NS_ERROR_NOT_INITIALIZED; + } + AddStyleSheet(*mEditorBase, mSheet); return NS_OK; } diff --git a/editor/libeditor/StyleSheetTransactions.h b/editor/libeditor/StyleSheetTransactions.h index 16bde683fb0d..9b0e746269e2 100644 --- a/editor/libeditor/StyleSheetTransactions.h +++ b/editor/libeditor/StyleSheetTransactions.h @@ -32,7 +32,7 @@ public: protected: // The editor that created this transaction. - EditorBase& mEditor; + RefPtr mEditorBase; // The style sheet to add. RefPtr mSheet; }; @@ -55,7 +55,7 @@ public: protected: // The editor that created this transaction. - EditorBase& mEditor; + RefPtr mEditorBase; // The style sheet to remove. RefPtr mSheet;