6 Commits
Author SHA1 Message Date
Jürgen MummertandClaude Opus 5 204fee73f5 feat: optional fullscreen mode
New content element option "Vollbild-Schaltfläche anzeigen" (on by default).
The button only appears once the browser confirms it exposes the Fullscreen API
for ordinary elements -- iOS Safari offers it for video only, so there it stays
hidden rather than presenting a control that cannot work.

Fitting the book to the screen needed the layout to become height-aware. Page
size was derived from width alone, which at screen width puts an A4-proportioned
page well below the bottom of the viewport. In fullscreen the page now fits to
the available height and the narrower book is centred; pages re-render at the
new size through the existing generation-stamped path.

The height fit writes a max-width onto the stage, so in fullscreen the available
width is measured on the parent instead -- measuring the element we just
constrained would oscillate. Verified stable across repeated samples.

The resize handler body moved into relayout(), shared with the fullscreen
toggle. destroy() leaves fullscreen first so the browser is not left holding a
node that is about to go away.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 15:12:10 +02:00
Jürgen MummertandClaude Opus 5 0e7996df01 fix: bound memory, harden rendering, make assets path-independent
Memory: rendered page canvases were never released, so flipping through a
document accumulated one supersampled canvas per page for the lifetime of the
page. Measured on a 30-page PDF this reached 174 MB and stayed there; the figure
grows linearly with page count, which puts a mid-sized catalogue past what a
mobile browser will tolerate. Pages outside a window around the current spread
now have their canvas released (dimensions zeroed so the backing store goes
immediately) and their placeholder restored. Same document now plateaus at
64 MB regardless of reading position.

Supersampling was pinned at 2x even on 1x displays, which costs four times the
memory of a 1x canvas for no visible gain there. It now follows the device pixel
ratio between 1.5x and 2x.

Startup: buildPageDescriptors() walked the entire document calling getPage() on
every page, including when spread splitting was disabled -- the default. On long
PDFs that is hundreds of sequential PDF.js round trips before the first paint.
The walk now happens only when splitting is actually on.

Rendering races: a resize landing while a page was rasterising left that page
with a canvas sized for the previous layout, marked as rendered and therefore
never corrected. Renders now carry a generation stamp and are discarded if the
layout moved underneath them, and the in-flight task is cancelled rather than
left to finish work that is already void. Not reproduced from outside -- the
window is narrow -- but the sequence is plain in the code.

Deployment: asset URLs were absolute from the web root, so the bundle broke
whenever Contao ran in a subdirectory. They now derive from import.meta.url.
Verified under /kunde/shop/ with no failed requests.

Assets moved from the template into the controller via TL_HEAD, keyed so several
flipbooks on one page emit one copy each, in the head rather than after the
content.

Also:
- Front-end strings were hardcoded German despite the bundle shipping de/en.
  They now come from TL_LANG and reach the module as data attributes.
- Swallowed errors now reach the console; a failing PDF left no trace before.
- Canvas text is invisible to assistive technology: pages carry aria-labels and
  the source PDF is offered as an equivalent download. Honours reduced motion.
- No teardown existed; destroy() plus a MummertPdfFlipbook API for AJAX pages.
- Pages deviating from the document's dominant format were stretched. The
  layout ratio is now the median of a leading sample, with object-fit: contain.
- Aspect ratio, pointerdown stealing focus from buttons, single Audio element
  cutting itself off on fast flips.
- Vendored PDF.js cmaps and standard fonts: without them, PDFs using CID
  encodings or relying on the base-14 fonts render blank.
- Dropped pdf.min.mjs and pdf.worker.min.mjs -- byte-identical copies of the
  .js files that nothing referenced (1.7 MB).
- Third-party licence texts were referenced but never shipped. Added, including
  the separate Foxit and Liberation terms that come with the fonts. Recorded
  that flipbook-js publishes no LICENSE file upstream.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 21:39:32 +02:00
Jürgen Mummert a6c9aef952 feat: support PDF spread splitting and nav button states 2026-04-14 15:04:57 +02:00
Juergen 1564d96b01 fix: polish initial flipbook reveal and update third-party metadata 2026-04-13 22:18:45 +02:00
Juergen 781f050dfc feat: add optional page-turn sound toggle and refine flipbook UI 2026-04-13 22:00:39 +02:00
Juergen 9f9b1c9935 feat: refine flipbook start modes and UI behavior 2026-04-13 21:34:29 +02:00