22662, 16720: greatly improve formatting of html source for inserted html tags. r=jfrancis

git-svn-id: svn://10.0.0.236/trunk@58667 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
akkana%netscape.com 2000-01-26 00:57:37 +00:00
parent 1b2ae3e812
commit 831fa6d5c7
12 changed files with 662 additions and 1296 deletions

View File

@ -25,7 +25,7 @@
#include "nsIContent.h"
#ifdef NS_DEBUG
static PRBool gNoisy = PR_FALSE;
static PRBool gNoisy = PR_TRUE;
#else
static const PRBool gNoisy = PR_FALSE;
#endif
@ -106,6 +106,9 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
if (NS_FAILED(result)) return result;
if (!resultNode) return NS_ERROR_NULL_POINTER;
// Try to insert formatting whitespace for the new node:
mEditor->InsertFormattingForNode(resultNode);
// only set selection to insertion point if editor gives permission
PRBool bAdjustSelection;
mEditor->ShouldTxnSetSelection(&bAdjustSelection);

File diff suppressed because it is too large Load Diff

View File

@ -80,38 +80,20 @@ protected:
nsresult ReturnInHeader(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
nsresult ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
nsresult ReturnInListItem(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
// helper methods
static PRBool IsHeader(nsIDOMNode *aNode);
static PRBool IsParagraph(nsIDOMNode *aNode);
static PRBool IsListItem(nsIDOMNode *aNode);
static PRBool IsTableCell(nsIDOMNode *aNode);
static PRBool IsList(nsIDOMNode *aNode);
static PRBool IsUnorderedList(nsIDOMNode *aNode);
static PRBool IsOrderedList(nsIDOMNode *aNode);
static PRBool IsBlockquote(nsIDOMNode *aNode);
static PRBool IsAnchor(nsIDOMNode *aNode);
static PRBool IsImage(nsIDOMNode *aNode);
static PRBool IsDiv(nsIDOMNode *aNode);
static PRBool IsNormalDiv(nsIDOMNode *aNode);
static PRBool IsMozDiv(nsIDOMNode *aNode);
static PRBool IsMailCite(nsIDOMNode *aNode);
nsresult IsEmptyBlock(nsIDOMNode *aNode,
PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE);
PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE);
nsresult IsEmptyNode(nsIDOMNode *aNode,
PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE);
PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent);
PRBool IsFirstNode(nsIDOMNode *aNode);
PRBool IsLastNode(nsIDOMNode *aNode);
PRBool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
PRBool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
nsresult GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt32 aOffset,
PRInt32 actionID, nsCOMPtr<nsIDOMNode> *outNode, PRInt32 *outOffset);
nsresult GetPromotedRanges(nsIDOMSelection *inSelection,

View File

@ -24,6 +24,7 @@
#include "nsHTMLEditor.h"
#include "nsHTMLEditRules.h"
#include "nsHTMLEditUtils.h"
#include "nsEditorEventListeners.h"
@ -3421,6 +3422,7 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList)
NS_IMETHODIMP
nsHTMLEditor::InsertFormattingForNode(nsIDOMNode* aNode)
{
return NS_OK;
nsresult res;
// Don't insert any formatting unless it's an element node
@ -3431,54 +3433,102 @@ nsHTMLEditor::InsertFormattingForNode(nsIDOMNode* aNode)
if (nodeType != nsIDOMNode::ELEMENT_NODE)
return NS_OK;
// Insert formatting only for block nodes
// (would it be better to insert for any non-inline node?)
PRBool block;
res = IsNodeBlock(aNode, block);
if (NS_FAILED(res))
return res;
if (!block)
// Don't insert formatting if we're a plaintext editor.
// The newlines get considered to be part of the text.
// This, of course, makes the html look lousy, but we're expecting
// that plaintext editors will only output plaintext, not html.
if (mFlags & nsHTMLEditor::eEditorPlaintextMask)
return NS_OK;
nsCOMPtr<nsIDOMNode> parent;
res = aNode->GetParentNode(getter_AddRefs(parent));
if (NS_FAILED(res))
return res;
PRInt32 offset = GetIndexOf(parent, aNode);
nsString namestr;
aNode->GetNodeName(namestr);
// Don't insert formatting for pre or br if we're a plaintext editor.
// The newlines get considered to be part of the text, yet the
// edit rules also insert breaks, so we end up with too much
// vertical whitespace any time the user hits return.
// This, of course, makes the html look lousy, but we're
// expecting that no one will look at the html from a plaintext editor.
if ((mFlags & nsHTMLEditor::eEditorPlaintextMask)
&& (namestr.Equals("pre", PR_TRUE) || namestr.Equals("br", PR_TRUE)))
return NS_OK;
#ifdef DEBUG_akkana
#define DEBUG_formatting
#endif
#ifdef DEBUG_formatting
nsString namestr;
aNode->GetNodeName(namestr);
//DumpContentTree();
char* nodename = namestr.ToNewCString();
printf("Inserting formatting for node <%s> at offset %d\n",
nodename, offset);
nodename, GetIndexOf(parent, aNode));
#endif /* DEBUG_formatting */
// If it has children, first iterate over the children:
nsCOMPtr<nsIDOMNode> child;
res = aNode->GetFirstChild(getter_AddRefs(child));
if (NS_SUCCEEDED(res) && child)
{
#ifdef DEBUG_formatting
printf("%s: Iterating over children\n", nodename);
#endif /* DEBUG_formatting */
while (child)
{
#ifdef DEBUG_formatting
printf("%s child\n", nodename);
#endif /* DEBUG_formatting */
InsertFormattingForNode(child);
nsCOMPtr<nsIDOMNode> nextSib;
child->GetNextSibling(getter_AddRefs(nextSib));
child = nextSib;
}
}
nsAutoString newline ("\n");
//
// XXX Would be nice, ultimately, to format according to user prefs.
//
res = NS_OK;
PRInt32 offset = GetIndexOf(parent, aNode);
if (nsHTMLEditUtils::IsBreak(aNode) && !nsHTMLEditUtils::IsMozBR(aNode))
{
// After the close tag
res = InsertNoneditableTextNode(parent, offset+1, newline);
}
else if (nsEditor::IsBlockNode(aNode))
{
#ifdef DEBUG_formatting
printf("Block node %s at offset %d\n-----------\n", nodename, offset);
DumpContentTree();
#endif /* DEBUG_formatting */
if (!nsHTMLEditUtils::IsListItem(aNode))
{
// After the close tag
InsertNoneditableTextNode(parent, offset+1, newline);
#ifdef DEBUG_formatting
printf("Now %s has offset %d\n-----------\n",
nodename, GetIndexOf(parent, aNode));
DumpContentTree();
printf("----------------\n");
#endif /* DEBUG_formatting */
}
// Before the open tag
res = InsertNoneditableTextNode(parent, offset, newline);
#ifdef DEBUG_formatting
printf("And NOW, %s has offset %d\n-----------\n", nodename, GetIndexOf(parent, aNode));
DumpContentTree();
printf("----------------\n");
#endif /* DEBUG_formatting */
}
// Some inline tags for which we might want formatting:
else if (nsHTMLEditUtils::IsImage(aNode))
{
res = InsertNoneditableTextNode(parent, offset, newline);
}
#ifdef DEBUG_formatting
Recycle(nodename);
#endif /* DEBUG_akkana */
//
// XXX We don't yet have a real formatter. As a cheap stopgap,
// XXX just insert a newline before and after each newly inserted tag.
//
nsAutoString str ("\n");
// After the close tag
//res = InsertNoneditableTextNode(parent, offset+1, str);
// Before the open tag
res = InsertNoneditableTextNode(parent, offset, str);
#endif /* DEBUG_formatting */
return res;
}
@ -3725,15 +3775,14 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRBool &aCanPaste)
// add the HTML-editor only flavors
if ((editorFlags & eEditorPlaintextMask) == 0)
{
for (char** flavor = htmlEditorFlavors; *flavor; flavor++)
for (char** htmlFlavor = htmlEditorFlavors; *htmlFlavor; htmlFlavor++)
{
nsCOMPtr<nsISupportsString> flavorString;
nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull,
NS_GET_IID(nsISupportsString), getter_AddRefs(flavorString));
if (flavorString)
{
flavorString->SetData(*flavor);
flavorString->SetData(*htmlFlavor);
flavorsList->AppendElement(flavorString);
}
}

View File

@ -23,6 +23,7 @@
#include "nsTextEditRules.h"
#include "nsEditor.h"
#include "nsHTMLEditUtils.h"
#include "nsCOMPtr.h"
#include "nsIDOMNode.h"
@ -322,7 +323,7 @@ nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
if (NS_FAILED(res)) return res;
// get prior node
res = GetPriorHTMLNode(selNode, selOffset, &priorNode);
if (NS_SUCCEEDED(res) && priorNode && IsMozBR(priorNode))
if (NS_SUCCEEDED(res) && priorNode && nsHTMLEditUtils::IsMozBR(priorNode))
{
nsCOMPtr<nsIDOMNode> block1, block2;
if (mEditor->IsBlockNode(selNode)) block1 = selNode;
@ -456,7 +457,7 @@ nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
if (NS_FAILED(res)) return res;
res = GetPriorHTMLNode(selNode, selOffset, &nearNode);
if (NS_FAILED(res)) return res;
if (nearNode && IsBreak(nearNode) && !IsMozBR(nearNode))
if (nearNode && nsHTMLEditUtils::IsBreak(nearNode) && !nsHTMLEditUtils::IsMozBR(nearNode))
{
PRBool bIsLast;
res = IsLastEditableChild(nearNode, &bIsLast);
@ -483,7 +484,7 @@ nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
nsCOMPtr<nsIDOMNode> nextNode;
res = GetNextHTMLNode(nearNode, &nextNode);
if (NS_FAILED(res)) return res;
if (IsMozBR(nextNode))
if (nsHTMLEditUtils::IsMozBR(nextNode))
{
res = nsEditor::GetNodeLocation(nextNode, &selNode, &selOffset);
if (NS_FAILED(res)) return res;
@ -1666,7 +1667,7 @@ nsTextEditRules::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outN
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1685,7 +1686,7 @@ nsTextEditRules::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMP
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1705,7 +1706,7 @@ nsTextEditRules::GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNo
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1724,7 +1725,7 @@ nsTextEditRules::GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPt
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1832,98 +1833,6 @@ nsTextEditRules::GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *
}
///////////////////////////////////////////////////////////////////////////
// IsBody: true if node an html body node
//
PRBool
nsTextEditRules::IsBody(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsTextEditRules::IsBody");
nsAutoString tag;
nsEditor::GetTagString(node,tag);
tag.ToLowerCase();
if (tag == "body")
{
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// IsBreak: true if node an html break node
//
PRBool
nsTextEditRules::IsBreak(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsTextEditRules::IsBreak");
nsAutoString tag;
nsEditor::GetTagString(node,tag);
tag.ToLowerCase();
if (tag == "br")
{
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// IsMozBR: true if node an html br node with type = _moz
//
PRBool
nsTextEditRules::IsMozBR(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsTextEditRules::IsMozBR");
if (IsBreak(node) && HasMozAttr(node)) return PR_TRUE;
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// HasMozAttr: true if node has type attribute = _moz
// (used to indicate the div's and br's we use in
// mail compose rules)
//
PRBool
nsTextEditRules::HasMozAttr(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsTextEditRules::HasMozAttr");
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(node);
if (elem)
{
nsAutoString typeAttrName("type");
nsAutoString typeAttrVal;
nsresult res = elem->GetAttribute(typeAttrName, typeAttrVal);
typeAttrVal.ToLowerCase();
if (NS_SUCCEEDED(res) && (typeAttrVal == "_moz"))
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// InBody: true if node is a descendant of the body
//
PRBool
nsTextEditRules::InBody(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsTextEditRules::InBody");
nsCOMPtr<nsIDOMNode> tmp;
nsCOMPtr<nsIDOMNode> p = do_QueryInterface(node);
while (p && !IsBody(p))
{
if ( NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) // no parent, ran off top of tree
return PR_FALSE;
p = tmp;
}
if (p) return PR_TRUE;
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// CreateMozBR: put a BR node with moz attribute at {aNode, aOffset}
//

View File

@ -219,13 +219,6 @@ protected:
nsresult GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild);
nsresult GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild);
static PRBool IsBody(nsIDOMNode *aNode);
static PRBool IsBreak(nsIDOMNode *aNode);
static PRBool IsMozBR(nsIDOMNode *aNode);
static PRBool HasMozAttr(nsIDOMNode *aNode);
static PRBool InBody(nsIDOMNode *aNode);
nsresult CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outBRNode);

View File

@ -25,7 +25,7 @@
#include "nsIContent.h"
#ifdef NS_DEBUG
static PRBool gNoisy = PR_FALSE;
static PRBool gNoisy = PR_TRUE;
#else
static const PRBool gNoisy = PR_FALSE;
#endif
@ -106,6 +106,9 @@ NS_IMETHODIMP InsertElementTxn::Do(void)
if (NS_FAILED(result)) return result;
if (!resultNode) return NS_ERROR_NULL_POINTER;
// Try to insert formatting whitespace for the new node:
mEditor->InsertFormattingForNode(resultNode);
// only set selection to insertion point if editor gives permission
PRBool bAdjustSelection;
mEditor->ShouldTxnSetSelection(&bAdjustSelection);

File diff suppressed because it is too large Load Diff

View File

@ -80,38 +80,20 @@ protected:
nsresult ReturnInHeader(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
nsresult ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
nsresult ReturnInListItem(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
// helper methods
static PRBool IsHeader(nsIDOMNode *aNode);
static PRBool IsParagraph(nsIDOMNode *aNode);
static PRBool IsListItem(nsIDOMNode *aNode);
static PRBool IsTableCell(nsIDOMNode *aNode);
static PRBool IsList(nsIDOMNode *aNode);
static PRBool IsUnorderedList(nsIDOMNode *aNode);
static PRBool IsOrderedList(nsIDOMNode *aNode);
static PRBool IsBlockquote(nsIDOMNode *aNode);
static PRBool IsAnchor(nsIDOMNode *aNode);
static PRBool IsImage(nsIDOMNode *aNode);
static PRBool IsDiv(nsIDOMNode *aNode);
static PRBool IsNormalDiv(nsIDOMNode *aNode);
static PRBool IsMozDiv(nsIDOMNode *aNode);
static PRBool IsMailCite(nsIDOMNode *aNode);
nsresult IsEmptyBlock(nsIDOMNode *aNode,
PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE);
PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE);
nsresult IsEmptyNode(nsIDOMNode *aNode,
PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE);
PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent);
PRBool IsFirstNode(nsIDOMNode *aNode);
PRBool IsLastNode(nsIDOMNode *aNode);
PRBool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
PRBool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
nsresult GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt32 aOffset,
PRInt32 actionID, nsCOMPtr<nsIDOMNode> *outNode, PRInt32 *outOffset);
nsresult GetPromotedRanges(nsIDOMSelection *inSelection,

View File

@ -24,6 +24,7 @@
#include "nsHTMLEditor.h"
#include "nsHTMLEditRules.h"
#include "nsHTMLEditUtils.h"
#include "nsEditorEventListeners.h"
@ -3421,6 +3422,7 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList)
NS_IMETHODIMP
nsHTMLEditor::InsertFormattingForNode(nsIDOMNode* aNode)
{
return NS_OK;
nsresult res;
// Don't insert any formatting unless it's an element node
@ -3431,54 +3433,102 @@ nsHTMLEditor::InsertFormattingForNode(nsIDOMNode* aNode)
if (nodeType != nsIDOMNode::ELEMENT_NODE)
return NS_OK;
// Insert formatting only for block nodes
// (would it be better to insert for any non-inline node?)
PRBool block;
res = IsNodeBlock(aNode, block);
if (NS_FAILED(res))
return res;
if (!block)
// Don't insert formatting if we're a plaintext editor.
// The newlines get considered to be part of the text.
// This, of course, makes the html look lousy, but we're expecting
// that plaintext editors will only output plaintext, not html.
if (mFlags & nsHTMLEditor::eEditorPlaintextMask)
return NS_OK;
nsCOMPtr<nsIDOMNode> parent;
res = aNode->GetParentNode(getter_AddRefs(parent));
if (NS_FAILED(res))
return res;
PRInt32 offset = GetIndexOf(parent, aNode);
nsString namestr;
aNode->GetNodeName(namestr);
// Don't insert formatting for pre or br if we're a plaintext editor.
// The newlines get considered to be part of the text, yet the
// edit rules also insert breaks, so we end up with too much
// vertical whitespace any time the user hits return.
// This, of course, makes the html look lousy, but we're
// expecting that no one will look at the html from a plaintext editor.
if ((mFlags & nsHTMLEditor::eEditorPlaintextMask)
&& (namestr.Equals("pre", PR_TRUE) || namestr.Equals("br", PR_TRUE)))
return NS_OK;
#ifdef DEBUG_akkana
#define DEBUG_formatting
#endif
#ifdef DEBUG_formatting
nsString namestr;
aNode->GetNodeName(namestr);
//DumpContentTree();
char* nodename = namestr.ToNewCString();
printf("Inserting formatting for node <%s> at offset %d\n",
nodename, offset);
nodename, GetIndexOf(parent, aNode));
#endif /* DEBUG_formatting */
// If it has children, first iterate over the children:
nsCOMPtr<nsIDOMNode> child;
res = aNode->GetFirstChild(getter_AddRefs(child));
if (NS_SUCCEEDED(res) && child)
{
#ifdef DEBUG_formatting
printf("%s: Iterating over children\n", nodename);
#endif /* DEBUG_formatting */
while (child)
{
#ifdef DEBUG_formatting
printf("%s child\n", nodename);
#endif /* DEBUG_formatting */
InsertFormattingForNode(child);
nsCOMPtr<nsIDOMNode> nextSib;
child->GetNextSibling(getter_AddRefs(nextSib));
child = nextSib;
}
}
nsAutoString newline ("\n");
//
// XXX Would be nice, ultimately, to format according to user prefs.
//
res = NS_OK;
PRInt32 offset = GetIndexOf(parent, aNode);
if (nsHTMLEditUtils::IsBreak(aNode) && !nsHTMLEditUtils::IsMozBR(aNode))
{
// After the close tag
res = InsertNoneditableTextNode(parent, offset+1, newline);
}
else if (nsEditor::IsBlockNode(aNode))
{
#ifdef DEBUG_formatting
printf("Block node %s at offset %d\n-----------\n", nodename, offset);
DumpContentTree();
#endif /* DEBUG_formatting */
if (!nsHTMLEditUtils::IsListItem(aNode))
{
// After the close tag
InsertNoneditableTextNode(parent, offset+1, newline);
#ifdef DEBUG_formatting
printf("Now %s has offset %d\n-----------\n",
nodename, GetIndexOf(parent, aNode));
DumpContentTree();
printf("----------------\n");
#endif /* DEBUG_formatting */
}
// Before the open tag
res = InsertNoneditableTextNode(parent, offset, newline);
#ifdef DEBUG_formatting
printf("And NOW, %s has offset %d\n-----------\n", nodename, GetIndexOf(parent, aNode));
DumpContentTree();
printf("----------------\n");
#endif /* DEBUG_formatting */
}
// Some inline tags for which we might want formatting:
else if (nsHTMLEditUtils::IsImage(aNode))
{
res = InsertNoneditableTextNode(parent, offset, newline);
}
#ifdef DEBUG_formatting
Recycle(nodename);
#endif /* DEBUG_akkana */
//
// XXX We don't yet have a real formatter. As a cheap stopgap,
// XXX just insert a newline before and after each newly inserted tag.
//
nsAutoString str ("\n");
// After the close tag
//res = InsertNoneditableTextNode(parent, offset+1, str);
// Before the open tag
res = InsertNoneditableTextNode(parent, offset, str);
#endif /* DEBUG_formatting */
return res;
}
@ -3725,15 +3775,14 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRBool &aCanPaste)
// add the HTML-editor only flavors
if ((editorFlags & eEditorPlaintextMask) == 0)
{
for (char** flavor = htmlEditorFlavors; *flavor; flavor++)
for (char** htmlFlavor = htmlEditorFlavors; *htmlFlavor; htmlFlavor++)
{
nsCOMPtr<nsISupportsString> flavorString;
nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull,
NS_GET_IID(nsISupportsString), getter_AddRefs(flavorString));
if (flavorString)
{
flavorString->SetData(*flavor);
flavorString->SetData(*htmlFlavor);
flavorsList->AppendElement(flavorString);
}
}

View File

@ -23,6 +23,7 @@
#include "nsTextEditRules.h"
#include "nsEditor.h"
#include "nsHTMLEditUtils.h"
#include "nsCOMPtr.h"
#include "nsIDOMNode.h"
@ -322,7 +323,7 @@ nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
if (NS_FAILED(res)) return res;
// get prior node
res = GetPriorHTMLNode(selNode, selOffset, &priorNode);
if (NS_SUCCEEDED(res) && priorNode && IsMozBR(priorNode))
if (NS_SUCCEEDED(res) && priorNode && nsHTMLEditUtils::IsMozBR(priorNode))
{
nsCOMPtr<nsIDOMNode> block1, block2;
if (mEditor->IsBlockNode(selNode)) block1 = selNode;
@ -456,7 +457,7 @@ nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
if (NS_FAILED(res)) return res;
res = GetPriorHTMLNode(selNode, selOffset, &nearNode);
if (NS_FAILED(res)) return res;
if (nearNode && IsBreak(nearNode) && !IsMozBR(nearNode))
if (nearNode && nsHTMLEditUtils::IsBreak(nearNode) && !nsHTMLEditUtils::IsMozBR(nearNode))
{
PRBool bIsLast;
res = IsLastEditableChild(nearNode, &bIsLast);
@ -483,7 +484,7 @@ nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
nsCOMPtr<nsIDOMNode> nextNode;
res = GetNextHTMLNode(nearNode, &nextNode);
if (NS_FAILED(res)) return res;
if (IsMozBR(nextNode))
if (nsHTMLEditUtils::IsMozBR(nextNode))
{
res = nsEditor::GetNodeLocation(nextNode, &selNode, &selOffset);
if (NS_FAILED(res)) return res;
@ -1666,7 +1667,7 @@ nsTextEditRules::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outN
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1685,7 +1686,7 @@ nsTextEditRules::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMP
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1705,7 +1706,7 @@ nsTextEditRules::GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNo
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1724,7 +1725,7 @@ nsTextEditRules::GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPt
if (NS_FAILED(res)) return res;
// if it's not in the body, then zero it out
if (*outNode && !InBody(*outNode))
if (*outNode && !nsHTMLEditUtils::InBody(*outNode))
{
*outNode = nsnull;
}
@ -1832,98 +1833,6 @@ nsTextEditRules::GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *
}
///////////////////////////////////////////////////////////////////////////
// IsBody: true if node an html body node
//
PRBool
nsTextEditRules::IsBody(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsTextEditRules::IsBody");
nsAutoString tag;
nsEditor::GetTagString(node,tag);
tag.ToLowerCase();
if (tag == "body")
{
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// IsBreak: true if node an html break node
//
PRBool
nsTextEditRules::IsBreak(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsTextEditRules::IsBreak");
nsAutoString tag;
nsEditor::GetTagString(node,tag);
tag.ToLowerCase();
if (tag == "br")
{
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// IsMozBR: true if node an html br node with type = _moz
//
PRBool
nsTextEditRules::IsMozBR(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsTextEditRules::IsMozBR");
if (IsBreak(node) && HasMozAttr(node)) return PR_TRUE;
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// HasMozAttr: true if node has type attribute = _moz
// (used to indicate the div's and br's we use in
// mail compose rules)
//
PRBool
nsTextEditRules::HasMozAttr(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsTextEditRules::HasMozAttr");
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(node);
if (elem)
{
nsAutoString typeAttrName("type");
nsAutoString typeAttrVal;
nsresult res = elem->GetAttribute(typeAttrName, typeAttrVal);
typeAttrVal.ToLowerCase();
if (NS_SUCCEEDED(res) && (typeAttrVal == "_moz"))
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// InBody: true if node is a descendant of the body
//
PRBool
nsTextEditRules::InBody(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsTextEditRules::InBody");
nsCOMPtr<nsIDOMNode> tmp;
nsCOMPtr<nsIDOMNode> p = do_QueryInterface(node);
while (p && !IsBody(p))
{
if ( NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) // no parent, ran off top of tree
return PR_FALSE;
p = tmp;
}
if (p) return PR_TRUE;
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// CreateMozBR: put a BR node with moz attribute at {aNode, aOffset}
//

View File

@ -219,13 +219,6 @@ protected:
nsresult GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild);
nsresult GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild);
static PRBool IsBody(nsIDOMNode *aNode);
static PRBool IsBreak(nsIDOMNode *aNode);
static PRBool IsMozBR(nsIDOMNode *aNode);
static PRBool HasMozAttr(nsIDOMNode *aNode);
static PRBool InBody(nsIDOMNode *aNode);
nsresult CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outBRNode);