Fixed a ton of errors where we were not handling error results correctly.

Added some comments of the form "// XXX: ERROR_HANDLING <explanation>"
wherever I saw a potential error but wasn't 100% sure of the intention of the code.
Fixed a few bugs along the way.
This commit is contained in:
buster%netscape.com 1999-08-19 13:30:48 +00:00
Родитель 8dbe37f8bd
Коммит 3bc5912284
31 изменённых файлов: 5610 добавлений и 4772 удалений

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

@ -35,23 +35,24 @@ NS_IMETHODIMP ChangeAttributeTxn::Init(nsIEditor *aEditor,
const nsString& aValue, const nsString& aValue,
PRBool aRemoveAttribute) PRBool aRemoveAttribute)
{ {
if (nsnull!=aEditor && nsnull!=aElement) NS_ASSERTION(aEditor && aElement, "bad arg");
{ if (!aEditor || !aElement) { return NS_ERROR_NULL_POINTER; }
mEditor = aEditor;
mElement = do_QueryInterface(aElement); mEditor = aEditor;
mAttribute = aAttribute; mElement = do_QueryInterface(aElement);
mValue = aValue; mAttribute = aAttribute;
mRemoveAttribute = aRemoveAttribute; mValue = aValue;
mAttributeWasSet=PR_FALSE; mRemoveAttribute = aRemoveAttribute;
mUndoValue=""; mAttributeWasSet=PR_FALSE;
return NS_OK; mUndoValue="";
} return NS_OK;
else
return NS_ERROR_NULL_POINTER;
} }
NS_IMETHODIMP ChangeAttributeTxn::Do(void) NS_IMETHODIMP ChangeAttributeTxn::Do(void)
{ {
NS_ASSERTION(mEditor && mElement, "bad state");
if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
// need to get the current value of the attribute and save it, and set mAttributeWasSet // need to get the current value of the attribute and save it, and set mAttributeWasSet
nsresult result = mEditor->GetAttributeValue(mElement, mAttribute, mUndoValue, mAttributeWasSet); nsresult result = mEditor->GetAttributeValue(mElement, mAttribute, mUndoValue, mAttributeWasSet);
// XXX: hack until attribute-was-set code is implemented // XXX: hack until attribute-was-set code is implemented
@ -70,6 +71,9 @@ NS_IMETHODIMP ChangeAttributeTxn::Do(void)
NS_IMETHODIMP ChangeAttributeTxn::Undo(void) NS_IMETHODIMP ChangeAttributeTxn::Undo(void)
{ {
NS_ASSERTION(mEditor && mElement, "bad state");
if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result=NS_OK; nsresult result=NS_OK;
if (PR_TRUE==mAttributeWasSet) if (PR_TRUE==mAttributeWasSet)
result = mElement->SetAttribute(mAttribute, mUndoValue); result = mElement->SetAttribute(mAttribute, mUndoValue);
@ -81,6 +85,9 @@ NS_IMETHODIMP ChangeAttributeTxn::Undo(void)
NS_IMETHODIMP ChangeAttributeTxn::Redo(void) NS_IMETHODIMP ChangeAttributeTxn::Redo(void)
{ {
NS_ASSERTION(mEditor && mElement, "bad state");
if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result; nsresult result;
if (PR_FALSE==mRemoveAttribute) if (PR_FALSE==mRemoveAttribute)

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

@ -41,24 +41,21 @@ NS_IMETHODIMP CreateElementTxn::Init(nsIEditor *aEditor,
PRUint32 aOffsetInParent) PRUint32 aOffsetInParent)
{ {
NS_ASSERTION(aEditor&&aParent, "null args"); NS_ASSERTION(aEditor&&aParent, "null args");
if (aEditor && aParent) if (!aEditor || !aParent) { return NS_ERROR_NULL_POINTER; }
{
mEditor = aEditor; mEditor = aEditor;
mTag = aTag; mTag = aTag;
mParent = do_QueryInterface(aParent); mParent = do_QueryInterface(aParent);
mOffsetInParent = aOffsetInParent; mOffsetInParent = aOffsetInParent;
#ifdef NS_DEBUG #ifdef NS_DEBUG
{ {
nsCOMPtr<nsIDOMNodeList> testChildNodes; nsCOMPtr<nsIDOMNodeList> testChildNodes;
nsresult testResult = mParent->GetChildNodes(getter_AddRefs(testChildNodes)); nsresult testResult = mParent->GetChildNodes(getter_AddRefs(testChildNodes));
NS_ASSERTION(testChildNodes, "bad parent type, can't have children."); NS_ASSERTION(testChildNodes, "bad parent type, can't have children.");
NS_ASSERTION(NS_SUCCEEDED(testResult), "bad result."); NS_ASSERTION(NS_SUCCEEDED(testResult), "bad result.");
}
#endif
return NS_OK;
} }
else #endif
return NS_ERROR_NULL_POINTER; return NS_OK;
} }
@ -70,69 +67,69 @@ NS_IMETHODIMP CreateElementTxn::Do(void)
{ {
if (gNoisy) { printf("Do Create Element parent = %p, offset = %d\n", if (gNoisy) { printf("Do Create Element parent = %p, offset = %d\n",
mParent.get(), mOffsetInParent); } mParent.get(), mOffsetInParent); }
NS_ASSERTION(mEditor, "bad state -- null editor"); NS_ASSERTION(mEditor && mParent, "bad state");
nsresult result = NS_ERROR_NULL_POINTER; if (!mEditor || !mParent) return NS_ERROR_NOT_INITIALIZED;
if (mEditor) nsresult result;
// create a new node
nsCOMPtr<nsIDOMDocument>doc;
result = mEditor->GetDocument(getter_AddRefs(doc));
if (NS_FAILED(result)) return result;
if (!doc) return NS_ERROR_NULL_POINTER;
if (nsEditor::GetTextNodeTag() == mTag)
{ {
// create a new node const nsString stringData;
nsCOMPtr<nsIDOMDocument>doc; nsCOMPtr<nsIDOMText>newTextNode;
result = mEditor->GetDocument(getter_AddRefs(doc)); result = doc->CreateTextNode(stringData, getter_AddRefs(newTextNode));
if ((NS_SUCCEEDED(result)) && (doc)) if (NS_FAILED(result)) return result;
if (!newTextNode) return NS_ERROR_NULL_POINTER;
mNewNode = do_QueryInterface(newTextNode);
}
else
{
nsCOMPtr<nsIDOMElement>newElement;
result = doc->CreateElement(mTag, getter_AddRefs(newElement));
if (NS_FAILED(result)) return result;
if (!newElement) return NS_ERROR_NULL_POINTER;
mNewNode = do_QueryInterface(newElement);
}
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewNode)), "could not create element.");
if (!mNewNode) return NS_ERROR_NULL_POINTER;
if (gNoisy) { printf(" newNode = %p\n", mNewNode.get()); }
// insert the new node
nsCOMPtr<nsIDOMNode> resultNode;
if (CreateElementTxn::eAppend==(PRInt32)mOffsetInParent)
{
result = mParent->AppendChild(mNewNode, getter_AddRefs(resultNode));
}
else
{
nsCOMPtr<nsIDOMNodeList> childNodes;
result = mParent->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
{ {
if (nsEditor::GetTextNodeTag() == mTag) PRUint32 count;
childNodes->GetLength(&count);
if (mOffsetInParent>count)
mOffsetInParent = count;
result = childNodes->Item(mOffsetInParent, getter_AddRefs(mRefNode));
if (NS_SUCCEEDED(result)) // note, it's ok for mRefNode to be null. that means append
{ {
const nsString stringData; result = mParent->InsertBefore(mNewNode, mRefNode, getter_AddRefs(resultNode));
nsCOMPtr<nsIDOMText>newTextNode; if (NS_SUCCEEDED(result))
result = doc->CreateTextNode(stringData, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result) && newTextNode) {
mNewNode = do_QueryInterface(newTextNode);
}
}
else
{
nsCOMPtr<nsIDOMElement>newElement;
result = doc->CreateElement(mTag, getter_AddRefs(newElement));
if (NS_SUCCEEDED(result) && newElement) {
mNewNode = do_QueryInterface(newElement);
}
}
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewNode)), "could not create element.");
if ((NS_SUCCEEDED(result)) && (mNewNode))
{
if (gNoisy) { printf(" newNode = %p\n", mNewNode.get()); }
// insert the new node
nsCOMPtr<nsIDOMNode> resultNode;
if (CreateElementTxn::eAppend==(PRInt32)mOffsetInParent)
{ {
result = mParent->AppendChild(mNewNode, getter_AddRefs(resultNode)); nsCOMPtr<nsIDOMSelection> selection;
} result = mEditor->GetSelection(getter_AddRefs(selection));
else if (NS_FAILED(result)) return result;
{ if (!selection) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNodeList> childNodes;
result = mParent->GetChildNodes(getter_AddRefs(childNodes)); PRInt32 offset=0;
if ((NS_SUCCEEDED(result)) && (childNodes)) result = nsEditor::GetChildOffset(mNewNode, mParent, offset);
{ if (NS_FAILED(result)) return result;
PRUint32 count;
childNodes->GetLength(&count); result = selection->Collapse(mParent, offset+1);
if (mOffsetInParent>count) NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert.");
mOffsetInParent = count;
result = childNodes->Item(mOffsetInParent, getter_AddRefs(mRefNode));
if (NS_SUCCEEDED(result)) // note, it's ok for mRefNode to be null. that means append
{
result = mParent->InsertBefore(mNewNode, mRefNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMSelection> selection;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(selectionResult) && selection) {
PRInt32 offset=0;
nsEditor::GetChildOffset(mNewNode, mParent, offset);
selectionResult = selection->Collapse(mParent, offset+1);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after insert.");
}
}
}
}
} }
} }
} }
@ -144,20 +141,24 @@ NS_IMETHODIMP CreateElementTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Create Element, mParent = %p, node = %p\n", if (gNoisy) { printf("Undo Create Element, mParent = %p, node = %p\n",
mParent.get(), mNewNode.get()); } mParent.get(), mNewNode.get()); }
NS_ASSERTION(mEditor && mParent, "bad state");
if (!mEditor || !mParent) return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsIDOMNode> resultNode; nsCOMPtr<nsIDOMNode> resultNode;
nsresult result = mParent->RemoveChild(mNewNode, getter_AddRefs(resultNode)); nsresult result = mParent->RemoveChild(mNewNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result))
{ {
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(selectionResult) && selection) { if (NS_FAILED(result)) return result;
PRInt32 offset=0; if (!selection) return NS_ERROR_NULL_POINTER;
if (mRefNode) {
nsEditor::GetChildOffset(mRefNode, mParent, offset); PRInt32 offset=0;
} if (mRefNode) {
selectionResult = selection->Collapse(mParent, offset); nsEditor::GetChildOffset(mRefNode, mParent, offset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert.");
} }
result = selection->Collapse(mParent, offset);
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
} }
return result; return result;
} }
@ -165,6 +166,8 @@ NS_IMETHODIMP CreateElementTxn::Undo(void)
NS_IMETHODIMP CreateElementTxn::Redo(void) NS_IMETHODIMP CreateElementTxn::Redo(void)
{ {
if (gNoisy) { printf("Redo Create Element\n"); } if (gNoisy) { printf("Redo Create Element\n"); }
NS_ASSERTION(mEditor && mParent, "bad state");
if (!mEditor || !mParent) return NS_ERROR_NOT_INITIALIZED;
// first, reset mNewNode so it has no attributes or content // first, reset mNewNode so it has no attributes or content
nsCOMPtr<nsIDOMCharacterData>nodeAsText; nsCOMPtr<nsIDOMCharacterData>nodeAsText;
@ -182,12 +185,12 @@ NS_IMETHODIMP CreateElementTxn::Redo(void)
{ {
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result) && selection) { if (NS_FAILED(result)) return result;
PRInt32 offset=0; if (!selection) return NS_ERROR_NULL_POINTER;
nsEditor::GetChildOffset(mNewNode, mParent, offset); PRInt32 offset=0;
nsresult selectionResult = selection->Collapse(mParent, offset); nsEditor::GetChildOffset(mNewNode, mParent, offset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert."); result = selection->Collapse(mParent, offset);
} NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
} }
return result; return result;
} }

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

@ -51,16 +51,11 @@ DeleteElementTxn::~DeleteElementTxn()
NS_IMETHODIMP DeleteElementTxn::Do(void) NS_IMETHODIMP DeleteElementTxn::Do(void)
{ {
if (gNoisy) { printf("%p Do Delete Element element = %p\n", this, mElement.get()); } if (gNoisy) { printf("%p Do Delete Element element = %p\n", this, mElement.get()); }
if (!mElement) if (!mElement) return NS_ERROR_NOT_INITIALIZED;
return NS_ERROR_NULL_POINTER;
nsresult result = mElement->GetParentNode(getter_AddRefs(mParent)); nsresult result = mElement->GetParentNode(getter_AddRefs(mParent));
if (NS_FAILED(result)) { if (NS_FAILED(result)) { return result; }
return result; if (!mParent) { return NS_OK; } // this is a no-op, there's no parent to delete mElement from
}
if (!mParent) {
return NS_OK; // this is a no-op, there's no parent to delete mElement from
}
#ifdef NS_DEBUG #ifdef NS_DEBUG
// begin debug output // begin debug output

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

@ -46,21 +46,22 @@ DeleteRangeTxn::DeleteRangeTxn()
NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange) NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
{ {
if (aEditor && aRange) NS_ASSERTION(aEditor && aRange, "bad state");
{ if (!aEditor || !aRange) { return NS_ERROR_NOT_INITIALIZED; }
mEditor = aEditor;
mRange = do_QueryInterface(aRange);
nsresult result = aRange->GetStartParent(getter_AddRefs(mStartParent)); mEditor = aEditor;
NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartParent failed."); mRange = do_QueryInterface(aRange);
result = aRange->GetEndParent(getter_AddRefs(mEndParent));
NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndParent failed."); nsresult result = aRange->GetStartParent(getter_AddRefs(mStartParent));
result = aRange->GetStartOffset(&mStartOffset); NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartParent failed.");
NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartOffset failed."); result = aRange->GetEndParent(getter_AddRefs(mEndParent));
result = aRange->GetEndOffset(&mEndOffset); NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndParent failed.");
NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndOffset failed."); result = aRange->GetStartOffset(&mStartOffset);
result = aRange->GetCommonParent(getter_AddRefs(mCommonParent)); NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartOffset failed.");
NS_ASSERTION((NS_SUCCEEDED(result)), "GetCommonParent failed."); result = aRange->GetEndOffset(&mEndOffset);
NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndOffset failed.");
result = aRange->GetCommonParent(getter_AddRefs(mCommonParent));
NS_ASSERTION((NS_SUCCEEDED(result)), "GetCommonParent failed.");
#ifdef NS_DEBUG #ifdef NS_DEBUG
{ {
@ -96,10 +97,8 @@ NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
} }
} }
#endif #endif
return result; return result;
}
else
return NS_ERROR_NULL_POINTER;
} }
DeleteRangeTxn::~DeleteRangeTxn() DeleteRangeTxn::~DeleteRangeTxn()
@ -109,11 +108,10 @@ DeleteRangeTxn::~DeleteRangeTxn()
NS_IMETHODIMP DeleteRangeTxn::Do(void) NS_IMETHODIMP DeleteRangeTxn::Do(void)
{ {
if (gNoisy) { printf("Do Delete Range\n"); } if (gNoisy) { printf("Do Delete Range\n"); }
if (!mStartParent || !mEndParent || !mCommonParent) if (!mStartParent || !mEndParent || !mCommonParent || !mEditor)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NOT_INITIALIZED;
nsresult result; nsresult result;
// build the child transactions // build the child transactions
if (mStartParent==mEndParent) if (mStartParent==mEndParent)
@ -145,9 +143,9 @@ NS_IMETHODIMP DeleteRangeTxn::Do(void)
// set the resulting selection // set the resulting selection
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) { if (NS_FAILED(result)) return result;
result = selection->Collapse(mStartParent, mStartOffset); if (!selection) return NS_ERROR_NULL_POINTER;
} result = selection->Collapse(mStartParent, mStartOffset);
} }
return result; return result;
@ -156,19 +154,21 @@ NS_IMETHODIMP DeleteRangeTxn::Do(void)
NS_IMETHODIMP DeleteRangeTxn::Undo(void) NS_IMETHODIMP DeleteRangeTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Delete Range\n"); } if (gNoisy) { printf("Undo Delete Range\n"); }
if (!mStartParent || !mEndParent || !mCommonParent) if (!mStartParent || !mEndParent || !mCommonParent || !mEditor)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NOT_INITIALIZED;
nsresult result = EditAggregateTxn::Undo(); nsresult result = EditAggregateTxn::Undo();
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result))
{
// set the resulting selection // set the resulting selection
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) { if (NS_FAILED(result)) return result;
selection->Collapse(mStartParent, mStartOffset); if (!selection) return NS_ERROR_NULL_POINTER;
selection->Extend(mEndParent, mEndOffset); result = selection->Collapse(mStartParent, mStartOffset);
} if (NS_FAILED(result)) return result;
result = selection->Extend(mEndParent, mEndOffset);
} }
return result; return result;
@ -177,8 +177,8 @@ NS_IMETHODIMP DeleteRangeTxn::Undo(void)
NS_IMETHODIMP DeleteRangeTxn::Redo(void) NS_IMETHODIMP DeleteRangeTxn::Redo(void)
{ {
if (gNoisy) { printf("Redo Delete Range\n"); } if (gNoisy) { printf("Redo Delete Range\n"); }
if (!mStartParent || !mEndParent || !mCommonParent) if (!mStartParent || !mEndParent || !mCommonParent || !mEditor)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NOT_INITIALIZED;
nsresult result = EditAggregateTxn::Redo(); nsresult result = EditAggregateTxn::Redo();
@ -186,9 +186,9 @@ NS_IMETHODIMP DeleteRangeTxn::Redo(void)
// set the resulting selection // set the resulting selection
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) { if (NS_FAILED(result)) return result;
result = selection->Collapse(mStartParent, mStartOffset); if (!selection) return NS_ERROR_NULL_POINTER;
} result = selection->Collapse(mStartParent, mStartOffset);
} }
return result; return result;
@ -224,9 +224,10 @@ NS_IMETHODIMP DeleteRangeTxn::GetRedoString(nsString *aString)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent, NS_IMETHODIMP
PRUint32 aStartOffset, DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent,
PRUint32 aEndOffset) PRUint32 aStartOffset,
PRUint32 aEndOffset)
{ {
nsresult result; nsresult result;
// see what kind of node we have // see what kind of node we have
@ -236,44 +237,42 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent
{ // if the node is a text node, then delete text content { // if the node is a text node, then delete text content
DeleteTextTxn *txn; DeleteTextTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn); result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn);
if (nsnull!=txn) if (NS_FAILED(result)) return result;
{ if (!txn) return NS_ERROR_NULL_POINTER;
PRInt32 numToDel;
if (aStartOffset==aEndOffset) PRInt32 numToDel;
numToDel = 1; if (aStartOffset==aEndOffset)
else numToDel = 1;
numToDel = aEndOffset-aStartOffset; else
txn->Init(mEditor, textNode, aStartOffset, numToDel); numToDel = aEndOffset-aStartOffset;
AppendChild(txn); txn->Init(mEditor, textNode, aStartOffset, numToDel);
} AppendChild(txn);
} }
else else
{ {
PRUint32 childCount; PRUint32 childCount;
nsCOMPtr<nsIDOMNodeList> children; nsCOMPtr<nsIDOMNodeList> children;
result = aStartParent->GetChildNodes(getter_AddRefs(children)); result = aStartParent->GetChildNodes(getter_AddRefs(children));
if ((NS_SUCCEEDED(result)) && children) if (NS_FAILED(result)) return result;
if (!children) return NS_ERROR_NULL_POINTER;
children->GetLength(&childCount);
NS_ASSERTION(aEndOffset<=childCount, "bad aEndOffset");
PRUint32 i;
for (i=aStartOffset; i<aEndOffset; i++)
{ {
children->GetLength(&childCount); nsCOMPtr<nsIDOMNode> child;
NS_ASSERTION(aEndOffset<=childCount, "bad aEndOffset"); result = children->Item(i, getter_AddRefs(child));
PRUint32 i; if (NS_FAILED(result)) return result;
for (i=aStartOffset; i<aEndOffset; i++) if (!child) return NS_ERROR_NULL_POINTER;
{
nsCOMPtr<nsIDOMNode> child; DeleteElementTxn *txn;
result = children->Item(i, getter_AddRefs(child)); result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn);
if ((NS_SUCCEEDED(result)) && child) if (NS_FAILED(result)) return result;
{ if (!txn) return NS_ERROR_NULL_POINTER;
DeleteElementTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn); txn->Init(child);
if (nsnull!=txn) AppendChild(txn);
{
txn->Init(child);
AppendChild(txn);
}
else
return NS_ERROR_NULL_POINTER;
}
}
} }
} }
return result; return result;
@ -306,13 +305,11 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteContent(nsIDOMNode *aParent,
{ {
DeleteTextTxn *txn; DeleteTextTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn); result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn);
if (nsnull!=txn) if (NS_FAILED(result)) return result;
{ if (!txn) return NS_ERROR_NULL_POINTER;
txn->Init(mEditor, textNode, start, numToDelete);
AppendChild(txn); txn->Init(mEditor, textNode, start, numToDelete);
} AppendChild(txn);
else
return NS_ERROR_NULL_POINTER;
} }
} }
@ -332,11 +329,11 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteNodesBetween()
nsnull, nsnull,
nsIContentIterator::GetIID(), nsIContentIterator::GetIID(),
getter_AddRefs(iter)); getter_AddRefs(iter));
if (!NS_SUCCEEDED(result)) if (NS_FAILED(result)) return result;
return result; if (!iter) return NS_ERROR_NULL_POINTER;
result = iter->Init(mRange); result = iter->Init(mRange);
if (!NS_SUCCEEDED(result)) if (NS_FAILED(result)) return result;
return result;
while (NS_COMFALSE == iter->IsDone()) while (NS_COMFALSE == iter->IsDone())
{ {
@ -344,18 +341,16 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteNodesBetween()
nsCOMPtr<nsIContent> content; nsCOMPtr<nsIContent> content;
result = iter->CurrentNode(getter_AddRefs(content)); result = iter->CurrentNode(getter_AddRefs(content));
node = do_QueryInterface(content); node = do_QueryInterface(content);
if ((NS_SUCCEEDED(result)) && node) if (NS_FAILED(result)) return result;
{ if (!node) return NS_ERROR_NULL_POINTER;
DeleteElementTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn); DeleteElementTxn *txn;
if (nsnull!=txn) result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn);
{ if (NS_FAILED(result)) return result;
txn->Init(node); if (!txn) return NS_ERROR_NULL_POINTER;
AppendChild(txn);
} txn->Init(node);
else AppendChild(txn);
return NS_ERROR_NULL_POINTER;
}
iter->Next(); iter->Next();
} }
return result; return result;

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

@ -41,6 +41,8 @@ NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
PRUint32 aNumCharsToDelete) PRUint32 aNumCharsToDelete)
{ {
NS_ASSERTION(aEditor&&aElement, "bad arg"); NS_ASSERTION(aEditor&&aElement, "bad arg");
if (!aEditor || !aElement) { return NS_ERROR_NULL_POINTER; }
mEditor = aEditor; mEditor = aEditor;
mElement = do_QueryInterface(aElement); mElement = do_QueryInterface(aElement);
mOffset = aOffset; mOffset = aOffset;
@ -57,22 +59,20 @@ NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
NS_IMETHODIMP DeleteTextTxn::Do(void) NS_IMETHODIMP DeleteTextTxn::Do(void)
{ {
if (gNoisy) { printf("Do Delete Text\n"); } if (gNoisy) { printf("Do Delete Text\n"); }
nsresult result = NS_ERROR_NULL_POINTER; NS_ASSERTION(mEditor && mElement, "bad state");
if (mEditor && mElement) if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
// get the text that we're about to delete
nsresult result = mElement->SubstringData(mOffset, mNumCharsToDelete, mDeletedText);
NS_ASSERTION(NS_SUCCEEDED(result), "could not get text to delete.");
result = mElement->DeleteData(mOffset, mNumCharsToDelete);
if (NS_SUCCEEDED(result))
{ {
// get the text that we're about to delete nsCOMPtr<nsIDOMSelection> selection;
result = mElement->SubstringData(mOffset, mNumCharsToDelete, mDeletedText); result = mEditor->GetSelection(getter_AddRefs(selection));
NS_ASSERTION(NS_SUCCEEDED(result), "could not get text to delete."); if (NS_FAILED(result)) return result;
result = mElement->DeleteData(mOffset, mNumCharsToDelete); if (!selection) return NS_ERROR_NULL_POINTER;
if (NS_SUCCEEDED(result)) result = selection->Collapse(mElement, mOffset);
{ NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
nsCOMPtr<nsIDOMSelection> selection;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(selectionResult) && selection) {
selectionResult = selection->Collapse(mElement, mOffset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert.");
}
}
} }
return result; return result;
} }
@ -82,19 +82,19 @@ NS_IMETHODIMP DeleteTextTxn::Do(void)
NS_IMETHODIMP DeleteTextTxn::Undo(void) NS_IMETHODIMP DeleteTextTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Delete Text\n"); } if (gNoisy) { printf("Undo Delete Text\n"); }
nsresult result = NS_ERROR_NULL_POINTER; NS_ASSERTION(mEditor && mElement, "bad state");
if (mEditor && mElement) if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result;
result = mElement->InsertData(mOffset, mDeletedText);
if (NS_SUCCEEDED(result))
{ {
result = mElement->InsertData(mOffset, mDeletedText); nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(result)) nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection));
{ if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMSelection> selection; if (!selection) return NS_ERROR_NULL_POINTER;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection)); result = selection->Collapse(mElement, mOffset);
if (NS_SUCCEEDED(selectionResult) && selection) { NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
selectionResult = selection->Collapse(mElement, mOffset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert.");
}
}
} }
return result; return result;
} }

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

@ -64,8 +64,7 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
printf("%p Do Insert Element of %p into parent %p at offset %d\n", printf("%p Do Insert Element of %p into parent %p at offset %d\n",
this, nodeAsContent.get(), parentAsContent.get(), mOffset); this, nodeAsContent.get(), parentAsContent.get(), mOffset);
} }
if (!mNode || !mParent) if (!mNode || !mParent) return NS_ERROR_NOT_INITIALIZED;
return NS_ERROR_NULL_POINTER;
nsresult result; nsresult result;
nsCOMPtr<nsIDOMNode>refNode; nsCOMPtr<nsIDOMNode>refNode;
@ -92,16 +91,16 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
nsCOMPtr<nsIDOMNode> resultNode; nsCOMPtr<nsIDOMNode> resultNode;
result = mParent->InsertBefore(mNode, refNode, getter_AddRefs(resultNode)); result = mParent->InsertBefore(mNode, refNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result) && resultNode) if (NS_FAILED(result)) return result;
{ if (!resultNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); nsCOMPtr<nsIDOMSelection> selection;
if ((NS_SUCCEEDED(result)) && selection) result = mEditor->GetSelection(getter_AddRefs(selection));
{ // place the selection just after the inserted element if (NS_FAILED(result)) return result;
selection->Collapse(mParent, mOffset+1); if (!selection) return NS_ERROR_NULL_POINTER;
//selection->Extend(mParent, mOffset+1); // place the selection just after the inserted element
} selection->Collapse(mParent, mOffset+1);
} //selection->Extend(mParent, mOffset+1);
return result; return result;
} }
@ -109,8 +108,7 @@ NS_IMETHODIMP InsertElementTxn::Undo(void)
{ {
if (gNoisy) { printf("%p Undo Insert Element of %p into parent %p at offset %d\n", if (gNoisy) { printf("%p Undo Insert Element of %p into parent %p at offset %d\n",
this, mNode.get(), mParent.get(), mOffset); } this, mNode.get(), mParent.get(), mOffset); }
if (!mNode || !mParent) if (!mNode || !mParent) return NS_ERROR_NOT_INITIALIZED;
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> resultNode; nsCOMPtr<nsIDOMNode> resultNode;
nsresult result = mParent->RemoveChild(mNode, getter_AddRefs(resultNode)); nsresult result = mParent->RemoveChild(mNode, getter_AddRefs(resultNode));

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

@ -62,6 +62,9 @@ NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
printf("\n"); printf("\n");
#endif #endif
NS_ASSERTION(aElement&&aPresShell, "bad args");
if (!aElement || !aPresShell) return NS_ERROR_NULL_POINTER;
mElement = do_QueryInterface(aElement); mElement = do_QueryInterface(aElement);
mOffset = aOffset; mOffset = aOffset;
mStringToInsert = aStringToInsert; mStringToInsert = aStringToInsert;
@ -72,16 +75,19 @@ NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
NS_IMETHODIMP InsertTextTxn::Do(void) NS_IMETHODIMP InsertTextTxn::Do(void)
{ {
if (gNoisy) { printf("Do Insert Text element = %p\n", mElement.get()); } if (gNoisy) { printf("Do Insert Text element = %p\n", mElement.get()); }
NS_ASSERTION(mElement && mPresShell, "bad state");
if (!mElement || !mPresShell) { return NS_ERROR_NOT_INITIALIZED; }
// advance caret: This requires the presentation shell to get the selection. // advance caret: This requires the presentation shell to get the selection.
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
nsresult result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)); nsresult result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection));
NS_ASSERTION(selection,"Could not get selection in InsertTextTxn::Do\n"); if (NS_FAILED(result)) return result;
if (NS_SUCCEEDED(result) && selection) { if (!selection) return NS_ERROR_NULL_POINTER;
result = mElement->InsertData(mOffset, mStringToInsert); result = mElement->InsertData(mOffset, mStringToInsert);
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result))
result = selection->Collapse(mElement, mOffset+mStringToInsert.Length()); {
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert."); result = selection->Collapse(mElement, mOffset+mStringToInsert.Length());
} NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert.");
} }
return result; return result;
} }
@ -89,6 +95,9 @@ NS_IMETHODIMP InsertTextTxn::Do(void)
NS_IMETHODIMP InsertTextTxn::Undo(void) NS_IMETHODIMP InsertTextTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Insert Text element = %p\n", mElement.get()); } if (gNoisy) { printf("Undo Insert Text element = %p\n", mElement.get()); }
NS_ASSERTION(mElement && mPresShell, "bad state");
if (!mElement || !mPresShell) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result; nsresult result;
PRUint32 length = mStringToInsert.Length(); PRUint32 length = mStringToInsert.Length();
result = mElement->DeleteData(mOffset, length); result = mElement->DeleteData(mOffset, length);
@ -96,10 +105,10 @@ NS_IMETHODIMP InsertTextTxn::Undo(void)
{ // set the selection to the insertion point where the string was removed { // set the selection to the insertion point where the string was removed
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)); result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection));
if (NS_SUCCEEDED(result) && selection) { if (NS_FAILED(result)) return result;
result = selection->Collapse(mElement, mOffset); if (!selection) return NS_ERROR_NULL_POINTER;
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert."); result = selection->Collapse(mElement, mOffset);
} NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
} }
return result; return result;
} }

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

@ -37,6 +37,8 @@ NS_IMETHODIMP JoinElementTxn::Init(nsIEditor *aEditor,
nsIDOMNode *aLeftNode, nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode) nsIDOMNode *aRightNode)
{ {
NS_PRECONDITION((aEditor && aLeftNode && aRightNode), "null arg");
if (!aEditor || !aLeftNode || !aRightNode) { return NS_ERROR_NULL_POINTER; }
mEditor = aEditor; mEditor = aEditor;
mLeftNode = do_QueryInterface(aLeftNode); mLeftNode = do_QueryInterface(aLeftNode);
mRightNode = do_QueryInterface(aRightNode); mRightNode = do_QueryInterface(aRightNode);
@ -52,54 +54,54 @@ JoinElementTxn::~JoinElementTxn()
NS_IMETHODIMP JoinElementTxn::Do(void) NS_IMETHODIMP JoinElementTxn::Do(void)
{ {
if (gNoisy) { printf("%p Do Join of %p and %p\n", this, mLeftNode.get(), mRightNode.get()); } if (gNoisy) { printf("%p Do Join of %p and %p\n", this, mLeftNode.get(), mRightNode.get()); }
nsresult result; NS_PRECONDITION((mEditor && mLeftNode && mRightNode), "null arg");
if (!mEditor || !mLeftNode || !mRightNode) { return NS_ERROR_NOT_INITIALIZED; }
if ((mLeftNode) && (mRightNode)) // get the parent node
{ // get the parent node nsCOMPtr<nsIDOMNode>leftParent;
nsCOMPtr<nsIDOMNode>leftParent; nsresult result = mLeftNode->GetParentNode(getter_AddRefs(leftParent));
result = mLeftNode->GetParentNode(getter_AddRefs(leftParent)); if (NS_FAILED(result)) return result;
if ((NS_SUCCEEDED(result)) && (leftParent)) if (!leftParent) return NS_ERROR_NULL_POINTER;
{ // verify that mLeftNode and mRightNode have the same parent
nsCOMPtr<nsIDOMNode>rightParent; // verify that mLeftNode and mRightNode have the same parent
result = mRightNode->GetParentNode(getter_AddRefs(rightParent)); nsCOMPtr<nsIDOMNode>rightParent;
if ((NS_SUCCEEDED(result)) && (rightParent)) result = mRightNode->GetParentNode(getter_AddRefs(rightParent));
{ if (NS_FAILED(result)) return result;
if (leftParent==rightParent) if (!rightParent) return NS_ERROR_NULL_POINTER;
{
mParent= do_QueryInterface(leftParent); // set this instance mParent. if (leftParent==rightParent)
// Other methods will see a non-null mParent and know all is well {
nsCOMPtr<nsIDOMNodeList> childNodes; mParent= do_QueryInterface(leftParent); // set this instance mParent.
result = mLeftNode->GetChildNodes(getter_AddRefs(childNodes)); // Other methods will see a non-null mParent and know all is well
if ((NS_SUCCEEDED(result)) && (childNodes)) { nsCOMPtr<nsIDOMNodeList> childNodes;
childNodes->GetLength(&mOffset); result = mLeftNode->GetChildNodes(getter_AddRefs(childNodes));
} if (NS_FAILED(result)) return result;
else if (childNodes) {
{ childNodes->GetLength(&mOffset);
nsCOMPtr<nsIDOMCharacterData> leftNodeAsText; }
leftNodeAsText = do_QueryInterface(mLeftNode); else
if (leftNodeAsText) { {
leftNodeAsText->GetLength(&mOffset); nsCOMPtr<nsIDOMCharacterData> leftNodeAsText;
} leftNodeAsText = do_QueryInterface(mLeftNode);
} if (leftNodeAsText) {
result = nsEditor::JoinNodesImpl(mRightNode, mLeftNode, mParent, PR_FALSE); leftNodeAsText->GetLength(&mOffset);
if (NS_SUCCEEDED(result))
{
if (gNoisy) { printf(" left node = %p removed\n", mLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (selection)
{
selection->Collapse(mRightNode, mOffset);
}
}
}
else
{
NS_ASSERTION(PR_FALSE, "2 nodes do not have same parent");
return NS_ERROR_INVALID_ARG;
}
} }
} }
result = nsEditor::JoinNodesImpl(mRightNode, mLeftNode, mParent, PR_FALSE);
if (NS_SUCCEEDED(result))
{
if (gNoisy) { printf(" left node = %p removed\n", mLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result)) return result;
if (!selection) return NS_ERROR_NULL_POINTER;
selection->Collapse(mRightNode, mOffset);
}
}
else
{
NS_ASSERTION(PR_FALSE, "2 nodes do not have same parent");
return NS_ERROR_INVALID_ARG;
} }
return result; return result;
} }
@ -110,9 +112,7 @@ NS_IMETHODIMP JoinElementTxn::Undo(void)
{ {
if (gNoisy) { printf("%p Undo Join, right node = %p\n", this, mRightNode.get()); } if (gNoisy) { printf("%p Undo Join, right node = %p\n", this, mRightNode.get()); }
NS_ASSERTION(mRightNode && mLeftNode && mParent, "bad state"); NS_ASSERTION(mRightNode && mLeftNode && mParent, "bad state");
if (!mRightNode || !mLeftNode || !mParent) { if (!mRightNode || !mLeftNode || !mParent) { return NS_ERROR_NOT_INITIALIZED; }
return NS_ERROR_NOT_INITIALIZED;
}
nsresult result; nsresult result;
nsCOMPtr<nsIDOMNode>resultNode; nsCOMPtr<nsIDOMNode>resultNode;
// first, massage the existing node so it is in its post-split state // first, massage the existing node so it is in its post-split state

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

@ -39,6 +39,9 @@ NS_IMETHODIMP SplitElementTxn::Init(nsIEditor *aEditor,
nsIDOMNode *aNode, nsIDOMNode *aNode,
PRInt32 aOffset) PRInt32 aOffset)
{ {
NS_ASSERTION(aEditor && aNode, "bad args");
if (!aEditor || !aNode) { return NS_ERROR_NOT_INITIALIZED; }
mEditor = aEditor; mEditor = aEditor;
mExistingRightNode = do_QueryInterface(aNode); mExistingRightNode = do_QueryInterface(aNode);
mOffset = aOffset; mOffset = aOffset;
@ -52,36 +55,33 @@ SplitElementTxn::~SplitElementTxn()
NS_IMETHODIMP SplitElementTxn::Do(void) NS_IMETHODIMP SplitElementTxn::Do(void)
{ {
if (gNoisy) { printf("%p Do Split of node %p offset %d\n", this, mExistingRightNode.get(), mOffset); } if (gNoisy) { printf("%p Do Split of node %p offset %d\n", this, mExistingRightNode.get(), mOffset); }
NS_ASSERTION(mExistingRightNode, "bad state"); NS_ASSERTION(mExistingRightNode && mEditor, "bad state");
if (!mExistingRightNode) { if (!mExistingRightNode || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
return NS_ERROR_NOT_INITIALIZED;
}
// create a new node // create a new node
nsresult result = mExistingRightNode->CloneNode(PR_FALSE, getter_AddRefs(mNewLeftNode)); nsresult result = mExistingRightNode->CloneNode(PR_FALSE, getter_AddRefs(mNewLeftNode));
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element."); NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element.");
if (NS_FAILED(result)) return result;
if (!mNewLeftNode) return NS_ERROR_NULL_POINTER;
if ((NS_SUCCEEDED(result)) && (mNewLeftNode)) if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); }
// get the parent node
result = mExistingRightNode->GetParentNode(getter_AddRefs(mParent));
if (NS_FAILED(result)) return result;
if (!mParent) return NS_ERROR_NULL_POINTER;
// insert the new node
result = nsEditor::SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
if (NS_SUCCEEDED(result) && mNewLeftNode)
{ {
if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); } nsCOMPtr<nsIDOMSelection>selection;
// get the parent node mEditor->GetSelection(getter_AddRefs(selection));
result = mExistingRightNode->GetParentNode(getter_AddRefs(mParent)); if (NS_FAILED(result)) return result;
// insert the new node if (!selection) return NS_ERROR_NULL_POINTER;
if ((NS_SUCCEEDED(result)) && (mParent)) result = selection->Collapse(mNewLeftNode, mOffset);
{ }
result = nsEditor::SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent); else {
if (NS_SUCCEEDED(result) && mNewLeftNode) result = NS_ERROR_NOT_IMPLEMENTED;
{
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (selection)
{
selection->Collapse(mNewLeftNode, mOffset);
}
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
}
} }
return result; return result;
} }
@ -92,8 +92,8 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
printf("%p Undo Split of existing node %p and new node %p offset %d\n", printf("%p Undo Split of existing node %p and new node %p offset %d\n",
this, mExistingRightNode.get(), mNewLeftNode.get(), mOffset); this, mExistingRightNode.get(), mNewLeftNode.get(), mOffset);
} }
NS_ASSERTION(mExistingRightNode && mNewLeftNode && mParent, "bad state"); NS_ASSERTION(mEditor && mExistingRightNode && mNewLeftNode && mParent, "bad state");
if (!mExistingRightNode || !mNewLeftNode || !mParent) { if (!mEditor || !mExistingRightNode || !mNewLeftNode || !mParent) {
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
} }
@ -110,10 +110,9 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
if (gNoisy) { printf(" left node = %p removed\n", mNewLeftNode.get()); } if (gNoisy) { printf(" left node = %p removed\n", mNewLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection; nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection)); mEditor->GetSelection(getter_AddRefs(selection));
if (selection) if (NS_FAILED(result)) return result;
{ if (!selection) return NS_ERROR_NULL_POINTER;
selection->Collapse(mExistingRightNode, mOffset); result = selection->Collapse(mExistingRightNode, mOffset);
}
} }
else { else {
result = NS_ERROR_NOT_IMPLEMENTED; result = NS_ERROR_NOT_IMPLEMENTED;
@ -126,8 +125,8 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
*/ */
NS_IMETHODIMP SplitElementTxn::Redo(void) NS_IMETHODIMP SplitElementTxn::Redo(void)
{ {
NS_ASSERTION(mExistingRightNode && mNewLeftNode && mParent, "bad state"); NS_ASSERTION(mEditor && mExistingRightNode && mNewLeftNode && mParent, "bad state");
if (!mExistingRightNode || !mNewLeftNode || !mParent) { if (!mEditor || !mExistingRightNode || !mNewLeftNode || !mParent) {
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
} }
if (gNoisy) { if (gNoisy) {
@ -146,7 +145,7 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
if (gNoisy) if (gNoisy)
{ {
printf("** after delete of text in right text node %p offset %d\n", rightNodeAsText.get(), mOffset); printf("** after delete of text in right text node %p offset %d\n", rightNodeAsText.get(), mOffset);
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG mEditor->DebugDumpContent(); // DEBUG
} }
} }
else else

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

@ -239,6 +239,7 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
// disable links // disable links
nsCOMPtr<nsIPresContext> context; nsCOMPtr<nsIPresContext> context;
mPresShell->GetPresContext(getter_AddRefs(context)); mPresShell->GetPresContext(getter_AddRefs(context));
if (!context) return NS_ERROR_NULL_POINTER;
context->SetLinkHandler(0); context->SetLinkHandler(0);
// Set up the DTD // Set up the DTD
@ -252,9 +253,9 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
if (!mEditProperty) {return NS_ERROR_NULL_POINTER;} if (!mEditProperty) {return NS_ERROR_NULL_POINTER;}
mPresShell->GetViewManager(&mViewManager); mPresShell->GetViewManager(&mViewManager);
if (mViewManager){ if (!mViewManager) {return NS_ERROR_NULL_POINTER;}
mViewManager->Release(); //we want a weak link mViewManager->Release(); //we want a weak link
}
mPresShell->SetDisplayNonTextSelection(PR_TRUE);//we want to see all the selection reflected to user mPresShell->SetDisplayNonTextSelection(PR_TRUE);//we want to see all the selection reflected to user
mUpdateCount=0; mUpdateCount=0;
InsertTextTxn::ClassInit(); InsertTextTxn::ClassInit();
@ -267,22 +268,25 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
mIMEBufferLength = 0; mIMEBufferLength = 0;
/* Show the caret */ /* Show the caret */
// XXX: I suppose it's legal to fail to get a caret, so don't propogate the
// result of GetCaret
nsCOMPtr<nsICaret> caret; nsCOMPtr<nsICaret> caret;
if (NS_SUCCEEDED(mPresShell->GetCaret(getter_AddRefs(caret))) && caret) if (NS_SUCCEEDED(mPresShell->GetCaret(getter_AddRefs(caret))) && caret)
{ {
caret->SetCaretVisible(PR_TRUE); caret->SetCaretVisible(PR_TRUE);
caret->SetCaretReadOnly(PR_FALSE); caret->SetCaretReadOnly(PR_FALSE);
} }
// NOTE: We don't fail if we can't get prefs or string bundles // NOTE: We don't fail if we can't get prefs or string bundles
// since we could still be used as the text edit widget without prefs // since we could still be used as the text edit widget without prefs
// Get the prefs service (Note: can't use nsCOMPtr for service pointers) // Get the prefs service (Note: can't use nsCOMPtr for service pointers)
result = nsServiceManager::GetService(kPrefCID, nsresult ignoredResult = nsServiceManager::GetService(kPrefCID,
nsIPref::GetIID(), nsIPref::GetIID(),
(nsISupports**)&mPrefs); (nsISupports**)&mPrefs);
if (NS_FAILED(result) || !mPrefs) if (NS_FAILED(ignoredResult) || !mPrefs)
{ {
printf("ERROR: Failed to get Prefs Service instance.\n"); if (gNoisy) { printf("ERROR: Failed to get Prefs Service instance.\n");}
} }
// TODO: Cache basic preferences? // TODO: Cache basic preferences?
@ -290,20 +294,21 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
// respond to while running // respond to while running
nsIStringBundleService* service; nsIStringBundleService* service;
result = nsServiceManager::GetService(kStringBundleServiceCID, ignoredResult = nsServiceManager::GetService(kStringBundleServiceCID,
nsIStringBundleService::GetIID(), nsIStringBundleService::GetIID(),
(nsISupports**)&service); (nsISupports**)&service);
if (NS_SUCCEEDED(result) && service) if (NS_SUCCEEDED(ignoredResult) && service)
{ {
nsILocale* locale = nsnull; nsILocale* locale = nsnull;
result = service->CreateBundle(EDITOR_BUNDLE_URL, locale, ignoredResult = service->CreateBundle(EDITOR_BUNDLE_URL, locale,
getter_AddRefs(mStringBundle)); getter_AddRefs(mStringBundle));
// We don't need to keep service around once we created the bundle // We don't need to keep service around once we created the bundle
nsServiceManager::ReleaseService(kStringBundleServiceCID, service); nsServiceManager::ReleaseService(kStringBundleServiceCID, service);
} else { } else {
printf("ERROR: Failed to get StringBundle Service instance.\n"); if (gNoisy) printf("ERROR: Failed to get StringBundle Service instance.\n");
} }
/* /*
Example of getting a string: Example of getting a string:
nsString value; nsString value;
@ -374,8 +379,8 @@ NS_IMETHODIMP nsEditor::SaveDocument(PRBool saveAs, PRBool saveCopy)
// get the document // get the document
nsCOMPtr<nsIDOMDocument> doc; nsCOMPtr<nsIDOMDocument> doc;
rv = GetDocument(getter_AddRefs(doc)); rv = GetDocument(getter_AddRefs(doc));
if (NS_FAILED(rv) || !doc) if (NS_FAILED(rv)) return rv;
return rv; if (!doc) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(doc); nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(doc);
if (!diskDoc) if (!diskDoc)
@ -1238,7 +1243,6 @@ nsEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivateTex
return result; return result;
} }
#ifdef XP_MAC #ifdef XP_MAC
#pragma mark - #pragma mark -
#pragma mark --- public nsEditor methods --- #pragma mark --- public nsEditor methods ---

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

@ -387,7 +387,7 @@ public:
* @param aNodeToKeep The node that will remain after the join. * @param aNodeToKeep The node that will remain after the join.
* @param aNodeToJoin The node that will be joined with aNodeToKeep. * @param aNodeToJoin The node that will be joined with aNodeToKeep.
* There is no requirement that the two nodes be of the same type. * There is no requirement that the two nodes be of the same type.
* @param aParent The parent of aExistingRightNode * @param aParent The parent of aNodeToKeep
* @param aNodeToKeepIsFirst if PR_TRUE, the contents|children of aNodeToKeep come before the * @param aNodeToKeepIsFirst if PR_TRUE, the contents|children of aNodeToKeep come before the
* contents|children of aNodeToJoin, otherwise their positions are switched. * contents|children of aNodeToJoin, otherwise their positions are switched.
*/ */

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

@ -47,12 +47,18 @@
#include "nsIDragSession.h" #include "nsIDragSession.h"
#include "nsITransferable.h" #include "nsITransferable.h"
#include "nsIFormatConverter.h" #include "nsIFormatConverter.h"
#include "nsIContentIterator.h"
#include "nsIContent.h"
#include "nsLayoutCID.h"
// Drag & Drop, Clipboard Support // Drag & Drop, Clipboard Support
static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID); static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID);
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID); static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
static NS_DEFINE_IID(kCDataFlavorCID, NS_DATAFLAVOR_CID); static NS_DEFINE_IID(kCDataFlavorCID, NS_DATAFLAVOR_CID);
static NS_DEFINE_IID(kCXIFFormatConverterCID, NS_XIFFORMATCONVERTER_CID); static NS_DEFINE_IID(kContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
static NS_DEFINE_IID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID);
/* /*
@ -116,8 +122,7 @@ nsresult
nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent) nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
{ {
PRUint32 keyCode; PRUint32 keyCode;
PRBool isShift; PRBool isShift, ctrlKey, altKey, metaKey;
PRBool ctrlKey;
nsCOMPtr<nsIDOMUIEvent>uiEvent; nsCOMPtr<nsIDOMUIEvent>uiEvent;
uiEvent = do_QueryInterface(aKeyEvent); uiEvent = do_QueryInterface(aKeyEvent);
@ -126,87 +131,87 @@ nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
return NS_OK; return NS_OK;
} }
if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode)) && PRBool keyProcessed;
NS_SUCCEEDED(uiEvent->GetShiftKey(&isShift)) && ProcessShortCutKeys(aKeyEvent, keyProcessed);
NS_SUCCEEDED(uiEvent->GetCtrlKey(&ctrlKey)) if (PR_FALSE==keyProcessed)
) { {
PRBool keyProcessed; if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode)) &&
ProcessShortCutKeys(aKeyEvent, keyProcessed); NS_SUCCEEDED(uiEvent->GetShiftKey(&isShift)) &&
if (PR_FALSE==keyProcessed) NS_SUCCEEDED(uiEvent->GetCtrlKey(&ctrlKey)) &&
{ NS_SUCCEEDED(uiEvent->GetAltKey(&altKey)) &&
switch(keyCode) { NS_SUCCEEDED(uiEvent->GetMetaKey(&metaKey)))
// case nsIDOMUIEvent::VK_BACK: {
// mEditor->DeleteSelection(nsIEditor::eDeleteLeft); {
// break; switch(keyCode) {
// case nsIDOMUIEvent::VK_BACK:
// mEditor->DeleteSelection(nsIEditor::eDeleteLeft);
// break;
case nsIDOMUIEvent::VK_DELETE: case nsIDOMUIEvent::VK_DELETE:
mEditor->DeleteSelection(nsIEditor::eDeleteNext); mEditor->DeleteSelection(nsIEditor::eDeleteNext);
break; break;
// case nsIDOMUIEvent::VK_RETURN: // case nsIDOMUIEvent::VK_RETURN:
//case nsIDOMUIEvent::VK_ENTER: // why does this not exist? //case nsIDOMUIEvent::VK_ENTER: // why does this not exist?
// Need to implement creation of either <P> or <BR> nodes. // Need to implement creation of either <P> or <BR> nodes.
// mEditor->InsertBreak(); // mEditor->InsertBreak();
// break; // break;
case nsIDOMUIEvent::VK_LEFT: case nsIDOMUIEvent::VK_LEFT:
case nsIDOMUIEvent::VK_RIGHT: case nsIDOMUIEvent::VK_RIGHT:
case nsIDOMUIEvent::VK_UP: case nsIDOMUIEvent::VK_UP:
case nsIDOMUIEvent::VK_DOWN: case nsIDOMUIEvent::VK_DOWN:
// these have already been handled in nsRangeList. Why are we getting them // these have already been handled in nsRangeList. Why are we getting them
// again here (Mac)? In switch to avoid putting in bogus chars. // again here (Mac)? In switch to avoid putting in bogus chars.
//return NS_OK to allow page scrolling. //return NS_OK to allow page scrolling.
return NS_OK; return NS_OK;
break; break;
case nsIDOMUIEvent::VK_HOME: case nsIDOMUIEvent::VK_HOME:
case nsIDOMUIEvent::VK_END: case nsIDOMUIEvent::VK_END:
// who handles these? // who handles these?
#if DEBUG #if DEBUG
printf("Key not handled\n"); printf("Key not handled\n");
#endif #endif
return NS_OK; return NS_OK;
break; break;
case nsIDOMUIEvent::VK_PAGE_UP: case nsIDOMUIEvent::VK_PAGE_UP:
case nsIDOMUIEvent::VK_PAGE_DOWN: case nsIDOMUIEvent::VK_PAGE_DOWN:
//return NS_OK to allow page scrolling. //return NS_OK to allow page scrolling.
return NS_OK; return NS_OK;
break; break;
case nsIDOMUIEvent::VK_TAB: case nsIDOMUIEvent::VK_TAB:
{ {
PRUint32 flags=0; PRUint32 flags=0;
mEditor->GetFlags(&flags); mEditor->GetFlags(&flags);
if (! (flags & nsIHTMLEditor::eEditorSingleLineMask)) if (! (flags & nsIHTMLEditor::eEditorSingleLineMask))
{ {
PRBool ctrlKey, altKey, metaKey; if (metaKey || altKey)
uiEvent->GetCtrlKey(&ctrlKey); return NS_OK; // don't consume
uiEvent->GetAltKey(&altKey); // else we insert the tab straight through
uiEvent->GetMetaKey(&metaKey); nsAutoString key;
if (metaKey || altKey) key += keyCode;
return NS_OK; // don't consume
// else we insert the tab straight through
nsAutoString key;
key += keyCode;
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor); nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
if (htmlEditor) if (htmlEditor)
htmlEditor->InsertText(key); htmlEditor->InsertText(key);
return NS_ERROR_BASE; // this means "I handled the event, don't do default processing" return NS_ERROR_BASE; // this means "I handled the event, don't do default processing"
} }
else { else {
return NS_OK; return NS_OK;
} }
break; break;
} }
default: default:
return NS_OK; // this indicates that we have not handled the keyDown event in any way. return NS_OK; // this indicates that we have not handled the keyDown event in any way.
} }
} }
} }
}
return NS_ERROR_BASE; return NS_ERROR_BASE;
} }
@ -238,19 +243,20 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
// eaiser // eaiser
// //
PRBool ctrlKey, altKey, metaKey; PRBool ctrlKey, altKey, metaKey;
uiEvent->GetCtrlKey(&ctrlKey); uiEvent->GetCtrlKey(&ctrlKey);
uiEvent->GetAltKey(&altKey); uiEvent->GetAltKey(&altKey);
uiEvent->GetMetaKey(&metaKey); uiEvent->GetMetaKey(&metaKey);
if (metaKey)
return NS_OK; // don't consume
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor); if (metaKey)
if (!htmlEditor) return NS_ERROR_NO_INTERFACE; return NS_OK; // don't consume
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
if (!htmlEditor) return NS_ERROR_NO_INTERFACE;
if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode))) if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode)))
{ {
if (nsIDOMUIEvent::VK_BACK==keyCode) { if (nsIDOMUIEvent::VK_BACK==keyCode) {
mEditor->DeleteSelection(nsIEditor::eDeletePrevious); mEditor->DeleteSelection(nsIEditor::eDeletePrevious);
return NS_ERROR_BASE; // consumed return NS_ERROR_BASE; // consumed
} }
@ -261,14 +267,14 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
} }
if ((PR_FALSE==altKey) && (PR_FALSE==ctrlKey) && if ((PR_FALSE==altKey) && (PR_FALSE==ctrlKey) &&
(NS_SUCCEEDED(uiEvent->GetCharCode(&character)))) (NS_SUCCEEDED(uiEvent->GetCharCode(&character))))
{ {
if (nsIDOMUIEvent::VK_TAB==character) { if (nsIDOMUIEvent::VK_TAB==character) {
return NS_OK; // ignore tabs here, they're handled in keyDown if at all return NS_OK; // ignore tabs here, they're handled in keyDown if at all
} }
key += character; key += character;
htmlEditor->InsertText(key); htmlEditor->InsertText(key);
} }
return NS_ERROR_BASE; // consumed return NS_ERROR_BASE; // consumed
@ -843,6 +849,62 @@ nsTextEditorMouseListener::HandleEvent(nsIDOMEvent* aEvent)
// XXX: evil global functions, move them to proper support module
nsresult
IsNodeInSelection(nsIDOMNode *aInNode, nsIDOMSelection *aInSelection, PRBool &aOutIsInSel)
{
aOutIsInSel = PR_FALSE; // init out-param
if (!aInNode || !aInSelection) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIContentIterator>iter;
nsresult result = nsComponentManager::CreateInstance(kContentIteratorCID, nsnull,
nsIContentIterator::GetIID(),
getter_AddRefs(iter));
if (NS_FAILED(result)) { return result; }
if (!iter) { return NS_ERROR_OUT_OF_MEMORY; }
nsCOMPtr<nsIEnumerator> enumerator;
result = aInSelection->GetEnumerator(getter_AddRefs(enumerator));
if (NS_FAILED(result)) { return result; }
if (!enumerator) { return NS_ERROR_OUT_OF_MEMORY; }
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
{
nsCOMPtr<nsISupports> currentItem;
result = enumerator->CurrentItem(getter_AddRefs(currentItem));
if ((NS_SUCCEEDED(result)) && (currentItem))
{
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
iter->Init(range);
nsCOMPtr<nsIContent> currentContent;
iter->CurrentNode(getter_AddRefs(currentContent));
while (NS_COMFALSE == iter->IsDone())
{
nsCOMPtr<nsIDOMNode>currentNode = do_QueryInterface(currentContent);
if (currentNode.get()==aInNode)
{
// if it's a start or end node, need to test whether the (x,y)
// of the event falls within the selection
// talk to Mike
aOutIsInSel = PR_TRUE;
return NS_OK;
}
/* do not check result here, and especially do not return the result code.
* we rely on iter->IsDone to tell us when the iteration is complete
*/
iter->Next();
iter->CurrentNode(getter_AddRefs(currentContent));
}
}
}
return NS_OK;
}
nsresult nsresult
nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
{ {
@ -856,49 +918,141 @@ nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK; return NS_OK;
} }
// We only do anything special for middle-mouse click (paste); nsCOMPtr<nsIEditor> editor (do_QueryInterface(mEditor));
// ignore all other events. if (!editor) { return NS_OK; }
// get the document
nsCOMPtr<nsIDOMDocument>domDoc;
editor->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) { return NS_OK; }
nsCOMPtr<nsIDocument>doc = do_QueryInterface(domDoc);
if (!doc) { return NS_OK; }
PRUint16 button = 0; PRUint16 button = 0;
uiEvent->GetButton(&button); uiEvent->GetButton(&button);
if (button != 2) // left button click might be a drag-start
return NS_OK; if (1==button)
{
#ifndef EXPERIMENTAL_DRAG_CODE
return NS_OK;
#else
nsString XIFBuffer;
// get the DOM select here
nsCOMPtr<nsIDOMSelection> sel;
editor->GetSelection(getter_AddRefs(sel));
nsCOMPtr<nsIEditor> editor (do_QueryInterface(mEditor)); // convert the DOMselection to XIF
if (!editor) if (sel)
return NS_ERROR_FAILURE; {
// if we are within the selection, start the drag
// Set the selection to the point under the mouse cursor: nsCOMPtr<nsIDOMNode> target;
nsCOMPtr<nsIDOMNSUIEvent> mouseEvent (do_QueryInterface(aMouseEvent)); nsresult rv = aMouseEvent->GetTarget(getter_AddRefs(target));
if (NS_FAILED(rv) || !target) { return NS_OK; }
PRBool isInSel;
rv = IsNodeInSelection(target, sel, isInSel);
if (NS_FAILED(rv) || PR_FALSE==isInSel) { return NS_OK; }
doc->CreateXIF(XIFBuffer, sel);
if (!mouseEvent) // Get the Clipboard
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event". nsIClipboard* clipboard;
nsCOMPtr<nsIDOMNode> parent; rv = nsServiceManager::GetService(kCClipboardCID,
if (!NS_SUCCEEDED(mouseEvent->GetRangeParent(getter_AddRefs(parent)))) nsIClipboard::GetIID(),
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event". (nsISupports **)&clipboard);
PRInt32 offset = 0; if (NS_OK == rv)
if (!NS_SUCCEEDED(mouseEvent->GetRangeOffset(&offset))) {
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event". // Create a data flavor to tell the transferable
// that it is about to receive XIF
nsAutoString flavor(kXIFMime);
nsCOMPtr<nsIDOMSelection> selection; // Create a transferable for putting data on the Clipboard
if (NS_SUCCEEDED(editor->GetSelection(getter_AddRefs(selection)))) nsCOMPtr<nsITransferable> trans;
(void)selection->Collapse(parent, offset); rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
nsITransferable::GetIID(),
(void**) getter_AddRefs(trans));
if (NS_OK == rv) {
// The data on the clipboard will be in "XIF" format
// so give the clipboard transferable a "XIFConverter" for
// converting from XIF to other formats
nsCOMPtr<nsIFormatConverter> xifConverter;
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
nsIFormatConverter::GetIID(), (void**) getter_AddRefs(xifConverter));
if (NS_OK == rv) {
// Add the XIF DataFlavor to the transferable
// this tells the transferable that it can handle receiving the XIF format
trans->AddDataFlavor(&flavor);
// If the ctrl key is pressed, we'll do paste as quotation. // Add the converter for going from XIF to other formats
// Would've used the alt key, but the kde wmgr treats alt-middle specially. trans->SetConverter(xifConverter);
PRBool ctrlKey = PR_FALSE;
uiEvent->GetCtrlKey(&ctrlKey);
if (ctrlKey) // Now add the XIF data to the transferable
{ // the transferable wants the number bytes for the data and since it is double byte
nsCOMPtr<nsIEditorMailSupport> mailEditor = do_QueryInterface(mEditor); // we multiply by 2
if (mailEditor) trans->SetTransferData(&flavor, XIFBuffer.ToNewUnicode(), XIFBuffer.Length()*2);
mailEditor->PasteAsQuotation();
// Now invoke the drag session
nsIDragService* dragService;
nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
nsIDragService::GetIID(),
(nsISupports **)&dragService);
if (NS_OK == rv) {
nsCOMPtr<nsISupportsArray> items;
NS_NewISupportsArray(getter_AddRefs(items));
if ( items ) {
items->AppendElement(trans);
dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE);
}
nsServiceManager::ReleaseService(kCDragServiceCID, dragService);
}
}
}
nsServiceManager::ReleaseService(kCClipboardCID, clipboard);
}
return NS_ERROR_BASE; // return that we've handled the event
}
#endif
} }
return editor->Paste(); // middle-mouse click (paste);
else if (button == 2)
{
// Set the selection to the point under the mouse cursor:
nsCOMPtr<nsIDOMNSUIEvent> mouseEvent (do_QueryInterface(aMouseEvent));
if (!mouseEvent)
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
nsCOMPtr<nsIDOMNode> parent;
if (!NS_SUCCEEDED(mouseEvent->GetRangeParent(getter_AddRefs(parent))))
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
PRInt32 offset = 0;
if (!NS_SUCCEEDED(mouseEvent->GetRangeOffset(&offset)))
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(editor->GetSelection(getter_AddRefs(selection))))
(void)selection->Collapse(parent, offset);
// If the ctrl key is pressed, we'll do paste as quotation.
// Would've used the alt key, but the kde wmgr treats alt-middle specially.
PRBool ctrlKey = PR_FALSE;
uiEvent->GetCtrlKey(&ctrlKey);
if (ctrlKey)
{
nsCOMPtr<nsIEditorMailSupport> mailEditor = do_QueryInterface(mEditor);
if (mailEditor)
mailEditor->PasteAsQuotation();
}
editor->Paste();
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
}
return NS_OK; // did not process the event
} }
nsresult nsresult
nsTextEditorMouseListener::MouseUp(nsIDOMEvent* aMouseEvent) nsTextEditorMouseListener::MouseUp(nsIDOMEvent* aMouseEvent)
{ {
@ -1425,9 +1579,6 @@ nsTextEditorFocusListener::HandleEvent(nsIDOMEvent* aEvent)
nsresult nsresult
nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent) nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
{ {
// turn on selection and caret
if (mEditor)
{
// turn on selection and caret // turn on selection and caret
if (mEditor) if (mEditor)
{ {
@ -1474,8 +1625,6 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
} }
return NS_OK; return NS_OK;
} }
return NS_OK;
}
nsresult nsresult
nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent) nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -192,7 +192,15 @@ protected:
virtual void InitRules(); virtual void InitRules();
NS_IMETHOD GetLayoutObject(nsIDOMNode *aNode, nsISupports **aLayoutObject); /** returns the layout object (nsIFrame in the real world) for aNode
* @param aNode the content to get a frame for
* @param aLayoutObject the "primary frame" for aNode, if one exists. May be null
* @return NS_OK whether a frame is found or not
* an error if some serious error occurs
*/
NS_IMETHOD GetLayoutObject(nsIDOMNode *aInNode, nsISupports **aOutLayoutObject);
NS_IMETHOD CollapseAdjacentTextNodes(nsIDOMSelection *aInSelection);
NS_IMETHOD DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode); NS_IMETHOD DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode);
@ -382,10 +390,10 @@ protected:
const nsString *aAttribute, const nsString *aAttribute,
const nsString *aValue); const nsString *aValue);
void GetTextSelectionOffsetsForRange(nsIDOMSelection *aSelection, NS_IMETHOD GetTextSelectionOffsetsForRange(nsIDOMSelection *aSelection,
nsIDOMNode **aParent, nsIDOMNode **aParent,
PRInt32 &aStartOffset, PRInt32 &aStartOffset,
PRInt32 &aEndOffset); PRInt32 &aEndOffset);
void ResetTextSelectionForRange(nsIDOMNode *aParent, void ResetTextSelectionForRange(nsIDOMNode *aParent,
PRInt32 aStartOffset, PRInt32 aStartOffset,

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

@ -104,11 +104,10 @@ nsTextEditRules::SetFlags(PRUint32 aFlags)
// put a "white-space: pre" style on the body // put a "white-space: pre" style on the body
nsCOMPtr<nsIDOMElement> bodyElement; nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
if (NS_SUCCEEDED(res) && bodyElement) if (NS_FAILED(res)) return res;
{ if (!bodyElement) return NS_ERROR_NULL_POINTER;
// not going through the editor to do this. // not going through the editor to do this.
bodyElement->SetAttribute("style", "white-space: pre"); bodyElement->SetAttribute("style", "white-space: pre");
}
} }
} }
mFlags = aFlags; mFlags = aFlags;
@ -394,7 +393,9 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
// splitting anchor twice sets newTextNode as an empty text node between // splitting anchor twice sets newTextNode as an empty text node between
// two halves of the original text node // two halves of the original text node
result = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode)); result = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
result = mEditor->SplitNode(anchorAsText, 0, getter_AddRefs(newTextNode)); if (NS_SUCCEEDED(result)) {
result = mEditor->SplitNode(anchorAsText, 0, getter_AddRefs(newTextNode));
}
} }
} }
// now we have the new text node we are going to insert into. // now we have the new text node we are going to insert into.
@ -464,37 +465,30 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
} }
else // we have no selection, so insert a style tag in the body else // we have no selection, so insert a style tag in the body
{ {
nsCOMPtr<nsIDOMDocument>doc; nsCOMPtr<nsIDOMElement> bodyElement;
mEditor->GetDocument(getter_AddRefs(doc)); nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
nsCOMPtr<nsIDOMNodeList>nodeList; if (NS_FAILED(res)) return res;
nsAutoString bodyTag = "body"; if (!bodyElement) return NS_ERROR_NULL_POINTER;
result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
if ((NS_SUCCEEDED(result)) && nodeList) nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
{ if (bodyNode)
PRUint32 count; { // now we've got the body tag. insert the style tag
nodeList->GetLength(&count); if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!"); {
nsCOMPtr<nsIDOMNode>bodyNode; if (PR_TRUE==aTypeInState.GetBold()) {
result = nodeList->Item(0, getter_AddRefs(bodyNode)); InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
if ((NS_SUCCEEDED(result)) && bodyNode)
{ // now we've got the body tag. insert the style tag
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
{
if (PR_TRUE==aTypeInState.GetBold()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
}
} }
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC)) }
{ if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
if (PR_TRUE==aTypeInState.GetItalic()) { {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection); if (PR_TRUE==aTypeInState.GetItalic()) {
} InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection);
} }
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE)) }
{ if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
if (PR_TRUE==aTypeInState.GetUnderline()) { {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::u, aSelection); if (PR_TRUE==aTypeInState.GetUnderline()) {
} InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::u, aSelection);
} }
} }
} }
@ -513,12 +507,11 @@ nsTextEditRules::CreateFontStyleForInsertText(nsIDOMNode *aNewTextNode,
if (0!=aValue.Length()) if (0!=aValue.Length())
{ {
result = InsertStyleNode(aNewTextNode, nsIEditProperty::font, aSelection, getter_AddRefs(newStyleNode)); result = InsertStyleNode(aNewTextNode, nsIEditProperty::font, aSelection, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result) && newStyleNode) if (NS_FAILED(result)) return result;
{ if (!newStyleNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement>element = do_QueryInterface(newStyleNode); nsCOMPtr<nsIDOMElement>element = do_QueryInterface(newStyleNode);
if (element) { if (element) {
result = mEditor->SetAttribute(element, aAttr, aValue); result = mEditor->SetAttribute(element, aAttr, aValue);
}
} }
} }
else else
@ -540,21 +533,26 @@ nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode,
nsresult result; nsresult result;
nsCOMPtr<nsIDOMNode>parent; nsCOMPtr<nsIDOMNode>parent;
aNode->GetParentNode(getter_AddRefs(parent)); aNode->GetParentNode(getter_AddRefs(parent));
if (NS_FAILED(result)) return result;
if (!parent) return NS_ERROR_NULL_POINTER;
PRInt32 offsetInParent; PRInt32 offsetInParent;
nsEditor::GetChildOffset(aNode, parent, offsetInParent); result = nsEditor::GetChildOffset(aNode, parent, offsetInParent);
if (NS_FAILED(result)) return result;
nsAutoString tag; nsAutoString tag;
aTag->ToString(tag); aTag->ToString(tag);
result = mEditor->CreateNode(tag, parent, offsetInParent, aNewNode); result = mEditor->CreateNode(tag, parent, offsetInParent, aNewNode);
if ((NS_SUCCEEDED(result)) && *aNewNode) if (NS_FAILED(result)) return result;
if (!aNewNode) return NS_ERROR_NULL_POINTER;
result = mEditor->DeleteNode(aNode);
if (NS_SUCCEEDED(result))
{ {
result = mEditor->DeleteNode(aNode); result = mEditor->InsertNode(aNode, *aNewNode, 0);
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result)) {
{ if (aSelection) {
result = mEditor->InsertNode(aNode, *aNewNode, 0); result = aSelection->Collapse(aNode, 0);
if (NS_SUCCEEDED(result)) {
if (aSelection) {
aSelection->Collapse(aNode, 0);
}
} }
} }
} }
@ -575,16 +573,17 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
nsCOMPtr<nsIDOMNode>anchor; nsCOMPtr<nsIDOMNode>anchor;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(anchor)); result = aSelection->GetAnchorNode(getter_AddRefs(anchor));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && anchor) if (NS_FAILED(result)) return result;
if (!anchor) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMCharacterData>anchorAsText;
anchorAsText = do_QueryInterface(anchor);
if (anchorAsText)
{ {
nsCOMPtr<nsIDOMCharacterData>anchorAsText; nsCOMPtr<nsIDOMNode> newStyleNode;
anchorAsText = do_QueryInterface(anchor); result = InsertStyleNode(anchor, aTag, aSelection, getter_AddRefs(newStyleNode));
if (anchorAsText) return result;
{
nsCOMPtr<nsIDOMNode> newStyleNode;
result = InsertStyleNode(anchor, aTag, aSelection, getter_AddRefs(newStyleNode));
return result;
}
} }
} }
// if we get here, there is no selected text node so we create one. // if we get here, there is no selected text node so we create one.
@ -593,15 +592,15 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
nsCOMPtr<nsIDOMNode>newStyleNode; nsCOMPtr<nsIDOMNode>newStyleNode;
nsCOMPtr<nsIDOMNode>newTextNode; nsCOMPtr<nsIDOMNode>newTextNode;
result = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode)); result = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result)) if (NS_FAILED(result)) return result;
{ if (!newStyleNode) return NS_ERROR_NULL_POINTER;
result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result)) result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
{ if (NS_FAILED(result)) return result;
if (aSelection) { if (!newTextNode) return NS_ERROR_NULL_POINTER;
aSelection->Collapse(newTextNode, 0);
} if (aSelection) {
} result = aSelection->Collapse(newTextNode, 0);
} }
return result; return result;
} }
@ -707,55 +706,63 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection,
nsCOMPtr<nsIDOMNode>anchor; nsCOMPtr<nsIDOMNode>anchor;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(anchor)); result = aSelection->GetAnchorNode(getter_AddRefs(anchor));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && anchor) if (NS_FAILED(result)) return result;
if (!anchor) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMNodeList> anchorChildren;
result = anchor->GetChildNodes(getter_AddRefs(anchorChildren));
nsCOMPtr<nsIDOMNode> selectedNode;
if ((NS_SUCCEEDED(result)) && anchorChildren) {
result = anchorChildren->Item(offset, getter_AddRefs(selectedNode));
}
else {
selectedNode = do_QueryInterface(anchor);
}
if ((NS_SUCCEEDED(result)) && selectedNode)
{ {
nsCOMPtr<nsIDOMNodeList> anchorChildren; nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText;
result = anchor->GetChildNodes(getter_AddRefs(anchorChildren)); selectedNodeAsText = do_QueryInterface(selectedNode);
nsCOMPtr<nsIDOMNode> selectedNode; if (selectedNodeAsText)
if ((NS_SUCCEEDED(result)) && anchorChildren) {
result = anchorChildren->Item(offset, getter_AddRefs(selectedNode));
}
else {
selectedNode = do_QueryInterface(anchor);
}
if ((NS_SUCCEEDED(result)) && selectedNode)
{ {
nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText; nsCOMPtr<nsIDOMNode> siblingNode;
selectedNodeAsText = do_QueryInterface(selectedNode); selectedNode->GetPreviousSibling(getter_AddRefs(siblingNode));
if (selectedNodeAsText) if (siblingNode)
{ {
nsCOMPtr<nsIDOMNode> siblingNode; nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
selectedNode->GetPreviousSibling(getter_AddRefs(siblingNode)); siblingNodeAsText = do_QueryInterface(siblingNode);
if (siblingNode) if (siblingNodeAsText)
{ {
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText; PRUint32 siblingLength; // the length of siblingNode before the join
siblingNodeAsText = do_QueryInterface(siblingNode); siblingNodeAsText->GetLength(&siblingLength);
if (siblingNodeAsText) nsCOMPtr<nsIDOMNode> parentNode;
{ result = selectedNode->GetParentNode(getter_AddRefs(parentNode));
PRUint32 siblingLength; // the length of siblingNode before the join if (NS_FAILED(result)) return result;
siblingNodeAsText->GetLength(&siblingLength); if (!parentNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parentNode; result = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
selectedNode->GetParentNode(getter_AddRefs(parentNode)); // selectedNode will remain after the join, siblingNode is removed
result = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
// selectedNode will remain after the join, siblingNode is removed
}
} }
selectedNode->GetNextSibling(getter_AddRefs(siblingNode)); }
if (siblingNode) selectedNode->GetNextSibling(getter_AddRefs(siblingNode));
if (siblingNode)
{
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
siblingNodeAsText = do_QueryInterface(siblingNode);
if (siblingNodeAsText)
{ {
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText; PRUint32 selectedNodeLength; // the length of siblingNode before the join
siblingNodeAsText = do_QueryInterface(siblingNode); selectedNodeAsText->GetLength(&selectedNodeLength);
if (siblingNodeAsText) nsCOMPtr<nsIDOMNode> parentNode;
{ result = selectedNode->GetParentNode(getter_AddRefs(parentNode));
PRUint32 selectedNodeLength; // the length of siblingNode before the join if (NS_FAILED(result)) return result;
selectedNodeAsText->GetLength(&selectedNodeLength); if (!parentNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parentNode;
selectedNode->GetParentNode(getter_AddRefs(parentNode)); result = mEditor->JoinNodes(selectedNode, siblingNode, parentNode);
result = mEditor->JoinNodes(selectedNode, siblingNode, parentNode); if (NS_FAILED(result)) return result;
// selectedNode will remain after the join, siblingNode is removed // selectedNode will remain after the join, siblingNode is removed
// set selection // set selection
aSelection->Collapse(siblingNode, selectedNodeLength); result = aSelection->Collapse(siblingNode, selectedNodeLength);
}
} }
} }
} }
@ -795,23 +802,24 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
nsCOMPtr<nsIDOMNode>node; nsCOMPtr<nsIDOMNode>node;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(node)); result = aSelection->GetAnchorNode(getter_AddRefs(node));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && node) if (NS_FAILED(result)) return result;
if (!node) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMElement>element;
element = do_QueryInterface(node);
if (element)
{ {
nsCOMPtr<nsIDOMElement>element; nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
element = do_QueryInterface(node); nsAutoString val;
if (element) (void)element->GetAttribute(att, val);
{ if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); mBogusNode = do_QueryInterface(element);
nsAutoString val;
(void)element->GetAttribute(att, val);
if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
mBogusNode = do_QueryInterface(element);
}
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
} }
return result; return result;
@ -842,23 +850,24 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
nsCOMPtr<nsIDOMNode>node; nsCOMPtr<nsIDOMNode>node;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(node)); result = aSelection->GetAnchorNode(getter_AddRefs(node));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && node) if (NS_FAILED(result)) return result;
if (!node) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMElement>element;
element = do_QueryInterface(node);
if (element)
{ {
nsCOMPtr<nsIDOMElement>element; nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
element = do_QueryInterface(node); nsAutoString val;
if (element) (void)element->GetAttribute(att, val);
{ if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); mBogusNode = do_QueryInterface(element);
nsAutoString val;
(void)element->GetAttribute(att, val);
if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
mBogusNode = do_QueryInterface(element);
}
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
} }
return result; return result;
@ -895,86 +904,63 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection)
{ {
if (!aSelection) { return NS_ERROR_NULL_POINTER; } if (!aSelection) { return NS_ERROR_NULL_POINTER; }
if (!mEditor) { return NS_ERROR_NULL_POINTER; } if (!mEditor) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIDOMDocument>doc;
mEditor->GetDocument(getter_AddRefs(doc)); nsCOMPtr<nsIDOMElement> bodyElement;
nsCOMPtr<nsIDOMNodeList>nodeList; nsresult result = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
nsAutoString bodyTag = "body"; if (NS_FAILED(result)) return result;
nsresult result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList)); if (!bodyElement) return NS_ERROR_NULL_POINTER;
if ((NS_SUCCEEDED(result)) && nodeList) nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
// now we've got the body tag.
// iterate the body tag, looking for editable content
// if no editable content is found, insert the bogus node
PRBool needsBogusContent=PR_TRUE;
nsCOMPtr<nsIDOMNode>bodyChild;
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
while ((NS_SUCCEEDED(result)) && bodyChild)
{ {
PRUint32 count; if (PR_TRUE==mEditor->IsEditable(bodyChild))
nodeList->GetLength(&count); {
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!"); needsBogusContent = PR_FALSE;
nsCOMPtr<nsIDOMNode>bodyNode; break;
result = nodeList->Item(0, getter_AddRefs(bodyNode)); }
if ((NS_SUCCEEDED(result)) && bodyNode) nsCOMPtr<nsIDOMNode>temp;
{ // now we've got the body tag. bodyChild->GetNextSibling(getter_AddRefs(temp));
// iterate the body tag, looking for editable content bodyChild = do_QueryInterface(temp);
// if no editable content is found, insert the bogus node }
PRBool needsBogusContent=PR_TRUE; if (PR_TRUE==needsBogusContent)
nsCOMPtr<nsIDOMNode>bodyChild; {
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild)); // set mBogusNode to be the newly created <P>
while ((NS_SUCCEEDED(result)) && bodyChild) result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0,
{ getter_AddRefs(mBogusNode));
if (PR_TRUE==mEditor->IsEditable(bodyChild)) if (NS_FAILED(result)) return result;
{ if (!mBogusNode) return NS_ERROR_NULL_POINTER;
needsBogusContent = PR_FALSE;
break; nsCOMPtr<nsIDOMNode>newTNode;
} result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), mBogusNode, 0,
nsCOMPtr<nsIDOMNode>temp; getter_AddRefs(newTNode));
bodyChild->GetNextSibling(getter_AddRefs(temp)); if (NS_FAILED(result)) return result;
bodyChild = do_QueryInterface(temp); if (!newTNode) return NS_ERROR_NULL_POINTER;
}
if (PR_TRUE==needsBogusContent) nsCOMPtr<nsIDOMCharacterData>newNodeAsText;
{ newNodeAsText = do_QueryInterface(newTNode);
// set mBogusNode to be the newly created <P> if (newNodeAsText)
result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0, {
getter_AddRefs(mBogusNode)); nsAutoString data;
if ((NS_SUCCEEDED(result)) && mBogusNode) data += 160;
{ newNodeAsText->SetData(data);
nsCOMPtr<nsIDOMNode>newTNode; aSelection->Collapse(newTNode, 0);
result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), mBogusNode, 0, }
getter_AddRefs(newTNode)); // make sure we know the PNode is bogus
if ((NS_SUCCEEDED(result)) && newTNode) nsCOMPtr<nsIDOMElement>newPElement;
{ newPElement = do_QueryInterface(mBogusNode);
nsCOMPtr<nsIDOMCharacterData>newNodeAsText; if (newPElement)
newNodeAsText = do_QueryInterface(newTNode); {
if (newNodeAsText) nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
{ nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
nsAutoString data; newPElement->SetAttribute(att, val);
data += 160;
newNodeAsText->SetData(data);
aSelection->Collapse(newTNode, 0);
}
}
// make sure we know the PNode is bogus
nsCOMPtr<nsIDOMElement>newPElement;
newPElement = do_QueryInterface(mBogusNode);
if (newPElement)
{
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
newPElement->SetAttribute(att, val);
}
}
}
} }
} }
return result; return result;
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -35,23 +35,24 @@ NS_IMETHODIMP ChangeAttributeTxn::Init(nsIEditor *aEditor,
const nsString& aValue, const nsString& aValue,
PRBool aRemoveAttribute) PRBool aRemoveAttribute)
{ {
if (nsnull!=aEditor && nsnull!=aElement) NS_ASSERTION(aEditor && aElement, "bad arg");
{ if (!aEditor || !aElement) { return NS_ERROR_NULL_POINTER; }
mEditor = aEditor;
mElement = do_QueryInterface(aElement); mEditor = aEditor;
mAttribute = aAttribute; mElement = do_QueryInterface(aElement);
mValue = aValue; mAttribute = aAttribute;
mRemoveAttribute = aRemoveAttribute; mValue = aValue;
mAttributeWasSet=PR_FALSE; mRemoveAttribute = aRemoveAttribute;
mUndoValue=""; mAttributeWasSet=PR_FALSE;
return NS_OK; mUndoValue="";
} return NS_OK;
else
return NS_ERROR_NULL_POINTER;
} }
NS_IMETHODIMP ChangeAttributeTxn::Do(void) NS_IMETHODIMP ChangeAttributeTxn::Do(void)
{ {
NS_ASSERTION(mEditor && mElement, "bad state");
if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
// need to get the current value of the attribute and save it, and set mAttributeWasSet // need to get the current value of the attribute and save it, and set mAttributeWasSet
nsresult result = mEditor->GetAttributeValue(mElement, mAttribute, mUndoValue, mAttributeWasSet); nsresult result = mEditor->GetAttributeValue(mElement, mAttribute, mUndoValue, mAttributeWasSet);
// XXX: hack until attribute-was-set code is implemented // XXX: hack until attribute-was-set code is implemented
@ -70,6 +71,9 @@ NS_IMETHODIMP ChangeAttributeTxn::Do(void)
NS_IMETHODIMP ChangeAttributeTxn::Undo(void) NS_IMETHODIMP ChangeAttributeTxn::Undo(void)
{ {
NS_ASSERTION(mEditor && mElement, "bad state");
if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result=NS_OK; nsresult result=NS_OK;
if (PR_TRUE==mAttributeWasSet) if (PR_TRUE==mAttributeWasSet)
result = mElement->SetAttribute(mAttribute, mUndoValue); result = mElement->SetAttribute(mAttribute, mUndoValue);
@ -81,6 +85,9 @@ NS_IMETHODIMP ChangeAttributeTxn::Undo(void)
NS_IMETHODIMP ChangeAttributeTxn::Redo(void) NS_IMETHODIMP ChangeAttributeTxn::Redo(void)
{ {
NS_ASSERTION(mEditor && mElement, "bad state");
if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result; nsresult result;
if (PR_FALSE==mRemoveAttribute) if (PR_FALSE==mRemoveAttribute)

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

@ -41,24 +41,21 @@ NS_IMETHODIMP CreateElementTxn::Init(nsIEditor *aEditor,
PRUint32 aOffsetInParent) PRUint32 aOffsetInParent)
{ {
NS_ASSERTION(aEditor&&aParent, "null args"); NS_ASSERTION(aEditor&&aParent, "null args");
if (aEditor && aParent) if (!aEditor || !aParent) { return NS_ERROR_NULL_POINTER; }
{
mEditor = aEditor; mEditor = aEditor;
mTag = aTag; mTag = aTag;
mParent = do_QueryInterface(aParent); mParent = do_QueryInterface(aParent);
mOffsetInParent = aOffsetInParent; mOffsetInParent = aOffsetInParent;
#ifdef NS_DEBUG #ifdef NS_DEBUG
{ {
nsCOMPtr<nsIDOMNodeList> testChildNodes; nsCOMPtr<nsIDOMNodeList> testChildNodes;
nsresult testResult = mParent->GetChildNodes(getter_AddRefs(testChildNodes)); nsresult testResult = mParent->GetChildNodes(getter_AddRefs(testChildNodes));
NS_ASSERTION(testChildNodes, "bad parent type, can't have children."); NS_ASSERTION(testChildNodes, "bad parent type, can't have children.");
NS_ASSERTION(NS_SUCCEEDED(testResult), "bad result."); NS_ASSERTION(NS_SUCCEEDED(testResult), "bad result.");
}
#endif
return NS_OK;
} }
else #endif
return NS_ERROR_NULL_POINTER; return NS_OK;
} }
@ -70,69 +67,69 @@ NS_IMETHODIMP CreateElementTxn::Do(void)
{ {
if (gNoisy) { printf("Do Create Element parent = %p, offset = %d\n", if (gNoisy) { printf("Do Create Element parent = %p, offset = %d\n",
mParent.get(), mOffsetInParent); } mParent.get(), mOffsetInParent); }
NS_ASSERTION(mEditor, "bad state -- null editor"); NS_ASSERTION(mEditor && mParent, "bad state");
nsresult result = NS_ERROR_NULL_POINTER; if (!mEditor || !mParent) return NS_ERROR_NOT_INITIALIZED;
if (mEditor) nsresult result;
// create a new node
nsCOMPtr<nsIDOMDocument>doc;
result = mEditor->GetDocument(getter_AddRefs(doc));
if (NS_FAILED(result)) return result;
if (!doc) return NS_ERROR_NULL_POINTER;
if (nsEditor::GetTextNodeTag() == mTag)
{ {
// create a new node const nsString stringData;
nsCOMPtr<nsIDOMDocument>doc; nsCOMPtr<nsIDOMText>newTextNode;
result = mEditor->GetDocument(getter_AddRefs(doc)); result = doc->CreateTextNode(stringData, getter_AddRefs(newTextNode));
if ((NS_SUCCEEDED(result)) && (doc)) if (NS_FAILED(result)) return result;
if (!newTextNode) return NS_ERROR_NULL_POINTER;
mNewNode = do_QueryInterface(newTextNode);
}
else
{
nsCOMPtr<nsIDOMElement>newElement;
result = doc->CreateElement(mTag, getter_AddRefs(newElement));
if (NS_FAILED(result)) return result;
if (!newElement) return NS_ERROR_NULL_POINTER;
mNewNode = do_QueryInterface(newElement);
}
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewNode)), "could not create element.");
if (!mNewNode) return NS_ERROR_NULL_POINTER;
if (gNoisy) { printf(" newNode = %p\n", mNewNode.get()); }
// insert the new node
nsCOMPtr<nsIDOMNode> resultNode;
if (CreateElementTxn::eAppend==(PRInt32)mOffsetInParent)
{
result = mParent->AppendChild(mNewNode, getter_AddRefs(resultNode));
}
else
{
nsCOMPtr<nsIDOMNodeList> childNodes;
result = mParent->GetChildNodes(getter_AddRefs(childNodes));
if ((NS_SUCCEEDED(result)) && (childNodes))
{ {
if (nsEditor::GetTextNodeTag() == mTag) PRUint32 count;
childNodes->GetLength(&count);
if (mOffsetInParent>count)
mOffsetInParent = count;
result = childNodes->Item(mOffsetInParent, getter_AddRefs(mRefNode));
if (NS_SUCCEEDED(result)) // note, it's ok for mRefNode to be null. that means append
{ {
const nsString stringData; result = mParent->InsertBefore(mNewNode, mRefNode, getter_AddRefs(resultNode));
nsCOMPtr<nsIDOMText>newTextNode; if (NS_SUCCEEDED(result))
result = doc->CreateTextNode(stringData, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result) && newTextNode) {
mNewNode = do_QueryInterface(newTextNode);
}
}
else
{
nsCOMPtr<nsIDOMElement>newElement;
result = doc->CreateElement(mTag, getter_AddRefs(newElement));
if (NS_SUCCEEDED(result) && newElement) {
mNewNode = do_QueryInterface(newElement);
}
}
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewNode)), "could not create element.");
if ((NS_SUCCEEDED(result)) && (mNewNode))
{
if (gNoisy) { printf(" newNode = %p\n", mNewNode.get()); }
// insert the new node
nsCOMPtr<nsIDOMNode> resultNode;
if (CreateElementTxn::eAppend==(PRInt32)mOffsetInParent)
{ {
result = mParent->AppendChild(mNewNode, getter_AddRefs(resultNode)); nsCOMPtr<nsIDOMSelection> selection;
} result = mEditor->GetSelection(getter_AddRefs(selection));
else if (NS_FAILED(result)) return result;
{ if (!selection) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNodeList> childNodes;
result = mParent->GetChildNodes(getter_AddRefs(childNodes)); PRInt32 offset=0;
if ((NS_SUCCEEDED(result)) && (childNodes)) result = nsEditor::GetChildOffset(mNewNode, mParent, offset);
{ if (NS_FAILED(result)) return result;
PRUint32 count;
childNodes->GetLength(&count); result = selection->Collapse(mParent, offset+1);
if (mOffsetInParent>count) NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert.");
mOffsetInParent = count;
result = childNodes->Item(mOffsetInParent, getter_AddRefs(mRefNode));
if (NS_SUCCEEDED(result)) // note, it's ok for mRefNode to be null. that means append
{
result = mParent->InsertBefore(mNewNode, mRefNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMSelection> selection;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(selectionResult) && selection) {
PRInt32 offset=0;
nsEditor::GetChildOffset(mNewNode, mParent, offset);
selectionResult = selection->Collapse(mParent, offset+1);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after insert.");
}
}
}
}
} }
} }
} }
@ -144,20 +141,24 @@ NS_IMETHODIMP CreateElementTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Create Element, mParent = %p, node = %p\n", if (gNoisy) { printf("Undo Create Element, mParent = %p, node = %p\n",
mParent.get(), mNewNode.get()); } mParent.get(), mNewNode.get()); }
NS_ASSERTION(mEditor && mParent, "bad state");
if (!mEditor || !mParent) return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsIDOMNode> resultNode; nsCOMPtr<nsIDOMNode> resultNode;
nsresult result = mParent->RemoveChild(mNewNode, getter_AddRefs(resultNode)); nsresult result = mParent->RemoveChild(mNewNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result))
{ {
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(selectionResult) && selection) { if (NS_FAILED(result)) return result;
PRInt32 offset=0; if (!selection) return NS_ERROR_NULL_POINTER;
if (mRefNode) {
nsEditor::GetChildOffset(mRefNode, mParent, offset); PRInt32 offset=0;
} if (mRefNode) {
selectionResult = selection->Collapse(mParent, offset); nsEditor::GetChildOffset(mRefNode, mParent, offset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert.");
} }
result = selection->Collapse(mParent, offset);
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
} }
return result; return result;
} }
@ -165,6 +166,8 @@ NS_IMETHODIMP CreateElementTxn::Undo(void)
NS_IMETHODIMP CreateElementTxn::Redo(void) NS_IMETHODIMP CreateElementTxn::Redo(void)
{ {
if (gNoisy) { printf("Redo Create Element\n"); } if (gNoisy) { printf("Redo Create Element\n"); }
NS_ASSERTION(mEditor && mParent, "bad state");
if (!mEditor || !mParent) return NS_ERROR_NOT_INITIALIZED;
// first, reset mNewNode so it has no attributes or content // first, reset mNewNode so it has no attributes or content
nsCOMPtr<nsIDOMCharacterData>nodeAsText; nsCOMPtr<nsIDOMCharacterData>nodeAsText;
@ -182,12 +185,12 @@ NS_IMETHODIMP CreateElementTxn::Redo(void)
{ {
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result) && selection) { if (NS_FAILED(result)) return result;
PRInt32 offset=0; if (!selection) return NS_ERROR_NULL_POINTER;
nsEditor::GetChildOffset(mNewNode, mParent, offset); PRInt32 offset=0;
nsresult selectionResult = selection->Collapse(mParent, offset); nsEditor::GetChildOffset(mNewNode, mParent, offset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert."); result = selection->Collapse(mParent, offset);
} NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
} }
return result; return result;
} }

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

@ -51,16 +51,11 @@ DeleteElementTxn::~DeleteElementTxn()
NS_IMETHODIMP DeleteElementTxn::Do(void) NS_IMETHODIMP DeleteElementTxn::Do(void)
{ {
if (gNoisy) { printf("%p Do Delete Element element = %p\n", this, mElement.get()); } if (gNoisy) { printf("%p Do Delete Element element = %p\n", this, mElement.get()); }
if (!mElement) if (!mElement) return NS_ERROR_NOT_INITIALIZED;
return NS_ERROR_NULL_POINTER;
nsresult result = mElement->GetParentNode(getter_AddRefs(mParent)); nsresult result = mElement->GetParentNode(getter_AddRefs(mParent));
if (NS_FAILED(result)) { if (NS_FAILED(result)) { return result; }
return result; if (!mParent) { return NS_OK; } // this is a no-op, there's no parent to delete mElement from
}
if (!mParent) {
return NS_OK; // this is a no-op, there's no parent to delete mElement from
}
#ifdef NS_DEBUG #ifdef NS_DEBUG
// begin debug output // begin debug output

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

@ -46,21 +46,22 @@ DeleteRangeTxn::DeleteRangeTxn()
NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange) NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
{ {
if (aEditor && aRange) NS_ASSERTION(aEditor && aRange, "bad state");
{ if (!aEditor || !aRange) { return NS_ERROR_NOT_INITIALIZED; }
mEditor = aEditor;
mRange = do_QueryInterface(aRange);
nsresult result = aRange->GetStartParent(getter_AddRefs(mStartParent)); mEditor = aEditor;
NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartParent failed."); mRange = do_QueryInterface(aRange);
result = aRange->GetEndParent(getter_AddRefs(mEndParent));
NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndParent failed."); nsresult result = aRange->GetStartParent(getter_AddRefs(mStartParent));
result = aRange->GetStartOffset(&mStartOffset); NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartParent failed.");
NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartOffset failed."); result = aRange->GetEndParent(getter_AddRefs(mEndParent));
result = aRange->GetEndOffset(&mEndOffset); NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndParent failed.");
NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndOffset failed."); result = aRange->GetStartOffset(&mStartOffset);
result = aRange->GetCommonParent(getter_AddRefs(mCommonParent)); NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartOffset failed.");
NS_ASSERTION((NS_SUCCEEDED(result)), "GetCommonParent failed."); result = aRange->GetEndOffset(&mEndOffset);
NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndOffset failed.");
result = aRange->GetCommonParent(getter_AddRefs(mCommonParent));
NS_ASSERTION((NS_SUCCEEDED(result)), "GetCommonParent failed.");
#ifdef NS_DEBUG #ifdef NS_DEBUG
{ {
@ -96,10 +97,8 @@ NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
} }
} }
#endif #endif
return result; return result;
}
else
return NS_ERROR_NULL_POINTER;
} }
DeleteRangeTxn::~DeleteRangeTxn() DeleteRangeTxn::~DeleteRangeTxn()
@ -109,11 +108,10 @@ DeleteRangeTxn::~DeleteRangeTxn()
NS_IMETHODIMP DeleteRangeTxn::Do(void) NS_IMETHODIMP DeleteRangeTxn::Do(void)
{ {
if (gNoisy) { printf("Do Delete Range\n"); } if (gNoisy) { printf("Do Delete Range\n"); }
if (!mStartParent || !mEndParent || !mCommonParent) if (!mStartParent || !mEndParent || !mCommonParent || !mEditor)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NOT_INITIALIZED;
nsresult result; nsresult result;
// build the child transactions // build the child transactions
if (mStartParent==mEndParent) if (mStartParent==mEndParent)
@ -145,9 +143,9 @@ NS_IMETHODIMP DeleteRangeTxn::Do(void)
// set the resulting selection // set the resulting selection
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) { if (NS_FAILED(result)) return result;
result = selection->Collapse(mStartParent, mStartOffset); if (!selection) return NS_ERROR_NULL_POINTER;
} result = selection->Collapse(mStartParent, mStartOffset);
} }
return result; return result;
@ -156,19 +154,21 @@ NS_IMETHODIMP DeleteRangeTxn::Do(void)
NS_IMETHODIMP DeleteRangeTxn::Undo(void) NS_IMETHODIMP DeleteRangeTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Delete Range\n"); } if (gNoisy) { printf("Undo Delete Range\n"); }
if (!mStartParent || !mEndParent || !mCommonParent) if (!mStartParent || !mEndParent || !mCommonParent || !mEditor)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NOT_INITIALIZED;
nsresult result = EditAggregateTxn::Undo(); nsresult result = EditAggregateTxn::Undo();
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result))
{
// set the resulting selection // set the resulting selection
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) { if (NS_FAILED(result)) return result;
selection->Collapse(mStartParent, mStartOffset); if (!selection) return NS_ERROR_NULL_POINTER;
selection->Extend(mEndParent, mEndOffset); result = selection->Collapse(mStartParent, mStartOffset);
} if (NS_FAILED(result)) return result;
result = selection->Extend(mEndParent, mEndOffset);
} }
return result; return result;
@ -177,8 +177,8 @@ NS_IMETHODIMP DeleteRangeTxn::Undo(void)
NS_IMETHODIMP DeleteRangeTxn::Redo(void) NS_IMETHODIMP DeleteRangeTxn::Redo(void)
{ {
if (gNoisy) { printf("Redo Delete Range\n"); } if (gNoisy) { printf("Redo Delete Range\n"); }
if (!mStartParent || !mEndParent || !mCommonParent) if (!mStartParent || !mEndParent || !mCommonParent || !mEditor)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NOT_INITIALIZED;
nsresult result = EditAggregateTxn::Redo(); nsresult result = EditAggregateTxn::Redo();
@ -186,9 +186,9 @@ NS_IMETHODIMP DeleteRangeTxn::Redo(void)
// set the resulting selection // set the resulting selection
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result)) { if (NS_FAILED(result)) return result;
result = selection->Collapse(mStartParent, mStartOffset); if (!selection) return NS_ERROR_NULL_POINTER;
} result = selection->Collapse(mStartParent, mStartOffset);
} }
return result; return result;
@ -224,9 +224,10 @@ NS_IMETHODIMP DeleteRangeTxn::GetRedoString(nsString *aString)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent, NS_IMETHODIMP
PRUint32 aStartOffset, DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent,
PRUint32 aEndOffset) PRUint32 aStartOffset,
PRUint32 aEndOffset)
{ {
nsresult result; nsresult result;
// see what kind of node we have // see what kind of node we have
@ -236,44 +237,42 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteBetween(nsIDOMNode *aStartParent
{ // if the node is a text node, then delete text content { // if the node is a text node, then delete text content
DeleteTextTxn *txn; DeleteTextTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn); result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn);
if (nsnull!=txn) if (NS_FAILED(result)) return result;
{ if (!txn) return NS_ERROR_NULL_POINTER;
PRInt32 numToDel;
if (aStartOffset==aEndOffset) PRInt32 numToDel;
numToDel = 1; if (aStartOffset==aEndOffset)
else numToDel = 1;
numToDel = aEndOffset-aStartOffset; else
txn->Init(mEditor, textNode, aStartOffset, numToDel); numToDel = aEndOffset-aStartOffset;
AppendChild(txn); txn->Init(mEditor, textNode, aStartOffset, numToDel);
} AppendChild(txn);
} }
else else
{ {
PRUint32 childCount; PRUint32 childCount;
nsCOMPtr<nsIDOMNodeList> children; nsCOMPtr<nsIDOMNodeList> children;
result = aStartParent->GetChildNodes(getter_AddRefs(children)); result = aStartParent->GetChildNodes(getter_AddRefs(children));
if ((NS_SUCCEEDED(result)) && children) if (NS_FAILED(result)) return result;
if (!children) return NS_ERROR_NULL_POINTER;
children->GetLength(&childCount);
NS_ASSERTION(aEndOffset<=childCount, "bad aEndOffset");
PRUint32 i;
for (i=aStartOffset; i<aEndOffset; i++)
{ {
children->GetLength(&childCount); nsCOMPtr<nsIDOMNode> child;
NS_ASSERTION(aEndOffset<=childCount, "bad aEndOffset"); result = children->Item(i, getter_AddRefs(child));
PRUint32 i; if (NS_FAILED(result)) return result;
for (i=aStartOffset; i<aEndOffset; i++) if (!child) return NS_ERROR_NULL_POINTER;
{
nsCOMPtr<nsIDOMNode> child; DeleteElementTxn *txn;
result = children->Item(i, getter_AddRefs(child)); result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn);
if ((NS_SUCCEEDED(result)) && child) if (NS_FAILED(result)) return result;
{ if (!txn) return NS_ERROR_NULL_POINTER;
DeleteElementTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn); txn->Init(child);
if (nsnull!=txn) AppendChild(txn);
{
txn->Init(child);
AppendChild(txn);
}
else
return NS_ERROR_NULL_POINTER;
}
}
} }
} }
return result; return result;
@ -306,13 +305,11 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteContent(nsIDOMNode *aParent,
{ {
DeleteTextTxn *txn; DeleteTextTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn); result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn);
if (nsnull!=txn) if (NS_FAILED(result)) return result;
{ if (!txn) return NS_ERROR_NULL_POINTER;
txn->Init(mEditor, textNode, start, numToDelete);
AppendChild(txn); txn->Init(mEditor, textNode, start, numToDelete);
} AppendChild(txn);
else
return NS_ERROR_NULL_POINTER;
} }
} }
@ -332,11 +329,11 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteNodesBetween()
nsnull, nsnull,
nsIContentIterator::GetIID(), nsIContentIterator::GetIID(),
getter_AddRefs(iter)); getter_AddRefs(iter));
if (!NS_SUCCEEDED(result)) if (NS_FAILED(result)) return result;
return result; if (!iter) return NS_ERROR_NULL_POINTER;
result = iter->Init(mRange); result = iter->Init(mRange);
if (!NS_SUCCEEDED(result)) if (NS_FAILED(result)) return result;
return result;
while (NS_COMFALSE == iter->IsDone()) while (NS_COMFALSE == iter->IsDone())
{ {
@ -344,18 +341,16 @@ NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteNodesBetween()
nsCOMPtr<nsIContent> content; nsCOMPtr<nsIContent> content;
result = iter->CurrentNode(getter_AddRefs(content)); result = iter->CurrentNode(getter_AddRefs(content));
node = do_QueryInterface(content); node = do_QueryInterface(content);
if ((NS_SUCCEEDED(result)) && node) if (NS_FAILED(result)) return result;
{ if (!node) return NS_ERROR_NULL_POINTER;
DeleteElementTxn *txn;
result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn); DeleteElementTxn *txn;
if (nsnull!=txn) result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn);
{ if (NS_FAILED(result)) return result;
txn->Init(node); if (!txn) return NS_ERROR_NULL_POINTER;
AppendChild(txn);
} txn->Init(node);
else AppendChild(txn);
return NS_ERROR_NULL_POINTER;
}
iter->Next(); iter->Next();
} }
return result; return result;

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

@ -41,6 +41,8 @@ NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
PRUint32 aNumCharsToDelete) PRUint32 aNumCharsToDelete)
{ {
NS_ASSERTION(aEditor&&aElement, "bad arg"); NS_ASSERTION(aEditor&&aElement, "bad arg");
if (!aEditor || !aElement) { return NS_ERROR_NULL_POINTER; }
mEditor = aEditor; mEditor = aEditor;
mElement = do_QueryInterface(aElement); mElement = do_QueryInterface(aElement);
mOffset = aOffset; mOffset = aOffset;
@ -57,22 +59,20 @@ NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
NS_IMETHODIMP DeleteTextTxn::Do(void) NS_IMETHODIMP DeleteTextTxn::Do(void)
{ {
if (gNoisy) { printf("Do Delete Text\n"); } if (gNoisy) { printf("Do Delete Text\n"); }
nsresult result = NS_ERROR_NULL_POINTER; NS_ASSERTION(mEditor && mElement, "bad state");
if (mEditor && mElement) if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
// get the text that we're about to delete
nsresult result = mElement->SubstringData(mOffset, mNumCharsToDelete, mDeletedText);
NS_ASSERTION(NS_SUCCEEDED(result), "could not get text to delete.");
result = mElement->DeleteData(mOffset, mNumCharsToDelete);
if (NS_SUCCEEDED(result))
{ {
// get the text that we're about to delete nsCOMPtr<nsIDOMSelection> selection;
result = mElement->SubstringData(mOffset, mNumCharsToDelete, mDeletedText); result = mEditor->GetSelection(getter_AddRefs(selection));
NS_ASSERTION(NS_SUCCEEDED(result), "could not get text to delete."); if (NS_FAILED(result)) return result;
result = mElement->DeleteData(mOffset, mNumCharsToDelete); if (!selection) return NS_ERROR_NULL_POINTER;
if (NS_SUCCEEDED(result)) result = selection->Collapse(mElement, mOffset);
{ NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
nsCOMPtr<nsIDOMSelection> selection;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(selectionResult) && selection) {
selectionResult = selection->Collapse(mElement, mOffset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert.");
}
}
} }
return result; return result;
} }
@ -82,19 +82,19 @@ NS_IMETHODIMP DeleteTextTxn::Do(void)
NS_IMETHODIMP DeleteTextTxn::Undo(void) NS_IMETHODIMP DeleteTextTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Delete Text\n"); } if (gNoisy) { printf("Undo Delete Text\n"); }
nsresult result = NS_ERROR_NULL_POINTER; NS_ASSERTION(mEditor && mElement, "bad state");
if (mEditor && mElement) if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result;
result = mElement->InsertData(mOffset, mDeletedText);
if (NS_SUCCEEDED(result))
{ {
result = mElement->InsertData(mOffset, mDeletedText); nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(result)) nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection));
{ if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMSelection> selection; if (!selection) return NS_ERROR_NULL_POINTER;
nsresult selectionResult = mEditor->GetSelection(getter_AddRefs(selection)); result = selection->Collapse(mElement, mOffset);
if (NS_SUCCEEDED(selectionResult) && selection) { NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
selectionResult = selection->Collapse(mElement, mOffset);
NS_ASSERTION((NS_SUCCEEDED(selectionResult)), "selection could not be collapsed after undo of insert.");
}
}
} }
return result; return result;
} }

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

@ -64,8 +64,7 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
printf("%p Do Insert Element of %p into parent %p at offset %d\n", printf("%p Do Insert Element of %p into parent %p at offset %d\n",
this, nodeAsContent.get(), parentAsContent.get(), mOffset); this, nodeAsContent.get(), parentAsContent.get(), mOffset);
} }
if (!mNode || !mParent) if (!mNode || !mParent) return NS_ERROR_NOT_INITIALIZED;
return NS_ERROR_NULL_POINTER;
nsresult result; nsresult result;
nsCOMPtr<nsIDOMNode>refNode; nsCOMPtr<nsIDOMNode>refNode;
@ -92,16 +91,16 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
nsCOMPtr<nsIDOMNode> resultNode; nsCOMPtr<nsIDOMNode> resultNode;
result = mParent->InsertBefore(mNode, refNode, getter_AddRefs(resultNode)); result = mParent->InsertBefore(mNode, refNode, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result) && resultNode) if (NS_FAILED(result)) return result;
{ if (!resultNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMSelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection)); nsCOMPtr<nsIDOMSelection> selection;
if ((NS_SUCCEEDED(result)) && selection) result = mEditor->GetSelection(getter_AddRefs(selection));
{ // place the selection just after the inserted element if (NS_FAILED(result)) return result;
selection->Collapse(mParent, mOffset+1); if (!selection) return NS_ERROR_NULL_POINTER;
//selection->Extend(mParent, mOffset+1); // place the selection just after the inserted element
} selection->Collapse(mParent, mOffset+1);
} //selection->Extend(mParent, mOffset+1);
return result; return result;
} }
@ -109,8 +108,7 @@ NS_IMETHODIMP InsertElementTxn::Undo(void)
{ {
if (gNoisy) { printf("%p Undo Insert Element of %p into parent %p at offset %d\n", if (gNoisy) { printf("%p Undo Insert Element of %p into parent %p at offset %d\n",
this, mNode.get(), mParent.get(), mOffset); } this, mNode.get(), mParent.get(), mOffset); }
if (!mNode || !mParent) if (!mNode || !mParent) return NS_ERROR_NOT_INITIALIZED;
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> resultNode; nsCOMPtr<nsIDOMNode> resultNode;
nsresult result = mParent->RemoveChild(mNode, getter_AddRefs(resultNode)); nsresult result = mParent->RemoveChild(mNode, getter_AddRefs(resultNode));

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

@ -62,6 +62,9 @@ NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
printf("\n"); printf("\n");
#endif #endif
NS_ASSERTION(aElement&&aPresShell, "bad args");
if (!aElement || !aPresShell) return NS_ERROR_NULL_POINTER;
mElement = do_QueryInterface(aElement); mElement = do_QueryInterface(aElement);
mOffset = aOffset; mOffset = aOffset;
mStringToInsert = aStringToInsert; mStringToInsert = aStringToInsert;
@ -72,16 +75,19 @@ NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
NS_IMETHODIMP InsertTextTxn::Do(void) NS_IMETHODIMP InsertTextTxn::Do(void)
{ {
if (gNoisy) { printf("Do Insert Text element = %p\n", mElement.get()); } if (gNoisy) { printf("Do Insert Text element = %p\n", mElement.get()); }
NS_ASSERTION(mElement && mPresShell, "bad state");
if (!mElement || !mPresShell) { return NS_ERROR_NOT_INITIALIZED; }
// advance caret: This requires the presentation shell to get the selection. // advance caret: This requires the presentation shell to get the selection.
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
nsresult result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)); nsresult result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection));
NS_ASSERTION(selection,"Could not get selection in InsertTextTxn::Do\n"); if (NS_FAILED(result)) return result;
if (NS_SUCCEEDED(result) && selection) { if (!selection) return NS_ERROR_NULL_POINTER;
result = mElement->InsertData(mOffset, mStringToInsert); result = mElement->InsertData(mOffset, mStringToInsert);
if (NS_SUCCEEDED(result)) { if (NS_SUCCEEDED(result))
result = selection->Collapse(mElement, mOffset+mStringToInsert.Length()); {
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert."); result = selection->Collapse(mElement, mOffset+mStringToInsert.Length());
} NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after insert.");
} }
return result; return result;
} }
@ -89,6 +95,9 @@ NS_IMETHODIMP InsertTextTxn::Do(void)
NS_IMETHODIMP InsertTextTxn::Undo(void) NS_IMETHODIMP InsertTextTxn::Undo(void)
{ {
if (gNoisy) { printf("Undo Insert Text element = %p\n", mElement.get()); } if (gNoisy) { printf("Undo Insert Text element = %p\n", mElement.get()); }
NS_ASSERTION(mElement && mPresShell, "bad state");
if (!mElement || !mPresShell) { return NS_ERROR_NOT_INITIALIZED; }
nsresult result; nsresult result;
PRUint32 length = mStringToInsert.Length(); PRUint32 length = mStringToInsert.Length();
result = mElement->DeleteData(mOffset, length); result = mElement->DeleteData(mOffset, length);
@ -96,10 +105,10 @@ NS_IMETHODIMP InsertTextTxn::Undo(void)
{ // set the selection to the insertion point where the string was removed { // set the selection to the insertion point where the string was removed
nsCOMPtr<nsIDOMSelection> selection; nsCOMPtr<nsIDOMSelection> selection;
result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)); result = mPresShell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection));
if (NS_SUCCEEDED(result) && selection) { if (NS_FAILED(result)) return result;
result = selection->Collapse(mElement, mOffset); if (!selection) return NS_ERROR_NULL_POINTER;
NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert."); result = selection->Collapse(mElement, mOffset);
} NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of insert.");
} }
return result; return result;
} }

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

@ -37,6 +37,8 @@ NS_IMETHODIMP JoinElementTxn::Init(nsIEditor *aEditor,
nsIDOMNode *aLeftNode, nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode) nsIDOMNode *aRightNode)
{ {
NS_PRECONDITION((aEditor && aLeftNode && aRightNode), "null arg");
if (!aEditor || !aLeftNode || !aRightNode) { return NS_ERROR_NULL_POINTER; }
mEditor = aEditor; mEditor = aEditor;
mLeftNode = do_QueryInterface(aLeftNode); mLeftNode = do_QueryInterface(aLeftNode);
mRightNode = do_QueryInterface(aRightNode); mRightNode = do_QueryInterface(aRightNode);
@ -52,54 +54,54 @@ JoinElementTxn::~JoinElementTxn()
NS_IMETHODIMP JoinElementTxn::Do(void) NS_IMETHODIMP JoinElementTxn::Do(void)
{ {
if (gNoisy) { printf("%p Do Join of %p and %p\n", this, mLeftNode.get(), mRightNode.get()); } if (gNoisy) { printf("%p Do Join of %p and %p\n", this, mLeftNode.get(), mRightNode.get()); }
nsresult result; NS_PRECONDITION((mEditor && mLeftNode && mRightNode), "null arg");
if (!mEditor || !mLeftNode || !mRightNode) { return NS_ERROR_NOT_INITIALIZED; }
if ((mLeftNode) && (mRightNode)) // get the parent node
{ // get the parent node nsCOMPtr<nsIDOMNode>leftParent;
nsCOMPtr<nsIDOMNode>leftParent; nsresult result = mLeftNode->GetParentNode(getter_AddRefs(leftParent));
result = mLeftNode->GetParentNode(getter_AddRefs(leftParent)); if (NS_FAILED(result)) return result;
if ((NS_SUCCEEDED(result)) && (leftParent)) if (!leftParent) return NS_ERROR_NULL_POINTER;
{ // verify that mLeftNode and mRightNode have the same parent
nsCOMPtr<nsIDOMNode>rightParent; // verify that mLeftNode and mRightNode have the same parent
result = mRightNode->GetParentNode(getter_AddRefs(rightParent)); nsCOMPtr<nsIDOMNode>rightParent;
if ((NS_SUCCEEDED(result)) && (rightParent)) result = mRightNode->GetParentNode(getter_AddRefs(rightParent));
{ if (NS_FAILED(result)) return result;
if (leftParent==rightParent) if (!rightParent) return NS_ERROR_NULL_POINTER;
{
mParent= do_QueryInterface(leftParent); // set this instance mParent. if (leftParent==rightParent)
// Other methods will see a non-null mParent and know all is well {
nsCOMPtr<nsIDOMNodeList> childNodes; mParent= do_QueryInterface(leftParent); // set this instance mParent.
result = mLeftNode->GetChildNodes(getter_AddRefs(childNodes)); // Other methods will see a non-null mParent and know all is well
if ((NS_SUCCEEDED(result)) && (childNodes)) { nsCOMPtr<nsIDOMNodeList> childNodes;
childNodes->GetLength(&mOffset); result = mLeftNode->GetChildNodes(getter_AddRefs(childNodes));
} if (NS_FAILED(result)) return result;
else if (childNodes) {
{ childNodes->GetLength(&mOffset);
nsCOMPtr<nsIDOMCharacterData> leftNodeAsText; }
leftNodeAsText = do_QueryInterface(mLeftNode); else
if (leftNodeAsText) { {
leftNodeAsText->GetLength(&mOffset); nsCOMPtr<nsIDOMCharacterData> leftNodeAsText;
} leftNodeAsText = do_QueryInterface(mLeftNode);
} if (leftNodeAsText) {
result = nsEditor::JoinNodesImpl(mRightNode, mLeftNode, mParent, PR_FALSE); leftNodeAsText->GetLength(&mOffset);
if (NS_SUCCEEDED(result))
{
if (gNoisy) { printf(" left node = %p removed\n", mLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (selection)
{
selection->Collapse(mRightNode, mOffset);
}
}
}
else
{
NS_ASSERTION(PR_FALSE, "2 nodes do not have same parent");
return NS_ERROR_INVALID_ARG;
}
} }
} }
result = nsEditor::JoinNodesImpl(mRightNode, mLeftNode, mParent, PR_FALSE);
if (NS_SUCCEEDED(result))
{
if (gNoisy) { printf(" left node = %p removed\n", mLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result)) return result;
if (!selection) return NS_ERROR_NULL_POINTER;
selection->Collapse(mRightNode, mOffset);
}
}
else
{
NS_ASSERTION(PR_FALSE, "2 nodes do not have same parent");
return NS_ERROR_INVALID_ARG;
} }
return result; return result;
} }
@ -110,9 +112,7 @@ NS_IMETHODIMP JoinElementTxn::Undo(void)
{ {
if (gNoisy) { printf("%p Undo Join, right node = %p\n", this, mRightNode.get()); } if (gNoisy) { printf("%p Undo Join, right node = %p\n", this, mRightNode.get()); }
NS_ASSERTION(mRightNode && mLeftNode && mParent, "bad state"); NS_ASSERTION(mRightNode && mLeftNode && mParent, "bad state");
if (!mRightNode || !mLeftNode || !mParent) { if (!mRightNode || !mLeftNode || !mParent) { return NS_ERROR_NOT_INITIALIZED; }
return NS_ERROR_NOT_INITIALIZED;
}
nsresult result; nsresult result;
nsCOMPtr<nsIDOMNode>resultNode; nsCOMPtr<nsIDOMNode>resultNode;
// first, massage the existing node so it is in its post-split state // first, massage the existing node so it is in its post-split state

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

@ -39,6 +39,9 @@ NS_IMETHODIMP SplitElementTxn::Init(nsIEditor *aEditor,
nsIDOMNode *aNode, nsIDOMNode *aNode,
PRInt32 aOffset) PRInt32 aOffset)
{ {
NS_ASSERTION(aEditor && aNode, "bad args");
if (!aEditor || !aNode) { return NS_ERROR_NOT_INITIALIZED; }
mEditor = aEditor; mEditor = aEditor;
mExistingRightNode = do_QueryInterface(aNode); mExistingRightNode = do_QueryInterface(aNode);
mOffset = aOffset; mOffset = aOffset;
@ -52,36 +55,33 @@ SplitElementTxn::~SplitElementTxn()
NS_IMETHODIMP SplitElementTxn::Do(void) NS_IMETHODIMP SplitElementTxn::Do(void)
{ {
if (gNoisy) { printf("%p Do Split of node %p offset %d\n", this, mExistingRightNode.get(), mOffset); } if (gNoisy) { printf("%p Do Split of node %p offset %d\n", this, mExistingRightNode.get(), mOffset); }
NS_ASSERTION(mExistingRightNode, "bad state"); NS_ASSERTION(mExistingRightNode && mEditor, "bad state");
if (!mExistingRightNode) { if (!mExistingRightNode || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
return NS_ERROR_NOT_INITIALIZED;
}
// create a new node // create a new node
nsresult result = mExistingRightNode->CloneNode(PR_FALSE, getter_AddRefs(mNewLeftNode)); nsresult result = mExistingRightNode->CloneNode(PR_FALSE, getter_AddRefs(mNewLeftNode));
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element."); NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element.");
if (NS_FAILED(result)) return result;
if (!mNewLeftNode) return NS_ERROR_NULL_POINTER;
if ((NS_SUCCEEDED(result)) && (mNewLeftNode)) if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); }
// get the parent node
result = mExistingRightNode->GetParentNode(getter_AddRefs(mParent));
if (NS_FAILED(result)) return result;
if (!mParent) return NS_ERROR_NULL_POINTER;
// insert the new node
result = nsEditor::SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
if (NS_SUCCEEDED(result) && mNewLeftNode)
{ {
if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); } nsCOMPtr<nsIDOMSelection>selection;
// get the parent node mEditor->GetSelection(getter_AddRefs(selection));
result = mExistingRightNode->GetParentNode(getter_AddRefs(mParent)); if (NS_FAILED(result)) return result;
// insert the new node if (!selection) return NS_ERROR_NULL_POINTER;
if ((NS_SUCCEEDED(result)) && (mParent)) result = selection->Collapse(mNewLeftNode, mOffset);
{ }
result = nsEditor::SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent); else {
if (NS_SUCCEEDED(result) && mNewLeftNode) result = NS_ERROR_NOT_IMPLEMENTED;
{
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (selection)
{
selection->Collapse(mNewLeftNode, mOffset);
}
}
else {
result = NS_ERROR_NOT_IMPLEMENTED;
}
}
} }
return result; return result;
} }
@ -92,8 +92,8 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
printf("%p Undo Split of existing node %p and new node %p offset %d\n", printf("%p Undo Split of existing node %p and new node %p offset %d\n",
this, mExistingRightNode.get(), mNewLeftNode.get(), mOffset); this, mExistingRightNode.get(), mNewLeftNode.get(), mOffset);
} }
NS_ASSERTION(mExistingRightNode && mNewLeftNode && mParent, "bad state"); NS_ASSERTION(mEditor && mExistingRightNode && mNewLeftNode && mParent, "bad state");
if (!mExistingRightNode || !mNewLeftNode || !mParent) { if (!mEditor || !mExistingRightNode || !mNewLeftNode || !mParent) {
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
} }
@ -110,10 +110,9 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
if (gNoisy) { printf(" left node = %p removed\n", mNewLeftNode.get()); } if (gNoisy) { printf(" left node = %p removed\n", mNewLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection; nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection)); mEditor->GetSelection(getter_AddRefs(selection));
if (selection) if (NS_FAILED(result)) return result;
{ if (!selection) return NS_ERROR_NULL_POINTER;
selection->Collapse(mExistingRightNode, mOffset); result = selection->Collapse(mExistingRightNode, mOffset);
}
} }
else { else {
result = NS_ERROR_NOT_IMPLEMENTED; result = NS_ERROR_NOT_IMPLEMENTED;
@ -126,8 +125,8 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
*/ */
NS_IMETHODIMP SplitElementTxn::Redo(void) NS_IMETHODIMP SplitElementTxn::Redo(void)
{ {
NS_ASSERTION(mExistingRightNode && mNewLeftNode && mParent, "bad state"); NS_ASSERTION(mEditor && mExistingRightNode && mNewLeftNode && mParent, "bad state");
if (!mExistingRightNode || !mNewLeftNode || !mParent) { if (!mEditor || !mExistingRightNode || !mNewLeftNode || !mParent) {
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
} }
if (gNoisy) { if (gNoisy) {
@ -146,7 +145,7 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
if (gNoisy) if (gNoisy)
{ {
printf("** after delete of text in right text node %p offset %d\n", rightNodeAsText.get(), mOffset); printf("** after delete of text in right text node %p offset %d\n", rightNodeAsText.get(), mOffset);
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG mEditor->DebugDumpContent(); // DEBUG
} }
} }
else else

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

@ -239,6 +239,7 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
// disable links // disable links
nsCOMPtr<nsIPresContext> context; nsCOMPtr<nsIPresContext> context;
mPresShell->GetPresContext(getter_AddRefs(context)); mPresShell->GetPresContext(getter_AddRefs(context));
if (!context) return NS_ERROR_NULL_POINTER;
context->SetLinkHandler(0); context->SetLinkHandler(0);
// Set up the DTD // Set up the DTD
@ -252,9 +253,9 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
if (!mEditProperty) {return NS_ERROR_NULL_POINTER;} if (!mEditProperty) {return NS_ERROR_NULL_POINTER;}
mPresShell->GetViewManager(&mViewManager); mPresShell->GetViewManager(&mViewManager);
if (mViewManager){ if (!mViewManager) {return NS_ERROR_NULL_POINTER;}
mViewManager->Release(); //we want a weak link mViewManager->Release(); //we want a weak link
}
mPresShell->SetDisplayNonTextSelection(PR_TRUE);//we want to see all the selection reflected to user mPresShell->SetDisplayNonTextSelection(PR_TRUE);//we want to see all the selection reflected to user
mUpdateCount=0; mUpdateCount=0;
InsertTextTxn::ClassInit(); InsertTextTxn::ClassInit();
@ -267,22 +268,25 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
mIMEBufferLength = 0; mIMEBufferLength = 0;
/* Show the caret */ /* Show the caret */
// XXX: I suppose it's legal to fail to get a caret, so don't propogate the
// result of GetCaret
nsCOMPtr<nsICaret> caret; nsCOMPtr<nsICaret> caret;
if (NS_SUCCEEDED(mPresShell->GetCaret(getter_AddRefs(caret))) && caret) if (NS_SUCCEEDED(mPresShell->GetCaret(getter_AddRefs(caret))) && caret)
{ {
caret->SetCaretVisible(PR_TRUE); caret->SetCaretVisible(PR_TRUE);
caret->SetCaretReadOnly(PR_FALSE); caret->SetCaretReadOnly(PR_FALSE);
} }
// NOTE: We don't fail if we can't get prefs or string bundles // NOTE: We don't fail if we can't get prefs or string bundles
// since we could still be used as the text edit widget without prefs // since we could still be used as the text edit widget without prefs
// Get the prefs service (Note: can't use nsCOMPtr for service pointers) // Get the prefs service (Note: can't use nsCOMPtr for service pointers)
result = nsServiceManager::GetService(kPrefCID, nsresult ignoredResult = nsServiceManager::GetService(kPrefCID,
nsIPref::GetIID(), nsIPref::GetIID(),
(nsISupports**)&mPrefs); (nsISupports**)&mPrefs);
if (NS_FAILED(result) || !mPrefs) if (NS_FAILED(ignoredResult) || !mPrefs)
{ {
printf("ERROR: Failed to get Prefs Service instance.\n"); if (gNoisy) { printf("ERROR: Failed to get Prefs Service instance.\n");}
} }
// TODO: Cache basic preferences? // TODO: Cache basic preferences?
@ -290,20 +294,21 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, PRUint32 aFlags)
// respond to while running // respond to while running
nsIStringBundleService* service; nsIStringBundleService* service;
result = nsServiceManager::GetService(kStringBundleServiceCID, ignoredResult = nsServiceManager::GetService(kStringBundleServiceCID,
nsIStringBundleService::GetIID(), nsIStringBundleService::GetIID(),
(nsISupports**)&service); (nsISupports**)&service);
if (NS_SUCCEEDED(result) && service) if (NS_SUCCEEDED(ignoredResult) && service)
{ {
nsILocale* locale = nsnull; nsILocale* locale = nsnull;
result = service->CreateBundle(EDITOR_BUNDLE_URL, locale, ignoredResult = service->CreateBundle(EDITOR_BUNDLE_URL, locale,
getter_AddRefs(mStringBundle)); getter_AddRefs(mStringBundle));
// We don't need to keep service around once we created the bundle // We don't need to keep service around once we created the bundle
nsServiceManager::ReleaseService(kStringBundleServiceCID, service); nsServiceManager::ReleaseService(kStringBundleServiceCID, service);
} else { } else {
printf("ERROR: Failed to get StringBundle Service instance.\n"); if (gNoisy) printf("ERROR: Failed to get StringBundle Service instance.\n");
} }
/* /*
Example of getting a string: Example of getting a string:
nsString value; nsString value;
@ -374,8 +379,8 @@ NS_IMETHODIMP nsEditor::SaveDocument(PRBool saveAs, PRBool saveCopy)
// get the document // get the document
nsCOMPtr<nsIDOMDocument> doc; nsCOMPtr<nsIDOMDocument> doc;
rv = GetDocument(getter_AddRefs(doc)); rv = GetDocument(getter_AddRefs(doc));
if (NS_FAILED(rv) || !doc) if (NS_FAILED(rv)) return rv;
return rv; if (!doc) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(doc); nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(doc);
if (!diskDoc) if (!diskDoc)
@ -1238,7 +1243,6 @@ nsEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivateTex
return result; return result;
} }
#ifdef XP_MAC #ifdef XP_MAC
#pragma mark - #pragma mark -
#pragma mark --- public nsEditor methods --- #pragma mark --- public nsEditor methods ---

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

@ -387,7 +387,7 @@ public:
* @param aNodeToKeep The node that will remain after the join. * @param aNodeToKeep The node that will remain after the join.
* @param aNodeToJoin The node that will be joined with aNodeToKeep. * @param aNodeToJoin The node that will be joined with aNodeToKeep.
* There is no requirement that the two nodes be of the same type. * There is no requirement that the two nodes be of the same type.
* @param aParent The parent of aExistingRightNode * @param aParent The parent of aNodeToKeep
* @param aNodeToKeepIsFirst if PR_TRUE, the contents|children of aNodeToKeep come before the * @param aNodeToKeepIsFirst if PR_TRUE, the contents|children of aNodeToKeep come before the
* contents|children of aNodeToJoin, otherwise their positions are switched. * contents|children of aNodeToJoin, otherwise their positions are switched.
*/ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -192,7 +192,15 @@ protected:
virtual void InitRules(); virtual void InitRules();
NS_IMETHOD GetLayoutObject(nsIDOMNode *aNode, nsISupports **aLayoutObject); /** returns the layout object (nsIFrame in the real world) for aNode
* @param aNode the content to get a frame for
* @param aLayoutObject the "primary frame" for aNode, if one exists. May be null
* @return NS_OK whether a frame is found or not
* an error if some serious error occurs
*/
NS_IMETHOD GetLayoutObject(nsIDOMNode *aInNode, nsISupports **aOutLayoutObject);
NS_IMETHOD CollapseAdjacentTextNodes(nsIDOMSelection *aInSelection);
NS_IMETHOD DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode); NS_IMETHOD DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode);
@ -382,10 +390,10 @@ protected:
const nsString *aAttribute, const nsString *aAttribute,
const nsString *aValue); const nsString *aValue);
void GetTextSelectionOffsetsForRange(nsIDOMSelection *aSelection, NS_IMETHOD GetTextSelectionOffsetsForRange(nsIDOMSelection *aSelection,
nsIDOMNode **aParent, nsIDOMNode **aParent,
PRInt32 &aStartOffset, PRInt32 &aStartOffset,
PRInt32 &aEndOffset); PRInt32 &aEndOffset);
void ResetTextSelectionForRange(nsIDOMNode *aParent, void ResetTextSelectionForRange(nsIDOMNode *aParent,
PRInt32 aStartOffset, PRInt32 aStartOffset,

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

@ -47,12 +47,18 @@
#include "nsIDragSession.h" #include "nsIDragSession.h"
#include "nsITransferable.h" #include "nsITransferable.h"
#include "nsIFormatConverter.h" #include "nsIFormatConverter.h"
#include "nsIContentIterator.h"
#include "nsIContent.h"
#include "nsLayoutCID.h"
// Drag & Drop, Clipboard Support // Drag & Drop, Clipboard Support
static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID); static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID);
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID); static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
static NS_DEFINE_IID(kCDataFlavorCID, NS_DATAFLAVOR_CID); static NS_DEFINE_IID(kCDataFlavorCID, NS_DATAFLAVOR_CID);
static NS_DEFINE_IID(kCXIFFormatConverterCID, NS_XIFFORMATCONVERTER_CID); static NS_DEFINE_IID(kContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
static NS_DEFINE_IID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID);
/* /*
@ -116,8 +122,7 @@ nsresult
nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent) nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
{ {
PRUint32 keyCode; PRUint32 keyCode;
PRBool isShift; PRBool isShift, ctrlKey, altKey, metaKey;
PRBool ctrlKey;
nsCOMPtr<nsIDOMUIEvent>uiEvent; nsCOMPtr<nsIDOMUIEvent>uiEvent;
uiEvent = do_QueryInterface(aKeyEvent); uiEvent = do_QueryInterface(aKeyEvent);
@ -126,87 +131,87 @@ nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
return NS_OK; return NS_OK;
} }
if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode)) && PRBool keyProcessed;
NS_SUCCEEDED(uiEvent->GetShiftKey(&isShift)) && ProcessShortCutKeys(aKeyEvent, keyProcessed);
NS_SUCCEEDED(uiEvent->GetCtrlKey(&ctrlKey)) if (PR_FALSE==keyProcessed)
) { {
PRBool keyProcessed; if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode)) &&
ProcessShortCutKeys(aKeyEvent, keyProcessed); NS_SUCCEEDED(uiEvent->GetShiftKey(&isShift)) &&
if (PR_FALSE==keyProcessed) NS_SUCCEEDED(uiEvent->GetCtrlKey(&ctrlKey)) &&
{ NS_SUCCEEDED(uiEvent->GetAltKey(&altKey)) &&
switch(keyCode) { NS_SUCCEEDED(uiEvent->GetMetaKey(&metaKey)))
// case nsIDOMUIEvent::VK_BACK: {
// mEditor->DeleteSelection(nsIEditor::eDeleteLeft); {
// break; switch(keyCode) {
// case nsIDOMUIEvent::VK_BACK:
// mEditor->DeleteSelection(nsIEditor::eDeleteLeft);
// break;
case nsIDOMUIEvent::VK_DELETE: case nsIDOMUIEvent::VK_DELETE:
mEditor->DeleteSelection(nsIEditor::eDeleteNext); mEditor->DeleteSelection(nsIEditor::eDeleteNext);
break; break;
// case nsIDOMUIEvent::VK_RETURN: // case nsIDOMUIEvent::VK_RETURN:
//case nsIDOMUIEvent::VK_ENTER: // why does this not exist? //case nsIDOMUIEvent::VK_ENTER: // why does this not exist?
// Need to implement creation of either <P> or <BR> nodes. // Need to implement creation of either <P> or <BR> nodes.
// mEditor->InsertBreak(); // mEditor->InsertBreak();
// break; // break;
case nsIDOMUIEvent::VK_LEFT: case nsIDOMUIEvent::VK_LEFT:
case nsIDOMUIEvent::VK_RIGHT: case nsIDOMUIEvent::VK_RIGHT:
case nsIDOMUIEvent::VK_UP: case nsIDOMUIEvent::VK_UP:
case nsIDOMUIEvent::VK_DOWN: case nsIDOMUIEvent::VK_DOWN:
// these have already been handled in nsRangeList. Why are we getting them // these have already been handled in nsRangeList. Why are we getting them
// again here (Mac)? In switch to avoid putting in bogus chars. // again here (Mac)? In switch to avoid putting in bogus chars.
//return NS_OK to allow page scrolling. //return NS_OK to allow page scrolling.
return NS_OK; return NS_OK;
break; break;
case nsIDOMUIEvent::VK_HOME: case nsIDOMUIEvent::VK_HOME:
case nsIDOMUIEvent::VK_END: case nsIDOMUIEvent::VK_END:
// who handles these? // who handles these?
#if DEBUG #if DEBUG
printf("Key not handled\n"); printf("Key not handled\n");
#endif #endif
return NS_OK; return NS_OK;
break; break;
case nsIDOMUIEvent::VK_PAGE_UP: case nsIDOMUIEvent::VK_PAGE_UP:
case nsIDOMUIEvent::VK_PAGE_DOWN: case nsIDOMUIEvent::VK_PAGE_DOWN:
//return NS_OK to allow page scrolling. //return NS_OK to allow page scrolling.
return NS_OK; return NS_OK;
break; break;
case nsIDOMUIEvent::VK_TAB: case nsIDOMUIEvent::VK_TAB:
{ {
PRUint32 flags=0; PRUint32 flags=0;
mEditor->GetFlags(&flags); mEditor->GetFlags(&flags);
if (! (flags & nsIHTMLEditor::eEditorSingleLineMask)) if (! (flags & nsIHTMLEditor::eEditorSingleLineMask))
{ {
PRBool ctrlKey, altKey, metaKey; if (metaKey || altKey)
uiEvent->GetCtrlKey(&ctrlKey); return NS_OK; // don't consume
uiEvent->GetAltKey(&altKey); // else we insert the tab straight through
uiEvent->GetMetaKey(&metaKey); nsAutoString key;
if (metaKey || altKey) key += keyCode;
return NS_OK; // don't consume
// else we insert the tab straight through
nsAutoString key;
key += keyCode;
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor); nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
if (htmlEditor) if (htmlEditor)
htmlEditor->InsertText(key); htmlEditor->InsertText(key);
return NS_ERROR_BASE; // this means "I handled the event, don't do default processing" return NS_ERROR_BASE; // this means "I handled the event, don't do default processing"
} }
else { else {
return NS_OK; return NS_OK;
} }
break; break;
} }
default: default:
return NS_OK; // this indicates that we have not handled the keyDown event in any way. return NS_OK; // this indicates that we have not handled the keyDown event in any way.
} }
} }
} }
}
return NS_ERROR_BASE; return NS_ERROR_BASE;
} }
@ -238,19 +243,20 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
// eaiser // eaiser
// //
PRBool ctrlKey, altKey, metaKey; PRBool ctrlKey, altKey, metaKey;
uiEvent->GetCtrlKey(&ctrlKey); uiEvent->GetCtrlKey(&ctrlKey);
uiEvent->GetAltKey(&altKey); uiEvent->GetAltKey(&altKey);
uiEvent->GetMetaKey(&metaKey); uiEvent->GetMetaKey(&metaKey);
if (metaKey)
return NS_OK; // don't consume
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor); if (metaKey)
if (!htmlEditor) return NS_ERROR_NO_INTERFACE; return NS_OK; // don't consume
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
if (!htmlEditor) return NS_ERROR_NO_INTERFACE;
if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode))) if (NS_SUCCEEDED(uiEvent->GetKeyCode(&keyCode)))
{ {
if (nsIDOMUIEvent::VK_BACK==keyCode) { if (nsIDOMUIEvent::VK_BACK==keyCode) {
mEditor->DeleteSelection(nsIEditor::eDeletePrevious); mEditor->DeleteSelection(nsIEditor::eDeletePrevious);
return NS_ERROR_BASE; // consumed return NS_ERROR_BASE; // consumed
} }
@ -261,14 +267,14 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
} }
if ((PR_FALSE==altKey) && (PR_FALSE==ctrlKey) && if ((PR_FALSE==altKey) && (PR_FALSE==ctrlKey) &&
(NS_SUCCEEDED(uiEvent->GetCharCode(&character)))) (NS_SUCCEEDED(uiEvent->GetCharCode(&character))))
{ {
if (nsIDOMUIEvent::VK_TAB==character) { if (nsIDOMUIEvent::VK_TAB==character) {
return NS_OK; // ignore tabs here, they're handled in keyDown if at all return NS_OK; // ignore tabs here, they're handled in keyDown if at all
} }
key += character; key += character;
htmlEditor->InsertText(key); htmlEditor->InsertText(key);
} }
return NS_ERROR_BASE; // consumed return NS_ERROR_BASE; // consumed
@ -843,6 +849,62 @@ nsTextEditorMouseListener::HandleEvent(nsIDOMEvent* aEvent)
// XXX: evil global functions, move them to proper support module
nsresult
IsNodeInSelection(nsIDOMNode *aInNode, nsIDOMSelection *aInSelection, PRBool &aOutIsInSel)
{
aOutIsInSel = PR_FALSE; // init out-param
if (!aInNode || !aInSelection) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIContentIterator>iter;
nsresult result = nsComponentManager::CreateInstance(kContentIteratorCID, nsnull,
nsIContentIterator::GetIID(),
getter_AddRefs(iter));
if (NS_FAILED(result)) { return result; }
if (!iter) { return NS_ERROR_OUT_OF_MEMORY; }
nsCOMPtr<nsIEnumerator> enumerator;
result = aInSelection->GetEnumerator(getter_AddRefs(enumerator));
if (NS_FAILED(result)) { return result; }
if (!enumerator) { return NS_ERROR_OUT_OF_MEMORY; }
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
{
nsCOMPtr<nsISupports> currentItem;
result = enumerator->CurrentItem(getter_AddRefs(currentItem));
if ((NS_SUCCEEDED(result)) && (currentItem))
{
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
iter->Init(range);
nsCOMPtr<nsIContent> currentContent;
iter->CurrentNode(getter_AddRefs(currentContent));
while (NS_COMFALSE == iter->IsDone())
{
nsCOMPtr<nsIDOMNode>currentNode = do_QueryInterface(currentContent);
if (currentNode.get()==aInNode)
{
// if it's a start or end node, need to test whether the (x,y)
// of the event falls within the selection
// talk to Mike
aOutIsInSel = PR_TRUE;
return NS_OK;
}
/* do not check result here, and especially do not return the result code.
* we rely on iter->IsDone to tell us when the iteration is complete
*/
iter->Next();
iter->CurrentNode(getter_AddRefs(currentContent));
}
}
}
return NS_OK;
}
nsresult nsresult
nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
{ {
@ -856,49 +918,141 @@ nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK; return NS_OK;
} }
// We only do anything special for middle-mouse click (paste); nsCOMPtr<nsIEditor> editor (do_QueryInterface(mEditor));
// ignore all other events. if (!editor) { return NS_OK; }
// get the document
nsCOMPtr<nsIDOMDocument>domDoc;
editor->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) { return NS_OK; }
nsCOMPtr<nsIDocument>doc = do_QueryInterface(domDoc);
if (!doc) { return NS_OK; }
PRUint16 button = 0; PRUint16 button = 0;
uiEvent->GetButton(&button); uiEvent->GetButton(&button);
if (button != 2) // left button click might be a drag-start
return NS_OK; if (1==button)
{
#ifndef EXPERIMENTAL_DRAG_CODE
return NS_OK;
#else
nsString XIFBuffer;
// get the DOM select here
nsCOMPtr<nsIDOMSelection> sel;
editor->GetSelection(getter_AddRefs(sel));
nsCOMPtr<nsIEditor> editor (do_QueryInterface(mEditor)); // convert the DOMselection to XIF
if (!editor) if (sel)
return NS_ERROR_FAILURE; {
// if we are within the selection, start the drag
// Set the selection to the point under the mouse cursor: nsCOMPtr<nsIDOMNode> target;
nsCOMPtr<nsIDOMNSUIEvent> mouseEvent (do_QueryInterface(aMouseEvent)); nsresult rv = aMouseEvent->GetTarget(getter_AddRefs(target));
if (NS_FAILED(rv) || !target) { return NS_OK; }
PRBool isInSel;
rv = IsNodeInSelection(target, sel, isInSel);
if (NS_FAILED(rv) || PR_FALSE==isInSel) { return NS_OK; }
doc->CreateXIF(XIFBuffer, sel);
if (!mouseEvent) // Get the Clipboard
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event". nsIClipboard* clipboard;
nsCOMPtr<nsIDOMNode> parent; rv = nsServiceManager::GetService(kCClipboardCID,
if (!NS_SUCCEEDED(mouseEvent->GetRangeParent(getter_AddRefs(parent)))) nsIClipboard::GetIID(),
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event". (nsISupports **)&clipboard);
PRInt32 offset = 0; if (NS_OK == rv)
if (!NS_SUCCEEDED(mouseEvent->GetRangeOffset(&offset))) {
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event". // Create a data flavor to tell the transferable
// that it is about to receive XIF
nsAutoString flavor(kXIFMime);
nsCOMPtr<nsIDOMSelection> selection; // Create a transferable for putting data on the Clipboard
if (NS_SUCCEEDED(editor->GetSelection(getter_AddRefs(selection)))) nsCOMPtr<nsITransferable> trans;
(void)selection->Collapse(parent, offset); rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
nsITransferable::GetIID(),
(void**) getter_AddRefs(trans));
if (NS_OK == rv) {
// The data on the clipboard will be in "XIF" format
// so give the clipboard transferable a "XIFConverter" for
// converting from XIF to other formats
nsCOMPtr<nsIFormatConverter> xifConverter;
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
nsIFormatConverter::GetIID(), (void**) getter_AddRefs(xifConverter));
if (NS_OK == rv) {
// Add the XIF DataFlavor to the transferable
// this tells the transferable that it can handle receiving the XIF format
trans->AddDataFlavor(&flavor);
// If the ctrl key is pressed, we'll do paste as quotation. // Add the converter for going from XIF to other formats
// Would've used the alt key, but the kde wmgr treats alt-middle specially. trans->SetConverter(xifConverter);
PRBool ctrlKey = PR_FALSE;
uiEvent->GetCtrlKey(&ctrlKey);
if (ctrlKey) // Now add the XIF data to the transferable
{ // the transferable wants the number bytes for the data and since it is double byte
nsCOMPtr<nsIEditorMailSupport> mailEditor = do_QueryInterface(mEditor); // we multiply by 2
if (mailEditor) trans->SetTransferData(&flavor, XIFBuffer.ToNewUnicode(), XIFBuffer.Length()*2);
mailEditor->PasteAsQuotation();
// Now invoke the drag session
nsIDragService* dragService;
nsresult rv = nsServiceManager::GetService(kCDragServiceCID,
nsIDragService::GetIID(),
(nsISupports **)&dragService);
if (NS_OK == rv) {
nsCOMPtr<nsISupportsArray> items;
NS_NewISupportsArray(getter_AddRefs(items));
if ( items ) {
items->AppendElement(trans);
dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE);
}
nsServiceManager::ReleaseService(kCDragServiceCID, dragService);
}
}
}
nsServiceManager::ReleaseService(kCClipboardCID, clipboard);
}
return NS_ERROR_BASE; // return that we've handled the event
}
#endif
} }
return editor->Paste(); // middle-mouse click (paste);
else if (button == 2)
{
// Set the selection to the point under the mouse cursor:
nsCOMPtr<nsIDOMNSUIEvent> mouseEvent (do_QueryInterface(aMouseEvent));
if (!mouseEvent)
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
nsCOMPtr<nsIDOMNode> parent;
if (!NS_SUCCEEDED(mouseEvent->GetRangeParent(getter_AddRefs(parent))))
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
PRInt32 offset = 0;
if (!NS_SUCCEEDED(mouseEvent->GetRangeOffset(&offset)))
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(editor->GetSelection(getter_AddRefs(selection))))
(void)selection->Collapse(parent, offset);
// If the ctrl key is pressed, we'll do paste as quotation.
// Would've used the alt key, but the kde wmgr treats alt-middle specially.
PRBool ctrlKey = PR_FALSE;
uiEvent->GetCtrlKey(&ctrlKey);
if (ctrlKey)
{
nsCOMPtr<nsIEditorMailSupport> mailEditor = do_QueryInterface(mEditor);
if (mailEditor)
mailEditor->PasteAsQuotation();
}
editor->Paste();
return NS_ERROR_BASE; // NS_ERROR_BASE means "We did process the event".
}
return NS_OK; // did not process the event
} }
nsresult nsresult
nsTextEditorMouseListener::MouseUp(nsIDOMEvent* aMouseEvent) nsTextEditorMouseListener::MouseUp(nsIDOMEvent* aMouseEvent)
{ {
@ -1425,9 +1579,6 @@ nsTextEditorFocusListener::HandleEvent(nsIDOMEvent* aEvent)
nsresult nsresult
nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent) nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
{ {
// turn on selection and caret
if (mEditor)
{
// turn on selection and caret // turn on selection and caret
if (mEditor) if (mEditor)
{ {
@ -1474,8 +1625,6 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
} }
return NS_OK; return NS_OK;
} }
return NS_OK;
}
nsresult nsresult
nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent) nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)

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

@ -104,11 +104,10 @@ nsTextEditRules::SetFlags(PRUint32 aFlags)
// put a "white-space: pre" style on the body // put a "white-space: pre" style on the body
nsCOMPtr<nsIDOMElement> bodyElement; nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
if (NS_SUCCEEDED(res) && bodyElement) if (NS_FAILED(res)) return res;
{ if (!bodyElement) return NS_ERROR_NULL_POINTER;
// not going through the editor to do this. // not going through the editor to do this.
bodyElement->SetAttribute("style", "white-space: pre"); bodyElement->SetAttribute("style", "white-space: pre");
}
} }
} }
mFlags = aFlags; mFlags = aFlags;
@ -394,7 +393,9 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
// splitting anchor twice sets newTextNode as an empty text node between // splitting anchor twice sets newTextNode as an empty text node between
// two halves of the original text node // two halves of the original text node
result = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode)); result = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
result = mEditor->SplitNode(anchorAsText, 0, getter_AddRefs(newTextNode)); if (NS_SUCCEEDED(result)) {
result = mEditor->SplitNode(anchorAsText, 0, getter_AddRefs(newTextNode));
}
} }
} }
// now we have the new text node we are going to insert into. // now we have the new text node we are going to insert into.
@ -464,37 +465,30 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
} }
else // we have no selection, so insert a style tag in the body else // we have no selection, so insert a style tag in the body
{ {
nsCOMPtr<nsIDOMDocument>doc; nsCOMPtr<nsIDOMElement> bodyElement;
mEditor->GetDocument(getter_AddRefs(doc)); nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
nsCOMPtr<nsIDOMNodeList>nodeList; if (NS_FAILED(res)) return res;
nsAutoString bodyTag = "body"; if (!bodyElement) return NS_ERROR_NULL_POINTER;
result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
if ((NS_SUCCEEDED(result)) && nodeList) nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
{ if (bodyNode)
PRUint32 count; { // now we've got the body tag. insert the style tag
nodeList->GetLength(&count); if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!"); {
nsCOMPtr<nsIDOMNode>bodyNode; if (PR_TRUE==aTypeInState.GetBold()) {
result = nodeList->Item(0, getter_AddRefs(bodyNode)); InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
if ((NS_SUCCEEDED(result)) && bodyNode)
{ // now we've got the body tag. insert the style tag
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
{
if (PR_TRUE==aTypeInState.GetBold()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
}
} }
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC)) }
{ if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
if (PR_TRUE==aTypeInState.GetItalic()) { {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection); if (PR_TRUE==aTypeInState.GetItalic()) {
} InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection);
} }
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE)) }
{ if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
if (PR_TRUE==aTypeInState.GetUnderline()) { {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::u, aSelection); if (PR_TRUE==aTypeInState.GetUnderline()) {
} InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::u, aSelection);
} }
} }
} }
@ -513,12 +507,11 @@ nsTextEditRules::CreateFontStyleForInsertText(nsIDOMNode *aNewTextNode,
if (0!=aValue.Length()) if (0!=aValue.Length())
{ {
result = InsertStyleNode(aNewTextNode, nsIEditProperty::font, aSelection, getter_AddRefs(newStyleNode)); result = InsertStyleNode(aNewTextNode, nsIEditProperty::font, aSelection, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result) && newStyleNode) if (NS_FAILED(result)) return result;
{ if (!newStyleNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement>element = do_QueryInterface(newStyleNode); nsCOMPtr<nsIDOMElement>element = do_QueryInterface(newStyleNode);
if (element) { if (element) {
result = mEditor->SetAttribute(element, aAttr, aValue); result = mEditor->SetAttribute(element, aAttr, aValue);
}
} }
} }
else else
@ -540,21 +533,26 @@ nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode,
nsresult result; nsresult result;
nsCOMPtr<nsIDOMNode>parent; nsCOMPtr<nsIDOMNode>parent;
aNode->GetParentNode(getter_AddRefs(parent)); aNode->GetParentNode(getter_AddRefs(parent));
if (NS_FAILED(result)) return result;
if (!parent) return NS_ERROR_NULL_POINTER;
PRInt32 offsetInParent; PRInt32 offsetInParent;
nsEditor::GetChildOffset(aNode, parent, offsetInParent); result = nsEditor::GetChildOffset(aNode, parent, offsetInParent);
if (NS_FAILED(result)) return result;
nsAutoString tag; nsAutoString tag;
aTag->ToString(tag); aTag->ToString(tag);
result = mEditor->CreateNode(tag, parent, offsetInParent, aNewNode); result = mEditor->CreateNode(tag, parent, offsetInParent, aNewNode);
if ((NS_SUCCEEDED(result)) && *aNewNode) if (NS_FAILED(result)) return result;
if (!aNewNode) return NS_ERROR_NULL_POINTER;
result = mEditor->DeleteNode(aNode);
if (NS_SUCCEEDED(result))
{ {
result = mEditor->DeleteNode(aNode); result = mEditor->InsertNode(aNode, *aNewNode, 0);
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result)) {
{ if (aSelection) {
result = mEditor->InsertNode(aNode, *aNewNode, 0); result = aSelection->Collapse(aNode, 0);
if (NS_SUCCEEDED(result)) {
if (aSelection) {
aSelection->Collapse(aNode, 0);
}
} }
} }
} }
@ -575,16 +573,17 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
nsCOMPtr<nsIDOMNode>anchor; nsCOMPtr<nsIDOMNode>anchor;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(anchor)); result = aSelection->GetAnchorNode(getter_AddRefs(anchor));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && anchor) if (NS_FAILED(result)) return result;
if (!anchor) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMCharacterData>anchorAsText;
anchorAsText = do_QueryInterface(anchor);
if (anchorAsText)
{ {
nsCOMPtr<nsIDOMCharacterData>anchorAsText; nsCOMPtr<nsIDOMNode> newStyleNode;
anchorAsText = do_QueryInterface(anchor); result = InsertStyleNode(anchor, aTag, aSelection, getter_AddRefs(newStyleNode));
if (anchorAsText) return result;
{
nsCOMPtr<nsIDOMNode> newStyleNode;
result = InsertStyleNode(anchor, aTag, aSelection, getter_AddRefs(newStyleNode));
return result;
}
} }
} }
// if we get here, there is no selected text node so we create one. // if we get here, there is no selected text node so we create one.
@ -593,15 +592,15 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
nsCOMPtr<nsIDOMNode>newStyleNode; nsCOMPtr<nsIDOMNode>newStyleNode;
nsCOMPtr<nsIDOMNode>newTextNode; nsCOMPtr<nsIDOMNode>newTextNode;
result = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode)); result = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result)) if (NS_FAILED(result)) return result;
{ if (!newStyleNode) return NS_ERROR_NULL_POINTER;
result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result)) result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
{ if (NS_FAILED(result)) return result;
if (aSelection) { if (!newTextNode) return NS_ERROR_NULL_POINTER;
aSelection->Collapse(newTextNode, 0);
} if (aSelection) {
} result = aSelection->Collapse(newTextNode, 0);
} }
return result; return result;
} }
@ -707,55 +706,63 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection,
nsCOMPtr<nsIDOMNode>anchor; nsCOMPtr<nsIDOMNode>anchor;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(anchor)); result = aSelection->GetAnchorNode(getter_AddRefs(anchor));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && anchor) if (NS_FAILED(result)) return result;
if (!anchor) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMNodeList> anchorChildren;
result = anchor->GetChildNodes(getter_AddRefs(anchorChildren));
nsCOMPtr<nsIDOMNode> selectedNode;
if ((NS_SUCCEEDED(result)) && anchorChildren) {
result = anchorChildren->Item(offset, getter_AddRefs(selectedNode));
}
else {
selectedNode = do_QueryInterface(anchor);
}
if ((NS_SUCCEEDED(result)) && selectedNode)
{ {
nsCOMPtr<nsIDOMNodeList> anchorChildren; nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText;
result = anchor->GetChildNodes(getter_AddRefs(anchorChildren)); selectedNodeAsText = do_QueryInterface(selectedNode);
nsCOMPtr<nsIDOMNode> selectedNode; if (selectedNodeAsText)
if ((NS_SUCCEEDED(result)) && anchorChildren) {
result = anchorChildren->Item(offset, getter_AddRefs(selectedNode));
}
else {
selectedNode = do_QueryInterface(anchor);
}
if ((NS_SUCCEEDED(result)) && selectedNode)
{ {
nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText; nsCOMPtr<nsIDOMNode> siblingNode;
selectedNodeAsText = do_QueryInterface(selectedNode); selectedNode->GetPreviousSibling(getter_AddRefs(siblingNode));
if (selectedNodeAsText) if (siblingNode)
{ {
nsCOMPtr<nsIDOMNode> siblingNode; nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
selectedNode->GetPreviousSibling(getter_AddRefs(siblingNode)); siblingNodeAsText = do_QueryInterface(siblingNode);
if (siblingNode) if (siblingNodeAsText)
{ {
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText; PRUint32 siblingLength; // the length of siblingNode before the join
siblingNodeAsText = do_QueryInterface(siblingNode); siblingNodeAsText->GetLength(&siblingLength);
if (siblingNodeAsText) nsCOMPtr<nsIDOMNode> parentNode;
{ result = selectedNode->GetParentNode(getter_AddRefs(parentNode));
PRUint32 siblingLength; // the length of siblingNode before the join if (NS_FAILED(result)) return result;
siblingNodeAsText->GetLength(&siblingLength); if (!parentNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parentNode; result = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
selectedNode->GetParentNode(getter_AddRefs(parentNode)); // selectedNode will remain after the join, siblingNode is removed
result = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
// selectedNode will remain after the join, siblingNode is removed
}
} }
selectedNode->GetNextSibling(getter_AddRefs(siblingNode)); }
if (siblingNode) selectedNode->GetNextSibling(getter_AddRefs(siblingNode));
if (siblingNode)
{
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
siblingNodeAsText = do_QueryInterface(siblingNode);
if (siblingNodeAsText)
{ {
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText; PRUint32 selectedNodeLength; // the length of siblingNode before the join
siblingNodeAsText = do_QueryInterface(siblingNode); selectedNodeAsText->GetLength(&selectedNodeLength);
if (siblingNodeAsText) nsCOMPtr<nsIDOMNode> parentNode;
{ result = selectedNode->GetParentNode(getter_AddRefs(parentNode));
PRUint32 selectedNodeLength; // the length of siblingNode before the join if (NS_FAILED(result)) return result;
selectedNodeAsText->GetLength(&selectedNodeLength); if (!parentNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parentNode;
selectedNode->GetParentNode(getter_AddRefs(parentNode)); result = mEditor->JoinNodes(selectedNode, siblingNode, parentNode);
result = mEditor->JoinNodes(selectedNode, siblingNode, parentNode); if (NS_FAILED(result)) return result;
// selectedNode will remain after the join, siblingNode is removed // selectedNode will remain after the join, siblingNode is removed
// set selection // set selection
aSelection->Collapse(siblingNode, selectedNodeLength); result = aSelection->Collapse(siblingNode, selectedNodeLength);
}
} }
} }
} }
@ -795,23 +802,24 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
nsCOMPtr<nsIDOMNode>node; nsCOMPtr<nsIDOMNode>node;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(node)); result = aSelection->GetAnchorNode(getter_AddRefs(node));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && node) if (NS_FAILED(result)) return result;
if (!node) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMElement>element;
element = do_QueryInterface(node);
if (element)
{ {
nsCOMPtr<nsIDOMElement>element; nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
element = do_QueryInterface(node); nsAutoString val;
if (element) (void)element->GetAttribute(att, val);
{ if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); mBogusNode = do_QueryInterface(element);
nsAutoString val;
(void)element->GetAttribute(att, val);
if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
mBogusNode = do_QueryInterface(element);
}
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
} }
return result; return result;
@ -842,23 +850,24 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
nsCOMPtr<nsIDOMNode>node; nsCOMPtr<nsIDOMNode>node;
PRInt32 offset; PRInt32 offset;
result = aSelection->GetAnchorNode(getter_AddRefs(node)); result = aSelection->GetAnchorNode(getter_AddRefs(node));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && node) if (NS_FAILED(result)) return result;
if (!node) return NS_ERROR_NULL_POINTER;
result = aSelection->GetAnchorOffset(&offset);
if (NS_FAILED(result)) return result;
nsCOMPtr<nsIDOMElement>element;
element = do_QueryInterface(node);
if (element)
{ {
nsCOMPtr<nsIDOMElement>element; nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
element = do_QueryInterface(node); nsAutoString val;
if (element) (void)element->GetAttribute(att, val);
{ if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); mBogusNode = do_QueryInterface(element);
nsAutoString val;
(void)element->GetAttribute(att, val);
if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
mBogusNode = do_QueryInterface(element);
}
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
nsCOMPtr<nsIDOMNode> temp;
result = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
} }
} }
return result; return result;
@ -895,86 +904,63 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection)
{ {
if (!aSelection) { return NS_ERROR_NULL_POINTER; } if (!aSelection) { return NS_ERROR_NULL_POINTER; }
if (!mEditor) { return NS_ERROR_NULL_POINTER; } if (!mEditor) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIDOMDocument>doc;
mEditor->GetDocument(getter_AddRefs(doc)); nsCOMPtr<nsIDOMElement> bodyElement;
nsCOMPtr<nsIDOMNodeList>nodeList; nsresult result = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
nsAutoString bodyTag = "body"; if (NS_FAILED(result)) return result;
nsresult result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList)); if (!bodyElement) return NS_ERROR_NULL_POINTER;
if ((NS_SUCCEEDED(result)) && nodeList) nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
// now we've got the body tag.
// iterate the body tag, looking for editable content
// if no editable content is found, insert the bogus node
PRBool needsBogusContent=PR_TRUE;
nsCOMPtr<nsIDOMNode>bodyChild;
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
while ((NS_SUCCEEDED(result)) && bodyChild)
{ {
PRUint32 count; if (PR_TRUE==mEditor->IsEditable(bodyChild))
nodeList->GetLength(&count); {
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!"); needsBogusContent = PR_FALSE;
nsCOMPtr<nsIDOMNode>bodyNode; break;
result = nodeList->Item(0, getter_AddRefs(bodyNode)); }
if ((NS_SUCCEEDED(result)) && bodyNode) nsCOMPtr<nsIDOMNode>temp;
{ // now we've got the body tag. bodyChild->GetNextSibling(getter_AddRefs(temp));
// iterate the body tag, looking for editable content bodyChild = do_QueryInterface(temp);
// if no editable content is found, insert the bogus node }
PRBool needsBogusContent=PR_TRUE; if (PR_TRUE==needsBogusContent)
nsCOMPtr<nsIDOMNode>bodyChild; {
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild)); // set mBogusNode to be the newly created <P>
while ((NS_SUCCEEDED(result)) && bodyChild) result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0,
{ getter_AddRefs(mBogusNode));
if (PR_TRUE==mEditor->IsEditable(bodyChild)) if (NS_FAILED(result)) return result;
{ if (!mBogusNode) return NS_ERROR_NULL_POINTER;
needsBogusContent = PR_FALSE;
break; nsCOMPtr<nsIDOMNode>newTNode;
} result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), mBogusNode, 0,
nsCOMPtr<nsIDOMNode>temp; getter_AddRefs(newTNode));
bodyChild->GetNextSibling(getter_AddRefs(temp)); if (NS_FAILED(result)) return result;
bodyChild = do_QueryInterface(temp); if (!newTNode) return NS_ERROR_NULL_POINTER;
}
if (PR_TRUE==needsBogusContent) nsCOMPtr<nsIDOMCharacterData>newNodeAsText;
{ newNodeAsText = do_QueryInterface(newTNode);
// set mBogusNode to be the newly created <P> if (newNodeAsText)
result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0, {
getter_AddRefs(mBogusNode)); nsAutoString data;
if ((NS_SUCCEEDED(result)) && mBogusNode) data += 160;
{ newNodeAsText->SetData(data);
nsCOMPtr<nsIDOMNode>newTNode; aSelection->Collapse(newTNode, 0);
result = mEditor->CreateNode(nsEditor::GetTextNodeTag(), mBogusNode, 0, }
getter_AddRefs(newTNode)); // make sure we know the PNode is bogus
if ((NS_SUCCEEDED(result)) && newTNode) nsCOMPtr<nsIDOMElement>newPElement;
{ newPElement = do_QueryInterface(mBogusNode);
nsCOMPtr<nsIDOMCharacterData>newNodeAsText; if (newPElement)
newNodeAsText = do_QueryInterface(newTNode); {
if (newNodeAsText) nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
{ nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
nsAutoString data; newPElement->SetAttribute(att, val);
data += 160;
newNodeAsText->SetData(data);
aSelection->Collapse(newTNode, 0);
}
}
// make sure we know the PNode is bogus
nsCOMPtr<nsIDOMElement>newPElement;
newPElement = do_QueryInterface(mBogusNode);
if (newPElement)
{
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
newPElement->SetAttribute(att, val);
}
}
}
} }
} }
return result; return result;
} }