WIP on remove text attributes
This commit is contained in:
buster%netscape.com 1999-04-05 20:52:29 +00:00
Родитель 7c8d08b9a1
Коммит e879c875d9
9 изменённых файлов: 381 добавлений и 239 удалений

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

@ -90,7 +90,7 @@ NS_IMETHODIMP JoinElementTxn::Do(void)
result = editor->JoinNodesImpl(mRightNode, mLeftNode, mParent, PR_FALSE);
if (NS_SUCCEEDED(result))
{
if (gNoisy) { printf(" left node = %p removed\n", this, mLeftNode.get()); }
if (gNoisy) { printf(" left node = %p removed\n", mLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (selection)

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

@ -286,7 +286,7 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
InsertStyleNode(newTextNode, nsIEditProperty::b, aSelection);
}
else {
printf("not yet implemented, make unbold in a bold context\n");
printf("not yet implemented, make not bold in a bold context\n");
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
@ -296,7 +296,7 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
}
else
{
printf("not yet implemented, make unitalic in a italic context\n");
printf("not yet implemented, make not italic in a italic context\n");
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
@ -334,21 +334,20 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
{ // now we've got the body tag. insert the style tag
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
{
if (PR_TRUE==aTypeInState.GetBold())
{ // make the next char bold
nsAutoString tag;
nsIEditProperty::b->ToString(tag);
nsCOMPtr<nsIDOMNode>newStyleNode;
nsCOMPtr<nsIDOMNode>newTextNode;
result = mEditor->CreateNode(tag, bodyNode, 0, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result))
{
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result))
{
aSelection->Collapse(newTextNode, 0);
}
}
if (PR_TRUE==aTypeInState.GetBold()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
{
if (PR_TRUE==aTypeInState.GetItalic()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection);
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
{
if (PR_TRUE==aTypeInState.GetUnderline()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::u, aSelection);
}
}
}
@ -389,6 +388,50 @@ nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelecti
}
NS_IMETHODIMP
nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
{
NS_ASSERTION(aParentNode && aTag, "bad args");
if (!aParentNode || !aTag) { return NS_ERROR_NULL_POINTER; }
nsresult result;
// if the selection already points to a text node, just call InsertStyleNode()
if (aSelection)
{
nsCOMPtr<nsIDOMNode>anchor;
PRInt32 offset;
nsresult result = aSelection->GetAnchorNodeAndOffset(getter_AddRefs(anchor), &offset);
if ((NS_SUCCEEDED(result)) && anchor)
{
nsCOMPtr<nsIDOMCharacterData>anchorAsText;
anchorAsText = do_QueryInterface(anchor);
if (anchorAsText)
{
result = InsertStyleNode(anchor, aTag, aSelection);
return result;
}
}
}
// if we get here, there is no selected text node so we create one.
nsAutoString tag;
aTag->ToString(tag);
nsCOMPtr<nsIDOMNode>newStyleNode;
nsCOMPtr<nsIDOMNode>newTextNode;
result = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result))
{
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result))
{
if (aSelection) {
aSelection->Collapse(newTextNode, 0);
}
}
}
return result;
}
/*
NS_IMETHODIMP
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
@ -529,6 +572,7 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
nsCOMPtr<nsIDOMNode> parentNode;
selectedNode->GetParentNode(getter_AddRefs(parentNode));
result = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
// selectedNode will remain after the join, siblingNode is removed
}
}
selectedNode->GetNextSibling(getter_AddRefs(siblingNode));
@ -543,8 +587,9 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
nsCOMPtr<nsIDOMNode> parentNode;
selectedNode->GetParentNode(getter_AddRefs(parentNode));
result = mEditor->JoinNodes(selectedNode, siblingNode, parentNode);
// selectedNode will remain after the join, siblingNode is removed
// set selection
aSelection->Collapse(selectedNode, selectedNodeLength);
aSelection->Collapse(siblingNode, selectedNodeLength);
}
}
}

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

@ -89,7 +89,19 @@ protected:
* aSelection is optional. If provided, aSelection is set to (aNode, 0)
* if aNode was successfully placed in a new style node
*/
NS_IMETHOD InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelection *aSelection);
NS_IMETHOD InsertStyleNode(nsIDOMNode *aNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
/** create a new style node of type aTag in aParentNode, and put a new text node
* in the new style node.
* If aSelection is provided and points to a text node, just call InsertStyleNode instead.
* aSelection is optional. If provided, aSelection is set to (newTextNode, 0)
* if newTextNode was successfully created.
*/
NS_IMETHOD InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
// data
nsTextEditor *mEditor; // note that we do not refcount the editor

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

@ -97,7 +97,7 @@ static NS_DEFINE_IID(kIContentIteratorIID, NS_ICONTENTITERTOR_IID);
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
#ifdef NS_DEBUG
static PRBool gNoisy = PR_FALSE;
static PRBool gNoisy = PR_TRUE;
#else
static const PRBool gNoisy = PR_FALSE;
#endif
@ -1350,6 +1350,7 @@ nsTextEditor::SetTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRange,
}
}
// create a style node for the text in the start parent
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
nodeAsChar = do_QueryInterface(aStartNode);
if (!nodeAsChar)
@ -1381,106 +1382,81 @@ NS_IMETHODIMP nsTextEditor::RemoveTextPropertiesForNode(nsIDOMNode *aNode,
nsresult result=NS_OK;
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
nodeAsChar = do_QueryInterface(aNode);
if (!nodeAsChar)
return NS_ERROR_FAILURE;
PRBool insertAfter=PR_FALSE;
PRBool textPropertySet;
IsTextPropertySetByContent(aNode, aPropName, textPropertySet);
if (PR_TRUE==textPropertySet)
{
nsCOMPtr<nsIDOMNode>parent; // initially set to first interior parent node to process
nsCOMPtr<nsIDOMNode>newMiddleNode; // this will be the middle node after any required splits
nsCOMPtr<nsIDOMNode>newLeftNode; // this will be the leftmost node,
// the node being split will be rightmost
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))
// if aNode is a text node, treat is specially
if (nodeAsChar)
{
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());
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
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
}
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)
if (NS_SUCCEEDED(result))
{
// 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)
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);
insertAfter = PR_TRUE;
}
NS_ASSERTION(newMiddleNode, "no middle node created");
// now that the text node is split, split parent nodes until we get to the style node
parent = do_QueryInterface(aParent); // we know this has to succeed, no need to check
}
}
else {
newMiddleNode = do_QueryInterface(aNode);
parent = do_QueryInterface(aParent);
}
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)
{
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))
{
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))
{
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))
{
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);
}
}
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
}
}
// 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;
@ -1488,40 +1464,78 @@ NS_IMETHODIMP nsTextEditor::RemoveTextPropertiesForNode(nsIDOMNode *aNode,
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());
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
}
if (NS_SUCCEEDED(result))
{ // promote the selection to the grandparent
nsCOMPtr<nsIDOMNode>grandParent;
result = parent->GetParentNode(getter_AddRefs(grandParent));
if (NS_SUCCEEDED(result) && grandParent)
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))
{
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))
{
PRInt32 position;
result = nsIEditorSupport::GetChildOffset(parent, grandParent, position);
if (PR_TRUE==insertAfter)
{
if (gNoisy) {printf("insertAfter=PR_TRUE, incr. position\n"); }
position++;
insertAfter = PR_FALSE;
}
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))
{
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
}
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
}
}
}
@ -1529,8 +1543,8 @@ NS_IMETHODIMP nsTextEditor::RemoveTextPropertiesForNode(nsIDOMNode *aNode,
}
}
}
break;
}
break;
}
}
}
@ -1549,93 +1563,76 @@ nsTextEditor::RemoveTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode,
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)
PRInt32 startOffset = aStartOffset;
PRInt32 endOffset;
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
nsCOMPtr<nsIDOMNode>parentNode = do_QueryInterface(aParent);
// remove aPropName from all intermediate nodes
nsCOMPtr<nsIDOMNode>siblingNode;
nsCOMPtr<nsIDOMNode>nextSiblingNode; // temp to hold the next node in the list
result = aStartNode->GetNextSibling(getter_AddRefs(siblingNode));
while (siblingNode && NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode>newLeftTextNode; // this will be the middle text node
if (0!=aStartOffset) {
result = nsEditor::SplitNode(aStartNode, aStartOffset, getter_AddRefs(newLeftTextNode));
// get next sibling right away, before we move siblingNode!
siblingNode->GetNextSibling(getter_AddRefs(nextSiblingNode));
if (aEndNode==siblingNode.get()) { // found the end node, handle that below
break;
}
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
{ // found a sibling node between aStartNode and aEndNode
PRUint32 childCount=0;
nodeAsChar = do_QueryInterface(siblingNode);
if (nodeAsChar) {
nodeAsChar->GetLength(&childCount);
}
else {
newRightTextNode = do_QueryInterface(aEndNode);
}
if (NS_SUCCEEDED(result))
else
{
PRInt32 offsetInParent;
if (newLeftTextNode) {
result = nsIEditorSupport::GetChildOffset(newLeftTextNode, aParent, offsetInParent);
nsCOMPtr<nsIDOMNodeList>grandChildNodes;
result = siblingNode->GetChildNodes(getter_AddRefs(grandChildNodes));
if (NS_SUCCEEDED(result) && grandChildNodes) {
grandChildNodes->GetLength(&childCount);
}
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);
}
}
}
}
}
}
if (0==childCount)
{ // node has no children
// XXX: for now, I think that's ok. just pass in 0
}
}
if (NS_SUCCEEDED(result)) {
siblingNode->GetParentNode(getter_AddRefs(parentNode));
result = RemoveTextPropertiesForNode(siblingNode, parentNode, 0, childCount, aPropName);
}
}
siblingNode = do_QueryInterface(nextSiblingNode);
}
if (NS_SUCCEEDED(result))
{
// remove aPropName from aStartNode
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
nodeAsChar = do_QueryInterface(aStartNode);
if (nodeAsChar) {
nodeAsChar->GetLength((PRUint32 *)&endOffset);
}
else
{
printf("not yet supported\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
result = aStartNode->GetParentNode(getter_AddRefs(parentNode));
if (NS_SUCCEEDED(result)) {
result = RemoveTextPropertiesForNode(aStartNode, parentNode, startOffset, endOffset, aPropName);
}
}
if (NS_SUCCEEDED(result))
{
// remove aPropName from the end node
startOffset = 0;
endOffset = aEndOffset;
result = aEndNode->GetParentNode(getter_AddRefs(parentNode));
if (NS_SUCCEEDED(result)) {
result = RemoveTextPropertiesForNode(aEndNode, parentNode, startOffset, endOffset, aPropName);
}
}
return result;

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

@ -90,7 +90,7 @@ NS_IMETHODIMP JoinElementTxn::Do(void)
result = editor->JoinNodesImpl(mRightNode, mLeftNode, mParent, PR_FALSE);
if (NS_SUCCEEDED(result))
{
if (gNoisy) { printf(" left node = %p removed\n", this, mLeftNode.get()); }
if (gNoisy) { printf(" left node = %p removed\n", mLeftNode.get()); }
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (selection)

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

@ -286,7 +286,7 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
InsertStyleNode(newTextNode, nsIEditProperty::b, aSelection);
}
else {
printf("not yet implemented, make unbold in a bold context\n");
printf("not yet implemented, make not bold in a bold context\n");
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
@ -296,7 +296,7 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
}
else
{
printf("not yet implemented, make unitalic in a italic context\n");
printf("not yet implemented, make not italic in a italic context\n");
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
@ -334,21 +334,20 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
{ // now we've got the body tag. insert the style tag
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
{
if (PR_TRUE==aTypeInState.GetBold())
{ // make the next char bold
nsAutoString tag;
nsIEditProperty::b->ToString(tag);
nsCOMPtr<nsIDOMNode>newStyleNode;
nsCOMPtr<nsIDOMNode>newTextNode;
result = mEditor->CreateNode(tag, bodyNode, 0, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result))
{
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result))
{
aSelection->Collapse(newTextNode, 0);
}
}
if (PR_TRUE==aTypeInState.GetBold()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
{
if (PR_TRUE==aTypeInState.GetItalic()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection);
}
}
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
{
if (PR_TRUE==aTypeInState.GetUnderline()) {
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::u, aSelection);
}
}
}
@ -389,6 +388,50 @@ nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelecti
}
NS_IMETHODIMP
nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
{
NS_ASSERTION(aParentNode && aTag, "bad args");
if (!aParentNode || !aTag) { return NS_ERROR_NULL_POINTER; }
nsresult result;
// if the selection already points to a text node, just call InsertStyleNode()
if (aSelection)
{
nsCOMPtr<nsIDOMNode>anchor;
PRInt32 offset;
nsresult result = aSelection->GetAnchorNodeAndOffset(getter_AddRefs(anchor), &offset);
if ((NS_SUCCEEDED(result)) && anchor)
{
nsCOMPtr<nsIDOMCharacterData>anchorAsText;
anchorAsText = do_QueryInterface(anchor);
if (anchorAsText)
{
result = InsertStyleNode(anchor, aTag, aSelection);
return result;
}
}
}
// if we get here, there is no selected text node so we create one.
nsAutoString tag;
aTag->ToString(tag);
nsCOMPtr<nsIDOMNode>newStyleNode;
nsCOMPtr<nsIDOMNode>newTextNode;
result = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode));
if (NS_SUCCEEDED(result))
{
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
if (NS_SUCCEEDED(result))
{
if (aSelection) {
aSelection->Collapse(newTextNode, 0);
}
}
}
return result;
}
/*
NS_IMETHODIMP
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
@ -529,6 +572,7 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
nsCOMPtr<nsIDOMNode> parentNode;
selectedNode->GetParentNode(getter_AddRefs(parentNode));
result = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
// selectedNode will remain after the join, siblingNode is removed
}
}
selectedNode->GetNextSibling(getter_AddRefs(siblingNode));
@ -543,8 +587,9 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
nsCOMPtr<nsIDOMNode> parentNode;
selectedNode->GetParentNode(getter_AddRefs(parentNode));
result = mEditor->JoinNodes(selectedNode, siblingNode, parentNode);
// selectedNode will remain after the join, siblingNode is removed
// set selection
aSelection->Collapse(selectedNode, selectedNodeLength);
aSelection->Collapse(siblingNode, selectedNodeLength);
}
}
}

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

@ -89,7 +89,19 @@ protected:
* aSelection is optional. If provided, aSelection is set to (aNode, 0)
* if aNode was successfully placed in a new style node
*/
NS_IMETHOD InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelection *aSelection);
NS_IMETHOD InsertStyleNode(nsIDOMNode *aNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
/** create a new style node of type aTag in aParentNode, and put a new text node
* in the new style node.
* If aSelection is provided and points to a text node, just call InsertStyleNode instead.
* aSelection is optional. If provided, aSelection is set to (newTextNode, 0)
* if newTextNode was successfully created.
*/
NS_IMETHOD InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
// data
nsTextEditor *mEditor; // note that we do not refcount the editor

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

@ -113,8 +113,8 @@ public:
* @param aValue the value to set aAttribute to
*/
NS_IMETHOD SetAttribute(nsIDOMElement * aElement,
const nsString& aAttribute,
const nsString& aValue)=0;
const nsString& aAttribute,
const nsString& aValue)=0;
/**
* GetAttributeValue() retrieves the attribute's value for aElement.
@ -158,6 +158,8 @@ public:
* @param aNode The DOM Node to insert.
* @param aParent The node to insert the new object into
* @param aPosition The place in aParent to insert the new node
* 0=first child, 1=second child, etc.
* any number > number of current children = last child
*/
NS_IMETHOD InsertNode(nsIDOMNode * aNode,
nsIDOMNode * aParent,
@ -203,8 +205,8 @@ public:
* @param aNewLeftNode [OUT] the new node resulting from the split, becomes aExistingRightNode's previous sibling.
*/
NS_IMETHOD SplitNode(nsIDOMNode * aExistingRightNode,
PRInt32 aOffset,
nsIDOMNode ** aNewLeftNode)=0;
PRInt32 aOffset,
nsIDOMNode ** aNewLeftNode)=0;
/**
* JoinNodes() takes 2 nodes and merge their content|children.

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

@ -19,6 +19,10 @@
#include "nsTransactionItem.h"
#include "nsCOMPtr.h"
#ifdef NS_DEBUG
//#define NOISY
#endif
nsTransactionItem::nsTransactionItem(nsITransaction *aTransaction)
: mTransaction(aTransaction), mUndoStack(0), mRedoStack(0)
{
@ -112,6 +116,12 @@ nsTransactionItem::Undo()
if (!mTransaction)
return NS_OK;
#ifdef NOISY
nsAutoString redoString;
mTransaction->GetRedoString(&redoString);
printf("undoing %s\n", redoString);
#endif
result = mTransaction->Undo();
if (NS_FAILED(result)) {
@ -149,6 +159,12 @@ nsTransactionItem::UndoChildren()
return result;
}
#ifdef NOISY
nsAutoString redoString;
item->GetRedoString(&redoString);
printf("undoing %s\n", redoString);
#endif
result = item->Undo();
if (NS_FAILED(result)) {
@ -181,6 +197,13 @@ nsTransactionItem::Redo()
nsresult result;
if (mTransaction) {
#ifdef NOISY
nsAutoString undoString;
mTransaction->GetUndoString(&undoString);
printf("redoing %s\n", undoString);
#endif
result = mTransaction->Redo();
if (NS_FAILED(result))
@ -221,6 +244,12 @@ nsTransactionItem::RedoChildren()
return result;
}
#ifdef NOISY
nsAutoString undoString;
item->GetUndoString(&undoString);
printf("redoing %s\n", undoString);
#endif
result = item->Redo();
if (NS_FAILED(result)) {