fixed a dozen bugs

git-svn-id: svn://10.0.0.236/trunk@24432 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rickg%netscape.com
1999-03-19 08:47:51 +00:00
parent e635708ea1
commit 2a7f41a86b
40 changed files with 592 additions and 524 deletions

View File

@@ -36,6 +36,7 @@
#include "nsTagHandler.h"
#include "nsViewSourceHTML.h"
#include "nsHTMLTokenizer.h"
#include "nsTime.h"
#ifdef XP_PC
#include <direct.h> //this is here for debug reasons...
@@ -437,9 +438,6 @@ eAutoDetectResult CNavDTD::CanParse(nsString& aContentType, nsString& aCommand,
if(PR_TRUE==aContentType.Equals(kHTMLTextContentType)) {
result=ePrimaryDetect;
}
else if(PR_TRUE==aContentType.Equals(kPlainTextContentType)) {
result=eValidDetect;
}
else {
//otherwise, look into the buffer to see if you recognize anything...
if(BufferContainsHTML(aBuffer)){
@@ -453,24 +451,32 @@ eAutoDetectResult CNavDTD::CanParse(nsString& aContentType, nsString& aCommand,
}
PRTime gStartTime;
/**
*
* @update gess5/18/98
* @param
* @return
*/
nsresult CNavDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink){
nsresult CNavDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aFilename;
if(aParser){
mHasOpenBody=PR_FALSE;
mHadBodyOrFrameset=PR_FALSE;
mLineNumber=1;
mSink=(nsIHTMLContentSink*)aSink;
if((aNotifySink) && (mSink)) {
result = mSink->WillBuildModel();
}
mHasOpenBody=PR_FALSE;
mHadBodyOrFrameset=PR_FALSE;
mLineNumber=1;
mIsPlaintext=aSourceType.Equals(kPlainTextContentType);
mSink=(nsIHTMLContentSink*)aSink;
if((aNotifySink) && (mSink)) {
#ifdef RGESS_DEBUG
gStartTime = PR_Now();
printf("Begin parsing...\n");
#endif
result = mSink->WillBuildModel();
mComputedCRC32=0;
mExpectedCRC32=0;
}
@@ -536,6 +542,15 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
result = CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE);
}
#ifdef RGESS_DEBUG
PRTime theEnd= PR_Now();
PRTime creates, ustoms;
LL_I2L(ustoms, 1000);
LL_SUB(creates, theEnd, gStartTime);
LL_DIV(creates, creates, ustoms);
printf("End parse elapsed: %lldms\n",creates);
#endif
//let's only grab this state once!
if(!gShowCRC) {
gShowCRC=1; //this only indicates we'll not initialize again.
@@ -822,78 +837,83 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
//Sick as it sounds, I have to make sure the body has been
//opened before other tags can be added to the content sink...
PRBool rickgSkip=PR_FALSE;
if(!rickgSkip) {
static eHTMLTags gBodyBlockers[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_map};
PRInt32 theBodyBlocker=GetTopmostIndexOf(gBodyBlockers,sizeof(gBodyBlockers)/sizeof(eHTMLTag_unknown));
if((kNotFound==theBodyBlocker) && (!mHasOpenHead)){
if(CanPropagate(eHTMLTag_body,aChildTag)) {
mHasOpenBody=PR_TRUE;
CStartToken theToken(eHTMLTag_body); //open the body container...
result=HandleStartToken(&theToken);
}
}//if
/***********************************************************************
Subtlety alert:
The REAL story on when tags are opened is somewhat confusing, but it's
important to understand. Since this is where we deal with it, it's time
for a quick disseration. Here goes:
Given a stack of open tags, a new (child) tag comes along and we need
to see if it can be opened in place. There are at least 2 reasons why
it cannot be opened: 1) the parent says so; 2) the child says so.
Parents refuse to take children they KNOW they can't contain. Consider
that the <HTML> tag is only *supposed* to contain certain tags --
no one would expect it to accept a rogue <LI> tag (for example).
After the parent decides it CAN accept a child (usually based on the class
of the tag, the child decides it if agrees. For example, consider this stack:
<HTML><BODY>
<DL>
<DT>
<DD>
<LI>
<DT>
static eHTMLTags gBodyBlockers[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_map};
PRInt32 theBodyBlocker=GetTopmostIndexOf(gBodyBlockers,sizeof(gBodyBlockers)/sizeof(eHTMLTag_unknown));
if((kNotFound==theBodyBlocker) && (!mHasOpenHead)){
if(CanPropagate(eHTMLTag_body,aChildTag)) {
mHasOpenBody=PR_TRUE;
CStartToken theToken(eHTMLTag_body); //open the body container...
result=HandleStartToken(&theToken);
}
}//if
Technically, the <LI> *can* contain the <DT> tag, but the <DT> knows that
this isn't appropriate, since another <DT> is already open on the stack.
Therefore the child will refuse the placement.
/***********************************************************************
Subtlety alert:
***********************************************************************/
The REAL story on when tags are opened is somewhat confusing, but it's
important to understand. Since this is where we deal with it, it's time
for a quick disseration. Here goes:
eHTMLTags theParentTag=mBodyContext->Last();
PRBool theCanContainResult=CanContain(theParentTag,aChildTag);
PRBool theChildAgrees=CanBeContained(aChildTag,mBodyContext->mTags);
Given a stack of open tags, a new (child) tag comes along and we need
to see if it can be opened in place. There are at least 2 reasons why
it cannot be opened: 1) the parent says so; 2) the child says so.
Parents refuse to take children they KNOW they can't contain. Consider
that the <HTML> tag is only *supposed* to contain certain tags --
no one would expect it to accept a rogue <LI> tag (for example).
After the parent decides it CAN accept a child (usually based on the class
of the tag, the child decides it if agrees. For example, consider this stack:
<HTML><BODY>
<DL>
<DT>
<DD>
<LI>
<DT>
Technically, the <LI> *can* contain the <DT> tag, but the <DT> knows that
this isn't appropriate, since another <DT> is already open on the stack.
Therefore the child will refuse the placement.
***********************************************************************/
eHTMLTags theParentTag=mBodyContext->Last();
PRBool theCanContainResult=CanContain(theParentTag,aChildTag);
PRBool theChildAgrees=CanBeContained(aChildTag,mBodyContext->mTags);
if(!(theCanContainResult && theChildAgrees)) {
eHTMLTags theTarget=FindAutoCloseTargetForStartTag(aChildTag,mBodyContext->mTags);
if(eHTMLTag_unknown!=theTarget){
result=CloseContainersTo(theTarget,PR_TRUE);
theParentTag=mBodyContext->Last();
theCanContainResult=CanContain(theParentTag,aChildTag);
}
}
if(PR_FALSE==theCanContainResult){
if(CanPropagate(theParentTag,aChildTag))
result=CreateContextStackFor(aChildTag);
else result=kCantPropagate;
if(NS_OK!=result) {
//if you're here, then the new topmost container can't contain aToken.
//You must determine what container hierarchy you need to hold aToken,
//and create that on the parsestack.
result=ReduceContextStackFor(aChildTag);
PRBool theCanContainResult=CanContain(mBodyContext->Last(),aChildTag);
if(PR_FALSE==theCanContainResult) {
//we unwound too far; now we have to recreate a valid context stack.
result=CreateContextStackFor(aChildTag);
if(!(theCanContainResult && theChildAgrees)) {
eHTMLTags theTarget=FindAutoCloseTargetForStartTag(aChildTag,mBodyContext->mTags);
if(eHTMLTag_unknown!=theTarget){
result=CloseContainersTo(theTarget,PR_TRUE);
theParentTag=mBodyContext->Last();
theCanContainResult=CanContain(theParentTag,aChildTag);
}
}
}
if(PR_FALSE==theCanContainResult){
if(CanPropagate(theParentTag,aChildTag))
result=CreateContextStackFor(aChildTag);
else result=kCantPropagate;
if(NS_OK!=result) {
//if you're here, then the new topmost container can't contain aToken.
//You must determine what container hierarchy you need to hold aToken,
//and create that on the parsestack.
result=ReduceContextStackFor(aChildTag);
PRBool theCanContainResult=CanContain(mBodyContext->Last(),aChildTag);
if(PR_FALSE==theCanContainResult) {
//we unwound too far; now we have to recreate a valid context stack.
result=CreateContextStackFor(aChildTag);
}
}
}
}//if(!rickGSkip)...
if(IsContainer(aChildTag)){
//first, let's see if it's a style element...
@@ -992,7 +1012,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
if(!gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag)){
CEndToken theToken(eHTMLTag_head);
nsCParserNode theNode(&theToken,mLineNumber);
result=CloseContainer(theNode,eHTMLTag_head,PR_FALSE);
result=CloseHead(theNode);
}
}
}
@@ -1024,59 +1044,26 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
PRInt16 attrCount=aToken->GetAttributeCount();
nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(attrNode,attrCount);
eHTMLTags theParent=mBodyContext->Last();
if(NS_OK==result) {
if(NS_OK==WillHandleStartTag(aToken,theChildTag,attrNode)) {
PRBool theHeadIsParent=nsHTMLElement::IsChildOfHead(theChildTag);
switch(theChildTag) {
case eHTMLTag_title:
result=OpenHead(attrNode);
if(NS_OK==result) {
// result=CollectSkippedContent(attrNode,theAttrCount);
if(mSink) {
mSink->SetTitle(attrNode.GetSkippedContent());
}
if(NS_OK==result)
result=CloseHead(attrNode);
}
break;
case eHTMLTag_base:
case eHTMLTag_link:
case eHTMLTag_meta:
result=AddHeadLeaf(attrNode);
break;
case eHTMLTag_style:
result=OpenHead(attrNode);
if(NS_OK==result) {
// CollectSkippedContent(attrNode,theCount);
if(NS_OK==result) {
result=AddLeaf(attrNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
nsresult rv=CloseHead(attrNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the
// parser has blocked (i.e. return the result of
// the AddLeaf.
if (rv != NS_OK) {
result = rv;
}
}
}
}
break;
case eHTMLTag_area:
if (mHasOpenMap && mSink)
result=mSink->AddLeaf(attrNode);
break;
case eHTMLTag_script:
theHeadIsParent=(!mHasOpenBody); //intentionally fall through...
default:
if(PR_FALSE==CanOmit(theParent,theChildTag)) {
result=HandleDefaultStartToken(aToken,theChildTag,attrNode);
if(theHeadIsParent)
result=AddHeadLeaf(attrNode);
else if(PR_FALSE==CanOmit(theParent,theChildTag)) {
result=HandleDefaultStartToken(aToken,theChildTag,attrNode);
}
break;
} //switch
@@ -1308,7 +1295,9 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
case eHTMLTag_td:
break;
default:
result=(mSink) ? mSink->AddComment(aNode) : NS_OK;
if(mHasOpenBody){
result=(mSink) ? mSink->AddComment(aNode) : NS_OK;
}
}
return result;
}
@@ -2149,6 +2138,13 @@ nsresult CNavDTD::OpenBody(const nsIParserNode& aNode){
if(NS_OK==result) {
result=(mSink) ? mSink->OpenBody(aNode) : NS_OK;
mBodyContext->Push((eHTMLTags)aNode.GetNodeType());
//now THIS is a hack to support plaintext documents in this DTD...
if((NS_OK==result) && mIsPlaintext) {
CStartToken theToken(eHTMLTag_pre); //open the body container...
result=HandleStartToken(&theToken);
}
}
return result;
}
@@ -2194,6 +2190,7 @@ nsresult CNavDTD::OpenForm(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
nsresult CNavDTD::CloseForm(const nsIParserNode& aNode){
NS_PRECONDITION(mBodyContext->GetCount() > 0, kInvalidTagStackPos);
nsresult result=NS_OK;
if(mHasOpenForm) {
mHasOpenForm=PR_FALSE;
@@ -2230,6 +2227,7 @@ nsresult CNavDTD::OpenMap(const nsIParserNode& aNode){
* @return TRUE if ok, FALSE if error
*/
nsresult CNavDTD::CloseMap(const nsIParserNode& aNode){
NS_PRECONDITION(mBodyContext->GetCount() > 0, kInvalidTagStackPos);
nsresult result=NS_OK;
if(mHasOpenMap) {
mHasOpenMap=PR_FALSE;
@@ -2367,7 +2365,6 @@ CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
nsresult
CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,
PRBool aUpdateStyles){
NS_PRECONDITION(mBodyContext->GetCount() > 0, kInvalidTagStackPos);
nsresult result=NS_OK;
eHTMLTags nodeType=(eHTMLTags)aNode.GetNodeType();
@@ -2519,7 +2516,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
* Call this method ONLY when you want to write a leaf
* into the head container.
*
* @update vidur 11/14/98
* @update gess 03/14/99
* @param aNode -- next node to be added to model
* @return error code; 0 means OK
*/
@@ -2530,19 +2527,34 @@ nsresult CNavDTD::AddHeadLeaf(const nsIParserNode& aNode){
//this code has been added to prevent <meta> tags from being processed inside
//the document if the <meta> tag itself was found in a <noframe>, <nolayer>, or <noscript> tag.
if(eHTMLTag_meta==aNode.GetNodeType())
eHTMLTags theTag=(eHTMLTags)aNode.GetNodeType();
if(eHTMLTag_meta==theTag)
if(HasOpenContainer(gNoXTags,sizeof(gNoXTags)/sizeof(eHTMLTag_unknown))) {
return result;
}
result=OpenHead(aNode);
if(NS_OK==result) {
result=AddLeaf(aNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
CloseHead(aNode);
if(mSink) {
result=OpenHead(aNode);
if(NS_OK==result) {
if(eHTMLTag_title==theTag)
mSink->SetTitle(aNode.GetSkippedContent());
else result=AddLeaf(aNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
nsresult rv=CloseHead(aNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the
// parser has blocked (i.e. return the result of
// the AddLeaf.
if (rv != NS_OK) {
result = rv;
}
}
}
}
return result;
}