Authors should not specify a language attribute on a script element. If
the attribute is present, its value must be an ASCII case-insensitive match for the string
"JavaScript" and either the type attribute must be omitted or its value
must be an ASCII case-insensitive match for the string "text/javascript".
The attribute should be entirely omitted instead (with the value "JavaScript", it has
no effect), or replaced with use of the type attribute.

Authors should not specify the name attribute on a elements. If the
attribute is present, its value must not be the empty string and must neither be equal to the
value of any of the IDs in the element’s tree other than the element’s own ID if any, nor be equal to the value of any of the other name attributes on a elements in the element’s tree. If this attribute is present and the
element has an ID, then the attribute’s value must be equal to the element’s ID. In
earlier versions of the language, this attribute was intended as a way to specify possible targets
for fragments in URLs. The id attribute should be used instead.

Authors should not, but may despite requirements to the contrary elsewhere in this specification,
specify the maxlength and size attributes on input elements
whose type attributes are in the Number state. One
valid reason for using these attributes regardless is to help legacy user agents that do not
support input elements with type="number" to still render the text control with a
useful width.

11.1.1. Warnings for obsolete but conforming features

To ease the transition from HTML Transitional documents to the language defined in this specification, and to discourage certain features that are only allowed in very few circumstances,
conformance checkers must warn the user when the following features are used in a document. These
are generally old obsolete features that have no effect, and are allowed only to distinguish
between likely mistakes (regular conformance errors) and mere vestigial markup or unusual and
discouraged practices (these warnings).

The following features must be categorized as described above:

The presence of a border attribute on an img element if its value is the string
"0".

The presence of a size attribute on an input element whose type attribute is in the Number state.

Conformance checkers must distinguish between pages that have no conformance errors and have none
of these obsolete features, and pages that have no conformance errors but do have some of these
obsolete features.

For example, a validator could report some pages as "Valid HTML" and others as "Valid HTML with
warnings".

11.2. Non-conforming features

Elements in the following list are entirely obsolete, and must not be used by authors:

Either use iframe and CSS instead, or use server-side includes to generate
complete pages with the various invariant parts merged in.

hgroup

To mark up subheadings, consider putting the subheading into a p element after
the h1—h6 element containing the main heading, or putting the subheading
directly within the h1-h6 element containing the
main heading, but separated from the main heading by punctuation and/or within,
for example, a span class="subheading" element with differentiated styling.

Headings and subheadings, alternative titles, or taglines can be grouped using
the header or div elements.

Where the tt element would have been used for marking up keyboard input,
consider the kbd element; for variables, consider the var element;
for computer code, consider the code element; and for computer output, consider
the samp element.

Similarly, if the big element is being used to denote a heading, consider using
the h1 element; if it is being used for marking up important passages, consider
the strong element; and if it is being used for highlighting text for reference
purposes, consider the mark element.

Use text that begins in an unambiguous and terse manner, and include any more elaborate text
after that. The title attribute can also be useful in including more detailed
text, so that the cell’s contents can be made terse. If it’s a heading, use th (which has an abbr attribute).

A marquee element has a marquee scroll interval, which is obtained as follows:

If the element has a scrolldelay attribute,
and parsing its value using the rules for parsing non-negative integers does not return
an error, then let delay be the parsed value. Otherwise, let delay be

If the element does not have a truespeed attribute, and the delay value
is less than 60, then let delay be 60 instead.

A marquee element has a marquee scroll distance, which, if the
element has a scrollamount attribute, and
parsing its value using the rules for parsing non-negative integers does not return an
error, is the parsed value interpreted in CSS pixels, and otherwise is 6 CSS pixels.

A marquee element has a marquee loop count, which, if the element has a loop content attribute, and parsing its value
using the rules for parsing integers does not return an error or a number less than 1, is
the parsed value, and otherwise is -1.

The loop IDL attribute, on getting,
must return the element’s marquee loop count; and on setting, if the new value is different
than the element’s marquee loop count and either greater than zero or equal to -1, must set
the element’s loop content attribute (adding it if necessary) to the valid integer that represents the new value. (Other values are ignored.)

A marquee element also has a marquee current loop index, which is zero when the
element is created.

The rendering layer will occasionally increment the marquee current loop index, which
must cause the following steps to be run:

The name, scrolling, and src IDL attributes of the frame element must reflect the respective content attributes of the same name. For the purposes
of reflection, the frame element’s src content attribute is defined as containing a URL.

The frameBorder IDL attribute of the frame element must reflect the element’s frameborder content attribute.

The longDesc IDL attribute of the frame element must reflect the element’s longdesc content attribute, which
for the purposes of reflection is defined as containing a URL.

The noResize IDL attribute of the frame element must reflect the element’s noresize content attribute.

The contentDocument IDL attribute, on
getting, must return the content document.

The align IDL attribute of the h1—h6 elements must reflect the content attribute of the same name.

The profile IDL attribute on head elements (with the HTMLHeadElement interface) is intentionally omitted. Unless so required
by another applicable specification, implementations would
therefore not support this attribute. (It is mentioned here as it was defined in a previous
version of the DOM specifications.)

User agents may treat the scheme content attribute
on the meta element as an extension of the element’s name content attribute when
processing a meta element with a name attribute whose value is one that the user
agent recognizes as supporting the scheme attribute.

User agents are encouraged to ignore the scheme attribute and instead process the
value given to the metadata name as if it had been specified for each expected value of the scheme attribute.

For example, if the user agent acts on meta elements with name attributes having the value "eGMS.subject.keyword", and knows that the scheme attribute is used with this metadata name, then it could take the scheme attribute
into account, acting as if it was an extension of the name attribute. Thus the
following two meta elements could be treated as two elements giving values for two
different metadata names, one consisting of a combination of "eGMS.subject.keyword" and "LGCL",
and the other consisting of a combination of "eGMS.subject.keyword" and "ORLY":

The attributes of the Document object listed in the first column of the following table must reflect the content attribute on the body element with the name given in the
corresponding cell in the second column on the same row, if the body element is a body element (as opposed to a frameset element). When there is no body element or if it is a frameset element, the attributes must instead return the empty string on getting and do
nothing on setting.

The user agent must act as if the ToBoolean abstract operator in JavaScript converts the
object returned for all to the false value.

The user agent must act as if the Abstract Equality Comparison algorithm, when given the
object returned for all, returns true when compared to the undefined and null values. (Comparisons using the Strict Equality Comparison algorithm,
and Abstract Equality comparisons to other values such as strings or objects, are unaffected.)

The user agent must act such that the typeof operator in JavaScript returns the
string undefined when applied to the object returned for all.

These requirements are a willful violation of the JavaScript specification current at the
time of writing. The JavaScript specification requires that ToBoolean return true for all
objects to the true value, and does not have provisions for objects acting as if they were undefined for the purposes of certain operators. This violation is motivated by a
desire for compatibility with two classes of legacy content: one that uses the presence of document.all as a way to detect legacy user agents, and one that only supports
those legacy user agents and uses the document.all object without testing for
its presence first. [ECMA-262]

A PluginArray object represents none, some, or all of the plugins supported by the user agent, each of which is represented by a Plugin object. Each of these Plugin objects may be hidden plugins. A hidden plugin can’t
be enumerated, but can still be inspected by using its name.

The fewer plugins are represented by the PluginArray object, and of those, the more that are hidden, the more the user’s privacy will be protected. Each exposed plugin
increases the number of bits that can be derived for fingerprinting. Hiding a plugin helps, but
unless it is an extremely rare plugin, it is likely that a site attempting to derive the list of
plugins can still determine whether the plugin is supported or not by probing for it by name (the
names of popular plugins are widely known). Therefore not exposing a plugin at all is preferred.
Unfortunately, many legacy sites use this feature to determine, for example, which plugin to use
to play video. Not exposing any plugins at all might therefore not be entirely plausible.

The PluginArray objects created by a user agent must not be live. The
set of plugins represented by the objects must not change once an object is created, except when
it is updated by the refresh() method.

Each plugin represented by a PluginArray can support a number of MIME types. For each such plugin, the user agent must
pick one or more of these MIME types to be those that are explicitly supported.

The explicitly supportedMIME types of
a plugin are those that are exposed through the Plugin and MimeTypeArray interfaces. As with plugins themselves, any variation between users regarding what is exposed
allows sites to fingerprint users. User agents are therefore encouraged to expose the same MIME types for all users of a plugin, regardless of the
actual types supported... at least, within the constraints imposed by compatibility with legacy
content.

The length attribute must return the
number of non-hiddenplugins represented by the object.

The item(unsigned long index) method of a PluginArray object must return null if the argument is not one of the object’s supported property indices, and otherwise must return the result of running the
following steps, using the method’s argument as index:

Let list be the Plugin objects
representing the non-hiddenplugins represented by the PluginArray object.

Sort list alphabetically by the name of each Plugin.

Return the indexth entry in list.

It is important for privacy that the order of plugins not leak additional information,
e.g., the order in which plugins were installed.

The supported property names of a PluginArray object are the values
of the name attributes of all the Plugin objects represented by the PluginArray object. The
properties exposed in this way must be unenumerable.

The namedItem(DOMString name) method of a PluginArray object must return null if the argument is not one of the object’s supported property names, and otherwise must return the Plugin object, of those represented by the PluginArray object, that has a name equal to the method’s argument.

The refresh() method of the PluginArray object of a Navigator object, when invoked, must check to
see if any plugins have been installed or reconfigured since the user
agent created the PluginArray object. If so, and the method’s argument is true, then
the user agent must act as if the location.reload() method was called instead. Otherwise, the user agent must update the PluginArray object and MimeTypeArray object created for attributes of that Navigator object, and the Plugin and MimeType objects created
for those PluginArray and MimeTypeArray objects, using the same Plugin objects for cases where the name is the same, and the same MimeType objects for
cases where the type is the same, and creating new objects
for cases where there were no matching objects immediately prior to the refresh() call. Old Plugin and MimeType objects must continue to return the same values that they had prior to
the update, though naturally now the data is stale and may appear inconsistent (for example, an
old MimeType entry might list as its enabledPlugin a Plugin object that no longer lists that MimeType as a supported MimeType).

The MimeTypeArray objects created by a user agent must not be live.
The set of MIME types represented by the objects must not change once an object is created, except
when it is updated by the PluginArray object’s refresh() method.

The item(unsigned long index) method of a MimeTypeArray object must return null if the argument is not one of the object’s supported property indices, and otherwise must return the result of running the
following steps, using the method’s argument as index:

It is important for
privacy that the order of MIME types not leak additional information, e.g., the order in
which plugins were installed.

The supported property names of a MimeTypeArray object are the values
of the type attributes of all the MimeType objects represented by the MimeTypeArray object. The properties exposed in this way
must be unenumerable.

The namedItem(DOMString name) method of a MimeTypeArray object must return null if the argument is not one of the object’s supported property names, and otherwise must return the MimeType object
that has a type equal to the method’s argument.

A Plugin object represents a plugin. It has
several attributes to provide details about the plugin, and can be enumerated to obtain the list
of MIME types that it explicitly supports.

The Plugin objects created by a user agent must not be live. The set of MIME types represented by the objects, and the values of the
objects' attributes, must not change once an object is created, except when updated by the PluginArray object’s refresh() method.

The reported MIME types for a Plugin object are the MIME typesexplicitly supported by the corresponding plugin when this object was last created or updated by PluginArray.refresh(), whichever happened most recently.

The item(unsigned long index) method of a Plugin object must return null if the argument is not one of the
object’s supported property indices, and otherwise must return the result of running
the following steps, using the method’s argument as index:

The namedItem(DOMString name) method of
a Plugin object must return null if the argument is not one of the
object’s supported property names, and otherwise must return the MimeType object that has a type equal to the method’s argument.

The description and filename attributes must return user-agent-defined
(or, in all likelihood, plugin-defined) strings. In each case, the same string must
be returned each time, except that the strings returned may change when the PluginArray.refresh() method updates the object.

If the values returned by the description or filename attributes
vary between versions of a plugin, they can be used both as a fingerprinting vector
and, even more importantly, as a trivial way to determine what security vulnerabilities a plugin (and thus a browser) may have. It is thus highly recommended that the description attribute just return the same value as the name attribute, and that the filename attribute return the empty string.

The MimeType objects created by a user agent must not be live. The
values of the objects' attributes must not change once an object is created, except when updated
by the PluginArray object’s refresh() method.

The description and suffixes attributes must return
user-agent-defined (or, in all likelihood, plugin-defined) strings. In each case, the
same string must be returned each time, except that the strings returned may change when the PluginArray.refresh() method updates the object.

If the values returned by the description or suffixes attributes vary between versions of a plugin, they can be used both as a
fingerprinting vector and, even more importantly, as a trivial way to determine what
security vulnerabilities a plugin (and thus a browser) may have. It is thus highly
recommended that the description attribute just return the same value as the type attribute, and that the suffixes attribute return the
empty string.

Commas in the suffixes attribute are interpreted as separating
subsequent filename extensions, as in "htm,html".

The enabledPlugin attribute must
return the Plugin object that represents the plugin that explicitly supported the MIME type that this MimeType object represents when this object was last created or updated by PluginArray.refresh(), whichever happened most
recently.

The javaEnabled() attribute
must return true if the user agent supports a plugin that supports the MIME
type "application/x-java-vm"; otherwise it must return false.