fixed nsbeta3 bugs (crash and compatibility), an FMM, reduced memory usage. Top100+Regression tests ok. R=harishd/buster
git-svn-id: svn://10.0.0.236/trunk@78537 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -26,9 +26,6 @@
|
||||
|
||||
#define ENABLE_RESIDUALSTYLE
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
#include <fstream.h>
|
||||
#endif
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
@@ -183,7 +180,7 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
||||
|
||||
void CNavDTD::ReleaseTable(void) {
|
||||
if(gHTMLElements) {
|
||||
delete gHTMLElements;
|
||||
delete [] gHTMLElements; //fixed bug 49564
|
||||
gHTMLElements=0;
|
||||
}
|
||||
}
|
||||
@@ -540,7 +537,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
result=HandleToken(theEndToken,mParser);
|
||||
}
|
||||
}
|
||||
if(!mBodyContext->mHadDocTypeDecl) {
|
||||
if(!mBodyContext->mFlags.mHadDocTypeDecl) {
|
||||
CToken* theDocTypeToken=mTokenAllocator->CreateTokenOfType(eToken_doctypeDecl,eHTMLTag_markupDecl);
|
||||
if(theDocTypeToken) {
|
||||
nsAutoString theDocTypeStr;
|
||||
@@ -1003,7 +1000,7 @@ PRBool CanBeContained(eHTMLTags aChildTag,nsDTDContext& aContext) {
|
||||
return result;
|
||||
}
|
||||
|
||||
enum eProcessRule {eIgnore,eTest};
|
||||
enum eProcessRule {eNormalOp,eLetInlineContainBlock};
|
||||
|
||||
/**
|
||||
* This method gets called when a start token has been
|
||||
@@ -1039,9 +1036,24 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
|
||||
return result;
|
||||
}
|
||||
|
||||
eProcessRule theRule=eTest;
|
||||
eProcessRule theRule=eNormalOp;
|
||||
|
||||
if((!theParentContains) &&
|
||||
(nsHTMLElement::IsResidualStyleTag(theParentTag)) &&
|
||||
(IsBlockElement(aChildTag,theParentTag))) {
|
||||
|
||||
if(eHTMLTag_table!=aChildTag) {
|
||||
nsCParserNode* theParentNode= NS_STATIC_CAST(nsCParserNode*, mBodyContext->PeekNode());
|
||||
if(theParentNode->mToken->IsWellFormed()) {
|
||||
theRule=eLetInlineContainBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(theRule){
|
||||
case eTest:
|
||||
|
||||
case eNormalOp:
|
||||
|
||||
theChildAgrees=PR_TRUE;
|
||||
if(theParentContains) {
|
||||
|
||||
@@ -1115,7 +1127,11 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
|
||||
}
|
||||
}//if
|
||||
break;
|
||||
case eIgnore:
|
||||
|
||||
case eLetInlineContainBlock:
|
||||
theParentContains=theChildAgrees=PR_TRUE; //cause us to fall out of loop and open the block.
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -1171,6 +1187,19 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
*
|
||||
* Now a little code to deal with bug #49687 (crash when layout stack gets too deep)
|
||||
*
|
||||
**************************************************************************************/
|
||||
|
||||
if(MAX_REFLOW_DEPTH<mBodyContext->GetCount()) {
|
||||
if(gHTMLElements[aTag].IsMemberOf(kInlineEntity)) {
|
||||
if(!gHTMLElements[aTag].IsMemberOf(kFormControl)) {
|
||||
return kHierarchyTooDeep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STOP_TIMER()
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this));
|
||||
@@ -1547,6 +1576,12 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
}//if
|
||||
} //if
|
||||
|
||||
if(kHierarchyTooDeep==result) {
|
||||
//reset this error to ok; all that happens here is that given inline tag
|
||||
//gets dropped because the stack is too deep. Don't terminate parsing.
|
||||
result=NS_OK;
|
||||
}
|
||||
|
||||
mNodeRecycler->RecycleNode(theNode);
|
||||
return result;
|
||||
}
|
||||
@@ -1929,8 +1964,12 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
//if you're here we have a bogus entity.
|
||||
//convert it into a text token.
|
||||
theToken=(CTextToken*)mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,NS_ConvertToString("&"));
|
||||
if(theToken) {
|
||||
nsString &theTokenStr=theToken->GetStringValueXXX();
|
||||
theTokenStr.Append(theStr); //should append the entity name; fix bug 51161.
|
||||
}
|
||||
}
|
||||
return HandleToken(theToken,mParser);
|
||||
return HandleToken(theToken,mParser); //theToken should get recycled automagically...
|
||||
}
|
||||
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
@@ -2086,7 +2125,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mBodyContext) {
|
||||
mBodyContext->mHadDocTypeDecl=PR_TRUE;
|
||||
mBodyContext->mFlags.mHadDocTypeDecl=PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
@@ -2182,7 +2221,8 @@ nsresult CNavDTD::CollectAttributes(nsCParserNode& aNode,eHTMLTags aTag,PRInt32
|
||||
/**
|
||||
* Causes the next skipped-content token (if any) to
|
||||
* be consumed by this node.
|
||||
* @update gess5/11/98
|
||||
*
|
||||
* @update gess 4Sep2000
|
||||
* @param node to consume skipped-content
|
||||
* @param holds the number of skipped content elements encountered
|
||||
* @return Error condition.
|
||||
@@ -2199,7 +2239,7 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||
PRBool aMustConvertLinebreaks = PR_FALSE;
|
||||
|
||||
mScratch.Truncate();
|
||||
aNode.SetSkippedContent(mScratch);
|
||||
aNode.SetSkippedContent(mScratch); //this guarantees us some skipped content storage.
|
||||
|
||||
for(aIndex=0;aIndex<aMax;aIndex++){
|
||||
CHTMLToken* theNextToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
@@ -2210,8 +2250,8 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||
// the start token as mTrailing content and will get appended in
|
||||
// start token's GetSource();
|
||||
if(eToken_attribute!=theTokenType) {
|
||||
if (eToken_entity==theTokenType) {
|
||||
if((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag)) {
|
||||
if ((eToken_entity==theTokenType) &&
|
||||
((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag))) {
|
||||
mScratch.Truncate();
|
||||
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
|
||||
// since this is an entity, we know that it's only one character.
|
||||
@@ -2222,10 +2262,10 @@ nsresult CNavDTD::CollectSkippedContent(nsCParserNode& aNode,PRInt32 &aCount) {
|
||||
aNode.mSkippedContent->Append(mScratch);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
theNextToken->AppendSource(*aNode.mSkippedContent);
|
||||
}
|
||||
else theNextToken->AppendSource(*aNode.mSkippedContent);
|
||||
}
|
||||
else {
|
||||
theNextToken->AppendSource(*aNode.mSkippedContent);
|
||||
}
|
||||
IF_FREE(theNextToken);
|
||||
}
|
||||
|
||||
@@ -513,7 +513,7 @@ protected:
|
||||
PRInt32 mLineNumber;
|
||||
nsParser* mParser;
|
||||
nsITokenizer* mTokenizer;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
CNodeRecycler* mNodeRecycler;
|
||||
nsDeque mMisplacedContent;
|
||||
nsDeque mSkippedContent;
|
||||
@@ -528,11 +528,11 @@ protected:
|
||||
|
||||
PRUint32 mComputedCRC32;
|
||||
PRUint32 mExpectedCRC32;
|
||||
nsAutoString mScratch; //used for various purposes; non-persistent
|
||||
nsString mScratch; //used for various purposes; non-persistent
|
||||
PRBool mStyleHandlingEnabled;
|
||||
PRBool mRequestedHead;
|
||||
PRBool mIsFormContainer;
|
||||
nsAutoString mMimeType;
|
||||
nsAutoString mMimeType; //ok as an autostring; these are short.
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -416,7 +416,7 @@ nsresult COtherDTD::WillBuildModel( const CParserContext& aParserContext,nsICon
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: COtherDTD::WillBuildModel(), this=%p\n", this));
|
||||
|
||||
mDocType=aParserContext.mDocType;
|
||||
mBodyContext->mTransitional=PRBool(aParserContext.mDTDMode==eDTDMode_transitional);
|
||||
mBodyContext->mFlags.mTransitional=PRBool(aParserContext.mDTDMode==eDTDMode_transitional);
|
||||
|
||||
if(aSink && (!mSink)) {
|
||||
result=aSink->QueryInterface(kIHTMLContentSinkIID, (void **)&mSink);
|
||||
|
||||
@@ -344,7 +344,7 @@ protected:
|
||||
|
||||
PRUint32 mComputedCRC32;
|
||||
PRUint32 mExpectedCRC32;
|
||||
nsAutoString mScratch; //used for various purposes; non-persistent
|
||||
nsString mScratch; //used for various purposes; non-persistent
|
||||
eParserDocType mDocType;
|
||||
PRBool mEnableStrict;
|
||||
|
||||
|
||||
@@ -159,17 +159,6 @@ public:
|
||||
anElement.mContainsGroups.mAllBits=aContainsGroups.mAllBits;
|
||||
}
|
||||
|
||||
static PRBool HasOptionalEndTag(CElement* anElement) {
|
||||
static eHTMLTags gContainersWithOptionalEndTag[]={eHTMLTag_body,eHTMLTag_colgroup,eHTMLTag_dd,eHTMLTag_dt,
|
||||
eHTMLTag_head,eHTMLTag_li,eHTMLTag_option,
|
||||
eHTMLTag_p,eHTMLTag_tbody,eHTMLTag_td,eHTMLTag_tfoot,
|
||||
eHTMLTag_th,eHTMLTag_thead,eHTMLTag_tr,eHTMLTag_unknown};
|
||||
if(anElement) {
|
||||
return ListContainsTag(gContainersWithOptionalEndTag,anElement->mTag);
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
inline CElement* GetDelegate(void);
|
||||
inline CElement* GetDefaultContainerFor(CElement* anElement);
|
||||
|
||||
@@ -236,7 +225,7 @@ public:
|
||||
PRInt32 result=-1;
|
||||
|
||||
if(mTag!=aTag) {
|
||||
if(HasOptionalEndTag(this) && (0<anIndex)) {
|
||||
if(HasOptionalEndTag(mTag) && (0<anIndex)) {
|
||||
eHTMLTags theGrandParentTag=aContext->TagAt(--anIndex);
|
||||
CElement *theGrandParent=GetElement(theGrandParentTag);
|
||||
if(theGrandParent) {
|
||||
@@ -340,7 +329,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called to close a tag in the sink and in the context
|
||||
**********************************************************/
|
||||
virtual nsresult CloseContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult CloseContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
if(mTag!=aTag) {
|
||||
CElement *theElement=GetElement(aTag);
|
||||
@@ -600,7 +589,7 @@ public:
|
||||
|
||||
virtual PRBool CanContain(CElement* anElement,nsDTDContext* aContext) {
|
||||
PRBool result=CElement::CanContain(anElement,aContext);
|
||||
if((!result) && (aContext->mTransitional)) {
|
||||
if((!result) && (aContext->mFlags.mTransitional)) {
|
||||
|
||||
//If we're in transitional mode, then also allow inline elements...
|
||||
|
||||
@@ -1209,9 +1198,9 @@ public:
|
||||
|
||||
nsresult result=NS_OK;
|
||||
if(aSink && aContext) {
|
||||
if(aContext->mHasOpenHead==PR_FALSE) {
|
||||
if(aContext->mFlags.mHasOpenHead==PR_FALSE) {
|
||||
result=aSink->OpenHead(*aNode);
|
||||
aContext->mHasOpenHead=PR_TRUE;
|
||||
aContext->mFlags.mHasOpenHead=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -1222,9 +1211,9 @@ public:
|
||||
|
||||
nsresult result=NS_OK;
|
||||
if(aSink && aContext) {
|
||||
if(aContext->mHasOpenHead==PR_TRUE) {
|
||||
if(aContext->mFlags.mHasOpenHead==PR_TRUE) {
|
||||
result=aSink->CloseHead(*aNode);
|
||||
aContext->mHasOpenHead=PR_FALSE;
|
||||
aContext->mFlags.mHasOpenHead=PR_FALSE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -1809,7 +1798,7 @@ public:
|
||||
case eHTMLTag_frameset:
|
||||
result=aSink->OpenFrameset(*aNode);
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
aContext->mHadFrameset=PR_TRUE;
|
||||
aContext->mFlags.mHadFrameset=PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_base: //nothing to do for these empty tags...
|
||||
@@ -1943,7 +1932,7 @@ public:
|
||||
|
||||
virtual PRBool CanContain(CElement* anElement,nsDTDContext* aContext) {
|
||||
PRBool result=CElement::CanContain(anElement,aContext);
|
||||
if((!result) && (aContext->mTransitional)) {
|
||||
if((!result) && (aContext->mFlags.mTransitional)) {
|
||||
//let's try so additions that are specific to the body tag,
|
||||
//and only work in transitional mode...
|
||||
|
||||
@@ -1979,9 +1968,9 @@ public:
|
||||
// If that's the case then make sure that we don't open up multiple contexts, however,
|
||||
// don't forget to inform the sink because it needs to account for the BODY attributes.
|
||||
if(aContext) {
|
||||
if(!aContext->mHadBody) {
|
||||
if(!aContext->mFlags.mHadBody) {
|
||||
result=OpenContext(aNode,aTag,aContext,aSink);
|
||||
aContext->mHadBody=PR_TRUE;
|
||||
aContext->mFlags.mHadBody=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return (NS_SUCCEEDED(result))? OpenContainer(aNode,aTag,aContext,aSink):result;
|
||||
@@ -2596,7 +2585,7 @@ PRInt32 CElement::FindAutoCloseIndexForStartTag(CElement* anElement,PRInt32 aPar
|
||||
CElement* theParent=gElementTable->mElements[theParentTag];
|
||||
|
||||
if(!theParent->CanContain(anElement,aContext)) {
|
||||
if(HasOptionalEndTag(theParent)) {
|
||||
if(HasOptionalEndTag(theParentTag)) {
|
||||
|
||||
if(ListContainsTag(theParent->mAutoClose,anElement->mTag)) {
|
||||
result=theParent->FindAutoCloseIndexForStartTag(anElement,aParentIndex-1,aContext);
|
||||
@@ -2636,7 +2625,7 @@ PRBool CElement::CanBeClosedByEndTag(CElement* anElement,nsDTDContext* aContext)
|
||||
else {
|
||||
eHTMLTags theTag=aContext->Last();
|
||||
CElement* theElement=gElementTable->mElements[theTag];
|
||||
if(HasOptionalEndTag(theElement)) {
|
||||
if(HasOptionalEndTag(theTag)) {
|
||||
if(anElement->CanContain(theElement,aContext)){
|
||||
result=PR_TRUE;
|
||||
}
|
||||
@@ -2678,7 +2667,7 @@ PRBool CElement::CanContain(CElement* anElement,nsDTDContext* aContext) {
|
||||
this table, and to override CanContain() there.
|
||||
***************************************************/
|
||||
|
||||
if((!result) && (aContext->mTransitional)) {
|
||||
if((!result) && (aContext->mFlags.mTransitional)) {
|
||||
switch(mTag) {
|
||||
case eHTMLTag_address:
|
||||
if(eHTMLTag_p==anElement->mTag)
|
||||
@@ -2750,7 +2739,7 @@ nsresult CElement::HandleStartToken( nsIParserNode* aNode,
|
||||
|
||||
//Ok, so we have a start token that is misplaced. Before handing this off
|
||||
//to a default container (parent), let's check the autoclose condition.
|
||||
if(HasOptionalEndTag(this)) {
|
||||
if(HasOptionalEndTag(mTag)) {
|
||||
|
||||
//aha! We have a case where this tag is autoclosed by anElement.
|
||||
//Let's close this container, then try to open theElement.
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
|
||||
eRTFTags mTag;
|
||||
nsAutoString mArgument;
|
||||
nsString mArgument;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -367,13 +367,9 @@ nsDTDContext::nsDTDContext() : mStack(), mEntities(0){
|
||||
mResidualStyleCount=0;
|
||||
mContextTopIndex=0;
|
||||
mTableStates=0;
|
||||
mHadBody=PR_FALSE;
|
||||
mHadFrameset=PR_TRUE;
|
||||
mTransitional=PR_FALSE;
|
||||
ResetCounters();
|
||||
mHadDocTypeDecl=PR_FALSE;
|
||||
mHasOpenHead=PR_FALSE;
|
||||
mCounters=0;
|
||||
mTokenAllocator=0;
|
||||
mAllBits=0;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
memset(mXTags,0,sizeof(mXTags));
|
||||
@@ -408,6 +404,10 @@ nsDTDContext::~nsDTDContext() {
|
||||
|
||||
CEntityDeallocator theDeallocator;
|
||||
mEntities.ForEach(theDeallocator);
|
||||
if(mCounters) {
|
||||
delete [] mCounters;
|
||||
mCounters = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -757,12 +757,25 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 11May2000
|
||||
*/
|
||||
void nsDTDContext::AllocateCounters(void) {
|
||||
if(!mCounters) {
|
||||
mCounters = new PRInt32 [NS_HTML_TAG_MAX]; //in addition to reseting, you may need to allocate.
|
||||
ResetCounters();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 11May2000
|
||||
*/
|
||||
void nsDTDContext::ResetCounters(void) {
|
||||
memset(mCounters,0,sizeof(mCounters));
|
||||
if(mCounters) {
|
||||
memset(mCounters,0,NS_HTML_TAG_MAX*sizeof(PRInt32));
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
@@ -824,8 +837,13 @@ PRInt32 nsDTDContext::IncrementCounter(eHTMLTags aTag,nsCParserNode& aNode,nsStr
|
||||
PRInt32 err=0;
|
||||
theNewValue=theValue.ToInteger(&err);
|
||||
if(!err) {
|
||||
|
||||
theIncrValue=0;
|
||||
mCounters[aTag]=theNewValue;
|
||||
|
||||
AllocateCounters();
|
||||
if(mCounters) {
|
||||
mCounters[aTag]=theNewValue;
|
||||
}
|
||||
}
|
||||
else theNewValue=-1;
|
||||
}
|
||||
@@ -834,7 +852,13 @@ PRInt32 nsDTDContext::IncrementCounter(eHTMLTags aTag,nsCParserNode& aNode,nsStr
|
||||
if(theEntity && (eHTMLTag_userdefined==aTag)) {
|
||||
result=theEntity->mOrdinal+=theIncrValue;
|
||||
}
|
||||
else result=mCounters[aTag]+=theIncrValue;
|
||||
else {
|
||||
AllocateCounters();
|
||||
if(mCounters) {
|
||||
result=mCounters[aTag]+=theIncrValue;
|
||||
}
|
||||
else result=0;
|
||||
}
|
||||
CAbacus::GetFormattedString(theNumFormat,result,aResult,0,0,0);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -206,9 +206,9 @@ public:
|
||||
|
||||
}
|
||||
|
||||
nsAutoString mName;
|
||||
nsAutoString mValue;
|
||||
PRInt32 mOrdinal;
|
||||
nsString mName;
|
||||
nsString mValue;
|
||||
PRInt32 mOrdinal;
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
@@ -304,6 +304,7 @@ public:
|
||||
CNamedEntity* GetEntity(const nsString& aName)const;
|
||||
|
||||
void ResetCounters(void);
|
||||
void AllocateCounters(void);
|
||||
PRInt32 IncrementCounter(eHTMLTags aTag,nsCParserNode& aNode,nsString& aResult);
|
||||
|
||||
void SetTokenAllocator(nsTokenAllocator* aTokenAllocator) { mTokenAllocator=aTokenAllocator; }
|
||||
@@ -311,19 +312,29 @@ public:
|
||||
nsEntryStack mStack; //this will hold a list of tagentries...
|
||||
PRInt32 mResidualStyleCount;
|
||||
PRInt32 mContextTopIndex;
|
||||
PRBool mHadBody;
|
||||
PRBool mHadFrameset;
|
||||
PRBool mHasOpenHead;
|
||||
PRBool mTransitional;
|
||||
PRBool mHadDocTypeDecl;
|
||||
|
||||
//break this struct out seperately so that lame compilers don't gack.
|
||||
//By using these bits instead of bools, we have a bit-o-memory.
|
||||
struct CFlags {
|
||||
PRUint8 mHadBody:1;
|
||||
PRUint8 mHadFrameset:1;
|
||||
PRUint8 mHasOpenHead:1;
|
||||
PRUint8 mTransitional:1;
|
||||
PRUint8 mHadDocTypeDecl:1;
|
||||
};
|
||||
|
||||
union {
|
||||
PRUint32 mAllBits;
|
||||
CFlags mFlags;
|
||||
};
|
||||
|
||||
|
||||
static CNodeRecycler *gNodeRecycler;
|
||||
|
||||
nsTokenAllocator *mTokenAllocator;
|
||||
CTableState *mTableStates;
|
||||
PRInt32 mCounters[NS_HTML_TAG_MAX];
|
||||
nsString mDefaultEntity;
|
||||
nsDeque mEntities;
|
||||
nsTokenAllocator *mTokenAllocator;
|
||||
CTableState *mTableStates;
|
||||
PRInt32 *mCounters;
|
||||
nsDeque mEntities;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
enum { eMaxTags = 100 };
|
||||
@@ -589,6 +600,21 @@ inline PRInt32 FirstOf(nsDTDContext& aContext,PRInt32 aStartOffset,TagList& aTag
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this to find out whether the DTD thinks the tag requires an END tag </xxx>
|
||||
* @update gess 01/04/99
|
||||
* @param id of tag
|
||||
* @return TRUE of the element's end tag is optional
|
||||
*/
|
||||
static PRBool HasOptionalEndTag(eHTMLTags aTag) {
|
||||
static eHTMLTags gHasOptionalEndTags[]={eHTMLTag_body,eHTMLTag_colgroup,eHTMLTag_dd,eHTMLTag_dt,
|
||||
eHTMLTag_head,eHTMLTag_li,eHTMLTag_option,
|
||||
eHTMLTag_p,eHTMLTag_tbody,eHTMLTag_td,eHTMLTag_tfoot,
|
||||
eHTMLTag_th,eHTMLTag_thead,eHTMLTag_tr,eHTMLTag_unknown};
|
||||
return FindTagInSet(aTag,gHasOptionalEndTags,sizeof(gHasOptionalEndTags)/sizeof(eHTMLTag_body));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ TagList gCaptionAutoClose={1,{eHTMLTag_tbody}};
|
||||
TagList gLIAutoClose={2,{eHTMLTag_p,eHTMLTag_li}};
|
||||
TagList gPAutoClose={2,{eHTMLTag_p,eHTMLTag_li}};
|
||||
TagList gHRAutoClose={1,{eHTMLTag_p}};
|
||||
TagList gOLAutoClose={3,{eHTMLTag_p,eHTMLTag_ol,eHTMLTag_ul}};
|
||||
TagList gOLAutoClose={2,{eHTMLTag_p,eHTMLTag_ol}};
|
||||
TagList gDivAutoClose={1,{eHTMLTag_p}};
|
||||
|
||||
TagList gHeadingTags={6,{eHTMLTag_h1,eHTMLTag_h2,eHTMLTag_h3,eHTMLTag_h4,eHTMLTag_h5,eHTMLTag_h6}};
|
||||
@@ -132,6 +132,7 @@ TagList gTRCloseTags={3,{eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th}};
|
||||
TagList gTDCloseTags={2,{eHTMLTag_td,eHTMLTag_th}};
|
||||
TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}};
|
||||
TagList gULCloseTags={1,{eHTMLTag_li}};
|
||||
TagList gULAutoClose={2,{eHTMLTag_p,eHTMLTag_ul}}; //fix bug 50261..
|
||||
|
||||
|
||||
TagList gExcludableParents={1,{eHTMLTag_pre}}; // Ref Bug 22913
|
||||
@@ -948,7 +949,7 @@ void InitializeElementTable(void) {
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kPreformatted, kFlowEntity, kNone, //I'm allowing WAY too much in here. Spec says inline.
|
||||
/*parent,incl,exclgroups*/ kPreformatted, (kSelf|kFlowEntity), kNone, //I'm allowing WAY too much in here. Spec says inline.
|
||||
/*special props, prop-range*/ 0, kDefaultPropRange,
|
||||
/*special parents,kids,skip*/ 0,&gPreKids,eHTMLTag_unknown);
|
||||
|
||||
@@ -1209,7 +1210,7 @@ void InitializeElementTable(void) {
|
||||
/*tag*/ eHTMLTag_ul,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gOLRootTags,&gOLRootTags,
|
||||
/*autoclose starttags and endtags*/ &gOLAutoClose,&gULCloseTags,0,0,
|
||||
/*autoclose starttags and endtags*/ &gULAutoClose,&gULCloseTags,0,0,
|
||||
/*parent,incl,exclgroups*/ kList, (kFlowEntity|kSelf), kNone,
|
||||
/*special props, prop-range*/ 0,kDefaultPropRange,
|
||||
/*special parents,kids,skip*/ 0,&gULKids,eHTMLTag_unknown);
|
||||
@@ -1888,10 +1889,22 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
||||
|
||||
int theCount=aContext.GetCount();
|
||||
int theIndex=theCount;
|
||||
|
||||
if(IsMemberOf(kPhrase)){
|
||||
|
||||
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
|
||||
eHTMLTags theTag=aContext.TagAt(theIndex);
|
||||
if(theTag!=mTagID) {
|
||||
|
||||
//fixes a derivative of bug 22842...
|
||||
if(CanContainType(kBlock)) { //INS/DEL can contain blocks.
|
||||
if(gHTMLElements[eHTMLTags(theTag)].IsMemberOf(kBlockEntity)) {
|
||||
if(HasOptionalEndTag(theTag)) {
|
||||
continue; //then I can close it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//phrasal elements can close other phrasals, along with fontstyle and special tags...
|
||||
if(!gHTMLElements[theTag].IsMemberOf(kSpecial|kFontStyle|kPhrase)) {
|
||||
break; //it's not something I can close
|
||||
@@ -1903,17 +1916,27 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(IsMemberOf(kSpecial)){
|
||||
|
||||
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
|
||||
eHTMLTags theTag=aContext.TagAt(theIndex);
|
||||
if(theTag!=mTagID) {
|
||||
//phrasal elements can close other phrasals, along with fontstyle and special tags...
|
||||
|
||||
if(gHTMLElements[theTag].IsSpecialEntity() || gHTMLElements[theTag].IsFontStyleEntity()) {
|
||||
// if(TestBits(gHTMLElements[theTag].mParentBits,kSpecial) ||
|
||||
// TestBits(gHTMLElements[theTag].mParentBits,kFontStyle)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
//fixes bug 22842...
|
||||
if(CanContainType(kBlock)) {
|
||||
if(gHTMLElements[eHTMLTags(theTag)].IsMemberOf(kBlockEntity)) {
|
||||
if(HasOptionalEndTag(theTag)) {
|
||||
continue; //then I can close it.
|
||||
}
|
||||
}
|
||||
}
|
||||
break; //it's not something I can close
|
||||
}
|
||||
}
|
||||
@@ -1923,7 +1946,9 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(IsMemberOf(kFormControl|kExtensions|kPreformatted)){
|
||||
|
||||
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
|
||||
eHTMLTags theTag=aContext.TagAt(theIndex);
|
||||
if(theTag!=mTagID) {
|
||||
@@ -1937,7 +1962,9 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(IsMemberOf(kList)){
|
||||
|
||||
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
|
||||
eHTMLTags theTag=aContext.TagAt(theIndex);
|
||||
if(theTag!=mTagID) {
|
||||
@@ -1951,6 +1978,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(IsResidualStyleTag(mTagID)){
|
||||
|
||||
// Ref. bug 37618
|
||||
|
||||
@@ -119,6 +119,7 @@ NS_IMPL_RELEASE(nsHTMLTokenizer)
|
||||
mRecordTrailingContent=PR_FALSE;
|
||||
mParserCommand=aCommand;
|
||||
mTokenAllocator=nsnull;
|
||||
mTokenScanPos=0;
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +238,8 @@ CToken* nsHTMLTokenizer::GetTokenAt(PRInt32 anIndex){
|
||||
nsresult nsHTMLTokenizer::WillTokenize(PRBool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)
|
||||
{
|
||||
mTokenAllocator=aTokenAllocator;
|
||||
mIsFinalChunk=aIsFinalChunk;
|
||||
mTokenScanPos=mTokenDeque.GetSize()+1; //cause scanDocStructure to search from here for new tokens...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -260,9 +263,160 @@ void nsHTMLTokenizer::PrependTokens(nsDeque& aDeque){
|
||||
|
||||
}
|
||||
|
||||
nsresult nsHTMLTokenizer::DidTokenize(PRBool aIsFinalChunk)
|
||||
{
|
||||
return NS_OK;
|
||||
static nsDeque& GetTempStack() {
|
||||
static nsDeque theTempStack(0);
|
||||
return theTempStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a utilty method for ScanDocStructure, which finds a given
|
||||
* tag in the stack.
|
||||
*
|
||||
* @update gess 08/30/00
|
||||
* @param aTag -- the ID of the tag we're seeking
|
||||
* @param aTagStack -- the stack to be searched
|
||||
* @return index pos of tag in stack if found, otherwise kNotFound
|
||||
*/
|
||||
static PRInt32 FindLastIndexOfTag(eHTMLTags aTag,nsDeque &aTagStack) {
|
||||
PRInt32 theCount=aTagStack.GetSize();
|
||||
|
||||
while(0<theCount) {
|
||||
CHTMLToken *theToken=(CHTMLToken*)aTagStack.ObjectAt(--theCount);
|
||||
if(theToken) {
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
if(theTag==aTag) {
|
||||
return theCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method scans the sequence of tokens to determine the
|
||||
* well formedness of each tag structure. This is used to
|
||||
* disable residual-style handling in well formed cases.
|
||||
*
|
||||
* @update gess 1Sep2000
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsresult nsHTMLTokenizer::ScanDocStructure(PRBool aFinalChunk) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
|
||||
CHTMLToken *theRootToken=0;
|
||||
|
||||
//*** start by finding the first start tag that hasn't been reviewed.
|
||||
|
||||
while(mTokenScanPos>0) {
|
||||
theRootToken=(CHTMLToken*)mTokenDeque.ObjectAt(mTokenScanPos);
|
||||
if(theRootToken) {
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theRootToken->GetTokenType());
|
||||
if(eToken_start==theType) {
|
||||
if(eFormUnknown==theRootToken->GetContainerInfo()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mTokenScanPos--;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* Now that we know where to start, let's walk through the
|
||||
* tokens to see which are well-formed. Stop when you run out
|
||||
* of fresh tokens.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
theRootToken=(CHTMLToken*)mTokenDeque.ObjectAt(mTokenScanPos); //init to root
|
||||
|
||||
nsDeque &theStack=GetTempStack();
|
||||
eHTMLTags theRootTag=eHTMLTag_unknown;
|
||||
CHTMLToken *theToken=theRootToken; //init to root
|
||||
PRInt32 theStackDepth=0;
|
||||
|
||||
static const PRInt32 theMaxStackDepth=200; //dont bother if we get ridiculously deep.
|
||||
|
||||
while(theToken && (theStackDepth<theMaxStackDepth)) {
|
||||
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity);
|
||||
PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity);
|
||||
|
||||
if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) {
|
||||
|
||||
switch(theType) {
|
||||
|
||||
case eToken_start:
|
||||
if(0==theStack.GetSize()) {
|
||||
//track the tag on the top of the stack...
|
||||
theRootToken=theToken;
|
||||
theRootTag=theTag;
|
||||
}
|
||||
theStack.Push(theToken);
|
||||
theStackDepth++;
|
||||
break;
|
||||
|
||||
case eToken_end:
|
||||
{
|
||||
CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
if(theLastToken) {
|
||||
if(theTag==theLastToken->GetTypeID()) {
|
||||
theStack.Pop(); //yank it for real
|
||||
theStackDepth--;
|
||||
theLastToken->SetContainerInfo(eWellFormed);
|
||||
|
||||
//in addition, let's look above this container to see if we can find
|
||||
//any tags that are already marked malformed. If so, pop them too!
|
||||
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
while(theLastToken) {
|
||||
if(eMalformed==theRootToken->GetContainerInfo()) {
|
||||
theStack.Pop(); //yank the malformed token for real.
|
||||
theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//the topmost token isn't what we expected, so that container must
|
||||
//be malformed. If the tag is a block, we don't really care (but we'll
|
||||
//mark it anyway). If it's an inline we DO care, especially if the
|
||||
//inline tried to contain a block (that's when RS handling kicks in).
|
||||
if(theTagIsInline) {
|
||||
PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack);
|
||||
if(kNotFound!=theIndex) {
|
||||
theToken=(CHTMLToken*)theStack.ObjectAt(theIndex);
|
||||
theToken->SetContainerInfo(eMalformed);
|
||||
}
|
||||
//otherwise we ignore an out-of-place end tag.
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
|
||||
}
|
||||
|
||||
theToken=(CHTMLToken*)mTokenDeque.ObjectAt(++mTokenScanPos);
|
||||
}
|
||||
|
||||
theStack.Empty();
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsHTMLTokenizer::DidTokenize(PRBool aFinalChunk) {
|
||||
return ScanDocStructure(aFinalChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -475,6 +629,12 @@ nsresult nsHTMLTokenizer::ConsumeScriptContent(nsScanner& aScanner,CToken*& aTok
|
||||
return result;
|
||||
}
|
||||
|
||||
nsString& GetScratchString(void) {
|
||||
static nsString gScratchString;
|
||||
gScratchString.Truncate(0);
|
||||
return gScratchString;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/28/98
|
||||
@@ -500,10 +660,10 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
|
||||
//Good. Now, let's see if the next char is ">".
|
||||
//If so, we have a complete tag, otherwise, we have attributes.
|
||||
mScratch.Truncate(0);
|
||||
nsString &theScratchStr=GetScratchString();
|
||||
PRBool theTagHasAttributes=PR_FALSE;
|
||||
if(NS_OK==result) {
|
||||
result=(eViewSource==mParserCommand) ? aScanner.ReadWhitespace(mScratch) : aScanner.SkipWhitespace();
|
||||
result=(eViewSource==mParserCommand) ? aScanner.ReadWhitespace(theScratchStr) : aScanner.SkipWhitespace();
|
||||
aToken->mNewlineCount += aScanner.GetNewlinesSkipped();
|
||||
if(NS_OK==result) {
|
||||
result=aScanner.GetChar(aChar);
|
||||
@@ -518,7 +678,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
}
|
||||
|
||||
if(theTagHasAttributes) {
|
||||
result=ConsumeAttributes(aChar,(CStartToken*)aToken,aScanner,mScratch);
|
||||
result=ConsumeAttributes(aChar,(CStartToken*)aToken,aScanner,theScratchStr);
|
||||
}
|
||||
|
||||
/* Now that that's over with, we have one more problem to solve.
|
||||
@@ -528,7 +688,8 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
|
||||
//XXX - Find a better soution to record content
|
||||
if((theTag==eHTMLTag_textarea || theTag==eHTMLTag_xmp) && !mRecordTrailingContent) {
|
||||
//Added _plaintext to fix bug 46054.
|
||||
if((eHTMLTag_textarea==theTag || eHTMLTag_xmp==theTag || eHTMLTag_plaintext==theTag) && !mRecordTrailingContent) {
|
||||
mRecordTrailingContent=PR_TRUE;
|
||||
}
|
||||
|
||||
@@ -633,6 +794,10 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne
|
||||
aToken=theToken;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(mIsFinalChunk && (kEOF==result)) {
|
||||
result=NS_OK; //use as much of the entity as you can get.
|
||||
}
|
||||
AddToken(aToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
}//if
|
||||
|
||||
@@ -68,10 +68,10 @@ public:
|
||||
|
||||
virtual CToken* PushTokenFront(CToken* theToken);
|
||||
virtual CToken* PushToken(CToken* theToken);
|
||||
virtual CToken* PopToken(void);
|
||||
virtual CToken* PeekToken(void);
|
||||
virtual CToken* GetTokenAt(PRInt32 anIndex);
|
||||
virtual PRInt32 GetCount(void);
|
||||
virtual CToken* PopToken(void);
|
||||
virtual CToken* PeekToken(void);
|
||||
virtual CToken* GetTokenAt(PRInt32 anIndex);
|
||||
virtual PRInt32 GetCount(void);
|
||||
|
||||
virtual void PrependTokens(nsDeque& aDeque);
|
||||
|
||||
@@ -89,7 +89,9 @@ protected:
|
||||
virtual nsresult ConsumeText(const nsString& aString,CToken*& aToken,nsScanner& aScanner);
|
||||
virtual nsresult ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
|
||||
virtual nsresult ConsumeProcessingInstruction(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
|
||||
|
||||
|
||||
nsresult ScanDocStructure(PRBool aIsFinalChunk);
|
||||
|
||||
virtual void RecordTrailingContent(CStartToken* aStartToken,nsScanner& aScanner);
|
||||
|
||||
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,nsTokenAllocator* aTokenAllocator);
|
||||
@@ -100,8 +102,9 @@ protected:
|
||||
eParserDocType mDocType;
|
||||
PRBool mRecordTrailingContent;
|
||||
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
|
||||
nsAutoString mScratch;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
PRInt32 mTokenScanPos;
|
||||
PRBool mIsFinalChunk;
|
||||
};
|
||||
|
||||
extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer( nsITokenizer** aInstancePtrResult,
|
||||
|
||||
@@ -61,9 +61,9 @@ CHTMLToken::CHTMLToken(const nsString& aName,eHTMLTags aTag) : CToken(aName) {
|
||||
* @return
|
||||
*/
|
||||
CHTMLToken::CHTMLToken(eHTMLTags aTag) : CToken(aTag) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
CHTMLToken::~CHTMLToken() {
|
||||
|
||||
}
|
||||
@@ -108,6 +108,7 @@ CStartToken::CStartToken(eHTMLTags aTag) : CHTMLToken(aTag) {
|
||||
mAttributed=PR_FALSE;
|
||||
mEmpty=PR_FALSE;
|
||||
mOrigin=-1;
|
||||
mContainerInfo=eFormUnknown;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -121,12 +122,14 @@ CStartToken::CStartToken(const nsString& aString) : CHTMLToken(aString) {
|
||||
mAttributed=PR_FALSE;
|
||||
mEmpty=PR_FALSE;
|
||||
mOrigin=-1;
|
||||
mContainerInfo=eFormUnknown;
|
||||
}
|
||||
|
||||
CStartToken::CStartToken(const nsString& aName,eHTMLTags aTag) : CHTMLToken(aName,aTag) {
|
||||
mAttributed=PR_FALSE;
|
||||
mEmpty=PR_FALSE;
|
||||
mOrigin=-1;
|
||||
mContainerInfo=eFormUnknown;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,6 +145,7 @@ void CStartToken::Reinitialize(PRInt32 aTag, const nsString& aString){
|
||||
mEmpty=PR_FALSE;
|
||||
mOrigin=-1;
|
||||
mTrailingContent.Truncate();
|
||||
mContainerInfo=eFormUnknown;
|
||||
}
|
||||
|
||||
nsresult CStartToken::GetIDAttributeAtom(nsIAtom** aResult)
|
||||
@@ -271,7 +275,12 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode
|
||||
}
|
||||
else {
|
||||
mTextValue.Assign(aChar);
|
||||
result=aScanner.ReadIdentifier(mTextValue);
|
||||
|
||||
//added PR_TRUE to readId() call below to fix bug 46083. The problem was that the tag given
|
||||
//was written <title_> but since we didn't respect the '_', we only saw <title>. Then
|
||||
//we searched for end title, which never comes (they give </title_>).
|
||||
|
||||
result=aScanner.ReadIdentifier(mTextValue,PR_TRUE);
|
||||
mTypeID = nsHTMLTags::LookupTag(mTextValue);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,18 +89,22 @@ const char* GetTagName(PRInt32 aTag);
|
||||
//PRInt32 FindEntityIndex(nsString& aString,PRInt32 aCount=-1);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This declares the basic token type used in the HTML DTD's.
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CHTMLToken : public CToken {
|
||||
public:
|
||||
virtual ~CHTMLToken();
|
||||
|
||||
CHTMLToken(eHTMLTags aTag);
|
||||
CHTMLToken(const nsString& aString,eHTMLTags aTag=eHTMLTag_unknown);
|
||||
virtual void SetCStringValue(const char* name);
|
||||
virtual nsString& GetStringValueXXX(void);
|
||||
virtual ~CHTMLToken();
|
||||
|
||||
virtual eContainerInfo GetContainerInfo(void) const {return eFormUnknown;}
|
||||
virtual void SetContainerInfo(eContainerInfo aInfo) { }
|
||||
|
||||
protected:
|
||||
};
|
||||
@@ -129,6 +133,12 @@ class CStartToken: public CHTMLToken {
|
||||
virtual void DebugDumpSource(nsOutputStream& out);
|
||||
virtual void GetSource(nsString& anOutputString);
|
||||
virtual void AppendSource(nsString& anOutputString);
|
||||
|
||||
//the following info is used to set well-formedness state on start tags...
|
||||
virtual eContainerInfo GetContainerInfo(void) const {return mContainerInfo;}
|
||||
virtual void SetContainerInfo(eContainerInfo aContainerInfo) {mContainerInfo=aContainerInfo;}
|
||||
virtual PRBool IsWellFormed(void) const {return PRBool(eWellFormed==mContainerInfo);}
|
||||
|
||||
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
|
||||
|
||||
/*
|
||||
@@ -140,11 +150,13 @@ class CStartToken: public CHTMLToken {
|
||||
virtual nsresult GetIDAttributeAtom(nsIAtom** aResult);
|
||||
virtual nsresult SetIDAttributeAtom(nsIAtom* aID);
|
||||
|
||||
nsString mTrailingContent;
|
||||
PRInt32 mOrigin;
|
||||
nsString mTrailingContent;
|
||||
PRInt32 mOrigin;
|
||||
protected:
|
||||
PRBool mAttributed;
|
||||
PRBool mEmpty;
|
||||
PRBool mAttributed;
|
||||
|
||||
PRBool mEmpty;
|
||||
eContainerInfo mContainerInfo;
|
||||
nsCOMPtr<nsIAtom> mIDAttributeAtom;
|
||||
};
|
||||
|
||||
|
||||
@@ -72,6 +72,10 @@
|
||||
#define NS_IHTML_CONTENT_SINK_IID \
|
||||
{ 0xa6cf9051, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
|
||||
|
||||
|
||||
#define MAX_REFLOW_DEPTH 200
|
||||
|
||||
|
||||
class nsIHTMLContentSink : public nsIContentSink {
|
||||
public:
|
||||
|
||||
|
||||
@@ -291,6 +291,8 @@ class nsIParser : public nsISupports {
|
||||
#define NS_ERROR_HTMLPARSER_BADCONTEXT NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1014)
|
||||
#define NS_ERROR_HTMLPARSER_STOPPARSING NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1015)
|
||||
#define NS_ERROR_HTMLPARSER_UNTERMINATEDSTRINGLITERAL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1016)
|
||||
#define NS_ERROR_HTMLPARSER_HIERARCHYTOODEEP NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_HTMLPARSER,1017)
|
||||
|
||||
|
||||
#define NS_HTMLPARSER_ALTERNATECONTENT NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_HTMLPARSER,1)
|
||||
|
||||
@@ -306,6 +308,7 @@ const PRUint32 kBadURL = NS_ERROR_HTMLPARSER_BADURL;
|
||||
const PRUint32 kInvalidParserContext = NS_ERROR_HTMLPARSER_INVALIDPARSERCONTEXT;
|
||||
const PRUint32 kBlocked = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
const PRUint32 kBadStringLiteral = NS_ERROR_HTMLPARSER_UNTERMINATEDSTRINGLITERAL;
|
||||
const PRUint32 kHierarchyTooDeep = NS_ERROR_HTMLPARSER_HIERARCHYTOODEEP;
|
||||
|
||||
const PRUnichar kNewLine = '\n';
|
||||
const PRUnichar kCR = '\r';
|
||||
|
||||
@@ -109,8 +109,17 @@ public:
|
||||
NS_NewNavHTMLDTD(&theDTD); //do this as a default HTML DTD...
|
||||
mDTDDeque.Push(theDTD);
|
||||
|
||||
NS_NewOtherHTMLDTD(&mOtherDTD); //do this as the default DTD for strict documents...
|
||||
mDTDDeque.Push(mOtherDTD);
|
||||
|
||||
#if 1 //to fix bug 50070.
|
||||
const char* theStrictDTDEnabled="true";
|
||||
#else
|
||||
const char* theStrictDTDEnabled=PR_GetEnv("ENABLE_STRICT"); //always false (except rickg's machine)
|
||||
#endif
|
||||
|
||||
if(theStrictDTDEnabled) {
|
||||
NS_NewOtherHTMLDTD(&mOtherDTD); //do this as the default DTD for strict documents...
|
||||
mDTDDeque.Push(mOtherDTD);
|
||||
}
|
||||
|
||||
mHasViewSourceDTD=PR_FALSE;
|
||||
mHasRTFDTD=mHasXMLDTD=PR_FALSE;
|
||||
@@ -673,16 +682,17 @@ void DetermineParseMode(nsString& aBuffer,nsDTDMode& aParseMode,eParserDocType&
|
||||
|
||||
//now let's see if we have HTML or XHTML...
|
||||
|
||||
PRInt32 theLTPos=aBuffer.FindChar(kLessThan);
|
||||
PRInt32 theGTPos=aBuffer.FindChar(kGreaterThan);
|
||||
|
||||
if(kNotFound!=theGTPos) {
|
||||
|
||||
if((kNotFound!=theGTPos) && (kNotFound!=theLTPos)) {
|
||||
|
||||
const PRUnichar* theBuffer=aBuffer.GetUnicode();
|
||||
CWordTokenizer theTokenizer(aBuffer,1,theGTPos);
|
||||
CWordTokenizer theTokenizer(aBuffer,theLTPos,theGTPos);
|
||||
PRInt32 theOffset=theTokenizer.GetNextWord(); //try to find ?xml, !doctype, etc...
|
||||
|
||||
if((kNotFound!=theOffset) &&
|
||||
(0==nsCRT::strncasecmp(theBuffer+theOffset,"DOCTYPE",theTokenizer.mLength))) {
|
||||
(0==nsCRT::strncasecmp(theBuffer+theOffset,"!DOCTYPE",theTokenizer.mLength))) {
|
||||
|
||||
//Ok -- so assume it's (X)HTML; now figure out the flavor...
|
||||
|
||||
@@ -2285,16 +2295,18 @@ theContext->mTransferBufferSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
theContext->mScanner->Append(theContext->mTransferBuffer,theNumRead);
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
static int dump=0;
|
||||
if(dump) {
|
||||
theContext->mTransferBuffer[theNumRead]=0;
|
||||
printf("\n-----------------\n%s",theContext->mTransferBuffer);
|
||||
printf("\n\n-----------------------------------------------------%s\n",theContext->mTransferBuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
theContext->mScanner->Append(theContext->mTransferBuffer,theNumRead);
|
||||
|
||||
|
||||
#ifdef rickgdebug
|
||||
theContext->mTransferBuffer[theNumRead]=0;
|
||||
theContext->mTransferBuffer[theNumRead+1]=0;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
class nsTagHandler : public nsITagHandler {
|
||||
|
||||
public:
|
||||
nsAutoString mTheTagName;
|
||||
nsAutoString mTheTagName; //ok as autostring; VERY few if any get used.
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -49,6 +49,14 @@
|
||||
|
||||
class nsScanner;
|
||||
|
||||
|
||||
enum eContainerInfo {
|
||||
eWellFormed,
|
||||
eMalformed,
|
||||
eFormUnknown
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Token objects represent sequences of characters as they
|
||||
* are consumed from the input stream (URL). While they're
|
||||
@@ -242,6 +250,17 @@ class CToken {
|
||||
*/
|
||||
virtual const char* GetClassName(void);
|
||||
|
||||
|
||||
/**
|
||||
* For tokens who care, this can tell us whether the token is
|
||||
* well formed or not.
|
||||
*
|
||||
* @update gess 8/30/00
|
||||
* @return PR_FALSE; subclasses MUST override if they care.
|
||||
*/
|
||||
virtual PRBool IsWellFormed(void) const {return PR_FALSE;}
|
||||
|
||||
|
||||
/**
|
||||
* perform self test.
|
||||
* @update gess5/11/98
|
||||
|
||||
Reference in New Issue
Block a user