| /** |
| * @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; |