@vaadin-component-factory/vcf-pdf-viewer 3.1.0 → 3.2.0
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.
- package/package.json +22 -16
- package/pdfjs/dist/event_utils.js +207 -0
- package/pdfjs/dist/genericl10n.js +2395 -0
- package/pdfjs/dist/message_handler.js +325 -190
- package/pdfjs/dist/node_stream.js +2 -494
- package/pdfjs/dist/node_stream2.js +1754 -0
- package/pdfjs/dist/pdf.js +19294 -11168
- package/pdfjs/dist/pdf.worker.js +23 -0
- package/pdfjs/dist/pdf_link_service.js +222 -378
- package/pdfjs/dist/pdf_rendering_queue.js +61 -62
- package/pdfjs/dist/pdf_thumbnail_viewer.js +214 -399
- package/pdfjs/dist/pdf_viewer.js +3432 -2295
- package/pdfjs/dist/ui_utils.js +209 -480
- package/pdfjs/dist/util.js +382 -568
- package/pdfjs/dist/worker.js +41580 -42492
- package/src/vcf-pdf-viewer.js +157 -19
package/pdfjs/dist/ui_utils.js
CHANGED
|
@@ -12,16 +12,22 @@
|
|
|
12
12
|
* See the License for the specific language governing permissions and
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
const DEFAULT_SCALE_VALUE = "auto";
|
|
17
17
|
const DEFAULT_SCALE = 1.0;
|
|
18
|
+
const DEFAULT_SCALE_DELTA = 1.1;
|
|
18
19
|
const MIN_SCALE = 0.1;
|
|
19
20
|
const MAX_SCALE = 10.0;
|
|
20
21
|
const UNKNOWN_SCALE = 0;
|
|
21
22
|
const MAX_AUTO_SCALE = 1.25;
|
|
22
23
|
const SCROLLBAR_PADDING = 40;
|
|
23
24
|
const VERTICAL_PADDING = 5;
|
|
24
|
-
const
|
|
25
|
+
const RenderingStates = {
|
|
26
|
+
INITIAL: 0,
|
|
27
|
+
RUNNING: 1,
|
|
28
|
+
PAUSED: 2,
|
|
29
|
+
FINISHED: 3
|
|
30
|
+
};
|
|
25
31
|
const PresentationModeState = {
|
|
26
32
|
UNKNOWN: 0,
|
|
27
33
|
NORMAL: 1,
|
|
@@ -37,21 +43,18 @@ const SidebarView = {
|
|
|
37
43
|
ATTACHMENTS: 3,
|
|
38
44
|
LAYERS: 4
|
|
39
45
|
};
|
|
40
|
-
const RendererType = {
|
|
41
|
-
CANVAS: "canvas",
|
|
42
|
-
SVG: "svg"
|
|
43
|
-
};
|
|
44
46
|
const TextLayerMode = {
|
|
45
47
|
DISABLE: 0,
|
|
46
48
|
ENABLE: 1,
|
|
47
|
-
|
|
49
|
+
ENABLE_PERMISSIONS: 2
|
|
48
50
|
};
|
|
49
51
|
const ScrollMode = {
|
|
50
52
|
UNKNOWN: -1,
|
|
51
53
|
VERTICAL: 0,
|
|
52
54
|
// Default value.
|
|
53
55
|
HORIZONTAL: 1,
|
|
54
|
-
WRAPPED: 2
|
|
56
|
+
WRAPPED: 2,
|
|
57
|
+
PAGE: 3
|
|
55
58
|
};
|
|
56
59
|
const SpreadMode = {
|
|
57
60
|
UNKNOWN: -1,
|
|
@@ -59,109 +62,112 @@ const SpreadMode = {
|
|
|
59
62
|
// Default value.
|
|
60
63
|
ODD: 1,
|
|
61
64
|
EVEN: 2
|
|
62
|
-
};
|
|
65
|
+
};
|
|
66
|
+
const CursorTool = {
|
|
67
|
+
SELECT: 0,
|
|
68
|
+
// The default value.
|
|
69
|
+
HAND: 1,
|
|
70
|
+
ZOOM: 2
|
|
71
|
+
};
|
|
63
72
|
|
|
73
|
+
// Used by `PDFViewerApplication`, and by the API unit-tests.
|
|
64
74
|
const AutoPrintRegExp = /\bprint\s*\(/;
|
|
75
|
+
|
|
65
76
|
/**
|
|
66
|
-
*
|
|
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.
|
|
77
|
+
* Scale factors for the canvas, necessary with HiDPI displays.
|
|
70
78
|
*/
|
|
79
|
+
class OutputScale {
|
|
80
|
+
constructor() {
|
|
81
|
+
const pixelRatio = window.devicePixelRatio || 1;
|
|
71
82
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
/**
|
|
84
|
+
* @type {number} Horizontal scale.
|
|
85
|
+
*/
|
|
86
|
+
this.sx = pixelRatio;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @type {number} Vertical scale.
|
|
90
|
+
*/
|
|
91
|
+
this.sy = pixelRatio;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @type {boolean} Returns `true` when scaling is required, `false` otherwise.
|
|
96
|
+
*/
|
|
97
|
+
get scaled() {
|
|
98
|
+
return this.sx !== 1 || this.sy !== 1;
|
|
99
|
+
}
|
|
81
100
|
}
|
|
101
|
+
|
|
82
102
|
/**
|
|
83
103
|
* Scrolls specified element into view of its parent.
|
|
84
|
-
* @param {
|
|
85
|
-
* @param {Object} spot - An object with optional top and left properties,
|
|
104
|
+
* @param {HTMLElement} element - The element to be visible.
|
|
105
|
+
* @param {Object} [spot] - An object with optional top and left properties,
|
|
86
106
|
* specifying the offset from the top left edge.
|
|
107
|
+
* @param {number} [spot.left]
|
|
108
|
+
* @param {number} [spot.top]
|
|
87
109
|
* @param {boolean} [scrollMatches] - When scrolling search results into view,
|
|
88
110
|
* ignore elements that either: Contains marked content identifiers,
|
|
89
111
|
* or have the CSS-rule `overflow: hidden;` set. The default value is `false`.
|
|
90
112
|
*/
|
|
91
|
-
|
|
92
|
-
|
|
93
113
|
function scrollIntoView(element, spot, scrollMatches = false) {
|
|
94
114
|
// Assuming offsetParent is available (it's not available when viewer is in
|
|
95
115
|
// hidden iframe or object). We have to scroll: if the offsetParent is not set
|
|
96
116
|
// producing the error. See also animationStarted.
|
|
97
117
|
let parent = element.offsetParent;
|
|
98
|
-
|
|
99
118
|
if (!parent) {
|
|
100
119
|
console.error("offsetParent is not set -- cannot scroll");
|
|
101
120
|
return;
|
|
102
121
|
}
|
|
103
|
-
|
|
104
122
|
let offsetY = element.offsetTop + element.clientTop;
|
|
105
123
|
let offsetX = element.offsetLeft + element.clientLeft;
|
|
106
|
-
|
|
107
124
|
while (parent.clientHeight === parent.scrollHeight && parent.clientWidth === parent.scrollWidth || scrollMatches && (parent.classList.contains("markedContent") || getComputedStyle(parent).overflow === "hidden")) {
|
|
108
125
|
offsetY += parent.offsetTop;
|
|
109
126
|
offsetX += parent.offsetLeft;
|
|
110
127
|
parent = parent.offsetParent;
|
|
111
|
-
|
|
112
128
|
if (!parent) {
|
|
113
129
|
return; // no need to scroll
|
|
114
130
|
}
|
|
115
131
|
}
|
|
116
|
-
|
|
117
132
|
if (spot) {
|
|
118
133
|
if (spot.top !== undefined) {
|
|
119
134
|
offsetY += spot.top;
|
|
120
135
|
}
|
|
121
|
-
|
|
122
136
|
if (spot.left !== undefined) {
|
|
123
137
|
offsetX += spot.left;
|
|
124
138
|
parent.scrollLeft = offsetX;
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
|
-
|
|
128
141
|
parent.scrollTop = offsetY;
|
|
129
142
|
}
|
|
143
|
+
|
|
130
144
|
/**
|
|
131
145
|
* Helper function to start monitoring the scroll event and converting them into
|
|
132
146
|
* PDF.js friendly one: with scroll debounce and scroll direction.
|
|
133
147
|
*/
|
|
134
|
-
|
|
135
|
-
|
|
136
148
|
function watchScroll(viewAreaElement, callback) {
|
|
137
149
|
const debounceScroll = function (evt) {
|
|
138
150
|
if (rAF) {
|
|
139
151
|
return;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
152
|
+
}
|
|
153
|
+
// schedule an invocation of scroll for next animation frame.
|
|
143
154
|
rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {
|
|
144
155
|
rAF = null;
|
|
145
156
|
const currentX = viewAreaElement.scrollLeft;
|
|
146
157
|
const lastX = state.lastX;
|
|
147
|
-
|
|
148
158
|
if (currentX !== lastX) {
|
|
149
159
|
state.right = currentX > lastX;
|
|
150
160
|
}
|
|
151
|
-
|
|
152
161
|
state.lastX = currentX;
|
|
153
162
|
const currentY = viewAreaElement.scrollTop;
|
|
154
163
|
const lastY = state.lastY;
|
|
155
|
-
|
|
156
164
|
if (currentY !== lastY) {
|
|
157
165
|
state.down = currentY > lastY;
|
|
158
166
|
}
|
|
159
|
-
|
|
160
167
|
state.lastY = currentY;
|
|
161
168
|
callback(state);
|
|
162
169
|
});
|
|
163
170
|
};
|
|
164
|
-
|
|
165
171
|
const state = {
|
|
166
172
|
right: true,
|
|
167
173
|
down: true,
|
|
@@ -173,24 +179,35 @@ function watchScroll(viewAreaElement, callback) {
|
|
|
173
179
|
viewAreaElement.addEventListener("scroll", debounceScroll, true);
|
|
174
180
|
return state;
|
|
175
181
|
}
|
|
182
|
+
|
|
176
183
|
/**
|
|
177
|
-
* Helper function to parse query string (e.g. ?param1=value&
|
|
184
|
+
* Helper function to parse query string (e.g. ?param1=value¶m2=...).
|
|
185
|
+
* @param {string} query
|
|
186
|
+
* @returns {Map}
|
|
178
187
|
*/
|
|
179
|
-
|
|
180
|
-
|
|
181
188
|
function parseQueryString(query) {
|
|
182
|
-
const
|
|
183
|
-
const
|
|
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);
|
|
189
|
+
const params = new Map();
|
|
190
|
+
for (const [key, value] of new URLSearchParams(query)) {
|
|
191
|
+
params.set(key.toLowerCase(), value);
|
|
190
192
|
}
|
|
191
|
-
|
|
192
193
|
return params;
|
|
193
194
|
}
|
|
195
|
+
const InvisibleCharsRegExp = /[\x00-\x1F]/g;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @param {string} str
|
|
199
|
+
* @param {boolean} [replaceInvisible]
|
|
200
|
+
*/
|
|
201
|
+
function removeNullCharacters(str, replaceInvisible = false) {
|
|
202
|
+
if (!InvisibleCharsRegExp.test(str)) {
|
|
203
|
+
return str;
|
|
204
|
+
}
|
|
205
|
+
if (replaceInvisible) {
|
|
206
|
+
return str.replaceAll(InvisibleCharsRegExp, m => m === "\x00" ? "" : " ");
|
|
207
|
+
}
|
|
208
|
+
return str.replaceAll("\x00", "");
|
|
209
|
+
}
|
|
210
|
+
|
|
194
211
|
/**
|
|
195
212
|
* Use binary search to find the index of the first item in a given array which
|
|
196
213
|
* passes a given condition. The items are expected to be sorted in the sense
|
|
@@ -200,34 +217,27 @@ function parseQueryString(query) {
|
|
|
200
217
|
* @returns {number} Index of the first array element to pass the test,
|
|
201
218
|
* or |items.length| if no such element exists.
|
|
202
219
|
*/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
function binarySearchFirstItem(items, condition) {
|
|
206
|
-
let minIndex = 0;
|
|
220
|
+
function binarySearchFirstItem(items, condition, start = 0) {
|
|
221
|
+
let minIndex = start;
|
|
207
222
|
let maxIndex = items.length - 1;
|
|
208
|
-
|
|
209
223
|
if (maxIndex < 0 || !condition(items[maxIndex])) {
|
|
210
224
|
return items.length;
|
|
211
225
|
}
|
|
212
|
-
|
|
213
226
|
if (condition(items[minIndex])) {
|
|
214
227
|
return minIndex;
|
|
215
228
|
}
|
|
216
|
-
|
|
217
229
|
while (minIndex < maxIndex) {
|
|
218
230
|
const currentIndex = minIndex + maxIndex >> 1;
|
|
219
231
|
const currentItem = items[currentIndex];
|
|
220
|
-
|
|
221
232
|
if (condition(currentItem)) {
|
|
222
233
|
maxIndex = currentIndex;
|
|
223
234
|
} else {
|
|
224
235
|
minIndex = currentIndex + 1;
|
|
225
236
|
}
|
|
226
237
|
}
|
|
227
|
-
|
|
228
|
-
return minIndex;
|
|
229
|
-
/* === maxIndex */
|
|
238
|
+
return minIndex; /* === maxIndex */
|
|
230
239
|
}
|
|
240
|
+
|
|
231
241
|
/**
|
|
232
242
|
* Approximates float number as a fraction using Farey sequence (max order
|
|
233
243
|
* of 8).
|
|
@@ -235,39 +245,32 @@ function binarySearchFirstItem(items, condition) {
|
|
|
235
245
|
* @returns {Array} Estimated fraction: the first array item is a numerator,
|
|
236
246
|
* the second one is a denominator.
|
|
237
247
|
*/
|
|
238
|
-
|
|
239
|
-
|
|
240
248
|
function approximateFraction(x) {
|
|
241
249
|
// Fast paths for int numbers or their inversions.
|
|
242
250
|
if (Math.floor(x) === x) {
|
|
243
251
|
return [x, 1];
|
|
244
252
|
}
|
|
245
|
-
|
|
246
253
|
const xinv = 1 / x;
|
|
247
254
|
const limit = 8;
|
|
248
|
-
|
|
249
255
|
if (xinv > limit) {
|
|
250
256
|
return [1, limit];
|
|
251
257
|
} else if (Math.floor(xinv) === xinv) {
|
|
252
258
|
return [1, xinv];
|
|
253
259
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
260
|
+
const x_ = x > 1 ? xinv : x;
|
|
261
|
+
// a/b and c/d are neighbours in Farey sequence.
|
|
257
262
|
let a = 0,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
263
|
+
b = 1,
|
|
264
|
+
c = 1,
|
|
265
|
+
d = 1;
|
|
266
|
+
// Limiting search to order 8.
|
|
262
267
|
while (true) {
|
|
263
268
|
// Generating next term in sequence (order of q).
|
|
264
269
|
const p = a + c,
|
|
265
|
-
|
|
266
|
-
|
|
270
|
+
q = b + d;
|
|
267
271
|
if (q > limit) {
|
|
268
272
|
break;
|
|
269
273
|
}
|
|
270
|
-
|
|
271
274
|
if (x_ <= p / q) {
|
|
272
275
|
c = p;
|
|
273
276
|
d = q;
|
|
@@ -276,38 +279,45 @@ function approximateFraction(x) {
|
|
|
276
279
|
b = q;
|
|
277
280
|
}
|
|
278
281
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
+
let result;
|
|
283
|
+
// Select closest of the neighbours to x.
|
|
282
284
|
if (x_ - a / b < c / d - x_) {
|
|
283
285
|
result = x_ === x ? [a, b] : [b, a];
|
|
284
286
|
} else {
|
|
285
287
|
result = x_ === x ? [c, d] : [d, c];
|
|
286
288
|
}
|
|
287
|
-
|
|
288
289
|
return result;
|
|
289
290
|
}
|
|
290
|
-
|
|
291
291
|
function roundToDivide(x, div) {
|
|
292
292
|
const r = x % div;
|
|
293
293
|
return r === 0 ? x : Math.round(x - r + div);
|
|
294
294
|
}
|
|
295
|
+
|
|
295
296
|
/**
|
|
296
|
-
*
|
|
297
|
-
* @
|
|
298
|
-
*
|
|
299
|
-
* @
|
|
300
|
-
* and {number} `height`, given in inches.
|
|
297
|
+
* @typedef {Object} GetPageSizeInchesParameters
|
|
298
|
+
* @property {number[]} view
|
|
299
|
+
* @property {number} userUnit
|
|
300
|
+
* @property {number} rotate
|
|
301
301
|
*/
|
|
302
302
|
|
|
303
|
+
/**
|
|
304
|
+
* @typedef {Object} PageSize
|
|
305
|
+
* @property {number} width - In inches.
|
|
306
|
+
* @property {number} height - In inches.
|
|
307
|
+
*/
|
|
303
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Gets the size of the specified page, converted from PDF units to inches.
|
|
311
|
+
* @param {GetPageSizeInchesParameters} params
|
|
312
|
+
* @returns {PageSize}
|
|
313
|
+
*/
|
|
304
314
|
function getPageSizeInches({
|
|
305
315
|
view,
|
|
306
316
|
userUnit,
|
|
307
317
|
rotate
|
|
308
318
|
}) {
|
|
309
|
-
const [x1, y1, x2, y2] = view;
|
|
310
|
-
|
|
319
|
+
const [x1, y1, x2, y2] = view;
|
|
320
|
+
// We need to take the page rotation into account as well.
|
|
311
321
|
const changeOrientation = rotate % 180 !== 0;
|
|
312
322
|
const width = (x2 - x1) / 72 * userUnit;
|
|
313
323
|
const height = (y2 - y1) / 72 * userUnit;
|
|
@@ -316,6 +326,7 @@ function getPageSizeInches({
|
|
|
316
326
|
height: changeOrientation ? width : height
|
|
317
327
|
};
|
|
318
328
|
}
|
|
329
|
+
|
|
319
330
|
/**
|
|
320
331
|
* Helper function for getVisibleElements.
|
|
321
332
|
*
|
|
@@ -327,8 +338,6 @@ function getPageSizeInches({
|
|
|
327
338
|
* this will be the first element in the first partially visible row in
|
|
328
339
|
* `views`, although sometimes it goes back one row further.)
|
|
329
340
|
*/
|
|
330
|
-
|
|
331
|
-
|
|
332
341
|
function backtrackBeforeAllVisibleElements(index, views, top) {
|
|
333
342
|
// binarySearchFirstItem's assumption is that the input is ordered, with only
|
|
334
343
|
// one index where the conditions flips from false to true: [false ...,
|
|
@@ -339,11 +348,14 @@ function backtrackBeforeAllVisibleElements(index, views, top) {
|
|
|
339
348
|
// So there is no guarantee that the binary search yields the index of the
|
|
340
349
|
// first visible element. It could have been any of the other visible elements
|
|
341
350
|
// that were preceded by a hidden element.
|
|
351
|
+
|
|
342
352
|
// Of course, if either this element or the previous (hidden) element is also
|
|
343
353
|
// the first element, there's nothing to worry about.
|
|
344
354
|
if (index < 2) {
|
|
345
355
|
return index;
|
|
346
|
-
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// That aside, the possible cases are represented below.
|
|
347
359
|
//
|
|
348
360
|
// **** = fully hidden
|
|
349
361
|
// A*B* = mix of partially visible and/or hidden pages
|
|
@@ -361,15 +373,13 @@ function backtrackBeforeAllVisibleElements(index, views, top) {
|
|
|
361
373
|
// ABCD = mix of fully and/or partially visible pages
|
|
362
374
|
//
|
|
363
375
|
// (4) Binary search could only have returned A.
|
|
376
|
+
|
|
364
377
|
// Initially assume that we need to find the beginning of the current row
|
|
365
378
|
// (case 1, 2, or 4), which means finding a page that is above the current
|
|
366
379
|
// page's top. If the found page is partially visible, we're definitely not in
|
|
367
380
|
// case 3, and this assumption is correct.
|
|
368
|
-
|
|
369
|
-
|
|
370
381
|
let elt = views[index].div;
|
|
371
382
|
let pageTop = elt.offsetTop + elt.clientTop;
|
|
372
|
-
|
|
373
383
|
if (pageTop >= top) {
|
|
374
384
|
// The found page is fully visible, so we're actually either in case 3 or 4,
|
|
375
385
|
// and unfortunately we can't tell the difference between them without
|
|
@@ -378,7 +388,9 @@ function backtrackBeforeAllVisibleElements(index, views, top) {
|
|
|
378
388
|
// in the previous row, so use its top instead.
|
|
379
389
|
elt = views[index - 1].div;
|
|
380
390
|
pageTop = elt.offsetTop + elt.clientTop;
|
|
381
|
-
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Now we backtrack to the first page that still has its bottom below
|
|
382
394
|
// `pageTop`, which is the top of a page in the first visible row (unless
|
|
383
395
|
// we're in case 4, in which case it's the row before that).
|
|
384
396
|
// `index` is found by binary search, so the page at `index - 1` is
|
|
@@ -386,23 +398,19 @@ function backtrackBeforeAllVisibleElements(index, views, top) {
|
|
|
386
398
|
// `index - 2`. (However, if this loop terminates on its first iteration,
|
|
387
399
|
// which is the case when pages are stacked vertically, `index` should remain
|
|
388
400
|
// unchanged, so we use a distinct loop variable.)
|
|
389
|
-
|
|
390
|
-
|
|
391
401
|
for (let i = index - 2; i >= 0; --i) {
|
|
392
402
|
elt = views[i].div;
|
|
393
|
-
|
|
394
403
|
if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) {
|
|
395
404
|
// We have reached the previous row, so stop now.
|
|
396
405
|
// This loop is expected to terminate relatively quickly because the
|
|
397
406
|
// number of pages per row is expected to be small.
|
|
398
407
|
break;
|
|
399
408
|
}
|
|
400
|
-
|
|
401
409
|
index = i;
|
|
402
410
|
}
|
|
403
|
-
|
|
404
411
|
return index;
|
|
405
412
|
}
|
|
413
|
+
|
|
406
414
|
/**
|
|
407
415
|
* @typedef {Object} GetVisibleElementsParameters
|
|
408
416
|
* @property {HTMLElement} scrollEl - A container that can possibly scroll.
|
|
@@ -435,11 +443,9 @@ function backtrackBeforeAllVisibleElements(index, views, top) {
|
|
|
435
443
|
* rendering canvas. Earlier and later refer to index in `views`, not page
|
|
436
444
|
* layout.)
|
|
437
445
|
*
|
|
438
|
-
* @param {GetVisibleElementsParameters}
|
|
446
|
+
* @param {GetVisibleElementsParameters} params
|
|
439
447
|
* @returns {Object} `{ first, last, views: [{ id, x, y, view, percent }] }`
|
|
440
448
|
*/
|
|
441
|
-
|
|
442
|
-
|
|
443
449
|
function getVisibleElements({
|
|
444
450
|
scrollEl,
|
|
445
451
|
views,
|
|
@@ -448,9 +454,11 @@ function getVisibleElements({
|
|
|
448
454
|
rtl = false
|
|
449
455
|
}) {
|
|
450
456
|
const top = scrollEl.scrollTop,
|
|
451
|
-
|
|
457
|
+
bottom = top + scrollEl.clientHeight;
|
|
452
458
|
const left = scrollEl.scrollLeft,
|
|
453
|
-
|
|
459
|
+
right = left + scrollEl.clientWidth;
|
|
460
|
+
|
|
461
|
+
// Throughout this "generic" function, comments will assume we're working with
|
|
454
462
|
// PDF document pages, which is the most important and complex case. In this
|
|
455
463
|
// case, the visible elements we're actually interested is the page canvas,
|
|
456
464
|
// which is contained in a wrapper which adds no padding/border/margin, which
|
|
@@ -460,25 +468,24 @@ function getVisibleElements({
|
|
|
460
468
|
// offsetLeft/Top (which includes margin) and adding clientLeft/Top (which is
|
|
461
469
|
// the border). Adding clientWidth/Height gets us the bottom-right corner of
|
|
462
470
|
// the padding edge.
|
|
463
|
-
|
|
464
471
|
function isElementBottomAfterViewTop(view) {
|
|
465
472
|
const element = view.div;
|
|
466
473
|
const elementBottom = element.offsetTop + element.clientTop + element.clientHeight;
|
|
467
474
|
return elementBottom > top;
|
|
468
475
|
}
|
|
469
|
-
|
|
470
476
|
function isElementNextAfterViewHorizontally(view) {
|
|
471
477
|
const element = view.div;
|
|
472
478
|
const elementLeft = element.offsetLeft + element.clientLeft;
|
|
473
479
|
const elementRight = elementLeft + element.clientWidth;
|
|
474
480
|
return rtl ? elementLeft < right : elementRight > left;
|
|
475
481
|
}
|
|
476
|
-
|
|
477
482
|
const visible = [],
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
483
|
+
ids = new Set(),
|
|
484
|
+
numViews = views.length;
|
|
485
|
+
let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop);
|
|
481
486
|
|
|
487
|
+
// Please note the return value of the `binarySearchFirstItem` function when
|
|
488
|
+
// no valid element is found (hence the `firstVisibleElementInd` check below).
|
|
482
489
|
if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) {
|
|
483
490
|
// In wrapped scrolling (or vertical scrolling with spreads), with some page
|
|
484
491
|
// sizes, isElementBottomAfterViewTop doesn't satisfy the binary search
|
|
@@ -486,7 +493,9 @@ function getVisibleElements({
|
|
|
486
493
|
// pages with bottoms below. This function detects and corrects that error;
|
|
487
494
|
// see it for more comments.
|
|
488
495
|
firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top);
|
|
489
|
-
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// lastEdge acts as a cutoff for us to stop looping, because we know all
|
|
490
499
|
// subsequent pages will be hidden.
|
|
491
500
|
//
|
|
492
501
|
// When using wrapped scrolling or vertical scrolling with spreads, we can't
|
|
@@ -494,20 +503,16 @@ function getVisibleElements({
|
|
|
494
503
|
// the tops of subsequent pages on the same row could still be visible. In
|
|
495
504
|
// horizontal scrolling, we don't have that issue, so we can stop as soon as
|
|
496
505
|
// we pass `right`, without needing the code below that handles the -1 case.
|
|
497
|
-
|
|
498
|
-
|
|
499
506
|
let lastEdge = horizontal ? right : -1;
|
|
500
|
-
|
|
501
507
|
for (let i = firstVisibleElementInd; i < numViews; i++) {
|
|
502
508
|
const view = views[i],
|
|
503
|
-
|
|
509
|
+
element = view.div;
|
|
504
510
|
const currentWidth = element.offsetLeft + element.clientLeft;
|
|
505
511
|
const currentHeight = element.offsetTop + element.clientTop;
|
|
506
512
|
const viewWidth = element.clientWidth,
|
|
507
|
-
|
|
513
|
+
viewHeight = element.clientHeight;
|
|
508
514
|
const viewRight = currentWidth + viewWidth;
|
|
509
515
|
const viewBottom = currentHeight + viewHeight;
|
|
510
|
-
|
|
511
516
|
if (lastEdge === -1) {
|
|
512
517
|
// As commented above, this is only needed in non-horizontal cases.
|
|
513
518
|
// Setting lastEdge to the bottom of the first page that is partially
|
|
@@ -519,15 +524,13 @@ function getVisibleElements({
|
|
|
519
524
|
} else if ((horizontal ? currentWidth : currentHeight) > lastEdge) {
|
|
520
525
|
break;
|
|
521
526
|
}
|
|
522
|
-
|
|
523
527
|
if (viewBottom <= top || currentHeight >= bottom || viewRight <= left || currentWidth >= right) {
|
|
524
528
|
continue;
|
|
525
529
|
}
|
|
526
|
-
|
|
527
530
|
const hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, viewBottom - bottom);
|
|
528
531
|
const hiddenWidth = Math.max(0, left - currentWidth) + Math.max(0, viewRight - right);
|
|
529
532
|
const fractionHeight = (viewHeight - hiddenHeight) / viewHeight,
|
|
530
|
-
|
|
533
|
+
fractionWidth = (viewWidth - hiddenWidth) / viewWidth;
|
|
531
534
|
const percent = fractionHeight * fractionWidth * 100 | 0;
|
|
532
535
|
visible.push({
|
|
533
536
|
id: view.id,
|
|
@@ -537,145 +540,65 @@ function getVisibleElements({
|
|
|
537
540
|
percent,
|
|
538
541
|
widthPercent: fractionWidth * 100 | 0
|
|
539
542
|
});
|
|
543
|
+
ids.add(view.id);
|
|
540
544
|
}
|
|
541
|
-
|
|
542
545
|
const first = visible[0],
|
|
543
|
-
|
|
544
|
-
|
|
546
|
+
last = visible.at(-1);
|
|
545
547
|
if (sortByVisibility) {
|
|
546
548
|
visible.sort(function (a, b) {
|
|
547
549
|
const pc = a.percent - b.percent;
|
|
548
|
-
|
|
549
550
|
if (Math.abs(pc) > 0.001) {
|
|
550
551
|
return -pc;
|
|
551
552
|
}
|
|
552
|
-
|
|
553
553
|
return a.id - b.id; // ensure stability
|
|
554
554
|
});
|
|
555
555
|
}
|
|
556
|
-
|
|
557
556
|
return {
|
|
558
557
|
first,
|
|
559
558
|
last,
|
|
560
|
-
views: visible
|
|
559
|
+
views: visible,
|
|
560
|
+
ids
|
|
561
561
|
};
|
|
562
562
|
}
|
|
563
|
-
/**
|
|
564
|
-
* Event handler to suppress context menu.
|
|
565
|
-
*/
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
function noContextMenuHandler(evt) {
|
|
569
|
-
evt.preventDefault();
|
|
570
|
-
}
|
|
571
|
-
|
|
572
563
|
function normalizeWheelEventDirection(evt) {
|
|
573
564
|
let delta = Math.hypot(evt.deltaX, evt.deltaY);
|
|
574
565
|
const angle = Math.atan2(evt.deltaY, evt.deltaX);
|
|
575
|
-
|
|
576
566
|
if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {
|
|
577
567
|
// All that is left-up oriented has to change the sign.
|
|
578
568
|
delta = -delta;
|
|
579
569
|
}
|
|
580
|
-
|
|
581
570
|
return delta;
|
|
582
571
|
}
|
|
583
|
-
|
|
584
572
|
function normalizeWheelEventDelta(evt) {
|
|
573
|
+
const deltaMode = evt.deltaMode; // Avoid being affected by bug 1392460.
|
|
585
574
|
let delta = normalizeWheelEventDirection(evt);
|
|
586
|
-
const MOUSE_DOM_DELTA_PIXEL_MODE = 0;
|
|
587
|
-
const MOUSE_DOM_DELTA_LINE_MODE = 1;
|
|
588
575
|
const MOUSE_PIXELS_PER_LINE = 30;
|
|
589
|
-
const MOUSE_LINES_PER_PAGE = 30;
|
|
576
|
+
const MOUSE_LINES_PER_PAGE = 30;
|
|
590
577
|
|
|
591
|
-
|
|
578
|
+
// Converts delta to per-page units
|
|
579
|
+
if (deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
|
|
592
580
|
delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE;
|
|
593
|
-
} else if (
|
|
581
|
+
} else if (deltaMode === WheelEvent.DOM_DELTA_LINE) {
|
|
594
582
|
delta /= MOUSE_LINES_PER_PAGE;
|
|
595
583
|
}
|
|
596
|
-
|
|
597
584
|
return delta;
|
|
598
585
|
}
|
|
599
|
-
|
|
600
586
|
function isValidRotation(angle) {
|
|
601
587
|
return Number.isInteger(angle) && angle % 90 === 0;
|
|
602
588
|
}
|
|
603
|
-
|
|
604
589
|
function isValidScrollMode(mode) {
|
|
605
590
|
return Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && mode !== ScrollMode.UNKNOWN;
|
|
606
591
|
}
|
|
607
|
-
|
|
608
592
|
function isValidSpreadMode(mode) {
|
|
609
593
|
return Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && mode !== SpreadMode.UNKNOWN;
|
|
610
594
|
}
|
|
611
|
-
|
|
612
595
|
function isPortraitOrientation(size) {
|
|
613
596
|
return size.width <= size.height;
|
|
614
597
|
}
|
|
615
598
|
|
|
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
599
|
/**
|
|
675
600
|
* Promise that is resolved when DOM window becomes visible.
|
|
676
601
|
*/
|
|
677
|
-
|
|
678
|
-
|
|
679
602
|
const animationStarted = new Promise(function (resolve) {
|
|
680
603
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("LIB") && typeof window === "undefined") {
|
|
681
604
|
// Prevent "ReferenceError: window is not defined" errors when running the
|
|
@@ -683,272 +606,73 @@ const animationStarted = new Promise(function (resolve) {
|
|
|
683
606
|
setTimeout(resolve, 20);
|
|
684
607
|
return;
|
|
685
608
|
}
|
|
686
|
-
|
|
687
609
|
window.requestAnimationFrame(resolve);
|
|
688
610
|
});
|
|
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
|
-
|
|
611
|
+
const docStyle = typeof PDFJSDev !== "undefined" && PDFJSDev.test("LIB") && typeof document === "undefined" ? null : document.documentElement.style;
|
|
848
612
|
function clamp(v, min, max) {
|
|
849
613
|
return Math.min(Math.max(v, min), max);
|
|
850
614
|
}
|
|
851
|
-
|
|
852
615
|
class ProgressBar {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
this
|
|
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;
|
|
616
|
+
#classList = null;
|
|
617
|
+
#disableAutoFetchTimeout = null;
|
|
618
|
+
#percent = 0;
|
|
619
|
+
#style = null;
|
|
620
|
+
#visible = true;
|
|
621
|
+
constructor(bar) {
|
|
622
|
+
this.#classList = bar.classList;
|
|
623
|
+
this.#style = bar.style;
|
|
870
624
|
}
|
|
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
625
|
get percent() {
|
|
885
|
-
return this
|
|
626
|
+
return this.#percent;
|
|
886
627
|
}
|
|
887
|
-
|
|
888
628
|
set percent(val) {
|
|
889
|
-
this
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
629
|
+
this.#percent = clamp(val, 0, 100);
|
|
630
|
+
if (isNaN(val)) {
|
|
631
|
+
this.#classList.add("indeterminate");
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
this.#classList.remove("indeterminate");
|
|
635
|
+
this.#style.setProperty("--progressBar-percent", `${this.#percent}%`);
|
|
893
636
|
}
|
|
894
|
-
|
|
895
637
|
setWidth(viewer) {
|
|
896
638
|
if (!viewer) {
|
|
897
639
|
return;
|
|
898
640
|
}
|
|
899
|
-
|
|
900
641
|
const container = viewer.parentNode;
|
|
901
642
|
const scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
|
|
902
|
-
|
|
903
643
|
if (scrollbarWidth > 0) {
|
|
904
|
-
|
|
905
|
-
doc.style.setProperty(LOADINGBAR_END_OFFSET_VAR, `${scrollbarWidth}px`);
|
|
644
|
+
this.#style.setProperty("--progressBar-end-offset", `${scrollbarWidth}px`);
|
|
906
645
|
}
|
|
907
646
|
}
|
|
908
|
-
|
|
647
|
+
setDisableAutoFetch(delay = /* ms = */5000) {
|
|
648
|
+
if (isNaN(this.#percent)) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
if (this.#disableAutoFetchTimeout) {
|
|
652
|
+
clearTimeout(this.#disableAutoFetchTimeout);
|
|
653
|
+
}
|
|
654
|
+
this.show();
|
|
655
|
+
this.#disableAutoFetchTimeout = setTimeout(() => {
|
|
656
|
+
this.#disableAutoFetchTimeout = null;
|
|
657
|
+
this.hide();
|
|
658
|
+
}, delay);
|
|
659
|
+
}
|
|
909
660
|
hide() {
|
|
910
|
-
if (!this
|
|
661
|
+
if (!this.#visible) {
|
|
911
662
|
return;
|
|
912
663
|
}
|
|
913
|
-
|
|
914
|
-
this.
|
|
915
|
-
this.bar.classList.add("hidden");
|
|
664
|
+
this.#visible = false;
|
|
665
|
+
this.#classList.add("hidden");
|
|
916
666
|
}
|
|
917
|
-
|
|
918
667
|
show() {
|
|
919
|
-
if (this
|
|
668
|
+
if (this.#visible) {
|
|
920
669
|
return;
|
|
921
670
|
}
|
|
922
|
-
|
|
923
|
-
this.
|
|
924
|
-
this.bar.classList.remove("hidden");
|
|
671
|
+
this.#visible = true;
|
|
672
|
+
this.#classList.remove("hidden");
|
|
925
673
|
}
|
|
926
|
-
|
|
927
674
|
}
|
|
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
675
|
|
|
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
676
|
/**
|
|
953
677
|
* Get the active or focused element in current DOM.
|
|
954
678
|
*
|
|
@@ -957,48 +681,50 @@ function moveToEndOfArray(arr, condition) {
|
|
|
957
681
|
*
|
|
958
682
|
* @returns {Element} the truly active or focused element.
|
|
959
683
|
*/
|
|
960
|
-
|
|
961
|
-
|
|
962
684
|
function getActiveOrFocusedElement() {
|
|
963
685
|
let curRoot = document;
|
|
964
686
|
let curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
|
|
965
|
-
|
|
966
687
|
while ((_curActiveOrFocused = curActiveOrFocused) !== null && _curActiveOrFocused !== void 0 && _curActiveOrFocused.shadowRoot) {
|
|
967
688
|
var _curActiveOrFocused;
|
|
968
|
-
|
|
969
689
|
curRoot = curActiveOrFocused.shadowRoot;
|
|
970
690
|
curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
|
|
971
691
|
}
|
|
972
|
-
|
|
973
692
|
return curActiveOrFocused;
|
|
974
693
|
}
|
|
694
|
+
|
|
975
695
|
/**
|
|
976
696
|
* Converts API PageLayout values to the format used by `BaseViewer`.
|
|
977
|
-
*
|
|
978
|
-
*
|
|
979
|
-
* and TwoPageRight all suggests using non-continuous scrolling).
|
|
980
|
-
* @param {string} mode - The API PageLayout value.
|
|
981
|
-
* @returns {number} A value from {SpreadMode}.
|
|
697
|
+
* @param {string} layout - The API PageLayout value.
|
|
698
|
+
* @returns {Object}
|
|
982
699
|
*/
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
700
|
+
function apiPageLayoutToViewerModes(layout) {
|
|
701
|
+
let scrollMode = ScrollMode.VERTICAL,
|
|
702
|
+
spreadMode = SpreadMode.NONE;
|
|
986
703
|
switch (layout) {
|
|
987
704
|
case "SinglePage":
|
|
705
|
+
scrollMode = ScrollMode.PAGE;
|
|
706
|
+
break;
|
|
988
707
|
case "OneColumn":
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
case "TwoColumnLeft":
|
|
708
|
+
break;
|
|
992
709
|
case "TwoPageLeft":
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
case "
|
|
710
|
+
scrollMode = ScrollMode.PAGE;
|
|
711
|
+
/* falls through */
|
|
712
|
+
case "TwoColumnLeft":
|
|
713
|
+
spreadMode = SpreadMode.ODD;
|
|
714
|
+
break;
|
|
996
715
|
case "TwoPageRight":
|
|
997
|
-
|
|
716
|
+
scrollMode = ScrollMode.PAGE;
|
|
717
|
+
/* falls through */
|
|
718
|
+
case "TwoColumnRight":
|
|
719
|
+
spreadMode = SpreadMode.EVEN;
|
|
720
|
+
break;
|
|
998
721
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
722
|
+
return {
|
|
723
|
+
scrollMode,
|
|
724
|
+
spreadMode
|
|
725
|
+
};
|
|
1001
726
|
}
|
|
727
|
+
|
|
1002
728
|
/**
|
|
1003
729
|
* Converts API PageMode values to the format used by `PDFSidebar`.
|
|
1004
730
|
* NOTE: There's also a "FullScreen" parameter which is not possible to support,
|
|
@@ -1007,27 +733,30 @@ function apiPageLayoutToSpreadMode(layout) {
|
|
|
1007
733
|
* @param {string} mode - The API PageMode value.
|
|
1008
734
|
* @returns {number} A value from {SidebarView}.
|
|
1009
735
|
*/
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
736
|
function apiPageModeToSidebarView(mode) {
|
|
1013
737
|
switch (mode) {
|
|
1014
738
|
case "UseNone":
|
|
1015
739
|
return SidebarView.NONE;
|
|
1016
|
-
|
|
1017
740
|
case "UseThumbs":
|
|
1018
741
|
return SidebarView.THUMBS;
|
|
1019
|
-
|
|
1020
742
|
case "UseOutlines":
|
|
1021
743
|
return SidebarView.OUTLINE;
|
|
1022
|
-
|
|
1023
744
|
case "UseAttachments":
|
|
1024
745
|
return SidebarView.ATTACHMENTS;
|
|
1025
|
-
|
|
1026
746
|
case "UseOC":
|
|
1027
747
|
return SidebarView.LAYERS;
|
|
1028
748
|
}
|
|
1029
|
-
|
|
1030
749
|
return SidebarView.NONE; // Default value.
|
|
1031
750
|
}
|
|
751
|
+
function toggleCheckedBtn(button, toggle, view = null) {
|
|
752
|
+
button.classList.toggle("toggled", toggle);
|
|
753
|
+
button.setAttribute("aria-checked", toggle);
|
|
754
|
+
view === null || view === void 0 ? void 0 : view.classList.toggle("hidden", !toggle);
|
|
755
|
+
}
|
|
756
|
+
function toggleExpandedBtn(button, toggle, view = null) {
|
|
757
|
+
button.classList.toggle("toggled", toggle);
|
|
758
|
+
button.setAttribute("aria-expanded", toggle);
|
|
759
|
+
view === null || view === void 0 ? void 0 : view.classList.toggle("hidden", !toggle);
|
|
760
|
+
}
|
|
1032
761
|
|
|
1033
|
-
export { AutoPrintRegExp,
|
|
762
|
+
export { AutoPrintRegExp, CursorTool, DEFAULT_SCALE, DEFAULT_SCALE_DELTA, DEFAULT_SCALE_VALUE, MAX_AUTO_SCALE, MAX_SCALE, MIN_SCALE, OutputScale, PresentationModeState, ProgressBar, RenderingStates, SCROLLBAR_PADDING, ScrollMode, SidebarView, SpreadMode, TextLayerMode, UNKNOWN_SCALE, VERTICAL_PADDING, animationStarted, apiPageLayoutToViewerModes, apiPageModeToSidebarView, approximateFraction, backtrackBeforeAllVisibleElements, binarySearchFirstItem, docStyle, getActiveOrFocusedElement, getPageSizeInches, getVisibleElements, isPortraitOrientation, isValidRotation, isValidScrollMode, isValidSpreadMode, normalizeWheelEventDelta, normalizeWheelEventDirection, parseQueryString, removeNullCharacters, roundToDivide, scrollIntoView, toggleCheckedBtn, toggleExpandedBtn, watchScroll };
|