Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions ghost/core/core/server/services/oembed/oembed-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,12 @@ class OEmbedService {

const pickFn = (sizes, pickDefault) => {
const appleTouchIcon = sizes.find(item => item.rel?.includes('apple') && item.sizes && item.size?.width >= 180);
// Bookmark cards render the icon inline in the post body, where the
// site's standard (often transparent) favicon matches surrounding
// chrome better than an Apple Touch icon's solid-background square.
// Other call sites (Recommendations Avatar via type='mention', plus
// the generic oembed fallback) scale the icon up into a larger
// tile, where Apple Touch is the better fit.
// Bookmark cards (including the oembed fallback, which resolves to a
// bookmark) render the icon inline in the post body, where the site's
// standard (often transparent) favicon matches surrounding chrome
// better than an Apple Touch icon's solid-background square. The
// Recommendations Avatar (type='mention') instead scales the icon up
// into a larger tile, where Apple Touch is the better fit.
if (type === 'bookmark') {
// metascraper-logo-favicon gathers anything matching link[rel*="icon"], which
// includes apple-touch-icon, mask-icon (Safari pinned-tab silhouette), and
Expand Down Expand Up @@ -588,7 +588,7 @@ class OEmbedService {

// fallback to bookmark when we can't get oembed
if (!data && !type) {
data = await this.fetchBookmarkData(url, body, type);
data = await this.fetchBookmarkData(url, body, 'bookmark');
}

// couldn't get anything, throw a validation error
Expand Down
24 changes: 24 additions & 0 deletions ghost/core/test/unit/server/services/oembed/oembed-service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,30 @@ describe('oembed-service', function () {
assert.equal(response.metadata.title, 'Example');
});

it('prefers the standard favicon over an apple-touch-icon in the bookmark fallback', async function () {
// With no oembed endpoint and no explicit type, fetchOembedDataFromUrl
// falls through to the bookmark fallback (!data && !type). That path
// resolves to a bookmark card, so it must pick the standard favicon,
// not the apple-touch-icon reserved for scaled-up call sites.
sinon.stub(oembedService, 'processImageFromUrl').callsFake(async imageUrl => imageUrl);

nock('https://www.example.com')
.get('/')
.query(true)
.reply(200, `<html><head>
<title>Example</title>
<link rel="apple-touch-icon" sizes="180x180" href="https://www.example.com/apple.png">
<link rel="icon" href="https://www.example.com/favicon.png">
</head></html>`);

const response = await oembedService.fetchOembedDataFromUrl('https://www.example.com');

assert.equal(response.type, 'bookmark');
assert.equal(response.metadata.icon, 'https://www.example.com/favicon.png');

sinon.restore();
});

it('converts YT live URLs to watch URLs', async function () {
nock('https://www.youtube.com')
.get('/oembed')
Expand Down
Loading