mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1056166 part 2 - Clean up InsertTextTxn; r=ehsan
This commit is contained in:
parent
7752358f63
commit
bfb6a46780
@ -3,20 +3,28 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <stdio.h> // for printf
|
||||
|
||||
#include "InsertTextTxn.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsDebug.h" // for NS_ASSERTION, etc
|
||||
#include "nsError.h" // for NS_OK, etc
|
||||
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
|
||||
#include "nsIEditor.h" // for nsIEditor
|
||||
#include "nsISelection.h" // for nsISelection
|
||||
#include "nsISupportsUtils.h" // for NS_ADDREF_THIS, NS_RELEASE
|
||||
#include "nsITransaction.h" // for nsITransaction
|
||||
|
||||
InsertTextTxn::InsertTextTxn()
|
||||
#include "mozilla/dom/Selection.h" // Selection local var
|
||||
#include "mozilla/dom/Text.h" // mTextNode
|
||||
#include "nsAString.h" // nsAString parameter
|
||||
#include "nsDebug.h" // for NS_ASSERTION, etc
|
||||
#include "nsEditor.h" // mEditor
|
||||
#include "nsError.h" // for NS_OK, etc
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
class nsITransaction;
|
||||
|
||||
InsertTextTxn::InsertTextTxn(Text& aTextNode, uint32_t aOffset,
|
||||
const nsAString& aStringToInsert,
|
||||
nsEditor& aEditor)
|
||||
: EditTxn()
|
||||
, mTextNode(&aTextNode)
|
||||
, mOffset(aOffset)
|
||||
, mStringToInsert(aStringToInsert)
|
||||
, mEditor(aEditor)
|
||||
{
|
||||
}
|
||||
|
||||
@ -25,129 +33,83 @@ InsertTextTxn::~InsertTextTxn()
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertTextTxn, EditTxn,
|
||||
mElement)
|
||||
mTextNode)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(InsertTextTxn, EditTxn)
|
||||
NS_IMPL_RELEASE_INHERITED(InsertTextTxn, EditTxn)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertTextTxn)
|
||||
if (aIID.Equals(InsertTextTxn::GetCID())) {
|
||||
*aInstancePtr = (void*)(InsertTextTxn*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
} else
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsITransaction, InsertTextTxn)
|
||||
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
|
||||
|
||||
NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
|
||||
uint32_t aOffset,
|
||||
const nsAString &aStringToInsert,
|
||||
nsIEditor *aEditor)
|
||||
|
||||
NS_IMETHODIMP
|
||||
InsertTextTxn::DoTransaction()
|
||||
{
|
||||
#if 0
|
||||
nsAutoString text;
|
||||
aElement->GetData(text);
|
||||
printf("InsertTextTxn: Offset to insert at = %d. Text of the node to insert into:\n", aOffset);
|
||||
wprintf(text.get());
|
||||
printf("\n");
|
||||
#endif
|
||||
nsresult res = mTextNode->InsertData(mOffset, mStringToInsert);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
NS_ASSERTION(aElement && aEditor, "bad args");
|
||||
NS_ENSURE_TRUE(aElement && aEditor, NS_ERROR_NULL_POINTER);
|
||||
// Only set selection to insertion point if editor gives permission
|
||||
if (mEditor.GetShouldTxnSetSelection()) {
|
||||
nsRefPtr<Selection> selection = mEditor.GetSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
res = selection->Collapse(mTextNode,
|
||||
mOffset + mStringToInsert.Length());
|
||||
NS_ASSERTION(NS_SUCCEEDED(res),
|
||||
"Selection could not be collapsed after insert");
|
||||
} else {
|
||||
// Do nothing - DOM Range gravity will adjust selection
|
||||
}
|
||||
|
||||
mElement = do_QueryInterface(aElement);
|
||||
mOffset = aOffset;
|
||||
mStringToInsert = aStringToInsert;
|
||||
mEditor = aEditor;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP InsertTextTxn::DoTransaction(void)
|
||||
NS_IMETHODIMP
|
||||
InsertTextTxn::UndoTransaction()
|
||||
{
|
||||
NS_ASSERTION(mElement && mEditor, "bad state");
|
||||
if (!mElement || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsresult result = mElement->InsertData(mOffset, mStringToInsert);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// only set selection to insertion point if editor gives permission
|
||||
bool bAdjustSelection;
|
||||
mEditor->ShouldTxnSetSelection(&bAdjustSelection);
|
||||
if (bAdjustSelection)
|
||||
{
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
result = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
result = selection->Collapse(mElement, mOffset+mStringToInsert.Length());
|
||||
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing - dom range gravity will adjust selection
|
||||
}
|
||||
|
||||
return result;
|
||||
return mTextNode->DeleteData(mOffset, mStringToInsert.Length());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP InsertTextTxn::UndoTransaction(void)
|
||||
NS_IMETHODIMP
|
||||
InsertTextTxn::Merge(nsITransaction* aTransaction, bool* aDidMerge)
|
||||
{
|
||||
NS_ASSERTION(mElement && mEditor, "bad state");
|
||||
if (!mElement || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
uint32_t length = mStringToInsert.Length();
|
||||
return mElement->DeleteData(mOffset, length);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP InsertTextTxn::Merge(nsITransaction *aTransaction, bool *aDidMerge)
|
||||
{
|
||||
// set out param default value
|
||||
if (aDidMerge)
|
||||
*aDidMerge = false;
|
||||
nsresult result = NS_OK;
|
||||
if (aDidMerge && aTransaction)
|
||||
{
|
||||
// if aTransaction is a InsertTextTxn, and if the selection hasn't changed,
|
||||
// then absorb it
|
||||
InsertTextTxn *otherInsTxn = nullptr;
|
||||
aTransaction->QueryInterface(InsertTextTxn::GetCID(), (void **)&otherInsTxn);
|
||||
if (otherInsTxn)
|
||||
{
|
||||
if (IsSequentialInsert(otherInsTxn))
|
||||
{
|
||||
nsAutoString otherData;
|
||||
otherInsTxn->GetData(otherData);
|
||||
mStringToInsert += otherData;
|
||||
*aDidMerge = true;
|
||||
}
|
||||
NS_RELEASE(otherInsTxn);
|
||||
}
|
||||
if (!aTransaction || !aDidMerge) {
|
||||
return NS_OK;
|
||||
}
|
||||
return result;
|
||||
// Set out param default value
|
||||
*aDidMerge = false;
|
||||
|
||||
// If aTransaction is a InsertTextTxn, and if the selection hasn't changed,
|
||||
// then absorb it
|
||||
nsRefPtr<InsertTextTxn> otherInsTxn = do_QueryObject(aTransaction);
|
||||
if (otherInsTxn && IsSequentialInsert(*otherInsTxn)) {
|
||||
nsAutoString otherData;
|
||||
otherInsTxn->GetData(otherData);
|
||||
mStringToInsert += otherData;
|
||||
*aDidMerge = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP InsertTextTxn::GetTxnDescription(nsAString& aString)
|
||||
NS_IMETHODIMP
|
||||
InsertTextTxn::GetTxnDescription(nsAString& aString)
|
||||
{
|
||||
aString.AssignLiteral("InsertTextTxn: ");
|
||||
aString += mStringToInsert;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* ============ protected methods ================== */
|
||||
/* ============ private methods ================== */
|
||||
|
||||
NS_IMETHODIMP InsertTextTxn::GetData(nsString& aResult)
|
||||
void
|
||||
InsertTextTxn::GetData(nsString& aResult)
|
||||
{
|
||||
aResult = mStringToInsert;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool InsertTextTxn::IsSequentialInsert(InsertTextTxn *aOtherTxn)
|
||||
bool
|
||||
InsertTextTxn::IsSequentialInsert(InsertTextTxn& aOtherTxn)
|
||||
{
|
||||
NS_ASSERTION(aOtherTxn, "null param");
|
||||
if (aOtherTxn && aOtherTxn->mElement == mElement)
|
||||
{
|
||||
// here, we need to compare offsets.
|
||||
int32_t length = mStringToInsert.Length();
|
||||
if (aOtherTxn->mOffset == (mOffset + length))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return aOtherTxn.mTextNode == mTextNode &&
|
||||
aOtherTxn.mOffset == mOffset + mStringToInsert.Length();
|
||||
}
|
||||
|
@ -6,73 +6,74 @@
|
||||
#ifndef InsertTextTxn_h__
|
||||
#define InsertTextTxn_h__
|
||||
|
||||
#include "EditTxn.h" // for EditTxn, NS_DECL_EDITTXN
|
||||
#include "nsCOMPtr.h" // for nsCOMPtr
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsID.h" // for nsIID
|
||||
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
|
||||
#include "nsISupportsImpl.h" // for NS_DECL_ISUPPORTS_INHERITED
|
||||
#include "nsString.h" // for nsString
|
||||
#include "nscore.h" // for NS_IMETHOD, nsAString
|
||||
#include "EditTxn.h" // base class
|
||||
#include "nsAutoPtr.h" // nsRefPtr members
|
||||
#include "nsCycleCollectionParticipant.h" // various macros
|
||||
#include "nsID.h" // NS_DECLARE_STATIC_IID_ACCESSOR
|
||||
#include "nsISupportsImpl.h" // NS_DECL_ISUPPORTS_INHERITED
|
||||
#include "nsString.h" // nsString members
|
||||
#include "nscore.h" // NS_IMETHOD, nsAString
|
||||
|
||||
class nsIEditor;
|
||||
class nsEditor;
|
||||
class nsITransaction;
|
||||
|
||||
#define NS_INSERTTEXTTXN_IID \
|
||||
{ 0x8c9ad77f, 0x22a7, 0x4d01, \
|
||||
{ 0xb1, 0x59, 0x8a, 0x0f, 0xdb, 0x1d, 0x08, 0xe9 } }
|
||||
|
||||
#define INSERT_TEXT_TXN_CID \
|
||||
{/* 93276f00-ab2c-11d2-8f4b-006008159b0c*/ \
|
||||
0x93276f00, 0xab2c, 0x11d2, \
|
||||
{0x8f, 0xb4, 0x0, 0x60, 0x8, 0x15, 0x9b, 0xc} }
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Text;
|
||||
|
||||
/**
|
||||
* A transaction that inserts text into a content node.
|
||||
* A transaction that inserts text into a content node.
|
||||
*/
|
||||
class InsertTextTxn : public EditTxn
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_INSERTTEXTTXN_IID)
|
||||
|
||||
static const nsIID& GetCID() { static const nsIID iid = INSERT_TEXT_TXN_CID; return iid; }
|
||||
|
||||
/** initialize the transaction
|
||||
* @param aElement the text content node
|
||||
/** @param aElement the text content node
|
||||
* @param aOffset the location in aElement to do the insertion
|
||||
* @param aString the new text to insert
|
||||
* @param aPresShell used to get and set the selection
|
||||
*/
|
||||
NS_IMETHOD Init(nsIDOMCharacterData *aElement,
|
||||
uint32_t aOffset,
|
||||
const nsAString& aString,
|
||||
nsIEditor *aEditor);
|
||||
|
||||
InsertTextTxn();
|
||||
InsertTextTxn(Text& aTextNode, uint32_t aOffset, const nsAString& aString,
|
||||
nsEditor& aEditor);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(InsertTextTxn, EditTxn)
|
||||
|
||||
NS_DECL_EDITTXN
|
||||
|
||||
NS_IMETHOD Merge(nsITransaction *aTransaction, bool *aDidMerge);
|
||||
NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) MOZ_OVERRIDE;
|
||||
|
||||
/** return the string data associated with this transaction */
|
||||
NS_IMETHOD GetData(nsString& aResult);
|
||||
/** Return the string data associated with this transaction */
|
||||
void GetData(nsString& aResult);
|
||||
|
||||
protected:
|
||||
private:
|
||||
virtual ~InsertTextTxn();
|
||||
|
||||
/** return true if aOtherTxn immediately follows this txn */
|
||||
virtual bool IsSequentialInsert(InsertTextTxn *aOtherTxn);
|
||||
|
||||
/** the text element to operate upon */
|
||||
nsCOMPtr<nsIDOMCharacterData> mElement;
|
||||
|
||||
/** the offset into mElement where the insertion is to take place */
|
||||
/** Return true if aOtherTxn immediately follows this txn */
|
||||
bool IsSequentialInsert(InsertTextTxn& aOtherTxn);
|
||||
|
||||
/** The Text node to operate upon */
|
||||
nsRefPtr<Text> mTextNode;
|
||||
|
||||
/** The offset into mTextNode where the insertion is to take place */
|
||||
uint32_t mOffset;
|
||||
|
||||
/** the text to insert into mElement at mOffset */
|
||||
/** The text to insert into mTextNode at mOffset */
|
||||
nsString mStringToInsert;
|
||||
|
||||
/** the editor, which we'll need to get the selection */
|
||||
nsIEditor *mEditor;
|
||||
/** The editor, which we'll need to get the selection */
|
||||
nsEditor& mEditor;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(InsertTextTxn, NS_INSERTTEXTTXN_IID)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2335,17 +2335,15 @@ nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
node = newNode;
|
||||
offset = 0;
|
||||
}
|
||||
nsCOMPtr<nsIDOMCharacterData> charDataNode = do_QueryInterface(node);
|
||||
NS_ENSURE_STATE(charDataNode);
|
||||
res = InsertTextIntoTextNodeImpl(aStringToInsert, charDataNode, offset);
|
||||
res = InsertTextIntoTextNodeImpl(aStringToInsert, *node->GetAsText(),
|
||||
offset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
offset += aStringToInsert.Length();
|
||||
} else {
|
||||
if (node->IsNodeOfType(nsINode::eTEXT)) {
|
||||
// we are inserting text into an existing text node.
|
||||
nsCOMPtr<nsIDOMCharacterData> charDataNode = do_QueryInterface(node);
|
||||
NS_ENSURE_STATE(charDataNode);
|
||||
res = InsertTextIntoTextNodeImpl(aStringToInsert, charDataNode, offset);
|
||||
res = InsertTextIntoTextNodeImpl(aStringToInsert, *node->GetAsText(),
|
||||
offset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
offset += aStringToInsert.Length();
|
||||
} else {
|
||||
@ -2368,29 +2366,19 @@ nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
}
|
||||
|
||||
|
||||
nsresult nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
Text* aTextNode,
|
||||
int32_t aOffset,
|
||||
bool aSuppressIME)
|
||||
{
|
||||
return InsertTextIntoTextNodeImpl(aStringToInsert,
|
||||
static_cast<nsIDOMCharacterData*>(GetAsDOMNode(aTextNode)),
|
||||
aOffset, aSuppressIME);
|
||||
}
|
||||
|
||||
nsresult nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
nsIDOMCharacterData *aTextNode,
|
||||
int32_t aOffset,
|
||||
bool aSuppressIME)
|
||||
nsresult
|
||||
nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
Text& aTextNode,
|
||||
int32_t aOffset, bool aSuppressIME)
|
||||
{
|
||||
nsRefPtr<EditTxn> txn;
|
||||
nsresult result = NS_OK;
|
||||
bool isIMETransaction = false;
|
||||
// aSuppressIME is used when editor must insert text, yet this text is not
|
||||
// part of current ime operation. example: adjusting whitespace around an ime insertion.
|
||||
// part of the current IME operation. Example: adjusting whitespace around an
|
||||
// IME insertion.
|
||||
if (mComposition && !aSuppressIME) {
|
||||
if (!mIMETextNode) {
|
||||
mIMETextNode = aTextNode;
|
||||
mIMETextNode = do_QueryInterface(&aTextNode);
|
||||
mIMETextOffset = aOffset;
|
||||
}
|
||||
// Modify mPhonetic with raw text input clauses.
|
||||
@ -2410,58 +2398,58 @@ nsresult nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
}
|
||||
|
||||
nsRefPtr<IMETextTxn> imeTxn;
|
||||
result = CreateTxnForIMEText(aStringToInsert, getter_AddRefs(imeTxn));
|
||||
nsresult res = CreateTxnForIMEText(aStringToInsert,
|
||||
getter_AddRefs(imeTxn));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
txn = imeTxn;
|
||||
isIMETransaction = true;
|
||||
} else {
|
||||
txn = CreateTxnForInsertText(aStringToInsert, aTextNode, aOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsRefPtr<InsertTextTxn> insertTxn;
|
||||
result = CreateTxnForInsertText(aStringToInsert, aTextNode, aOffset,
|
||||
getter_AddRefs(insertTxn));
|
||||
txn = insertTxn;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// let listeners know what's up
|
||||
int32_t i;
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->WillInsertText(aTextNode, aOffset, aStringToInsert);
|
||||
|
||||
// XXX we may not need these view batches anymore. This is handled at a higher level now I believe
|
||||
// Let listeners know what's up
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillInsertText(
|
||||
static_cast<nsIDOMCharacterData*>(aTextNode.AsDOMNode()), aOffset,
|
||||
aStringToInsert);
|
||||
}
|
||||
|
||||
// XXX We may not need these view batches anymore. This is handled at a
|
||||
// higher level now I believe.
|
||||
BeginUpdateViewBatch();
|
||||
result = DoTransaction(txn);
|
||||
nsresult res = DoTransaction(txn);
|
||||
EndUpdateViewBatch();
|
||||
|
||||
mRangeUpdater.SelAdjInsertText(aTextNode, aOffset, aStringToInsert);
|
||||
|
||||
// let listeners know what happened
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->DidInsertText(aTextNode, aOffset, aStringToInsert, result);
|
||||
|
||||
// Added some cruft here for bug 43366. Layout was crashing because we left an
|
||||
// empty text node lying around in the document. So I delete empty text nodes
|
||||
// caused by IME. I have to mark the IME transaction as "fixed", which means
|
||||
// that furure ime txns won't merge with it. This is because we don't want
|
||||
// future ime txns trying to put their text into a node that is no longer in
|
||||
// the document. This does not break undo/redo, because all these txns are
|
||||
// wrapped in a parent PlaceHolder txn, and placeholder txns are already
|
||||
// savvy to having multiple ime txns inside them.
|
||||
|
||||
// delete empty ime text node if there is one
|
||||
if (isIMETransaction && mIMETextNode)
|
||||
{
|
||||
// let listeners know what happened
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidInsertText(
|
||||
static_cast<nsIDOMCharacterData*>(aTextNode.AsDOMNode()),
|
||||
aOffset, aStringToInsert, res);
|
||||
}
|
||||
|
||||
// Added some cruft here for bug 43366. Layout was crashing because we left
|
||||
// an empty text node lying around in the document. So I delete empty text
|
||||
// nodes caused by IME. I have to mark the IME transaction as "fixed", which
|
||||
// means that furure IME txns won't merge with it. This is because we don't
|
||||
// want future IME txns trying to put their text into a node that is no
|
||||
// longer in the document. This does not break undo/redo, because all these
|
||||
// txns are wrapped in a parent PlaceHolder txn, and placeholder txns are
|
||||
// already savvy to having multiple ime txns inside them.
|
||||
|
||||
// Delete empty IME text node if there is one
|
||||
if (isIMETransaction && mIMETextNode) {
|
||||
uint32_t len;
|
||||
mIMETextNode->GetLength(&len);
|
||||
if (!len)
|
||||
{
|
||||
if (!len) {
|
||||
DeleteNode(mIMETextNode);
|
||||
mIMETextNode = nullptr;
|
||||
static_cast<IMETextTxn*>(txn.get())->MarkFixed(); // mark the ime txn "fixed"
|
||||
static_cast<IMETextTxn*>(txn.get())->MarkFixed();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -2549,22 +2537,13 @@ nsEditor::NotifyDocumentListeners(TDocumentListenerNotification aNotificationTyp
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsEditor::CreateTxnForInsertText(const nsAString & aStringToInsert,
|
||||
nsIDOMCharacterData *aTextNode,
|
||||
int32_t aOffset,
|
||||
InsertTextTxn ** aTxn)
|
||||
already_AddRefed<InsertTextTxn>
|
||||
nsEditor::CreateTxnForInsertText(const nsAString& aStringToInsert,
|
||||
Text& aTextNode, int32_t aOffset)
|
||||
{
|
||||
NS_ENSURE_TRUE(aTextNode && aTxn, NS_ERROR_NULL_POINTER);
|
||||
nsresult rv;
|
||||
|
||||
nsRefPtr<InsertTextTxn> txn = new InsertTextTxn();
|
||||
rv = txn->Init(aTextNode, aOffset, aStringToInsert, this);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
txn.forget(aTxn);
|
||||
}
|
||||
|
||||
return rv;
|
||||
nsRefPtr<InsertTextTxn> txn = new InsertTextTxn(aTextNode, aOffset,
|
||||
aStringToInsert, *this);
|
||||
return txn.forget();
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,6 @@ class ChangeAttributeTxn;
|
||||
class DeleteNodeTxn;
|
||||
class EditAggregateTxn;
|
||||
class IMETextTxn;
|
||||
class InsertTextTxn;
|
||||
class JoinElementTxn;
|
||||
class RemoveStyleSheetTxn;
|
||||
class SplitElementTxn;
|
||||
@ -74,6 +73,7 @@ class DataTransfer;
|
||||
class DeleteTextTxn;
|
||||
class Element;
|
||||
class EventTarget;
|
||||
class InsertTextTxn;
|
||||
class InsertNodeTxn;
|
||||
class Selection;
|
||||
class Text;
|
||||
@ -207,11 +207,7 @@ public:
|
||||
int32_t *aInOutOffset,
|
||||
nsIDOMDocument *aDoc);
|
||||
nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
mozilla::dom::Text* aTextNode,
|
||||
int32_t aOffset,
|
||||
bool aSuppressIME = false);
|
||||
nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
nsIDOMCharacterData *aTextNode,
|
||||
mozilla::dom::Text& aTextNode,
|
||||
int32_t aOffset,
|
||||
bool aSuppressIME = false);
|
||||
NS_IMETHOD DeleteSelectionImpl(EDirection aAction,
|
||||
@ -306,13 +302,12 @@ protected:
|
||||
int32_t* aLength);
|
||||
|
||||
|
||||
/** create a transaction for inserting aStringToInsert into aTextNode
|
||||
* if aTextNode is null, the string is inserted at the current selection.
|
||||
/** Create a transaction for inserting aStringToInsert into aTextNode. Never
|
||||
* returns null.
|
||||
*/
|
||||
NS_IMETHOD CreateTxnForInsertText(const nsAString & aStringToInsert,
|
||||
nsIDOMCharacterData *aTextNode,
|
||||
int32_t aOffset,
|
||||
InsertTextTxn ** aTxn);
|
||||
already_AddRefed<mozilla::dom::InsertTextTxn>
|
||||
CreateTxnForInsertText(const nsAString& aStringToInsert,
|
||||
mozilla::dom::Text& aTextNode, int32_t aOffset);
|
||||
|
||||
NS_IMETHOD CreateTxnForIMEText(const nsAString & aStringToInsert,
|
||||
IMETextTxn ** aTxn);
|
||||
|
@ -446,45 +446,35 @@ nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode* aLeftNode,
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjInsertText(nsIContent* aTextNode, int32_t aOffset,
|
||||
const nsAString &aString)
|
||||
void
|
||||
nsRangeUpdater::SelAdjInsertText(Text& aTextNode, int32_t aOffset,
|
||||
const nsAString& aString)
|
||||
{
|
||||
if (mLock) {
|
||||
// lock set by Will/DidReplaceParent, etc...
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
uint32_t len = aString.Length();
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
if (item->startNode == aTextNode && item->startOffset > aOffset) {
|
||||
if (item->startNode == &aTextNode && item->startOffset > aOffset) {
|
||||
item->startOffset += len;
|
||||
}
|
||||
if (item->endNode == aTextNode && item->endOffset > aOffset) {
|
||||
if (item->endNode == &aTextNode && item->endOffset > aOffset) {
|
||||
item->endOffset += len;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData* aTextNode,
|
||||
int32_t aOffset, const nsAString &aString)
|
||||
{
|
||||
nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
|
||||
return SelAdjInsertText(textNode, aOffset, aString);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjDeleteText(nsIContent* aTextNode, int32_t aOffset,
|
||||
int32_t aLength)
|
||||
|
@ -20,6 +20,7 @@ class nsRange;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Selection;
|
||||
class Text;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,9 +109,8 @@ class nsRangeUpdater
|
||||
nsIDOMNode *aParent,
|
||||
int32_t aOffset,
|
||||
int32_t aOldLeftNodeLength);
|
||||
nsresult SelAdjInsertText(nsIContent* aTextNode, int32_t aOffset,
|
||||
void SelAdjInsertText(mozilla::dom::Text& aTextNode, int32_t aOffset,
|
||||
const nsAString &aString);
|
||||
nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString);
|
||||
nsresult SelAdjDeleteText(nsIContent* aTextNode, int32_t aOffset,
|
||||
int32_t aLength);
|
||||
nsresult SelAdjDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength);
|
||||
|
@ -1506,7 +1506,7 @@ nsWSRunObject::ConvertToNBSP(WSPoint aPoint, AreaRestriction aAR)
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
|
||||
nsAutoString nbspStr(nbsp);
|
||||
nsresult res = mHTMLEditor->InsertTextIntoTextNodeImpl(nbspStr,
|
||||
aPoint.mTextNode, aPoint.mOffset, true);
|
||||
*aPoint.mTextNode, aPoint.mOffset, true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// Next, find range of ws it will replace
|
||||
@ -1821,7 +1821,7 @@ nsWSRunObject::CheckTrailingNBSPOfRun(WSFragment *aRun)
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
|
||||
nsAutoString spaceStr(char16_t(32));
|
||||
res = mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr,
|
||||
thePoint.mTextNode,
|
||||
*thePoint.mTextNode,
|
||||
thePoint.mOffset, true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
@ -1851,7 +1851,7 @@ nsWSRunObject::CheckTrailingNBSPOfRun(WSFragment *aRun)
|
||||
// Finally, insert that nbsp before the ASCII ws run
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
|
||||
nsAutoString nbspStr(nbsp);
|
||||
res = mHTMLEditor->InsertTextIntoTextNodeImpl(nbspStr, startNode,
|
||||
res = mHTMLEditor->InsertTextIntoTextNodeImpl(nbspStr, *startNode,
|
||||
startOffset, true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
@ -1887,7 +1887,7 @@ nsWSRunObject::CheckTrailingNBSP(WSFragment* aRun, nsINode* aNode,
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
|
||||
nsAutoString spaceStr(char16_t(32));
|
||||
nsresult res = mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr,
|
||||
thePoint.mTextNode, thePoint.mOffset, true);
|
||||
*thePoint.mTextNode, thePoint.mOffset, true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// Finally, delete that nbsp
|
||||
@ -1928,7 +1928,7 @@ nsWSRunObject::CheckLeadingNBSP(WSFragment* aRun, nsINode* aNode,
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
|
||||
nsAutoString spaceStr(char16_t(32));
|
||||
nsresult res = mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr,
|
||||
thePoint.mTextNode, thePoint.mOffset, true);
|
||||
*thePoint.mTextNode, thePoint.mOffset, true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// Finally, delete that nbsp
|
||||
|
Loading…
Reference in New Issue
Block a user