fix(cli): pick the highest-quality favicon and keep its transparent background (#3606)
* fix(cli): capture the best declared favicon, not the first one
Pages routinely declare a legacy 16px .ico first and the good asset (an SVG,
or a 180x180 apple-touch PNG) after it. The capture's page evaluate kept only
{rel, href} and the download loop took whichever candidate fetched first, so
the .ico won on every such page. The dropped sizes/type attributes are the only
evidence of quality: page.html on disk does not keep the <link> tags and only
the winner's bytes are fetched, so the choice was unrecoverable downstream.
Keep sizes and type, and rank candidates before downloading: SVG first, then
the largest declared size (an unsized apple-touch-icon counts as 180), then
.ico. The loop still falls through to the next candidate when one fails to
download, so the ranking changes which icon wins, never whether one lands.
Ranking is a pure function over the declared attributes, unit-tested against
the link shapes three sites actually publish.
* fix(cli): rank a pinned-tab mask-icon below real favicons
`link[rel*="icon"]` also matches `rel="mask-icon"`, Safari's pinned-tab
asset: a single-colour silhouette drawn in a browser-chosen tint, not the
site mark. It is served as an SVG, so ranking by format alone promoted the
outline above the page's actual colour favicon.
Give mask-icon its own lowest tier rather than dropping it, so a page that
declares nothing else still lands an icon instead of none. M
Miguel Ángel committed
5a5e841c5dd2818b712d41a8989aa9256c3800f8
Parent: ae7e530
Committed by GitHub <noreply@github.com>
on 9/3/2026, 3:53:45 AM