src/share/classes/com/sun/tools/doclint/HtmlTag.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 2413
fe033d997ddf
parent 0
959103a6100f
child 3446
e468915bad3a
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.doclint;
aoqi@0 27
aoqi@0 28 import java.util.Set;
aoqi@0 29 import java.util.Collections;
aoqi@0 30 import java.util.EnumMap;
aoqi@0 31 import java.util.EnumSet;
aoqi@0 32 import java.util.HashMap;
aoqi@0 33 import java.util.Locale;
aoqi@0 34 import java.util.Map;
aoqi@0 35
aoqi@0 36 import javax.lang.model.element.Name;
aoqi@0 37
aoqi@0 38 import static com.sun.tools.doclint.HtmlTag.Attr.*;
aoqi@0 39 import com.sun.tools.javac.util.StringUtils;
aoqi@0 40
aoqi@0 41 /**
aoqi@0 42 * Enum representing HTML tags.
aoqi@0 43 *
aoqi@0 44 * The intent of this class is to embody the semantics of W3C HTML 4.01
aoqi@0 45 * to the extent supported/used by javadoc.
aoqi@0 46 * In time, we may wish to transition javadoc and doclint to using HTML 5.
aoqi@0 47 *
aoqi@0 48 * This is derivative of com.sun.tools.doclets.formats.html.markup.HtmlTag.
aoqi@0 49 * Eventually, these two should be merged back together, and possibly made
aoqi@0 50 * public.
aoqi@0 51 *
aoqi@0 52 * @see <a href="http://www.w3.org/TR/REC-html40/">HTML 4.01 Specification</a>
aoqi@0 53 * @see <a href="http://www.w3.org/TR/html5/">HTML 5 Specification</a>
aoqi@0 54 * @author Bhavesh Patel
aoqi@0 55 * @author Jonathan Gibbons (revised)
aoqi@0 56 */
aoqi@0 57 public enum HtmlTag {
aoqi@0 58 A(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 59 attrs(AttrKind.OK, HREF, TARGET, NAME)),
aoqi@0 60
aoqi@0 61 B(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 62 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 63
aoqi@0 64 BIG(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 65 EnumSet.of(Flag.EXPECT_CONTENT)),
aoqi@0 66
aoqi@0 67 BLOCKQUOTE(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 68 EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
aoqi@0 69
aoqi@0 70 BODY(BlockType.OTHER, EndKind.REQUIRED),
aoqi@0 71
aoqi@0 72 BR(BlockType.INLINE, EndKind.NONE,
aoqi@0 73 attrs(AttrKind.USE_CSS, CLEAR)),
aoqi@0 74
aoqi@0 75 CAPTION(BlockType.TABLE_ITEM, EndKind.REQUIRED,
aoqi@0 76 EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
aoqi@0 77
aoqi@0 78 CENTER(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 79 EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
aoqi@0 80
aoqi@0 81 CITE(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 82 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 83
aoqi@0 84 CODE(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 85 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 86
aoqi@0 87 DD(BlockType.LIST_ITEM, EndKind.OPTIONAL,
aoqi@0 88 EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
aoqi@0 89
aoqi@0 90 DFN(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 91 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 92
aoqi@0 93 DIV(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 94 EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
aoqi@0 95
aoqi@0 96 DL(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 97 EnumSet.of(Flag.EXPECT_CONTENT),
aoqi@0 98 attrs(AttrKind.USE_CSS, COMPACT)) {
aoqi@0 99 @Override
aoqi@0 100 public boolean accepts(HtmlTag t) {
aoqi@0 101 return (t == DT) || (t == DD);
aoqi@0 102 }
aoqi@0 103 },
aoqi@0 104
aoqi@0 105 DT(BlockType.LIST_ITEM, EndKind.OPTIONAL,
aoqi@0 106 EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
aoqi@0 107
aoqi@0 108 EM(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 109 EnumSet.of(Flag.NO_NEST)),
aoqi@0 110
aoqi@0 111 FONT(BlockType.INLINE, EndKind.REQUIRED, // tag itself is deprecated
aoqi@0 112 EnumSet.of(Flag.EXPECT_CONTENT),
aoqi@0 113 attrs(AttrKind.USE_CSS, SIZE, COLOR, FACE)),
aoqi@0 114
aoqi@0 115 FRAME(BlockType.OTHER, EndKind.NONE),
aoqi@0 116
aoqi@0 117 FRAMESET(BlockType.OTHER, EndKind.REQUIRED),
aoqi@0 118
aoqi@0 119 H1(BlockType.BLOCK, EndKind.REQUIRED),
aoqi@0 120 H2(BlockType.BLOCK, EndKind.REQUIRED),
aoqi@0 121 H3(BlockType.BLOCK, EndKind.REQUIRED),
aoqi@0 122 H4(BlockType.BLOCK, EndKind.REQUIRED),
aoqi@0 123 H5(BlockType.BLOCK, EndKind.REQUIRED),
aoqi@0 124 H6(BlockType.BLOCK, EndKind.REQUIRED),
aoqi@0 125
aoqi@0 126 HEAD(BlockType.OTHER, EndKind.REQUIRED),
aoqi@0 127
aoqi@0 128 HR(BlockType.BLOCK, EndKind.NONE,
aoqi@0 129 attrs(AttrKind.OK, WIDTH)), // OK in 4.01; not allowed in 5
aoqi@0 130
aoqi@0 131 HTML(BlockType.OTHER, EndKind.REQUIRED),
aoqi@0 132
aoqi@0 133 I(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 134 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 135
aoqi@0 136 IMG(BlockType.INLINE, EndKind.NONE,
aoqi@0 137 attrs(AttrKind.OK, SRC, ALT, HEIGHT, WIDTH),
aoqi@0 138 attrs(AttrKind.OBSOLETE, NAME),
aoqi@0 139 attrs(AttrKind.USE_CSS, ALIGN, HSPACE, VSPACE, BORDER)),
aoqi@0 140
aoqi@0 141 LI(BlockType.LIST_ITEM, EndKind.OPTIONAL,
aoqi@0 142 EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE),
aoqi@0 143 attrs(AttrKind.OK, VALUE)),
aoqi@0 144
aoqi@0 145 LINK(BlockType.OTHER, EndKind.NONE),
aoqi@0 146
aoqi@0 147 MENU(BlockType.BLOCK, EndKind.REQUIRED) {
aoqi@0 148 @Override
aoqi@0 149 public boolean accepts(HtmlTag t) {
aoqi@0 150 return (t == LI);
aoqi@0 151 }
aoqi@0 152 },
aoqi@0 153
aoqi@0 154 META(BlockType.OTHER, EndKind.NONE),
aoqi@0 155
aoqi@0 156 NOFRAMES(BlockType.OTHER, EndKind.REQUIRED),
aoqi@0 157
aoqi@0 158 NOSCRIPT(BlockType.BLOCK, EndKind.REQUIRED),
aoqi@0 159
aoqi@0 160 OL(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 161 EnumSet.of(Flag.EXPECT_CONTENT),
aoqi@0 162 attrs(AttrKind.OK, START, TYPE)) {
aoqi@0 163 @Override
aoqi@0 164 public boolean accepts(HtmlTag t) {
aoqi@0 165 return (t == LI);
aoqi@0 166 }
aoqi@0 167 },
aoqi@0 168
aoqi@0 169 P(BlockType.BLOCK, EndKind.OPTIONAL,
aoqi@0 170 EnumSet.of(Flag.EXPECT_CONTENT),
aoqi@0 171 attrs(AttrKind.USE_CSS, ALIGN)),
aoqi@0 172
aoqi@0 173 PRE(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 174 EnumSet.of(Flag.EXPECT_CONTENT)) {
aoqi@0 175 @Override
aoqi@0 176 public boolean accepts(HtmlTag t) {
aoqi@0 177 switch (t) {
aoqi@0 178 case IMG: case BIG: case SMALL: case SUB: case SUP:
aoqi@0 179 return false;
aoqi@0 180 default:
aoqi@0 181 return (t.blockType == BlockType.INLINE);
aoqi@0 182 }
aoqi@0 183 }
aoqi@0 184 },
aoqi@0 185
aoqi@0 186 SCRIPT(BlockType.OTHER, EndKind.REQUIRED),
aoqi@0 187
aoqi@0 188 SMALL(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 189 EnumSet.of(Flag.EXPECT_CONTENT)),
aoqi@0 190
aoqi@0 191 SPAN(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 192 EnumSet.of(Flag.EXPECT_CONTENT)),
aoqi@0 193
aoqi@0 194 STRONG(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 195 EnumSet.of(Flag.EXPECT_CONTENT)),
aoqi@0 196
aoqi@0 197 SUB(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 198 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 199
aoqi@0 200 SUP(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 201 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 202
aoqi@0 203 TABLE(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 204 EnumSet.of(Flag.EXPECT_CONTENT),
aoqi@0 205 attrs(AttrKind.OK, SUMMARY, Attr.FRAME, RULES, BORDER,
aoqi@0 206 CELLPADDING, CELLSPACING, WIDTH), // width OK in 4.01; not allowed in 5
aoqi@0 207 attrs(AttrKind.USE_CSS, ALIGN, BGCOLOR)) {
aoqi@0 208 @Override
aoqi@0 209 public boolean accepts(HtmlTag t) {
aoqi@0 210 switch (t) {
aoqi@0 211 case CAPTION:
aoqi@0 212 case THEAD: case TBODY: case TFOOT:
aoqi@0 213 case TR: // HTML 3.2
aoqi@0 214 return true;
aoqi@0 215 default:
aoqi@0 216 return false;
aoqi@0 217 }
aoqi@0 218 }
aoqi@0 219 },
aoqi@0 220
aoqi@0 221 TBODY(BlockType.TABLE_ITEM, EndKind.REQUIRED,
aoqi@0 222 EnumSet.of(Flag.EXPECT_CONTENT),
aoqi@0 223 attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
aoqi@0 224 @Override
aoqi@0 225 public boolean accepts(HtmlTag t) {
aoqi@0 226 return (t == TR);
aoqi@0 227 }
aoqi@0 228 },
aoqi@0 229
aoqi@0 230 TD(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
aoqi@0 231 EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE),
aoqi@0 232 attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS,
aoqi@0 233 ALIGN, CHAR, CHAROFF, VALIGN),
aoqi@0 234 attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)),
aoqi@0 235
aoqi@0 236 TFOOT(BlockType.TABLE_ITEM, EndKind.REQUIRED,
aoqi@0 237 attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
aoqi@0 238 @Override
aoqi@0 239 public boolean accepts(HtmlTag t) {
aoqi@0 240 return (t == TR);
aoqi@0 241 }
aoqi@0 242 },
aoqi@0 243
aoqi@0 244 TH(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
aoqi@0 245 EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE),
aoqi@0 246 attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS,
aoqi@0 247 ALIGN, CHAR, CHAROFF, VALIGN),
aoqi@0 248 attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)),
aoqi@0 249
aoqi@0 250 THEAD(BlockType.TABLE_ITEM, EndKind.REQUIRED,
aoqi@0 251 attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
aoqi@0 252 @Override
aoqi@0 253 public boolean accepts(HtmlTag t) {
aoqi@0 254 return (t == TR);
aoqi@0 255 }
aoqi@0 256 },
aoqi@0 257
aoqi@0 258 TITLE(BlockType.OTHER, EndKind.REQUIRED),
aoqi@0 259
aoqi@0 260 TR(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
aoqi@0 261 attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN),
aoqi@0 262 attrs(AttrKind.USE_CSS, BGCOLOR)) {
aoqi@0 263 @Override
aoqi@0 264 public boolean accepts(HtmlTag t) {
aoqi@0 265 return (t == TH) || (t == TD);
aoqi@0 266 }
aoqi@0 267 },
aoqi@0 268
aoqi@0 269 TT(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 270 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 271
aoqi@0 272 U(BlockType.INLINE, EndKind.REQUIRED,
aoqi@0 273 EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
aoqi@0 274
aoqi@0 275 UL(BlockType.BLOCK, EndKind.REQUIRED,
aoqi@0 276 EnumSet.of(Flag.EXPECT_CONTENT),
aoqi@0 277 attrs(AttrKind.OK, COMPACT, TYPE)) { // OK in 4.01; not allowed in 5
aoqi@0 278 @Override
aoqi@0 279 public boolean accepts(HtmlTag t) {
aoqi@0 280 return (t == LI);
aoqi@0 281 }
aoqi@0 282 },
aoqi@0 283
aoqi@0 284 VAR(BlockType.INLINE, EndKind.REQUIRED);
aoqi@0 285
aoqi@0 286 /**
aoqi@0 287 * Enum representing the type of HTML element.
aoqi@0 288 */
aoqi@0 289 public static enum BlockType {
aoqi@0 290 BLOCK,
aoqi@0 291 INLINE,
aoqi@0 292 LIST_ITEM,
aoqi@0 293 TABLE_ITEM,
aoqi@0 294 OTHER;
aoqi@0 295 }
aoqi@0 296
aoqi@0 297 /**
aoqi@0 298 * Enum representing HTML end tag requirement.
aoqi@0 299 */
aoqi@0 300 public static enum EndKind {
aoqi@0 301 NONE,
aoqi@0 302 OPTIONAL,
aoqi@0 303 REQUIRED;
aoqi@0 304 }
aoqi@0 305
aoqi@0 306 public static enum Flag {
aoqi@0 307 ACCEPTS_BLOCK,
aoqi@0 308 ACCEPTS_INLINE,
aoqi@0 309 EXPECT_CONTENT,
aoqi@0 310 NO_NEST
aoqi@0 311 }
aoqi@0 312
aoqi@0 313 public static enum Attr {
aoqi@0 314 ABBR,
aoqi@0 315 ALIGN,
aoqi@0 316 ALT,
aoqi@0 317 AXIS,
aoqi@0 318 BGCOLOR,
aoqi@0 319 BORDER,
aoqi@0 320 CELLSPACING,
aoqi@0 321 CELLPADDING,
aoqi@0 322 CHAR,
aoqi@0 323 CHAROFF,
aoqi@0 324 CLEAR,
aoqi@0 325 CLASS,
aoqi@0 326 COLOR,
aoqi@0 327 COLSPAN,
aoqi@0 328 COMPACT,
aoqi@0 329 FACE,
aoqi@0 330 FRAME,
aoqi@0 331 HEADERS,
aoqi@0 332 HEIGHT,
aoqi@0 333 HREF,
aoqi@0 334 HSPACE,
aoqi@0 335 ID,
aoqi@0 336 NAME,
aoqi@0 337 NOWRAP,
aoqi@0 338 REVERSED,
aoqi@0 339 ROWSPAN,
aoqi@0 340 RULES,
aoqi@0 341 SCOPE,
aoqi@0 342 SIZE,
aoqi@0 343 SPACE,
aoqi@0 344 SRC,
aoqi@0 345 START,
aoqi@0 346 STYLE,
aoqi@0 347 SUMMARY,
aoqi@0 348 TARGET,
aoqi@0 349 TYPE,
aoqi@0 350 VALIGN,
aoqi@0 351 VALUE,
aoqi@0 352 VSPACE,
aoqi@0 353 WIDTH;
aoqi@0 354
aoqi@0 355 public String getText() {
aoqi@0 356 return StringUtils.toLowerCase(name());
aoqi@0 357 }
aoqi@0 358
aoqi@0 359 static final Map<String,Attr> index = new HashMap<String,Attr>();
aoqi@0 360 static {
aoqi@0 361 for (Attr t: values()) {
aoqi@0 362 index.put(t.getText(), t);
aoqi@0 363 }
aoqi@0 364 }
aoqi@0 365 }
aoqi@0 366
aoqi@0 367 public static enum AttrKind {
aoqi@0 368 INVALID,
aoqi@0 369 OBSOLETE,
aoqi@0 370 USE_CSS,
aoqi@0 371 OK
aoqi@0 372 }
aoqi@0 373
aoqi@0 374 // This class exists to avoid warnings from using parameterized vararg type
aoqi@0 375 // Map<Attr,AttrKind> in signature of HtmlTag constructor.
aoqi@0 376 private static class AttrMap extends EnumMap<Attr,AttrKind> {
aoqi@0 377 private static final long serialVersionUID = 0;
aoqi@0 378 AttrMap() {
aoqi@0 379 super(Attr.class);
aoqi@0 380 }
aoqi@0 381 }
aoqi@0 382
aoqi@0 383
aoqi@0 384 public final BlockType blockType;
aoqi@0 385 public final EndKind endKind;
aoqi@0 386 public final Set<Flag> flags;
aoqi@0 387 private final Map<Attr,AttrKind> attrs;
aoqi@0 388
aoqi@0 389 HtmlTag(BlockType blockType, EndKind endKind, AttrMap... attrMaps) {
aoqi@0 390 this(blockType, endKind, Collections.<Flag>emptySet(), attrMaps);
aoqi@0 391 }
aoqi@0 392
aoqi@0 393 HtmlTag(BlockType blockType, EndKind endKind, Set<Flag> flags, AttrMap... attrMaps) {
aoqi@0 394 this.blockType = blockType;
aoqi@0 395 this.endKind = endKind;
aoqi@0 396 this.flags = flags;
aoqi@0 397 this.attrs = new EnumMap<Attr,AttrKind>(Attr.class);
aoqi@0 398 for (Map<Attr,AttrKind> m: attrMaps)
aoqi@0 399 this.attrs.putAll(m);
aoqi@0 400 attrs.put(Attr.CLASS, AttrKind.OK);
aoqi@0 401 attrs.put(Attr.ID, AttrKind.OK);
aoqi@0 402 attrs.put(Attr.STYLE, AttrKind.OK);
aoqi@0 403 }
aoqi@0 404
aoqi@0 405 public boolean accepts(HtmlTag t) {
aoqi@0 406 if (flags.contains(Flag.ACCEPTS_BLOCK) && flags.contains(Flag.ACCEPTS_INLINE)) {
aoqi@0 407 return (t.blockType == BlockType.BLOCK) || (t.blockType == BlockType.INLINE);
aoqi@0 408 } else if (flags.contains(Flag.ACCEPTS_BLOCK)) {
aoqi@0 409 return (t.blockType == BlockType.BLOCK);
aoqi@0 410 } else if (flags.contains(Flag.ACCEPTS_INLINE)) {
aoqi@0 411 return (t.blockType == BlockType.INLINE);
aoqi@0 412 } else
aoqi@0 413 switch (blockType) {
aoqi@0 414 case BLOCK:
aoqi@0 415 case INLINE:
aoqi@0 416 return (t.blockType == BlockType.INLINE);
aoqi@0 417 case OTHER:
aoqi@0 418 // OTHER tags are invalid in doc comments, and will be
aoqi@0 419 // reported separately, so silently accept/ignore any content
aoqi@0 420 return true;
aoqi@0 421 default:
aoqi@0 422 // any combination which could otherwise arrive here
aoqi@0 423 // ought to have been handled in an overriding method
aoqi@0 424 throw new AssertionError(this + ":" + t);
aoqi@0 425 }
aoqi@0 426 }
aoqi@0 427
aoqi@0 428 public boolean acceptsText() {
aoqi@0 429 // generally, anywhere we can put text we can also put inline tag
aoqi@0 430 // so check if a typical inline tag is allowed
aoqi@0 431 return accepts(B);
aoqi@0 432 }
aoqi@0 433
aoqi@0 434 public String getText() {
aoqi@0 435 return StringUtils.toLowerCase(name());
aoqi@0 436 }
aoqi@0 437
aoqi@0 438 public Attr getAttr(Name attrName) {
aoqi@0 439 return Attr.index.get(StringUtils.toLowerCase(attrName.toString()));
aoqi@0 440 }
aoqi@0 441
aoqi@0 442 public AttrKind getAttrKind(Name attrName) {
aoqi@0 443 AttrKind k = attrs.get(getAttr(attrName)); // null-safe
aoqi@0 444 return (k == null) ? AttrKind.INVALID : k;
aoqi@0 445 }
aoqi@0 446
aoqi@0 447 private static AttrMap attrs(AttrKind k, Attr... attrs) {
aoqi@0 448 AttrMap map = new AttrMap();
aoqi@0 449 for (Attr a: attrs) map.put(a, k);
aoqi@0 450 return map;
aoqi@0 451 }
aoqi@0 452
aoqi@0 453 private static final Map<String,HtmlTag> index = new HashMap<String,HtmlTag>();
aoqi@0 454 static {
aoqi@0 455 for (HtmlTag t: values()) {
aoqi@0 456 index.put(t.getText(), t);
aoqi@0 457 }
aoqi@0 458 }
aoqi@0 459
aoqi@0 460 static HtmlTag get(Name tagName) {
aoqi@0 461 return index.get(StringUtils.toLowerCase(tagName.toString()));
aoqi@0 462 }
aoqi@0 463
aoqi@0 464 }

mercurial