mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
final factoring of DTDs, and removal of nsHTMLDTD.*
This commit is contained in:
parent
78b4db3cce
commit
c29b8f890f
@ -30,7 +30,6 @@
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
static NS_DEFINE_IID(kHTMLDTDIID, NS_IHTML_DTD_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_INAVHTML_DTD_IID);
|
||||
|
||||
|
||||
@ -98,7 +97,7 @@ NS_IMPL_RELEASE(CNavDTD)
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
CNavDTD::CNavDTD() : nsHTMLDTD() {
|
||||
CNavDTD::CNavDTD() : nsIDTD() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
@ -121,7 +120,347 @@ CNavDTD::~CNavDTD(){
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContain(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
//tagset1 has 61 members...
|
||||
static char gTagSet1[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
|
||||
eHTMLTag_bold, eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big,
|
||||
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
|
||||
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
|
||||
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_hr, eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_img,
|
||||
eHTMLTag_input, eHTMLTag_isindex, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_noframes, eHTMLTag_noscript,
|
||||
eHTMLTag_object, eHTMLTag_ol, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_table, eHTMLTag_textarea,
|
||||
eHTMLTag_tt, eHTMLTag_u, eHTMLTag_ul, eHTMLTag_userdefined,
|
||||
eHTMLTag_var, 0};
|
||||
|
||||
//tagset2 has 37 members...
|
||||
static char gTagSet2[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr, eHTMLTag_italic,
|
||||
eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_map, eHTMLTag_object, eHTMLTag_paragraph,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt, eHTMLTag_textarea,
|
||||
eHTMLTag_u, eHTMLTag_var,0};
|
||||
|
||||
//tagset3 has 53 members...
|
||||
static char gTagSet3[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
|
||||
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
|
||||
eHTMLTag_code, eHTMLTag_dd, eHTMLTag_del, eHTMLTag_dfn,
|
||||
eHTMLTag_div, eHTMLTag_dt, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_ins, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_legend, eHTMLTag_listitem, eHTMLTag_noframes,
|
||||
eHTMLTag_noscript, eHTMLTag_object, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strong, eHTMLTag_sub, eHTMLTag_sup,
|
||||
eHTMLTag_td, eHTMLTag_th, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
|
||||
//This hack code is here because we don't yet know what to do
|
||||
//with userdefined tags... XXX Hack
|
||||
if(eHTMLTag_userdefined==aChild) // XXX Hack: For now...
|
||||
result=PR_TRUE;
|
||||
|
||||
switch(aParent) {
|
||||
case eHTMLTag_a:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_acronym:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_address:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_applet:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont,eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_italic, eHTMLTag_iframe,
|
||||
eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_object, eHTMLTag_param, eHTMLTag_quotation,
|
||||
eHTMLTag_samp, eHTMLTag_script, eHTMLTag_select, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong, eHTMLTag_sub,
|
||||
eHTMLTag_sup, eHTMLTag_textarea, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_basefont:
|
||||
case eHTMLTag_br:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_bdo:
|
||||
case eHTMLTag_big:
|
||||
case eHTMLTag_blink:
|
||||
case eHTMLTag_bold:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_blockquote:
|
||||
case eHTMLTag_body:
|
||||
if(eHTMLTag_userdefined==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_button:
|
||||
result=PRBool(0!=strchr(gTagSet3,aChild)); break;
|
||||
|
||||
case eHTMLTag_caption:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_center:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_cite: case eHTMLTag_code:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_dd:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_del: case eHTMLTag_dfn:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_div:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_dl:
|
||||
{
|
||||
char okTags[]={eHTMLTag_dd,eHTMLTag_dt,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_dt:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_em:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_fieldset:
|
||||
if(eHTMLTag_legend==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_font:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_form:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_frame:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_h1: case eHTMLTag_h2:
|
||||
case eHTMLTag_h3: case eHTMLTag_h4:
|
||||
case eHTMLTag_h5: case eHTMLTag_h6:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_base, eHTMLTag_isindex, eHTMLTag_link, eHTMLTag_meta,
|
||||
eHTMLTag_script,eHTMLTag_style, eHTMLTag_title, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_hr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_italic:
|
||||
case eHTMLTag_ins:
|
||||
case eHTMLTag_kbd:
|
||||
case eHTMLTag_label:
|
||||
case eHTMLTag_legend:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_layer:
|
||||
break;
|
||||
|
||||
case eHTMLTag_link:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
// XXX hey rickg: listing is like xmp or plaintext and has
|
||||
// NOTHING to do with html lists.
|
||||
case eHTMLTag_listing:
|
||||
result=PRBool(eHTMLTag_listitem==aChild); break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
result=PRBool(eHTMLTag_area==aChild); break;
|
||||
|
||||
case eHTMLTag_marquee:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_math:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_meta:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
if(eHTMLTag_body==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_noscript:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_note:
|
||||
|
||||
case eHTMLTag_object:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_menu:
|
||||
case eHTMLTag_dir:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_ul:
|
||||
// XXX kipp was here
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_listitem:
|
||||
if (eHTMLTag_listitem == aChild) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_paragraph:
|
||||
if(eHTMLTag_paragraph==aChild)
|
||||
result=PR_FALSE;
|
||||
else result=PRBool(0!=strchr(gTagSet2,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_param:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_plaintext:
|
||||
break;
|
||||
|
||||
case eHTMLTag_pre:
|
||||
case eHTMLTag_quotation:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_strike:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
break; //unadorned script text...
|
||||
|
||||
case eHTMLTag_select:
|
||||
result=PRBool(eHTMLTag_option==aChild); break;
|
||||
|
||||
case eHTMLTag_small:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_span:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_strong:
|
||||
case eHTMLTag_samp:
|
||||
case eHTMLTag_sub:
|
||||
case eHTMLTag_sup:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_col, eHTMLTag_colgroup,eHTMLTag_tbody,
|
||||
eHTMLTag_tfoot, eHTMLTag_tr, eHTMLTag_thead, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
result=PRBool(eHTMLTag_tr==aChild); break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_title:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_tr:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_td,eHTMLTag_th,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tt:
|
||||
case eHTMLTag_u:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_var:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_userdefined:
|
||||
result=PR_TRUE; break; //XXX for now...
|
||||
|
||||
case eHTMLTag_xmp:
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -136,7 +475,39 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool CNavDTD::CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContainIndirect(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParent) {
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_head, eHTMLTag_body,
|
||||
eHTMLTag_header, eHTMLTag_footer,0
|
||||
};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=PR_TRUE; break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_colgroup,
|
||||
eHTMLTag_tbody, eHTMLTag_tfoot,
|
||||
eHTMLTag_thead, eHTMLTag_tr,
|
||||
eHTMLTag_td, eHTMLTag_th,
|
||||
eHTMLTag_col, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
result=PR_TRUE; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -180,7 +551,27 @@ PRBool CNavDTD::CanOmit(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool CNavDTD::IsContainer(PRInt32 aTag) const {
|
||||
PRBool result=nsHTMLDTD::IsContainer(aTag);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aTag){
|
||||
case eHTMLTag_area: case eHTMLTag_base:
|
||||
case eHTMLTag_basefont: case eHTMLTag_br:
|
||||
case eHTMLTag_col: case eHTMLTag_colgroup:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_hr: case eHTMLTag_img:
|
||||
case eHTMLTag_input: case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_math: case eHTMLTag_meta:
|
||||
case eHTMLTag_option: case eHTMLTag_param:
|
||||
case eHTMLTag_style: case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
case eHTMLTag_form:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -270,7 +661,7 @@ PRInt32 CNavDTD::GetDefaultParentTagFor(PRInt32 aTag) const{
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
PRBool CNavDTD::VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const {
|
||||
PRBool CNavDTD::VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const {
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
if(aCount>0) {
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef NS_NAVHTMLDTD__
|
||||
#define NS_NAVHTMLDTD__
|
||||
|
||||
#include "nsHTMLDTD.h"
|
||||
#include "nsIDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
|
||||
@ -37,32 +37,32 @@
|
||||
|
||||
|
||||
|
||||
class CNavDTD : public nsHTMLDTD {
|
||||
class CNavDTD : public nsIDTD {
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
CNavDTD();
|
||||
*/
|
||||
CNavDTD();
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
*/
|
||||
virtual ~CNavDTD();
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
@ -70,10 +70,10 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
@ -81,41 +81,41 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method gets called to determine whether a given
|
||||
* tag can contain newlines. Most do not.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool CanOmit(PRInt32 aParent,PRInt32 aChild)const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool IsContainer(PRInt32 aTags) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
* 2nd, pass this message on to the sink.
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRInt32 GetDefaultParentTagFor(PRInt32 aTag) const;
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
@ -124,10 +124,10 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const;
|
||||
*/
|
||||
virtual PRBool VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the parent down to the
|
||||
* child.
|
||||
@ -137,10 +137,10 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRInt32 ForwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the child up to the parent.
|
||||
*
|
||||
@ -149,7 +149,7 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRInt32 BackwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
};
|
||||
|
@ -18,9 +18,9 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include "CNavDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsParserTypes.h"
|
||||
#include "CNavDTD.h"
|
||||
|
||||
|
||||
// Note: We already handle the following special case conditions:
|
||||
@ -32,38 +32,51 @@
|
||||
static char gIdentChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CNavDelegate::CNavDelegate() : CHTMLTokenizerDelegate(){
|
||||
*/
|
||||
CNavDelegate::CNavDelegate() :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CNavDelegate::CNavDelegate(CNavDelegate& aDelegate) : CHTMLTokenizerDelegate() {
|
||||
*/
|
||||
CNavDelegate::CNavDelegate(CNavDelegate& aDelegate) :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
eParseMode CNavDelegate::GetParseMode() const {
|
||||
return eParseMode_navigator;
|
||||
return eParseMode_unknown;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Cause delegate to create and return a new DTD.
|
||||
*
|
||||
* @update gess4/22/98
|
||||
* @return new DTD or null
|
||||
*/
|
||||
nsIDTD* CNavDelegate::GetDTD(void) const{
|
||||
return new CNavDTD();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of some kind of tagged
|
||||
* element. We don't know yet if it's a tag or a comment.
|
||||
@ -71,7 +84,7 @@ eParseMode CNavDelegate::GetParseMode() const {
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result=0;
|
||||
nsAutoString empty("");
|
||||
@ -95,7 +108,7 @@ CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anE
|
||||
nsAutoString temp("<");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
}
|
||||
} //switch
|
||||
|
||||
if(result!=0) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
@ -107,7 +120,35 @@ CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anE
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after we've consumed a start
|
||||
* tag, and we now have to consume its attributes.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @return
|
||||
*/
|
||||
void CNavDelegate::ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
PRBool done=PR_FALSE;
|
||||
nsAutoString as("");
|
||||
anErrorCode=kNoError;
|
||||
while((!done) && (anErrorCode==kNoError)) {
|
||||
CToken* result = new CAttributeToken(as);
|
||||
if(result){
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
mTokenDeque.Push(result);
|
||||
}
|
||||
aScanner.Peek(aChar);
|
||||
if(aChar==kGreaterThan) { //you just ate the '>'
|
||||
aScanner.GetChar(aChar); //skip the '>'
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a special case method. It's job is to consume
|
||||
* all of the given tag up to an including the end tag.
|
||||
*
|
||||
@ -115,7 +156,7 @@ CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anE
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
|
||||
//In the case that we just read the given tag, we should go and
|
||||
@ -129,7 +170,7 @@ CToken* CNavDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar a
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of a tag.
|
||||
*
|
||||
@ -138,14 +179,14 @@ CToken* CNavDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar a
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CStartToken* result=new CStartToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(result->IsAttributed())
|
||||
if(result->IsAttributed()) {
|
||||
ConsumeAttributes(aChar,aScanner,anErrorCode);
|
||||
|
||||
}
|
||||
//now that that's over with, we have one more problem to solve.
|
||||
//In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
//consume all the content itself.
|
||||
@ -169,13 +210,13 @@ CToken* CNavDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
|
||||
CEndToken* endtoken=new CEndToken(str);
|
||||
mTokenDeque.Push(endtoken);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
} //if
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "&" has been consumed
|
||||
* and we know we're at the start of an entity.
|
||||
*
|
||||
@ -184,7 +225,7 @@ CToken* CNavDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = 0;
|
||||
PRUnichar ch;
|
||||
@ -197,8 +238,7 @@ CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32&
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
//oops, we're actually looking at plain text...
|
||||
nsAutoString temp("&");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
@ -206,7 +246,75 @@ CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32&
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after whitespace has been
|
||||
* consumed and we know we're at the start a whitespace run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = new CWhitespaceToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a "<!" has been consumed
|
||||
* and we know we're at the start of a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result= new CCommentToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a known text char has
|
||||
* been consumed and we should read a text run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CTextToken(aString);
|
||||
if(result) {
|
||||
PRUnichar ch;
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a newline has been consumed.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CNewlineToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method repeatedly called by the tokenizer.
|
||||
* Each time, we determine the kind of token were about to
|
||||
* read, and then we call the appropriate method to handle
|
||||
@ -217,17 +325,107 @@ CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32&
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CNavDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
return CHTMLTokenizerDelegate::GetToken(aScanner,anErrorCode);
|
||||
*/
|
||||
CToken* CNavDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=0;
|
||||
PRUnichar aChar;
|
||||
|
||||
if(mTokenDeque.GetSize()>0) {
|
||||
return (CToken*)mTokenDeque.Pop();
|
||||
}
|
||||
|
||||
while(!aScanner.Eof()) {
|
||||
anErrorCode=aScanner.GetChar(aChar);
|
||||
switch(aChar) {
|
||||
case kAmpersand:
|
||||
return ConsumeEntity(aChar,aScanner,anErrorCode);
|
||||
case kLessThan:
|
||||
return ConsumeTag(aChar,aScanner,anErrorCode);
|
||||
case kCR: case kLF:
|
||||
return ConsumeNewline(aChar,aScanner,anErrorCode);
|
||||
case kNotFound:
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsSpace(aChar))
|
||||
return ConsumeWhitespace(aChar,aScanner,anErrorCode);
|
||||
else
|
||||
{
|
||||
nsAutoString temp(aChar);
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
if(anErrorCode==kEOF)
|
||||
anErrorCode=0;
|
||||
} //while
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::CreateTokenOfType(eHTMLTokenTypes aType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is by the tokenizer, once for each new token
|
||||
* we've constructed. This method determines whether or not
|
||||
* the new token (argument) should be accepted as a valid
|
||||
* token. If so, the token is added to the deque of tokens
|
||||
* contained within the tokenzier. If no, the token is
|
||||
* ignored.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aToken: token to be tested for acceptance
|
||||
* @return TRUE if token should be accepted.
|
||||
*/
|
||||
PRBool CNavDelegate::WillAddToken(CToken& /*aToken*/) {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just before a stream
|
||||
* is parsed. This method is called so that the delegate
|
||||
* can do any "pre-parsing" initialization.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool CNavDelegate::WillTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just after a stream
|
||||
* was parsed. This method is called so that the delegate
|
||||
* can do any "post-parsing" cleanup.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool CNavDelegate::DidTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the selftest method for the delegate class.
|
||||
* Unfortunately, there's not much you can do with this
|
||||
* class alone, so we do the selftesting as part of the
|
||||
* parser class.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
void CNavDelegate::SelfTest(void) {
|
||||
#ifdef _DEBUG
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,8 +20,7 @@
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/1/98
|
||||
*
|
||||
* This class is used as the HTML tokenizer delegate for
|
||||
* netscape navigator compatibility.
|
||||
* This class is used as the HTML tokenizer delegate.
|
||||
*
|
||||
* The tokenzier class has the smarts to open an source,
|
||||
* and iterate over its characters to produce a list of
|
||||
@ -37,32 +36,46 @@
|
||||
* scanner.stream, and produces an HTML specific CToken.
|
||||
*/
|
||||
|
||||
#ifndef __NAV_DELEGATE
|
||||
#define __NAV_DELEGATE
|
||||
#ifndef _NAV_DELEGATE
|
||||
#define _NAV_DELEGATE
|
||||
|
||||
#include "nsToken.h"
|
||||
#include "nsHTMLDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsITokenizerDelegate.h"
|
||||
#include "nsDeque.h"
|
||||
#include "nsIDTD.h"
|
||||
|
||||
|
||||
class CNavDelegate : public CHTMLTokenizerDelegate {
|
||||
class CNavDelegate : public ITokenizerDelegate {
|
||||
public:
|
||||
CNavDelegate();
|
||||
CNavDelegate(CNavDelegate& aDelegate);
|
||||
CNavDelegate();
|
||||
CNavDelegate(CNavDelegate& aDelegate);
|
||||
|
||||
virtual CToken* GetToken(CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual PRBool WillAddToken(CToken& aToken);
|
||||
|
||||
virtual PRBool WillTokenize();
|
||||
virtual PRBool DidTokenize();
|
||||
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual nsIDTD* GetDTD(void) const;
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
|
||||
virtual CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
|
||||
CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
void ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
//the only special case method...
|
||||
virtual CToken* ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
nsDeque mTokenDeque;
|
||||
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
static NS_DEFINE_IID(kHTMLDTDIID, NS_IHTML_DTD_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_IOtherHTML_DTD_IID);
|
||||
|
||||
|
||||
@ -98,7 +97,7 @@ NS_IMPL_RELEASE(COtherDTD)
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
COtherDTD::COtherDTD() : nsHTMLDTD() {
|
||||
COtherDTD::COtherDTD() : nsIDTD() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
@ -121,7 +120,347 @@ COtherDTD::~COtherDTD(){
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool COtherDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContain(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
//tagset1 has 61 members...
|
||||
static char gTagSet1[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
|
||||
eHTMLTag_bold, eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big,
|
||||
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
|
||||
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
|
||||
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_hr, eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_img,
|
||||
eHTMLTag_input, eHTMLTag_isindex, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_noframes, eHTMLTag_noscript,
|
||||
eHTMLTag_object, eHTMLTag_ol, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_table, eHTMLTag_textarea,
|
||||
eHTMLTag_tt, eHTMLTag_u, eHTMLTag_ul, eHTMLTag_userdefined,
|
||||
eHTMLTag_var, 0};
|
||||
|
||||
//tagset2 has 37 members...
|
||||
static char gTagSet2[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr, eHTMLTag_italic,
|
||||
eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_map, eHTMLTag_object, eHTMLTag_paragraph,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt, eHTMLTag_textarea,
|
||||
eHTMLTag_u, eHTMLTag_var,0};
|
||||
|
||||
//tagset3 has 53 members...
|
||||
static char gTagSet3[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
|
||||
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
|
||||
eHTMLTag_code, eHTMLTag_dd, eHTMLTag_del, eHTMLTag_dfn,
|
||||
eHTMLTag_div, eHTMLTag_dt, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_ins, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_legend, eHTMLTag_listitem, eHTMLTag_noframes,
|
||||
eHTMLTag_noscript, eHTMLTag_object, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strong, eHTMLTag_sub, eHTMLTag_sup,
|
||||
eHTMLTag_td, eHTMLTag_th, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
|
||||
//This hack code is here because we don't yet know what to do
|
||||
//with userdefined tags... XXX Hack
|
||||
if(eHTMLTag_userdefined==aChild) // XXX Hack: For now...
|
||||
result=PR_TRUE;
|
||||
|
||||
switch(aParent) {
|
||||
case eHTMLTag_a:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_acronym:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_address:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_applet:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont,eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_italic, eHTMLTag_iframe,
|
||||
eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_object, eHTMLTag_param, eHTMLTag_quotation,
|
||||
eHTMLTag_samp, eHTMLTag_script, eHTMLTag_select, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong, eHTMLTag_sub,
|
||||
eHTMLTag_sup, eHTMLTag_textarea, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_basefont:
|
||||
case eHTMLTag_br:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_bdo:
|
||||
case eHTMLTag_big:
|
||||
case eHTMLTag_blink:
|
||||
case eHTMLTag_bold:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_blockquote:
|
||||
case eHTMLTag_body:
|
||||
if(eHTMLTag_userdefined==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_button:
|
||||
result=PRBool(0!=strchr(gTagSet3,aChild)); break;
|
||||
|
||||
case eHTMLTag_caption:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_center:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_cite: case eHTMLTag_code:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_dd:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_del: case eHTMLTag_dfn:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_div:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_dl:
|
||||
{
|
||||
char okTags[]={eHTMLTag_dd,eHTMLTag_dt,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_dt:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_em:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_fieldset:
|
||||
if(eHTMLTag_legend==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_font:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_form:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_frame:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_h1: case eHTMLTag_h2:
|
||||
case eHTMLTag_h3: case eHTMLTag_h4:
|
||||
case eHTMLTag_h5: case eHTMLTag_h6:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_base, eHTMLTag_isindex, eHTMLTag_link, eHTMLTag_meta,
|
||||
eHTMLTag_script,eHTMLTag_style, eHTMLTag_title, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_hr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_italic:
|
||||
case eHTMLTag_ins:
|
||||
case eHTMLTag_kbd:
|
||||
case eHTMLTag_label:
|
||||
case eHTMLTag_legend:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_layer:
|
||||
break;
|
||||
|
||||
case eHTMLTag_link:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
// XXX hey rickg: listing is like xmp or plaintext and has
|
||||
// NOTHING to do with html lists.
|
||||
case eHTMLTag_listing:
|
||||
result=PRBool(eHTMLTag_listitem==aChild); break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
result=PRBool(eHTMLTag_area==aChild); break;
|
||||
|
||||
case eHTMLTag_marquee:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_math:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_meta:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
if(eHTMLTag_body==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_noscript:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_note:
|
||||
|
||||
case eHTMLTag_object:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_menu:
|
||||
case eHTMLTag_dir:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_ul:
|
||||
// XXX kipp was here
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_listitem:
|
||||
if (eHTMLTag_listitem == aChild) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_paragraph:
|
||||
if(eHTMLTag_paragraph==aChild)
|
||||
result=PR_FALSE;
|
||||
else result=PRBool(0!=strchr(gTagSet2,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_param:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_plaintext:
|
||||
break;
|
||||
|
||||
case eHTMLTag_pre:
|
||||
case eHTMLTag_quotation:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_strike:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
break; //unadorned script text...
|
||||
|
||||
case eHTMLTag_select:
|
||||
result=PRBool(eHTMLTag_option==aChild); break;
|
||||
|
||||
case eHTMLTag_small:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_span:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_strong:
|
||||
case eHTMLTag_samp:
|
||||
case eHTMLTag_sub:
|
||||
case eHTMLTag_sup:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_col, eHTMLTag_colgroup,eHTMLTag_tbody,
|
||||
eHTMLTag_tfoot, eHTMLTag_tr, eHTMLTag_thead, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
result=PRBool(eHTMLTag_tr==aChild); break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_title:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_tr:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_td,eHTMLTag_th,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tt:
|
||||
case eHTMLTag_u:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_var:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_userdefined:
|
||||
result=PR_TRUE; break; //XXX for now...
|
||||
|
||||
case eHTMLTag_xmp:
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -136,7 +475,39 @@ PRBool COtherDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool COtherDTD::CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContainIndirect(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParent) {
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_head, eHTMLTag_body,
|
||||
eHTMLTag_header, eHTMLTag_footer,0
|
||||
};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=PR_TRUE; break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_colgroup,
|
||||
eHTMLTag_tbody, eHTMLTag_tfoot,
|
||||
eHTMLTag_thead, eHTMLTag_tr,
|
||||
eHTMLTag_td, eHTMLTag_th,
|
||||
eHTMLTag_col, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
result=PR_TRUE; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -180,7 +551,27 @@ PRBool COtherDTD::CanOmit(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool COtherDTD::IsContainer(PRInt32 aTag) const {
|
||||
PRBool result=nsHTMLDTD::IsContainer(aTag);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aTag){
|
||||
case eHTMLTag_area: case eHTMLTag_base:
|
||||
case eHTMLTag_basefont: case eHTMLTag_br:
|
||||
case eHTMLTag_col: case eHTMLTag_colgroup:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_hr: case eHTMLTag_img:
|
||||
case eHTMLTag_input: case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_math: case eHTMLTag_meta:
|
||||
case eHTMLTag_option: case eHTMLTag_param:
|
||||
case eHTMLTag_style: case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
case eHTMLTag_form:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -270,7 +661,7 @@ PRInt32 COtherDTD::GetDefaultParentTagFor(PRInt32 aTag) const{
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
PRBool COtherDTD::VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const {
|
||||
PRBool COtherDTD::VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const {
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
if(aCount>0) {
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef NS_OTHERHTMLDTD__
|
||||
#define NS_OTHERHTMLDTD__
|
||||
|
||||
#include "nsHTMLDTD.h"
|
||||
#include "nsIDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
|
||||
class COtherDTD : public nsHTMLDTD {
|
||||
class COtherDTD : public nsIDTD {
|
||||
|
||||
public:
|
||||
|
||||
@ -126,7 +126,7 @@ class COtherDTD : public nsHTMLDTD {
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const;
|
||||
virtual PRBool VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
|
@ -18,9 +18,10 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include "COtherDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsParserTypes.h"
|
||||
#include "COtherDTD.h"
|
||||
|
||||
|
||||
|
||||
// Note: We already handle the following special case conditions:
|
||||
@ -32,38 +33,50 @@
|
||||
static char gIdentChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
COtherDelegate::COtherDelegate() : CHTMLTokenizerDelegate(){
|
||||
*/
|
||||
COtherDelegate::COtherDelegate() :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
COtherDelegate::COtherDelegate(COtherDelegate& aDelegate) : CHTMLTokenizerDelegate(){
|
||||
*/
|
||||
COtherDelegate::COtherDelegate(COtherDelegate& aDelegate) :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
eParseMode COtherDelegate::GetParseMode() const {
|
||||
return eParseMode_other;
|
||||
return eParseMode_unknown;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Cause delegate to create and return a new DTD.
|
||||
*
|
||||
* @update gess4/22/98
|
||||
* @return new DTD or null
|
||||
*/
|
||||
nsIDTD* COtherDelegate::GetDTD(void) const{
|
||||
return new COtherDTD();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of some kind of tagged
|
||||
* element. We don't know yet if it's a tag or a comment.
|
||||
@ -71,7 +84,7 @@ eParseMode COtherDelegate::GetParseMode() const {
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result=0;
|
||||
nsAutoString empty("");
|
||||
@ -95,7 +108,7 @@ CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& a
|
||||
nsAutoString temp("<");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
}
|
||||
} //switch
|
||||
|
||||
if(result!=0) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
@ -107,8 +120,35 @@ CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& a
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after we've consumed a start
|
||||
* tag, and we now have to consume its attributes.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @return
|
||||
*/
|
||||
void COtherDelegate::ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
PRBool done=PR_FALSE;
|
||||
nsAutoString as("");
|
||||
anErrorCode=kNoError;
|
||||
while((!done) && (anErrorCode==kNoError)) {
|
||||
CToken* result = new CAttributeToken(as);
|
||||
if(result){
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
mTokenDeque.Push(result);
|
||||
}
|
||||
aScanner.Peek(aChar);
|
||||
if(aChar==kGreaterThan) { //you just ate the '>'
|
||||
aScanner.GetChar(aChar); //skip the '>'
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
* This is a special case method. It's job is to consume
|
||||
* all of the given tag up to an including the end tag.
|
||||
*
|
||||
@ -116,7 +156,7 @@ CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& a
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
|
||||
//In the case that we just read the given tag, we should go and
|
||||
@ -130,7 +170,7 @@ CToken* COtherDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of a tag.
|
||||
*
|
||||
@ -139,21 +179,22 @@ CToken* COtherDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CStartToken* result=new CStartToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(result->IsAttributed())
|
||||
if(result->IsAttributed()) {
|
||||
ConsumeAttributes(aChar,aScanner,anErrorCode);
|
||||
|
||||
}
|
||||
//now that that's over with, we have one more problem to solve.
|
||||
//In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
//consume all the content itself.
|
||||
nsString& str=result->GetText();
|
||||
if(str.EqualsIgnoreCase("SCRIPT") ||
|
||||
str.EqualsIgnoreCase("STYLE") ||
|
||||
str.EqualsIgnoreCase("TITLE")) {
|
||||
str.EqualsIgnoreCase("TITLE") ||
|
||||
str.EqualsIgnoreCase("TEXTAREA")) {
|
||||
CToken* sc=ConsumeContentToEndTag(str,aChar,aScanner,anErrorCode);
|
||||
|
||||
if(sc){
|
||||
@ -169,13 +210,13 @@ CToken* COtherDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt
|
||||
|
||||
CEndToken* endtoken=new CEndToken(str);
|
||||
mTokenDeque.Push(endtoken);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
} //if
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "&" has been consumed
|
||||
* and we know we're at the start of an entity.
|
||||
*
|
||||
@ -184,7 +225,7 @@ CToken* COtherDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = 0;
|
||||
PRUnichar ch;
|
||||
@ -197,8 +238,7 @@ CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
//oops, we're actually looking at plain text...
|
||||
nsAutoString temp("&");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
@ -206,8 +246,75 @@ CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after whitespace has been
|
||||
* consumed and we know we're at the start a whitespace run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = new CWhitespaceToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "<!" has been consumed
|
||||
* and we know we're at the start of a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result= new CCommentToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a known text char has
|
||||
* been consumed and we should read a text run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CTextToken(aString);
|
||||
if(result) {
|
||||
PRUnichar ch;
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a newline has been consumed.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CNewlineToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method repeatedly called by the tokenizer.
|
||||
* Each time, we determine the kind of token were about to
|
||||
* read, and then we call the appropriate method to handle
|
||||
@ -218,18 +325,107 @@ CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode){
|
||||
return CHTMLTokenizerDelegate::GetToken(aScanner,anErrorCode);
|
||||
CToken* result=0;
|
||||
PRUnichar aChar;
|
||||
|
||||
if(mTokenDeque.GetSize()>0) {
|
||||
return (CToken*)mTokenDeque.Pop();
|
||||
}
|
||||
|
||||
while(!aScanner.Eof()) {
|
||||
anErrorCode=aScanner.GetChar(aChar);
|
||||
switch(aChar) {
|
||||
case kAmpersand:
|
||||
return ConsumeEntity(aChar,aScanner,anErrorCode);
|
||||
case kLessThan:
|
||||
return ConsumeTag(aChar,aScanner,anErrorCode);
|
||||
case kCR: case kLF:
|
||||
return ConsumeNewline(aChar,aScanner,anErrorCode);
|
||||
case kNotFound:
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsSpace(aChar))
|
||||
return ConsumeWhitespace(aChar,aScanner,anErrorCode);
|
||||
else
|
||||
{
|
||||
nsAutoString temp(aChar);
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
if(anErrorCode==kEOF)
|
||||
anErrorCode=0;
|
||||
} //while
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::CreateTokenOfType(eHTMLTokenTypes aType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is by the tokenizer, once for each new token
|
||||
* we've constructed. This method determines whether or not
|
||||
* the new token (argument) should be accepted as a valid
|
||||
* token. If so, the token is added to the deque of tokens
|
||||
* contained within the tokenzier. If no, the token is
|
||||
* ignored.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aToken: token to be tested for acceptance
|
||||
* @return TRUE if token should be accepted.
|
||||
*/
|
||||
PRBool COtherDelegate::WillAddToken(CToken& /*aToken*/) {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just before a stream
|
||||
* is parsed. This method is called so that the delegate
|
||||
* can do any "pre-parsing" initialization.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool COtherDelegate::WillTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just after a stream
|
||||
* was parsed. This method is called so that the delegate
|
||||
* can do any "post-parsing" cleanup.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool COtherDelegate::DidTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the selftest method for the delegate class.
|
||||
* Unfortunately, there's not much you can do with this
|
||||
* class alone, so we do the selftesting as part of the
|
||||
* parser class.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
void COtherDelegate::SelfTest(void) {
|
||||
#ifdef _DEBUG
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,9 +20,7 @@
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/1/98
|
||||
*
|
||||
* This class is used as the HTML tokenizer delegate for
|
||||
* an alternate html browser.
|
||||
|
||||
* This class is used as the HTML tokenizer delegate.
|
||||
*
|
||||
* The tokenzier class has the smarts to open an source,
|
||||
* and iterate over its characters to produce a list of
|
||||
@ -38,32 +36,46 @@
|
||||
* scanner.stream, and produces an HTML specific CToken.
|
||||
*/
|
||||
|
||||
#ifndef __OTHER_DELEGATE
|
||||
#define __OTHER_DELEGATE
|
||||
#ifndef _OTHER_DELEGATE
|
||||
#define _OTHER_DELEGATE
|
||||
|
||||
#include "nsToken.h"
|
||||
#include "nsHTMLDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsITokenizerDelegate.h"
|
||||
#include "nsDeque.h"
|
||||
#include "nsIDTD.h"
|
||||
|
||||
|
||||
class COtherDelegate : public CHTMLTokenizerDelegate {
|
||||
class COtherDelegate : public ITokenizerDelegate {
|
||||
public:
|
||||
COtherDelegate();
|
||||
COtherDelegate(COtherDelegate& aDelegate);
|
||||
COtherDelegate();
|
||||
COtherDelegate(COtherDelegate& aDelegate);
|
||||
|
||||
virtual CToken* GetToken(CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual PRBool WillAddToken(CToken& aToken);
|
||||
|
||||
virtual PRBool WillTokenize();
|
||||
virtual PRBool DidTokenize();
|
||||
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual nsIDTD* GetDTD(void) const;
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
|
||||
virtual CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
|
||||
CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
void ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
//the only special case method...
|
||||
virtual CToken* ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
nsDeque mTokenDeque;
|
||||
|
||||
};
|
||||
|
||||
|
@ -28,14 +28,12 @@ CPPSRCS = \
|
||||
nsToken.cpp \
|
||||
nsTokenizer.cpp \
|
||||
nsTokenHandler.cpp \
|
||||
nsHTMLParser.cpp \
|
||||
nsHTMLTokens.cpp \
|
||||
nsHTMLDelegate.cpp \
|
||||
nsHTMLDTD.cpp \
|
||||
CNavDelegate.cpp \
|
||||
CNavDTD.cpp \
|
||||
COtherDelegate.cpp \
|
||||
COtherDTD.cpp \
|
||||
nsHTMLParser.cpp \
|
||||
nsHTMLTokens.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
|
@ -23,20 +23,20 @@ DEFINES=-D_IMPL_NS_HTMLPARS
|
||||
MODULE=raptor
|
||||
REQUIRES=xpcom raptor
|
||||
|
||||
CPPSRCS=nsHTMLContentSink.cpp nsHTMLDelegate.cpp nsHTMLDTD.cpp \
|
||||
nsHTMLParser.cpp nsHTMLTokens.cpp nsParserNode.cpp nsScanner.cpp \
|
||||
CPPSRCS=nsHTMLContentSink.cpp \
|
||||
nsHTMLTokens.cpp nsParserNode.cpp nsScanner.cpp \
|
||||
nsToken.cpp nsTokenizer.cpp nsTokenHandler.cpp \
|
||||
CNavDTD.cpp CNavDelegate.cpp \
|
||||
COtherDTD.cpp COtherDelegate.cpp
|
||||
COtherDTD.cpp COtherDelegate.cpp \
|
||||
nsHTMLParser.cpp
|
||||
|
||||
EXPORTS=nshtmlpars.h nsIContentSink.h nsIHTMLContentSink.h \
|
||||
nsHTMLTokens.h nsIParserNode.h nsIParser.h nsToken.h
|
||||
|
||||
CPP_OBJS=.\$(OBJDIR)\nsHTMLContentSink.obj \
|
||||
.\$(OBJDIR)\nsHTMLDelegate.obj .\$(OBJDIR)\nsHTMLParser.obj \
|
||||
.\$(OBJDIR)\nsHTMLDTD.obj \
|
||||
.\$(OBJDIR)\CNavDelegate.obj .\$(OBJDIR)\CNavDTD.obj \
|
||||
.\$(OBJDIR)\COtherDelegate.obj .\$(OBJDIR)\COtherDTD.obj \
|
||||
.\$(OBJDIR)\nsHTMLParser.obj \
|
||||
.\$(OBJDIR)\nsHTMLTokens.obj .\$(OBJDIR)\nsParserNode.obj \
|
||||
.\$(OBJDIR)\nsScanner.obj .\$(OBJDIR)\nsToken.obj \
|
||||
.\$(OBJDIR)\nsTokenizer.obj .\$(OBJDIR)\nsTokenHandler.obj
|
||||
|
@ -1,704 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/8/98
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsHTMLDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsParserTypes.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_IHTML_DTD_IID);
|
||||
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method gets called as part of our COM-like interfaces.
|
||||
* Its purpose is to create an interface to parser object
|
||||
* of some type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param nsIID id of object to discover
|
||||
* @param aInstancePtr ptr to newly discovered interface
|
||||
* @return NS_xxx result code
|
||||
*------------------------------------------------------*/
|
||||
nsresult nsHTMLDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
|
||||
*aInstancePtr = (nsIDTD*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
|
||||
*aInstancePtr = (nsIDTD*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kClassIID)) { //do this class...
|
||||
*aInstancePtr = (nsHTMLDTD*)(this);
|
||||
}
|
||||
else {
|
||||
*aInstancePtr=0;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
((nsISupports*) *aInstancePtr)->AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsHTMLParser.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param nsIParser** ptr to newly instantiated parser
|
||||
* @return NS_xxx error result
|
||||
*------------------------------------------------------*/
|
||||
NS_HTMLPARS nsresult NS_NewHTMLDTD(nsIDTD** aInstancePtrResult)
|
||||
{
|
||||
nsHTMLDTD* it = new nsHTMLDTD();
|
||||
|
||||
if (it == 0) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLDTD)
|
||||
NS_IMPL_RELEASE(nsHTMLDTD)
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default constructor
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
nsHTMLDTD::nsHTMLDTD(){
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default destructor
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
nsHTMLDTD::~nsHTMLDTD(){
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
//tagset1 has 61 members...
|
||||
static char gTagSet1[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
|
||||
eHTMLTag_bold, eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big,
|
||||
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
|
||||
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
|
||||
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_hr, eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_img,
|
||||
eHTMLTag_input, eHTMLTag_isindex, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_noframes, eHTMLTag_noscript,
|
||||
eHTMLTag_object, eHTMLTag_ol, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_table, eHTMLTag_textarea,
|
||||
eHTMLTag_tt, eHTMLTag_u, eHTMLTag_ul, eHTMLTag_userdefined,
|
||||
eHTMLTag_var, 0};
|
||||
|
||||
//tagset2 has 37 members...
|
||||
static char gTagSet2[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr, eHTMLTag_italic,
|
||||
eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_map, eHTMLTag_object, eHTMLTag_paragraph,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt, eHTMLTag_textarea,
|
||||
eHTMLTag_u, eHTMLTag_var,0};
|
||||
|
||||
//tagset3 has 53 members...
|
||||
static char gTagSet3[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
|
||||
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
|
||||
eHTMLTag_code, eHTMLTag_dd, eHTMLTag_del, eHTMLTag_dfn,
|
||||
eHTMLTag_div, eHTMLTag_dt, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_ins, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_legend, eHTMLTag_listitem, eHTMLTag_noframes,
|
||||
eHTMLTag_noscript, eHTMLTag_object, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strong, eHTMLTag_sub, eHTMLTag_sup,
|
||||
eHTMLTag_td, eHTMLTag_th, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
|
||||
//This hack code is here because we don't yet know what to do
|
||||
//with userdefined tags... XXX Hack
|
||||
if(eHTMLTag_userdefined==aChild) // XXX Hack: For now...
|
||||
result=PR_TRUE;
|
||||
|
||||
switch(aParent) {
|
||||
case eHTMLTag_a:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_acronym:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_address:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_applet:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont,eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_italic, eHTMLTag_iframe,
|
||||
eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_object, eHTMLTag_param, eHTMLTag_quotation,
|
||||
eHTMLTag_samp, eHTMLTag_script, eHTMLTag_select, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong, eHTMLTag_sub,
|
||||
eHTMLTag_sup, eHTMLTag_textarea, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_basefont:
|
||||
case eHTMLTag_br:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_bdo:
|
||||
case eHTMLTag_big:
|
||||
case eHTMLTag_blink:
|
||||
case eHTMLTag_bold:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_blockquote:
|
||||
case eHTMLTag_body:
|
||||
if(eHTMLTag_userdefined==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_button:
|
||||
result=PRBool(0!=strchr(gTagSet3,aChild)); break;
|
||||
|
||||
case eHTMLTag_caption:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_center:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_cite: case eHTMLTag_code:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_dd:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_del: case eHTMLTag_dfn:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_div:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_dl:
|
||||
{
|
||||
char okTags[]={eHTMLTag_dd,eHTMLTag_dt,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_dt:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_em:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_fieldset:
|
||||
if(eHTMLTag_legend==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_font:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_form:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_frame:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_h1: case eHTMLTag_h2:
|
||||
case eHTMLTag_h3: case eHTMLTag_h4:
|
||||
case eHTMLTag_h5: case eHTMLTag_h6:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_base, eHTMLTag_isindex, eHTMLTag_link, eHTMLTag_meta,
|
||||
eHTMLTag_script,eHTMLTag_style, eHTMLTag_title, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_hr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_italic:
|
||||
case eHTMLTag_ins:
|
||||
case eHTMLTag_kbd:
|
||||
case eHTMLTag_label:
|
||||
case eHTMLTag_legend:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_layer:
|
||||
break;
|
||||
|
||||
case eHTMLTag_link:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
// XXX hey rickg: listing is like xmp or plaintext and has
|
||||
// NOTHING to do with html lists.
|
||||
case eHTMLTag_listing:
|
||||
result=PRBool(eHTMLTag_listitem==aChild); break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
result=PRBool(eHTMLTag_area==aChild); break;
|
||||
|
||||
case eHTMLTag_marquee:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_math:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_meta:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
if(eHTMLTag_body==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_noscript:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_note:
|
||||
|
||||
case eHTMLTag_object:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_menu:
|
||||
case eHTMLTag_dir:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_ul:
|
||||
// XXX kipp was here
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_listitem:
|
||||
if (eHTMLTag_listitem == aChild) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_paragraph:
|
||||
if(eHTMLTag_paragraph==aChild)
|
||||
result=PR_FALSE;
|
||||
else result=PRBool(0!=strchr(gTagSet2,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_param:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_plaintext:
|
||||
break;
|
||||
|
||||
case eHTMLTag_pre:
|
||||
case eHTMLTag_quotation:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_strike:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
break; //unadorned script text...
|
||||
|
||||
case eHTMLTag_select:
|
||||
result=PRBool(eHTMLTag_option==aChild); break;
|
||||
|
||||
case eHTMLTag_small:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_span:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_strong:
|
||||
case eHTMLTag_samp:
|
||||
case eHTMLTag_sub:
|
||||
case eHTMLTag_sup:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_col, eHTMLTag_colgroup,eHTMLTag_tbody,
|
||||
eHTMLTag_tfoot, eHTMLTag_tr, eHTMLTag_thead, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
result=PRBool(eHTMLTag_tr==aChild); break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_title:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_tr:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_td,eHTMLTag_th,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tt:
|
||||
case eHTMLTag_u:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_var:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_userdefined:
|
||||
result=PR_TRUE; break; //XXX for now...
|
||||
|
||||
case eHTMLTag_xmp:
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParent) {
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_head, eHTMLTag_body,
|
||||
eHTMLTag_header, eHTMLTag_footer,0
|
||||
};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=PR_TRUE; break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_colgroup,
|
||||
eHTMLTag_tbody, eHTMLTag_tfoot,
|
||||
eHTMLTag_thead, eHTMLTag_tr,
|
||||
eHTMLTag_td, eHTMLTag_th,
|
||||
eHTMLTag_col, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
result=PR_TRUE; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag can contain newlines. Most do not.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::CanOmit(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch((eHTMLTags)aParent) {
|
||||
case eHTMLTag_tr:
|
||||
case eHTMLTag_table:
|
||||
case eHTMLTag_thead:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
if((aChild==eHTMLTag_newline) ||
|
||||
(aChild==eHTMLTag_whitespace))
|
||||
result=PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::IsContainer(PRInt32 aTag) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aTag){
|
||||
case eHTMLTag_area: case eHTMLTag_base:
|
||||
case eHTMLTag_basefont: case eHTMLTag_br:
|
||||
case eHTMLTag_col: case eHTMLTag_colgroup:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_hr: case eHTMLTag_img:
|
||||
case eHTMLTag_input: case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_math: case eHTMLTag_meta:
|
||||
case eHTMLTag_param:
|
||||
case eHTMLTag_style: case eHTMLTag_spacer:
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_wbr:
|
||||
case eHTMLTag_form:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
* 2nd, pass this message on to the sink.
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*------------------------------------------------------*/
|
||||
PRInt32 nsHTMLDTD::GetDefaultParentTagFor(PRInt32 aTag) const{
|
||||
eHTMLTags result=eHTMLTag_unknown;
|
||||
switch(aTag) {
|
||||
case eHTMLTag_html:
|
||||
result=(eHTMLTags)kNotFound; break;
|
||||
|
||||
case eHTMLTag_body:
|
||||
case eHTMLTag_head:
|
||||
case eHTMLTag_header:
|
||||
case eHTMLTag_footer:
|
||||
case eHTMLTag_frameset:
|
||||
result=eHTMLTag_html; break;
|
||||
|
||||
//These tags are head specific...
|
||||
case eHTMLTag_style:
|
||||
case eHTMLTag_meta:
|
||||
case eHTMLTag_title:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_link:
|
||||
result=eHTMLTag_head; break;
|
||||
|
||||
//These tags are table specific...
|
||||
case eHTMLTag_caption:
|
||||
case eHTMLTag_colgroup:
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
case eHTMLTag_tr:
|
||||
result=eHTMLTag_table; break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=eHTMLTag_tr; break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
result=eHTMLTag_colgroup; break;
|
||||
|
||||
//These have to do with listings...
|
||||
case eHTMLTag_listitem:
|
||||
result=eHTMLTag_ul; break;
|
||||
|
||||
case eHTMLTag_dd:
|
||||
case eHTMLTag_dt:
|
||||
result=eHTMLTag_dl; break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
result=eHTMLTag_select; break;
|
||||
|
||||
//These have to do with image maps...
|
||||
case eHTMLTag_area:
|
||||
result=eHTMLTag_map; break;
|
||||
|
||||
//These have to do with applets...
|
||||
case eHTMLTag_param:
|
||||
result=eHTMLTag_applet; break;
|
||||
|
||||
//These have to do with frames...
|
||||
case eHTMLTag_frame:
|
||||
result=eHTMLTag_frameset; break;
|
||||
|
||||
default:
|
||||
result=eHTMLTag_body; //XXX Hack! Just for now.
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
PRBool nsHTMLDTD::VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const {
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
if(aCount>0) {
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the parent down to the
|
||||
* child.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
PRInt32 nsHTMLDTD::ForwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const{
|
||||
int result=0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the child up to the parent.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
PRInt32 nsHTMLDTD::BackwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const{
|
||||
int result=0;
|
||||
return result;
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/8/98
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NS_HTMLDTD__
|
||||
#define NS_HTMLDTD__
|
||||
|
||||
#include "nsIDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
|
||||
|
||||
#define NS_IHTML_DTD_IID \
|
||||
{0x5c5cce40, 0xcfd6, 0x11d1, \
|
||||
{0xaa, 0xda, 0x00, 0x80, 0x5f, 0x8a, 0x3e, 0x14}}
|
||||
|
||||
|
||||
|
||||
class nsHTMLDTD : public nsIDTD {
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
||||
/** -------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
nsHTMLDTD();
|
||||
|
||||
/** -------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
virtual ~nsHTMLDTD();
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag can contain newlines. Most do not.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanOmit(PRInt32 aParent,PRInt32 aChild)const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool IsContainer(PRInt32 aTags) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
* 2nd, pass this message on to the sink.
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRInt32 GetDefaultParentTagFor(PRInt32 aTag) const;
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the parent down to the
|
||||
* child.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
virtual ForwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the child up to the parent.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
virtual BackwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,420 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "nsHTMLDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsParserTypes.h"
|
||||
|
||||
|
||||
// Note: We already handle the following special case conditions:
|
||||
// 1) If you see </>, simply treat it as a bad tag.
|
||||
// 2) If you see </ ...>, treat it like a comment.
|
||||
// 3) If you see <> or <_ (< space) simply treat it as text.
|
||||
// 4) If you see <~ (< followed by non-alpha), treat it as text.
|
||||
|
||||
static char gIdentChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CHTMLTokenizerDelegate::CHTMLTokenizerDelegate() :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CHTMLTokenizerDelegate::CHTMLTokenizerDelegate(CHTMLTokenizerDelegate& aDelegate) :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
eParseMode CHTMLTokenizerDelegate::GetParseMode() const {
|
||||
return eParseMode_unknown;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of some kind of tagged
|
||||
* element. We don't know yet if it's a tag or a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result=0;
|
||||
nsAutoString empty("");
|
||||
anErrorCode=anErrorCode=aScanner.GetChar(aChar);
|
||||
|
||||
switch(aChar) {
|
||||
case kForwardSlash:
|
||||
PRUnichar ch;
|
||||
anErrorCode=aScanner.Peek(ch);
|
||||
if(nsString::IsAlpha(ch))
|
||||
result=new CEndToken(empty);
|
||||
else result=new CCommentToken(empty); //Special case: </ ...> is treated as a comment
|
||||
break;
|
||||
case kExclamation:
|
||||
result=new CCommentToken(empty);
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsAlpha(aChar))
|
||||
return ConsumeStartTag(aChar,aScanner,anErrorCode);
|
||||
else if(kNotFound!=aChar) {
|
||||
nsAutoString temp("<");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
|
||||
if(result!=0) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(anErrorCode) {
|
||||
result=0;
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after we've consumed a start
|
||||
* tag, and we now have to consume its attributes.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
void CHTMLTokenizerDelegate::ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
PRBool done=PR_FALSE;
|
||||
nsAutoString as("");
|
||||
anErrorCode=kNoError;
|
||||
while((!done) && (anErrorCode==kNoError)) {
|
||||
CToken* result = new CAttributeToken(as);
|
||||
if(result){
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
mTokenDeque.Push(result);
|
||||
}
|
||||
aScanner.Peek(aChar);
|
||||
if(aChar==kGreaterThan) { //you just ate the '>'
|
||||
aScanner.GetChar(aChar); //skip the '>'
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* This is a special case method. It's job is to consume
|
||||
* all of the given tag up to an including the end tag.
|
||||
*
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
|
||||
//In the case that we just read the given tag, we should go and
|
||||
//consume all the input until we find a matching end tag.
|
||||
|
||||
nsAutoString endTag("</");
|
||||
endTag.Append(aString);
|
||||
endTag.Append(">");
|
||||
CSkippedContentToken* sc=new CSkippedContentToken(endTag);
|
||||
anErrorCode= sc->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of a tag.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CStartToken* result=new CStartToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(result->IsAttributed()) {
|
||||
ConsumeAttributes(aChar,aScanner,anErrorCode);
|
||||
}
|
||||
//now that that's over with, we have one more problem to solve.
|
||||
//In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
//consume all the content itself.
|
||||
nsString& str=result->GetText();
|
||||
if(str.EqualsIgnoreCase("SCRIPT") ||
|
||||
str.EqualsIgnoreCase("STYLE") ||
|
||||
str.EqualsIgnoreCase("TITLE") ||
|
||||
str.EqualsIgnoreCase("TEXTAREA")) {
|
||||
CToken* sc=ConsumeContentToEndTag(str,aChar,aScanner,anErrorCode);
|
||||
|
||||
if(sc){
|
||||
//now we strip the ending sequence from our new SkippedContent token...
|
||||
PRInt32 slen=str.Length()+3;
|
||||
nsString& skippedText=sc->GetText();
|
||||
|
||||
skippedText.Cut(skippedText.Length()-slen,slen);
|
||||
mTokenDeque.Push(sc);
|
||||
|
||||
//In the case that we just read a given tag, we should go and
|
||||
//consume all the tag content itself (and throw it all away).
|
||||
|
||||
CEndToken* endtoken=new CEndToken(str);
|
||||
mTokenDeque.Push(endtoken);
|
||||
} //if
|
||||
} //if
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "&" has been consumed
|
||||
* and we know we're at the start of an entity.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = 0;
|
||||
PRUnichar ch;
|
||||
anErrorCode=aScanner.GetChar(ch);
|
||||
if(nsString::IsAlpha(ch)) { //handle common enity references &xxx; or �.
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode= result->Consume(ch,aScanner); //tell new token to finish consuming text...
|
||||
}
|
||||
else if(kHashsign==ch) {
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
else {
|
||||
//oops, we're actually looking at plain text...
|
||||
nsAutoString temp("&");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after whitespace has been
|
||||
* consumed and we know we're at the start a whitespace run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = new CWhitespaceToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "<!" has been consumed
|
||||
* and we know we're at the start of a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result= new CCommentToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a known text char has
|
||||
* been consumed and we should read a text run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CTextToken(aString);
|
||||
if(result) {
|
||||
PRUnichar ch;
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a newline has been consumed.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CNewlineToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method repeatedly called by the tokenizer.
|
||||
* Each time, we determine the kind of token were about to
|
||||
* read, and then we call the appropriate method to handle
|
||||
* that token type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=0;
|
||||
PRUnichar aChar;
|
||||
|
||||
if(mTokenDeque.GetSize()>0) {
|
||||
return (CToken*)mTokenDeque.Pop();
|
||||
}
|
||||
|
||||
while(!aScanner.Eof()) {
|
||||
anErrorCode=aScanner.GetChar(aChar);
|
||||
switch(aChar) {
|
||||
case kAmpersand:
|
||||
return ConsumeEntity(aChar,aScanner,anErrorCode);
|
||||
case kLessThan:
|
||||
return ConsumeTag(aChar,aScanner,anErrorCode);
|
||||
case kCR: case kLF:
|
||||
return ConsumeNewline(aChar,aScanner,anErrorCode);
|
||||
case kNotFound:
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsSpace(aChar))
|
||||
return ConsumeWhitespace(aChar,aScanner,anErrorCode);
|
||||
else
|
||||
{
|
||||
nsAutoString temp(aChar);
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
if(anErrorCode==kEOF)
|
||||
anErrorCode=0;
|
||||
} //while
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::CreateTokenOfType(eHTMLTokenTypes aType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is by the tokenizer, once for each new token
|
||||
* we've constructed. This method determines whether or not
|
||||
* the new token (argument) should be accepted as a valid
|
||||
* token. If so, the token is added to the deque of tokens
|
||||
* contained within the tokenzier. If no, the token is
|
||||
* ignored.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aToken: token to be tested for acceptance
|
||||
* @return TRUE if token should be accepted.
|
||||
*------------------------------------------------------*/
|
||||
PRBool CHTMLTokenizerDelegate::WillAddToken(CToken& /*aToken*/) {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called by the parser, just before a stream
|
||||
* is parsed. This method is called so that the delegate
|
||||
* can do any "pre-parsing" initialization.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*------------------------------------------------------*/
|
||||
PRBool CHTMLTokenizerDelegate::WillTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called by the parser, just after a stream
|
||||
* was parsed. This method is called so that the delegate
|
||||
* can do any "post-parsing" cleanup.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*------------------------------------------------------*/
|
||||
PRBool CHTMLTokenizerDelegate::DidTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This is the selftest method for the delegate class.
|
||||
* Unfortunately, there's not much you can do with this
|
||||
* class alone, so we do the selftesting as part of the
|
||||
* parser class.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*------------------------------------------------------*/
|
||||
void CHTMLTokenizerDelegate::SelfTest(void) {
|
||||
#ifdef _DEBUG
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,82 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/1/98
|
||||
*
|
||||
* This class is used as the HTML tokenizer delegate.
|
||||
*
|
||||
* The tokenzier class has the smarts to open an source,
|
||||
* and iterate over its characters to produce a list of
|
||||
* tokens. The tokenizer doesn't know HTML, which is
|
||||
* where this delegate comes into play.
|
||||
*
|
||||
* The tokenizer calls methods on this class to help
|
||||
* with the creation of HTML-specific tokens from a source
|
||||
* stream.
|
||||
*
|
||||
* The interface here is very simple, mainly the call
|
||||
* to GetToken(), which Consumes bytes from the underlying
|
||||
* scanner.stream, and produces an HTML specific CToken.
|
||||
*/
|
||||
|
||||
#ifndef TOKENIZER_DELEGATE
|
||||
#define TOKENIZER_DELEGATE
|
||||
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsITokenizerDelegate.h"
|
||||
#include "nsDeque.h"
|
||||
|
||||
|
||||
class CHTMLTokenizerDelegate : public ITokenizerDelegate {
|
||||
public:
|
||||
CHTMLTokenizerDelegate();
|
||||
CHTMLTokenizerDelegate(CHTMLTokenizerDelegate& aDelegate);
|
||||
|
||||
virtual CToken* GetToken(CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual PRBool WillAddToken(CToken& aToken);
|
||||
|
||||
virtual PRBool WillTokenize();
|
||||
virtual PRBool DidTokenize();
|
||||
|
||||
virtual eParseMode GetParseMode() const;
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
|
||||
CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
void ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
//the only special case method...
|
||||
virtual CToken* ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -363,7 +363,7 @@ PRBool nsHTMLParser::IterateTokens() {
|
||||
//later you have to Handle them, because they're relevent to certain containers (eg PRE).
|
||||
break;
|
||||
}
|
||||
mDTD->VerifyContextStack(mContextStack,mContextStackPos);
|
||||
// mDTD->VerifyContextStack(mContextStack,mContextStackPos);
|
||||
++(*mCurrentPos);
|
||||
done=PRBool(e==*mCurrentPos);
|
||||
}
|
||||
@ -410,15 +410,18 @@ PRBool nsHTMLParser::Parse(nsIURL* aURL,eParseMode aMode){
|
||||
result=PR_TRUE;
|
||||
mParseMode=aMode;
|
||||
ITokenizerDelegate* theDelegate=0;
|
||||
|
||||
|
||||
mDTD=0;
|
||||
switch(mParseMode) {
|
||||
case eParseMode_navigator:
|
||||
theDelegate=new CNavDelegate();
|
||||
mDTD= new CNavDTD();
|
||||
if(theDelegate)
|
||||
mDTD=theDelegate->GetDTD();
|
||||
break;
|
||||
case eParseMode_other:
|
||||
theDelegate=new COtherDelegate();
|
||||
mDTD= new COtherDTD();
|
||||
if(theDelegate)
|
||||
mDTD=theDelegate->GetDTD();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -427,9 +430,6 @@ PRBool nsHTMLParser::Parse(nsIURL* aURL,eParseMode aMode){
|
||||
NS_ERROR(kNullTokenizer);
|
||||
return PR_FALSE;
|
||||
}
|
||||
if(!mDTD) {
|
||||
mDTD= new nsHTMLDTD();
|
||||
}
|
||||
|
||||
mTokenizer=new CTokenizer(aURL, theDelegate, mParseMode);
|
||||
mTokenizer->Tokenize();
|
||||
|
@ -72,7 +72,7 @@ class CTokenizer;
|
||||
class IContentSink;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIURL;
|
||||
class nsHTMLDTD;
|
||||
class nsIDTD;
|
||||
|
||||
|
||||
class nsHTMLParser : public nsIParser {
|
||||
@ -153,7 +153,7 @@ friend class CTokenHandler;
|
||||
PRInt32 mTokenHandlerCount;
|
||||
nsDequeIterator* mCurrentPos;
|
||||
|
||||
nsHTMLDTD* mDTD;
|
||||
nsIDTD* mDTD;
|
||||
eParseMode mParseMode;
|
||||
};
|
||||
|
||||
|
@ -83,6 +83,18 @@ class nsIDTD : public nsISupports {
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanOmit(PRInt32 aParent,PRInt32 aChild)const=0;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const=0;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsParserTypes.h"
|
||||
#include "nsIDTD.h"
|
||||
|
||||
class CScanner;
|
||||
class CToken;
|
||||
@ -54,6 +55,7 @@ class ITokenizerDelegate {
|
||||
virtual PRBool WillAddToken(CToken& aToken)=0;
|
||||
|
||||
virtual eParseMode GetParseMode() const=0;
|
||||
virtual nsIDTD* GetDTD(void) const=0;
|
||||
};
|
||||
|
||||
#endif
|
@ -30,7 +30,6 @@
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
static NS_DEFINE_IID(kHTMLDTDIID, NS_IHTML_DTD_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_INAVHTML_DTD_IID);
|
||||
|
||||
|
||||
@ -98,7 +97,7 @@ NS_IMPL_RELEASE(CNavDTD)
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
CNavDTD::CNavDTD() : nsHTMLDTD() {
|
||||
CNavDTD::CNavDTD() : nsIDTD() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
@ -121,7 +120,347 @@ CNavDTD::~CNavDTD(){
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContain(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
//tagset1 has 61 members...
|
||||
static char gTagSet1[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
|
||||
eHTMLTag_bold, eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big,
|
||||
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
|
||||
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
|
||||
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_hr, eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_img,
|
||||
eHTMLTag_input, eHTMLTag_isindex, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_noframes, eHTMLTag_noscript,
|
||||
eHTMLTag_object, eHTMLTag_ol, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_table, eHTMLTag_textarea,
|
||||
eHTMLTag_tt, eHTMLTag_u, eHTMLTag_ul, eHTMLTag_userdefined,
|
||||
eHTMLTag_var, 0};
|
||||
|
||||
//tagset2 has 37 members...
|
||||
static char gTagSet2[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr, eHTMLTag_italic,
|
||||
eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_map, eHTMLTag_object, eHTMLTag_paragraph,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt, eHTMLTag_textarea,
|
||||
eHTMLTag_u, eHTMLTag_var,0};
|
||||
|
||||
//tagset3 has 53 members...
|
||||
static char gTagSet3[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
|
||||
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
|
||||
eHTMLTag_code, eHTMLTag_dd, eHTMLTag_del, eHTMLTag_dfn,
|
||||
eHTMLTag_div, eHTMLTag_dt, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_ins, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_legend, eHTMLTag_listitem, eHTMLTag_noframes,
|
||||
eHTMLTag_noscript, eHTMLTag_object, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strong, eHTMLTag_sub, eHTMLTag_sup,
|
||||
eHTMLTag_td, eHTMLTag_th, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
|
||||
//This hack code is here because we don't yet know what to do
|
||||
//with userdefined tags... XXX Hack
|
||||
if(eHTMLTag_userdefined==aChild) // XXX Hack: For now...
|
||||
result=PR_TRUE;
|
||||
|
||||
switch(aParent) {
|
||||
case eHTMLTag_a:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_acronym:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_address:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_applet:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont,eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_italic, eHTMLTag_iframe,
|
||||
eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_object, eHTMLTag_param, eHTMLTag_quotation,
|
||||
eHTMLTag_samp, eHTMLTag_script, eHTMLTag_select, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong, eHTMLTag_sub,
|
||||
eHTMLTag_sup, eHTMLTag_textarea, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_basefont:
|
||||
case eHTMLTag_br:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_bdo:
|
||||
case eHTMLTag_big:
|
||||
case eHTMLTag_blink:
|
||||
case eHTMLTag_bold:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_blockquote:
|
||||
case eHTMLTag_body:
|
||||
if(eHTMLTag_userdefined==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_button:
|
||||
result=PRBool(0!=strchr(gTagSet3,aChild)); break;
|
||||
|
||||
case eHTMLTag_caption:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_center:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_cite: case eHTMLTag_code:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_dd:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_del: case eHTMLTag_dfn:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_div:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_dl:
|
||||
{
|
||||
char okTags[]={eHTMLTag_dd,eHTMLTag_dt,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_dt:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_em:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_fieldset:
|
||||
if(eHTMLTag_legend==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_font:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_form:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_frame:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_h1: case eHTMLTag_h2:
|
||||
case eHTMLTag_h3: case eHTMLTag_h4:
|
||||
case eHTMLTag_h5: case eHTMLTag_h6:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_base, eHTMLTag_isindex, eHTMLTag_link, eHTMLTag_meta,
|
||||
eHTMLTag_script,eHTMLTag_style, eHTMLTag_title, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_hr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_italic:
|
||||
case eHTMLTag_ins:
|
||||
case eHTMLTag_kbd:
|
||||
case eHTMLTag_label:
|
||||
case eHTMLTag_legend:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_layer:
|
||||
break;
|
||||
|
||||
case eHTMLTag_link:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
// XXX hey rickg: listing is like xmp or plaintext and has
|
||||
// NOTHING to do with html lists.
|
||||
case eHTMLTag_listing:
|
||||
result=PRBool(eHTMLTag_listitem==aChild); break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
result=PRBool(eHTMLTag_area==aChild); break;
|
||||
|
||||
case eHTMLTag_marquee:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_math:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_meta:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
if(eHTMLTag_body==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_noscript:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_note:
|
||||
|
||||
case eHTMLTag_object:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_menu:
|
||||
case eHTMLTag_dir:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_ul:
|
||||
// XXX kipp was here
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_listitem:
|
||||
if (eHTMLTag_listitem == aChild) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_paragraph:
|
||||
if(eHTMLTag_paragraph==aChild)
|
||||
result=PR_FALSE;
|
||||
else result=PRBool(0!=strchr(gTagSet2,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_param:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_plaintext:
|
||||
break;
|
||||
|
||||
case eHTMLTag_pre:
|
||||
case eHTMLTag_quotation:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_strike:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
break; //unadorned script text...
|
||||
|
||||
case eHTMLTag_select:
|
||||
result=PRBool(eHTMLTag_option==aChild); break;
|
||||
|
||||
case eHTMLTag_small:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_span:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_strong:
|
||||
case eHTMLTag_samp:
|
||||
case eHTMLTag_sub:
|
||||
case eHTMLTag_sup:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_col, eHTMLTag_colgroup,eHTMLTag_tbody,
|
||||
eHTMLTag_tfoot, eHTMLTag_tr, eHTMLTag_thead, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
result=PRBool(eHTMLTag_tr==aChild); break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_title:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_tr:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_td,eHTMLTag_th,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tt:
|
||||
case eHTMLTag_u:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_var:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_userdefined:
|
||||
result=PR_TRUE; break; //XXX for now...
|
||||
|
||||
case eHTMLTag_xmp:
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -136,7 +475,39 @@ PRBool CNavDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool CNavDTD::CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContainIndirect(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParent) {
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_head, eHTMLTag_body,
|
||||
eHTMLTag_header, eHTMLTag_footer,0
|
||||
};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=PR_TRUE; break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_colgroup,
|
||||
eHTMLTag_tbody, eHTMLTag_tfoot,
|
||||
eHTMLTag_thead, eHTMLTag_tr,
|
||||
eHTMLTag_td, eHTMLTag_th,
|
||||
eHTMLTag_col, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
result=PR_TRUE; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -180,7 +551,27 @@ PRBool CNavDTD::CanOmit(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool CNavDTD::IsContainer(PRInt32 aTag) const {
|
||||
PRBool result=nsHTMLDTD::IsContainer(aTag);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aTag){
|
||||
case eHTMLTag_area: case eHTMLTag_base:
|
||||
case eHTMLTag_basefont: case eHTMLTag_br:
|
||||
case eHTMLTag_col: case eHTMLTag_colgroup:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_hr: case eHTMLTag_img:
|
||||
case eHTMLTag_input: case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_math: case eHTMLTag_meta:
|
||||
case eHTMLTag_option: case eHTMLTag_param:
|
||||
case eHTMLTag_style: case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
case eHTMLTag_form:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -270,7 +661,7 @@ PRInt32 CNavDTD::GetDefaultParentTagFor(PRInt32 aTag) const{
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
PRBool CNavDTD::VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const {
|
||||
PRBool CNavDTD::VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const {
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
if(aCount>0) {
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef NS_NAVHTMLDTD__
|
||||
#define NS_NAVHTMLDTD__
|
||||
|
||||
#include "nsHTMLDTD.h"
|
||||
#include "nsIDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
|
||||
@ -37,32 +37,32 @@
|
||||
|
||||
|
||||
|
||||
class CNavDTD : public nsHTMLDTD {
|
||||
class CNavDTD : public nsIDTD {
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
CNavDTD();
|
||||
*/
|
||||
CNavDTD();
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
*/
|
||||
virtual ~CNavDTD();
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
@ -70,10 +70,10 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
@ -81,41 +81,41 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method gets called to determine whether a given
|
||||
* tag can contain newlines. Most do not.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool CanOmit(PRInt32 aParent,PRInt32 aChild)const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRBool IsContainer(PRInt32 aTags) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
* 2nd, pass this message on to the sink.
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRInt32 GetDefaultParentTagFor(PRInt32 aTag) const;
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
/**
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
@ -124,10 +124,10 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const;
|
||||
*/
|
||||
virtual PRBool VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the parent down to the
|
||||
* child.
|
||||
@ -137,10 +137,10 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRInt32 ForwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
/**
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the child up to the parent.
|
||||
*
|
||||
@ -149,7 +149,7 @@ class CNavDTD : public nsHTMLDTD {
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
*/
|
||||
virtual PRInt32 BackwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
};
|
||||
|
@ -18,9 +18,9 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include "CNavDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsParserTypes.h"
|
||||
#include "CNavDTD.h"
|
||||
|
||||
|
||||
// Note: We already handle the following special case conditions:
|
||||
@ -32,38 +32,51 @@
|
||||
static char gIdentChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CNavDelegate::CNavDelegate() : CHTMLTokenizerDelegate(){
|
||||
*/
|
||||
CNavDelegate::CNavDelegate() :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CNavDelegate::CNavDelegate(CNavDelegate& aDelegate) : CHTMLTokenizerDelegate() {
|
||||
*/
|
||||
CNavDelegate::CNavDelegate(CNavDelegate& aDelegate) :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
eParseMode CNavDelegate::GetParseMode() const {
|
||||
return eParseMode_navigator;
|
||||
return eParseMode_unknown;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Cause delegate to create and return a new DTD.
|
||||
*
|
||||
* @update gess4/22/98
|
||||
* @return new DTD or null
|
||||
*/
|
||||
nsIDTD* CNavDelegate::GetDTD(void) const{
|
||||
return new CNavDTD();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of some kind of tagged
|
||||
* element. We don't know yet if it's a tag or a comment.
|
||||
@ -71,7 +84,7 @@ eParseMode CNavDelegate::GetParseMode() const {
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result=0;
|
||||
nsAutoString empty("");
|
||||
@ -95,7 +108,7 @@ CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anE
|
||||
nsAutoString temp("<");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
}
|
||||
} //switch
|
||||
|
||||
if(result!=0) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
@ -107,7 +120,35 @@ CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anE
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after we've consumed a start
|
||||
* tag, and we now have to consume its attributes.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @return
|
||||
*/
|
||||
void CNavDelegate::ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
PRBool done=PR_FALSE;
|
||||
nsAutoString as("");
|
||||
anErrorCode=kNoError;
|
||||
while((!done) && (anErrorCode==kNoError)) {
|
||||
CToken* result = new CAttributeToken(as);
|
||||
if(result){
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
mTokenDeque.Push(result);
|
||||
}
|
||||
aScanner.Peek(aChar);
|
||||
if(aChar==kGreaterThan) { //you just ate the '>'
|
||||
aScanner.GetChar(aChar); //skip the '>'
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a special case method. It's job is to consume
|
||||
* all of the given tag up to an including the end tag.
|
||||
*
|
||||
@ -115,7 +156,7 @@ CToken* CNavDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anE
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
|
||||
//In the case that we just read the given tag, we should go and
|
||||
@ -129,7 +170,7 @@ CToken* CNavDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar a
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of a tag.
|
||||
*
|
||||
@ -138,14 +179,14 @@ CToken* CNavDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar a
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CStartToken* result=new CStartToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(result->IsAttributed())
|
||||
if(result->IsAttributed()) {
|
||||
ConsumeAttributes(aChar,aScanner,anErrorCode);
|
||||
|
||||
}
|
||||
//now that that's over with, we have one more problem to solve.
|
||||
//In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
//consume all the content itself.
|
||||
@ -169,13 +210,13 @@ CToken* CNavDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
|
||||
CEndToken* endtoken=new CEndToken(str);
|
||||
mTokenDeque.Push(endtoken);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
} //if
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "&" has been consumed
|
||||
* and we know we're at the start of an entity.
|
||||
*
|
||||
@ -184,7 +225,7 @@ CToken* CNavDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = 0;
|
||||
PRUnichar ch;
|
||||
@ -197,8 +238,7 @@ CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32&
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
//oops, we're actually looking at plain text...
|
||||
nsAutoString temp("&");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
@ -206,7 +246,75 @@ CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32&
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after whitespace has been
|
||||
* consumed and we know we're at the start a whitespace run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = new CWhitespaceToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a "<!" has been consumed
|
||||
* and we know we're at the start of a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result= new CCommentToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a known text char has
|
||||
* been consumed and we should read a text run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CTextToken(aString);
|
||||
if(result) {
|
||||
PRUnichar ch;
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a newline has been consumed.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* CNavDelegate::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CNewlineToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method repeatedly called by the tokenizer.
|
||||
* Each time, we determine the kind of token were about to
|
||||
* read, and then we call the appropriate method to handle
|
||||
@ -217,17 +325,107 @@ CToken* CNavDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32&
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CNavDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
return CHTMLTokenizerDelegate::GetToken(aScanner,anErrorCode);
|
||||
*/
|
||||
CToken* CNavDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=0;
|
||||
PRUnichar aChar;
|
||||
|
||||
if(mTokenDeque.GetSize()>0) {
|
||||
return (CToken*)mTokenDeque.Pop();
|
||||
}
|
||||
|
||||
while(!aScanner.Eof()) {
|
||||
anErrorCode=aScanner.GetChar(aChar);
|
||||
switch(aChar) {
|
||||
case kAmpersand:
|
||||
return ConsumeEntity(aChar,aScanner,anErrorCode);
|
||||
case kLessThan:
|
||||
return ConsumeTag(aChar,aScanner,anErrorCode);
|
||||
case kCR: case kLF:
|
||||
return ConsumeNewline(aChar,aScanner,anErrorCode);
|
||||
case kNotFound:
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsSpace(aChar))
|
||||
return ConsumeWhitespace(aChar,aScanner,anErrorCode);
|
||||
else
|
||||
{
|
||||
nsAutoString temp(aChar);
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
if(anErrorCode==kEOF)
|
||||
anErrorCode=0;
|
||||
} //while
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* CNavDelegate::CreateTokenOfType(eHTMLTokenTypes aType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is by the tokenizer, once for each new token
|
||||
* we've constructed. This method determines whether or not
|
||||
* the new token (argument) should be accepted as a valid
|
||||
* token. If so, the token is added to the deque of tokens
|
||||
* contained within the tokenzier. If no, the token is
|
||||
* ignored.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aToken: token to be tested for acceptance
|
||||
* @return TRUE if token should be accepted.
|
||||
*/
|
||||
PRBool CNavDelegate::WillAddToken(CToken& /*aToken*/) {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just before a stream
|
||||
* is parsed. This method is called so that the delegate
|
||||
* can do any "pre-parsing" initialization.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool CNavDelegate::WillTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just after a stream
|
||||
* was parsed. This method is called so that the delegate
|
||||
* can do any "post-parsing" cleanup.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool CNavDelegate::DidTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the selftest method for the delegate class.
|
||||
* Unfortunately, there's not much you can do with this
|
||||
* class alone, so we do the selftesting as part of the
|
||||
* parser class.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
void CNavDelegate::SelfTest(void) {
|
||||
#ifdef _DEBUG
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,8 +20,7 @@
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/1/98
|
||||
*
|
||||
* This class is used as the HTML tokenizer delegate for
|
||||
* netscape navigator compatibility.
|
||||
* This class is used as the HTML tokenizer delegate.
|
||||
*
|
||||
* The tokenzier class has the smarts to open an source,
|
||||
* and iterate over its characters to produce a list of
|
||||
@ -37,32 +36,46 @@
|
||||
* scanner.stream, and produces an HTML specific CToken.
|
||||
*/
|
||||
|
||||
#ifndef __NAV_DELEGATE
|
||||
#define __NAV_DELEGATE
|
||||
#ifndef _NAV_DELEGATE
|
||||
#define _NAV_DELEGATE
|
||||
|
||||
#include "nsToken.h"
|
||||
#include "nsHTMLDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsITokenizerDelegate.h"
|
||||
#include "nsDeque.h"
|
||||
#include "nsIDTD.h"
|
||||
|
||||
|
||||
class CNavDelegate : public CHTMLTokenizerDelegate {
|
||||
class CNavDelegate : public ITokenizerDelegate {
|
||||
public:
|
||||
CNavDelegate();
|
||||
CNavDelegate(CNavDelegate& aDelegate);
|
||||
CNavDelegate();
|
||||
CNavDelegate(CNavDelegate& aDelegate);
|
||||
|
||||
virtual CToken* GetToken(CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual PRBool WillAddToken(CToken& aToken);
|
||||
|
||||
virtual PRBool WillTokenize();
|
||||
virtual PRBool DidTokenize();
|
||||
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual nsIDTD* GetDTD(void) const;
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
|
||||
virtual CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
|
||||
CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
void ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
//the only special case method...
|
||||
virtual CToken* ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
nsDeque mTokenDeque;
|
||||
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
static NS_DEFINE_IID(kHTMLDTDIID, NS_IHTML_DTD_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_IOtherHTML_DTD_IID);
|
||||
|
||||
|
||||
@ -98,7 +97,7 @@ NS_IMPL_RELEASE(COtherDTD)
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
COtherDTD::COtherDTD() : nsHTMLDTD() {
|
||||
COtherDTD::COtherDTD() : nsIDTD() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
@ -121,7 +120,347 @@ COtherDTD::~COtherDTD(){
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool COtherDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContain(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
//tagset1 has 61 members...
|
||||
static char gTagSet1[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
|
||||
eHTMLTag_bold, eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big,
|
||||
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
|
||||
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
|
||||
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_hr, eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_img,
|
||||
eHTMLTag_input, eHTMLTag_isindex, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_noframes, eHTMLTag_noscript,
|
||||
eHTMLTag_object, eHTMLTag_ol, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_table, eHTMLTag_textarea,
|
||||
eHTMLTag_tt, eHTMLTag_u, eHTMLTag_ul, eHTMLTag_userdefined,
|
||||
eHTMLTag_var, 0};
|
||||
|
||||
//tagset2 has 37 members...
|
||||
static char gTagSet2[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr, eHTMLTag_italic,
|
||||
eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_map, eHTMLTag_object, eHTMLTag_paragraph,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt, eHTMLTag_textarea,
|
||||
eHTMLTag_u, eHTMLTag_var,0};
|
||||
|
||||
//tagset3 has 53 members...
|
||||
static char gTagSet3[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
|
||||
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
|
||||
eHTMLTag_code, eHTMLTag_dd, eHTMLTag_del, eHTMLTag_dfn,
|
||||
eHTMLTag_div, eHTMLTag_dt, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_ins, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_legend, eHTMLTag_listitem, eHTMLTag_noframes,
|
||||
eHTMLTag_noscript, eHTMLTag_object, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strong, eHTMLTag_sub, eHTMLTag_sup,
|
||||
eHTMLTag_td, eHTMLTag_th, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
|
||||
//This hack code is here because we don't yet know what to do
|
||||
//with userdefined tags... XXX Hack
|
||||
if(eHTMLTag_userdefined==aChild) // XXX Hack: For now...
|
||||
result=PR_TRUE;
|
||||
|
||||
switch(aParent) {
|
||||
case eHTMLTag_a:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_acronym:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_address:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_applet:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont,eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_italic, eHTMLTag_iframe,
|
||||
eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_object, eHTMLTag_param, eHTMLTag_quotation,
|
||||
eHTMLTag_samp, eHTMLTag_script, eHTMLTag_select, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong, eHTMLTag_sub,
|
||||
eHTMLTag_sup, eHTMLTag_textarea, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_basefont:
|
||||
case eHTMLTag_br:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_bdo:
|
||||
case eHTMLTag_big:
|
||||
case eHTMLTag_blink:
|
||||
case eHTMLTag_bold:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_blockquote:
|
||||
case eHTMLTag_body:
|
||||
if(eHTMLTag_userdefined==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_button:
|
||||
result=PRBool(0!=strchr(gTagSet3,aChild)); break;
|
||||
|
||||
case eHTMLTag_caption:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_center:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_cite: case eHTMLTag_code:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_dd:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_del: case eHTMLTag_dfn:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_div:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_dl:
|
||||
{
|
||||
char okTags[]={eHTMLTag_dd,eHTMLTag_dt,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_dt:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_em:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_fieldset:
|
||||
if(eHTMLTag_legend==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_font:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_form:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_frame:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_h1: case eHTMLTag_h2:
|
||||
case eHTMLTag_h3: case eHTMLTag_h4:
|
||||
case eHTMLTag_h5: case eHTMLTag_h6:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_base, eHTMLTag_isindex, eHTMLTag_link, eHTMLTag_meta,
|
||||
eHTMLTag_script,eHTMLTag_style, eHTMLTag_title, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_hr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_italic:
|
||||
case eHTMLTag_ins:
|
||||
case eHTMLTag_kbd:
|
||||
case eHTMLTag_label:
|
||||
case eHTMLTag_legend:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_layer:
|
||||
break;
|
||||
|
||||
case eHTMLTag_link:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
// XXX hey rickg: listing is like xmp or plaintext and has
|
||||
// NOTHING to do with html lists.
|
||||
case eHTMLTag_listing:
|
||||
result=PRBool(eHTMLTag_listitem==aChild); break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
result=PRBool(eHTMLTag_area==aChild); break;
|
||||
|
||||
case eHTMLTag_marquee:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_math:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_meta:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
if(eHTMLTag_body==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_noscript:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_note:
|
||||
|
||||
case eHTMLTag_object:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_menu:
|
||||
case eHTMLTag_dir:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_ul:
|
||||
// XXX kipp was here
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_listitem:
|
||||
if (eHTMLTag_listitem == aChild) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_paragraph:
|
||||
if(eHTMLTag_paragraph==aChild)
|
||||
result=PR_FALSE;
|
||||
else result=PRBool(0!=strchr(gTagSet2,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_param:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_plaintext:
|
||||
break;
|
||||
|
||||
case eHTMLTag_pre:
|
||||
case eHTMLTag_quotation:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_strike:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
break; //unadorned script text...
|
||||
|
||||
case eHTMLTag_select:
|
||||
result=PRBool(eHTMLTag_option==aChild); break;
|
||||
|
||||
case eHTMLTag_small:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_span:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_strong:
|
||||
case eHTMLTag_samp:
|
||||
case eHTMLTag_sub:
|
||||
case eHTMLTag_sup:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_col, eHTMLTag_colgroup,eHTMLTag_tbody,
|
||||
eHTMLTag_tfoot, eHTMLTag_tr, eHTMLTag_thead, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
result=PRBool(eHTMLTag_tr==aChild); break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_title:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_tr:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_td,eHTMLTag_th,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tt:
|
||||
case eHTMLTag_u:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_var:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_userdefined:
|
||||
result=PR_TRUE; break; //XXX for now...
|
||||
|
||||
case eHTMLTag_xmp:
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -136,7 +475,39 @@ PRBool COtherDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool COtherDTD::CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=nsHTMLDTD::CanContainIndirect(aParent,aChild);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParent) {
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_head, eHTMLTag_body,
|
||||
eHTMLTag_header, eHTMLTag_footer,0
|
||||
};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=PR_TRUE; break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_colgroup,
|
||||
eHTMLTag_tbody, eHTMLTag_tfoot,
|
||||
eHTMLTag_thead, eHTMLTag_tr,
|
||||
eHTMLTag_td, eHTMLTag_th,
|
||||
eHTMLTag_col, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
result=PR_TRUE; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -180,7 +551,27 @@ PRBool COtherDTD::CanOmit(PRInt32 aParent,PRInt32 aChild) const {
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool COtherDTD::IsContainer(PRInt32 aTag) const {
|
||||
PRBool result=nsHTMLDTD::IsContainer(aTag);
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aTag){
|
||||
case eHTMLTag_area: case eHTMLTag_base:
|
||||
case eHTMLTag_basefont: case eHTMLTag_br:
|
||||
case eHTMLTag_col: case eHTMLTag_colgroup:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_hr: case eHTMLTag_img:
|
||||
case eHTMLTag_input: case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_math: case eHTMLTag_meta:
|
||||
case eHTMLTag_option: case eHTMLTag_param:
|
||||
case eHTMLTag_style: case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
case eHTMLTag_form:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -270,7 +661,7 @@ PRInt32 COtherDTD::GetDefaultParentTagFor(PRInt32 aTag) const{
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
PRBool COtherDTD::VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const {
|
||||
PRBool COtherDTD::VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const {
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
if(aCount>0) {
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef NS_OTHERHTMLDTD__
|
||||
#define NS_OTHERHTMLDTD__
|
||||
|
||||
#include "nsHTMLDTD.h"
|
||||
#include "nsIDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
|
||||
class COtherDTD : public nsHTMLDTD {
|
||||
class COtherDTD : public nsIDTD {
|
||||
|
||||
public:
|
||||
|
||||
@ -126,7 +126,7 @@ class COtherDTD : public nsHTMLDTD {
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const;
|
||||
virtual PRBool VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
|
@ -18,9 +18,10 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include "COtherDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsParserTypes.h"
|
||||
#include "COtherDTD.h"
|
||||
|
||||
|
||||
|
||||
// Note: We already handle the following special case conditions:
|
||||
@ -32,38 +33,50 @@
|
||||
static char gIdentChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
COtherDelegate::COtherDelegate() : CHTMLTokenizerDelegate(){
|
||||
*/
|
||||
COtherDelegate::COtherDelegate() :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
COtherDelegate::COtherDelegate(COtherDelegate& aDelegate) : CHTMLTokenizerDelegate(){
|
||||
*/
|
||||
COtherDelegate::COtherDelegate(COtherDelegate& aDelegate) :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
eParseMode COtherDelegate::GetParseMode() const {
|
||||
return eParseMode_other;
|
||||
return eParseMode_unknown;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* Cause delegate to create and return a new DTD.
|
||||
*
|
||||
* @update gess4/22/98
|
||||
* @return new DTD or null
|
||||
*/
|
||||
nsIDTD* COtherDelegate::GetDTD(void) const{
|
||||
return new COtherDTD();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of some kind of tagged
|
||||
* element. We don't know yet if it's a tag or a comment.
|
||||
@ -71,7 +84,7 @@ eParseMode COtherDelegate::GetParseMode() const {
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result=0;
|
||||
nsAutoString empty("");
|
||||
@ -95,7 +108,7 @@ CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& a
|
||||
nsAutoString temp("<");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
}
|
||||
} //switch
|
||||
|
||||
if(result!=0) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
@ -107,8 +120,35 @@ CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& a
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after we've consumed a start
|
||||
* tag, and we now have to consume its attributes.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @return
|
||||
*/
|
||||
void COtherDelegate::ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
PRBool done=PR_FALSE;
|
||||
nsAutoString as("");
|
||||
anErrorCode=kNoError;
|
||||
while((!done) && (anErrorCode==kNoError)) {
|
||||
CToken* result = new CAttributeToken(as);
|
||||
if(result){
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
mTokenDeque.Push(result);
|
||||
}
|
||||
aScanner.Peek(aChar);
|
||||
if(aChar==kGreaterThan) { //you just ate the '>'
|
||||
aScanner.GetChar(aChar); //skip the '>'
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
* This is a special case method. It's job is to consume
|
||||
* all of the given tag up to an including the end tag.
|
||||
*
|
||||
@ -116,7 +156,7 @@ CToken* COtherDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& a
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
|
||||
//In the case that we just read the given tag, we should go and
|
||||
@ -130,7 +170,7 @@ CToken* COtherDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of a tag.
|
||||
*
|
||||
@ -139,21 +179,22 @@ CToken* COtherDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CStartToken* result=new CStartToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(result->IsAttributed())
|
||||
if(result->IsAttributed()) {
|
||||
ConsumeAttributes(aChar,aScanner,anErrorCode);
|
||||
|
||||
}
|
||||
//now that that's over with, we have one more problem to solve.
|
||||
//In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
//consume all the content itself.
|
||||
nsString& str=result->GetText();
|
||||
if(str.EqualsIgnoreCase("SCRIPT") ||
|
||||
str.EqualsIgnoreCase("STYLE") ||
|
||||
str.EqualsIgnoreCase("TITLE")) {
|
||||
str.EqualsIgnoreCase("TITLE") ||
|
||||
str.EqualsIgnoreCase("TEXTAREA")) {
|
||||
CToken* sc=ConsumeContentToEndTag(str,aChar,aScanner,anErrorCode);
|
||||
|
||||
if(sc){
|
||||
@ -169,13 +210,13 @@ CToken* COtherDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt
|
||||
|
||||
CEndToken* endtoken=new CEndToken(str);
|
||||
mTokenDeque.Push(endtoken);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
} //if
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "&" has been consumed
|
||||
* and we know we're at the start of an entity.
|
||||
*
|
||||
@ -184,7 +225,7 @@ CToken* COtherDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = 0;
|
||||
PRUnichar ch;
|
||||
@ -197,8 +238,7 @@ CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
//oops, we're actually looking at plain text...
|
||||
nsAutoString temp("&");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
@ -206,8 +246,75 @@ CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after whitespace has been
|
||||
* consumed and we know we're at the start a whitespace run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = new CWhitespaceToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
/**
|
||||
* This method is called just after a "<!" has been consumed
|
||||
* and we know we're at the start of a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result= new CCommentToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a known text char has
|
||||
* been consumed and we should read a text run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CTextToken(aString);
|
||||
if(result) {
|
||||
PRUnichar ch;
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called just after a newline has been consumed.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*/
|
||||
CToken* COtherDelegate::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CNewlineToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method repeatedly called by the tokenizer.
|
||||
* Each time, we determine the kind of token were about to
|
||||
* read, and then we call the appropriate method to handle
|
||||
@ -218,18 +325,107 @@ CToken* COtherDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode){
|
||||
return CHTMLTokenizerDelegate::GetToken(aScanner,anErrorCode);
|
||||
CToken* result=0;
|
||||
PRUnichar aChar;
|
||||
|
||||
if(mTokenDeque.GetSize()>0) {
|
||||
return (CToken*)mTokenDeque.Pop();
|
||||
}
|
||||
|
||||
while(!aScanner.Eof()) {
|
||||
anErrorCode=aScanner.GetChar(aChar);
|
||||
switch(aChar) {
|
||||
case kAmpersand:
|
||||
return ConsumeEntity(aChar,aScanner,anErrorCode);
|
||||
case kLessThan:
|
||||
return ConsumeTag(aChar,aScanner,anErrorCode);
|
||||
case kCR: case kLF:
|
||||
return ConsumeNewline(aChar,aScanner,anErrorCode);
|
||||
case kNotFound:
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsSpace(aChar))
|
||||
return ConsumeWhitespace(aChar,aScanner,anErrorCode);
|
||||
else
|
||||
{
|
||||
nsAutoString temp(aChar);
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
if(anErrorCode==kEOF)
|
||||
anErrorCode=0;
|
||||
} //while
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
*/
|
||||
CToken* COtherDelegate::CreateTokenOfType(eHTMLTokenTypes aType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is by the tokenizer, once for each new token
|
||||
* we've constructed. This method determines whether or not
|
||||
* the new token (argument) should be accepted as a valid
|
||||
* token. If so, the token is added to the deque of tokens
|
||||
* contained within the tokenzier. If no, the token is
|
||||
* ignored.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aToken: token to be tested for acceptance
|
||||
* @return TRUE if token should be accepted.
|
||||
*/
|
||||
PRBool COtherDelegate::WillAddToken(CToken& /*aToken*/) {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just before a stream
|
||||
* is parsed. This method is called so that the delegate
|
||||
* can do any "pre-parsing" initialization.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool COtherDelegate::WillTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the parser, just after a stream
|
||||
* was parsed. This method is called so that the delegate
|
||||
* can do any "post-parsing" cleanup.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*/
|
||||
PRBool COtherDelegate::DidTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the selftest method for the delegate class.
|
||||
* Unfortunately, there's not much you can do with this
|
||||
* class alone, so we do the selftesting as part of the
|
||||
* parser class.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
void COtherDelegate::SelfTest(void) {
|
||||
#ifdef _DEBUG
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,9 +20,7 @@
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/1/98
|
||||
*
|
||||
* This class is used as the HTML tokenizer delegate for
|
||||
* an alternate html browser.
|
||||
|
||||
* This class is used as the HTML tokenizer delegate.
|
||||
*
|
||||
* The tokenzier class has the smarts to open an source,
|
||||
* and iterate over its characters to produce a list of
|
||||
@ -38,32 +36,46 @@
|
||||
* scanner.stream, and produces an HTML specific CToken.
|
||||
*/
|
||||
|
||||
#ifndef __OTHER_DELEGATE
|
||||
#define __OTHER_DELEGATE
|
||||
#ifndef _OTHER_DELEGATE
|
||||
#define _OTHER_DELEGATE
|
||||
|
||||
#include "nsToken.h"
|
||||
#include "nsHTMLDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsITokenizerDelegate.h"
|
||||
#include "nsDeque.h"
|
||||
#include "nsIDTD.h"
|
||||
|
||||
|
||||
class COtherDelegate : public CHTMLTokenizerDelegate {
|
||||
class COtherDelegate : public ITokenizerDelegate {
|
||||
public:
|
||||
COtherDelegate();
|
||||
COtherDelegate(COtherDelegate& aDelegate);
|
||||
COtherDelegate();
|
||||
COtherDelegate(COtherDelegate& aDelegate);
|
||||
|
||||
virtual CToken* GetToken(CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual PRBool WillAddToken(CToken& aToken);
|
||||
|
||||
virtual PRBool WillTokenize();
|
||||
virtual PRBool DidTokenize();
|
||||
|
||||
virtual eParseMode GetParseMode() const;
|
||||
virtual nsIDTD* GetDTD(void) const;
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
|
||||
virtual CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
|
||||
CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
void ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
//the only special case method...
|
||||
virtual CToken* ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
nsDeque mTokenDeque;
|
||||
|
||||
};
|
||||
|
||||
|
@ -28,14 +28,12 @@ CPPSRCS = \
|
||||
nsToken.cpp \
|
||||
nsTokenizer.cpp \
|
||||
nsTokenHandler.cpp \
|
||||
nsHTMLParser.cpp \
|
||||
nsHTMLTokens.cpp \
|
||||
nsHTMLDelegate.cpp \
|
||||
nsHTMLDTD.cpp \
|
||||
CNavDelegate.cpp \
|
||||
CNavDTD.cpp \
|
||||
COtherDelegate.cpp \
|
||||
COtherDTD.cpp \
|
||||
nsHTMLParser.cpp \
|
||||
nsHTMLTokens.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
|
@ -23,20 +23,20 @@ DEFINES=-D_IMPL_NS_HTMLPARS
|
||||
MODULE=raptor
|
||||
REQUIRES=xpcom raptor
|
||||
|
||||
CPPSRCS=nsHTMLContentSink.cpp nsHTMLDelegate.cpp nsHTMLDTD.cpp \
|
||||
nsHTMLParser.cpp nsHTMLTokens.cpp nsParserNode.cpp nsScanner.cpp \
|
||||
CPPSRCS=nsHTMLContentSink.cpp \
|
||||
nsHTMLTokens.cpp nsParserNode.cpp nsScanner.cpp \
|
||||
nsToken.cpp nsTokenizer.cpp nsTokenHandler.cpp \
|
||||
CNavDTD.cpp CNavDelegate.cpp \
|
||||
COtherDTD.cpp COtherDelegate.cpp
|
||||
COtherDTD.cpp COtherDelegate.cpp \
|
||||
nsHTMLParser.cpp
|
||||
|
||||
EXPORTS=nshtmlpars.h nsIContentSink.h nsIHTMLContentSink.h \
|
||||
nsHTMLTokens.h nsIParserNode.h nsIParser.h nsToken.h
|
||||
|
||||
CPP_OBJS=.\$(OBJDIR)\nsHTMLContentSink.obj \
|
||||
.\$(OBJDIR)\nsHTMLDelegate.obj .\$(OBJDIR)\nsHTMLParser.obj \
|
||||
.\$(OBJDIR)\nsHTMLDTD.obj \
|
||||
.\$(OBJDIR)\CNavDelegate.obj .\$(OBJDIR)\CNavDTD.obj \
|
||||
.\$(OBJDIR)\COtherDelegate.obj .\$(OBJDIR)\COtherDTD.obj \
|
||||
.\$(OBJDIR)\nsHTMLParser.obj \
|
||||
.\$(OBJDIR)\nsHTMLTokens.obj .\$(OBJDIR)\nsParserNode.obj \
|
||||
.\$(OBJDIR)\nsScanner.obj .\$(OBJDIR)\nsToken.obj \
|
||||
.\$(OBJDIR)\nsTokenizer.obj .\$(OBJDIR)\nsTokenHandler.obj
|
||||
|
@ -1,704 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/8/98
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsHTMLDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsParserTypes.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_IHTML_DTD_IID);
|
||||
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
||||
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method gets called as part of our COM-like interfaces.
|
||||
* Its purpose is to create an interface to parser object
|
||||
* of some type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param nsIID id of object to discover
|
||||
* @param aInstancePtr ptr to newly discovered interface
|
||||
* @return NS_xxx result code
|
||||
*------------------------------------------------------*/
|
||||
nsresult nsHTMLDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
|
||||
*aInstancePtr = (nsIDTD*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
|
||||
*aInstancePtr = (nsIDTD*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kClassIID)) { //do this class...
|
||||
*aInstancePtr = (nsHTMLDTD*)(this);
|
||||
}
|
||||
else {
|
||||
*aInstancePtr=0;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
((nsISupports*) *aInstancePtr)->AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsHTMLParser.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param nsIParser** ptr to newly instantiated parser
|
||||
* @return NS_xxx error result
|
||||
*------------------------------------------------------*/
|
||||
NS_HTMLPARS nsresult NS_NewHTMLDTD(nsIDTD** aInstancePtrResult)
|
||||
{
|
||||
nsHTMLDTD* it = new nsHTMLDTD();
|
||||
|
||||
if (it == 0) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return it->QueryInterface(kClassIID, (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsHTMLDTD)
|
||||
NS_IMPL_RELEASE(nsHTMLDTD)
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default constructor
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
nsHTMLDTD::nsHTMLDTD(){
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default destructor
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
nsHTMLDTD::~nsHTMLDTD(){
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::CanContain(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
//tagset1 has 61 members...
|
||||
static char gTagSet1[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_address, eHTMLTag_applet,
|
||||
eHTMLTag_bold, eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big,
|
||||
eHTMLTag_blockquote,eHTMLTag_br, eHTMLTag_button, eHTMLTag_center,
|
||||
eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn, eHTMLTag_dir,
|
||||
eHTMLTag_div, eHTMLTag_dl, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_hr, eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_img,
|
||||
eHTMLTag_input, eHTMLTag_isindex, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_menu, eHTMLTag_noframes, eHTMLTag_noscript,
|
||||
eHTMLTag_object, eHTMLTag_ol, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_table, eHTMLTag_textarea,
|
||||
eHTMLTag_tt, eHTMLTag_u, eHTMLTag_ul, eHTMLTag_userdefined,
|
||||
eHTMLTag_var, 0};
|
||||
|
||||
//tagset2 has 37 members...
|
||||
static char gTagSet2[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont, eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_hr, eHTMLTag_italic,
|
||||
eHTMLTag_iframe, eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_map, eHTMLTag_object, eHTMLTag_paragraph,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_script,
|
||||
eHTMLTag_select, eHTMLTag_small, eHTMLTag_span, eHTMLTag_strong,
|
||||
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt, eHTMLTag_textarea,
|
||||
eHTMLTag_u, eHTMLTag_var,0};
|
||||
|
||||
//tagset3 has 53 members...
|
||||
static char gTagSet3[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br, eHTMLTag_blockquote,
|
||||
eHTMLTag_body, eHTMLTag_caption, eHTMLTag_center, eHTMLTag_cite,
|
||||
eHTMLTag_code, eHTMLTag_dd, eHTMLTag_del, eHTMLTag_dfn,
|
||||
eHTMLTag_div, eHTMLTag_dt, eHTMLTag_em, eHTMLTag_fieldset,
|
||||
eHTMLTag_font, eHTMLTag_form, eHTMLTag_h1, eHTMLTag_h2,
|
||||
eHTMLTag_h3, eHTMLTag_h4, eHTMLTag_h5, eHTMLTag_h6,
|
||||
eHTMLTag_italic, eHTMLTag_iframe, eHTMLTag_ins, eHTMLTag_kbd,
|
||||
eHTMLTag_label, eHTMLTag_legend, eHTMLTag_listitem, eHTMLTag_noframes,
|
||||
eHTMLTag_noscript, eHTMLTag_object, eHTMLTag_paragraph, eHTMLTag_pre,
|
||||
eHTMLTag_quotation, eHTMLTag_strike, eHTMLTag_samp, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strong, eHTMLTag_sub, eHTMLTag_sup,
|
||||
eHTMLTag_td, eHTMLTag_th, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
|
||||
//This hack code is here because we don't yet know what to do
|
||||
//with userdefined tags... XXX Hack
|
||||
if(eHTMLTag_userdefined==aChild) // XXX Hack: For now...
|
||||
result=PR_TRUE;
|
||||
|
||||
switch(aParent) {
|
||||
case eHTMLTag_a:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_acronym:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_address:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_applet:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_applet, eHTMLTag_bold,
|
||||
eHTMLTag_basefont,eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_br,
|
||||
eHTMLTag_button, eHTMLTag_cite, eHTMLTag_code, eHTMLTag_dfn,
|
||||
eHTMLTag_em, eHTMLTag_font, eHTMLTag_italic, eHTMLTag_iframe,
|
||||
eHTMLTag_img, eHTMLTag_input, eHTMLTag_kbd, eHTMLTag_label,
|
||||
eHTMLTag_map, eHTMLTag_object, eHTMLTag_param, eHTMLTag_quotation,
|
||||
eHTMLTag_samp, eHTMLTag_script, eHTMLTag_select, eHTMLTag_small,
|
||||
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong, eHTMLTag_sub,
|
||||
eHTMLTag_sup, eHTMLTag_textarea, eHTMLTag_tt, eHTMLTag_u,
|
||||
eHTMLTag_var,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
|
||||
case eHTMLTag_area:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_basefont:
|
||||
case eHTMLTag_br:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_bdo:
|
||||
case eHTMLTag_big:
|
||||
case eHTMLTag_blink:
|
||||
case eHTMLTag_bold:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_blockquote:
|
||||
case eHTMLTag_body:
|
||||
if(eHTMLTag_userdefined==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_button:
|
||||
result=PRBool(0!=strchr(gTagSet3,aChild)); break;
|
||||
|
||||
case eHTMLTag_caption:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_center:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_cite: case eHTMLTag_code:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_dd:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_del: case eHTMLTag_dfn:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_div:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_dl:
|
||||
{
|
||||
char okTags[]={eHTMLTag_dd,eHTMLTag_dt,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_dt:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_em:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_fieldset:
|
||||
if(eHTMLTag_legend==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_font:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_form:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_frame:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_frameset:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_frame,eHTMLTag_frameset,eHTMLTag_noframes,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_h1: case eHTMLTag_h2:
|
||||
case eHTMLTag_h3: case eHTMLTag_h4:
|
||||
case eHTMLTag_h5: case eHTMLTag_h6:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_base, eHTMLTag_isindex, eHTMLTag_link, eHTMLTag_meta,
|
||||
eHTMLTag_script,eHTMLTag_style, eHTMLTag_title, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_hr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_body,eHTMLTag_frameset,eHTMLTag_head,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_img:
|
||||
case eHTMLTag_input:
|
||||
case eHTMLTag_isindex:
|
||||
case eHTMLTag_spacer:
|
||||
case eHTMLTag_wbr:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
case eHTMLTag_italic:
|
||||
case eHTMLTag_ins:
|
||||
case eHTMLTag_kbd:
|
||||
case eHTMLTag_label:
|
||||
case eHTMLTag_legend:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_layer:
|
||||
break;
|
||||
|
||||
case eHTMLTag_link:
|
||||
break; //singletons can't contain anything...
|
||||
|
||||
// XXX hey rickg: listing is like xmp or plaintext and has
|
||||
// NOTHING to do with html lists.
|
||||
case eHTMLTag_listing:
|
||||
result=PRBool(eHTMLTag_listitem==aChild); break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
result=PRBool(eHTMLTag_area==aChild); break;
|
||||
|
||||
case eHTMLTag_marquee:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_math:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_meta:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_noframes:
|
||||
if(eHTMLTag_body==aChild)
|
||||
result=PR_TRUE;
|
||||
else result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_noscript:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_note:
|
||||
|
||||
case eHTMLTag_object:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_menu:
|
||||
case eHTMLTag_dir:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_ul:
|
||||
// XXX kipp was here
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_listitem:
|
||||
if (eHTMLTag_listitem == aChild) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
result = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_paragraph:
|
||||
if(eHTMLTag_paragraph==aChild)
|
||||
result=PR_FALSE;
|
||||
else result=PRBool(0!=strchr(gTagSet2,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_param:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_plaintext:
|
||||
break;
|
||||
|
||||
case eHTMLTag_pre:
|
||||
case eHTMLTag_quotation:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_strike:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
break; //unadorned script text...
|
||||
|
||||
case eHTMLTag_select:
|
||||
result=PRBool(eHTMLTag_option==aChild); break;
|
||||
|
||||
case eHTMLTag_small:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_span:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
break; //singletons can't contain other tags
|
||||
|
||||
case eHTMLTag_strong:
|
||||
case eHTMLTag_samp:
|
||||
case eHTMLTag_sub:
|
||||
case eHTMLTag_sup:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild)); break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_col, eHTMLTag_colgroup,eHTMLTag_tbody,
|
||||
eHTMLTag_tfoot, eHTMLTag_tr, eHTMLTag_thead, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
result=PRBool(eHTMLTag_tr==aChild); break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=PRBool(0!=strchr(gTagSet1,aChild));
|
||||
break;
|
||||
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_title:
|
||||
break; //nothing but plain text...
|
||||
|
||||
case eHTMLTag_tr:
|
||||
{
|
||||
static char okTags[]={eHTMLTag_td,eHTMLTag_th,0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_tt:
|
||||
case eHTMLTag_u:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_var:
|
||||
result=PRBool(0!=strchr(gTagSet2,aChild)); break;
|
||||
|
||||
case eHTMLTag_userdefined:
|
||||
result=PR_TRUE; break; //XXX for now...
|
||||
|
||||
case eHTMLTag_xmp:
|
||||
default:
|
||||
break;
|
||||
} //switch
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aParent) {
|
||||
|
||||
case eHTMLTag_html:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_head, eHTMLTag_body,
|
||||
eHTMLTag_header, eHTMLTag_footer,0
|
||||
};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
|
||||
case eHTMLTag_body:
|
||||
result=PR_TRUE; break;
|
||||
|
||||
case eHTMLTag_table:
|
||||
{
|
||||
static char okTags[]={
|
||||
eHTMLTag_caption, eHTMLTag_colgroup,
|
||||
eHTMLTag_tbody, eHTMLTag_tfoot,
|
||||
eHTMLTag_thead, eHTMLTag_tr,
|
||||
eHTMLTag_td, eHTMLTag_th,
|
||||
eHTMLTag_col, 0};
|
||||
result=PRBool(0!=strchr(okTags,aChild));
|
||||
}
|
||||
break;
|
||||
|
||||
result=PR_TRUE; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag can contain newlines. Most do not.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::CanOmit(PRInt32 aParent,PRInt32 aChild) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch((eHTMLTags)aParent) {
|
||||
case eHTMLTag_tr:
|
||||
case eHTMLTag_table:
|
||||
case eHTMLTag_thead:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_col:
|
||||
case eHTMLTag_colgroup:
|
||||
if((aChild==eHTMLTag_newline) ||
|
||||
(aChild==eHTMLTag_whitespace))
|
||||
result=PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
PRBool nsHTMLDTD::IsContainer(PRInt32 aTag) const {
|
||||
PRBool result=PR_FALSE;
|
||||
|
||||
switch(aTag){
|
||||
case eHTMLTag_area: case eHTMLTag_base:
|
||||
case eHTMLTag_basefont: case eHTMLTag_br:
|
||||
case eHTMLTag_col: case eHTMLTag_colgroup:
|
||||
case eHTMLTag_frame:
|
||||
case eHTMLTag_hr: case eHTMLTag_img:
|
||||
case eHTMLTag_input: case eHTMLTag_isindex:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_math: case eHTMLTag_meta:
|
||||
case eHTMLTag_param:
|
||||
case eHTMLTag_style: case eHTMLTag_spacer:
|
||||
case eHTMLTag_textarea:
|
||||
case eHTMLTag_wbr:
|
||||
case eHTMLTag_form:
|
||||
result=PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
result=PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
* 2nd, pass this message on to the sink.
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*------------------------------------------------------*/
|
||||
PRInt32 nsHTMLDTD::GetDefaultParentTagFor(PRInt32 aTag) const{
|
||||
eHTMLTags result=eHTMLTag_unknown;
|
||||
switch(aTag) {
|
||||
case eHTMLTag_html:
|
||||
result=(eHTMLTags)kNotFound; break;
|
||||
|
||||
case eHTMLTag_body:
|
||||
case eHTMLTag_head:
|
||||
case eHTMLTag_header:
|
||||
case eHTMLTag_footer:
|
||||
case eHTMLTag_frameset:
|
||||
result=eHTMLTag_html; break;
|
||||
|
||||
//These tags are head specific...
|
||||
case eHTMLTag_style:
|
||||
case eHTMLTag_meta:
|
||||
case eHTMLTag_title:
|
||||
case eHTMLTag_base:
|
||||
case eHTMLTag_link:
|
||||
result=eHTMLTag_head; break;
|
||||
|
||||
//These tags are table specific...
|
||||
case eHTMLTag_caption:
|
||||
case eHTMLTag_colgroup:
|
||||
case eHTMLTag_tbody:
|
||||
case eHTMLTag_tfoot:
|
||||
case eHTMLTag_thead:
|
||||
case eHTMLTag_tr:
|
||||
result=eHTMLTag_table; break;
|
||||
|
||||
case eHTMLTag_td:
|
||||
case eHTMLTag_th:
|
||||
result=eHTMLTag_tr; break;
|
||||
|
||||
case eHTMLTag_col:
|
||||
result=eHTMLTag_colgroup; break;
|
||||
|
||||
//These have to do with listings...
|
||||
case eHTMLTag_listitem:
|
||||
result=eHTMLTag_ul; break;
|
||||
|
||||
case eHTMLTag_dd:
|
||||
case eHTMLTag_dt:
|
||||
result=eHTMLTag_dl; break;
|
||||
|
||||
case eHTMLTag_option:
|
||||
result=eHTMLTag_select; break;
|
||||
|
||||
//These have to do with image maps...
|
||||
case eHTMLTag_area:
|
||||
result=eHTMLTag_map; break;
|
||||
|
||||
//These have to do with applets...
|
||||
case eHTMLTag_param:
|
||||
result=eHTMLTag_applet; break;
|
||||
|
||||
//These have to do with frames...
|
||||
case eHTMLTag_frame:
|
||||
result=eHTMLTag_frameset; break;
|
||||
|
||||
default:
|
||||
result=eHTMLTag_body; //XXX Hack! Just for now.
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
PRBool nsHTMLDTD::VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const {
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
if(aCount>0) {
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the parent down to the
|
||||
* child.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
PRInt32 nsHTMLDTD::ForwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const{
|
||||
int result=0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the child up to the parent.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
PRInt32 nsHTMLDTD::BackwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const{
|
||||
int result=0;
|
||||
return result;
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/8/98
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NS_HTMLDTD__
|
||||
#define NS_HTMLDTD__
|
||||
|
||||
#include "nsIDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nshtmlpars.h"
|
||||
|
||||
|
||||
#define NS_IHTML_DTD_IID \
|
||||
{0x5c5cce40, 0xcfd6, 0x11d1, \
|
||||
{0xaa, 0xda, 0x00, 0x80, 0x5f, 0x8a, 0x3e, 0x14}}
|
||||
|
||||
|
||||
|
||||
class nsHTMLDTD : public nsIDTD {
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
||||
/** -------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
nsHTMLDTD();
|
||||
|
||||
/** -------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/9/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //------------------------------------------------------
|
||||
virtual ~nsHTMLDTD();
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanContain(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aParent -- tag enum of parent container
|
||||
* @param aChild -- tag enum of child container
|
||||
* @return PR_TRUE if parent can contain child
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanContainIndirect(PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag can contain newlines. Most do not.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanOmit(PRInt32 aParent,PRInt32 aChild)const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method gets called to determine whether a given
|
||||
* tag is itself a container
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aTag -- tag to test for containership
|
||||
* @return PR_TRUE if given tag can contain other tags
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool IsContainer(PRInt32 aTags) const;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
* 2nd, pass this message on to the sink.
|
||||
* @update gess4/6/98
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRInt32 GetDefaultParentTagFor(PRInt32 aTag) const;
|
||||
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(eHTMLTags aStack[],PRInt32 aCount) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the parent down to the
|
||||
* child.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
virtual ForwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method tries to design a context map (without actually
|
||||
* changing our parser state) from the child up to the parent.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aParent -- tag type of parent
|
||||
* @param aChild -- tag type of child
|
||||
* @return Non zero count of intermediate nodes;
|
||||
* 0 if unable to comply
|
||||
*/ //----------------------------------------------------
|
||||
virtual BackwardPropagate(PRInt32 aVector[],PRInt32 aParent,PRInt32 aChild) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,420 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "nsHTMLDelegate.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsScanner.h"
|
||||
#include "nsParserTypes.h"
|
||||
|
||||
|
||||
// Note: We already handle the following special case conditions:
|
||||
// 1) If you see </>, simply treat it as a bad tag.
|
||||
// 2) If you see </ ...>, treat it like a comment.
|
||||
// 3) If you see <> or <_ (< space) simply treat it as text.
|
||||
// 4) If you see <~ (< followed by non-alpha), treat it as text.
|
||||
|
||||
static char gIdentChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CHTMLTokenizerDelegate::CHTMLTokenizerDelegate() :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* Default constructor
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CHTMLTokenizerDelegate::CHTMLTokenizerDelegate(CHTMLTokenizerDelegate& aDelegate) :
|
||||
ITokenizerDelegate(), mTokenDeque() {
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
eParseMode CHTMLTokenizerDelegate::GetParseMode() const {
|
||||
return eParseMode_unknown;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of some kind of tagged
|
||||
* element. We don't know yet if it's a tag or a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*-----------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result=0;
|
||||
nsAutoString empty("");
|
||||
anErrorCode=anErrorCode=aScanner.GetChar(aChar);
|
||||
|
||||
switch(aChar) {
|
||||
case kForwardSlash:
|
||||
PRUnichar ch;
|
||||
anErrorCode=aScanner.Peek(ch);
|
||||
if(nsString::IsAlpha(ch))
|
||||
result=new CEndToken(empty);
|
||||
else result=new CCommentToken(empty); //Special case: </ ...> is treated as a comment
|
||||
break;
|
||||
case kExclamation:
|
||||
result=new CCommentToken(empty);
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsAlpha(aChar))
|
||||
return ConsumeStartTag(aChar,aScanner,anErrorCode);
|
||||
else if(kNotFound!=aChar) {
|
||||
nsAutoString temp("<");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
|
||||
if(result!=0) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(anErrorCode) {
|
||||
result=0;
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after we've consumed a start
|
||||
* tag, and we now have to consume its attributes.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
void CHTMLTokenizerDelegate::ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
PRBool done=PR_FALSE;
|
||||
nsAutoString as("");
|
||||
anErrorCode=kNoError;
|
||||
while((!done) && (anErrorCode==kNoError)) {
|
||||
CToken* result = new CAttributeToken(as);
|
||||
if(result){
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
mTokenDeque.Push(result);
|
||||
}
|
||||
aScanner.Peek(aChar);
|
||||
if(aChar==kGreaterThan) { //you just ate the '>'
|
||||
aScanner.GetChar(aChar); //skip the '>'
|
||||
done=PR_TRUE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* This is a special case method. It's job is to consume
|
||||
* all of the given tag up to an including the end tag.
|
||||
*
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
|
||||
//In the case that we just read the given tag, we should go and
|
||||
//consume all the input until we find a matching end tag.
|
||||
|
||||
nsAutoString endTag("</");
|
||||
endTag.Append(aString);
|
||||
endTag.Append(">");
|
||||
CSkippedContentToken* sc=new CSkippedContentToken(endTag);
|
||||
anErrorCode= sc->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "<" has been consumed
|
||||
* and we know we're at the start of a tag.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CStartToken* result=new CStartToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode= result->Consume(aChar,aScanner); //tell new token to finish consuming text...
|
||||
if(result->IsAttributed()) {
|
||||
ConsumeAttributes(aChar,aScanner,anErrorCode);
|
||||
}
|
||||
//now that that's over with, we have one more problem to solve.
|
||||
//In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
//consume all the content itself.
|
||||
nsString& str=result->GetText();
|
||||
if(str.EqualsIgnoreCase("SCRIPT") ||
|
||||
str.EqualsIgnoreCase("STYLE") ||
|
||||
str.EqualsIgnoreCase("TITLE") ||
|
||||
str.EqualsIgnoreCase("TEXTAREA")) {
|
||||
CToken* sc=ConsumeContentToEndTag(str,aChar,aScanner,anErrorCode);
|
||||
|
||||
if(sc){
|
||||
//now we strip the ending sequence from our new SkippedContent token...
|
||||
PRInt32 slen=str.Length()+3;
|
||||
nsString& skippedText=sc->GetText();
|
||||
|
||||
skippedText.Cut(skippedText.Length()-slen,slen);
|
||||
mTokenDeque.Push(sc);
|
||||
|
||||
//In the case that we just read a given tag, we should go and
|
||||
//consume all the tag content itself (and throw it all away).
|
||||
|
||||
CEndToken* endtoken=new CEndToken(str);
|
||||
mTokenDeque.Push(endtoken);
|
||||
} //if
|
||||
} //if
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "&" has been consumed
|
||||
* and we know we're at the start of an entity.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = 0;
|
||||
PRUnichar ch;
|
||||
anErrorCode=aScanner.GetChar(ch);
|
||||
if(nsString::IsAlpha(ch)) { //handle common enity references &xxx; or �.
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode= result->Consume(ch,aScanner); //tell new token to finish consuming text...
|
||||
}
|
||||
else if(kHashsign==ch) {
|
||||
result = new CEntityToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
else {
|
||||
//oops, we're actually looking at plain text...
|
||||
nsAutoString temp("&");
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after whitespace has been
|
||||
* consumed and we know we're at the start a whitespace run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode) {
|
||||
CToken* result = new CWhitespaceToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a "<!" has been consumed
|
||||
* and we know we're at the start of a comment.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result= new CCommentToken(nsAutoString(""));
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a known text char has
|
||||
* been consumed and we should read a text run.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CTextToken(aString);
|
||||
if(result) {
|
||||
PRUnichar ch;
|
||||
anErrorCode=result->Consume(ch,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called just after a newline has been consumed.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=new CNewlineToken(nsAutoString(""));
|
||||
if(result) {
|
||||
anErrorCode=result->Consume(aChar,aScanner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method repeatedly called by the tokenizer.
|
||||
* Each time, we determine the kind of token were about to
|
||||
* read, and then we call the appropriate method to handle
|
||||
* that token type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aChar: last char read
|
||||
* @param aScanner: see nsScanner.h
|
||||
* @param anErrorCode: arg that will hold error condition
|
||||
* @return new token or null
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::GetToken(CScanner& aScanner,PRInt32& anErrorCode){
|
||||
CToken* result=0;
|
||||
PRUnichar aChar;
|
||||
|
||||
if(mTokenDeque.GetSize()>0) {
|
||||
return (CToken*)mTokenDeque.Pop();
|
||||
}
|
||||
|
||||
while(!aScanner.Eof()) {
|
||||
anErrorCode=aScanner.GetChar(aChar);
|
||||
switch(aChar) {
|
||||
case kAmpersand:
|
||||
return ConsumeEntity(aChar,aScanner,anErrorCode);
|
||||
case kLessThan:
|
||||
return ConsumeTag(aChar,aScanner,anErrorCode);
|
||||
case kCR: case kLF:
|
||||
return ConsumeNewline(aChar,aScanner,anErrorCode);
|
||||
case kNotFound:
|
||||
break;
|
||||
default:
|
||||
if(nsString::IsSpace(aChar))
|
||||
return ConsumeWhitespace(aChar,aScanner,anErrorCode);
|
||||
else
|
||||
{
|
||||
nsAutoString temp(aChar);
|
||||
return ConsumeText(temp,aScanner,anErrorCode);
|
||||
}
|
||||
} //switch
|
||||
if(anErrorCode==kEOF)
|
||||
anErrorCode=0;
|
||||
} //while
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* @update gess4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*------------------------------------------------------*/
|
||||
CToken* CHTMLTokenizerDelegate::CreateTokenOfType(eHTMLTokenTypes aType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is by the tokenizer, once for each new token
|
||||
* we've constructed. This method determines whether or not
|
||||
* the new token (argument) should be accepted as a valid
|
||||
* token. If so, the token is added to the deque of tokens
|
||||
* contained within the tokenzier. If no, the token is
|
||||
* ignored.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aToken: token to be tested for acceptance
|
||||
* @return TRUE if token should be accepted.
|
||||
*------------------------------------------------------*/
|
||||
PRBool CHTMLTokenizerDelegate::WillAddToken(CToken& /*aToken*/) {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called by the parser, just before a stream
|
||||
* is parsed. This method is called so that the delegate
|
||||
* can do any "pre-parsing" initialization.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*------------------------------------------------------*/
|
||||
PRBool CHTMLTokenizerDelegate::WillTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This method is called by the parser, just after a stream
|
||||
* was parsed. This method is called so that the delegate
|
||||
* can do any "post-parsing" cleanup.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @return TRUE if preinitialization completed successfully
|
||||
*------------------------------------------------------*/
|
||||
PRBool CHTMLTokenizerDelegate::DidTokenize() {
|
||||
PRBool result=PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**-------------------------------------------------------
|
||||
* This is the selftest method for the delegate class.
|
||||
* Unfortunately, there's not much you can do with this
|
||||
* class alone, so we do the selftesting as part of the
|
||||
* parser class.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*------------------------------------------------------*/
|
||||
void CHTMLTokenizerDelegate::SelfTest(void) {
|
||||
#ifdef _DEBUG
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,82 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/1/98
|
||||
*
|
||||
* This class is used as the HTML tokenizer delegate.
|
||||
*
|
||||
* The tokenzier class has the smarts to open an source,
|
||||
* and iterate over its characters to produce a list of
|
||||
* tokens. The tokenizer doesn't know HTML, which is
|
||||
* where this delegate comes into play.
|
||||
*
|
||||
* The tokenizer calls methods on this class to help
|
||||
* with the creation of HTML-specific tokens from a source
|
||||
* stream.
|
||||
*
|
||||
* The interface here is very simple, mainly the call
|
||||
* to GetToken(), which Consumes bytes from the underlying
|
||||
* scanner.stream, and produces an HTML specific CToken.
|
||||
*/
|
||||
|
||||
#ifndef TOKENIZER_DELEGATE
|
||||
#define TOKENIZER_DELEGATE
|
||||
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsITokenizerDelegate.h"
|
||||
#include "nsDeque.h"
|
||||
|
||||
|
||||
class CHTMLTokenizerDelegate : public ITokenizerDelegate {
|
||||
public:
|
||||
CHTMLTokenizerDelegate();
|
||||
CHTMLTokenizerDelegate(CHTMLTokenizerDelegate& aDelegate);
|
||||
|
||||
virtual CToken* GetToken(CScanner& aScanner,PRInt32& anErrorCode);
|
||||
virtual PRBool WillAddToken(CToken& aToken);
|
||||
|
||||
virtual PRBool WillTokenize();
|
||||
virtual PRBool DidTokenize();
|
||||
|
||||
virtual eParseMode GetParseMode() const;
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType);
|
||||
|
||||
CToken* ConsumeTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeStartTag(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
void ConsumeAttributes(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeText(const nsString& aString,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeEntity(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeWhitespace(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeComment(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
CToken* ConsumeNewline(PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
//the only special case method...
|
||||
virtual CToken* ConsumeContentToEndTag(const nsString& aString,PRUnichar aChar,CScanner& aScanner,PRInt32& anErrorCode);
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -363,7 +363,7 @@ PRBool nsHTMLParser::IterateTokens() {
|
||||
//later you have to Handle them, because they're relevent to certain containers (eg PRE).
|
||||
break;
|
||||
}
|
||||
mDTD->VerifyContextStack(mContextStack,mContextStackPos);
|
||||
// mDTD->VerifyContextStack(mContextStack,mContextStackPos);
|
||||
++(*mCurrentPos);
|
||||
done=PRBool(e==*mCurrentPos);
|
||||
}
|
||||
@ -410,15 +410,18 @@ PRBool nsHTMLParser::Parse(nsIURL* aURL,eParseMode aMode){
|
||||
result=PR_TRUE;
|
||||
mParseMode=aMode;
|
||||
ITokenizerDelegate* theDelegate=0;
|
||||
|
||||
|
||||
mDTD=0;
|
||||
switch(mParseMode) {
|
||||
case eParseMode_navigator:
|
||||
theDelegate=new CNavDelegate();
|
||||
mDTD= new CNavDTD();
|
||||
if(theDelegate)
|
||||
mDTD=theDelegate->GetDTD();
|
||||
break;
|
||||
case eParseMode_other:
|
||||
theDelegate=new COtherDelegate();
|
||||
mDTD= new COtherDTD();
|
||||
if(theDelegate)
|
||||
mDTD=theDelegate->GetDTD();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -427,9 +430,6 @@ PRBool nsHTMLParser::Parse(nsIURL* aURL,eParseMode aMode){
|
||||
NS_ERROR(kNullTokenizer);
|
||||
return PR_FALSE;
|
||||
}
|
||||
if(!mDTD) {
|
||||
mDTD= new nsHTMLDTD();
|
||||
}
|
||||
|
||||
mTokenizer=new CTokenizer(aURL, theDelegate, mParseMode);
|
||||
mTokenizer->Tokenize();
|
||||
|
@ -72,7 +72,7 @@ class CTokenizer;
|
||||
class IContentSink;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIURL;
|
||||
class nsHTMLDTD;
|
||||
class nsIDTD;
|
||||
|
||||
|
||||
class nsHTMLParser : public nsIParser {
|
||||
@ -153,7 +153,7 @@ friend class CTokenHandler;
|
||||
PRInt32 mTokenHandlerCount;
|
||||
nsDequeIterator* mCurrentPos;
|
||||
|
||||
nsHTMLDTD* mDTD;
|
||||
nsIDTD* mDTD;
|
||||
eParseMode mParseMode;
|
||||
};
|
||||
|
||||
|
@ -83,6 +83,18 @@ class nsIDTD : public nsISupports {
|
||||
*/ //----------------------------------------------------
|
||||
virtual PRBool CanOmit(PRInt32 aParent,PRInt32 aChild)const=0;
|
||||
|
||||
/** ------------------------------------------------------
|
||||
* This method gets called at various times by the parser
|
||||
* whenever we want to verify a valid context stack. This
|
||||
* method also gives us a hook to add debugging metrics.
|
||||
*
|
||||
* @update gess4/6/98
|
||||
* @param aStack[] array of ints (tokens)
|
||||
* @param aCount number of elements in given array
|
||||
* @return TRUE if stack is valid, else FALSE
|
||||
*/ //-----------------------------------------------------
|
||||
virtual PRBool VerifyContextStack(PRInt32 aStack[],PRInt32 aCount) const=0;
|
||||
|
||||
/** -------------------------------------------------------
|
||||
* This method does two things: 1st, help construct
|
||||
* our own internal model of the content-stack; and
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsParserTypes.h"
|
||||
#include "nsIDTD.h"
|
||||
|
||||
class CScanner;
|
||||
class CToken;
|
||||
@ -54,6 +55,7 @@ class ITokenizerDelegate {
|
||||
virtual PRBool WillAddToken(CToken& aToken)=0;
|
||||
|
||||
virtual eParseMode GetParseMode() const=0;
|
||||
virtual nsIDTD* GetDTD(void) const=0;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user