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@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 */
getWhitelist()61   public static HtmlWhitelist getWhitelist() {
62     return HTML4.defaultWhitelist;
63   }
64 
65   /** Looks for a HTML4 element */
lookupElement(String name)66   public static HTML.Element lookupElement(String name) {
67     return elements.get(name.toLowerCase());
68   }
69 
70   /** Looks for a HTML4 attribute */
lookupAttribute(String name)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    */
getAllElements()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    */
getAllAttributes()87   public static Map<String, HTML.Attribute> getAllAttributes() {
88     return Collections.unmodifiableMap(attributes);
89   }
90 
91   /** Creates and adds a element to the map */
addElement(String tag, String flags)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 */
addElement(String tag, String flags, HTML.Element.Flow flow)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 */
addTableElement(String tag, String flags, HTML.Element.Flow flow)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 */
addElement(String tag, String flags, HTML.Element.Flow flow, int type)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 */
addAttribute(String attribute)128   private static HTML.Attribute addAttribute(String attribute) {
129     return addAttribute(attribute, HTML.Attribute.NO_TYPE);
130   }
131 
addAttribute(String attribute, int type)132   private static HTML.Attribute addAttribute(String attribute, int type) {
133     return addAttribute(attribute, type, null);
134   }
135 
addAttribute(String attribute, int type, String[] values)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 }