mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
implemented simple cases of RemoveTextProperty. other cases are no-op'd now.
added aFirst out param to GetTextProperty, so the caller can know if the first character has the property in the case of aAny=true and aAll=false. fixed a bunch of places where result was being used incorrectly as a return val from do_QueryInterface some minor undo/redo fixes to split and join of interior nodes.
This commit is contained in:
parent
b249af5eeb
commit
16027c9454
@ -50,7 +50,7 @@ DeleteElementTxn::~DeleteElementTxn()
|
||||
|
||||
NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
{
|
||||
if (gNoisy) { printf("Do Delete Element element = %p\n", mElement.get()); }
|
||||
if (gNoisy) { printf("%p Do Delete Element element = %p\n", this, mElement.get()); }
|
||||
if (!mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
@ -65,12 +65,12 @@ NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
#ifdef NS_DEBUG
|
||||
// begin debug output
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
element = do_QueryInterface(mElement, &result);
|
||||
element = do_QueryInterface(mElement);
|
||||
nsAutoString elementTag="text node";
|
||||
if (element)
|
||||
element->GetTagName(elementTag);
|
||||
nsCOMPtr<nsIDOMElement> parentElement;
|
||||
parentElement = do_QueryInterface(mParent, &result);
|
||||
parentElement = do_QueryInterface(mParent);
|
||||
nsAutoString parentElementTag="text node";
|
||||
if (parentElement)
|
||||
parentElement->GetTagName(parentElementTag);
|
||||
@ -80,7 +80,7 @@ NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
if (c&&p)
|
||||
{
|
||||
if (gNoisy)
|
||||
printf("DeleteElementTxn: deleting child %s from parent %s\n", c, p);
|
||||
printf(" DeleteElementTxn: deleting child %s from parent %s\n", c, p);
|
||||
delete [] c;
|
||||
delete [] p;
|
||||
}
|
||||
@ -97,10 +97,35 @@ NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
|
||||
NS_IMETHODIMP DeleteElementTxn::Undo(void)
|
||||
{
|
||||
if (gNoisy) { printf("Do Delete Element element = %p, parent = %p\n", mElement.get(), mParent.get()); }
|
||||
if (gNoisy) { printf("%p Undo Delete Element element = %p, parent = %p\n", this, mElement.get(), mParent.get()); }
|
||||
if (!mParent || !mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// begin debug output
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
element = do_QueryInterface(mElement);
|
||||
nsAutoString elementTag="text node";
|
||||
if (element)
|
||||
element->GetTagName(elementTag);
|
||||
nsCOMPtr<nsIDOMElement> parentElement;
|
||||
parentElement = do_QueryInterface(mParent);
|
||||
nsAutoString parentElementTag="text node";
|
||||
if (parentElement)
|
||||
parentElement->GetTagName(parentElementTag);
|
||||
char *c, *p;
|
||||
c = elementTag.ToNewCString();
|
||||
p = parentElementTag.ToNewCString();
|
||||
if (c&&p)
|
||||
{
|
||||
if (gNoisy)
|
||||
printf(" DeleteElementTxn: inserting child %s back into parent %s\n", c, p);
|
||||
delete [] c;
|
||||
delete [] p;
|
||||
}
|
||||
// end debug output
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
nsresult result = mParent->InsertBefore(mElement, mRefNode, getter_AddRefs(resultNode));
|
||||
return result;
|
||||
@ -108,7 +133,7 @@ NS_IMETHODIMP DeleteElementTxn::Undo(void)
|
||||
|
||||
NS_IMETHODIMP DeleteElementTxn::Redo(void)
|
||||
{
|
||||
if (gNoisy) { printf("Redo Delete Element\n"); }
|
||||
if (gNoisy) { printf("%p Redo Delete Element element = %p, parent = %p\n", this, mElement.get(), mParent.get()); }
|
||||
if (!mParent || !mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -69,7 +69,7 @@ NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
|
||||
{
|
||||
PRUint32 count;
|
||||
nsCOMPtr<nsIDOMCharacterData> textNode;
|
||||
textNode = do_QueryInterface(mStartParent, &result);
|
||||
textNode = do_QueryInterface(mStartParent);
|
||||
if (textNode)
|
||||
textNode->GetLength(&count);
|
||||
else
|
||||
@ -81,7 +81,7 @@ NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
|
||||
}
|
||||
NS_ASSERTION(mStartOffset<=(PRInt32)count, "bad start offset");
|
||||
|
||||
textNode = do_QueryInterface(mEndParent, &result);
|
||||
textNode = do_QueryInterface(mEndParent);
|
||||
if (textNode)
|
||||
textNode->GetLength(&count);
|
||||
else
|
||||
|
@ -36,9 +36,9 @@ DeleteTextTxn::~DeleteTextTxn()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
|
||||
nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aNumCharsToDelete)
|
||||
nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aNumCharsToDelete)
|
||||
{
|
||||
NS_ASSERTION(aEditor&&aElement, "bad arg");
|
||||
mEditor = do_QueryInterface(aEditor);
|
||||
@ -46,6 +46,10 @@ NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
|
||||
mOffset = aOffset;
|
||||
mNumCharsToDelete = aNumCharsToDelete;
|
||||
NS_ASSERTION(0!=aNumCharsToDelete, "bad arg, numCharsToDelete");
|
||||
PRUint32 count;
|
||||
aElement->GetLength(&count);
|
||||
NS_ASSERTION(count<aNumCharsToDelete, "bad arg, numCharsToDelete. Not enough characters in node");
|
||||
NS_ASSERTION(count<aOffset+aNumCharsToDelete, "bad arg, numCharsToDelete. Not enough characters in node");
|
||||
mDeletedText = "";
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -54,13 +54,14 @@ InsertElementTxn::~InsertElementTxn()
|
||||
|
||||
NS_IMETHODIMP InsertElementTxn::Do(void)
|
||||
{
|
||||
if (gNoisy) { printf("Do Insert Element\n"); }
|
||||
if (gNoisy) { printf("%p Do Insert Element of %p into parent %p at offset %d\n",
|
||||
this, mNode, mParent, mOffset); }
|
||||
if (!mNode || !mParent)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult result;
|
||||
nsCOMPtr<nsIDOMNode>refNode;
|
||||
if (0!=mOffset)
|
||||
//if (0!=mOffset)
|
||||
{ // get a ref node
|
||||
PRInt32 i=0;
|
||||
result = mParent->GetFirstChild(getter_AddRefs(refNode));
|
||||
@ -94,7 +95,8 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
|
||||
|
||||
NS_IMETHODIMP InsertElementTxn::Undo(void)
|
||||
{
|
||||
if (gNoisy) { printf("Undo Insert Element\n"); }
|
||||
if (gNoisy) { printf("%p Undo Insert Element of %p into parent %p at offset %d\n",
|
||||
this, mNode, mParent, mOffset); }
|
||||
if (!mNode || !mParent)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -135,7 +135,7 @@ NS_IMETHODIMP InsertTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransacti
|
||||
if (childTxn)
|
||||
{
|
||||
nsCOMPtr<InsertTextTxn> otherInsertTxn;
|
||||
otherInsertTxn = do_QueryInterface(childTxn, &result);
|
||||
otherInsertTxn = do_QueryInterface(childTxn);
|
||||
if (otherInsertTxn)
|
||||
{
|
||||
if (PR_TRUE==IsSequentialInsert(otherInsertTxn))
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "nsIEditorSupport.h"
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gNoisy = PR_TRUE;
|
||||
static PRBool gNoisy = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gNoisy = PR_FALSE;
|
||||
#endif
|
||||
@ -63,7 +63,7 @@ NS_IMETHODIMP SplitElementTxn::Do(void)
|
||||
|
||||
if ((NS_SUCCEEDED(result)) && (mNewLeftNode))
|
||||
{
|
||||
if (gNoisy) { printf(" created left node = %p\n", this, mNewLeftNode.get()); }
|
||||
if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); }
|
||||
// get the parent node
|
||||
result = mExistingRightNode->GetParentNode(getter_AddRefs(mParent));
|
||||
// insert the new node
|
||||
@ -103,21 +103,6 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// sanity check
|
||||
nsCOMPtr<nsIDOMNode>parent;
|
||||
nsresult debugResult = mExistingRightNode->GetParentNode(getter_AddRefs(parent));
|
||||
NS_ASSERTION((NS_SUCCEEDED(debugResult)), "bad GetParentNode result for right child");
|
||||
NS_ASSERTION(parent, "bad GetParentNode for right child");
|
||||
NS_ASSERTION(parent==mParent, "bad GetParentNode for right child, parents don't match");
|
||||
|
||||
debugResult = mNewLeftNode->GetParentNode(getter_AddRefs(parent));
|
||||
NS_ASSERTION((NS_SUCCEEDED(debugResult)), "bad GetParentNode result for left child");
|
||||
NS_ASSERTION(parent, "bad GetParentNode for left child");
|
||||
NS_ASSERTION(parent==mParent, "bad GetParentNode for right child, left don't match");
|
||||
|
||||
#endif
|
||||
|
||||
// this assumes Do inserted the new node in front of the prior existing node
|
||||
nsresult result;
|
||||
nsCOMPtr<nsIEditorSupport> editor;
|
||||
@ -125,6 +110,11 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
|
||||
if (NS_SUCCEEDED(result) && editor)
|
||||
{
|
||||
result = editor->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** after join left child node %p into right node %p\n", mNewLeftNode.get(), mExistingRightNode.get());
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
if (gNoisy) { printf(" left node = %p removed\n", this, mNewLeftNode.get()); }
|
||||
@ -154,6 +144,7 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
|
||||
if (gNoisy) {
|
||||
printf("%p Redo Split of existing node %p and new node %p offset %d\n",
|
||||
this, mExistingRightNode.get(), mNewLeftNode.get(), mOffset);
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
nsresult result;
|
||||
nsCOMPtr<nsIDOMNode>resultNode;
|
||||
@ -163,6 +154,11 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
|
||||
if (rightNodeAsText)
|
||||
{
|
||||
result = rightNodeAsText->DeleteData(0, mOffset);
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** after delete of text in right text node %p offset %d\n", rightNodeAsText.get(), mOffset);
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -176,11 +172,25 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
|
||||
if (!child) {return NS_ERROR_NULL_POINTER;}
|
||||
child->GetNextSibling(getter_AddRefs(nextSibling));
|
||||
result = mExistingRightNode->RemoveChild(child, getter_AddRefs(resultNode));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
result = mNewLeftNode->AppendChild(child, getter_AddRefs(resultNode));
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** move child node %p from right node %p to left node %p\n", child.get(), mExistingRightNode.get(), mNewLeftNode.get());
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
}
|
||||
child = do_QueryInterface(nextSibling);
|
||||
}
|
||||
}
|
||||
// second, re-insert the left node into the tree
|
||||
result = mParent->InsertBefore(mNewLeftNode, mExistingRightNode, getter_AddRefs(resultNode));
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** reinsert left child node %p before right node %p\n", mNewLeftNode.get(), mExistingRightNode.get());
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1128,7 +1128,7 @@ NS_IMETHODIMP nsEditor::CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
{
|
||||
result = NS_ERROR_UNEXPECTED;
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = do_QueryInterface(selection,&result);
|
||||
enumerator = do_QueryInterface(selection);
|
||||
if (enumerator)
|
||||
{
|
||||
enumerator->First();
|
||||
@ -1144,8 +1144,7 @@ NS_IMETHODIMP nsEditor::CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
result = range->GetStartParent(getter_AddRefs(node));
|
||||
if ((NS_SUCCEEDED(result)) && (node))
|
||||
{
|
||||
result = NS_ERROR_UNEXPECTED;
|
||||
nodeAsText = do_QueryInterface(node,&result);
|
||||
nodeAsText = do_QueryInterface(node);
|
||||
range->GetStartOffset(&offset);
|
||||
if (!nodeAsText) {
|
||||
result = NS_ERROR_EDITOR_NO_TEXTNODE;
|
||||
@ -1451,7 +1450,7 @@ NS_IMETHODIMP nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
||||
if ((NS_SUCCEEDED(result)) && selection)
|
||||
{
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = do_QueryInterface(selection,&result);
|
||||
enumerator = do_QueryInterface(selection);
|
||||
if (enumerator)
|
||||
{
|
||||
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
|
||||
@ -1553,7 +1552,7 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
||||
{ // there is a priorNode, so delete it's last child (if text content, delete the last char.)
|
||||
// if it has no children, delete it
|
||||
nsCOMPtr<nsIDOMCharacterData> priorNodeAsText;
|
||||
priorNodeAsText = do_QueryInterface(priorNode, &result);
|
||||
priorNodeAsText = do_QueryInterface(priorNode);
|
||||
if (priorNodeAsText)
|
||||
{
|
||||
PRUint32 length=0;
|
||||
@ -1590,7 +1589,7 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
||||
{ // there is a priorNode, so delete it's last child (if text content, delete the last char.)
|
||||
// if it has no children, delete it
|
||||
nsCOMPtr<nsIDOMCharacterData> nextNodeAsText;
|
||||
nextNodeAsText = do_QueryInterface(nextNode,&result);
|
||||
nextNodeAsText = do_QueryInterface(nextNode);
|
||||
if (nextNodeAsText)
|
||||
{
|
||||
PRUint32 length=0;
|
||||
@ -1815,6 +1814,9 @@ nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
|
||||
nsIDOMNode* aNewLeftNode,
|
||||
nsIDOMNode* aParent)
|
||||
{
|
||||
|
||||
printf("SplitNodeImpl: left=%p, right=%p, offset=%d\n", aNewLeftNode, aExistingRightNode, aOffset);
|
||||
|
||||
nsresult result;
|
||||
NS_ASSERTION(((nsnull!=aExistingRightNode) &&
|
||||
(nsnull!=aNewLeftNode) &&
|
||||
@ -1826,6 +1828,7 @@ nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
result = aParent->InsertBefore(aNewLeftNode, aExistingRightNode, getter_AddRefs(resultNode));
|
||||
//printf(" after insert\n"); content->List(); // DEBUG
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
// split the children between the 2 nodes
|
||||
@ -1847,21 +1850,26 @@ nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
|
||||
}
|
||||
else
|
||||
{ // otherwise it's an interior node, so shuffle around the children
|
||||
// go through list backwards so deletes don't interfere with the iteration
|
||||
nsCOMPtr<nsIDOMNodeList> childNodes;
|
||||
result = aExistingRightNode->GetChildNodes(getter_AddRefs(childNodes));
|
||||
if ((NS_SUCCEEDED(result)) && (childNodes))
|
||||
{
|
||||
PRInt32 i=0;
|
||||
for ( ; ((NS_SUCCEEDED(result)) && (i<aOffset)); i++)
|
||||
PRInt32 i=aOffset-1;
|
||||
for ( ; ((NS_SUCCEEDED(result)) && (0<=i)); i--)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
result = childNodes->Item(i, getter_AddRefs(childNode));
|
||||
if ((NS_SUCCEEDED(result)) && (childNode))
|
||||
{
|
||||
result = aExistingRightNode->RemoveChild(childNode, getter_AddRefs(resultNode));
|
||||
//printf(" after remove\n"); content->List(); // DEBUG
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
result = aNewLeftNode->AppendChild(childNode, getter_AddRefs(resultNode));
|
||||
nsCOMPtr<nsIDOMNode> firstChild;
|
||||
aNewLeftNode->GetFirstChild(getter_AddRefs(firstChild));
|
||||
result = aNewLeftNode->InsertBefore(childNode, firstChild, getter_AddRefs(resultNode));
|
||||
//printf(" after append\n"); content->List(); // DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1917,7 +1925,7 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
|
||||
result = aNodeToJoin->GetChildNodes(getter_AddRefs(childNodes));
|
||||
if ((NS_SUCCEEDED(result)) && (childNodes))
|
||||
{
|
||||
PRUint32 i;
|
||||
PRInt32 i; // must be signed int!
|
||||
PRUint32 childCount=0;
|
||||
childNodes->GetLength(&childCount);
|
||||
nsCOMPtr<nsIDOMNode> firstNode; //only used if aNodeToKeepIsFirst is false
|
||||
@ -1927,7 +1935,9 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
|
||||
// GetFirstChild returns nsnull firstNode if aNodeToKeep has no children, that's ok.
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
for (i=0; ((NS_SUCCEEDED(result)) && (i<childCount)); i++)
|
||||
// have to go through the list backwards to keep deletes from interfering with iteration
|
||||
nsCOMPtr<nsIDOMNode> previousChild;
|
||||
for (i=childCount-1; ((NS_SUCCEEDED(result)) && (0<=i)); i--)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
result = childNodes->Item(i, getter_AddRefs(childNode));
|
||||
@ -1935,11 +1945,15 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
|
||||
{
|
||||
if (PR_TRUE==aNodeToKeepIsFirst)
|
||||
{ // append children of aNodeToJoin
|
||||
result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
|
||||
//was result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
|
||||
result = aNodeToKeep->InsertBefore(childNode, previousChild, getter_AddRefs(resultNode));
|
||||
previousChild = do_QueryInterface(childNode);
|
||||
}
|
||||
else
|
||||
{ // prepend children of aNodeToJoin
|
||||
//was result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
|
||||
result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
|
||||
firstNode = do_QueryInterface(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2047,6 +2061,28 @@ NS_IMETHODIMP nsEditor::GetLayoutObject(nsIDOMNode *aNode, nsISupports **aLayout
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditor::DebugDumpContent() const
|
||||
{
|
||||
nsCOMPtr<nsIContent>content;
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString bodyTag = "body";
|
||||
mDoc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
||||
if (nodeList)
|
||||
{
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
||||
nsCOMPtr<nsIDOMNode>bodyNode;
|
||||
nodeList->Item(0, getter_AddRefs(bodyNode));
|
||||
if (bodyNode) {
|
||||
content = do_QueryInterface(bodyNode);
|
||||
}
|
||||
}
|
||||
content->List();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//END nsEditor Private methods
|
||||
|
||||
|
@ -60,13 +60,15 @@ private:
|
||||
nsIPresShell *mPresShell;
|
||||
nsIViewManager *mViewManager;
|
||||
PRUint32 mUpdateCount;
|
||||
nsCOMPtr<nsIDOMDocument> mDoc;
|
||||
nsCOMPtr<nsITransactionManager> mTxnMgr;
|
||||
|
||||
|
||||
friend PRBool NSCanUnload(nsISupports* serviceMgr);
|
||||
static PRInt32 gInstanceCount;
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDOMDocument> mDoc;
|
||||
|
||||
public:
|
||||
/** The default constructor. This should suffice. the setting of the interfaces is done
|
||||
* after the construction of the editor class.
|
||||
@ -278,8 +280,6 @@ protected:
|
||||
|
||||
NS_IMETHOD GetLeftmostChild(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode);
|
||||
|
||||
//Methods not exposed in nsIEditor
|
||||
|
||||
/** Create an aggregate transaction for deleting current selection
|
||||
* Used by all methods that need to delete current selection,
|
||||
* then insert something new to replace it
|
||||
@ -290,6 +290,8 @@ protected:
|
||||
*/
|
||||
NS_IMETHOD CreateAggregateTxnForDeleteSelection(nsIAtom *aTxnName, EditAggregateTxn **aAggTxn);
|
||||
|
||||
NS_IMETHOD DebugDumpContent() const;
|
||||
|
||||
protected:
|
||||
// XXXX: Horrible hack! We are doing this because
|
||||
// of an error in Gecko which is not rendering the
|
||||
|
@ -310,7 +310,18 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
|
||||
aProcessed=PR_TRUE;
|
||||
if (mEditor)
|
||||
{
|
||||
mEditor->SetTextProperty(nsIEditProperty::i);
|
||||
// XXX: move this logic down into texteditor rules delegate
|
||||
// should just call mEditor->ChangeTextProperty(prop)
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first = PR_FALSE;
|
||||
mEditor->GetTextProperty(nsIEditProperty::i, first, any, all);
|
||||
if (PR_FALSE==first) {
|
||||
mEditor->SetTextProperty(nsIEditProperty::i);
|
||||
}
|
||||
else {
|
||||
mEditor->RemoveTextProperty(nsIEditProperty::i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +347,18 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
|
||||
aProcessed=PR_TRUE;
|
||||
if (mEditor)
|
||||
{
|
||||
mEditor->SetTextProperty(nsIEditProperty::b);
|
||||
// XXX: move this logic down into texteditor rules delegate
|
||||
// should just call mEditor->ChangeTextProperty(prop)
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first = PR_FALSE;
|
||||
mEditor->GetTextProperty(nsIEditProperty::b, first, any, all);
|
||||
if (PR_FALSE==first) {
|
||||
mEditor->SetTextProperty(nsIEditProperty::b);
|
||||
}
|
||||
else {
|
||||
mEditor->RemoveTextProperty(nsIEditProperty::b);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -348,7 +370,19 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
|
||||
aProcessed=PR_TRUE;
|
||||
if (mEditor)
|
||||
{
|
||||
mEditor->SetTextProperty(nsIEditProperty::u);
|
||||
// XXX: move this logic down into texteditor rules delegate
|
||||
// should just call mEditor->ChangeTextProperty(prop)
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first = PR_FALSE;
|
||||
mEditor->GetTextProperty(nsIEditProperty::u, first, any, all);
|
||||
if (PR_FALSE==first) {
|
||||
mEditor->SetTextProperty(nsIEditProperty::u);
|
||||
}
|
||||
else {
|
||||
mEditor->RemoveTextProperty(nsIEditProperty::u);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -113,9 +113,9 @@ NS_IMETHODIMP nsHTMLEditor::SetTextProperty(nsIAtom *aProperty)
|
||||
return nsTextEditor::SetTextProperty(aProperty);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PRBool &aAll)
|
||||
NS_IMETHODIMP nsHTMLEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, PRBool &aAny, PRBool &aAll)
|
||||
{
|
||||
return nsTextEditor::GetTextProperty(aProperty, aAny, aAll);
|
||||
return nsTextEditor::GetTextProperty(aProperty, aFirst, aAny, aAll);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::RemoveTextProperty(nsIAtom *aProperty)
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
// Editing Operations
|
||||
NS_IMETHOD SetTextProperty(nsIAtom *aProperty);
|
||||
NS_IMETHOD GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PRBool &aAll);
|
||||
NS_IMETHOD GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, PRBool &aAny, PRBool &aAll);
|
||||
NS_IMETHOD RemoveTextProperty(nsIAtom *aProperty);
|
||||
NS_IMETHOD DeleteSelection(nsIEditor::Direction aDir);
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
|
@ -96,6 +96,11 @@ static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
|
||||
static NS_DEFINE_IID(kIContentIteratorIID, NS_ICONTENTITERTOR_IID);
|
||||
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gNoisy = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gNoisy = PR_FALSE;
|
||||
#endif
|
||||
|
||||
/* ---------- TypeInState implementation ---------- */
|
||||
// most methods are defined inline in TypeInState.h
|
||||
@ -317,8 +322,8 @@ NS_IMETHODIMP nsTextEditor::SetTextProperty(nsIAtom *aProperty)
|
||||
{
|
||||
nsEditor::BeginTransaction();
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = do_QueryInterface(selection, &result);
|
||||
if ((NS_SUCCEEDED(result)) && enumerator)
|
||||
enumerator = do_QueryInterface(selection);
|
||||
if (enumerator)
|
||||
{
|
||||
enumerator->First();
|
||||
nsISupports *currentItem;
|
||||
@ -401,7 +406,7 @@ NS_IMETHODIMP nsTextEditor::SetTextProperty(nsIAtom *aProperty)
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PRBool &aAll)
|
||||
NS_IMETHODIMP nsTextEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, PRBool &aAny, PRBool &aAll)
|
||||
{
|
||||
if (!aProperty)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
@ -409,13 +414,15 @@ NS_IMETHODIMP nsTextEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PR
|
||||
nsresult result=NS_ERROR_NOT_INITIALIZED;
|
||||
aAny=PR_FALSE;
|
||||
aAll=PR_TRUE;
|
||||
aFirst=PR_FALSE;
|
||||
PRBool first=PR_TRUE;
|
||||
nsCOMPtr<nsIDOMSelection>selection;
|
||||
result = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
if ((NS_SUCCEEDED(result)) && selection)
|
||||
{
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = do_QueryInterface(selection, &result);
|
||||
if ((NS_SUCCEEDED(result)) && enumerator)
|
||||
enumerator = do_QueryInterface(selection);
|
||||
if (enumerator)
|
||||
{
|
||||
enumerator->First();
|
||||
nsISupports *currentItem;
|
||||
@ -448,6 +455,11 @@ NS_IMETHODIMP nsTextEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PR
|
||||
{
|
||||
PRBool isSet;
|
||||
IsTextPropertySetByContent(node, aProperty, isSet);
|
||||
if (PR_TRUE==first)
|
||||
{
|
||||
aFirst = isSet;
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if (PR_TRUE==isSet) {
|
||||
aAny = PR_TRUE;
|
||||
}
|
||||
@ -523,7 +535,107 @@ void nsTextEditor::IsTextPropertySetByContent(nsIDOMNode *aNode,
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::RemoveTextProperty(nsIAtom *aProperty)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (!aProperty)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult result=NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIDOMSelection>selection;
|
||||
result = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
if ((NS_SUCCEEDED(result)) && selection)
|
||||
{
|
||||
PRBool isCollapsed;
|
||||
selection->IsCollapsed(&isCollapsed);
|
||||
if (PR_TRUE==isCollapsed)
|
||||
{
|
||||
// manipulating text attributes on a collapsed selection only sets state for the next text insertion
|
||||
SetTypeInStateForProperty(mTypeInState, aProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsEditor::BeginTransaction();
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = do_QueryInterface(selection);
|
||||
if (enumerator)
|
||||
{
|
||||
enumerator->First();
|
||||
nsISupports *currentItem;
|
||||
result = enumerator->CurrentItem(¤tItem);
|
||||
if ((NS_SUCCEEDED(result)) && (nsnull!=currentItem))
|
||||
{
|
||||
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
|
||||
nsCOMPtr<nsIDOMNode>commonParent;
|
||||
result = range->GetCommonParent(getter_AddRefs(commonParent));
|
||||
if ((NS_SUCCEEDED(result)) && commonParent)
|
||||
{
|
||||
PRInt32 startOffset, endOffset;
|
||||
range->GetStartOffset(&startOffset);
|
||||
range->GetEndOffset(&endOffset);
|
||||
nsCOMPtr<nsIDOMNode> startParent; nsCOMPtr<nsIDOMNode> endParent;
|
||||
range->GetStartParent(getter_AddRefs(startParent));
|
||||
range->GetEndParent(getter_AddRefs(endParent));
|
||||
if (startParent.get()==endParent.get())
|
||||
{ // the range is entirely contained within a single text node
|
||||
// commonParent==aStartParent, so get the "real" parent of the selection
|
||||
startParent->GetParentNode(getter_AddRefs(commonParent));
|
||||
result = RemoveTextPropertiesForNode(startParent, commonParent,
|
||||
startOffset, endOffset,
|
||||
aProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> startGrandParent;
|
||||
startParent->GetParentNode(getter_AddRefs(startGrandParent));
|
||||
nsCOMPtr<nsIDOMNode> endGrandParent;
|
||||
endParent->GetParentNode(getter_AddRefs(endGrandParent));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
PRBool canCollapseStyleNode = PR_FALSE;
|
||||
if (endGrandParent.get()==startGrandParent.get())
|
||||
{
|
||||
result = IntermediateNodesAreInline(range, startParent, startOffset,
|
||||
endParent, endOffset,
|
||||
startGrandParent, canCollapseStyleNode);
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
if (PR_TRUE==canCollapseStyleNode)
|
||||
{ // the range is between 2 nodes that have a common (immediate) grandparent,
|
||||
// and any intermediate nodes are just inline style nodes
|
||||
result = RemoveTextPropertiesForNodesWithSameParent(startParent,startOffset,
|
||||
endParent, endOffset,
|
||||
commonParent,
|
||||
aProperty);
|
||||
}
|
||||
else
|
||||
{ // the range is between 2 nodes that have no simple relationship
|
||||
result = RemoveTextPropertiesForNodeWithDifferentParents(range,
|
||||
startParent,startOffset,
|
||||
endParent, endOffset,
|
||||
commonParent,
|
||||
aProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{ // compute a range for the selection
|
||||
// don't want to actually do anything with selection, because
|
||||
// we are still iterating through it. Just want to create and remember
|
||||
// an nsIDOMRange, and later add the range to the selection after clearing it.
|
||||
// XXX: I'm blocked here because nsIDOMSelection doesn't provide a mechanism
|
||||
// for setting a compound selection yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nsEditor::EndTransaction();
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{ // set the selection
|
||||
// XXX: can't do anything until I can create ranges
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::DeleteSelection(nsIEditor::Direction aDir)
|
||||
@ -1255,6 +1367,382 @@ nsTextEditor::SetTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRange,
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::RemoveTextPropertiesForNode(nsIDOMNode *aNode,
|
||||
nsIDOMNode *aParent,
|
||||
PRInt32 aStartOffset,
|
||||
PRInt32 aEndOffset,
|
||||
nsIAtom *aPropName)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
|
||||
nodeAsChar = do_QueryInterface(aNode);
|
||||
if (!nodeAsChar)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool textPropertySet;
|
||||
IsTextPropertySetByContent(aNode, aPropName, textPropertySet);
|
||||
if (PR_TRUE==textPropertySet)
|
||||
{
|
||||
PRUint32 count;
|
||||
nodeAsChar->GetLength(&count);
|
||||
// split the node, and all parent nodes up to the style node
|
||||
// then promote the selected content to the parent of the style node
|
||||
nsCOMPtr<nsIDOMNode>newLeftNode; // this will be the leftmost node,
|
||||
// the node being split will be rightmost
|
||||
if (0!=aStartOffset) {
|
||||
printf("* splitting text node %p at %d\n", aNode, aStartOffset);
|
||||
result = nsEditor::SplitNode(aNode, aStartOffset, getter_AddRefs(newLeftNode));
|
||||
printf("* split created left node %p\n", newLeftNode.get());
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newMiddleNode; // this will be the middle node
|
||||
if ((PRInt32)count!=aEndOffset) {
|
||||
printf("* splitting text node (right node) %p at %d\n", aNode, aEndOffset-aStartOffset);
|
||||
result = nsEditor::SplitNode(aNode, aEndOffset-aStartOffset, getter_AddRefs(newMiddleNode));
|
||||
printf("* split created middle node %p\n", newMiddleNode.get());
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
else {
|
||||
printf("* no need to split text node\n");
|
||||
newMiddleNode = do_QueryInterface(aNode);
|
||||
}
|
||||
NS_ASSERTION(newMiddleNode, "no middle node created");
|
||||
// now that the text node is split, split parent nodes until we get to the style node
|
||||
nsCOMPtr<nsIDOMNode>parent;
|
||||
parent = do_QueryInterface(aParent); // we know this has to succeed, no need to check
|
||||
if (NS_SUCCEEDED(result) && newMiddleNode)
|
||||
{
|
||||
// split every ancestor until we find the node that is giving us the style we want to remove
|
||||
// then split the style node and promote the selected content to the style node's parent
|
||||
while (NS_SUCCEEDED(result) && parent)
|
||||
{
|
||||
printf("* looking at parent %p\n", parent);
|
||||
// get the tag from parent and see if we're done
|
||||
nsCOMPtr<nsIDOMNode>temp;
|
||||
nsCOMPtr<nsIDOMElement>element;
|
||||
element = do_QueryInterface(parent);
|
||||
if (element)
|
||||
{
|
||||
nsAutoString tag;
|
||||
result = element->GetTagName(tag);
|
||||
printf("* parent has tag %s\n", tag.ToNewCString()); // leak!
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
if (PR_FALSE==tag.Equals(aPropName))
|
||||
{
|
||||
printf("* this is not the style node\n");
|
||||
PRInt32 offsetInParent;
|
||||
result = nsIEditorSupport::GetChildOffset(newMiddleNode, parent, offsetInParent);
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
if (0!=offsetInParent) {
|
||||
printf("* splitting parent %p at offset %d\n", parent, offsetInParent);
|
||||
result = nsEditor::SplitNode(parent, offsetInParent, getter_AddRefs(newLeftNode));
|
||||
printf("* split created left node %p sibling of parent\n", newLeftNode.get());
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNodeList>childNodes;
|
||||
result = parent->GetChildNodes(getter_AddRefs(childNodes));
|
||||
if (NS_SUCCEEDED(result) && childNodes)
|
||||
{
|
||||
childNodes->GetLength(&count);
|
||||
NS_ASSERTION(count>0, "bad child count in newly split node");
|
||||
if ((PRInt32)count!=1)
|
||||
{
|
||||
printf("* splitting parent %p at offset %d\n", parent, 1);
|
||||
result = nsEditor::SplitNode(parent, 1, getter_AddRefs(newMiddleNode));
|
||||
printf("* split created middle node %p sibling of parent\n", newMiddleNode.get());
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
else {
|
||||
printf("* no need to split parent, newMiddleNode=parent\n");
|
||||
newMiddleNode = do_QueryInterface(parent);
|
||||
}
|
||||
NS_ASSERTION(newMiddleNode, "no middle node created");
|
||||
parent->GetParentNode(getter_AddRefs(temp));
|
||||
parent = do_QueryInterface(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// else we've found the style tag (referred to by "parent")
|
||||
// nwMiddleNode is the node that is an ancestor to the selection
|
||||
else
|
||||
{
|
||||
printf("* this is the style node\n");
|
||||
PRInt32 offsetInParent;
|
||||
result = nsIEditorSupport::GetChildOffset(newMiddleNode, parent, offsetInParent);
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNodeList>childNodes;
|
||||
result = parent->GetChildNodes(getter_AddRefs(childNodes));
|
||||
if (NS_SUCCEEDED(result) && childNodes)
|
||||
{
|
||||
childNodes->GetLength(&count);
|
||||
if (0!=offsetInParent && ((PRInt32)count!=offsetInParent+1)) {
|
||||
printf("* splitting parent %p at offset %d\n", parent, offsetInParent);
|
||||
result = nsEditor::SplitNode(parent, offsetInParent, getter_AddRefs(newLeftNode));
|
||||
printf("* split created left node %p sibling of parent\n", newLeftNode.get());
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{ // promote the selection to the grandparent
|
||||
nsCOMPtr<nsIDOMNode>grandParent;
|
||||
result = parent->GetParentNode(getter_AddRefs(grandParent));
|
||||
if (NS_SUCCEEDED(result) && grandParent)
|
||||
{
|
||||
printf("* deleting middle node %p\n", newMiddleNode.get());
|
||||
result = nsEditor::DeleteNode(newMiddleNode);
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
PRInt32 position;
|
||||
result = nsIEditorSupport::GetChildOffset(parent, grandParent, position);
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
printf("* inserting node %p in grandparent %p at offset %d\n",
|
||||
newMiddleNode.get(), grandParent.get(), position);
|
||||
result = nsEditor::InsertNode(newMiddleNode, grandParent, position);
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
PRBool hasChildren=PR_TRUE;
|
||||
parent->HasChildNodes(&hasChildren);
|
||||
if (PR_FALSE==hasChildren) {
|
||||
printf("* deleting empty style node %p\n", parent.get());
|
||||
result = nsEditor::DeleteNode(parent);
|
||||
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* this should only get called if the only intervening nodes are inline style nodes */
|
||||
NS_IMETHODIMP
|
||||
nsTextEditor::RemoveTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode,
|
||||
PRInt32 aStartOffset,
|
||||
nsIDOMNode *aEndNode,
|
||||
PRInt32 aEndOffset,
|
||||
nsIDOMNode *aParent,
|
||||
nsIAtom *aPropName)
|
||||
{
|
||||
printf("not yet implemented\n");
|
||||
return NS_OK;
|
||||
nsresult result=NS_OK;
|
||||
PRBool textPropertySet;
|
||||
IsTextPropertySetByContent(aStartNode, aPropName, textPropertySet);
|
||||
if (PR_FALSE==textPropertySet)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newLeftTextNode; // this will be the middle text node
|
||||
if (0!=aStartOffset) {
|
||||
result = nsEditor::SplitNode(aStartNode, aStartOffset, getter_AddRefs(newLeftTextNode));
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsCOMPtr<nsIDOMCharacterData>endNodeAsChar;
|
||||
endNodeAsChar = do_QueryInterface(aEndNode);
|
||||
if (!endNodeAsChar)
|
||||
return NS_ERROR_FAILURE;
|
||||
PRUint32 count;
|
||||
endNodeAsChar->GetLength(&count);
|
||||
nsCOMPtr<nsIDOMNode>newRightTextNode; // this will be the middle text node
|
||||
if ((PRInt32)count!=aEndOffset) {
|
||||
result = nsEditor::SplitNode(aEndNode, aEndOffset, getter_AddRefs(newRightTextNode));
|
||||
}
|
||||
else {
|
||||
newRightTextNode = do_QueryInterface(aEndNode);
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
PRInt32 offsetInParent;
|
||||
if (newLeftTextNode) {
|
||||
result = nsIEditorSupport::GetChildOffset(newLeftTextNode, aParent, offsetInParent);
|
||||
}
|
||||
else {
|
||||
offsetInParent = -1; // relies on +1 below in call to CreateNode
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsAutoString tag;
|
||||
aPropName->ToString(tag);
|
||||
// create the new style node, which will be the new parent for the selected nodes
|
||||
nsCOMPtr<nsIDOMNode>newStyleNode;
|
||||
result = nsEditor::CreateNode(tag, aParent, offsetInParent+1, getter_AddRefs(newStyleNode));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{ // move the right half of the start node into the new style node
|
||||
nsCOMPtr<nsIDOMNode>intermediateNode;
|
||||
result = aStartNode->GetNextSibling(getter_AddRefs(intermediateNode));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
result = nsEditor::DeleteNode(aStartNode);
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
PRInt32 childIndex=0;
|
||||
result = nsEditor::InsertNode(aStartNode, newStyleNode, childIndex);
|
||||
childIndex++;
|
||||
if (NS_SUCCEEDED(result))
|
||||
{ // move all the intermediate nodes into the new style node
|
||||
nsCOMPtr<nsIDOMNode>nextSibling;
|
||||
while (intermediateNode.get() != aEndNode)
|
||||
{
|
||||
if (!intermediateNode)
|
||||
result = NS_ERROR_NULL_POINTER;
|
||||
if (NS_FAILED(result)) {
|
||||
break;
|
||||
}
|
||||
// get the next sibling before moving the current child!!!
|
||||
intermediateNode->GetNextSibling(getter_AddRefs(nextSibling));
|
||||
result = nsEditor::DeleteNode(intermediateNode);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = nsEditor::InsertNode(intermediateNode, newStyleNode, childIndex);
|
||||
childIndex++;
|
||||
}
|
||||
intermediateNode = do_QueryInterface(nextSibling);
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{ // move the left half of the end node into the new style node
|
||||
result = nsEditor::DeleteNode(newRightTextNode);
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
result = nsEditor::InsertNode(newRightTextNode, newStyleNode, childIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditor::RemoveTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRange,
|
||||
nsIDOMNode *aStartNode,
|
||||
PRInt32 aStartOffset,
|
||||
nsIDOMNode *aEndNode,
|
||||
PRInt32 aEndOffset,
|
||||
nsIDOMNode *aParent,
|
||||
nsIAtom *aPropName)
|
||||
{
|
||||
printf("not yet implemented\n");
|
||||
return NS_OK;
|
||||
nsresult result=NS_OK;
|
||||
if (!aRange || !aStartNode || !aEndNode || !aParent || !aPropName)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
// create a style node for the text in the start parent
|
||||
nsCOMPtr<nsIDOMNode>parent;
|
||||
result = aStartNode->GetParentNode(getter_AddRefs(parent));
|
||||
if (NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// create style nodes for all the content between the start and end nodes
|
||||
nsCOMPtr<nsIContentIterator>iter;
|
||||
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
||||
kIContentIteratorIID, getter_AddRefs(iter));
|
||||
if ((NS_SUCCEEDED(result)) && iter)
|
||||
{
|
||||
nsCOMPtr<nsIContent>startContent;
|
||||
startContent = do_QueryInterface(aStartNode);
|
||||
nsCOMPtr<nsIContent>endContent;
|
||||
endContent = do_QueryInterface(aEndNode);
|
||||
if (startContent && endContent)
|
||||
{
|
||||
iter->Init(aRange);
|
||||
nsCOMPtr<nsIContent> content;
|
||||
iter->CurrentNode(getter_AddRefs(content));
|
||||
nsAutoString tag;
|
||||
aPropName->ToString(tag);
|
||||
while (NS_COMFALSE == iter->IsDone())
|
||||
{
|
||||
if ((content.get() != startContent.get()) &&
|
||||
(content.get() != endContent.get()))
|
||||
{
|
||||
nsCOMPtr<nsIDOMCharacterData>charNode;
|
||||
charNode = do_QueryInterface(content);
|
||||
if (charNode)
|
||||
{
|
||||
// only want to wrap the text node in a new style node if it doesn't already have that style
|
||||
nsCOMPtr<nsIDOMNode>node;
|
||||
node = do_QueryInterface(content);
|
||||
PRBool textPropertySet;
|
||||
IsTextPropertySetByContent(node, aPropName, textPropertySet);
|
||||
if (PR_FALSE==textPropertySet)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>parent;
|
||||
charNode->GetParentNode(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsCOMPtr<nsIContent>parentContent;
|
||||
parentContent = do_QueryInterface(parent);
|
||||
|
||||
PRInt32 offsetInParent;
|
||||
parentContent->IndexOf(content, offsetInParent);
|
||||
|
||||
nsCOMPtr<nsIDOMNode>newStyleNode;
|
||||
result = nsEditor::CreateNode(tag, parent, offsetInParent, getter_AddRefs(newStyleNode));
|
||||
if (NS_SUCCEEDED(result) && newStyleNode) {
|
||||
nsCOMPtr<nsIDOMNode>contentNode;
|
||||
contentNode = do_QueryInterface(content);
|
||||
result = nsEditor::DeleteNode(contentNode);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = nsEditor::InsertNode(contentNode, newStyleNode, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// note we don't check the result, we just rely on iter->IsDone
|
||||
iter->Next();
|
||||
result = iter->CurrentNode(getter_AddRefs(content));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
|
||||
nodeAsChar = do_QueryInterface(aStartNode);
|
||||
if (!nodeAsChar)
|
||||
return NS_ERROR_FAILURE;
|
||||
PRUint32 count;
|
||||
nodeAsChar->GetLength(&count);
|
||||
result = SetTextPropertiesForNode(aStartNode, parent, aStartOffset, count, aPropName);
|
||||
|
||||
// create a style node for the text in the end parent
|
||||
result = aEndNode->GetParentNode(getter_AddRefs(parent));
|
||||
if (NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
nodeAsChar = do_QueryInterface(aEndNode);
|
||||
if (!nodeAsChar)
|
||||
return NS_ERROR_FAILURE;
|
||||
nodeAsChar->GetLength(&count);
|
||||
result = SetTextPropertiesForNode(aEndNode, parent, 0, aEndOffset, aPropName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditor::SetTypeInStateForProperty(TypeInState &aTypeInState, nsIAtom *aPropName)
|
||||
{
|
||||
@ -1271,7 +1759,8 @@ nsTextEditor::SetTypeInStateForProperty(TypeInState &aTypeInState, nsIAtom *aPro
|
||||
{ // get the current style and set boldness to the opposite of the current state
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
GetTextProperty(aPropName, any, all); // operates on current selection
|
||||
PRBool first = PR_FALSE;
|
||||
GetTextProperty(aPropName, first, any, all); // operates on current selection
|
||||
aTypeInState.SetBold(!any);
|
||||
}
|
||||
}
|
||||
@ -1285,7 +1774,8 @@ nsTextEditor::SetTypeInStateForProperty(TypeInState &aTypeInState, nsIAtom *aPro
|
||||
{ // get the current style and set boldness to the opposite of the current state
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
GetTextProperty(aPropName, any, all); // operates on current selection
|
||||
PRBool first = PR_FALSE;
|
||||
GetTextProperty(aPropName, first, any, all); // operates on current selection
|
||||
aTypeInState.SetItalic(!any);
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
|
||||
// Editing Operations
|
||||
NS_IMETHOD SetTextProperty(nsIAtom *aProperty);
|
||||
NS_IMETHOD GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PRBool &aAll);
|
||||
NS_IMETHOD GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, PRBool &aAny, PRBool &aAll);
|
||||
NS_IMETHOD RemoveTextProperty(nsIAtom *aProperty);
|
||||
NS_IMETHOD DeleteSelection(nsIEditor::Direction aDir);
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
@ -137,6 +137,28 @@ protected:
|
||||
nsIDOMNode *aParent,
|
||||
nsIAtom *aPropName);
|
||||
|
||||
NS_IMETHOD RemoveTextPropertiesForNode(nsIDOMNode *aNode,
|
||||
nsIDOMNode *aParent,
|
||||
PRInt32 aStartOffset,
|
||||
PRInt32 aEndOffset,
|
||||
nsIAtom *aPropName);
|
||||
|
||||
NS_IMETHOD RemoveTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode,
|
||||
PRInt32 aStartOffset,
|
||||
nsIDOMNode *aEndNode,
|
||||
PRInt32 aEndOffset,
|
||||
nsIDOMNode *aParent,
|
||||
nsIAtom *aPropName);
|
||||
|
||||
NS_IMETHOD RemoveTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRange,
|
||||
nsIDOMNode *aStartNode,
|
||||
PRInt32 aStartOffset,
|
||||
nsIDOMNode *aEndNode,
|
||||
PRInt32 aEndOffset,
|
||||
nsIDOMNode *aParent,
|
||||
nsIAtom *aPropName);
|
||||
|
||||
|
||||
|
||||
NS_IMETHOD SetTypeInStateForProperty(TypeInState &aTypeInState, nsIAtom *aPropName);
|
||||
|
||||
|
@ -50,7 +50,7 @@ DeleteElementTxn::~DeleteElementTxn()
|
||||
|
||||
NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
{
|
||||
if (gNoisy) { printf("Do Delete Element element = %p\n", mElement.get()); }
|
||||
if (gNoisy) { printf("%p Do Delete Element element = %p\n", this, mElement.get()); }
|
||||
if (!mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
@ -65,12 +65,12 @@ NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
#ifdef NS_DEBUG
|
||||
// begin debug output
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
element = do_QueryInterface(mElement, &result);
|
||||
element = do_QueryInterface(mElement);
|
||||
nsAutoString elementTag="text node";
|
||||
if (element)
|
||||
element->GetTagName(elementTag);
|
||||
nsCOMPtr<nsIDOMElement> parentElement;
|
||||
parentElement = do_QueryInterface(mParent, &result);
|
||||
parentElement = do_QueryInterface(mParent);
|
||||
nsAutoString parentElementTag="text node";
|
||||
if (parentElement)
|
||||
parentElement->GetTagName(parentElementTag);
|
||||
@ -80,7 +80,7 @@ NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
if (c&&p)
|
||||
{
|
||||
if (gNoisy)
|
||||
printf("DeleteElementTxn: deleting child %s from parent %s\n", c, p);
|
||||
printf(" DeleteElementTxn: deleting child %s from parent %s\n", c, p);
|
||||
delete [] c;
|
||||
delete [] p;
|
||||
}
|
||||
@ -97,10 +97,35 @@ NS_IMETHODIMP DeleteElementTxn::Do(void)
|
||||
|
||||
NS_IMETHODIMP DeleteElementTxn::Undo(void)
|
||||
{
|
||||
if (gNoisy) { printf("Do Delete Element element = %p, parent = %p\n", mElement.get(), mParent.get()); }
|
||||
if (gNoisy) { printf("%p Undo Delete Element element = %p, parent = %p\n", this, mElement.get(), mParent.get()); }
|
||||
if (!mParent || !mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// begin debug output
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
element = do_QueryInterface(mElement);
|
||||
nsAutoString elementTag="text node";
|
||||
if (element)
|
||||
element->GetTagName(elementTag);
|
||||
nsCOMPtr<nsIDOMElement> parentElement;
|
||||
parentElement = do_QueryInterface(mParent);
|
||||
nsAutoString parentElementTag="text node";
|
||||
if (parentElement)
|
||||
parentElement->GetTagName(parentElementTag);
|
||||
char *c, *p;
|
||||
c = elementTag.ToNewCString();
|
||||
p = parentElementTag.ToNewCString();
|
||||
if (c&&p)
|
||||
{
|
||||
if (gNoisy)
|
||||
printf(" DeleteElementTxn: inserting child %s back into parent %s\n", c, p);
|
||||
delete [] c;
|
||||
delete [] p;
|
||||
}
|
||||
// end debug output
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
nsresult result = mParent->InsertBefore(mElement, mRefNode, getter_AddRefs(resultNode));
|
||||
return result;
|
||||
@ -108,7 +133,7 @@ NS_IMETHODIMP DeleteElementTxn::Undo(void)
|
||||
|
||||
NS_IMETHODIMP DeleteElementTxn::Redo(void)
|
||||
{
|
||||
if (gNoisy) { printf("Redo Delete Element\n"); }
|
||||
if (gNoisy) { printf("%p Redo Delete Element element = %p, parent = %p\n", this, mElement.get(), mParent.get()); }
|
||||
if (!mParent || !mElement)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -69,7 +69,7 @@ NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
|
||||
{
|
||||
PRUint32 count;
|
||||
nsCOMPtr<nsIDOMCharacterData> textNode;
|
||||
textNode = do_QueryInterface(mStartParent, &result);
|
||||
textNode = do_QueryInterface(mStartParent);
|
||||
if (textNode)
|
||||
textNode->GetLength(&count);
|
||||
else
|
||||
@ -81,7 +81,7 @@ NS_IMETHODIMP DeleteRangeTxn::Init(nsIEditor *aEditor, nsIDOMRange *aRange)
|
||||
}
|
||||
NS_ASSERTION(mStartOffset<=(PRInt32)count, "bad start offset");
|
||||
|
||||
textNode = do_QueryInterface(mEndParent, &result);
|
||||
textNode = do_QueryInterface(mEndParent);
|
||||
if (textNode)
|
||||
textNode->GetLength(&count);
|
||||
else
|
||||
|
@ -36,9 +36,9 @@ DeleteTextTxn::~DeleteTextTxn()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
|
||||
nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aNumCharsToDelete)
|
||||
nsIDOMCharacterData *aElement,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aNumCharsToDelete)
|
||||
{
|
||||
NS_ASSERTION(aEditor&&aElement, "bad arg");
|
||||
mEditor = do_QueryInterface(aEditor);
|
||||
@ -46,6 +46,10 @@ NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
|
||||
mOffset = aOffset;
|
||||
mNumCharsToDelete = aNumCharsToDelete;
|
||||
NS_ASSERTION(0!=aNumCharsToDelete, "bad arg, numCharsToDelete");
|
||||
PRUint32 count;
|
||||
aElement->GetLength(&count);
|
||||
NS_ASSERTION(count<aNumCharsToDelete, "bad arg, numCharsToDelete. Not enough characters in node");
|
||||
NS_ASSERTION(count<aOffset+aNumCharsToDelete, "bad arg, numCharsToDelete. Not enough characters in node");
|
||||
mDeletedText = "";
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -54,13 +54,14 @@ InsertElementTxn::~InsertElementTxn()
|
||||
|
||||
NS_IMETHODIMP InsertElementTxn::Do(void)
|
||||
{
|
||||
if (gNoisy) { printf("Do Insert Element\n"); }
|
||||
if (gNoisy) { printf("%p Do Insert Element of %p into parent %p at offset %d\n",
|
||||
this, mNode, mParent, mOffset); }
|
||||
if (!mNode || !mParent)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult result;
|
||||
nsCOMPtr<nsIDOMNode>refNode;
|
||||
if (0!=mOffset)
|
||||
//if (0!=mOffset)
|
||||
{ // get a ref node
|
||||
PRInt32 i=0;
|
||||
result = mParent->GetFirstChild(getter_AddRefs(refNode));
|
||||
@ -94,7 +95,8 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
|
||||
|
||||
NS_IMETHODIMP InsertElementTxn::Undo(void)
|
||||
{
|
||||
if (gNoisy) { printf("Undo Insert Element\n"); }
|
||||
if (gNoisy) { printf("%p Undo Insert Element of %p into parent %p at offset %d\n",
|
||||
this, mNode, mParent, mOffset); }
|
||||
if (!mNode || !mParent)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -135,7 +135,7 @@ NS_IMETHODIMP InsertTextTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransacti
|
||||
if (childTxn)
|
||||
{
|
||||
nsCOMPtr<InsertTextTxn> otherInsertTxn;
|
||||
otherInsertTxn = do_QueryInterface(childTxn, &result);
|
||||
otherInsertTxn = do_QueryInterface(childTxn);
|
||||
if (otherInsertTxn)
|
||||
{
|
||||
if (PR_TRUE==IsSequentialInsert(otherInsertTxn))
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "nsIEditorSupport.h"
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gNoisy = PR_TRUE;
|
||||
static PRBool gNoisy = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gNoisy = PR_FALSE;
|
||||
#endif
|
||||
@ -63,7 +63,7 @@ NS_IMETHODIMP SplitElementTxn::Do(void)
|
||||
|
||||
if ((NS_SUCCEEDED(result)) && (mNewLeftNode))
|
||||
{
|
||||
if (gNoisy) { printf(" created left node = %p\n", this, mNewLeftNode.get()); }
|
||||
if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); }
|
||||
// get the parent node
|
||||
result = mExistingRightNode->GetParentNode(getter_AddRefs(mParent));
|
||||
// insert the new node
|
||||
@ -103,21 +103,6 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// sanity check
|
||||
nsCOMPtr<nsIDOMNode>parent;
|
||||
nsresult debugResult = mExistingRightNode->GetParentNode(getter_AddRefs(parent));
|
||||
NS_ASSERTION((NS_SUCCEEDED(debugResult)), "bad GetParentNode result for right child");
|
||||
NS_ASSERTION(parent, "bad GetParentNode for right child");
|
||||
NS_ASSERTION(parent==mParent, "bad GetParentNode for right child, parents don't match");
|
||||
|
||||
debugResult = mNewLeftNode->GetParentNode(getter_AddRefs(parent));
|
||||
NS_ASSERTION((NS_SUCCEEDED(debugResult)), "bad GetParentNode result for left child");
|
||||
NS_ASSERTION(parent, "bad GetParentNode for left child");
|
||||
NS_ASSERTION(parent==mParent, "bad GetParentNode for right child, left don't match");
|
||||
|
||||
#endif
|
||||
|
||||
// this assumes Do inserted the new node in front of the prior existing node
|
||||
nsresult result;
|
||||
nsCOMPtr<nsIEditorSupport> editor;
|
||||
@ -125,6 +110,11 @@ NS_IMETHODIMP SplitElementTxn::Undo(void)
|
||||
if (NS_SUCCEEDED(result) && editor)
|
||||
{
|
||||
result = editor->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent, PR_FALSE);
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** after join left child node %p into right node %p\n", mNewLeftNode.get(), mExistingRightNode.get());
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
if (gNoisy) { printf(" left node = %p removed\n", this, mNewLeftNode.get()); }
|
||||
@ -154,6 +144,7 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
|
||||
if (gNoisy) {
|
||||
printf("%p Redo Split of existing node %p and new node %p offset %d\n",
|
||||
this, mExistingRightNode.get(), mNewLeftNode.get(), mOffset);
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
nsresult result;
|
||||
nsCOMPtr<nsIDOMNode>resultNode;
|
||||
@ -163,6 +154,11 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
|
||||
if (rightNodeAsText)
|
||||
{
|
||||
result = rightNodeAsText->DeleteData(0, mOffset);
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** after delete of text in right text node %p offset %d\n", rightNodeAsText.get(), mOffset);
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -176,11 +172,25 @@ NS_IMETHODIMP SplitElementTxn::Redo(void)
|
||||
if (!child) {return NS_ERROR_NULL_POINTER;}
|
||||
child->GetNextSibling(getter_AddRefs(nextSibling));
|
||||
result = mExistingRightNode->RemoveChild(child, getter_AddRefs(resultNode));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
result = mNewLeftNode->AppendChild(child, getter_AddRefs(resultNode));
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** move child node %p from right node %p to left node %p\n", child.get(), mExistingRightNode.get(), mNewLeftNode.get());
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
}
|
||||
child = do_QueryInterface(nextSibling);
|
||||
}
|
||||
}
|
||||
// second, re-insert the left node into the tree
|
||||
result = mParent->InsertBefore(mNewLeftNode, mExistingRightNode, getter_AddRefs(resultNode));
|
||||
if (gNoisy)
|
||||
{
|
||||
printf("** reinsert left child node %p before right node %p\n", mNewLeftNode.get(), mExistingRightNode.get());
|
||||
if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1128,7 +1128,7 @@ NS_IMETHODIMP nsEditor::CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
{
|
||||
result = NS_ERROR_UNEXPECTED;
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = do_QueryInterface(selection,&result);
|
||||
enumerator = do_QueryInterface(selection);
|
||||
if (enumerator)
|
||||
{
|
||||
enumerator->First();
|
||||
@ -1144,8 +1144,7 @@ NS_IMETHODIMP nsEditor::CreateTxnForInsertText(const nsString & aStringToInsert,
|
||||
result = range->GetStartParent(getter_AddRefs(node));
|
||||
if ((NS_SUCCEEDED(result)) && (node))
|
||||
{
|
||||
result = NS_ERROR_UNEXPECTED;
|
||||
nodeAsText = do_QueryInterface(node,&result);
|
||||
nodeAsText = do_QueryInterface(node);
|
||||
range->GetStartOffset(&offset);
|
||||
if (!nodeAsText) {
|
||||
result = NS_ERROR_EDITOR_NO_TEXTNODE;
|
||||
@ -1451,7 +1450,7 @@ NS_IMETHODIMP nsEditor::CreateTxnForDeleteSelection(nsIEditor::Direction aDir,
|
||||
if ((NS_SUCCEEDED(result)) && selection)
|
||||
{
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
enumerator = do_QueryInterface(selection,&result);
|
||||
enumerator = do_QueryInterface(selection);
|
||||
if (enumerator)
|
||||
{
|
||||
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
|
||||
@ -1553,7 +1552,7 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
||||
{ // there is a priorNode, so delete it's last child (if text content, delete the last char.)
|
||||
// if it has no children, delete it
|
||||
nsCOMPtr<nsIDOMCharacterData> priorNodeAsText;
|
||||
priorNodeAsText = do_QueryInterface(priorNode, &result);
|
||||
priorNodeAsText = do_QueryInterface(priorNode);
|
||||
if (priorNodeAsText)
|
||||
{
|
||||
PRUint32 length=0;
|
||||
@ -1590,7 +1589,7 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsIDOMRange *aRange,
|
||||
{ // there is a priorNode, so delete it's last child (if text content, delete the last char.)
|
||||
// if it has no children, delete it
|
||||
nsCOMPtr<nsIDOMCharacterData> nextNodeAsText;
|
||||
nextNodeAsText = do_QueryInterface(nextNode,&result);
|
||||
nextNodeAsText = do_QueryInterface(nextNode);
|
||||
if (nextNodeAsText)
|
||||
{
|
||||
PRUint32 length=0;
|
||||
@ -1815,6 +1814,9 @@ nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
|
||||
nsIDOMNode* aNewLeftNode,
|
||||
nsIDOMNode* aParent)
|
||||
{
|
||||
|
||||
printf("SplitNodeImpl: left=%p, right=%p, offset=%d\n", aNewLeftNode, aExistingRightNode, aOffset);
|
||||
|
||||
nsresult result;
|
||||
NS_ASSERTION(((nsnull!=aExistingRightNode) &&
|
||||
(nsnull!=aNewLeftNode) &&
|
||||
@ -1826,6 +1828,7 @@ nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
result = aParent->InsertBefore(aNewLeftNode, aExistingRightNode, getter_AddRefs(resultNode));
|
||||
//printf(" after insert\n"); content->List(); // DEBUG
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
// split the children between the 2 nodes
|
||||
@ -1847,21 +1850,26 @@ nsEditor::SplitNodeImpl(nsIDOMNode * aExistingRightNode,
|
||||
}
|
||||
else
|
||||
{ // otherwise it's an interior node, so shuffle around the children
|
||||
// go through list backwards so deletes don't interfere with the iteration
|
||||
nsCOMPtr<nsIDOMNodeList> childNodes;
|
||||
result = aExistingRightNode->GetChildNodes(getter_AddRefs(childNodes));
|
||||
if ((NS_SUCCEEDED(result)) && (childNodes))
|
||||
{
|
||||
PRInt32 i=0;
|
||||
for ( ; ((NS_SUCCEEDED(result)) && (i<aOffset)); i++)
|
||||
PRInt32 i=aOffset-1;
|
||||
for ( ; ((NS_SUCCEEDED(result)) && (0<=i)); i--)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
result = childNodes->Item(i, getter_AddRefs(childNode));
|
||||
if ((NS_SUCCEEDED(result)) && (childNode))
|
||||
{
|
||||
result = aExistingRightNode->RemoveChild(childNode, getter_AddRefs(resultNode));
|
||||
//printf(" after remove\n"); content->List(); // DEBUG
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
result = aNewLeftNode->AppendChild(childNode, getter_AddRefs(resultNode));
|
||||
nsCOMPtr<nsIDOMNode> firstChild;
|
||||
aNewLeftNode->GetFirstChild(getter_AddRefs(firstChild));
|
||||
result = aNewLeftNode->InsertBefore(childNode, firstChild, getter_AddRefs(resultNode));
|
||||
//printf(" after append\n"); content->List(); // DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1917,7 +1925,7 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
|
||||
result = aNodeToJoin->GetChildNodes(getter_AddRefs(childNodes));
|
||||
if ((NS_SUCCEEDED(result)) && (childNodes))
|
||||
{
|
||||
PRUint32 i;
|
||||
PRInt32 i; // must be signed int!
|
||||
PRUint32 childCount=0;
|
||||
childNodes->GetLength(&childCount);
|
||||
nsCOMPtr<nsIDOMNode> firstNode; //only used if aNodeToKeepIsFirst is false
|
||||
@ -1927,7 +1935,9 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
|
||||
// GetFirstChild returns nsnull firstNode if aNodeToKeep has no children, that's ok.
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
for (i=0; ((NS_SUCCEEDED(result)) && (i<childCount)); i++)
|
||||
// have to go through the list backwards to keep deletes from interfering with iteration
|
||||
nsCOMPtr<nsIDOMNode> previousChild;
|
||||
for (i=childCount-1; ((NS_SUCCEEDED(result)) && (0<=i)); i--)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
result = childNodes->Item(i, getter_AddRefs(childNode));
|
||||
@ -1935,11 +1945,15 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
|
||||
{
|
||||
if (PR_TRUE==aNodeToKeepIsFirst)
|
||||
{ // append children of aNodeToJoin
|
||||
result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
|
||||
//was result = aNodeToKeep->AppendChild(childNode, getter_AddRefs(resultNode));
|
||||
result = aNodeToKeep->InsertBefore(childNode, previousChild, getter_AddRefs(resultNode));
|
||||
previousChild = do_QueryInterface(childNode);
|
||||
}
|
||||
else
|
||||
{ // prepend children of aNodeToJoin
|
||||
//was result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
|
||||
result = aNodeToKeep->InsertBefore(childNode, firstNode, getter_AddRefs(resultNode));
|
||||
firstNode = do_QueryInterface(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2047,6 +2061,28 @@ NS_IMETHODIMP nsEditor::GetLayoutObject(nsIDOMNode *aNode, nsISupports **aLayout
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditor::DebugDumpContent() const
|
||||
{
|
||||
nsCOMPtr<nsIContent>content;
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString bodyTag = "body";
|
||||
mDoc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
||||
if (nodeList)
|
||||
{
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
||||
nsCOMPtr<nsIDOMNode>bodyNode;
|
||||
nodeList->Item(0, getter_AddRefs(bodyNode));
|
||||
if (bodyNode) {
|
||||
content = do_QueryInterface(bodyNode);
|
||||
}
|
||||
}
|
||||
content->List();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//END nsEditor Private methods
|
||||
|
||||
|
@ -60,13 +60,15 @@ private:
|
||||
nsIPresShell *mPresShell;
|
||||
nsIViewManager *mViewManager;
|
||||
PRUint32 mUpdateCount;
|
||||
nsCOMPtr<nsIDOMDocument> mDoc;
|
||||
nsCOMPtr<nsITransactionManager> mTxnMgr;
|
||||
|
||||
|
||||
friend PRBool NSCanUnload(nsISupports* serviceMgr);
|
||||
static PRInt32 gInstanceCount;
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDOMDocument> mDoc;
|
||||
|
||||
public:
|
||||
/** The default constructor. This should suffice. the setting of the interfaces is done
|
||||
* after the construction of the editor class.
|
||||
@ -278,8 +280,6 @@ protected:
|
||||
|
||||
NS_IMETHOD GetLeftmostChild(nsIDOMNode *aCurrentNode, nsIDOMNode **aResultNode);
|
||||
|
||||
//Methods not exposed in nsIEditor
|
||||
|
||||
/** Create an aggregate transaction for deleting current selection
|
||||
* Used by all methods that need to delete current selection,
|
||||
* then insert something new to replace it
|
||||
@ -290,6 +290,8 @@ protected:
|
||||
*/
|
||||
NS_IMETHOD CreateAggregateTxnForDeleteSelection(nsIAtom *aTxnName, EditAggregateTxn **aAggTxn);
|
||||
|
||||
NS_IMETHOD DebugDumpContent() const;
|
||||
|
||||
protected:
|
||||
// XXXX: Horrible hack! We are doing this because
|
||||
// of an error in Gecko which is not rendering the
|
||||
|
@ -113,9 +113,9 @@ NS_IMETHODIMP nsHTMLEditor::SetTextProperty(nsIAtom *aProperty)
|
||||
return nsTextEditor::SetTextProperty(aProperty);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PRBool &aAll)
|
||||
NS_IMETHODIMP nsHTMLEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, PRBool &aAny, PRBool &aAll)
|
||||
{
|
||||
return nsTextEditor::GetTextProperty(aProperty, aAny, aAll);
|
||||
return nsTextEditor::GetTextProperty(aProperty, aFirst, aAny, aAll);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::RemoveTextProperty(nsIAtom *aProperty)
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
// Editing Operations
|
||||
NS_IMETHOD SetTextProperty(nsIAtom *aProperty);
|
||||
NS_IMETHOD GetTextProperty(nsIAtom *aProperty, PRBool &aAny, PRBool &aAll);
|
||||
NS_IMETHOD GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, PRBool &aAny, PRBool &aAll);
|
||||
NS_IMETHOD RemoveTextProperty(nsIAtom *aProperty);
|
||||
NS_IMETHOD DeleteSelection(nsIEditor::Direction aDir);
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
|
@ -310,7 +310,18 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
|
||||
aProcessed=PR_TRUE;
|
||||
if (mEditor)
|
||||
{
|
||||
mEditor->SetTextProperty(nsIEditProperty::i);
|
||||
// XXX: move this logic down into texteditor rules delegate
|
||||
// should just call mEditor->ChangeTextProperty(prop)
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first = PR_FALSE;
|
||||
mEditor->GetTextProperty(nsIEditProperty::i, first, any, all);
|
||||
if (PR_FALSE==first) {
|
||||
mEditor->SetTextProperty(nsIEditProperty::i);
|
||||
}
|
||||
else {
|
||||
mEditor->RemoveTextProperty(nsIEditProperty::i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +347,18 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
|
||||
aProcessed=PR_TRUE;
|
||||
if (mEditor)
|
||||
{
|
||||
mEditor->SetTextProperty(nsIEditProperty::b);
|
||||
// XXX: move this logic down into texteditor rules delegate
|
||||
// should just call mEditor->ChangeTextProperty(prop)
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first = PR_FALSE;
|
||||
mEditor->GetTextProperty(nsIEditProperty::b, first, any, all);
|
||||
if (PR_FALSE==first) {
|
||||
mEditor->SetTextProperty(nsIEditProperty::b);
|
||||
}
|
||||
else {
|
||||
mEditor->RemoveTextProperty(nsIEditProperty::b);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -348,7 +370,19 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr
|
||||
aProcessed=PR_TRUE;
|
||||
if (mEditor)
|
||||
{
|
||||
mEditor->SetTextProperty(nsIEditProperty::u);
|
||||
// XXX: move this logic down into texteditor rules delegate
|
||||
// should just call mEditor->ChangeTextProperty(prop)
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first = PR_FALSE;
|
||||
mEditor->GetTextProperty(nsIEditProperty::u, first, any, all);
|
||||
if (PR_FALSE==first) {
|
||||
mEditor->SetTextProperty(nsIEditProperty::u);
|
||||
}
|
||||
else {
|
||||
mEditor->RemoveTextProperty(nsIEditProperty::u);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user