Exercise 2: A Void Element With Real Attributes — Possible Solution
====================================================================
THE TEST
------------------------------
tokenize("")
RESULT
------------------------------
[voidtag('input', {'type': 'text', 'value': '42'})]
token.kind == 'voidtag'
token.attrs == {'type': 'text', 'value': '42'}
WHY input NEEDS NO CLOSING TAG, ATTRIBUTES OR NOT
------------------------------
'input' is one of the fourteen names in VOID_ELEMENTS, checked
AFTER attribute parsing has already happened -- the tag name and the
attribute string are split apart from the raw tag content first
(everything up to the first whitespace is the name; everything after
is handed to parse_attrs), and only then does tokenize ask whether
that specific name belongs to the void set. Having real, meaningful
attributes on the tag has no bearing on that check at all -- the
void-vs-not decision is made purely by tag NAME, independent of
whatever attributes happen to be present.
This matters because it would be easy to assume, incorrectly, that
"self-closing" and "void" mean the same thing, or that an element
needs to look empty/attribute-free to qualify as void. Real HTML
void elements are usually the OPPOSITE of attribute-free -- ,
, and are essentially always written with several
attributes, since the attributes are the whole reason those elements
exist (a value, a source URL, a stylesheet href). The void
designation is a fixed property of the ELEMENT TYPE ITSELF, decided
once in the HTML specification, not something inferred from how a
particular tag happens to be written in the source.