From c27dcf2b0331a3efe3da3a957e0056d329342190 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 9 Sep 2020 15:07:38 +0200 Subject: [PATCH] Ensure that the `container` div, on `BaseViewer`-instances, is absolutely positioned The `getVisibleElements` helper function currently requires the viewerContainer to be absolutely positioned; possibly fixing this is tracked in issue 11626. Without `position: absolute;` set, in the CSS, there's a number of things that won't work correctly such as e.g. - Determining which pages are currently visible, thus forcing all of them to render on load and increasing resource usage significantly; note https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#allthepages - Scrolling pages into view, by using the `BaseViewer.currentPageNumber` setter or similar. Based on the number of opened issues over the years, the fact that `position: absolute;` is required has shown to be something that users can very easily overlook unless they follow e.g. the `simpleviewer` example to the letter. Hence, to improve things until such a time that issue 11626 is fixed, we'll now refuse to initialize a `BaseViewer` instance unless the `container` has the required CSS set. (Forcibly setting `position: absolute;` on the viewerContainer element is bound to cause significantly more issues/confusion, hence the current approach of throwing an Error.) --- web/base_viewer.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/web/base_viewer.js b/web/base_viewer.js index 9d7ac1d71..36c63cba0 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -145,14 +145,21 @@ class BaseViewer { this.viewer = options.viewer || options.container.firstElementChild; if ( - (typeof PDFJSDev === "undefined" || - PDFJSDev.test("!PRODUCTION || GENERIC")) && - !( - this.container instanceof HTMLDivElement && - this.viewer instanceof HTMLDivElement - ) + typeof PDFJSDev === "undefined" || + PDFJSDev.test("!PRODUCTION || GENERIC") ) { - throw new Error("Invalid `container` and/or `viewer` option."); + if ( + !( + this.container instanceof HTMLDivElement && + this.viewer instanceof HTMLDivElement + ) + ) { + throw new Error("Invalid `container` and/or `viewer` option."); + } + + if (getComputedStyle(this.container).position !== "absolute") { + throw new Error("The `container` must be absolutely positioned."); + } } this.eventBus = options.eventBus; this.linkService = options.linkService || new SimpleLinkService();