mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
Bug 1056166 part 6 - Clean up IMETextTxn; r=ehsan
This commit is contained in:
parent
7547add233
commit
57373fa0f6
@ -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<nsISelectionController> 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> 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<nsISelectionController> 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<nsISelectionController> 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<nsISelection> 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<IMETextTxn> 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<nsISelectionController> selCon;
|
||||
mEditor->GetSelectionController(getter_AddRefs(selCon));
|
||||
NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);
|
||||
nsRefPtr<Selection> selection = mEditor.GetSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsresult rv =
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISelectionPrivate> 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<nsISelectionController> selCon;
|
||||
mEditor.GetSelectionController(getter_AddRefs(selCon));
|
||||
NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
for (uint32_t i = 0; i < ArrayLength(kIMESelections); ++i) {
|
||||
nsCOMPtr<nsISelection> selectionOfIME;
|
||||
if (NS_FAILED(selCon->GetSelection(kIMESelections[i],
|
||||
getter_AddRefs(selectionOfIME)))) {
|
||||
continue;
|
||||
}
|
||||
DebugOnly<nsresult> 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<uint32_t>(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<uint32_t>(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<int32_t>(mOffset + insertedLength);
|
||||
MOZ_ASSERT(caretOffset >= 0 &&
|
||||
static_cast<uint32_t>(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;
|
||||
}
|
||||
|
||||
|
@ -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<nsIDOMCharacterData> mElement;
|
||||
|
||||
/** the offsets into mElement where the insertion should be placed*/
|
||||
/** The text element to operate upon */
|
||||
nsRefPtr<Text> 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<mozilla::TextRangeArray> 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
|
||||
|
@ -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<IMETextTxn> otherTxn;
|
||||
if (NS_SUCCEEDED(aTransaction->QueryInterface(IMETextTxn::GetCID(), getter_AddRefs(otherTxn))) && otherTxn)
|
||||
{
|
||||
nsRefPtr<IMETextTxn> 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)
|
||||
|
@ -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.
|
||||
|
@ -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<IMETextTxn> 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<IMETextTxn>
|
||||
nsEditor::CreateTxnForIMEText(const nsAString& aStringToInsert)
|
||||
{
|
||||
NS_ASSERTION(aTxn, "illegal value- null ptr- aTxn");
|
||||
|
||||
nsRefPtr<IMETextTxn> 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<IMETextTxn> txn = new IMETextTxn(*mIMETextNode, mIMETextOffset,
|
||||
mComposition->String().Length(),
|
||||
mComposition->GetRanges(),
|
||||
aStringToInsert, *this);
|
||||
return txn.forget();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<mozilla::dom::IMETextTxn>
|
||||
CreateTxnForIMEText(const nsAString & aStringToInsert);
|
||||
|
||||
/** create a transaction for adding a style sheet
|
||||
*/
|
||||
@ -835,7 +836,7 @@ protected:
|
||||
|
||||
nsRefPtr<nsTransactionManager> mTxnMgr;
|
||||
nsCOMPtr<mozilla::dom::Element> mRootElement; // cached root node
|
||||
nsCOMPtr<nsIDOMCharacterData> mIMETextNode; // current IME text node
|
||||
nsRefPtr<mozilla::dom::Text> mIMETextNode; // current IME text node
|
||||
nsCOMPtr<mozilla::dom::EventTarget> mEventTarget; // The form field as an event receiver
|
||||
nsCOMPtr<nsIDOMEventListener> mEventListener;
|
||||
nsWeakPtr mSelConWeak; // weak reference to the nsISelectionController
|
||||
|
Loading…
Reference in New Issue
Block a user