// Job: Jay's Own Browser, a web browser written in Java by Jay Skeer // Copyright (C) 1996 Jay Skeer, Jay Prime Positive // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // /** Base class for all HTML document subparts. E.g. Heading, list, paragraph, etc. */ import java.io.*; import HtmlToken; import HtmlTokenStream; public class HtmlComponent { /** The HTML type of this class, see HtmlComponent.BODY etc. */ int id; /** a string with the actual key for this component, eg "body" */ String id_string; /** The value of TEXT components, and hack to hold "begin", "end" or "only" marker for <...> expresions */ String value; /** The name of a name=value pair */ String name; /** Internal, pointer to next sibling component */ HtmlComponent sib; /** Internal, pointer to first child component */ HtmlComponent first_kid; /** Internal, pointer to last child component */ HtmlComponent last_kid; /** The list of arguments==parameters to this <...> document */ HtmlComponent arg; /** next sibling (either kid, or arg) component */ public HtmlComponent sib() { return this.sib; } /** first child component */ public HtmlComponent kid() { return this.first_kid; } /** last child component */ public HtmlComponent last_kid() { return this.last_kid; } /** first argument==parameter component */ public HtmlComponent arg() { return this.arg; } /** HTML is root of html document trees */ public static final int HTML= 0; /** HEAD is title (and other parts?) */ public static final int HEAD= 100; /** TITLE is title of this document */ public static final int TITLE= 101; /** BODY is main part of document */ public static final int BODY= 200; /** H1 is heading level 1 (highest level) */ public static final int H1= 201; /** H2 is heading level 2 */ public static final int H2= 202; /** H3 is heading level 3 (middle level) */ public static final int H3= 203; /** H4 is heading level 4 */ public static final int H4= 204; /** H5 is heading level 5 (lowest level) */ public static final int H5= 205; /** PRE is a kind of paragraph format (fixed width font) */ public static final int PRE= 206; /** TT is a kind of text format (fixed width font, fill ok) */ public static final int TT= 207; /** STRONG is a kind of text format (bold i believe) */ public static final int STRONG= 208; /** B is a kind of text format (bold i believe) */ public static final int B= 209; /** HR is a horizontal rule line */ public static final int HR= 210; /** P is a paragraph (a sequence) of TEXT */ public static final int P= 220; /** TEXT is a (sequence of) characters */ public static final int TEXT= 221; /** ANCHOR, a subtype of TEXT, is abstract super of HREF's and NAME's */ public static final int ANCHOR= 222; /** AHREF is a reference to (another) HTML doc */ public static final int AHREF= 223; /** ANAME is a name for a section (position) in an HTML doc */ public static final int ANAME= 224; /** LIST is abstract supertype of UL, DL, etc. */ public static final int LIST= 230; /** UL is a kind of list */ public static final int UL= 231; /** DL is a kind of list */ public static final int DL= 232; /** ITEM is a kind of list item marker */ public static final int ITEM= 240; /** LI is a kind of list item marker */ public static final int LI= 241; /** DD is a kind of list item marker */ public static final int DD= 242; /** DT is a kind of list item marker */ public static final int DT= 243; /** IMG is a image */ public static final int IMG= 250; /** CENTER is centered text */ public static final int CENTER= 260; /** OTHER is a html tag not recognized by this parser */ public static final int OTHER= 999; /** ARG is a html name=value pair */ public static final int ARG= 1000; /** Given an id number, return an id_string */ public static String idToIdString(int id) { switch (id) { case HTML: return "html"; case HEAD: return "head"; case TITLE: return "title"; case BODY: return "body"; case H1: return "h1"; case H2: return "h2"; case H3: return "h3"; case H4: return "h4"; case H5: return "h5"; case PRE: return "pre"; case TT: return "tt"; case STRONG: return "strong"; case B: return "b"; case HR: return "hr"; case P: return "p"; case TEXT: return "text"; case ANCHOR: return "a"; case AHREF: return "a-href"; case ANAME: return "a-name"; case LIST: return "list-abstract"; case UL: return "ul"; case DL: return "dl"; case ITEM: return "list-item-abstract"; case LI: return "li"; case DD: return "dd"; case DT: return "dt"; case IMG: return "img"; case CENTER: return "center"; case OTHER: return "other"; case ARG: return "arg"; default: return "error"; } } /** Given an id_string, return an id number */ public static int idStringToId(String id) { if (id.equalsIgnoreCase("HTML")) return HTML; else if (id.equalsIgnoreCase("HEAD")) return HEAD; else if (id.equalsIgnoreCase("TITLE")) return TITLE; else if (id.equalsIgnoreCase("BODY")) return BODY; else if (id.equalsIgnoreCase("H1")) return H1; else if (id.equalsIgnoreCase("H2")) return H2; else if (id.equalsIgnoreCase("H3")) return H3; else if (id.equalsIgnoreCase("H4")) return H4; else if (id.equalsIgnoreCase("H5")) return H5; else if (id.equalsIgnoreCase("PRE")) return PRE; else if (id.equalsIgnoreCase("TT")) return TT; else if (id.equalsIgnoreCase("STRONG")) return STRONG; else if (id.equalsIgnoreCase("B")) return B; else if (id.equalsIgnoreCase("HR")) return HR; else if (id.equalsIgnoreCase("P")) return P; else if (id.equalsIgnoreCase("TEXT")) return TEXT; else if (id.equalsIgnoreCase("ANCHOR")) return ANCHOR; else if (id.equalsIgnoreCase("A")) return ANCHOR; else if (id.equalsIgnoreCase("AHREF")) return AHREF; else if (id.equalsIgnoreCase("ANAME")) return ANAME; else if (id.equalsIgnoreCase("UL")) return UL; else if (id.equalsIgnoreCase("DL")) return DL; else if (id.equalsIgnoreCase("LI")) return LI; else if (id.equalsIgnoreCase("DD")) return DD; else if (id.equalsIgnoreCase("DT")) return DT; else if (id.equalsIgnoreCase("IMG")) return IMG; else if (id.equalsIgnoreCase("CENTER")) return CENTER; else if (id.equalsIgnoreCase("ARG")) return ARG; else return OTHER; } /** Creates a new HtmlComponent with the given id, and id_string */ public HtmlComponent(int id, String id_string) { this.id= id; this.id_string= id_string; this.first_kid= null; this.last_kid= null; this.sib= null; this.arg= null; this.name= null; this.value= null; } /** Creates a new HtmlComponent with the given id */ public HtmlComponent(int id) { this.id= id; this.id_string= HtmlComponent.idToIdString(id); this.first_kid= null; this.last_kid= null; this.sib= null; this.arg= null; this.name= null; this.value= null; } /** Creates a new HtmlComponent with the given id_string */ public HtmlComponent(String id_string) { this.id= HtmlComponent.idStringToId(id_string); this.id_string= id_string; this.first_kid= null; this.last_kid= null; this.sib= null; this.arg= null; this.name= null; this.value= null; } /** Adds (another) child component to this component */ public void add(HtmlComponent new_kid) { if (null != new_kid.sib) { /* error */ new_kid.sib= null; } if (null == this.last_kid) { this.first_kid= new_kid; } else { this.last_kid.sib= new_kid; } this.last_kid= new_kid; } /** Adds (another) argument component to this component */ public void addArg(HtmlComponent new_arg) { if (null != new_arg.sib) { /* error */ } new_arg.sib= this.arg; this.arg= new_arg; } public String kidsToString() { String rv= new String(); HtmlComponent k= this.kid(); while (null != k) { rv= rv + k.toString(); k= k.sib(); } return rv; } public String argsToString() { String rv= null; HtmlComponent k= this.arg; while (null != k) { if (null == rv) { rv= k.toString(); } else { rv= k.toString() + " " + rv; } k= k.sib; } if (null == rv) { rv= new String(); } return rv; } /** returns value of name=value arg pair of this component */ public String getArgValue(String name) { HtmlComponent a= this.arg(); while (null != a) { if (a.ARG != a.id) { return new String(); } else if (a.name.equalsIgnoreCase(name)) { return a.value; } else { a= a.sib(); } } return new String(); /* none found */ } /** debugging interest only -- produce a string which captures the formating structure of the HtmlComponent */ public String toString() { switch (this.id) { case HtmlComponent.HTML: case HtmlComponent.HEAD: case HtmlComponent.TITLE: case HtmlComponent.BODY: case HtmlComponent.H1: case HtmlComponent.H2: case HtmlComponent.H3: case HtmlComponent.H4: case HtmlComponent.H5: case HtmlComponent.PRE: case HtmlComponent.TT: case HtmlComponent.STRONG: case HtmlComponent.CENTER: case HtmlComponent.B: case HtmlComponent.HR: case HtmlComponent.DL: case HtmlComponent.UL: case HtmlComponent.LI: case HtmlComponent.DD: case HtmlComponent.DT: return "[" + HtmlComponent.idToIdString(this.id) + ((null!=this.value)?(" " + this.value):(""))+ ((null!=this.kid())?(" "+this.kidsToString()):(""))+ "]"; case HtmlComponent.P: return "[P" + ((null!=this.kid())?(" "+this.kidsToString()):(""))+ "]"; case HtmlComponent.TEXT: return "[\"" + this.id_string + "\"]"; // hack! case HtmlComponent.ANCHOR: case HtmlComponent.AHREF: case HtmlComponent.ANAME: case HtmlComponent.IMG: return "[" + HtmlComponent.idToIdString(this.id) + ((null!=this.value)?(" " + this.value):(""))+ ((null!=this.arg())?(" ("+this.argsToString()+")"):(""))+ ((null!=this.kid())?(" "+this.kidsToString()):(""))+ "]"; case HtmlComponent.ARG: return "{" + this.name + "}={" + this.value + "}"; case HtmlComponent.OTHER: return "[OTHER" + ((null!=this.id_string)?(" \""+this.id_string+"\""):(""))+ ((null!=this.value)?(" " + this.value):(""))+ ((null!=this.arg())?(" ("+this.argsToString()+")"):(""))+ ((null!=this.kid())?(" "+this.kidsToString()):(""))+ "]"; default: return "[-error-]"; } } }