UNPKG

14.9 kBJavaScriptView Raw
1/**
2 * @licstart The following is the entire license notice for the
3 * Javascript code in this page
4 *
5 * Copyright 2019 Mozilla Foundation
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * @licend The above is the entire license notice for the
20 * Javascript code in this page
21 */
22"use strict";
23
24Object.defineProperty(exports, "__esModule", {
25 value: true
26});
27exports.PDFPresentationMode = void 0;
28
29var _ui_utils = require("./ui_utils");
30
31function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
32
33function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
34
35function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
36
37var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500;
38var DELAY_BEFORE_HIDING_CONTROLS = 3000;
39var ACTIVE_SELECTOR = 'pdfPresentationMode';
40var CONTROLS_SELECTOR = 'pdfPresentationModeControls';
41var MOUSE_SCROLL_COOLDOWN_TIME = 50;
42var PAGE_SWITCH_THRESHOLD = 0.1;
43var SWIPE_MIN_DISTANCE_THRESHOLD = 50;
44var SWIPE_ANGLE_THRESHOLD = Math.PI / 6;
45
46var PDFPresentationMode =
47/*#__PURE__*/
48function () {
49 function PDFPresentationMode(_ref) {
50 var _this = this;
51
52 var container = _ref.container,
53 _ref$viewer = _ref.viewer,
54 viewer = _ref$viewer === void 0 ? null : _ref$viewer,
55 pdfViewer = _ref.pdfViewer,
56 eventBus = _ref.eventBus,
57 _ref$contextMenuItems = _ref.contextMenuItems,
58 contextMenuItems = _ref$contextMenuItems === void 0 ? null : _ref$contextMenuItems;
59
60 _classCallCheck(this, PDFPresentationMode);
61
62 this.container = container;
63 this.viewer = viewer || container.firstElementChild;
64 this.pdfViewer = pdfViewer;
65 this.eventBus = eventBus;
66 this.active = false;
67 this.args = null;
68 this.contextMenuOpen = false;
69 this.mouseScrollTimeStamp = 0;
70 this.mouseScrollDelta = 0;
71 this.touchSwipeState = null;
72
73 if (contextMenuItems) {
74 contextMenuItems.contextFirstPage.addEventListener('click', function () {
75 _this.contextMenuOpen = false;
76
77 _this.eventBus.dispatch('firstpage', {
78 source: _this
79 });
80 });
81 contextMenuItems.contextLastPage.addEventListener('click', function () {
82 _this.contextMenuOpen = false;
83
84 _this.eventBus.dispatch('lastpage', {
85 source: _this
86 });
87 });
88 contextMenuItems.contextPageRotateCw.addEventListener('click', function () {
89 _this.contextMenuOpen = false;
90
91 _this.eventBus.dispatch('rotatecw', {
92 source: _this
93 });
94 });
95 contextMenuItems.contextPageRotateCcw.addEventListener('click', function () {
96 _this.contextMenuOpen = false;
97
98 _this.eventBus.dispatch('rotateccw', {
99 source: _this
100 });
101 });
102 }
103 }
104
105 _createClass(PDFPresentationMode, [{
106 key: "request",
107 value: function request() {
108 if (this.switchInProgress || this.active || !this.viewer.hasChildNodes()) {
109 return false;
110 }
111
112 this._addFullscreenChangeListeners();
113
114 this._setSwitchInProgress();
115
116 this._notifyStateChange();
117
118 if (this.container.requestFullscreen) {
119 this.container.requestFullscreen();
120 } else if (this.container.mozRequestFullScreen) {
121 this.container.mozRequestFullScreen();
122 } else if (this.container.webkitRequestFullscreen) {
123 this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
124 } else if (this.container.msRequestFullscreen) {
125 this.container.msRequestFullscreen();
126 } else {
127 return false;
128 }
129
130 this.args = {
131 page: this.pdfViewer.currentPageNumber,
132 previousScale: this.pdfViewer.currentScaleValue
133 };
134 return true;
135 }
136 }, {
137 key: "_mouseWheel",
138 value: function _mouseWheel(evt) {
139 if (!this.active) {
140 return;
141 }
142
143 evt.preventDefault();
144 var delta = (0, _ui_utils.normalizeWheelEventDelta)(evt);
145 var currentTime = new Date().getTime();
146 var storedTime = this.mouseScrollTimeStamp;
147
148 if (currentTime > storedTime && currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) {
149 return;
150 }
151
152 if (this.mouseScrollDelta > 0 && delta < 0 || this.mouseScrollDelta < 0 && delta > 0) {
153 this._resetMouseScrollState();
154 }
155
156 this.mouseScrollDelta += delta;
157
158 if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) {
159 var totalDelta = this.mouseScrollDelta;
160
161 this._resetMouseScrollState();
162
163 var success = totalDelta > 0 ? this._goToPreviousPage() : this._goToNextPage();
164
165 if (success) {
166 this.mouseScrollTimeStamp = currentTime;
167 }
168 }
169 }
170 }, {
171 key: "_goToPreviousPage",
172 value: function _goToPreviousPage() {
173 var page = this.pdfViewer.currentPageNumber;
174
175 if (page <= 1) {
176 return false;
177 }
178
179 this.pdfViewer.currentPageNumber = page - 1;
180 return true;
181 }
182 }, {
183 key: "_goToNextPage",
184 value: function _goToNextPage() {
185 var page = this.pdfViewer.currentPageNumber;
186
187 if (page >= this.pdfViewer.pagesCount) {
188 return false;
189 }
190
191 this.pdfViewer.currentPageNumber = page + 1;
192 return true;
193 }
194 }, {
195 key: "_notifyStateChange",
196 value: function _notifyStateChange() {
197 this.eventBus.dispatch('presentationmodechanged', {
198 source: this,
199 active: this.active,
200 switchInProgress: !!this.switchInProgress
201 });
202 }
203 }, {
204 key: "_setSwitchInProgress",
205 value: function _setSwitchInProgress() {
206 var _this2 = this;
207
208 if (this.switchInProgress) {
209 clearTimeout(this.switchInProgress);
210 }
211
212 this.switchInProgress = setTimeout(function () {
213 _this2._removeFullscreenChangeListeners();
214
215 delete _this2.switchInProgress;
216
217 _this2._notifyStateChange();
218 }, DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS);
219 }
220 }, {
221 key: "_resetSwitchInProgress",
222 value: function _resetSwitchInProgress() {
223 if (this.switchInProgress) {
224 clearTimeout(this.switchInProgress);
225 delete this.switchInProgress;
226 }
227 }
228 }, {
229 key: "_enter",
230 value: function _enter() {
231 var _this3 = this;
232
233 this.active = true;
234
235 this._resetSwitchInProgress();
236
237 this._notifyStateChange();
238
239 this.container.classList.add(ACTIVE_SELECTOR);
240 setTimeout(function () {
241 _this3.pdfViewer.currentPageNumber = _this3.args.page;
242 _this3.pdfViewer.currentScaleValue = 'page-fit';
243 }, 0);
244
245 this._addWindowListeners();
246
247 this._showControls();
248
249 this.contextMenuOpen = false;
250 this.container.setAttribute('contextmenu', 'viewerContextMenu');
251 window.getSelection().removeAllRanges();
252 }
253 }, {
254 key: "_exit",
255 value: function _exit() {
256 var _this4 = this;
257
258 var page = this.pdfViewer.currentPageNumber;
259 this.container.classList.remove(ACTIVE_SELECTOR);
260 setTimeout(function () {
261 _this4.active = false;
262
263 _this4._removeFullscreenChangeListeners();
264
265 _this4._notifyStateChange();
266
267 _this4.pdfViewer.currentScaleValue = _this4.args.previousScale;
268 _this4.pdfViewer.currentPageNumber = page;
269 _this4.args = null;
270 }, 0);
271
272 this._removeWindowListeners();
273
274 this._hideControls();
275
276 this._resetMouseScrollState();
277
278 this.container.removeAttribute('contextmenu');
279 this.contextMenuOpen = false;
280 }
281 }, {
282 key: "_mouseDown",
283 value: function _mouseDown(evt) {
284 if (this.contextMenuOpen) {
285 this.contextMenuOpen = false;
286 evt.preventDefault();
287 return;
288 }
289
290 if (evt.button === 0) {
291 var isInternalLink = evt.target.href && evt.target.classList.contains('internalLink');
292
293 if (!isInternalLink) {
294 evt.preventDefault();
295
296 if (evt.shiftKey) {
297 this._goToPreviousPage();
298 } else {
299 this._goToNextPage();
300 }
301 }
302 }
303 }
304 }, {
305 key: "_contextMenu",
306 value: function _contextMenu() {
307 this.contextMenuOpen = true;
308 }
309 }, {
310 key: "_showControls",
311 value: function _showControls() {
312 var _this5 = this;
313
314 if (this.controlsTimeout) {
315 clearTimeout(this.controlsTimeout);
316 } else {
317 this.container.classList.add(CONTROLS_SELECTOR);
318 }
319
320 this.controlsTimeout = setTimeout(function () {
321 _this5.container.classList.remove(CONTROLS_SELECTOR);
322
323 delete _this5.controlsTimeout;
324 }, DELAY_BEFORE_HIDING_CONTROLS);
325 }
326 }, {
327 key: "_hideControls",
328 value: function _hideControls() {
329 if (!this.controlsTimeout) {
330 return;
331 }
332
333 clearTimeout(this.controlsTimeout);
334 this.container.classList.remove(CONTROLS_SELECTOR);
335 delete this.controlsTimeout;
336 }
337 }, {
338 key: "_resetMouseScrollState",
339 value: function _resetMouseScrollState() {
340 this.mouseScrollTimeStamp = 0;
341 this.mouseScrollDelta = 0;
342 }
343 }, {
344 key: "_touchSwipe",
345 value: function _touchSwipe(evt) {
346 if (!this.active) {
347 return;
348 }
349
350 if (evt.touches.length > 1) {
351 this.touchSwipeState = null;
352 return;
353 }
354
355 switch (evt.type) {
356 case 'touchstart':
357 this.touchSwipeState = {
358 startX: evt.touches[0].pageX,
359 startY: evt.touches[0].pageY,
360 endX: evt.touches[0].pageX,
361 endY: evt.touches[0].pageY
362 };
363 break;
364
365 case 'touchmove':
366 if (this.touchSwipeState === null) {
367 return;
368 }
369
370 this.touchSwipeState.endX = evt.touches[0].pageX;
371 this.touchSwipeState.endY = evt.touches[0].pageY;
372 evt.preventDefault();
373 break;
374
375 case 'touchend':
376 if (this.touchSwipeState === null) {
377 return;
378 }
379
380 var delta = 0;
381 var dx = this.touchSwipeState.endX - this.touchSwipeState.startX;
382 var dy = this.touchSwipeState.endY - this.touchSwipeState.startY;
383 var absAngle = Math.abs(Math.atan2(dy, dx));
384
385 if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD && (absAngle <= SWIPE_ANGLE_THRESHOLD || absAngle >= Math.PI - SWIPE_ANGLE_THRESHOLD)) {
386 delta = dx;
387 } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD && Math.abs(absAngle - Math.PI / 2) <= SWIPE_ANGLE_THRESHOLD) {
388 delta = dy;
389 }
390
391 if (delta > 0) {
392 this._goToPreviousPage();
393 } else if (delta < 0) {
394 this._goToNextPage();
395 }
396
397 break;
398 }
399 }
400 }, {
401 key: "_addWindowListeners",
402 value: function _addWindowListeners() {
403 this.showControlsBind = this._showControls.bind(this);
404 this.mouseDownBind = this._mouseDown.bind(this);
405 this.mouseWheelBind = this._mouseWheel.bind(this);
406 this.resetMouseScrollStateBind = this._resetMouseScrollState.bind(this);
407 this.contextMenuBind = this._contextMenu.bind(this);
408 this.touchSwipeBind = this._touchSwipe.bind(this);
409 window.addEventListener('mousemove', this.showControlsBind);
410 window.addEventListener('mousedown', this.mouseDownBind);
411 window.addEventListener('wheel', this.mouseWheelBind);
412 window.addEventListener('keydown', this.resetMouseScrollStateBind);
413 window.addEventListener('contextmenu', this.contextMenuBind);
414 window.addEventListener('touchstart', this.touchSwipeBind);
415 window.addEventListener('touchmove', this.touchSwipeBind);
416 window.addEventListener('touchend', this.touchSwipeBind);
417 }
418 }, {
419 key: "_removeWindowListeners",
420 value: function _removeWindowListeners() {
421 window.removeEventListener('mousemove', this.showControlsBind);
422 window.removeEventListener('mousedown', this.mouseDownBind);
423 window.removeEventListener('wheel', this.mouseWheelBind);
424 window.removeEventListener('keydown', this.resetMouseScrollStateBind);
425 window.removeEventListener('contextmenu', this.contextMenuBind);
426 window.removeEventListener('touchstart', this.touchSwipeBind);
427 window.removeEventListener('touchmove', this.touchSwipeBind);
428 window.removeEventListener('touchend', this.touchSwipeBind);
429 delete this.showControlsBind;
430 delete this.mouseDownBind;
431 delete this.mouseWheelBind;
432 delete this.resetMouseScrollStateBind;
433 delete this.contextMenuBind;
434 delete this.touchSwipeBind;
435 }
436 }, {
437 key: "_fullscreenChange",
438 value: function _fullscreenChange() {
439 if (this.isFullscreen) {
440 this._enter();
441 } else {
442 this._exit();
443 }
444 }
445 }, {
446 key: "_addFullscreenChangeListeners",
447 value: function _addFullscreenChangeListeners() {
448 this.fullscreenChangeBind = this._fullscreenChange.bind(this);
449 window.addEventListener('fullscreenchange', this.fullscreenChangeBind);
450 window.addEventListener('mozfullscreenchange', this.fullscreenChangeBind);
451 window.addEventListener('webkitfullscreenchange', this.fullscreenChangeBind);
452 window.addEventListener('MSFullscreenChange', this.fullscreenChangeBind);
453 }
454 }, {
455 key: "_removeFullscreenChangeListeners",
456 value: function _removeFullscreenChangeListeners() {
457 window.removeEventListener('fullscreenchange', this.fullscreenChangeBind);
458 window.removeEventListener('mozfullscreenchange', this.fullscreenChangeBind);
459 window.removeEventListener('webkitfullscreenchange', this.fullscreenChangeBind);
460 window.removeEventListener('MSFullscreenChange', this.fullscreenChangeBind);
461 delete this.fullscreenChangeBind;
462 }
463 }, {
464 key: "isFullscreen",
465 get: function get() {
466 return !!(document.fullscreenElement || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement);
467 }
468 }]);
469
470 return PDFPresentationMode;
471}();
472
473exports.PDFPresentationMode = PDFPresentationMode;
\No newline at end of file