diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index cd862c55f..c79c2fc3f 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -18,42 +18,33 @@ 'use strict'; -var PDFDocumentProperties = { - overlayName: null, - rawFileSize: 0, - - // Document property fields (in the viewer). - fileNameField: null, - fileSizeField: null, - titleField: null, - authorField: null, - subjectField: null, - keywordsField: null, - creationDateField: null, - modificationDateField: null, - creatorField: null, - producerField: null, - versionField: null, - pageCountField: null, - url: null, - pdfDocument: null, - - initialize: function documentPropertiesInitialize(options) { +/** + * @class + */ +var PDFDocumentProperties = (function PDFDocumentPropertiesClosure() { + /** + * @constructs PDFDocumentProperties + * @param {PDFDocumentPropertiesOptions} options + */ + function PDFDocumentProperties(options) { + this.rawFileSize = 0; + this.url = null; + this.pdfDocument = null; this.overlayName = options.overlayName; // Set the document property fields. - this.fileNameField = options.fileNameField; - this.fileSizeField = options.fileSizeField; - this.titleField = options.titleField; - this.authorField = options.authorField; - this.subjectField = options.subjectField; - this.keywordsField = options.keywordsField; - this.creationDateField = options.creationDateField; - this.modificationDateField = options.modificationDateField; - this.creatorField = options.creatorField; - this.producerField = options.producerField; - this.versionField = options.versionField; - this.pageCountField = options.pageCountField; + this.fileNameField = options.fileNameField || null; + this.fileSizeField = options.fileSizeField || null; + this.titleField = options.titleField || null; + this.authorField = options.authorField || null; + this.subjectField = options.subjectField || null; + this.keywordsField = options.keywordsField || null; + this.creationDateField = options.creationDateField || null; + this.modificationDateField = options.modificationDateField || null; + this.creatorField = options.creatorField || null; + this.producerField = options.producerField || null; + this.versionField = options.versionField || null; + this.pageCountField = options.pageCountField || null; // Bind the event listener for the Close button. if (options.closeButton) { @@ -65,135 +56,139 @@ var PDFDocumentProperties = { }.bind(this)); OverlayManager.register(this.overlayName, this.close.bind(this)); - }, + } - getProperties: function documentPropertiesGetProperties() { - if (!OverlayManager.active) { - // If the dialog was closed before dataAvailablePromise was resolved, - // don't bother updating the properties. - return; - } - // Get the file size (if it hasn't already been set). - this.pdfDocument.getDownloadInfo().then(function(data) { - if (data.length === this.rawFileSize) { + PDFDocumentProperties.prototype = { + getProperties: function PDFDocumentProperties_getProperties() { + if (!OverlayManager.active) { + // If the dialog was closed before dataAvailablePromise was resolved, + // don't bother updating the properties. return; } - this.setFileSize(data.length); - this.updateUI(this.fileSizeField, this.parseFileSize()); - }.bind(this)); + // Get the file size (if it hasn't already been set). + this.pdfDocument.getDownloadInfo().then(function(data) { + if (data.length === this.rawFileSize) { + return; + } + this.setFileSize(data.length); + this.updateUI(this.fileSizeField, this.parseFileSize()); + }.bind(this)); - // Get the document properties. - this.pdfDocument.getMetadata().then(function(data) { - var fields = [ - { field: this.fileNameField, - content: getPDFFileNameFromURL(this.url) }, - { field: this.fileSizeField, content: this.parseFileSize() }, - { field: this.titleField, content: data.info.Title }, - { field: this.authorField, content: data.info.Author }, - { field: this.subjectField, content: data.info.Subject }, - { field: this.keywordsField, content: data.info.Keywords }, - { field: this.creationDateField, - content: this.parseDate(data.info.CreationDate) }, - { field: this.modificationDateField, - content: this.parseDate(data.info.ModDate) }, - { field: this.creatorField, content: data.info.Creator }, - { field: this.producerField, content: data.info.Producer }, - { field: this.versionField, content: data.info.PDFFormatVersion }, - { field: this.pageCountField, content: this.pdfDocument.numPages } - ]; + // Get the document properties. + this.pdfDocument.getMetadata().then(function(data) { + var fields = [ + { field: this.fileNameField, + content: getPDFFileNameFromURL(this.url) }, + { field: this.fileSizeField, content: this.parseFileSize() }, + { field: this.titleField, content: data.info.Title }, + { field: this.authorField, content: data.info.Author }, + { field: this.subjectField, content: data.info.Subject }, + { field: this.keywordsField, content: data.info.Keywords }, + { field: this.creationDateField, + content: this.parseDate(data.info.CreationDate) }, + { field: this.modificationDateField, + content: this.parseDate(data.info.ModDate) }, + { field: this.creatorField, content: data.info.Creator }, + { field: this.producerField, content: data.info.Producer }, + { field: this.versionField, content: data.info.PDFFormatVersion }, + { field: this.pageCountField, content: this.pdfDocument.numPages } + ]; - // Show the properties in the dialog. - for (var item in fields) { - var element = fields[item]; - this.updateUI(element.field, element.content); + // Show the properties in the dialog. + for (var item in fields) { + var element = fields[item]; + this.updateUI(element.field, element.content); + } + }.bind(this)); + }, + + updateUI: function PDFDocumentProperties_updateUI(field, content) { + if (field && content !== undefined && content !== '') { + field.textContent = content; } - }.bind(this)); - }, + }, - updateUI: function documentPropertiesUpdateUI(field, content) { - if (field && content !== undefined && content !== '') { - field.textContent = content; + setFileSize: function PDFDocumentProperties_setFileSize(fileSize) { + if (fileSize > 0) { + this.rawFileSize = fileSize; + } + }, + + parseFileSize: function PDFDocumentProperties_parseFileSize() { + var fileSize = this.rawFileSize, kb = fileSize / 1024; + if (!kb) { + return; + } else if (kb < 1024) { + return mozL10n.get('document_properties_kb', { + size_kb: (+kb.toPrecision(3)).toLocaleString(), + size_b: fileSize.toLocaleString() + }, '{{size_kb}} KB ({{size_b}} bytes)'); + } else { + return mozL10n.get('document_properties_mb', { + size_mb: (+(kb / 1024).toPrecision(3)).toLocaleString(), + size_b: fileSize.toLocaleString() + }, '{{size_mb}} MB ({{size_b}} bytes)'); + } + }, + + open: function PDFDocumentProperties_open() { + Promise.all([OverlayManager.open(this.overlayName), + this.dataAvailablePromise]).then(function () { + this.getProperties(); + }.bind(this)); + }, + + close: function PDFDocumentProperties_close() { + OverlayManager.close(this.overlayName); + }, + + parseDate: function PDFDocumentProperties_parseDate(inputDate) { + // This is implemented according to the PDF specification, but note that + // Adobe Reader doesn't handle changing the date to universal time + // and doesn't use the user's time zone (they're effectively ignoring + // the HH' and mm' parts of the date string). + var dateToParse = inputDate; + if (dateToParse === undefined) { + return ''; + } + + // Remove the D: prefix if it is available. + if (dateToParse.substring(0,2) === 'D:') { + dateToParse = dateToParse.substring(2); + } + + // Get all elements from the PDF date string. + // JavaScript's Date object expects the month to be between + // 0 and 11 instead of 1 and 12, so we're correcting for this. + var year = parseInt(dateToParse.substring(0,4), 10); + var month = parseInt(dateToParse.substring(4,6), 10) - 1; + var day = parseInt(dateToParse.substring(6,8), 10); + var hours = parseInt(dateToParse.substring(8,10), 10); + var minutes = parseInt(dateToParse.substring(10,12), 10); + var seconds = parseInt(dateToParse.substring(12,14), 10); + var utRel = dateToParse.substring(14,15); + var offsetHours = parseInt(dateToParse.substring(15,17), 10); + var offsetMinutes = parseInt(dateToParse.substring(18,20), 10); + + // As per spec, utRel = 'Z' means equal to universal time. + // The other cases ('-' and '+') have to be handled here. + if (utRel === '-') { + hours += offsetHours; + minutes += offsetMinutes; + } else if (utRel === '+') { + hours -= offsetHours; + minutes -= offsetMinutes; + } + + // Return the new date format from the user's locale. + var date = new Date(Date.UTC(year, month, day, hours, minutes, seconds)); + var dateString = date.toLocaleDateString(); + var timeString = date.toLocaleTimeString(); + return mozL10n.get('document_properties_date_string', + {date: dateString, time: timeString}, + '{{date}}, {{time}}'); } - }, + }; - setFileSize: function documentPropertiesSetFileSize(fileSize) { - if (fileSize > 0) { - this.rawFileSize = fileSize; - } - }, - - parseFileSize: function documentPropertiesParseFileSize() { - var fileSize = this.rawFileSize, kb = fileSize / 1024; - if (!kb) { - return; - } else if (kb < 1024) { - return mozL10n.get('document_properties_kb', { - size_kb: (+kb.toPrecision(3)).toLocaleString(), - size_b: fileSize.toLocaleString() - }, '{{size_kb}} KB ({{size_b}} bytes)'); - } else { - return mozL10n.get('document_properties_mb', { - size_mb: (+(kb / 1024).toPrecision(3)).toLocaleString(), - size_b: fileSize.toLocaleString() - }, '{{size_mb}} MB ({{size_b}} bytes)'); - } - }, - - open: function documentPropertiesOpen() { - Promise.all([OverlayManager.open(this.overlayName), - this.dataAvailablePromise]).then(function () { - this.getProperties(); - }.bind(this)); - }, - - close: function documentPropertiesClose() { - OverlayManager.close(this.overlayName); - }, - - parseDate: function documentPropertiesParseDate(inputDate) { - // This is implemented according to the PDF specification, but note that - // Adobe Reader doesn't handle changing the date to universal time - // and doesn't use the user's time zone (they're effectively ignoring - // the HH' and mm' parts of the date string). - var dateToParse = inputDate; - if (dateToParse === undefined) { - return ''; - } - - // Remove the D: prefix if it is available. - if (dateToParse.substring(0,2) === 'D:') { - dateToParse = dateToParse.substring(2); - } - - // Get all elements from the PDF date string. - // JavaScript's Date object expects the month to be between - // 0 and 11 instead of 1 and 12, so we're correcting for this. - var year = parseInt(dateToParse.substring(0,4), 10); - var month = parseInt(dateToParse.substring(4,6), 10) - 1; - var day = parseInt(dateToParse.substring(6,8), 10); - var hours = parseInt(dateToParse.substring(8,10), 10); - var minutes = parseInt(dateToParse.substring(10,12), 10); - var seconds = parseInt(dateToParse.substring(12,14), 10); - var utRel = dateToParse.substring(14,15); - var offsetHours = parseInt(dateToParse.substring(15,17), 10); - var offsetMinutes = parseInt(dateToParse.substring(18,20), 10); - - // As per spec, utRel = 'Z' means equal to universal time. - // The other cases ('-' and '+') have to be handled here. - if (utRel === '-') { - hours += offsetHours; - minutes += offsetMinutes; - } else if (utRel === '+') { - hours -= offsetHours; - minutes -= offsetMinutes; - } - - // Return the new date format from the user's locale. - var date = new Date(Date.UTC(year, month, day, hours, minutes, seconds)); - var dateString = date.toLocaleDateString(); - var timeString = date.toLocaleTimeString(); - return mozL10n.get('document_properties_date_string', - {date: dateString, time: timeString}, - '{{date}}, {{time}}'); - } -}; + return PDFDocumentProperties; +})(); diff --git a/web/viewer.js b/web/viewer.js index 7308976c7..7b6f3e6f5 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -109,6 +109,8 @@ var PDFViewerApplication = { pdfRenderingQueue: null, /** @type {PDFPresentationMode} */ pdfPresentationMode: null, + /** @type {PDFDocumentProperties} */ + pdfDocumentProperties: null, pageRotation: 0, updateScaleControls: true, isInitialViewSet: false, @@ -172,6 +174,23 @@ var PDFViewerApplication = { toggleHandTool: document.getElementById('toggleHandTool') }); + this.pdfDocumentProperties = new PDFDocumentProperties({ + overlayName: 'documentPropertiesOverlay', + closeButton: document.getElementById('documentPropertiesClose'), + fileNameField: document.getElementById('fileNameField'), + fileSizeField: document.getElementById('fileSizeField'), + titleField: document.getElementById('titleField'), + authorField: document.getElementById('authorField'), + subjectField: document.getElementById('subjectField'), + keywordsField: document.getElementById('keywordsField'), + creationDateField: document.getElementById('creationDateField'), + modificationDateField: document.getElementById('modificationDateField'), + creatorField: document.getElementById('creatorField'), + producerField: document.getElementById('producerField'), + versionField: document.getElementById('versionField'), + pageCountField: document.getElementById('pageCountField') + }); + SecondaryToolbar.initialize({ toolbar: document.getElementById('secondaryToolbar'), toggleButton: document.getElementById('secondaryToolbarToggle'), @@ -185,7 +204,7 @@ var PDFViewerApplication = { lastPage: document.getElementById('lastPage'), pageRotateCw: document.getElementById('pageRotateCw'), pageRotateCcw: document.getElementById('pageRotateCcw'), - documentProperties: PDFDocumentProperties, + documentProperties: this.pdfDocumentProperties, documentPropertiesButton: document.getElementById('documentProperties') }); @@ -216,23 +235,6 @@ var PDFViewerApplication = { passwordCancel: document.getElementById('passwordCancel') }); - PDFDocumentProperties.initialize({ - overlayName: 'documentPropertiesOverlay', - closeButton: document.getElementById('documentPropertiesClose'), - fileNameField: document.getElementById('fileNameField'), - fileSizeField: document.getElementById('fileSizeField'), - titleField: document.getElementById('titleField'), - authorField: document.getElementById('authorField'), - subjectField: document.getElementById('subjectField'), - keywordsField: document.getElementById('keywordsField'), - creationDateField: document.getElementById('creationDateField'), - modificationDateField: document.getElementById('modificationDateField'), - creatorField: document.getElementById('creatorField'), - producerField: document.getElementById('producerField'), - versionField: document.getElementById('versionField'), - pageCountField: document.getElementById('pageCountField') - }); - var self = this; var initializedPromise = Promise.all([ Preferences.get('enableWebGL').then(function resolved(value) { @@ -410,7 +412,8 @@ var PDFViewerApplication = { pdfDataRangeTransport); if (args.length) { - PDFDocumentProperties.setFileSize(args.length); + PDFViewerApplication.pdfDocumentProperties + .setFileSize(args.length); } break; case 'range': @@ -556,7 +559,7 @@ var PDFViewerApplication = { ); if (args && args.length) { - PDFDocumentProperties.setFileSize(args.length); + PDFViewerApplication.pdfDocumentProperties.setFileSize(args.length); } }, @@ -853,9 +856,9 @@ var PDFViewerApplication = { this.pdfDocument = pdfDocument; - PDFDocumentProperties.url = this.url; - PDFDocumentProperties.pdfDocument = pdfDocument; - PDFDocumentProperties.resolveDataAvailable(); + this.pdfDocumentProperties.url = this.url; + this.pdfDocumentProperties.pdfDocument = pdfDocument; + this.pdfDocumentProperties.resolveDataAvailable(); var downloadedPromise = pdfDocument.getDownloadInfo().then(function() { self.downloadComplete = true;