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