minor fixes and lots of comments

This commit is contained in:
buster%netscape.com 1999-02-15 18:25:30 +00:00
Родитель 667207f280
Коммит c947533db7
32 изменённых файлов: 436 добавлений и 196 удалений

Просмотреть файл

@ -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,