@vaadin-component-factory/vcf-pdf-viewer 0.9.0 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +1 -1
  2. package/package.json +33 -18
  3. package/{src/display → pdfjs/dist}/display_utils.js +344 -139
  4. package/{src/display → pdfjs/dist}/fetch_stream.js +115 -97
  5. package/pdfjs/dist/get.js +1857 -0
  6. package/pdfjs/dist/index.js +767 -0
  7. package/pdfjs/dist/l10n_utils.js +140 -0
  8. package/{src/shared → pdfjs/dist}/message_handler.js +243 -259
  9. package/{src/display → pdfjs/dist}/network.js +149 -87
  10. package/{src/display/content_disposition.js → pdfjs/dist/network_utils.js} +167 -55
  11. package/{src/display → pdfjs/dist}/node_stream.js +133 -98
  12. package/pdfjs/dist/pdf.js +12778 -0
  13. package/pdfjs/dist/pdf_link_service.js +638 -0
  14. package/pdfjs/dist/pdf_rendering_queue.js +199 -0
  15. package/pdfjs/dist/pdf_thumbnail_viewer.js +819 -0
  16. package/pdfjs/dist/pdf_viewer.js +3598 -0
  17. package/pdfjs/dist/typeof.js +100 -0
  18. package/pdfjs/dist/ui_utils.js +1033 -0
  19. package/{src/shared → pdfjs/dist}/util.js +301 -287
  20. package/pdfjs/dist/worker.js +62813 -0
  21. package/src/vcf-pdf-viewer.js +77 -27
  22. package/theme/lumo/vcf-pdf-viewer-styles.js +1 -1
  23. package/theme/material/vcf-pdf-viewer.js +2 -2
  24. package/src/core/.eslintrc +0 -13
  25. package/src/core/annotation.js +0 -2948
  26. package/src/core/arithmetic_decoder.js +0 -182
  27. package/src/core/ascii_85_stream.js +0 -98
  28. package/src/core/ascii_hex_stream.js +0 -79
  29. package/src/core/base_stream.js +0 -110
  30. package/src/core/bidi.js +0 -438
  31. package/src/core/calibri_factors.js +0 -308
  32. package/src/core/catalog.js +0 -1459
  33. package/src/core/ccitt.js +0 -1062
  34. package/src/core/ccitt_stream.js +0 -60
  35. package/src/core/cff_font.js +0 -116
  36. package/src/core/cff_parser.js +0 -1949
  37. package/src/core/charsets.js +0 -119
  38. package/src/core/chunked_stream.js +0 -557
  39. package/src/core/cmap.js +0 -1039
  40. package/src/core/colorspace.js +0 -1533
  41. package/src/core/core_utils.js +0 -464
  42. package/src/core/crypto.js +0 -1900
  43. package/src/core/decode_stream.js +0 -170
  44. package/src/core/decrypt_stream.js +0 -59
  45. package/src/core/default_appearance.js +0 -99
  46. package/src/core/document.js +0 -1456
  47. package/src/core/encodings.js +0 -301
  48. package/src/core/evaluator.js +0 -4601
  49. package/src/core/file_spec.js +0 -108
  50. package/src/core/flate_stream.js +0 -402
  51. package/src/core/font_renderer.js +0 -882
  52. package/src/core/fonts.js +0 -3260
  53. package/src/core/fonts_utils.js +0 -221
  54. package/src/core/function.js +0 -1257
  55. package/src/core/glyf.js +0 -706
  56. package/src/core/glyphlist.js +0 -4558
  57. package/src/core/helvetica_factors.js +0 -353
  58. package/src/core/image.js +0 -802
  59. package/src/core/image_utils.js +0 -291
  60. package/src/core/jbig2.js +0 -2572
  61. package/src/core/jbig2_stream.js +0 -73
  62. package/src/core/jpeg_stream.js +0 -105
  63. package/src/core/jpg.js +0 -1416
  64. package/src/core/jpx.js +0 -2343
  65. package/src/core/jpx_stream.js +0 -87
  66. package/src/core/liberationsans_widths.js +0 -221
  67. package/src/core/lzw_stream.js +0 -150
  68. package/src/core/metadata_parser.js +0 -146
  69. package/src/core/metrics.js +0 -2970
  70. package/src/core/murmurhash3.js +0 -139
  71. package/src/core/myriadpro_factors.js +0 -290
  72. package/src/core/name_number_tree.js +0 -153
  73. package/src/core/object_loader.js +0 -149
  74. package/src/core/opentype_file_builder.js +0 -154
  75. package/src/core/operator_list.js +0 -734
  76. package/src/core/parser.js +0 -1416
  77. package/src/core/pattern.js +0 -985
  78. package/src/core/pdf_manager.js +0 -217
  79. package/src/core/predictor_stream.js +0 -238
  80. package/src/core/primitives.js +0 -402
  81. package/src/core/ps_parser.js +0 -272
  82. package/src/core/run_length_stream.js +0 -61
  83. package/src/core/segoeui_factors.js +0 -308
  84. package/src/core/standard_fonts.js +0 -817
  85. package/src/core/stream.js +0 -103
  86. package/src/core/struct_tree.js +0 -335
  87. package/src/core/to_unicode_map.js +0 -103
  88. package/src/core/type1_font.js +0 -421
  89. package/src/core/type1_parser.js +0 -776
  90. package/src/core/unicode.js +0 -1649
  91. package/src/core/worker.js +0 -848
  92. package/src/core/worker_stream.js +0 -135
  93. package/src/core/writer.js +0 -278
  94. package/src/core/xfa/bind.js +0 -652
  95. package/src/core/xfa/builder.js +0 -207
  96. package/src/core/xfa/config.js +0 -1926
  97. package/src/core/xfa/connection_set.js +0 -202
  98. package/src/core/xfa/data.js +0 -82
  99. package/src/core/xfa/datasets.js +0 -76
  100. package/src/core/xfa/factory.js +0 -111
  101. package/src/core/xfa/fonts.js +0 -181
  102. package/src/core/xfa/formcalc_lexer.js +0 -385
  103. package/src/core/xfa/formcalc_parser.js +0 -1340
  104. package/src/core/xfa/html_utils.js +0 -639
  105. package/src/core/xfa/layout.js +0 -383
  106. package/src/core/xfa/locale_set.js +0 -345
  107. package/src/core/xfa/namespaces.js +0 -81
  108. package/src/core/xfa/parser.js +0 -184
  109. package/src/core/xfa/setup.js +0 -38
  110. package/src/core/xfa/signature.js +0 -40
  111. package/src/core/xfa/som.js +0 -338
  112. package/src/core/xfa/stylesheet.js +0 -40
  113. package/src/core/xfa/template.js +0 -6260
  114. package/src/core/xfa/text.js +0 -290
  115. package/src/core/xfa/unknown.js +0 -29
  116. package/src/core/xfa/utils.js +0 -217
  117. package/src/core/xfa/xdp.js +0 -59
  118. package/src/core/xfa/xfa_object.js +0 -1130
  119. package/src/core/xfa/xhtml.js +0 -543
  120. package/src/core/xfa_fonts.js +0 -208
  121. package/src/core/xml_parser.js +0 -507
  122. package/src/core/xref.js +0 -899
  123. package/src/display/annotation_layer.js +0 -2107
  124. package/src/display/annotation_storage.js +0 -113
  125. package/src/display/api.js +0 -3292
  126. package/src/display/base_factory.js +0 -180
  127. package/src/display/canvas.js +0 -2828
  128. package/src/display/font_loader.js +0 -484
  129. package/src/display/metadata.js +0 -41
  130. package/src/display/network_utils.js +0 -100
  131. package/src/display/node_utils.js +0 -83
  132. package/src/display/optional_content_config.js +0 -189
  133. package/src/display/pattern_helper.js +0 -659
  134. package/src/display/svg.js +0 -1709
  135. package/src/display/text_layer.js +0 -847
  136. package/src/display/transport_stream.js +0 -303
  137. package/src/display/worker_options.js +0 -40
  138. package/src/display/xfa_layer.js +0 -204
  139. package/src/doc_helper.js +0 -25
  140. package/src/images/logo.svg +0 -41
  141. package/src/interfaces.js +0 -169
  142. package/src/license_header.js +0 -14
  143. package/src/license_header_libre.js +0 -21
  144. package/src/pdf.image_decoders.js +0 -46
  145. package/src/pdf.js +0 -146
  146. package/src/pdf.sandbox.external.js +0 -181
  147. package/src/pdf.sandbox.js +0 -151
  148. package/src/pdf.scripting.js +0 -25
  149. package/src/pdf.worker.entry.js +0 -19
  150. package/src/pdf.worker.js +0 -23
  151. package/src/scripting_api/aform.js +0 -608
  152. package/src/scripting_api/app.js +0 -621
  153. package/src/scripting_api/color.js +0 -129
  154. package/src/scripting_api/common.js +0 -58
  155. package/src/scripting_api/console.js +0 -38
  156. package/src/scripting_api/constants.js +0 -208
  157. package/src/scripting_api/doc.js +0 -1195
  158. package/src/scripting_api/error.js +0 -23
  159. package/src/scripting_api/event.js +0 -232
  160. package/src/scripting_api/field.js +0 -620
  161. package/src/scripting_api/fullscreen.js +0 -145
  162. package/src/scripting_api/initialization.js +0 -223
  163. package/src/scripting_api/pdf_object.js +0 -24
  164. package/src/scripting_api/print_params.js +0 -146
  165. package/src/scripting_api/proxy.js +0 -139
  166. package/src/scripting_api/thermometer.js +0 -69
  167. package/src/scripting_api/util.js +0 -581
  168. package/src/shared/.eslintrc +0 -13
  169. package/src/shared/cffStandardStrings.js +0 -311
  170. package/src/shared/compatibility.js +0 -114
  171. package/src/shared/fonts_utils.js +0 -429
  172. package/src/shared/is_node.js +0 -27
  173. package/src/shared/scripting_utils.js +0 -85
  174. package/src/worker_loader.js +0 -32
@@ -0,0 +1,1033 @@
1
+ /* Copyright 2012 Mozilla Foundation
2
+ *
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+ const CSS_UNITS = 96.0 / 72.0;
16
+ const DEFAULT_SCALE_VALUE = "auto";
17
+ const DEFAULT_SCALE = 1.0;
18
+ const MIN_SCALE = 0.1;
19
+ const MAX_SCALE = 10.0;
20
+ const UNKNOWN_SCALE = 0;
21
+ const MAX_AUTO_SCALE = 1.25;
22
+ const SCROLLBAR_PADDING = 40;
23
+ const VERTICAL_PADDING = 5;
24
+ const LOADINGBAR_END_OFFSET_VAR = "--loadingBar-end-offset";
25
+ const PresentationModeState = {
26
+ UNKNOWN: 0,
27
+ NORMAL: 1,
28
+ CHANGING: 2,
29
+ FULLSCREEN: 3
30
+ };
31
+ const SidebarView = {
32
+ UNKNOWN: -1,
33
+ NONE: 0,
34
+ THUMBS: 1,
35
+ // Default value.
36
+ OUTLINE: 2,
37
+ ATTACHMENTS: 3,
38
+ LAYERS: 4
39
+ };
40
+ const RendererType = {
41
+ CANVAS: "canvas",
42
+ SVG: "svg"
43
+ };
44
+ const TextLayerMode = {
45
+ DISABLE: 0,
46
+ ENABLE: 1,
47
+ ENABLE_ENHANCE: 2
48
+ };
49
+ const ScrollMode = {
50
+ UNKNOWN: -1,
51
+ VERTICAL: 0,
52
+ // Default value.
53
+ HORIZONTAL: 1,
54
+ WRAPPED: 2
55
+ };
56
+ const SpreadMode = {
57
+ UNKNOWN: -1,
58
+ NONE: 0,
59
+ // Default value.
60
+ ODD: 1,
61
+ EVEN: 2
62
+ }; // Used by `PDFViewerApplication`, and by the API unit-tests.
63
+
64
+ const AutoPrintRegExp = /\bprint\s*\(/;
65
+ /**
66
+ * Returns scale factor for the canvas. It makes sense for the HiDPI displays.
67
+ * @returns {Object} The object with horizontal (sx) and vertical (sy)
68
+ * scales. The scaled property is set to false if scaling is
69
+ * not required, true otherwise.
70
+ */
71
+
72
+ function getOutputScale(ctx) {
73
+ const devicePixelRatio = window.devicePixelRatio || 1;
74
+ const backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
75
+ const pixelRatio = devicePixelRatio / backingStoreRatio;
76
+ return {
77
+ sx: pixelRatio,
78
+ sy: pixelRatio,
79
+ scaled: pixelRatio !== 1
80
+ };
81
+ }
82
+ /**
83
+ * Scrolls specified element into view of its parent.
84
+ * @param {Object} element - The element to be visible.
85
+ * @param {Object} spot - An object with optional top and left properties,
86
+ * specifying the offset from the top left edge.
87
+ * @param {boolean} [scrollMatches] - When scrolling search results into view,
88
+ * ignore elements that either: Contains marked content identifiers,
89
+ * or have the CSS-rule `overflow: hidden;` set. The default value is `false`.
90
+ */
91
+
92
+
93
+ function scrollIntoView(element, spot, scrollMatches = false) {
94
+ // Assuming offsetParent is available (it's not available when viewer is in
95
+ // hidden iframe or object). We have to scroll: if the offsetParent is not set
96
+ // producing the error. See also animationStarted.
97
+ let parent = element.offsetParent;
98
+
99
+ if (!parent) {
100
+ console.error("offsetParent is not set -- cannot scroll");
101
+ return;
102
+ }
103
+
104
+ let offsetY = element.offsetTop + element.clientTop;
105
+ let offsetX = element.offsetLeft + element.clientLeft;
106
+
107
+ while (parent.clientHeight === parent.scrollHeight && parent.clientWidth === parent.scrollWidth || scrollMatches && (parent.classList.contains("markedContent") || getComputedStyle(parent).overflow === "hidden")) {
108
+ offsetY += parent.offsetTop;
109
+ offsetX += parent.offsetLeft;
110
+ parent = parent.offsetParent;
111
+
112
+ if (!parent) {
113
+ return; // no need to scroll
114
+ }
115
+ }
116
+
117
+ if (spot) {
118
+ if (spot.top !== undefined) {
119
+ offsetY += spot.top;
120
+ }
121
+
122
+ if (spot.left !== undefined) {
123
+ offsetX += spot.left;
124
+ parent.scrollLeft = offsetX;
125
+ }
126
+ }
127
+
128
+ parent.scrollTop = offsetY;
129
+ }
130
+ /**
131
+ * Helper function to start monitoring the scroll event and converting them into
132
+ * PDF.js friendly one: with scroll debounce and scroll direction.
133
+ */
134
+
135
+
136
+ function watchScroll(viewAreaElement, callback) {
137
+ const debounceScroll = function (evt) {
138
+ if (rAF) {
139
+ return;
140
+ } // schedule an invocation of scroll for next animation frame.
141
+
142
+
143
+ rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {
144
+ rAF = null;
145
+ const currentX = viewAreaElement.scrollLeft;
146
+ const lastX = state.lastX;
147
+
148
+ if (currentX !== lastX) {
149
+ state.right = currentX > lastX;
150
+ }
151
+
152
+ state.lastX = currentX;
153
+ const currentY = viewAreaElement.scrollTop;
154
+ const lastY = state.lastY;
155
+
156
+ if (currentY !== lastY) {
157
+ state.down = currentY > lastY;
158
+ }
159
+
160
+ state.lastY = currentY;
161
+ callback(state);
162
+ });
163
+ };
164
+
165
+ const state = {
166
+ right: true,
167
+ down: true,
168
+ lastX: viewAreaElement.scrollLeft,
169
+ lastY: viewAreaElement.scrollTop,
170
+ _eventHandler: debounceScroll
171
+ };
172
+ let rAF = null;
173
+ viewAreaElement.addEventListener("scroll", debounceScroll, true);
174
+ return state;
175
+ }
176
+ /**
177
+ * Helper function to parse query string (e.g. ?param1=value&parm2=...).
178
+ */
179
+
180
+
181
+ function parseQueryString(query) {
182
+ const parts = query.split("&");
183
+ const params = Object.create(null);
184
+
185
+ for (let i = 0, ii = parts.length; i < ii; ++i) {
186
+ const param = parts[i].split("=");
187
+ const key = param[0].toLowerCase();
188
+ const value = param.length > 1 ? param[1] : null;
189
+ params[decodeURIComponent(key)] = decodeURIComponent(value);
190
+ }
191
+
192
+ return params;
193
+ }
194
+ /**
195
+ * Use binary search to find the index of the first item in a given array which
196
+ * passes a given condition. The items are expected to be sorted in the sense
197
+ * that if the condition is true for one item in the array, then it is also true
198
+ * for all following items.
199
+ *
200
+ * @returns {number} Index of the first array element to pass the test,
201
+ * or |items.length| if no such element exists.
202
+ */
203
+
204
+
205
+ function binarySearchFirstItem(items, condition) {
206
+ let minIndex = 0;
207
+ let maxIndex = items.length - 1;
208
+
209
+ if (maxIndex < 0 || !condition(items[maxIndex])) {
210
+ return items.length;
211
+ }
212
+
213
+ if (condition(items[minIndex])) {
214
+ return minIndex;
215
+ }
216
+
217
+ while (minIndex < maxIndex) {
218
+ const currentIndex = minIndex + maxIndex >> 1;
219
+ const currentItem = items[currentIndex];
220
+
221
+ if (condition(currentItem)) {
222
+ maxIndex = currentIndex;
223
+ } else {
224
+ minIndex = currentIndex + 1;
225
+ }
226
+ }
227
+
228
+ return minIndex;
229
+ /* === maxIndex */
230
+ }
231
+ /**
232
+ * Approximates float number as a fraction using Farey sequence (max order
233
+ * of 8).
234
+ * @param {number} x - Positive float number.
235
+ * @returns {Array} Estimated fraction: the first array item is a numerator,
236
+ * the second one is a denominator.
237
+ */
238
+
239
+
240
+ function approximateFraction(x) {
241
+ // Fast paths for int numbers or their inversions.
242
+ if (Math.floor(x) === x) {
243
+ return [x, 1];
244
+ }
245
+
246
+ const xinv = 1 / x;
247
+ const limit = 8;
248
+
249
+ if (xinv > limit) {
250
+ return [1, limit];
251
+ } else if (Math.floor(xinv) === xinv) {
252
+ return [1, xinv];
253
+ }
254
+
255
+ const x_ = x > 1 ? xinv : x; // a/b and c/d are neighbours in Farey sequence.
256
+
257
+ let a = 0,
258
+ b = 1,
259
+ c = 1,
260
+ d = 1; // Limiting search to order 8.
261
+
262
+ while (true) {
263
+ // Generating next term in sequence (order of q).
264
+ const p = a + c,
265
+ q = b + d;
266
+
267
+ if (q > limit) {
268
+ break;
269
+ }
270
+
271
+ if (x_ <= p / q) {
272
+ c = p;
273
+ d = q;
274
+ } else {
275
+ a = p;
276
+ b = q;
277
+ }
278
+ }
279
+
280
+ let result; // Select closest of the neighbours to x.
281
+
282
+ if (x_ - a / b < c / d - x_) {
283
+ result = x_ === x ? [a, b] : [b, a];
284
+ } else {
285
+ result = x_ === x ? [c, d] : [d, c];
286
+ }
287
+
288
+ return result;
289
+ }
290
+
291
+ function roundToDivide(x, div) {
292
+ const r = x % div;
293
+ return r === 0 ? x : Math.round(x - r + div);
294
+ }
295
+ /**
296
+ * Gets the size of the specified page, converted from PDF units to inches.
297
+ * @param {Object} An Object containing the properties: {Array} `view`,
298
+ * {number} `userUnit`, and {number} `rotate`.
299
+ * @returns {Object} An Object containing the properties: {number} `width`
300
+ * and {number} `height`, given in inches.
301
+ */
302
+
303
+
304
+ function getPageSizeInches({
305
+ view,
306
+ userUnit,
307
+ rotate
308
+ }) {
309
+ const [x1, y1, x2, y2] = view; // We need to take the page rotation into account as well.
310
+
311
+ const changeOrientation = rotate % 180 !== 0;
312
+ const width = (x2 - x1) / 72 * userUnit;
313
+ const height = (y2 - y1) / 72 * userUnit;
314
+ return {
315
+ width: changeOrientation ? height : width,
316
+ height: changeOrientation ? width : height
317
+ };
318
+ }
319
+ /**
320
+ * Helper function for getVisibleElements.
321
+ *
322
+ * @param {number} index - initial guess at the first visible element
323
+ * @param {Array} views - array of pages, into which `index` is an index
324
+ * @param {number} top - the top of the scroll pane
325
+ * @returns {number} less than or equal to `index` that is definitely at or
326
+ * before the first visible element in `views`, but not by too much. (Usually,
327
+ * this will be the first element in the first partially visible row in
328
+ * `views`, although sometimes it goes back one row further.)
329
+ */
330
+
331
+
332
+ function backtrackBeforeAllVisibleElements(index, views, top) {
333
+ // binarySearchFirstItem's assumption is that the input is ordered, with only
334
+ // one index where the conditions flips from false to true: [false ...,
335
+ // true...]. With vertical scrolling and spreads, it is possible to have
336
+ // [false ..., true, false, true ...]. With wrapped scrolling we can have a
337
+ // similar sequence, with many more mixed true and false in the middle.
338
+ //
339
+ // So there is no guarantee that the binary search yields the index of the
340
+ // first visible element. It could have been any of the other visible elements
341
+ // that were preceded by a hidden element.
342
+ // Of course, if either this element or the previous (hidden) element is also
343
+ // the first element, there's nothing to worry about.
344
+ if (index < 2) {
345
+ return index;
346
+ } // That aside, the possible cases are represented below.
347
+ //
348
+ // **** = fully hidden
349
+ // A*B* = mix of partially visible and/or hidden pages
350
+ // CDEF = fully visible
351
+ //
352
+ // (1) Binary search could have returned A, in which case we can stop.
353
+ // (2) Binary search could also have returned B, in which case we need to
354
+ // check the whole row.
355
+ // (3) Binary search could also have returned C, in which case we need to
356
+ // check the whole previous row.
357
+ //
358
+ // There's one other possibility:
359
+ //
360
+ // **** = fully hidden
361
+ // ABCD = mix of fully and/or partially visible pages
362
+ //
363
+ // (4) Binary search could only have returned A.
364
+ // Initially assume that we need to find the beginning of the current row
365
+ // (case 1, 2, or 4), which means finding a page that is above the current
366
+ // page's top. If the found page is partially visible, we're definitely not in
367
+ // case 3, and this assumption is correct.
368
+
369
+
370
+ let elt = views[index].div;
371
+ let pageTop = elt.offsetTop + elt.clientTop;
372
+
373
+ if (pageTop >= top) {
374
+ // The found page is fully visible, so we're actually either in case 3 or 4,
375
+ // and unfortunately we can't tell the difference between them without
376
+ // scanning the entire previous row, so we just conservatively assume that
377
+ // we do need to backtrack to that row. In both cases, the previous page is
378
+ // in the previous row, so use its top instead.
379
+ elt = views[index - 1].div;
380
+ pageTop = elt.offsetTop + elt.clientTop;
381
+ } // Now we backtrack to the first page that still has its bottom below
382
+ // `pageTop`, which is the top of a page in the first visible row (unless
383
+ // we're in case 4, in which case it's the row before that).
384
+ // `index` is found by binary search, so the page at `index - 1` is
385
+ // invisible and we can start looking for potentially visible pages from
386
+ // `index - 2`. (However, if this loop terminates on its first iteration,
387
+ // which is the case when pages are stacked vertically, `index` should remain
388
+ // unchanged, so we use a distinct loop variable.)
389
+
390
+
391
+ for (let i = index - 2; i >= 0; --i) {
392
+ elt = views[i].div;
393
+
394
+ if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) {
395
+ // We have reached the previous row, so stop now.
396
+ // This loop is expected to terminate relatively quickly because the
397
+ // number of pages per row is expected to be small.
398
+ break;
399
+ }
400
+
401
+ index = i;
402
+ }
403
+
404
+ return index;
405
+ }
406
+ /**
407
+ * @typedef {Object} GetVisibleElementsParameters
408
+ * @property {HTMLElement} scrollEl - A container that can possibly scroll.
409
+ * @property {Array} views - Objects with a `div` property that contains an
410
+ * HTMLElement, which should all be descendants of `scrollEl` satisfying the
411
+ * relevant layout assumptions.
412
+ * @property {boolean} sortByVisibility - If `true`, the returned elements are
413
+ * sorted in descending order of the percent of their padding box that is
414
+ * visible. The default value is `false`.
415
+ * @property {boolean} horizontal - If `true`, the elements are assumed to be
416
+ * laid out horizontally instead of vertically. The default value is `false`.
417
+ * @property {boolean} rtl - If `true`, the `scrollEl` container is assumed to
418
+ * be in right-to-left mode. The default value is `false`.
419
+ */
420
+
421
+ /**
422
+ * Generic helper to find out what elements are visible within a scroll pane.
423
+ *
424
+ * Well, pretty generic. There are some assumptions placed on the elements
425
+ * referenced by `views`:
426
+ * - If `horizontal`, no left of any earlier element is to the right of the
427
+ * left of any later element.
428
+ * - Otherwise, `views` can be split into contiguous rows where, within a row,
429
+ * no top of any element is below the bottom of any other element, and
430
+ * between rows, no bottom of any element in an earlier row is below the
431
+ * top of any element in a later row.
432
+ *
433
+ * (Here, top, left, etc. all refer to the padding edge of the element in
434
+ * question. For pages, that ends up being equivalent to the bounding box of the
435
+ * rendering canvas. Earlier and later refer to index in `views`, not page
436
+ * layout.)
437
+ *
438
+ * @param {GetVisibleElementsParameters}
439
+ * @returns {Object} `{ first, last, views: [{ id, x, y, view, percent }] }`
440
+ */
441
+
442
+
443
+ function getVisibleElements({
444
+ scrollEl,
445
+ views,
446
+ sortByVisibility = false,
447
+ horizontal = false,
448
+ rtl = false
449
+ }) {
450
+ const top = scrollEl.scrollTop,
451
+ bottom = top + scrollEl.clientHeight;
452
+ const left = scrollEl.scrollLeft,
453
+ right = left + scrollEl.clientWidth; // Throughout this "generic" function, comments will assume we're working with
454
+ // PDF document pages, which is the most important and complex case. In this
455
+ // case, the visible elements we're actually interested is the page canvas,
456
+ // which is contained in a wrapper which adds no padding/border/margin, which
457
+ // is itself contained in `view.div` which adds no padding (but does add a
458
+ // border). So, as specified in this function's doc comment, this function
459
+ // does all of its work on the padding edge of the provided views, starting at
460
+ // offsetLeft/Top (which includes margin) and adding clientLeft/Top (which is
461
+ // the border). Adding clientWidth/Height gets us the bottom-right corner of
462
+ // the padding edge.
463
+
464
+ function isElementBottomAfterViewTop(view) {
465
+ const element = view.div;
466
+ const elementBottom = element.offsetTop + element.clientTop + element.clientHeight;
467
+ return elementBottom > top;
468
+ }
469
+
470
+ function isElementNextAfterViewHorizontally(view) {
471
+ const element = view.div;
472
+ const elementLeft = element.offsetLeft + element.clientLeft;
473
+ const elementRight = elementLeft + element.clientWidth;
474
+ return rtl ? elementLeft < right : elementRight > left;
475
+ }
476
+
477
+ const visible = [],
478
+ numViews = views.length;
479
+ let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop); // Please note the return value of the `binarySearchFirstItem` function when
480
+ // no valid element is found (hence the `firstVisibleElementInd` check below).
481
+
482
+ if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) {
483
+ // In wrapped scrolling (or vertical scrolling with spreads), with some page
484
+ // sizes, isElementBottomAfterViewTop doesn't satisfy the binary search
485
+ // condition: there can be pages with bottoms above the view top between
486
+ // pages with bottoms below. This function detects and corrects that error;
487
+ // see it for more comments.
488
+ firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top);
489
+ } // lastEdge acts as a cutoff for us to stop looping, because we know all
490
+ // subsequent pages will be hidden.
491
+ //
492
+ // When using wrapped scrolling or vertical scrolling with spreads, we can't
493
+ // simply stop the first time we reach a page below the bottom of the view;
494
+ // the tops of subsequent pages on the same row could still be visible. In
495
+ // horizontal scrolling, we don't have that issue, so we can stop as soon as
496
+ // we pass `right`, without needing the code below that handles the -1 case.
497
+
498
+
499
+ let lastEdge = horizontal ? right : -1;
500
+
501
+ for (let i = firstVisibleElementInd; i < numViews; i++) {
502
+ const view = views[i],
503
+ element = view.div;
504
+ const currentWidth = element.offsetLeft + element.clientLeft;
505
+ const currentHeight = element.offsetTop + element.clientTop;
506
+ const viewWidth = element.clientWidth,
507
+ viewHeight = element.clientHeight;
508
+ const viewRight = currentWidth + viewWidth;
509
+ const viewBottom = currentHeight + viewHeight;
510
+
511
+ if (lastEdge === -1) {
512
+ // As commented above, this is only needed in non-horizontal cases.
513
+ // Setting lastEdge to the bottom of the first page that is partially
514
+ // visible ensures that the next page fully below lastEdge is on the
515
+ // next row, which has to be fully hidden along with all subsequent rows.
516
+ if (viewBottom >= bottom) {
517
+ lastEdge = viewBottom;
518
+ }
519
+ } else if ((horizontal ? currentWidth : currentHeight) > lastEdge) {
520
+ break;
521
+ }
522
+
523
+ if (viewBottom <= top || currentHeight >= bottom || viewRight <= left || currentWidth >= right) {
524
+ continue;
525
+ }
526
+
527
+ const hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, viewBottom - bottom);
528
+ const hiddenWidth = Math.max(0, left - currentWidth) + Math.max(0, viewRight - right);
529
+ const fractionHeight = (viewHeight - hiddenHeight) / viewHeight,
530
+ fractionWidth = (viewWidth - hiddenWidth) / viewWidth;
531
+ const percent = fractionHeight * fractionWidth * 100 | 0;
532
+ visible.push({
533
+ id: view.id,
534
+ x: currentWidth,
535
+ y: currentHeight,
536
+ view,
537
+ percent,
538
+ widthPercent: fractionWidth * 100 | 0
539
+ });
540
+ }
541
+
542
+ const first = visible[0],
543
+ last = visible[visible.length - 1];
544
+
545
+ if (sortByVisibility) {
546
+ visible.sort(function (a, b) {
547
+ const pc = a.percent - b.percent;
548
+
549
+ if (Math.abs(pc) > 0.001) {
550
+ return -pc;
551
+ }
552
+
553
+ return a.id - b.id; // ensure stability
554
+ });
555
+ }
556
+
557
+ return {
558
+ first,
559
+ last,
560
+ views: visible
561
+ };
562
+ }
563
+ /**
564
+ * Event handler to suppress context menu.
565
+ */
566
+
567
+
568
+ function noContextMenuHandler(evt) {
569
+ evt.preventDefault();
570
+ }
571
+
572
+ function normalizeWheelEventDirection(evt) {
573
+ let delta = Math.hypot(evt.deltaX, evt.deltaY);
574
+ const angle = Math.atan2(evt.deltaY, evt.deltaX);
575
+
576
+ if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {
577
+ // All that is left-up oriented has to change the sign.
578
+ delta = -delta;
579
+ }
580
+
581
+ return delta;
582
+ }
583
+
584
+ function normalizeWheelEventDelta(evt) {
585
+ let delta = normalizeWheelEventDirection(evt);
586
+ const MOUSE_DOM_DELTA_PIXEL_MODE = 0;
587
+ const MOUSE_DOM_DELTA_LINE_MODE = 1;
588
+ const MOUSE_PIXELS_PER_LINE = 30;
589
+ const MOUSE_LINES_PER_PAGE = 30; // Converts delta to per-page units
590
+
591
+ if (evt.deltaMode === MOUSE_DOM_DELTA_PIXEL_MODE) {
592
+ delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE;
593
+ } else if (evt.deltaMode === MOUSE_DOM_DELTA_LINE_MODE) {
594
+ delta /= MOUSE_LINES_PER_PAGE;
595
+ }
596
+
597
+ return delta;
598
+ }
599
+
600
+ function isValidRotation(angle) {
601
+ return Number.isInteger(angle) && angle % 90 === 0;
602
+ }
603
+
604
+ function isValidScrollMode(mode) {
605
+ return Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && mode !== ScrollMode.UNKNOWN;
606
+ }
607
+
608
+ function isValidSpreadMode(mode) {
609
+ return Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && mode !== SpreadMode.UNKNOWN;
610
+ }
611
+
612
+ function isPortraitOrientation(size) {
613
+ return size.width <= size.height;
614
+ }
615
+
616
+ const WaitOnType = {
617
+ EVENT: "event",
618
+ TIMEOUT: "timeout"
619
+ };
620
+ /**
621
+ * @typedef {Object} WaitOnEventOrTimeoutParameters
622
+ * @property {Object} target - The event target, can for example be:
623
+ * `window`, `document`, a DOM element, or an {EventBus} instance.
624
+ * @property {string} name - The name of the event.
625
+ * @property {number} delay - The delay, in milliseconds, after which the
626
+ * timeout occurs (if the event wasn't already dispatched).
627
+ */
628
+
629
+ /**
630
+ * Allows waiting for an event or a timeout, whichever occurs first.
631
+ * Can be used to ensure that an action always occurs, even when an event
632
+ * arrives late or not at all.
633
+ *
634
+ * @param {WaitOnEventOrTimeoutParameters}
635
+ * @returns {Promise} A promise that is resolved with a {WaitOnType} value.
636
+ */
637
+
638
+ function waitOnEventOrTimeout({
639
+ target,
640
+ name,
641
+ delay = 0
642
+ }) {
643
+ return new Promise(function (resolve, reject) {
644
+ if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) {
645
+ throw new Error("waitOnEventOrTimeout - invalid parameters.");
646
+ }
647
+
648
+ function handler(type) {
649
+ if (target instanceof EventBus) {
650
+ target._off(name, eventHandler);
651
+ } else {
652
+ target.removeEventListener(name, eventHandler);
653
+ }
654
+
655
+ if (timeout) {
656
+ clearTimeout(timeout);
657
+ }
658
+
659
+ resolve(type);
660
+ }
661
+
662
+ const eventHandler = handler.bind(null, WaitOnType.EVENT);
663
+
664
+ if (target instanceof EventBus) {
665
+ target._on(name, eventHandler);
666
+ } else {
667
+ target.addEventListener(name, eventHandler);
668
+ }
669
+
670
+ const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT);
671
+ const timeout = setTimeout(timeoutHandler, delay);
672
+ });
673
+ }
674
+ /**
675
+ * Promise that is resolved when DOM window becomes visible.
676
+ */
677
+
678
+
679
+ const animationStarted = new Promise(function (resolve) {
680
+ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("LIB") && typeof window === "undefined") {
681
+ // Prevent "ReferenceError: window is not defined" errors when running the
682
+ // unit-tests in Node.js environments.
683
+ setTimeout(resolve, 20);
684
+ return;
685
+ }
686
+
687
+ window.requestAnimationFrame(resolve);
688
+ });
689
+ /**
690
+ * NOTE: Only used to support various PDF viewer tests in `mozilla-central`.
691
+ */
692
+
693
+ function dispatchDOMEvent(eventName, args = null) {
694
+ if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("MOZCENTRAL")) {
695
+ throw new Error("Not implemented: dispatchDOMEvent");
696
+ }
697
+
698
+ const details = Object.create(null);
699
+
700
+ if ((args === null || args === void 0 ? void 0 : args.length) > 0) {
701
+ const obj = args[0];
702
+
703
+ for (const key in obj) {
704
+ const value = obj[key];
705
+
706
+ if (key === "source") {
707
+ if (value === window || value === document) {
708
+ return; // No need to re-dispatch (already) global events.
709
+ }
710
+
711
+ continue; // Ignore the `source` property.
712
+ }
713
+
714
+ details[key] = value;
715
+ }
716
+ }
717
+
718
+ const event = document.createEvent("CustomEvent");
719
+ event.initCustomEvent(eventName, true, true, details);
720
+ document.dispatchEvent(event);
721
+ }
722
+ /**
723
+ * Simple event bus for an application. Listeners are attached using the `on`
724
+ * and `off` methods. To raise an event, the `dispatch` method shall be used.
725
+ */
726
+
727
+
728
+ class EventBus {
729
+ constructor(options) {
730
+ this._listeners = Object.create(null);
731
+
732
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL")) {
733
+ this._isInAutomation = (options === null || options === void 0 ? void 0 : options.isInAutomation) === true;
734
+ }
735
+ }
736
+ /**
737
+ * @param {string} eventName
738
+ * @param {function} listener
739
+ * @param {Object} [options]
740
+ */
741
+
742
+
743
+ on(eventName, listener, options = null) {
744
+ this._on(eventName, listener, {
745
+ external: true,
746
+ once: options === null || options === void 0 ? void 0 : options.once
747
+ });
748
+ }
749
+ /**
750
+ * @param {string} eventName
751
+ * @param {function} listener
752
+ * @param {Object} [options]
753
+ */
754
+
755
+
756
+ off(eventName, listener, options = null) {
757
+ this._off(eventName, listener, {
758
+ external: true,
759
+ once: options === null || options === void 0 ? void 0 : options.once
760
+ });
761
+ }
762
+
763
+ dispatch(eventName) {
764
+ const eventListeners = this._listeners[eventName];
765
+
766
+ if (!eventListeners || eventListeners.length === 0) {
767
+ if ((typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL")) && this._isInAutomation) {
768
+ const args = Array.prototype.slice.call(arguments, 1);
769
+ dispatchDOMEvent(eventName, args);
770
+ }
771
+
772
+ return;
773
+ } // Passing all arguments after the eventName to the listeners.
774
+
775
+
776
+ const args = Array.prototype.slice.call(arguments, 1);
777
+ let externalListeners; // Making copy of the listeners array in case if it will be modified
778
+ // during dispatch.
779
+
780
+ for (const {
781
+ listener,
782
+ external,
783
+ once
784
+ } of eventListeners.slice(0)) {
785
+ if (once) {
786
+ this._off(eventName, listener);
787
+ }
788
+
789
+ if (external) {
790
+ (externalListeners || (externalListeners = [])).push(listener);
791
+ continue;
792
+ }
793
+
794
+ listener.apply(null, args);
795
+ } // Dispatch any "external" listeners *after* the internal ones, to give the
796
+ // viewer components time to handle events and update their state first.
797
+
798
+
799
+ if (externalListeners) {
800
+ for (const listener of externalListeners) {
801
+ listener.apply(null, args);
802
+ }
803
+
804
+ externalListeners = null;
805
+ }
806
+
807
+ if ((typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL")) && this._isInAutomation) {
808
+ dispatchDOMEvent(eventName, args);
809
+ }
810
+ }
811
+ /**
812
+ * @ignore
813
+ */
814
+
815
+
816
+ _on(eventName, listener, options = null) {
817
+ var _this$_listeners;
818
+
819
+ const eventListeners = (_this$_listeners = this._listeners)[eventName] || (_this$_listeners[eventName] = []);
820
+ eventListeners.push({
821
+ listener,
822
+ external: (options === null || options === void 0 ? void 0 : options.external) === true,
823
+ once: (options === null || options === void 0 ? void 0 : options.once) === true
824
+ });
825
+ }
826
+ /**
827
+ * @ignore
828
+ */
829
+
830
+
831
+ _off(eventName, listener, options = null) {
832
+ const eventListeners = this._listeners[eventName];
833
+
834
+ if (!eventListeners) {
835
+ return;
836
+ }
837
+
838
+ for (let i = 0, ii = eventListeners.length; i < ii; i++) {
839
+ if (eventListeners[i].listener === listener) {
840
+ eventListeners.splice(i, 1);
841
+ return;
842
+ }
843
+ }
844
+ }
845
+
846
+ }
847
+
848
+ function clamp(v, min, max) {
849
+ return Math.min(Math.max(v, min), max);
850
+ }
851
+
852
+ class ProgressBar {
853
+ constructor(id, {
854
+ height,
855
+ width,
856
+ units
857
+ } = {}) {
858
+ this.visible = true; // Fetch the sub-elements for later.
859
+
860
+ this.div = document.querySelector(id + " .progress"); // Get the loading bar element, so it can be resized to fit the viewer.
861
+
862
+ this.bar = this.div.parentNode; // Get options, with sensible defaults.
863
+
864
+ this.height = height || 100;
865
+ this.width = width || 100;
866
+ this.units = units || "%"; // Initialize heights.
867
+
868
+ this.div.style.height = this.height + this.units;
869
+ this.percent = 0;
870
+ }
871
+
872
+ _updateBar() {
873
+ if (this._indeterminate) {
874
+ this.div.classList.add("indeterminate");
875
+ this.div.style.width = this.width + this.units;
876
+ return;
877
+ }
878
+
879
+ this.div.classList.remove("indeterminate");
880
+ const progressSize = this.width * this._percent / 100;
881
+ this.div.style.width = progressSize + this.units;
882
+ }
883
+
884
+ get percent() {
885
+ return this._percent;
886
+ }
887
+
888
+ set percent(val) {
889
+ this._indeterminate = isNaN(val);
890
+ this._percent = clamp(val, 0, 100);
891
+
892
+ this._updateBar();
893
+ }
894
+
895
+ setWidth(viewer) {
896
+ if (!viewer) {
897
+ return;
898
+ }
899
+
900
+ const container = viewer.parentNode;
901
+ const scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
902
+
903
+ if (scrollbarWidth > 0) {
904
+ const doc = document.documentElement;
905
+ doc.style.setProperty(LOADINGBAR_END_OFFSET_VAR, `${scrollbarWidth}px`);
906
+ }
907
+ }
908
+
909
+ hide() {
910
+ if (!this.visible) {
911
+ return;
912
+ }
913
+
914
+ this.visible = false;
915
+ this.bar.classList.add("hidden");
916
+ }
917
+
918
+ show() {
919
+ if (this.visible) {
920
+ return;
921
+ }
922
+
923
+ this.visible = true;
924
+ this.bar.classList.remove("hidden");
925
+ }
926
+
927
+ }
928
+ /**
929
+ * Moves all elements of an array that satisfy condition to the end of the
930
+ * array, preserving the order of the rest.
931
+ */
932
+
933
+
934
+ function moveToEndOfArray(arr, condition) {
935
+ const moved = [],
936
+ len = arr.length;
937
+ let write = 0;
938
+
939
+ for (let read = 0; read < len; ++read) {
940
+ if (condition(arr[read])) {
941
+ moved.push(arr[read]);
942
+ } else {
943
+ arr[write] = arr[read];
944
+ ++write;
945
+ }
946
+ }
947
+
948
+ for (let read = 0; write < len; ++read, ++write) {
949
+ arr[write] = moved[read];
950
+ }
951
+ }
952
+ /**
953
+ * Get the active or focused element in current DOM.
954
+ *
955
+ * Recursively search for the truly active or focused element in case there are
956
+ * shadow DOMs.
957
+ *
958
+ * @returns {Element} the truly active or focused element.
959
+ */
960
+
961
+
962
+ function getActiveOrFocusedElement() {
963
+ let curRoot = document;
964
+ let curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
965
+
966
+ while ((_curActiveOrFocused = curActiveOrFocused) !== null && _curActiveOrFocused !== void 0 && _curActiveOrFocused.shadowRoot) {
967
+ var _curActiveOrFocused;
968
+
969
+ curRoot = curActiveOrFocused.shadowRoot;
970
+ curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
971
+ }
972
+
973
+ return curActiveOrFocused;
974
+ }
975
+ /**
976
+ * Converts API PageLayout values to the format used by `BaseViewer`.
977
+ * NOTE: This is supported to the extent that the viewer implements the
978
+ * necessary Scroll/Spread modes (since SinglePage, TwoPageLeft,
979
+ * and TwoPageRight all suggests using non-continuous scrolling).
980
+ * @param {string} mode - The API PageLayout value.
981
+ * @returns {number} A value from {SpreadMode}.
982
+ */
983
+
984
+
985
+ function apiPageLayoutToSpreadMode(layout) {
986
+ switch (layout) {
987
+ case "SinglePage":
988
+ case "OneColumn":
989
+ return SpreadMode.NONE;
990
+
991
+ case "TwoColumnLeft":
992
+ case "TwoPageLeft":
993
+ return SpreadMode.ODD;
994
+
995
+ case "TwoColumnRight":
996
+ case "TwoPageRight":
997
+ return SpreadMode.EVEN;
998
+ }
999
+
1000
+ return SpreadMode.NONE; // Default value.
1001
+ }
1002
+ /**
1003
+ * Converts API PageMode values to the format used by `PDFSidebar`.
1004
+ * NOTE: There's also a "FullScreen" parameter which is not possible to support,
1005
+ * since the Fullscreen API used in browsers requires that entering
1006
+ * fullscreen mode only occurs as a result of a user-initiated event.
1007
+ * @param {string} mode - The API PageMode value.
1008
+ * @returns {number} A value from {SidebarView}.
1009
+ */
1010
+
1011
+
1012
+ function apiPageModeToSidebarView(mode) {
1013
+ switch (mode) {
1014
+ case "UseNone":
1015
+ return SidebarView.NONE;
1016
+
1017
+ case "UseThumbs":
1018
+ return SidebarView.THUMBS;
1019
+
1020
+ case "UseOutlines":
1021
+ return SidebarView.OUTLINE;
1022
+
1023
+ case "UseAttachments":
1024
+ return SidebarView.ATTACHMENTS;
1025
+
1026
+ case "UseOC":
1027
+ return SidebarView.LAYERS;
1028
+ }
1029
+
1030
+ return SidebarView.NONE; // Default value.
1031
+ }
1032
+
1033
+ export { AutoPrintRegExp, CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, EventBus, MAX_AUTO_SCALE, MAX_SCALE, MIN_SCALE, PresentationModeState, ProgressBar, RendererType, SCROLLBAR_PADDING, ScrollMode, SidebarView, SpreadMode, TextLayerMode, UNKNOWN_SCALE, VERTICAL_PADDING, WaitOnType, animationStarted, apiPageLayoutToSpreadMode, apiPageModeToSidebarView, approximateFraction, backtrackBeforeAllVisibleElements, binarySearchFirstItem, getActiveOrFocusedElement, getOutputScale, getPageSizeInches, getVisibleElements, isPortraitOrientation, isValidRotation, isValidScrollMode, isValidSpreadMode, moveToEndOfArray, noContextMenuHandler, normalizeWheelEventDelta, normalizeWheelEventDirection, parseQueryString, roundToDivide, scrollIntoView, waitOnEventOrTimeout, watchScroll };