mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
fix or partial fix to lots of bugs
This commit is contained in:
parent
10f11b0cca
commit
8871f5e989
@ -684,12 +684,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_meta:
|
||||
{
|
||||
result=OpenHead(attrNode);
|
||||
if(NS_OK==result)
|
||||
result=AddLeaf(attrNode);
|
||||
result=CloseHead(attrNode);
|
||||
}
|
||||
result=AddHeadLeaf(attrNode);
|
||||
break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
@ -1275,13 +1270,9 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
|
||||
case eHTMLTag_dt:
|
||||
{
|
||||
static eHTMLTags datalistTags[]={eHTMLTag_dt,eHTMLTag_dd};
|
||||
|
||||
if(FindTagInSet(aChild,datalistTags,sizeof(datalistTags)/sizeof(eHTMLTag_unknown))) {
|
||||
if(eHTMLTag_dt==aChild)
|
||||
result=PR_TRUE;
|
||||
}
|
||||
else
|
||||
result=FindTagInSet(aChild,gTagSet1,sizeof(gTagSet1)/sizeof(eHTMLTag_unknown));
|
||||
else result=FindTagInSet(aChild,gTagSet1,sizeof(gTagSet1)/sizeof(eHTMLTag_unknown));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1373,6 +1364,8 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
|
||||
if(eHTMLTag_p==aChild)
|
||||
result=PR_FALSE;
|
||||
if(eHTMLTag_div==aChild)
|
||||
result=PR_FALSE;
|
||||
else if(FindTagInSet(aChild,datalistTags,sizeof(datalistTags)/sizeof(eHTMLTag_unknown))) {
|
||||
//we now allow DT/DD inside a paragraph, so long as a DL is open...
|
||||
if(PR_TRUE==HasOpenContainer(eHTMLTag_dl)) {
|
||||
@ -1817,6 +1810,16 @@ PRBool CNavDTD::RequiresAutomaticClosure(eHTMLTags aParentTag,eHTMLTags aChildTa
|
||||
}
|
||||
}
|
||||
*/
|
||||
//this little bit of code forces DT and DD to autoclose each other.
|
||||
if(eHTMLTag_dd==aChildTag) {
|
||||
if(eHTMLTag_dt==aParentTag)
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if(eHTMLTag_dt==aChildTag) {
|
||||
if(eHTMLTag_dd==aParentTag)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
How this works:
|
||||
1. Find the nearest parent on the appropriate stack that can gate the given child.
|
||||
@ -1855,6 +1858,8 @@ PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
|
||||
case eHTMLTag_table:
|
||||
if(eHTMLTag_form==aChild)
|
||||
result=PR_FALSE;
|
||||
else if(FindTagInSet(aChild,gFormElementTags,sizeof(gFormElementTags)/sizeof(eHTMLTag_unknown)))
|
||||
result=!HasOpenContainer(eHTMLTag_form);
|
||||
else result=!FindTagInSet(aChild,gTableTags,sizeof(gTableTags)/sizeof(eHTMLTag_unknown));
|
||||
break;
|
||||
|
||||
@ -1867,6 +1872,8 @@ PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
default:
|
||||
if(FindTagInSet(aChild,gFormElementTags,sizeof(gFormElementTags)/sizeof(eHTMLTag_unknown)))
|
||||
result=!HasOpenContainer(eHTMLTag_form);
|
||||
result=PR_TRUE;
|
||||
}
|
||||
break;
|
||||
@ -1906,8 +1913,7 @@ PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
|
||||
case eHTMLTag_label: case eHTMLTag_legend:
|
||||
case eHTMLTag_select: case eHTMLTag_textarea:
|
||||
case eHTMLTag_option:
|
||||
if(PR_FALSE==HasOpenContainer(eHTMLTag_form))
|
||||
result=PR_TRUE;
|
||||
result=!HasOpenContainer(eHTMLTag_form);
|
||||
break;
|
||||
|
||||
case eHTMLTag_newline:
|
||||
@ -2236,10 +2242,9 @@ PRBool CNavDTD::BackwardPropagate(nsTagStack& aStack,eHTMLTags aParentTag,eHTMLT
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method allows the caller to determine if a form
|
||||
* element is currently open.
|
||||
* This method allows the caller to determine if a given container
|
||||
* is currently open
|
||||
*
|
||||
* @update gess 11/9/98
|
||||
* @param
|
||||
@ -2259,6 +2264,27 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the caller to determine if a any member
|
||||
* in a set of tags is currently open
|
||||
*
|
||||
* @update gess 11/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRBool CNavDTD::HasOpenContainer(const eHTMLTags aTagSet[],PRInt32 aCount) const {
|
||||
|
||||
int theIndex;
|
||||
int theTopIndex=mBodyContext->mElements.mCount-1;
|
||||
|
||||
for(theIndex=theTopIndex;theIndex>0;theIndex--){
|
||||
if(FindTagInSet(mBodyContext->mElements.mTags[theIndex],aTagSet,aCount))
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this method when you want to determine whether a
|
||||
* given tag should be prevented (gated) from closing.
|
||||
@ -2723,6 +2749,9 @@ CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
|
||||
case eHTMLTag_form:
|
||||
result=OpenForm(aNode); break;
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
result=OpenFrameset(aNode); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
{
|
||||
nsCParserNode& theCNode=*(nsCParserNode*)&aNode;
|
||||
@ -2783,6 +2812,9 @@ CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,
|
||||
case eHTMLTag_form:
|
||||
result=CloseForm(aNode); break;
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
result=CloseFrameset(aNode); break;
|
||||
|
||||
case eHTMLTag_title:
|
||||
default:
|
||||
result=mSink->CloseContainer(aNode);
|
||||
@ -2897,6 +2929,36 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method ONLY when you want to write a leaf
|
||||
* into the head container.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return error code; 0 means OK
|
||||
*/
|
||||
nsresult CNavDTD::AddHeadLeaf(const nsIParserNode& aNode){
|
||||
|
||||
static eHTMLTags gNoXTags[]={eHTMLTag_noframes,eHTMLTag_nolayer,eHTMLTag_noscript};
|
||||
|
||||
//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())
|
||||
if(HasOpenContainer(gNoXTags,sizeof(gNoXTags)/sizeof(eHTMLTag_unknown))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult result=OpenHead(aNode);
|
||||
if(NS_OK==result) {
|
||||
result=AddLeaf(aNode);
|
||||
if(NS_OK==result) {
|
||||
result=CloseHead(aNode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static nsTagStack kPropagationStack;
|
||||
|
||||
/**
|
||||
|
@ -393,6 +393,14 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
*/
|
||||
virtual PRBool HasOpenContainer(eHTMLTags aContainer) const;
|
||||
|
||||
/**
|
||||
* Ask parser if a given container is open ANYWHERE on stack
|
||||
* @update gess5/11/98
|
||||
* @param id of container you want to test for
|
||||
* @return TRUE if the given container type is open -- otherwise FALSE
|
||||
*/
|
||||
virtual PRBool HasOpenContainer(const eHTMLTags aTagSet[],PRInt32 aCount) const;
|
||||
|
||||
/**
|
||||
* This method is used to determine the index on the stack of the
|
||||
* nearest container tag that can constrain autoclosure. It is possible
|
||||
@ -516,6 +524,7 @@ protected:
|
||||
* @return error code - 0 if all went well.
|
||||
*/
|
||||
nsresult AddLeaf(const nsIParserNode& aNode);
|
||||
nsresult AddHeadLeaf(const nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* Causes auto-closures of context vector stack in order to find a
|
||||
|
@ -1203,29 +1203,33 @@ PRInt32 CEntityToken::TranslateToUnicodeStr(nsString& aString) {
|
||||
PRInt32 value=0;
|
||||
PRInt32 theRadix[2]={16,10};
|
||||
|
||||
PRUnichar theChar=mTextValue[0];
|
||||
PRBool isDigit=nsString::IsDigit(theChar);
|
||||
if(isDigit || (('x'==theChar) || ('X'==theChar))) {
|
||||
PRInt32 err=0;
|
||||
value=mTextValue.ToInteger(&err,theRadix[isDigit]);
|
||||
if(0==err) {
|
||||
#ifdef PA_REMAP_128_TO_160_ILLEGAL_NCR
|
||||
/* for some illegal, but popular usage */
|
||||
if ((value >= 0x0080) && (value <= 0x009f)) {
|
||||
value = PA_HackTable[value - 0x0080];
|
||||
}
|
||||
#endif
|
||||
aString.Append(PRUnichar(value));
|
||||
if(mTextValue.Length()>1) {
|
||||
PRUnichar theChar1=mTextValue[0];
|
||||
PRUnichar theChar2=mTextValue[1];
|
||||
PRBool isDigit1=nsString::IsDigit(theChar1);
|
||||
|
||||
if(isDigit1 || (('x'==theChar1) || ('X'==theChar1)))
|
||||
if(nsString::IsDigit(theChar2)) {
|
||||
PRInt32 err=0;
|
||||
value=mTextValue.ToInteger(&err,theRadix[isDigit1]);
|
||||
if(0==err) {
|
||||
#ifdef PA_REMAP_128_TO_160_ILLEGAL_NCR
|
||||
/* for some illegal, but popular usage */
|
||||
if ((value >= 0x0080) && (value <= 0x009f)) {
|
||||
value = PA_HackTable[value - 0x0080];
|
||||
}
|
||||
#endif
|
||||
aString.Append(PRUnichar(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
char cbuf[30];
|
||||
mTextValue.ToCString(cbuf, sizeof(cbuf));
|
||||
value = NS_EntityToUnicode(cbuf);
|
||||
if(-1 != value) {
|
||||
aString = PRUnichar(value);
|
||||
}
|
||||
}
|
||||
|
||||
char cbuf[30];
|
||||
mTextValue.ToCString(cbuf, sizeof(cbuf));
|
||||
value = NS_EntityToUnicode(cbuf);
|
||||
if(-1 != value) {
|
||||
aString = PRUnichar(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -770,6 +770,7 @@ nsresult WriteNewline(nsIContentSink& aSink) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called when a tag needs to be sent out
|
||||
*
|
||||
@ -777,7 +778,25 @@ nsresult WriteNewline(nsIContentSink& aSink) {
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
nsresult WriteNBSP(PRInt32 aCount, nsIContentSink& aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
CEntityToken theEntity("nbsp");
|
||||
nsCParserNode theEntityNode(&theEntity,0);
|
||||
int theIndex;
|
||||
for(theIndex=0;theIndex<aCount;theIndex++)
|
||||
result=aSink.AddLeaf(theEntityNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a tag needs to be sent out
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
nsresult WriteText(CToken* aToken,nsIContentSink& aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsString& theText=aToken->GetStringValueXXX();
|
||||
@ -786,7 +805,7 @@ nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
if(-1<theOffset){
|
||||
while(-1!=theOffset){
|
||||
nsString temp;
|
||||
theText.Mid(temp,theStart,theOffset-theStart);
|
||||
theText.Mid(temp,theStart,theOffset-theStart-1);
|
||||
CTextToken theToken(temp);
|
||||
nsCParserNode theNode((CToken*)&theToken,0);
|
||||
result=aSink.AddLeaf(theNode); //just dump the whole string...
|
||||
@ -802,9 +821,77 @@ nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
CTextToken theToken(temp);
|
||||
nsCParserNode theNode((CToken*)&theToken,0);
|
||||
result=aSink.AddLeaf(theNode); //just dump the whole string...
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a comment needs to be saved.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
nsresult WriteComment(CToken* aToken,nsIContentSink& aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
SetColor("green",PR_TRUE,aSink);
|
||||
SetStyle(eHTMLTag_i,PR_TRUE,aSink);
|
||||
|
||||
nsString& theText=aToken->GetStringValueXXX();
|
||||
CTextToken theTextToken;
|
||||
nsCParserNode theTextNode((CToken*)&theTextToken,0);
|
||||
nsString& temp=theTextToken.GetStringValueXXX();
|
||||
|
||||
PRInt32 theEnd=theText.Length();
|
||||
PRInt32 theOffset=0;
|
||||
|
||||
while(theOffset<theEnd){
|
||||
switch(theText[theOffset]){
|
||||
case kCR:
|
||||
{
|
||||
if(temp.Length())
|
||||
result=aSink.AddLeaf(theTextNode); //just dump the whole string...
|
||||
WriteNewline(aSink);
|
||||
}
|
||||
temp="";
|
||||
break;
|
||||
case kSpace:
|
||||
if(kSpace==theText[theOffset+1]) {
|
||||
if(temp.Length())
|
||||
result=aSink.AddLeaf(theTextNode); //just dump the whole string...
|
||||
WriteNBSP(1,aSink);
|
||||
temp="";
|
||||
break;
|
||||
}
|
||||
//fall through...
|
||||
default:
|
||||
//scan ahead looking for valid chars...
|
||||
temp+=theText[theOffset];
|
||||
break;
|
||||
}//switch...
|
||||
theOffset++;
|
||||
}
|
||||
if(temp.Length())
|
||||
result=aSink.AddLeaf(theTextNode); //just dump the whole string...
|
||||
SetStyle(eHTMLTag_i,PR_FALSE,aSink);
|
||||
SetStyle(eHTMLTag_font,PR_FALSE,aSink);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
|
||||
PRInt32 theFirst=theOffset;
|
||||
while((++theOffset<theEnd) && (kNewLine!=theText[theOffset]) && (kSpace!=theText[theOffset]));
|
||||
theText.Mid(temp,theFirst,theOffset-theFirst);
|
||||
CTextToken theToken(temp);
|
||||
nsCParserNode theNode((CToken*)&theToken,0);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method gets called when a tag needs to be sent out
|
||||
*
|
||||
@ -812,7 +899,7 @@ nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
PRBool EmitTag(nsCParserNode& aNode,nsIContentSink& aSink,PRBool anEndToken,PRBool aIsHTML) {
|
||||
PRBool WriteTag(nsCParserNode& aNode,nsIContentSink& aSink,PRBool anEndToken,PRBool aIsHTML) {
|
||||
static nsString theString;
|
||||
static nsAutoString theLTEntity("lt");
|
||||
static nsAutoString theGTEntity("gt");
|
||||
@ -904,11 +991,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken) {
|
||||
case eToken_whitespace:
|
||||
{
|
||||
PRInt32 theLength=aToken->GetStringValueXXX().Length();
|
||||
CEntityToken theEntity("nbsp");
|
||||
nsCParserNode theEntityNode(&theEntity,mLineNumber);
|
||||
int theIndex;
|
||||
for(theIndex=0;theIndex<theLength;theIndex++)
|
||||
result=mSink->AddLeaf(theEntityNode);
|
||||
WriteNBSP(theLength,*mSink);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -916,15 +999,17 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken) {
|
||||
result=mSink->AddLeaf(theNode);
|
||||
break;
|
||||
|
||||
case eToken_text:
|
||||
EmitText(aToken,*mSink);
|
||||
case eToken_comment:
|
||||
WriteComment(aToken,*mSink);
|
||||
break;
|
||||
|
||||
case eToken_text:
|
||||
WriteText(aToken,*mSink);
|
||||
break;
|
||||
|
||||
case eToken_comment:
|
||||
case eToken_instruction:
|
||||
{
|
||||
static const char* colors[] = {"orange","green"};
|
||||
SetColor(colors[eToken_comment==theType],PR_TRUE,*mSink);
|
||||
SetColor("orange",PR_TRUE,*mSink);
|
||||
SetStyle(eHTMLTag_i,PR_TRUE,*mSink);
|
||||
CTextToken theTextToken(aToken->GetStringValueXXX());
|
||||
nsCParserNode theTextNode(&theTextToken,mLineNumber);
|
||||
@ -956,7 +1041,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken) {
|
||||
//intentionally fall through...
|
||||
|
||||
case eToken_end:
|
||||
EmitTag(theNode,*mSink,theEndTag,mIsHTML);
|
||||
WriteTag(theNode,*mSink,theEndTag,mIsHTML);
|
||||
break;
|
||||
|
||||
case eToken_style:
|
||||
|
@ -684,12 +684,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_meta:
|
||||
{
|
||||
result=OpenHead(attrNode);
|
||||
if(NS_OK==result)
|
||||
result=AddLeaf(attrNode);
|
||||
result=CloseHead(attrNode);
|
||||
}
|
||||
result=AddHeadLeaf(attrNode);
|
||||
break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
@ -1275,13 +1270,9 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
|
||||
case eHTMLTag_dt:
|
||||
{
|
||||
static eHTMLTags datalistTags[]={eHTMLTag_dt,eHTMLTag_dd};
|
||||
|
||||
if(FindTagInSet(aChild,datalistTags,sizeof(datalistTags)/sizeof(eHTMLTag_unknown))) {
|
||||
if(eHTMLTag_dt==aChild)
|
||||
result=PR_TRUE;
|
||||
}
|
||||
else
|
||||
result=FindTagInSet(aChild,gTagSet1,sizeof(gTagSet1)/sizeof(eHTMLTag_unknown));
|
||||
else result=FindTagInSet(aChild,gTagSet1,sizeof(gTagSet1)/sizeof(eHTMLTag_unknown));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1373,6 +1364,8 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
|
||||
if(eHTMLTag_p==aChild)
|
||||
result=PR_FALSE;
|
||||
if(eHTMLTag_div==aChild)
|
||||
result=PR_FALSE;
|
||||
else if(FindTagInSet(aChild,datalistTags,sizeof(datalistTags)/sizeof(eHTMLTag_unknown))) {
|
||||
//we now allow DT/DD inside a paragraph, so long as a DL is open...
|
||||
if(PR_TRUE==HasOpenContainer(eHTMLTag_dl)) {
|
||||
@ -1817,6 +1810,16 @@ PRBool CNavDTD::RequiresAutomaticClosure(eHTMLTags aParentTag,eHTMLTags aChildTa
|
||||
}
|
||||
}
|
||||
*/
|
||||
//this little bit of code forces DT and DD to autoclose each other.
|
||||
if(eHTMLTag_dd==aChildTag) {
|
||||
if(eHTMLTag_dt==aParentTag)
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if(eHTMLTag_dt==aChildTag) {
|
||||
if(eHTMLTag_dd==aParentTag)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
How this works:
|
||||
1. Find the nearest parent on the appropriate stack that can gate the given child.
|
||||
@ -1855,6 +1858,8 @@ PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
|
||||
case eHTMLTag_table:
|
||||
if(eHTMLTag_form==aChild)
|
||||
result=PR_FALSE;
|
||||
else if(FindTagInSet(aChild,gFormElementTags,sizeof(gFormElementTags)/sizeof(eHTMLTag_unknown)))
|
||||
result=!HasOpenContainer(eHTMLTag_form);
|
||||
else result=!FindTagInSet(aChild,gTableTags,sizeof(gTableTags)/sizeof(eHTMLTag_unknown));
|
||||
break;
|
||||
|
||||
@ -1867,6 +1872,8 @@ PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
default:
|
||||
if(FindTagInSet(aChild,gFormElementTags,sizeof(gFormElementTags)/sizeof(eHTMLTag_unknown)))
|
||||
result=!HasOpenContainer(eHTMLTag_form);
|
||||
result=PR_TRUE;
|
||||
}
|
||||
break;
|
||||
@ -1906,8 +1913,7 @@ PRBool CNavDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
|
||||
case eHTMLTag_label: case eHTMLTag_legend:
|
||||
case eHTMLTag_select: case eHTMLTag_textarea:
|
||||
case eHTMLTag_option:
|
||||
if(PR_FALSE==HasOpenContainer(eHTMLTag_form))
|
||||
result=PR_TRUE;
|
||||
result=!HasOpenContainer(eHTMLTag_form);
|
||||
break;
|
||||
|
||||
case eHTMLTag_newline:
|
||||
@ -2236,10 +2242,9 @@ PRBool CNavDTD::BackwardPropagate(nsTagStack& aStack,eHTMLTags aParentTag,eHTMLT
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method allows the caller to determine if a form
|
||||
* element is currently open.
|
||||
* This method allows the caller to determine if a given container
|
||||
* is currently open
|
||||
*
|
||||
* @update gess 11/9/98
|
||||
* @param
|
||||
@ -2259,6 +2264,27 @@ PRBool CNavDTD::HasOpenContainer(eHTMLTags aContainer) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the caller to determine if a any member
|
||||
* in a set of tags is currently open
|
||||
*
|
||||
* @update gess 11/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRBool CNavDTD::HasOpenContainer(const eHTMLTags aTagSet[],PRInt32 aCount) const {
|
||||
|
||||
int theIndex;
|
||||
int theTopIndex=mBodyContext->mElements.mCount-1;
|
||||
|
||||
for(theIndex=theTopIndex;theIndex>0;theIndex--){
|
||||
if(FindTagInSet(mBodyContext->mElements.mTags[theIndex],aTagSet,aCount))
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this method when you want to determine whether a
|
||||
* given tag should be prevented (gated) from closing.
|
||||
@ -2723,6 +2749,9 @@ CNavDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
|
||||
case eHTMLTag_form:
|
||||
result=OpenForm(aNode); break;
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
result=OpenFrameset(aNode); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
{
|
||||
nsCParserNode& theCNode=*(nsCParserNode*)&aNode;
|
||||
@ -2783,6 +2812,9 @@ CNavDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,
|
||||
case eHTMLTag_form:
|
||||
result=CloseForm(aNode); break;
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
result=CloseFrameset(aNode); break;
|
||||
|
||||
case eHTMLTag_title:
|
||||
default:
|
||||
result=mSink->CloseContainer(aNode);
|
||||
@ -2897,6 +2929,36 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method ONLY when you want to write a leaf
|
||||
* into the head container.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return error code; 0 means OK
|
||||
*/
|
||||
nsresult CNavDTD::AddHeadLeaf(const nsIParserNode& aNode){
|
||||
|
||||
static eHTMLTags gNoXTags[]={eHTMLTag_noframes,eHTMLTag_nolayer,eHTMLTag_noscript};
|
||||
|
||||
//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())
|
||||
if(HasOpenContainer(gNoXTags,sizeof(gNoXTags)/sizeof(eHTMLTag_unknown))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult result=OpenHead(aNode);
|
||||
if(NS_OK==result) {
|
||||
result=AddLeaf(aNode);
|
||||
if(NS_OK==result) {
|
||||
result=CloseHead(aNode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static nsTagStack kPropagationStack;
|
||||
|
||||
/**
|
||||
|
@ -393,6 +393,14 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
*/
|
||||
virtual PRBool HasOpenContainer(eHTMLTags aContainer) const;
|
||||
|
||||
/**
|
||||
* Ask parser if a given container is open ANYWHERE on stack
|
||||
* @update gess5/11/98
|
||||
* @param id of container you want to test for
|
||||
* @return TRUE if the given container type is open -- otherwise FALSE
|
||||
*/
|
||||
virtual PRBool HasOpenContainer(const eHTMLTags aTagSet[],PRInt32 aCount) const;
|
||||
|
||||
/**
|
||||
* This method is used to determine the index on the stack of the
|
||||
* nearest container tag that can constrain autoclosure. It is possible
|
||||
@ -516,6 +524,7 @@ protected:
|
||||
* @return error code - 0 if all went well.
|
||||
*/
|
||||
nsresult AddLeaf(const nsIParserNode& aNode);
|
||||
nsresult AddHeadLeaf(const nsIParserNode& aNode);
|
||||
|
||||
/**
|
||||
* Causes auto-closures of context vector stack in order to find a
|
||||
|
@ -1203,29 +1203,33 @@ PRInt32 CEntityToken::TranslateToUnicodeStr(nsString& aString) {
|
||||
PRInt32 value=0;
|
||||
PRInt32 theRadix[2]={16,10};
|
||||
|
||||
PRUnichar theChar=mTextValue[0];
|
||||
PRBool isDigit=nsString::IsDigit(theChar);
|
||||
if(isDigit || (('x'==theChar) || ('X'==theChar))) {
|
||||
PRInt32 err=0;
|
||||
value=mTextValue.ToInteger(&err,theRadix[isDigit]);
|
||||
if(0==err) {
|
||||
#ifdef PA_REMAP_128_TO_160_ILLEGAL_NCR
|
||||
/* for some illegal, but popular usage */
|
||||
if ((value >= 0x0080) && (value <= 0x009f)) {
|
||||
value = PA_HackTable[value - 0x0080];
|
||||
}
|
||||
#endif
|
||||
aString.Append(PRUnichar(value));
|
||||
if(mTextValue.Length()>1) {
|
||||
PRUnichar theChar1=mTextValue[0];
|
||||
PRUnichar theChar2=mTextValue[1];
|
||||
PRBool isDigit1=nsString::IsDigit(theChar1);
|
||||
|
||||
if(isDigit1 || (('x'==theChar1) || ('X'==theChar1)))
|
||||
if(nsString::IsDigit(theChar2)) {
|
||||
PRInt32 err=0;
|
||||
value=mTextValue.ToInteger(&err,theRadix[isDigit1]);
|
||||
if(0==err) {
|
||||
#ifdef PA_REMAP_128_TO_160_ILLEGAL_NCR
|
||||
/* for some illegal, but popular usage */
|
||||
if ((value >= 0x0080) && (value <= 0x009f)) {
|
||||
value = PA_HackTable[value - 0x0080];
|
||||
}
|
||||
#endif
|
||||
aString.Append(PRUnichar(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
char cbuf[30];
|
||||
mTextValue.ToCString(cbuf, sizeof(cbuf));
|
||||
value = NS_EntityToUnicode(cbuf);
|
||||
if(-1 != value) {
|
||||
aString = PRUnichar(value);
|
||||
}
|
||||
}
|
||||
|
||||
char cbuf[30];
|
||||
mTextValue.ToCString(cbuf, sizeof(cbuf));
|
||||
value = NS_EntityToUnicode(cbuf);
|
||||
if(-1 != value) {
|
||||
aString = PRUnichar(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -770,6 +770,7 @@ nsresult WriteNewline(nsIContentSink& aSink) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called when a tag needs to be sent out
|
||||
*
|
||||
@ -777,7 +778,25 @@ nsresult WriteNewline(nsIContentSink& aSink) {
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
nsresult WriteNBSP(PRInt32 aCount, nsIContentSink& aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
CEntityToken theEntity("nbsp");
|
||||
nsCParserNode theEntityNode(&theEntity,0);
|
||||
int theIndex;
|
||||
for(theIndex=0;theIndex<aCount;theIndex++)
|
||||
result=aSink.AddLeaf(theEntityNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a tag needs to be sent out
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
nsresult WriteText(CToken* aToken,nsIContentSink& aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsString& theText=aToken->GetStringValueXXX();
|
||||
@ -786,7 +805,7 @@ nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
if(-1<theOffset){
|
||||
while(-1!=theOffset){
|
||||
nsString temp;
|
||||
theText.Mid(temp,theStart,theOffset-theStart);
|
||||
theText.Mid(temp,theStart,theOffset-theStart-1);
|
||||
CTextToken theToken(temp);
|
||||
nsCParserNode theNode((CToken*)&theToken,0);
|
||||
result=aSink.AddLeaf(theNode); //just dump the whole string...
|
||||
@ -802,9 +821,77 @@ nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
CTextToken theToken(temp);
|
||||
nsCParserNode theNode((CToken*)&theToken,0);
|
||||
result=aSink.AddLeaf(theNode); //just dump the whole string...
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a comment needs to be saved.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
nsresult WriteComment(CToken* aToken,nsIContentSink& aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
SetColor("green",PR_TRUE,aSink);
|
||||
SetStyle(eHTMLTag_i,PR_TRUE,aSink);
|
||||
|
||||
nsString& theText=aToken->GetStringValueXXX();
|
||||
CTextToken theTextToken;
|
||||
nsCParserNode theTextNode((CToken*)&theTextToken,0);
|
||||
nsString& temp=theTextToken.GetStringValueXXX();
|
||||
|
||||
PRInt32 theEnd=theText.Length();
|
||||
PRInt32 theOffset=0;
|
||||
|
||||
while(theOffset<theEnd){
|
||||
switch(theText[theOffset]){
|
||||
case kCR:
|
||||
{
|
||||
if(temp.Length())
|
||||
result=aSink.AddLeaf(theTextNode); //just dump the whole string...
|
||||
WriteNewline(aSink);
|
||||
}
|
||||
temp="";
|
||||
break;
|
||||
case kSpace:
|
||||
if(kSpace==theText[theOffset+1]) {
|
||||
if(temp.Length())
|
||||
result=aSink.AddLeaf(theTextNode); //just dump the whole string...
|
||||
WriteNBSP(1,aSink);
|
||||
temp="";
|
||||
break;
|
||||
}
|
||||
//fall through...
|
||||
default:
|
||||
//scan ahead looking for valid chars...
|
||||
temp+=theText[theOffset];
|
||||
break;
|
||||
}//switch...
|
||||
theOffset++;
|
||||
}
|
||||
if(temp.Length())
|
||||
result=aSink.AddLeaf(theTextNode); //just dump the whole string...
|
||||
SetStyle(eHTMLTag_i,PR_FALSE,aSink);
|
||||
SetStyle(eHTMLTag_font,PR_FALSE,aSink);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
|
||||
PRInt32 theFirst=theOffset;
|
||||
while((++theOffset<theEnd) && (kNewLine!=theText[theOffset]) && (kSpace!=theText[theOffset]));
|
||||
theText.Mid(temp,theFirst,theOffset-theFirst);
|
||||
CTextToken theToken(temp);
|
||||
nsCParserNode theNode((CToken*)&theToken,0);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method gets called when a tag needs to be sent out
|
||||
*
|
||||
@ -812,7 +899,7 @@ nsresult EmitText(CToken* aToken,nsIContentSink& aSink) {
|
||||
* @param
|
||||
* @return result status
|
||||
*/
|
||||
PRBool EmitTag(nsCParserNode& aNode,nsIContentSink& aSink,PRBool anEndToken,PRBool aIsHTML) {
|
||||
PRBool WriteTag(nsCParserNode& aNode,nsIContentSink& aSink,PRBool anEndToken,PRBool aIsHTML) {
|
||||
static nsString theString;
|
||||
static nsAutoString theLTEntity("lt");
|
||||
static nsAutoString theGTEntity("gt");
|
||||
@ -904,11 +991,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken) {
|
||||
case eToken_whitespace:
|
||||
{
|
||||
PRInt32 theLength=aToken->GetStringValueXXX().Length();
|
||||
CEntityToken theEntity("nbsp");
|
||||
nsCParserNode theEntityNode(&theEntity,mLineNumber);
|
||||
int theIndex;
|
||||
for(theIndex=0;theIndex<theLength;theIndex++)
|
||||
result=mSink->AddLeaf(theEntityNode);
|
||||
WriteNBSP(theLength,*mSink);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -916,15 +999,17 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken) {
|
||||
result=mSink->AddLeaf(theNode);
|
||||
break;
|
||||
|
||||
case eToken_text:
|
||||
EmitText(aToken,*mSink);
|
||||
case eToken_comment:
|
||||
WriteComment(aToken,*mSink);
|
||||
break;
|
||||
|
||||
case eToken_text:
|
||||
WriteText(aToken,*mSink);
|
||||
break;
|
||||
|
||||
case eToken_comment:
|
||||
case eToken_instruction:
|
||||
{
|
||||
static const char* colors[] = {"orange","green"};
|
||||
SetColor(colors[eToken_comment==theType],PR_TRUE,*mSink);
|
||||
SetColor("orange",PR_TRUE,*mSink);
|
||||
SetStyle(eHTMLTag_i,PR_TRUE,*mSink);
|
||||
CTextToken theTextToken(aToken->GetStringValueXXX());
|
||||
nsCParserNode theTextNode(&theTextToken,mLineNumber);
|
||||
@ -956,7 +1041,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken) {
|
||||
//intentionally fall through...
|
||||
|
||||
case eToken_end:
|
||||
EmitTag(theNode,*mSink,theEndTag,mIsHTML);
|
||||
WriteTag(theNode,*mSink,theEndTag,mIsHTML);
|
||||
break;
|
||||
|
||||
case eToken_style:
|
||||
|
Loading…
Reference in New Issue
Block a user