63423 - Unblock parser before evaluating external js content.
63661 - Do not create an end token automatically if the tag did not contain '>' 33051 - Handle residual style before closing a tag. 58992 - Leaf content should go thro' the normal HandleToken path. 61462 - Release parser bundle only when the parser is about to shutdown r=jst sr=vidur git-svn-id: svn://10.0.0.236/trunk@86373 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -730,7 +730,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
if((FindTagInSet(theTag,gLegalElements,sizeof(gLegalElements)/sizeof(theTag))) ||
|
||||
(gHTMLElements[theParentTag].CanContain(theTag))) {
|
||||
(gHTMLElements[theParentTag].CanContain(theTag)) && (theTag!=eHTMLTag_comment)) { // Added comment -> bug 40855
|
||||
|
||||
mDTDState=NS_OK; // reset the state since all the misplaced tokens are about to get handled.
|
||||
result=HandleSavedTokens(mBodyContext->mContextTopIndex);
|
||||
@@ -1928,6 +1928,12 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
if(result==NS_OK) {
|
||||
eHTMLTags theTarget=FindAutoCloseTargetForEndTag(theChildTag,*mBodyContext);
|
||||
if(eHTMLTag_unknown!=theTarget) {
|
||||
if (nsHTMLElement::IsResidualStyleTag(theChildTag)) {
|
||||
result=OpenTransientStyles(theChildTag);
|
||||
if(NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result=CloseContainersTo(theTarget,PR_FALSE);
|
||||
}
|
||||
}
|
||||
@@ -3739,69 +3745,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
|
||||
result=mSink->AddLeaf(*aNode);
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
PRBool done=PR_FALSE;
|
||||
eHTMLTags thePrevTag=theTag;
|
||||
//nsCParserNode theNode;
|
||||
|
||||
while(!done && NS_SUCCEEDED(result)) {
|
||||
CToken* theToken=mTokenizer->PeekToken();
|
||||
if(theToken) {
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(theToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
thePrevTag=theTag;
|
||||
}
|
||||
break;
|
||||
case eHTMLTag_text:
|
||||
if((mHasOpenBody) && (!mHasOpenHead) &&
|
||||
!(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
|
||||
theToken=mTokenizer->PopToken();
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
|
||||
mLineNumber += theToken->mNewlineCount;
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
else done=PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
NS_IF_RELEASE(theNode);
|
||||
} //if
|
||||
}//if
|
||||
else done=PR_TRUE;
|
||||
} //while
|
||||
} //if
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
|
||||
@@ -56,7 +56,6 @@ CParserContext::CParserContext(nsScanner* aScanner,
|
||||
mDTD=aDTD;
|
||||
NS_IF_ADDREF(mDTD);
|
||||
mTransferBufferSize=eTransferBufferSize;
|
||||
mParserEnabled=PR_TRUE;
|
||||
mStreamListenerState=eNone;
|
||||
mMultipart=PR_TRUE;
|
||||
mContextType=eCTNone;
|
||||
@@ -90,7 +89,6 @@ CParserContext::CParserContext(const CParserContext &aContext) : mMimeType() {
|
||||
NS_IF_ADDREF(mDTD);
|
||||
|
||||
mTransferBufferSize=eTransferBufferSize;
|
||||
mParserEnabled=aContext.mParserEnabled;
|
||||
mStreamListenerState=aContext.mStreamListenerState;
|
||||
mMultipart=aContext.mMultipart;
|
||||
mContextType=aContext.mContextType;
|
||||
|
||||
@@ -83,7 +83,6 @@ public:
|
||||
|
||||
void* mKey;
|
||||
PRUint32 mTransferBufferSize;
|
||||
PRBool mParserEnabled;
|
||||
PRBool mCopyUnused;
|
||||
};
|
||||
|
||||
|
||||
@@ -606,11 +606,6 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
done=PR_TRUE;
|
||||
}
|
||||
else if(aChar==kLessThan) {
|
||||
eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID();
|
||||
if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){
|
||||
CToken* theEndToken=theAllocator->CreateTokenOfType(eToken_end,theEndTag);
|
||||
AddToken(theEndToken,NS_OK,&mTokenDeque,theAllocator);
|
||||
}
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}//if
|
||||
|
||||
@@ -219,8 +219,20 @@ class nsIParser : public nsISupports {
|
||||
* until you wind up being emitted to the given contentsink (which may or may not
|
||||
* be a proxy for the NGLayout content model).
|
||||
******************************************************************************************/
|
||||
virtual nsresult EnableParser(PRBool aState) = 0;
|
||||
virtual PRBool IsParserEnabled() = 0;
|
||||
|
||||
// This method enables the parser ( by calling UnblockParser() ) and resumes parsing.
|
||||
virtual nsresult ResumeParsing() =0;
|
||||
|
||||
// Stops parsing temporarily.
|
||||
virtual void BlockParser() =0;
|
||||
|
||||
// Open up the parser for tokenization, building up content
|
||||
// model..etc. However, this method does not resume parsing
|
||||
// automatically. It's the callers' responsibility to restart
|
||||
// the parsing engine.
|
||||
virtual void UnblockParser() =0;
|
||||
|
||||
virtual PRBool IsParserEnabled() =0;
|
||||
|
||||
virtual nsresult Parse(nsIURI* aURL,nsIStreamObserver* aListener = nsnull,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
|
||||
virtual nsresult Parse(nsIInputStream& aStream, const nsString& aMimeType,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
|
||||
|
||||
@@ -237,6 +237,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) {
|
||||
mInternalState=NS_OK;
|
||||
mObserversEnabled=PR_TRUE;
|
||||
mCommand=eViewNormal;
|
||||
mParserEnabled=PR_TRUE;
|
||||
mBundle=nsnull;
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Reset: Parse Time: nsParser::nsParser(), this=%p\n", this));
|
||||
@@ -1413,10 +1414,12 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
|
||||
//One last thing...close any open containers.
|
||||
nsresult result=anErrorCode;
|
||||
|
||||
if((mParserContext) && mParserContext->mParserEnabled) {
|
||||
if((!mParserContext->mPrevContext) && (mParserContext->mDTD)) {
|
||||
if(mParserEnabled && mParserContext && !mParserContext->mPrevContext) {
|
||||
if(mParserContext->mDTD) {
|
||||
result=mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext),this,mSink);
|
||||
}
|
||||
//Ref. to bug 61462.
|
||||
NS_IF_RELEASE(mBundle);
|
||||
}//if
|
||||
|
||||
return result;
|
||||
@@ -1432,9 +1435,6 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
|
||||
*/
|
||||
void nsParser::PushContext(CParserContext& aContext) {
|
||||
aContext.mPrevContext=mParserContext;
|
||||
if (mParserContext) {
|
||||
aContext.mParserEnabled = mParserContext->mParserEnabled;
|
||||
}
|
||||
mParserContext=&aContext;
|
||||
}
|
||||
|
||||
@@ -1453,7 +1453,6 @@ CParserContext* nsParser::PopContext() {
|
||||
// back to the new one. Also, propagate the stream listener state
|
||||
// but don't override onStop state to guarantee the call to DidBuildModel().
|
||||
if (mParserContext) {
|
||||
mParserContext->mParserEnabled = oldContext->mParserEnabled;
|
||||
if(mParserContext->mStreamListenerState!=eOnStop) {
|
||||
mParserContext->mStreamListenerState = oldContext->mStreamListenerState;
|
||||
}
|
||||
@@ -1499,49 +1498,64 @@ nsresult nsParser::Terminate(void){
|
||||
return mInternalState;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this when you want control whether or not the parser will parse
|
||||
* and tokenize input (TRUE), or whether it just caches input to be
|
||||
* parsed later (FALSE).
|
||||
* Call this when you want to toggle from the blocked state and resume parsing
|
||||
*
|
||||
* @update gess 1/29/99
|
||||
* @param aState determines whether we parse/tokenize or just cache.
|
||||
* @return current state
|
||||
*/
|
||||
nsresult nsParser::EnableParser(PRBool aState){
|
||||
|
||||
nsresult nsParser::ResumeParsing(){
|
||||
|
||||
// If the stream has already finished, there's a good chance
|
||||
// that we might start closing things down when the parser
|
||||
// is reenabled. To make sure that we're not deleted across
|
||||
// the reenabling process, hold a reference to ourselves.
|
||||
nsresult result=NS_OK;
|
||||
nsIParser* me = this;
|
||||
NS_ADDREF(me);
|
||||
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
|
||||
|
||||
// If we're reenabling the parser
|
||||
if(mParserContext) {
|
||||
mParserContext->mParserEnabled=aState;
|
||||
if(aState) {
|
||||
// Enable the parser
|
||||
UnblockParser();
|
||||
|
||||
//printf(" Re-enable parser\n");
|
||||
PRBool isFinalChunk=(mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
|
||||
|
||||
result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
|
||||
|
||||
if(result!=NS_OK)
|
||||
result=mInternalState;
|
||||
}
|
||||
else {
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::EnableParser(), this=%p\n", this));
|
||||
MOZ_TIMER_STOP(mParseTime);
|
||||
}
|
||||
}
|
||||
PRBool isFinalChunk=(mParserContext && mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
|
||||
|
||||
result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
|
||||
|
||||
if(result!=NS_OK)
|
||||
result=mInternalState;
|
||||
|
||||
// Release reference if we added one at the top of this routine
|
||||
NS_IF_RELEASE(me);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops parsing temporarily. That's it will prevent the
|
||||
* parser from building up content model.
|
||||
*
|
||||
* @update
|
||||
* @return
|
||||
*/
|
||||
void nsParser::BlockParser() {
|
||||
mParserEnabled=PR_FALSE;
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::BlockParser(), this=%p\n", this));
|
||||
MOZ_TIMER_STOP(mParseTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open up the parser for tokenization, building up content
|
||||
* model..etc. However, this method does not resume parsing
|
||||
* automatically. It's the callers' responsibility to restart
|
||||
* the parsing engine.
|
||||
*
|
||||
* @update
|
||||
* @return
|
||||
*/
|
||||
void nsParser::UnblockParser() {
|
||||
mParserEnabled=PR_TRUE;
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this));
|
||||
MOZ_TIMER_START(mParseTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to query whether the parser is enabled or not.
|
||||
*
|
||||
@@ -1549,7 +1563,7 @@ nsresult nsParser::EnableParser(PRBool aState){
|
||||
* @return current state
|
||||
*/
|
||||
PRBool nsParser::IsParserEnabled() {
|
||||
return mParserContext->mParserEnabled;
|
||||
return mParserEnabled;
|
||||
}
|
||||
|
||||
|
||||
@@ -1863,7 +1877,7 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mParserContext->mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
if(mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::ResumeParse(), this=%p\n", this));
|
||||
@@ -1904,8 +1918,8 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
|
||||
if(NS_ERROR_HTMLPARSER_BLOCK==result) {
|
||||
//BLOCK == 2152596464
|
||||
mParserContext->mDTD->WillInterruptParse();
|
||||
result=EnableParser(PR_FALSE);
|
||||
return result;
|
||||
BlockParser();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
else if (NS_ERROR_HTMLPARSER_STOPPARSING==result) {
|
||||
@@ -2392,7 +2406,7 @@ nsresult nsParser::OnStopRequest(nsIChannel* channel, nsISupports* aContext,
|
||||
gOutFile=0;
|
||||
}
|
||||
#endif
|
||||
NS_IF_RELEASE(mBundle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,9 @@ class nsParser : public nsIParser,
|
||||
* @param aState determines whether we parse/tokenize or just cache.
|
||||
* @return current state
|
||||
*/
|
||||
virtual nsresult EnableParser(PRBool aState);
|
||||
virtual nsresult ResumeParsing();
|
||||
virtual void BlockParser();
|
||||
virtual void UnblockParser();
|
||||
virtual nsresult Terminate(void);
|
||||
|
||||
/**
|
||||
@@ -407,7 +409,7 @@ protected:
|
||||
CObserverService mObserverService;
|
||||
PRBool mObserversEnabled;
|
||||
nsString mCommandStr;
|
||||
|
||||
PRBool mParserEnabled;
|
||||
nsParserBundle* mBundle;
|
||||
nsTokenAllocator mTokenAllocator;
|
||||
|
||||
|
||||
@@ -730,7 +730,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
if((FindTagInSet(theTag,gLegalElements,sizeof(gLegalElements)/sizeof(theTag))) ||
|
||||
(gHTMLElements[theParentTag].CanContain(theTag))) {
|
||||
(gHTMLElements[theParentTag].CanContain(theTag)) && (theTag!=eHTMLTag_comment)) { // Added comment -> bug 40855
|
||||
|
||||
mDTDState=NS_OK; // reset the state since all the misplaced tokens are about to get handled.
|
||||
result=HandleSavedTokens(mBodyContext->mContextTopIndex);
|
||||
@@ -1928,6 +1928,12 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
||||
if(result==NS_OK) {
|
||||
eHTMLTags theTarget=FindAutoCloseTargetForEndTag(theChildTag,*mBodyContext);
|
||||
if(eHTMLTag_unknown!=theTarget) {
|
||||
if (nsHTMLElement::IsResidualStyleTag(theChildTag)) {
|
||||
result=OpenTransientStyles(theChildTag);
|
||||
if(NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result=CloseContainersTo(theTarget,PR_FALSE);
|
||||
}
|
||||
}
|
||||
@@ -3739,69 +3745,6 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
|
||||
result=mSink->AddLeaf(*aNode);
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
PRBool done=PR_FALSE;
|
||||
eHTMLTags thePrevTag=theTag;
|
||||
//nsCParserNode theNode;
|
||||
|
||||
while(!done && NS_SUCCEEDED(result)) {
|
||||
CToken* theToken=mTokenizer->PeekToken();
|
||||
if(theToken) {
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(theToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
switch(theTag) {
|
||||
case eHTMLTag_newline:
|
||||
mLineNumber++;
|
||||
case eHTMLTag_whitespace:
|
||||
{
|
||||
theToken=mTokenizer->PopToken();
|
||||
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
thePrevTag=theTag;
|
||||
}
|
||||
break;
|
||||
case eHTMLTag_text:
|
||||
if((mHasOpenBody) && (!mHasOpenHead) &&
|
||||
!(nsHTMLElement::IsWhitespaceTag(thePrevTag))) {
|
||||
theToken=mTokenizer->PopToken();
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
|
||||
mLineNumber += theToken->mNewlineCount;
|
||||
result=mSink->AddLeaf(*theNode);
|
||||
|
||||
if((NS_SUCCEEDED(result))||(NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
else done=PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
done=PR_TRUE;
|
||||
} //switch
|
||||
NS_IF_RELEASE(theNode);
|
||||
} //if
|
||||
}//if
|
||||
else done=PR_TRUE;
|
||||
} //while
|
||||
} //if
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
|
||||
@@ -56,7 +56,6 @@ CParserContext::CParserContext(nsScanner* aScanner,
|
||||
mDTD=aDTD;
|
||||
NS_IF_ADDREF(mDTD);
|
||||
mTransferBufferSize=eTransferBufferSize;
|
||||
mParserEnabled=PR_TRUE;
|
||||
mStreamListenerState=eNone;
|
||||
mMultipart=PR_TRUE;
|
||||
mContextType=eCTNone;
|
||||
@@ -90,7 +89,6 @@ CParserContext::CParserContext(const CParserContext &aContext) : mMimeType() {
|
||||
NS_IF_ADDREF(mDTD);
|
||||
|
||||
mTransferBufferSize=eTransferBufferSize;
|
||||
mParserEnabled=aContext.mParserEnabled;
|
||||
mStreamListenerState=aContext.mStreamListenerState;
|
||||
mMultipart=aContext.mMultipart;
|
||||
mContextType=aContext.mContextType;
|
||||
|
||||
@@ -83,7 +83,6 @@ public:
|
||||
|
||||
void* mKey;
|
||||
PRUint32 mTransferBufferSize;
|
||||
PRBool mParserEnabled;
|
||||
PRBool mCopyUnused;
|
||||
};
|
||||
|
||||
|
||||
@@ -606,11 +606,6 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
done=PR_TRUE;
|
||||
}
|
||||
else if(aChar==kLessThan) {
|
||||
eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID();
|
||||
if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){
|
||||
CToken* theEndToken=theAllocator->CreateTokenOfType(eToken_end,theEndTag);
|
||||
AddToken(theEndToken,NS_OK,&mTokenDeque,theAllocator);
|
||||
}
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}//if
|
||||
|
||||
@@ -219,8 +219,20 @@ class nsIParser : public nsISupports {
|
||||
* until you wind up being emitted to the given contentsink (which may or may not
|
||||
* be a proxy for the NGLayout content model).
|
||||
******************************************************************************************/
|
||||
virtual nsresult EnableParser(PRBool aState) = 0;
|
||||
virtual PRBool IsParserEnabled() = 0;
|
||||
|
||||
// This method enables the parser ( by calling UnblockParser() ) and resumes parsing.
|
||||
virtual nsresult ResumeParsing() =0;
|
||||
|
||||
// Stops parsing temporarily.
|
||||
virtual void BlockParser() =0;
|
||||
|
||||
// Open up the parser for tokenization, building up content
|
||||
// model..etc. However, this method does not resume parsing
|
||||
// automatically. It's the callers' responsibility to restart
|
||||
// the parsing engine.
|
||||
virtual void UnblockParser() =0;
|
||||
|
||||
virtual PRBool IsParserEnabled() =0;
|
||||
|
||||
virtual nsresult Parse(nsIURI* aURL,nsIStreamObserver* aListener = nsnull,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
|
||||
virtual nsresult Parse(nsIInputStream& aStream, const nsString& aMimeType,PRBool aEnableVerify=PR_FALSE, void* aKey=0,nsDTDMode aMode=eDTDMode_autodetect) = 0;
|
||||
|
||||
@@ -237,6 +237,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) {
|
||||
mInternalState=NS_OK;
|
||||
mObserversEnabled=PR_TRUE;
|
||||
mCommand=eViewNormal;
|
||||
mParserEnabled=PR_TRUE;
|
||||
mBundle=nsnull;
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Reset: Parse Time: nsParser::nsParser(), this=%p\n", this));
|
||||
@@ -1413,10 +1414,12 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
|
||||
//One last thing...close any open containers.
|
||||
nsresult result=anErrorCode;
|
||||
|
||||
if((mParserContext) && mParserContext->mParserEnabled) {
|
||||
if((!mParserContext->mPrevContext) && (mParserContext->mDTD)) {
|
||||
if(mParserEnabled && mParserContext && !mParserContext->mPrevContext) {
|
||||
if(mParserContext->mDTD) {
|
||||
result=mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext),this,mSink);
|
||||
}
|
||||
//Ref. to bug 61462.
|
||||
NS_IF_RELEASE(mBundle);
|
||||
}//if
|
||||
|
||||
return result;
|
||||
@@ -1432,9 +1435,6 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
|
||||
*/
|
||||
void nsParser::PushContext(CParserContext& aContext) {
|
||||
aContext.mPrevContext=mParserContext;
|
||||
if (mParserContext) {
|
||||
aContext.mParserEnabled = mParserContext->mParserEnabled;
|
||||
}
|
||||
mParserContext=&aContext;
|
||||
}
|
||||
|
||||
@@ -1453,7 +1453,6 @@ CParserContext* nsParser::PopContext() {
|
||||
// back to the new one. Also, propagate the stream listener state
|
||||
// but don't override onStop state to guarantee the call to DidBuildModel().
|
||||
if (mParserContext) {
|
||||
mParserContext->mParserEnabled = oldContext->mParserEnabled;
|
||||
if(mParserContext->mStreamListenerState!=eOnStop) {
|
||||
mParserContext->mStreamListenerState = oldContext->mStreamListenerState;
|
||||
}
|
||||
@@ -1499,49 +1498,64 @@ nsresult nsParser::Terminate(void){
|
||||
return mInternalState;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this when you want control whether or not the parser will parse
|
||||
* and tokenize input (TRUE), or whether it just caches input to be
|
||||
* parsed later (FALSE).
|
||||
* Call this when you want to toggle from the blocked state and resume parsing
|
||||
*
|
||||
* @update gess 1/29/99
|
||||
* @param aState determines whether we parse/tokenize or just cache.
|
||||
* @return current state
|
||||
*/
|
||||
nsresult nsParser::EnableParser(PRBool aState){
|
||||
|
||||
nsresult nsParser::ResumeParsing(){
|
||||
|
||||
// If the stream has already finished, there's a good chance
|
||||
// that we might start closing things down when the parser
|
||||
// is reenabled. To make sure that we're not deleted across
|
||||
// the reenabling process, hold a reference to ourselves.
|
||||
nsresult result=NS_OK;
|
||||
nsIParser* me = this;
|
||||
NS_ADDREF(me);
|
||||
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
|
||||
|
||||
// If we're reenabling the parser
|
||||
if(mParserContext) {
|
||||
mParserContext->mParserEnabled=aState;
|
||||
if(aState) {
|
||||
// Enable the parser
|
||||
UnblockParser();
|
||||
|
||||
//printf(" Re-enable parser\n");
|
||||
PRBool isFinalChunk=(mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
|
||||
|
||||
result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
|
||||
|
||||
if(result!=NS_OK)
|
||||
result=mInternalState;
|
||||
}
|
||||
else {
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::EnableParser(), this=%p\n", this));
|
||||
MOZ_TIMER_STOP(mParseTime);
|
||||
}
|
||||
}
|
||||
PRBool isFinalChunk=(mParserContext && mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
|
||||
|
||||
result=ResumeParse(PR_TRUE,isFinalChunk); // Ref. bug 57999
|
||||
|
||||
if(result!=NS_OK)
|
||||
result=mInternalState;
|
||||
|
||||
// Release reference if we added one at the top of this routine
|
||||
NS_IF_RELEASE(me);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops parsing temporarily. That's it will prevent the
|
||||
* parser from building up content model.
|
||||
*
|
||||
* @update
|
||||
* @return
|
||||
*/
|
||||
void nsParser::BlockParser() {
|
||||
mParserEnabled=PR_FALSE;
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::BlockParser(), this=%p\n", this));
|
||||
MOZ_TIMER_STOP(mParseTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open up the parser for tokenization, building up content
|
||||
* model..etc. However, this method does not resume parsing
|
||||
* automatically. It's the callers' responsibility to restart
|
||||
* the parsing engine.
|
||||
*
|
||||
* @update
|
||||
* @return
|
||||
*/
|
||||
void nsParser::UnblockParser() {
|
||||
mParserEnabled=PR_TRUE;
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this));
|
||||
MOZ_TIMER_START(mParseTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to query whether the parser is enabled or not.
|
||||
*
|
||||
@@ -1549,7 +1563,7 @@ nsresult nsParser::EnableParser(PRBool aState){
|
||||
* @return current state
|
||||
*/
|
||||
PRBool nsParser::IsParserEnabled() {
|
||||
return mParserContext->mParserEnabled;
|
||||
return mParserEnabled;
|
||||
}
|
||||
|
||||
|
||||
@@ -1863,7 +1877,7 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mParserContext->mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
if(mParserEnabled && mInternalState!=NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::ResumeParse(), this=%p\n", this));
|
||||
@@ -1904,8 +1918,8 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk) {
|
||||
if(NS_ERROR_HTMLPARSER_BLOCK==result) {
|
||||
//BLOCK == 2152596464
|
||||
mParserContext->mDTD->WillInterruptParse();
|
||||
result=EnableParser(PR_FALSE);
|
||||
return result;
|
||||
BlockParser();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
else if (NS_ERROR_HTMLPARSER_STOPPARSING==result) {
|
||||
@@ -2392,7 +2406,7 @@ nsresult nsParser::OnStopRequest(nsIChannel* channel, nsISupports* aContext,
|
||||
gOutFile=0;
|
||||
}
|
||||
#endif
|
||||
NS_IF_RELEASE(mBundle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,9 @@ class nsParser : public nsIParser,
|
||||
* @param aState determines whether we parse/tokenize or just cache.
|
||||
* @return current state
|
||||
*/
|
||||
virtual nsresult EnableParser(PRBool aState);
|
||||
virtual nsresult ResumeParsing();
|
||||
virtual void BlockParser();
|
||||
virtual void UnblockParser();
|
||||
virtual nsresult Terminate(void);
|
||||
|
||||
/**
|
||||
@@ -407,7 +409,7 @@ protected:
|
||||
CObserverService mObserverService;
|
||||
PRBool mObserversEnabled;
|
||||
nsString mCommandStr;
|
||||
|
||||
PRBool mParserEnabled;
|
||||
nsParserBundle* mBundle;
|
||||
nsTokenAllocator mTokenAllocator;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user