Home | History | Annotate | Download | only in parser
      1 /**
      2  * Copyright (c) 2004, Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.android.mail.common.html.parser;
     18 
     19 import com.google.common.collect.Maps;
     20 
     21 import java.util.Collections;
     22 import java.util.HashMap;
     23 import java.util.HashSet;
     24 import java.util.Map;
     25 import java.util.Set;
     26 
     27 /**
     28  * HTML4 contains HTML 4.0 definitions and specifications
     29  * See http://www.w3.org/TR/html401/
     30  * See http://www.w3.org/TR/html401/index/elements.html
     31  * See http://www.w3.org/TR/html401/index/attributes.html
     32  *
     33  * @author jlim (at) google.com (Jing Yee Lim)
     34  */
     35 public final class HTML4 {
     36 
     37   /** Map of all elements */
     38   private static final HashMap<String,HTML.Element> elements = Maps.newHashMap();
     39 
     40   /** Map of all attributes */
     41   private static final HashMap<String,HTML.Attribute> attributes = Maps.newHashMap();
     42 
     43   /** Default Whitelist */
     44   private static final HtmlWhitelist defaultWhitelist = new HtmlWhitelist() {
     45     /**
     46      * @see com.google.common.html.parser.HtmlWhitelist#lookupElement(String)
     47      */
     48     public HTML.Element lookupElement(String name) {
     49       return HTML4.lookupElement(name);
     50     }
     51 
     52     /**
     53      * @see com.google.common.html.parser.HtmlWhitelist#lookupAttribute(String)
     54      */
     55     public HTML.Attribute lookupAttribute(String name) {
     56       return HTML4.lookupAttribute(name);
     57     }
     58   };
     59 
     60   /** Gets the default Whitelist */
     61   public static HtmlWhitelist getWhitelist() {
     62     return HTML4.defaultWhitelist;
     63   }
     64 
     65   /** Looks for a HTML4 element */
     66   public static HTML.Element lookupElement(String name) {
     67     return elements.get(name.toLowerCase());
     68   }
     69 
     70   /** Looks for a HTML4 attribute */
     71   public static HTML.Attribute lookupAttribute(String name) {
     72     return attributes.get(name.toLowerCase());
     73   }
     74 
     75   /**
     76    * @return Unmodifiable Map of all valid HTML4 elements.  Key is lowercase
     77    * element name.
     78    */
     79   public static Map<String, HTML.Element> getAllElements() {
     80     return Collections.unmodifiableMap(elements);
     81   }
     82 
     83   /**
     84    * @return Unmodifiable Map of all valid HTML4 attributes.  Key is lowercase
     85    * attribute name.
     86    */
     87   public static Map<String, HTML.Attribute> getAllAttributes() {
     88     return Collections.unmodifiableMap(attributes);
     89   }
     90 
     91   /** Creates and adds a element to the map */
     92   private static HTML.Element addElement(String tag, String flags) {
     93     return addElement(tag, flags, HTML.Element.Flow.NONE);
     94   }
     95 
     96   /** Creates and adds a element to the map */
     97   private static HTML.Element addElement(String tag, String flags, HTML.Element.Flow flow) {
     98     return addElement(tag, flags, flow, HTML.Element.NO_TYPE);
     99   }
    100 
    101   /** Creates and adds a element to the map */
    102   private static HTML.Element addTableElement(String tag, String flags, HTML.Element.Flow flow) {
    103     return addElement(tag, flags, flow, HTML.Element.TABLE_TYPE);
    104   }
    105 
    106   /** Creates and adds a element to the map */
    107   private static HTML.Element addElement(String tag, String flags, HTML.Element.Flow flow,
    108       int type) {
    109     tag = tag.toLowerCase();
    110 
    111     boolean empty = false;
    112     boolean optionalEndTag = false;
    113     boolean breaksFlow = false;
    114     for (int i = 0; i < flags.length(); i++) {
    115       switch (flags.charAt(i)) {
    116         case 'E': empty = true; break;
    117         case 'O': optionalEndTag = true; break;
    118         case 'B': breaksFlow = true; break;
    119         default: throw new Error("Unknown element flag");
    120       }
    121     }
    122     HTML.Element element = new HTML.Element(tag, type, empty, optionalEndTag, breaksFlow, flow);
    123     elements.put(tag, element);
    124     return element;
    125   }
    126 
    127   /** Creates and add an attribute to the map */
    128   private static HTML.Attribute addAttribute(String attribute) {
    129     return addAttribute(attribute, HTML.Attribute.NO_TYPE);
    130   }
    131 
    132   private static HTML.Attribute addAttribute(String attribute, int type) {
    133     return addAttribute(attribute, type, null);
    134   }
    135 
    136   private static HTML.Attribute addAttribute(String attribute,
    137                                              int type,
    138                                              String[] values) {
    139     attribute = attribute.toLowerCase();
    140     Set<String> valueSet = null;
    141     if (values != null) {
    142       valueSet = new HashSet<String>();
    143       for (String x : values) {
    144         valueSet.add(x.toLowerCase());
    145       }
    146       valueSet = Collections.unmodifiableSet(valueSet);
    147     }
    148     HTML.Attribute attr = new HTML.Attribute(attribute, type, valueSet);
    149     attributes.put(attribute, attr);
    150     return attr;
    151   }
    152 
    153   /**
    154    * All HTML4 elements.
    155    *
    156    * Block vs inline flow:
    157    * http://www.w3.org/TR/REC-html40/sgml/dtd.html#block
    158    * http://www.w3.org/TR/REC-html40/sgml/dtd.html#inline
    159    * Some deprecated elements aren't listed there so we make an educated guess:
    160    * - CENTER is equivalent to DIV align=center, so we make it BLOCK.
    161    * - S, STRIKE and FONT are clearly inline like U, I, etc.
    162    * - MENU and DIR are like OL and UL, so we make them block.
    163    *
    164    * Optional end tag and empty:
    165    * http://www.w3.org/TR/REC-html40/index/elements.html
    166    */
    167   public static final HTML.Element
    168     A_ELEMENT          = addElement("A", "", HTML.Element.Flow.INLINE),
    169     ABBR_ELEMENT       = addElement("ABBR", "", HTML.Element.Flow.INLINE),
    170     ACRONYM_ELEMENT    = addElement("ACRONYM", "", HTML.Element.Flow.INLINE),
    171     ADDRESS_ELEMENT    = addElement("ADDRESS", "", HTML.Element.Flow.BLOCK),
    172     APPLET_ELEMENT     = addElement("APPLET", ""),
    173     AREA_ELEMENT       = addElement("AREA", "E"),
    174     B_ELEMENT          = addElement("B", "", HTML.Element.Flow.INLINE),
    175     BASE_ELEMENT       = addElement("BASE", "E"),
    176     BASEFONT_ELEMENT   = addElement("BASEFONT", "E"),
    177     BDO_ELEMENT        = addElement("BDO", "", HTML.Element.Flow.INLINE),
    178     BIG_ELEMENT        = addElement("BIG", "", HTML.Element.Flow.INLINE),
    179     BLOCKQUOTE_ELEMENT = addElement("BLOCKQUOTE", "B", HTML.Element.Flow.BLOCK),
    180     BODY_ELEMENT       = addElement("BODY", "O"),
    181     BR_ELEMENT         = addElement("BR", "EB", HTML.Element.Flow.INLINE),
    182     BUTTON_ELEMENT     = addElement("BUTTON", "", HTML.Element.Flow.INLINE),
    183     CAPTION_ELEMENT    = addTableElement("CAPTION", "", HTML.Element.Flow.NONE),
    184     CENTER_ELEMENT     = addElement("CENTER", "B", HTML.Element.Flow.BLOCK),
    185     CITE_ELEMENT       = addElement("CITE", "", HTML.Element.Flow.INLINE),
    186     CODE_ELEMENT       = addElement("CODE", "", HTML.Element.Flow.INLINE),
    187     COL_ELEMENT        = addTableElement("COL", "E", HTML.Element.Flow.NONE),
    188     COLGROUP_ELEMENT   = addTableElement("COLGROUP", "O", HTML.Element.Flow.NONE),
    189     DD_ELEMENT         = addElement("DD", "OB"),
    190     DEL_ELEMENT        = addElement("DEL", ""),
    191     DFN_ELEMENT        = addElement("DFN", "", HTML.Element.Flow.INLINE),
    192     DIR_ELEMENT        = addElement("DIR", "B", HTML.Element.Flow.BLOCK),
    193     DIV_ELEMENT        = addElement("DIV", "B", HTML.Element.Flow.BLOCK),
    194     DL_ELEMENT         = addElement("DL", "B", HTML.Element.Flow.BLOCK),
    195     DT_ELEMENT         = addElement("DT", "OB"),
    196     EM_ELEMENT         = addElement("EM", "", HTML.Element.Flow.INLINE),
    197     FIELDSET_ELEMENT   = addElement("FIELDSET", "", HTML.Element.Flow.BLOCK),
    198     FONT_ELEMENT       = addElement("FONT", "", HTML.Element.Flow.INLINE),
    199     FORM_ELEMENT       = addElement("FORM", "B", HTML.Element.Flow.BLOCK),
    200     FRAME_ELEMENT      = addElement("FRAME", "E"),
    201     FRAMESET_ELEMENT   = addElement("FRAMESET", ""),
    202     H1_ELEMENT         = addElement("H1", "B", HTML.Element.Flow.BLOCK),
    203     H2_ELEMENT         = addElement("H2", "B", HTML.Element.Flow.BLOCK),
    204     H3_ELEMENT         = addElement("H3", "B", HTML.Element.Flow.BLOCK),
    205     H4_ELEMENT         = addElement("H4", "B", HTML.Element.Flow.BLOCK),
    206     H5_ELEMENT         = addElement("H5", "B", HTML.Element.Flow.BLOCK),
    207     H6_ELEMENT         = addElement("H6", "B", HTML.Element.Flow.BLOCK),
    208     HEAD_ELEMENT       = addElement("HEAD", "OB"),
    209     HR_ELEMENT         = addElement("HR", "EB", HTML.Element.Flow.BLOCK),
    210     HTML_ELEMENT       = addElement("HTML", "OB"),
    211     I_ELEMENT          = addElement("I", "", HTML.Element.Flow.INLINE),
    212     IFRAME_ELEMENT     = addElement("IFRAME", ""),
    213     IMG_ELEMENT        = addElement("IMG", "E", HTML.Element.Flow.INLINE),
    214     INPUT_ELEMENT      = addElement("INPUT", "E", HTML.Element.Flow.INLINE),
    215     INS_ELEMENT        = addElement("INS", ""),
    216     ISINDEX_ELEMENT    = addElement("ISINDEX", "EB"),
    217     KBD_ELEMENT        = addElement("KBD", "", HTML.Element.Flow.INLINE),
    218     LABEL_ELEMENT      = addElement("LABEL", "", HTML.Element.Flow.INLINE),
    219     LEGEND_ELEMENT     = addElement("LEGEND", ""),
    220     LI_ELEMENT         = addElement("LI", "OB"),
    221     LINK_ELEMENT       = addElement("LINK", "E"),
    222     MAP_ELEMENT        = addElement("MAP", "", HTML.Element.Flow.INLINE),
    223     MENU_ELEMENT       = addElement("MENU", "B", HTML.Element.Flow.BLOCK),
    224     META_ELEMENT       = addElement("META", "E"),
    225     NOFRAMES_ELEMENT   = addElement("NOFRAMES", "B"),
    226     NOSCRIPT_ELEMENT   = addElement("NOSCRIPT", "", HTML.Element.Flow.BLOCK),
    227     OBJECT_ELEMENT     = addElement("OBJECT", "", HTML.Element.Flow.INLINE),
    228     OL_ELEMENT         = addElement("OL", "B", HTML.Element.Flow.BLOCK),
    229     OPTGROUP_ELEMENT   = addElement("OPTGROUP", ""),
    230     OPTION_ELEMENT     = addElement("OPTION", "O"),
    231     P_ELEMENT          = addElement("P", "OB", HTML.Element.Flow.BLOCK),
    232     PARAM_ELEMENT      = addElement("PARAM", "E"),
    233     PRE_ELEMENT        = addElement("PRE", "B", HTML.Element.Flow.BLOCK),
    234     Q_ELEMENT          = addElement("Q", "", HTML.Element.Flow.INLINE),
    235     S_ELEMENT          = addElement("S", "", HTML.Element.Flow.INLINE),
    236     SAMP_ELEMENT       = addElement("SAMP", "", HTML.Element.Flow.INLINE),
    237     SCRIPT_ELEMENT     = addElement("SCRIPT", "", HTML.Element.Flow.INLINE),
    238     SELECT_ELEMENT     = addElement("SELECT", "", HTML.Element.Flow.INLINE),
    239     SMALL_ELEMENT      = addElement("SMALL", "", HTML.Element.Flow.INLINE),
    240     SPAN_ELEMENT       = addElement("SPAN", "", HTML.Element.Flow.INLINE),
    241     STRIKE_ELEMENT     = addElement("STRIKE", "", HTML.Element.Flow.INLINE),
    242     STRONG_ELEMENT     = addElement("STRONG", "", HTML.Element.Flow.INLINE),
    243     STYLE_ELEMENT      = addElement("STYLE", ""),
    244     SUB_ELEMENT        = addElement("SUB", "", HTML.Element.Flow.INLINE),
    245     SUP_ELEMENT        = addElement("SUP", "", HTML.Element.Flow.INLINE),
    246     TABLE_ELEMENT      = addTableElement("TABLE", "B", HTML.Element.Flow.BLOCK),
    247     TBODY_ELEMENT      = addTableElement("TBODY", "O", HTML.Element.Flow.NONE),
    248     TD_ELEMENT         = addTableElement("TD", "OB", HTML.Element.Flow.NONE),
    249     TEXTAREA_ELEMENT   = addElement("TEXTAREA", "", HTML.Element.Flow.INLINE),
    250     TFOOT_ELEMENT      = addTableElement("TFOOT", "O", HTML.Element.Flow.NONE),
    251     TH_ELEMENT         = addTableElement("TH", "OB", HTML.Element.Flow.NONE),
    252     THEAD_ELEMENT      = addTableElement("THEAD", "O", HTML.Element.Flow.NONE),
    253     TITLE_ELEMENT      = addElement("TITLE", "B"),
    254     TR_ELEMENT         = addTableElement("TR", "OB", HTML.Element.Flow.NONE),
    255     TT_ELEMENT         = addElement("TT", "", HTML.Element.Flow.INLINE),
    256     U_ELEMENT          = addElement("U", "", HTML.Element.Flow.INLINE),
    257     UL_ELEMENT         = addElement("UL", "B", HTML.Element.Flow.BLOCK),
    258     VAR_ELEMENT        = addElement("VAR", "", HTML.Element.Flow.INLINE);
    259 
    260   /**
    261    * All the HTML4 attributes
    262    */
    263   public static final HTML.Attribute
    264     ABBR_ATTRIBUTE           = addAttribute("ABBR"),
    265     ACCEPT_ATTRIBUTE         = addAttribute("ACCEPT"),
    266     ACCEPT_CHARSET_ATTRIBUTE = addAttribute("ACCEPT-CHARSET"),
    267     ACCESSKEY_ATTRIBUTE      = addAttribute("ACCESSKEY"),
    268     ACTION_ATTRIBUTE         = addAttribute("ACTION", HTML.Attribute.URI_TYPE),
    269     ALIGN_ATTRIBUTE          = addAttribute("ALIGN",
    270         HTML.Attribute.ENUM_TYPE,
    271         new String[] {"left", "center", "right", "justify",
    272             "char", "top", "bottom", "middle"}),
    273     ALINK_ATTRIBUTE          = addAttribute("ALINK"),
    274     ALT_ATTRIBUTE            = addAttribute("ALT"),
    275     ARCHIVE_ATTRIBUTE        = addAttribute("ARCHIVE", HTML.Attribute.URI_TYPE),
    276     AXIS_ATTRIBUTE           = addAttribute("AXIS"),
    277     BACKGROUND_ATTRIBUTE     = addAttribute("BACKGROUND", HTML.Attribute.URI_TYPE),
    278     BGCOLOR_ATTRIBUTE        = addAttribute("BGCOLOR"),
    279     BORDER_ATTRIBUTE         = addAttribute("BORDER"),
    280     CELLPADDING_ATTRIBUTE    = addAttribute("CELLPADDING"),
    281     CELLSPACING_ATTRIBUTE    = addAttribute("CELLSPACING"),
    282     CHAR_ATTRIBUTE           = addAttribute("CHAR"),
    283     CHAROFF_ATTRIBUTE        = addAttribute("CHAROFF"),
    284     CHARSET_ATTRIBUTE        = addAttribute("CHARSET"),
    285     CHECKED_ATTRIBUTE        = addAttribute("CHECKED", HTML.Attribute.BOOLEAN_TYPE),
    286     CITE_ATTRIBUTE           = addAttribute("CITE", HTML.Attribute.URI_TYPE),
    287     CLASS_ATTRIBUTE          = addAttribute("CLASS"),
    288     CLASSID_ATTRIBUTE        = addAttribute("CLASSID", HTML.Attribute.URI_TYPE),
    289     CLEAR_ATTRIBUTE          = addAttribute("CLEAR",
    290         HTML.Attribute.ENUM_TYPE,
    291         new String[] {"left", "all", "right", "none"}),
    292     CODE_ATTRIBUTE           = addAttribute("CODE"),
    293     CODEBASE_ATTRIBUTE       = addAttribute("CODEBASE", HTML.Attribute.URI_TYPE),
    294     CODETYPE_ATTRIBUTE       = addAttribute("CODETYPE"),
    295     COLOR_ATTRIBUTE          = addAttribute("COLOR"),
    296     COLS_ATTRIBUTE           = addAttribute("COLS"),
    297     COLSPAN_ATTRIBUTE        = addAttribute("COLSPAN"),
    298     COMPACT_ATTRIBUTE        = addAttribute("COMPACT", HTML.Attribute.BOOLEAN_TYPE),
    299     CONTENT_ATTRIBUTE        = addAttribute("CONTENT"),
    300     COORDS_ATTRIBUTE         = addAttribute("COORDS"),
    301     DATA_ATTRIBUTE           = addAttribute("DATA", HTML.Attribute.URI_TYPE),
    302     DATETIME_ATTRIBUTE       = addAttribute("DATETIME"),
    303     DECLARE_ATTRIBUTE        = addAttribute("DECLARE", HTML.Attribute.BOOLEAN_TYPE),
    304     DEFER_ATTRIBUTE          = addAttribute("DEFER", HTML.Attribute.BOOLEAN_TYPE),
    305     DIR_ATTRIBUTE            = addAttribute("DIR",
    306         HTML.Attribute.ENUM_TYPE,
    307         new String[] {"ltr", "rtl"}),
    308     DISABLED_ATTRIBUTE       = addAttribute("DISABLED", HTML.Attribute.BOOLEAN_TYPE),
    309     ENCTYPE_ATTRIBUTE        = addAttribute("ENCTYPE"),
    310     FACE_ATTRIBUTE           = addAttribute("FACE"),
    311     FOR_ATTRIBUTE            = addAttribute("FOR"),
    312     FRAME_ATTRIBUTE          = addAttribute("FRAME"),
    313     FRAMEBORDER_ATTRIBUTE    = addAttribute("FRAMEBORDER",
    314         HTML.Attribute.ENUM_TYPE,
    315         new String[] {"1", "0"}),
    316     HEADERS_ATTRIBUTE        = addAttribute("HEADERS"),
    317     HEIGHT_ATTRIBUTE         = addAttribute("HEIGHT"),
    318     HREF_ATTRIBUTE           = addAttribute("HREF", HTML.Attribute.URI_TYPE),
    319     HREFLANG_ATTRIBUTE       = addAttribute("HREFLANG"),
    320     HSPACE_ATTRIBUTE         = addAttribute("HSPACE"),
    321     HTTP_EQUIV_ATTRIBUTE     = addAttribute("HTTP-EQUIV"),
    322     ID_ATTRIBUTE             = addAttribute("ID"),
    323     ISMAP_ATTRIBUTE          = addAttribute("ISMAP", HTML.Attribute.BOOLEAN_TYPE),
    324     LABEL_ATTRIBUTE          = addAttribute("LABEL"),
    325     LANG_ATTRIBUTE           = addAttribute("LANG"),
    326     LANGUAGE_ATTRIBUTE       = addAttribute("LANGUAGE"),
    327     LINK_ATTRIBUTE           = addAttribute("LINK"),
    328     LONGDESC_ATTRIBUTE       = addAttribute("LONGDESC", HTML.Attribute.URI_TYPE),
    329     MARGINHEIGHT_ATTRIBUTE   = addAttribute("MARGINHEIGHT"),
    330     MARGINWIDTH_ATTRIBUTE    = addAttribute("MARGINWIDTH"),
    331     MAXLENGTH_ATTRIBUTE      = addAttribute("MAXLENGTH"),
    332     MEDIA_ATTRIBUTE          = addAttribute("MEDIA"),
    333     METHOD_ATTRIBUTE         = addAttribute("METHOD",
    334         HTML.Attribute.ENUM_TYPE,
    335         new String[] {"get", "post"}),
    336     MULTIPLE_ATTRIBUTE       = addAttribute("MULTIPLE", HTML.Attribute.BOOLEAN_TYPE),
    337     NAME_ATTRIBUTE           = addAttribute("NAME"),
    338     NOHREF_ATTRIBUTE         = addAttribute("NOHREF", HTML.Attribute.BOOLEAN_TYPE),
    339     NORESIZE_ATTRIBUTE       = addAttribute("NORESIZE", HTML.Attribute.BOOLEAN_TYPE),
    340     NOSHADE_ATTRIBUTE        = addAttribute("NOSHADE", HTML.Attribute.BOOLEAN_TYPE),
    341     NOWRAP_ATTRIBUTE         = addAttribute("NOWRAP", HTML.Attribute.BOOLEAN_TYPE),
    342     OBJECT_ATTRIBUTE         = addAttribute("OBJECT"),
    343     ONBLUR_ATTRIBUTE         = addAttribute("ONBLUR", HTML.Attribute.SCRIPT_TYPE),
    344     ONCHANGE_ATTRIBUTE       = addAttribute("ONCHANGE", HTML.Attribute.SCRIPT_TYPE),
    345     ONCLICK_ATTRIBUTE        = addAttribute("ONCLICK", HTML.Attribute.SCRIPT_TYPE),
    346     ONDBLCLICK_ATTRIBUTE     = addAttribute("ONDBLCLICK", HTML.Attribute.SCRIPT_TYPE),
    347     ONFOCUS_ATTRIBUTE        = addAttribute("ONFOCUS", HTML.Attribute.SCRIPT_TYPE),
    348     ONKEYDOWN_ATTRIBUTE      = addAttribute("ONKEYDOWN", HTML.Attribute.SCRIPT_TYPE),
    349     ONKEYPRESS_ATTRIBUTE     = addAttribute("ONKEYPRESS", HTML.Attribute.SCRIPT_TYPE),
    350     ONKEYUP_ATTRIBUTE        = addAttribute("ONKEYUP", HTML.Attribute.SCRIPT_TYPE),
    351     ONLOAD_ATTRIBUTE         = addAttribute("ONLOAD", HTML.Attribute.SCRIPT_TYPE),
    352     ONMOUSEDOWN_ATTRIBUTE    = addAttribute("ONMOUSEDOWN", HTML.Attribute.SCRIPT_TYPE),
    353     ONMOUSEMOVE_ATTRIBUTE    = addAttribute("ONMOUSEMOVE", HTML.Attribute.SCRIPT_TYPE),
    354     ONMOUSEOUT_ATTRIBUTE     = addAttribute("ONMOUSEOUT", HTML.Attribute.SCRIPT_TYPE),
    355     ONMOUSEOVER_ATTRIBUTE    = addAttribute("ONMOUSEOVER", HTML.Attribute.SCRIPT_TYPE),
    356     ONMOUSEUP_ATTRIBUTE      = addAttribute("ONMOUSEUP", HTML.Attribute.SCRIPT_TYPE),
    357     ONRESET_ATTRIBUTE        = addAttribute("ONRESET", HTML.Attribute.SCRIPT_TYPE),
    358     ONSELECT_ATTRIBUTE       = addAttribute("ONSELECT", HTML.Attribute.SCRIPT_TYPE),
    359     ONSUBMIT_ATTRIBUTE       = addAttribute("ONSUBMIT", HTML.Attribute.SCRIPT_TYPE),
    360     ONUNLOAD_ATTRIBUTE       = addAttribute("ONUNLOAD", HTML.Attribute.SCRIPT_TYPE),
    361     PROFILE_ATTRIBUTE        = addAttribute("PROFILE", HTML.Attribute.URI_TYPE),
    362     PROMPT_ATTRIBUTE         = addAttribute("PROMPT"),
    363     READONLY_ATTRIBUTE       = addAttribute("READONLY", HTML.Attribute.BOOLEAN_TYPE),
    364     REL_ATTRIBUTE            = addAttribute("REL"),
    365     REV_ATTRIBUTE            = addAttribute("REV"),
    366     ROWS_ATTRIBUTE           = addAttribute("ROWS"),
    367     ROWSPAN_ATTRIBUTE        = addAttribute("ROWSPAN"),
    368     RULES_ATTRIBUTE          = addAttribute("RULES"),
    369     SCHEME_ATTRIBUTE         = addAttribute("SCHEME"),
    370     SCOPE_ATTRIBUTE          = addAttribute("SCOPE"),
    371     SCROLLING_ATTRIBUTE      = addAttribute("SCROLLING",
    372         HTML.Attribute.ENUM_TYPE,
    373         new String[] {"yes", "no", "auto"}),
    374     SELECTED_ATTRIBUTE       = addAttribute("SELECTED", HTML.Attribute.BOOLEAN_TYPE),
    375     SHAPE_ATTRIBUTE          = addAttribute("SHAPE"),
    376     SIZE_ATTRIBUTE           = addAttribute("SIZE"),
    377     SPAN_ATTRIBUTE           = addAttribute("SPAN"),
    378     SRC_ATTRIBUTE            = addAttribute("SRC", HTML.Attribute.URI_TYPE),
    379     STANDBY_ATTRIBUTE        = addAttribute("STANDBY"),
    380     START_ATTRIBUTE          = addAttribute("START"),
    381     STYLE_ATTRIBUTE          = addAttribute("STYLE"),
    382     SUMMARY_ATTRIBUTE        = addAttribute("SUMMARY"),
    383     TABINDEX_ATTRIBUTE       = addAttribute("TABINDEX"),
    384     TARGET_ATTRIBUTE         = addAttribute("TARGET"),
    385     TEXT_ATTRIBUTE           = addAttribute("TEXT"),
    386     TITLE_ATTRIBUTE          = addAttribute("TITLE"),
    387     TYPE_ATTRIBUTE           = addAttribute("TYPE"),
    388     USEMAP_ATTRIBUTE         = addAttribute("USEMAP", HTML.Attribute.URI_TYPE),
    389     VALIGN_ATTRIBUTE         = addAttribute("VALIGN",
    390         HTML.Attribute.ENUM_TYPE,
    391         new String[] {"top", "middle", "bottom", "baseline"}),
    392     VALUE_ATTRIBUTE          = addAttribute("VALUE"),
    393     VALUETYPE_ATTRIBUTE      = addAttribute("VALUETYPE",
    394         HTML.Attribute.ENUM_TYPE,
    395         new String[] {"data", "ref", "object"}),
    396     VERSION_ATTRIBUTE        = addAttribute("VERSION"),
    397     VLINK_ATTRIBUTE          = addAttribute("VLINK"),
    398     VSPACE_ATTRIBUTE         = addAttribute("VSPACE"),
    399     WIDTH_ATTRIBUTE          = addAttribute("WIDTH");
    400 }