Skip to content

Commit 7dc31bd

Browse files
fix(cli): score apple-touch-icon-precomposed at the 180px default (#3607)
declaredSize() matched the rel token "apple-touch-icon" exactly, so the legacy "apple-touch-icon-precomposed" spelling (one token, not two) fell through to 0 instead of the 180px Apple default, even though the selector already collects it. Same page, one spelling apart, opposite winner inside tier 1 — it never drops a candidate and never beats the .ico tier. Switch to a startsWith check on the token. Exact-token matching stays for mask-icon, where a longer rel really would be a different asset.
1 parent da09428 commit 7dc31bd

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

‎packages/cli/src/capture/faviconRanker.test.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,24 @@ describe("rankIconCandidates", () => {
108108
expect(hrefs([{ rel: "icon", href: "" }, ...NOTION])).toHaveLength(2);
109109
});
110110

111+
it("scores apple-touch-icon-precomposed at the same 180px default as apple-touch-icon", () => {
112+
// Precomposed is one token longer, not a different rel: it must win against a small
113+
// sized png the same way a plain apple-touch-icon would.
114+
const precomposed: IconCandidate[] = [
115+
{
116+
rel: "apple-touch-icon-precomposed",
117+
href: "https://x.test/apple-touch-icon-precomposed.png",
118+
sizes: null,
119+
type: null,
120+
},
121+
{ rel: "icon", href: "https://x.test/favicon-32.png", sizes: "32x32", type: "image/png" },
122+
];
123+
expect(hrefs(precomposed)).toEqual([
124+
"https://x.test/apple-touch-icon-precomposed.png",
125+
"https://x.test/favicon-32.png",
126+
]);
127+
});
128+
111129
it("keeps DOM order between candidates of equal rank", () => {
112130
const same: IconCandidate[] = [
113131
{ rel: "icon", href: "https://x.test/a.png", sizes: "32x32" },

‎packages/cli/src/capture/faviconRanker.ts‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ function isIco(c: IconCandidate): boolean {
6868
function declaredSize(c: IconCandidate): number {
6969
const parsed = parseSizes(c.sizes);
7070
if (parsed > 0) return parsed;
71-
return c.rel.toLowerCase().split(/\s+/).includes("apple-touch-icon") ? APPLE_TOUCH_DEFAULT_PX : 0;
71+
// `startsWith`, not an exact-token match: `apple-touch-icon-precomposed` is the same
72+
// 180px default, one spelling later. Exact match is right for `mask-icon` (isMaskIcon),
73+
// where a longer rel really would be a different asset.
74+
return c.rel
75+
.toLowerCase()
76+
.split(/\s+/)
77+
.some((t) => t.startsWith("apple-touch-icon"))
78+
? APPLE_TOUCH_DEFAULT_PX
79+
: 0;
7280
}
7381

7482
function tierOf(c: IconCandidate): number {

0 commit comments

Comments
 (0)