updated to new nsCOMPtr usage
nsTextEditor::InsertBreak() implemented
  splits the text node at the caret (deletes any extended selection to force a collapsed selection.)
  inserts a <BR> which I assume we'll convert to a CR when we write to a text stream.
  undo and redo work, except for the bug noted below

More stuff:
interface cleanup
strategic debugging code added
delete selection txn sets the collapses the selection...this is just a placeholder, but I needed it for undo/redo of InsertBreak.
join and split now work for text nodes as well as interior nodes
This commit is contained in:
buster%netscape.com 1999-02-17 19:42:29 +00:00
Родитель f43db5b48f
Коммит 061b766061
18 изменённых файлов: 589 добавлений и 140 удалений

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

@ -37,6 +37,13 @@ nsresult CreateElementTxn::Init(nsIDOMDocument *aDoc,
mOffsetInParent = aOffsetInParent;
mNewNode = nsnull;
mRefNode = nsnull;
#ifdef NS_DEBUG
{
nsCOMPtr<nsIDOMNodeList> testChildNodes;
nsresult testResult = mParent->GetChildNodes(getter_AddRefs(testChildNodes));
NS_ASSERTION(testChildNodes, "bad parent type, can't have children.");
}
#endif
return NS_OK;
}
else

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

@ -20,6 +20,7 @@
#include "nsIDOMRange.h"
#include "nsIDOMCharacterData.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMSelection.h"
#include "DeleteTextTxn.h"
#include "DeleteElementTxn.h"
#include "TransactionFactory.h"
@ -44,10 +45,11 @@ DeleteRangeTxn::DeleteRangeTxn()
{
}
nsresult DeleteRangeTxn::Init(nsIDOMRange *aRange)
nsresult DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
{
if (nsnull!=aRange)
if (aEditor && aRange)
{
mEditor = aEditor;
nsresult result = aRange->GetStartParent(getter_AddRefs(mStartParent));
NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartParent failed.");
result = aRange->GetEndParent(getter_AddRefs(mEndParent));
@ -60,6 +62,7 @@ nsresult DeleteRangeTxn::Init(nsIDOMRange *aRange)
NS_ASSERTION((NS_SUCCEEDED(result)), "GetCommonParent failed.");
#ifdef NS_DEBUG
{
PRUint32 count;
nsCOMPtr<nsIDOMCharacterData> textNode;
textNode = do_QueryInterface(mStartParent, &result);
@ -88,6 +91,7 @@ nsresult DeleteRangeTxn::Init(nsIDOMRange *aRange)
if (gNoisy)
printf ("DeleteRange: %d of %p to %d of %p\n",
mStartOffset, (void *)mStartParent, mEndOffset, (void *)mEndParent);
}
#endif
return result;
}
@ -129,8 +133,18 @@ nsresult DeleteRangeTxn::Do(void)
}
// if we've successfully built this aggregate transaction, then do it.
if (NS_SUCCEEDED(result))
if (NS_SUCCEEDED(result)) {
result = EditAggregateTxn::Do();
}
if (NS_SUCCEEDED(result)) {
// set the resulting selection
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) {
result = selection->Collapse(mStartParent, mStartOffset);
}
}
return result;
}
@ -141,6 +155,16 @@ nsresult DeleteRangeTxn::Undo(void)
return NS_ERROR_NULL_POINTER;
nsresult result = EditAggregateTxn::Undo();
if (NS_SUCCEEDED(result)) {
// set the resulting selection
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) {
result = selection->Collapse(mStartParent, mStartOffset);
}
}
return result;
}
@ -150,6 +174,16 @@ nsresult DeleteRangeTxn::Redo(void)
return NS_ERROR_NULL_POINTER;
nsresult result = EditAggregateTxn::Redo();
if (NS_SUCCEEDED(result)) {
// set the resulting selection
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) {
result = selection->Collapse(mStartParent, mStartOffset);
}
}
return result;
}

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

@ -41,9 +41,10 @@ class DeleteRangeTxn : public EditAggregateTxn
public:
/** initialize the transaction.
* @param aEditor the object providing basic editing operations
* @param aRange the range to delete
*/
virtual nsresult Init(nsIDOMRange *aRange);
virtual nsresult Init(nsIEditor *aEditor, nsIDOMRange *aRange);
private:
DeleteRangeTxn();
@ -100,6 +101,9 @@ protected:
/** p2 offset */
PRInt32 mEndOffset;
/** the editor for this transaction */
nsCOMPtr<nsIEditor> mEditor;
friend class TransactionFactory;
};

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

@ -18,6 +18,9 @@
#include "JoinElementTxn.h"
#include "nsIDOMNodeList.h"
#include "nsIEditorSupport.h"
static NS_DEFINE_IID(kIEditorSupportIID, NS_IEDITORSUPPORT_IID);
JoinElementTxn::JoinElementTxn()
@ -64,6 +67,12 @@ nsresult JoinElementTxn::Do(void)
{
childNodes->GetLength(&mOffset);
}
//XXX: WRONG! needs commented code below
/*
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->JoinNodesImpl(mLeftNode, mRightNode, mParent, PR_FALSE);
*/
result = mEditor->JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
}
}
@ -75,7 +84,15 @@ nsresult JoinElementTxn::Do(void)
nsresult JoinElementTxn::Undo(void)
{
nsresult result = mEditor->SplitNode(mRightNode, mOffset, mLeftNode, mParent);
nsresult result;
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->SplitNodeImpl(mRightNode, mOffset, mLeftNode, mParent);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}

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

@ -19,6 +19,9 @@
#include "SplitElementTxn.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIEditorSupport.h"
static NS_DEFINE_IID(kIEditorSupportIID, NS_IEDITORSUPPORT_IID);
// note that aEditor is not refcounted
SplitElementTxn::SplitElementTxn()
@ -53,7 +56,14 @@ nsresult SplitElementTxn::Do(void)
// insert the new node
if ((NS_SUCCEEDED(result)) && (mParent))
{
result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
}
}
return result;
@ -62,13 +72,29 @@ nsresult SplitElementTxn::Do(void)
nsresult SplitElementTxn::Undo(void)
{
// this assumes Do inserted the new node in front of the prior existing node
nsresult result = mEditor->JoinNodes(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
nsresult result;
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
nsresult SplitElementTxn::Redo(void)
{
nsresult result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
nsresult result;
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}

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

@ -86,7 +86,7 @@ nsEditFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult
if (mCID.Equals(kEditorCID))
obj = (nsISupports *)new nsEditor();
obj = (nsISupports *)(nsIEditor*)new nsEditor();
//more class ids to support. here

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

@ -67,6 +67,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID);
static NS_DEFINE_IID(kIEditorIID, NS_IEDITOR_IID);
static NS_DEFINE_IID(kIEditorSupportIID, NS_IEDITORSUPPORT_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kEditorCID, NS_EDITOR_CID);
static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
@ -211,7 +212,9 @@ nsEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)this;
nsIEditor *tmp = this;
nsISupports *tmp2 = tmp;
*aInstancePtr = (void*)tmp2;
NS_ADDREF_THIS();
return NS_OK;
}
@ -220,6 +223,11 @@ nsEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIEditorSupportIID)) {
*aInstancePtr = (void*)(nsIEditorSupport*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -235,7 +243,15 @@ nsEditor::GetDocument(nsIDOMDocument **aDoc)
return mDoc->QueryInterface(kIDOMDocumentIID, (void **)aDoc);
}
nsresult
nsEditor::GetSelection(nsIDOMSelection **aSelection)
{
if (!aSelection)
return NS_ERROR_NULL_POINTER;
*aSelection = nsnull;
nsresult result = mPresShell->GetSelection(aSelection); // does an addref
return result;
}
nsresult
nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell)
@ -383,9 +399,9 @@ nsEditor::GetAttributeValue(nsIDOMElement *aElement,
nsresult result=NS_OK;
if (nsnull!=aElement)
{
nsIDOMAttr* attNode=nsnull;
result = aElement->GetAttributeNode(aAttribute, &attNode);
if ((NS_SUCCEEDED(result)) && (nsnull!=attNode))
nsCOMPtr<nsIDOMAttr> attNode;
result = aElement->GetAttributeNode(aAttribute, getter_AddRefs(attNode));
if ((NS_SUCCEEDED(result)) && attNode)
{
attNode->GetSpecified(&aResultIsSet);
attNode->GetValue(aResultValue);
@ -955,7 +971,7 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
result = TransactionFactory::GetNewTransaction(kDeleteRangeTxnIID, (EditTxn **)&txn);
if ((NS_SUCCEEDED(result)) && (nsnull!=txn))
{
txn->Init(range);
txn->Init(this, range);
(*aTxn)->AppendChild(txn);
}
else
@ -1224,6 +1240,18 @@ nsEditor::GetLeftmostChild(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode)
return result;
}
nsresult
nsEditor::SplitNode(nsIDOMNode * aNode,
PRInt32 aOffset)
{
SplitElementTxn *txn;
nsresult result = CreateTxnForSplitNode(aNode, aOffset, &txn);
if (NS_SUCCEEDED(result)) {
result = Do(txn);
}
return result;
}
nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
PRUint32 aOffset,
SplitElementTxn **aTxn)
@ -1239,6 +1267,20 @@ nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
return result;
}
nsresult
nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst)
{
JoinElementTxn *txn;
nsresult result = CreateTxnForJoinNode(aNodeToKeep, aNodeToJoin, &txn);
if (NS_SUCCEEDED(result)) {
result = Do(txn);
}
return result;
}
nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
JoinElementTxn **aTxn)
@ -1255,10 +1297,10 @@ nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
}
nsresult
nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode* aNewLeftNode,
nsIDOMNode* aParent)
nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode* aNewLeftNode,
nsIDOMNode* aParent)
{
nsresult result;
NS_ASSERTION(((nsnull!=aExistingRightNode) &&
@ -1278,25 +1320,40 @@ nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
// move all the children whose index is < aOffset to aNewLeftNode
if (0<=aOffset) // don't bother unless we're going to move at least one child
{
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aExistingRightNode->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
// if it's a text node, just shuffle around some text
nsCOMPtr<nsIDOMCharacterData> rightNodeAsText(aExistingRightNode);
nsCOMPtr<nsIDOMCharacterData> leftNodeAsText(aNewLeftNode);
if (leftNodeAsText && rightNodeAsText)
{
PRInt32 i=0;
for ( ; ((NS_SUCCEEDED(result)) && (i<aOffset)); i++)
// fix right node
nsString leftText;
rightNodeAsText->SubstringData(0, aOffset, leftText);
rightNodeAsText->DeleteData(0, aOffset);
// fix left node
leftNodeAsText->SetData(leftText);
}
else
{ // otherwise it's an interior node, so shuffle around the children
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aExistingRightNode->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
{
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
PRInt32 i=0;
for ( ; ((NS_SUCCEEDED(result)) && (i<aOffset)); i++)
{
result = aExistingRightNode->RemoveChild(childNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result))
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
{
result = aNewLeftNode->AppendChild(childNode, getter_AddRefs(resultNode));
result = aExistingRightNode->RemoveChild(childNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result))
{
result = aNewLeftNode->AppendChild(childNode, getter_AddRefs(resultNode));
}
}
}
}
}
}
}
}
}
}
@ -1307,10 +1364,10 @@ nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
}
nsresult
nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst)
nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst)
{
nsresult result;
NS_ASSERTION(((nsnull!=aNodeToKeep) &&
@ -1321,41 +1378,68 @@ nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep,
(nsnull!=aNodeToJoin) &&
(nsnull!=aParent))
{
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aNodeToJoin->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
// if it's a text node, just shuffle around some text
nsCOMPtr<nsIDOMCharacterData> keepNodeAsText(aNodeToKeep);
nsCOMPtr<nsIDOMCharacterData> joinNodeAsText(aNodeToJoin);
if (keepNodeAsText && joinNodeAsText)
{
PRUint32 i;
PRUint32 childCount=0;
childNodes->GetLength(&childCount);
nsCOMPtr<nsIDOMNode> firstNode; //only used if aNodeToKeepIsFirst is false
if (PR_FALSE==aNodeToKeepIsFirst)
{ // remember the first child in aNodeToKeep, we'll insert all the children of aNodeToJoin in front of it
result = aNodeToKeep->GetFirstChild(getter_AddRefs(firstNode));
// GetFirstChild returns nsnull firstNode if aNodeToKeep has no children, that's ok.
}
nsCOMPtr<nsIDOMNode> resultNode;
for (i=0; ((NS_SUCCEEDED(result)) && (i<childCount)); i++)
nsString rightText;
nsString leftText;
if (aNodeToKeepIsFirst)
{
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
keepNodeAsText->GetData(leftText);
joinNodeAsText->GetData(rightText);
}
else
{
keepNodeAsText->GetData(rightText);
joinNodeAsText->GetData(leftText);
}
leftText += rightText;
keepNodeAsText->SetData(leftText);
}
else
{ // otherwise it's an interior node, so shuffle around the children
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aNodeToJoin->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
{
PRUint32 i;
PRUint32 childCount=0;
childNodes->GetLength(&childCount);
nsCOMPtr<nsIDOMNode> firstNode; //only used if aNodeToKeepIsFirst is false
if (PR_FALSE==aNodeToKeepIsFirst)
{ // remember the first child in aNodeToKeep, we'll insert all the children of aNodeToJoin in front of it
result = aNodeToKeep->GetFirstChild(getter_AddRefs(firstNode));
// GetFirstChild returns nsnull firstNode if aNodeToKeep has no children, that's ok.
}
nsCOMPtr<nsIDOMNode> resultNode;
for (i=0; ((NS_SUCCEEDED(result)) && (i<childCount)); i++)
{
if (PR_TRUE==aNodeToKeepIsFirst)
{ // append children of aNodeToJoin
result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
}
else
{ // prepend children of aNodeToJoin
result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
{
if (PR_TRUE==aNodeToKeepIsFirst)
{ // append children of aNodeToJoin
result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
}
else
{ // prepend children of aNodeToJoin
result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
}
}
}
}
if (NS_SUCCEEDED(result))
{ // delete the extra node
result = aParent->RemoveChild(aNodeToJoin, getter_AddRefs(resultNode));
else if (!childNodes) {
result = NS_ERROR_NULL_POINTER;
}
}
if (NS_SUCCEEDED(result))
{ // delete the extra node
nsCOMPtr<nsIDOMNode> resultNode;
result = aParent->RemoveChild(aNodeToJoin, getter_AddRefs(resultNode));
}
}
else
result = NS_ERROR_INVALID_ARG;

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

@ -21,6 +21,7 @@
#include "prmon.h"
#include "nsIEditor.h"
#include "nsIEditorSupport.h"
#include "nsIContextLoader.h"
#include "nsIDOMDocument.h"
#include "nsIDOMEventListener.h"
@ -28,7 +29,6 @@
#include "nsITransactionManager.h"
#include "TransactionFactory.h"
#include "nsRepository.h"
//#include "nsISelection.h"
class nsIDOMCharacterData;
class nsIDOMRange;
@ -72,7 +72,7 @@ inline Property::Property(nsIAtom *aPropName, nsIAtom *aValue, PRBool aAppliesTo
* manager, event interfaces. the idea for the event interfaces is to have them
* delegate the actual commands to the editor independent of the XPFE implementation.
*/
class nsEditor : public nsIEditor
class nsEditor : public nsIEditor, public nsIEditorSupport
{
private:
nsIPresShell *mPresShell;
@ -104,6 +104,8 @@ public:
virtual nsresult GetDocument(nsIDOMDocument **aDoc);
virtual nsresult GetSelection(nsIDOMSelection **aSelection);
virtual nsresult SetProperties(nsVoidArray *aPropList);
virtual nsresult GetProperties(nsVoidArray *aPropList);
@ -133,9 +135,7 @@ public:
virtual nsresult DeleteSelection(nsIEditor::Direction aDir);
virtual nsresult SplitNode(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode * aNewLeftNode,
nsIDOMNode * aParent);
PRInt32 aOffset);
virtual nsresult JoinNodes(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
@ -232,10 +232,20 @@ protected:
PRUint32 aOffset,
SplitElementTxn **aTxn);
virtual nsresult SplitNodeImpl(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode * aNewLeftNode,
nsIDOMNode * aParent);
virtual nsresult CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
JoinElementTxn **aTxn);
virtual nsresult JoinNodesImpl(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst);
#if 0
nsresult CreateTxnToHandleEnterKey(EditAggregateTxn **aTxn);
#endif

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

@ -22,8 +22,12 @@
#include "nsIDOMEventReceiver.h"
#include "nsIDOMKeyListener.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMSelection.h"
#include "nsIDOMNodeList.h"
#include "nsEditorCID.h"
#include "CreateElementTxn.h"
#include "nsRepository.h"
#include "nsIServiceManager.h"
@ -171,7 +175,42 @@ nsresult nsTextEditor::InsertBreak(PRBool aCtrlKey)
nsresult result=NS_ERROR_NOT_INITIALIZED;
if (mEditor)
{
result = NS_ERROR_NOT_IMPLEMENTED;
PRBool beganTransaction = PR_FALSE;
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if ((NS_SUCCEEDED(result)) && selection)
{
beganTransaction = PR_TRUE;
result = mEditor->BeginTransaction();
PRBool collapsed;
result = selection->IsCollapsed(&collapsed);
if (NS_SUCCEEDED(result) && !collapsed)
{
result = mEditor->DeleteSelection(nsIEditor::eLTR);
// get the new selection
result = mEditor->GetSelection(getter_AddRefs(selection));
#ifdef NS_DEBUG
PRBool testCollapsed;
result = selection->IsCollapsed(&testCollapsed);
NS_ASSERTION(PR_TRUE==testCollapsed, "selection not reset after deletion");
#endif
}
// split the text node
nsCOMPtr<nsIDOMNode> node;
PRInt32 offset;
result = selection->GetAnchorNodeAndOffset(getter_AddRefs(node), &offset);
nsCOMPtr<nsIDOMNode> parentNode;
result = node->GetParentNode(getter_AddRefs(parentNode));
result = mEditor->SplitNode(node, offset);
// now get the node's offset in it's parent, and insert the new BR there
result = GetChildOffset(node, parentNode, offset);
nsAutoString tag("BR");
result = mEditor->CreateNode(tag, parentNode, offset);
selection->Collapse(parentNode, offset);
}
if (PR_TRUE==beganTransaction) {
result = mEditor->EndTransaction();
}
}
return result;
}
@ -389,3 +428,39 @@ nsTextEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
}
return NS_NOINTERFACE;
}
// utility methods
nsresult nsTextEditor::GetChildOffset(nsIDOMNode *aChild, nsIDOMNode *aParent, PRInt32 &aOffset)
{
NS_ASSERTION((aChild && aParent), "bad args");
nsresult result = NS_ERROR_NULL_POINTER;
if (aChild && aParent)
{
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aParent->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
{
PRInt32 i=0;
for ( ; NS_SUCCEEDED(result); i++)
{
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
{
if (childNode==aChild)
{
aOffset = i;
break;
}
}
else if (!childNode)
result = NS_ERROR_NULL_POINTER;
}
}
else if (!childNodes)
result = NS_ERROR_NULL_POINTER;
}
return result;
}

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

@ -77,6 +77,11 @@ public:
virtual nsresult OutputText(nsIOutputStream *aOutputStream);
virtual nsresult OutputHTML(nsIOutputStream *aOutputStream);
// Utility methods
protected:
virtual nsresult GetChildOffset(nsIDOMNode *aChild, nsIDOMNode *aParent, PRInt32 &aOffset);
// Data members
protected:
nsCOMPtr<nsIEditor> mEditor;
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;

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

@ -37,6 +37,13 @@ nsresult CreateElementTxn::Init(nsIDOMDocument *aDoc,
mOffsetInParent = aOffsetInParent;
mNewNode = nsnull;
mRefNode = nsnull;
#ifdef NS_DEBUG
{
nsCOMPtr<nsIDOMNodeList> testChildNodes;
nsresult testResult = mParent->GetChildNodes(getter_AddRefs(testChildNodes));
NS_ASSERTION(testChildNodes, "bad parent type, can't have children.");
}
#endif
return NS_OK;
}
else

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

@ -20,6 +20,7 @@
#include "nsIDOMRange.h"
#include "nsIDOMCharacterData.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMSelection.h"
#include "DeleteTextTxn.h"
#include "DeleteElementTxn.h"
#include "TransactionFactory.h"
@ -44,10 +45,11 @@ DeleteRangeTxn::DeleteRangeTxn()
{
}
nsresult DeleteRangeTxn::Init(nsIDOMRange *aRange)
nsresult DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
{
if (nsnull!=aRange)
if (aEditor && aRange)
{
mEditor = aEditor;
nsresult result = aRange->GetStartParent(getter_AddRefs(mStartParent));
NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartParent failed.");
result = aRange->GetEndParent(getter_AddRefs(mEndParent));
@ -60,6 +62,7 @@ nsresult DeleteRangeTxn::Init(nsIDOMRange *aRange)
NS_ASSERTION((NS_SUCCEEDED(result)), "GetCommonParent failed.");
#ifdef NS_DEBUG
{
PRUint32 count;
nsCOMPtr<nsIDOMCharacterData> textNode;
textNode = do_QueryInterface(mStartParent, &result);
@ -88,6 +91,7 @@ nsresult DeleteRangeTxn::Init(nsIDOMRange *aRange)
if (gNoisy)
printf ("DeleteRange: %d of %p to %d of %p\n",
mStartOffset, (void *)mStartParent, mEndOffset, (void *)mEndParent);
}
#endif
return result;
}
@ -129,8 +133,18 @@ nsresult DeleteRangeTxn::Do(void)
}
// if we've successfully built this aggregate transaction, then do it.
if (NS_SUCCEEDED(result))
if (NS_SUCCEEDED(result)) {
result = EditAggregateTxn::Do();
}
if (NS_SUCCEEDED(result)) {
// set the resulting selection
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) {
result = selection->Collapse(mStartParent, mStartOffset);
}
}
return result;
}
@ -141,6 +155,16 @@ nsresult DeleteRangeTxn::Undo(void)
return NS_ERROR_NULL_POINTER;
nsresult result = EditAggregateTxn::Undo();
if (NS_SUCCEEDED(result)) {
// set the resulting selection
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) {
result = selection->Collapse(mStartParent, mStartOffset);
}
}
return result;
}
@ -150,6 +174,16 @@ nsresult DeleteRangeTxn::Redo(void)
return NS_ERROR_NULL_POINTER;
nsresult result = EditAggregateTxn::Redo();
if (NS_SUCCEEDED(result)) {
// set the resulting selection
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) {
result = selection->Collapse(mStartParent, mStartOffset);
}
}
return result;
}

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

@ -41,9 +41,10 @@ class DeleteRangeTxn : public EditAggregateTxn
public:
/** initialize the transaction.
* @param aEditor the object providing basic editing operations
* @param aRange the range to delete
*/
virtual nsresult Init(nsIDOMRange *aRange);
virtual nsresult Init(nsIEditor *aEditor, nsIDOMRange *aRange);
private:
DeleteRangeTxn();
@ -100,6 +101,9 @@ protected:
/** p2 offset */
PRInt32 mEndOffset;
/** the editor for this transaction */
nsCOMPtr<nsIEditor> mEditor;
friend class TransactionFactory;
};

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

@ -18,6 +18,9 @@
#include "JoinElementTxn.h"
#include "nsIDOMNodeList.h"
#include "nsIEditorSupport.h"
static NS_DEFINE_IID(kIEditorSupportIID, NS_IEDITORSUPPORT_IID);
JoinElementTxn::JoinElementTxn()
@ -64,6 +67,12 @@ nsresult JoinElementTxn::Do(void)
{
childNodes->GetLength(&mOffset);
}
//XXX: WRONG! needs commented code below
/*
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->JoinNodesImpl(mLeftNode, mRightNode, mParent, PR_FALSE);
*/
result = mEditor->JoinNodes(mLeftNode, mRightNode, mParent, PR_FALSE);
}
}
@ -75,7 +84,15 @@ nsresult JoinElementTxn::Do(void)
nsresult JoinElementTxn::Undo(void)
{
nsresult result = mEditor->SplitNode(mRightNode, mOffset, mLeftNode, mParent);
nsresult result;
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->SplitNodeImpl(mRightNode, mOffset, mLeftNode, mParent);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}

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

@ -19,6 +19,9 @@
#include "SplitElementTxn.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIEditorSupport.h"
static NS_DEFINE_IID(kIEditorSupportIID, NS_IEDITORSUPPORT_IID);
// note that aEditor is not refcounted
SplitElementTxn::SplitElementTxn()
@ -53,7 +56,14 @@ nsresult SplitElementTxn::Do(void)
// insert the new node
if ((NS_SUCCEEDED(result)) && (mParent))
{
result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
}
}
return result;
@ -62,13 +72,29 @@ nsresult SplitElementTxn::Do(void)
nsresult SplitElementTxn::Undo(void)
{
// this assumes Do inserted the new node in front of the prior existing node
nsresult result = mEditor->JoinNodes(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
nsresult result;
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
nsresult SplitElementTxn::Redo(void)
{
nsresult result = mEditor->SplitNode(mExistingRightNode, mOffset, mNewLeftNode, mParent);
nsresult result;
nsCOMPtr<nsIEditorSupport> editor;
result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor));
if (NS_SUCCEEDED(result) && editor) {
result = editor->SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}

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

@ -67,6 +67,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kIEditFactoryIID, NS_IEDITORFACTORY_IID);
static NS_DEFINE_IID(kIEditorIID, NS_IEDITOR_IID);
static NS_DEFINE_IID(kIEditorSupportIID, NS_IEDITORSUPPORT_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kEditorCID, NS_EDITOR_CID);
static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
@ -211,7 +212,9 @@ nsEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)this;
nsIEditor *tmp = this;
nsISupports *tmp2 = tmp;
*aInstancePtr = (void*)tmp2;
NS_ADDREF_THIS();
return NS_OK;
}
@ -220,6 +223,11 @@ nsEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIEditorSupportIID)) {
*aInstancePtr = (void*)(nsIEditorSupport*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -235,7 +243,15 @@ nsEditor::GetDocument(nsIDOMDocument **aDoc)
return mDoc->QueryInterface(kIDOMDocumentIID, (void **)aDoc);
}
nsresult
nsEditor::GetSelection(nsIDOMSelection **aSelection)
{
if (!aSelection)
return NS_ERROR_NULL_POINTER;
*aSelection = nsnull;
nsresult result = mPresShell->GetSelection(aSelection); // does an addref
return result;
}
nsresult
nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell)
@ -383,9 +399,9 @@ nsEditor::GetAttributeValue(nsIDOMElement *aElement,
nsresult result=NS_OK;
if (nsnull!=aElement)
{
nsIDOMAttr* attNode=nsnull;
result = aElement->GetAttributeNode(aAttribute, &attNode);
if ((NS_SUCCEEDED(result)) && (nsnull!=attNode))
nsCOMPtr<nsIDOMAttr> attNode;
result = aElement->GetAttributeNode(aAttribute, getter_AddRefs(attNode));
if ((NS_SUCCEEDED(result)) && attNode)
{
attNode->GetSpecified(&aResultIsSet);
attNode->GetValue(aResultValue);
@ -955,7 +971,7 @@ nsresult nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
result = TransactionFactory::GetNewTransaction(kDeleteRangeTxnIID, (EditTxn **)&txn);
if ((NS_SUCCEEDED(result)) && (nsnull!=txn))
{
txn->Init(range);
txn->Init(this, range);
(*aTxn)->AppendChild(txn);
}
else
@ -1224,6 +1240,18 @@ nsEditor::GetLeftmostChild(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode)
return result;
}
nsresult
nsEditor::SplitNode(nsIDOMNode * aNode,
PRInt32 aOffset)
{
SplitElementTxn *txn;
nsresult result = CreateTxnForSplitNode(aNode, aOffset, &txn);
if (NS_SUCCEEDED(result)) {
result = Do(txn);
}
return result;
}
nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
PRUint32 aOffset,
SplitElementTxn **aTxn)
@ -1239,6 +1267,20 @@ nsresult nsEditor::CreateTxnForSplitNode(nsIDOMNode *aNode,
return result;
}
nsresult
nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst)
{
JoinElementTxn *txn;
nsresult result = CreateTxnForJoinNode(aNodeToKeep, aNodeToJoin, &txn);
if (NS_SUCCEEDED(result)) {
result = Do(txn);
}
return result;
}
nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
JoinElementTxn **aTxn)
@ -1255,10 +1297,10 @@ nsresult nsEditor::CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
}
nsresult
nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode* aNewLeftNode,
nsIDOMNode* aParent)
nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode* aNewLeftNode,
nsIDOMNode* aParent)
{
nsresult result;
NS_ASSERTION(((nsnull!=aExistingRightNode) &&
@ -1278,25 +1320,40 @@ nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
// move all the children whose index is < aOffset to aNewLeftNode
if (0<=aOffset) // don't bother unless we're going to move at least one child
{
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aExistingRightNode->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
// if it's a text node, just shuffle around some text
nsCOMPtr<nsIDOMCharacterData> rightNodeAsText(aExistingRightNode);
nsCOMPtr<nsIDOMCharacterData> leftNodeAsText(aNewLeftNode);
if (leftNodeAsText && rightNodeAsText)
{
PRInt32 i=0;
for ( ; ((NS_SUCCEEDED(result)) && (i<aOffset)); i++)
// fix right node
nsString leftText;
rightNodeAsText->SubstringData(0, aOffset, leftText);
rightNodeAsText->DeleteData(0, aOffset);
// fix left node
leftNodeAsText->SetData(leftText);
}
else
{ // otherwise it's an interior node, so shuffle around the children
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aExistingRightNode->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
{
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
PRInt32 i=0;
for ( ; ((NS_SUCCEEDED(result)) && (i<aOffset)); i++)
{
result = aExistingRightNode->RemoveChild(childNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result))
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
{
result = aNewLeftNode->AppendChild(childNode, getter_AddRefs(resultNode));
result = aExistingRightNode->RemoveChild(childNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result))
{
result = aNewLeftNode->AppendChild(childNode, getter_AddRefs(resultNode));
}
}
}
}
}
}
}
}
}
}
@ -1307,10 +1364,10 @@ nsEditor::SplitNode(nsIDOMNode * aExistingRightNode,
}
nsresult
nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst)
nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst)
{
nsresult result;
NS_ASSERTION(((nsnull!=aNodeToKeep) &&
@ -1321,41 +1378,68 @@ nsEditor::JoinNodes(nsIDOMNode * aNodeToKeep,
(nsnull!=aNodeToJoin) &&
(nsnull!=aParent))
{
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aNodeToJoin->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
// if it's a text node, just shuffle around some text
nsCOMPtr<nsIDOMCharacterData> keepNodeAsText(aNodeToKeep);
nsCOMPtr<nsIDOMCharacterData> joinNodeAsText(aNodeToJoin);
if (keepNodeAsText && joinNodeAsText)
{
PRUint32 i;
PRUint32 childCount=0;
childNodes->GetLength(&childCount);
nsCOMPtr<nsIDOMNode> firstNode; //only used if aNodeToKeepIsFirst is false
if (PR_FALSE==aNodeToKeepIsFirst)
{ // remember the first child in aNodeToKeep, we'll insert all the children of aNodeToJoin in front of it
result = aNodeToKeep->GetFirstChild(getter_AddRefs(firstNode));
// GetFirstChild returns nsnull firstNode if aNodeToKeep has no children, that's ok.
}
nsCOMPtr<nsIDOMNode> resultNode;
for (i=0; ((NS_SUCCEEDED(result)) && (i<childCount)); i++)
nsString rightText;
nsString leftText;
if (aNodeToKeepIsFirst)
{
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
keepNodeAsText->GetData(leftText);
joinNodeAsText->GetData(rightText);
}
else
{
keepNodeAsText->GetData(rightText);
joinNodeAsText->GetData(leftText);
}
leftText += rightText;
keepNodeAsText->SetData(leftText);
}
else
{ // otherwise it's an interior node, so shuffle around the children
nsCOMPtr<nsIDOMNodeList> childNodes;
result = aNodeToJoin->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
{
PRUint32 i;
PRUint32 childCount=0;
childNodes->GetLength(&childCount);
nsCOMPtr<nsIDOMNode> firstNode; //only used if aNodeToKeepIsFirst is false
if (PR_FALSE==aNodeToKeepIsFirst)
{ // remember the first child in aNodeToKeep, we'll insert all the children of aNodeToJoin in front of it
result = aNodeToKeep->GetFirstChild(getter_AddRefs(firstNode));
// GetFirstChild returns nsnull firstNode if aNodeToKeep has no children, that's ok.
}
nsCOMPtr<nsIDOMNode> resultNode;
for (i=0; ((NS_SUCCEEDED(result)) && (i<childCount)); i++)
{
if (PR_TRUE==aNodeToKeepIsFirst)
{ // append children of aNodeToJoin
result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
}
else
{ // prepend children of aNodeToJoin
result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
nsCOMPtr<nsIDOMNode> childNode;
result = childNodes->Item(i, getter_AddRefs(childNode));
if ((NS_SUCCEEDED(result)) && (childNode))
{
if (PR_TRUE==aNodeToKeepIsFirst)
{ // append children of aNodeToJoin
result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
}
else
{ // prepend children of aNodeToJoin
result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
}
}
}
}
if (NS_SUCCEEDED(result))
{ // delete the extra node
result = aParent->RemoveChild(aNodeToJoin, getter_AddRefs(resultNode));
else if (!childNodes) {
result = NS_ERROR_NULL_POINTER;
}
}
if (NS_SUCCEEDED(result))
{ // delete the extra node
nsCOMPtr<nsIDOMNode> resultNode;
result = aParent->RemoveChild(aNodeToJoin, getter_AddRefs(resultNode));
}
}
else
result = NS_ERROR_INVALID_ARG;

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

@ -21,6 +21,7 @@
#include "prmon.h"
#include "nsIEditor.h"
#include "nsIEditorSupport.h"
#include "nsIContextLoader.h"
#include "nsIDOMDocument.h"
#include "nsIDOMEventListener.h"
@ -28,7 +29,6 @@
#include "nsITransactionManager.h"
#include "TransactionFactory.h"
#include "nsRepository.h"
//#include "nsISelection.h"
class nsIDOMCharacterData;
class nsIDOMRange;
@ -72,7 +72,7 @@ inline Property::Property(nsIAtom *aPropName, nsIAtom *aValue, PRBool aAppliesTo
* manager, event interfaces. the idea for the event interfaces is to have them
* delegate the actual commands to the editor independent of the XPFE implementation.
*/
class nsEditor : public nsIEditor
class nsEditor : public nsIEditor, public nsIEditorSupport
{
private:
nsIPresShell *mPresShell;
@ -104,6 +104,8 @@ public:
virtual nsresult GetDocument(nsIDOMDocument **aDoc);
virtual nsresult GetSelection(nsIDOMSelection **aSelection);
virtual nsresult SetProperties(nsVoidArray *aPropList);
virtual nsresult GetProperties(nsVoidArray *aPropList);
@ -133,9 +135,7 @@ public:
virtual nsresult DeleteSelection(nsIEditor::Direction aDir);
virtual nsresult SplitNode(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode * aNewLeftNode,
nsIDOMNode * aParent);
PRInt32 aOffset);
virtual nsresult JoinNodes(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
@ -232,10 +232,20 @@ protected:
PRUint32 aOffset,
SplitElementTxn **aTxn);
virtual nsresult SplitNodeImpl(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode * aNewLeftNode,
nsIDOMNode * aParent);
virtual nsresult CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
JoinElementTxn **aTxn);
virtual nsresult JoinNodesImpl(nsIDOMNode * aNodeToKeep,
nsIDOMNode * aNodeToJoin,
nsIDOMNode * aParent,
PRBool aNodeToKeepIsFirst);
#if 0
nsresult CreateTxnToHandleEnterKey(EditAggregateTxn **aTxn);
#endif

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

@ -44,6 +44,7 @@ Editor interface to outside world
{ 0x8f, 0x4c, 0x0, 0x60, 0x8, 0x15, 0x9b, 0xc } }
class nsIDOMDocument;
class nsIDOMSelection;
class nsIPresShell;
class nsString;
@ -79,6 +80,13 @@ public:
*/
virtual nsresult GetDocument(nsIDOMDocument **aDoc)=0;
/**
* return the DOM Selection for the presentation shell that has focus
* (or most recently had focus.)
* @param aSelection [OUT] the dom interface for the selection
*/
virtual nsresult GetSelection(nsIDOMSelection **aSelection)=0;
/**
* SetAttribute() sets the attribute of aElement.
* No checking is done to see if aAttribute is a legal attribute of the node,
@ -168,12 +176,9 @@ public:
* @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;
PRInt32 aOffset)=0;
/**
* JoinNodes() takes 2 nodes and merge their content|children.