Fix for Bugs

13640, 13736 - Memory leaks - R=rickg
1312 - Hooked up XHTML DOCTYPE - R=rickg
7590 - Prematuredly closing <SCRIPT> on seeing </SCRIPTERR>
2749 - Strict comment handling for noquirks mode - R=rickg
14955 - LEGEND inside FIELDSET was causing infinite looping - R=rickg,pollmann
14952 - LABEL got closed on seeing SPAN (LABEL can contain SPAN ) - R=pollmann
15381 - comment handling for XIF and HTML - R=akkana
15346 - Stray end tag caused loading blank document - R=rickg,pollmann
This commit is contained in:
harishd%netscape.com 1999-10-06 19:04:29 +00:00
parent 72ce36baa9
commit 21b3ba1b23
34 changed files with 418 additions and 214 deletions

View File

@ -408,7 +408,8 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString
START_TIMER();
CStartToken theToken(eHTMLTag_html);
nsAutoString theTagName("html");
CStartToken theToken(theTagName,eHTMLTag_html);
HandleStartToken(&theToken);
mSkipTarget=eHTMLTag_unknown;
@ -1203,14 +1204,19 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
if(nsHTMLElement::IsSectionTag(theChildTag)){
switch(theChildTag){
case eHTMLTag_body:
if(mHasOpenBody)
return OpenContainer(*theNode,PR_FALSE);
if(mHasOpenBody) {
result=OpenContainer(*theNode,PR_FALSE);
RecycleNode(theNode);
return result;
}
break;
case eHTMLTag_head:
if(mHadBody || mHadFrameset) {
result=HandleOmittedTag(aToken,theChildTag,theParent,*theNode);
if(result == NS_OK)
if(result == NS_OK) {
RecycleNode(theNode);
return result;
}
}
break;
default:
@ -1430,20 +1436,19 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
if((kNotFound==GetIndexOfChildOrSynonym(mBodyContext->mStack,theChildTag)) ||
(!gHTMLElements[theChildTag].CanAutoCloseTag(mBodyContext->Last()))) {
UpdateStyleStackForCloseTag(theChildTag,theChildTag);
if(gHTMLElements[theChildTag].IsMemberOf(kBlockEntity)) {
if(gHTMLElements[theChildTag].IsMemberOf(kBlockEntity) &&
mParseMode!=eParseMode_noquirks) {
// Oh boy!! we found a "stray" block entity. Nav4.x and IE introduce line break in
// such cases. So, let's simulate that effect for compatibility.
// Ex. <html><body>Hello</P>There</body></html>
#if 0
mTokenizer->PushTokenFront(aToken); //put this end token back...
CHTMLToken* theToken = (CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theChildTag);
mTokenizer->PushTokenFront(theToken); //put this new token onto stack...
#endif
CHTMLToken* theToken = (CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theChildTag);
result=HandleToken(theToken,mParser);
if(!CanOmit(mBodyContext->Last(),theChildTag)) {
mTokenizer->PushTokenFront(aToken); //put this end token back...
aToken->mRecycle=PR_FALSE; // make sure not to recycle this token because it's not used yet!!
CHTMLToken* theToken = (CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theChildTag);
mTokenizer->PushTokenFront(theToken); //put this new token onto stack...
}
}
else return result;
return result;
}
if(result==NS_OK) {
eHTMLTags theTarget=FindAutoCloseTargetForEndTag(theChildTag,mBodyContext->mStack);
@ -1689,20 +1694,17 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
WriteTokenToLog(aToken);
#endif
CParserContext* pc=(mParser)? mParser->PeekContext():nsnull;
if(pc) {
nsString& docTypeStr=aToken->GetStringValueXXX();
mLineNumber += (docTypeStr).CountChar(kNewLine);
docTypeStr.Trim("<!>");
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
nsString& docTypeStr=aToken->GetStringValueXXX();
mLineNumber += (docTypeStr).CountChar(kNewLine);
docTypeStr.Trim("<!>");
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
STOP_TIMER();
STOP_TIMER();
result = (mSink)? mSink->AddDocTypeDecl(theNode,mParseMode):NS_OK;
START_TIMER();
result = (mSink)? mSink->AddDocTypeDecl(theNode, pc->mParseMode):NS_OK;
START_TIMER();
}
return result;
}
@ -1858,7 +1860,8 @@ PRBool CNavDTD::CanPropagate(eHTMLTags aParentTag,eHTMLTags aChildTag) const {
theTempTag=aChildTag;
while(eHTMLTag_unknown!=aChildTag) {
if(parentCanContain){
result=PR_TRUE;
if(!CanOmit(aParentTag,aChildTag))
result=PR_TRUE;
break;
}//if
TagList* theTagList=gHTMLElements[aChildTag].GetRootTags();
@ -2779,7 +2782,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
PRBool done=PR_FALSE;
nsCParserNode* theNode=CreateNode();
CTokenRecycler* theRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
while(!done) {
@ -2993,7 +2995,7 @@ nsITokenRecycler* CNavDTD::GetTokenRecycler(void){
*/
nsITokenizer* CNavDTD::GetTokenizer(void) {
if(!mTokenizer)
mTokenizer=new nsHTMLTokenizer();
mTokenizer=new nsHTMLTokenizer(mParseMode);
return mTokenizer;
}

View File

@ -121,6 +121,7 @@ TagList gFramesetKids={3,eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes};
TagList gHtmlKids={8,eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace};
TagList gHeadKids={9,eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed,eHTMLTag_noscript};
TagList gLabelKids={1,eHTMLTag_span};
TagList gLIKids={2,eHTMLTag_ol,eHTMLTag_ul};
TagList gMapKids={1,eHTMLTag_area};
TagList gNoframesKids={1,eHTMLTag_body};
@ -776,7 +777,7 @@ void InitializeElementTable(void) {
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kFormControl, kInlineEntity, kSelf,
/*special props, prop-range*/ 0,kDefaultPropRange,
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
/*special parents,kids,skip*/ 0,&gLabelKids,eHTMLTag_unknown);
Initialize(
/*tag*/ eHTMLTag_layer,

View File

@ -94,6 +94,10 @@ nsresult nsExpatTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr
return NS_OK;
}
void
nsExpatTokenizer::FreeTokenRecycler(void) {
nsHTMLTokenizer::FreeTokenRecycler();
}
/**
* This method is defined in nsIParser. It is used to

View File

@ -58,6 +58,7 @@ public:
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
virtual void FrontloadMisplacedContent(nsDeque& aDeque);
static void FreeTokenRecycler(void);
protected:

View File

@ -1165,7 +1165,7 @@ nsHTMLContentSinkStream::AddComment(const nsIParserNode& aNode){
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
#endif
Write("<!--");
Write(aNode.GetText());
return NS_OK;
}

View File

@ -70,6 +70,15 @@ nsresult nsHTMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
static CTokenRecycler* gTokenRecycler=0;
void
nsHTMLTokenizer::FreeTokenRecycler(void) {
if(gTokenRecycler) {
delete gTokenRecycler;
gTokenRecycler=0;
}
}
/**
* This method is defined in nsIParser. It is used to
@ -101,13 +110,17 @@ NS_IMPL_RELEASE(nsHTMLTokenizer)
* @param
* @return
*/
nsHTMLTokenizer::nsHTMLTokenizer() : nsITokenizer(), mTokenDeque(0){
nsHTMLTokenizer::nsHTMLTokenizer(PRInt32 aParseMode) : nsITokenizer(),
mTokenDeque(0),
mParseMode(aParseMode)
{
NS_INIT_REFCNT();
mDoXMLEmptyTags=PR_FALSE;
}
/**
* Default constructor
* Destructor
*
* @update gess 4/9/98
* @param
@ -147,7 +160,6 @@ void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,
*/
nsITokenRecycler* nsHTMLTokenizer::GetTokenRecycler(void) {
//let's move to this once we eliminate the leaking of tokens...
static CTokenRecycler* gTokenRecycler=0;
if(!gTokenRecycler)
gTokenRecycler=new CTokenRecycler();
return gTokenRecycler;
@ -391,7 +403,7 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
while((!done) && (result==NS_OK)) {
CToken* theToken= (CAttributeToken*)theRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown);
if(theToken){
result=theToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
result=theToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
//Much as I hate to do this, here's some special case code.
//This handles the case of empty-tags in XML. Our last
@ -472,7 +484,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
aToken=theRecycler->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
if(aToken) {
result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
if(NS_SUCCEEDED(result)) {
AddToken(aToken,result,mTokenDeque,theRecycler);
@ -491,7 +503,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
nsAutoString endTag(nsHTMLTags::GetStringValue(theTag));
endTag.Insert("</",0,2);
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,theTag);
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag); //tell new token to finish consuming text...
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text...
//endTag.Append(">");
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
AddToken(textToken,result,mTokenDeque,theRecycler);
@ -528,7 +540,7 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne
nsresult result=NS_OK;
if(aToken) {
result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
AddToken(aToken,result,mTokenDeque,theRecycler);
} //if
return result;
@ -552,11 +564,11 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
if(NS_OK==result) {
if(nsString::IsAlpha(theChar)) { //handle common enity references &xxx; or &#000.
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
result = aToken->Consume(theChar,aScanner); //tell new token to finish consuming text...
result = aToken->Consume(theChar,aScanner,mParseMode); //tell new token to finish consuming text...
}
else if(kHashsign==theChar) {
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
result=aToken->Consume(theChar,aScanner);
result=aToken->Consume(theChar,aScanner,mParseMode);
}
else {
//oops, we're actually looking at plain text...
@ -597,7 +609,7 @@ nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsSc
aToken = theRecycler->CreateTokenOfType(eToken_whitespace,eHTMLTag_whitespace);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -618,7 +630,7 @@ nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScann
aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -640,7 +652,7 @@ nsresult nsHTMLTokenizer::ConsumeText(const nsString& aString,CToken*& aToken,ns
aToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,aString);
if(aToken) {
PRUnichar ch=0;
result=aToken->Consume(ch,aScanner);
result=aToken->Consume(ch,aScanner,mParseMode);
if(!NS_SUCCEEDED(result)) {
nsString& temp=aToken->GetStringValueXXX();
if(0==temp.Length()){
@ -680,7 +692,7 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n
aToken = theRecycler->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -700,7 +712,7 @@ nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScann
aToken=theRecycler->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -721,7 +733,7 @@ nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*&
aToken=theRecycler->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;

View File

@ -50,7 +50,7 @@
CLASS_EXPORT_HTMLPARS nsHTMLTokenizer : public nsITokenizer {
public:
nsHTMLTokenizer();
nsHTMLTokenizer(PRInt32 aParseMode=eParseMode_quirks);
virtual ~nsHTMLTokenizer();
NS_DECL_ISUPPORTS
@ -68,6 +68,7 @@ public:
virtual PRInt32 GetCount(void);
virtual void PrependTokens(nsDeque& aDeque);
static void FreeTokenRecycler(void);
protected:
@ -88,6 +89,7 @@ protected:
nsDeque mTokenDeque;
PRBool mDoXMLEmptyTags;
PRInt32 mParseMode;
};
extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsIDTD** aInstancePtrResult);

View File

@ -201,7 +201,7 @@ PRBool CStartToken::IsEmpty(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
//if you're here, we've already Consumed the < char, and are
//ready to Consume the rest of the open tag identifier.
@ -291,7 +291,7 @@ CEndToken::CEndToken(const nsString& aName) : CHTMLToken(aName) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
//if you're here, we've already Consumed the <! chars, and are
//ready to Consume the rest of the open tag identifier.
//Stop consuming as soon as you see a space or a '>'.
@ -436,7 +436,7 @@ PRInt32 CTextToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
static const char* theTerminals="\n\r&<";
nsresult result=NS_OK;
PRBool done=PR_FALSE;
@ -478,7 +478,7 @@ nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString){
nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString,PRInt32 aMode){
PRBool done=PR_FALSE;
nsresult result=NS_OK;
PRUnichar theChar;
@ -503,7 +503,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
if((NS_OK==result) && (kExclamation==theChar) && (PR_FALSE==aIgnoreComments)) {
//read a comment...
static CCommentToken theComment;
result=theComment.Consume(aChar,aScanner);
result=theComment.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
//result=aScanner.SkipWhitespace();
mTextValue.Append(theComment.GetStringValueXXX());
@ -517,7 +517,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
}
else if(('\b'==theChar) || ('\t'==theChar) || (' '==theChar)) {
static CWhitespaceToken theWS;
result=theWS.Consume(aChar,aScanner);
result=theWS.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
mTextValue.Append(theWS.GetStringValueXXX());
}
@ -528,8 +528,16 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
}
mTextValue.Right(theRight,termStrLen+10); //first, get a wad of chars from the temp string
rpos=theRight.RFindChar('<'); //now scan for the '<'
if(-1<rpos)
if(-1<rpos) {
rpos=theRight.RFind(aTerminalString,PR_TRUE);
if(-1<rpos && aMode!=eParseMode_noquirks) {
nsAutoString temp(theRight);
temp.Cut(0,rpos);
temp.StripWhitespace();
PRUnichar ch=temp.CharAt(aTerminalString.Length());
rpos=(ch==kGreaterThan)? rpos:kNotFound;
}
}
done=PRBool(-1<rpos);
} //while
if(NS_SUCCEEDED(result)) {
@ -596,7 +604,7 @@ PRInt32 CCDATASectionToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
static const char* theTerminals="\r]";
nsresult result=NS_OK;
PRBool done=PR_FALSE;
@ -843,9 +851,9 @@ nsresult ConsumeComment(PRUnichar aChar, nsScanner& aScanner,nsString& aString)
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
PRBool theStrictForm=PR_FALSE;
nsresult result=(theStrictForm) ? ConsumeStrictComment(aChar,aScanner,mTextValue) : ConsumeComment(aChar,aScanner,mTextValue);
nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
nsresult result=(aMode==eParseMode_noquirks) ? ConsumeStrictComment(aChar,aScanner,mTextValue)
: ConsumeComment(aChar,aScanner,mTextValue);
#if 0
if(NS_OK==result) {
@ -949,7 +957,7 @@ nsString& CNewlineToken::GetStringValueXXX(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
mTextValue=aChar;
//we already read the \r or \n, let's see what's next!
@ -1169,7 +1177,7 @@ nsresult ConsumeAttributeValueText(PRUnichar,nsString& aString,nsScanner& aScann
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
nsresult result=aScanner.SkipWhitespace(); //skip leading whitespace
if(NS_OK==result) {
@ -1340,7 +1348,7 @@ PRInt32 CWhitespaceToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
mTextValue=aChar;
nsresult result=aScanner.ReadWhitespace(mTextValue);
if(NS_OK==result) {
@ -1384,7 +1392,7 @@ CEntityToken::CEntityToken(const nsString& aName) : CHTMLToken(aName) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CEntityToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CEntityToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
if(aChar)
mTextValue=aChar;
nsresult result=ConsumeEntity(aChar,mTextValue,aScanner);
@ -1696,7 +1704,7 @@ PRInt32 CSkippedContentToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode) {
PRBool done=PR_FALSE;
nsresult result=NS_OK;
nsString temp;
@ -1715,7 +1723,7 @@ nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
if((NS_OK==result) && (kExclamation==theChar)) {
//read a comment...
static CCommentToken theComment;
result=theComment.Consume(aChar,aScanner);
result=theComment.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
//result=aScanner.SkipWhitespace();
temp.Append(theComment.GetStringValueXXX());
@ -1729,7 +1737,7 @@ nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
}
else if(('\b'==theChar) || ('\t'==theChar) || (' '==theChar)) {
static CWhitespaceToken theWS;
result=theWS.Consume(aChar,aScanner);
result=theWS.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
temp.Append(theWS.GetStringValueXXX());
}
@ -1818,7 +1826,7 @@ CInstructionToken::CInstructionToken(const nsString& aString) : CHTMLToken(aStri
* @param
* @return
*/
nsresult CInstructionToken::Consume(PRUnichar aChar,nsScanner& aScanner){
nsresult CInstructionToken::Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode){
mTextValue="<?";
nsresult result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
return result;
@ -1879,7 +1887,7 @@ const nsParserError * CErrorToken::GetError(void)
CDoctypeDeclToken::CDoctypeDeclToken() : CHTMLToken(eHTMLTag_unknown) {
}
nsresult CDoctypeDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CDoctypeDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
return ConsumeComment(aChar,aScanner,mTextValue);
}

View File

@ -111,7 +111,7 @@ class CStartToken: public CHTMLToken {
public:
CStartToken(eHTMLTags aTag);
CStartToken(nsString& aName,eHTMLTags aTag=eHTMLTag_unknown);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual PRInt32 GetTypeID(void);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
@ -142,7 +142,7 @@ class CEndToken: public CHTMLToken {
public:
CEndToken(eHTMLTags aTag);
CEndToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual PRInt32 GetTypeID(void);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
@ -163,7 +163,7 @@ class CCommentToken: public CHTMLToken {
public:
CCommentToken();
CCommentToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
char mLeadingChar;
@ -184,7 +184,7 @@ class CEntityToken : public CHTMLToken {
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
PRInt32 TranslateToUnicodeStr(nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
static PRInt32 ConsumeEntity(PRUnichar aChar,nsString& aString,nsScanner& aScanner);
static PRInt32 TranslateToUnicodeStr(PRInt32 aValue,nsString& aString);
virtual void DebugDumpSource(nsOutputStream& out);
@ -203,7 +203,7 @@ class CWhitespaceToken: public CHTMLToken {
public:
CWhitespaceToken();
CWhitespaceToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -219,8 +219,8 @@ class CTextToken: public CHTMLToken {
public:
CTextToken();
CTextToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
nsresult ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
nsresult ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -237,7 +237,7 @@ class CCDATASectionToken : public CHTMLToken {
public:
CCDATASectionToken();
CCDATASectionToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -257,7 +257,7 @@ class CAttributeToken: public CHTMLToken {
CAttributeToken();
CAttributeToken(const nsString& aString);
CAttributeToken(const nsString& aKey, const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
virtual nsString& GetKey(void) {return mTextKey;}
@ -283,7 +283,7 @@ class CNewlineToken: public CHTMLToken {
public:
CNewlineToken();
CNewlineToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
virtual nsString& GetStringValueXXX(void);
@ -336,7 +336,7 @@ class CStyleToken: public CHTMLToken {
class CSkippedContentToken: public CAttributeToken {
public:
CSkippedContentToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
virtual void DebugDumpSource(nsOutputStream& out);
@ -356,7 +356,7 @@ class CInstructionToken: public CHTMLToken {
public:
CInstructionToken();
CInstructionToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -388,7 +388,7 @@ protected:
class CDoctypeDeclToken: public CHTMLToken {
public:
CDoctypeDeclToken();
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};

View File

@ -460,26 +460,41 @@ eParseMode DetermineParseMode(nsParser& aParser) {
theBufCopy.StripWhitespace();
PRInt32 theSubIndex=theBufCopy.FindChar(kGreaterThan,theIndex+1);
theBufCopy.Truncate(theSubIndex);
theSubIndex=theBufCopy.Find("HTML4.0",PR_TRUE,theIndex+8);
if(kNotFound<theSubIndex) {
if(theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex)>kNotFound)
return eParseMode_quirks;
else if((theBufCopy.Find("FRAMESET",PR_TRUE,theSubIndex)>kNotFound) ||
(theBufCopy.Find("LATIN1", PR_TRUE,theSubIndex) >kNotFound) ||
(theBufCopy.Find("SYMBOLS",PR_TRUE,theSubIndex) >kNotFound) ||
(theBufCopy.Find("SPECIAL",PR_TRUE,theSubIndex) >kNotFound))
return eParseMode_quirks; // XXX -HACK- Set the appropriate mode.
else
return eParseMode_noquirks;
}
theSubIndex=theBufCopy.Find("ISO/IEC15445:1999",PR_TRUE,theIndex+8);
theSubIndex=theBufCopy.Find("-//W3C//DTD",PR_TRUE,theIndex+8);
if(kNotFound<theSubIndex) {
if(kNotFound<(theSubIndex=theBufCopy.Find("HTML4.0",PR_TRUE,theSubIndex+11))) {
PRUnichar num=theBufCopy.CharAt(theSubIndex+7);
if(num > '0' && num < '9') {
if(theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex+7)>kNotFound)
return eParseMode_noquirks; // XXX - investigate this more.
}
if((theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex+7)>kNotFound)||
(theBufCopy.Find("FRAMESET",PR_TRUE,theSubIndex+7)>kNotFound) ||
(theBufCopy.Find("LATIN1", PR_TRUE,theSubIndex+7) >kNotFound) ||
(theBufCopy.Find("SYMBOLS",PR_TRUE,theSubIndex+7) >kNotFound) ||
(theBufCopy.Find("SPECIAL",PR_TRUE,theSubIndex+7) >kNotFound))
return eParseMode_quirks; // XXX -HACK- Set the appropriate mode.
else
return eParseMode_noquirks;
}else
if(kNotFound<(theSubIndex=theBufCopy.Find("XHTML",PR_TRUE,theSubIndex+11))) {
if((theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex)>kNotFound)||
(theBufCopy.Find("STRICT",PR_TRUE,theSubIndex) >kNotFound) ||
(theBufCopy.Find("FRAMESET",PR_TRUE,theSubIndex) >kNotFound))
return eParseMode_noquirks;
else
return eParseMode_quirks;
}
}else
if(kNotFound<(theSubIndex=theBufCopy.Find("ISO/IEC15445:1999",PR_TRUE,theIndex+8))) {
theSubIndex=theBufCopy.Find("HTML",PR_TRUE,theSubIndex+18);
if(kNotFound==theSubIndex)
theSubIndex=theBufCopy.Find("HYPERTEXTMARKUPLANGUAGE",PR_TRUE,theSubIndex+18);
return eParseMode_noquirks;
}
}
}else
if(kNotFound<(theIndex=theBufCopy.Find("?XML",PR_TRUE)))
return eParseMode_noquirks;
theIndex=theBufCopy.Find("NOQUIRKS",PR_TRUE);
if(kNotFound<theIndex) {

View File

@ -28,6 +28,9 @@
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLToTXTSinkStream.h"
#include "nsHTMLEntities.h"
#include "nsHTMLTokenizer.h"
#include "nsXMLTokenizer.h"
#include "nsExpatTokenizer.h"
#include "nsIParserService.h"
static NS_DEFINE_IID(kIParserServiceIID, NS_IPARSERSERVICE_IID);
@ -181,6 +184,9 @@ nsParserModule::Shutdown()
if (mInitialized) {
nsHTMLTags::ReleaseTable();
nsHTMLEntities::ReleaseTable();
nsHTMLTokenizer::FreeTokenRecycler();
nsXMLTokenizer::FreeTokenRecycler();
nsExpatTokenizer::FreeTokenRecycler();
mInitialized = PR_FALSE;
}
}

View File

@ -114,7 +114,7 @@ void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
* @param aScanner -- object to retrieve data from
* @return int error code
*/
nsresult CToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
nsresult CToken::Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode) {
nsresult result=NS_OK;
return result;
}

View File

@ -160,7 +160,7 @@ class CToken {
* @param aScanner -- input source where token should get data
* @return error code (0 means ok)
*/
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
/**
* Causes token to dump itself in debug form to given output stream

View File

@ -648,11 +648,12 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
{
case eXIFTag_container:
case eXIFTag_leaf:
case eXIFTag_comment:
StartTopOfStack();
result = OpenContainer(node);
break;
case eXIFTag_comment:
result=CollectContentComment(aToken,node);
break;
case eXIFTag_entity:
StartTopOfStack();
ProcessEntityTag(node);
@ -741,10 +742,6 @@ nsresult nsXIFDTD::HandleEndToken(CToken* aToken) {
case eXIFTag_content:
mInContent = PR_FALSE;
break;
case eXIFTag_comment:
CloseContainer(node);
break;
case eXIFTag_css_stylesheet:
mInContent = PR_FALSE;
@ -1462,9 +1459,6 @@ nsresult nsXIFDTD::OpenContainer(const nsIParserNode& aNode)
case eXIFTag_leaf:
BeginStartTag(aNode);
break;
case eXIFTag_comment:
mSink->AddComment(aNode);
break;
default:
break;
}
@ -1612,6 +1606,56 @@ 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="<!--"; // overwrite comment with "<!--"
while (!done && NS_SUCCEEDED(result))
{
token=mTokenizer->PopToken();
if(!token) return result;
type=(eHTMLTokenTypes)token->GetTokenType();
fragment=token->GetStringValueXXX();
if(fragment=="content") {
if(type==eToken_start)
inContent=PR_TRUE;
else inContent=PR_FALSE;
}
else if(fragment=="comment") {
comment.Append("-->");
result=(mSink)? mSink->AddComment(aNode):NS_OK;
done=PR_TRUE;
}
else {
if(inContent) comment.Append(fragment);
}
recycler->RecycleToken(token);
}
}
}
return result;
}
/**
*

View File

@ -550,6 +550,7 @@ protected:
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;

View File

@ -74,6 +74,10 @@ nsresult nsXMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
void
nsXMLTokenizer::FreeTokenRecycler(void) {
nsHTMLTokenizer::FreeTokenRecycler();
}
/**
* This method is defined in nsIParser. It is used to
@ -199,7 +203,7 @@ nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanne
nsAutoString theEmpty;
aToken=theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,eParseMode_noquirks);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
}
@ -242,7 +246,7 @@ nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,ns
if(isComment) aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,eParseMode_noquirks);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
}

View File

@ -57,6 +57,8 @@ public:
virtual nsresult ConsumeToken(nsScanner& aScanner);
virtual nsITokenRecycler* GetTokenRecycler(void);
static void FreeTokenRecycler(void);
protected:

View File

@ -408,7 +408,8 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString
START_TIMER();
CStartToken theToken(eHTMLTag_html);
nsAutoString theTagName("html");
CStartToken theToken(theTagName,eHTMLTag_html);
HandleStartToken(&theToken);
mSkipTarget=eHTMLTag_unknown;
@ -1203,14 +1204,19 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
if(nsHTMLElement::IsSectionTag(theChildTag)){
switch(theChildTag){
case eHTMLTag_body:
if(mHasOpenBody)
return OpenContainer(*theNode,PR_FALSE);
if(mHasOpenBody) {
result=OpenContainer(*theNode,PR_FALSE);
RecycleNode(theNode);
return result;
}
break;
case eHTMLTag_head:
if(mHadBody || mHadFrameset) {
result=HandleOmittedTag(aToken,theChildTag,theParent,*theNode);
if(result == NS_OK)
if(result == NS_OK) {
RecycleNode(theNode);
return result;
}
}
break;
default:
@ -1430,20 +1436,19 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
if((kNotFound==GetIndexOfChildOrSynonym(mBodyContext->mStack,theChildTag)) ||
(!gHTMLElements[theChildTag].CanAutoCloseTag(mBodyContext->Last()))) {
UpdateStyleStackForCloseTag(theChildTag,theChildTag);
if(gHTMLElements[theChildTag].IsMemberOf(kBlockEntity)) {
if(gHTMLElements[theChildTag].IsMemberOf(kBlockEntity) &&
mParseMode!=eParseMode_noquirks) {
// Oh boy!! we found a "stray" block entity. Nav4.x and IE introduce line break in
// such cases. So, let's simulate that effect for compatibility.
// Ex. <html><body>Hello</P>There</body></html>
#if 0
mTokenizer->PushTokenFront(aToken); //put this end token back...
CHTMLToken* theToken = (CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theChildTag);
mTokenizer->PushTokenFront(theToken); //put this new token onto stack...
#endif
CHTMLToken* theToken = (CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theChildTag);
result=HandleToken(theToken,mParser);
if(!CanOmit(mBodyContext->Last(),theChildTag)) {
mTokenizer->PushTokenFront(aToken); //put this end token back...
aToken->mRecycle=PR_FALSE; // make sure not to recycle this token because it's not used yet!!
CHTMLToken* theToken = (CHTMLToken*)gRecycler->CreateTokenOfType(eToken_start,theChildTag);
mTokenizer->PushTokenFront(theToken); //put this new token onto stack...
}
}
else return result;
return result;
}
if(result==NS_OK) {
eHTMLTags theTarget=FindAutoCloseTargetForEndTag(theChildTag,mBodyContext->mStack);
@ -1689,20 +1694,17 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
WriteTokenToLog(aToken);
#endif
CParserContext* pc=(mParser)? mParser->PeekContext():nsnull;
if(pc) {
nsString& docTypeStr=aToken->GetStringValueXXX();
mLineNumber += (docTypeStr).CountChar(kNewLine);
docTypeStr.Trim("<!>");
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
nsString& docTypeStr=aToken->GetStringValueXXX();
mLineNumber += (docTypeStr).CountChar(kNewLine);
docTypeStr.Trim("<!>");
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
STOP_TIMER();
STOP_TIMER();
result = (mSink)? mSink->AddDocTypeDecl(theNode,mParseMode):NS_OK;
START_TIMER();
result = (mSink)? mSink->AddDocTypeDecl(theNode, pc->mParseMode):NS_OK;
START_TIMER();
}
return result;
}
@ -1858,7 +1860,8 @@ PRBool CNavDTD::CanPropagate(eHTMLTags aParentTag,eHTMLTags aChildTag) const {
theTempTag=aChildTag;
while(eHTMLTag_unknown!=aChildTag) {
if(parentCanContain){
result=PR_TRUE;
if(!CanOmit(aParentTag,aChildTag))
result=PR_TRUE;
break;
}//if
TagList* theTagList=gHTMLElements[aChildTag].GetRootTags();
@ -2779,7 +2782,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
PRBool done=PR_FALSE;
nsCParserNode* theNode=CreateNode();
CTokenRecycler* theRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
while(!done) {
@ -2993,7 +2995,7 @@ nsITokenRecycler* CNavDTD::GetTokenRecycler(void){
*/
nsITokenizer* CNavDTD::GetTokenizer(void) {
if(!mTokenizer)
mTokenizer=new nsHTMLTokenizer();
mTokenizer=new nsHTMLTokenizer(mParseMode);
return mTokenizer;
}

View File

@ -121,6 +121,7 @@ TagList gFramesetKids={3,eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes};
TagList gHtmlKids={8,eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,eHTMLTag_map,eHTMLTag_noscript,eHTMLTag_script,eHTMLTag_newline,eHTMLTag_whitespace};
TagList gHeadKids={9,eHTMLTag_base,eHTMLTag_bgsound,eHTMLTag_link,eHTMLTag_meta,eHTMLTag_script,eHTMLTag_style,eHTMLTag_title,eHTMLTag_noembed,eHTMLTag_noscript};
TagList gLabelKids={1,eHTMLTag_span};
TagList gLIKids={2,eHTMLTag_ol,eHTMLTag_ul};
TagList gMapKids={1,eHTMLTag_area};
TagList gNoframesKids={1,eHTMLTag_body};
@ -776,7 +777,7 @@ void InitializeElementTable(void) {
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kFormControl, kInlineEntity, kSelf,
/*special props, prop-range*/ 0,kDefaultPropRange,
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
/*special parents,kids,skip*/ 0,&gLabelKids,eHTMLTag_unknown);
Initialize(
/*tag*/ eHTMLTag_layer,

View File

@ -94,6 +94,10 @@ nsresult nsExpatTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr
return NS_OK;
}
void
nsExpatTokenizer::FreeTokenRecycler(void) {
nsHTMLTokenizer::FreeTokenRecycler();
}
/**
* This method is defined in nsIParser. It is used to

View File

@ -58,6 +58,7 @@ public:
virtual nsresult DidTokenize(PRBool aIsFinalChunk);
virtual void FrontloadMisplacedContent(nsDeque& aDeque);
static void FreeTokenRecycler(void);
protected:

View File

@ -1165,7 +1165,7 @@ nsHTMLContentSinkStream::AddComment(const nsIParserNode& aNode){
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
#endif
Write("<!--");
Write(aNode.GetText());
return NS_OK;
}

View File

@ -70,6 +70,15 @@ nsresult nsHTMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
static CTokenRecycler* gTokenRecycler=0;
void
nsHTMLTokenizer::FreeTokenRecycler(void) {
if(gTokenRecycler) {
delete gTokenRecycler;
gTokenRecycler=0;
}
}
/**
* This method is defined in nsIParser. It is used to
@ -101,13 +110,17 @@ NS_IMPL_RELEASE(nsHTMLTokenizer)
* @param
* @return
*/
nsHTMLTokenizer::nsHTMLTokenizer() : nsITokenizer(), mTokenDeque(0){
nsHTMLTokenizer::nsHTMLTokenizer(PRInt32 aParseMode) : nsITokenizer(),
mTokenDeque(0),
mParseMode(aParseMode)
{
NS_INIT_REFCNT();
mDoXMLEmptyTags=PR_FALSE;
}
/**
* Default constructor
* Destructor
*
* @update gess 4/9/98
* @param
@ -147,7 +160,6 @@ void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,
*/
nsITokenRecycler* nsHTMLTokenizer::GetTokenRecycler(void) {
//let's move to this once we eliminate the leaking of tokens...
static CTokenRecycler* gTokenRecycler=0;
if(!gTokenRecycler)
gTokenRecycler=new CTokenRecycler();
return gTokenRecycler;
@ -391,7 +403,7 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
while((!done) && (result==NS_OK)) {
CToken* theToken= (CAttributeToken*)theRecycler->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown);
if(theToken){
result=theToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
result=theToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
//Much as I hate to do this, here's some special case code.
//This handles the case of empty-tags in XML. Our last
@ -472,7 +484,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
aToken=theRecycler->CreateTokenOfType(eToken_start,eHTMLTag_unknown);
if(aToken) {
result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
if(NS_SUCCEEDED(result)) {
AddToken(aToken,result,mTokenDeque,theRecycler);
@ -491,7 +503,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
nsAutoString endTag(nsHTMLTags::GetStringValue(theTag));
endTag.Insert("</",0,2);
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,theTag);
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag); //tell new token to finish consuming text...
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text...
//endTag.Append(">");
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
AddToken(textToken,result,mTokenDeque,theRecycler);
@ -528,7 +540,7 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne
nsresult result=NS_OK;
if(aToken) {
result= aToken->Consume(aChar,aScanner); //tell new token to finish consuming text...
result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text...
AddToken(aToken,result,mTokenDeque,theRecycler);
} //if
return result;
@ -552,11 +564,11 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
if(NS_OK==result) {
if(nsString::IsAlpha(theChar)) { //handle common enity references &xxx; or &#000.
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
result = aToken->Consume(theChar,aScanner); //tell new token to finish consuming text...
result = aToken->Consume(theChar,aScanner,mParseMode); //tell new token to finish consuming text...
}
else if(kHashsign==theChar) {
aToken = theRecycler->CreateTokenOfType(eToken_entity,eHTMLTag_entity);
result=aToken->Consume(theChar,aScanner);
result=aToken->Consume(theChar,aScanner,mParseMode);
}
else {
//oops, we're actually looking at plain text...
@ -597,7 +609,7 @@ nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsSc
aToken = theRecycler->CreateTokenOfType(eToken_whitespace,eHTMLTag_whitespace);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -618,7 +630,7 @@ nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScann
aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -640,7 +652,7 @@ nsresult nsHTMLTokenizer::ConsumeText(const nsString& aString,CToken*& aToken,ns
aToken=theRecycler->CreateTokenOfType(eToken_text,eHTMLTag_text,aString);
if(aToken) {
PRUnichar ch=0;
result=aToken->Consume(ch,aScanner);
result=aToken->Consume(ch,aScanner,mParseMode);
if(!NS_SUCCEEDED(result)) {
nsString& temp=aToken->GetStringValueXXX();
if(0==temp.Length()){
@ -680,7 +692,7 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n
aToken = theRecycler->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -700,7 +712,7 @@ nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScann
aToken=theRecycler->CreateTokenOfType(eToken_newline,eHTMLTag_newline);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;
@ -721,7 +733,7 @@ nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*&
aToken=theRecycler->CreateTokenOfType(eToken_instruction,eHTMLTag_unknown);
nsresult result=NS_OK;
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,mParseMode);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
return result;

View File

@ -50,7 +50,7 @@
CLASS_EXPORT_HTMLPARS nsHTMLTokenizer : public nsITokenizer {
public:
nsHTMLTokenizer();
nsHTMLTokenizer(PRInt32 aParseMode=eParseMode_quirks);
virtual ~nsHTMLTokenizer();
NS_DECL_ISUPPORTS
@ -68,6 +68,7 @@ public:
virtual PRInt32 GetCount(void);
virtual void PrependTokens(nsDeque& aDeque);
static void FreeTokenRecycler(void);
protected:
@ -88,6 +89,7 @@ protected:
nsDeque mTokenDeque;
PRBool mDoXMLEmptyTags;
PRInt32 mParseMode;
};
extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsIDTD** aInstancePtrResult);

View File

@ -201,7 +201,7 @@ PRBool CStartToken::IsEmpty(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
//if you're here, we've already Consumed the < char, and are
//ready to Consume the rest of the open tag identifier.
@ -291,7 +291,7 @@ CEndToken::CEndToken(const nsString& aName) : CHTMLToken(aName) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
//if you're here, we've already Consumed the <! chars, and are
//ready to Consume the rest of the open tag identifier.
//Stop consuming as soon as you see a space or a '>'.
@ -436,7 +436,7 @@ PRInt32 CTextToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
static const char* theTerminals="\n\r&<";
nsresult result=NS_OK;
PRBool done=PR_FALSE;
@ -478,7 +478,7 @@ nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString){
nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString,PRInt32 aMode){
PRBool done=PR_FALSE;
nsresult result=NS_OK;
PRUnichar theChar;
@ -503,7 +503,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
if((NS_OK==result) && (kExclamation==theChar) && (PR_FALSE==aIgnoreComments)) {
//read a comment...
static CCommentToken theComment;
result=theComment.Consume(aChar,aScanner);
result=theComment.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
//result=aScanner.SkipWhitespace();
mTextValue.Append(theComment.GetStringValueXXX());
@ -517,7 +517,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
}
else if(('\b'==theChar) || ('\t'==theChar) || (' '==theChar)) {
static CWhitespaceToken theWS;
result=theWS.Consume(aChar,aScanner);
result=theWS.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
mTextValue.Append(theWS.GetStringValueXXX());
}
@ -528,8 +528,16 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
}
mTextValue.Right(theRight,termStrLen+10); //first, get a wad of chars from the temp string
rpos=theRight.RFindChar('<'); //now scan for the '<'
if(-1<rpos)
if(-1<rpos) {
rpos=theRight.RFind(aTerminalString,PR_TRUE);
if(-1<rpos && aMode!=eParseMode_noquirks) {
nsAutoString temp(theRight);
temp.Cut(0,rpos);
temp.StripWhitespace();
PRUnichar ch=temp.CharAt(aTerminalString.Length());
rpos=(ch==kGreaterThan)? rpos:kNotFound;
}
}
done=PRBool(-1<rpos);
} //while
if(NS_SUCCEEDED(result)) {
@ -596,7 +604,7 @@ PRInt32 CCDATASectionToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
static const char* theTerminals="\r]";
nsresult result=NS_OK;
PRBool done=PR_FALSE;
@ -843,9 +851,9 @@ nsresult ConsumeComment(PRUnichar aChar, nsScanner& aScanner,nsString& aString)
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
PRBool theStrictForm=PR_FALSE;
nsresult result=(theStrictForm) ? ConsumeStrictComment(aChar,aScanner,mTextValue) : ConsumeComment(aChar,aScanner,mTextValue);
nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
nsresult result=(aMode==eParseMode_noquirks) ? ConsumeStrictComment(aChar,aScanner,mTextValue)
: ConsumeComment(aChar,aScanner,mTextValue);
#if 0
if(NS_OK==result) {
@ -949,7 +957,7 @@ nsString& CNewlineToken::GetStringValueXXX(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
mTextValue=aChar;
//we already read the \r or \n, let's see what's next!
@ -1169,7 +1177,7 @@ nsresult ConsumeAttributeValueText(PRUnichar,nsString& aString,nsScanner& aScann
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
nsresult result=aScanner.SkipWhitespace(); //skip leading whitespace
if(NS_OK==result) {
@ -1340,7 +1348,7 @@ PRInt32 CWhitespaceToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
mTextValue=aChar;
nsresult result=aScanner.ReadWhitespace(mTextValue);
if(NS_OK==result) {
@ -1384,7 +1392,7 @@ CEntityToken::CEntityToken(const nsString& aName) : CHTMLToken(aName) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CEntityToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CEntityToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
if(aChar)
mTextValue=aChar;
nsresult result=ConsumeEntity(aChar,mTextValue,aScanner);
@ -1696,7 +1704,7 @@ PRInt32 CSkippedContentToken::GetTokenType(void) {
* @param aScanner -- controller of underlying input source
* @return error result
*/
nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode) {
PRBool done=PR_FALSE;
nsresult result=NS_OK;
nsString temp;
@ -1715,7 +1723,7 @@ nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
if((NS_OK==result) && (kExclamation==theChar)) {
//read a comment...
static CCommentToken theComment;
result=theComment.Consume(aChar,aScanner);
result=theComment.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
//result=aScanner.SkipWhitespace();
temp.Append(theComment.GetStringValueXXX());
@ -1729,7 +1737,7 @@ nsresult CSkippedContentToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
}
else if(('\b'==theChar) || ('\t'==theChar) || (' '==theChar)) {
static CWhitespaceToken theWS;
result=theWS.Consume(aChar,aScanner);
result=theWS.Consume(aChar,aScanner,aMode);
if(NS_OK==result) {
temp.Append(theWS.GetStringValueXXX());
}
@ -1818,7 +1826,7 @@ CInstructionToken::CInstructionToken(const nsString& aString) : CHTMLToken(aStri
* @param
* @return
*/
nsresult CInstructionToken::Consume(PRUnichar aChar,nsScanner& aScanner){
nsresult CInstructionToken::Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode){
mTextValue="<?";
nsresult result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
return result;
@ -1879,7 +1887,7 @@ const nsParserError * CErrorToken::GetError(void)
CDoctypeDeclToken::CDoctypeDeclToken() : CHTMLToken(eHTMLTag_unknown) {
}
nsresult CDoctypeDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
nsresult CDoctypeDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
return ConsumeComment(aChar,aScanner,mTextValue);
}

View File

@ -111,7 +111,7 @@ class CStartToken: public CHTMLToken {
public:
CStartToken(eHTMLTags aTag);
CStartToken(nsString& aName,eHTMLTags aTag=eHTMLTag_unknown);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual PRInt32 GetTypeID(void);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
@ -142,7 +142,7 @@ class CEndToken: public CHTMLToken {
public:
CEndToken(eHTMLTags aTag);
CEndToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual PRInt32 GetTypeID(void);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
@ -163,7 +163,7 @@ class CCommentToken: public CHTMLToken {
public:
CCommentToken();
CCommentToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
char mLeadingChar;
@ -184,7 +184,7 @@ class CEntityToken : public CHTMLToken {
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
PRInt32 TranslateToUnicodeStr(nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
static PRInt32 ConsumeEntity(PRUnichar aChar,nsString& aString,nsScanner& aScanner);
static PRInt32 TranslateToUnicodeStr(PRInt32 aValue,nsString& aString);
virtual void DebugDumpSource(nsOutputStream& out);
@ -203,7 +203,7 @@ class CWhitespaceToken: public CHTMLToken {
public:
CWhitespaceToken();
CWhitespaceToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -219,8 +219,8 @@ class CTextToken: public CHTMLToken {
public:
CTextToken();
CTextToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
nsresult ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
nsresult ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScanner& aScanner,nsString& aTerminalString,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -237,7 +237,7 @@ class CCDATASectionToken : public CHTMLToken {
public:
CCDATASectionToken();
CCDATASectionToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -257,7 +257,7 @@ class CAttributeToken: public CHTMLToken {
CAttributeToken();
CAttributeToken(const nsString& aString);
CAttributeToken(const nsString& aKey, const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
virtual nsString& GetKey(void) {return mTextKey;}
@ -283,7 +283,7 @@ class CNewlineToken: public CHTMLToken {
public:
CNewlineToken();
CNewlineToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
virtual nsString& GetStringValueXXX(void);
@ -336,7 +336,7 @@ class CStyleToken: public CHTMLToken {
class CSkippedContentToken: public CAttributeToken {
public:
CSkippedContentToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
virtual void DebugDumpSource(nsOutputStream& out);
@ -356,7 +356,7 @@ class CInstructionToken: public CHTMLToken {
public:
CInstructionToken();
CInstructionToken(const nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};
@ -388,7 +388,7 @@ protected:
class CDoctypeDeclToken: public CHTMLToken {
public:
CDoctypeDeclToken();
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
};

View File

@ -460,26 +460,41 @@ eParseMode DetermineParseMode(nsParser& aParser) {
theBufCopy.StripWhitespace();
PRInt32 theSubIndex=theBufCopy.FindChar(kGreaterThan,theIndex+1);
theBufCopy.Truncate(theSubIndex);
theSubIndex=theBufCopy.Find("HTML4.0",PR_TRUE,theIndex+8);
if(kNotFound<theSubIndex) {
if(theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex)>kNotFound)
return eParseMode_quirks;
else if((theBufCopy.Find("FRAMESET",PR_TRUE,theSubIndex)>kNotFound) ||
(theBufCopy.Find("LATIN1", PR_TRUE,theSubIndex) >kNotFound) ||
(theBufCopy.Find("SYMBOLS",PR_TRUE,theSubIndex) >kNotFound) ||
(theBufCopy.Find("SPECIAL",PR_TRUE,theSubIndex) >kNotFound))
return eParseMode_quirks; // XXX -HACK- Set the appropriate mode.
else
return eParseMode_noquirks;
}
theSubIndex=theBufCopy.Find("ISO/IEC15445:1999",PR_TRUE,theIndex+8);
theSubIndex=theBufCopy.Find("-//W3C//DTD",PR_TRUE,theIndex+8);
if(kNotFound<theSubIndex) {
if(kNotFound<(theSubIndex=theBufCopy.Find("HTML4.0",PR_TRUE,theSubIndex+11))) {
PRUnichar num=theBufCopy.CharAt(theSubIndex+7);
if(num > '0' && num < '9') {
if(theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex+7)>kNotFound)
return eParseMode_noquirks; // XXX - investigate this more.
}
if((theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex+7)>kNotFound)||
(theBufCopy.Find("FRAMESET",PR_TRUE,theSubIndex+7)>kNotFound) ||
(theBufCopy.Find("LATIN1", PR_TRUE,theSubIndex+7) >kNotFound) ||
(theBufCopy.Find("SYMBOLS",PR_TRUE,theSubIndex+7) >kNotFound) ||
(theBufCopy.Find("SPECIAL",PR_TRUE,theSubIndex+7) >kNotFound))
return eParseMode_quirks; // XXX -HACK- Set the appropriate mode.
else
return eParseMode_noquirks;
}else
if(kNotFound<(theSubIndex=theBufCopy.Find("XHTML",PR_TRUE,theSubIndex+11))) {
if((theBufCopy.Find("TRANSITIONAL",PR_TRUE,theSubIndex)>kNotFound)||
(theBufCopy.Find("STRICT",PR_TRUE,theSubIndex) >kNotFound) ||
(theBufCopy.Find("FRAMESET",PR_TRUE,theSubIndex) >kNotFound))
return eParseMode_noquirks;
else
return eParseMode_quirks;
}
}else
if(kNotFound<(theSubIndex=theBufCopy.Find("ISO/IEC15445:1999",PR_TRUE,theIndex+8))) {
theSubIndex=theBufCopy.Find("HTML",PR_TRUE,theSubIndex+18);
if(kNotFound==theSubIndex)
theSubIndex=theBufCopy.Find("HYPERTEXTMARKUPLANGUAGE",PR_TRUE,theSubIndex+18);
return eParseMode_noquirks;
}
}
}else
if(kNotFound<(theIndex=theBufCopy.Find("?XML",PR_TRUE)))
return eParseMode_noquirks;
theIndex=theBufCopy.Find("NOQUIRKS",PR_TRUE);
if(kNotFound<theIndex) {

View File

@ -28,6 +28,9 @@
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLToTXTSinkStream.h"
#include "nsHTMLEntities.h"
#include "nsHTMLTokenizer.h"
#include "nsXMLTokenizer.h"
#include "nsExpatTokenizer.h"
#include "nsIParserService.h"
static NS_DEFINE_IID(kIParserServiceIID, NS_IPARSERSERVICE_IID);
@ -181,6 +184,9 @@ nsParserModule::Shutdown()
if (mInitialized) {
nsHTMLTags::ReleaseTable();
nsHTMLEntities::ReleaseTable();
nsHTMLTokenizer::FreeTokenRecycler();
nsXMLTokenizer::FreeTokenRecycler();
nsExpatTokenizer::FreeTokenRecycler();
mInitialized = PR_FALSE;
}
}

View File

@ -114,7 +114,7 @@ void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
* @param aScanner -- object to retrieve data from
* @return int error code
*/
nsresult CToken::Consume(PRUnichar aChar,nsScanner& aScanner) {
nsresult CToken::Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode) {
nsresult result=NS_OK;
return result;
}

View File

@ -160,7 +160,7 @@ class CToken {
* @param aScanner -- input source where token should get data
* @return error code (0 means ok)
*/
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
/**
* Causes token to dump itself in debug form to given output stream

View File

@ -648,11 +648,12 @@ nsresult nsXIFDTD::HandleStartToken(CToken* aToken) {
{
case eXIFTag_container:
case eXIFTag_leaf:
case eXIFTag_comment:
StartTopOfStack();
result = OpenContainer(node);
break;
case eXIFTag_comment:
result=CollectContentComment(aToken,node);
break;
case eXIFTag_entity:
StartTopOfStack();
ProcessEntityTag(node);
@ -741,10 +742,6 @@ nsresult nsXIFDTD::HandleEndToken(CToken* aToken) {
case eXIFTag_content:
mInContent = PR_FALSE;
break;
case eXIFTag_comment:
CloseContainer(node);
break;
case eXIFTag_css_stylesheet:
mInContent = PR_FALSE;
@ -1462,9 +1459,6 @@ nsresult nsXIFDTD::OpenContainer(const nsIParserNode& aNode)
case eXIFTag_leaf:
BeginStartTag(aNode);
break;
case eXIFTag_comment:
mSink->AddComment(aNode);
break;
default:
break;
}
@ -1612,6 +1606,56 @@ 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="<!--"; // overwrite comment with "<!--"
while (!done && NS_SUCCEEDED(result))
{
token=mTokenizer->PopToken();
if(!token) return result;
type=(eHTMLTokenTypes)token->GetTokenType();
fragment=token->GetStringValueXXX();
if(fragment=="content") {
if(type==eToken_start)
inContent=PR_TRUE;
else inContent=PR_FALSE;
}
else if(fragment=="comment") {
comment.Append("-->");
result=(mSink)? mSink->AddComment(aNode):NS_OK;
done=PR_TRUE;
}
else {
if(inContent) comment.Append(fragment);
}
recycler->RecycleToken(token);
}
}
}
return result;
}
/**
*

View File

@ -550,6 +550,7 @@ protected:
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;

View File

@ -74,6 +74,10 @@ nsresult nsXMLTokenizer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
void
nsXMLTokenizer::FreeTokenRecycler(void) {
nsHTMLTokenizer::FreeTokenRecycler();
}
/**
* This method is defined in nsIParser. It is used to
@ -199,7 +203,7 @@ nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanne
nsAutoString theEmpty;
aToken=theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,eParseMode_noquirks);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
}
@ -242,7 +246,7 @@ nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,ns
if(isComment) aToken = theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty);
if(aToken) {
result=aToken->Consume(aChar,aScanner);
result=aToken->Consume(aChar,aScanner,eParseMode_noquirks);
AddToken(aToken,result,mTokenDeque,theRecycler);
}
}

View File

@ -57,6 +57,8 @@ public:
virtual nsresult ConsumeToken(nsScanner& aScanner);
virtual nsITokenRecycler* GetTokenRecycler(void);
static void FreeTokenRecycler(void);
protected: