358 lines
9.9 KiB
JavaScript
358 lines
9.9 KiB
JavaScript
/**
|
|
* @licstart The following is the entire license notice for the
|
|
* JavaScript code in this page
|
|
*
|
|
* Copyright 2022 Mozilla Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* @licend The above is the entire license notice for the
|
|
* JavaScript code in this page
|
|
*/
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.PDFSidebar = void 0;
|
|
|
|
var _ui_utils = require("./ui_utils.js");
|
|
|
|
const UI_NOTIFICATION_CLASS = "pdfSidebarNotification";
|
|
|
|
class PDFSidebar {
|
|
constructor({
|
|
elements,
|
|
pdfViewer,
|
|
pdfThumbnailViewer,
|
|
eventBus,
|
|
l10n
|
|
}) {
|
|
this.isOpen = false;
|
|
this.active = _ui_utils.SidebarView.THUMBS;
|
|
this.isInitialViewSet = false;
|
|
this.isInitialEventDispatched = false;
|
|
this.onToggled = null;
|
|
this.pdfViewer = pdfViewer;
|
|
this.pdfThumbnailViewer = pdfThumbnailViewer;
|
|
this.outerContainer = elements.outerContainer;
|
|
this.sidebarContainer = elements.sidebarContainer;
|
|
this.toggleButton = elements.toggleButton;
|
|
this.thumbnailButton = elements.thumbnailButton;
|
|
this.outlineButton = elements.outlineButton;
|
|
this.attachmentsButton = elements.attachmentsButton;
|
|
this.layersButton = elements.layersButton;
|
|
this.thumbnailView = elements.thumbnailView;
|
|
this.outlineView = elements.outlineView;
|
|
this.attachmentsView = elements.attachmentsView;
|
|
this.layersView = elements.layersView;
|
|
this._outlineOptionsContainer = elements.outlineOptionsContainer;
|
|
this._currentOutlineItemButton = elements.currentOutlineItemButton;
|
|
this.eventBus = eventBus;
|
|
this.l10n = l10n;
|
|
this.#addEventListeners();
|
|
}
|
|
|
|
reset() {
|
|
this.isInitialViewSet = false;
|
|
this.isInitialEventDispatched = false;
|
|
this.#hideUINotification(true);
|
|
this.switchView(_ui_utils.SidebarView.THUMBS);
|
|
this.outlineButton.disabled = false;
|
|
this.attachmentsButton.disabled = false;
|
|
this.layersButton.disabled = false;
|
|
this._currentOutlineItemButton.disabled = true;
|
|
}
|
|
|
|
get visibleView() {
|
|
return this.isOpen ? this.active : _ui_utils.SidebarView.NONE;
|
|
}
|
|
|
|
setInitialView(view = _ui_utils.SidebarView.NONE) {
|
|
if (this.isInitialViewSet) {
|
|
return;
|
|
}
|
|
|
|
this.isInitialViewSet = true;
|
|
|
|
if (view === _ui_utils.SidebarView.NONE || view === _ui_utils.SidebarView.UNKNOWN) {
|
|
this.#dispatchEvent();
|
|
return;
|
|
}
|
|
|
|
this.switchView(view, true);
|
|
|
|
if (!this.isInitialEventDispatched) {
|
|
this.#dispatchEvent();
|
|
}
|
|
}
|
|
|
|
switchView(view, forceOpen = false) {
|
|
const isViewChanged = view !== this.active;
|
|
let shouldForceRendering = false;
|
|
|
|
switch (view) {
|
|
case _ui_utils.SidebarView.NONE:
|
|
if (this.isOpen) {
|
|
this.close();
|
|
}
|
|
|
|
return;
|
|
|
|
case _ui_utils.SidebarView.THUMBS:
|
|
if (this.isOpen && isViewChanged) {
|
|
shouldForceRendering = true;
|
|
}
|
|
|
|
break;
|
|
|
|
case _ui_utils.SidebarView.OUTLINE:
|
|
if (this.outlineButton.disabled) {
|
|
return;
|
|
}
|
|
|
|
break;
|
|
|
|
case _ui_utils.SidebarView.ATTACHMENTS:
|
|
if (this.attachmentsButton.disabled) {
|
|
return;
|
|
}
|
|
|
|
break;
|
|
|
|
case _ui_utils.SidebarView.LAYERS:
|
|
if (this.layersButton.disabled) {
|
|
return;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
console.error(`PDFSidebar.switchView: "${view}" is not a valid view.`);
|
|
return;
|
|
}
|
|
|
|
this.active = view;
|
|
const isThumbs = view === _ui_utils.SidebarView.THUMBS,
|
|
isOutline = view === _ui_utils.SidebarView.OUTLINE,
|
|
isAttachments = view === _ui_utils.SidebarView.ATTACHMENTS,
|
|
isLayers = view === _ui_utils.SidebarView.LAYERS;
|
|
this.thumbnailButton.classList.toggle("toggled", isThumbs);
|
|
this.outlineButton.classList.toggle("toggled", isOutline);
|
|
this.attachmentsButton.classList.toggle("toggled", isAttachments);
|
|
this.layersButton.classList.toggle("toggled", isLayers);
|
|
this.thumbnailButton.setAttribute("aria-checked", isThumbs);
|
|
this.outlineButton.setAttribute("aria-checked", isOutline);
|
|
this.attachmentsButton.setAttribute("aria-checked", isAttachments);
|
|
this.layersButton.setAttribute("aria-checked", isLayers);
|
|
this.thumbnailView.classList.toggle("hidden", !isThumbs);
|
|
this.outlineView.classList.toggle("hidden", !isOutline);
|
|
this.attachmentsView.classList.toggle("hidden", !isAttachments);
|
|
this.layersView.classList.toggle("hidden", !isLayers);
|
|
|
|
this._outlineOptionsContainer.classList.toggle("hidden", !isOutline);
|
|
|
|
if (forceOpen && !this.isOpen) {
|
|
this.open();
|
|
return;
|
|
}
|
|
|
|
if (shouldForceRendering) {
|
|
this.#updateThumbnailViewer();
|
|
this.#forceRendering();
|
|
}
|
|
|
|
if (isViewChanged) {
|
|
this.#dispatchEvent();
|
|
}
|
|
}
|
|
|
|
open() {
|
|
if (this.isOpen) {
|
|
return;
|
|
}
|
|
|
|
this.isOpen = true;
|
|
this.toggleButton.classList.add("toggled");
|
|
this.toggleButton.setAttribute("aria-expanded", "true");
|
|
this.outerContainer.classList.add("sidebarMoving", "sidebarOpen");
|
|
|
|
if (this.active === _ui_utils.SidebarView.THUMBS) {
|
|
this.#updateThumbnailViewer();
|
|
}
|
|
|
|
this.#forceRendering();
|
|
this.#dispatchEvent();
|
|
this.#hideUINotification();
|
|
}
|
|
|
|
close() {
|
|
if (!this.isOpen) {
|
|
return;
|
|
}
|
|
|
|
this.isOpen = false;
|
|
this.toggleButton.classList.remove("toggled");
|
|
this.toggleButton.setAttribute("aria-expanded", "false");
|
|
this.outerContainer.classList.add("sidebarMoving");
|
|
this.outerContainer.classList.remove("sidebarOpen");
|
|
this.#forceRendering();
|
|
this.#dispatchEvent();
|
|
}
|
|
|
|
toggle() {
|
|
if (this.isOpen) {
|
|
this.close();
|
|
} else {
|
|
this.open();
|
|
}
|
|
}
|
|
|
|
#dispatchEvent() {
|
|
if (this.isInitialViewSet && !this.isInitialEventDispatched) {
|
|
this.isInitialEventDispatched = true;
|
|
}
|
|
|
|
this.eventBus.dispatch("sidebarviewchanged", {
|
|
source: this,
|
|
view: this.visibleView
|
|
});
|
|
}
|
|
|
|
#forceRendering() {
|
|
if (this.onToggled) {
|
|
this.onToggled();
|
|
} else {
|
|
this.pdfViewer.forceRendering();
|
|
this.pdfThumbnailViewer.forceRendering();
|
|
}
|
|
}
|
|
|
|
#updateThumbnailViewer() {
|
|
const {
|
|
pdfViewer,
|
|
pdfThumbnailViewer
|
|
} = this;
|
|
const pagesCount = pdfViewer.pagesCount;
|
|
|
|
for (let pageIndex = 0; pageIndex < pagesCount; pageIndex++) {
|
|
const pageView = pdfViewer.getPageView(pageIndex);
|
|
|
|
if (pageView?.renderingState === _ui_utils.RenderingStates.FINISHED) {
|
|
const thumbnailView = pdfThumbnailViewer.getThumbnail(pageIndex);
|
|
thumbnailView.setImage(pageView);
|
|
}
|
|
}
|
|
|
|
pdfThumbnailViewer.scrollThumbnailIntoView(pdfViewer.currentPageNumber);
|
|
}
|
|
|
|
#showUINotification() {
|
|
this.l10n.get("toggle_sidebar_notification2.title").then(msg => {
|
|
this.toggleButton.title = msg;
|
|
});
|
|
|
|
if (!this.isOpen) {
|
|
this.toggleButton.classList.add(UI_NOTIFICATION_CLASS);
|
|
}
|
|
}
|
|
|
|
#hideUINotification(reset = false) {
|
|
if (this.isOpen || reset) {
|
|
this.toggleButton.classList.remove(UI_NOTIFICATION_CLASS);
|
|
}
|
|
|
|
if (reset) {
|
|
this.l10n.get("toggle_sidebar.title").then(msg => {
|
|
this.toggleButton.title = msg;
|
|
});
|
|
}
|
|
}
|
|
|
|
#addEventListeners() {
|
|
this.sidebarContainer.addEventListener("transitionend", evt => {
|
|
if (evt.target === this.sidebarContainer) {
|
|
this.outerContainer.classList.remove("sidebarMoving");
|
|
}
|
|
});
|
|
this.toggleButton.addEventListener("click", () => {
|
|
this.toggle();
|
|
});
|
|
this.thumbnailButton.addEventListener("click", () => {
|
|
this.switchView(_ui_utils.SidebarView.THUMBS);
|
|
});
|
|
this.outlineButton.addEventListener("click", () => {
|
|
this.switchView(_ui_utils.SidebarView.OUTLINE);
|
|
});
|
|
this.outlineButton.addEventListener("dblclick", () => {
|
|
this.eventBus.dispatch("toggleoutlinetree", {
|
|
source: this
|
|
});
|
|
});
|
|
this.attachmentsButton.addEventListener("click", () => {
|
|
this.switchView(_ui_utils.SidebarView.ATTACHMENTS);
|
|
});
|
|
this.layersButton.addEventListener("click", () => {
|
|
this.switchView(_ui_utils.SidebarView.LAYERS);
|
|
});
|
|
this.layersButton.addEventListener("dblclick", () => {
|
|
this.eventBus.dispatch("resetlayers", {
|
|
source: this
|
|
});
|
|
});
|
|
|
|
this._currentOutlineItemButton.addEventListener("click", () => {
|
|
this.eventBus.dispatch("currentoutlineitem", {
|
|
source: this
|
|
});
|
|
});
|
|
|
|
const onTreeLoaded = (count, button, view) => {
|
|
button.disabled = !count;
|
|
|
|
if (count) {
|
|
this.#showUINotification();
|
|
} else if (this.active === view) {
|
|
this.switchView(_ui_utils.SidebarView.THUMBS);
|
|
}
|
|
};
|
|
|
|
this.eventBus._on("outlineloaded", evt => {
|
|
onTreeLoaded(evt.outlineCount, this.outlineButton, _ui_utils.SidebarView.OUTLINE);
|
|
evt.currentOutlineItemPromise.then(enabled => {
|
|
if (!this.isInitialViewSet) {
|
|
return;
|
|
}
|
|
|
|
this._currentOutlineItemButton.disabled = !enabled;
|
|
});
|
|
});
|
|
|
|
this.eventBus._on("attachmentsloaded", evt => {
|
|
onTreeLoaded(evt.attachmentsCount, this.attachmentsButton, _ui_utils.SidebarView.ATTACHMENTS);
|
|
});
|
|
|
|
this.eventBus._on("layersloaded", evt => {
|
|
onTreeLoaded(evt.layersCount, this.layersButton, _ui_utils.SidebarView.LAYERS);
|
|
});
|
|
|
|
this.eventBus._on("presentationmodechanged", evt => {
|
|
if (evt.state === _ui_utils.PresentationModeState.NORMAL && this.visibleView === _ui_utils.SidebarView.THUMBS) {
|
|
this.#updateThumbnailViewer();
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
exports.PDFSidebar = PDFSidebar; |