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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
24d5606b26
commit
204fee73f5
@@ -12,6 +12,7 @@ Contao Inhaltselement zum Darstellen von PDFs als blätterbares Flipbook.
|
||||
mehrhundertseitigen PDFs beschränkt bleibt
|
||||
- Optionales Aufteilen von Doppelseiten in linke und rechte Einzelseite
|
||||
- Optionale Vor-/Zurück-Navigation, optionaler Blättersound
|
||||
- Optionaler Vollbildmodus, der die Seitengröße an die Bildschirmhöhe anpasst
|
||||
- Tastatursteuerung (Pfeiltasten) und Touch-Swipe
|
||||
- Responsive Breite mit beibehaltenem Seitenverhältnis
|
||||
- Frontend-Texte übersetzbar (DE/EN mitgeliefert)
|
||||
@@ -33,6 +34,7 @@ Felder:
|
||||
- `Startmodus` (zentriert oder als Doppelseite)
|
||||
- `Doppelseiten aufteilen` (optional)
|
||||
- `Navigation anzeigen` (optional)
|
||||
- `Vollbild-Schaltfläche anzeigen` (optional)
|
||||
- `Blättersound abspielen` (optional)
|
||||
|
||||
## Hinweise
|
||||
@@ -58,6 +60,16 @@ unter dem Flipbook einen Download-Link auf die Original-PDF ein — das ist die
|
||||
gleichwertige Alternative im Sinne von WCAG. Wird der Link per CSS ausgeblendet,
|
||||
entfällt diese Gleichwertigkeit.
|
||||
|
||||
### Vollbild
|
||||
|
||||
Die Schaltfläche wird erst eingeblendet, wenn der Browser die Fullscreen-API für
|
||||
normale Elemente anbietet. Safari auf dem iPhone gehört nicht dazu — dort bleibt
|
||||
sie verborgen, statt eine Funktion anzubieten, die nicht arbeiten kann.
|
||||
|
||||
Im Vollbild wird die Seitenhöhe an den Bildschirm angepasst und das Buch
|
||||
zentriert; ohne das wäre eine A4-Seite bei Bildschirmbreite deutlich höher als
|
||||
der Viewport. Die Seiten werden dabei in der neuen Größe neu gerendert.
|
||||
|
||||
### Geschützte Ordner
|
||||
|
||||
Contao liefert Dateien unter `files/` nur aus, wenn der Ordner öffentlich
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_content']['palettes']['blatterbares_pdf'] = '{type_legend},type,headline;{flipbook_legend},flipbookPdfSrc,flipbookInitialPages,flipbookStartMode,flipbookSplitSpreads,flipbookShowNavigation,flipbookPlaySound;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},cssID;{invisible_legend:hide},invisible,start,stop';
|
||||
$GLOBALS['TL_DCA']['tl_content']['palettes']['blatterbares_pdf'] = '{type_legend},type,headline;{flipbook_legend},flipbookPdfSrc,flipbookInitialPages,flipbookStartMode,flipbookSplitSpreads,flipbookShowNavigation,flipbookShowFullscreen,flipbookPlaySound;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},cssID;{invisible_legend:hide},invisible,start,stop';
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_content']['fields']['flipbookPdfSrc'] = [
|
||||
'label' => &$GLOBALS['TL_LANG']['tl_content']['flipbookPdfSrc'],
|
||||
@@ -48,6 +48,14 @@ $GLOBALS['TL_DCA']['tl_content']['fields']['flipbookShowNavigation'] = [
|
||||
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => '1'],
|
||||
];
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_content']['fields']['flipbookShowFullscreen'] = [
|
||||
'label' => &$GLOBALS['TL_LANG']['tl_content']['flipbookShowFullscreen'],
|
||||
'exclude' => true,
|
||||
'inputType' => 'checkbox',
|
||||
'eval' => ['tl_class' => 'w50 m12'],
|
||||
'sql' => ['type' => 'string', 'length' => 1, 'fixed' => true, 'default' => '1'],
|
||||
];
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_content']['fields']['flipbookPlaySound'] = [
|
||||
'label' => &$GLOBALS['TL_LANG']['tl_content']['flipbookPlaySound'],
|
||||
'exclude' => true,
|
||||
|
||||
@@ -17,3 +17,5 @@ $GLOBALS['TL_LANG']['MSC']['flipbookNavLabel'] = 'Flipbook-Navigation';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookPrev'] = 'Zurück';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookNext'] = 'Weiter';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookDownload'] = 'PDF herunterladen';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookFullscreenEnter'] = 'Vollbild';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookFullscreenExit'] = 'Vollbild beenden';
|
||||
|
||||
@@ -17,4 +17,5 @@ $GLOBALS['TL_LANG']['tl_content']['flipbookStartModeOptions'] = [
|
||||
];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookSplitSpreads'] = ['Doppelseiten aufteilen', 'Teilt breite PDF-Seiten ab Seite 2 automatisch in linke und rechte Einzelseite.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookShowNavigation'] = ['Navigation anzeigen', 'Zeigt Vor-/Zurück-Buttons unter dem Flipbook an.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookPlaySound'] = ['Blättersound abspielen', 'Spielt beim Blättern einen Sound ab.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookShowFullscreen'] = ['Vollbild-Schaltfläche anzeigen', 'Zeigt eine Schaltfläche, mit der das Flipbook bildschirmfüllend dargestellt wird.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookPlaySound'] =['Blättersound abspielen', 'Spielt beim Blättern einen Sound ab.'];
|
||||
|
||||
@@ -17,3 +17,5 @@ $GLOBALS['TL_LANG']['MSC']['flipbookNavLabel'] = 'Flipbook navigation';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookPrev'] = 'Previous';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookNext'] = 'Next';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookDownload'] = 'Download PDF';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookFullscreenEnter'] = 'Fullscreen';
|
||||
$GLOBALS['TL_LANG']['MSC']['flipbookFullscreenExit'] = 'Exit fullscreen';
|
||||
|
||||
@@ -17,4 +17,5 @@ $GLOBALS['TL_LANG']['tl_content']['flipbookStartModeOptions'] = [
|
||||
];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookSplitSpreads'] = ['Split double-page spreads', 'Automatically splits wide PDF pages from page 2 onwards into left and right single pages.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookShowNavigation'] = ['Show navigation', 'Displays previous/next buttons below the flipbook.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookPlaySound'] = ['Play page-turn sound', 'Plays a sound effect while turning pages.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookShowFullscreen'] = ['Show fullscreen button', 'Displays a button that expands the flipbook to fill the screen.'];
|
||||
$GLOBALS['TL_LANG']['tl_content']['flipbookPlaySound'] =['Play page-turn sound', 'Plays a sound effect while turning pages.'];
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
data-start-mode="{{ startMode|default('center')|e('html_attr') }}"
|
||||
data-split-spreads="{{ splitSpreads ? '1' : '0' }}"
|
||||
data-show-navigation="{{ showNavigation ? '1' : '0' }}"
|
||||
data-show-fullscreen="{{ showFullscreen ? '1' : '0' }}"
|
||||
data-play-turn-sound="{{ ((playTurnSound is defined) ? playTurnSound : true) ? '1' : '0' }}"
|
||||
data-i18n-loading="{{ 'MSC.flipbookLoading'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
data-i18n-error="{{ 'MSC.flipbookError'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
@@ -17,6 +18,8 @@
|
||||
data-i18n-rendering="{{ 'MSC.flipbookRendering'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
data-i18n-blank="{{ 'MSC.flipbookBlank'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
data-i18n-page-label="{{ 'MSC.flipbookPageLabel'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
data-i18n-fullscreen-enter="{{ 'MSC.flipbookFullscreenEnter'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
data-i18n-fullscreen-exit="{{ 'MSC.flipbookFullscreenExit'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
role="region"
|
||||
aria-label="{{ 'MSC.flipbookRegionLabel'|trans([], 'contao_default')|e('html_attr') }}"
|
||||
tabindex="0"
|
||||
@@ -27,10 +30,16 @@
|
||||
<div class="c-flipbook" data-flipbook-book="1"></div>
|
||||
</div>
|
||||
|
||||
{% if showNavigation %}
|
||||
{% if showNavigation or showFullscreen %}
|
||||
<div class="mod-pdf-flipbook__controls" data-flipbook-controls="1" role="group" aria-label="{{ 'MSC.flipbookNavLabel'|trans([], 'contao_default')|e('html_attr') }}" style="visibility:hidden;opacity:0">
|
||||
{% if showNavigation %}
|
||||
<button type="button" data-flipbook-prev="1">{{ 'MSC.flipbookPrev'|trans([], 'contao_default') }}</button>
|
||||
<button type="button" data-flipbook-next="1">{{ 'MSC.flipbookNext'|trans([], 'contao_default') }}</button>
|
||||
{% endif %}
|
||||
{% if showFullscreen %}
|
||||
{# Hidden until the module confirms the browser exposes the Fullscreen API. #}
|
||||
<button type="button" class="mod-pdf-flipbook__fullscreen" data-flipbook-fullscreen="1" aria-pressed="false" hidden>{{ 'MSC.flipbookFullscreenEnter'|trans([], 'contao_default') }}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -114,6 +114,34 @@
|
||||
color: #9f1f1f;
|
||||
}
|
||||
|
||||
/* Set by the module once the browser confirms the Fullscreen API is usable. */
|
||||
.mod-pdf-flipbook.is-fullscreen {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
padding: 1.5rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mod-pdf-flipbook.is-fullscreen .mod-pdf-flipbook__stage {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mod-pdf-flipbook.is-fullscreen .mod-pdf-flipbook__status {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* The equivalent alternative stays on the page itself; repeating it inside the
|
||||
viewer would only eat height the book can use. */
|
||||
.mod-pdf-flipbook.is-fullscreen .mod-pdf-flipbook__download {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Text in a canvas is invisible to assistive technology and cannot be selected
|
||||
or searched, so the original file stays reachable as an equivalent
|
||||
alternative. */
|
||||
|
||||
@@ -34,6 +34,8 @@ const DEFAULT_TEXTS = {
|
||||
rendering: 'Seite {page} wird gerendert ...',
|
||||
blank: 'Leere Seite',
|
||||
pageLabel: 'Seite {page} von {total}',
|
||||
fullscreenEnter: 'Vollbild',
|
||||
fullscreenExit: 'Vollbild beenden',
|
||||
};
|
||||
|
||||
let dependenciesPromise;
|
||||
@@ -78,6 +80,7 @@ class PdfFlipbookModule {
|
||||
: 4;
|
||||
this.splitSpreads = root.dataset.splitSpreads === '1';
|
||||
this.showNavigation = root.dataset.showNavigation === '1';
|
||||
this.showFullscreen = root.dataset.showFullscreen === '1';
|
||||
this.playTurnSoundEnabled = root.dataset.playTurnSound !== '0';
|
||||
this.startMode = (root.dataset.startMode === 'spread' || root.dataset.startMode === 'cover')
|
||||
? 'spread'
|
||||
@@ -89,6 +92,8 @@ class PdfFlipbookModule {
|
||||
rendering: root.dataset.i18nRendering || DEFAULT_TEXTS.rendering,
|
||||
blank: root.dataset.i18nBlank || DEFAULT_TEXTS.blank,
|
||||
pageLabel: root.dataset.i18nPageLabel || DEFAULT_TEXTS.pageLabel,
|
||||
fullscreenEnter: root.dataset.i18nFullscreenEnter || DEFAULT_TEXTS.fullscreenEnter,
|
||||
fullscreenExit: root.dataset.i18nFullscreenExit || DEFAULT_TEXTS.fullscreenExit,
|
||||
};
|
||||
this.loader = root.querySelector('[data-flipbook-loader="1"]');
|
||||
this.stage = root.querySelector('[data-flipbook-stage="1"]');
|
||||
@@ -96,6 +101,7 @@ class PdfFlipbookModule {
|
||||
this.controlsElement = root.querySelector('[data-flipbook-controls="1"]');
|
||||
this.nextButton = this.showNavigation ? root.querySelector('[data-flipbook-next="1"]') : null;
|
||||
this.prevButton = this.showNavigation ? root.querySelector('[data-flipbook-prev="1"]') : null;
|
||||
this.fullscreenButton = this.showFullscreen ? root.querySelector('[data-flipbook-fullscreen="1"]') : null;
|
||||
|
||||
this.pdf = null;
|
||||
this.flipbook = null;
|
||||
@@ -153,6 +159,7 @@ class PdfFlipbookModule {
|
||||
this.bindKeyboard();
|
||||
this.bindTouchSwipe();
|
||||
this.bindResize();
|
||||
this.setupFullscreen();
|
||||
this.queuePages(this.getLazyCandidates());
|
||||
await this.showReadyState();
|
||||
this.setStatus('');
|
||||
@@ -372,10 +379,34 @@ class PdfFlipbookModule {
|
||||
}
|
||||
|
||||
updateLayout() {
|
||||
const stageWidth = Math.max(this.stage.clientWidth || 0, 282);
|
||||
const fullscreen = this.isFullscreen();
|
||||
// In fullscreen the width is measured on the parent, not on the stage:
|
||||
// the height fit below writes a max-width onto the stage, and measuring
|
||||
// the element we just constrained would oscillate.
|
||||
const availableWidth = fullscreen
|
||||
? this.getContentWidth(this.stage.parentElement)
|
||||
: (this.stage.clientWidth || 0);
|
||||
const stageWidth = Math.max(availableWidth, 282);
|
||||
|
||||
this.pageWidth = Math.max(Math.floor((stageWidth - this.pageGap) / 2), 140);
|
||||
this.pageHeight = Math.max(Math.floor(this.pageWidth * this.aspectRatio), 180);
|
||||
|
||||
if (fullscreen) {
|
||||
// A page in A4 proportions at screen width would run well past the
|
||||
// bottom of the viewport, so fit to height and centre the narrower
|
||||
// book instead.
|
||||
const heightLimit = this.getFullscreenHeightLimit();
|
||||
|
||||
if (this.pageHeight > heightLimit) {
|
||||
this.pageHeight = Math.max(Math.floor(heightLimit), 180);
|
||||
this.pageWidth = Math.max(Math.floor(this.pageHeight / this.aspectRatio), 140);
|
||||
}
|
||||
|
||||
this.stage.style.maxWidth = `${this.pageWidth * 2 + this.pageGap}px`;
|
||||
} else if (this.stage.style.maxWidth) {
|
||||
this.stage.style.maxWidth = '';
|
||||
}
|
||||
|
||||
this.stage.style.height = `${this.pageHeight}px`;
|
||||
this.bookElement.style.height = `${this.pageHeight}px`;
|
||||
|
||||
@@ -556,7 +587,22 @@ class PdfFlipbookModule {
|
||||
bindResize() {
|
||||
const onResize = () => {
|
||||
window.clearTimeout(this.resizeTimer);
|
||||
this.resizeTimer = window.setTimeout(() => {
|
||||
this.resizeTimer = window.setTimeout(() => this.relayout(), 120);
|
||||
};
|
||||
|
||||
if ('ResizeObserver' in window) {
|
||||
this.resizeObserver = new ResizeObserver(onResize);
|
||||
this.resizeObserver.observe(this.stage);
|
||||
} else {
|
||||
window.addEventListener('resize', onResize, { passive: true, signal: this.abortController.signal });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recomputes the page box and, if it actually moved, re-renders everything
|
||||
* for the new size. Shared by the resize observer and the fullscreen toggle.
|
||||
*/
|
||||
relayout() {
|
||||
if (!this.pdf || this.destroyed) {
|
||||
return;
|
||||
}
|
||||
@@ -569,8 +615,8 @@ class PdfFlipbookModule {
|
||||
return;
|
||||
}
|
||||
|
||||
// Invalidate everything rendered for the old page size, including
|
||||
// a render that may still be in flight.
|
||||
// Invalidate everything rendered for the old page size, including a
|
||||
// render that may still be in flight.
|
||||
this.renderGeneration += 1;
|
||||
this.cancelActiveRender();
|
||||
|
||||
@@ -584,15 +630,98 @@ class PdfFlipbookModule {
|
||||
});
|
||||
|
||||
this.queuePages(rerender, true);
|
||||
}, 120);
|
||||
};
|
||||
|
||||
if ('ResizeObserver' in window) {
|
||||
this.resizeObserver = new ResizeObserver(onResize);
|
||||
this.resizeObserver.observe(this.stage);
|
||||
} else {
|
||||
window.addEventListener('resize', onResize, { passive: true, signal: this.abortController.signal });
|
||||
}
|
||||
|
||||
getContentWidth(element) {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const styles = window.getComputedStyle(element);
|
||||
|
||||
return element.clientWidth
|
||||
- parseFloat(styles.paddingLeft || '0')
|
||||
- parseFloat(styles.paddingRight || '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Height the book may occupy in fullscreen: the viewport minus the element's
|
||||
* own padding and every sibling of the stage (status line, controls, the
|
||||
* download link), plus a little slack for the margins those carry.
|
||||
*/
|
||||
getFullscreenHeightLimit() {
|
||||
const styles = window.getComputedStyle(this.root);
|
||||
let reserved = parseFloat(styles.paddingTop || '0') + parseFloat(styles.paddingBottom || '0');
|
||||
|
||||
Array.from(this.root.children).forEach((child) => {
|
||||
if (child !== this.stage) {
|
||||
reserved += child.offsetHeight;
|
||||
}
|
||||
});
|
||||
|
||||
return Math.max(window.innerHeight - reserved - 32, 180);
|
||||
}
|
||||
|
||||
isFullscreenSupported() {
|
||||
return !!(this.root.requestFullscreen || this.root.webkitRequestFullscreen);
|
||||
}
|
||||
|
||||
isFullscreen() {
|
||||
const current = document.fullscreenElement || document.webkitFullscreenElement || null;
|
||||
|
||||
return current === this.root;
|
||||
}
|
||||
|
||||
setupFullscreen() {
|
||||
// iOS Safari exposes the API for video only, so the button stays hidden
|
||||
// there rather than offering something that cannot work.
|
||||
if (!this.fullscreenButton || !this.isFullscreenSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { signal } = this.abortController;
|
||||
|
||||
this.fullscreenButton.hidden = false;
|
||||
this.fullscreenButton.addEventListener('click', () => this.toggleFullscreen(), { signal });
|
||||
|
||||
['fullscreenchange', 'webkitfullscreenchange'].forEach((eventName) => {
|
||||
document.addEventListener(eventName, () => this.onFullscreenChange(), { signal });
|
||||
});
|
||||
}
|
||||
|
||||
async toggleFullscreen() {
|
||||
try {
|
||||
if (this.isFullscreen()) {
|
||||
await (document.exitFullscreen?.() ?? document.webkitExitFullscreen?.());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await (this.root.requestFullscreen?.() ?? this.root.webkitRequestFullscreen?.());
|
||||
} catch (error) {
|
||||
console.error('[flipbook] Vollbild nicht möglich:', error);
|
||||
}
|
||||
}
|
||||
|
||||
onFullscreenChange() {
|
||||
if (this.destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const active = this.isFullscreen();
|
||||
|
||||
this.root.classList.toggle('is-fullscreen', active);
|
||||
|
||||
if (this.fullscreenButton) {
|
||||
this.fullscreenButton.textContent = active ? this.texts.fullscreenExit : this.texts.fullscreenEnter;
|
||||
this.fullscreenButton.setAttribute('aria-pressed', active ? 'true' : 'false');
|
||||
}
|
||||
|
||||
if (!active) {
|
||||
this.stage.style.maxWidth = '';
|
||||
}
|
||||
|
||||
this.relayout();
|
||||
}
|
||||
|
||||
cancelActiveRender() {
|
||||
@@ -868,6 +997,13 @@ class PdfFlipbookModule {
|
||||
return;
|
||||
}
|
||||
|
||||
// Leaving the element in fullscreen would strand the browser on a node
|
||||
// that is about to be torn down.
|
||||
if (this.isFullscreen()) {
|
||||
(document.exitFullscreen?.() ?? document.webkitExitFullscreen?.())?.catch?.(() => {
|
||||
});
|
||||
}
|
||||
|
||||
this.destroyed = true;
|
||||
this.renderGeneration += 1;
|
||||
this.cancelActiveRender();
|
||||
|
||||
@@ -20,7 +20,7 @@ class BlatterbaresPdfController extends AbstractContentElementController
|
||||
/**
|
||||
* Bumped when the shipped assets change, so browsers do not keep a stale copy.
|
||||
*/
|
||||
private const ASSET_VERSION = '2.0.0';
|
||||
private const ASSET_VERSION = '2.1.0';
|
||||
|
||||
public function __construct(
|
||||
#[Autowire('%kernel.project_dir%')]
|
||||
@@ -35,6 +35,7 @@ class BlatterbaresPdfController extends AbstractContentElementController
|
||||
|
||||
$template->set('pdfUrl', $this->resolvePdfUrl($model));
|
||||
$template->set('showNavigation', '1' === (string) ($model->flipbookShowNavigation ?? '1'));
|
||||
$template->set('showFullscreen', '1' === (string) ($model->flipbookShowFullscreen ?? '1'));
|
||||
$template->set('playTurnSound', '1' === (string) ($model->flipbookPlaySound ?? '1'));
|
||||
$template->set('splitSpreads', '1' === (string) ($model->flipbookSplitSpreads ?? '0'));
|
||||
$template->set('initialRenderPages', $this->normalizeInitialRenderPages((string) ($model->flipbookInitialPages ?? '4')));
|
||||
|
||||
Reference in New Issue
Block a user