Skip to content

Commit

Permalink
Remove the internal "toolbarreset" event and slightly re-factor the code
Browse files Browse the repository at this point in the history
With modern JavaScript class features we can move the relevant event handling into private methods, and thus invoke it directly when resetting the toolbar UI-state.

*Please note:* This patch slightly reduces the size of the `web/toolbar.js` file.
  • Loading branch information
Snuffleupagus committed Dec 26, 2023
1 parent 3b94e9f commit 234b57b
Showing 1 changed file with 74 additions and 86 deletions.
160 changes: 74 additions & 86 deletions web/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@ import {
*/

class Toolbar {
#opts;

/**
* @param {ToolbarOptions} options
* @param {EventBus} eventBus
*/
constructor(options, eventBus) {
this.toolbar = options.container;
this.#opts = options;
this.eventBus = eventBus;
this.buttons = [
const buttons = [
{ element: options.previous, eventName: "previouspage" },
{ element: options.next, eventName: "nextpage" },
{ element: options.zoomIn, eventName: "zoomin" },
Expand Down Expand Up @@ -106,22 +108,12 @@ class Toolbar {
},
},
];
this.items = {
numPages: options.numPages,
pageNumber: options.pageNumber,
scaleSelect: options.scaleSelect,
customScaleOption: options.customScaleOption,
previous: options.previous,
next: options.next,
zoomIn: options.zoomIn,
zoomOut: options.zoomOut,
};

// Bind the event listeners for click and various other actions.
this.#bindListeners(options);
this.#bindListeners(buttons);

if (options.editorHighlightColorPicker) {
this.eventBus._on(
eventBus._on(
"annotationeditoruimanager",
({ uiManager }) => {
this.#setAnnotationEditorUIManager(
Expand Down Expand Up @@ -172,18 +164,19 @@ class Toolbar {
this.updateLoadingIndicatorState();

// Reset the Editor buttons too, since they're document specific.
this.eventBus.dispatch("toolbarreset", { source: this });
this.#editorModeChanged({ mode: AnnotationEditorType.DISABLE });
}

#bindListeners(options) {
const { pageNumber, scaleSelect } = this.items;
#bindListeners(buttons) {
const { eventBus } = this;
const { pageNumber, scaleSelect } = this.#opts;
const self = this;

// The buttons within the toolbar.
for (const { element, eventName, eventDetails } of this.buttons) {
for (const { element, eventName, eventDetails } of buttons) {
element.addEventListener("click", evt => {
if (eventName !== null) {
this.eventBus.dispatch(eventName, {
eventBus.dispatch(eventName, {
source: this,
...eventDetails,
// evt.detail is the number of clicks.
Expand All @@ -197,7 +190,7 @@ class Toolbar {
this.select();
});
pageNumber.addEventListener("change", function () {
self.eventBus.dispatch("pagenumberchanged", {
eventBus.dispatch("pagenumberchanged", {
source: self,
value: this.value,
});
Expand All @@ -207,15 +200,14 @@ class Toolbar {
if (this.value === "custom") {
return;
}
self.eventBus.dispatch("scalechanged", {
eventBus.dispatch("scalechanged", {
source: self,
value: this.value,
});
});
// Here we depend on browsers dispatching the "click" event *after* the
// "change" event, when the <select>-element changes.
scaleSelect.addEventListener("click", function (evt) {
const target = evt.target;
scaleSelect.addEventListener("click", function ({ target }) {
// Remove focus when an <option>-element was *clicked*, to improve the UX
// for mouse users (fixes bug 1300525 and issue 4923).
if (
Expand All @@ -228,95 +220,92 @@ class Toolbar {
// Suppress context menus for some controls.
scaleSelect.oncontextmenu = noContextMenu;

this.#bindEditorToolsListener(options);
eventBus._on(
"annotationeditormodechanged",
this.#editorModeChanged.bind(this)
);
}

#bindEditorToolsListener({
editorFreeTextButton,
editorFreeTextParamsToolbar,
editorHighlightButton,
editorHighlightParamsToolbar,
editorInkButton,
editorInkParamsToolbar,
editorStampButton,
editorStampParamsToolbar,
}) {
const editorModeChanged = ({ mode }) => {
toggleCheckedBtn(
editorFreeTextButton,
mode === AnnotationEditorType.FREETEXT,
editorFreeTextParamsToolbar
);
toggleCheckedBtn(
editorHighlightButton,
mode === AnnotationEditorType.HIGHLIGHT,
editorHighlightParamsToolbar
);
toggleCheckedBtn(
editorInkButton,
mode === AnnotationEditorType.INK,
editorInkParamsToolbar
);
toggleCheckedBtn(
editorStampButton,
mode === AnnotationEditorType.STAMP,
editorStampParamsToolbar
);
#editorModeChanged({ mode }) {
const {
editorFreeTextButton,
editorFreeTextParamsToolbar,
editorHighlightButton,
editorHighlightParamsToolbar,
editorInkButton,
editorInkParamsToolbar,
editorStampButton,
editorStampParamsToolbar,
} = this.#opts;

const isDisable = mode === AnnotationEditorType.DISABLE;
editorFreeTextButton.disabled = isDisable;
editorHighlightButton.disabled = isDisable;
editorInkButton.disabled = isDisable;
editorStampButton.disabled = isDisable;
};
this.eventBus._on("annotationeditormodechanged", editorModeChanged);
toggleCheckedBtn(
editorFreeTextButton,
mode === AnnotationEditorType.FREETEXT,
editorFreeTextParamsToolbar
);
toggleCheckedBtn(
editorHighlightButton,
mode === AnnotationEditorType.HIGHLIGHT,
editorHighlightParamsToolbar
);
toggleCheckedBtn(
editorInkButton,
mode === AnnotationEditorType.INK,
editorInkParamsToolbar
);
toggleCheckedBtn(
editorStampButton,
mode === AnnotationEditorType.STAMP,
editorStampParamsToolbar
);

this.eventBus._on("toolbarreset", evt => {
if (evt.source === this) {
editorModeChanged({ mode: AnnotationEditorType.DISABLE });
}
});
const isDisable = mode === AnnotationEditorType.DISABLE;
editorFreeTextButton.disabled = isDisable;
editorHighlightButton.disabled = isDisable;
editorInkButton.disabled = isDisable;
editorStampButton.disabled = isDisable;
}

#updateUIState(resetNumPages = false) {
const { pageNumber, pagesCount, pageScaleValue, pageScale, items } = this;
const { pageNumber, pagesCount, pageScaleValue, pageScale } = this;
const opts = this.#opts;

if (resetNumPages) {
if (this.hasPageLabels) {
items.pageNumber.type = "text";
opts.pageNumber.type = "text";

items.numPages.setAttribute("data-l10n-id", "pdfjs-page-of-pages");
opts.numPages.setAttribute("data-l10n-id", "pdfjs-page-of-pages");
} else {
items.pageNumber.type = "number";
opts.pageNumber.type = "number";

items.numPages.setAttribute("data-l10n-id", "pdfjs-of-pages");
items.numPages.setAttribute(
opts.numPages.setAttribute("data-l10n-id", "pdfjs-of-pages");
opts.numPages.setAttribute(
"data-l10n-args",
JSON.stringify({ pagesCount })
);
}
items.pageNumber.max = pagesCount;
opts.pageNumber.max = pagesCount;
}

if (this.hasPageLabels) {
items.pageNumber.value = this.pageLabel;
opts.pageNumber.value = this.pageLabel;

items.numPages.setAttribute(
opts.numPages.setAttribute(
"data-l10n-args",
JSON.stringify({ pageNumber, pagesCount })
);
} else {
items.pageNumber.value = pageNumber;
opts.pageNumber.value = pageNumber;
}

items.previous.disabled = pageNumber <= 1;
items.next.disabled = pageNumber >= pagesCount;
opts.previous.disabled = pageNumber <= 1;
opts.next.disabled = pageNumber >= pagesCount;

items.zoomOut.disabled = pageScale <= MIN_SCALE;
items.zoomIn.disabled = pageScale >= MAX_SCALE;
opts.zoomOut.disabled = pageScale <= MIN_SCALE;
opts.zoomIn.disabled = pageScale >= MAX_SCALE;

let predefinedValueFound = false;
for (const option of items.scaleSelect.options) {
for (const option of opts.scaleSelect.options) {
if (option.value !== pageScaleValue) {
option.selected = false;
continue;
Expand All @@ -325,8 +314,8 @@ class Toolbar {
predefinedValueFound = true;
}
if (!predefinedValueFound) {
items.customScaleOption.selected = true;
items.customScaleOption.setAttribute(
opts.customScaleOption.selected = true;
opts.customScaleOption.setAttribute(
"data-l10n-args",
JSON.stringify({
scale: Math.round(pageScale * 10000) / 100,
Expand All @@ -336,8 +325,7 @@ class Toolbar {
}

updateLoadingIndicatorState(loading = false) {
const { pageNumber } = this.items;

const { pageNumber } = this.#opts;
pageNumber.classList.toggle("loading", loading);
}
}
Expand Down

0 comments on commit 234b57b

Please sign in to comment.