You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
9.4 KiB
310 lines
9.4 KiB
/**
|
|
* @licstart The following is the entire license notice for the
|
|
* Javascript code in this page
|
|
*
|
|
* Copyright 2020 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.
|
|
*
|
|
* @licend The above is the entire license notice for the
|
|
* Javascript code in this page
|
|
*/
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.PDFDocumentProperties = void 0;
|
|
|
|
var _pdf = require("../pdf");
|
|
|
|
var _ui_utils = require("./ui_utils.js");
|
|
|
|
const DEFAULT_FIELD_CONTENT = "-";
|
|
const NON_METRIC_LOCALES = ["en-us", "en-lr", "my"];
|
|
const US_PAGE_NAMES = {
|
|
"8.5x11": "Letter",
|
|
"8.5x14": "Legal"
|
|
};
|
|
const METRIC_PAGE_NAMES = {
|
|
"297x420": "A3",
|
|
"210x297": "A4"
|
|
};
|
|
|
|
function getPageName(size, isPortrait, pageNames) {
|
|
const width = isPortrait ? size.width : size.height;
|
|
const height = isPortrait ? size.height : size.width;
|
|
return pageNames[`${width}x${height}`];
|
|
}
|
|
|
|
class PDFDocumentProperties {
|
|
constructor({
|
|
overlayName,
|
|
fields,
|
|
container,
|
|
closeButton
|
|
}, overlayManager, eventBus, l10n = _ui_utils.NullL10n) {
|
|
this.overlayName = overlayName;
|
|
this.fields = fields;
|
|
this.container = container;
|
|
this.overlayManager = overlayManager;
|
|
this.l10n = l10n;
|
|
|
|
this._reset();
|
|
|
|
closeButton.addEventListener("click", this.close.bind(this));
|
|
this.overlayManager.register(this.overlayName, this.container, this.close.bind(this));
|
|
|
|
eventBus._on("pagechanging", evt => {
|
|
this._currentPageNumber = evt.pageNumber;
|
|
});
|
|
|
|
eventBus._on("rotationchanging", evt => {
|
|
this._pagesRotation = evt.pagesRotation;
|
|
});
|
|
|
|
this._isNonMetricLocale = true;
|
|
l10n.getLanguage().then(locale => {
|
|
this._isNonMetricLocale = NON_METRIC_LOCALES.includes(locale);
|
|
});
|
|
}
|
|
|
|
open() {
|
|
const freezeFieldData = data => {
|
|
Object.defineProperty(this, "fieldData", {
|
|
value: Object.freeze(data),
|
|
writable: false,
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
};
|
|
|
|
Promise.all([this.overlayManager.open(this.overlayName), this._dataAvailableCapability.promise]).then(() => {
|
|
const currentPageNumber = this._currentPageNumber;
|
|
const pagesRotation = this._pagesRotation;
|
|
|
|
if (this.fieldData && currentPageNumber === this.fieldData._currentPageNumber && pagesRotation === this.fieldData._pagesRotation) {
|
|
this._updateUI();
|
|
|
|
return;
|
|
}
|
|
|
|
this.pdfDocument.getMetadata().then(({
|
|
info,
|
|
metadata,
|
|
contentDispositionFilename
|
|
}) => {
|
|
return Promise.all([info, metadata, contentDispositionFilename || (0, _ui_utils.getPDFFileNameFromURL)(this.url), this._parseFileSize(this.maybeFileSize), this._parseDate(info.CreationDate), this._parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then(pdfPage => {
|
|
return this._parsePageSize((0, _ui_utils.getPageSizeInches)(pdfPage), pagesRotation);
|
|
}), this._parseLinearization(info.IsLinearized)]);
|
|
}).then(([info, metadata, fileName, fileSize, creationDate, modDate, pageSize, isLinearized]) => {
|
|
freezeFieldData({
|
|
fileName,
|
|
fileSize,
|
|
title: info.Title,
|
|
author: info.Author,
|
|
subject: info.Subject,
|
|
keywords: info.Keywords,
|
|
creationDate,
|
|
modificationDate: modDate,
|
|
creator: info.Creator,
|
|
producer: info.Producer,
|
|
version: info.PDFFormatVersion,
|
|
pageCount: this.pdfDocument.numPages,
|
|
pageSize,
|
|
linearized: isLinearized,
|
|
_currentPageNumber: currentPageNumber,
|
|
_pagesRotation: pagesRotation
|
|
});
|
|
|
|
this._updateUI();
|
|
|
|
return this.pdfDocument.getDownloadInfo();
|
|
}).then(({
|
|
length
|
|
}) => {
|
|
this.maybeFileSize = length;
|
|
return this._parseFileSize(length);
|
|
}).then(fileSize => {
|
|
if (fileSize === this.fieldData.fileSize) {
|
|
return;
|
|
}
|
|
|
|
const data = Object.assign(Object.create(null), this.fieldData);
|
|
data.fileSize = fileSize;
|
|
freezeFieldData(data);
|
|
|
|
this._updateUI();
|
|
});
|
|
});
|
|
}
|
|
|
|
close() {
|
|
this.overlayManager.close(this.overlayName);
|
|
}
|
|
|
|
setDocument(pdfDocument, url = null) {
|
|
if (this.pdfDocument) {
|
|
this._reset();
|
|
|
|
this._updateUI(true);
|
|
}
|
|
|
|
if (!pdfDocument) {
|
|
return;
|
|
}
|
|
|
|
this.pdfDocument = pdfDocument;
|
|
this.url = url;
|
|
|
|
this._dataAvailableCapability.resolve();
|
|
}
|
|
|
|
setFileSize(fileSize) {
|
|
if (Number.isInteger(fileSize) && fileSize > 0) {
|
|
this.maybeFileSize = fileSize;
|
|
}
|
|
}
|
|
|
|
_reset() {
|
|
this.pdfDocument = null;
|
|
this.url = null;
|
|
this.maybeFileSize = 0;
|
|
delete this.fieldData;
|
|
this._dataAvailableCapability = (0, _pdf.createPromiseCapability)();
|
|
this._currentPageNumber = 1;
|
|
this._pagesRotation = 0;
|
|
}
|
|
|
|
_updateUI(reset = false) {
|
|
if (reset || !this.fieldData) {
|
|
for (const id in this.fields) {
|
|
this.fields[id].textContent = DEFAULT_FIELD_CONTENT;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (this.overlayManager.active !== this.overlayName) {
|
|
return;
|
|
}
|
|
|
|
for (const id in this.fields) {
|
|
const content = this.fieldData[id];
|
|
this.fields[id].textContent = content || content === 0 ? content : DEFAULT_FIELD_CONTENT;
|
|
}
|
|
}
|
|
|
|
async _parseFileSize(fileSize = 0) {
|
|
const kb = fileSize / 1024;
|
|
|
|
if (!kb) {
|
|
return undefined;
|
|
} else if (kb < 1024) {
|
|
return this.l10n.get("document_properties_kb", {
|
|
size_kb: (+kb.toPrecision(3)).toLocaleString(),
|
|
size_b: fileSize.toLocaleString()
|
|
}, "{{size_kb}} KB ({{size_b}} bytes)");
|
|
}
|
|
|
|
return this.l10n.get("document_properties_mb", {
|
|
size_mb: (+(kb / 1024).toPrecision(3)).toLocaleString(),
|
|
size_b: fileSize.toLocaleString()
|
|
}, "{{size_mb}} MB ({{size_b}} bytes)");
|
|
}
|
|
|
|
async _parsePageSize(pageSizeInches, pagesRotation) {
|
|
if (!pageSizeInches) {
|
|
return undefined;
|
|
}
|
|
|
|
if (pagesRotation % 180 !== 0) {
|
|
pageSizeInches = {
|
|
width: pageSizeInches.height,
|
|
height: pageSizeInches.width
|
|
};
|
|
}
|
|
|
|
const isPortrait = (0, _ui_utils.isPortraitOrientation)(pageSizeInches);
|
|
let sizeInches = {
|
|
width: Math.round(pageSizeInches.width * 100) / 100,
|
|
height: Math.round(pageSizeInches.height * 100) / 100
|
|
};
|
|
let sizeMillimeters = {
|
|
width: Math.round(pageSizeInches.width * 25.4 * 10) / 10,
|
|
height: Math.round(pageSizeInches.height * 25.4 * 10) / 10
|
|
};
|
|
let pageName = null;
|
|
let rawName = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES);
|
|
|
|
if (!rawName && !(Number.isInteger(sizeMillimeters.width) && Number.isInteger(sizeMillimeters.height))) {
|
|
const exactMillimeters = {
|
|
width: pageSizeInches.width * 25.4,
|
|
height: pageSizeInches.height * 25.4
|
|
};
|
|
const intMillimeters = {
|
|
width: Math.round(sizeMillimeters.width),
|
|
height: Math.round(sizeMillimeters.height)
|
|
};
|
|
|
|
if (Math.abs(exactMillimeters.width - intMillimeters.width) < 0.1 && Math.abs(exactMillimeters.height - intMillimeters.height) < 0.1) {
|
|
rawName = getPageName(intMillimeters, isPortrait, METRIC_PAGE_NAMES);
|
|
|
|
if (rawName) {
|
|
sizeInches = {
|
|
width: Math.round(intMillimeters.width / 25.4 * 100) / 100,
|
|
height: Math.round(intMillimeters.height / 25.4 * 100) / 100
|
|
};
|
|
sizeMillimeters = intMillimeters;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rawName) {
|
|
pageName = this.l10n.get("document_properties_page_size_name_" + rawName.toLowerCase(), null, rawName);
|
|
}
|
|
|
|
return Promise.all([this._isNonMetricLocale ? sizeInches : sizeMillimeters, this.l10n.get("document_properties_page_size_unit_" + (this._isNonMetricLocale ? "inches" : "millimeters"), null, this._isNonMetricLocale ? "in" : "mm"), pageName, this.l10n.get("document_properties_page_size_orientation_" + (isPortrait ? "portrait" : "landscape"), null, isPortrait ? "portrait" : "landscape")]).then(([{
|
|
width,
|
|
height
|
|
}, unit, name, orientation]) => {
|
|
return this.l10n.get("document_properties_page_size_dimension_" + (name ? "name_" : "") + "string", {
|
|
width: width.toLocaleString(),
|
|
height: height.toLocaleString(),
|
|
unit,
|
|
name,
|
|
orientation
|
|
}, "{{width}} × {{height}} {{unit}} (" + (name ? "{{name}}, " : "") + "{{orientation}})");
|
|
});
|
|
}
|
|
|
|
async _parseDate(inputDate) {
|
|
const dateObject = _pdf.PDFDateString.toDateObject(inputDate);
|
|
|
|
if (!dateObject) {
|
|
return undefined;
|
|
}
|
|
|
|
return this.l10n.get("document_properties_date_string", {
|
|
date: dateObject.toLocaleDateString(),
|
|
time: dateObject.toLocaleTimeString()
|
|
}, "{{date}}, {{time}}");
|
|
}
|
|
|
|
_parseLinearization(isLinearized) {
|
|
return this.l10n.get("document_properties_linearized_" + (isLinearized ? "yes" : "no"), null, isLinearized ? "Yes" : "No");
|
|
}
|
|
|
|
}
|
|
|
|
exports.PDFDocumentProperties = PDFDocumentProperties;
|