@vaadin-component-factory/vcf-pdf-viewer 4.0.2 → 4.1.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.
@@ -1,848 +0,0 @@
1
- import { u as unreachable, D as CMapCompressionType, K as BaseException, c as assert, J as removeNullCharacters, w as warn, L as isString, n as stringToBytes, e as Util } from './util.js';
2
-
3
- /* Copyright 2015 Mozilla Foundation
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- class BaseCanvasFactory {
19
- constructor() {
20
- if (this.constructor === BaseCanvasFactory) {
21
- unreachable("Cannot initialize BaseCanvasFactory.");
22
- }
23
- }
24
-
25
- create(width, height) {
26
- if (width <= 0 || height <= 0) {
27
- throw new Error("Invalid canvas size");
28
- }
29
-
30
- const canvas = this._createCanvas(width, height);
31
-
32
- return {
33
- canvas,
34
- context: canvas.getContext("2d")
35
- };
36
- }
37
-
38
- reset(canvasAndContext, width, height) {
39
- if (!canvasAndContext.canvas) {
40
- throw new Error("Canvas is not specified");
41
- }
42
-
43
- if (width <= 0 || height <= 0) {
44
- throw new Error("Invalid canvas size");
45
- }
46
-
47
- canvasAndContext.canvas.width = width;
48
- canvasAndContext.canvas.height = height;
49
- }
50
-
51
- destroy(canvasAndContext) {
52
- if (!canvasAndContext.canvas) {
53
- throw new Error("Canvas is not specified");
54
- } // Zeroing the width and height cause Firefox to release graphics
55
- // resources immediately, which can greatly reduce memory consumption.
56
-
57
-
58
- canvasAndContext.canvas.width = 0;
59
- canvasAndContext.canvas.height = 0;
60
- canvasAndContext.canvas = null;
61
- canvasAndContext.context = null;
62
- }
63
- /**
64
- * @private
65
- */
66
-
67
-
68
- _createCanvas(width, height) {
69
- unreachable("Abstract method `_createCanvas` called.");
70
- }
71
-
72
- }
73
-
74
- class BaseCMapReaderFactory {
75
- constructor({
76
- baseUrl = null,
77
- isCompressed = false
78
- }) {
79
- if (this.constructor === BaseCMapReaderFactory) {
80
- unreachable("Cannot initialize BaseCMapReaderFactory.");
81
- }
82
-
83
- this.baseUrl = baseUrl;
84
- this.isCompressed = isCompressed;
85
- }
86
-
87
- async fetch({
88
- name
89
- }) {
90
- if (!this.baseUrl) {
91
- throw new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.');
92
- }
93
-
94
- if (!name) {
95
- throw new Error("CMap name must be specified.");
96
- }
97
-
98
- const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : "");
99
- const compressionType = this.isCompressed ? CMapCompressionType.BINARY : CMapCompressionType.NONE;
100
- return this._fetchData(url, compressionType).catch(reason => {
101
- throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`);
102
- });
103
- }
104
- /**
105
- * @private
106
- */
107
-
108
-
109
- _fetchData(url, compressionType) {
110
- unreachable("Abstract method `_fetchData` called.");
111
- }
112
-
113
- }
114
-
115
- class BaseStandardFontDataFactory {
116
- constructor({
117
- baseUrl = null
118
- }) {
119
- if (this.constructor === BaseStandardFontDataFactory) {
120
- unreachable("Cannot initialize BaseStandardFontDataFactory.");
121
- }
122
-
123
- this.baseUrl = baseUrl;
124
- }
125
-
126
- async fetch({
127
- filename
128
- }) {
129
- if (!this.baseUrl) {
130
- throw new Error('The standard font "baseUrl" parameter must be specified, ensure that ' + 'the "standardFontDataUrl" API parameter is provided.');
131
- }
132
-
133
- if (!filename) {
134
- throw new Error("Font filename must be specified.");
135
- }
136
-
137
- const url = `${this.baseUrl}${filename}`;
138
- return this._fetchData(url).catch(reason => {
139
- throw new Error(`Unable to load font data at: ${url}`);
140
- });
141
- }
142
- /**
143
- * @private
144
- */
145
-
146
-
147
- _fetchData(url) {
148
- unreachable("Abstract method `_fetchData` called.");
149
- }
150
-
151
- }
152
-
153
- class BaseSVGFactory {
154
- constructor() {
155
- if (this.constructor === BaseSVGFactory) {
156
- unreachable("Cannot initialize BaseSVGFactory.");
157
- }
158
- }
159
-
160
- create(width, height) {
161
- if (width <= 0 || height <= 0) {
162
- throw new Error("Invalid SVG dimensions");
163
- }
164
-
165
- const svg = this._createSVG("svg:svg");
166
-
167
- svg.setAttribute("version", "1.1");
168
- svg.setAttribute("width", `${width}px`);
169
- svg.setAttribute("height", `${height}px`);
170
- svg.setAttribute("preserveAspectRatio", "none");
171
- svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
172
- return svg;
173
- }
174
-
175
- createElement(type) {
176
- if (typeof type !== "string") {
177
- throw new Error("Invalid SVG element type");
178
- }
179
-
180
- return this._createSVG(type);
181
- }
182
- /**
183
- * @private
184
- */
185
-
186
-
187
- _createSVG(type) {
188
- unreachable("Abstract method `_createSVG` called.");
189
- }
190
-
191
- }
192
-
193
- /* Copyright 2015 Mozilla Foundation
194
- *
195
- * Licensed under the Apache License, Version 2.0 (the "License");
196
- * you may not use this file except in compliance with the License.
197
- * You may obtain a copy of the License at
198
- *
199
- * http://www.apache.org/licenses/LICENSE-2.0
200
- *
201
- * Unless required by applicable law or agreed to in writing, software
202
- * distributed under the License is distributed on an "AS IS" BASIS,
203
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
204
- * See the License for the specific language governing permissions and
205
- * limitations under the License.
206
- */
207
- const DEFAULT_LINK_REL = "noopener noreferrer nofollow";
208
- const SVG_NS = "http://www.w3.org/2000/svg";
209
-
210
- class DOMCanvasFactory extends BaseCanvasFactory {
211
- constructor({
212
- ownerDocument = globalThis.document
213
- } = {}) {
214
- super();
215
- this._document = ownerDocument;
216
- }
217
-
218
- _createCanvas(width, height) {
219
- const canvas = this._document.createElement("canvas");
220
-
221
- canvas.width = width;
222
- canvas.height = height;
223
- return canvas;
224
- }
225
-
226
- }
227
-
228
- async function fetchData(url, asTypedArray = false) {
229
- if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL") || isValidFetchUrl(url, document.baseURI)) {
230
- const response = await fetch(url);
231
-
232
- if (!response.ok) {
233
- throw new Error(response.statusText);
234
- }
235
-
236
- return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : stringToBytes(await response.text());
237
- } // The Fetch API is not supported.
238
-
239
-
240
- return new Promise((resolve, reject) => {
241
- const request = new XMLHttpRequest();
242
- request.open("GET", url,
243
- /* asTypedArray = */
244
- true);
245
-
246
- if (asTypedArray) {
247
- request.responseType = "arraybuffer";
248
- }
249
-
250
- request.onreadystatechange = () => {
251
- if (request.readyState !== XMLHttpRequest.DONE) {
252
- return;
253
- }
254
-
255
- if (request.status === 200 || request.status === 0) {
256
- let data;
257
-
258
- if (asTypedArray && request.response) {
259
- data = new Uint8Array(request.response);
260
- } else if (!asTypedArray && request.responseText) {
261
- data = stringToBytes(request.responseText);
262
- }
263
-
264
- if (data) {
265
- resolve(data);
266
- return;
267
- }
268
- }
269
-
270
- reject(new Error(request.statusText));
271
- };
272
-
273
- request.send(null);
274
- });
275
- }
276
-
277
- class DOMCMapReaderFactory extends BaseCMapReaderFactory {
278
- _fetchData(url, compressionType) {
279
- return fetchData(url,
280
- /* asTypedArray = */
281
- this.isCompressed).then(data => {
282
- return {
283
- cMapData: data,
284
- compressionType
285
- };
286
- });
287
- }
288
-
289
- }
290
-
291
- class DOMStandardFontDataFactory extends BaseStandardFontDataFactory {
292
- _fetchData(url) {
293
- return fetchData(url,
294
- /* asTypedArray = */
295
- true);
296
- }
297
-
298
- }
299
-
300
- class DOMSVGFactory extends BaseSVGFactory {
301
- _createSVG(type) {
302
- return document.createElementNS(SVG_NS, type);
303
- }
304
-
305
- }
306
- /**
307
- * @typedef {Object} PageViewportParameters
308
- * @property {Array<number>} viewBox - The xMin, yMin, xMax and
309
- * yMax coordinates.
310
- * @property {number} scale - The scale of the viewport.
311
- * @property {number} rotation - The rotation, in degrees, of the viewport.
312
- * @property {number} [offsetX] - The horizontal, i.e. x-axis, offset. The
313
- * default value is `0`.
314
- * @property {number} [offsetY] - The vertical, i.e. y-axis, offset. The
315
- * default value is `0`.
316
- * @property {boolean} [dontFlip] - If true, the y-axis will not be flipped.
317
- * The default value is `false`.
318
- */
319
-
320
- /**
321
- * @typedef {Object} PageViewportCloneParameters
322
- * @property {number} [scale] - The scale, overriding the one in the cloned
323
- * viewport. The default value is `this.scale`.
324
- * @property {number} [rotation] - The rotation, in degrees, overriding the one
325
- * in the cloned viewport. The default value is `this.rotation`.
326
- * @property {number} [offsetX] - The horizontal, i.e. x-axis, offset.
327
- * The default value is `this.offsetX`.
328
- * @property {number} [offsetY] - The vertical, i.e. y-axis, offset.
329
- * The default value is `this.offsetY`.
330
- * @property {boolean} [dontFlip] - If true, the x-axis will not be flipped.
331
- * The default value is `false`.
332
- */
333
-
334
- /**
335
- * PDF page viewport created based on scale, rotation and offset.
336
- */
337
-
338
-
339
- class PageViewport {
340
- /**
341
- * @param {PageViewportParameters}
342
- */
343
- constructor({
344
- viewBox,
345
- scale,
346
- rotation,
347
- offsetX = 0,
348
- offsetY = 0,
349
- dontFlip = false
350
- }) {
351
- this.viewBox = viewBox;
352
- this.scale = scale;
353
- this.rotation = rotation;
354
- this.offsetX = offsetX;
355
- this.offsetY = offsetY; // creating transform to convert pdf coordinate system to the normal
356
- // canvas like coordinates taking in account scale and rotation
357
-
358
- const centerX = (viewBox[2] + viewBox[0]) / 2;
359
- const centerY = (viewBox[3] + viewBox[1]) / 2;
360
- let rotateA, rotateB, rotateC, rotateD; // Normalize the rotation, by clamping it to the [0, 360) range.
361
-
362
- rotation %= 360;
363
-
364
- if (rotation < 0) {
365
- rotation += 360;
366
- }
367
-
368
- switch (rotation) {
369
- case 180:
370
- rotateA = -1;
371
- rotateB = 0;
372
- rotateC = 0;
373
- rotateD = 1;
374
- break;
375
-
376
- case 90:
377
- rotateA = 0;
378
- rotateB = 1;
379
- rotateC = 1;
380
- rotateD = 0;
381
- break;
382
-
383
- case 270:
384
- rotateA = 0;
385
- rotateB = -1;
386
- rotateC = -1;
387
- rotateD = 0;
388
- break;
389
-
390
- case 0:
391
- rotateA = 1;
392
- rotateB = 0;
393
- rotateC = 0;
394
- rotateD = -1;
395
- break;
396
-
397
- default:
398
- throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees.");
399
- }
400
-
401
- if (dontFlip) {
402
- rotateC = -rotateC;
403
- rotateD = -rotateD;
404
- }
405
-
406
- let offsetCanvasX, offsetCanvasY;
407
- let width, height;
408
-
409
- if (rotateA === 0) {
410
- offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
411
- offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
412
- width = Math.abs(viewBox[3] - viewBox[1]) * scale;
413
- height = Math.abs(viewBox[2] - viewBox[0]) * scale;
414
- } else {
415
- offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
416
- offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
417
- width = Math.abs(viewBox[2] - viewBox[0]) * scale;
418
- height = Math.abs(viewBox[3] - viewBox[1]) * scale;
419
- } // creating transform for the following operations:
420
- // translate(-centerX, -centerY), rotate and flip vertically,
421
- // scale, and translate(offsetCanvasX, offsetCanvasY)
422
-
423
-
424
- this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY];
425
- this.width = width;
426
- this.height = height;
427
- }
428
- /**
429
- * Clones viewport, with optional additional properties.
430
- * @param {PageViewportCloneParameters} [params]
431
- * @returns {PageViewport} Cloned viewport.
432
- */
433
-
434
-
435
- clone({
436
- scale = this.scale,
437
- rotation = this.rotation,
438
- offsetX = this.offsetX,
439
- offsetY = this.offsetY,
440
- dontFlip = false
441
- } = {}) {
442
- return new PageViewport({
443
- viewBox: this.viewBox.slice(),
444
- scale,
445
- rotation,
446
- offsetX,
447
- offsetY,
448
- dontFlip
449
- });
450
- }
451
- /**
452
- * Converts PDF point to the viewport coordinates. For examples, useful for
453
- * converting PDF location into canvas pixel coordinates.
454
- * @param {number} x - The x-coordinate.
455
- * @param {number} y - The y-coordinate.
456
- * @returns {Object} Object containing `x` and `y` properties of the
457
- * point in the viewport coordinate space.
458
- * @see {@link convertToPdfPoint}
459
- * @see {@link convertToViewportRectangle}
460
- */
461
-
462
-
463
- convertToViewportPoint(x, y) {
464
- return Util.applyTransform([x, y], this.transform);
465
- }
466
- /**
467
- * Converts PDF rectangle to the viewport coordinates.
468
- * @param {Array} rect - The xMin, yMin, xMax and yMax coordinates.
469
- * @returns {Array} Array containing corresponding coordinates of the
470
- * rectangle in the viewport coordinate space.
471
- * @see {@link convertToViewportPoint}
472
- */
473
-
474
-
475
- convertToViewportRectangle(rect) {
476
- const topLeft = Util.applyTransform([rect[0], rect[1]], this.transform);
477
- const bottomRight = Util.applyTransform([rect[2], rect[3]], this.transform);
478
- return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]];
479
- }
480
- /**
481
- * Converts viewport coordinates to the PDF location. For examples, useful
482
- * for converting canvas pixel location into PDF one.
483
- * @param {number} x - The x-coordinate.
484
- * @param {number} y - The y-coordinate.
485
- * @returns {Object} Object containing `x` and `y` properties of the
486
- * point in the PDF coordinate space.
487
- * @see {@link convertToViewportPoint}
488
- */
489
-
490
-
491
- convertToPdfPoint(x, y) {
492
- return Util.applyInverseTransform([x, y], this.transform);
493
- }
494
-
495
- }
496
-
497
- class RenderingCancelledException extends BaseException {
498
- constructor(msg, type) {
499
- super(msg);
500
- this.type = type;
501
- }
502
-
503
- }
504
-
505
- const LinkTarget = {
506
- NONE: 0,
507
- // Default value.
508
- SELF: 1,
509
- BLANK: 2,
510
- PARENT: 3,
511
- TOP: 4
512
- };
513
- /**
514
- * @typedef ExternalLinkParameters
515
- * @typedef {Object} ExternalLinkParameters
516
- * @property {string} url - An absolute URL.
517
- * @property {LinkTarget} [target] - The link target. The default value is
518
- * `LinkTarget.NONE`.
519
- * @property {string} [rel] - The link relationship. The default value is
520
- * `DEFAULT_LINK_REL`.
521
- * @property {boolean} [enabled] - Whether the link should be enabled. The
522
- * default value is true.
523
- */
524
-
525
- /**
526
- * Adds various attributes (href, title, target, rel) to hyperlinks.
527
- * @param {HTMLLinkElement} link - The link element.
528
- * @param {ExternalLinkParameters} params
529
- */
530
-
531
- function addLinkAttributes(link, {
532
- url,
533
- target,
534
- rel,
535
- enabled = true
536
- } = {}) {
537
- assert(url && typeof url === "string", 'addLinkAttributes: A valid "url" parameter must provided.');
538
- const urlNullRemoved = removeNullCharacters(url);
539
-
540
- if (enabled) {
541
- link.href = link.title = urlNullRemoved;
542
- } else {
543
- link.href = "";
544
- link.title = `Disabled: ${urlNullRemoved}`;
545
-
546
- link.onclick = () => {
547
- return false;
548
- };
549
- }
550
-
551
- let targetStr = ""; // LinkTarget.NONE
552
-
553
- switch (target) {
554
- case LinkTarget.NONE:
555
- break;
556
-
557
- case LinkTarget.SELF:
558
- targetStr = "_self";
559
- break;
560
-
561
- case LinkTarget.BLANK:
562
- targetStr = "_blank";
563
- break;
564
-
565
- case LinkTarget.PARENT:
566
- targetStr = "_parent";
567
- break;
568
-
569
- case LinkTarget.TOP:
570
- targetStr = "_top";
571
- break;
572
- }
573
-
574
- link.target = targetStr;
575
- link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL;
576
- }
577
-
578
- function isDataScheme(url) {
579
- const ii = url.length;
580
- let i = 0;
581
-
582
- while (i < ii && url[i].trim() === "") {
583
- i++;
584
- }
585
-
586
- return url.substring(i, i + 5).toLowerCase() === "data:";
587
- }
588
-
589
- function isPdfFile(filename) {
590
- return typeof filename === "string" && /\.pdf$/i.test(filename);
591
- }
592
- /**
593
- * Gets the filename from a given URL.
594
- * @param {string} url
595
- * @returns {string}
596
- */
597
-
598
-
599
- function getFilenameFromUrl(url) {
600
- const anchor = url.indexOf("#");
601
- const query = url.indexOf("?");
602
- const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);
603
- return url.substring(url.lastIndexOf("/", end) + 1, end);
604
- }
605
- /**
606
- * Returns the filename or guessed filename from the url (see issue 3455).
607
- * @param {string} url - The original PDF location.
608
- * @param {string} defaultFilename - The value returned if the filename is
609
- * unknown, or the protocol is unsupported.
610
- * @returns {string} Guessed PDF filename.
611
- */
612
-
613
-
614
- function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
615
- if (typeof url !== "string") {
616
- return defaultFilename;
617
- }
618
-
619
- if (isDataScheme(url)) {
620
- warn('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.');
621
- return defaultFilename;
622
- }
623
-
624
- const reURI = /^(?:(?:[^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/; // SCHEME HOST 1.PATH 2.QUERY 3.REF
625
- // Pattern to get last matching NAME.pdf
626
-
627
- const reFilename = /[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
628
- const splitURI = reURI.exec(url);
629
- let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]);
630
-
631
- if (suggestedFilename) {
632
- suggestedFilename = suggestedFilename[0];
633
-
634
- if (suggestedFilename.includes("%")) {
635
- // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
636
- try {
637
- suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0];
638
- } catch (ex) {// Possible (extremely rare) errors:
639
- // URIError "Malformed URI", e.g. for "%AA.pdf"
640
- // TypeError "null has no properties", e.g. for "%2F.pdf"
641
- }
642
- }
643
- }
644
-
645
- return suggestedFilename || defaultFilename;
646
- }
647
-
648
- class StatTimer {
649
- constructor() {
650
- this.started = Object.create(null);
651
- this.times = [];
652
- }
653
-
654
- time(name) {
655
- if (name in this.started) {
656
- warn(`Timer is already running for ${name}`);
657
- }
658
-
659
- this.started[name] = Date.now();
660
- }
661
-
662
- timeEnd(name) {
663
- if (!(name in this.started)) {
664
- warn(`Timer has not been started for ${name}`);
665
- }
666
-
667
- this.times.push({
668
- name,
669
- start: this.started[name],
670
- end: Date.now()
671
- }); // Remove timer from started so it can be called again.
672
-
673
- delete this.started[name];
674
- }
675
-
676
- toString() {
677
- // Find the longest name for padding purposes.
678
- const outBuf = [];
679
- let longest = 0;
680
-
681
- for (const time of this.times) {
682
- const name = time.name;
683
-
684
- if (name.length > longest) {
685
- longest = name.length;
686
- }
687
- }
688
-
689
- for (const time of this.times) {
690
- const duration = time.end - time.start;
691
- outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\n`);
692
- }
693
-
694
- return outBuf.join("");
695
- }
696
-
697
- }
698
-
699
- function isValidFetchUrl(url, baseUrl) {
700
- try {
701
- const {
702
- protocol
703
- } = baseUrl ? new URL(url, baseUrl) : new URL(url); // The Fetch API only supports the http/https protocols, and not file/ftp.
704
-
705
- return protocol === "http:" || protocol === "https:";
706
- } catch (ex) {
707
- return false; // `new URL()` will throw on incorrect data.
708
- }
709
- }
710
- /**
711
- * @param {string} src
712
- * @param {boolean} [removeScriptElement]
713
- * @returns {Promise<void>}
714
- */
715
-
716
-
717
- function loadScript(src, removeScriptElement = false) {
718
- return new Promise((resolve, reject) => {
719
- const script = document.createElement("script");
720
- script.src = src;
721
-
722
- script.onload = function (evt) {
723
- if (removeScriptElement) {
724
- script.remove();
725
- }
726
-
727
- resolve(evt);
728
- };
729
-
730
- script.onerror = function () {
731
- reject(new Error(`Cannot load script at: ${script.src}`));
732
- };
733
-
734
- (document.head || document.documentElement).appendChild(script);
735
- });
736
- } // Deprecated API function -- display regardless of the `verbosity` setting.
737
-
738
-
739
- function deprecated(details) {
740
- console.log("Deprecated API usage: " + details);
741
- }
742
-
743
- let pdfDateStringRegex;
744
-
745
- class PDFDateString {
746
- /**
747
- * Convert a PDF date string to a JavaScript `Date` object.
748
- *
749
- * The PDF date string format is described in section 7.9.4 of the official
750
- * PDF 32000-1:2008 specification. However, in the PDF 1.7 reference (sixth
751
- * edition) Adobe describes the same format including a trailing apostrophe.
752
- * This syntax in incorrect, but Adobe Acrobat creates PDF files that contain
753
- * them. We ignore all apostrophes as they are not necessary for date parsing.
754
- *
755
- * Moreover, Adobe Acrobat doesn't handle changing the date to universal time
756
- * and doesn't use the user's time zone (effectively ignoring the HH' and mm'
757
- * parts of the date string).
758
- *
759
- * @param {string} input
760
- * @returns {Date|null}
761
- */
762
- static toDateObject(input) {
763
- if (!input || !isString(input)) {
764
- return null;
765
- } // Lazily initialize the regular expression.
766
-
767
-
768
- if (!pdfDateStringRegex) {
769
- pdfDateStringRegex = new RegExp("^D:" + // Prefix (required)
770
- "(\\d{4})" + // Year (required)
771
- "(\\d{2})?" + // Month (optional)
772
- "(\\d{2})?" + // Day (optional)
773
- "(\\d{2})?" + // Hour (optional)
774
- "(\\d{2})?" + // Minute (optional)
775
- "(\\d{2})?" + // Second (optional)
776
- "([Z|+|-])?" + // Universal time relation (optional)
777
- "(\\d{2})?" + // Offset hour (optional)
778
- "'?" + // Splitting apostrophe (optional)
779
- "(\\d{2})?" + // Offset minute (optional)
780
- "'?" // Trailing apostrophe (optional)
781
- );
782
- } // Optional fields that don't satisfy the requirements from the regular
783
- // expression (such as incorrect digit counts or numbers that are out of
784
- // range) will fall back the defaults from the specification.
785
-
786
-
787
- const matches = pdfDateStringRegex.exec(input);
788
-
789
- if (!matches) {
790
- return null;
791
- } // JavaScript's `Date` object expects the month to be between 0 and 11
792
- // instead of 1 and 12, so we have to correct for that.
793
-
794
-
795
- const year = parseInt(matches[1], 10);
796
- let month = parseInt(matches[2], 10);
797
- month = month >= 1 && month <= 12 ? month - 1 : 0;
798
- let day = parseInt(matches[3], 10);
799
- day = day >= 1 && day <= 31 ? day : 1;
800
- let hour = parseInt(matches[4], 10);
801
- hour = hour >= 0 && hour <= 23 ? hour : 0;
802
- let minute = parseInt(matches[5], 10);
803
- minute = minute >= 0 && minute <= 59 ? minute : 0;
804
- let second = parseInt(matches[6], 10);
805
- second = second >= 0 && second <= 59 ? second : 0;
806
- const universalTimeRelation = matches[7] || "Z";
807
- let offsetHour = parseInt(matches[8], 10);
808
- offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0;
809
- let offsetMinute = parseInt(matches[9], 10) || 0;
810
- offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0; // Universal time relation 'Z' means that the local time is equal to the
811
- // universal time, whereas the relations '+'/'-' indicate that the local
812
- // time is later respectively earlier than the universal time. Every date
813
- // is normalized to universal time.
814
-
815
- if (universalTimeRelation === "-") {
816
- hour += offsetHour;
817
- minute += offsetMinute;
818
- } else if (universalTimeRelation === "+") {
819
- hour -= offsetHour;
820
- minute -= offsetMinute;
821
- }
822
-
823
- return new Date(Date.UTC(year, month, day, hour, minute, second));
824
- }
825
-
826
- }
827
- /**
828
- * NOTE: This is (mostly) intended to support printing of XFA forms.
829
- */
830
-
831
-
832
- function getXfaPageViewport(xfaPage, {
833
- scale = 1,
834
- rotation = 0
835
- }) {
836
- const {
837
- width,
838
- height
839
- } = xfaPage.attributes.style;
840
- const viewBox = [0, 0, parseInt(width), parseInt(height)];
841
- return new PageViewport({
842
- viewBox,
843
- scale,
844
- rotation
845
- });
846
- }
847
-
848
- export { BaseCanvasFactory as B, DOMCanvasFactory as D, LinkTarget as L, PageViewport as P, RenderingCancelledException as R, StatTimer as S, BaseCMapReaderFactory as a, BaseStandardFontDataFactory as b, DOMCMapReaderFactory as c, DOMStandardFontDataFactory as d, isDataScheme as e, deprecated as f, DOMSVGFactory as g, addLinkAttributes as h, isPdfFile as i, PDFDateString as j, getFilenameFromUrl as k, loadScript as l, isValidFetchUrl as m, getPdfFilenameFromUrl as n, getXfaPageViewport as o };