checkpointing html typing rules

This commit is contained in:
jfrancis%netscape.com 1999-04-12 12:01:32 +00:00
Родитель 1c335bacb3
Коммит 0b0035a95c
13 изменённых файлов: 944 добавлений и 144 удалений

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

@ -22,15 +22,30 @@
class nsIEditor;
class nsIDOMSelection;
/** Interface of editing rules.
*
*/
/***************************************************************************
* base for an object to encapsulate any additional info needed to be passed
* to rules system by the editor
*/
class nsRulesInfo
{
public:
nsRulesInfo(int aAction) : action(aAction) {}
virtual ~nsRulesInfo() {}
int action;
};
/***************************************************************************
* Interface of editing rules.
*
*/
class nsEditRules
{
public:
NS_IMETHOD Init(nsIEditor *aEditor)=0;
NS_IMETHOD WillDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, PRBool *aCancel)=0;
NS_IMETHOD DidDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, nsresult aResult)=0;
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel)=0;
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
};

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

@ -20,7 +20,6 @@
#include "nsEditor.h"
#include "PlaceholderTxn.h"
#include "InsertTextTxn.h"
#include "nsCOMPtr.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIDOMNodeList.h"
@ -35,16 +34,110 @@ const static char* kMOZEditorBogusNodeValue="TRUE";
static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
nsIAtom *nsHTMLEditRules::sAAtom;
nsIAtom *nsHTMLEditRules::sAddressAtom;
nsIAtom *nsHTMLEditRules::sBigAtom;
nsIAtom *nsHTMLEditRules::sBlinkAtom;
nsIAtom *nsHTMLEditRules::sBAtom;
nsIAtom *nsHTMLEditRules::sCiteAtom;
nsIAtom *nsHTMLEditRules::sCodeAtom;
nsIAtom *nsHTMLEditRules::sDfnAtom;
nsIAtom *nsHTMLEditRules::sEmAtom;
nsIAtom *nsHTMLEditRules::sFontAtom;
nsIAtom *nsHTMLEditRules::sIAtom;
nsIAtom *nsHTMLEditRules::sKbdAtom;
nsIAtom *nsHTMLEditRules::sKeygenAtom;
nsIAtom *nsHTMLEditRules::sNobrAtom;
nsIAtom *nsHTMLEditRules::sSAtom;
nsIAtom *nsHTMLEditRules::sSampAtom;
nsIAtom *nsHTMLEditRules::sSmallAtom;
nsIAtom *nsHTMLEditRules::sSpacerAtom;
nsIAtom *nsHTMLEditRules::sSpanAtom;
nsIAtom *nsHTMLEditRules::sStrikeAtom;
nsIAtom *nsHTMLEditRules::sStrongAtom;
nsIAtom *nsHTMLEditRules::sSubAtom;
nsIAtom *nsHTMLEditRules::sSupAtom;
nsIAtom *nsHTMLEditRules::sTtAtom;
nsIAtom *nsHTMLEditRules::sUAtom;
nsIAtom *nsHTMLEditRules::sVarAtom;
nsIAtom *nsHTMLEditRules::sWbrAtom;
PRInt32 nsHTMLEditRules::sInstanceCount;
/********************************************************
* Constructor/Destructor
********************************************************/
nsHTMLEditRules::nsHTMLEditRules()
{
if (sInstanceCount <= 0)
{
sAAtom = NS_NewAtom("a");
sAddressAtom = NS_NewAtom("address");
sBigAtom = NS_NewAtom("big");
sBlinkAtom = NS_NewAtom("blink");
sBAtom = NS_NewAtom("b");
sCiteAtom = NS_NewAtom("cite");
sCodeAtom = NS_NewAtom("code");
sDfnAtom = NS_NewAtom("dfn");
sEmAtom = NS_NewAtom("em");
sFontAtom = NS_NewAtom("font");
sIAtom = NS_NewAtom("i");
sKbdAtom = NS_NewAtom("kbd");
sKeygenAtom = NS_NewAtom("keygen");
sNobrAtom = NS_NewAtom("nobr");
sSAtom = NS_NewAtom("s");
sSampAtom = NS_NewAtom("samp");
sSmallAtom = NS_NewAtom("small");
sSpacerAtom = NS_NewAtom("spacer");
sSpanAtom = NS_NewAtom("span");
sStrikeAtom = NS_NewAtom("strike");
sStrongAtom = NS_NewAtom("strong");
sSubAtom = NS_NewAtom("sub");
sSupAtom = NS_NewAtom("sup");
sTtAtom = NS_NewAtom("tt");
sUAtom = NS_NewAtom("u");
sVarAtom = NS_NewAtom("var");
sWbrAtom = NS_NewAtom("wbr");
}
++sInstanceCount;
}
nsHTMLEditRules::~nsHTMLEditRules()
{
if (sInstanceCount <= 1)
{
NS_IF_RELEASE(sAAtom);
NS_IF_RELEASE(sAddressAtom);
NS_IF_RELEASE(sBigAtom);
NS_IF_RELEASE(sBlinkAtom);
NS_IF_RELEASE(sBAtom);
NS_IF_RELEASE(sCiteAtom);
NS_IF_RELEASE(sCodeAtom);
NS_IF_RELEASE(sDfnAtom);
NS_IF_RELEASE(sEmAtom);
NS_IF_RELEASE(sFontAtom);
NS_IF_RELEASE(sIAtom);
NS_IF_RELEASE(sKbdAtom);
NS_IF_RELEASE(sKeygenAtom);
NS_IF_RELEASE(sNobrAtom);
NS_IF_RELEASE(sSAtom);
NS_IF_RELEASE(sSampAtom);
NS_IF_RELEASE(sSmallAtom);
NS_IF_RELEASE(sSpacerAtom);
NS_IF_RELEASE(sSpanAtom);
NS_IF_RELEASE(sStrikeAtom);
NS_IF_RELEASE(sStrongAtom);
NS_IF_RELEASE(sSubAtom);
NS_IF_RELEASE(sSupAtom);
NS_IF_RELEASE(sTtAtom);
NS_IF_RELEASE(sUAtom);
NS_IF_RELEASE(sVarAtom);
NS_IF_RELEASE(sWbrAtom);
}
--sInstanceCount;
}
@ -53,40 +146,94 @@ nsHTMLEditRules::~nsHTMLEditRules()
********************************************************/
NS_IMETHODIMP
nsHTMLEditRules::WillDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, PRBool *aCancel)
nsHTMLEditRules::WillDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, PRBool *aCancel)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
switch (aAction)
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (info->action)
{
case kInsertText:
return WillInsertText(aSelection,
aCancel,
info->placeTxn,
info->inString,
info->outString,
info->typeInState);
case kInsertBreak:
return WillInsertBreak(aSelection, aCancel);
}
return nsTextEditRules::WillDoAction(aAction, aSelection, aOtherInfo, aCancel);
return nsTextEditRules::WillDoAction(aSelection, aInfo, aCancel);
}
NS_IMETHODIMP
nsHTMLEditRules::DidDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, nsresult aResult)
nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, nsresult aResult)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
switch (aAction)
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (info->action)
{
case kInsertText:
return DidInsertText(aSelection, aResult);
case kInsertBreak:
return DidInsertBreak(aSelection, aResult);
}
return nsTextEditRules::DidDoAction(aAction, aSelection, aOtherInfo, aResult);
return nsTextEditRules::DidDoAction(aSelection, aInfo, aResult);
}
/********************************************************
* Protected methods
* Protected rules methods
********************************************************/
NS_IMETHODIMP
nsresult
nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
// initialize out param
*aCancel = PR_FALSE;
// XXX - need to handle strings of length >1 with embedded tabs or spaces
// is it a tab?
if (*inString == "\t" )
return InsertTab(aSelection,aCancel,aTxn,outString);
// is it a space?
if (*inString == " ")
return InsertSpace(aSelection,aCancel,aTxn,outString);
// otherwise, return nsTextEditRules version
return nsTextEditRules::WillInsertText(aSelection,
aCancel,
aTxn,
inString,
outString,
typeInState);
}
nsresult
nsHTMLEditRules::DidInsertText(nsIDOMSelection *aSelection,
nsresult aResult)
{
// for now, return nsTextEditRules version
return nsTextEditRules::DidInsertText(aSelection, aResult);
}
nsresult
nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -97,7 +244,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
// XXX: this code is all experimental, and has no effect on the content model yet
// the point here is to collapse adjacent BR's into P's
NS_IMETHODIMP
nsresult
nsHTMLEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.
@ -196,3 +343,153 @@ nsHTMLEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
}
return result;
}
/********************************************************
* helper methods
********************************************************/
PRBool
nsHTMLEditRules::IsBlockNode(nsIContent *aContent)
{
nsIAtom* atom = nsnull;
PRBool result;
aContent->GetTag(atom);
if (!atom)
return PR_TRUE;
if (sAAtom != atom &&
sAddressAtom != atom &&
sBigAtom != atom &&
sBlinkAtom != atom &&
sBAtom != atom &&
sCiteAtom != atom &&
sCodeAtom != atom &&
sDfnAtom != atom &&
sEmAtom != atom &&
sFontAtom != atom &&
sIAtom != atom &&
sKbdAtom != atom &&
sKeygenAtom != atom &&
sNobrAtom != atom &&
sSAtom != atom &&
sSampAtom != atom &&
sSmallAtom != atom &&
sSpacerAtom != atom &&
sSpanAtom != atom &&
sStrikeAtom != atom &&
sStrongAtom != atom &&
sSubAtom != atom &&
sSupAtom != atom &&
sTtAtom != atom &&
sUAtom != atom &&
sVarAtom != atom &&
sWbrAtom != atom)
{
result = PR_TRUE;
}
else
{
result = PR_FALSE;
}
NS_RELEASE(atom);
return result;
}
nsCOMPtr<nsIContent>
nsHTMLEditRules::GetBlockNodeParent(nsCOMPtr<nsIContent> aContent)
{
nsCOMPtr<nsIContent> p;
if (NS_FAILED(aContent->GetParent(*getter_AddRefs(p)))) // no parent, ran off top of tree
return aContent;
nsCOMPtr<nsIContent> tmp;
while (p && !IsBlockNode(p))
{
if (NS_FAILED(p->GetParent(*getter_AddRefs(tmp)))) // no parent, ran off top of tree
return p;
p = tmp;
}
return p;
}
///////////////////////////////////////////////////////////////////////////
// GetStartNode: returns whatever the start parent is of the first range
// in the selection.
nsCOMPtr<nsIDOMNode>
nsHTMLEditRules::GetStartNode(nsIDOMSelection *aSelection)
{
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIEnumerator> enumerator;
enumerator = do_QueryInterface(aSelection);
if (!enumerator)
return startNode;
enumerator->First();
nsISupports *currentItem;
if ((NS_FAILED(enumerator->CurrentItem(&currentItem))) || !currentItem)
return startNode;
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
if (!range)
return startNode;
range->GetStartParent(getter_AddRefs(startNode));
return startNode;
}
///////////////////////////////////////////////////////////////////////////
// IsPreformatted: checks the style info for the node for the preformatted
// text style.
nsresult
nsHTMLEditRules::IsPreformatted(nsCOMPtr<nsIDOMNode> aNode, PRBool *aResult)
{
return PR_TRUE;
}
nsresult
nsHTMLEditRules::InsertTab(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
nsString *outString)
{
nsCOMPtr<nsIDOMNode> theNode;
PRBool isPRE;
theNode = GetStartNode(aSelection);
if (!theNode)
return NS_ERROR_UNEXPECTED;
nsresult result = IsPreformatted(theNode,&isPRE);
if (NS_FAILED(result))
return result;
if (isPRE)
{
outString += '\t';
// we're done - let everything fall through to the InsertText code
// in nsTextEditor which will insert the tab as is.
}
else
{
}
return NS_OK;
}
nsresult
nsHTMLEditRules::InsertSpace(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
nsString *outString)
{
return NS_OK;
}

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

@ -20,6 +20,9 @@
#define nsHTMLEditRules_h__
#include "nsTextEditRules.h"
#include "nsCOMPtr.h"
class nsIContent;
class nsHTMLEditRules : public nsTextEditRules
{
@ -29,8 +32,8 @@ public:
virtual ~nsHTMLEditRules();
// nsEditRules methods
NS_IMETHOD WillDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, nsresult aResult);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
// nsHTMLEditRules action id's
enum
@ -40,9 +43,56 @@ public:
protected:
// nsHTMLEditRules implementation methods
NS_IMETHOD WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState);
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
nsresult InsertTab(nsIDOMSelection *aSelection, PRBool *aCancel, PlaceholderTxn **aTxn, nsString *outString);
nsresult InsertSpace(nsIDOMSelection *aSelection, PRBool *aCancel, PlaceholderTxn **aTxn, nsString *outString);
// helper methods
PRBool IsBlockNode(nsIContent *aContent);
nsCOMPtr<nsIContent> GetBlockNodeParent(nsCOMPtr<nsIContent> aContent);
nsCOMPtr<nsIDOMNode> GetStartNode(nsIDOMSelection *aSelection);
nsresult IsPreformatted(nsCOMPtr<nsIDOMNode> aNode, PRBool *aResult);
// data
static nsIAtom *sAAtom;
static nsIAtom *sAddressAtom;
static nsIAtom *sBigAtom;
static nsIAtom *sBlinkAtom;
static nsIAtom *sBAtom;
static nsIAtom *sCiteAtom;
static nsIAtom *sCodeAtom;
static nsIAtom *sDfnAtom;
static nsIAtom *sEmAtom;
static nsIAtom *sFontAtom;
static nsIAtom *sIAtom;
static nsIAtom *sKbdAtom;
static nsIAtom *sKeygenAtom;
static nsIAtom *sNobrAtom;
static nsIAtom *sSAtom;
static nsIAtom *sSampAtom;
static nsIAtom *sSmallAtom;
static nsIAtom *sSpacerAtom;
static nsIAtom *sSpanAtom;
static nsIAtom *sStrikeAtom;
static nsIAtom *sStrongAtom;
static nsIAtom *sSubAtom;
static nsIAtom *sSupAtom;
static nsIAtom *sTtAtom;
static nsIAtom *sUAtom;
static nsIAtom *sVarAtom;
static nsIAtom *sWbrAtom;
static PRInt32 sInstanceCount;
};
#endif //nsHTMLEditRules_h__

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

@ -147,7 +147,8 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->WillDoAction(nsHTMLEditRules::kInsertBreak, selection, nsnull, &cancel);
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertBreak);
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
// create the new BR node
@ -197,7 +198,7 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
}
}
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
result = mRules->DidDoAction(nsHTMLEditRules::kInsertBreak, selection, nsnull, result);
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");

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

@ -125,16 +125,24 @@ nsTextEditRules::Init(nsIEditor *aEditor)
}
NS_IMETHODIMP
nsTextEditRules::WillDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, PRBool *aCancel)
nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, PRBool *aCancel)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (aAction)
switch (info->action)
{
case kInsertText:
return WillInsertText(aSelection, aCancel, (PlaceholderTxn**)aOtherInfo);
return WillInsertText(aSelection,
aCancel,
info->placeTxn,
info->inString,
info->outString,
info->typeInState);
case kDeleteSelection:
return WillDeleteSelection(aSelection, aCancel);
case kUndo:
@ -146,13 +154,16 @@ nsTextEditRules::WillDoAction(int aAction, nsIDOMSelection *aSelection,
}
NS_IMETHODIMP
nsTextEditRules::DidDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, nsresult aResult)
nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, nsresult aResult)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
switch (aAction)
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (info->action)
{
case kInsertText:
return DidInsertText(aSelection, aResult);
@ -172,7 +183,7 @@ nsTextEditRules::DidDoAction(int aAction, nsIDOMSelection *aSelection,
********************************************************/
NS_IMETHODIMP
nsresult
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -191,21 +202,23 @@ nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
{
return NS_OK;
}
NS_IMETHODIMP
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn)
nsresult
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
// initialize out param
*aCancel = PR_FALSE;
TypeInState typeInState = mEditor->GetTypeInState();
if (mBogusNode || (PR_TRUE==typeInState.IsAnySet()))
{
nsresult result = TransactionFactory::GetNewTransaction(kPlaceholderTxnIID, (EditTxn **)aTxn);
@ -225,14 +238,14 @@ nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::DidInsertText(nsIDOMSelection *aSelection,
nsresult aResult)
{
return DidInsert(aSelection, aResult);
}
NS_IMETHODIMP
nsresult
nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState)
{
// private method, we know aSelection is not null, and that it is collapsed
@ -356,7 +369,7 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
{
NS_ASSERTION(aNode && aTag, "bad args");
@ -388,7 +401,7 @@ nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelecti
}
NS_IMETHODIMP
nsresult
nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
{
NS_ASSERTION(aParentNode && aTag, "bad args");
@ -433,7 +446,7 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
/*
NS_IMETHODIMP
nsresult
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
{
if (!aTag) { return NS_ERROR_NULL_POINTER; }
@ -442,7 +455,7 @@ nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
}
*/
NS_IMETHODIMP
nsresult
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -459,7 +472,7 @@ nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCance
// if the document is empty, insert a bogus text node with a &nbsp;
// if we ended up with consecutive text nodes, merge them
NS_IMETHODIMP
nsresult
nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we just return it
@ -600,7 +613,7 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -614,7 +627,7 @@ nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
* There is a tradeoff between doing here and at redo, or doing it everywhere else that might care.
* Since undo and redo are relatively rare, it makes sense to take the (small) performance hit here.
*/
NS_IMETHODIMP
nsresult
nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.
@ -651,7 +664,7 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -660,7 +673,7 @@ nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.

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

@ -48,8 +48,8 @@ public:
// nsEditRules methods
NS_IMETHOD Init(nsIEditor *aEditor);
NS_IMETHOD WillDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, nsresult aResult);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
// nsTextEditRules action id's
enum
@ -63,23 +63,26 @@ public:
protected:
// nsTextEditRules implementation methods
NS_IMETHOD WillInsertText(nsIDOMSelection *aSelection,
nsresult WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn);
NS_IMETHOD DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState);
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
nsresult CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
NS_IMETHOD WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidInsert(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidInsert(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidUndo(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidUndo(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidRedo(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidRedo(nsIDOMSelection *aSelection, nsresult aResult);
// helper functions
static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag);
@ -89,7 +92,7 @@ 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,
nsresult InsertStyleNode(nsIDOMNode *aNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
@ -99,7 +102,7 @@ protected:
* aSelection is optional. If provided, aSelection is set to (newTextNode, 0)
* if newTextNode was successfully created.
*/
NS_IMETHOD InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
nsresult InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
@ -108,5 +111,21 @@ protected:
nsCOMPtr<nsIDOMNode> mBogusNode; // magic node acts as placeholder in empty doc
};
class nsTextRulesInfo : public nsRulesInfo
{
public:
nsTextRulesInfo(int aAction) : nsRulesInfo(aAction),placeTxn(0),inString(0),outString(0),typeInState() {}
virtual ~nsTextRulesInfo() {}
// used by kInsertText
PlaceholderTxn **placeTxn;
const nsString *inString;
nsString *outString;
TypeInState typeInState;
};
#endif //nsTextEditRules_h__

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

@ -705,12 +705,13 @@ NS_IMETHODIMP nsTextEditor::DeleteSelection(nsIEditor::Direction aDir)
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->WillDoAction(nsTextEditRules::kDeleteSelection, selection, nsnull, &cancel);
nsTextRulesInfo ruleInfo(nsTextEditRules::kDeleteSelection);
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
result = nsEditor::DeleteSelection(aDir);
// post-process
result = mRules->DidDoAction(nsTextEditRules::kDeleteSelection, selection, nsnull, result);
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
@ -736,13 +737,20 @@ NS_IMETHODIMP nsTextEditor::InsertText(const nsString& aStringToInsert)
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
nsString resultString;
PlaceholderTxn *placeholderTxn=nsnull;
nsresult result = mRules->WillDoAction(nsTextEditRules::kInsertText, selection, (void**)&placeholderTxn, &cancel);
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertText);
ruleInfo.placeTxn = &placeholderTxn;
ruleInfo.inString = &aStringToInsert;
ruleInfo.outString = &resultString;
ruleInfo.typeInState = mTypeInState;
nsresult result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
result = nsEditor::InsertText(aStringToInsert);
// post-process
result = mRules->DidDoAction(nsTextEditRules::kInsertText, selection, nsnull, result);
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
if (placeholderTxn)
placeholderTxn->SetAbsorb(PR_FALSE); // this ends the merging of txns into placeholderTxn
@ -774,12 +782,13 @@ NS_IMETHODIMP nsTextEditor::Undo(PRUint32 aCount)
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
nsresult result = mRules->WillDoAction(nsTextEditRules::kUndo, selection, nsnull, &cancel);
nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo);
nsresult result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
result = nsEditor::Undo(aCount);
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->DidDoAction(nsTextEditRules::kUndo, selection, nsnull, result);
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
return result;
}
@ -796,12 +805,13 @@ NS_IMETHODIMP nsTextEditor::Redo(PRUint32 aCount)
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
nsresult result = mRules->WillDoAction(nsTextEditRules::kRedo, selection, nsnull, &cancel);
nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo);
nsresult result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
result = nsEditor::Redo(aCount);
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->DidDoAction(nsTextEditRules::kRedo, selection, nsnull, result);
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
return result;
}

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

@ -22,15 +22,30 @@
class nsIEditor;
class nsIDOMSelection;
/** Interface of editing rules.
*
*/
/***************************************************************************
* base for an object to encapsulate any additional info needed to be passed
* to rules system by the editor
*/
class nsRulesInfo
{
public:
nsRulesInfo(int aAction) : action(aAction) {}
virtual ~nsRulesInfo() {}
int action;
};
/***************************************************************************
* Interface of editing rules.
*
*/
class nsEditRules
{
public:
NS_IMETHOD Init(nsIEditor *aEditor)=0;
NS_IMETHOD WillDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, PRBool *aCancel)=0;
NS_IMETHOD DidDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, nsresult aResult)=0;
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel)=0;
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
};

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

@ -20,7 +20,6 @@
#include "nsEditor.h"
#include "PlaceholderTxn.h"
#include "InsertTextTxn.h"
#include "nsCOMPtr.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIDOMNodeList.h"
@ -35,16 +34,110 @@ const static char* kMOZEditorBogusNodeValue="TRUE";
static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
nsIAtom *nsHTMLEditRules::sAAtom;
nsIAtom *nsHTMLEditRules::sAddressAtom;
nsIAtom *nsHTMLEditRules::sBigAtom;
nsIAtom *nsHTMLEditRules::sBlinkAtom;
nsIAtom *nsHTMLEditRules::sBAtom;
nsIAtom *nsHTMLEditRules::sCiteAtom;
nsIAtom *nsHTMLEditRules::sCodeAtom;
nsIAtom *nsHTMLEditRules::sDfnAtom;
nsIAtom *nsHTMLEditRules::sEmAtom;
nsIAtom *nsHTMLEditRules::sFontAtom;
nsIAtom *nsHTMLEditRules::sIAtom;
nsIAtom *nsHTMLEditRules::sKbdAtom;
nsIAtom *nsHTMLEditRules::sKeygenAtom;
nsIAtom *nsHTMLEditRules::sNobrAtom;
nsIAtom *nsHTMLEditRules::sSAtom;
nsIAtom *nsHTMLEditRules::sSampAtom;
nsIAtom *nsHTMLEditRules::sSmallAtom;
nsIAtom *nsHTMLEditRules::sSpacerAtom;
nsIAtom *nsHTMLEditRules::sSpanAtom;
nsIAtom *nsHTMLEditRules::sStrikeAtom;
nsIAtom *nsHTMLEditRules::sStrongAtom;
nsIAtom *nsHTMLEditRules::sSubAtom;
nsIAtom *nsHTMLEditRules::sSupAtom;
nsIAtom *nsHTMLEditRules::sTtAtom;
nsIAtom *nsHTMLEditRules::sUAtom;
nsIAtom *nsHTMLEditRules::sVarAtom;
nsIAtom *nsHTMLEditRules::sWbrAtom;
PRInt32 nsHTMLEditRules::sInstanceCount;
/********************************************************
* Constructor/Destructor
********************************************************/
nsHTMLEditRules::nsHTMLEditRules()
{
if (sInstanceCount <= 0)
{
sAAtom = NS_NewAtom("a");
sAddressAtom = NS_NewAtom("address");
sBigAtom = NS_NewAtom("big");
sBlinkAtom = NS_NewAtom("blink");
sBAtom = NS_NewAtom("b");
sCiteAtom = NS_NewAtom("cite");
sCodeAtom = NS_NewAtom("code");
sDfnAtom = NS_NewAtom("dfn");
sEmAtom = NS_NewAtom("em");
sFontAtom = NS_NewAtom("font");
sIAtom = NS_NewAtom("i");
sKbdAtom = NS_NewAtom("kbd");
sKeygenAtom = NS_NewAtom("keygen");
sNobrAtom = NS_NewAtom("nobr");
sSAtom = NS_NewAtom("s");
sSampAtom = NS_NewAtom("samp");
sSmallAtom = NS_NewAtom("small");
sSpacerAtom = NS_NewAtom("spacer");
sSpanAtom = NS_NewAtom("span");
sStrikeAtom = NS_NewAtom("strike");
sStrongAtom = NS_NewAtom("strong");
sSubAtom = NS_NewAtom("sub");
sSupAtom = NS_NewAtom("sup");
sTtAtom = NS_NewAtom("tt");
sUAtom = NS_NewAtom("u");
sVarAtom = NS_NewAtom("var");
sWbrAtom = NS_NewAtom("wbr");
}
++sInstanceCount;
}
nsHTMLEditRules::~nsHTMLEditRules()
{
if (sInstanceCount <= 1)
{
NS_IF_RELEASE(sAAtom);
NS_IF_RELEASE(sAddressAtom);
NS_IF_RELEASE(sBigAtom);
NS_IF_RELEASE(sBlinkAtom);
NS_IF_RELEASE(sBAtom);
NS_IF_RELEASE(sCiteAtom);
NS_IF_RELEASE(sCodeAtom);
NS_IF_RELEASE(sDfnAtom);
NS_IF_RELEASE(sEmAtom);
NS_IF_RELEASE(sFontAtom);
NS_IF_RELEASE(sIAtom);
NS_IF_RELEASE(sKbdAtom);
NS_IF_RELEASE(sKeygenAtom);
NS_IF_RELEASE(sNobrAtom);
NS_IF_RELEASE(sSAtom);
NS_IF_RELEASE(sSampAtom);
NS_IF_RELEASE(sSmallAtom);
NS_IF_RELEASE(sSpacerAtom);
NS_IF_RELEASE(sSpanAtom);
NS_IF_RELEASE(sStrikeAtom);
NS_IF_RELEASE(sStrongAtom);
NS_IF_RELEASE(sSubAtom);
NS_IF_RELEASE(sSupAtom);
NS_IF_RELEASE(sTtAtom);
NS_IF_RELEASE(sUAtom);
NS_IF_RELEASE(sVarAtom);
NS_IF_RELEASE(sWbrAtom);
}
--sInstanceCount;
}
@ -53,40 +146,94 @@ nsHTMLEditRules::~nsHTMLEditRules()
********************************************************/
NS_IMETHODIMP
nsHTMLEditRules::WillDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, PRBool *aCancel)
nsHTMLEditRules::WillDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, PRBool *aCancel)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
switch (aAction)
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (info->action)
{
case kInsertText:
return WillInsertText(aSelection,
aCancel,
info->placeTxn,
info->inString,
info->outString,
info->typeInState);
case kInsertBreak:
return WillInsertBreak(aSelection, aCancel);
}
return nsTextEditRules::WillDoAction(aAction, aSelection, aOtherInfo, aCancel);
return nsTextEditRules::WillDoAction(aSelection, aInfo, aCancel);
}
NS_IMETHODIMP
nsHTMLEditRules::DidDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, nsresult aResult)
nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, nsresult aResult)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
switch (aAction)
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (info->action)
{
case kInsertText:
return DidInsertText(aSelection, aResult);
case kInsertBreak:
return DidInsertBreak(aSelection, aResult);
}
return nsTextEditRules::DidDoAction(aAction, aSelection, aOtherInfo, aResult);
return nsTextEditRules::DidDoAction(aSelection, aInfo, aResult);
}
/********************************************************
* Protected methods
* Protected rules methods
********************************************************/
NS_IMETHODIMP
nsresult
nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
// initialize out param
*aCancel = PR_FALSE;
// XXX - need to handle strings of length >1 with embedded tabs or spaces
// is it a tab?
if (*inString == "\t" )
return InsertTab(aSelection,aCancel,aTxn,outString);
// is it a space?
if (*inString == " ")
return InsertSpace(aSelection,aCancel,aTxn,outString);
// otherwise, return nsTextEditRules version
return nsTextEditRules::WillInsertText(aSelection,
aCancel,
aTxn,
inString,
outString,
typeInState);
}
nsresult
nsHTMLEditRules::DidInsertText(nsIDOMSelection *aSelection,
nsresult aResult)
{
// for now, return nsTextEditRules version
return nsTextEditRules::DidInsertText(aSelection, aResult);
}
nsresult
nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -97,7 +244,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
// XXX: this code is all experimental, and has no effect on the content model yet
// the point here is to collapse adjacent BR's into P's
NS_IMETHODIMP
nsresult
nsHTMLEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.
@ -196,3 +343,153 @@ nsHTMLEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
}
return result;
}
/********************************************************
* helper methods
********************************************************/
PRBool
nsHTMLEditRules::IsBlockNode(nsIContent *aContent)
{
nsIAtom* atom = nsnull;
PRBool result;
aContent->GetTag(atom);
if (!atom)
return PR_TRUE;
if (sAAtom != atom &&
sAddressAtom != atom &&
sBigAtom != atom &&
sBlinkAtom != atom &&
sBAtom != atom &&
sCiteAtom != atom &&
sCodeAtom != atom &&
sDfnAtom != atom &&
sEmAtom != atom &&
sFontAtom != atom &&
sIAtom != atom &&
sKbdAtom != atom &&
sKeygenAtom != atom &&
sNobrAtom != atom &&
sSAtom != atom &&
sSampAtom != atom &&
sSmallAtom != atom &&
sSpacerAtom != atom &&
sSpanAtom != atom &&
sStrikeAtom != atom &&
sStrongAtom != atom &&
sSubAtom != atom &&
sSupAtom != atom &&
sTtAtom != atom &&
sUAtom != atom &&
sVarAtom != atom &&
sWbrAtom != atom)
{
result = PR_TRUE;
}
else
{
result = PR_FALSE;
}
NS_RELEASE(atom);
return result;
}
nsCOMPtr<nsIContent>
nsHTMLEditRules::GetBlockNodeParent(nsCOMPtr<nsIContent> aContent)
{
nsCOMPtr<nsIContent> p;
if (NS_FAILED(aContent->GetParent(*getter_AddRefs(p)))) // no parent, ran off top of tree
return aContent;
nsCOMPtr<nsIContent> tmp;
while (p && !IsBlockNode(p))
{
if (NS_FAILED(p->GetParent(*getter_AddRefs(tmp)))) // no parent, ran off top of tree
return p;
p = tmp;
}
return p;
}
///////////////////////////////////////////////////////////////////////////
// GetStartNode: returns whatever the start parent is of the first range
// in the selection.
nsCOMPtr<nsIDOMNode>
nsHTMLEditRules::GetStartNode(nsIDOMSelection *aSelection)
{
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIEnumerator> enumerator;
enumerator = do_QueryInterface(aSelection);
if (!enumerator)
return startNode;
enumerator->First();
nsISupports *currentItem;
if ((NS_FAILED(enumerator->CurrentItem(&currentItem))) || !currentItem)
return startNode;
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
if (!range)
return startNode;
range->GetStartParent(getter_AddRefs(startNode));
return startNode;
}
///////////////////////////////////////////////////////////////////////////
// IsPreformatted: checks the style info for the node for the preformatted
// text style.
nsresult
nsHTMLEditRules::IsPreformatted(nsCOMPtr<nsIDOMNode> aNode, PRBool *aResult)
{
return PR_TRUE;
}
nsresult
nsHTMLEditRules::InsertTab(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
nsString *outString)
{
nsCOMPtr<nsIDOMNode> theNode;
PRBool isPRE;
theNode = GetStartNode(aSelection);
if (!theNode)
return NS_ERROR_UNEXPECTED;
nsresult result = IsPreformatted(theNode,&isPRE);
if (NS_FAILED(result))
return result;
if (isPRE)
{
outString += '\t';
// we're done - let everything fall through to the InsertText code
// in nsTextEditor which will insert the tab as is.
}
else
{
}
return NS_OK;
}
nsresult
nsHTMLEditRules::InsertSpace(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
nsString *outString)
{
return NS_OK;
}

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

@ -20,6 +20,9 @@
#define nsHTMLEditRules_h__
#include "nsTextEditRules.h"
#include "nsCOMPtr.h"
class nsIContent;
class nsHTMLEditRules : public nsTextEditRules
{
@ -29,8 +32,8 @@ public:
virtual ~nsHTMLEditRules();
// nsEditRules methods
NS_IMETHOD WillDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, nsresult aResult);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
// nsHTMLEditRules action id's
enum
@ -40,9 +43,56 @@ public:
protected:
// nsHTMLEditRules implementation methods
NS_IMETHOD WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState);
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
nsresult InsertTab(nsIDOMSelection *aSelection, PRBool *aCancel, PlaceholderTxn **aTxn, nsString *outString);
nsresult InsertSpace(nsIDOMSelection *aSelection, PRBool *aCancel, PlaceholderTxn **aTxn, nsString *outString);
// helper methods
PRBool IsBlockNode(nsIContent *aContent);
nsCOMPtr<nsIContent> GetBlockNodeParent(nsCOMPtr<nsIContent> aContent);
nsCOMPtr<nsIDOMNode> GetStartNode(nsIDOMSelection *aSelection);
nsresult IsPreformatted(nsCOMPtr<nsIDOMNode> aNode, PRBool *aResult);
// data
static nsIAtom *sAAtom;
static nsIAtom *sAddressAtom;
static nsIAtom *sBigAtom;
static nsIAtom *sBlinkAtom;
static nsIAtom *sBAtom;
static nsIAtom *sCiteAtom;
static nsIAtom *sCodeAtom;
static nsIAtom *sDfnAtom;
static nsIAtom *sEmAtom;
static nsIAtom *sFontAtom;
static nsIAtom *sIAtom;
static nsIAtom *sKbdAtom;
static nsIAtom *sKeygenAtom;
static nsIAtom *sNobrAtom;
static nsIAtom *sSAtom;
static nsIAtom *sSampAtom;
static nsIAtom *sSmallAtom;
static nsIAtom *sSpacerAtom;
static nsIAtom *sSpanAtom;
static nsIAtom *sStrikeAtom;
static nsIAtom *sStrongAtom;
static nsIAtom *sSubAtom;
static nsIAtom *sSupAtom;
static nsIAtom *sTtAtom;
static nsIAtom *sUAtom;
static nsIAtom *sVarAtom;
static nsIAtom *sWbrAtom;
static PRInt32 sInstanceCount;
};
#endif //nsHTMLEditRules_h__

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

@ -147,7 +147,8 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
// pre-process
nsEditor::GetSelection(getter_AddRefs(selection));
result = mRules->WillDoAction(nsHTMLEditRules::kInsertBreak, selection, nsnull, &cancel);
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertBreak);
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
{
// create the new BR node
@ -197,7 +198,7 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
}
}
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
result = mRules->DidDoAction(nsHTMLEditRules::kInsertBreak, selection, nsnull, result);
result = mRules->DidDoAction(selection, &ruleInfo, result);
}
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");

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

@ -125,16 +125,24 @@ nsTextEditRules::Init(nsIEditor *aEditor)
}
NS_IMETHODIMP
nsTextEditRules::WillDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, PRBool *aCancel)
nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, PRBool *aCancel)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (aAction)
switch (info->action)
{
case kInsertText:
return WillInsertText(aSelection, aCancel, (PlaceholderTxn**)aOtherInfo);
return WillInsertText(aSelection,
aCancel,
info->placeTxn,
info->inString,
info->outString,
info->typeInState);
case kDeleteSelection:
return WillDeleteSelection(aSelection, aCancel);
case kUndo:
@ -146,13 +154,16 @@ nsTextEditRules::WillDoAction(int aAction, nsIDOMSelection *aSelection,
}
NS_IMETHODIMP
nsTextEditRules::DidDoAction(int aAction, nsIDOMSelection *aSelection,
void **aOtherInfo, nsresult aResult)
nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection,
nsRulesInfo *aInfo, nsresult aResult)
{
if (!aSelection)
if (!aSelection || !aInfo)
return NS_ERROR_NULL_POINTER;
switch (aAction)
// my kingdom for dynamic cast
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
switch (info->action)
{
case kInsertText:
return DidInsertText(aSelection, aResult);
@ -172,7 +183,7 @@ nsTextEditRules::DidDoAction(int aAction, nsIDOMSelection *aSelection,
********************************************************/
NS_IMETHODIMP
nsresult
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -191,21 +202,23 @@ nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
{
return NS_OK;
}
NS_IMETHODIMP
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn)
nsresult
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
// initialize out param
*aCancel = PR_FALSE;
TypeInState typeInState = mEditor->GetTypeInState();
if (mBogusNode || (PR_TRUE==typeInState.IsAnySet()))
{
nsresult result = TransactionFactory::GetNewTransaction(kPlaceholderTxnIID, (EditTxn **)aTxn);
@ -225,14 +238,14 @@ nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::DidInsertText(nsIDOMSelection *aSelection,
nsresult aResult)
{
return DidInsert(aSelection, aResult);
}
NS_IMETHODIMP
nsresult
nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState)
{
// private method, we know aSelection is not null, and that it is collapsed
@ -356,7 +369,7 @@ nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInSta
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
{
NS_ASSERTION(aNode && aTag, "bad args");
@ -388,7 +401,7 @@ nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelecti
}
NS_IMETHODIMP
nsresult
nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
{
NS_ASSERTION(aParentNode && aTag, "bad args");
@ -433,7 +446,7 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
/*
NS_IMETHODIMP
nsresult
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
{
if (!aTag) { return NS_ERROR_NULL_POINTER; }
@ -442,7 +455,7 @@ nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
}
*/
NS_IMETHODIMP
nsresult
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -459,7 +472,7 @@ nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCance
// if the document is empty, insert a bogus text node with a &nbsp;
// if we ended up with consecutive text nodes, merge them
NS_IMETHODIMP
nsresult
nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we just return it
@ -600,7 +613,7 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -614,7 +627,7 @@ nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
* There is a tradeoff between doing here and at redo, or doing it everywhere else that might care.
* Since undo and redo are relatively rare, it makes sense to take the (small) performance hit here.
*/
NS_IMETHODIMP
nsresult
nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.
@ -651,7 +664,7 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
return result;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
{
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
@ -660,7 +673,7 @@ nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
{
nsresult result = aResult; // if aResult is an error, we return it.

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

@ -48,8 +48,8 @@ public:
// nsEditRules methods
NS_IMETHOD Init(nsIEditor *aEditor);
NS_IMETHOD WillDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(int aAction, nsIDOMSelection *aSelection, void **aOtherInfo, nsresult aResult);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
// nsTextEditRules action id's
enum
@ -63,23 +63,26 @@ public:
protected:
// nsTextEditRules implementation methods
NS_IMETHOD WillInsertText(nsIDOMSelection *aSelection,
nsresult WillInsertText(nsIDOMSelection *aSelection,
PRBool *aCancel,
PlaceholderTxn **aTxn);
NS_IMETHOD DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
PlaceholderTxn **aTxn,
const nsString *inString,
nsString *outString,
TypeInState typeInState);
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
nsresult CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
NS_IMETHOD WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidInsert(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidInsert(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidUndo(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidUndo(nsIDOMSelection *aSelection, nsresult aResult);
NS_IMETHOD WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel);
NS_IMETHOD DidRedo(nsIDOMSelection *aSelection, nsresult aResult);
nsresult WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel);
nsresult DidRedo(nsIDOMSelection *aSelection, nsresult aResult);
// helper functions
static PRBool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag);
@ -89,7 +92,7 @@ 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,
nsresult InsertStyleNode(nsIDOMNode *aNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
@ -99,7 +102,7 @@ protected:
* aSelection is optional. If provided, aSelection is set to (newTextNode, 0)
* if newTextNode was successfully created.
*/
NS_IMETHOD InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
nsresult InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
nsIAtom *aTag,
nsIDOMSelection *aSelection);
@ -108,5 +111,21 @@ protected:
nsCOMPtr<nsIDOMNode> mBogusNode; // magic node acts as placeholder in empty doc
};
class nsTextRulesInfo : public nsRulesInfo
{
public:
nsTextRulesInfo(int aAction) : nsRulesInfo(aAction),placeTxn(0),inString(0),outString(0),typeInState() {}
virtual ~nsTextRulesInfo() {}
// used by kInsertText
PlaceholderTxn **placeTxn;
const nsString *inString;
nsString *outString;
TypeInState typeInState;
};
#endif //nsTextEditRules_h__