You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The empty language range :lang("") now has its Selectors 4 meaning — "the
element's language is not known" — where it was rejected as a malformed
range. It is the complement of :lang(*), so it translates to that range's
test negated: e:lang("") is e[not(ancestor-or-self::*[@lang][1][string-length(@lang) > 0])] under Mode::Html, and the same shape over @xml:lang under Mode::Generic and
over both attributes under Mode::Xhtml. An empty attribute counts as no
language, as it does for :lang(*): an element under lang="" matches :lang("") rather than inheriting the tag above it. XPath's own lang()
cannot express this, so Mode::Generic walks the language attribute
directly, as it already did for :lang(*).
Changed
A :lang() language range that no language tag could match — an empty
subtag (en-, --x) or a * glued to one rather than standing as a whole
subtag (en*, *en) — is now refused by the translator, which names it: the :lang() language range "en-" (an empty subtag, which a language range cannot have). These were rejected by the argument grammar before, as `lang` is not a supported pseudo-class or pseudo-element — a message
that named neither the range nor what was wrong with it. So they are now Error::Unsupported (with no offset) where they were Error::Parse (with a
caret on lang); the set of selectors that error is unchanged apart from :lang(""), which now translates. The grammar still decides what it alone
can: whether the tokens assemble into ranges at all, which is where :lang(), :lang(5), :lang(en fr) and a stray comma are still refused.
Every message payload echoed from the selector is bounded by one rule: a :lang() range is now sanitized and elided past 40 bytes, as a token or
pseudo-class name in a parse error already was. This is visible only in the :lang() errors above and in the existing "a wildcard outside the final
subtag" one, whose range came through raw however long it was.
Fixed
A :lang() range built from more than one token is no longer refused when
it follows another range in the list: :lang(en, *-CH) and :lang(en, de-*) now parse, as :lang(*-CH, en) and :lang(de-*, en)
already did. The argument grammar reads whitespace as a range terminator,
and the flag recording it was not cleared once the next range had started,
so the space after a comma went on separating the tokens of every range
after it — making the multi-token ranges (*-CH, which the tokenizer
splits into * and -CH) look like two ranges with no comma between them.
Whitespace inside a range is still an error: :lang(en, * -CH) and :lang(en fr) are refused as before.