зеркало из https://github.com/mozilla/pjs.git
minor fixes and lots of comments
This commit is contained in:
Родитель
667207f280
Коммит
c947533db7
|
@ -37,8 +37,15 @@ class ChangeAttributeTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** Initialize the transaction.
|
||||
* @param aEditor the object providing core editing operations
|
||||
* @param aNode the node whose attribute will be changed
|
||||
* @param aAttribute the name of the attribute to change
|
||||
* @param aValue the new value for aAttribute, if aRemoveAttribute is false
|
||||
* @param aRemoveAttribute if PR_TRUE, remove aAttribute from aNode
|
||||
*/
|
||||
virtual nsresult Init(nsIEditor *aEditor,
|
||||
nsIDOMElement *aElement,
|
||||
nsIDOMElement *aNode,
|
||||
const nsString& aAttribute,
|
||||
const nsString& aValue,
|
||||
PRBool aRemoveAttribute);
|
||||
|
|
|
@ -39,6 +39,13 @@ public:
|
|||
|
||||
enum { eAppend=-1 };
|
||||
|
||||
/** Initialize the transaction.
|
||||
* @param aDoc the document containing aParent
|
||||
* @param aTag the tag (P, HR, TABLE, etc.) for the new element
|
||||
* @param aParent the node into which the new element will be inserted
|
||||
* @param aOffsetInParent the location in aParent to insert the new element
|
||||
* if eAppend, the new element is appended as the last child
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMDocument *aDoc,
|
||||
const nsString& aTag,
|
||||
nsIDOMNode *aParent,
|
||||
|
|
|
@ -33,17 +33,14 @@ DeleteElementTxn::DeleteElementTxn()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult DeleteElementTxn::Init(nsIDOMNode *aElement,
|
||||
nsIDOMNode *aParent)
|
||||
nsresult DeleteElementTxn::Init(nsIDOMNode *aElement)
|
||||
{
|
||||
if ((nsnull!=aElement) && (nsnull!=aParent))
|
||||
{
|
||||
if (nsnull!=aElement) {
|
||||
mElement = aElement;
|
||||
mParent = aParent;
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
else
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,8 +50,17 @@ DeleteElementTxn::~DeleteElementTxn()
|
|||
|
||||
nsresult DeleteElementTxn::Do(void)
|
||||
{
|
||||
if (!mParent || !mElement)
|
||||
if (!mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult result = mElement->GetParentNode(getter_AddRefs(mParent));
|
||||
if (NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
if (!mParent) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// begin debug output
|
||||
nsCOMPtr<nsIDOMElement> element(mElement);
|
||||
|
@ -76,17 +82,10 @@ nsresult DeleteElementTxn::Do(void)
|
|||
delete [] p;
|
||||
}
|
||||
// end debug output
|
||||
// begin sanity check 1: parent-child relationship
|
||||
nsresult testResult;
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
testResult = mElement->GetParentNode(getter_AddRefs(parentNode));
|
||||
NS_ASSERTION((NS_SUCCEEDED(testResult)), "bad mElement, couldn't get parent");
|
||||
NS_ASSERTION((parentNode==mParent), "bad mParent, mParent!=mElement->GetParent() ");
|
||||
// end sanity check 1.
|
||||
#endif
|
||||
|
||||
// remember which child mElement was (by remembering which child was next)
|
||||
nsresult result = mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode
|
||||
result = mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode
|
||||
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode));
|
||||
|
|
|
@ -35,8 +35,10 @@ class DeleteElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
virtual nsresult Init(nsIDOMNode *aElement,
|
||||
nsIDOMNode *aParent);
|
||||
/** initialize the transaction.
|
||||
* @param aElement the node to delete
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMNode *aElement);
|
||||
|
||||
private:
|
||||
DeleteElementTxn();
|
||||
|
|
|
@ -221,7 +221,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, aStartParent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -286,7 +286,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteContent(nsIDOMNode *aParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, aParent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -307,7 +307,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteContent(nsIDOMNode *aParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, aParent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -387,7 +387,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsIDOMNode *aCommonParen
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, parent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -449,7 +449,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsIDOMNode *aCommonParen
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, parent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -40,6 +40,9 @@ class DeleteRangeTxn : public EditAggregateTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction.
|
||||
* @param aRange the range to delete
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMRange *aRange);
|
||||
|
||||
private:
|
||||
|
|
|
@ -29,13 +29,17 @@
|
|||
{0x86, 0xd8, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74} }
|
||||
|
||||
/**
|
||||
* A transaction that changes an attribute of a content node.
|
||||
* This transaction covers add, remove, and change attribute.
|
||||
* A transaction that removes text from a content node.
|
||||
*/
|
||||
class DeleteTextTxn : public EditTxn
|
||||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction.
|
||||
* @param aElement the content node to remove text from
|
||||
* @param aOffset the location in aElement to begin the deletion
|
||||
* @param aNumCharsToDelete the number of characters to delete. Not the number of bytes!
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aNumCharsToDelete);
|
||||
|
@ -49,7 +53,6 @@ public:
|
|||
|
||||
virtual nsresult Undo(void);
|
||||
|
||||
|
||||
virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction);
|
||||
|
||||
virtual nsresult Write(nsIOutputStream *aOutputStream);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
EditAggregateTxn::EditAggregateTxn()
|
||||
: EditTxn()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mChildren = new nsVoidArray();
|
||||
}
|
||||
|
||||
|
@ -106,7 +107,18 @@ nsresult EditAggregateTxn::GetIsTransient(PRBool *aIsTransient)
|
|||
|
||||
nsresult EditAggregateTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction)
|
||||
{
|
||||
return NS_OK;
|
||||
nsresult result=NS_OK; // it's legal (but not very useful) to have an empty child list
|
||||
if (nsnull!=aDidMerge)
|
||||
*aDidMerge=PR_FALSE;
|
||||
if (nsnull!=mChildren)
|
||||
{
|
||||
PRInt32 i;
|
||||
PRInt32 count = mChildren->Count();
|
||||
EditTxn *txn = (EditTxn*)(mChildren->ElementAt(count-1));
|
||||
result = txn->Merge(aDidMerge, aTransaction);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::Write(nsIOutputStream *aOutputStream)
|
||||
|
@ -138,6 +150,56 @@ nsresult EditAggregateTxn::AppendChild(EditTxn *aTxn)
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::SetName(nsIAtom *aName)
|
||||
{
|
||||
mName = aName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::GetName(nsIAtom **aName)
|
||||
{
|
||||
if (aName)
|
||||
{
|
||||
if (mName)
|
||||
{
|
||||
*aName = mName;
|
||||
NS_ADDREF(*aName);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::GetCount(PRInt32 *aCount)
|
||||
{
|
||||
if (!aCount) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aCount=0;
|
||||
if (mChildren) {
|
||||
*aCount = mChildren->Count();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::GetTxnAt(PRInt32 aIndex, EditTxn **aTxn)
|
||||
{
|
||||
if (!aTxn) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (!mChildren) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
const PRInt32 txnCount = mChildren->Count();
|
||||
if (0>aIndex || txnCount<=aIndex) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
*aTxn = (EditTxn *)(mChildren->ElementAt(aIndex));
|
||||
if (!*aTxn)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
NS_ADDREF(*aTxn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#define EditAggregateTxn_h__
|
||||
|
||||
#include "EditTxn.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define EDIT_AGGREGATE_TXN_IID \
|
||||
{/* 345921a0-ac49-11d2-86d8-000064657374 */ \
|
||||
|
@ -56,12 +58,30 @@ public:
|
|||
|
||||
virtual nsresult GetRedoString(nsString **aString);
|
||||
|
||||
/** append a transaction to this aggregate */
|
||||
virtual nsresult AppendChild(EditTxn *aTxn);
|
||||
|
||||
/** get the number of nested txns.
|
||||
* This is the number of top-level txns, it does not do recursive decent.
|
||||
*/
|
||||
virtual nsresult GetCount(PRInt32 *aCount);
|
||||
|
||||
/** get the txn at index aIndex.
|
||||
* returns NS_ERROR_UNEXPECTED if there is no txn at aIndex.
|
||||
*/
|
||||
virtual nsresult GetTxnAt(PRInt32 aIndex, EditTxn **aTxn);
|
||||
|
||||
/** set the name assigned to this aggregate txn */
|
||||
virtual nsresult SetName(nsIAtom *aName);
|
||||
|
||||
/** get the name assigned to this aggregate txn */
|
||||
virtual nsresult GetName(nsIAtom **aName);
|
||||
|
||||
protected:
|
||||
|
||||
//XXX: if this was an nsISupportsArray, it would handle refcounting for us
|
||||
nsVoidArray *mChildren;
|
||||
nsVoidArray * mChildren;
|
||||
nsCOMPtr<nsIAtom> mName;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -31,18 +31,26 @@
|
|||
class nsIPresShell;
|
||||
|
||||
/**
|
||||
* A transaction that changes an attribute of a content node.
|
||||
* This transaction covers add, remove, and change attribute.
|
||||
* TODO: do we need to add a direction field, and do the insert and
|
||||
* merging based on the direction?
|
||||
*/
|
||||
* A transaction that inserts text into a content node.
|
||||
*/
|
||||
class InsertTextTxn : public EditTxn
|
||||
{
|
||||
public:
|
||||
|
||||
/** used to name aggregate transactions that consist only of a single InsertTextTxn,
|
||||
* or a DeleteSelection followed by an InsertTextTxn.
|
||||
*/
|
||||
static nsIAtom *gInsertTextTxnName;
|
||||
|
||||
/** initialize the transaction
|
||||
* @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
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
const nsString& aStringToInsert,
|
||||
const nsString& aString,
|
||||
nsIPresShell* aPresShell);
|
||||
|
||||
private:
|
||||
|
@ -74,6 +82,9 @@ public:
|
|||
/** return the string data associated with this transaction */
|
||||
virtual nsresult GetData(nsString& aResult);
|
||||
|
||||
/** must be called before any InsertTextTxn is instantiated */
|
||||
static nsresult ClassInit();
|
||||
|
||||
protected:
|
||||
|
||||
/** return PR_TRUE if aOtherTxn immediately follows this txn */
|
||||
|
|
|
@ -38,6 +38,11 @@ class JoinElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction
|
||||
* @param aEditor the provider of core editing operations
|
||||
* @param aLeftNode the first of two nodes to join
|
||||
* @param aRightNode the second of two nodes to join
|
||||
*/
|
||||
virtual nsresult Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode);
|
||||
|
@ -73,8 +78,8 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> mRightNode;
|
||||
|
||||
/** the offset into mNode where the children of mElement are split (for undo).<BR>
|
||||
* mOffset is the index of the last child in the left node.
|
||||
* -1 means the left node gets no children.
|
||||
* mOffset is the index of the first child in the right node.
|
||||
* -1 means the left node had no children.
|
||||
*/
|
||||
PRUint32 mOffset;
|
||||
|
||||
|
|
|
@ -37,6 +37,13 @@ class SplitElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction.
|
||||
* @param aEditor the provider of core editing operations
|
||||
* @param aNode the node to split
|
||||
* @param aOffset the location within aNode to do the split.
|
||||
* aOffset may refer to children of aNode, or content of aNode.
|
||||
* The left node will have child|content 0..aOffset-1.
|
||||
*/
|
||||
virtual nsresult Init (nsIEditor *aEditor,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset);
|
||||
|
@ -66,7 +73,7 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> mExistingRightNode;
|
||||
|
||||
/** the offset into mElement where the children of mElement are split.<BR>
|
||||
* mOffset is the index of the last child in the left node.
|
||||
* mOffset is the index of the first child in the right node.
|
||||
* -1 means the new node gets no children.
|
||||
*/
|
||||
PRInt32 mOffset;
|
||||
|
|
|
@ -69,9 +69,14 @@ TransactionFactory::GetNewTransaction(REFNSIID aTxnType, EditTxn **aResult)
|
|||
*aResult = new JoinElementTxn();
|
||||
else if (aTxnType.Equals(kEditAggregateTxnIID))
|
||||
*aResult = new EditAggregateTxn();
|
||||
else
|
||||
result = NS_ERROR_NO_INTERFACE;
|
||||
|
||||
if (nsnull==*aResult)
|
||||
result = NS_ERROR_INVALID_ARG;
|
||||
if (NS_SUCCEEDED(result) && nsnull==*aResult)
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_SUCCEEDED(result))
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ protected:
|
|||
virtual ~TransactionFactory();
|
||||
|
||||
public:
|
||||
/** return a transaction object of aTxnType, refcounted
|
||||
* @return NS_ERROR_NO_INTERFACE if aTxnType is unknown,
|
||||
* NS_ERROR_OUT_OF_MEMORY if the allocations fails.
|
||||
*/
|
||||
static nsresult GetNewTransaction(REFNSIID aTxnType, EditTxn **aResult);
|
||||
|
||||
};
|
||||
|
|
|
@ -249,6 +249,7 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell)
|
|||
NS_ADDREF(mPresShell);
|
||||
mPresShell->GetViewManager(&mViewManager);
|
||||
mUpdateCount=0;
|
||||
InsertTextTxn::ClassInit();
|
||||
|
||||
/* Show the caret */
|
||||
nsCOMPtr<nsICaret> caret;
|
||||
|
@ -365,8 +366,7 @@ nsEditor::CreateTxnForSetAttribute(nsIDOMElement *aElement,
|
|||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kChangeAttributeTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(this, aElement, aAttribute, aValue, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -414,7 +414,7 @@ nsEditor::CreateTxnForRemoveAttribute(nsIDOMElement *aElement,
|
|||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kChangeAttributeTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsAutoString value;
|
||||
result = (*aTxn)->Init(this, aElement, aAttribute, value, PR_TRUE);
|
||||
|
@ -655,12 +655,9 @@ nsresult nsEditor::CreateTxnForCreateElement(const nsString& aTag,
|
|||
if (nsnull != aParent)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kCreateElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull != *aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(mDoc, aTag, aParent, aPosition);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -681,31 +678,26 @@ nsresult nsEditor::InsertNode(nsIDOMNode * aNode,
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult nsEditor::DeleteNode(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement)
|
||||
nsresult nsEditor::DeleteNode(nsIDOMNode * aElement)
|
||||
{
|
||||
DeleteElementTxn *txn;
|
||||
nsresult result = CreateTxnForDeleteElement(aParent, aElement, &txn);
|
||||
nsresult result = CreateTxnForDeleteElement(aElement, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = Do(txn);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement,
|
||||
nsresult nsEditor::CreateTxnForDeleteElement(nsIDOMNode * aElement,
|
||||
DeleteElementTxn ** aTxn)
|
||||
{
|
||||
nsresult result = NS_ERROR_NULL_POINTER;
|
||||
if ((nsnull != aParent) && (nsnull != aElement))
|
||||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
result = (*aTxn)->Init(aElement, aParent);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(aElement);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -715,23 +707,33 @@ nsresult
|
|||
nsEditor::InsertText(const nsString& aStringToInsert)
|
||||
{
|
||||
nsresult result;
|
||||
EditAggregateTxn *aggTxn;
|
||||
result = TransactionFactory::GetNewTransaction(kEditAggregateTxnIID, (EditTxn **)&aggTxn);
|
||||
if ((NS_FAILED(result)) || (nsnull==aggTxn)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aggTxn->SetName(InsertTextTxn::gInsertTextTxnName);
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
result = mPresShell->GetSelection(getter_AddRefs(selection));
|
||||
//BeginTransaction();
|
||||
if (NS_SUCCEEDED(result) && selection)
|
||||
{
|
||||
PRBool collapsed;
|
||||
result = selection->IsCollapsed(&collapsed);
|
||||
if (NS_SUCCEEDED(result) && !collapsed)
|
||||
DeleteSelection(eLTR);
|
||||
if (NS_SUCCEEDED(result) && !collapsed) {
|
||||
EditAggregateTxn *delSelTxn;
|
||||
result = CreateTxnForDeleteSelection(nsIEditor::eLTR, &delSelTxn);
|
||||
if (NS_SUCCEEDED(result) && delSelTxn) {
|
||||
aggTxn->AppendChild(delSelTxn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InsertTextTxn *txn;
|
||||
result = CreateTxnForInsertText(aStringToInsert, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = Do(txn);
|
||||
if ((NS_SUCCEEDED(result)) && txn) {
|
||||
aggTxn->AppendChild(txn);
|
||||
result = Do(aggTxn);
|
||||
}
|
||||
//EndTransaction();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -809,12 +811,9 @@ nsresult nsEditor::CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
|||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kDeleteTextTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(aElement, aOffset, aLength);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -924,6 +923,10 @@ nsEditor::DeleteSelection(nsIEditor::Direction aDir)
|
|||
nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
||||
EditAggregateTxn ** aTxn)
|
||||
{
|
||||
if (!aTxn)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*aTxn = nsnull;
|
||||
|
||||
nsresult result;
|
||||
// allocate the out-param transaction
|
||||
result = TransactionFactory::GetNewTransaction(kEditAggregateTxnIID, (EditTxn **)aTxn);
|
||||
|
@ -1049,15 +1052,10 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
|||
}
|
||||
else
|
||||
{ // priorNode is not text, so tell it's parent to delete it
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
result = priorNode->GetParentNode(getter_AddRefs(parent));
|
||||
if ((NS_SUCCEEDED(result)) && parent)
|
||||
{
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(parent, priorNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(priorNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1090,15 +1088,10 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
|||
}
|
||||
else
|
||||
{ // nextNode is not text, so tell it's parent to delete it
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
result = nextNode->GetParentNode(getter_AddRefs(parent));
|
||||
if ((NS_SUCCEEDED(result)) && parent)
|
||||
{
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(parent, nextNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(nextNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1234,12 +1227,9 @@ nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
|
|||
if (nsnull != aNode)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kSplitElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(this, aNode, aOffset);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1252,12 +1242,9 @@ nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
|
|||
if ((nsnull != aLeftNode) && (nsnull != aRightNode))
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kJoinElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(this, aLeftNode, aRightNode);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -128,8 +128,7 @@ public:
|
|||
PRInt32 aPosition);
|
||||
virtual nsresult InsertText(const nsString& aStringToInsert);
|
||||
|
||||
virtual nsresult DeleteNode(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aChild);
|
||||
virtual nsresult DeleteNode(nsIDOMNode * aChild);
|
||||
|
||||
virtual nsresult DeleteSelection(nsIEditor::Direction aDir);
|
||||
|
||||
|
@ -206,8 +205,7 @@ protected:
|
|||
PRInt32 aPosition,
|
||||
CreateElementTxn ** aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement,
|
||||
virtual nsresult CreateTxnForDeleteElement(nsIDOMNode * aElement,
|
||||
DeleteElementTxn ** aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
|
|
|
@ -37,8 +37,15 @@ class ChangeAttributeTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** Initialize the transaction.
|
||||
* @param aEditor the object providing core editing operations
|
||||
* @param aNode the node whose attribute will be changed
|
||||
* @param aAttribute the name of the attribute to change
|
||||
* @param aValue the new value for aAttribute, if aRemoveAttribute is false
|
||||
* @param aRemoveAttribute if PR_TRUE, remove aAttribute from aNode
|
||||
*/
|
||||
virtual nsresult Init(nsIEditor *aEditor,
|
||||
nsIDOMElement *aElement,
|
||||
nsIDOMElement *aNode,
|
||||
const nsString& aAttribute,
|
||||
const nsString& aValue,
|
||||
PRBool aRemoveAttribute);
|
||||
|
|
|
@ -39,6 +39,13 @@ public:
|
|||
|
||||
enum { eAppend=-1 };
|
||||
|
||||
/** Initialize the transaction.
|
||||
* @param aDoc the document containing aParent
|
||||
* @param aTag the tag (P, HR, TABLE, etc.) for the new element
|
||||
* @param aParent the node into which the new element will be inserted
|
||||
* @param aOffsetInParent the location in aParent to insert the new element
|
||||
* if eAppend, the new element is appended as the last child
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMDocument *aDoc,
|
||||
const nsString& aTag,
|
||||
nsIDOMNode *aParent,
|
||||
|
|
|
@ -33,17 +33,14 @@ DeleteElementTxn::DeleteElementTxn()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult DeleteElementTxn::Init(nsIDOMNode *aElement,
|
||||
nsIDOMNode *aParent)
|
||||
nsresult DeleteElementTxn::Init(nsIDOMNode *aElement)
|
||||
{
|
||||
if ((nsnull!=aElement) && (nsnull!=aParent))
|
||||
{
|
||||
if (nsnull!=aElement) {
|
||||
mElement = aElement;
|
||||
mParent = aParent;
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
else
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,8 +50,17 @@ DeleteElementTxn::~DeleteElementTxn()
|
|||
|
||||
nsresult DeleteElementTxn::Do(void)
|
||||
{
|
||||
if (!mParent || !mElement)
|
||||
if (!mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult result = mElement->GetParentNode(getter_AddRefs(mParent));
|
||||
if (NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
if (!mParent) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// begin debug output
|
||||
nsCOMPtr<nsIDOMElement> element(mElement);
|
||||
|
@ -76,17 +82,10 @@ nsresult DeleteElementTxn::Do(void)
|
|||
delete [] p;
|
||||
}
|
||||
// end debug output
|
||||
// begin sanity check 1: parent-child relationship
|
||||
nsresult testResult;
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
testResult = mElement->GetParentNode(getter_AddRefs(parentNode));
|
||||
NS_ASSERTION((NS_SUCCEEDED(testResult)), "bad mElement, couldn't get parent");
|
||||
NS_ASSERTION((parentNode==mParent), "bad mParent, mParent!=mElement->GetParent() ");
|
||||
// end sanity check 1.
|
||||
#endif
|
||||
|
||||
// remember which child mElement was (by remembering which child was next)
|
||||
nsresult result = mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode
|
||||
result = mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode
|
||||
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode));
|
||||
|
|
|
@ -35,8 +35,10 @@ class DeleteElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
virtual nsresult Init(nsIDOMNode *aElement,
|
||||
nsIDOMNode *aParent);
|
||||
/** initialize the transaction.
|
||||
* @param aElement the node to delete
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMNode *aElement);
|
||||
|
||||
private:
|
||||
DeleteElementTxn();
|
||||
|
|
|
@ -221,7 +221,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, aStartParent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -286,7 +286,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteContent(nsIDOMNode *aParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, aParent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -307,7 +307,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteContent(nsIDOMNode *aParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, aParent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -387,7 +387,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsIDOMNode *aCommonParen
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, parent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
@ -449,7 +449,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsIDOMNode *aCommonParen
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)&txn);
|
||||
if (nsnull!=txn)
|
||||
{
|
||||
txn->Init(child, parent);
|
||||
txn->Init(child);
|
||||
AppendChild(txn);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -40,6 +40,9 @@ class DeleteRangeTxn : public EditAggregateTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction.
|
||||
* @param aRange the range to delete
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMRange *aRange);
|
||||
|
||||
private:
|
||||
|
|
|
@ -29,13 +29,17 @@
|
|||
{0x86, 0xd8, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74} }
|
||||
|
||||
/**
|
||||
* A transaction that changes an attribute of a content node.
|
||||
* This transaction covers add, remove, and change attribute.
|
||||
* A transaction that removes text from a content node.
|
||||
*/
|
||||
class DeleteTextTxn : public EditTxn
|
||||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction.
|
||||
* @param aElement the content node to remove text from
|
||||
* @param aOffset the location in aElement to begin the deletion
|
||||
* @param aNumCharsToDelete the number of characters to delete. Not the number of bytes!
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aNumCharsToDelete);
|
||||
|
@ -49,7 +53,6 @@ public:
|
|||
|
||||
virtual nsresult Undo(void);
|
||||
|
||||
|
||||
virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction);
|
||||
|
||||
virtual nsresult Write(nsIOutputStream *aOutputStream);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
EditAggregateTxn::EditAggregateTxn()
|
||||
: EditTxn()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mChildren = new nsVoidArray();
|
||||
}
|
||||
|
||||
|
@ -106,7 +107,18 @@ nsresult EditAggregateTxn::GetIsTransient(PRBool *aIsTransient)
|
|||
|
||||
nsresult EditAggregateTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction)
|
||||
{
|
||||
return NS_OK;
|
||||
nsresult result=NS_OK; // it's legal (but not very useful) to have an empty child list
|
||||
if (nsnull!=aDidMerge)
|
||||
*aDidMerge=PR_FALSE;
|
||||
if (nsnull!=mChildren)
|
||||
{
|
||||
PRInt32 i;
|
||||
PRInt32 count = mChildren->Count();
|
||||
EditTxn *txn = (EditTxn*)(mChildren->ElementAt(count-1));
|
||||
result = txn->Merge(aDidMerge, aTransaction);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::Write(nsIOutputStream *aOutputStream)
|
||||
|
@ -138,6 +150,56 @@ nsresult EditAggregateTxn::AppendChild(EditTxn *aTxn)
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::SetName(nsIAtom *aName)
|
||||
{
|
||||
mName = aName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::GetName(nsIAtom **aName)
|
||||
{
|
||||
if (aName)
|
||||
{
|
||||
if (mName)
|
||||
{
|
||||
*aName = mName;
|
||||
NS_ADDREF(*aName);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::GetCount(PRInt32 *aCount)
|
||||
{
|
||||
if (!aCount) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aCount=0;
|
||||
if (mChildren) {
|
||||
*aCount = mChildren->Count();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditAggregateTxn::GetTxnAt(PRInt32 aIndex, EditTxn **aTxn)
|
||||
{
|
||||
if (!aTxn) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (!mChildren) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
const PRInt32 txnCount = mChildren->Count();
|
||||
if (0>aIndex || txnCount<=aIndex) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
*aTxn = (EditTxn *)(mChildren->ElementAt(aIndex));
|
||||
if (!*aTxn)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
NS_ADDREF(*aTxn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#define EditAggregateTxn_h__
|
||||
|
||||
#include "EditTxn.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define EDIT_AGGREGATE_TXN_IID \
|
||||
{/* 345921a0-ac49-11d2-86d8-000064657374 */ \
|
||||
|
@ -56,12 +58,30 @@ public:
|
|||
|
||||
virtual nsresult GetRedoString(nsString **aString);
|
||||
|
||||
/** append a transaction to this aggregate */
|
||||
virtual nsresult AppendChild(EditTxn *aTxn);
|
||||
|
||||
/** get the number of nested txns.
|
||||
* This is the number of top-level txns, it does not do recursive decent.
|
||||
*/
|
||||
virtual nsresult GetCount(PRInt32 *aCount);
|
||||
|
||||
/** get the txn at index aIndex.
|
||||
* returns NS_ERROR_UNEXPECTED if there is no txn at aIndex.
|
||||
*/
|
||||
virtual nsresult GetTxnAt(PRInt32 aIndex, EditTxn **aTxn);
|
||||
|
||||
/** set the name assigned to this aggregate txn */
|
||||
virtual nsresult SetName(nsIAtom *aName);
|
||||
|
||||
/** get the name assigned to this aggregate txn */
|
||||
virtual nsresult GetName(nsIAtom **aName);
|
||||
|
||||
protected:
|
||||
|
||||
//XXX: if this was an nsISupportsArray, it would handle refcounting for us
|
||||
nsVoidArray *mChildren;
|
||||
nsVoidArray * mChildren;
|
||||
nsCOMPtr<nsIAtom> mName;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -31,18 +31,26 @@
|
|||
class nsIPresShell;
|
||||
|
||||
/**
|
||||
* A transaction that changes an attribute of a content node.
|
||||
* This transaction covers add, remove, and change attribute.
|
||||
* TODO: do we need to add a direction field, and do the insert and
|
||||
* merging based on the direction?
|
||||
*/
|
||||
* A transaction that inserts text into a content node.
|
||||
*/
|
||||
class InsertTextTxn : public EditTxn
|
||||
{
|
||||
public:
|
||||
|
||||
/** used to name aggregate transactions that consist only of a single InsertTextTxn,
|
||||
* or a DeleteSelection followed by an InsertTextTxn.
|
||||
*/
|
||||
static nsIAtom *gInsertTextTxnName;
|
||||
|
||||
/** initialize the transaction
|
||||
* @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
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
const nsString& aStringToInsert,
|
||||
const nsString& aString,
|
||||
nsIPresShell* aPresShell);
|
||||
|
||||
private:
|
||||
|
@ -74,6 +82,9 @@ public:
|
|||
/** return the string data associated with this transaction */
|
||||
virtual nsresult GetData(nsString& aResult);
|
||||
|
||||
/** must be called before any InsertTextTxn is instantiated */
|
||||
static nsresult ClassInit();
|
||||
|
||||
protected:
|
||||
|
||||
/** return PR_TRUE if aOtherTxn immediately follows this txn */
|
||||
|
|
|
@ -38,6 +38,11 @@ class JoinElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction
|
||||
* @param aEditor the provider of core editing operations
|
||||
* @param aLeftNode the first of two nodes to join
|
||||
* @param aRightNode the second of two nodes to join
|
||||
*/
|
||||
virtual nsresult Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode);
|
||||
|
@ -73,8 +78,8 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> mRightNode;
|
||||
|
||||
/** the offset into mNode where the children of mElement are split (for undo).<BR>
|
||||
* mOffset is the index of the last child in the left node.
|
||||
* -1 means the left node gets no children.
|
||||
* mOffset is the index of the first child in the right node.
|
||||
* -1 means the left node had no children.
|
||||
*/
|
||||
PRUint32 mOffset;
|
||||
|
||||
|
|
|
@ -37,6 +37,13 @@ class SplitElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
/** initialize the transaction.
|
||||
* @param aEditor the provider of core editing operations
|
||||
* @param aNode the node to split
|
||||
* @param aOffset the location within aNode to do the split.
|
||||
* aOffset may refer to children of aNode, or content of aNode.
|
||||
* The left node will have child|content 0..aOffset-1.
|
||||
*/
|
||||
virtual nsresult Init (nsIEditor *aEditor,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset);
|
||||
|
@ -66,7 +73,7 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> mExistingRightNode;
|
||||
|
||||
/** the offset into mElement where the children of mElement are split.<BR>
|
||||
* mOffset is the index of the last child in the left node.
|
||||
* mOffset is the index of the first child in the right node.
|
||||
* -1 means the new node gets no children.
|
||||
*/
|
||||
PRInt32 mOffset;
|
||||
|
|
|
@ -69,9 +69,14 @@ TransactionFactory::GetNewTransaction(REFNSIID aTxnType, EditTxn **aResult)
|
|||
*aResult = new JoinElementTxn();
|
||||
else if (aTxnType.Equals(kEditAggregateTxnIID))
|
||||
*aResult = new EditAggregateTxn();
|
||||
else
|
||||
result = NS_ERROR_NO_INTERFACE;
|
||||
|
||||
if (nsnull==*aResult)
|
||||
result = NS_ERROR_INVALID_ARG;
|
||||
if (NS_SUCCEEDED(result) && nsnull==*aResult)
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_SUCCEEDED(result))
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ protected:
|
|||
virtual ~TransactionFactory();
|
||||
|
||||
public:
|
||||
/** return a transaction object of aTxnType, refcounted
|
||||
* @return NS_ERROR_NO_INTERFACE if aTxnType is unknown,
|
||||
* NS_ERROR_OUT_OF_MEMORY if the allocations fails.
|
||||
*/
|
||||
static nsresult GetNewTransaction(REFNSIID aTxnType, EditTxn **aResult);
|
||||
|
||||
};
|
||||
|
|
|
@ -249,6 +249,7 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell)
|
|||
NS_ADDREF(mPresShell);
|
||||
mPresShell->GetViewManager(&mViewManager);
|
||||
mUpdateCount=0;
|
||||
InsertTextTxn::ClassInit();
|
||||
|
||||
/* Show the caret */
|
||||
nsCOMPtr<nsICaret> caret;
|
||||
|
@ -365,8 +366,7 @@ nsEditor::CreateTxnForSetAttribute(nsIDOMElement *aElement,
|
|||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kChangeAttributeTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(this, aElement, aAttribute, aValue, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -414,7 +414,7 @@ nsEditor::CreateTxnForRemoveAttribute(nsIDOMElement *aElement,
|
|||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kChangeAttributeTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsAutoString value;
|
||||
result = (*aTxn)->Init(this, aElement, aAttribute, value, PR_TRUE);
|
||||
|
@ -655,12 +655,9 @@ nsresult nsEditor::CreateTxnForCreateElement(const nsString& aTag,
|
|||
if (nsnull != aParent)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kCreateElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull != *aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(mDoc, aTag, aParent, aPosition);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -681,31 +678,26 @@ nsresult nsEditor::InsertNode(nsIDOMNode * aNode,
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult nsEditor::DeleteNode(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement)
|
||||
nsresult nsEditor::DeleteNode(nsIDOMNode * aElement)
|
||||
{
|
||||
DeleteElementTxn *txn;
|
||||
nsresult result = CreateTxnForDeleteElement(aParent, aElement, &txn);
|
||||
nsresult result = CreateTxnForDeleteElement(aElement, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = Do(txn);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement,
|
||||
nsresult nsEditor::CreateTxnForDeleteElement(nsIDOMNode * aElement,
|
||||
DeleteElementTxn ** aTxn)
|
||||
{
|
||||
nsresult result = NS_ERROR_NULL_POINTER;
|
||||
if ((nsnull != aParent) && (nsnull != aElement))
|
||||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
result = (*aTxn)->Init(aElement, aParent);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(aElement);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -715,23 +707,33 @@ nsresult
|
|||
nsEditor::InsertText(const nsString& aStringToInsert)
|
||||
{
|
||||
nsresult result;
|
||||
EditAggregateTxn *aggTxn;
|
||||
result = TransactionFactory::GetNewTransaction(kEditAggregateTxnIID, (EditTxn **)&aggTxn);
|
||||
if ((NS_FAILED(result)) || (nsnull==aggTxn)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aggTxn->SetName(InsertTextTxn::gInsertTextTxnName);
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
result = mPresShell->GetSelection(getter_AddRefs(selection));
|
||||
//BeginTransaction();
|
||||
if (NS_SUCCEEDED(result) && selection)
|
||||
{
|
||||
PRBool collapsed;
|
||||
result = selection->IsCollapsed(&collapsed);
|
||||
if (NS_SUCCEEDED(result) && !collapsed)
|
||||
DeleteSelection(eLTR);
|
||||
if (NS_SUCCEEDED(result) && !collapsed) {
|
||||
EditAggregateTxn *delSelTxn;
|
||||
result = CreateTxnForDeleteSelection(nsIEditor::eLTR, &delSelTxn);
|
||||
if (NS_SUCCEEDED(result) && delSelTxn) {
|
||||
aggTxn->AppendChild(delSelTxn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InsertTextTxn *txn;
|
||||
result = CreateTxnForInsertText(aStringToInsert, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = Do(txn);
|
||||
if ((NS_SUCCEEDED(result)) && txn) {
|
||||
aggTxn->AppendChild(txn);
|
||||
result = Do(aggTxn);
|
||||
}
|
||||
//EndTransaction();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -809,12 +811,9 @@ nsresult nsEditor::CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
|||
if (nsnull != aElement)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kDeleteTextTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(aElement, aOffset, aLength);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -924,6 +923,10 @@ nsEditor::DeleteSelection(nsIEditor::Direction aDir)
|
|||
nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
||||
EditAggregateTxn ** aTxn)
|
||||
{
|
||||
if (!aTxn)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*aTxn = nsnull;
|
||||
|
||||
nsresult result;
|
||||
// allocate the out-param transaction
|
||||
result = TransactionFactory::GetNewTransaction(kEditAggregateTxnIID, (EditTxn **)aTxn);
|
||||
|
@ -1049,15 +1052,10 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
|||
}
|
||||
else
|
||||
{ // priorNode is not text, so tell it's parent to delete it
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
result = priorNode->GetParentNode(getter_AddRefs(parent));
|
||||
if ((NS_SUCCEEDED(result)) && parent)
|
||||
{
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(parent, priorNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(priorNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1090,15 +1088,10 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
|||
}
|
||||
else
|
||||
{ // nextNode is not text, so tell it's parent to delete it
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
result = nextNode->GetParentNode(getter_AddRefs(parent));
|
||||
if ((NS_SUCCEEDED(result)) && parent)
|
||||
{
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(parent, nextNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
DeleteElementTxn *txn;
|
||||
result = CreateTxnForDeleteElement(nextNode, &txn);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
aTxn->AppendChild(txn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1234,12 +1227,9 @@ nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
|
|||
if (nsnull != aNode)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kSplitElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(this, aNode, aOffset);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1252,12 +1242,9 @@ nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
|
|||
if ((nsnull != aLeftNode) && (nsnull != aRightNode))
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kJoinElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = (*aTxn)->Init(this, aLeftNode, aRightNode);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -128,8 +128,7 @@ public:
|
|||
PRInt32 aPosition);
|
||||
virtual nsresult InsertText(const nsString& aStringToInsert);
|
||||
|
||||
virtual nsresult DeleteNode(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aChild);
|
||||
virtual nsresult DeleteNode(nsIDOMNode * aChild);
|
||||
|
||||
virtual nsresult DeleteSelection(nsIEditor::Direction aDir);
|
||||
|
||||
|
@ -206,8 +205,7 @@ protected:
|
|||
PRInt32 aPosition,
|
||||
CreateElementTxn ** aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement,
|
||||
virtual nsresult CreateTxnForDeleteElement(nsIDOMNode * aElement,
|
||||
DeleteElementTxn ** aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
|
|
Загрузка…
Ссылка в новой задаче