1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | "use strict";
|
23 |
|
24 | Object.defineProperty(exports, "__esModule", {
|
25 | value: true
|
26 | });
|
27 | exports.Toolbar = void 0;
|
28 |
|
29 | var _ui_utils = require("./ui_utils.js");
|
30 |
|
31 | var _pdf = require("../pdf");
|
32 |
|
33 | const PAGE_NUMBER_LOADING_INDICATOR = "visiblePageIsLoading";
|
34 |
|
35 | class Toolbar {
|
36 | constructor(options, eventBus, l10n) {
|
37 | this.toolbar = options.container;
|
38 | this.eventBus = eventBus;
|
39 | this.l10n = l10n;
|
40 | this.buttons = [{
|
41 | element: options.previous,
|
42 | eventName: "previouspage"
|
43 | }, {
|
44 | element: options.next,
|
45 | eventName: "nextpage"
|
46 | }, {
|
47 | element: options.zoomIn,
|
48 | eventName: "zoomin"
|
49 | }, {
|
50 | element: options.zoomOut,
|
51 | eventName: "zoomout"
|
52 | }, {
|
53 | element: options.print,
|
54 | eventName: "print"
|
55 | }, {
|
56 | element: options.presentationModeButton,
|
57 | eventName: "presentationmode"
|
58 | }, {
|
59 | element: options.download,
|
60 | eventName: "download"
|
61 | }, {
|
62 | element: options.viewBookmark,
|
63 | eventName: null
|
64 | }, {
|
65 | element: options.editorNoneButton,
|
66 | eventName: "switchannotationeditormode",
|
67 | eventDetails: {
|
68 | mode: _pdf.AnnotationEditorType.NONE
|
69 | }
|
70 | }, {
|
71 | element: options.editorFreeTextButton,
|
72 | eventName: "switchannotationeditormode",
|
73 | eventDetails: {
|
74 | mode: _pdf.AnnotationEditorType.FREETEXT
|
75 | }
|
76 | }, {
|
77 | element: options.editorInkButton,
|
78 | eventName: "switchannotationeditormode",
|
79 | eventDetails: {
|
80 | mode: _pdf.AnnotationEditorType.INK
|
81 | }
|
82 | }];
|
83 | this.buttons.push({
|
84 | element: options.openFile,
|
85 | eventName: "openfile"
|
86 | });
|
87 | this.items = {
|
88 | numPages: options.numPages,
|
89 | pageNumber: options.pageNumber,
|
90 | scaleSelect: options.scaleSelect,
|
91 | customScaleOption: options.customScaleOption,
|
92 | previous: options.previous,
|
93 | next: options.next,
|
94 | zoomIn: options.zoomIn,
|
95 | zoomOut: options.zoomOut,
|
96 | editorNoneButton: options.editorNoneButton,
|
97 | editorFreeTextButton: options.editorFreeTextButton,
|
98 | editorFreeTextParamsToolbar: options.editorFreeTextParamsToolbar,
|
99 | editorInkButton: options.editorInkButton,
|
100 | editorInkParamsToolbar: options.editorInkParamsToolbar
|
101 | };
|
102 | this._wasLocalized = false;
|
103 | this.reset();
|
104 |
|
105 | this._bindListeners(options);
|
106 | }
|
107 |
|
108 | setPageNumber(pageNumber, pageLabel) {
|
109 | this.pageNumber = pageNumber;
|
110 | this.pageLabel = pageLabel;
|
111 |
|
112 | this._updateUIState(false);
|
113 | }
|
114 |
|
115 | setPagesCount(pagesCount, hasPageLabels) {
|
116 | this.pagesCount = pagesCount;
|
117 | this.hasPageLabels = hasPageLabels;
|
118 |
|
119 | this._updateUIState(true);
|
120 | }
|
121 |
|
122 | setPageScale(pageScaleValue, pageScale) {
|
123 | this.pageScaleValue = (pageScaleValue || pageScale).toString();
|
124 | this.pageScale = pageScale;
|
125 |
|
126 | this._updateUIState(false);
|
127 | }
|
128 |
|
129 | reset() {
|
130 | this.pageNumber = 0;
|
131 | this.pageLabel = null;
|
132 | this.hasPageLabels = false;
|
133 | this.pagesCount = 0;
|
134 | this.pageScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
|
135 | this.pageScale = _ui_utils.DEFAULT_SCALE;
|
136 |
|
137 | this._updateUIState(true);
|
138 |
|
139 | this.updateLoadingIndicatorState();
|
140 | this.eventBus.dispatch("toolbarreset", {
|
141 | source: this
|
142 | });
|
143 | }
|
144 |
|
145 | _bindListeners(options) {
|
146 | const {
|
147 | pageNumber,
|
148 | scaleSelect
|
149 | } = this.items;
|
150 | const self = this;
|
151 |
|
152 | for (const {
|
153 | element,
|
154 | eventName,
|
155 | eventDetails
|
156 | } of this.buttons) {
|
157 | element.addEventListener("click", evt => {
|
158 | if (eventName !== null) {
|
159 | const details = {
|
160 | source: this
|
161 | };
|
162 |
|
163 | if (eventDetails) {
|
164 | for (const property in eventDetails) {
|
165 | details[property] = eventDetails[property];
|
166 | }
|
167 | }
|
168 |
|
169 | this.eventBus.dispatch(eventName, details);
|
170 | }
|
171 | });
|
172 | }
|
173 |
|
174 | pageNumber.addEventListener("click", function () {
|
175 | this.select();
|
176 | });
|
177 | pageNumber.addEventListener("change", function () {
|
178 | self.eventBus.dispatch("pagenumberchanged", {
|
179 | source: self,
|
180 | value: this.value
|
181 | });
|
182 | });
|
183 | scaleSelect.addEventListener("change", function () {
|
184 | if (this.value === "custom") {
|
185 | return;
|
186 | }
|
187 |
|
188 | self.eventBus.dispatch("scalechanged", {
|
189 | source: self,
|
190 | value: this.value
|
191 | });
|
192 | });
|
193 | scaleSelect.addEventListener("click", function (evt) {
|
194 | const target = evt.target;
|
195 |
|
196 | if (this.value === self.pageScaleValue && target.tagName.toUpperCase() === "OPTION") {
|
197 | this.blur();
|
198 | }
|
199 | });
|
200 | scaleSelect.oncontextmenu = _ui_utils.noContextMenuHandler;
|
201 |
|
202 | this.eventBus._on("localized", () => {
|
203 | this._wasLocalized = true;
|
204 | this.#adjustScaleWidth();
|
205 |
|
206 | this._updateUIState(true);
|
207 | });
|
208 |
|
209 | this.#bindEditorToolsListener(options);
|
210 | }
|
211 |
|
212 | #bindEditorToolsListener({
|
213 | editorNoneButton,
|
214 | editorFreeTextButton,
|
215 | editorFreeTextParamsToolbar,
|
216 | editorInkButton,
|
217 | editorInkParamsToolbar
|
218 | }) {
|
219 | const editorModeChanged = (evt, disableButtons = false) => {
|
220 | const editorButtons = [{
|
221 | mode: _pdf.AnnotationEditorType.NONE,
|
222 | button: editorNoneButton
|
223 | }, {
|
224 | mode: _pdf.AnnotationEditorType.FREETEXT,
|
225 | button: editorFreeTextButton,
|
226 | toolbar: editorFreeTextParamsToolbar
|
227 | }, {
|
228 | mode: _pdf.AnnotationEditorType.INK,
|
229 | button: editorInkButton,
|
230 | toolbar: editorInkParamsToolbar
|
231 | }];
|
232 |
|
233 | for (const {
|
234 | mode,
|
235 | button,
|
236 | toolbar
|
237 | } of editorButtons) {
|
238 | const checked = mode === evt.mode;
|
239 | button.classList.toggle("toggled", checked);
|
240 | button.setAttribute("aria-checked", checked);
|
241 | button.disabled = disableButtons;
|
242 |
|
243 | if (toolbar) {
|
244 | toolbar.classList.toggle("hidden", !checked);
|
245 | }
|
246 | }
|
247 | };
|
248 |
|
249 | this.eventBus._on("annotationeditormodechanged", editorModeChanged);
|
250 |
|
251 | this.eventBus._on("toolbarreset", evt => {
|
252 | if (evt.source === this) {
|
253 | editorModeChanged({
|
254 | mode: _pdf.AnnotationEditorType.NONE
|
255 | }, true);
|
256 | }
|
257 | });
|
258 | }
|
259 |
|
260 | _updateUIState(resetNumPages = false) {
|
261 | if (!this._wasLocalized) {
|
262 | return;
|
263 | }
|
264 |
|
265 | const {
|
266 | pageNumber,
|
267 | pagesCount,
|
268 | pageScaleValue,
|
269 | pageScale,
|
270 | items
|
271 | } = this;
|
272 |
|
273 | if (resetNumPages) {
|
274 | if (this.hasPageLabels) {
|
275 | items.pageNumber.type = "text";
|
276 | } else {
|
277 | items.pageNumber.type = "number";
|
278 | this.l10n.get("of_pages", {
|
279 | pagesCount
|
280 | }).then(msg => {
|
281 | items.numPages.textContent = msg;
|
282 | });
|
283 | }
|
284 |
|
285 | items.pageNumber.max = pagesCount;
|
286 | }
|
287 |
|
288 | if (this.hasPageLabels) {
|
289 | items.pageNumber.value = this.pageLabel;
|
290 | this.l10n.get("page_of_pages", {
|
291 | pageNumber,
|
292 | pagesCount
|
293 | }).then(msg => {
|
294 | items.numPages.textContent = msg;
|
295 | });
|
296 | } else {
|
297 | items.pageNumber.value = pageNumber;
|
298 | }
|
299 |
|
300 | items.previous.disabled = pageNumber <= 1;
|
301 | items.next.disabled = pageNumber >= pagesCount;
|
302 | items.zoomOut.disabled = pageScale <= _ui_utils.MIN_SCALE;
|
303 | items.zoomIn.disabled = pageScale >= _ui_utils.MAX_SCALE;
|
304 | this.l10n.get("page_scale_percent", {
|
305 | scale: Math.round(pageScale * 10000) / 100
|
306 | }).then(msg => {
|
307 | let predefinedValueFound = false;
|
308 |
|
309 | for (const option of items.scaleSelect.options) {
|
310 | if (option.value !== pageScaleValue) {
|
311 | option.selected = false;
|
312 | continue;
|
313 | }
|
314 |
|
315 | option.selected = true;
|
316 | predefinedValueFound = true;
|
317 | }
|
318 |
|
319 | if (!predefinedValueFound) {
|
320 | items.customScaleOption.textContent = msg;
|
321 | items.customScaleOption.selected = true;
|
322 | }
|
323 | });
|
324 | }
|
325 |
|
326 | updateLoadingIndicatorState(loading = false) {
|
327 | const {
|
328 | pageNumber
|
329 | } = this.items;
|
330 | pageNumber.classList.toggle(PAGE_NUMBER_LOADING_INDICATOR, loading);
|
331 | }
|
332 |
|
333 | async #adjustScaleWidth() {
|
334 | const {
|
335 | items,
|
336 | l10n
|
337 | } = this;
|
338 | const predefinedValuesPromise = Promise.all([l10n.get("page_scale_auto"), l10n.get("page_scale_actual"), l10n.get("page_scale_fit"), l10n.get("page_scale_width")]);
|
339 | await _ui_utils.animationStarted;
|
340 | const style = getComputedStyle(items.scaleSelect),
|
341 | scaleSelectContainerWidth = parseInt(style.getPropertyValue("--scale-select-container-width"), 10),
|
342 | scaleSelectOverflow = parseInt(style.getPropertyValue("--scale-select-overflow"), 10);
|
343 | const canvas = document.createElement("canvas");
|
344 | const ctx = canvas.getContext("2d", {
|
345 | alpha: false
|
346 | });
|
347 | ctx.font = `${style.fontSize} ${style.fontFamily}`;
|
348 | let maxWidth = 0;
|
349 |
|
350 | for (const predefinedValue of await predefinedValuesPromise) {
|
351 | const {
|
352 | width
|
353 | } = ctx.measureText(predefinedValue);
|
354 |
|
355 | if (width > maxWidth) {
|
356 | maxWidth = width;
|
357 | }
|
358 | }
|
359 |
|
360 | maxWidth += 2 * scaleSelectOverflow;
|
361 |
|
362 | if (maxWidth > scaleSelectContainerWidth) {
|
363 | _ui_utils.docStyle.setProperty("--scale-select-container-width", `${maxWidth}px`);
|
364 | }
|
365 |
|
366 | canvas.width = 0;
|
367 | canvas.height = 0;
|
368 | }
|
369 |
|
370 | }
|
371 |
|
372 | exports.Toolbar = Toolbar; |
\ | No newline at end of file |