This commit is contained in:
rickg%netscape.com 1998-10-04 04:56:55 +00:00
Родитель bbc76113d1
Коммит 04214a2813
6 изменённых файлов: 302 добавлений и 112 удалений

Просмотреть файл

@ -14,7 +14,7 @@
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
*/
#include "nsIDTDDebug.h"
@ -530,6 +530,36 @@ nsresult CNavDTD::HandleToken(CToken* aToken){
return result;
}
/**
* This gets called after we've handled a given start tag.
* It's a generic hook to let us to post processing.
* @param aToken contains the tag in question
* @param aChildTag is the tag itself.
* @return status
*/
PRInt32 CNavDTD::DidHandleStartTag(CToken* aToken,eHTMLTags aChildTag){
PRInt32 result=kNoError;
CToken* theNextToken=mParser->PeekToken();
if(theNextToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
if(eToken_newline==theType){
switch(aChildTag){
case eHTMLTag_pre:
case eHTMLTag_listing:
//we skip the first newline token inside PRE and LISTING
mParser->PopToken();
break;
default:
break;
}//switch
}//if
}//if
return result;
}
/**
@ -549,11 +579,14 @@ nsresult CNavDTD::HandleToken(CToken* aToken){
nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode) {
NS_PRECONDITION(0!=aToken,kNullToken);
eHTMLTags theParentTag=mBodyContext->mElements.Last();
nsresult result=NS_OK;
PRBool contains=CanContain(theParentTag,aChildTag);
eHTMLTags theParentTag=mBodyContext->mElements.Last();
if(PR_FALSE==contains){
if(RequiresAutomaticClosure(theParentTag,aChildTag)){
result=CloseContainersTo(aChildTag,PR_TRUE);
}
if(PR_FALSE==CanContain(theParentTag,aChildTag)){
if(CanPropagate(theParentTag,aChildTag))
result=CreateContextStackFor(aChildTag);
else result=kCantPropagate;
@ -581,6 +614,10 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
}
result=AddLeaf(aNode);
}
//now do any post processing necessary on the tag...
if(NS_OK==result)
DidHandleStartTag(aToken,aChildTag);
return result;
}
@ -600,18 +637,20 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
*/
nsresult CNavDTD::HandleStartToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,kNullToken);
eHTMLTags tokenTagType=(eHTMLTags)aToken->GetTypeID();
//Begin by gathering up attributes...
nsCParserNode attrNode((CHTMLToken*)aToken,mLineNumber);
PRInt16 attrCount=aToken->GetAttributeCount();
nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(attrNode,attrCount);
eHTMLTags theParent=mBodyContext->mElements.Last();
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
if(NS_OK==result) {
//now check to see if this token should be omitted...
if(PR_FALSE==CanOmit(mBodyContext->mElements.Last(),tokenTagType)) {
if(PR_FALSE==CanOmit(theParent,theChildTag)) {
switch(tokenTagType) {
switch(theChildTag) {
case eHTMLTag_title:
{
@ -658,13 +697,13 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
break;
default:
result=HandleDefaultStartToken(aToken,tokenTagType,attrNode);
result=HandleDefaultStartToken(aToken,theChildTag,attrNode);
break;
} //switch
} //if
} //if
if(eHTMLTag_newline==tokenTagType)
if(eHTMLTag_newline==theChildTag)
mLineNumber++;
return result;
@ -1050,18 +1089,20 @@ PRBool CNavDTD::CanContainStyles(eHTMLTags aParent) const {
***********************************************************************************/
static eHTMLTags gTagSet1[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
eHTMLTag_a, eHTMLTag_abbr, eHTMLTag_acronym,
eHTMLTag_address, eHTMLTag_applet,
eHTMLTag_blink, eHTMLTag_b, eHTMLTag_basefont, eHTMLTag_bdo,
eHTMLTag_big,
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
eHTMLTag_cite, eHTMLTag_code,
eHTMLTag_del, eHTMLTag_dfn, eHTMLTag_dir,
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_dt,
eHTMLTag_em, eHTMLTag_embed,
eHTMLTag_fieldset, eHTMLTag_font, eHTMLTag_form,
eHTMLTag_h1, eHTMLTag_h2, eHTMLTag_h3,
eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
eHTMLTag_hr, eHTMLTag_i, eHTMLTag_iframe, eHTMLTag_img,
eHTMLTag_input, eHTMLTag_isindex,
eHTMLTag_input, eHTMLTag_ins, eHTMLTag_isindex,
eHTMLTag_kbd, eHTMLTag_label, eHTMLTag_layer, eHTMLTag_li,
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_newline, eHTMLTag_nobr,
@ -1077,13 +1118,16 @@ static eHTMLTags gTagSet1[]={
eHTMLTag_whitespace};
static eHTMLTags gTagSet2[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_a, eHTMLTag_abbr, eHTMLTag_acronym,
eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_b,
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
eHTMLTag_div, eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr,
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code,
eHTMLTag_del, eHTMLTag_dfn, eHTMLTag_div,
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr,
eHTMLTag_embed,
eHTMLTag_i, eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input,
eHTMLTag_i, eHTMLTag_iframe, eHTMLTag_img,
eHTMLTag_input, eHTMLTag_ins,
eHTMLTag_kbd,
eHTMLTag_label, eHTMLTag_layer, eHTMLTag_map, eHTMLTag_newline,
@ -1099,7 +1143,8 @@ static eHTMLTags gTagSet2[]={
eHTMLTag_wbr, eHTMLTag_whitespace};
static eHTMLTags gTagSet3[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_a, eHTMLTag_abbr, eHTMLTag_acronym,
eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_b,
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
@ -1156,7 +1201,7 @@ inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount
*/
PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
PRBool result=(eHTMLTag_userdefined==aChild) ? PR_TRUE : !IsContainer(aParent);
PRBool result=!IsContainer(aParent);
/***************************************************************************
@ -1196,16 +1241,6 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
}
else {
switch((eHTMLTags)aParent) {
case eHTMLTag_address:
result=FindTagInSet(aChild,gTagSet2,sizeof(gTagSet2)/sizeof(eHTMLTag_unknown));
break;
case eHTMLTag_applet:
if(eHTMLTag_param==aChild)
result=PR_TRUE;
else
result=FindTagInSet(aChild,gTagSet2,sizeof(gTagSet2)/sizeof(eHTMLTag_unknown));
break;
case eHTMLTag_blockquote:
case eHTMLTag_body:
@ -1351,7 +1386,15 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
}
break;
case eHTMLTag_applet:
case eHTMLTag_object:
if(eHTMLTag_param==aChild) {
result=PR_TRUE;
break;
}
//otherwise fall through...
case eHTMLTag_address:
case eHTMLTag_pre:
result=FindTagInSet(aChild,gTagSet2,sizeof(gTagSet2)/sizeof(eHTMLTag_unknown));
break;
@ -1483,6 +1526,40 @@ PRBool CNavDTD::CanContainIndirect(eHTMLTags aParent,eHTMLTags aChild) const {
return result;
}
/**
* This method is called to determine whether or not a tag
* can be autoclosed. This means that based on the current
* context, the stack should be closed to the nearest matching
* tag.
*
* @param aTag -- tag enum of child to be tested
* @return PR_TRUE if autoclosure should occur
*/
PRBool CNavDTD::RequiresAutomaticClosure(eHTMLTags aParentTag,eHTMLTags aChildTag) const {
static eHTMLTags gAutoCloseTags[]={eHTMLTag_li,eHTMLTag_td,eHTMLTag_tr};
PRBool result=PR_FALSE;
PRInt32 theParentIndex=kNotFound;
/***************************************************************************************
How this works:
1. Find the nearest parent on the appropriate stack that can gate the given child.
2. See if another child tag that matches this one is already open.
3. If there is and IT'S NOT GATED then autoclose it.
***************************************************************************************/
if(eHTMLTag_unknown!=aParentTag){
if(PR_TRUE==FindTagInSet(aChildTag,gAutoCloseTags,sizeof(gAutoCloseTags)/sizeof(eHTMLTag_unknown))) {
if(PR_TRUE==HasOpenContainer(aChildTag)) {
if(PR_FALSE==IsGatedFromClosing(aChildTag))
result=PR_TRUE;
}
}
}
return result;
}
/**
* This method gets called to determine whether a given
* tag can contain newlines. Most do not.

Просмотреть файл

@ -516,11 +516,12 @@ protected:
* @param aTag -- represents the transient style tag to be handled.
* @return error code -- usually 0
*/
nsresult OpenTransientStyles(eHTMLTags aTag);
nsresult CloseTransientStyles(eHTMLTags aTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
PRBool CanContainStyles(eHTMLTags aTag) const;
nsresult OpenTransientStyles(eHTMLTags aTag);
nsresult CloseTransientStyles(eHTMLTags aTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
PRBool CanContainStyles(eHTMLTags aTag) const;
PRBool RequiresAutomaticClosure(eHTMLTags aParentTag,eHTMLTags aChildTag) const;
/****************************************************
These methods interface with the parser to do
@ -566,8 +567,8 @@ protected:
PRInt32 CollectAttributes(nsCParserNode& aNode,PRInt32 aCount);
PRInt32 CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
PRInt32 DidHandleStartTag(CToken* aToken,eHTMLTags aChildTag);
nsParser* mParser;
nsIHTMLContentSink* mSink;

Просмотреть файл

@ -800,30 +800,43 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
//now it's time to Consume the (optional) value...
if(NS_OK == (result=aScanner.SkipWhitespace())) {
//Skip ahead until you find an equal sign or a '>'...
if(NS_OK == (result=aScanner.Peek(aChar))) {
if(kEqual==aChar){
result=aScanner.GetChar(aChar); //skip the equal sign...
if(NS_OK == (result=aScanner.Peek(aChar))) {
if(kEqual==aChar){
result=aScanner.GetChar(aChar); //skip the equal sign...
if(NS_OK==result) {
result=aScanner.SkipWhitespace(); //now skip any intervening whitespace
if(NS_OK==result) {
result=aScanner.SkipWhitespace(); //now skip any intervening whitespace
result=aScanner.GetChar(aChar); //and grab the next char.
if(NS_OK==result) {
result=aScanner.GetChar(aChar); //and grab the next char.
if(NS_OK==result) {
if((kQuote==aChar) || (kApostrophe==aChar)) {
mTextValue=aChar;
result=ConsumeQuotedString(aChar,mTextValue,aScanner);
}
else {
mTextValue=aChar; //it's an alphanum attribute...
result=ConsumeAttributeValueText(aChar,mTextValue,aScanner);
}
}//if
if(NS_OK==result)
result=aScanner.SkipWhitespace();
if((kQuote==aChar) || (kApostrophe==aChar)) {
mTextValue=aChar;
result=ConsumeQuotedString(aChar,mTextValue,aScanner);
}
else {
mTextValue=aChar; //it's an alphanum attribute...
result=ConsumeAttributeValueText(aChar,mTextValue,aScanner);
}
}//if
if(NS_OK==result)
result=aScanner.SkipWhitespace();
}//if
}//if
}//if
// }if
else {
//This is where we have to handle fairly busted content.
//If you're here, it means we saw an attribute name, but couldn't find
//the following equal sign. <tag NAME=....
//Doing this right in all cases is <i>REALLY</i> ugly.
//My best guess is to grab the next non-ws char. We know it's not '=',
//so let's see what it is. If it's a '"', then assume we're reading
//from the middle of the value. Try stripping the quote and continuing...
if(kQuote==aChar){
result=aScanner.GetChar(aChar); //strip quote.
}
}
}//if
}
if(NS_OK==result) {
result=aScanner.Peek(aChar);
@ -1075,14 +1088,18 @@ static PRUint16 PA_HackTable[] = {
* unicode equivalent.
*
* @update gess 3/25/98
* @param
* @return
* @param aString will hold the resulting string value
* @return numeric (unichar) value
*/
PRInt32 CEntityToken::TranslateToUnicodeStr(nsString& aString) {
PRInt32 value=0;
if(nsString::IsDigit(mTextValue[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);
value=mTextValue.ToInteger(&err,theRadix[isDigit]);
if(0==err) {
#ifdef PA_REMAP_128_TO_160_ILLEGAL_NCR
/* for some illegal, but popular usage */

Просмотреть файл

@ -14,7 +14,7 @@
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
*/
#include "nsIDTDDebug.h"
@ -530,6 +530,36 @@ nsresult CNavDTD::HandleToken(CToken* aToken){
return result;
}
/**
* This gets called after we've handled a given start tag.
* It's a generic hook to let us to post processing.
* @param aToken contains the tag in question
* @param aChildTag is the tag itself.
* @return status
*/
PRInt32 CNavDTD::DidHandleStartTag(CToken* aToken,eHTMLTags aChildTag){
PRInt32 result=kNoError;
CToken* theNextToken=mParser->PeekToken();
if(theNextToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
if(eToken_newline==theType){
switch(aChildTag){
case eHTMLTag_pre:
case eHTMLTag_listing:
//we skip the first newline token inside PRE and LISTING
mParser->PopToken();
break;
default:
break;
}//switch
}//if
}//if
return result;
}
/**
@ -549,11 +579,14 @@ nsresult CNavDTD::HandleToken(CToken* aToken){
nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode) {
NS_PRECONDITION(0!=aToken,kNullToken);
eHTMLTags theParentTag=mBodyContext->mElements.Last();
nsresult result=NS_OK;
PRBool contains=CanContain(theParentTag,aChildTag);
eHTMLTags theParentTag=mBodyContext->mElements.Last();
if(PR_FALSE==contains){
if(RequiresAutomaticClosure(theParentTag,aChildTag)){
result=CloseContainersTo(aChildTag,PR_TRUE);
}
if(PR_FALSE==CanContain(theParentTag,aChildTag)){
if(CanPropagate(theParentTag,aChildTag))
result=CreateContextStackFor(aChildTag);
else result=kCantPropagate;
@ -581,6 +614,10 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
}
result=AddLeaf(aNode);
}
//now do any post processing necessary on the tag...
if(NS_OK==result)
DidHandleStartTag(aToken,aChildTag);
return result;
}
@ -600,18 +637,20 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
*/
nsresult CNavDTD::HandleStartToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,kNullToken);
eHTMLTags tokenTagType=(eHTMLTags)aToken->GetTypeID();
//Begin by gathering up attributes...
nsCParserNode attrNode((CHTMLToken*)aToken,mLineNumber);
PRInt16 attrCount=aToken->GetAttributeCount();
nsresult result=(0==attrCount) ? NS_OK : CollectAttributes(attrNode,attrCount);
eHTMLTags theParent=mBodyContext->mElements.Last();
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
if(NS_OK==result) {
//now check to see if this token should be omitted...
if(PR_FALSE==CanOmit(mBodyContext->mElements.Last(),tokenTagType)) {
if(PR_FALSE==CanOmit(theParent,theChildTag)) {
switch(tokenTagType) {
switch(theChildTag) {
case eHTMLTag_title:
{
@ -658,13 +697,13 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
break;
default:
result=HandleDefaultStartToken(aToken,tokenTagType,attrNode);
result=HandleDefaultStartToken(aToken,theChildTag,attrNode);
break;
} //switch
} //if
} //if
if(eHTMLTag_newline==tokenTagType)
if(eHTMLTag_newline==theChildTag)
mLineNumber++;
return result;
@ -1050,18 +1089,20 @@ PRBool CNavDTD::CanContainStyles(eHTMLTags aParent) const {
***********************************************************************************/
static eHTMLTags gTagSet1[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
eHTMLTag_a, eHTMLTag_abbr, eHTMLTag_acronym,
eHTMLTag_address, eHTMLTag_applet,
eHTMLTag_blink, eHTMLTag_b, eHTMLTag_basefont, eHTMLTag_bdo,
eHTMLTag_big,
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
eHTMLTag_cite, eHTMLTag_code,
eHTMLTag_del, eHTMLTag_dfn, eHTMLTag_dir,
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_dt,
eHTMLTag_em, eHTMLTag_embed,
eHTMLTag_fieldset, eHTMLTag_font, eHTMLTag_form,
eHTMLTag_h1, eHTMLTag_h2, eHTMLTag_h3,
eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
eHTMLTag_hr, eHTMLTag_i, eHTMLTag_iframe, eHTMLTag_img,
eHTMLTag_input, eHTMLTag_isindex,
eHTMLTag_input, eHTMLTag_ins, eHTMLTag_isindex,
eHTMLTag_kbd, eHTMLTag_label, eHTMLTag_layer, eHTMLTag_li,
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_newline, eHTMLTag_nobr,
@ -1077,13 +1118,16 @@ static eHTMLTags gTagSet1[]={
eHTMLTag_whitespace};
static eHTMLTags gTagSet2[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_a, eHTMLTag_abbr, eHTMLTag_acronym,
eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_b,
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
eHTMLTag_div, eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr,
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code,
eHTMLTag_del, eHTMLTag_dfn, eHTMLTag_div,
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr,
eHTMLTag_embed,
eHTMLTag_i, eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input,
eHTMLTag_i, eHTMLTag_iframe, eHTMLTag_img,
eHTMLTag_input, eHTMLTag_ins,
eHTMLTag_kbd,
eHTMLTag_label, eHTMLTag_layer, eHTMLTag_map, eHTMLTag_newline,
@ -1099,7 +1143,8 @@ static eHTMLTags gTagSet2[]={
eHTMLTag_wbr, eHTMLTag_whitespace};
static eHTMLTags gTagSet3[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_a, eHTMLTag_abbr, eHTMLTag_acronym,
eHTMLTag_applet, eHTMLTag_blink,
eHTMLTag_b,
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
@ -1156,7 +1201,7 @@ inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount
*/
PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
PRBool result=(eHTMLTag_userdefined==aChild) ? PR_TRUE : !IsContainer(aParent);
PRBool result=!IsContainer(aParent);
/***************************************************************************
@ -1196,16 +1241,6 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
}
else {
switch((eHTMLTags)aParent) {
case eHTMLTag_address:
result=FindTagInSet(aChild,gTagSet2,sizeof(gTagSet2)/sizeof(eHTMLTag_unknown));
break;
case eHTMLTag_applet:
if(eHTMLTag_param==aChild)
result=PR_TRUE;
else
result=FindTagInSet(aChild,gTagSet2,sizeof(gTagSet2)/sizeof(eHTMLTag_unknown));
break;
case eHTMLTag_blockquote:
case eHTMLTag_body:
@ -1351,7 +1386,15 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
}
break;
case eHTMLTag_applet:
case eHTMLTag_object:
if(eHTMLTag_param==aChild) {
result=PR_TRUE;
break;
}
//otherwise fall through...
case eHTMLTag_address:
case eHTMLTag_pre:
result=FindTagInSet(aChild,gTagSet2,sizeof(gTagSet2)/sizeof(eHTMLTag_unknown));
break;
@ -1483,6 +1526,40 @@ PRBool CNavDTD::CanContainIndirect(eHTMLTags aParent,eHTMLTags aChild) const {
return result;
}
/**
* This method is called to determine whether or not a tag
* can be autoclosed. This means that based on the current
* context, the stack should be closed to the nearest matching
* tag.
*
* @param aTag -- tag enum of child to be tested
* @return PR_TRUE if autoclosure should occur
*/
PRBool CNavDTD::RequiresAutomaticClosure(eHTMLTags aParentTag,eHTMLTags aChildTag) const {
static eHTMLTags gAutoCloseTags[]={eHTMLTag_li,eHTMLTag_td,eHTMLTag_tr};
PRBool result=PR_FALSE;
PRInt32 theParentIndex=kNotFound;
/***************************************************************************************
How this works:
1. Find the nearest parent on the appropriate stack that can gate the given child.
2. See if another child tag that matches this one is already open.
3. If there is and IT'S NOT GATED then autoclose it.
***************************************************************************************/
if(eHTMLTag_unknown!=aParentTag){
if(PR_TRUE==FindTagInSet(aChildTag,gAutoCloseTags,sizeof(gAutoCloseTags)/sizeof(eHTMLTag_unknown))) {
if(PR_TRUE==HasOpenContainer(aChildTag)) {
if(PR_FALSE==IsGatedFromClosing(aChildTag))
result=PR_TRUE;
}
}
}
return result;
}
/**
* This method gets called to determine whether a given
* tag can contain newlines. Most do not.

Просмотреть файл

@ -516,11 +516,12 @@ protected:
* @param aTag -- represents the transient style tag to be handled.
* @return error code -- usually 0
*/
nsresult OpenTransientStyles(eHTMLTags aTag);
nsresult CloseTransientStyles(eHTMLTags aTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
PRBool CanContainStyles(eHTMLTags aTag) const;
nsresult OpenTransientStyles(eHTMLTags aTag);
nsresult CloseTransientStyles(eHTMLTags aTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
PRBool CanContainStyles(eHTMLTags aTag) const;
PRBool RequiresAutomaticClosure(eHTMLTags aParentTag,eHTMLTags aChildTag) const;
/****************************************************
These methods interface with the parser to do
@ -566,8 +567,8 @@ protected:
PRInt32 CollectAttributes(nsCParserNode& aNode,PRInt32 aCount);
PRInt32 CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
PRInt32 DidHandleStartTag(CToken* aToken,eHTMLTags aChildTag);
nsParser* mParser;
nsIHTMLContentSink* mSink;

Просмотреть файл

@ -800,30 +800,43 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, CScanner& aScanner) {
//now it's time to Consume the (optional) value...
if(NS_OK == (result=aScanner.SkipWhitespace())) {
//Skip ahead until you find an equal sign or a '>'...
if(NS_OK == (result=aScanner.Peek(aChar))) {
if(kEqual==aChar){
result=aScanner.GetChar(aChar); //skip the equal sign...
if(NS_OK == (result=aScanner.Peek(aChar))) {
if(kEqual==aChar){
result=aScanner.GetChar(aChar); //skip the equal sign...
if(NS_OK==result) {
result=aScanner.SkipWhitespace(); //now skip any intervening whitespace
if(NS_OK==result) {
result=aScanner.SkipWhitespace(); //now skip any intervening whitespace
result=aScanner.GetChar(aChar); //and grab the next char.
if(NS_OK==result) {
result=aScanner.GetChar(aChar); //and grab the next char.
if(NS_OK==result) {
if((kQuote==aChar) || (kApostrophe==aChar)) {
mTextValue=aChar;
result=ConsumeQuotedString(aChar,mTextValue,aScanner);
}
else {
mTextValue=aChar; //it's an alphanum attribute...
result=ConsumeAttributeValueText(aChar,mTextValue,aScanner);
}
}//if
if(NS_OK==result)
result=aScanner.SkipWhitespace();
if((kQuote==aChar) || (kApostrophe==aChar)) {
mTextValue=aChar;
result=ConsumeQuotedString(aChar,mTextValue,aScanner);
}
else {
mTextValue=aChar; //it's an alphanum attribute...
result=ConsumeAttributeValueText(aChar,mTextValue,aScanner);
}
}//if
if(NS_OK==result)
result=aScanner.SkipWhitespace();
}//if
}//if
}//if
// }if
else {
//This is where we have to handle fairly busted content.
//If you're here, it means we saw an attribute name, but couldn't find
//the following equal sign. <tag NAME=....
//Doing this right in all cases is <i>REALLY</i> ugly.
//My best guess is to grab the next non-ws char. We know it's not '=',
//so let's see what it is. If it's a '"', then assume we're reading
//from the middle of the value. Try stripping the quote and continuing...
if(kQuote==aChar){
result=aScanner.GetChar(aChar); //strip quote.
}
}
}//if
}
if(NS_OK==result) {
result=aScanner.Peek(aChar);
@ -1075,14 +1088,18 @@ static PRUint16 PA_HackTable[] = {
* unicode equivalent.
*
* @update gess 3/25/98
* @param
* @return
* @param aString will hold the resulting string value
* @return numeric (unichar) value
*/
PRInt32 CEntityToken::TranslateToUnicodeStr(nsString& aString) {
PRInt32 value=0;
if(nsString::IsDigit(mTextValue[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);
value=mTextValue.ToInteger(&err,theRadix[isDigit]);
if(0==err) {
#ifdef PA_REMAP_128_TO_160_ILLEGAL_NCR
/* for some illegal, but popular usage */