diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp
index ea934d671ba..04e90de92d4 100644
--- a/mozilla/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/htmlparser/src/CNavDTD.cpp
@@ -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(0mUseCount)) {
-
- 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 "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);
}
diff --git a/mozilla/htmlparser/src/CNavDTD.h b/mozilla/htmlparser/src/CNavDTD.h
index 0b5f4d3ea8a..65439ac5d6e 100644
--- a/mozilla/htmlparser/src/CNavDTD.h
+++ b/mozilla/htmlparser/src/CNavDTD.h
@@ -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)
diff --git a/mozilla/htmlparser/src/nsDTDUtils.cpp b/mozilla/htmlparser/src/nsDTDUtils.cpp
index e376561a682..ef762c6854f 100644
--- a/mozilla/htmlparser/src/nsDTDUtils.cpp
+++ b/mozilla/htmlparser/src/nsDTDUtils.cpp
@@ -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(0GetTokenRecycler();
+ mParser=(nsParser*)aParser;
- while (NS_SUCCEEDED(result))
- {
- CToken* theToken=mTokenizer->PopToken();
- if(theToken) {
- result=HandleToken(theToken,aParser);
- if (NS_SUCCEEDED(result)) {
- theRecycler->RecycleToken(theToken);
- }
- else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
- mTokenizer->PushTokenFront(theToken);
- }
- // theRootDTD->Verify(kEmptyString,aParser);
+ if(mTokenizer) {
+
+ mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
+ result=mXIFContext->GetNodeRecycler(mNodeRecycler);
+
+ if(NS_FAILED(result)) return result;
+
+ if(mSink) {
+ while(NS_SUCCEEDED(result)){
+ if(mDTDState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
+ CToken* theToken=mTokenizer->PopToken();
+ if(theToken) {
+ result=HandleToken(theToken,aParser);
+ }
+ else break;
+ }
+ else {
+ result=mDTDState;
+ break;
+ }
+ }//while
+ mTokenizer=oldTokenizer;
}
- else break;
- }//while
- mTokenizer=oldTokenizer;
+ }
}
else result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
return result;
@@ -428,143 +443,165 @@ nsresult nsXIFDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPars
return result;
}
+/**
+ * Do preprocessing on the token
+ *
+ * @update harishd 04/06/00
+ * @param aType - Set the appropriate type.
+ * @param aToken - The type of the token..
+ * @return
+ */
+nsresult nsXIFDTD::WillHandleToken(CToken* aToken,eHTMLTokenTypes& aType) {
+ NS_ASSERTION(aToken!=nsnull,"invalid token");
+
+ nsresult result=NS_OK;
+ if(aToken) {
+ aType=eHTMLTokenTypes(aToken->GetTokenType());
+ eXIFTags theNewType = eXIFTag_userdefined;
+
+ if((eToken_start==aType) || (eToken_end==aType)) {
+ nsString& name = aToken->GetStringValueXXX();
+ theNewType=DetermineXIFTagType(name);
+ if (theNewType != eXIFTag_userdefined) {
+ aToken->SetTypeID(theNewType);
+ }
+ }
+ }
+ return NS_OK;
+}
/**
* This big dispatch method is used to route token handler calls to the right place.
* What's wrong with it? This table, and the dispatch methods themselves need to be
* moved over to the delegate. Ah, so much to do...
*
- * @update gpk 06/18/98
+ * @update harishd 04/06/00
* @param aType
* @param aToken
* @param aParser
* @return
*/
-nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
- nsresult result=NS_OK;
-
- mParser=(nsParser*)aParser;
- mSink=(nsIHTMLContentSink*)aParser->GetContentSink(); //this can change in the parser between calls.
+nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser){
+ nsresult result=NS_OK;
if(aToken) {
- CHTMLToken* theToken= (CHTMLToken*)(aToken);
- eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
-
- eXIFTags type = eXIFTag_userdefined;
- if((eToken_start==theType) || (eToken_end==theType)) {
- nsString& name = aToken->GetStringValueXXX();
- type=DetermineXIFTagType(name);
- if (type != eXIFTag_userdefined)
- aToken->SetTypeID(type);
+ eHTMLTokenTypes theType=eToken_unknown;
+ result=WillHandleToken(aToken,theType);
+
+ if(result==NS_OK) {
+
+ aToken->mUseCount=0; //assume every token coming into this system needs recycling.
+
+ switch(theType) {
+ case eToken_text:
+ case eToken_start:
+ case eToken_newline:
+ case eToken_whitespace:
+ result=HandleStartToken(aToken); break;
+ case eToken_end:
+ result=HandleEndToken(aToken); break;
+ default:
+ result=NS_OK;
+ }//switch
+ result=DidHandleToken(aToken);
}
-
- switch(theType) {
- case eToken_start:
- result=HandleStartToken(aToken); break;
- case eToken_end:
- result=HandleEndToken(aToken); break;
- case eToken_comment:
- result=HandleCommentToken(aToken); break;
- case eToken_whitespace:
- result=HandleWhiteSpaceToken(aToken); break;
- case eToken_newline:
- result=HandleWhiteSpaceToken(aToken); break;
- case eToken_text:
- result=HandleTextToken(aToken); break;
- case eToken_attribute:
- result=HandleAttributeToken(aToken); break;
- default:
- result=NS_OK;
- }//switch
-
}//if
return result;
}
-
/**
- * This method gets called when a start token has been
- * encountered in the parse process.
+ * Do postprocessing on the token.
*
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @param aNode -- CParserNode representing this start token
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * @update harishd 04/06/00
+ * @param aToken -
+ * @param aResult -
+ * @return
*/
-nsresult nsXIFDTD::HandleWhiteSpaceToken(CToken* aToken) {
- NS_PRECONDITION(0!=aToken,kNullToken);
- //CStartToken* st = (CStartToken*)(aToken);
+nsresult nsXIFDTD::DidHandleToken(CToken* aToken, nsresult aResult) {
+ NS_ASSERTION(mTokenRecycler!=nsnull,"We need a recycler");
+ nsresult result=aResult;
+ if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
+ if(aToken) {
+ if(0>=aToken->mUseCount)
+ if(mTokenRecycler) mTokenRecycler->RecycleToken(aToken);
+ }
+ }
+ else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
+ mDTDState=result;
+ else result=NS_OK;
- //Begin by gathering up attributes...
- nsCParserNode node((CHTMLToken*)aToken);
- PRInt16 attrCount=aToken->GetAttributeCount();
- nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(node,attrCount);
-
- if (NS_SUCCEEDED(result))
- {
- if (mInContent == PR_TRUE)
- mSink->AddLeaf(node);
- }
return result;
}
/**
- * This method gets called when a start token has been
- * encountered in the parse process.
- *
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @param aNode -- CParserNode representing this start token
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * Call this method to open the top most node in the stack
+ * It also prevents the node from opening up twice
+ *
+ * harishd 04/10/00
+ * @param - nil
*/
-nsresult nsXIFDTD::HandleTextToken(CToken* aToken) {
- NS_PRECONDITION(0!=aToken,kNullToken);
-
- CStartToken* st = (CStartToken*)(aToken);
- eXIFTags type =(eXIFTags)st->GetTypeID();
- nsCParserNode node((CHTMLToken*)aToken);
-
- nsresult result = NS_OK;
-
- if (type == eXIFTag_text)
- {
- nsString& temp = aToken->GetStringValueXXX();
-
- if (!temp.EqualsWithConversion(""))
- {
- result= AddLeaf(node);
+nsresult nsXIFDTD::PreprocessStack(void) {
+ nsresult result=NS_OK;
+ nsCParserNode* theNode=(nsCParserNode*)mXIFContext->PeekNode();
+
+ if(theNode){
+ // mUseCount = 0 ---> Node is not on the internal stack
+ // mUseCount = 1 ---> Node is on the internal stack and can be passed to the sink.
+ // mUseCount = 2 ---> Node passed to the sink already so don't open once again.
+ if(theNode->mUseCount==1) {
+ eHTMLTags theTag=(theNode->mToken)? (eHTMLTags)theNode->mToken->GetTypeID():eHTMLTag_unknown;
+ if(theTag!=eHTMLTag_unknown) {
+ if(IsHTMLContainer(theTag)) {
+ result=mSink->OpenContainer(*theNode);
+ }
+ else {
+ result=mSink->AddLeaf(*theNode);
+ }
+ }
+ theNode->mUseCount++; // This will make sure that the node is not opened twice.
}
}
+
return result;
}
+/**
+ * Closes the top most contaier node on the internal stack..
+ *
+ * @update harishd 04/12/00
+ * @param aToken -
+ * @param aTag - The tag that might require preprocessing.
+ * @param aNode - The node to be handled
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
+ */
-void nsXIFDTD::AddAttribute(nsIParserNode& aNode) {
- nsIParserNode* top = PeekNode();
- if (top != nsnull)
- {
- nsString key;
- nsString value;
- PRBool hasValue;
+nsresult nsXIFDTD::WillHandleStartToken(CToken* aToken, eXIFTags aTag, nsIParserNode& aNode) {
+ nsresult result=NS_OK;
- hasValue = GetAttributePair(aNode,key,value);
- // XXX should we still be calling AddAttribute if hasValue is false?
- CAttributeToken* attribute = new CAttributeToken(key,value);
- ((nsCParserNode*)top)->AddAttribute(attribute);
+ switch(aTag) {
+ case eXIFTag_leaf:
+ case eXIFTag_comment:
+ case eXIFTag_entity:
+ case eXIFTag_container:
+ result=PreprocessStack(); // Pass the topmost node to the sink ( if it hasn't been yet ).
+ break;
+ default:
+ break;
}
-}
+ return result;
+}
/**
* This method gets called when a start token has been
* encountered in the parse process.
*
- * @update gess 12/28/98
+ * @update harishd 04/12/00
* @param aToken -- next (start) token to be handled
* @param aNode -- CParserNode representing this start token
* @return PR_TRUE if all went well; PR_FALSE if error occured
@@ -576,166 +613,265 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
eXIFTags type =(eXIFTags)st->GetTypeID();
//Begin by gathering up attributes...
- nsCParserNode node = ((CHTMLToken*)aToken);
+ nsCParserNode* node=mNodeRecycler->CreateNode();
+ node->Init(aToken,mLineNumber,mTokenRecycler);
+
PRInt16 attrCount=aToken->GetAttributeCount();
- nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(node,attrCount);
+ nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(*node,attrCount);
if (NS_SUCCEEDED(result))
{
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- StartTopOfStack();
- result = OpenContainer(node);
- break;
- case eXIFTag_comment:
- result=CollectContentComment(aToken,node);
- break;
- case eXIFTag_entity:
- StartTopOfStack();
- ProcessEntityTag(node);
- break;
-
- case eXIFTag_content:
- StartTopOfStack();
- mInContent = PR_TRUE;
- break;
-
- case eXIFTag_encode:
- ProcessEncodeTag(node);
- break;
-
- case eXIFTag_attr:
- AddAttribute(node);
- break;
-
- case eXIFTag_css_stylesheet:
- StartTopOfStack();
- BeginCSSStyleSheet(node);
- break;
-
- case eXIFTag_css_rule:
- BeginCSSStyleRule(node);
- break;
-
- case eXIFTag_css_selector:
- AddCSSSelector(node);
- break;
-
- case eXIFTag_css_declaration_list:
- BeginCSSDeclarationList(node);
- break;
-
- case eXIFTag_css_declaration:
- AddCSSDeclaration(node);
- break;
-
- case eXIFTag_document_info:
- // This is XIF only tag. For HTML it's userdefined.
- node.mToken->SetTypeID(eHTMLTag_userdefined);
- // fall through to call OpenContainer:
-
- case eXIFTag_markupDecl:
- mSink->OpenContainer(node);
- break;
-
- default:
- break;
+ result=WillHandleStartToken(aToken,type,*node);
+ if(NS_SUCCEEDED(result)) {
+ switch (type)
+ {
+ case eXIFTag_attr:
+ result=HandleAttributeToken(aToken,*node);
+ break;
+ case eXIFTag_comment:
+ result=HandleCommentToken(aToken,*node);
+ break;
+ case eXIFTag_content:
+ mInContent=PR_TRUE;
+ break;
+ case eXIFTag_encode:
+ ProcessEncodeTag(*node);
+ break;
+ case eXIFTag_entity:
+ ProcessEntityTag(*node);
+ break;
+ case eXIFTag_markupDecl:
+ mXIFContext->Push(node);
+ break;
+ case eXIFTag_document_info:
+ // This is XIF only tag. For HTML it's userdefined.
+ node->mToken->SetTypeID(eHTMLTag_userdefined);
+ result=mSink->OpenContainer(*node);
+ break;
+ default:
+ result=HandleDefaultToken(aToken,*node);
+ break;
+ }
}
- }
+ }
+
+ mNodeRecycler->RecycleNode(node,mTokenRecycler);
return result;
}
-
/**
- * This method gets called when an end token has been
- * encountered in the parse process. If the end tag matches
- * the start tag on the stack, then simply close it. Otherwise,
- * we have a erroneous state condition. This can be because we
- * have a close tag with no prior open tag (user error) or because
- * we screwed something up in the parse process. I'm not sure
- * yet how to tell the difference.
- *
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * This method determines if the token should be processed as
+ * a contianer or as a leaf. Also determines if the token can
+ * can be handled or not.
+ *
+ * @update harishd 04/12/00
+ * @param aToken - The start token.
+ * @param aNode - The container node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
-nsresult nsXIFDTD::HandleEndToken(CToken* aToken) {
- NS_PRECONDITION(0!=aToken,kNullToken);
- nsresult result = NS_OK;
- CEndToken* et = (CEndToken*)(aToken);
- eXIFTags tokenTagType = (eXIFTags)et->GetTypeID();
- nsCParserNode node = ((CHTMLToken*)aToken);
+nsresult nsXIFDTD::HandleDefaultToken(CToken* aToken,nsIParserNode& aNode) {
+ nsresult result=NS_OK;
- switch (tokenTagType)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- StartTopOfStack();
- result=CloseContainer(node);
- break;
-
- case eXIFTag_content:
- mInContent = PR_FALSE;
- break;
-
- case eXIFTag_css_stylesheet:
- mInContent = PR_FALSE;
- EndCSSStyleSheet(node);
- break;
-
- case eXIFTag_css_rule:
- mInContent = PR_FALSE;
- EndCSSStyleRule(node);
- break;
-
- case eXIFTag_css_declaration_list:
- mInContent = PR_FALSE;
- EndCSSDeclarationList(node);
- break;
-
- case eXIFTag_markupDecl:
- mSink->CloseContainer(node);
-
- default:
- break;
+ PRBool isConainer;
+ eXIFTags theTag=(eXIFTags)aToken->GetTypeID();
+
+ // First find out if the tag can be handled or not....
+ // because there are a few tags that do not belong to HTML
+ if(CanHandleDefaultTag(theTag,isConainer)) {
+ if(isConainer) {
+ result=HandleContainer(aNode);
+ }
+ else {
+ result=AddLeaf(aNode);
+ }
}
return result;
}
/**
- * This method gets called when a comment token has been
- * encountered in the parse process. After making sure
- * we're somewhere in the body, we handle the comment
- * in the same code that we use for text.
+ * This method gets called when container needs to be processed.
+ * It collects the actual name ( html equivalent ), which resides as an
+ * attribute on the node, of the container and reinitializes the node
+ * with the new name
*
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * @update harishd 04/12/00
+ * @param aNode -- The container node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
-nsresult nsXIFDTD::HandleCommentToken(CToken* aToken) {
+
+nsresult nsXIFDTD::HandleContainer(nsIParserNode& aNode) {
+
+ nsCParserNode* theNode=(nsCParserNode*)&aNode;
+
+ NS_ASSERTION(theNode!=nsnull,"need a node to process");
+
+ nsresult result=NS_OK;
+
+ if(theNode) {
+ nsAutoString theTagName;
+ eHTMLTags theTagID;
+
+ if(theNode->mToken) {
+ // The attribute key is "isa" ( mContainerKey )
+ // The attribute value is the TAG name.
+ GetAttribute(aNode,mContainerKey,theTagName);
+
+ theTagID=nsHTMLTags::LookupTag(theTagName);
+
+ theNode->mToken->Reinitialize(theTagID,theTagName);
+ theNode->Init(theNode->mToken,0,mTokenRecycler);
+ }
+ mXIFContext->Push(&aNode);
+ }
+ return result;
+}
+
+/**
+ * This method does a couple of jobs.
+ * a) Determines if the tag could be handled or not
+ * b) Determins if the tag is a container
+ *
+ * @update harishd 04/12/00
+ * @param aTag - The tag in question
+ * @param aIsConainer - 0 if non-container, 1 if conainer, -1 if unknown
+ * @return - TRUE if the tag can be handled
+ */
+
+PRBool nsXIFDTD::CanHandleDefaultTag(eXIFTags aTag,PRInt32& aIsContainer) {
+ PRBool result=PR_TRUE;
+
+ switch(aTag) {
+ case eXIFTag_newline:
+ case eXIFTag_whitespace:
+ case eXIFTag_text:
+ aIsContainer=0; // it's a leaf
+ break;
+ case eXIFTag_leaf:
+ case eXIFTag_container:
+ aIsContainer=1; // it's a conainer
+ break;
+ default:
+ aIsContainer=-1; // unknown state
+ result=PR_FALSE; // don't know how to handle this tag...
+ break;
+ }
+ return result;
+}
+
+/**
+ * This method gets called when an end token has been
+ * encountered in the parse process. If the end tag matches
+ * the start tag on the stack, then simply close it.
+ *
+ * @update harishd 04/12/00
+ * @param aToken -- next (end) token to be handled
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
+ */
+nsresult nsXIFDTD::HandleEndToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,kNullToken);
- return NS_OK;
+
+ nsresult result =NS_OK;
+ eXIFTags theTag =(eXIFTags)aToken->GetTypeID();
+ nsCParserNode* theNode =(nsCParserNode*)mXIFContext->PeekNode();
+
+ if(NS_SUCCEEDED(result)) {
+ switch (theTag)
+ {
+ case eXIFTag_leaf:
+ case eXIFTag_container:
+ case eXIFTag_markupDecl:
+ result=CloseContainer(*theNode);
+ break;
+ case eXIFTag_content:
+ mInContent=PR_FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+ return result;
+}
+
+/**
+ * Consumes contents of a comment in one gulp.
+ *
+ * @update harishd 10/05/99
+ * @param aNode - node to consume comment
+ * @param aToken - a comment token
+ * @return Error condition.
+ */
+
+nsresult nsXIFDTD::HandleCommentToken(CToken* aToken, nsIParserNode& aNode) {
+ NS_PRECONDITION(aToken!=nsnull,"empty token");
+
+ nsresult result=NS_OK;
+ CToken* token=nsnull;
+ eHTMLTokenTypes type=(eHTMLTokenTypes)aToken->GetTokenType();
+
+ if(type==eToken_start) {
+ nsITokenRecycler* recycler=(mTokenizer)? mTokenizer->GetTokenRecycler():nsnull;
+ if(recycler) {
+ nsAutoString fragment;
+ PRBool done=PR_FALSE;
+ PRBool inContent=PR_FALSE;
+ nsString& comment=aToken->GetStringValueXXX();
+ comment.AssignWithConversion("");
+ result=(mSink)? mSink->AddComment(aNode):NS_OK;
+ done=PR_TRUE;
+ }
+ else {
+ if(inContent) comment.Append(fragment);
+ }
+ recycler->RecycleToken(token);
+ }
+ }
+ }
+ return result;
}
/**
* This method gets called when an attribute token has been
- * encountered in the parse process. This is an error, since
- * all attributes should have been accounted for in the prior
- * start or end tokens
+ * encountered in the parse process.
*
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
+ * @update harishd 04/10/00
+ * @param aToken -- the attribute token to be handled
* @return PR_TRUE if all went well; PR_FALSE if error occured
*/
-nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken) {
- //CAttributeToken* at = (CAttributeToken*)(aToken);
+nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken,nsIParserNode& aNode) {
NS_PRECONDITION(0!=aToken,kNullToken);
- NS_ERROR("attribute encountered -- this shouldn't happen!");
nsresult result=NS_OK;
+ nsCParserNode* thePeekNode=(nsCParserNode*)mXIFContext->PeekNode();
+
+ if(thePeekNode) {
+ nsAutoString theKey;
+ nsAutoString theValue;
+
+ PRBool hasValue=GetAttributePair(aNode,theKey,theValue);
+
+ if(hasValue) {
+ CToken* attribute = mTokenRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theValue);
+ nsString& key=((CAttributeToken*)attribute)->GetKey();
+ key=theKey; // set the new key on the attribute..
+ thePeekNode->AddAttribute(attribute);
+ }
+ }
return result;
}
@@ -752,8 +888,7 @@ nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken) {
* @return PR_TRUE if given tag can contain other tags
*/
PRBool nsXIFDTD::IsContainer(PRInt32 aTag) const{
- PRBool result=PR_FALSE;
- return result;
+ return PR_TRUE;
}
@@ -804,8 +939,9 @@ NS_IMETHODIMP nsXIFDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32*
* @param aTag -- tag to test for containership
* @return PR_TRUE if given tag can contain other tags
*/
+
PRBool nsXIFDTD::IsHTMLContainer(eHTMLTags aTag) const {
- PRBool result=PR_TRUE; // by default everything is a
+ PRBool result=PR_TRUE; // by default everything is a container
switch(aTag) {
case eHTMLTag_meta:
@@ -815,7 +951,6 @@ PRBool nsXIFDTD::IsHTMLContainer(eHTMLTags aTag) const {
break;
default:
break;
-
}
return result;
}
@@ -883,309 +1018,79 @@ PRBool nsXIFDTD::GetAttributePair(nsIParserNode& aNode, nsString& aKey, nsString
return hasValue;
}
-
-
-
/**
- *
- * @update gess12/28/98
- * @param
- * @return
+ * Closes the top most contaier node on the internal stack..
+ *
+ * @update harishd 04/12/00
+ * @param aNode - The leaf node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
-eHTMLTags nsXIFDTD::GetStartTag(const nsIParserNode& aNode, nsString& aName)
-{
- eXIFTags type = (eXIFTags)aNode.GetNodeType();
- eHTMLTags tag = eHTMLTag_unknown;
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- if (GetAttribute(aNode,NS_ConvertToString("isa"),aName))
- tag = tag = nsHTMLTags::LookupTag(aName);
- break;
-
- case eXIFTag_css_stylesheet:
- aName.AssignWithConversion("style");
- tag = nsHTMLTags::LookupTag(aName);
- break;
-
- default:
- break;
- }
- return tag;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PushHTMLTag(const eHTMLTags aTag, const nsString& aName)
-{
-
- mHTMLTagStack[mHTMLStackPos]=aTag;
- mHTMLNameStack[mHTMLStackPos]=new nsAutoString(aName);
- mHTMLTagStack[++mHTMLStackPos]=eHTMLTag_unknown;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PopHTMLTag(eHTMLTags& aTag, nsString*& aName)
-{
- NS_ASSERTION(mHTMLStackPos > 0,"The stack must not be empty");
-
- aTag = eHTMLTag_unknown;
- if (mHTMLStackPos > 0)
- {
- aTag = mHTMLTagStack[mHTMLStackPos-1];
- aName = mHTMLNameStack[mHTMLStackPos-1];
- mHTMLTagStack[--mHTMLStackPos] = eHTMLTag_unknown;
- }
-}
-
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PushNodeAndToken(nsString& aName)
-{
- CToken* token = new CStartToken(aName);
- nsCParserNode* node = new nsCParserNode(token);
-
- mTokenStack.AppendElement((void*)token);
- mNodeStack.AppendElement((void*)node);
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-nsIParserNode* nsXIFDTD::PeekNode()
-{
- PRInt32 count = mNodeStack.Count()-1;
-
- if (count >= 0)
- return (nsIParserNode*)mNodeStack.ElementAt(mNodeStack.Count()-1);
- return nsnull;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-CToken* nsXIFDTD::PeekToken()
-{
- PRInt32 count = mTokenStack.Count()-1;
- if (count >= 0)
- return (CToken*)mTokenStack.ElementAt(mTokenStack.Count()-1);
- return nsnull;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PopAndDelete()
-{
- nsIParserNode* node = PeekNode();
- CToken* token = PeekToken();
-
- if (node != nsnull && token != nsnull)
- {
- mNodeStack.RemoveElement(node);
- mTokenStack.RemoveElement(token);
-
- delete (nsCParserNode*)node;
- delete token;
- }
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-PRBool nsXIFDTD::StartTopOfStack()
-{
- // If something is already on the stack, then
- // emit it and pop it off the stack
- nsIParserNode* top = PeekNode();
- if (top != nsnull)
- {
- eHTMLTags tag = (eHTMLTags)top->GetNodeType();
-
- if (IsHTMLContainer(tag))
- {
- mInContent = PR_TRUE;
- mSink->OpenContainer(*top);
- }
- else
- mSink->AddLeaf(*top);
-
- PopAndDelete();
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::BeginStartTag(const nsIParserNode& aNode)
-{
- eXIFTags type = (eXIFTags)aNode.GetNodeType();
- eHTMLTags tag;
- nsString tagName;
-
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- tag = GetStartTag(aNode,tagName);
- if (type == eXIFTag_container)
- PushHTMLTag(tag,tagName);
-
-// CToken* token = new CStartToken(tagName);
-// nsCParserNode* node = new nsCParserNode(token);
- PushNodeAndToken(tagName);
- break;
- default:
- break;
- }
-}
-
-// Translate aNode (which has a typeID corresponding to its XIF tag)
-// to the correct node for the sink.
-void nsXIFDTD::AddEndTag(const nsIParserNode& aNode)
-{
- // Get the top the HTML stack
- eHTMLTags tag;
- nsString* name = nsnull;
- PopHTMLTag(tag,name);
-
- // Create a parse node for form this token
- CEndToken token(*name);
- nsCParserNode node(&token);
-
- // close the container
- mSink->CloseContainer(node);
-
- // delete the name
- if (name != nsnull)
- delete name;
-}
-
-// Translate aNode (which has a typeID corresponding to its XIF tag)
-// to the correct node for the sink.
-void nsXIFDTD::AddEndCommentTag(const nsIParserNode& aNode)
-{
- // Make a comment token
- eHTMLTags tag = eHTMLTag_comment;
-
- // Create a parse node for this token
- CEndToken token(tag);
- nsCParserNode node(&token);
-
- // close the container
- mSink->CloseContainer(node);
-}
-
-/**
- * This method does two things: 1st, help construct
- * our own internal model of the content-stack; and
- * 2nd, pass this message on to the sink.
- * @update gpk 06/18/98
- * @param aNode -- next node to be added to model
- * @return TRUE if ok, FALSE if error
- */
-nsresult nsXIFDTD::OpenContainer(const nsIParserNode& aNode)
-{
- NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
-
- nsresult result=NS_OK;
- eXIFTags type =(eXIFTags)aNode.GetNodeType();
-
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- BeginStartTag(aNode);
- break;
- default:
- break;
- }
- mContextStack[mContextStackPos++]=type;
-
- return result;
-}
-
-/**
- * This method does two things: 1st, help construct
- * our own internal model of the content-stack; and
- * 2nd, pass this message on to the sink.
- * @update gpk 06/18/98
- * @param aNode -- next node to be removed from our model
- * @return TRUE if ok, FALSE if error
- */
nsresult nsXIFDTD::CloseContainer(const nsIParserNode& aNode)
{
- NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
+ nsresult result=NS_OK;
- nsresult result=NS_OK; //was false
- eXIFTags type=(eXIFTags)aNode.GetNodeType();
+ PreprocessStack();
- if (type == eXIFTag_container)
- AddEndTag(aNode);
- else if (type == eXIFTag_comment)
- AddEndCommentTag(aNode);
-
- mContextStack[--mContextStackPos]=eXIFTag_unknown;
-
-
+ nsCParserNode* theNode=(nsCParserNode*)mXIFContext->Pop();
+ if(theNode) {
+ eHTMLTags theTag=(theNode->mToken)? (eHTMLTags)theNode->mToken->GetTypeID():eHTMLTag_unknown;
+
+ // theNode->mUseCount is decremented by one when it's popped out of the
+ // context, i.e. theNode->mUseCount will be 1 after pop. But inorder to
+ // recycle the node, mUseCount should be set to zero...so let's decrement
+ // by one more..
+ theNode->mUseCount--; // Do this to recycle the node...
+ if(IsHTMLContainer(theTag) && theTag!=eHTMLTag_unknown) {
+ result=mSink->CloseContainer(aNode);
+ }
+ mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
+ }
return result;
}
-
/**
- * This method does two things: 1st, help construct
- * our own internal model of the content-stack; and
- * 2nd, pass this message on to the sink.
- * @update gpk 06/18/98
- * @param aNode -- next node to be added to model
- * @return TRUE if ok, FALSE if error
+ * process leaf nodes
+ *
+ * @update harishd 04/12/00
+ * @param aNode - The leaf node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
+
nsresult nsXIFDTD::AddLeaf(const nsIParserNode& aNode)
{
- //eXIFTags type = (eXIFTags)aNode.GetNodeType();
- nsresult result=mSink->AddLeaf(aNode);
+ nsresult result=NS_OK;
+
+ nsCParserNode* theNode=(nsCParserNode*)&aNode;
+
+ if(theNode) {
+ CToken* theToken=((nsCParserNode&)aNode).mToken;
+ eXIFTags theTag=(theToken)? (eXIFTags)theToken->GetTypeID():eXIFTag_unknown;
+ PRBool handled=PR_FALSE;
+
+ switch(theTag) {
+ case eXIFTag_newline:
+ if(mInContent) mLineNumber++;
+ case eXIFTag_whitespace:
+ if(!mInContent) handled=PR_TRUE;
+ break;
+ case eXIFTag_text:
+ if(theToken) {
+ nsString& temp =theToken->GetStringValueXXX();
+ if (temp.Equals("")) handled=PR_TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ if(!handled) {
+ // Handle top node that has not been passed
+ // on to the sink yet.
+ PreprocessStack();
+ result=mSink->AddLeaf(aNode);
+ }
+ }
+
return result;
}
@@ -1277,57 +1182,6 @@ nsresult nsXIFDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
return result;
}
-/**
- * Consumes contents of a comment in one gulp.
- *
- * @update harishd 10/05/99
- * @param aNode - node to consume comment
- * @param aToken - a comment token
- * @return Error condition.
- */
-nsresult nsXIFDTD::CollectContentComment(CToken* aToken, nsCParserNode& aNode) {
- NS_PRECONDITION(aToken!=nsnull,"empty token");
-
- nsresult result=NS_OK;
- CToken* token=nsnull;
- eHTMLTokenTypes type=(eHTMLTokenTypes)aToken->GetTokenType();
-
- if(type==eToken_start) {
- nsITokenRecycler* recycler=(mTokenizer)? mTokenizer->GetTokenRecycler():nsnull;
- if(recycler) {
- nsAutoString fragment;
- PRBool done=PR_FALSE;
- PRBool inContent=PR_FALSE;
- nsString& comment=aToken->GetStringValueXXX();
- comment.AssignWithConversion("");
- result=(mSink)? mSink->AddComment(aNode):NS_OK;
- done=PR_TRUE;
- }
- else {
- if(inContent) comment.Append(fragment);
- }
- recycler->RecycleToken(token);
- }
- }
- }
- return result;
-}
-
/**
*
* @update gpk 06/18/98
@@ -1409,8 +1263,16 @@ void nsXIFDTD::SetURLRef(char * aURLRef)
{
}
-void nsXIFDTD::ProcessEncodeTag(const nsIParserNode& aNode)
+/**
+ *
+ * @update harishd 04/12/00
+ * @param aNode -
+ * @return NS_OK if success.
+ */
+
+nsresult nsXIFDTD::ProcessEncodeTag(const nsIParserNode& aNode)
{
+ nsresult result=NS_OK;
nsString value;
PRInt32 error;
@@ -1419,82 +1281,122 @@ void nsXIFDTD::ProcessEncodeTag(const nsIParserNode& aNode)
PRInt32 temp = value.ToInteger(&error);
if (temp == 1)
{
- mSink->DoFragment(PR_TRUE);
- return;
+ result=mSink->DoFragment(PR_TRUE);
}
}
- mSink->DoFragment(PR_FALSE);
+ result=mSink->DoFragment(PR_FALSE);
+
+ return result;
}
+/**
+ *
+ *
+ * @update harishd 04/12/00
+ * @param aNode - The entity node
+ * @return NS_OK if success.
+ */
-void nsXIFDTD::ProcessEntityTag(const nsIParserNode& aNode)
+nsresult nsXIFDTD::ProcessEntityTag(const nsIParserNode& aNode)
{
+ nsresult result=NS_OK;
nsAutoString value;
+ // Get the entity from the node. This resides as an
+ // attribute on the node.
+ //
+ // XXX - Entities within STYLE and SCRIPT should probably be translated.
+ // Why were we given entities in the first place. Could be a problem in
+ // the XIF converter.
+ // Ex. is being given to us, by the
+ // converter as .
+ // That's totally worng.
if (GetAttribute(aNode,NS_ConvertToString("value"),value)) {
value.AppendWithConversion(';');
- CEntityToken* entity = new CEntityToken(value);
- nsCParserNode node((CToken*)entity);
- mSink->AddLeaf(node);
+ CToken* entity=((nsCParserNode&)aNode).mToken;
+ if(entity) {
+ entity->Reinitialize(eHTMLTag_entity,value);
+ nsCParserNode* thePeekNode=(nsCParserNode*)mXIFContext->PeekNode();
+ if(thePeekNode) {
+ eHTMLTags theTag=(eHTMLTags)thePeekNode->mToken->GetTypeID();
+ if(theTag==eHTMLTag_script || theTag==eHTMLTag_style) {
+ nsAutoString scratch;
+ ((CEntityToken*)entity)->TranslateToUnicodeStr(scratch); // Ex. > would become '<'
+ entity->Reinitialize(eHTMLTag_text,scratch); // Covert type to text and set the translated value.
+ }
+ }
+ ((nsCParserNode&)aNode).Init(entity,mLineNumber,mTokenRecycler);
+ }
+ result=mSink->AddLeaf(aNode);
}
+ return result;
}
-/*** CSS Methods ****/
+/*******************************
+ * ----- CSS Methods Begin-----*
+ * *
+ * XXX - CURRENTLY NOT IN USE *
+ * *
+ *******************************/
-void nsXIFDTD::BeginCSSStyleSheet(const nsIParserNode& aNode)
+nsresult nsXIFDTD::BeginCSSStyleSheet(const nsIParserNode& aNode)
{
- nsString value;
+ nsresult result=NS_OK;
+
PRInt32 error;
+ nsAutoString value;
+ CToken* theToken=((nsCParserNode&)aNode).mToken;
+
+ if(theToken) {
+ theToken->Reinitialize(eHTMLTag_style,"style");
+ mXIFContext->Push(&aNode);
+ }
mBuffer.Truncate(0);
mMaxCSSSelectorWidth = 10;
- if (GetAttribute(aNode,NS_ConvertToString("max_css_selector_width"),value))
+ if (GetAttribute(aNode,mCSSStyleSheetKey,value))
{
PRInt32 temp = value.ToInteger(&error);
if (error == NS_OK)
mMaxCSSSelectorWidth = temp;
}
-
- //const char* name = nsHTMLTags::GetStringValue(eHTMLTag_html);
+ return result;
}
-void nsXIFDTD::EndCSSStyleSheet(const nsIParserNode& aNode)
+nsresult nsXIFDTD::EndCSSStyleSheet(const nsIParserNode& aNode)
{
- nsString tagName(nsHTMLTags::GetStringValue(eHTMLTag_style));
+ nsresult result=NS_OK;
+ nsAutoString tagName(nsHTMLTags::GetStringValue(eHTMLTag_style));
- if (mLowerCaseTags == PR_TRUE)
- tagName.ToLowerCase();
- else
- tagName.ToUpperCase();
-
- CStartToken startToken(tagName);
- nsCParserNode startNode((CToken*)&startToken);
-
- mBuffer.AppendWithConversion("");
+ mBuffer.Append("");
mBuffer.Append(tagName);
- mBuffer.AppendWithConversion(">");
- startNode.SetSkippedContent(mBuffer);
- mSink->AddLeaf(startNode);
-
+ mBuffer.Append(">");
+ ((nsCParserNode&)aNode).SetSkippedContent(mBuffer);
+
+ result=mSink->AddLeaf(aNode);
+ mNodeRecycler->RecycleNode((nsCParserNode*)mXIFContext->Pop());
+ return result;
}
-void nsXIFDTD::BeginCSSStyleRule(const nsIParserNode& aNode)
+nsresult nsXIFDTD::BeginCSSStyleRule(const nsIParserNode& aNode)
{
mCSSDeclarationCount = 0;
- mCSSSelectorCount = 0;
+ mCSSSelectorCount = 0;
+ return NS_OK;
}
-void nsXIFDTD::EndCSSStyleRule(const nsIParserNode& aNode)
+nsresult nsXIFDTD::EndCSSStyleRule(const nsIParserNode& aNode)
{
+ return NS_OK;
}
-void nsXIFDTD::AddCSSSelector(const nsIParserNode& aNode)
+nsresult nsXIFDTD::AddCSSSelector(const nsIParserNode& aNode)
{
- nsString value;
+ nsAutoString value;
- if (GetAttribute(aNode, NS_ConvertToString("selectors"), value))
+ if (GetAttribute(aNode,mCSSSelectorKey, value))
{
if (mLowerCaseAttributes == PR_TRUE)
value.ToLowerCase();
@@ -1502,11 +1404,13 @@ void nsXIFDTD::AddCSSSelector(const nsIParserNode& aNode)
value.ToUpperCase();
value.CompressWhitespace();
mBuffer.Append(value);
- }
+ }
+ return NS_OK;
}
-void nsXIFDTD::BeginCSSDeclarationList(const nsIParserNode& aNode)
+nsresult nsXIFDTD::BeginCSSDeclarationList(const nsIParserNode& aNode)
{
+ nsresult result=NS_OK;
PRInt32 indx = mBuffer.RFindChar('\n');
if (indx == kNotFound)
indx = 0;
@@ -1517,34 +1421,41 @@ void nsXIFDTD::BeginCSSDeclarationList(const nsIParserNode& aNode)
count = 0;
for (PRInt32 i = 0; i < count; i++)
- mBuffer.AppendWithConversion(" ");
+ mBuffer.Append(" ");
- mBuffer.AppendWithConversion(" {");
+ mBuffer.Append(" {");
mCSSDeclarationCount = 0;
-
+ return result;
}
-void nsXIFDTD::EndCSSDeclarationList(const nsIParserNode& aNode)
+nsresult nsXIFDTD::EndCSSDeclarationList(const nsIParserNode& aNode)
{
- mBuffer.AppendWithConversion("}\n");
+ mBuffer.Append("}\n");
+ return NS_OK;
}
-void nsXIFDTD::AddCSSDeclaration(const nsIParserNode& aNode)
+nsresult nsXIFDTD::AddCSSDeclaration(const nsIParserNode& aNode)
{
- nsString property;
- nsString value;
+ nsAutoString property;
+ nsAutoString value;
- if (PR_TRUE == GetAttribute(aNode, NS_ConvertToString("property"), property))
- if (PR_TRUE == GetAttribute(aNode, NS_ConvertToString("value"), value))
+ if (PR_TRUE == GetAttribute(aNode, mCSSDeclarationKey, property)) {
+ if (PR_TRUE == GetAttribute(aNode, mGenericKey, value))
{
if (mCSSDeclarationCount != 0)
- mBuffer.AppendWithConversion(";");
- mBuffer.AppendWithConversion(" ");
+ mBuffer.Append(";");
+ mBuffer.Append(" ");
mBuffer.Append(property);
- mBuffer.AppendWithConversion(": ");
+ mBuffer.Append(": ");
mBuffer.Append(value);
mCSSDeclarationCount++;
}
+ }
+ return NS_OK;
}
+
+/*******************************
+ * ----- CSS Methods Ends------*
+ *******************************/
\ No newline at end of file
diff --git a/mozilla/htmlparser/src/nsXIFDTD.h b/mozilla/htmlparser/src/nsXIFDTD.h
index 51e69035422..90c73b6f01e 100644
--- a/mozilla/htmlparser/src/nsXIFDTD.h
+++ b/mozilla/htmlparser/src/nsXIFDTD.h
@@ -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;
};
diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp
index ea934d671ba..04e90de92d4 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp
@@ -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(0mUseCount)) {
-
- 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 "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);
}
diff --git a/mozilla/parser/htmlparser/src/CNavDTD.h b/mozilla/parser/htmlparser/src/CNavDTD.h
index 0b5f4d3ea8a..65439ac5d6e 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.h
+++ b/mozilla/parser/htmlparser/src/CNavDTD.h
@@ -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)
diff --git a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp
index e376561a682..ef762c6854f 100644
--- a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp
+++ b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp
@@ -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(0GetTokenRecycler();
+ mParser=(nsParser*)aParser;
- while (NS_SUCCEEDED(result))
- {
- CToken* theToken=mTokenizer->PopToken();
- if(theToken) {
- result=HandleToken(theToken,aParser);
- if (NS_SUCCEEDED(result)) {
- theRecycler->RecycleToken(theToken);
- }
- else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
- mTokenizer->PushTokenFront(theToken);
- }
- // theRootDTD->Verify(kEmptyString,aParser);
+ if(mTokenizer) {
+
+ mTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
+ result=mXIFContext->GetNodeRecycler(mNodeRecycler);
+
+ if(NS_FAILED(result)) return result;
+
+ if(mSink) {
+ while(NS_SUCCEEDED(result)){
+ if(mDTDState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
+ CToken* theToken=mTokenizer->PopToken();
+ if(theToken) {
+ result=HandleToken(theToken,aParser);
+ }
+ else break;
+ }
+ else {
+ result=mDTDState;
+ break;
+ }
+ }//while
+ mTokenizer=oldTokenizer;
}
- else break;
- }//while
- mTokenizer=oldTokenizer;
+ }
}
else result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
return result;
@@ -428,143 +443,165 @@ nsresult nsXIFDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPars
return result;
}
+/**
+ * Do preprocessing on the token
+ *
+ * @update harishd 04/06/00
+ * @param aType - Set the appropriate type.
+ * @param aToken - The type of the token..
+ * @return
+ */
+nsresult nsXIFDTD::WillHandleToken(CToken* aToken,eHTMLTokenTypes& aType) {
+ NS_ASSERTION(aToken!=nsnull,"invalid token");
+
+ nsresult result=NS_OK;
+ if(aToken) {
+ aType=eHTMLTokenTypes(aToken->GetTokenType());
+ eXIFTags theNewType = eXIFTag_userdefined;
+
+ if((eToken_start==aType) || (eToken_end==aType)) {
+ nsString& name = aToken->GetStringValueXXX();
+ theNewType=DetermineXIFTagType(name);
+ if (theNewType != eXIFTag_userdefined) {
+ aToken->SetTypeID(theNewType);
+ }
+ }
+ }
+ return NS_OK;
+}
/**
* This big dispatch method is used to route token handler calls to the right place.
* What's wrong with it? This table, and the dispatch methods themselves need to be
* moved over to the delegate. Ah, so much to do...
*
- * @update gpk 06/18/98
+ * @update harishd 04/06/00
* @param aType
* @param aToken
* @param aParser
* @return
*/
-nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
- nsresult result=NS_OK;
-
- mParser=(nsParser*)aParser;
- mSink=(nsIHTMLContentSink*)aParser->GetContentSink(); //this can change in the parser between calls.
+nsresult nsXIFDTD::HandleToken(CToken* aToken,nsIParser* aParser){
+ nsresult result=NS_OK;
if(aToken) {
- CHTMLToken* theToken= (CHTMLToken*)(aToken);
- eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
-
- eXIFTags type = eXIFTag_userdefined;
- if((eToken_start==theType) || (eToken_end==theType)) {
- nsString& name = aToken->GetStringValueXXX();
- type=DetermineXIFTagType(name);
- if (type != eXIFTag_userdefined)
- aToken->SetTypeID(type);
+ eHTMLTokenTypes theType=eToken_unknown;
+ result=WillHandleToken(aToken,theType);
+
+ if(result==NS_OK) {
+
+ aToken->mUseCount=0; //assume every token coming into this system needs recycling.
+
+ switch(theType) {
+ case eToken_text:
+ case eToken_start:
+ case eToken_newline:
+ case eToken_whitespace:
+ result=HandleStartToken(aToken); break;
+ case eToken_end:
+ result=HandleEndToken(aToken); break;
+ default:
+ result=NS_OK;
+ }//switch
+ result=DidHandleToken(aToken);
}
-
- switch(theType) {
- case eToken_start:
- result=HandleStartToken(aToken); break;
- case eToken_end:
- result=HandleEndToken(aToken); break;
- case eToken_comment:
- result=HandleCommentToken(aToken); break;
- case eToken_whitespace:
- result=HandleWhiteSpaceToken(aToken); break;
- case eToken_newline:
- result=HandleWhiteSpaceToken(aToken); break;
- case eToken_text:
- result=HandleTextToken(aToken); break;
- case eToken_attribute:
- result=HandleAttributeToken(aToken); break;
- default:
- result=NS_OK;
- }//switch
-
}//if
return result;
}
-
/**
- * This method gets called when a start token has been
- * encountered in the parse process.
+ * Do postprocessing on the token.
*
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @param aNode -- CParserNode representing this start token
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * @update harishd 04/06/00
+ * @param aToken -
+ * @param aResult -
+ * @return
*/
-nsresult nsXIFDTD::HandleWhiteSpaceToken(CToken* aToken) {
- NS_PRECONDITION(0!=aToken,kNullToken);
- //CStartToken* st = (CStartToken*)(aToken);
+nsresult nsXIFDTD::DidHandleToken(CToken* aToken, nsresult aResult) {
+ NS_ASSERTION(mTokenRecycler!=nsnull,"We need a recycler");
+ nsresult result=aResult;
+ if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
+ if(aToken) {
+ if(0>=aToken->mUseCount)
+ if(mTokenRecycler) mTokenRecycler->RecycleToken(aToken);
+ }
+ }
+ else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
+ mDTDState=result;
+ else result=NS_OK;
- //Begin by gathering up attributes...
- nsCParserNode node((CHTMLToken*)aToken);
- PRInt16 attrCount=aToken->GetAttributeCount();
- nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(node,attrCount);
-
- if (NS_SUCCEEDED(result))
- {
- if (mInContent == PR_TRUE)
- mSink->AddLeaf(node);
- }
return result;
}
/**
- * This method gets called when a start token has been
- * encountered in the parse process.
- *
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @param aNode -- CParserNode representing this start token
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * Call this method to open the top most node in the stack
+ * It also prevents the node from opening up twice
+ *
+ * harishd 04/10/00
+ * @param - nil
*/
-nsresult nsXIFDTD::HandleTextToken(CToken* aToken) {
- NS_PRECONDITION(0!=aToken,kNullToken);
-
- CStartToken* st = (CStartToken*)(aToken);
- eXIFTags type =(eXIFTags)st->GetTypeID();
- nsCParserNode node((CHTMLToken*)aToken);
-
- nsresult result = NS_OK;
-
- if (type == eXIFTag_text)
- {
- nsString& temp = aToken->GetStringValueXXX();
-
- if (!temp.EqualsWithConversion(""))
- {
- result= AddLeaf(node);
+nsresult nsXIFDTD::PreprocessStack(void) {
+ nsresult result=NS_OK;
+ nsCParserNode* theNode=(nsCParserNode*)mXIFContext->PeekNode();
+
+ if(theNode){
+ // mUseCount = 0 ---> Node is not on the internal stack
+ // mUseCount = 1 ---> Node is on the internal stack and can be passed to the sink.
+ // mUseCount = 2 ---> Node passed to the sink already so don't open once again.
+ if(theNode->mUseCount==1) {
+ eHTMLTags theTag=(theNode->mToken)? (eHTMLTags)theNode->mToken->GetTypeID():eHTMLTag_unknown;
+ if(theTag!=eHTMLTag_unknown) {
+ if(IsHTMLContainer(theTag)) {
+ result=mSink->OpenContainer(*theNode);
+ }
+ else {
+ result=mSink->AddLeaf(*theNode);
+ }
+ }
+ theNode->mUseCount++; // This will make sure that the node is not opened twice.
}
}
+
return result;
}
+/**
+ * Closes the top most contaier node on the internal stack..
+ *
+ * @update harishd 04/12/00
+ * @param aToken -
+ * @param aTag - The tag that might require preprocessing.
+ * @param aNode - The node to be handled
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
+ */
-void nsXIFDTD::AddAttribute(nsIParserNode& aNode) {
- nsIParserNode* top = PeekNode();
- if (top != nsnull)
- {
- nsString key;
- nsString value;
- PRBool hasValue;
+nsresult nsXIFDTD::WillHandleStartToken(CToken* aToken, eXIFTags aTag, nsIParserNode& aNode) {
+ nsresult result=NS_OK;
- hasValue = GetAttributePair(aNode,key,value);
- // XXX should we still be calling AddAttribute if hasValue is false?
- CAttributeToken* attribute = new CAttributeToken(key,value);
- ((nsCParserNode*)top)->AddAttribute(attribute);
+ switch(aTag) {
+ case eXIFTag_leaf:
+ case eXIFTag_comment:
+ case eXIFTag_entity:
+ case eXIFTag_container:
+ result=PreprocessStack(); // Pass the topmost node to the sink ( if it hasn't been yet ).
+ break;
+ default:
+ break;
}
-}
+ return result;
+}
/**
* This method gets called when a start token has been
* encountered in the parse process.
*
- * @update gess 12/28/98
+ * @update harishd 04/12/00
* @param aToken -- next (start) token to be handled
* @param aNode -- CParserNode representing this start token
* @return PR_TRUE if all went well; PR_FALSE if error occured
@@ -576,166 +613,265 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
eXIFTags type =(eXIFTags)st->GetTypeID();
//Begin by gathering up attributes...
- nsCParserNode node = ((CHTMLToken*)aToken);
+ nsCParserNode* node=mNodeRecycler->CreateNode();
+ node->Init(aToken,mLineNumber,mTokenRecycler);
+
PRInt16 attrCount=aToken->GetAttributeCount();
- nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(node,attrCount);
+ nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(*node,attrCount);
if (NS_SUCCEEDED(result))
{
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- StartTopOfStack();
- result = OpenContainer(node);
- break;
- case eXIFTag_comment:
- result=CollectContentComment(aToken,node);
- break;
- case eXIFTag_entity:
- StartTopOfStack();
- ProcessEntityTag(node);
- break;
-
- case eXIFTag_content:
- StartTopOfStack();
- mInContent = PR_TRUE;
- break;
-
- case eXIFTag_encode:
- ProcessEncodeTag(node);
- break;
-
- case eXIFTag_attr:
- AddAttribute(node);
- break;
-
- case eXIFTag_css_stylesheet:
- StartTopOfStack();
- BeginCSSStyleSheet(node);
- break;
-
- case eXIFTag_css_rule:
- BeginCSSStyleRule(node);
- break;
-
- case eXIFTag_css_selector:
- AddCSSSelector(node);
- break;
-
- case eXIFTag_css_declaration_list:
- BeginCSSDeclarationList(node);
- break;
-
- case eXIFTag_css_declaration:
- AddCSSDeclaration(node);
- break;
-
- case eXIFTag_document_info:
- // This is XIF only tag. For HTML it's userdefined.
- node.mToken->SetTypeID(eHTMLTag_userdefined);
- // fall through to call OpenContainer:
-
- case eXIFTag_markupDecl:
- mSink->OpenContainer(node);
- break;
-
- default:
- break;
+ result=WillHandleStartToken(aToken,type,*node);
+ if(NS_SUCCEEDED(result)) {
+ switch (type)
+ {
+ case eXIFTag_attr:
+ result=HandleAttributeToken(aToken,*node);
+ break;
+ case eXIFTag_comment:
+ result=HandleCommentToken(aToken,*node);
+ break;
+ case eXIFTag_content:
+ mInContent=PR_TRUE;
+ break;
+ case eXIFTag_encode:
+ ProcessEncodeTag(*node);
+ break;
+ case eXIFTag_entity:
+ ProcessEntityTag(*node);
+ break;
+ case eXIFTag_markupDecl:
+ mXIFContext->Push(node);
+ break;
+ case eXIFTag_document_info:
+ // This is XIF only tag. For HTML it's userdefined.
+ node->mToken->SetTypeID(eHTMLTag_userdefined);
+ result=mSink->OpenContainer(*node);
+ break;
+ default:
+ result=HandleDefaultToken(aToken,*node);
+ break;
+ }
}
- }
+ }
+
+ mNodeRecycler->RecycleNode(node,mTokenRecycler);
return result;
}
-
/**
- * This method gets called when an end token has been
- * encountered in the parse process. If the end tag matches
- * the start tag on the stack, then simply close it. Otherwise,
- * we have a erroneous state condition. This can be because we
- * have a close tag with no prior open tag (user error) or because
- * we screwed something up in the parse process. I'm not sure
- * yet how to tell the difference.
- *
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * This method determines if the token should be processed as
+ * a contianer or as a leaf. Also determines if the token can
+ * can be handled or not.
+ *
+ * @update harishd 04/12/00
+ * @param aToken - The start token.
+ * @param aNode - The container node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
-nsresult nsXIFDTD::HandleEndToken(CToken* aToken) {
- NS_PRECONDITION(0!=aToken,kNullToken);
- nsresult result = NS_OK;
- CEndToken* et = (CEndToken*)(aToken);
- eXIFTags tokenTagType = (eXIFTags)et->GetTypeID();
- nsCParserNode node = ((CHTMLToken*)aToken);
+nsresult nsXIFDTD::HandleDefaultToken(CToken* aToken,nsIParserNode& aNode) {
+ nsresult result=NS_OK;
- switch (tokenTagType)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- StartTopOfStack();
- result=CloseContainer(node);
- break;
-
- case eXIFTag_content:
- mInContent = PR_FALSE;
- break;
-
- case eXIFTag_css_stylesheet:
- mInContent = PR_FALSE;
- EndCSSStyleSheet(node);
- break;
-
- case eXIFTag_css_rule:
- mInContent = PR_FALSE;
- EndCSSStyleRule(node);
- break;
-
- case eXIFTag_css_declaration_list:
- mInContent = PR_FALSE;
- EndCSSDeclarationList(node);
- break;
-
- case eXIFTag_markupDecl:
- mSink->CloseContainer(node);
-
- default:
- break;
+ PRBool isConainer;
+ eXIFTags theTag=(eXIFTags)aToken->GetTypeID();
+
+ // First find out if the tag can be handled or not....
+ // because there are a few tags that do not belong to HTML
+ if(CanHandleDefaultTag(theTag,isConainer)) {
+ if(isConainer) {
+ result=HandleContainer(aNode);
+ }
+ else {
+ result=AddLeaf(aNode);
+ }
}
return result;
}
/**
- * This method gets called when a comment token has been
- * encountered in the parse process. After making sure
- * we're somewhere in the body, we handle the comment
- * in the same code that we use for text.
+ * This method gets called when container needs to be processed.
+ * It collects the actual name ( html equivalent ), which resides as an
+ * attribute on the node, of the container and reinitializes the node
+ * with the new name
*
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
- * @return PR_TRUE if all went well; PR_FALSE if error occured
+ * @update harishd 04/12/00
+ * @param aNode -- The container node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
-nsresult nsXIFDTD::HandleCommentToken(CToken* aToken) {
+
+nsresult nsXIFDTD::HandleContainer(nsIParserNode& aNode) {
+
+ nsCParserNode* theNode=(nsCParserNode*)&aNode;
+
+ NS_ASSERTION(theNode!=nsnull,"need a node to process");
+
+ nsresult result=NS_OK;
+
+ if(theNode) {
+ nsAutoString theTagName;
+ eHTMLTags theTagID;
+
+ if(theNode->mToken) {
+ // The attribute key is "isa" ( mContainerKey )
+ // The attribute value is the TAG name.
+ GetAttribute(aNode,mContainerKey,theTagName);
+
+ theTagID=nsHTMLTags::LookupTag(theTagName);
+
+ theNode->mToken->Reinitialize(theTagID,theTagName);
+ theNode->Init(theNode->mToken,0,mTokenRecycler);
+ }
+ mXIFContext->Push(&aNode);
+ }
+ return result;
+}
+
+/**
+ * This method does a couple of jobs.
+ * a) Determines if the tag could be handled or not
+ * b) Determins if the tag is a container
+ *
+ * @update harishd 04/12/00
+ * @param aTag - The tag in question
+ * @param aIsConainer - 0 if non-container, 1 if conainer, -1 if unknown
+ * @return - TRUE if the tag can be handled
+ */
+
+PRBool nsXIFDTD::CanHandleDefaultTag(eXIFTags aTag,PRInt32& aIsContainer) {
+ PRBool result=PR_TRUE;
+
+ switch(aTag) {
+ case eXIFTag_newline:
+ case eXIFTag_whitespace:
+ case eXIFTag_text:
+ aIsContainer=0; // it's a leaf
+ break;
+ case eXIFTag_leaf:
+ case eXIFTag_container:
+ aIsContainer=1; // it's a conainer
+ break;
+ default:
+ aIsContainer=-1; // unknown state
+ result=PR_FALSE; // don't know how to handle this tag...
+ break;
+ }
+ return result;
+}
+
+/**
+ * This method gets called when an end token has been
+ * encountered in the parse process. If the end tag matches
+ * the start tag on the stack, then simply close it.
+ *
+ * @update harishd 04/12/00
+ * @param aToken -- next (end) token to be handled
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
+ */
+nsresult nsXIFDTD::HandleEndToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,kNullToken);
- return NS_OK;
+
+ nsresult result =NS_OK;
+ eXIFTags theTag =(eXIFTags)aToken->GetTypeID();
+ nsCParserNode* theNode =(nsCParserNode*)mXIFContext->PeekNode();
+
+ if(NS_SUCCEEDED(result)) {
+ switch (theTag)
+ {
+ case eXIFTag_leaf:
+ case eXIFTag_container:
+ case eXIFTag_markupDecl:
+ result=CloseContainer(*theNode);
+ break;
+ case eXIFTag_content:
+ mInContent=PR_FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+ return result;
+}
+
+/**
+ * Consumes contents of a comment in one gulp.
+ *
+ * @update harishd 10/05/99
+ * @param aNode - node to consume comment
+ * @param aToken - a comment token
+ * @return Error condition.
+ */
+
+nsresult nsXIFDTD::HandleCommentToken(CToken* aToken, nsIParserNode& aNode) {
+ NS_PRECONDITION(aToken!=nsnull,"empty token");
+
+ nsresult result=NS_OK;
+ CToken* token=nsnull;
+ eHTMLTokenTypes type=(eHTMLTokenTypes)aToken->GetTokenType();
+
+ if(type==eToken_start) {
+ nsITokenRecycler* recycler=(mTokenizer)? mTokenizer->GetTokenRecycler():nsnull;
+ if(recycler) {
+ nsAutoString fragment;
+ PRBool done=PR_FALSE;
+ PRBool inContent=PR_FALSE;
+ nsString& comment=aToken->GetStringValueXXX();
+ comment.AssignWithConversion("");
+ result=(mSink)? mSink->AddComment(aNode):NS_OK;
+ done=PR_TRUE;
+ }
+ else {
+ if(inContent) comment.Append(fragment);
+ }
+ recycler->RecycleToken(token);
+ }
+ }
+ }
+ return result;
}
/**
* This method gets called when an attribute token has been
- * encountered in the parse process. This is an error, since
- * all attributes should have been accounted for in the prior
- * start or end tokens
+ * encountered in the parse process.
*
- * @update gpk 06/18/98
- * @param aToken -- next (start) token to be handled
+ * @update harishd 04/10/00
+ * @param aToken -- the attribute token to be handled
* @return PR_TRUE if all went well; PR_FALSE if error occured
*/
-nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken) {
- //CAttributeToken* at = (CAttributeToken*)(aToken);
+nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken,nsIParserNode& aNode) {
NS_PRECONDITION(0!=aToken,kNullToken);
- NS_ERROR("attribute encountered -- this shouldn't happen!");
nsresult result=NS_OK;
+ nsCParserNode* thePeekNode=(nsCParserNode*)mXIFContext->PeekNode();
+
+ if(thePeekNode) {
+ nsAutoString theKey;
+ nsAutoString theValue;
+
+ PRBool hasValue=GetAttributePair(aNode,theKey,theValue);
+
+ if(hasValue) {
+ CToken* attribute = mTokenRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,theValue);
+ nsString& key=((CAttributeToken*)attribute)->GetKey();
+ key=theKey; // set the new key on the attribute..
+ thePeekNode->AddAttribute(attribute);
+ }
+ }
return result;
}
@@ -752,8 +888,7 @@ nsresult nsXIFDTD::HandleAttributeToken(CToken* aToken) {
* @return PR_TRUE if given tag can contain other tags
*/
PRBool nsXIFDTD::IsContainer(PRInt32 aTag) const{
- PRBool result=PR_FALSE;
- return result;
+ return PR_TRUE;
}
@@ -804,8 +939,9 @@ NS_IMETHODIMP nsXIFDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32*
* @param aTag -- tag to test for containership
* @return PR_TRUE if given tag can contain other tags
*/
+
PRBool nsXIFDTD::IsHTMLContainer(eHTMLTags aTag) const {
- PRBool result=PR_TRUE; // by default everything is a
+ PRBool result=PR_TRUE; // by default everything is a container
switch(aTag) {
case eHTMLTag_meta:
@@ -815,7 +951,6 @@ PRBool nsXIFDTD::IsHTMLContainer(eHTMLTags aTag) const {
break;
default:
break;
-
}
return result;
}
@@ -883,309 +1018,79 @@ PRBool nsXIFDTD::GetAttributePair(nsIParserNode& aNode, nsString& aKey, nsString
return hasValue;
}
-
-
-
/**
- *
- * @update gess12/28/98
- * @param
- * @return
+ * Closes the top most contaier node on the internal stack..
+ *
+ * @update harishd 04/12/00
+ * @param aNode - The leaf node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
-eHTMLTags nsXIFDTD::GetStartTag(const nsIParserNode& aNode, nsString& aName)
-{
- eXIFTags type = (eXIFTags)aNode.GetNodeType();
- eHTMLTags tag = eHTMLTag_unknown;
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- if (GetAttribute(aNode,NS_ConvertToString("isa"),aName))
- tag = tag = nsHTMLTags::LookupTag(aName);
- break;
-
- case eXIFTag_css_stylesheet:
- aName.AssignWithConversion("style");
- tag = nsHTMLTags::LookupTag(aName);
- break;
-
- default:
- break;
- }
- return tag;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PushHTMLTag(const eHTMLTags aTag, const nsString& aName)
-{
-
- mHTMLTagStack[mHTMLStackPos]=aTag;
- mHTMLNameStack[mHTMLStackPos]=new nsAutoString(aName);
- mHTMLTagStack[++mHTMLStackPos]=eHTMLTag_unknown;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PopHTMLTag(eHTMLTags& aTag, nsString*& aName)
-{
- NS_ASSERTION(mHTMLStackPos > 0,"The stack must not be empty");
-
- aTag = eHTMLTag_unknown;
- if (mHTMLStackPos > 0)
- {
- aTag = mHTMLTagStack[mHTMLStackPos-1];
- aName = mHTMLNameStack[mHTMLStackPos-1];
- mHTMLTagStack[--mHTMLStackPos] = eHTMLTag_unknown;
- }
-}
-
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PushNodeAndToken(nsString& aName)
-{
- CToken* token = new CStartToken(aName);
- nsCParserNode* node = new nsCParserNode(token);
-
- mTokenStack.AppendElement((void*)token);
- mNodeStack.AppendElement((void*)node);
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-nsIParserNode* nsXIFDTD::PeekNode()
-{
- PRInt32 count = mNodeStack.Count()-1;
-
- if (count >= 0)
- return (nsIParserNode*)mNodeStack.ElementAt(mNodeStack.Count()-1);
- return nsnull;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-CToken* nsXIFDTD::PeekToken()
-{
- PRInt32 count = mTokenStack.Count()-1;
- if (count >= 0)
- return (CToken*)mTokenStack.ElementAt(mTokenStack.Count()-1);
- return nsnull;
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::PopAndDelete()
-{
- nsIParserNode* node = PeekNode();
- CToken* token = PeekToken();
-
- if (node != nsnull && token != nsnull)
- {
- mNodeStack.RemoveElement(node);
- mTokenStack.RemoveElement(token);
-
- delete (nsCParserNode*)node;
- delete token;
- }
-}
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-PRBool nsXIFDTD::StartTopOfStack()
-{
- // If something is already on the stack, then
- // emit it and pop it off the stack
- nsIParserNode* top = PeekNode();
- if (top != nsnull)
- {
- eHTMLTags tag = (eHTMLTags)top->GetNodeType();
-
- if (IsHTMLContainer(tag))
- {
- mInContent = PR_TRUE;
- mSink->OpenContainer(*top);
- }
- else
- mSink->AddLeaf(*top);
-
- PopAndDelete();
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-
-
-/**
- *
- * @update gess12/28/98
- * @param
- * @return
- */
-void nsXIFDTD::BeginStartTag(const nsIParserNode& aNode)
-{
- eXIFTags type = (eXIFTags)aNode.GetNodeType();
- eHTMLTags tag;
- nsString tagName;
-
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- tag = GetStartTag(aNode,tagName);
- if (type == eXIFTag_container)
- PushHTMLTag(tag,tagName);
-
-// CToken* token = new CStartToken(tagName);
-// nsCParserNode* node = new nsCParserNode(token);
- PushNodeAndToken(tagName);
- break;
- default:
- break;
- }
-}
-
-// Translate aNode (which has a typeID corresponding to its XIF tag)
-// to the correct node for the sink.
-void nsXIFDTD::AddEndTag(const nsIParserNode& aNode)
-{
- // Get the top the HTML stack
- eHTMLTags tag;
- nsString* name = nsnull;
- PopHTMLTag(tag,name);
-
- // Create a parse node for form this token
- CEndToken token(*name);
- nsCParserNode node(&token);
-
- // close the container
- mSink->CloseContainer(node);
-
- // delete the name
- if (name != nsnull)
- delete name;
-}
-
-// Translate aNode (which has a typeID corresponding to its XIF tag)
-// to the correct node for the sink.
-void nsXIFDTD::AddEndCommentTag(const nsIParserNode& aNode)
-{
- // Make a comment token
- eHTMLTags tag = eHTMLTag_comment;
-
- // Create a parse node for this token
- CEndToken token(tag);
- nsCParserNode node(&token);
-
- // close the container
- mSink->CloseContainer(node);
-}
-
-/**
- * This method does two things: 1st, help construct
- * our own internal model of the content-stack; and
- * 2nd, pass this message on to the sink.
- * @update gpk 06/18/98
- * @param aNode -- next node to be added to model
- * @return TRUE if ok, FALSE if error
- */
-nsresult nsXIFDTD::OpenContainer(const nsIParserNode& aNode)
-{
- NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
-
- nsresult result=NS_OK;
- eXIFTags type =(eXIFTags)aNode.GetNodeType();
-
- switch (type)
- {
- case eXIFTag_container:
- case eXIFTag_leaf:
- BeginStartTag(aNode);
- break;
- default:
- break;
- }
- mContextStack[mContextStackPos++]=type;
-
- return result;
-}
-
-/**
- * This method does two things: 1st, help construct
- * our own internal model of the content-stack; and
- * 2nd, pass this message on to the sink.
- * @update gpk 06/18/98
- * @param aNode -- next node to be removed from our model
- * @return TRUE if ok, FALSE if error
- */
nsresult nsXIFDTD::CloseContainer(const nsIParserNode& aNode)
{
- NS_PRECONDITION(mContextStackPos > 0, kInvalidTagStackPos);
+ nsresult result=NS_OK;
- nsresult result=NS_OK; //was false
- eXIFTags type=(eXIFTags)aNode.GetNodeType();
+ PreprocessStack();
- if (type == eXIFTag_container)
- AddEndTag(aNode);
- else if (type == eXIFTag_comment)
- AddEndCommentTag(aNode);
-
- mContextStack[--mContextStackPos]=eXIFTag_unknown;
-
-
+ nsCParserNode* theNode=(nsCParserNode*)mXIFContext->Pop();
+ if(theNode) {
+ eHTMLTags theTag=(theNode->mToken)? (eHTMLTags)theNode->mToken->GetTypeID():eHTMLTag_unknown;
+
+ // theNode->mUseCount is decremented by one when it's popped out of the
+ // context, i.e. theNode->mUseCount will be 1 after pop. But inorder to
+ // recycle the node, mUseCount should be set to zero...so let's decrement
+ // by one more..
+ theNode->mUseCount--; // Do this to recycle the node...
+ if(IsHTMLContainer(theTag) && theTag!=eHTMLTag_unknown) {
+ result=mSink->CloseContainer(aNode);
+ }
+ mNodeRecycler->RecycleNode(theNode,mTokenRecycler);
+ }
return result;
}
-
/**
- * This method does two things: 1st, help construct
- * our own internal model of the content-stack; and
- * 2nd, pass this message on to the sink.
- * @update gpk 06/18/98
- * @param aNode -- next node to be added to model
- * @return TRUE if ok, FALSE if error
+ * process leaf nodes
+ *
+ * @update harishd 04/12/00
+ * @param aNode - The leaf node
+ * @return NS_OK if all went well; NS_ERROR_XXX if error occured
*/
+
nsresult nsXIFDTD::AddLeaf(const nsIParserNode& aNode)
{
- //eXIFTags type = (eXIFTags)aNode.GetNodeType();
- nsresult result=mSink->AddLeaf(aNode);
+ nsresult result=NS_OK;
+
+ nsCParserNode* theNode=(nsCParserNode*)&aNode;
+
+ if(theNode) {
+ CToken* theToken=((nsCParserNode&)aNode).mToken;
+ eXIFTags theTag=(theToken)? (eXIFTags)theToken->GetTypeID():eXIFTag_unknown;
+ PRBool handled=PR_FALSE;
+
+ switch(theTag) {
+ case eXIFTag_newline:
+ if(mInContent) mLineNumber++;
+ case eXIFTag_whitespace:
+ if(!mInContent) handled=PR_TRUE;
+ break;
+ case eXIFTag_text:
+ if(theToken) {
+ nsString& temp =theToken->GetStringValueXXX();
+ if (temp.Equals("")) handled=PR_TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ if(!handled) {
+ // Handle top node that has not been passed
+ // on to the sink yet.
+ PreprocessStack();
+ result=mSink->AddLeaf(aNode);
+ }
+ }
+
return result;
}
@@ -1277,57 +1182,6 @@ nsresult nsXIFDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount) {
return result;
}
-/**
- * Consumes contents of a comment in one gulp.
- *
- * @update harishd 10/05/99
- * @param aNode - node to consume comment
- * @param aToken - a comment token
- * @return Error condition.
- */
-nsresult nsXIFDTD::CollectContentComment(CToken* aToken, nsCParserNode& aNode) {
- NS_PRECONDITION(aToken!=nsnull,"empty token");
-
- nsresult result=NS_OK;
- CToken* token=nsnull;
- eHTMLTokenTypes type=(eHTMLTokenTypes)aToken->GetTokenType();
-
- if(type==eToken_start) {
- nsITokenRecycler* recycler=(mTokenizer)? mTokenizer->GetTokenRecycler():nsnull;
- if(recycler) {
- nsAutoString fragment;
- PRBool done=PR_FALSE;
- PRBool inContent=PR_FALSE;
- nsString& comment=aToken->GetStringValueXXX();
- comment.AssignWithConversion("");
- result=(mSink)? mSink->AddComment(aNode):NS_OK;
- done=PR_TRUE;
- }
- else {
- if(inContent) comment.Append(fragment);
- }
- recycler->RecycleToken(token);
- }
- }
- }
- return result;
-}
-
/**
*
* @update gpk 06/18/98
@@ -1409,8 +1263,16 @@ void nsXIFDTD::SetURLRef(char * aURLRef)
{
}
-void nsXIFDTD::ProcessEncodeTag(const nsIParserNode& aNode)
+/**
+ *
+ * @update harishd 04/12/00
+ * @param aNode -
+ * @return NS_OK if success.
+ */
+
+nsresult nsXIFDTD::ProcessEncodeTag(const nsIParserNode& aNode)
{
+ nsresult result=NS_OK;
nsString value;
PRInt32 error;
@@ -1419,82 +1281,122 @@ void nsXIFDTD::ProcessEncodeTag(const nsIParserNode& aNode)
PRInt32 temp = value.ToInteger(&error);
if (temp == 1)
{
- mSink->DoFragment(PR_TRUE);
- return;
+ result=mSink->DoFragment(PR_TRUE);
}
}
- mSink->DoFragment(PR_FALSE);
+ result=mSink->DoFragment(PR_FALSE);
+
+ return result;
}
+/**
+ *
+ *
+ * @update harishd 04/12/00
+ * @param aNode - The entity node
+ * @return NS_OK if success.
+ */
-void nsXIFDTD::ProcessEntityTag(const nsIParserNode& aNode)
+nsresult nsXIFDTD::ProcessEntityTag(const nsIParserNode& aNode)
{
+ nsresult result=NS_OK;
nsAutoString value;
+ // Get the entity from the node. This resides as an
+ // attribute on the node.
+ //
+ // XXX - Entities within STYLE and SCRIPT should probably be translated.
+ // Why were we given entities in the first place. Could be a problem in
+ // the XIF converter.
+ // Ex. is being given to us, by the
+ // converter as .
+ // That's totally worng.
if (GetAttribute(aNode,NS_ConvertToString("value"),value)) {
value.AppendWithConversion(';');
- CEntityToken* entity = new CEntityToken(value);
- nsCParserNode node((CToken*)entity);
- mSink->AddLeaf(node);
+ CToken* entity=((nsCParserNode&)aNode).mToken;
+ if(entity) {
+ entity->Reinitialize(eHTMLTag_entity,value);
+ nsCParserNode* thePeekNode=(nsCParserNode*)mXIFContext->PeekNode();
+ if(thePeekNode) {
+ eHTMLTags theTag=(eHTMLTags)thePeekNode->mToken->GetTypeID();
+ if(theTag==eHTMLTag_script || theTag==eHTMLTag_style) {
+ nsAutoString scratch;
+ ((CEntityToken*)entity)->TranslateToUnicodeStr(scratch); // Ex. > would become '<'
+ entity->Reinitialize(eHTMLTag_text,scratch); // Covert type to text and set the translated value.
+ }
+ }
+ ((nsCParserNode&)aNode).Init(entity,mLineNumber,mTokenRecycler);
+ }
+ result=mSink->AddLeaf(aNode);
}
+ return result;
}
-/*** CSS Methods ****/
+/*******************************
+ * ----- CSS Methods Begin-----*
+ * *
+ * XXX - CURRENTLY NOT IN USE *
+ * *
+ *******************************/
-void nsXIFDTD::BeginCSSStyleSheet(const nsIParserNode& aNode)
+nsresult nsXIFDTD::BeginCSSStyleSheet(const nsIParserNode& aNode)
{
- nsString value;
+ nsresult result=NS_OK;
+
PRInt32 error;
+ nsAutoString value;
+ CToken* theToken=((nsCParserNode&)aNode).mToken;
+
+ if(theToken) {
+ theToken->Reinitialize(eHTMLTag_style,"style");
+ mXIFContext->Push(&aNode);
+ }
mBuffer.Truncate(0);
mMaxCSSSelectorWidth = 10;
- if (GetAttribute(aNode,NS_ConvertToString("max_css_selector_width"),value))
+ if (GetAttribute(aNode,mCSSStyleSheetKey,value))
{
PRInt32 temp = value.ToInteger(&error);
if (error == NS_OK)
mMaxCSSSelectorWidth = temp;
}
-
- //const char* name = nsHTMLTags::GetStringValue(eHTMLTag_html);
+ return result;
}
-void nsXIFDTD::EndCSSStyleSheet(const nsIParserNode& aNode)
+nsresult nsXIFDTD::EndCSSStyleSheet(const nsIParserNode& aNode)
{
- nsString tagName(nsHTMLTags::GetStringValue(eHTMLTag_style));
+ nsresult result=NS_OK;
+ nsAutoString tagName(nsHTMLTags::GetStringValue(eHTMLTag_style));
- if (mLowerCaseTags == PR_TRUE)
- tagName.ToLowerCase();
- else
- tagName.ToUpperCase();
-
- CStartToken startToken(tagName);
- nsCParserNode startNode((CToken*)&startToken);
-
- mBuffer.AppendWithConversion("");
+ mBuffer.Append("");
mBuffer.Append(tagName);
- mBuffer.AppendWithConversion(">");
- startNode.SetSkippedContent(mBuffer);
- mSink->AddLeaf(startNode);
-
+ mBuffer.Append(">");
+ ((nsCParserNode&)aNode).SetSkippedContent(mBuffer);
+
+ result=mSink->AddLeaf(aNode);
+ mNodeRecycler->RecycleNode((nsCParserNode*)mXIFContext->Pop());
+ return result;
}
-void nsXIFDTD::BeginCSSStyleRule(const nsIParserNode& aNode)
+nsresult nsXIFDTD::BeginCSSStyleRule(const nsIParserNode& aNode)
{
mCSSDeclarationCount = 0;
- mCSSSelectorCount = 0;
+ mCSSSelectorCount = 0;
+ return NS_OK;
}
-void nsXIFDTD::EndCSSStyleRule(const nsIParserNode& aNode)
+nsresult nsXIFDTD::EndCSSStyleRule(const nsIParserNode& aNode)
{
+ return NS_OK;
}
-void nsXIFDTD::AddCSSSelector(const nsIParserNode& aNode)
+nsresult nsXIFDTD::AddCSSSelector(const nsIParserNode& aNode)
{
- nsString value;
+ nsAutoString value;
- if (GetAttribute(aNode, NS_ConvertToString("selectors"), value))
+ if (GetAttribute(aNode,mCSSSelectorKey, value))
{
if (mLowerCaseAttributes == PR_TRUE)
value.ToLowerCase();
@@ -1502,11 +1404,13 @@ void nsXIFDTD::AddCSSSelector(const nsIParserNode& aNode)
value.ToUpperCase();
value.CompressWhitespace();
mBuffer.Append(value);
- }
+ }
+ return NS_OK;
}
-void nsXIFDTD::BeginCSSDeclarationList(const nsIParserNode& aNode)
+nsresult nsXIFDTD::BeginCSSDeclarationList(const nsIParserNode& aNode)
{
+ nsresult result=NS_OK;
PRInt32 indx = mBuffer.RFindChar('\n');
if (indx == kNotFound)
indx = 0;
@@ -1517,34 +1421,41 @@ void nsXIFDTD::BeginCSSDeclarationList(const nsIParserNode& aNode)
count = 0;
for (PRInt32 i = 0; i < count; i++)
- mBuffer.AppendWithConversion(" ");
+ mBuffer.Append(" ");
- mBuffer.AppendWithConversion(" {");
+ mBuffer.Append(" {");
mCSSDeclarationCount = 0;
-
+ return result;
}
-void nsXIFDTD::EndCSSDeclarationList(const nsIParserNode& aNode)
+nsresult nsXIFDTD::EndCSSDeclarationList(const nsIParserNode& aNode)
{
- mBuffer.AppendWithConversion("}\n");
+ mBuffer.Append("}\n");
+ return NS_OK;
}
-void nsXIFDTD::AddCSSDeclaration(const nsIParserNode& aNode)
+nsresult nsXIFDTD::AddCSSDeclaration(const nsIParserNode& aNode)
{
- nsString property;
- nsString value;
+ nsAutoString property;
+ nsAutoString value;
- if (PR_TRUE == GetAttribute(aNode, NS_ConvertToString("property"), property))
- if (PR_TRUE == GetAttribute(aNode, NS_ConvertToString("value"), value))
+ if (PR_TRUE == GetAttribute(aNode, mCSSDeclarationKey, property)) {
+ if (PR_TRUE == GetAttribute(aNode, mGenericKey, value))
{
if (mCSSDeclarationCount != 0)
- mBuffer.AppendWithConversion(";");
- mBuffer.AppendWithConversion(" ");
+ mBuffer.Append(";");
+ mBuffer.Append(" ");
mBuffer.Append(property);
- mBuffer.AppendWithConversion(": ");
+ mBuffer.Append(": ");
mBuffer.Append(value);
mCSSDeclarationCount++;
}
+ }
+ return NS_OK;
}
+
+/*******************************
+ * ----- CSS Methods Ends------*
+ *******************************/
\ No newline at end of file
diff --git a/mozilla/parser/htmlparser/src/nsXIFDTD.h b/mozilla/parser/htmlparser/src/nsXIFDTD.h
index 51e69035422..90c73b6f01e 100644
--- a/mozilla/parser/htmlparser/src/nsXIFDTD.h
+++ b/mozilla/parser/htmlparser/src/nsXIFDTD.h
@@ -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;
};