1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | "use strict";
|
23 |
|
24 | Object.defineProperty(exports, "__esModule", {
|
25 | value: true
|
26 | });
|
27 | exports.PDFDocumentProperties = void 0;
|
28 |
|
29 | var _pdf = require("../pdf");
|
30 |
|
31 | var _ui_utils = require("./ui_utils.js");
|
32 |
|
33 | const DEFAULT_FIELD_CONTENT = "-";
|
34 | const NON_METRIC_LOCALES = ["en-us", "en-lr", "my"];
|
35 | const US_PAGE_NAMES = {
|
36 | "8.5x11": "Letter",
|
37 | "8.5x14": "Legal"
|
38 | };
|
39 | const METRIC_PAGE_NAMES = {
|
40 | "297x420": "A3",
|
41 | "210x297": "A4"
|
42 | };
|
43 |
|
44 | function getPageName(size, isPortrait, pageNames) {
|
45 | const width = isPortrait ? size.width : size.height;
|
46 | const height = isPortrait ? size.height : size.width;
|
47 | return pageNames[`${width}x${height}`];
|
48 | }
|
49 |
|
50 | class PDFDocumentProperties {
|
51 | #fieldData = null;
|
52 |
|
53 | constructor({
|
54 | dialog,
|
55 | fields,
|
56 | closeButton
|
57 | }, overlayManager, eventBus, l10n, fileNameLookup) {
|
58 | this.dialog = dialog;
|
59 | this.fields = fields;
|
60 | this.overlayManager = overlayManager;
|
61 | this.l10n = l10n;
|
62 | this._fileNameLookup = fileNameLookup;
|
63 | this.#reset();
|
64 | closeButton.addEventListener("click", this.close.bind(this));
|
65 | this.overlayManager.register(this.dialog);
|
66 |
|
67 | eventBus._on("pagechanging", evt => {
|
68 | this._currentPageNumber = evt.pageNumber;
|
69 | });
|
70 |
|
71 | eventBus._on("rotationchanging", evt => {
|
72 | this._pagesRotation = evt.pagesRotation;
|
73 | });
|
74 |
|
75 | this._isNonMetricLocale = true;
|
76 | l10n.getLanguage().then(locale => {
|
77 | this._isNonMetricLocale = NON_METRIC_LOCALES.includes(locale);
|
78 | });
|
79 | }
|
80 |
|
81 | async open() {
|
82 | await Promise.all([this.overlayManager.open(this.dialog), this._dataAvailableCapability.promise]);
|
83 | const currentPageNumber = this._currentPageNumber;
|
84 | const pagesRotation = this._pagesRotation;
|
85 |
|
86 | if (this.#fieldData && currentPageNumber === this.#fieldData._currentPageNumber && pagesRotation === this.#fieldData._pagesRotation) {
|
87 | this.#updateUI();
|
88 | return;
|
89 | }
|
90 |
|
91 | const {
|
92 | info,
|
93 | contentLength
|
94 | } = await this.pdfDocument.getMetadata();
|
95 | const [fileName, fileSize, creationDate, modificationDate, pageSize, isLinearized] = await Promise.all([this._fileNameLookup(), this.#parseFileSize(contentLength), this.#parseDate(info.CreationDate), this.#parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then(pdfPage => {
|
96 | return this.#parsePageSize((0, _ui_utils.getPageSizeInches)(pdfPage), pagesRotation);
|
97 | }), this.#parseLinearization(info.IsLinearized)]);
|
98 | this.#fieldData = Object.freeze({
|
99 | fileName,
|
100 | fileSize,
|
101 | title: info.Title,
|
102 | author: info.Author,
|
103 | subject: info.Subject,
|
104 | keywords: info.Keywords,
|
105 | creationDate,
|
106 | modificationDate,
|
107 | creator: info.Creator,
|
108 | producer: info.Producer,
|
109 | version: info.PDFFormatVersion,
|
110 | pageCount: this.pdfDocument.numPages,
|
111 | pageSize,
|
112 | linearized: isLinearized,
|
113 | _currentPageNumber: currentPageNumber,
|
114 | _pagesRotation: pagesRotation
|
115 | });
|
116 | this.#updateUI();
|
117 | const {
|
118 | length
|
119 | } = await this.pdfDocument.getDownloadInfo();
|
120 |
|
121 | if (contentLength === length) {
|
122 | return;
|
123 | }
|
124 |
|
125 | const data = Object.assign(Object.create(null), this.#fieldData);
|
126 | data.fileSize = await this.#parseFileSize(length);
|
127 | this.#fieldData = Object.freeze(data);
|
128 | this.#updateUI();
|
129 | }
|
130 |
|
131 | async close() {
|
132 | this.overlayManager.close(this.dialog);
|
133 | }
|
134 |
|
135 | setDocument(pdfDocument) {
|
136 | if (this.pdfDocument) {
|
137 | this.#reset();
|
138 | this.#updateUI(true);
|
139 | }
|
140 |
|
141 | if (!pdfDocument) {
|
142 | return;
|
143 | }
|
144 |
|
145 | this.pdfDocument = pdfDocument;
|
146 |
|
147 | this._dataAvailableCapability.resolve();
|
148 | }
|
149 |
|
150 | #reset() {
|
151 | this.pdfDocument = null;
|
152 | this.#fieldData = null;
|
153 | this._dataAvailableCapability = (0, _pdf.createPromiseCapability)();
|
154 | this._currentPageNumber = 1;
|
155 | this._pagesRotation = 0;
|
156 | }
|
157 |
|
158 | #updateUI(reset = false) {
|
159 | if (reset || !this.#fieldData) {
|
160 | for (const id in this.fields) {
|
161 | this.fields[id].textContent = DEFAULT_FIELD_CONTENT;
|
162 | }
|
163 |
|
164 | return;
|
165 | }
|
166 |
|
167 | if (this.overlayManager.active !== this.dialog) {
|
168 | return;
|
169 | }
|
170 |
|
171 | for (const id in this.fields) {
|
172 | const content = this.#fieldData[id];
|
173 | this.fields[id].textContent = content || content === 0 ? content : DEFAULT_FIELD_CONTENT;
|
174 | }
|
175 | }
|
176 |
|
177 | async #parseFileSize(fileSize = 0) {
|
178 | const kb = fileSize / 1024,
|
179 | mb = kb / 1024;
|
180 |
|
181 | if (!kb) {
|
182 | return undefined;
|
183 | }
|
184 |
|
185 | return this.l10n.get(`document_properties_${mb >= 1 ? "mb" : "kb"}`, {
|
186 | size_mb: mb >= 1 && (+mb.toPrecision(3)).toLocaleString(),
|
187 | size_kb: mb < 1 && (+kb.toPrecision(3)).toLocaleString(),
|
188 | size_b: fileSize.toLocaleString()
|
189 | });
|
190 | }
|
191 |
|
192 | async #parsePageSize(pageSizeInches, pagesRotation) {
|
193 | if (!pageSizeInches) {
|
194 | return undefined;
|
195 | }
|
196 |
|
197 | if (pagesRotation % 180 !== 0) {
|
198 | pageSizeInches = {
|
199 | width: pageSizeInches.height,
|
200 | height: pageSizeInches.width
|
201 | };
|
202 | }
|
203 |
|
204 | const isPortrait = (0, _ui_utils.isPortraitOrientation)(pageSizeInches);
|
205 | let sizeInches = {
|
206 | width: Math.round(pageSizeInches.width * 100) / 100,
|
207 | height: Math.round(pageSizeInches.height * 100) / 100
|
208 | };
|
209 | let sizeMillimeters = {
|
210 | width: Math.round(pageSizeInches.width * 25.4 * 10) / 10,
|
211 | height: Math.round(pageSizeInches.height * 25.4 * 10) / 10
|
212 | };
|
213 | let rawName = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES);
|
214 |
|
215 | if (!rawName && !(Number.isInteger(sizeMillimeters.width) && Number.isInteger(sizeMillimeters.height))) {
|
216 | const exactMillimeters = {
|
217 | width: pageSizeInches.width * 25.4,
|
218 | height: pageSizeInches.height * 25.4
|
219 | };
|
220 | const intMillimeters = {
|
221 | width: Math.round(sizeMillimeters.width),
|
222 | height: Math.round(sizeMillimeters.height)
|
223 | };
|
224 |
|
225 | if (Math.abs(exactMillimeters.width - intMillimeters.width) < 0.1 && Math.abs(exactMillimeters.height - intMillimeters.height) < 0.1) {
|
226 | rawName = getPageName(intMillimeters, isPortrait, METRIC_PAGE_NAMES);
|
227 |
|
228 | if (rawName) {
|
229 | sizeInches = {
|
230 | width: Math.round(intMillimeters.width / 25.4 * 100) / 100,
|
231 | height: Math.round(intMillimeters.height / 25.4 * 100) / 100
|
232 | };
|
233 | sizeMillimeters = intMillimeters;
|
234 | }
|
235 | }
|
236 | }
|
237 |
|
238 | const [{
|
239 | width,
|
240 | height
|
241 | }, unit, name, orientation] = await Promise.all([this._isNonMetricLocale ? sizeInches : sizeMillimeters, this.l10n.get(`document_properties_page_size_unit_${this._isNonMetricLocale ? "inches" : "millimeters"}`), rawName && this.l10n.get(`document_properties_page_size_name_${rawName.toLowerCase()}`), this.l10n.get(`document_properties_page_size_orientation_${isPortrait ? "portrait" : "landscape"}`)]);
|
242 | return this.l10n.get(`document_properties_page_size_dimension_${name ? "name_" : ""}string`, {
|
243 | width: width.toLocaleString(),
|
244 | height: height.toLocaleString(),
|
245 | unit,
|
246 | name,
|
247 | orientation
|
248 | });
|
249 | }
|
250 |
|
251 | async #parseDate(inputDate) {
|
252 | const dateObject = _pdf.PDFDateString.toDateObject(inputDate);
|
253 |
|
254 | if (!dateObject) {
|
255 | return undefined;
|
256 | }
|
257 |
|
258 | return this.l10n.get("document_properties_date_string", {
|
259 | date: dateObject.toLocaleDateString(),
|
260 | time: dateObject.toLocaleTimeString()
|
261 | });
|
262 | }
|
263 |
|
264 | #parseLinearization(isLinearized) {
|
265 | return this.l10n.get(`document_properties_linearized_${isLinearized ? "yes" : "no"}`);
|
266 | }
|
267 |
|
268 | }
|
269 |
|
270 | exports.PDFDocumentProperties = PDFDocumentProperties; |
\ | No newline at end of file |