Skip to content

Fix book icon when branding has an image but cover has none (BL-16780) - #8256

Draft
hatton wants to merge 3 commits into
Version6.4from
BL-16780-book-icon
Draft

Fix book icon when branding has an image but cover has none (BL-16780)#8256
hatton wants to merge 3 commits into
Version6.4from
BL-16780-book-icon

Conversation

@hatton

@hatton hatton commented Aug 28, 2026

Copy link
Copy Markdown
Member

Problem

A branded book whose cover picture is still the placeholder gets the wrong book icon, or no icon at all. Bloom picks the branding logo as the book's cover image. With the ABC brandings that logo is an SVG, which PalasoImage cannot load, so the thumbnail fails completely. Example book: ABC-BARMM-007297-2656.

Cause

When the designated cover image is a placeholder, GetCoverImagePathAndElt looks for a fallback. That search accepted any img anywhere on the front cover. A cover also carries images that belong to the branding and to the license, and those are not pictures of the book.

Fix

The search is now one ordered list of candidates:

  1. Whatever the book marks as its cover.
  2. Otherwise, an image container or an image inside one.
  3. The placeholder only if nothing real turns up.

Restricting step 2 to image containers is what fixes the bug: the branding logo, the license image, and the QR code of the "Made with Bloom" badge never sit in a container.

The mark in step 1 is read from the img, from the image container, or from an image inside a marked container. Only the img carries it on this branch; marking the container came in on Version6.5, which is downstream, so accepting all three shapes lets this survive the merge forward. A marked container has no image URL of its own, so without the third shape the search would fall through to an earlier container and take the wrong picture.

Four tests cover the rules: the reported branding case, a loose real image on the cover, the container-level mark, and the pre-existing behaviour that a designated placeholder yields to a real picture.

Ref: https://issues.bloomlibrary.org/youtrack/issue/BL-16780

Devin review


This change is Reviewable

When a branded book's cover picture was still the placeholder, the search for a
fallback cover image accepted any img on the cover. It therefore chose the
branding logo, and for the ABC brandings that logo is an SVG, which PalasoImage
cannot load, so the book had no thumbnail at all.

The search now considers only a picture inside an image container, and rejects
any element carrying the branding, licenseImage, or QR code class. Both rules
are needed: the image container is the main guard, but a branding pack supplies
its own markup, so it may wrap its logo in a container.

The branding, license, and QR code test is now the shared helper
IsBrandingOrLicenseImage, used by both the cover-image search and HasImages().

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR narrows fallback cover-image selection so branding, license, and QR-code images are not mistaken for a book’s cover.

  • Extracts a shared helper for identifying branding and license images.
  • Restricts fallback cover candidates to image-container content while preserving designated cover-image behavior.
  • Adds tests for branding images both outside and inside image containers.

Important Files Changed

Filename Overview
src/BloomExe/Book/Book.cs Refines cover-image fallback selection and reuses a shared branding/license exclusion helper; no actionable defect was established.
src/BloomTests/Book/BookTests.cs Adds focused regression coverage for branding images outside and inside image containers.

Reviews (1): Last reviewed commit: "Fix the book icon taking the branding lo..." | Re-trigger Greptile

@hatton

hatton commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin on 2026-08-28 20:34 UTC up to commit b0579a0305511aecdec01fd5f723245007dc7e1a.

Devin found no bugs and nothing to investigate. It raised one informational item, which we agree with and are not acting on: restricting the fallback search to images inside an image container means a bare img sitting directly on the cover, with no data-book="coverImage", is no longer a candidate. That narrowing is the point of the fix — such an image is branding, a license badge, or decoration, never a picture of the book. A genuine cover picture in an old book is designated with data-book, and that path is untouched.

Greptile also reviewed this commit and raised nothing. CodeRabbit's auto-review is turned off for this repo (.coderabbit.yml).

Comment thread src/BloomExe/Book/Book.cs Outdated
if (candidate == designatedCoverImage)
continue;

// The image container is the main guard, but a branding pack supplies its own

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nah, don't be pessimistic. remove this guard.

Replaces the two-stage search with the rule stated plainly: take whatever the
book marks as its cover, failing that an image out of an image container, and
fall back to the placeholder only when nothing real turns up.

This drops the IsBrandingOrLicenseImage helper and leaves
NonTrivialImageFileExists exactly as it was. Restricting the search to image
containers already keeps the branding logo, the license image, and the QR code
out, because none of them sits in a container, so the class test was redundant
here and its only other caller had it inline already.

The mark is read from the img, from the image container, or from an image inside
a marked container. Only the img carries it on this branch; marking the container
came in on Version6.5, which is downstream, so accepting all three shapes lets
this survive the merge forward. A marked container has no image URL of its own,
so without the third shape the search would fall through to an earlier container
and take the wrong picture.

The candidate order is built with Concat rather than one XPath union, because a
union returns document order and would lose the preference for the marked image.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@hatton

hatton commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin on 2026-08-28 21:02 UTC up to commit 595860c3e94df4360fc80d0e4f6ff5acdc90c2f0.

No bugs and nothing to investigate. Two informational items, neither of which we are acting on:

  1. Devin noticed the PR description still described a branding-class check that the simplified code no longer has. It read the description as it stood at the moment of the push; the description was rewritten immediately afterwards and now matches the code. Far more useful, Devin went and read all 73 branding.json files under src/content/branding to check the risk the removed check covered: every one of them supplies its cover logo as a loose img, never inside an image container. We confirmed that independently. So the image-container rule is sufficient for every branding that exists today, and the class check really was redundant.

  2. A bare img sitting directly on the cover, with no data-book="coverImage" and no image container, is no longer a fallback candidate. That is the intended narrowing: such an image is branding, a license badge, or decoration. Devin reached the same conclusion.

…780)

The cover image search had no test for two of its rules. The first is the
ordinary case: the book marks its own cover picture, that picture is real,
and the mark must win even though a decoration sits earlier on the page.
That ordering is why the marked candidates are searched before the image
containers rather than in one pass over the document. The second is the
obsolete image representation, where the picture is a background image on
the image container itself with no img inside, which is why the container is
a candidate in its own right.

Both tests fail if the code that they cover is removed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant