A row of glyphs told a sighted reader nothing a screen reader was not already
being told. The npm mark, the package cube, an emoji someone pasted in for a chat
room — the name was in aria-label, where a mouse and a pair of eyes never reach
it.
Added
-
site.iconLinksand the GitHub button carry a tooltip, shown on hover and
on focus by
<tooltip-elemental>,
dismissed with Escape. The words are thetitleyou already write: the element
takes the attribute over so the browser's own tooltip cannot double up, and
writes those same words back asaria-label, which is where they were before.
Nothing to configure and no new key inpoops.json.A touch screen has no hover, and the element ignores pointer events coming from
one rather than half-handling them, so a tap opens a link instead of a bubble.
Nothing is lost: the name is on the link the whole time, which is what a screen
reader reads either way. With scripting off the browser draws the native tooltip
from thetitlethe element never came to claim.New DOM in the topbar. Each icon link is now
tooltip-elemental > a.icon-btn + span, and the glyph inside the link is
wrapped in<span aria-hidden="true">—iconmay be an emoji or a pasted
<svg>, and text the name computation can read would otherwise leave a link
called "💬" described as "Discord". That wrapper isdisplay: flex, so it is
the size of the glyph rather than a line box with the glyph on its baseline —
inline, it lands the icon a few pixels above the middle of its button. A site
styling.topbar-actions > .icon-btnshould drop the>;.icon-btnitself is
unchanged.New custom properties.
--tooltip-elemental-surface,
--tooltip-elemental-colorand--tooltip-elemental-border-colorare
re-pointed at--fgand--bg; the element's own default isCanvasTexton
Canvas, which follows the operating system rather than the switch in the bar.
The bubble is also lifted toz-index: 30, over the drawer it can be opened
inside.
Fixed
-
A quote in a page's
descriptionno longer truncates the description.
Poops renders withautoescapeoff, so the hand-written
content="{{ page.description or page.excerpt or site.description }}"shipped
front matter verbatim — and one"in a sentence closed the attribute, leaving
the page described by the words before it. Both layouts now use Poops'
descriptionfilter, which reads the same chain and escapes what it emits:{{ page | description(site) }}
-
Every other value written into an attribute is escaped. Same cause, same
silence, and none of it needed a filter — both engines shipescape.lang,
data-theme,robots, the edit-linkhref, the brand and nav linkhrefs and
titles, and the footer's package links all go through it now, as does the
<title>element, where a<opens a tag rather than ending a value. The
favicon'ssite.brandMarkgetsurlencodeinstead: it sits inside adata:
URI, which wants URI encoding, not entities.Site-owned front matter and config, so this was a footgun rather than a
vulnerability — unless a site takes docs pages by pull request, where front
matter is somebody else's input.
Changed
poops >=2.5.0is now the peer range, up from>=2.0.0. Thedescription
filter arrived in 2.5.0, and an older Poops raises an unknown-filter error
rather than skipping it quietly.
Full Changelog: v4.1.0...v4.2.0