From 57373fa0f61012abf2e867bcf3a5900a6f55de83 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Fri, 29 Aug 2014 14:43:24 +0300 Subject: [PATCH] Bug 1056166 part 6 - Clean up IMETextTxn; r=ehsan --- editor/libeditor/IMETextTxn.cpp | 232 ++++++++++++---------------- editor/libeditor/IMETextTxn.h | 92 ++++++----- editor/libeditor/PlaceholderTxn.cpp | 5 +- editor/libeditor/PlaceholderTxn.h | 7 +- editor/libeditor/nsEditor.cpp | 34 ++-- editor/libeditor/nsEditor.h | 9 +- 6 files changed, 162 insertions(+), 217 deletions(-) diff --git a/editor/libeditor/IMETextTxn.cpp b/editor/libeditor/IMETextTxn.cpp index 932ba5f4e803..973573aec2db 100644 --- a/editor/libeditor/IMETextTxn.cpp +++ b/editor/libeditor/IMETextTxn.cpp @@ -4,149 +4,111 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "IMETextTxn.h" -#include "mozilla/DebugOnly.h" // for DebugOnly -#include "mozilla/mozalloc.h" // for operator new -#include "mozilla/TextEvents.h" // for TextRangeStyle -#include "nsAString.h" // for nsAString_internal::Length, etc -#include "nsAutoPtr.h" // for nsRefPtr + +#include "mozilla/dom/Selection.h" // local var +#include "mozilla/dom/Text.h" // mTextNode +#include "nsAString.h" // params #include "nsDebug.h" // for NS_ASSERTION, etc +#include "nsEditor.h" // mEditor #include "nsError.h" // for NS_SUCCEEDED, NS_FAILED, etc -#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData -#include "nsIDOMRange.h" // for nsRange::SetEnd, etc -#include "nsIContent.h" // for nsIContent -#include "nsIEditor.h" // for nsIEditor -#include "nsIPresShell.h" // for SelectionType -#include "nsISelection.h" // for nsISelection -#include "nsISelectionController.h" // for nsISelectionController, etc -#include "nsISelectionPrivate.h" // for nsISelectionPrivate -#include "nsISupportsImpl.h" // for nsRange::AddRef, etc -#include "nsISupportsUtils.h" // for NS_ADDREF_THIS, NS_RELEASE -#include "nsITransaction.h" // for nsITransaction -#include "nsRange.h" // for nsRange -#include "nsString.h" // for nsString +#include "nsIPresShell.h" // nsISelectionController constants +#include "nsRange.h" // local var using namespace mozilla; +using namespace mozilla::dom; -// #define DEBUG_IMETXN - -IMETextTxn::IMETextTxn() +IMETextTxn::IMETextTxn(Text& aTextNode, uint32_t aOffset, + uint32_t aReplaceLength, + TextRangeArray* aTextRangeArray, + const nsAString& aStringToInsert, + nsEditor& aEditor) : EditTxn() + , mTextNode(&aTextNode) + , mOffset(aOffset) + , mReplaceLength(aReplaceLength) + , mRanges(aTextRangeArray) + , mStringToInsert(aStringToInsert) + , mEditor(aEditor) + , mFixed(false) +{ +} + +IMETextTxn::~IMETextTxn() { } NS_IMPL_CYCLE_COLLECTION_INHERITED(IMETextTxn, EditTxn, - mElement) + mTextNode) // mRangeList can't lead to cycles NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IMETextTxn) - if (aIID.Equals(IMETextTxn::GetCID())) { - *aInstancePtr = (void*)(IMETextTxn*)this; - NS_ADDREF_THIS(); - return NS_OK; - } else + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsITransaction, IMETextTxn) NS_INTERFACE_MAP_END_INHERITING(EditTxn) -NS_IMETHODIMP IMETextTxn::Init(nsIDOMCharacterData *aElement, - uint32_t aOffset, - uint32_t aReplaceLength, - TextRangeArray *aTextRangeArray, - const nsAString &aStringToInsert, - nsIEditor *aEditor) +NS_IMPL_ADDREF_INHERITED(IMETextTxn, EditTxn) +NS_IMPL_RELEASE_INHERITED(IMETextTxn, EditTxn) + +NS_IMETHODIMP +IMETextTxn::DoTransaction() { - NS_ENSURE_ARG_POINTER(aElement); - mElement = aElement; - mOffset = aOffset; - mReplaceLength = aReplaceLength; - mStringToInsert = aStringToInsert; - mEditor = aEditor; - mRanges = aTextRangeArray; - mFixed = false; + // Fail before making any changes if there's no selection controller + nsCOMPtr selCon; + mEditor.GetSelectionController(getter_AddRefs(selCon)); + NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); + + // Advance caret: This requires the presentation shell to get the selection. + nsresult res; + if (mReplaceLength == 0) { + res = mTextNode->InsertData(mOffset, mStringToInsert); + } else { + res = mTextNode->ReplaceData(mOffset, mReplaceLength, mStringToInsert); + } + NS_ENSURE_SUCCESS(res, res); + + res = SetSelectionForRanges(); + NS_ENSURE_SUCCESS(res, res); + return NS_OK; } -NS_IMETHODIMP IMETextTxn::DoTransaction(void) +NS_IMETHODIMP +IMETextTxn::UndoTransaction() { + // Get the selection first so we'll fail before making any changes if we + // can't get it + nsRefPtr selection = mEditor.GetSelection(); + NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED); -#ifdef DEBUG_IMETXN - printf("Do IME Text element = %p replace = %d len = %d\n", mElement.get(), mReplaceLength, mStringToInsert.Length()); -#endif + nsresult res = mTextNode->DeleteData(mOffset, mStringToInsert.Length()); + NS_ENSURE_SUCCESS(res, res); - nsCOMPtr selCon; - mEditor->GetSelectionController(getter_AddRefs(selCon)); - NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); + // set the selection to the insertion point where the string was removed + res = selection->Collapse(mTextNode, mOffset); + NS_ASSERTION(NS_SUCCEEDED(res), + "Selection could not be collapsed after undo of IME insert."); + NS_ENSURE_SUCCESS(res, res); - // advance caret: This requires the presentation shell to get the selection. - nsresult result; - if (mReplaceLength == 0) { - result = mElement->InsertData(mOffset, mStringToInsert); - } else { - result = mElement->ReplaceData(mOffset, mReplaceLength, mStringToInsert); - } - if (NS_SUCCEEDED(result)) { - result = SetSelectionForRanges(); - } - - return result; + return NS_OK; } -NS_IMETHODIMP IMETextTxn::UndoTransaction(void) +NS_IMETHODIMP +IMETextTxn::Merge(nsITransaction* aTransaction, bool* aDidMerge) { -#ifdef DEBUG_IMETXN - printf("Undo IME Text element = %p\n", mElement.get()); -#endif + NS_ENSURE_ARG_POINTER(aTransaction && aDidMerge); - nsCOMPtr selCon; - mEditor->GetSelectionController(getter_AddRefs(selCon)); - NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); - - nsresult result = mElement->DeleteData(mOffset, mStringToInsert.Length()); - if (NS_SUCCEEDED(result)) - { // set the selection to the insertion point where the string was removed - nsCOMPtr selection; - result = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection)); - if (NS_SUCCEEDED(result) && selection) { - result = selection->Collapse(mElement, mOffset); - NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of IME insert."); - } - } - return result; -} - -NS_IMETHODIMP IMETextTxn::Merge(nsITransaction *aTransaction, bool *aDidMerge) -{ - NS_ASSERTION(aDidMerge, "illegal vaule- null ptr- aDidMerge"); - NS_ASSERTION(aTransaction, "illegal vaule- null ptr- aTransaction"); - NS_ENSURE_TRUE(aDidMerge && aTransaction, NS_ERROR_NULL_POINTER); - -#ifdef DEBUG_IMETXN - printf("Merge IME Text element = %p\n", mElement.get()); -#endif - - // - // check to make sure we aren't fixed, if we are then nothing get's absorbed - // + // Check to make sure we aren't fixed, if we are then nothing gets absorbed if (mFixed) { *aDidMerge = false; return NS_OK; } - // - // if aTransaction is another IMETextTxn then absorb it - // - IMETextTxn* otherTxn = nullptr; - nsresult result = aTransaction->QueryInterface(IMETextTxn::GetCID(),(void**)&otherTxn); - if (otherTxn && NS_SUCCEEDED(result)) - { - // - // we absorb the next IME transaction by adopting its insert string as our own - // + // If aTransaction is another IMETextTxn then absorb it + nsRefPtr otherTxn = do_QueryObject(aTransaction); + if (otherTxn) { + // We absorb the next IME transaction by adopting its insert string mStringToInsert = otherTxn->mStringToInsert; mRanges = otherTxn->mRanges; *aDidMerge = true; -#ifdef DEBUG_IMETXN - printf("IMETextTxn assimilated IMETextTxn:%p\n", aTransaction); -#endif - NS_RELEASE(otherTxn); return NS_OK; } @@ -154,20 +116,21 @@ NS_IMETHODIMP IMETextTxn::Merge(nsITransaction *aTransaction, bool *aDidMerge) return NS_OK; } -NS_IMETHODIMP IMETextTxn::MarkFixed(void) +void +IMETextTxn::MarkFixed() { mFixed = true; - return NS_OK; } -NS_IMETHODIMP IMETextTxn::GetTxnDescription(nsAString& aString) +NS_IMETHODIMP +IMETextTxn::GetTxnDescription(nsAString& aString) { aString.AssignLiteral("IMETextTxn: "); aString += mStringToInsert; return NS_OK; } -/* ============ protected methods ================== */ +/* ============ private methods ================== */ static SelectionType ToSelectionType(uint32_t aTextRangeType) { @@ -189,18 +152,10 @@ ToSelectionType(uint32_t aTextRangeType) nsresult IMETextTxn::SetSelectionForRanges() { - nsCOMPtr selCon; - mEditor->GetSelectionController(getter_AddRefs(selCon)); - NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); + nsRefPtr selection = mEditor.GetSelection(); + NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED); - nsCOMPtr selection; - nsresult rv = - selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, - getter_AddRefs(selection)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr selPriv(do_QueryInterface(selection)); - rv = selPriv->StartBatchChanges(); + nsresult rv = selection->StartBatchChanges(); NS_ENSURE_SUCCESS(rv, rv); // First, remove all selections of IME composition. @@ -210,13 +165,18 @@ IMETextTxn::SetSelectionForRanges() nsISelectionController::SELECTION_IME_CONVERTEDTEXT, nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT }; + + nsCOMPtr selCon; + mEditor.GetSelectionController(getter_AddRefs(selCon)); + NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); + for (uint32_t i = 0; i < ArrayLength(kIMESelections); ++i) { nsCOMPtr selectionOfIME; if (NS_FAILED(selCon->GetSelection(kIMESelections[i], getter_AddRefs(selectionOfIME)))) { continue; } - DebugOnly rv = selectionOfIME->RemoveAllRanges(); + rv = selectionOfIME->RemoveAllRanges(); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to remove all ranges of IME selection"); } @@ -224,15 +184,14 @@ IMETextTxn::SetSelectionForRanges() // Set caret position and selection of IME composition with TextRangeArray. bool setCaret = false; uint32_t countOfRanges = mRanges ? mRanges->Length() : 0; + #ifdef DEBUG - // When this sets selection (caret) offset to out of the content of - // the editor, let's crash the process only on debug build. That makes such - // bugs detectable with automated tests. - uint32_t maxOffset = UINT32_MAX; - mElement->GetLength(&maxOffset); + // Bounds-checking on debug builds + uint32_t maxOffset = mTextNode->Length(); #endif + // The mStringToInsert may be truncated if maxlength attribute value doesn't - // allow to input all text of this composition. So, we can get actual length + // allow input of all text of this composition. So, we can get actual length // of the inserted string from it. uint32_t insertedLength = mStringToInsert.Length(); for (uint32_t i = 0; i < countOfRanges; ++i) { @@ -247,13 +206,13 @@ IMETextTxn::SetSelectionForRanges() mOffset + std::min(textRange.mStartOffset, insertedLength)); MOZ_ASSERT(caretOffset >= 0 && static_cast(caretOffset) <= maxOffset); - rv = selection->Collapse(mElement, caretOffset); + rv = selection->Collapse(mTextNode, caretOffset); setCaret = setCaret || NS_SUCCEEDED(rv); NS_ASSERTION(setCaret, "Failed to collapse normal selection"); continue; } - // If the clause length is 0, it's should be a bug. + // If the clause length is 0, it should be a bug. if (!textRange.Length()) { NS_WARNING("Any clauses must not be empty"); continue; @@ -268,8 +227,8 @@ IMETextTxn::SetSelectionForRanges() mOffset + std::min(textRange.mEndOffset, insertedLength)); MOZ_ASSERT(endOffset >= startOffset && static_cast(endOffset) <= maxOffset); - rv = nsRange::CreateRange(mElement, startOffset, - mElement, endOffset, + rv = nsRange::CreateRange(mTextNode, startOffset, + mTextNode, endOffset, getter_AddRefs(clauseRange)); if (NS_FAILED(rv)) { NS_WARNING("Failed to create a DOM range for a clause of composition"); @@ -312,14 +271,13 @@ IMETextTxn::SetSelectionForRanges() int32_t caretOffset = static_cast(mOffset + insertedLength); MOZ_ASSERT(caretOffset >= 0 && static_cast(caretOffset) <= maxOffset); - rv = selection->Collapse(mElement, caretOffset); + rv = selection->Collapse(mTextNode, caretOffset); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set caret at the end of composition string"); } - rv = selPriv->EndBatchChanges(); + rv = selection->EndBatchChanges(); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to end batch changes"); return rv; } - diff --git a/editor/libeditor/IMETextTxn.h b/editor/libeditor/IMETextTxn.h index 960fe3e9a198..55366b6c0399 100644 --- a/editor/libeditor/IMETextTxn.h +++ b/editor/libeditor/IMETextTxn.h @@ -6,86 +6,82 @@ #ifndef IMETextTxn_h__ #define IMETextTxn_h__ -#include "EditTxn.h" -#include "nsCOMPtr.h" -#include "nsCycleCollectionParticipant.h" -#include "nsID.h" -#include "nsIDOMCharacterData.h" -#include "nsString.h" -#include "nscore.h" -#include "mozilla/TextRange.h" +#include "EditTxn.h" // base class +#include "nsAutoPtr.h" // mTextNode, mRanges +#include "nsCycleCollectionParticipant.h" // various macros +#include "nsString.h" // mStringToInsert -class nsITransaction; +class nsEditor; -// {D4D25721-2813-11d3-9EA3-0060089FE59B} -#define IME_TEXT_TXN_CID \ -{0xd4d25721, 0x2813, 0x11d3, \ -{0x9e, 0xa3, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b }} +#define NS_IMETEXTTXN_IID \ + { 0xb391355d, 0x346c, 0x43d1, \ + { 0x85, 0xed, 0x9e, 0x65, 0xbe, 0xe7, 0x7e, 0x48 } } +namespace mozilla { -class nsIEditor; +class TextRangeArray; +namespace dom { + +class Text; /** - * A transaction that inserts text into a content node. + * A transaction that inserts text into a content node. */ class IMETextTxn : public EditTxn { public: - static const nsIID& GetCID() { static const nsIID iid = IME_TEXT_TXN_CID; return iid; } + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMETEXTTXN_IID) - /** initialize the transaction - * @param aElement the text content node - * @param aOffset the location in aElement to do the insertion + /** @param aTextNode the text content node + * @param aOffset the location in aTextNode to do the insertion * @param aReplaceLength the length of text to replace (0 == no replacement) * @param aTextRangeArray clauses and/or caret information. This may be null. - * @param aString the new text to insert - * @param aSelCon used to get and set the selection + * @param aString the new text to insert + * @param aEditor used to get and set the selection */ - NS_IMETHOD Init(nsIDOMCharacterData *aElement, - uint32_t aOffset, - uint32_t aReplaceLength, - mozilla::TextRangeArray* aTextRangeArray, - const nsAString& aString, - nsIEditor* aEditor); - - IMETextTxn(); + IMETextTxn(Text& aTextNode, uint32_t aOffset, uint32_t aReplaceLength, + TextRangeArray* aTextRangeArray, const nsAString& aString, + nsEditor& aEditor); NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IMETextTxn, EditTxn) + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_EDITTXN - NS_IMETHOD Merge(nsITransaction *aTransaction, bool *aDidMerge); + NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) MOZ_OVERRIDE; - NS_IMETHOD MarkFixed(void); + void MarkFixed(); -// nsISupports declarations - - // override QueryInterface to handle IMETextTxn request - NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); - -protected: +private: + ~IMETextTxn(); nsresult SetSelectionForRanges(); - /** the text element to operate upon */ - nsCOMPtr mElement; - - /** the offsets into mElement where the insertion should be placed*/ + /** The text element to operate upon */ + nsRefPtr mTextNode; + + /** The offsets into mTextNode where the insertion should be placed */ uint32_t mOffset; uint32_t mReplaceLength; - /** the text to insert into mElement at mOffset */ - nsString mStringToInsert; - - /** the range list **/ + /** The range list **/ nsRefPtr mRanges; - /** the editor, which is used to get the selection controller */ - nsIEditor *mEditor; + /** The text to insert into mTextNode at mOffset */ + nsString mStringToInsert; - bool mFixed; + /** The editor, which is used to get the selection controller */ + nsEditor& mEditor; + + bool mFixed; }; +NS_DEFINE_STATIC_IID_ACCESSOR(IMETextTxn, NS_IMETEXTTXN_IID) + +} +} + #endif diff --git a/editor/libeditor/PlaceholderTxn.cpp b/editor/libeditor/PlaceholderTxn.cpp index fea91ed0abbe..fba98b10bad0 100644 --- a/editor/libeditor/PlaceholderTxn.cpp +++ b/editor/libeditor/PlaceholderTxn.cpp @@ -126,9 +126,8 @@ NS_IMETHODIMP PlaceholderTxn::Merge(nsITransaction *aTransaction, bool *aDidMerg // we are absorbing all txn's if mAbsorb is lit. if (mAbsorb) { - nsRefPtr otherTxn; - if (NS_SUCCEEDED(aTransaction->QueryInterface(IMETextTxn::GetCID(), getter_AddRefs(otherTxn))) && otherTxn) - { + nsRefPtr otherTxn = do_QueryObject(aTransaction); + if (otherTxn) { // special handling for IMETextTxn's: they need to merge with any previous // IMETextTxn in this placeholder, if possible. if (!mIMETextTxn) diff --git a/editor/libeditor/PlaceholderTxn.h b/editor/libeditor/PlaceholderTxn.h index fc3381e69bec..bf61e1962356 100644 --- a/editor/libeditor/PlaceholderTxn.h +++ b/editor/libeditor/PlaceholderTxn.h @@ -16,7 +16,12 @@ #include "nsAutoPtr.h" class nsHTMLEditor; + +namespace mozilla { +namespace dom { class IMETextTxn; +} +} /** * An aggregate transaction that knows how to absorb all subsequent @@ -65,7 +70,7 @@ protected: /** the presentation shell, which we'll need to get the selection */ bool mAbsorb; // do we auto absorb any and all transaction? nsWeakPtr mForwarding; - IMETextTxn *mIMETextTxn; // first IME txn in this placeholder - used for IME merging + mozilla::dom::IMETextTxn *mIMETextTxn; // first IME txn in this placeholder - used for IME merging // non-owning for now - can't nsCOMPtr it due to broken transaction interfaces bool mCommitted; // do we stop auto absorbing any matching placeholder txns? // these next two members store the state of the selection in a safe way. diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index 3696e85d53e1..25926466d564 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -2378,7 +2378,7 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, // IME insertion. if (mComposition && !aSuppressIME) { if (!mIMETextNode) { - mIMETextNode = do_QueryInterface(&aTextNode); + mIMETextNode = &aTextNode; mIMETextOffset = aOffset; } // Modify mPhonetic with raw text input clauses. @@ -2397,11 +2397,7 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, textRange.mStartOffset, textRange.Length()); } - nsRefPtr imeTxn; - nsresult res = CreateTxnForIMEText(aStringToInsert, - getter_AddRefs(imeTxn)); - NS_ENSURE_SUCCESS(res, res); - txn = imeTxn; + txn = CreateTxnForIMEText(aStringToInsert); isIMETransaction = true; } else { txn = CreateTxnForInsertText(aStringToInsert, aTextNode, aOffset); @@ -2440,8 +2436,7 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, // Delete empty IME text node if there is one if (isIMETransaction && mIMETextNode) { - uint32_t len; - mIMETextNode->GetLength(&len); + uint32_t len = mIMETextNode->Length(); if (!len) { DeleteNode(mIMETextNode); mIMETextNode = nullptr; @@ -4290,25 +4285,16 @@ nsEditor::CreateTxnForDeleteNode(nsINode* aNode, DeleteNodeTxn** aTxn) return NS_OK; } -NS_IMETHODIMP -nsEditor::CreateTxnForIMEText(const nsAString& aStringToInsert, - IMETextTxn ** aTxn) +already_AddRefed +nsEditor::CreateTxnForIMEText(const nsAString& aStringToInsert) { - NS_ASSERTION(aTxn, "illegal value- null ptr- aTxn"); - - nsRefPtr txn = new IMETextTxn(); - // During handling IME composition, mComposition must have been initialized. // TODO: We can simplify IMETextTxn::Init() with TextComposition class. - nsresult rv = txn->Init(mIMETextNode, mIMETextOffset, - mComposition->String().Length(), - mComposition->GetRanges(), aStringToInsert, this); - if (NS_SUCCEEDED(rv)) - { - txn.forget(aTxn); - } - - return rv; + nsRefPtr txn = new IMETextTxn(*mIMETextNode, mIMETextOffset, + mComposition->String().Length(), + mComposition->GetRanges(), + aStringToInsert, *this); + return txn.forget(); } diff --git a/editor/libeditor/nsEditor.h b/editor/libeditor/nsEditor.h index c5cfcab996e8..e3b0549f93bd 100644 --- a/editor/libeditor/nsEditor.h +++ b/editor/libeditor/nsEditor.h @@ -30,7 +30,6 @@ class AddStyleSheetTxn; class DeleteNodeTxn; class EditAggregateTxn; -class IMETextTxn; class JoinElementTxn; class RemoveStyleSheetTxn; class SplitElementTxn; @@ -73,6 +72,7 @@ class DataTransfer; class DeleteTextTxn; class Element; class EventTarget; +class IMETextTxn; class InsertTextTxn; class InsertNodeTxn; class Selection; @@ -310,8 +310,9 @@ protected: CreateTxnForInsertText(const nsAString& aStringToInsert, mozilla::dom::Text& aTextNode, int32_t aOffset); - NS_IMETHOD CreateTxnForIMEText(const nsAString & aStringToInsert, - IMETextTxn ** aTxn); + // Never returns null. + already_AddRefed + CreateTxnForIMEText(const nsAString & aStringToInsert); /** create a transaction for adding a style sheet */ @@ -835,7 +836,7 @@ protected: nsRefPtr mTxnMgr; nsCOMPtr mRootElement; // cached root node - nsCOMPtr mIMETextNode; // current IME text node + nsRefPtr mIMETextNode; // current IME text node nsCOMPtr mEventTarget; // The form field as an event receiver nsCOMPtr mEventListener; nsWeakPtr mSelConWeak; // weak reference to the nsISelectionController