implemented a system to track what portion of a document is affect by an editor action. Used that system to help solve extensive whitespace handling problems, ans also problems with caret placement in response to returns (this lattter fix for html editors only - plaintext coming later). Fixed numerous list bugs involving outdenting, unlisting, and splitting lists.

This commit is contained in:
jfrancis%netscape.com 1999-11-25 00:19:45 +00:00
Родитель 09ed614b05
Коммит 49e900609d
9 изменённых файлов: 3134 добавлений и 526 удалений

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

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

@ -24,11 +24,14 @@
#define nsHTMLEditRules_h__ #define nsHTMLEditRules_h__
#include "nsTextEditRules.h" #include "nsTextEditRules.h"
#include "nsIEditActionListener.h"
#include "nsISupportsArray.h" #include "nsISupportsArray.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsString.h"
class nsISupportsArray; class nsISupportsArray;
class nsVoidArray; class nsVoidArray;
class nsIDOMElement;
class nsHTMLEditRules : public nsTextEditRules class nsHTMLEditRules : public nsTextEditRules
{ {
@ -38,6 +41,7 @@ public:
virtual ~nsHTMLEditRules(); virtual ~nsHTMLEditRules();
// nsEditRules methods // nsEditRules methods
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled); NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
@ -51,6 +55,7 @@ protected:
// nsHTMLEditRules implementation methods // nsHTMLEditRules implementation methods
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult WillInsertText( PRInt32 aAction, nsresult WillInsertText( PRInt32 aAction,
nsIDOMSelection *aSelection, nsIDOMSelection *aSelection,
PRBool *aCancel, PRBool *aCancel,
@ -71,7 +76,6 @@ protected:
nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString); nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString);
nsresult InsertSpace(nsIDOMSelection *aSelection, nsString *outString); nsresult InsertSpace(nsIDOMSelection *aSelection, nsString *outString);
nsresult InsertMozBR();
nsresult ReturnInHeader(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset); 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 ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
@ -84,6 +88,7 @@ protected:
static PRBool IsHeader(nsIDOMNode *aNode); static PRBool IsHeader(nsIDOMNode *aNode);
static PRBool IsParagraph(nsIDOMNode *aNode); static PRBool IsParagraph(nsIDOMNode *aNode);
static PRBool IsListItem(nsIDOMNode *aNode); static PRBool IsListItem(nsIDOMNode *aNode);
static PRBool IsTableCell(nsIDOMNode *aNode);
static PRBool IsList(nsIDOMNode *aNode); static PRBool IsList(nsIDOMNode *aNode);
static PRBool IsUnorderedList(nsIDOMNode *aNode); static PRBool IsUnorderedList(nsIDOMNode *aNode);
static PRBool IsOrderedList(nsIDOMNode *aNode); static PRBool IsOrderedList(nsIDOMNode *aNode);
@ -108,11 +113,15 @@ protected:
PRBool *outIsEmptyBlock, PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE, PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE); PRBool aListItemsNotEmpty = PR_FALSE);
PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent);
PRBool IsFirstNode(nsIDOMNode *aNode); PRBool IsFirstNode(nsIDOMNode *aNode);
PRBool IsLastNode(nsIDOMNode *aNode); PRBool IsLastNode(nsIDOMNode *aNode);
PRBool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock); PRBool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
PRBool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock); PRBool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
nsresult CreateMozDiv(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outDiv); nsresult CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outBRNode);
nsresult GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode); nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode); nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode); nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
@ -123,6 +132,7 @@ protected:
nsresult GetPromotedRanges(nsIDOMSelection *inSelection, nsresult GetPromotedRanges(nsIDOMSelection *inSelection,
nsCOMPtr<nsISupportsArray> *outArrayOfRanges, nsCOMPtr<nsISupportsArray> *outArrayOfRanges,
PRInt32 inOperationType); PRInt32 inOperationType);
nsresult PromoteRange(nsIDOMRange *inRange, PRInt32 inOperationType);
nsresult GetNodesForOperation(nsISupportsArray *inArrayOfRanges, nsresult GetNodesForOperation(nsISupportsArray *inArrayOfRanges,
nsCOMPtr<nsISupportsArray> *outArrayOfNodes, nsCOMPtr<nsISupportsArray> *outArrayOfNodes,
PRInt32 inOperationType); PRInt32 inOperationType);
@ -149,9 +159,73 @@ protected:
PRInt32 *aOutMergeOffset); PRInt32 *aOutMergeOffset);
nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode); nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode);
nsresult CleanUpSelection(nsIDOMSelection *aSelection);
nsresult PopListItem(nsIDOMNode *aListItem, PRBool *aOutOfList); nsresult PopListItem(nsIDOMNode *aListItem, PRBool *aOutOfList);
nsresult AdjustSpecialBreaks();
nsresult AdjustWhitespace();
nsresult AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction);
nsresult RemoveEmptyNodes();
nsresult DoTextNodeWhitespace(nsIDOMCharacterData *aTextNode, PRInt32 aStart, PRInt32 aEnd);
nsresult UpdateDocChangeRange(nsIDOMRange *aRange);
nsresult ConvertWhitespace(const nsString & inString, const nsString & outString);
// removed from use:
#if 0
nsresult AddTrailerBR(nsIDOMNode *aNode);
nsresult CreateMozDiv(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outDiv);
#endif
// data members
protected:
nsCOMPtr<nsIEditActionListener> mListener;
nsCOMPtr<nsIDOMRange> mDocChangeRange;
// friends
friend class nsHTMLEditListener;
friend nsresult NS_NewEditListener(nsIEditActionListener **aResult,
nsHTMLEditor *htmlEditor,
nsHTMLEditRules *htmlRules);
};
class nsHTMLEditListener : public nsIEditActionListener
{
public:
nsHTMLEditListener(nsHTMLEditor *htmlEditor, nsHTMLEditRules *htmlRules);
virtual ~nsHTMLEditListener();
NS_DECL_ISUPPORTS
// nsIEditActionListener methods
NS_IMETHOD WillCreateNode(const nsString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidCreateNode(const nsString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString, nsresult aResult);
NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
protected:
nsresult MakeRangeFromNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMRange> *outRange);
nsresult MakeRangeFromTextOffsets(nsIDOMCharacterData *inNode,
PRInt32 inStart,
PRInt32 inEnd,
nsCOMPtr<nsIDOMRange> *outRange);
PRBool IsDescendantOfBody(nsIDOMNode *inNode) ;
// data members
nsHTMLEditor *mEditor;
nsHTMLEditRules *mRules;
nsCOMPtr<nsIDOMNode> mBody;
}; };
#endif //nsHTMLEditRules_h__ #endif //nsHTMLEditRules_h__

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

@ -759,6 +759,55 @@ NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsHTMLEditor::CreateBR(nsIDOMNode *aNode, PRInt32 aOffset, nsCOMPtr<nsIDOMNode> *outBRNode)
{
if (!aNode || !outBRNode) return NS_ERROR_NULL_POINTER;
*outBRNode = nsnull;
nsresult res;
// we need to insert a br. unfortunately, we may have to split a text node to do it.
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(aNode);
nsAutoString brType("br");
nsCOMPtr<nsIDOMNode> brNode;
if (nodeAsText)
{
nsCOMPtr<nsIDOMNode> tmp;
PRInt32 offset;
PRUint32 len;
nodeAsText->GetLength(&len);
GetNodeLocation(aNode, &tmp, &offset);
if (!tmp) return NS_ERROR_FAILURE;
if (!aOffset)
{
// we are already set to go
}
else if (aOffset == (PRInt32)len)
{
// update offset to point AFTER the text node
offset++;
}
else
{
// split the text node
res = SplitNode(aNode, aOffset, getter_AddRefs(tmp));
if (NS_FAILED(res)) return res;
res = GetNodeLocation(aNode, &tmp, &offset);
if (NS_FAILED(res)) return res;
}
// create br
res = CreateNode(brType, tmp, offset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
}
else
{
res = CreateNode(brType, aNode, aOffset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
}
*outBRNode = brNode;
return NS_OK;
}
NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode) NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode)
{ {
PRBool bCollapsed; PRBool bCollapsed;
@ -780,33 +829,12 @@ NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode)
res = GetStartNodeAndOffset(selection, &selNode, &selOffset); res = GetStartNodeAndOffset(selection, &selNode, &selOffset);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
// now we need to insert a br. unfortunately, we may have to split a text node to do it. res = CreateBR(selNode, selOffset, outBRNode);
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(selNode);
nsAutoString brType("br");
nsCOMPtr<nsIDOMNode> brNode;
if (nodeAsText)
{
// split the text node
nsCOMPtr<nsIDOMNode> tmp;
PRInt32 offset;
res = SplitNode(selNode, selOffset, getter_AddRefs(tmp));
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
res = GetNodeLocation(selNode, &tmp, &offset);
if (NS_FAILED(res)) return res;
// create br
res = CreateNode(brType, tmp, offset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
// position selection in righthand text node
res = selection->Collapse(selNode, 0);
if (NS_FAILED(res)) return res;
}
else
{
res = CreateNode(brType, selNode, selOffset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
}
*outBRNode = brNode; // position selection in righthand text node
// moose
return NS_OK; return NS_OK;
} }
@ -2165,13 +2193,15 @@ nsHTMLEditor::InsertBasicBlock(const nsString& aBlockType)
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
// xxx // xxx
// i'm def'ing this out to see if auto br insertion is working for this case
#if 0
// put a space in it so layout will draw it // put a space in it so layout will draw it
res = selection->Collapse(newBlock,0); res = selection->Collapse(newBlock,0);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
nsAutoString theText(nbsp); nsAutoString theText(nbsp);
res = InsertText(theText); res = InsertText(theText);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
#endif
// reposition selection to before the space character // reposition selection to before the space character
res = GetStartNodeAndOffset(selection, &node, &offset); res = GetStartNodeAndOffset(selection, &node, &offset);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
@ -2642,6 +2672,8 @@ nsHTMLEditor::CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement*
{ {
newElement->SetAttribute("valign","top"); newElement->SetAttribute("valign","top");
// I'm def'ing this out to see if auto br insertion is working here
#if 0
// Insert the default space in a cell so border displays // Insert the default space in a cell so border displays
nsCOMPtr<nsIDOMNode> newCellNode = do_QueryInterface(newElement); nsCOMPtr<nsIDOMNode> newCellNode = do_QueryInterface(newElement);
if (newCellNode) if (newCellNode)
@ -2660,6 +2692,7 @@ nsHTMLEditor::CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement*
nsCOMPtr<nsIDOMNode>resultNode; nsCOMPtr<nsIDOMNode>resultNode;
result = newCellNode->AppendChild(newTextNode, getter_AddRefs(resultNode)); result = newCellNode->AppendChild(newTextNode, getter_AddRefs(resultNode));
} }
#endif
} }
// ADD OTHER DEFAULT ATTRIBUTES HERE // ADD OTHER DEFAULT ATTRIBUTES HERE

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

@ -261,6 +261,7 @@ protected:
// key event helpers // key event helpers
NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled); NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled);
NS_IMETHOD CreateBR(nsIDOMNode *aNode, PRInt32 aOffset, nsCOMPtr<nsIDOMNode> *outBRNode);
NS_IMETHOD InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode); NS_IMETHOD InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode);
// Table Editing (implemented in EditTable.cpp) // Table Editing (implemented in EditTable.cpp)

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

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

@ -24,11 +24,14 @@
#define nsHTMLEditRules_h__ #define nsHTMLEditRules_h__
#include "nsTextEditRules.h" #include "nsTextEditRules.h"
#include "nsIEditActionListener.h"
#include "nsISupportsArray.h" #include "nsISupportsArray.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsString.h"
class nsISupportsArray; class nsISupportsArray;
class nsVoidArray; class nsVoidArray;
class nsIDOMElement;
class nsHTMLEditRules : public nsTextEditRules class nsHTMLEditRules : public nsTextEditRules
{ {
@ -38,6 +41,7 @@ public:
virtual ~nsHTMLEditRules(); virtual ~nsHTMLEditRules();
// nsEditRules methods // nsEditRules methods
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled); NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
@ -51,6 +55,7 @@ protected:
// nsHTMLEditRules implementation methods // nsHTMLEditRules implementation methods
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult WillInsertText( PRInt32 aAction, nsresult WillInsertText( PRInt32 aAction,
nsIDOMSelection *aSelection, nsIDOMSelection *aSelection,
PRBool *aCancel, PRBool *aCancel,
@ -71,7 +76,6 @@ protected:
nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString); nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString);
nsresult InsertSpace(nsIDOMSelection *aSelection, nsString *outString); nsresult InsertSpace(nsIDOMSelection *aSelection, nsString *outString);
nsresult InsertMozBR();
nsresult ReturnInHeader(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset); 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 ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
@ -84,6 +88,7 @@ protected:
static PRBool IsHeader(nsIDOMNode *aNode); static PRBool IsHeader(nsIDOMNode *aNode);
static PRBool IsParagraph(nsIDOMNode *aNode); static PRBool IsParagraph(nsIDOMNode *aNode);
static PRBool IsListItem(nsIDOMNode *aNode); static PRBool IsListItem(nsIDOMNode *aNode);
static PRBool IsTableCell(nsIDOMNode *aNode);
static PRBool IsList(nsIDOMNode *aNode); static PRBool IsList(nsIDOMNode *aNode);
static PRBool IsUnorderedList(nsIDOMNode *aNode); static PRBool IsUnorderedList(nsIDOMNode *aNode);
static PRBool IsOrderedList(nsIDOMNode *aNode); static PRBool IsOrderedList(nsIDOMNode *aNode);
@ -108,11 +113,15 @@ protected:
PRBool *outIsEmptyBlock, PRBool *outIsEmptyBlock,
PRBool aMozBRDoesntCount = PR_FALSE, PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListItemsNotEmpty = PR_FALSE); PRBool aListItemsNotEmpty = PR_FALSE);
PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent);
PRBool IsFirstNode(nsIDOMNode *aNode); PRBool IsFirstNode(nsIDOMNode *aNode);
PRBool IsLastNode(nsIDOMNode *aNode); PRBool IsLastNode(nsIDOMNode *aNode);
PRBool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock); PRBool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
PRBool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock); PRBool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
nsresult CreateMozDiv(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outDiv); nsresult CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outBRNode);
nsresult GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode); nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode); nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode); nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
@ -123,6 +132,7 @@ protected:
nsresult GetPromotedRanges(nsIDOMSelection *inSelection, nsresult GetPromotedRanges(nsIDOMSelection *inSelection,
nsCOMPtr<nsISupportsArray> *outArrayOfRanges, nsCOMPtr<nsISupportsArray> *outArrayOfRanges,
PRInt32 inOperationType); PRInt32 inOperationType);
nsresult PromoteRange(nsIDOMRange *inRange, PRInt32 inOperationType);
nsresult GetNodesForOperation(nsISupportsArray *inArrayOfRanges, nsresult GetNodesForOperation(nsISupportsArray *inArrayOfRanges,
nsCOMPtr<nsISupportsArray> *outArrayOfNodes, nsCOMPtr<nsISupportsArray> *outArrayOfNodes,
PRInt32 inOperationType); PRInt32 inOperationType);
@ -149,9 +159,73 @@ protected:
PRInt32 *aOutMergeOffset); PRInt32 *aOutMergeOffset);
nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode); nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode);
nsresult CleanUpSelection(nsIDOMSelection *aSelection);
nsresult PopListItem(nsIDOMNode *aListItem, PRBool *aOutOfList); nsresult PopListItem(nsIDOMNode *aListItem, PRBool *aOutOfList);
nsresult AdjustSpecialBreaks();
nsresult AdjustWhitespace();
nsresult AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction);
nsresult RemoveEmptyNodes();
nsresult DoTextNodeWhitespace(nsIDOMCharacterData *aTextNode, PRInt32 aStart, PRInt32 aEnd);
nsresult UpdateDocChangeRange(nsIDOMRange *aRange);
nsresult ConvertWhitespace(const nsString & inString, const nsString & outString);
// removed from use:
#if 0
nsresult AddTrailerBR(nsIDOMNode *aNode);
nsresult CreateMozDiv(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outDiv);
#endif
// data members
protected:
nsCOMPtr<nsIEditActionListener> mListener;
nsCOMPtr<nsIDOMRange> mDocChangeRange;
// friends
friend class nsHTMLEditListener;
friend nsresult NS_NewEditListener(nsIEditActionListener **aResult,
nsHTMLEditor *htmlEditor,
nsHTMLEditRules *htmlRules);
};
class nsHTMLEditListener : public nsIEditActionListener
{
public:
nsHTMLEditListener(nsHTMLEditor *htmlEditor, nsHTMLEditRules *htmlRules);
virtual ~nsHTMLEditListener();
NS_DECL_ISUPPORTS
// nsIEditActionListener methods
NS_IMETHOD WillCreateNode(const nsString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidCreateNode(const nsString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString, nsresult aResult);
NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
protected:
nsresult MakeRangeFromNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMRange> *outRange);
nsresult MakeRangeFromTextOffsets(nsIDOMCharacterData *inNode,
PRInt32 inStart,
PRInt32 inEnd,
nsCOMPtr<nsIDOMRange> *outRange);
PRBool IsDescendantOfBody(nsIDOMNode *inNode) ;
// data members
nsHTMLEditor *mEditor;
nsHTMLEditRules *mRules;
nsCOMPtr<nsIDOMNode> mBody;
}; };
#endif //nsHTMLEditRules_h__ #endif //nsHTMLEditRules_h__

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

@ -759,6 +759,55 @@ NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsHTMLEditor::CreateBR(nsIDOMNode *aNode, PRInt32 aOffset, nsCOMPtr<nsIDOMNode> *outBRNode)
{
if (!aNode || !outBRNode) return NS_ERROR_NULL_POINTER;
*outBRNode = nsnull;
nsresult res;
// we need to insert a br. unfortunately, we may have to split a text node to do it.
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(aNode);
nsAutoString brType("br");
nsCOMPtr<nsIDOMNode> brNode;
if (nodeAsText)
{
nsCOMPtr<nsIDOMNode> tmp;
PRInt32 offset;
PRUint32 len;
nodeAsText->GetLength(&len);
GetNodeLocation(aNode, &tmp, &offset);
if (!tmp) return NS_ERROR_FAILURE;
if (!aOffset)
{
// we are already set to go
}
else if (aOffset == (PRInt32)len)
{
// update offset to point AFTER the text node
offset++;
}
else
{
// split the text node
res = SplitNode(aNode, aOffset, getter_AddRefs(tmp));
if (NS_FAILED(res)) return res;
res = GetNodeLocation(aNode, &tmp, &offset);
if (NS_FAILED(res)) return res;
}
// create br
res = CreateNode(brType, tmp, offset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
}
else
{
res = CreateNode(brType, aNode, aOffset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
}
*outBRNode = brNode;
return NS_OK;
}
NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode) NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode)
{ {
PRBool bCollapsed; PRBool bCollapsed;
@ -780,33 +829,12 @@ NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode)
res = GetStartNodeAndOffset(selection, &selNode, &selOffset); res = GetStartNodeAndOffset(selection, &selNode, &selOffset);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
// now we need to insert a br. unfortunately, we may have to split a text node to do it. res = CreateBR(selNode, selOffset, outBRNode);
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(selNode);
nsAutoString brType("br");
nsCOMPtr<nsIDOMNode> brNode;
if (nodeAsText)
{
// split the text node
nsCOMPtr<nsIDOMNode> tmp;
PRInt32 offset;
res = SplitNode(selNode, selOffset, getter_AddRefs(tmp));
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
res = GetNodeLocation(selNode, &tmp, &offset);
if (NS_FAILED(res)) return res;
// create br
res = CreateNode(brType, tmp, offset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
// position selection in righthand text node
res = selection->Collapse(selNode, 0);
if (NS_FAILED(res)) return res;
}
else
{
res = CreateNode(brType, selNode, selOffset, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
}
*outBRNode = brNode; // position selection in righthand text node
// moose
return NS_OK; return NS_OK;
} }
@ -2165,13 +2193,15 @@ nsHTMLEditor::InsertBasicBlock(const nsString& aBlockType)
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
// xxx // xxx
// i'm def'ing this out to see if auto br insertion is working for this case
#if 0
// put a space in it so layout will draw it // put a space in it so layout will draw it
res = selection->Collapse(newBlock,0); res = selection->Collapse(newBlock,0);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
nsAutoString theText(nbsp); nsAutoString theText(nbsp);
res = InsertText(theText); res = InsertText(theText);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
#endif
// reposition selection to before the space character // reposition selection to before the space character
res = GetStartNodeAndOffset(selection, &node, &offset); res = GetStartNodeAndOffset(selection, &node, &offset);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
@ -2642,6 +2672,8 @@ nsHTMLEditor::CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement*
{ {
newElement->SetAttribute("valign","top"); newElement->SetAttribute("valign","top");
// I'm def'ing this out to see if auto br insertion is working here
#if 0
// Insert the default space in a cell so border displays // Insert the default space in a cell so border displays
nsCOMPtr<nsIDOMNode> newCellNode = do_QueryInterface(newElement); nsCOMPtr<nsIDOMNode> newCellNode = do_QueryInterface(newElement);
if (newCellNode) if (newCellNode)
@ -2660,6 +2692,7 @@ nsHTMLEditor::CreateElementWithDefaults(const nsString& aTagName, nsIDOMElement*
nsCOMPtr<nsIDOMNode>resultNode; nsCOMPtr<nsIDOMNode>resultNode;
result = newCellNode->AppendChild(newTextNode, getter_AddRefs(resultNode)); result = newCellNode->AppendChild(newTextNode, getter_AddRefs(resultNode));
} }
#endif
} }
// ADD OTHER DEFAULT ATTRIBUTES HERE // ADD OTHER DEFAULT ATTRIBUTES HERE

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

@ -261,6 +261,7 @@ protected:
// key event helpers // key event helpers
NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled); NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled);
NS_IMETHOD CreateBR(nsIDOMNode *aNode, PRInt32 aOffset, nsCOMPtr<nsIDOMNode> *outBRNode);
NS_IMETHOD InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode); NS_IMETHOD InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode);
// Table Editing (implemented in EditTable.cpp) // Table Editing (implemented in EditTable.cpp)

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

@ -420,6 +420,7 @@
<menu id="paragraphMenu" value="&paragraphMenu.label;" accesskey="&formatparagraphmenu.accesskey;"> <menu id="paragraphMenu" value="&paragraphMenu.label;" accesskey="&formatparagraphmenu.accesskey;">
<menupopup> <menupopup>
<menuitem value="&paragraphNormalCmd.label;" accesskey="&paragraphnormal.accesskey;" oncommand="EditorSetParagraphFormat('normal')"/> <menuitem value="&paragraphNormalCmd.label;" accesskey="&paragraphnormal.accesskey;" oncommand="EditorSetParagraphFormat('normal')"/>
<menuitem value="&paragraphParagraphCmd.label;" accesskey="&paragraphparagraph.accesskey;" oncommand="EditorSetParagraphFormat('p')"/>
<menuitem value="&paragraphBlockquoteCmd.label;" accesskey="&paragraphblockquote.accesskey;" oncommand="EditorSetParagraphFormat('blockquote')"/> <menuitem value="&paragraphBlockquoteCmd.label;" accesskey="&paragraphblockquote.accesskey;" oncommand="EditorSetParagraphFormat('blockquote')"/>
<menuitem value="&paragraphAddressCmd.label;" accesskey="&paragraphaddress.accesskey;" oncommand="EditorSetParagraphFormat('address')"/> <menuitem value="&paragraphAddressCmd.label;" accesskey="&paragraphaddress.accesskey;" oncommand="EditorSetParagraphFormat('address')"/>
<menuitem value="&paragraphPreformatCmd.label;" accesskey="&paragraphpreformat.accesskey;" oncommand="EditorSetParagraphFormat('pre')"/> <menuitem value="&paragraphPreformatCmd.label;" accesskey="&paragraphpreformat.accesskey;" oncommand="EditorSetParagraphFormat('pre')"/>
@ -544,6 +545,7 @@
<html:select class="toolbar" id="ParagraphSelect" size="1" onchange="EditorSelectParagraphFormat()"> <html:select class="toolbar" id="ParagraphSelect" size="1" onchange="EditorSelectParagraphFormat()">
<observes element="Editor:Paragraph:Format" attribute="format" onbroadcast="onParagraphFormatChange()"/> <observes element="Editor:Paragraph:Format" attribute="format" onbroadcast="onParagraphFormatChange()"/>
<html:option>&headingNormalCmd.label;</html:option> <html:option>&headingNormalCmd.label;</html:option>
<html:option>&paragraphParagraphCmd.label;</html:option>
<html:option>&heading1Cmd.label;</html:option> <html:option>&heading1Cmd.label;</html:option>
<html:option>&heading2Cmd.label;</html:option> <html:option>&heading2Cmd.label;</html:option>
<html:option>&heading3Cmd.label;</html:option> <html:option>&heading3Cmd.label;</html:option>