2014-01-22 00:07:07 +01:00
|
|
|
/* Copyright 2012 Mozilla Foundation
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2024-04-03 23:49:06 +04:00
|
|
|
/** @typedef {import("./event_utils.js").EventBus} EventBus */
|
|
|
|
/** @typedef {import("./interfaces.js").IL10n} IL10n */
|
|
|
|
/** @typedef {import("./overlay_manager.js").OverlayManager} OverlayManager */
|
|
|
|
// eslint-disable-next-line max-len
|
|
|
|
/** @typedef {import("../src/display/api.js").PDFDocumentProxy} PDFDocumentProxy */
|
|
|
|
|
2021-03-16 11:56:31 +01:00
|
|
|
import { getPageSizeInches, isPortraitOrientation } from "./ui_utils.js";
|
[api-minor] Replace the `PromiseCapability` with `Promise.withResolvers()`
This replaces our custom `PromiseCapability`-class with the new native `Promise.withResolvers()` functionality, which does *almost* the same thing[1]; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
The only difference is that `PromiseCapability` also had a `settled`-getter, which was however not widely used and the call-sites can either be removed or re-factored to avoid it. In particular:
- In `src/display/api.js` we can tweak the `PDFObjects`-class to use a "special" initial data-value and just compare against that, in order to replace the `settled`-state.
- In `web/app.js` we change the only case to manually track the `settled`-state, which should hopefully be OK given how this is being used.
- In `web/pdf_outline_viewer.js` we can remove the `settled`-checks, since the code should work just fine without it. The only thing that could potentially happen is that we try to `resolve` a Promise multiple times, which is however *not* a problem since the value of a Promise cannot be changed once fulfilled or rejected.
- In `web/pdf_viewer.js` we can remove the `settled`-checks, since the code should work fine without them:
- For the `_onePageRenderedCapability` case the `settled`-check is used in a `EventBus`-listener which is *removed* on its first (valid) invocation.
- For the `_pagesCapability` case the `settled`-check is used in a print-related helper that works just fine with "only" the other checks.
- In `test/unit/api_spec.js` we can change the few relevant cases to manually track the `settled`-state, since this is both simple and *test-only* code.
---
[1] In browsers/environments that lack native support, note [the compatibility data](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers#browser_compatibility), it'll be polyfilled via the `core-js` library (but only in `legacy` builds).
2024-03-28 16:42:37 +01:00
|
|
|
import { PDFDateString } from "pdfjs-lib";
|
2016-04-08 12:34:27 -05:00
|
|
|
|
2018-03-20 13:51:56 +01:00
|
|
|
// See https://en.wikibooks.org/wiki/Lentis/Conversion_to_the_Metric_Standard_in_the_United_States
|
2023-11-13 13:55:01 +01:00
|
|
|
const NON_METRIC_LOCALES = ["en-us", "en-lr", "my"];
|
2018-03-20 13:51:56 +01:00
|
|
|
|
2023-10-21 10:27:47 +02:00
|
|
|
// Should use the format: `width x height`, in portrait orientation. The names,
|
|
|
|
// which are l10n-ids, should be lowercase.
|
2018-03-20 14:26:49 +01:00
|
|
|
// See https://en.wikipedia.org/wiki/Paper_size
|
|
|
|
const US_PAGE_NAMES = {
|
2024-08-29 12:49:53 +02:00
|
|
|
"8.5x11": "pdfjs-document-properties-page-size-name-letter",
|
|
|
|
"8.5x14": "pdfjs-document-properties-page-size-name-legal",
|
2018-03-20 14:26:49 +01:00
|
|
|
};
|
|
|
|
const METRIC_PAGE_NAMES = {
|
2024-08-29 12:49:53 +02:00
|
|
|
"297x420": "pdfjs-document-properties-page-size-name-a-three",
|
|
|
|
"210x297": "pdfjs-document-properties-page-size-name-a-four",
|
2018-03-20 14:26:49 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
function getPageName(size, isPortrait, pageNames) {
|
|
|
|
const width = isPortrait ? size.width : size.height;
|
|
|
|
const height = isPortrait ? size.height : size.width;
|
|
|
|
|
|
|
|
return pageNames[`${width}x${height}`];
|
|
|
|
}
|
|
|
|
|
2015-04-24 21:01:03 +02:00
|
|
|
/**
|
|
|
|
* @typedef {Object} PDFDocumentPropertiesOptions
|
2022-03-25 14:10:13 +01:00
|
|
|
* @property {HTMLDialogElement} dialog - The overlay's DOM element.
|
2015-04-24 21:19:58 +02:00
|
|
|
* @property {Object} fields - Names and elements of the overlay's fields.
|
|
|
|
* @property {HTMLButtonElement} closeButton - Button for closing the overlay.
|
2015-04-24 21:01:03 +02:00
|
|
|
*/
|
|
|
|
|
2017-04-16 16:42:57 +02:00
|
|
|
class PDFDocumentProperties {
|
2022-03-13 17:06:27 +01:00
|
|
|
#fieldData = null;
|
|
|
|
|
2015-04-24 20:47:38 +02:00
|
|
|
/**
|
|
|
|
* @param {PDFDocumentPropertiesOptions} options
|
2017-05-26 14:52:23 +02:00
|
|
|
* @param {OverlayManager} overlayManager - Manager for the viewer overlays.
|
2018-03-17 18:50:34 +01:00
|
|
|
* @param {EventBus} eventBus - The application event bus.
|
2017-05-03 20:05:53 -05:00
|
|
|
* @param {IL10n} l10n - Localization service.
|
2022-05-28 11:05:40 +02:00
|
|
|
* @param {function} fileNameLookup - The function that is used to lookup
|
|
|
|
* the document fileName.
|
2015-04-24 20:47:38 +02:00
|
|
|
*/
|
2022-05-28 11:05:40 +02:00
|
|
|
constructor(
|
|
|
|
{ dialog, fields, closeButton },
|
|
|
|
overlayManager,
|
|
|
|
eventBus,
|
|
|
|
l10n,
|
|
|
|
fileNameLookup
|
|
|
|
) {
|
2022-03-25 14:10:13 +01:00
|
|
|
this.dialog = dialog;
|
2017-05-05 14:04:08 +02:00
|
|
|
this.fields = fields;
|
2017-05-26 14:52:23 +02:00
|
|
|
this.overlayManager = overlayManager;
|
2017-05-03 20:05:53 -05:00
|
|
|
this.l10n = l10n;
|
2022-05-28 11:05:40 +02:00
|
|
|
this._fileNameLookup = fileNameLookup;
|
2015-04-24 21:19:58 +02:00
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#reset();
|
2020-03-22 15:46:50 +01:00
|
|
|
// Bind the event listener for the Close button.
|
|
|
|
closeButton.addEventListener("click", this.close.bind(this));
|
2014-01-22 00:07:07 +01:00
|
|
|
|
2022-03-25 14:10:22 +01:00
|
|
|
this.overlayManager.register(this.dialog);
|
2018-03-17 18:50:34 +01:00
|
|
|
|
2020-03-22 15:46:50 +01:00
|
|
|
eventBus._on("pagechanging", evt => {
|
|
|
|
this._currentPageNumber = evt.pageNumber;
|
|
|
|
});
|
|
|
|
eventBus._on("rotationchanging", evt => {
|
|
|
|
this._pagesRotation = evt.pagesRotation;
|
|
|
|
});
|
2015-04-24 20:47:38 +02:00
|
|
|
}
|
2014-01-22 00:07:07 +01:00
|
|
|
|
2017-04-16 16:42:57 +02:00
|
|
|
/**
|
|
|
|
* Open the document properties overlay.
|
|
|
|
*/
|
2020-11-21 13:42:02 +01:00
|
|
|
async open() {
|
|
|
|
await Promise.all([
|
2022-03-25 14:10:22 +01:00
|
|
|
this.overlayManager.open(this.dialog),
|
2017-04-16 16:42:57 +02:00
|
|
|
this._dataAvailableCapability.promise,
|
2020-11-21 13:42:02 +01:00
|
|
|
]);
|
|
|
|
const currentPageNumber = this._currentPageNumber;
|
|
|
|
const pagesRotation = this._pagesRotation;
|
|
|
|
|
|
|
|
// If the document properties were previously fetched (for this PDF file),
|
|
|
|
// just update the dialog immediately to avoid redundant lookups.
|
|
|
|
if (
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#fieldData &&
|
|
|
|
currentPageNumber === this.#fieldData._currentPageNumber &&
|
|
|
|
pagesRotation === this.#fieldData._pagesRotation
|
2020-11-21 13:42:02 +01:00
|
|
|
) {
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#updateUI();
|
2020-11-21 13:42:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the document properties.
|
2024-12-01 12:25:16 +01:00
|
|
|
const [
|
|
|
|
{ info, /* metadata, contentDispositionFilename, */ contentLength },
|
|
|
|
pdfPage,
|
|
|
|
] = await Promise.all([
|
|
|
|
this.pdfDocument.getMetadata(),
|
|
|
|
this.pdfDocument.getPage(currentPageNumber),
|
|
|
|
]);
|
2020-11-21 13:42:02 +01:00
|
|
|
|
|
|
|
const [
|
|
|
|
fileName,
|
|
|
|
fileSize,
|
|
|
|
creationDate,
|
|
|
|
modificationDate,
|
|
|
|
pageSize,
|
|
|
|
isLinearized,
|
|
|
|
] = await Promise.all([
|
2022-05-28 11:05:40 +02:00
|
|
|
this._fileNameLookup(),
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#parseFileSize(contentLength),
|
|
|
|
this.#parseDate(info.CreationDate),
|
|
|
|
this.#parseDate(info.ModDate),
|
2024-12-01 12:25:16 +01:00
|
|
|
this.#parsePageSize(getPageSizeInches(pdfPage), pagesRotation),
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#parseLinearization(info.IsLinearized),
|
2020-11-21 13:42:02 +01:00
|
|
|
]);
|
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#fieldData = Object.freeze({
|
2020-11-21 13:42:02 +01:00
|
|
|
fileName,
|
|
|
|
fileSize,
|
|
|
|
title: info.Title,
|
|
|
|
author: info.Author,
|
|
|
|
subject: info.Subject,
|
|
|
|
keywords: info.Keywords,
|
|
|
|
creationDate,
|
|
|
|
modificationDate,
|
|
|
|
creator: info.Creator,
|
|
|
|
producer: info.Producer,
|
|
|
|
version: info.PDFFormatVersion,
|
|
|
|
pageCount: this.pdfDocument.numPages,
|
|
|
|
pageSize,
|
|
|
|
linearized: isLinearized,
|
|
|
|
_currentPageNumber: currentPageNumber,
|
|
|
|
_pagesRotation: pagesRotation,
|
2017-04-16 16:42:57 +02:00
|
|
|
});
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#updateUI();
|
2020-11-21 13:42:02 +01:00
|
|
|
|
|
|
|
// Get the correct fileSize, since it may not have been available
|
|
|
|
// or could potentially be wrong.
|
|
|
|
const { length } = await this.pdfDocument.getDownloadInfo();
|
|
|
|
if (contentLength === length) {
|
|
|
|
return; // The fileSize has already been correctly set.
|
|
|
|
}
|
2022-03-13 17:06:27 +01:00
|
|
|
const data = Object.assign(Object.create(null), this.#fieldData);
|
|
|
|
data.fileSize = await this.#parseFileSize(length);
|
2020-11-21 13:42:02 +01:00
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#fieldData = Object.freeze(data);
|
|
|
|
this.#updateUI();
|
2017-04-16 16:42:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Close the document properties overlay.
|
|
|
|
*/
|
2022-03-25 14:10:13 +01:00
|
|
|
async close() {
|
2022-03-25 14:10:22 +01:00
|
|
|
this.overlayManager.close(this.dialog);
|
2017-04-16 16:42:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-05-28 11:05:40 +02:00
|
|
|
* Set a reference to the PDF document in order to populate the dialog fields
|
|
|
|
* with the document properties. Note that the dialog will contain no
|
|
|
|
* information if this method is not called.
|
2017-04-16 16:42:57 +02:00
|
|
|
*
|
2018-09-21 17:19:33 +02:00
|
|
|
* @param {PDFDocumentProxy} pdfDocument - A reference to the PDF document.
|
2017-04-16 16:42:57 +02:00
|
|
|
*/
|
2022-05-28 11:05:40 +02:00
|
|
|
setDocument(pdfDocument) {
|
2017-05-05 14:04:08 +02:00
|
|
|
if (this.pdfDocument) {
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#reset();
|
2024-08-27 14:48:18 +02:00
|
|
|
this.#updateUI();
|
2017-05-05 14:04:08 +02:00
|
|
|
}
|
|
|
|
if (!pdfDocument) {
|
|
|
|
return;
|
|
|
|
}
|
2017-04-16 16:42:57 +02:00
|
|
|
this.pdfDocument = pdfDocument;
|
2017-05-05 14:04:08 +02:00
|
|
|
|
2017-04-16 16:42:57 +02:00
|
|
|
this._dataAvailableCapability.resolve();
|
|
|
|
}
|
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
#reset() {
|
2017-05-05 14:04:08 +02:00
|
|
|
this.pdfDocument = null;
|
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
this.#fieldData = null;
|
[api-minor] Replace the `PromiseCapability` with `Promise.withResolvers()`
This replaces our custom `PromiseCapability`-class with the new native `Promise.withResolvers()` functionality, which does *almost* the same thing[1]; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
The only difference is that `PromiseCapability` also had a `settled`-getter, which was however not widely used and the call-sites can either be removed or re-factored to avoid it. In particular:
- In `src/display/api.js` we can tweak the `PDFObjects`-class to use a "special" initial data-value and just compare against that, in order to replace the `settled`-state.
- In `web/app.js` we change the only case to manually track the `settled`-state, which should hopefully be OK given how this is being used.
- In `web/pdf_outline_viewer.js` we can remove the `settled`-checks, since the code should work just fine without it. The only thing that could potentially happen is that we try to `resolve` a Promise multiple times, which is however *not* a problem since the value of a Promise cannot be changed once fulfilled or rejected.
- In `web/pdf_viewer.js` we can remove the `settled`-checks, since the code should work fine without them:
- For the `_onePageRenderedCapability` case the `settled`-check is used in a `EventBus`-listener which is *removed* on its first (valid) invocation.
- For the `_pagesCapability` case the `settled`-check is used in a print-related helper that works just fine with "only" the other checks.
- In `test/unit/api_spec.js` we can change the few relevant cases to manually track the `settled`-state, since this is both simple and *test-only* code.
---
[1] In browsers/environments that lack native support, note [the compatibility data](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers#browser_compatibility), it'll be polyfilled via the `core-js` library (but only in `legacy` builds).
2024-03-28 16:42:37 +01:00
|
|
|
this._dataAvailableCapability = Promise.withResolvers();
|
2018-03-17 18:50:34 +01:00
|
|
|
this._currentPageNumber = 1;
|
2018-03-20 13:37:19 +01:00
|
|
|
this._pagesRotation = 0;
|
2017-04-16 16:42:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-05-05 14:04:08 +02:00
|
|
|
* Always updates all of the dialog fields, to prevent inconsistent UI state.
|
|
|
|
* NOTE: If the contents of a particular field is neither a non-empty string,
|
2024-08-27 14:48:18 +02:00
|
|
|
* nor a number, it will fall back to "-".
|
2017-04-16 16:42:57 +02:00
|
|
|
*/
|
2024-08-27 14:48:18 +02:00
|
|
|
#updateUI() {
|
|
|
|
if (this.#fieldData && this.overlayManager.active !== this.dialog) {
|
|
|
|
// Don't bother updating the dialog if it's already been closed,
|
|
|
|
// unless it's being reset (i.e. `this.#fieldData === null`),
|
2017-05-05 14:04:08 +02:00
|
|
|
// since it will be updated the next time `this.open` is called.
|
|
|
|
return;
|
|
|
|
}
|
2019-12-27 00:22:32 +01:00
|
|
|
for (const id in this.fields) {
|
2024-08-27 14:48:18 +02:00
|
|
|
const content = this.#fieldData?.[id];
|
|
|
|
this.fields[id].textContent = content || content === 0 ? content : "-";
|
2017-04-16 16:42:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-21 17:15:32 +02:00
|
|
|
async #parseFileSize(b = 0) {
|
|
|
|
const kb = b / 1024,
|
2021-02-22 12:43:16 +01:00
|
|
|
mb = kb / 1024;
|
2024-08-21 17:15:32 +02:00
|
|
|
return kb
|
2024-08-29 12:49:53 +02:00
|
|
|
? this.l10n.get(
|
|
|
|
mb >= 1
|
|
|
|
? "pdfjs-document-properties-size-mb"
|
|
|
|
: "pdfjs-document-properties-size-kb",
|
|
|
|
{ mb, kb, b }
|
|
|
|
)
|
2024-08-21 17:15:32 +02:00
|
|
|
: undefined;
|
2017-04-16 16:42:57 +02:00
|
|
|
}
|
2014-01-22 00:07:07 +01:00
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
async #parsePageSize(pageSizeInches, pagesRotation) {
|
2018-03-08 18:23:47 +01:00
|
|
|
if (!pageSizeInches) {
|
2019-05-10 12:54:06 +02:00
|
|
|
return undefined;
|
2018-03-08 18:23:47 +01:00
|
|
|
}
|
2018-03-20 13:37:19 +01:00
|
|
|
// Take the viewer rotation into account as well; compare with Adobe Reader.
|
|
|
|
if (pagesRotation % 180 !== 0) {
|
|
|
|
pageSizeInches = {
|
|
|
|
width: pageSizeInches.height,
|
|
|
|
height: pageSizeInches.width,
|
|
|
|
};
|
|
|
|
}
|
2024-08-29 12:57:57 +02:00
|
|
|
const isPortrait = isPortraitOrientation(pageSizeInches),
|
|
|
|
nonMetric = NON_METRIC_LOCALES.includes(this.l10n.getLanguage());
|
2018-03-20 13:51:56 +01:00
|
|
|
|
2018-03-21 13:39:07 +01:00
|
|
|
let sizeInches = {
|
2018-03-20 13:51:56 +01:00
|
|
|
width: Math.round(pageSizeInches.width * 100) / 100,
|
|
|
|
height: Math.round(pageSizeInches.height * 100) / 100,
|
|
|
|
};
|
|
|
|
// 1in == 25.4mm; no need to round to 2 decimals for millimeters.
|
2018-03-21 13:39:07 +01:00
|
|
|
let sizeMillimeters = {
|
2018-03-20 13:51:56 +01:00
|
|
|
width: Math.round(pageSizeInches.width * 25.4 * 10) / 10,
|
|
|
|
height: Math.round(pageSizeInches.height * 25.4 * 10) / 10,
|
|
|
|
};
|
2018-03-17 17:10:37 +01:00
|
|
|
|
2024-08-29 12:49:53 +02:00
|
|
|
let nameId =
|
2018-03-21 13:39:07 +01:00
|
|
|
getPageName(sizeInches, isPortrait, US_PAGE_NAMES) ||
|
|
|
|
getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES);
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 15:59:37 +01:00
|
|
|
|
2018-03-21 13:39:07 +01:00
|
|
|
if (
|
2024-08-29 12:49:53 +02:00
|
|
|
!nameId &&
|
2018-03-21 13:39:07 +01:00
|
|
|
!(
|
|
|
|
Number.isInteger(sizeMillimeters.width) &&
|
|
|
|
Number.isInteger(sizeMillimeters.height)
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 15:59:37 +01:00
|
|
|
)
|
2018-03-21 13:39:07 +01:00
|
|
|
) {
|
|
|
|
// Attempt to improve the page name detection by falling back to fuzzy
|
|
|
|
// matching of the metric dimensions, to account for e.g. rounding errors
|
|
|
|
// and/or PDF files that define the page sizes in an imprecise manner.
|
|
|
|
const exactMillimeters = {
|
|
|
|
width: pageSizeInches.width * 25.4,
|
|
|
|
height: pageSizeInches.height * 25.4,
|
|
|
|
};
|
|
|
|
const intMillimeters = {
|
|
|
|
width: Math.round(sizeMillimeters.width),
|
|
|
|
height: Math.round(sizeMillimeters.height),
|
|
|
|
};
|
|
|
|
|
|
|
|
// Try to avoid false positives, by only considering "small" differences.
|
|
|
|
if (
|
|
|
|
Math.abs(exactMillimeters.width - intMillimeters.width) < 0.1 &&
|
|
|
|
Math.abs(exactMillimeters.height - intMillimeters.height) < 0.1
|
|
|
|
) {
|
2024-08-29 12:49:53 +02:00
|
|
|
nameId = getPageName(intMillimeters, isPortrait, METRIC_PAGE_NAMES);
|
|
|
|
if (nameId) {
|
2018-03-21 13:39:07 +01:00
|
|
|
// Update *both* sizes, computed above, to ensure that the displayed
|
|
|
|
// dimensions always correspond to the detected page name.
|
|
|
|
sizeInches = {
|
|
|
|
width: Math.round((intMillimeters.width / 25.4) * 100) / 100,
|
|
|
|
height: Math.round((intMillimeters.height / 25.4) * 100) / 100,
|
|
|
|
};
|
|
|
|
sizeMillimeters = intMillimeters;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-03-20 14:26:49 +01:00
|
|
|
|
2021-02-22 12:43:16 +01:00
|
|
|
const [{ width, height }, unit, name, orientation] = await Promise.all([
|
2024-08-29 12:57:57 +02:00
|
|
|
nonMetric ? sizeInches : sizeMillimeters,
|
2024-08-29 12:49:53 +02:00
|
|
|
this.l10n.get(
|
2024-08-29 12:57:57 +02:00
|
|
|
nonMetric
|
2024-08-29 12:49:53 +02:00
|
|
|
? "pdfjs-document-properties-page-size-unit-inches"
|
|
|
|
: "pdfjs-document-properties-page-size-unit-millimeters"
|
2018-03-20 13:51:56 +01:00
|
|
|
),
|
2024-08-29 12:49:53 +02:00
|
|
|
nameId && this.l10n.get(nameId),
|
|
|
|
this.l10n.get(
|
|
|
|
isPortrait
|
|
|
|
? "pdfjs-document-properties-page-size-orientation-portrait"
|
|
|
|
: "pdfjs-document-properties-page-size-orientation-landscape"
|
2018-03-20 13:58:55 +01:00
|
|
|
),
|
2021-02-22 12:43:16 +01:00
|
|
|
]);
|
|
|
|
|
2024-08-29 12:49:53 +02:00
|
|
|
return this.l10n.get(
|
|
|
|
name
|
|
|
|
? "pdfjs-document-properties-page-size-dimension-name-string"
|
|
|
|
: "pdfjs-document-properties-page-size-dimension-string",
|
2024-08-21 17:15:32 +02:00
|
|
|
{ width, height, unit, name, orientation }
|
2021-02-22 12:43:16 +01:00
|
|
|
);
|
2018-03-08 18:23:47 +01:00
|
|
|
}
|
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
async #parseDate(inputDate) {
|
2024-08-21 17:15:32 +02:00
|
|
|
const dateObj = PDFDateString.toDateObject(inputDate);
|
|
|
|
return dateObj
|
2024-10-04 19:36:30 +02:00
|
|
|
? this.l10n.get("pdfjs-document-properties-date-time-string", {
|
|
|
|
dateObj: dateObj.valueOf(),
|
|
|
|
})
|
2024-08-21 17:15:32 +02:00
|
|
|
: undefined;
|
2017-04-16 16:42:57 +02:00
|
|
|
}
|
2018-07-24 16:24:30 +02:00
|
|
|
|
2022-03-13 17:06:27 +01:00
|
|
|
#parseLinearization(isLinearized) {
|
2024-08-29 12:49:53 +02:00
|
|
|
return this.l10n.get(
|
|
|
|
isLinearized
|
|
|
|
? "pdfjs-document-properties-linearized-yes"
|
|
|
|
: "pdfjs-document-properties-linearized-no"
|
|
|
|
);
|
2018-07-24 16:24:30 +02:00
|
|
|
}
|
2017-04-16 16:42:57 +02:00
|
|
|
}
|
2016-04-08 12:34:27 -05:00
|
|
|
|
2017-03-28 01:07:27 +02:00
|
|
|
export { PDFDocumentProperties };
|