UNPKG

19 kBJavaScriptView Raw
1/**
2 * @licstart The following is the entire license notice for the
3 * Javascript code in this page
4 *
5 * Copyright 2017 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.waitOnEventOrTimeout = exports.WaitOnType = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.getPageSizeInches = exports.roundToDivide = exports.getVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.TextLayerMode = exports.RendererType = exports.PresentationModeState = exports.cloneObj = exports.isFileSchema = exports.isPortraitOrientation = exports.isValidRotation = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined;
28
29var _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
30
31var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
32
33var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
34
35var _pdf = require('../pdf');
36
37function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
38
39var CSS_UNITS = 96.0 / 72.0;
40var DEFAULT_SCALE_VALUE = 'auto';
41var DEFAULT_SCALE = 1.0;
42var MIN_SCALE = 0.10;
43var MAX_SCALE = 10.0;
44var UNKNOWN_SCALE = 0;
45var MAX_AUTO_SCALE = 1.25;
46var SCROLLBAR_PADDING = 40;
47var VERTICAL_PADDING = 5;
48var PresentationModeState = {
49 UNKNOWN: 0,
50 NORMAL: 1,
51 CHANGING: 2,
52 FULLSCREEN: 3
53};
54var RendererType = {
55 CANVAS: 'canvas',
56 SVG: 'svg'
57};
58var TextLayerMode = {
59 DISABLE: 0,
60 ENABLE: 1,
61 ENABLE_ENHANCE: 2
62};
63function formatL10nValue(text, args) {
64 if (!args) {
65 return text;
66 }
67 return text.replace(/\{\{\s*(\w+)\s*\}\}/g, function (all, name) {
68 return name in args ? args[name] : '{{' + name + '}}';
69 });
70}
71var NullL10n = {
72 getLanguage: function getLanguage() {
73 return Promise.resolve('en-us');
74 },
75 getDirection: function getDirection() {
76 return Promise.resolve('ltr');
77 },
78 get: function get(property, args, fallback) {
79 return Promise.resolve(formatL10nValue(fallback, args));
80 },
81 translate: function translate(element) {
82 return Promise.resolve();
83 }
84};
85function getOutputScale(ctx) {
86 var devicePixelRatio = window.devicePixelRatio || 1;
87 var backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
88 var pixelRatio = devicePixelRatio / backingStoreRatio;
89 return {
90 sx: pixelRatio,
91 sy: pixelRatio,
92 scaled: pixelRatio !== 1
93 };
94}
95function scrollIntoView(element, spot) {
96 var skipOverflowHiddenElements = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
97
98 var parent = element.offsetParent;
99 if (!parent) {
100 console.error('offsetParent is not set -- cannot scroll');
101 return;
102 }
103 var offsetY = element.offsetTop + element.clientTop;
104 var offsetX = element.offsetLeft + element.clientLeft;
105 while (parent.clientHeight === parent.scrollHeight || skipOverflowHiddenElements && getComputedStyle(parent).overflow === 'hidden') {
106 if (parent.dataset._scaleY) {
107 offsetY /= parent.dataset._scaleY;
108 offsetX /= parent.dataset._scaleX;
109 }
110 offsetY += parent.offsetTop;
111 offsetX += parent.offsetLeft;
112 parent = parent.offsetParent;
113 if (!parent) {
114 return;
115 }
116 }
117 if (spot) {
118 if (spot.top !== undefined) {
119 offsetY += spot.top;
120 }
121 if (spot.left !== undefined) {
122 offsetX += spot.left;
123 parent.scrollLeft = offsetX;
124 }
125 }
126 parent.scrollTop = offsetY;
127}
128function watchScroll(viewAreaElement, callback) {
129 var debounceScroll = function debounceScroll(evt) {
130 if (rAF) {
131 return;
132 }
133 rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {
134 rAF = null;
135 var currentY = viewAreaElement.scrollTop;
136 var lastY = state.lastY;
137 if (currentY !== lastY) {
138 state.down = currentY > lastY;
139 }
140 state.lastY = currentY;
141 callback(state);
142 });
143 };
144 var state = {
145 down: true,
146 lastY: viewAreaElement.scrollTop,
147 _eventHandler: debounceScroll
148 };
149 var rAF = null;
150 viewAreaElement.addEventListener('scroll', debounceScroll, true);
151 return state;
152}
153function parseQueryString(query) {
154 var parts = query.split('&');
155 var params = Object.create(null);
156 for (var i = 0, ii = parts.length; i < ii; ++i) {
157 var param = parts[i].split('=');
158 var key = param[0].toLowerCase();
159 var value = param.length > 1 ? param[1] : null;
160 params[decodeURIComponent(key)] = decodeURIComponent(value);
161 }
162 return params;
163}
164function binarySearchFirstItem(items, condition) {
165 var minIndex = 0;
166 var maxIndex = items.length - 1;
167 if (items.length === 0 || !condition(items[maxIndex])) {
168 return items.length;
169 }
170 if (condition(items[minIndex])) {
171 return minIndex;
172 }
173 while (minIndex < maxIndex) {
174 var currentIndex = minIndex + maxIndex >> 1;
175 var currentItem = items[currentIndex];
176 if (condition(currentItem)) {
177 maxIndex = currentIndex;
178 } else {
179 minIndex = currentIndex + 1;
180 }
181 }
182 return minIndex;
183}
184function approximateFraction(x) {
185 if (Math.floor(x) === x) {
186 return [x, 1];
187 }
188 var xinv = 1 / x;
189 var limit = 8;
190 if (xinv > limit) {
191 return [1, limit];
192 } else if (Math.floor(xinv) === xinv) {
193 return [1, xinv];
194 }
195 var x_ = x > 1 ? xinv : x;
196 var a = 0,
197 b = 1,
198 c = 1,
199 d = 1;
200 while (true) {
201 var p = a + c,
202 q = b + d;
203 if (q > limit) {
204 break;
205 }
206 if (x_ <= p / q) {
207 c = p;
208 d = q;
209 } else {
210 a = p;
211 b = q;
212 }
213 }
214 var result = void 0;
215 if (x_ - a / b < c / d - x_) {
216 result = x_ === x ? [a, b] : [b, a];
217 } else {
218 result = x_ === x ? [c, d] : [d, c];
219 }
220 return result;
221}
222function roundToDivide(x, div) {
223 var r = x % div;
224 return r === 0 ? x : Math.round(x - r + div);
225}
226function getPageSizeInches(_ref) {
227 var view = _ref.view,
228 userUnit = _ref.userUnit,
229 rotate = _ref.rotate;
230
231 var _view = _slicedToArray(view, 4),
232 x1 = _view[0],
233 y1 = _view[1],
234 x2 = _view[2],
235 y2 = _view[3];
236
237 var changeOrientation = rotate % 180 !== 0;
238 var width = (x2 - x1) / 72 * userUnit;
239 var height = (y2 - y1) / 72 * userUnit;
240 return {
241 width: changeOrientation ? height : width,
242 height: changeOrientation ? width : height
243 };
244}
245function getVisibleElements(scrollEl, views) {
246 var sortByVisibility = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
247
248 var top = scrollEl.scrollTop,
249 bottom = top + scrollEl.clientHeight;
250 var left = scrollEl.scrollLeft,
251 right = left + scrollEl.clientWidth;
252 function isElementBottomBelowViewTop(view) {
253 var element = view.div;
254 var elementBottom = element.offsetTop + element.clientTop + element.clientHeight;
255 return elementBottom > top;
256 }
257 var visible = [],
258 view = void 0,
259 element = void 0;
260 var currentHeight = void 0,
261 viewHeight = void 0,
262 hiddenHeight = void 0,
263 percentHeight = void 0;
264 var currentWidth = void 0,
265 viewWidth = void 0;
266 var firstVisibleElementInd = views.length === 0 ? 0 : binarySearchFirstItem(views, isElementBottomBelowViewTop);
267 for (var i = firstVisibleElementInd, ii = views.length; i < ii; i++) {
268 view = views[i];
269 element = view.div;
270 currentHeight = element.offsetTop + element.clientTop;
271 viewHeight = element.clientHeight;
272 if (currentHeight > bottom) {
273 break;
274 }
275 currentWidth = element.offsetLeft + element.clientLeft;
276 viewWidth = element.clientWidth;
277 if (currentWidth + viewWidth < left || currentWidth > right) {
278 continue;
279 }
280 hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, currentHeight + viewHeight - bottom);
281 percentHeight = (viewHeight - hiddenHeight) * 100 / viewHeight | 0;
282 visible.push({
283 id: view.id,
284 x: currentWidth,
285 y: currentHeight,
286 view: view,
287 percent: percentHeight
288 });
289 }
290 var first = visible[0];
291 var last = visible[visible.length - 1];
292 if (sortByVisibility) {
293 visible.sort(function (a, b) {
294 var pc = a.percent - b.percent;
295 if (Math.abs(pc) > 0.001) {
296 return -pc;
297 }
298 return a.id - b.id;
299 });
300 }
301 return {
302 first: first,
303 last: last,
304 views: visible
305 };
306}
307function noContextMenuHandler(evt) {
308 evt.preventDefault();
309}
310function isFileSchema(url) {
311 var i = 0,
312 ii = url.length;
313 while (i < ii && url[i].trim() === '') {
314 i++;
315 }
316 return url.substr(i, 7).toLowerCase() === 'file://';
317}
318function isDataSchema(url) {
319 var i = 0,
320 ii = url.length;
321 while (i < ii && url[i].trim() === '') {
322 i++;
323 }
324 return url.substr(i, 5).toLowerCase() === 'data:';
325}
326function getPDFFileNameFromURL(url) {
327 var defaultFilename = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'document.pdf';
328
329 if (isDataSchema(url)) {
330 console.warn('getPDFFileNameFromURL: ' + 'ignoring "data:" URL for performance reasons.');
331 return defaultFilename;
332 }
333 var reURI = /^(?:(?:[^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
334 var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
335 var splitURI = reURI.exec(url);
336 var suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]);
337 if (suggestedFilename) {
338 suggestedFilename = suggestedFilename[0];
339 if (suggestedFilename.includes('%')) {
340 try {
341 suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0];
342 } catch (ex) {}
343 }
344 }
345 return suggestedFilename || defaultFilename;
346}
347function normalizeWheelEventDelta(evt) {
348 var delta = Math.sqrt(evt.deltaX * evt.deltaX + evt.deltaY * evt.deltaY);
349 var angle = Math.atan2(evt.deltaY, evt.deltaX);
350 if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {
351 delta = -delta;
352 }
353 var MOUSE_DOM_DELTA_PIXEL_MODE = 0;
354 var MOUSE_DOM_DELTA_LINE_MODE = 1;
355 var MOUSE_PIXELS_PER_LINE = 30;
356 var MOUSE_LINES_PER_PAGE = 30;
357 if (evt.deltaMode === MOUSE_DOM_DELTA_PIXEL_MODE) {
358 delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE;
359 } else if (evt.deltaMode === MOUSE_DOM_DELTA_LINE_MODE) {
360 delta /= MOUSE_LINES_PER_PAGE;
361 }
362 return delta;
363}
364function isValidRotation(angle) {
365 return Number.isInteger(angle) && angle % 90 === 0;
366}
367function isPortraitOrientation(size) {
368 return size.width <= size.height;
369}
370function cloneObj(obj) {
371 var result = Object.create(null);
372 for (var i in obj) {
373 if (Object.prototype.hasOwnProperty.call(obj, i)) {
374 result[i] = obj[i];
375 }
376 }
377 return result;
378}
379var WaitOnType = {
380 EVENT: 'event',
381 TIMEOUT: 'timeout'
382};
383function waitOnEventOrTimeout(_ref2) {
384 var target = _ref2.target,
385 name = _ref2.name,
386 _ref2$delay = _ref2.delay,
387 delay = _ref2$delay === undefined ? 0 : _ref2$delay;
388
389 if ((typeof target === 'undefined' ? 'undefined' : _typeof(target)) !== 'object' || !(name && typeof name === 'string') || !(Number.isInteger(delay) && delay >= 0)) {
390 return Promise.reject(new Error('waitOnEventOrTimeout - invalid parameters.'));
391 }
392 var capability = (0, _pdf.createPromiseCapability)();
393 function handler(type) {
394 if (target instanceof EventBus) {
395 target.off(name, eventHandler);
396 } else {
397 target.removeEventListener(name, eventHandler);
398 }
399 if (timeout) {
400 clearTimeout(timeout);
401 }
402 capability.resolve(type);
403 }
404 var eventHandler = handler.bind(null, WaitOnType.EVENT);
405 if (target instanceof EventBus) {
406 target.on(name, eventHandler);
407 } else {
408 target.addEventListener(name, eventHandler);
409 }
410 var timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT);
411 var timeout = setTimeout(timeoutHandler, delay);
412 return capability.promise;
413}
414var animationStarted = new Promise(function (resolve) {
415 window.requestAnimationFrame(resolve);
416});
417
418var EventBus = function () {
419 function EventBus() {
420 _classCallCheck(this, EventBus);
421
422 this._listeners = Object.create(null);
423 }
424
425 _createClass(EventBus, [{
426 key: 'on',
427 value: function on(eventName, listener) {
428 var eventListeners = this._listeners[eventName];
429 if (!eventListeners) {
430 eventListeners = [];
431 this._listeners[eventName] = eventListeners;
432 }
433 eventListeners.push(listener);
434 }
435 }, {
436 key: 'off',
437 value: function off(eventName, listener) {
438 var eventListeners = this._listeners[eventName];
439 var i = void 0;
440 if (!eventListeners || (i = eventListeners.indexOf(listener)) < 0) {
441 return;
442 }
443 eventListeners.splice(i, 1);
444 }
445 }, {
446 key: 'dispatch',
447 value: function dispatch(eventName) {
448 var eventListeners = this._listeners[eventName];
449 if (!eventListeners || eventListeners.length === 0) {
450 return;
451 }
452 var args = Array.prototype.slice.call(arguments, 1);
453 eventListeners.slice(0).forEach(function (listener) {
454 listener.apply(null, args);
455 });
456 }
457 }]);
458
459 return EventBus;
460}();
461
462function clamp(v, min, max) {
463 return Math.min(Math.max(v, min), max);
464}
465
466var ProgressBar = function () {
467 function ProgressBar(id) {
468 var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
469 height = _ref3.height,
470 width = _ref3.width,
471 units = _ref3.units;
472
473 _classCallCheck(this, ProgressBar);
474
475 this.visible = true;
476 this.div = document.querySelector(id + ' .progress');
477 this.bar = this.div.parentNode;
478 this.height = height || 100;
479 this.width = width || 100;
480 this.units = units || '%';
481 this.div.style.height = this.height + this.units;
482 this.percent = 0;
483 }
484
485 _createClass(ProgressBar, [{
486 key: '_updateBar',
487 value: function _updateBar() {
488 if (this._indeterminate) {
489 this.div.classList.add('indeterminate');
490 this.div.style.width = this.width + this.units;
491 return;
492 }
493 this.div.classList.remove('indeterminate');
494 var progressSize = this.width * this._percent / 100;
495 this.div.style.width = progressSize + this.units;
496 }
497 }, {
498 key: 'setWidth',
499 value: function setWidth(viewer) {
500 if (!viewer) {
501 return;
502 }
503 var container = viewer.parentNode;
504 var scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
505 if (scrollbarWidth > 0) {
506 this.bar.setAttribute('style', 'width: calc(100% - ' + scrollbarWidth + 'px);');
507 }
508 }
509 }, {
510 key: 'hide',
511 value: function hide() {
512 if (!this.visible) {
513 return;
514 }
515 this.visible = false;
516 this.bar.classList.add('hidden');
517 document.body.classList.remove('loadingInProgress');
518 }
519 }, {
520 key: 'show',
521 value: function show() {
522 if (this.visible) {
523 return;
524 }
525 this.visible = true;
526 document.body.classList.add('loadingInProgress');
527 this.bar.classList.remove('hidden');
528 }
529 }, {
530 key: 'percent',
531 get: function get() {
532 return this._percent;
533 },
534 set: function set(val) {
535 this._indeterminate = isNaN(val);
536 this._percent = clamp(val, 0, 100);
537 this._updateBar();
538 }
539 }]);
540
541 return ProgressBar;
542}();
543
544exports.CSS_UNITS = CSS_UNITS;
545exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE;
546exports.DEFAULT_SCALE = DEFAULT_SCALE;
547exports.MIN_SCALE = MIN_SCALE;
548exports.MAX_SCALE = MAX_SCALE;
549exports.UNKNOWN_SCALE = UNKNOWN_SCALE;
550exports.MAX_AUTO_SCALE = MAX_AUTO_SCALE;
551exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING;
552exports.VERTICAL_PADDING = VERTICAL_PADDING;
553exports.isValidRotation = isValidRotation;
554exports.isPortraitOrientation = isPortraitOrientation;
555exports.isFileSchema = isFileSchema;
556exports.cloneObj = cloneObj;
557exports.PresentationModeState = PresentationModeState;
558exports.RendererType = RendererType;
559exports.TextLayerMode = TextLayerMode;
560exports.NullL10n = NullL10n;
561exports.EventBus = EventBus;
562exports.ProgressBar = ProgressBar;
563exports.getPDFFileNameFromURL = getPDFFileNameFromURL;
564exports.noContextMenuHandler = noContextMenuHandler;
565exports.parseQueryString = parseQueryString;
566exports.getVisibleElements = getVisibleElements;
567exports.roundToDivide = roundToDivide;
568exports.getPageSizeInches = getPageSizeInches;
569exports.approximateFraction = approximateFraction;
570exports.getOutputScale = getOutputScale;
571exports.scrollIntoView = scrollIntoView;
572exports.watchScroll = watchScroll;
573exports.binarySearchFirstItem = binarySearchFirstItem;
574exports.normalizeWheelEventDelta = normalizeWheelEventDelta;
575exports.animationStarted = animationStarted;
576exports.WaitOnType = WaitOnType;
577exports.waitOnEventOrTimeout = waitOnEventOrTimeout;
\No newline at end of file