зеркало из https://github.com/mozilla/gecko-dev.git
changed nsIEditor to enable undo separately from Init
work in progress API changes to nsIEditor and nsEditor
This commit is contained in:
Родитель
8583c23d49
Коммит
1d6de2d02b
|
@ -465,6 +465,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsIDOMNode *aCommonParen
|
|||
return result;
|
||||
}
|
||||
|
||||
// XXX: probably want to move this to editor as a standard support method
|
||||
nsresult DeleteRangeTxn::BuildAncestorList(nsIDOMNode *aNode, nsISupportsArray *aList)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
//XXX: if this was an nsISupportsArray, it would handle refcounting for us
|
||||
nsVoidArray *mChildren;
|
||||
|
||||
};
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "JoinElementTxn.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "editor.h"
|
||||
|
||||
|
||||
JoinElementTxn::JoinElementTxn()
|
||||
|
@ -26,9 +25,11 @@ JoinElementTxn::JoinElementTxn()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult JoinElementTxn::Init(nsIDOMNode *aLeftNode,
|
||||
nsresult JoinElementTxn::Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode)
|
||||
{
|
||||
mEditor = aEditor;
|
||||
mLeftNode = aLeftNode;
|
||||
mRightNode = aRightNode;
|
||||
mOffset=0;
|
||||
|
@ -63,7 +64,7 @@ nsresult JoinElementTxn::Do(void)
|
|||
{
|
||||
childNodes->GetLength(&mOffset);
|
||||
}
|
||||
result = nsEditor::JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
result = mEditor->JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,13 +75,13 @@ nsresult JoinElementTxn::Do(void)
|
|||
|
||||
nsresult JoinElementTxn::Undo(void)
|
||||
{
|
||||
nsresult result = nsEditor::SplitNode(mRightNode, mOffset, mLeftNode, mParent);
|
||||
nsresult result = mEditor->SplitNode(mRightNode, mOffset, mLeftNode, mParent);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult JoinElementTxn::Redo(void)
|
||||
{
|
||||
nsresult result = nsEditor::JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
nsresult result = mEditor->JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "EditTxn.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEditor.h"
|
||||
|
||||
#define JOIN_ELEMENT_TXN_IID \
|
||||
{/* 9bc5f9f0-ac48-11d2-86d8-000064657374 */ \
|
||||
|
@ -37,7 +38,8 @@ class JoinElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
virtual nsresult Init(nsIDOMNode *aLeftNode,
|
||||
virtual nsresult Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode);
|
||||
protected:
|
||||
JoinElementTxn();
|
||||
|
@ -78,6 +80,7 @@ protected:
|
|||
|
||||
/** the parent node containing mLeftNode and mRightNode */
|
||||
nsCOMPtr<nsIDOMNode> mParent;
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
|
||||
friend class TransactionFactory;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "SplitElementTxn.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "editor.h"
|
||||
|
||||
// note that aEditor is not refcounted
|
||||
SplitElementTxn::SplitElementTxn()
|
||||
|
@ -27,9 +26,11 @@ SplitElementTxn::SplitElementTxn()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult SplitElementTxn::Init(nsIDOMNode *aNode,
|
||||
nsresult SplitElementTxn::Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset)
|
||||
{
|
||||
mEditor = aEditor;
|
||||
mExistingRightNode = aNode;
|
||||
mOffset = aOffset;
|
||||
return NS_OK;
|
||||
|
@ -52,7 +53,7 @@ nsresult SplitElementTxn::Do(void)
|
|||
// insert the new node
|
||||
if ((NS_SUCCEEDED(result)) && (mParent))
|
||||
{
|
||||
result = nsEditor::SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -61,13 +62,13 @@ nsresult SplitElementTxn::Do(void)
|
|||
nsresult SplitElementTxn::Undo(void)
|
||||
{
|
||||
// this assumes Do inserted the new node in front of the prior existing node
|
||||
nsresult result = nsEditor::JoinNodes(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
|
||||
nsresult result = mEditor->JoinNodes(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult SplitElementTxn::Redo(void)
|
||||
{
|
||||
nsresult result = nsEditor::SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
nsresult result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "EditTxn.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEditor.h"
|
||||
|
||||
#define SPLIT_ELEMENT_TXN_IID \
|
||||
{/* 690c6290-ac48-11d2-86d8-000064657374 */ \
|
||||
|
@ -36,7 +37,8 @@ class SplitElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
virtual nsresult Init (nsIDOMNode *aNode,
|
||||
virtual nsresult Init (nsIEditor *aEditor,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset);
|
||||
protected:
|
||||
SplitElementTxn();
|
||||
|
@ -74,6 +76,7 @@ protected:
|
|||
|
||||
/** the parent shared by mExistingRightNode and mNewLeftNode */
|
||||
nsCOMPtr<nsIDOMNode> mParent;
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
|
||||
friend class TransactionFactory;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "nsICollection.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
// transactions the editor knows how to build
|
||||
#include "TransactionFactory.h"
|
||||
|
@ -58,7 +59,8 @@ static NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
|
|||
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
|
||||
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
|
||||
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
|
||||
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
|
||||
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
|
||||
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
|
||||
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID);
|
||||
|
@ -188,7 +190,7 @@ nsEditor::~nsEditor()
|
|||
//the autopointers will clear themselves up.
|
||||
//but we need to also remove the listeners or we have a leak
|
||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||
nsresult t_result = mDomInterfaceP->QueryInterface(kIDOMEventReceiverIID, getter_AddRefs(erP));
|
||||
nsresult t_result = mDoc->QueryInterface(kIDOMEventReceiverIID, getter_AddRefs(erP));
|
||||
if (NS_SUCCEEDED( t_result ))
|
||||
{
|
||||
erP->RemoveEventListener(mKeyListenerP, kIDOMKeyListenerIID);
|
||||
|
@ -231,20 +233,25 @@ nsEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
|
||||
|
||||
nsresult
|
||||
nsEditor::GetDomInterface(nsIDOMDocument **aDomInterface)
|
||||
nsEditor::GetDocument(nsIDOMDocument **aDoc)
|
||||
{
|
||||
*aDomInterface = mDomInterfaceP; return NS_OK;
|
||||
*aDoc = nsnull; // init out param
|
||||
NS_PRECONDITION(mDoc, "bad state, null mDoc");
|
||||
if (!mDoc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
return mDoc->QueryInterface(kIDOMDocumentIID, (void **)aDoc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell)
|
||||
nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell)
|
||||
{
|
||||
if ((nsnull==aDomInterface) || (nsnull==aPresShell))
|
||||
NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg");
|
||||
if ((nsnull==aDoc) || (nsnull==aPresShell))
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
mDomInterfaceP = aDomInterface;
|
||||
mDoc = aDoc;
|
||||
mPresShell = aPresShell;
|
||||
NS_ADDREF(mPresShell);
|
||||
mViewManager = mPresShell->GetViewManager();
|
||||
|
@ -264,7 +271,7 @@ nsEditor::Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell)
|
|||
return t_result;
|
||||
}
|
||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||
t_result = mDomInterfaceP->QueryInterface(kIDOMEventReceiverIID, getter_AddRefs(erP));
|
||||
t_result = mDoc->QueryInterface(kIDOMEventReceiverIID, getter_AddRefs(erP));
|
||||
if (NS_OK != t_result)
|
||||
{
|
||||
mKeyListenerP = 0;
|
||||
|
@ -277,61 +284,74 @@ nsEditor::Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell)
|
|||
|
||||
/* fire up the transaction manager */
|
||||
|
||||
/*
|
||||
now to handle selection
|
||||
*/
|
||||
/*
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
if (NS_SUCCEEDED(t_result = mDomInterfaceP->QueryInterface(kIDocumentIID, getter_AddRefs(document))))
|
||||
{
|
||||
if (!NS_SUCCEEDED(t_result = document->GetSelection(*getter_AddRefs(mSelectionP))))
|
||||
{
|
||||
NS_NOTREACHED("query interface");
|
||||
return t_result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_NOTREACHED("query interface");
|
||||
return t_result;
|
||||
}
|
||||
*/
|
||||
|
||||
nsISupports *isup = 0;
|
||||
nsresult result;
|
||||
|
||||
result = nsServiceManager::GetService(kCTransactionManagerFactoryCID,
|
||||
kITransactionManagerIID, &isup);
|
||||
|
||||
if (NS_FAILED(result) || !isup) {
|
||||
printf("ERROR: Failed to get TransactionManager nsISupports interface.\n");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = isup->QueryInterface(kITransactionManagerIID, (void **)&mTxnMgr);
|
||||
|
||||
if (NS_FAILED(result)) {
|
||||
printf("ERROR: Failed to get TransactionManager interface. (%d)\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!mTxnMgr) {
|
||||
printf("ERROR: QueryInterface() returned NULL pointer.\n");
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_POSTCONDITION(mDoc && mPresShell, "bad state");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::InsertString(nsString *aString)
|
||||
nsEditor::EnableUndo(PRBool aEnable)
|
||||
{
|
||||
nsISupports *isup = 0;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if (PR_TRUE==aEnable)
|
||||
{
|
||||
if (!mTxnMgr)
|
||||
{
|
||||
result = nsServiceManager::GetService(kCTransactionManagerFactoryCID,
|
||||
kITransactionManagerIID, &isup);
|
||||
if (NS_FAILED(result) || !isup) {
|
||||
printf("ERROR: Failed to get TransactionManager nsISupports interface.\n");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
result = isup->QueryInterface(kITransactionManagerIID, (void **)&mTxnMgr);
|
||||
if (NS_FAILED(result) || !mTxnMgr) {
|
||||
printf("ERROR: Failed to get TransactionManager interface. (%d)\n", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // disable the transaction manager if it is enabled
|
||||
if (mTxnMgr)
|
||||
{
|
||||
mTxnMgr = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CanUndo(PRBool &aIsEnabled, PRBool &aCanUndo)
|
||||
{
|
||||
aIsEnabled = ((PRBool)(mTxnMgr));
|
||||
if (aIsEnabled)
|
||||
{
|
||||
PRInt32 numTxns=0;
|
||||
mTxnMgr->GetNumberOfUndoItems(&numTxns);
|
||||
aCanUndo = ((PRBool)(0==numTxns));
|
||||
}
|
||||
else {
|
||||
aCanUndo = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsEditor::CanRedo(PRBool &aIsEnabled, PRBool &aCanRedo)
|
||||
{
|
||||
aIsEnabled = ((PRBool)(mTxnMgr));
|
||||
if (aIsEnabled)
|
||||
{
|
||||
PRInt32 numTxns=0;
|
||||
mTxnMgr->GetNumberOfRedoItems(&numTxns);
|
||||
aCanRedo = ((PRBool)(0==numTxns));
|
||||
}
|
||||
else {
|
||||
aCanRedo = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::SetProperties(Properties aProperties)
|
||||
|
@ -447,26 +467,6 @@ nsEditor::Commit(PRBool aCtrlKey)
|
|||
//END nsIEditorInterfaces
|
||||
|
||||
|
||||
//BEGIN nsEditor Calls from public
|
||||
PRBool
|
||||
nsEditor::KeyDown(int aKeycode)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nsEditor::MouseClick(int aX,int aY)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//END nsEditor Calls from public
|
||||
|
||||
|
||||
|
||||
//BEGIN nsEditor Private methods
|
||||
|
||||
|
@ -476,10 +476,12 @@ nsEditor::GetCurrentNode(nsIDOMNode ** aNode)
|
|||
{
|
||||
if (!aNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!mDoc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
/* If no node set, get first text node */
|
||||
nsCOMPtr<nsIDOMElement> docNode;
|
||||
|
||||
if (NS_SUCCEEDED(mDomInterfaceP->GetDocumentElement(getter_AddRefs(docNode))))
|
||||
if (NS_SUCCEEDED(mDoc->GetDocumentElement(getter_AddRefs(docNode))))
|
||||
{
|
||||
return docNode->QueryInterface(kIDOMNodeIID,(void **) aNode);
|
||||
}
|
||||
|
@ -491,6 +493,8 @@ nsEditor::GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDO
|
|||
{
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if (!mDoc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -500,7 +504,7 @@ nsEditor::GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDO
|
|||
|
||||
if (nsnull==aStartNode)
|
||||
{
|
||||
mDomInterfaceP->GetDocumentElement(getter_AddRefs(element));
|
||||
mDoc->GetDocumentElement(getter_AddRefs(element));
|
||||
result = element->QueryInterface(kIDOMNodeIID,getter_AddRefs(node));
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
@ -666,10 +670,6 @@ nsEditor::EndUpdate()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEditor::Delete(PRBool aForward, PRUint32 aCount)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CreateElement(const nsString& aTag,
|
||||
nsIDOMNode * aParent,
|
||||
|
@ -694,7 +694,7 @@ nsresult nsEditor::CreateTxnForCreateElement(const nsString& aTag,
|
|||
result = TransactionFactory::GetNewTransaction(kCreateElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull != *aTxn)
|
||||
{
|
||||
(*aTxn)->Init(mDomInterfaceP, aTag, aParent, aPosition);
|
||||
result = (*aTxn)->Init(mDoc, aTag, aParent, aPosition);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -723,7 +723,7 @@ nsresult nsEditor::CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
(*aTxn)->Init(aElement, aParent);
|
||||
result = (*aTxn)->Init(aElement, aParent);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -777,7 +777,7 @@ nsresult nsEditor::CreateTxnForInsertText(const nsString & aStringToInsert,
|
|||
result = TransactionFactory::GetNewTransaction(kInsertTextTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
(*aTxn)->Init(nodeAsText, offset, aStringToInsert);
|
||||
result = (*aTxn)->Init(nodeAsText, offset, aStringToInsert);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -817,7 +817,7 @@ nsresult nsEditor::CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteTextTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
(*aTxn)->Init(aElement, aOffset, aLength);
|
||||
result = (*aTxn)->Init(aElement, aOffset, aLength);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -825,6 +825,84 @@ nsresult nsEditor::CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
|||
return result;
|
||||
}
|
||||
|
||||
// operates on selection
|
||||
// deletes the selection (if not collapsed) and splits the current element
|
||||
// or an ancestor of the current element
|
||||
/* context-dependent behaviors
|
||||
SELECTION ACTION
|
||||
text node split text node (or a parent)
|
||||
block element insert a <BR>
|
||||
H1-H6 if at end, create a <P> following the header
|
||||
*/
|
||||
#if 0 // THIS CODE WILL BE REMOVED. WE ARE GOING TO IMPLEMENT
|
||||
// A GENERIC HANDLER SYSTEM.
|
||||
nsresult nsEditor::CreateTxnToHandleEnterKey(EditAggregateTxn **aTxn)
|
||||
{
|
||||
// allocate the out-param transaction
|
||||
nsresult result = TransactionFactory::GetNewTransaction(kEditAggregateTxnIID, (EditTxn **)aTxn);
|
||||
if (NS_FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
nsISelection* selection;
|
||||
result = mPresShell->GetSelection(&selection);
|
||||
if ((NS_SUCCEEDED(result)) && (nsnull!=selection))
|
||||
{
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = selection;
|
||||
if (enumerator)
|
||||
{
|
||||
// XXX: need to handle mutliple ranges here, probably by
|
||||
// disallowing the operation
|
||||
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
|
||||
{
|
||||
nsISupports *currentItem=nsnull;
|
||||
result = enumerator->CurrentItem(¤tItem);
|
||||
if ((NS_SUCCEEDED(result)) && (currentItem))
|
||||
{
|
||||
nsCOMPtr<nsIDOMRange> range(currentItem);
|
||||
PRBool isCollapsed;
|
||||
range->GetIsCollapsed(&isCollapsed);
|
||||
if(PR_FALSE==isCollapsed)
|
||||
{
|
||||
EditAggregateTxn *delSelTxn;
|
||||
result = CreateTxnForDeleteSelection(nsIEditor::eLTR, &delSelTxn);
|
||||
if ((NS_SUCCEEDED(result)) && (delSelTtxn)) {
|
||||
(*aTxn)->AppendChild(delSelTtxn);
|
||||
}
|
||||
}
|
||||
// at this point, we have a collapsed selection
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
result = range->GetStartParent(getter_AddRefs(node));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsVoidArray parentFrameList;
|
||||
result = GetParentFrameList(node, &parentFrameList);
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
EditAggregateTxn *enterKeyTxn;
|
||||
result = CreateTxnForEnterKeyAtInsertionPoint(range, &enterKeyTxn));
|
||||
if ((NS_SUCCEEDED(result)) && (enterKeyTxn)) {
|
||||
(*aTxn)->AppendChild(enterKeyTxn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if anything along the way failed, delete the out-param transaction
|
||||
if (NS_FAILED(result)) {
|
||||
NS_IF_RELEASE(*aTxn);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsEditor::DeleteSelection(nsIEditor::Direction aDir)
|
||||
{
|
||||
|
@ -854,7 +932,7 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
|||
enumerator = selection;
|
||||
if (enumerator)
|
||||
{
|
||||
for (enumerator->First();NS_OK != enumerator->IsDone() ; enumerator->Next())
|
||||
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
|
||||
{
|
||||
nsISupports *currentItem=nsnull;
|
||||
result = enumerator->CurrentItem(¤tItem);
|
||||
|
@ -863,7 +941,6 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
|||
nsCOMPtr<nsIDOMRange> range(currentItem);
|
||||
PRBool isCollapsed;
|
||||
range->GetIsCollapsed(&isCollapsed);
|
||||
printf("GetIsCollapsed returned %d\n", isCollapsed);
|
||||
if (PR_FALSE==isCollapsed)
|
||||
{
|
||||
DeleteRangeTxn *txn;
|
||||
|
@ -888,12 +965,6 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
|||
result = NS_ERROR_NULL_POINTER;
|
||||
|
||||
// if we didn't build the transaction correctly, destroy the out-param transaction so we don't leak it.
|
||||
if (NS_FAILED(result))
|
||||
{
|
||||
printf ("new result = %d, NS_FAILED=%d, macro expanded out=%d\n",
|
||||
result, NS_FAILED(result), ((result) & 0x80000000));
|
||||
}
|
||||
|
||||
if (NS_FAILED(result))
|
||||
{
|
||||
NS_IF_RELEASE(*aTxn);
|
||||
|
@ -1149,6 +1220,41 @@ nsEditor::GetLeftmostChild(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode)
|
|||
return result;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
|
||||
PRUint32 aOffset,
|
||||
SplitElementTxn **aTxn)
|
||||
{
|
||||
nsresult result=NS_ERROR_NULL_POINTER;
|
||||
if (nsnull != aNode)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kSplitElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
result = (*aTxn)->Init(this, aNode, aOffset);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode,
|
||||
JoinElementTxn **aTxn)
|
||||
{
|
||||
nsresult result=NS_ERROR_NULL_POINTER;
|
||||
if ((nsnull != aLeftNode) && (nsnull != aRightNode))
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kJoinElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
result = (*aTxn)->Init(this, aLeftNode, aRightNode);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
|
||||
|
|
|
@ -40,6 +40,8 @@ class CreateElementTxn;
|
|||
class DeleteElementTxn;
|
||||
class InsertTextTxn;
|
||||
class DeleteTextTxn;
|
||||
class SplitElementTxn;
|
||||
class JoinElementTxn;
|
||||
class EditAggregateTxn;
|
||||
|
||||
//This is the monitor for the editor.
|
||||
|
@ -57,7 +59,7 @@ private:
|
|||
nsIPresShell *mPresShell;
|
||||
nsIViewManager *mViewManager;
|
||||
PRUint32 mUpdateCount;
|
||||
nsCOMPtr<nsIDOMDocument> mDomInterfaceP;
|
||||
nsCOMPtr<nsIDOMDocument> mDoc;
|
||||
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
|
||||
// nsCOMPtr<nsISelection> mSelectionP;
|
||||
|
@ -82,9 +84,9 @@ public:
|
|||
/*interfaces for addref and release and queryinterface*/
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell);
|
||||
virtual nsresult Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell);
|
||||
|
||||
virtual nsresult GetDomInterface(nsIDOMDocument **aDomInterface);
|
||||
virtual nsresult GetDocument(nsIDOMDocument **aDoc);
|
||||
|
||||
virtual nsresult SetProperties(Properties aProperties);
|
||||
|
||||
|
@ -101,35 +103,47 @@ public:
|
|||
|
||||
virtual nsresult RemoveAttribute(nsIDOMElement *aElement, const nsString& aAttribute);
|
||||
|
||||
virtual nsresult CreateElement(const nsString& aTag,
|
||||
nsIDOMNode * aParent,
|
||||
PRInt32 aPosition);
|
||||
|
||||
virtual nsresult DeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aChild);
|
||||
|
||||
virtual nsresult DeleteSelection(nsIEditor::Direction aDir);
|
||||
|
||||
virtual nsresult InsertText(const nsString& aStringToInsert);
|
||||
|
||||
virtual nsresult SplitNode(nsIDOMNode * aExistingRightNode,
|
||||
PRInt32 aOffset,
|
||||
nsIDOMNode * aNewLeftNode,
|
||||
nsIDOMNode * aParent);
|
||||
|
||||
virtual nsresult JoinNodes(nsIDOMNode * aNodeToKeep,
|
||||
nsIDOMNode * aNodeToJoin,
|
||||
nsIDOMNode * aParent,
|
||||
PRBool aNodeToKeepIsFirst);
|
||||
|
||||
virtual nsresult Commit(PRBool aCtrlKey);
|
||||
|
||||
virtual nsresult EnableUndo(PRBool aEnable);
|
||||
|
||||
virtual nsresult Do(nsITransaction *aTxn);
|
||||
|
||||
virtual nsresult Undo(PRUint32 aCount);
|
||||
|
||||
virtual nsresult CanUndo(PRBool &aIsEnabled, PRBool &aCanUndo);
|
||||
|
||||
virtual nsresult Redo(PRUint32 aCount);
|
||||
|
||||
virtual nsresult CanRedo(PRBool &aIsEnabled, PRBool &aCanRedo);
|
||||
|
||||
virtual nsresult BeginUpdate();
|
||||
|
||||
virtual nsresult EndUpdate();
|
||||
|
||||
/*END nsIEditor interfaces*/
|
||||
|
||||
/*BEGIN nsEditor interfaces*/
|
||||
|
||||
|
||||
/*KeyListener Methods*/
|
||||
/** KeyDown is called from the key event lister "probably"
|
||||
* @param int aKeycode the keycode or ascii
|
||||
* value of the key that was hit for now
|
||||
* @return False if ignored
|
||||
*/
|
||||
PRBool KeyDown(int aKeycode);
|
||||
|
||||
/*MouseListener Methods*/
|
||||
/** MouseClick
|
||||
* @param int x the xposition of the click
|
||||
* @param int y the yposition of the click
|
||||
*/
|
||||
PRBool MouseClick(int aX,int aY); //it should also tell us the dom element that was selected.
|
||||
|
||||
/*BEGIN private methods used by the implementations of the above functions*/
|
||||
|
||||
|
@ -156,73 +170,60 @@ public:
|
|||
*/
|
||||
nsresult GetFirstNodeOfType(nsIDOMNode *aStartNode, const nsString &aTag, nsIDOMNode **aResult);
|
||||
|
||||
nsresult CreateElement(const nsString& aTag,
|
||||
nsIDOMNode * aParent,
|
||||
PRInt32 aPosition);
|
||||
|
||||
nsresult DeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement);
|
||||
|
||||
nsresult DeleteSelection(nsIEditor::Direction aDir);
|
||||
|
||||
nsresult InsertText(const nsString& aStringToInsert);
|
||||
|
||||
nsresult DeleteText(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aLength);
|
||||
|
||||
static nsresult SplitNode(nsIDOMNode * aExistingRightNode,
|
||||
PRInt32 aOffset,
|
||||
nsIDOMNode * aNewLeftNode,
|
||||
nsIDOMNode * aParent);
|
||||
|
||||
static nsresult JoinNodes(nsIDOMNode * aNodeToKeep,
|
||||
nsIDOMNode * aNodeToJoin,
|
||||
nsIDOMNode * aParent,
|
||||
PRBool aNodeToKeepIsFirst);
|
||||
|
||||
nsresult Delete(PRBool aForward, PRUint32 aCount);
|
||||
|
||||
virtual nsresult InsertString(nsString *aString);
|
||||
|
||||
virtual nsresult Commit(PRBool aCtrlKey);
|
||||
|
||||
/*END private methods of nsEditor*/
|
||||
|
||||
protected:
|
||||
nsresult CreateTxnForSetAttribute(nsIDOMElement *aElement,
|
||||
const nsString& aAttribute,
|
||||
const nsString& aValue,
|
||||
ChangeAttributeTxn ** aTxn);
|
||||
virtual nsresult CreateTxnForSetAttribute(nsIDOMElement *aElement,
|
||||
const nsString& aAttribute,
|
||||
const nsString& aValue,
|
||||
ChangeAttributeTxn ** aTxn);
|
||||
|
||||
nsresult CreateTxnForRemoveAttribute(nsIDOMElement *aElement,
|
||||
const nsString& aAttribute,
|
||||
ChangeAttributeTxn ** aTxn);
|
||||
virtual nsresult CreateTxnForRemoveAttribute(nsIDOMElement *aElement,
|
||||
const nsString& aAttribute,
|
||||
ChangeAttributeTxn ** aTxn);
|
||||
|
||||
nsresult CreateTxnForCreateElement(const nsString& aTag,
|
||||
nsIDOMNode *aParent,
|
||||
PRInt32 aPosition,
|
||||
CreateElementTxn ** aTxn);
|
||||
virtual nsresult CreateTxnForCreateElement(const nsString& aTag,
|
||||
nsIDOMNode *aParent,
|
||||
PRInt32 aPosition,
|
||||
CreateElementTxn ** aTxn);
|
||||
|
||||
nsresult CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement,
|
||||
DeleteElementTxn ** aTxn);
|
||||
virtual nsresult CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aElement,
|
||||
DeleteElementTxn ** aTxn);
|
||||
|
||||
nsresult CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
InsertTextTxn ** aTxn);
|
||||
virtual nsresult CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
InsertTextTxn ** aTxn);
|
||||
|
||||
nsresult CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aLength,
|
||||
DeleteTextTxn **aTxn);
|
||||
|
||||
nsresult CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
||||
EditAggregateTxn ** aTxn);
|
||||
virtual nsresult DeleteText(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aLength);
|
||||
|
||||
nsresult CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
||||
virtual nsresult CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aLength,
|
||||
DeleteTextTxn **aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
||||
EditAggregateTxn ** aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
||||
nsIEditor::Direction aDir,
|
||||
EditAggregateTxn *aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForSplitNode(nsIDOMNode *aNode,
|
||||
PRUint32 aOffset,
|
||||
SplitElementTxn **aTxn);
|
||||
|
||||
virtual nsresult CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode,
|
||||
JoinElementTxn **aTxn);
|
||||
|
||||
#if 0
|
||||
nsresult CreateTxnToHandleEnterKey(EditAggregateTxn **aTxn);
|
||||
#endif
|
||||
|
||||
nsresult GetPriorNode(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode);
|
||||
|
||||
nsresult GetNextNode(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode);
|
||||
|
|
|
@ -238,13 +238,13 @@ nsEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProces
|
|||
{
|
||||
result = TransactionFactory::GetNewTransaction(kSplitElementTxnIID, (EditTxn **)&txn);
|
||||
if (txn)
|
||||
txn->Init(currentNode, -1);
|
||||
txn->Init(mEditor, currentNode, -1);
|
||||
}
|
||||
else // split the element so there are 2 children in the first half
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kSplitElementTxnIID, (EditTxn **)&txn);
|
||||
if (txn)
|
||||
txn->Init(currentNode, 1);
|
||||
txn->Init(mEditor, currentNode, 1);
|
||||
}
|
||||
if (txn)
|
||||
mEditor->Do(txn);
|
||||
|
@ -409,7 +409,6 @@ nsEditorMouseListener::MouseUp(nsIDOMEvent* aMouseEvent)
|
|||
nsresult
|
||||
nsEditorMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
mEditor->MouseClick(0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -465,6 +465,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsIDOMNode *aCommonParen
|
|||
return result;
|
||||
}
|
||||
|
||||
// XXX: probably want to move this to editor as a standard support method
|
||||
nsresult DeleteRangeTxn::BuildAncestorList(nsIDOMNode *aNode, nsISupportsArray *aList)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
//XXX: if this was an nsISupportsArray, it would handle refcounting for us
|
||||
nsVoidArray *mChildren;
|
||||
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "nsICollection.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
// transactions the editor knows how to build
|
||||
#include "TransactionFactory.h"
|
||||
|
@ -694,7 +695,7 @@ nsresult nsEditor::CreateTxnForCreateElement(const nsString& aTag,
|
|||
result = TransactionFactory::GetNewTransaction(kCreateElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull != *aTxn)
|
||||
{
|
||||
(*aTxn)->Init(mDomInterfaceP, aTag, aParent, aPosition);
|
||||
result = (*aTxn)->Init(mDomInterfaceP, aTag, aParent, aPosition);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -723,7 +724,7 @@ nsresult nsEditor::CreateTxnForDeleteElement(nsIDOMNode * aParent,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
(*aTxn)->Init(aElement, aParent);
|
||||
result = (*aTxn)->Init(aElement, aParent);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -777,7 +778,7 @@ nsresult nsEditor::CreateTxnForInsertText(const nsString & aStringToInsert,
|
|||
result = TransactionFactory::GetNewTransaction(kInsertTextTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
(*aTxn)->Init(nodeAsText, offset, aStringToInsert);
|
||||
result = (*aTxn)->Init(nodeAsText, offset, aStringToInsert);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -817,7 +818,7 @@ nsresult nsEditor::CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
|||
result = TransactionFactory::GetNewTransaction(kDeleteTextTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
(*aTxn)->Init(aElement, aOffset, aLength);
|
||||
result = (*aTxn)->Init(aElement, aOffset, aLength);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -825,6 +826,82 @@ nsresult nsEditor::CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
|
|||
return result;
|
||||
}
|
||||
|
||||
// operates on selection
|
||||
// deletes the selection (if not collapsed) and splits the current element
|
||||
// or an ancestor of the current element
|
||||
/* context-dependent behaviors
|
||||
SELECTION ACTION
|
||||
text node split text node (or a parent)
|
||||
block element insert a <BR>
|
||||
H1-H6 if at end, create a <P> following the header
|
||||
*/
|
||||
nsresult nsEditor::CreateTxnToHandleEnterKey(EditAggregateTxn **aTxn)
|
||||
{
|
||||
// allocate the out-param transaction
|
||||
nsresult result = TransactionFactory::GetNewTransaction(kEditAggregateTxnIID, (EditTxn **)aTxn);
|
||||
if (NS_FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
nsISelection* selection;
|
||||
result = mPresShell->GetSelection(&selection);
|
||||
if ((NS_SUCCEEDED(result)) && (nsnull!=selection))
|
||||
{
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = selection;
|
||||
if (enumerator)
|
||||
{
|
||||
// XXX: need to handle mutliple ranges here, probably by
|
||||
// disallowing the operation
|
||||
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
|
||||
{
|
||||
nsISupports *currentItem=nsnull;
|
||||
result = enumerator->CurrentItem(¤tItem);
|
||||
if ((NS_SUCCEEDED(result)) && (currentItem))
|
||||
{
|
||||
nsCOMPtr<nsIDOMRange> range(currentItem);
|
||||
PRBool isCollapsed;
|
||||
range->GetIsCollapsed(&isCollapsed);
|
||||
if(PR_FALSE==isCollapsed)
|
||||
{
|
||||
EditAggregateTxn *delSelTxn;
|
||||
result = CreateTxnForDeleteSelection(nsIEditor::eLTR, &delSelTtxn);
|
||||
if ((NS_SUCCEEDED(result)) && (delSelTtxn)) {
|
||||
(*aTxn)->AppendChild(delSelTtxn);
|
||||
}
|
||||
}
|
||||
// at this point, we have a collapsed selection
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
result = range->GetStartParent(getter_AddRefs(node));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsVoidArray parentFrameList;
|
||||
result = GetParentFrameList(node, &parentFrameList);
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
EditAggregateTxn *enterKeyTxn;
|
||||
result = CreateTxnForEnterKeyAtInsertionPoint(range, &enterKeyTxn));
|
||||
if ((NS_SUCCEEDED(result)) && (enterKeyTxn)) {
|
||||
(*aTxn)->AppendChild(enterKeyTxn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if anything along the way failed, delete the out-param transaction
|
||||
if (NS_FAILED(result)) {
|
||||
NS_IF_RELEASE(*aTxn);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::DeleteSelection(nsIEditor::Direction aDir)
|
||||
{
|
||||
|
@ -854,7 +931,7 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
|||
enumerator = selection;
|
||||
if (enumerator)
|
||||
{
|
||||
for (enumerator->First();NS_OK != enumerator->IsDone() ; enumerator->Next())
|
||||
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
|
||||
{
|
||||
nsISupports *currentItem=nsnull;
|
||||
result = enumerator->CurrentItem(¤tItem);
|
||||
|
@ -863,7 +940,6 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
|||
nsCOMPtr<nsIDOMRange> range(currentItem);
|
||||
PRBool isCollapsed;
|
||||
range->GetIsCollapsed(&isCollapsed);
|
||||
printf("GetIsCollapsed returned %d\n", isCollapsed);
|
||||
if (PR_FALSE==isCollapsed)
|
||||
{
|
||||
DeleteRangeTxn *txn;
|
||||
|
@ -888,12 +964,6 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
|||
result = NS_ERROR_NULL_POINTER;
|
||||
|
||||
// if we didn't build the transaction correctly, destroy the out-param transaction so we don't leak it.
|
||||
if (NS_FAILED(result))
|
||||
{
|
||||
printf ("new result = %d, NS_FAILED=%d, macro expanded out=%d\n",
|
||||
result, NS_FAILED(result), ((result) & 0x80000000));
|
||||
}
|
||||
|
||||
if (NS_FAILED(result))
|
||||
{
|
||||
NS_IF_RELEASE(*aTxn);
|
||||
|
@ -1149,6 +1219,41 @@ nsEditor::GetLeftmostChild(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode)
|
|||
return result;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
|
||||
PRUint32 aOffset,
|
||||
SplitElementTxn **aTxn)
|
||||
{
|
||||
nsresult result=NS_ERROR_NULL_POINTER;
|
||||
if (nsnull != aNode)
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kSplitElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
result = (*aTxn)->Init(aNode, aOffset);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode,
|
||||
JoinElementTxn **aTxn)
|
||||
{
|
||||
nsresult result=NS_ERROR_NULL_POINTER;
|
||||
if ((nsnull != aLeftNode) && (nsnull != aRightNode))
|
||||
{
|
||||
result = TransactionFactory::GetNewTransaction(kJoinElementTxnIID, (EditTxn **)aTxn);
|
||||
if (nsnull!=*aTxn)
|
||||
{
|
||||
result = (*aTxn)->Init(aLeftNode, aRightNode);
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
|
||||
|
|
|
@ -40,6 +40,8 @@ class CreateElementTxn;
|
|||
class DeleteElementTxn;
|
||||
class InsertTextTxn;
|
||||
class DeleteTextTxn;
|
||||
class SplitElementTxn;
|
||||
class JoinElementTxn;
|
||||
class EditAggregateTxn;
|
||||
|
||||
//This is the monitor for the editor.
|
||||
|
@ -223,6 +225,16 @@ protected:
|
|||
nsIEditor::Direction aDir,
|
||||
EditAggregateTxn *aTxn);
|
||||
|
||||
nsresult CreateTxnForSplitNode(nsIDOMNode *aNode,
|
||||
PRUint32 aOffset,
|
||||
SplitElementTxn **aTxn);
|
||||
|
||||
nsresult CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode,
|
||||
JoinElementTxn **aTxn);
|
||||
|
||||
nsresult CreateTxnToHandleEnterKey(EditAggregateTxn **aTxn);
|
||||
|
||||
nsresult GetPriorNode(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode);
|
||||
|
||||
nsresult GetNextNode(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode);
|
||||
|
|
|
@ -465,6 +465,7 @@ nsresult DeleteRangeTxn::CreateTxnsToDeleteNodesBetween(nsIDOMNode *aCommonParen
|
|||
return result;
|
||||
}
|
||||
|
||||
// XXX: probably want to move this to editor as a standard support method
|
||||
nsresult DeleteRangeTxn::BuildAncestorList(nsIDOMNode *aNode, nsISupportsArray *aList)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
//XXX: if this was an nsISupportsArray, it would handle refcounting for us
|
||||
nsVoidArray *mChildren;
|
||||
|
||||
};
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "JoinElementTxn.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "editor.h"
|
||||
|
||||
|
||||
JoinElementTxn::JoinElementTxn()
|
||||
|
@ -26,9 +25,11 @@ JoinElementTxn::JoinElementTxn()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult JoinElementTxn::Init(nsIDOMNode *aLeftNode,
|
||||
nsresult JoinElementTxn::Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode)
|
||||
{
|
||||
mEditor = aEditor;
|
||||
mLeftNode = aLeftNode;
|
||||
mRightNode = aRightNode;
|
||||
mOffset=0;
|
||||
|
@ -63,7 +64,7 @@ nsresult JoinElementTxn::Do(void)
|
|||
{
|
||||
childNodes->GetLength(&mOffset);
|
||||
}
|
||||
result = nsEditor::JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
result = mEditor->JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,13 +75,13 @@ nsresult JoinElementTxn::Do(void)
|
|||
|
||||
nsresult JoinElementTxn::Undo(void)
|
||||
{
|
||||
nsresult result = nsEditor::SplitNode(mRightNode, mOffset, mLeftNode, mParent);
|
||||
nsresult result = mEditor->SplitNode(mRightNode, mOffset, mLeftNode, mParent);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult JoinElementTxn::Redo(void)
|
||||
{
|
||||
nsresult result = nsEditor::JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
nsresult result = mEditor->JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "EditTxn.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEditor.h"
|
||||
|
||||
#define JOIN_ELEMENT_TXN_IID \
|
||||
{/* 9bc5f9f0-ac48-11d2-86d8-000064657374 */ \
|
||||
|
@ -37,7 +38,8 @@ class JoinElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
virtual nsresult Init(nsIDOMNode *aLeftNode,
|
||||
virtual nsresult Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode);
|
||||
protected:
|
||||
JoinElementTxn();
|
||||
|
@ -78,6 +80,7 @@ protected:
|
|||
|
||||
/** the parent node containing mLeftNode and mRightNode */
|
||||
nsCOMPtr<nsIDOMNode> mParent;
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
|
||||
friend class TransactionFactory;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "SplitElementTxn.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "editor.h"
|
||||
|
||||
// note that aEditor is not refcounted
|
||||
SplitElementTxn::SplitElementTxn()
|
||||
|
@ -27,9 +26,11 @@ SplitElementTxn::SplitElementTxn()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult SplitElementTxn::Init(nsIDOMNode *aNode,
|
||||
nsresult SplitElementTxn::Init(nsIEditor *aEditor,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset)
|
||||
{
|
||||
mEditor = aEditor;
|
||||
mExistingRightNode = aNode;
|
||||
mOffset = aOffset;
|
||||
return NS_OK;
|
||||
|
@ -52,7 +53,7 @@ nsresult SplitElementTxn::Do(void)
|
|||
// insert the new node
|
||||
if ((NS_SUCCEEDED(result)) && (mParent))
|
||||
{
|
||||
result = nsEditor::SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -61,13 +62,13 @@ nsresult SplitElementTxn::Do(void)
|
|||
nsresult SplitElementTxn::Undo(void)
|
||||
{
|
||||
// this assumes Do inserted the new node in front of the prior existing node
|
||||
nsresult result = nsEditor::JoinNodes(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
|
||||
nsresult result = mEditor->JoinNodes(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult SplitElementTxn::Redo(void)
|
||||
{
|
||||
nsresult result = nsEditor::SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
nsresult result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "EditTxn.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEditor.h"
|
||||
|
||||
#define SPLIT_ELEMENT_TXN_IID \
|
||||
{/* 690c6290-ac48-11d2-86d8-000064657374 */ \
|
||||
|
@ -36,7 +37,8 @@ class SplitElementTxn : public EditTxn
|
|||
{
|
||||
public:
|
||||
|
||||
virtual nsresult Init (nsIDOMNode *aNode,
|
||||
virtual nsresult Init (nsIEditor *aEditor,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset);
|
||||
protected:
|
||||
SplitElementTxn();
|
||||
|
@ -74,6 +76,7 @@ protected:
|
|||
|
||||
/** the parent shared by mExistingRightNode and mNewLeftNode */
|
||||
nsCOMPtr<nsIDOMNode> mParent;
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
|
||||
friend class TransactionFactory;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsISupports.h"
|
||||
|
||||
class nsIDOMElement;
|
||||
class nsIDOMNode;
|
||||
class nsITransaction;
|
||||
|
||||
/*
|
||||
|
@ -60,29 +61,42 @@ public:
|
|||
|
||||
/**
|
||||
* Init tells is to tell the implementation of nsIEditor to begin its services
|
||||
* @param aDomInterface The dom interface being observed
|
||||
* @param aDomInterface The dom interface being observed
|
||||
* @param aPresShell TEMP: The presentation shell displaying the document
|
||||
* once events can tell us from what pres shell they originated,
|
||||
* this will no longer be necessary and the editor will no longer be
|
||||
* linked to a single pres shell.
|
||||
*/
|
||||
virtual nsresult Init(nsIDOMDocument *aDomInterface,
|
||||
nsIPresShell *aPresShell) = 0;
|
||||
|
||||
/**
|
||||
* GetDomInterface() WILL NOT RETURN AN ADDREFFED POINTER
|
||||
* return the DOM Document this editor is associated with
|
||||
*
|
||||
* @param aDomInterface The dom interface being observed
|
||||
* @param aDoc [OUT] the dom interface being observed, refcounted
|
||||
*/
|
||||
virtual nsresult GetDomInterface(nsIDOMDocument **)=0;
|
||||
virtual nsresult GetDocument(nsIDOMDocument **aDoc)=0;
|
||||
|
||||
/**
|
||||
* SetProperties() sets the properties of the current selection
|
||||
* SetProperties() sets the aggregate properties on the current selection
|
||||
*
|
||||
* @param aProperty An enum that lists the various properties that can be applied, bold, ect.
|
||||
* @see Properties
|
||||
* NOTE: this is an experimental interface. Since it's really just a shortcut for
|
||||
* the caller setting a set of attributes on a set of nodes, this method may be removed.
|
||||
* If it's more than just a convenience method (ie, it has logic about what objects in a selection get
|
||||
* which attributes) that's a whole other story.
|
||||
*/
|
||||
virtual nsresult SetProperties(Properties aProperties)=0;
|
||||
|
||||
/**
|
||||
* SetProperties() sets the properties of the current selection
|
||||
* GetProperties() gets the aggregate properties of the current selection.
|
||||
* All object in the current selection are scanned and their attributes are
|
||||
* represented in a list of Property object.
|
||||
*
|
||||
* @param aProperty An enum that will recieve the various properties that can be applied from the current selection.
|
||||
* @see nsIEditor::Properties
|
||||
* NOTE: this method is experimental, expect it to change.
|
||||
*/
|
||||
virtual nsresult GetProperties(Properties **aProperties)=0;
|
||||
|
||||
|
@ -122,12 +136,69 @@ public:
|
|||
virtual nsresult RemoveAttribute(nsIDOMElement * aElement,
|
||||
const nsString& aAttribute)=0;
|
||||
|
||||
/**
|
||||
* InsertString() Inserts a string at the current location
|
||||
*
|
||||
* @param aString An nsString that is the string to be inserted
|
||||
/**
|
||||
* CreateElement instantiates a new element of type aTag and inserts it into aParent at aPosition.
|
||||
* @param aTag The type of object to create
|
||||
* @param aParent The node to insert the new object into
|
||||
* @param aPosition The place in aParent to insert the new node
|
||||
*/
|
||||
virtual nsresult InsertString(nsString *aString)=0;
|
||||
virtual nsresult CreateElement(const nsString& aTag,
|
||||
nsIDOMNode * aParent,
|
||||
PRInt32 aPosition)=0;
|
||||
|
||||
/**
|
||||
* DeleteElement removes aChild from aParent.
|
||||
* If aChild is not a child of aParent, nothing is done and an error is returned.
|
||||
* @param aChild The node to delete
|
||||
* @param aParent The parent of aChild
|
||||
*/
|
||||
virtual nsresult DeleteElement(nsIDOMNode * aParent,
|
||||
nsIDOMNode * aChild)=0;
|
||||
|
||||
/**
|
||||
* DeleteSelection removes all nodes in the current selection.
|
||||
* @param aDir if eLTR, delete to the right (for example, the DEL key)
|
||||
* if eRTL, delete to the left (for example, the BACKSPACE key)
|
||||
*/
|
||||
virtual nsresult DeleteSelection(nsIEditor::Direction aDir)=0;
|
||||
|
||||
/**
|
||||
* SplitNode() creates a new node identical to an existing node, and split the contents between the two nodes
|
||||
* @param aExistingRightNode the node to split. It will become the new node's next sibling.
|
||||
* @param aOffset the offset of aExistingRightNode's content|children to do the split at
|
||||
* @param aNewLeftNode [OUT] the new node resulting from the split, becomes aExistingRightNode's previous sibling.
|
||||
* @param aParent the parent of aExistingRightNode
|
||||
*/
|
||||
virtual nsresult SplitNode(nsIDOMNode * aExistingRightNode,
|
||||
PRInt32 aOffset,
|
||||
nsIDOMNode * aNewLeftNode,
|
||||
nsIDOMNode * aParent)=0;
|
||||
|
||||
/**
|
||||
* JoinNodes() takes 2 nodes and merge their content|children.
|
||||
* @param aNodeToKeep The node that will remain after the join.
|
||||
* @param aNodeToJoin The node that will be joined with aNodeToKeep.
|
||||
* There is no requirement that the two nodes be of the same type.
|
||||
* @param aParent The parent of aExistingRightNode
|
||||
* @param aNodeToKeepIsFirst if PR_TRUE, the contents|children of aNodeToKeep come before the
|
||||
* contents|children of aNodeToJoin, otherwise their positions are switched.
|
||||
*/
|
||||
virtual nsresult JoinNodes(nsIDOMNode *aNodeToKeep,
|
||||
nsIDOMNode *aNodeToJoin,
|
||||
nsIDOMNode *aParent,
|
||||
PRBool aNodeToKeepIsFirst)=0;
|
||||
|
||||
|
||||
/**
|
||||
* InsertText() Inserts a string at the current location, given by the selection.
|
||||
* If the selection is not collapsed, the selection is deleted and the insertion
|
||||
* takes place at the resulting collapsed selection.
|
||||
*
|
||||
* NOTE: what happens if the string contains a CR?
|
||||
*
|
||||
* @param aString the string to be inserted
|
||||
*/
|
||||
virtual nsresult InsertText(const nsString& aStringToInsert)=0;
|
||||
|
||||
/**
|
||||
* Commit(PRBool aCtrlKey) is a catch all method. It may be depricated later.
|
||||
|
@ -137,8 +208,15 @@ public:
|
|||
*/
|
||||
virtual nsresult Commit(PRBool aCtrlKey)=0;
|
||||
|
||||
/** Do fires a transaction. It is provided here so clients can create their own transactions.
|
||||
* Clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
/** turn the undo system on or off
|
||||
* @param aEnable if PR_TRUE, the undo system is turned on if it is available
|
||||
* if PR_FALSE the undo system is turned off if it was previously on
|
||||
* @return if aEnable is PR_TRUE, returns NS_OK if the undo system could be initialized properly
|
||||
* if aEnable is PR_FALSE, returns NS_OK.
|
||||
*/
|
||||
virtual nsresult EnableUndo(PRBool aEnable)=0;
|
||||
|
||||
/** Do() fires a transaction. It is provided here so clients can create their own transactions.
|
||||
* If a transaction manager is present, it is used.
|
||||
* Otherwise, the transaction is just executed directly.
|
||||
*
|
||||
|
@ -146,32 +224,47 @@ public:
|
|||
*/
|
||||
virtual nsresult Do(nsITransaction *aTxn)=0;
|
||||
|
||||
/** Undo reverses the effects of the last ExecuteTransaction operation
|
||||
/** Undo reverses the effects of the last Do operation, if Undo is enabled in the editor.
|
||||
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is told to undo and the result of
|
||||
* that undo is returned.
|
||||
* Otherwise, the Undo request is ignored.
|
||||
* Otherwise, the Undo request is ignored and an error NS_ERROR_NOT_AVAILABLE is returned.
|
||||
*
|
||||
*/
|
||||
virtual nsresult Undo(PRUint32 aCount)=0;
|
||||
|
||||
/** returns state information about the undo system.
|
||||
* @param aIsEnabled [OUT] PR_TRUE if undo is enabled
|
||||
* @param aCanUndo [OUT] PR_TRUE if at least one transaction is currently ready to be undone.
|
||||
*/
|
||||
virtual nsresult CanUndo(PRBool &aIsEnabled, PRBool &aCanUndo)=0;
|
||||
|
||||
/** Redo reverses the effects of the last Undo operation
|
||||
* It is provided here so clients need no knowledge of whether the editor has a transaction manager or not.
|
||||
* If a transaction manager is present, it is told to redo and the result of
|
||||
* that redo is returned.
|
||||
* Otherwise, the Redo request is ignored.
|
||||
* If a transaction manager is present, it is told to redo and the result of the previously undone
|
||||
* transaction is reapplied to the document.
|
||||
* If no transaction is available for Redo, or if the document has no transaction manager,
|
||||
* the Redo request is ignored and an error NS_ERROR_NOT_AVAILABLE is returned.
|
||||
*
|
||||
*/
|
||||
virtual nsresult Redo(PRUint32 aCount)=0;
|
||||
|
||||
/** returns state information about the redo system.
|
||||
* @param aIsEnabled [OUT] PR_TRUE if redo is enabled
|
||||
* @param aCanRedo [OUT] PR_TRUE if at least one transaction is currently ready to be redone.
|
||||
*/
|
||||
virtual nsresult CanRedo(PRBool &aIsEnabled, PRBool &aCanRedo)=0;
|
||||
|
||||
/** BeginUpdate is a signal from the caller to the editor that the caller will execute multiple updates
|
||||
* to the content tree that should be treated in the most efficient way possible.
|
||||
* All transactions executed between a call to BeginUpdate and EndUpdate will be undoable as
|
||||
* an atomic action.
|
||||
* EndUpdate must be called after BeginUpdate.
|
||||
* Calls to BeginUpdate can be nested, as long as EndUpdate is called once per BeginUpdate.
|
||||
*/
|
||||
virtual nsresult BeginUpdate()=0;
|
||||
|
||||
/** EndUpdate is a signal from the caller to the editor that the caller is finished updating the content model.
|
||||
/** EndUpdate is a signal to the editor that the caller is finished updating the content model.
|
||||
* BeginUpdate must be called before EndUpdate is called.
|
||||
* Calls to BeginUpdate can be nested, as long as EndUpdate is called once per BeginUpdate.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче