Remove the loading icon div and replace it by a pure css solution using :after.

This way we don't have a lot of useless divs and we let the css engine handle the
creation/destruction of the :after pseudo-element.
It'll help to slightly improve performance when zooming.
This commit is contained in:
Calixte Denizet 2023-01-29 17:53:01 +01:00
parent 1bdee0b59b
commit aac073feeb
4 changed files with 34 additions and 26 deletions

View File

@ -207,7 +207,6 @@ page_scale_actual=Actual Size
page_scale_percent={{scale}}%
# Loading indicator messages
loading=Loading…
loading_error=An error occurred while loading the PDF.
invalid_file_error=Invalid or corrupted PDF file.
missing_file_error=Missing PDF file.

View File

@ -57,7 +57,6 @@ const DEFAULT_L10N_STRINGS = {
page_scale_actual: "Actual Size",
page_scale_percent: "{{scale}}%",
loading: "Loading…",
loading_error: "An error occurred while loading the PDF.",
invalid_file_error: "Invalid or corrupted PDF file.",
missing_file_error: "Missing PDF file.",

View File

@ -117,6 +117,8 @@ class PDFPageView {
#layerProperties = null;
#loadingId = null;
#previousRotation = null;
#renderingState = RenderingStates.INITIAL;
@ -232,21 +234,34 @@ class PDFPageView {
}
set renderingState(state) {
if (state === this.#renderingState) {
return;
}
this.#renderingState = state;
if (this.#loadingId) {
clearTimeout(this.#loadingId);
this.#loadingId = null;
}
switch (state) {
case RenderingStates.INITIAL:
case RenderingStates.PAUSED:
this.loadingIconDiv?.classList.add("notVisible");
this.div.classList.remove("loading");
break;
case RenderingStates.RUNNING:
this.loadingIconDiv?.classList.remove("notVisible");
this.div.classList.add("loadingIcon");
this.#loadingId = setTimeout(() => {
// Adding the loading class is slightly postponed in order to not have
// it with loadingIcon.
// If we don't do that the visibility of the background is changed but
// the transition isn't triggered.
this.div.classList.add("loading");
this.#loadingId = null;
}, 0);
break;
case RenderingStates.FINISHED:
if (this.loadingIconDiv) {
this.loadingIconDiv.remove();
delete this.loadingIconDiv;
}
this.div.classList.remove("loadingIcon", "loading");
break;
}
}
@ -468,7 +483,6 @@ class PDFPageView {
case annotationEditorLayerNode:
case xfaLayerNode:
case textLayerNode:
case this.loadingIconDiv:
continue;
}
node.remove();
@ -511,16 +525,6 @@ class PDFPageView {
this.paintedViewportMap.delete(this.svg);
delete this.svg;
}
if (!this.loadingIconDiv) {
this.loadingIconDiv = document.createElement("div");
this.loadingIconDiv.className = "loadingIcon notVisible";
this.loadingIconDiv.setAttribute("role", "img");
this.l10n.get("loading").then(msg => {
this.loadingIconDiv?.setAttribute("aria-label", msg);
});
div.append(this.loadingIconDiv);
}
}
update({

View File

@ -150,22 +150,28 @@
height: 100%;
}
.pdfViewer .page .loadingIcon {
.pdfViewer .page.loadingIcon:after {
position: absolute;
display: block;
left: 0;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: "";
width: 100%;
height: 100%;
background: url("images/loading-icon.gif") center no-repeat;
visibility: visible;
visibility: hidden;
/* Using a delay with background-image doesn't work,
consequently we use the visibility. */
transition-property: visibility;
transition-delay: var(--loading-icon-delay);
z-index: 5;
contain: strict;
}
.pdfViewer .page .loadingIcon.notVisible {
.pdfViewer .page.loading:after {
visibility: visible;
}
.pdfViewer .page:not(.loading):after {
transition-property: none;
visibility: hidden;
}