diff --git a/htmlparser/src/CNavDTD.cpp b/htmlparser/src/CNavDTD.cpp
index 5dc39b27e34..0ef7f919f7d 100644
--- a/htmlparser/src/CNavDTD.cpp
+++ b/htmlparser/src/CNavDTD.cpp
@@ -147,7 +147,7 @@ CNavDTD::CNavDTD() : nsIDTD(),
mHasOpenBody=PR_FALSE;
mHasOpenHead=0;
mHasOpenForm=PR_FALSE;
- mHasOpenMap=PR_FALSE;
+ mOpenMapCount=0;
mHasOpenNoXXX=0;
mFormContext=0;
mMapContext=0;
@@ -802,8 +802,13 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
if(theToken){
//Before dealing with the token normally, we need to deal with skip targets
- if((!execSkipContent) && (theType!=eToken_end) &&
- (eHTMLTag_unknown==mSkipTarget) && (gHTMLElements[theTag].mSkipTarget)){ //create a new target
+ CStartToken* theStartToken=NS_STATIC_CAST(CStartToken*,aToken);
+ if((!execSkipContent) &&
+ (theType!=eToken_end) &&
+ (eHTMLTag_unknown==mSkipTarget) &&
+ (gHTMLElements[theTag].mSkipTarget) &&
+ (!theStartToken->IsEmpty())) { // added empty token check for bug 44186
+ //create a new target
mSkipTarget=gHTMLElements[theTag].mSkipTarget;
mSkippedContent.Push(theToken);
}
@@ -1611,12 +1616,12 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
break;
case eHTMLTag_area:
- if(!mHasOpenMap) isTokenHandled=PR_TRUE;
+ if(!mOpenMapCount) isTokenHandled=PR_TRUE;
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleStartToken(), this=%p\n", this));
- if (mHasOpenMap && mSink) {
+ if (mOpenMapCount>0 && mSink) {
result=mSink->AddLeaf(*theNode);
isTokenHandled=PR_TRUE;
}
@@ -2756,7 +2761,7 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
case eHTMLTag_form:
result=mHasOpenForm; break;
case eHTMLTag_map:
- result=mHasOpenMap; break;
+ result=mOpenMapCount>0; break;
default:
result=mBodyContext->HasOpenContainer(aContainer);
break;
@@ -3162,8 +3167,6 @@ nsresult CNavDTD::CloseForm(const nsIParserNode *aNode){
* @return TRUE if ok, FALSE if error
*/
nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
- if(mHasOpenMap)
- CloseMap(aNode);
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenMap(), this=%p\n", this));
@@ -3175,7 +3178,7 @@ nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
if(NS_OK==result) {
mBodyContext->Push(aNode);
- mHasOpenMap=PR_TRUE;
+ mOpenMapCount++;
}
return result;
}
@@ -3191,8 +3194,8 @@ nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
nsresult CNavDTD::CloseMap(const nsIParserNode *aNode){
// NS_PRECONDITION(mBodyContext->GetCount() > 0, kInvalidTagStackPos);
nsresult result=NS_OK;
- if(mHasOpenMap) {
- mHasOpenMap=PR_FALSE;
+ if(mOpenMapCount) {
+ mOpenMapCount--;
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::CloseMap(), this=%p\n", this));
diff --git a/htmlparser/src/CNavDTD.h b/htmlparser/src/CNavDTD.h
index 3915b6b4e6a..63856d7bfb8 100644
--- a/htmlparser/src/CNavDTD.h
+++ b/htmlparser/src/CNavDTD.h
@@ -500,8 +500,8 @@ protected:
nsDTDContext* mFormContext;
nsDTDContext* mMapContext;
nsDTDContext* mTempContext;
- PRBool mHasOpenForm;
- PRBool mHasOpenMap;
+ PRInt32 mHasOpenForm;
+ PRInt32 mOpenMapCount;
PRInt32 mHasOpenHead;
PRBool mHasOpenBody;
PRInt32 mHasOpenNoXXX; //true when NOFRAMES, NOSCRIPT, NOEMBED, NOLAYER are open
diff --git a/htmlparser/src/nsDTDUtils.cpp b/htmlparser/src/nsDTDUtils.cpp
index bfeb72c2749..2bb2d22834a 100644
--- a/htmlparser/src/nsDTDUtils.cpp
+++ b/htmlparser/src/nsDTDUtils.cpp
@@ -371,7 +371,7 @@ nsDTDContext::nsDTDContext() : mStack(), mEntities(0){
MOZ_COUNT_CTOR(nsDTDContext);
mResidualStyleCount=0;
- mContextTopIndex=0;
+ mContextTopIndex=-1;
mTableStates=0;
mCounters=0;
mTokenAllocator=0;
diff --git a/htmlparser/src/nsElementTable.cpp b/htmlparser/src/nsElementTable.cpp
index a93ac9c9368..5be7f9a5683 100644
--- a/htmlparser/src/nsElementTable.cpp
+++ b/htmlparser/src/nsElementTable.cpp
@@ -857,7 +857,7 @@ void InitializeElementTable(void) {
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone,
/*special props, prop-range*/ 0, kNoPropRange,
- /*special parents,kids,skip*/ &gNoframeRoot,0,eHTMLTag_unknown);
+ /*special parents,kids,skip*/ &gNoframeRoot,0,eHTMLTag_noframes); // Added noframes - fix bug 62803 - since Mozilla supports frames.
Initialize(
/*tag*/ eHTMLTag_nolayer,
diff --git a/htmlparser/src/nsHTMLTokenizer.cpp b/htmlparser/src/nsHTMLTokenizer.cpp
index 3e8a207f89e..31294b781bb 100644
--- a/htmlparser/src/nsHTMLTokenizer.cpp
+++ b/htmlparser/src/nsHTMLTokenizer.cpp
@@ -576,17 +576,21 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
//and a textkey of "/". We should destroy it, and tell the
//start token it was empty.
if(NS_SUCCEEDED(result)) {
+ PRBool isUsableAttr=PR_TRUE;
const nsAReadableString& key=theToken->GetKey();
const nsAReadableString& text=theToken->GetValue();
- if((mDoXMLEmptyTags) && (kForwardSlash==key.CharAt(0)) && (0==text.Length())){
- //tada! our special case! Treat it like an empty start tag...
+ // support XML like syntax to fix bugs like 44186
+ if((kForwardSlash==key.CharAt(0)) && (0==text.Length())){
aToken->SetEmpty(PR_TRUE);
- IF_FREE(theToken);
+ isUsableAttr=!mDoXMLEmptyTags;
}
- else {
+ if(isUsableAttr) {
theAttrCount++;
AddToken((CToken*&)theToken,result,&mTokenDeque,theAllocator);
}
+ else {
+ IF_FREE(theToken);
+ }
}
else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){
aToken->SetEmpty(PR_TRUE);
@@ -677,6 +681,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
}//if
}
+ CStartToken* theStartToken=NS_STATIC_CAST(CStartToken*,aToken);
if(theTagHasAttributes) {
if (eViewSource==mParserCommand) {
// Since we conserve whitespace in view-source mode,
@@ -684,7 +689,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
// and let the first attribute grab it.
aScanner.SetPosition(start, PR_FALSE, PR_TRUE);
}
- result=ConsumeAttributes(aChar,(CStartToken*)aToken,aScanner);
+ result=ConsumeAttributes(aChar,theStartToken,aScanner);
}
/* Now that that's over with, we have one more problem to solve.
@@ -700,7 +705,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
}
if(mRecordTrailingContent)
- RecordTrailingContent((CStartToken*)aToken,aScanner,origin);
+ RecordTrailingContent(theStartToken,aScanner,origin);
//if((eHTMLTag_style==theTag) || (eHTMLTag_script==theTag)) {
if(gHTMLElements[theTag].CanContainType(kCDATA)) {
@@ -709,12 +714,22 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
endText.Assign(endTagName);
endText.InsertWithConversion("",0,2);
- CToken* textToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text);
- result=((CTextToken*)textToken)->ConsumeUntil(0,PRBool(theTag!=eHTMLTag_script),aScanner,endText,mParseMode,aFlushTokens); //tell new token to finish consuming text...
-
- CToken* endToken=theAllocator->CreateTokenOfType(eToken_end,theTag,endTagName);
- AddToken(textToken,result,&mTokenDeque,theAllocator);
- AddToken(endToken,result,&mTokenDeque,theAllocator);
+ CToken* text=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text);
+ CTextToken* textToken=NS_STATIC_CAST(CTextToken*,text);
+ result=textToken->ConsumeUntil(0,theTag!=eHTMLTag_script,aScanner,endText,mParseMode,aFlushTokens); //tell new token to finish consuming text...
+
+ // Fix bug 44186
+ // Support XML like syntax, i.e., ==
+ // Note: if aFlushTokens is TRUE then we have seen an
+ if(!theStartToken->IsEmpty() || aFlushTokens) {
+ theStartToken->SetEmpty(PR_FALSE); // Setting this would make cases like d.w("text"); work.
+ CToken* endToken=theAllocator->CreateTokenOfType(eToken_end,theTag,endTagName);
+ AddToken(text,result,&mTokenDeque,theAllocator);
+ AddToken(endToken,result,&mTokenDeque,theAllocator);
+ }
+ else {
+ IF_FREE(text);
+ }
}
}
diff --git a/parser/htmlparser/src/CNavDTD.cpp b/parser/htmlparser/src/CNavDTD.cpp
index 5dc39b27e34..0ef7f919f7d 100644
--- a/parser/htmlparser/src/CNavDTD.cpp
+++ b/parser/htmlparser/src/CNavDTD.cpp
@@ -147,7 +147,7 @@ CNavDTD::CNavDTD() : nsIDTD(),
mHasOpenBody=PR_FALSE;
mHasOpenHead=0;
mHasOpenForm=PR_FALSE;
- mHasOpenMap=PR_FALSE;
+ mOpenMapCount=0;
mHasOpenNoXXX=0;
mFormContext=0;
mMapContext=0;
@@ -802,8 +802,13 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
if(theToken){
//Before dealing with the token normally, we need to deal with skip targets
- if((!execSkipContent) && (theType!=eToken_end) &&
- (eHTMLTag_unknown==mSkipTarget) && (gHTMLElements[theTag].mSkipTarget)){ //create a new target
+ CStartToken* theStartToken=NS_STATIC_CAST(CStartToken*,aToken);
+ if((!execSkipContent) &&
+ (theType!=eToken_end) &&
+ (eHTMLTag_unknown==mSkipTarget) &&
+ (gHTMLElements[theTag].mSkipTarget) &&
+ (!theStartToken->IsEmpty())) { // added empty token check for bug 44186
+ //create a new target
mSkipTarget=gHTMLElements[theTag].mSkipTarget;
mSkippedContent.Push(theToken);
}
@@ -1611,12 +1616,12 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
break;
case eHTMLTag_area:
- if(!mHasOpenMap) isTokenHandled=PR_TRUE;
+ if(!mOpenMapCount) isTokenHandled=PR_TRUE;
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleStartToken(), this=%p\n", this));
- if (mHasOpenMap && mSink) {
+ if (mOpenMapCount>0 && mSink) {
result=mSink->AddLeaf(*theNode);
isTokenHandled=PR_TRUE;
}
@@ -2756,7 +2761,7 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
case eHTMLTag_form:
result=mHasOpenForm; break;
case eHTMLTag_map:
- result=mHasOpenMap; break;
+ result=mOpenMapCount>0; break;
default:
result=mBodyContext->HasOpenContainer(aContainer);
break;
@@ -3162,8 +3167,6 @@ nsresult CNavDTD::CloseForm(const nsIParserNode *aNode){
* @return TRUE if ok, FALSE if error
*/
nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
- if(mHasOpenMap)
- CloseMap(aNode);
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenMap(), this=%p\n", this));
@@ -3175,7 +3178,7 @@ nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
if(NS_OK==result) {
mBodyContext->Push(aNode);
- mHasOpenMap=PR_TRUE;
+ mOpenMapCount++;
}
return result;
}
@@ -3191,8 +3194,8 @@ nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
nsresult CNavDTD::CloseMap(const nsIParserNode *aNode){
// NS_PRECONDITION(mBodyContext->GetCount() > 0, kInvalidTagStackPos);
nsresult result=NS_OK;
- if(mHasOpenMap) {
- mHasOpenMap=PR_FALSE;
+ if(mOpenMapCount) {
+ mOpenMapCount--;
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::CloseMap(), this=%p\n", this));
diff --git a/parser/htmlparser/src/CNavDTD.h b/parser/htmlparser/src/CNavDTD.h
index 3915b6b4e6a..63856d7bfb8 100644
--- a/parser/htmlparser/src/CNavDTD.h
+++ b/parser/htmlparser/src/CNavDTD.h
@@ -500,8 +500,8 @@ protected:
nsDTDContext* mFormContext;
nsDTDContext* mMapContext;
nsDTDContext* mTempContext;
- PRBool mHasOpenForm;
- PRBool mHasOpenMap;
+ PRInt32 mHasOpenForm;
+ PRInt32 mOpenMapCount;
PRInt32 mHasOpenHead;
PRBool mHasOpenBody;
PRInt32 mHasOpenNoXXX; //true when NOFRAMES, NOSCRIPT, NOEMBED, NOLAYER are open
diff --git a/parser/htmlparser/src/nsDTDUtils.cpp b/parser/htmlparser/src/nsDTDUtils.cpp
index bfeb72c2749..2bb2d22834a 100644
--- a/parser/htmlparser/src/nsDTDUtils.cpp
+++ b/parser/htmlparser/src/nsDTDUtils.cpp
@@ -371,7 +371,7 @@ nsDTDContext::nsDTDContext() : mStack(), mEntities(0){
MOZ_COUNT_CTOR(nsDTDContext);
mResidualStyleCount=0;
- mContextTopIndex=0;
+ mContextTopIndex=-1;
mTableStates=0;
mCounters=0;
mTokenAllocator=0;
diff --git a/parser/htmlparser/src/nsElementTable.cpp b/parser/htmlparser/src/nsElementTable.cpp
index a93ac9c9368..5be7f9a5683 100644
--- a/parser/htmlparser/src/nsElementTable.cpp
+++ b/parser/htmlparser/src/nsElementTable.cpp
@@ -857,7 +857,7 @@ void InitializeElementTable(void) {
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone,
/*special props, prop-range*/ 0, kNoPropRange,
- /*special parents,kids,skip*/ &gNoframeRoot,0,eHTMLTag_unknown);
+ /*special parents,kids,skip*/ &gNoframeRoot,0,eHTMLTag_noframes); // Added noframes - fix bug 62803 - since Mozilla supports frames.
Initialize(
/*tag*/ eHTMLTag_nolayer,
diff --git a/parser/htmlparser/src/nsHTMLTokenizer.cpp b/parser/htmlparser/src/nsHTMLTokenizer.cpp
index 3e8a207f89e..31294b781bb 100644
--- a/parser/htmlparser/src/nsHTMLTokenizer.cpp
+++ b/parser/htmlparser/src/nsHTMLTokenizer.cpp
@@ -576,17 +576,21 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
//and a textkey of "/". We should destroy it, and tell the
//start token it was empty.
if(NS_SUCCEEDED(result)) {
+ PRBool isUsableAttr=PR_TRUE;
const nsAReadableString& key=theToken->GetKey();
const nsAReadableString& text=theToken->GetValue();
- if((mDoXMLEmptyTags) && (kForwardSlash==key.CharAt(0)) && (0==text.Length())){
- //tada! our special case! Treat it like an empty start tag...
+ // support XML like syntax to fix bugs like 44186
+ if((kForwardSlash==key.CharAt(0)) && (0==text.Length())){
aToken->SetEmpty(PR_TRUE);
- IF_FREE(theToken);
+ isUsableAttr=!mDoXMLEmptyTags;
}
- else {
+ if(isUsableAttr) {
theAttrCount++;
AddToken((CToken*&)theToken,result,&mTokenDeque,theAllocator);
}
+ else {
+ IF_FREE(theToken);
+ }
}
else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){
aToken->SetEmpty(PR_TRUE);
@@ -677,6 +681,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
}//if
}
+ CStartToken* theStartToken=NS_STATIC_CAST(CStartToken*,aToken);
if(theTagHasAttributes) {
if (eViewSource==mParserCommand) {
// Since we conserve whitespace in view-source mode,
@@ -684,7 +689,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
// and let the first attribute grab it.
aScanner.SetPosition(start, PR_FALSE, PR_TRUE);
}
- result=ConsumeAttributes(aChar,(CStartToken*)aToken,aScanner);
+ result=ConsumeAttributes(aChar,theStartToken,aScanner);
}
/* Now that that's over with, we have one more problem to solve.
@@ -700,7 +705,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
}
if(mRecordTrailingContent)
- RecordTrailingContent((CStartToken*)aToken,aScanner,origin);
+ RecordTrailingContent(theStartToken,aScanner,origin);
//if((eHTMLTag_style==theTag) || (eHTMLTag_script==theTag)) {
if(gHTMLElements[theTag].CanContainType(kCDATA)) {
@@ -709,12 +714,22 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
endText.Assign(endTagName);
endText.InsertWithConversion("",0,2);
- CToken* textToken=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text);
- result=((CTextToken*)textToken)->ConsumeUntil(0,PRBool(theTag!=eHTMLTag_script),aScanner,endText,mParseMode,aFlushTokens); //tell new token to finish consuming text...
-
- CToken* endToken=theAllocator->CreateTokenOfType(eToken_end,theTag,endTagName);
- AddToken(textToken,result,&mTokenDeque,theAllocator);
- AddToken(endToken,result,&mTokenDeque,theAllocator);
+ CToken* text=theAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text);
+ CTextToken* textToken=NS_STATIC_CAST(CTextToken*,text);
+ result=textToken->ConsumeUntil(0,theTag!=eHTMLTag_script,aScanner,endText,mParseMode,aFlushTokens); //tell new token to finish consuming text...
+
+ // Fix bug 44186
+ // Support XML like syntax, i.e., ==
+ // Note: if aFlushTokens is TRUE then we have seen an
+ if(!theStartToken->IsEmpty() || aFlushTokens) {
+ theStartToken->SetEmpty(PR_FALSE); // Setting this would make cases like d.w("text"); work.
+ CToken* endToken=theAllocator->CreateTokenOfType(eToken_end,theTag,endTagName);
+ AddToken(text,result,&mTokenDeque,theAllocator);
+ AddToken(endToken,result,&mTokenDeque,theAllocator);
+ }
+ else {
+ IF_FREE(text);
+ }
}
}