XIF DTD now depends on a single stack rather than
multiple stacks. r=akkana Moved Node recycling to DTD Utils so that the recycler could be used across DTDs. r=rickg Also fixed bug 27136. git-svn-id: svn://10.0.0.236/trunk@66309 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
aab7fba560
commit
9cd3c6e67f
@ -165,68 +165,14 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
||||
InitializeElementTable();
|
||||
}
|
||||
|
||||
mNodeRecycler=0;
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
//DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules");
|
||||
nsHTMLElement::DebugDumpContainment("c:/temp/contain.new","ElementTable Rules");
|
||||
nsHTMLElement::DebugDumpMembership("c:/temp/membership.out");
|
||||
nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out");
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
gNodeCount=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates a new parser node. It tries to get one from
|
||||
* the recycle list before allocating a new one.
|
||||
* @update gess1/8/99
|
||||
* @param
|
||||
* @return valid node*
|
||||
*/
|
||||
|
||||
nsCParserNode* CNavDTD::CreateNode(void) {
|
||||
|
||||
nsCParserNode* result=0;
|
||||
if(0<mSharedNodes.GetSize()) {
|
||||
result=(nsCParserNode*)mSharedNodes.Pop();
|
||||
}
|
||||
else{
|
||||
result=new nsCParserNode();
|
||||
#ifdef NS_DEBUG
|
||||
#if 1
|
||||
gNodeCount++;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method recycles a given node
|
||||
* @update gess1/8/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void CNavDTD::RecycleNode(nsCParserNode* aNode) {
|
||||
if(aNode && (!aNode->mUseCount)) {
|
||||
|
||||
if(aNode->mToken) {
|
||||
if(!aNode->mToken->mUseCount) {
|
||||
mTokenRecycler->RecycleToken(aNode->mToken);
|
||||
}
|
||||
}
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
if(!theToken->mUseCount) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
}
|
||||
|
||||
mSharedNodes.Push(aNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,26 +236,7 @@ CNavDTD::~CNavDTD(){
|
||||
if(mTempContext)
|
||||
delete mTempContext;
|
||||
|
||||
nsCParserNode* theNode=0;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#if 0
|
||||
PRInt32 count=gNodeCount-mSharedNodes.GetSize();
|
||||
if(count) {
|
||||
printf("%i of %i nodes leaked!\n",count,gNodeCount);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
while((theNode=(nsCParserNode*)mSharedNodes.Pop())){
|
||||
delete theNode;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
gNodeCount=0;
|
||||
#endif
|
||||
// delete mNodeRecycler;
|
||||
|
||||
NS_IF_RELEASE(mSink);
|
||||
NS_IF_RELEASE(mDTDDebug);
|
||||
@ -470,6 +397,8 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
|
||||
* @return error code (almost always NS_OK)
|
||||
*/
|
||||
nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
|
||||
NS_PRECONDITION(mBodyContext!=nsnull,"Create a context before calling build model");
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aTokenizer) {
|
||||
@ -480,6 +409,11 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
result=mBodyContext->GetNodeRecycler(mNodeRecycler); // Get a copy...
|
||||
|
||||
if(NS_FAILED(result)) return result;
|
||||
|
||||
if(mSink) {
|
||||
|
||||
if(!mBodyContext->GetCount()) {
|
||||
@ -579,7 +513,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
nsEntryStack *theChildStyles=0;
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
|
||||
theNode->mUseCount=0;
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
@ -1319,7 +1253,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
theNode->Init(aToken,mLineNumber,mTokenRecycler);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
@ -1431,7 +1365,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
}//if
|
||||
} //if
|
||||
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1790,7 +1724,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
nsresult result=NS_OK;
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
|
||||
@ -1805,7 +1739,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
#endif
|
||||
|
||||
result=AddLeaf(theNode);
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1828,7 +1762,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
nsString& theComment=aToken->GetStringValueXXX();
|
||||
mLineNumber += (theComment).CountChar(kNewLine);
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
|
||||
@ -1841,7 +1775,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
|
||||
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -1905,7 +1839,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
|
||||
@ -1918,7 +1852,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
|
||||
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -1954,7 +1888,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
}
|
||||
docTypeStr.Cut(0,2); // Now remove "<!" from the begining
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
|
||||
@ -1962,7 +1896,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
|
||||
result = (mSink)? mSink->AddDocTypeDecl(*theNode,mParseMode):NS_OK;
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2459,7 +2393,7 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
|
||||
//if the node tag can't contain the child tag, then remove the child tag from the style stack
|
||||
nsCParserNode* theRemovedNode=(nsCParserNode*)theStack->Remove(sindex,theNodeTag);
|
||||
if(theRemovedNode) {
|
||||
RecycleNode(theRemovedNode);
|
||||
mNodeRecycler->RecycleNode(theRemovedNode,mTokenRecycler);
|
||||
}
|
||||
theEntry--; //back up by one
|
||||
}
|
||||
@ -2529,7 +2463,7 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->PopStyle(aTag);
|
||||
if(theNode) {
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3197,7 +3131,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
}
|
||||
#endif
|
||||
}//if anode
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -106,6 +106,7 @@ class nsEntryStack;
|
||||
class nsITokenizer;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class CNodeRecycler;
|
||||
|
||||
/***************************************************************
|
||||
Now the main event: CNavDTD.
|
||||
@ -483,8 +484,6 @@ protected:
|
||||
nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
|
||||
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode *aNode);
|
||||
nsresult HandleSavedTokens(PRInt32 anIndex);
|
||||
nsCParserNode* CreateNode(void);
|
||||
void RecycleNode(nsCParserNode* aNode);
|
||||
void RecycleNodes(nsEntryStack *aNodeStack);
|
||||
|
||||
nsIHTMLContentSink* mSink;
|
||||
@ -507,6 +506,7 @@ protected:
|
||||
nsParser* mParser;
|
||||
nsITokenizer* mTokenizer;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsDeque mMisplacedContent;
|
||||
nsDeque mSkippedContent;
|
||||
PRBool mHasOpenScript;
|
||||
@ -526,10 +526,6 @@ protected:
|
||||
PRBool mIsFormContainer;
|
||||
nsAutoString mMimeType;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 gNodeCount;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
inline nsresult NS_NewNavHTMLDTD(nsIDTD** aInstancePtrResult)
|
||||
|
||||
@ -33,8 +33,10 @@
|
||||
MOZ_DECL_CTOR_COUNTER(nsEntryStack);
|
||||
MOZ_DECL_CTOR_COUNTER(nsDTDContext);
|
||||
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CNodeRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
A few notes about how residual style handling is performed:
|
||||
|
||||
@ -373,7 +375,7 @@ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const {
|
||||
/***************************************************************
|
||||
Now define the dtdcontext class
|
||||
***************************************************************/
|
||||
|
||||
CNodeRecycler* nsDTDContext::mNodeRecycler=0;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -454,6 +456,15 @@ nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/07/00
|
||||
*/
|
||||
|
||||
nsIParserNode* nsDTDContext::Pop() {
|
||||
nsEntryStack *theTempStyleStack=0; // This has no use here...
|
||||
return Pop(theTempStyleStack);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@ -640,6 +651,30 @@ nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/10/00
|
||||
*/
|
||||
nsresult nsDTDContext::GetNodeRecycler(CNodeRecycler*& aNodeRecycler){
|
||||
nsresult result=NS_OK;
|
||||
if(!mNodeRecycler) {
|
||||
mNodeRecycler=new CNodeRecycler();
|
||||
if(mNodeRecycler==0) result=NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aNodeRecycler=mNodeRecycler;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update hairshd 04/10/00
|
||||
*/
|
||||
void nsDTDContext::FreeNodeRecycler(){
|
||||
if(mNodeRecycler) {
|
||||
delete mNodeRecycler;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Now define the tokenrecycler class...
|
||||
**************************************************************/
|
||||
@ -801,6 +836,75 @@ CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag)
|
||||
return result;
|
||||
}
|
||||
|
||||
CNodeRecycler::CNodeRecycler(): mSharedNodes(0) {
|
||||
|
||||
MOZ_COUNT_CTOR(CTokenRecycler);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
gNodeCount=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
CNodeRecycler::~CNodeRecycler() {
|
||||
|
||||
MOZ_COUNT_DTOR(CTokenRecycler);
|
||||
|
||||
nsCParserNode* theNode=0;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#if 0
|
||||
PRInt32 count=gNodeCount-mSharedNodes.GetSize();
|
||||
if(count) {
|
||||
printf("%i of %i nodes leaked!\n",count,gNodeCount);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while((theNode=(nsCParserNode*)mSharedNodes.Pop())){
|
||||
delete theNode;
|
||||
}
|
||||
}
|
||||
|
||||
void CNodeRecycler::RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler) {
|
||||
|
||||
if(aNode && (!aNode->mUseCount)) {
|
||||
|
||||
// If the node contains tokens there better me a token recycler..
|
||||
if(aTokenRecycler) {
|
||||
if(aNode->mToken) {
|
||||
if(!aNode->mToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(aNode->mToken);
|
||||
}
|
||||
}
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
if(!theToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
mSharedNodes.Push(aNode);
|
||||
}
|
||||
}
|
||||
|
||||
nsCParserNode* CNodeRecycler::CreateNode(void) {
|
||||
|
||||
nsCParserNode* result=0;
|
||||
if(0<mSharedNodes.GetSize()) {
|
||||
result=(nsCParserNode*)mSharedNodes.Pop();
|
||||
}
|
||||
else{
|
||||
result=new nsCParserNode();
|
||||
#ifdef NS_DEBUG
|
||||
#if 1
|
||||
gNodeCount++;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) {
|
||||
#ifdef RICKG_DEBUG
|
||||
|
||||
|
||||
@ -41,8 +41,11 @@
|
||||
#include "nsITokenizer.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIElementObserver.h"
|
||||
#include "nsIParserNode.h"
|
||||
|
||||
class nsIParserNode;
|
||||
class nsCParserNode;
|
||||
class CNodeRecycler;
|
||||
|
||||
|
||||
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
|
||||
@ -138,6 +141,8 @@ public:
|
||||
|
||||
void Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
nsIParserNode* Pop(nsEntryStack*& aChildStack);
|
||||
nsIParserNode* Pop();
|
||||
nsIParserNode* PeekNode() { return mStack.NodeAt(mStack.mCount-1); }
|
||||
eHTMLTags First(void) const;
|
||||
eHTMLTags Last(void) const;
|
||||
nsTagEntry* LastEntry(void) const;
|
||||
@ -157,17 +162,21 @@ public:
|
||||
nsIParserNode* PopStyle(eHTMLTags aTag);
|
||||
nsIParserNode* RemoveStyle(eHTMLTags aTag);
|
||||
|
||||
nsresult GetNodeRecycler(CNodeRecycler*& aNodeRecycler);
|
||||
static void FreeNodeRecycler(void);
|
||||
|
||||
nsEntryStack mStack; //this will hold a list of tagentries...
|
||||
PRInt32 mResidualStyleCount;
|
||||
PRInt32 mContextTopIndex;
|
||||
|
||||
static CNodeRecycler* mNodeRecycler;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
enum { eMaxTags = 100 };
|
||||
eHTMLTags mXTags[eMaxTags];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Now define the token deallocator class...
|
||||
**************************************************************/
|
||||
@ -207,6 +216,29 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
CNodeRecycler class implementation.
|
||||
This class is used to recycle nodes.
|
||||
By using this simple class, we cut down on the number of nodes
|
||||
that get created during the run of the system.
|
||||
************************************************************************/
|
||||
|
||||
class CNodeRecycler {
|
||||
public:
|
||||
|
||||
CNodeRecycler();
|
||||
virtual ~CNodeRecycler();
|
||||
virtual nsCParserNode* CreateNode(void);
|
||||
virtual void RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler=0);
|
||||
|
||||
protected:
|
||||
nsDeque mSharedNodes;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 gNodeCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
ITagHandler class offers an API for taking care of specific tokens.
|
||||
************************************************************************/
|
||||
|
||||
@ -195,6 +195,7 @@ nsParserModule::Shutdown()
|
||||
nsXMLTokenizer::FreeTokenRecycler();
|
||||
nsExpatTokenizer::FreeTokenRecycler();
|
||||
// nsTextTokenizer::FreeTokenRecycler();
|
||||
nsDTDContext::FreeNodeRecycler();
|
||||
nsParser::FreeSharedObjects();
|
||||
mInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -48,6 +48,11 @@ class CTokenHandler;
|
||||
class nsIDTDDebug;
|
||||
class nsIHTMLContentSink;
|
||||
class nsITokenizer;
|
||||
class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class CNodeRecycler;
|
||||
|
||||
//*** This enum is used to define the known universe of XIF tags.
|
||||
//*** The use of this table doesn't preclude of from using non-standard
|
||||
@ -244,10 +249,6 @@ class nsXIFDTD : public nsIDTD {
|
||||
* --------------[ Sets DTD to STOP mode ]----------------
|
||||
* It's recommended to use this method in accordance with
|
||||
* the parser's terminate() method.
|
||||
*
|
||||
* @update harishd 07/22/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual nsresult Terminate(void);
|
||||
|
||||
@ -275,9 +276,6 @@ class nsXIFDTD : public nsIDTD {
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 12/1/99
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/
|
||||
virtual PRBool IsHTMLContainer(eHTMLTags aTag) const;
|
||||
|
||||
@ -296,52 +294,37 @@ class nsXIFDTD : public nsIDTD {
|
||||
/**
|
||||
* This method gets called when a start token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the start token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleStartToken(CToken* aToken);
|
||||
|
||||
/**
|
||||
* This method gets called when an end token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the end token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleEndToken(CToken* aToken);
|
||||
|
||||
/**
|
||||
* This method gets called when an entity token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the entity token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleEntityToken(CToken* aToken);
|
||||
|
||||
/**
|
||||
* This method gets called when a comment token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the comment token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleCommentToken(CToken* aToken);
|
||||
nsresult HandleCommentToken(CToken* aToken,nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* This method gets called when an attribute token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the attribute token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleAttributeToken(CToken* aToken);
|
||||
|
||||
nsresult HandleAttributeToken(CToken* aToken,nsIParserNode& aNode);
|
||||
|
||||
nsresult HandleWhiteSpaceToken(CToken* aToken);
|
||||
nsresult HandleTextToken(CToken* aToken);
|
||||
|
||||
nsresult HandleContainer(nsIParserNode& aNode);
|
||||
nsresult HandleDefaultToken(CToken* aToken,nsIParserNode& aNode);
|
||||
PRBool CanHandleDefaultTag(eXIFTags aTag, PRInt32& aIsContainer);
|
||||
|
||||
private:
|
||||
|
||||
@ -410,78 +393,65 @@ private:
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
eHTMLTags GetStartTag(const nsIParserNode& aNode, nsString& aName);
|
||||
|
||||
private:
|
||||
|
||||
void ProcessEncodeTag(const nsIParserNode& aNode);
|
||||
void ProcessEntityTag(const nsIParserNode& aNode);
|
||||
void ProcessDocumentInfoTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessEncodeTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessEntityTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessDocumentInfoTag(const nsIParserNode& aNode);
|
||||
|
||||
void BeginCSSStyleSheet(const nsIParserNode& aNode);
|
||||
void EndCSSStyleSheet(const nsIParserNode& aNode);
|
||||
nsresult BeginCSSStyleSheet(const nsIParserNode& aNode);
|
||||
nsresult EndCSSStyleSheet(const nsIParserNode& aNode);
|
||||
|
||||
void BeginCSSStyleRule(const nsIParserNode& aNode);
|
||||
void EndCSSStyleRule(const nsIParserNode& aNode);
|
||||
nsresult BeginCSSStyleRule(const nsIParserNode& aNode);
|
||||
nsresult EndCSSStyleRule(const nsIParserNode& aNode);
|
||||
|
||||
void AddCSSSelector(const nsIParserNode& aNode);
|
||||
void AddCSSDeclaration(const nsIParserNode& aNode);
|
||||
void BeginCSSDeclarationList(const nsIParserNode& aNode);
|
||||
void EndCSSDeclarationList(const nsIParserNode& aNode);
|
||||
|
||||
|
||||
void AddAttribute(nsIParserNode& aNode);
|
||||
void PushHTMLTag(const eHTMLTags aTag, const nsString& aName);
|
||||
void PopHTMLTag(eHTMLTags& aTag, nsString*& aName);
|
||||
nsresult AddCSSSelector(const nsIParserNode& aNode);
|
||||
nsresult AddCSSDeclaration(const nsIParserNode& aNode);
|
||||
nsresult BeginCSSDeclarationList(const nsIParserNode& aNode);
|
||||
nsresult EndCSSDeclarationList(const nsIParserNode& aNode);
|
||||
|
||||
PRBool GetAttributePair(nsIParserNode& aNode, nsString& aKey, nsString& aValue);
|
||||
PRBool GetAttribute(const nsIParserNode& aNode, const nsString& aKey, nsString& aValue);
|
||||
void BeginStartTag(const nsIParserNode& aNode);
|
||||
void AddEndTag(const nsIParserNode& aNode);
|
||||
void AddEndCommentTag(const nsIParserNode& aNode);
|
||||
|
||||
PRBool StartTopOfStack();
|
||||
nsIParserNode* PeekNode();
|
||||
CToken* PeekToken();
|
||||
void PushNodeAndToken(nsString& aName);
|
||||
void PopAndDelete();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
nsresult WillHandleToken(CToken* aToken,eHTMLTokenTypes& aType);
|
||||
nsresult DidHandleToken(CToken* aToken, nsresult aResult=NS_OK);
|
||||
nsresult WillHandleStartToken(CToken* aToken,eXIFTags aTag, nsIParserNode& aNode);
|
||||
nsresult DidHandleStartToken(CToken* aToken,eXIFTags aTag, nsIParserNode& aNode);
|
||||
nsresult PreprocessStack();
|
||||
PRBool CanContainFormElement(eXIFTags aParent,eXIFTags aChild) const;
|
||||
nsresult CollectAttributes(nsCParserNode& aNode,PRInt32 aCount);
|
||||
nsresult CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
|
||||
nsresult CollectContentComment(CToken* aToken,nsCParserNode& aNode);
|
||||
|
||||
nsParser* mParser;
|
||||
nsIHTMLContentSink* mSink;
|
||||
|
||||
PRBool mLeafBits[100];
|
||||
eXIFTags mContextStack[100];
|
||||
PRInt32 mContextStackPos;
|
||||
|
||||
PRBool mHasOpenForm;
|
||||
PRBool mHasOpenMap;
|
||||
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
|
||||
nsVoidArray mNodeStack;
|
||||
nsVoidArray mTokenStack;
|
||||
|
||||
PRInt32 mHTMLStackPos;
|
||||
eHTMLTags mHTMLTagStack[512];
|
||||
nsAutoString* mHTMLNameStack[512];
|
||||
PRBool mInContent;
|
||||
|
||||
nsString mBuffer;
|
||||
PRInt32 mMaxCSSSelectorWidth;
|
||||
PRInt32 mCSSDeclarationCount;
|
||||
PRInt32 mCSSSelectorCount;
|
||||
PRBool mLowerCaseTags;
|
||||
PRBool mLowerCaseAttributes;
|
||||
nsITokenizer* mTokenizer;
|
||||
nsString mCharset;
|
||||
|
||||
nsDTDContext* mXIFContext;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsresult mDTDState;
|
||||
|
||||
nsString mContainerKey;
|
||||
nsString mEncodeKey;
|
||||
nsString mCSSStyleSheetKey;
|
||||
nsString mCSSSelectorKey;
|
||||
nsString mCSSDeclarationKey;
|
||||
nsString mGenericKey;
|
||||
|
||||
PRInt32 mLineNumber;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -165,68 +165,14 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
||||
InitializeElementTable();
|
||||
}
|
||||
|
||||
mNodeRecycler=0;
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
//DebugDumpContainmentRules2(*this,"c:/temp/DTDRules.new","New CNavDTD Containment Rules");
|
||||
nsHTMLElement::DebugDumpContainment("c:/temp/contain.new","ElementTable Rules");
|
||||
nsHTMLElement::DebugDumpMembership("c:/temp/membership.out");
|
||||
nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out");
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
gNodeCount=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates a new parser node. It tries to get one from
|
||||
* the recycle list before allocating a new one.
|
||||
* @update gess1/8/99
|
||||
* @param
|
||||
* @return valid node*
|
||||
*/
|
||||
|
||||
nsCParserNode* CNavDTD::CreateNode(void) {
|
||||
|
||||
nsCParserNode* result=0;
|
||||
if(0<mSharedNodes.GetSize()) {
|
||||
result=(nsCParserNode*)mSharedNodes.Pop();
|
||||
}
|
||||
else{
|
||||
result=new nsCParserNode();
|
||||
#ifdef NS_DEBUG
|
||||
#if 1
|
||||
gNodeCount++;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method recycles a given node
|
||||
* @update gess1/8/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void CNavDTD::RecycleNode(nsCParserNode* aNode) {
|
||||
if(aNode && (!aNode->mUseCount)) {
|
||||
|
||||
if(aNode->mToken) {
|
||||
if(!aNode->mToken->mUseCount) {
|
||||
mTokenRecycler->RecycleToken(aNode->mToken);
|
||||
}
|
||||
}
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
if(!theToken->mUseCount) {
|
||||
mTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
}
|
||||
|
||||
mSharedNodes.Push(aNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,26 +236,7 @@ CNavDTD::~CNavDTD(){
|
||||
if(mTempContext)
|
||||
delete mTempContext;
|
||||
|
||||
nsCParserNode* theNode=0;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#if 0
|
||||
PRInt32 count=gNodeCount-mSharedNodes.GetSize();
|
||||
if(count) {
|
||||
printf("%i of %i nodes leaked!\n",count,gNodeCount);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
while((theNode=(nsCParserNode*)mSharedNodes.Pop())){
|
||||
delete theNode;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
gNodeCount=0;
|
||||
#endif
|
||||
// delete mNodeRecycler;
|
||||
|
||||
NS_IF_RELEASE(mSink);
|
||||
NS_IF_RELEASE(mDTDDebug);
|
||||
@ -470,6 +397,8 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
|
||||
* @return error code (almost always NS_OK)
|
||||
*/
|
||||
nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
|
||||
NS_PRECONDITION(mBodyContext!=nsnull,"Create a context before calling build model");
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aTokenizer) {
|
||||
@ -480,6 +409,11 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
||||
if(mTokenizer) {
|
||||
|
||||
mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
|
||||
|
||||
result=mBodyContext->GetNodeRecycler(mNodeRecycler); // Get a copy...
|
||||
|
||||
if(NS_FAILED(result)) return result;
|
||||
|
||||
if(mSink) {
|
||||
|
||||
if(!mBodyContext->GetCount()) {
|
||||
@ -579,7 +513,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
nsEntryStack *theChildStyles=0;
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->Pop(theChildStyles);
|
||||
theNode->mUseCount=0;
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
@ -1319,7 +1253,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
theNode->Init(aToken,mLineNumber,mTokenRecycler);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
@ -1431,7 +1365,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
}//if
|
||||
} //if
|
||||
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1790,7 +1724,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
nsresult result=NS_OK;
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
|
||||
@ -1805,7 +1739,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
#endif
|
||||
|
||||
result=AddLeaf(theNode);
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1828,7 +1762,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
nsString& theComment=aToken->GetStringValueXXX();
|
||||
mLineNumber += (theComment).CountChar(kNewLine);
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
|
||||
@ -1841,7 +1775,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
|
||||
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -1905,7 +1839,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
|
||||
@ -1918,7 +1852,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
|
||||
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -1954,7 +1888,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
}
|
||||
docTypeStr.Cut(0,2); // Now remove "<!" from the begining
|
||||
|
||||
nsCParserNode* theNode=CreateNode();
|
||||
nsCParserNode* theNode=mNodeRecycler->CreateNode();
|
||||
if(theNode) {
|
||||
theNode->Init(aToken,mLineNumber,0);
|
||||
|
||||
@ -1962,7 +1896,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
|
||||
result = (mSink)? mSink->AddDocTypeDecl(*theNode,mParseMode):NS_OK;
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2459,7 +2393,7 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
|
||||
//if the node tag can't contain the child tag, then remove the child tag from the style stack
|
||||
nsCParserNode* theRemovedNode=(nsCParserNode*)theStack->Remove(sindex,theNodeTag);
|
||||
if(theRemovedNode) {
|
||||
RecycleNode(theRemovedNode);
|
||||
mNodeRecycler->RecycleNode(theRemovedNode,mTokenRecycler);
|
||||
}
|
||||
theEntry--; //back up by one
|
||||
}
|
||||
@ -2529,7 +2463,7 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
|
||||
nsCParserNode* theNode=(nsCParserNode*)mBodyContext->PopStyle(aTag);
|
||||
if(theNode) {
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3197,7 +3131,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
}
|
||||
#endif
|
||||
}//if anode
|
||||
RecycleNode(theNode);
|
||||
mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -106,6 +106,7 @@ class nsEntryStack;
|
||||
class nsITokenizer;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class CNodeRecycler;
|
||||
|
||||
/***************************************************************
|
||||
Now the main event: CNavDTD.
|
||||
@ -483,8 +484,6 @@ protected:
|
||||
nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
|
||||
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode *aNode);
|
||||
nsresult HandleSavedTokens(PRInt32 anIndex);
|
||||
nsCParserNode* CreateNode(void);
|
||||
void RecycleNode(nsCParserNode* aNode);
|
||||
void RecycleNodes(nsEntryStack *aNodeStack);
|
||||
|
||||
nsIHTMLContentSink* mSink;
|
||||
@ -507,6 +506,7 @@ protected:
|
||||
nsParser* mParser;
|
||||
nsITokenizer* mTokenizer;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsDeque mMisplacedContent;
|
||||
nsDeque mSkippedContent;
|
||||
PRBool mHasOpenScript;
|
||||
@ -526,10 +526,6 @@ protected:
|
||||
PRBool mIsFormContainer;
|
||||
nsAutoString mMimeType;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 gNodeCount;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
inline nsresult NS_NewNavHTMLDTD(nsIDTD** aInstancePtrResult)
|
||||
|
||||
@ -33,8 +33,10 @@
|
||||
MOZ_DECL_CTOR_COUNTER(nsEntryStack);
|
||||
MOZ_DECL_CTOR_COUNTER(nsDTDContext);
|
||||
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CNodeRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
A few notes about how residual style handling is performed:
|
||||
|
||||
@ -373,7 +375,7 @@ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const {
|
||||
/***************************************************************
|
||||
Now define the dtdcontext class
|
||||
***************************************************************/
|
||||
|
||||
CNodeRecycler* nsDTDContext::mNodeRecycler=0;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -454,6 +456,15 @@ nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/07/00
|
||||
*/
|
||||
|
||||
nsIParserNode* nsDTDContext::Pop() {
|
||||
nsEntryStack *theTempStyleStack=0; // This has no use here...
|
||||
return Pop(theTempStyleStack);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@ -640,6 +651,30 @@ nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/10/00
|
||||
*/
|
||||
nsresult nsDTDContext::GetNodeRecycler(CNodeRecycler*& aNodeRecycler){
|
||||
nsresult result=NS_OK;
|
||||
if(!mNodeRecycler) {
|
||||
mNodeRecycler=new CNodeRecycler();
|
||||
if(mNodeRecycler==0) result=NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aNodeRecycler=mNodeRecycler;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update hairshd 04/10/00
|
||||
*/
|
||||
void nsDTDContext::FreeNodeRecycler(){
|
||||
if(mNodeRecycler) {
|
||||
delete mNodeRecycler;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Now define the tokenrecycler class...
|
||||
**************************************************************/
|
||||
@ -801,6 +836,75 @@ CToken* CTokenRecycler::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag)
|
||||
return result;
|
||||
}
|
||||
|
||||
CNodeRecycler::CNodeRecycler(): mSharedNodes(0) {
|
||||
|
||||
MOZ_COUNT_CTOR(CTokenRecycler);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
gNodeCount=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
CNodeRecycler::~CNodeRecycler() {
|
||||
|
||||
MOZ_COUNT_DTOR(CTokenRecycler);
|
||||
|
||||
nsCParserNode* theNode=0;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#if 0
|
||||
PRInt32 count=gNodeCount-mSharedNodes.GetSize();
|
||||
if(count) {
|
||||
printf("%i of %i nodes leaked!\n",count,gNodeCount);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while((theNode=(nsCParserNode*)mSharedNodes.Pop())){
|
||||
delete theNode;
|
||||
}
|
||||
}
|
||||
|
||||
void CNodeRecycler::RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler) {
|
||||
|
||||
if(aNode && (!aNode->mUseCount)) {
|
||||
|
||||
// If the node contains tokens there better me a token recycler..
|
||||
if(aTokenRecycler) {
|
||||
if(aNode->mToken) {
|
||||
if(!aNode->mToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(aNode->mToken);
|
||||
}
|
||||
}
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)aNode->PopAttributeToken())){
|
||||
if(!theToken->mUseCount) {
|
||||
aTokenRecycler->RecycleToken(theToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
mSharedNodes.Push(aNode);
|
||||
}
|
||||
}
|
||||
|
||||
nsCParserNode* CNodeRecycler::CreateNode(void) {
|
||||
|
||||
nsCParserNode* result=0;
|
||||
if(0<mSharedNodes.GetSize()) {
|
||||
result=(nsCParserNode*)mSharedNodes.Pop();
|
||||
}
|
||||
else{
|
||||
result=new nsCParserNode();
|
||||
#ifdef NS_DEBUG
|
||||
#if 1
|
||||
gNodeCount++;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) {
|
||||
#ifdef RICKG_DEBUG
|
||||
|
||||
|
||||
@ -41,8 +41,11 @@
|
||||
#include "nsITokenizer.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIElementObserver.h"
|
||||
#include "nsIParserNode.h"
|
||||
|
||||
class nsIParserNode;
|
||||
class nsCParserNode;
|
||||
class CNodeRecycler;
|
||||
|
||||
|
||||
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
|
||||
@ -138,6 +141,8 @@ public:
|
||||
|
||||
void Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
nsIParserNode* Pop(nsEntryStack*& aChildStack);
|
||||
nsIParserNode* Pop();
|
||||
nsIParserNode* PeekNode() { return mStack.NodeAt(mStack.mCount-1); }
|
||||
eHTMLTags First(void) const;
|
||||
eHTMLTags Last(void) const;
|
||||
nsTagEntry* LastEntry(void) const;
|
||||
@ -157,17 +162,21 @@ public:
|
||||
nsIParserNode* PopStyle(eHTMLTags aTag);
|
||||
nsIParserNode* RemoveStyle(eHTMLTags aTag);
|
||||
|
||||
nsresult GetNodeRecycler(CNodeRecycler*& aNodeRecycler);
|
||||
static void FreeNodeRecycler(void);
|
||||
|
||||
nsEntryStack mStack; //this will hold a list of tagentries...
|
||||
PRInt32 mResidualStyleCount;
|
||||
PRInt32 mContextTopIndex;
|
||||
|
||||
static CNodeRecycler* mNodeRecycler;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
enum { eMaxTags = 100 };
|
||||
eHTMLTags mXTags[eMaxTags];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Now define the token deallocator class...
|
||||
**************************************************************/
|
||||
@ -207,6 +216,29 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
CNodeRecycler class implementation.
|
||||
This class is used to recycle nodes.
|
||||
By using this simple class, we cut down on the number of nodes
|
||||
that get created during the run of the system.
|
||||
************************************************************************/
|
||||
|
||||
class CNodeRecycler {
|
||||
public:
|
||||
|
||||
CNodeRecycler();
|
||||
virtual ~CNodeRecycler();
|
||||
virtual nsCParserNode* CreateNode(void);
|
||||
virtual void RecycleNode(nsCParserNode* aNode,nsITokenRecycler* aTokenRecycler=0);
|
||||
|
||||
protected:
|
||||
nsDeque mSharedNodes;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 gNodeCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
ITagHandler class offers an API for taking care of specific tokens.
|
||||
************************************************************************/
|
||||
|
||||
@ -195,6 +195,7 @@ nsParserModule::Shutdown()
|
||||
nsXMLTokenizer::FreeTokenRecycler();
|
||||
nsExpatTokenizer::FreeTokenRecycler();
|
||||
// nsTextTokenizer::FreeTokenRecycler();
|
||||
nsDTDContext::FreeNodeRecycler();
|
||||
nsParser::FreeSharedObjects();
|
||||
mInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -48,6 +48,11 @@ class CTokenHandler;
|
||||
class nsIDTDDebug;
|
||||
class nsIHTMLContentSink;
|
||||
class nsITokenizer;
|
||||
class nsDTDContext;
|
||||
class nsEntryStack;
|
||||
class nsCParserNode;
|
||||
class CTokenRecycler;
|
||||
class CNodeRecycler;
|
||||
|
||||
//*** This enum is used to define the known universe of XIF tags.
|
||||
//*** The use of this table doesn't preclude of from using non-standard
|
||||
@ -244,10 +249,6 @@ class nsXIFDTD : public nsIDTD {
|
||||
* --------------[ Sets DTD to STOP mode ]----------------
|
||||
* It's recommended to use this method in accordance with
|
||||
* the parser's terminate() method.
|
||||
*
|
||||
* @update harishd 07/22/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual nsresult Terminate(void);
|
||||
|
||||
@ -275,9 +276,6 @@ class nsXIFDTD : public nsIDTD {
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 12/1/99
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/
|
||||
virtual PRBool IsHTMLContainer(eHTMLTags aTag) const;
|
||||
|
||||
@ -296,52 +294,37 @@ class nsXIFDTD : public nsIDTD {
|
||||
/**
|
||||
* This method gets called when a start token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the start token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleStartToken(CToken* aToken);
|
||||
|
||||
/**
|
||||
* This method gets called when an end token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the end token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleEndToken(CToken* aToken);
|
||||
|
||||
/**
|
||||
* This method gets called when an entity token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the entity token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleEntityToken(CToken* aToken);
|
||||
|
||||
/**
|
||||
* This method gets called when a comment token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the comment token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleCommentToken(CToken* aToken);
|
||||
nsresult HandleCommentToken(CToken* aToken,nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* This method gets called when an attribute token has been consumed and needs
|
||||
* to be handled (possibly added to content model via sink).
|
||||
* @update gpk 06/18/98
|
||||
* @param aToken is the attribute token to be handled
|
||||
* @return TRUE if the token was handled.
|
||||
*/
|
||||
nsresult HandleAttributeToken(CToken* aToken);
|
||||
|
||||
nsresult HandleAttributeToken(CToken* aToken,nsIParserNode& aNode);
|
||||
|
||||
nsresult HandleWhiteSpaceToken(CToken* aToken);
|
||||
nsresult HandleTextToken(CToken* aToken);
|
||||
|
||||
nsresult HandleContainer(nsIParserNode& aNode);
|
||||
nsresult HandleDefaultToken(CToken* aToken,nsIParserNode& aNode);
|
||||
PRBool CanHandleDefaultTag(eXIFTags aTag, PRInt32& aIsContainer);
|
||||
|
||||
private:
|
||||
|
||||
@ -410,78 +393,65 @@ private:
|
||||
* @return ptr to recycler (or null)
|
||||
*/
|
||||
virtual nsITokenRecycler* GetTokenRecycler(void);
|
||||
eHTMLTags GetStartTag(const nsIParserNode& aNode, nsString& aName);
|
||||
|
||||
private:
|
||||
|
||||
void ProcessEncodeTag(const nsIParserNode& aNode);
|
||||
void ProcessEntityTag(const nsIParserNode& aNode);
|
||||
void ProcessDocumentInfoTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessEncodeTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessEntityTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessDocumentInfoTag(const nsIParserNode& aNode);
|
||||
|
||||
void BeginCSSStyleSheet(const nsIParserNode& aNode);
|
||||
void EndCSSStyleSheet(const nsIParserNode& aNode);
|
||||
nsresult BeginCSSStyleSheet(const nsIParserNode& aNode);
|
||||
nsresult EndCSSStyleSheet(const nsIParserNode& aNode);
|
||||
|
||||
void BeginCSSStyleRule(const nsIParserNode& aNode);
|
||||
void EndCSSStyleRule(const nsIParserNode& aNode);
|
||||
nsresult BeginCSSStyleRule(const nsIParserNode& aNode);
|
||||
nsresult EndCSSStyleRule(const nsIParserNode& aNode);
|
||||
|
||||
void AddCSSSelector(const nsIParserNode& aNode);
|
||||
void AddCSSDeclaration(const nsIParserNode& aNode);
|
||||
void BeginCSSDeclarationList(const nsIParserNode& aNode);
|
||||
void EndCSSDeclarationList(const nsIParserNode& aNode);
|
||||
|
||||
|
||||
void AddAttribute(nsIParserNode& aNode);
|
||||
void PushHTMLTag(const eHTMLTags aTag, const nsString& aName);
|
||||
void PopHTMLTag(eHTMLTags& aTag, nsString*& aName);
|
||||
nsresult AddCSSSelector(const nsIParserNode& aNode);
|
||||
nsresult AddCSSDeclaration(const nsIParserNode& aNode);
|
||||
nsresult BeginCSSDeclarationList(const nsIParserNode& aNode);
|
||||
nsresult EndCSSDeclarationList(const nsIParserNode& aNode);
|
||||
|
||||
PRBool GetAttributePair(nsIParserNode& aNode, nsString& aKey, nsString& aValue);
|
||||
PRBool GetAttribute(const nsIParserNode& aNode, const nsString& aKey, nsString& aValue);
|
||||
void BeginStartTag(const nsIParserNode& aNode);
|
||||
void AddEndTag(const nsIParserNode& aNode);
|
||||
void AddEndCommentTag(const nsIParserNode& aNode);
|
||||
|
||||
PRBool StartTopOfStack();
|
||||
nsIParserNode* PeekNode();
|
||||
CToken* PeekToken();
|
||||
void PushNodeAndToken(nsString& aName);
|
||||
void PopAndDelete();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
nsresult WillHandleToken(CToken* aToken,eHTMLTokenTypes& aType);
|
||||
nsresult DidHandleToken(CToken* aToken, nsresult aResult=NS_OK);
|
||||
nsresult WillHandleStartToken(CToken* aToken,eXIFTags aTag, nsIParserNode& aNode);
|
||||
nsresult DidHandleStartToken(CToken* aToken,eXIFTags aTag, nsIParserNode& aNode);
|
||||
nsresult PreprocessStack();
|
||||
PRBool CanContainFormElement(eXIFTags aParent,eXIFTags aChild) const;
|
||||
nsresult CollectAttributes(nsCParserNode& aNode,PRInt32 aCount);
|
||||
nsresult CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
|
||||
nsresult CollectContentComment(CToken* aToken,nsCParserNode& aNode);
|
||||
|
||||
nsParser* mParser;
|
||||
nsIHTMLContentSink* mSink;
|
||||
|
||||
PRBool mLeafBits[100];
|
||||
eXIFTags mContextStack[100];
|
||||
PRInt32 mContextStackPos;
|
||||
|
||||
PRBool mHasOpenForm;
|
||||
PRBool mHasOpenMap;
|
||||
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
|
||||
nsVoidArray mNodeStack;
|
||||
nsVoidArray mTokenStack;
|
||||
|
||||
PRInt32 mHTMLStackPos;
|
||||
eHTMLTags mHTMLTagStack[512];
|
||||
nsAutoString* mHTMLNameStack[512];
|
||||
PRBool mInContent;
|
||||
|
||||
nsString mBuffer;
|
||||
PRInt32 mMaxCSSSelectorWidth;
|
||||
PRInt32 mCSSDeclarationCount;
|
||||
PRInt32 mCSSSelectorCount;
|
||||
PRBool mLowerCaseTags;
|
||||
PRBool mLowerCaseAttributes;
|
||||
nsITokenizer* mTokenizer;
|
||||
nsString mCharset;
|
||||
|
||||
nsDTDContext* mXIFContext;
|
||||
CTokenRecycler* mTokenRecycler;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsresult mDTDState;
|
||||
|
||||
nsString mContainerKey;
|
||||
nsString mEncodeKey;
|
||||
nsString mCSSStyleSheetKey;
|
||||
nsString mCSSSelectorKey;
|
||||
nsString mCSSDeclarationKey;
|
||||
nsString mGenericKey;
|
||||
|
||||
PRInt32 mLineNumber;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user