diff --git a/mozilla/editor/base/ChangeAttributeTxn.cpp b/mozilla/editor/base/ChangeAttributeTxn.cpp index 2cc764398f0..234e9031c84 100644 --- a/mozilla/editor/base/ChangeAttributeTxn.cpp +++ b/mozilla/editor/base/ChangeAttributeTxn.cpp @@ -94,6 +94,8 @@ nsresult ChangeAttributeTxn::GetIsTransient(PRBool *aIsTransient) nsresult ChangeAttributeTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/base/CreateElementTxn.cpp b/mozilla/editor/base/CreateElementTxn.cpp index fd42eec3f9f..c62adf8b423 100644 --- a/mozilla/editor/base/CreateElementTxn.cpp +++ b/mozilla/editor/base/CreateElementTxn.cpp @@ -110,6 +110,8 @@ nsresult CreateElementTxn::GetIsTransient(PRBool *aIsTransient) nsresult CreateElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/base/DeleteElementTxn.cpp b/mozilla/editor/base/DeleteElementTxn.cpp new file mode 100644 index 00000000000..85ca3462ebb --- /dev/null +++ b/mozilla/editor/base/DeleteElementTxn.cpp @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "DeleteElementTxn.h" +#include "editor.h" +#include "nsIDOMDocument.h" +#include "nsIDOMElement.h" + +// note that aEditor is not refcounted +DeleteElementTxn::DeleteElementTxn(nsEditor * aEditor, + nsIDOMDocument *aDoc, + nsIDOMNode * aElement, + nsIDOMNode * aParent) + : EditTxn(aEditor) +{ + mDoc = aDoc; + NS_ADDREF(mDoc); + mElement = aElement; + NS_ADDREF(mElement); + mParent = aParent; + NS_ADDREF(mParent); +} + +DeleteElementTxn::~DeleteElementTxn() +{ + NS_IF_RELEASE(mDoc); + NS_IF_RELEASE(mParent); + NS_IF_RELEASE(mElement); +} + +nsresult DeleteElementTxn::Do(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; +#ifdef NS_DEBUG + nsresult testResult; + nsCOMPtr 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() "); +#endif + + // remember which child mElement was (by remembering which child was next) + nsresult result = mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode + + nsCOMPtr resultNode; + result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::Undo(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr resultNode; + nsresult result = mParent->InsertBefore(mElement, mRefNode, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::Redo(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr resultNode; + nsresult result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::GetIsTransient(PRBool *aIsTransient) +{ + if (nsnull!=aIsTransient) + *aIsTransient = PR_FALSE; + return NS_OK; +} + +nsresult DeleteElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) +{ + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + return NS_OK; +} + +nsresult DeleteElementTxn::Write(nsIOutputStream *aOutputStream) +{ + return NS_OK; +} + +nsresult DeleteElementTxn::GetUndoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Insert Element: "; + } + return NS_OK; +} + +nsresult DeleteElementTxn::GetRedoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Remove Element: "; + } + return NS_OK; +} diff --git a/mozilla/editor/base/DeleteElementTxn.h b/mozilla/editor/base/DeleteElementTxn.h new file mode 100644 index 00000000000..dce2b04dcda --- /dev/null +++ b/mozilla/editor/base/DeleteElementTxn.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DeleteElementTxn_h__ +#define DeleteElementTxn_h__ + +#include "EditTxn.h" +#include "nsIDOMNode.h" +#include "nsCOMPtr.h" + +class nsIDOMDocument; +class nsIDOMElement; + +/** + * A transaction that deletes a single element + */ +class DeleteElementTxn : public EditTxn +{ +public: + + DeleteElementTxn(nsEditor *aEditor, + nsIDOMDocument *aDoc, + nsIDOMNode *aElement, + nsIDOMNode *aParent); + + virtual ~DeleteElementTxn(); + + virtual nsresult Do(void); + + virtual nsresult Undo(void); + + virtual nsresult Redo(void); + + virtual nsresult GetIsTransient(PRBool *aIsTransient); + + virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction); + + virtual nsresult Write(nsIOutputStream *aOutputStream); + + virtual nsresult GetUndoString(nsString **aString); + + virtual nsresult GetRedoString(nsString **aString); + +protected: + + /** the document into which the new node will be inserted */ + nsIDOMDocument *mDoc; + + /** the element to delete */ + nsIDOMNode *mElement; + + /** the node into which the new node will be inserted */ + nsIDOMNode *mParent; + + /** the index in mParent for the new node */ + PRUint32 mOffsetInParent; + + /** the node we will insert mNewNode before. We compute this ourselves. */ + nsCOMPtr mRefNode; + +}; + +#endif diff --git a/mozilla/editor/base/DeleteRangeTxn.cpp b/mozilla/editor/base/DeleteRangeTxn.cpp new file mode 100644 index 00000000000..84a1b397e4d --- /dev/null +++ b/mozilla/editor/base/DeleteRangeTxn.cpp @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "DeleteRangeTxn.h" +#include "editor.h" +#include "nsIDOMRange.h" + +// note that aEditor is not refcounted +DeleteRangeTxn::DeleteRangeTxn(nsEditor *aEditor, + nsIDOMRange *aRange) + : EditTxn(aEditor) +{ + aRange->GetStartParent(getter_AddRefs(mStartParent)); + aRange->GetEndParent(getter_AddRefs(mEndParent)); + aRange->GetStartOffset(&mStartOffset); + aRange->GetEndOffset(&mEndOffset); +} + +DeleteRangeTxn::~DeleteRangeTxn() +{ +} + +nsresult DeleteRangeTxn::Do(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::Undo(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::Redo(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::GetIsTransient(PRBool *aIsTransient) +{ + if (nsnull!=aIsTransient) + *aIsTransient = PR_FALSE; + return NS_OK; +} + +nsresult DeleteRangeTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) +{ + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + return NS_OK; +} + +nsresult DeleteRangeTxn::Write(nsIOutputStream *aOutputStream) +{ + return NS_OK; +} + +nsresult DeleteRangeTxn::GetUndoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Insert Range: "; + } + return NS_OK; +} + +nsresult DeleteRangeTxn::GetRedoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Remove Range: "; + } + return NS_OK; +} diff --git a/mozilla/editor/base/DeleteRangeTxn.h b/mozilla/editor/base/DeleteRangeTxn.h new file mode 100644 index 00000000000..675049f550a --- /dev/null +++ b/mozilla/editor/base/DeleteRangeTxn.h @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DeleteRangeTxn_h__ +#define DeleteRangeTxn_h__ + +#include "EditTxn.h" +#include "nsIDOMNode.h" +#include "nsCOMPtr.h" + +class nsIDOMDocument; +class nsIDOMRange; + +/** + * A transaction that deletes an entire range in the content tree + */ +class DeleteRangeTxn : public EditTxn +{ +public: + + DeleteRangeTxn(nsEditor *aEditor, + nsIDOMRange *aRange); + + virtual ~DeleteRangeTxn(); + + virtual nsresult Do(void); + + virtual nsresult Undo(void); + + virtual nsresult Redo(void); + + virtual nsresult GetIsTransient(PRBool *aIsTransient); + + virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction); + + virtual nsresult Write(nsIOutputStream *aOutputStream); + + virtual nsresult GetUndoString(nsString **aString); + + virtual nsresult GetRedoString(nsString **aString); + +protected: + + /** p1 in the range */ + nsCOMPtr mStartParent; + + /** p1 offset */ + PRInt32 mStartOffset; + + /** p2 in the range */ + nsCOMPtr mEndParent; + + /** p2 offset */ + PRInt32 mEndOffset; + +}; + +#endif diff --git a/mozilla/editor/base/DeleteTextTxn.cpp b/mozilla/editor/base/DeleteTextTxn.cpp index 1259ea9e233..09df4b2b0ab 100644 --- a/mozilla/editor/base/DeleteTextTxn.cpp +++ b/mozilla/editor/base/DeleteTextTxn.cpp @@ -55,6 +55,8 @@ nsresult DeleteTextTxn::GetIsTransient(PRBool *aIsTransient) nsresult DeleteTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/base/InsertTextTxn.cpp b/mozilla/editor/base/InsertTextTxn.cpp index 04e18841f4b..7f19c12796b 100644 --- a/mozilla/editor/base/InsertTextTxn.cpp +++ b/mozilla/editor/base/InsertTextTxn.cpp @@ -20,6 +20,8 @@ #include "editor.h" #include "nsIDOMCharacterData.h" +static NS_DEFINE_IID(kInsertTextTxnIID, INSERTTEXTTXN_IID); + // note that aEditor is not refcounted InsertTextTxn::InsertTextTxn(nsEditor *aEditor, nsIDOMCharacterData *aElement, @@ -52,6 +54,23 @@ nsresult InsertTextTxn::GetIsTransient(PRBool *aIsTransient) nsresult InsertTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + // set out param default value + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + + if ((nsnull!=aDidMerge) && (nsnull!=aTransaction)) + { + // if aTransaction isa InsertTextTxn, absorb it + nsCOMPtr otherTxn; + nsresult result = aTransaction->QueryInterface(kInsertTextTxnIID, getter_AddRefs(otherTxn)); + if (NS_SUCCEEDED(result) && (otherTxn)) + { + nsString otherData; + otherTxn->GetData(otherData); + mStringToInsert += otherData; + } + *aDidMerge = PR_TRUE; + } return NS_OK; } @@ -79,3 +98,27 @@ nsresult InsertTextTxn::GetRedoString(nsString **aString) } return NS_OK; } + +/* ============= nsISupports implementation ====================== */ + +nsresult +InsertTextTxn::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kInsertTextTxnIID)) { + *aInstancePtr = (void*)(InsertTextTxn*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + return (EditTxn::QueryInterface(aIID, aInstancePtr)); +} + +/* ============ protected methods ================== */ + +nsresult InsertTextTxn::GetData(nsString& aResult) +{ + aResult = mStringToInsert; + return NS_OK; +} diff --git a/mozilla/editor/base/InsertTextTxn.h b/mozilla/editor/base/InsertTextTxn.h index 7430e25b7b5..4006babdb0f 100644 --- a/mozilla/editor/base/InsertTextTxn.h +++ b/mozilla/editor/base/InsertTextTxn.h @@ -21,6 +21,11 @@ #include "EditTxn.h" +#define INSERTTEXTTXN_IID \ +{/* 93276f00-ab2c-11d2-8f4b-006008159b0c*/ \ +0x93276f00, 0xab2c, 0x11d2, \ +{0x8f, 0xb4, 0x0, 0x60, 0x8, 0x15, 0x9b, 0xc} } + class nsIDOMCharacterData; /** @@ -50,6 +55,16 @@ public: virtual nsresult GetRedoString(nsString **aString); +// nsISupports declarations + + // override QueryInterface to handle InsertTextTxn request + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + + static const nsIID& IID() { static nsIID iid = INSERTTEXTTXN_IID; return iid; } + + + virtual nsresult GetData(nsString& aResult); + protected: /** the text element to operate upon */ diff --git a/mozilla/editor/base/Makefile.in b/mozilla/editor/base/Makefile.in index 1d1b2e1f80a..e962b20f862 100644 --- a/mozilla/editor/base/Makefile.in +++ b/mozilla/editor/base/Makefile.in @@ -33,7 +33,9 @@ CPPSRCS = \ InsertTextTxn.cpp \ DeleteTextTxn.cpp \ CreateElementTxn.cpp \ - SplitElementTxn.cpp \ + DeleteElementTxn.cpp \ + DeleteRangeTxn.cpp \ + SplitElementTxn.cpp \ $(NULL) MODULE = editor diff --git a/mozilla/editor/base/SplitElementTxn.cpp b/mozilla/editor/base/SplitElementTxn.cpp index 26523978d22..2134cc5375c 100644 --- a/mozilla/editor/base/SplitElementTxn.cpp +++ b/mozilla/editor/base/SplitElementTxn.cpp @@ -82,6 +82,8 @@ nsresult SplitElementTxn::GetIsTransient(PRBool *aIsTransient) nsresult SplitElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/base/editor.cpp b/mozilla/editor/base/editor.cpp index 5402e223188..6d789f4f43b 100644 --- a/mozilla/editor/base/editor.cpp +++ b/mozilla/editor/base/editor.cpp @@ -25,6 +25,7 @@ #include "nsIDOMAttr.h" #include "nsIDOMNode.h" #include "nsIDOMNodeList.h" +#include "nsIDOMRange.h" #include "nsIDocument.h" #include "nsRepository.h" #include "nsIServiceManager.h" @@ -32,13 +33,17 @@ #include "nsEditorCID.h" #include "nsTransactionManagerCID.h" #include "nsITransactionManager.h" +#include "nsIPresShell.h" +#include "nsISelection.h" #include "nsIAtom.h" // transactions the editor knows how to build #include "ChangeAttributeTxn.h" #include "CreateElementTxn.h" +#include "DeleteElementTxn.h" #include "InsertTextTxn.h" #include "DeleteTextTxn.h" +#include "DeleteRangeTxn.h" static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); @@ -47,6 +52,7 @@ 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(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID); @@ -153,6 +159,9 @@ nsEditor::nsEditor() nsEditor::~nsEditor() { + NS_IF_RELEASE(mPresShell); + NS_IF_RELEASE(mTxnMgr); + //the autopointers will clear themselves up. //but we need to also remove the listeners or we have a leak nsCOMPtr erP; @@ -207,12 +216,14 @@ nsEditor::GetDomInterface(nsIDOMDocument **aDomInterface) nsresult -nsEditor::Init(nsIDOMDocument *aDomInterface) +nsEditor::Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell) { - if (!aDomInterface) + if ((nsnull==aDomInterface) || (nsnull==aPresShell)) return NS_ERROR_NULL_POINTER; mDomInterfaceP = aDomInterface; + mPresShell = aPresShell; + NS_ADDREF(mPresShell); nsresult t_result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this); if (NS_OK != t_result) @@ -596,8 +607,31 @@ nsresult nsEditor::CreateElement(const nsString& aTag, { CreateElementTxn *txn = new CreateElementTxn(this, mDomInterfaceP, aTag, aParent, aPosition); if (nsnull!=txn) - result = ExecuteTransaction(txn); + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; } + else + result = NS_ERROR_INVALID_ARG; + + return result; +} + +nsresult nsEditor::DeleteElement(nsIDOMNode * aParent, + nsIDOMNode * aElement) +{ + nsresult result; + if ((nsnull != aParent) && (nsnull != aElement)) + { + DeleteElementTxn *txn = new DeleteElementTxn(this, mDomInterfaceP, aElement, aParent); + if (nsnull!=txn) + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; + } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -610,8 +644,13 @@ nsresult nsEditor::InsertText(nsIDOMCharacterData *aElement, { InsertTextTxn *txn = new InsertTextTxn(this, aElement, aOffset, aStringToInsert); if (nsnull!=txn) - result = ExecuteTransaction(txn); + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -619,13 +658,42 @@ nsresult nsEditor::DeleteText(nsIDOMCharacterData *aElement, PRUint32 aOffset, PRUint32 aLength) { - nsresult result; + nsresult result=NS_OK; if (nsnull != aElement) { DeleteTextTxn *txn = new DeleteTextTxn(this, aElement, aOffset, aLength); if (nsnull!=txn) - result = ExecuteTransaction(txn); + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; } + else + result = NS_ERROR_INVALID_ARG; + + return result; +} + +nsresult nsEditor::DeleteSelection() +{ + nsresult result; + nsISelection* selection; + result = mPresShell->GetSelection(&selection); + if ((NS_SUCCEEDED(result)) && (nsnull!=selection)) + { + nsCOMPtr range; + result = selection->QueryInterface(kIDOMRangeIID, getter_AddRefs(range)); + if ((NS_SUCCEEDED(result)) && (range)) + { + DeleteRangeTxn *txn = new DeleteRangeTxn(this, range); + if (nsnull!=txn) + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; + } + } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -673,8 +741,10 @@ nsEditor::SplitNode(nsIDOMNode * aNode, } } } - else result = NS_ERROR_NULL_POINTER; } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -730,7 +800,8 @@ nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep, } } else - result = NS_ERROR_NULL_POINTER; + result = NS_ERROR_INVALID_ARG; + return result; } diff --git a/mozilla/editor/base/editor.h b/mozilla/editor/base/editor.h index 3195e9000ef..44055cce9f0 100644 --- a/mozilla/editor/base/editor.h +++ b/mozilla/editor/base/editor.h @@ -27,7 +27,7 @@ //#include "nsISelection.h" class nsIDOMCharacterData; - +class nsIPresShell; //This is the monitor for the editor. PRMonitor *getEditorMonitor(); @@ -41,6 +41,7 @@ PRMonitor *getEditorMonitor(); class nsEditor : public nsIEditor { private: + nsIPresShell *mPresShell; nsCOMPtr mDomInterfaceP; nsCOMPtr mKeyListenerP; nsCOMPtr mMouseListenerP; @@ -64,7 +65,7 @@ public: /*interfaces for addref and release and queryinterface*/ NS_DECL_ISUPPORTS - virtual nsresult Init(nsIDOMDocument *aDomInterface); + virtual nsresult Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell); virtual nsresult GetDomInterface(nsIDOMDocument **aDomInterface); @@ -171,6 +172,11 @@ public: nsIDOMNode * aParent, PRInt32 aPosition); + nsresult DeleteElement(nsIDOMNode * aParent, + nsIDOMNode * aElement); + + nsresult DeleteSelection(); + nsresult InsertText(nsIDOMCharacterData *aElement, PRUint32 aOffset, const nsString& aStringToInsert); diff --git a/mozilla/editor/base/editorInterfaces.cpp b/mozilla/editor/base/editorInterfaces.cpp index eb0acceda1f..a9d5a1abfb9 100644 --- a/mozilla/editor/base/editorInterfaces.cpp +++ b/mozilla/editor/base/editorInterfaces.cpp @@ -138,33 +138,55 @@ nsEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent) switch(keyCode) { case nsIDOMEvent::VK_BACK: { - // XXX: for now, just grab the first text node - nsCOMPtr currentNode; - nsCOMPtr textNode; - nsCOMPtr text; - if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && - NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && - NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + if (PR_FALSE==ctrlKey) { - // XXX: for now, just append the text - PRUint32 offset; - text->GetLength(&offset); - nsresult result = mEditor->DeleteText(text, offset-1, 1); + // XXX: for now, just grab the first text node + nsCOMPtr currentNode; + nsCOMPtr textNode; + nsCOMPtr text; + if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && + NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && + NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + { + // XXX: for now, just append the text + PRUint32 offset; + text->GetLength(&offset); + nsresult result = mEditor->DeleteText(text, offset-1, 1); + } + } + else + { + mEditor->DeleteSelection(); } } break; case nsIDOMEvent::VK_DELETE: { - // XXX: for now, just grab the first text node - nsCOMPtr currentNode; - nsCOMPtr textNode; - nsCOMPtr text; - if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && - NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && - NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + if (PR_FALSE==ctrlKey) { - nsresult result = mEditor->DeleteText(text, 0, 1); + // XXX: for now, just grab the first text node + nsCOMPtr currentNode; + nsCOMPtr textNode; + nsCOMPtr text; + if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && + NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && + NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + { + nsresult result = mEditor->DeleteText(text, 0, 1); + } + } + else + { // XXX: delete the first P we find + nsString pTag("P"); + nsCOMPtr currentNode; + nsCOMPtr parentNode; + nsCOMPtr element; + if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, pTag, getter_AddRefs(currentNode)))) + { + currentNode->GetParentNode(getter_AddRefs(parentNode)); + nsresult result = mEditor->DeleteElement(parentNode, currentNode); + } } } break; diff --git a/mozilla/editor/base/makefile.win b/mozilla/editor/base/makefile.win index df301fd471b..0eb893bbaf5 100644 --- a/mozilla/editor/base/makefile.win +++ b/mozilla/editor/base/makefile.win @@ -21,27 +21,31 @@ IGNORE_MANIFEST=1 LIBRARY_NAME=ender CPPSRCS = \ - editor.cpp \ - editorInterfaces.cpp \ - nsEditFactory.cpp \ - EditTxn.cpp \ + editor.cpp \ + editorInterfaces.cpp \ + nsEditFactory.cpp \ + EditTxn.cpp \ ChangeAttributeTxn.cpp \ - InsertTextTxn.cpp \ - DeleteTextTxn.cpp \ - CreateElementTxn.cpp \ - SplitElementTxn.cpp \ + InsertTextTxn.cpp \ + DeleteTextTxn.cpp \ + CreateElementTxn.cpp \ + DeleteElementTxn.cpp \ + DeleteRangeTxn.cpp \ + SplitElementTxn.cpp \ $(NULL) CPP_OBJS = \ - .\$(OBJDIR)\editor.obj \ - .\$(OBJDIR)\nsEditFactory.obj \ + .\$(OBJDIR)\editor.obj \ + .\$(OBJDIR)\nsEditFactory.obj \ .\$(OBJDIR)\editorInterfaces.obj \ - .\$(OBJDIR)\EditTxn.obj \ - .\$(OBJDIR)\ChangeAttributeTxn.obj \ - .\$(OBJDIR)\InsertTextTxn.obj \ - .\$(OBJDIR)\DeleteTextTxn.obj \ - .\$(OBJDIR)\CreateElementTxn.obj \ - .\$(OBJDIR)\SplitElementTxn.obj \ + .\$(OBJDIR)\EditTxn.obj \ + .\$(OBJDIR)\ChangeAttributeTxn.obj \ + .\$(OBJDIR)\InsertTextTxn.obj \ + .\$(OBJDIR)\DeleteTextTxn.obj \ + .\$(OBJDIR)\CreateElementTxn.obj \ + .\$(OBJDIR)\DeleteElementTxn.obj \ + .\$(OBJDIR)\DeleteRangeTxn.obj \ + .\$(OBJDIR)\SplitElementTxn.obj \ $(NULL) MODULE=editor diff --git a/mozilla/editor/core/ChangeAttributeTxn.cpp b/mozilla/editor/core/ChangeAttributeTxn.cpp index 2cc764398f0..234e9031c84 100644 --- a/mozilla/editor/core/ChangeAttributeTxn.cpp +++ b/mozilla/editor/core/ChangeAttributeTxn.cpp @@ -94,6 +94,8 @@ nsresult ChangeAttributeTxn::GetIsTransient(PRBool *aIsTransient) nsresult ChangeAttributeTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/core/CreateElementTxn.cpp b/mozilla/editor/core/CreateElementTxn.cpp index fd42eec3f9f..c62adf8b423 100644 --- a/mozilla/editor/core/CreateElementTxn.cpp +++ b/mozilla/editor/core/CreateElementTxn.cpp @@ -110,6 +110,8 @@ nsresult CreateElementTxn::GetIsTransient(PRBool *aIsTransient) nsresult CreateElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/core/DeleteElementTxn.cpp b/mozilla/editor/core/DeleteElementTxn.cpp new file mode 100644 index 00000000000..85ca3462ebb --- /dev/null +++ b/mozilla/editor/core/DeleteElementTxn.cpp @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "DeleteElementTxn.h" +#include "editor.h" +#include "nsIDOMDocument.h" +#include "nsIDOMElement.h" + +// note that aEditor is not refcounted +DeleteElementTxn::DeleteElementTxn(nsEditor * aEditor, + nsIDOMDocument *aDoc, + nsIDOMNode * aElement, + nsIDOMNode * aParent) + : EditTxn(aEditor) +{ + mDoc = aDoc; + NS_ADDREF(mDoc); + mElement = aElement; + NS_ADDREF(mElement); + mParent = aParent; + NS_ADDREF(mParent); +} + +DeleteElementTxn::~DeleteElementTxn() +{ + NS_IF_RELEASE(mDoc); + NS_IF_RELEASE(mParent); + NS_IF_RELEASE(mElement); +} + +nsresult DeleteElementTxn::Do(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; +#ifdef NS_DEBUG + nsresult testResult; + nsCOMPtr 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() "); +#endif + + // remember which child mElement was (by remembering which child was next) + nsresult result = mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode + + nsCOMPtr resultNode; + result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::Undo(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr resultNode; + nsresult result = mParent->InsertBefore(mElement, mRefNode, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::Redo(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr resultNode; + nsresult result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::GetIsTransient(PRBool *aIsTransient) +{ + if (nsnull!=aIsTransient) + *aIsTransient = PR_FALSE; + return NS_OK; +} + +nsresult DeleteElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) +{ + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + return NS_OK; +} + +nsresult DeleteElementTxn::Write(nsIOutputStream *aOutputStream) +{ + return NS_OK; +} + +nsresult DeleteElementTxn::GetUndoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Insert Element: "; + } + return NS_OK; +} + +nsresult DeleteElementTxn::GetRedoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Remove Element: "; + } + return NS_OK; +} diff --git a/mozilla/editor/core/DeleteElementTxn.h b/mozilla/editor/core/DeleteElementTxn.h new file mode 100644 index 00000000000..dce2b04dcda --- /dev/null +++ b/mozilla/editor/core/DeleteElementTxn.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DeleteElementTxn_h__ +#define DeleteElementTxn_h__ + +#include "EditTxn.h" +#include "nsIDOMNode.h" +#include "nsCOMPtr.h" + +class nsIDOMDocument; +class nsIDOMElement; + +/** + * A transaction that deletes a single element + */ +class DeleteElementTxn : public EditTxn +{ +public: + + DeleteElementTxn(nsEditor *aEditor, + nsIDOMDocument *aDoc, + nsIDOMNode *aElement, + nsIDOMNode *aParent); + + virtual ~DeleteElementTxn(); + + virtual nsresult Do(void); + + virtual nsresult Undo(void); + + virtual nsresult Redo(void); + + virtual nsresult GetIsTransient(PRBool *aIsTransient); + + virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction); + + virtual nsresult Write(nsIOutputStream *aOutputStream); + + virtual nsresult GetUndoString(nsString **aString); + + virtual nsresult GetRedoString(nsString **aString); + +protected: + + /** the document into which the new node will be inserted */ + nsIDOMDocument *mDoc; + + /** the element to delete */ + nsIDOMNode *mElement; + + /** the node into which the new node will be inserted */ + nsIDOMNode *mParent; + + /** the index in mParent for the new node */ + PRUint32 mOffsetInParent; + + /** the node we will insert mNewNode before. We compute this ourselves. */ + nsCOMPtr mRefNode; + +}; + +#endif diff --git a/mozilla/editor/core/DeleteRangeTxn.cpp b/mozilla/editor/core/DeleteRangeTxn.cpp new file mode 100644 index 00000000000..84a1b397e4d --- /dev/null +++ b/mozilla/editor/core/DeleteRangeTxn.cpp @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "DeleteRangeTxn.h" +#include "editor.h" +#include "nsIDOMRange.h" + +// note that aEditor is not refcounted +DeleteRangeTxn::DeleteRangeTxn(nsEditor *aEditor, + nsIDOMRange *aRange) + : EditTxn(aEditor) +{ + aRange->GetStartParent(getter_AddRefs(mStartParent)); + aRange->GetEndParent(getter_AddRefs(mEndParent)); + aRange->GetStartOffset(&mStartOffset); + aRange->GetEndOffset(&mEndOffset); +} + +DeleteRangeTxn::~DeleteRangeTxn() +{ +} + +nsresult DeleteRangeTxn::Do(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::Undo(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::Redo(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::GetIsTransient(PRBool *aIsTransient) +{ + if (nsnull!=aIsTransient) + *aIsTransient = PR_FALSE; + return NS_OK; +} + +nsresult DeleteRangeTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) +{ + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + return NS_OK; +} + +nsresult DeleteRangeTxn::Write(nsIOutputStream *aOutputStream) +{ + return NS_OK; +} + +nsresult DeleteRangeTxn::GetUndoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Insert Range: "; + } + return NS_OK; +} + +nsresult DeleteRangeTxn::GetRedoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Remove Range: "; + } + return NS_OK; +} diff --git a/mozilla/editor/core/DeleteRangeTxn.h b/mozilla/editor/core/DeleteRangeTxn.h new file mode 100644 index 00000000000..675049f550a --- /dev/null +++ b/mozilla/editor/core/DeleteRangeTxn.h @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DeleteRangeTxn_h__ +#define DeleteRangeTxn_h__ + +#include "EditTxn.h" +#include "nsIDOMNode.h" +#include "nsCOMPtr.h" + +class nsIDOMDocument; +class nsIDOMRange; + +/** + * A transaction that deletes an entire range in the content tree + */ +class DeleteRangeTxn : public EditTxn +{ +public: + + DeleteRangeTxn(nsEditor *aEditor, + nsIDOMRange *aRange); + + virtual ~DeleteRangeTxn(); + + virtual nsresult Do(void); + + virtual nsresult Undo(void); + + virtual nsresult Redo(void); + + virtual nsresult GetIsTransient(PRBool *aIsTransient); + + virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction); + + virtual nsresult Write(nsIOutputStream *aOutputStream); + + virtual nsresult GetUndoString(nsString **aString); + + virtual nsresult GetRedoString(nsString **aString); + +protected: + + /** p1 in the range */ + nsCOMPtr mStartParent; + + /** p1 offset */ + PRInt32 mStartOffset; + + /** p2 in the range */ + nsCOMPtr mEndParent; + + /** p2 offset */ + PRInt32 mEndOffset; + +}; + +#endif diff --git a/mozilla/editor/core/DeleteTextTxn.cpp b/mozilla/editor/core/DeleteTextTxn.cpp index 1259ea9e233..09df4b2b0ab 100644 --- a/mozilla/editor/core/DeleteTextTxn.cpp +++ b/mozilla/editor/core/DeleteTextTxn.cpp @@ -55,6 +55,8 @@ nsresult DeleteTextTxn::GetIsTransient(PRBool *aIsTransient) nsresult DeleteTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/core/InsertTextTxn.cpp b/mozilla/editor/core/InsertTextTxn.cpp index 04e18841f4b..7f19c12796b 100644 --- a/mozilla/editor/core/InsertTextTxn.cpp +++ b/mozilla/editor/core/InsertTextTxn.cpp @@ -20,6 +20,8 @@ #include "editor.h" #include "nsIDOMCharacterData.h" +static NS_DEFINE_IID(kInsertTextTxnIID, INSERTTEXTTXN_IID); + // note that aEditor is not refcounted InsertTextTxn::InsertTextTxn(nsEditor *aEditor, nsIDOMCharacterData *aElement, @@ -52,6 +54,23 @@ nsresult InsertTextTxn::GetIsTransient(PRBool *aIsTransient) nsresult InsertTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + // set out param default value + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + + if ((nsnull!=aDidMerge) && (nsnull!=aTransaction)) + { + // if aTransaction isa InsertTextTxn, absorb it + nsCOMPtr otherTxn; + nsresult result = aTransaction->QueryInterface(kInsertTextTxnIID, getter_AddRefs(otherTxn)); + if (NS_SUCCEEDED(result) && (otherTxn)) + { + nsString otherData; + otherTxn->GetData(otherData); + mStringToInsert += otherData; + } + *aDidMerge = PR_TRUE; + } return NS_OK; } @@ -79,3 +98,27 @@ nsresult InsertTextTxn::GetRedoString(nsString **aString) } return NS_OK; } + +/* ============= nsISupports implementation ====================== */ + +nsresult +InsertTextTxn::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kInsertTextTxnIID)) { + *aInstancePtr = (void*)(InsertTextTxn*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + return (EditTxn::QueryInterface(aIID, aInstancePtr)); +} + +/* ============ protected methods ================== */ + +nsresult InsertTextTxn::GetData(nsString& aResult) +{ + aResult = mStringToInsert; + return NS_OK; +} diff --git a/mozilla/editor/core/InsertTextTxn.h b/mozilla/editor/core/InsertTextTxn.h index 7430e25b7b5..4006babdb0f 100644 --- a/mozilla/editor/core/InsertTextTxn.h +++ b/mozilla/editor/core/InsertTextTxn.h @@ -21,6 +21,11 @@ #include "EditTxn.h" +#define INSERTTEXTTXN_IID \ +{/* 93276f00-ab2c-11d2-8f4b-006008159b0c*/ \ +0x93276f00, 0xab2c, 0x11d2, \ +{0x8f, 0xb4, 0x0, 0x60, 0x8, 0x15, 0x9b, 0xc} } + class nsIDOMCharacterData; /** @@ -50,6 +55,16 @@ public: virtual nsresult GetRedoString(nsString **aString); +// nsISupports declarations + + // override QueryInterface to handle InsertTextTxn request + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + + static const nsIID& IID() { static nsIID iid = INSERTTEXTTXN_IID; return iid; } + + + virtual nsresult GetData(nsString& aResult); + protected: /** the text element to operate upon */ diff --git a/mozilla/editor/core/Makefile.in b/mozilla/editor/core/Makefile.in index 1d1b2e1f80a..e962b20f862 100644 --- a/mozilla/editor/core/Makefile.in +++ b/mozilla/editor/core/Makefile.in @@ -33,7 +33,9 @@ CPPSRCS = \ InsertTextTxn.cpp \ DeleteTextTxn.cpp \ CreateElementTxn.cpp \ - SplitElementTxn.cpp \ + DeleteElementTxn.cpp \ + DeleteRangeTxn.cpp \ + SplitElementTxn.cpp \ $(NULL) MODULE = editor diff --git a/mozilla/editor/core/SplitElementTxn.cpp b/mozilla/editor/core/SplitElementTxn.cpp index 26523978d22..2134cc5375c 100644 --- a/mozilla/editor/core/SplitElementTxn.cpp +++ b/mozilla/editor/core/SplitElementTxn.cpp @@ -82,6 +82,8 @@ nsresult SplitElementTxn::GetIsTransient(PRBool *aIsTransient) nsresult SplitElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/core/editor.cpp b/mozilla/editor/core/editor.cpp index 5402e223188..6d789f4f43b 100644 --- a/mozilla/editor/core/editor.cpp +++ b/mozilla/editor/core/editor.cpp @@ -25,6 +25,7 @@ #include "nsIDOMAttr.h" #include "nsIDOMNode.h" #include "nsIDOMNodeList.h" +#include "nsIDOMRange.h" #include "nsIDocument.h" #include "nsRepository.h" #include "nsIServiceManager.h" @@ -32,13 +33,17 @@ #include "nsEditorCID.h" #include "nsTransactionManagerCID.h" #include "nsITransactionManager.h" +#include "nsIPresShell.h" +#include "nsISelection.h" #include "nsIAtom.h" // transactions the editor knows how to build #include "ChangeAttributeTxn.h" #include "CreateElementTxn.h" +#include "DeleteElementTxn.h" #include "InsertTextTxn.h" #include "DeleteTextTxn.h" +#include "DeleteRangeTxn.h" static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); @@ -47,6 +52,7 @@ 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(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID); @@ -153,6 +159,9 @@ nsEditor::nsEditor() nsEditor::~nsEditor() { + NS_IF_RELEASE(mPresShell); + NS_IF_RELEASE(mTxnMgr); + //the autopointers will clear themselves up. //but we need to also remove the listeners or we have a leak nsCOMPtr erP; @@ -207,12 +216,14 @@ nsEditor::GetDomInterface(nsIDOMDocument **aDomInterface) nsresult -nsEditor::Init(nsIDOMDocument *aDomInterface) +nsEditor::Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell) { - if (!aDomInterface) + if ((nsnull==aDomInterface) || (nsnull==aPresShell)) return NS_ERROR_NULL_POINTER; mDomInterfaceP = aDomInterface; + mPresShell = aPresShell; + NS_ADDREF(mPresShell); nsresult t_result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this); if (NS_OK != t_result) @@ -596,8 +607,31 @@ nsresult nsEditor::CreateElement(const nsString& aTag, { CreateElementTxn *txn = new CreateElementTxn(this, mDomInterfaceP, aTag, aParent, aPosition); if (nsnull!=txn) - result = ExecuteTransaction(txn); + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; } + else + result = NS_ERROR_INVALID_ARG; + + return result; +} + +nsresult nsEditor::DeleteElement(nsIDOMNode * aParent, + nsIDOMNode * aElement) +{ + nsresult result; + if ((nsnull != aParent) && (nsnull != aElement)) + { + DeleteElementTxn *txn = new DeleteElementTxn(this, mDomInterfaceP, aElement, aParent); + if (nsnull!=txn) + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; + } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -610,8 +644,13 @@ nsresult nsEditor::InsertText(nsIDOMCharacterData *aElement, { InsertTextTxn *txn = new InsertTextTxn(this, aElement, aOffset, aStringToInsert); if (nsnull!=txn) - result = ExecuteTransaction(txn); + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -619,13 +658,42 @@ nsresult nsEditor::DeleteText(nsIDOMCharacterData *aElement, PRUint32 aOffset, PRUint32 aLength) { - nsresult result; + nsresult result=NS_OK; if (nsnull != aElement) { DeleteTextTxn *txn = new DeleteTextTxn(this, aElement, aOffset, aLength); if (nsnull!=txn) - result = ExecuteTransaction(txn); + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; } + else + result = NS_ERROR_INVALID_ARG; + + return result; +} + +nsresult nsEditor::DeleteSelection() +{ + nsresult result; + nsISelection* selection; + result = mPresShell->GetSelection(&selection); + if ((NS_SUCCEEDED(result)) && (nsnull!=selection)) + { + nsCOMPtr range; + result = selection->QueryInterface(kIDOMRangeIID, getter_AddRefs(range)); + if ((NS_SUCCEEDED(result)) && (range)) + { + DeleteRangeTxn *txn = new DeleteRangeTxn(this, range); + if (nsnull!=txn) + result = ExecuteTransaction(txn); + else + result = NS_ERROR_OUT_OF_MEMORY; + } + } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -673,8 +741,10 @@ nsEditor::SplitNode(nsIDOMNode * aNode, } } } - else result = NS_ERROR_NULL_POINTER; } + else + result = NS_ERROR_INVALID_ARG; + return result; } @@ -730,7 +800,8 @@ nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep, } } else - result = NS_ERROR_NULL_POINTER; + result = NS_ERROR_INVALID_ARG; + return result; } diff --git a/mozilla/editor/core/editor.h b/mozilla/editor/core/editor.h index 3195e9000ef..44055cce9f0 100644 --- a/mozilla/editor/core/editor.h +++ b/mozilla/editor/core/editor.h @@ -27,7 +27,7 @@ //#include "nsISelection.h" class nsIDOMCharacterData; - +class nsIPresShell; //This is the monitor for the editor. PRMonitor *getEditorMonitor(); @@ -41,6 +41,7 @@ PRMonitor *getEditorMonitor(); class nsEditor : public nsIEditor { private: + nsIPresShell *mPresShell; nsCOMPtr mDomInterfaceP; nsCOMPtr mKeyListenerP; nsCOMPtr mMouseListenerP; @@ -64,7 +65,7 @@ public: /*interfaces for addref and release and queryinterface*/ NS_DECL_ISUPPORTS - virtual nsresult Init(nsIDOMDocument *aDomInterface); + virtual nsresult Init(nsIDOMDocument *aDomInterface, nsIPresShell* aPresShell); virtual nsresult GetDomInterface(nsIDOMDocument **aDomInterface); @@ -171,6 +172,11 @@ public: nsIDOMNode * aParent, PRInt32 aPosition); + nsresult DeleteElement(nsIDOMNode * aParent, + nsIDOMNode * aElement); + + nsresult DeleteSelection(); + nsresult InsertText(nsIDOMCharacterData *aElement, PRUint32 aOffset, const nsString& aStringToInsert); diff --git a/mozilla/editor/core/editorInterfaces.cpp b/mozilla/editor/core/editorInterfaces.cpp index eb0acceda1f..a9d5a1abfb9 100644 --- a/mozilla/editor/core/editorInterfaces.cpp +++ b/mozilla/editor/core/editorInterfaces.cpp @@ -138,33 +138,55 @@ nsEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent) switch(keyCode) { case nsIDOMEvent::VK_BACK: { - // XXX: for now, just grab the first text node - nsCOMPtr currentNode; - nsCOMPtr textNode; - nsCOMPtr text; - if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && - NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && - NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + if (PR_FALSE==ctrlKey) { - // XXX: for now, just append the text - PRUint32 offset; - text->GetLength(&offset); - nsresult result = mEditor->DeleteText(text, offset-1, 1); + // XXX: for now, just grab the first text node + nsCOMPtr currentNode; + nsCOMPtr textNode; + nsCOMPtr text; + if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && + NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && + NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + { + // XXX: for now, just append the text + PRUint32 offset; + text->GetLength(&offset); + nsresult result = mEditor->DeleteText(text, offset-1, 1); + } + } + else + { + mEditor->DeleteSelection(); } } break; case nsIDOMEvent::VK_DELETE: { - // XXX: for now, just grab the first text node - nsCOMPtr currentNode; - nsCOMPtr textNode; - nsCOMPtr text; - if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && - NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && - NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + if (PR_FALSE==ctrlKey) { - nsresult result = mEditor->DeleteText(text, 0, 1); + // XXX: for now, just grab the first text node + nsCOMPtr currentNode; + nsCOMPtr textNode; + nsCOMPtr text; + if (NS_SUCCEEDED(mEditor->GetCurrentNode(getter_AddRefs(currentNode))) && + NS_SUCCEEDED(mEditor->GetFirstTextNode(currentNode,getter_AddRefs(textNode))) && + NS_SUCCEEDED(textNode->QueryInterface(kIDOMCharacterDataIID, getter_AddRefs(text)))) + { + nsresult result = mEditor->DeleteText(text, 0, 1); + } + } + else + { // XXX: delete the first P we find + nsString pTag("P"); + nsCOMPtr currentNode; + nsCOMPtr parentNode; + nsCOMPtr element; + if (NS_SUCCEEDED(mEditor->GetFirstNodeOfType(nsnull, pTag, getter_AddRefs(currentNode)))) + { + currentNode->GetParentNode(getter_AddRefs(parentNode)); + nsresult result = mEditor->DeleteElement(parentNode, currentNode); + } } } break; diff --git a/mozilla/editor/core/makefile.win b/mozilla/editor/core/makefile.win index df301fd471b..0eb893bbaf5 100644 --- a/mozilla/editor/core/makefile.win +++ b/mozilla/editor/core/makefile.win @@ -21,27 +21,31 @@ IGNORE_MANIFEST=1 LIBRARY_NAME=ender CPPSRCS = \ - editor.cpp \ - editorInterfaces.cpp \ - nsEditFactory.cpp \ - EditTxn.cpp \ + editor.cpp \ + editorInterfaces.cpp \ + nsEditFactory.cpp \ + EditTxn.cpp \ ChangeAttributeTxn.cpp \ - InsertTextTxn.cpp \ - DeleteTextTxn.cpp \ - CreateElementTxn.cpp \ - SplitElementTxn.cpp \ + InsertTextTxn.cpp \ + DeleteTextTxn.cpp \ + CreateElementTxn.cpp \ + DeleteElementTxn.cpp \ + DeleteRangeTxn.cpp \ + SplitElementTxn.cpp \ $(NULL) CPP_OBJS = \ - .\$(OBJDIR)\editor.obj \ - .\$(OBJDIR)\nsEditFactory.obj \ + .\$(OBJDIR)\editor.obj \ + .\$(OBJDIR)\nsEditFactory.obj \ .\$(OBJDIR)\editorInterfaces.obj \ - .\$(OBJDIR)\EditTxn.obj \ - .\$(OBJDIR)\ChangeAttributeTxn.obj \ - .\$(OBJDIR)\InsertTextTxn.obj \ - .\$(OBJDIR)\DeleteTextTxn.obj \ - .\$(OBJDIR)\CreateElementTxn.obj \ - .\$(OBJDIR)\SplitElementTxn.obj \ + .\$(OBJDIR)\EditTxn.obj \ + .\$(OBJDIR)\ChangeAttributeTxn.obj \ + .\$(OBJDIR)\InsertTextTxn.obj \ + .\$(OBJDIR)\DeleteTextTxn.obj \ + .\$(OBJDIR)\CreateElementTxn.obj \ + .\$(OBJDIR)\DeleteElementTxn.obj \ + .\$(OBJDIR)\DeleteRangeTxn.obj \ + .\$(OBJDIR)\SplitElementTxn.obj \ $(NULL) MODULE=editor diff --git a/mozilla/editor/libeditor/base/ChangeAttributeTxn.cpp b/mozilla/editor/libeditor/base/ChangeAttributeTxn.cpp index 2cc764398f0..234e9031c84 100644 --- a/mozilla/editor/libeditor/base/ChangeAttributeTxn.cpp +++ b/mozilla/editor/libeditor/base/ChangeAttributeTxn.cpp @@ -94,6 +94,8 @@ nsresult ChangeAttributeTxn::GetIsTransient(PRBool *aIsTransient) nsresult ChangeAttributeTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/libeditor/base/CreateElementTxn.cpp b/mozilla/editor/libeditor/base/CreateElementTxn.cpp index fd42eec3f9f..c62adf8b423 100644 --- a/mozilla/editor/libeditor/base/CreateElementTxn.cpp +++ b/mozilla/editor/libeditor/base/CreateElementTxn.cpp @@ -110,6 +110,8 @@ nsresult CreateElementTxn::GetIsTransient(PRBool *aIsTransient) nsresult CreateElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/libeditor/base/DeleteElementTxn.cpp b/mozilla/editor/libeditor/base/DeleteElementTxn.cpp new file mode 100644 index 00000000000..85ca3462ebb --- /dev/null +++ b/mozilla/editor/libeditor/base/DeleteElementTxn.cpp @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "DeleteElementTxn.h" +#include "editor.h" +#include "nsIDOMDocument.h" +#include "nsIDOMElement.h" + +// note that aEditor is not refcounted +DeleteElementTxn::DeleteElementTxn(nsEditor * aEditor, + nsIDOMDocument *aDoc, + nsIDOMNode * aElement, + nsIDOMNode * aParent) + : EditTxn(aEditor) +{ + mDoc = aDoc; + NS_ADDREF(mDoc); + mElement = aElement; + NS_ADDREF(mElement); + mParent = aParent; + NS_ADDREF(mParent); +} + +DeleteElementTxn::~DeleteElementTxn() +{ + NS_IF_RELEASE(mDoc); + NS_IF_RELEASE(mParent); + NS_IF_RELEASE(mElement); +} + +nsresult DeleteElementTxn::Do(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; +#ifdef NS_DEBUG + nsresult testResult; + nsCOMPtr 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() "); +#endif + + // remember which child mElement was (by remembering which child was next) + nsresult result = mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode + + nsCOMPtr resultNode; + result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::Undo(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr resultNode; + nsresult result = mParent->InsertBefore(mElement, mRefNode, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::Redo(void) +{ + if (!mParent || !mElement) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr resultNode; + nsresult result = mParent->RemoveChild(mElement, getter_AddRefs(resultNode)); + return result; +} + +nsresult DeleteElementTxn::GetIsTransient(PRBool *aIsTransient) +{ + if (nsnull!=aIsTransient) + *aIsTransient = PR_FALSE; + return NS_OK; +} + +nsresult DeleteElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) +{ + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + return NS_OK; +} + +nsresult DeleteElementTxn::Write(nsIOutputStream *aOutputStream) +{ + return NS_OK; +} + +nsresult DeleteElementTxn::GetUndoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Insert Element: "; + } + return NS_OK; +} + +nsresult DeleteElementTxn::GetRedoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Remove Element: "; + } + return NS_OK; +} diff --git a/mozilla/editor/libeditor/base/DeleteElementTxn.h b/mozilla/editor/libeditor/base/DeleteElementTxn.h new file mode 100644 index 00000000000..dce2b04dcda --- /dev/null +++ b/mozilla/editor/libeditor/base/DeleteElementTxn.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DeleteElementTxn_h__ +#define DeleteElementTxn_h__ + +#include "EditTxn.h" +#include "nsIDOMNode.h" +#include "nsCOMPtr.h" + +class nsIDOMDocument; +class nsIDOMElement; + +/** + * A transaction that deletes a single element + */ +class DeleteElementTxn : public EditTxn +{ +public: + + DeleteElementTxn(nsEditor *aEditor, + nsIDOMDocument *aDoc, + nsIDOMNode *aElement, + nsIDOMNode *aParent); + + virtual ~DeleteElementTxn(); + + virtual nsresult Do(void); + + virtual nsresult Undo(void); + + virtual nsresult Redo(void); + + virtual nsresult GetIsTransient(PRBool *aIsTransient); + + virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction); + + virtual nsresult Write(nsIOutputStream *aOutputStream); + + virtual nsresult GetUndoString(nsString **aString); + + virtual nsresult GetRedoString(nsString **aString); + +protected: + + /** the document into which the new node will be inserted */ + nsIDOMDocument *mDoc; + + /** the element to delete */ + nsIDOMNode *mElement; + + /** the node into which the new node will be inserted */ + nsIDOMNode *mParent; + + /** the index in mParent for the new node */ + PRUint32 mOffsetInParent; + + /** the node we will insert mNewNode before. We compute this ourselves. */ + nsCOMPtr mRefNode; + +}; + +#endif diff --git a/mozilla/editor/libeditor/base/DeleteRangeTxn.cpp b/mozilla/editor/libeditor/base/DeleteRangeTxn.cpp new file mode 100644 index 00000000000..84a1b397e4d --- /dev/null +++ b/mozilla/editor/libeditor/base/DeleteRangeTxn.cpp @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "DeleteRangeTxn.h" +#include "editor.h" +#include "nsIDOMRange.h" + +// note that aEditor is not refcounted +DeleteRangeTxn::DeleteRangeTxn(nsEditor *aEditor, + nsIDOMRange *aRange) + : EditTxn(aEditor) +{ + aRange->GetStartParent(getter_AddRefs(mStartParent)); + aRange->GetEndParent(getter_AddRefs(mEndParent)); + aRange->GetStartOffset(&mStartOffset); + aRange->GetEndOffset(&mEndOffset); +} + +DeleteRangeTxn::~DeleteRangeTxn() +{ +} + +nsresult DeleteRangeTxn::Do(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::Undo(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::Redo(void) +{ + if (!mStartParent || !mEndParent) + return NS_ERROR_NULL_POINTER; + + nsresult result; + return result; +} + +nsresult DeleteRangeTxn::GetIsTransient(PRBool *aIsTransient) +{ + if (nsnull!=aIsTransient) + *aIsTransient = PR_FALSE; + return NS_OK; +} + +nsresult DeleteRangeTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) +{ + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + return NS_OK; +} + +nsresult DeleteRangeTxn::Write(nsIOutputStream *aOutputStream) +{ + return NS_OK; +} + +nsresult DeleteRangeTxn::GetUndoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Insert Range: "; + } + return NS_OK; +} + +nsresult DeleteRangeTxn::GetRedoString(nsString **aString) +{ + if (nsnull!=aString) + { + **aString="Remove Range: "; + } + return NS_OK; +} diff --git a/mozilla/editor/libeditor/base/DeleteRangeTxn.h b/mozilla/editor/libeditor/base/DeleteRangeTxn.h new file mode 100644 index 00000000000..675049f550a --- /dev/null +++ b/mozilla/editor/libeditor/base/DeleteRangeTxn.h @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DeleteRangeTxn_h__ +#define DeleteRangeTxn_h__ + +#include "EditTxn.h" +#include "nsIDOMNode.h" +#include "nsCOMPtr.h" + +class nsIDOMDocument; +class nsIDOMRange; + +/** + * A transaction that deletes an entire range in the content tree + */ +class DeleteRangeTxn : public EditTxn +{ +public: + + DeleteRangeTxn(nsEditor *aEditor, + nsIDOMRange *aRange); + + virtual ~DeleteRangeTxn(); + + virtual nsresult Do(void); + + virtual nsresult Undo(void); + + virtual nsresult Redo(void); + + virtual nsresult GetIsTransient(PRBool *aIsTransient); + + virtual nsresult Merge(PRBool *aDidMerge, nsITransaction *aTransaction); + + virtual nsresult Write(nsIOutputStream *aOutputStream); + + virtual nsresult GetUndoString(nsString **aString); + + virtual nsresult GetRedoString(nsString **aString); + +protected: + + /** p1 in the range */ + nsCOMPtr mStartParent; + + /** p1 offset */ + PRInt32 mStartOffset; + + /** p2 in the range */ + nsCOMPtr mEndParent; + + /** p2 offset */ + PRInt32 mEndOffset; + +}; + +#endif diff --git a/mozilla/editor/libeditor/base/DeleteTextTxn.cpp b/mozilla/editor/libeditor/base/DeleteTextTxn.cpp index 1259ea9e233..09df4b2b0ab 100644 --- a/mozilla/editor/libeditor/base/DeleteTextTxn.cpp +++ b/mozilla/editor/libeditor/base/DeleteTextTxn.cpp @@ -55,6 +55,8 @@ nsresult DeleteTextTxn::GetIsTransient(PRBool *aIsTransient) nsresult DeleteTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; } diff --git a/mozilla/editor/libeditor/base/InsertTextTxn.cpp b/mozilla/editor/libeditor/base/InsertTextTxn.cpp index 04e18841f4b..7f19c12796b 100644 --- a/mozilla/editor/libeditor/base/InsertTextTxn.cpp +++ b/mozilla/editor/libeditor/base/InsertTextTxn.cpp @@ -20,6 +20,8 @@ #include "editor.h" #include "nsIDOMCharacterData.h" +static NS_DEFINE_IID(kInsertTextTxnIID, INSERTTEXTTXN_IID); + // note that aEditor is not refcounted InsertTextTxn::InsertTextTxn(nsEditor *aEditor, nsIDOMCharacterData *aElement, @@ -52,6 +54,23 @@ nsresult InsertTextTxn::GetIsTransient(PRBool *aIsTransient) nsresult InsertTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + // set out param default value + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; + + if ((nsnull!=aDidMerge) && (nsnull!=aTransaction)) + { + // if aTransaction isa InsertTextTxn, absorb it + nsCOMPtr otherTxn; + nsresult result = aTransaction->QueryInterface(kInsertTextTxnIID, getter_AddRefs(otherTxn)); + if (NS_SUCCEEDED(result) && (otherTxn)) + { + nsString otherData; + otherTxn->GetData(otherData); + mStringToInsert += otherData; + } + *aDidMerge = PR_TRUE; + } return NS_OK; } @@ -79,3 +98,27 @@ nsresult InsertTextTxn::GetRedoString(nsString **aString) } return NS_OK; } + +/* ============= nsISupports implementation ====================== */ + +nsresult +InsertTextTxn::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kInsertTextTxnIID)) { + *aInstancePtr = (void*)(InsertTextTxn*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + return (EditTxn::QueryInterface(aIID, aInstancePtr)); +} + +/* ============ protected methods ================== */ + +nsresult InsertTextTxn::GetData(nsString& aResult) +{ + aResult = mStringToInsert; + return NS_OK; +} diff --git a/mozilla/editor/libeditor/base/InsertTextTxn.h b/mozilla/editor/libeditor/base/InsertTextTxn.h index 7430e25b7b5..4006babdb0f 100644 --- a/mozilla/editor/libeditor/base/InsertTextTxn.h +++ b/mozilla/editor/libeditor/base/InsertTextTxn.h @@ -21,6 +21,11 @@ #include "EditTxn.h" +#define INSERTTEXTTXN_IID \ +{/* 93276f00-ab2c-11d2-8f4b-006008159b0c*/ \ +0x93276f00, 0xab2c, 0x11d2, \ +{0x8f, 0xb4, 0x0, 0x60, 0x8, 0x15, 0x9b, 0xc} } + class nsIDOMCharacterData; /** @@ -50,6 +55,16 @@ public: virtual nsresult GetRedoString(nsString **aString); +// nsISupports declarations + + // override QueryInterface to handle InsertTextTxn request + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + + static const nsIID& IID() { static nsIID iid = INSERTTEXTTXN_IID; return iid; } + + + virtual nsresult GetData(nsString& aResult); + protected: /** the text element to operate upon */ diff --git a/mozilla/editor/libeditor/base/SplitElementTxn.cpp b/mozilla/editor/libeditor/base/SplitElementTxn.cpp index 26523978d22..2134cc5375c 100644 --- a/mozilla/editor/libeditor/base/SplitElementTxn.cpp +++ b/mozilla/editor/libeditor/base/SplitElementTxn.cpp @@ -82,6 +82,8 @@ nsresult SplitElementTxn::GetIsTransient(PRBool *aIsTransient) nsresult SplitElementTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransaction) { + if (nsnull!=aDidMerge) + *aDidMerge=PR_FALSE; return NS_OK; }