Simplify handling of requestFullscreen errors in PDFPresentationMode

Since quite some time the `Element.requestFullscreen()` method has been returning a Promise, see https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#return_value
Hence we can utilize that to detect failures to enter fullscreen-mode, and remove our old `setTimeout`-based hacks that were used for this purpose.

According to the MDN compatibility data, see https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#browser_compatibility, all browsers that we support have implemented this functionality. (Note that after PR 14606, we no longer support PresentationMode in Safari.)
This commit is contained in:
Jonas Jenwald 2022-04-09 11:25:53 +02:00
parent 2b673a6941
commit 8d61b7c088

View File

@ -20,7 +20,6 @@ import {
SpreadMode, SpreadMode,
} from "./ui_utils.js"; } from "./ui_utils.js";
const DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms
const DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms const DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms
const ACTIVE_SELECTOR = "pdfPresentationMode"; const ACTIVE_SELECTOR = "pdfPresentationMode";
const CONTROLS_SELECTOR = "pdfPresentationModeControls"; const CONTROLS_SELECTOR = "pdfPresentationModeControls";
@ -42,6 +41,8 @@ const SWIPE_ANGLE_THRESHOLD = Math.PI / 6;
*/ */
class PDFPresentationMode { class PDFPresentationMode {
#args = null;
/** /**
* @param {PDFPresentationModeOptions} options * @param {PDFPresentationModeOptions} options
*/ */
@ -51,7 +52,6 @@ class PDFPresentationMode {
this.eventBus = eventBus; this.eventBus = eventBus;
this.active = false; this.active = false;
this.args = null;
this.contextMenuOpen = false; this.contextMenuOpen = false;
this.mouseScrollTimeStamp = 0; this.mouseScrollTimeStamp = 0;
this.mouseScrollDelta = 0; this.mouseScrollDelta = 0;
@ -60,9 +60,9 @@ class PDFPresentationMode {
/** /**
* Request the browser to enter fullscreen mode. * Request the browser to enter fullscreen mode.
* @returns {boolean} Indicating if the request was successful. * @returns {Promise<boolean>} Indicating if the request was successful.
*/ */
request() { async request() {
if ( if (
this.switchInProgress || this.switchInProgress ||
this.active || this.active ||
@ -75,22 +75,30 @@ class PDFPresentationMode {
this.#setSwitchInProgress(); this.#setSwitchInProgress();
this.#notifyStateChange(); this.#notifyStateChange();
this.container.requestFullscreen(); const promise = this.container.requestFullscreen();
this.args = { this.#args = {
pageNumber: this.pdfViewer.currentPageNumber, pageNumber: this.pdfViewer.currentPageNumber,
scaleValue: this.pdfViewer.currentScaleValue, scaleValue: this.pdfViewer.currentScaleValue,
scrollMode: this.pdfViewer.scrollMode, scrollMode: this.pdfViewer.scrollMode,
spreadMode: this.pdfViewer.spreadMode, spreadMode: this.pdfViewer.spreadMode,
}; };
try {
await promise;
return true; return true;
} catch (reason) {
this.#removeFullscreenChangeListeners();
this.#resetSwitchInProgress();
this.#notifyStateChange();
}
return false;
} }
#mouseWheel(evt) { #mouseWheel(evt) {
if (!this.active) { if (!this.active) {
return; return;
} }
evt.preventDefault(); evt.preventDefault();
const delta = normalizeWheelEventDelta(evt); const delta = normalizeWheelEventDelta(evt);
@ -139,29 +147,12 @@ class PDFPresentationMode {
}); });
} }
/**
* Used to initialize a timeout when requesting Presentation Mode,
* i.e. when the browser is requested to enter fullscreen mode.
* This timeout is used to prevent the current page from being scrolled
* partially, or completely, out of view when entering Presentation Mode.
* NOTE: This issue seems limited to certain zoom levels (e.g. page-width).
*/
#setSwitchInProgress() { #setSwitchInProgress() {
if (this.switchInProgress) { this.switchInProgress = true;
clearTimeout(this.switchInProgress);
}
this.switchInProgress = setTimeout(() => {
this.#removeFullscreenChangeListeners();
delete this.switchInProgress;
this.#notifyStateChange();
}, DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS);
} }
#resetSwitchInProgress() { #resetSwitchInProgress() {
if (this.switchInProgress) { this.switchInProgress = false;
clearTimeout(this.switchInProgress);
delete this.switchInProgress;
}
} }
#enter() { #enter() {
@ -175,7 +166,7 @@ class PDFPresentationMode {
setTimeout(() => { setTimeout(() => {
this.pdfViewer.scrollMode = ScrollMode.PAGE; this.pdfViewer.scrollMode = ScrollMode.PAGE;
this.pdfViewer.spreadMode = SpreadMode.NONE; this.pdfViewer.spreadMode = SpreadMode.NONE;
this.pdfViewer.currentPageNumber = this.args.pageNumber; this.pdfViewer.currentPageNumber = this.#args.pageNumber;
this.pdfViewer.currentScaleValue = "page-fit"; this.pdfViewer.currentScaleValue = "page-fit";
}, 0); }, 0);
@ -200,11 +191,11 @@ class PDFPresentationMode {
this.#removeFullscreenChangeListeners(); this.#removeFullscreenChangeListeners();
this.#notifyStateChange(); this.#notifyStateChange();
this.pdfViewer.scrollMode = this.args.scrollMode; this.pdfViewer.scrollMode = this.#args.scrollMode;
this.pdfViewer.spreadMode = this.args.spreadMode; this.pdfViewer.spreadMode = this.#args.spreadMode;
this.pdfViewer.currentScaleValue = this.args.scaleValue; this.pdfViewer.currentScaleValue = this.#args.scaleValue;
this.pdfViewer.currentPageNumber = pageNumber; this.pdfViewer.currentPageNumber = pageNumber;
this.args = null; this.#args = null;
}, 0); }, 0);
this.#removeWindowListeners(); this.#removeWindowListeners();