Skip to content

Commit

Permalink
Merge pull request #16413 from Snuffleupagus/PDFSidebar-inline-resizing
Browse files Browse the repository at this point in the history
Move the sidebar-resizing handling into the `PDFSidebar` class
  • Loading branch information
timvandermeij authored May 12, 2023
2 parents a5336d9 + 8f3940f commit e738e15
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 189 deletions.
1 change: 0 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ function createWebpackConfig(
"web-pdf_outline_viewer": "web/pdf_outline_viewer.js",
"web-pdf_presentation_mode": "web/pdf_presentation_mode.js",
"web-pdf_sidebar": "web/pdf_sidebar.js",
"web-pdf_sidebar_resizer": "web/pdf_sidebar_resizer.js",
"web-pdf_thumbnail_viewer": "web/pdf_thumbnail_viewer.js",
"web-print_service": "",
"web-secondary_toolbar": "web/secondary_toolbar.js",
Expand Down
1 change: 0 additions & 1 deletion test/unit/unit_test.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"web-pdf_outline_viewer": "../../web/pdf_outline_viewer.js",
"web-pdf_presentation_mode": "../../web/pdf_presentation_mode.js",
"web-pdf_sidebar": "../../web/pdf_sidebar.js",
"web-pdf_sidebar_resizer": "../../web/pdf_sidebar_resizer.js",
"web-pdf_thumbnail_viewer": "../../web/pdf_thumbnail_viewer.js",
"web-print_service": "../../web/pdf_print_service.js",
"web-secondary_toolbar": "../../web/secondary_toolbar.js",
Expand Down
9 changes: 0 additions & 9 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ import { PDFPresentationMode } from "web-pdf_presentation_mode";
import { PDFRenderingQueue } from "./pdf_rendering_queue.js";
import { PDFScriptingManager } from "./pdf_scripting_manager.js";
import { PDFSidebar } from "web-pdf_sidebar";
import { PDFSidebarResizer } from "web-pdf_sidebar_resizer";
import { PDFThumbnailViewer } from "web-pdf_thumbnail_viewer";
import { PDFViewer } from "./pdf_viewer.js";
import { SecondaryToolbar } from "web-secondary_toolbar";
Expand Down Expand Up @@ -177,8 +176,6 @@ const PDFViewerApplication = {
pdfHistory: null,
/** @type {PDFSidebar} */
pdfSidebar: null,
/** @type {PDFSidebarResizer} */
pdfSidebarResizer: null,
/** @type {PDFOutlineViewer} */
pdfOutlineViewer: null,
/** @type {PDFAttachmentViewer} */
Expand Down Expand Up @@ -656,12 +653,6 @@ const PDFViewerApplication = {
l10n: this.l10n,
});
this.pdfSidebar.onToggled = this.forceRendering.bind(this);

this.pdfSidebarResizer = new PDFSidebarResizer(
appConfig.sidebarResizer,
eventBus,
this.l10n
);
}
},

Expand Down
118 changes: 116 additions & 2 deletions web/pdf_sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
*/

import {
docStyle,
PresentationModeState,
RenderingStates,
SidebarView,
toggleCheckedBtn,
toggleExpandedBtn,
} from "./ui_utils.js";

const SIDEBAR_WIDTH_VAR = "--sidebar-width";
const SIDEBAR_MIN_WIDTH = 200; // pixels
const SIDEBAR_RESIZING_CLASS = "sidebarResizing";
const UI_NOTIFICATION_CLASS = "pdfSidebarNotification";

/**
Expand All @@ -40,6 +44,8 @@ const UI_NOTIFICATION_CLASS = "pdfSidebarNotification";
* (in which the views are placed).
* @property {HTMLButtonElement} toggleButton - The button used for
* opening/closing the sidebar.
* @property {HTMLDivElement} resizer - The DOM element that can be dragged in
* order to adjust the width of the sidebar.
* @property {HTMLButtonElement} thumbnailButton - The button used to show
* the thumbnail view.
* @property {HTMLButtonElement} outlineButton - The button used to show
Expand All @@ -63,6 +69,16 @@ const UI_NOTIFICATION_CLASS = "pdfSidebarNotification";
*/

class PDFSidebar {
#isRTL = false;

#mouseMoveBound = this.#mouseMove.bind(this);

#mouseUpBound = this.#mouseUp.bind(this);

#outerContainerWidth = null;

#width = null;

/**
* @param {PDFSidebarOptions} options
*/
Expand All @@ -84,6 +100,7 @@ class PDFSidebar {
this.outerContainer = elements.outerContainer;
this.sidebarContainer = elements.sidebarContainer;
this.toggleButton = elements.toggleButton;
this.resizer = elements.resizer;

this.thumbnailButton = elements.thumbnailButton;
this.outlineButton = elements.outlineButton;
Expand All @@ -101,6 +118,9 @@ class PDFSidebar {
this.eventBus = eventBus;
this.l10n = l10n;

l10n.getDirection().then(dir => {
this.#isRTL = dir === "rtl";
});
this.#addEventListeners();
}

Expand Down Expand Up @@ -275,8 +295,8 @@ class PDFSidebar {
}

#dispatchEvent() {
if (this.isInitialViewSet && !this.isInitialEventDispatched) {
this.isInitialEventDispatched = true;
if (this.isInitialViewSet) {
this.isInitialEventDispatched ||= true;
}

this.eventBus.dispatch("sidebarviewchanged", {
Expand Down Expand Up @@ -411,6 +431,100 @@ class PDFSidebar {
this.#updateThumbnailViewer();
}
});

// Handle resizing of the sidebar.
this.resizer.addEventListener("mousedown", evt => {
if (evt.button !== 0) {
return;
}
// Disable the `transition-duration` rules when sidebar resizing begins,
// in order to improve responsiveness and to avoid visual glitches.
this.outerContainer.classList.add(SIDEBAR_RESIZING_CLASS);

window.addEventListener("mousemove", this.#mouseMoveBound);
window.addEventListener("mouseup", this.#mouseUpBound);
});

this.eventBus._on("resize", evt => {
// When the *entire* viewer is resized, such that it becomes narrower,
// ensure that the sidebar doesn't end up being too wide.
if (evt.source !== window) {
return;
}
// Always reset the cached width when the viewer is resized.
this.#outerContainerWidth = null;

if (!this.#width) {
// The sidebar hasn't been resized, hence no need to adjust its width.
return;
}
// NOTE: If the sidebar is closed, we don't need to worry about
// visual glitches nor ensure that rendering is triggered.
if (!this.isOpen) {
this.#updateWidth(this.#width);
return;
}
this.outerContainer.classList.add(SIDEBAR_RESIZING_CLASS);
const updated = this.#updateWidth(this.#width);

Promise.resolve().then(() => {
this.outerContainer.classList.remove(SIDEBAR_RESIZING_CLASS);
// Trigger rendering if the sidebar width changed, to avoid
// depending on the order in which 'resize' events are handled.
if (updated) {
this.eventBus.dispatch("resize", { source: this });
}
});
});
}

/**
* @type {number}
*/
get outerContainerWidth() {
return (this.#outerContainerWidth ||= this.outerContainer.clientWidth);
}

/**
* returns {boolean} Indicating if the sidebar width was updated.
*/
#updateWidth(width = 0) {
// Prevent the sidebar from becoming too narrow, or from occupying more
// than half of the available viewer width.
const maxWidth = Math.floor(this.outerContainerWidth / 2);
if (width > maxWidth) {
width = maxWidth;
}
if (width < SIDEBAR_MIN_WIDTH) {
width = SIDEBAR_MIN_WIDTH;
}
// Only update the UI when the sidebar width did in fact change.
if (width === this.#width) {
return false;
}
this.#width = width;

docStyle.setProperty(SIDEBAR_WIDTH_VAR, `${width}px`);
return true;
}

#mouseMove(evt) {
let width = evt.clientX;
// For sidebar resizing to work correctly in RTL mode, invert the width.
if (this.#isRTL) {
width = this.outerContainerWidth - width;
}
this.#updateWidth(width);
}

#mouseUp(evt) {
// Re-enable the `transition-duration` rules when sidebar resizing ends...
this.outerContainer.classList.remove(SIDEBAR_RESIZING_CLASS);
// ... and ensure that rendering will always be triggered.
this.eventBus.dispatch("resize", { source: this });

window.removeEventListener("mousemove", this.#mouseMoveBound);
window.removeEventListener("mouseup", this.#mouseUpBound);
}
}

Expand Down
168 changes: 0 additions & 168 deletions web/pdf_sidebar_resizer.js

This file was deleted.

Loading

0 comments on commit e738e15

Please sign in to comment.