diff --git a/mozilla/editor/base/JoinElementTxn.cpp b/mozilla/editor/base/JoinElementTxn.cpp index 4efa9caf8f6..e0dffad7bcc 100644 --- a/mozilla/editor/base/JoinElementTxn.cpp +++ b/mozilla/editor/base/JoinElementTxn.cpp @@ -115,29 +115,6 @@ NS_IMETHODIMP JoinElementTxn::Do(void) // and re-inserted mLeft? NS_IMETHODIMP JoinElementTxn::Undo(void) { - /* - nsresult result; - nsCOMPtr editor; - result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor)); - if (NS_SUCCEEDED(result) && editor) { - result = editor->SplitNodeImpl(mRightNode, mOffset, mLeftNode, mParent); - if (NS_SUCCEEDED(result) && mLeftNode) - { - if (gNoisy) { printf(" created left node = %p\n", this, mLeftNode.get()); } - nsCOMPtrselection; - mEditor->GetSelection(getter_AddRefs(selection)); - if (selection) - { - selection->Collapse(mLeftNode, mOffset); - } - } - } - else { - result = NS_ERROR_NOT_IMPLEMENTED; - } - return result; - */ - if (gNoisy) { printf("%p Undo Join, right node = %p\n", this, mRightNode.get()); } NS_ASSERTION(mRightNode && mLeftNode && mParent, "bad state"); if (!mRightNode || !mLeftNode || !mParent) { diff --git a/mozilla/editor/base/SplitElementTxn.cpp b/mozilla/editor/base/SplitElementTxn.cpp index 045213087ca..2ec8353eea2 100644 --- a/mozilla/editor/base/SplitElementTxn.cpp +++ b/mozilla/editor/base/SplitElementTxn.cpp @@ -23,7 +23,7 @@ #include "nsIEditorSupport.h" #ifdef NS_DEBUG -static PRBool gNoisy = PR_FALSE; +static PRBool gNoisy = PR_TRUE; #else static const PRBool gNoisy = PR_FALSE; #endif @@ -117,7 +117,7 @@ NS_IMETHODIMP SplitElementTxn::Undo(void) } if (NS_SUCCEEDED(result)) { - if (gNoisy) { printf(" left node = %p removed\n", this, mNewLeftNode.get()); } + if (gNoisy) { printf(" left node = %p removed\n", mNewLeftNode.get()); } nsCOMPtrselection; mEditor->GetSelection(getter_AddRefs(selection)); if (selection) diff --git a/mozilla/editor/base/nsTextEditor.cpp b/mozilla/editor/base/nsTextEditor.cpp index 1a19afad846..652d4461184 100644 --- a/mozilla/editor/base/nsTextEditor.cpp +++ b/mozilla/editor/base/nsTextEditor.cpp @@ -51,6 +51,7 @@ #include "nsLayoutCID.h" #include "nsIPresShell.h" #include "nsIStyleContext.h" +#include "nsVoidArray.h" // transactions the text editor knows how to build itself #include "TransactionFactory.h" @@ -454,7 +455,8 @@ NS_IMETHODIMP nsTextEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, if (node) { PRBool isSet; - IsTextPropertySetByContent(node, aProperty, isSet); + nsCOMPtrresultNode; + IsTextPropertySetByContent(node, aProperty, isSet, getter_AddRefs(resultNode)); if (PR_TRUE==first) { aFirst = isSet; @@ -497,9 +499,10 @@ void nsTextEditor::IsTextStyleSet(nsIStyleContext *aSC, } } -void nsTextEditor::IsTextPropertySetByContent(nsIDOMNode *aNode, - nsIAtom *aProperty, - PRBool &aIsSet) const +void nsTextEditor::IsTextPropertySetByContent(nsIDOMNode *aNode, + nsIAtom *aProperty, + PRBool &aIsSet, + nsIDOMNode **aStyleNode) const { nsresult result; aIsSet = PR_FALSE; @@ -1013,7 +1016,8 @@ NS_IMETHODIMP nsTextEditor::SetTextPropertiesForNode(nsIDOMNode *aNode, return NS_ERROR_FAILURE; PRBool textPropertySet; - IsTextPropertySetByContent(aNode, aPropName, textPropertySet); + nsCOMPtrresultNode; + IsTextPropertySetByContent(aNode, aPropName, textPropertySet, getter_AddRefs(resultNode)); if (PR_FALSE==textPropertySet) { PRUint32 count; @@ -1172,7 +1176,8 @@ nsTextEditor::SetTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode, { nsresult result=NS_OK; PRBool textPropertySet; - IsTextPropertySetByContent(aStartNode, aPropName, textPropertySet); + nsCOMPtrresultNode; + IsTextPropertySetByContent(aStartNode, aPropName, textPropertySet, getter_AddRefs(resultNode)); if (PR_FALSE==textPropertySet) { nsCOMPtrnewLeftTextNode; // this will be the middle text node @@ -1316,7 +1321,8 @@ nsTextEditor::SetTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRange, nsCOMPtrnode; node = do_QueryInterface(content); PRBool textPropertySet; - IsTextPropertySetByContent(node, aPropName, textPropertySet); + nsCOMPtrresultNode; + IsTextPropertySetByContent(node, aPropName, textPropertySet, getter_AddRefs(resultNode)); if (PR_FALSE==textPropertySet) { nsCOMPtrparent; @@ -1384,7 +1390,8 @@ NS_IMETHODIMP nsTextEditor::RemoveTextPropertiesForNode(nsIDOMNode *aNode, nodeAsChar = do_QueryInterface(aNode); PRBool insertAfter=PR_FALSE; PRBool textPropertySet; - IsTextPropertySetByContent(aNode, aPropName, textPropertySet); + nsCOMPtrresultNode; + IsTextPropertySetByContent(aNode, aPropName, textPropertySet, getter_AddRefs(resultNode)); if (PR_TRUE==textPropertySet) { nsCOMPtrparent; // initially set to first interior parent node to process @@ -1581,7 +1588,7 @@ nsTextEditor::RemoveTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode, break; } else - { // found a sibling node between aStartNode and aEndNode + { // found a sibling node between aStartNode and aEndNode, remove the style node PRUint32 childCount=0; nodeAsChar = do_QueryInterface(siblingNode); if (nodeAsChar) { @@ -1604,8 +1611,7 @@ nsTextEditor::RemoveTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode, result = RemoveTextPropertiesForNode(siblingNode, parentNode, 0, childCount, aPropName); } } - siblingNode = do_QueryInterface(nextSiblingNode); - + siblingNode = do_QueryInterface(nextSiblingNode); } if (NS_SUCCEEDED(result)) { @@ -1647,101 +1653,137 @@ nsTextEditor::RemoveTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRang 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 + + // delete the style node for the text in the start parent + nsCOMPtrnodeAsChar; + PRUint32 count; nsCOMPtrparent; result = aStartNode->GetParentNode(getter_AddRefs(parent)); if (NS_FAILED(result)) { return result; } + nodeAsChar = do_QueryInterface(aStartNode); + if (!nodeAsChar) { return NS_ERROR_FAILURE; } + nodeAsChar->GetLength(&count); + result = RemoveTextPropertiesForNode(aStartNode, parent, aStartOffset, count, aPropName); - // create style nodes for all the content between the start and end nodes - nsCOMPtriter; - result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull, - kIContentIteratorIID, getter_AddRefs(iter)); - if ((NS_SUCCEEDED(result)) && iter) + // delete the style node for the text in the end parent + if (NS_SUCCEEDED(result)) { - nsCOMPtrstartContent; - startContent = do_QueryInterface(aStartNode); - nsCOMPtrendContent; - endContent = do_QueryInterface(aEndNode); - if (startContent && endContent) + result = aEndNode->GetParentNode(getter_AddRefs(parent)); + if (NS_SUCCEEDED(result)) { - iter->Init(aRange); - nsCOMPtr 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())) - { - nsCOMPtrcharNode; - 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 - nsCOMPtrnode; - node = do_QueryInterface(content); - PRBool textPropertySet; - IsTextPropertySetByContent(node, aPropName, textPropertySet); - if (PR_FALSE==textPropertySet) - { - nsCOMPtrparent; - charNode->GetParentNode(getter_AddRefs(parent)); - if (!parent) { - return NS_ERROR_NULL_POINTER; - } - nsCOMPtrparentContent; - parentContent = do_QueryInterface(parent); - - PRInt32 offsetInParent; - parentContent->IndexOf(content, offsetInParent); + nodeAsChar = do_QueryInterface(aEndNode); + if (!nodeAsChar) { return NS_ERROR_FAILURE; } + nodeAsChar->GetLength(&count); + result = RemoveTextPropertiesForNode(aEndNode, parent, 0, aEndOffset, aPropName); + } + } - nsCOMPtrnewStyleNode; - result = nsEditor::CreateNode(tag, parent, offsetInParent, getter_AddRefs(newStyleNode)); - if (NS_SUCCEEDED(result) && newStyleNode) { - nsCOMPtrcontentNode; - contentNode = do_QueryInterface(content); - result = nsEditor::DeleteNode(contentNode); - if (NS_SUCCEEDED(result)) { - result = nsEditor::InsertNode(contentNode, newStyleNode, 0); + // remove aPropName style nodes for all the content between the start and end nodes + if (NS_SUCCEEDED(result)) + { + nsVoidArray nodeList; + nsCOMPtriter; + result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull, + kIContentIteratorIID, getter_AddRefs(iter)); + if ((NS_SUCCEEDED(result)) && iter) + { + nsCOMPtrstartContent; + startContent = do_QueryInterface(aStartNode); + nsCOMPtrendContent; + endContent = do_QueryInterface(aEndNode); + if (startContent && endContent) + { + iter->Init(aRange); + nsCOMPtr content; + iter->CurrentNode(getter_AddRefs(content)); + nsAutoString propName; // the property we are removing + aPropName->ToString(propName); + while (NS_COMFALSE == iter->IsDone()) + { + if ((content.get() != startContent.get()) && + (content.get() != endContent.get())) + { + nsCOMPtrelement; + element = do_QueryInterface(content); + if (element) + { + nsString tag; + element->GetTagName(tag); + if (propName.Equals(tag)) + { + if (-1==nodeList.IndexOf(content.get())) { + nodeList.AppendElement((void *)(content.get())); } } } } + // note we don't check the result, we just rely on iter->IsDone + iter->Next(); + iter->CurrentNode(getter_AddRefs(content)); } - // note we don't check the result, we just rely on iter->IsDone - iter->Next(); - result = iter->CurrentNode(getter_AddRefs(content)); + } + } + + // now delete all the style nodes we found + if (NS_SUCCEEDED(result)) + { + nsIContent *contentPtr; + contentPtr = (nsIContent*)(nodeList.ElementAt(0)); + while (NS_SUCCEEDED(result) && contentPtr) + { + nsCOMPtrstyleNode; + styleNode = do_QueryInterface(contentPtr); + // promote the children of styleNode + nsCOMPtrparentNode; + result = styleNode->GetParentNode(getter_AddRefs(parentNode)); + if (NS_SUCCEEDED(result) && parentNode) + { + PRInt32 position; + result = nsIEditorSupport::GetChildOffset(styleNode, parentNode, position); + if (NS_SUCCEEDED(result)) + { + nsCOMPtrpreviousSiblingNode; + nsCOMPtrchildNode; + result = styleNode->GetLastChild(getter_AddRefs(childNode)); + while (NS_SUCCEEDED(result) && childNode) + { + childNode->GetPreviousSibling(getter_AddRefs(previousSiblingNode)); + // explicitly delete of childNode from styleNode + // can't just rely on DOM semantics of InsertNode doing the delete implicitly, doesn't undo! + result = nsEditor::DeleteNode(childNode); + if (NS_SUCCEEDED(result)) + { + result = nsEditor::InsertNode(childNode, parentNode, position); + if (gNoisy) + { + printf("deleted next sibling node %p\n", childNode.get()); + DebugDumpContent(); // DEBUG + } + } + childNode = do_QueryInterface(previousSiblingNode); + } // end while loop + // delete styleNode + result = nsEditor::DeleteNode(styleNode); + if (gNoisy) + { + printf("deleted style node %p\n", styleNode.get()); + DebugDumpContent(); // DEBUG + } + } + } + + // get next content ptr + nodeList.RemoveElementAt(0); + contentPtr = (nsIContent*)(nodeList.ElementAt(0)); } } } - nsCOMPtrnodeAsChar; - 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; } diff --git a/mozilla/editor/base/nsTextEditor.h b/mozilla/editor/base/nsTextEditor.h index b9158655e42..603305ba1ed 100644 --- a/mozilla/editor/base/nsTextEditor.h +++ b/mozilla/editor/base/nsTextEditor.h @@ -98,9 +98,10 @@ protected: // Utility Methods - virtual void IsTextPropertySetByContent(nsIDOMNode *aNode, - nsIAtom *aProperty, - PRBool &aIsSet) const; + virtual void IsTextPropertySetByContent(nsIDOMNode *aNode, + nsIAtom *aProperty, + PRBool &aIsSet, + nsIDOMNode **aStyleNode) const; virtual void IsTextStyleSet(nsIStyleContext *aSC, nsIAtom *aProperty, diff --git a/mozilla/editor/libeditor/base/JoinElementTxn.cpp b/mozilla/editor/libeditor/base/JoinElementTxn.cpp index 4efa9caf8f6..e0dffad7bcc 100644 --- a/mozilla/editor/libeditor/base/JoinElementTxn.cpp +++ b/mozilla/editor/libeditor/base/JoinElementTxn.cpp @@ -115,29 +115,6 @@ NS_IMETHODIMP JoinElementTxn::Do(void) // and re-inserted mLeft? NS_IMETHODIMP JoinElementTxn::Undo(void) { - /* - nsresult result; - nsCOMPtr editor; - result = mEditor->QueryInterface(kIEditorSupportIID, getter_AddRefs(editor)); - if (NS_SUCCEEDED(result) && editor) { - result = editor->SplitNodeImpl(mRightNode, mOffset, mLeftNode, mParent); - if (NS_SUCCEEDED(result) && mLeftNode) - { - if (gNoisy) { printf(" created left node = %p\n", this, mLeftNode.get()); } - nsCOMPtrselection; - mEditor->GetSelection(getter_AddRefs(selection)); - if (selection) - { - selection->Collapse(mLeftNode, mOffset); - } - } - } - else { - result = NS_ERROR_NOT_IMPLEMENTED; - } - return result; - */ - if (gNoisy) { printf("%p Undo Join, right node = %p\n", this, mRightNode.get()); } NS_ASSERTION(mRightNode && mLeftNode && mParent, "bad state"); if (!mRightNode || !mLeftNode || !mParent) { diff --git a/mozilla/editor/libeditor/base/SplitElementTxn.cpp b/mozilla/editor/libeditor/base/SplitElementTxn.cpp index 045213087ca..2ec8353eea2 100644 --- a/mozilla/editor/libeditor/base/SplitElementTxn.cpp +++ b/mozilla/editor/libeditor/base/SplitElementTxn.cpp @@ -23,7 +23,7 @@ #include "nsIEditorSupport.h" #ifdef NS_DEBUG -static PRBool gNoisy = PR_FALSE; +static PRBool gNoisy = PR_TRUE; #else static const PRBool gNoisy = PR_FALSE; #endif @@ -117,7 +117,7 @@ NS_IMETHODIMP SplitElementTxn::Undo(void) } if (NS_SUCCEEDED(result)) { - if (gNoisy) { printf(" left node = %p removed\n", this, mNewLeftNode.get()); } + if (gNoisy) { printf(" left node = %p removed\n", mNewLeftNode.get()); } nsCOMPtrselection; mEditor->GetSelection(getter_AddRefs(selection)); if (selection)