diff --git a/web/document_properties.js b/web/document_properties.js
deleted file mode 100644
index 810a627ad..000000000
--- a/web/document_properties.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* 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.
- */
-/* globals Promise, mozL10n, getPDFFileNameFromURL, OverlayManager */
-
-'use strict';
-
-var DocumentProperties = {
- 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) {
- 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;
-
- // Bind the event listener for the Close button.
- if (options.closeButton) {
- options.closeButton.addEventListener('click', this.close.bind(this));
- }
-
- this.dataAvailablePromise = new Promise(function (resolve) {
- this.resolveDataAvailable = resolve;
- }.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) {
- 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 }
- ];
-
- // 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 documentPropertiesUpdateUI(field, content) {
- if (field && content !== undefined && content !== '') {
- field.textContent = content;
- }
- },
-
- 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}}');
- }
-};
diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js
new file mode 100644
index 000000000..51e36ec59
--- /dev/null
+++ b/web/pdf_document_properties.js
@@ -0,0 +1,226 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* 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.
+ */
+/* globals Promise, mozL10n, getPDFFileNameFromURL, OverlayManager */
+
+'use strict';
+
+/**
+ * @typedef {Object} PDFDocumentPropertiesOptions
+ * @property {string} overlayName - Name/identifier for the overlay.
+ * @property {Object} fields - Names and elements of the overlay's fields.
+ * @property {HTMLButtonElement} closeButton - Button for closing the overlay.
+ */
+
+/**
+ * @class
+ */
+var PDFDocumentProperties = (function PDFDocumentPropertiesClosure() {
+ /**
+ * @constructs PDFDocumentProperties
+ * @param {PDFDocumentPropertiesOptions} options
+ */
+ function PDFDocumentProperties(options) {
+ this.fields = options.fields;
+ this.overlayName = options.overlayName;
+
+ this.rawFileSize = 0;
+ this.url = null;
+ this.pdfDocument = null;
+
+ // Bind the event listener for the Close button.
+ if (options.closeButton) {
+ options.closeButton.addEventListener('click', this.close.bind(this));
+ }
+
+ this.dataAvailablePromise = new Promise(function (resolve) {
+ this.resolveDataAvailable = resolve;
+ }.bind(this));
+
+ OverlayManager.register(this.overlayName, this.close.bind(this));
+ }
+
+ PDFDocumentProperties.prototype = {
+ /**
+ * Open the document properties overlay.
+ */
+ open: function PDFDocumentProperties_open() {
+ Promise.all([OverlayManager.open(this.overlayName),
+ this.dataAvailablePromise]).then(function () {
+ this._getProperties();
+ }.bind(this));
+ },
+
+ /**
+ * Close the document properties overlay.
+ */
+ close: function PDFDocumentProperties_close() {
+ OverlayManager.close(this.overlayName);
+ },
+
+ /**
+ * Set the file size of the PDF document. This method is used to
+ * update the file size in the document properties overlay once it
+ * is known so we do not have to wait until the entire file is loaded.
+ *
+ * @param {number} fileSize - The file size of the PDF document.
+ */
+ setFileSize: function PDFDocumentProperties_setFileSize(fileSize) {
+ if (fileSize > 0) {
+ this.rawFileSize = fileSize;
+ }
+ },
+
+ /**
+ * Set a reference to the PDF document and the URL in order
+ * to populate the overlay fields with the document properties.
+ * Note that the overlay will contain no information if this method
+ * is not called.
+ *
+ * @param {Object} pdfDocument - A reference to the PDF document.
+ * @param {string} url - The URL of the document.
+ */
+ setDocumentAndUrl:
+ function PDFDocumentProperties_setDocumentAndUrl(pdfDocument, url) {
+ this.pdfDocument = pdfDocument;
+ this.url = url;
+ this.resolveDataAvailable();
+ },
+
+ /**
+ * @private
+ */
+ _getProperties: function PDFDocumentProperties_getProperties() {
+ 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) {
+ return;
+ }
+ this.setFileSize(data.length);
+ this._updateUI(this.fields['fileSize'], this._parseFileSize());
+ }.bind(this));
+
+ // Get the document properties.
+ this.pdfDocument.getMetadata().then(function(data) {
+ var content = {
+ 'fileName': getPDFFileNameFromURL(this.url),
+ 'fileSize': this._parseFileSize(),
+ 'title': data.info.Title,
+ 'author': data.info.Author,
+ 'subject': data.info.Subject,
+ 'keywords': data.info.Keywords,
+ 'creationDate': this._parseDate(data.info.CreationDate),
+ 'modificationDate': this._parseDate(data.info.ModDate),
+ 'creator': data.info.Creator,
+ 'producer': data.info.Producer,
+ 'version': data.info.PDFFormatVersion,
+ 'pageCount': this.pdfDocument.numPages
+ };
+
+ // Show the properties in the dialog.
+ for (var identifier in content) {
+ this._updateUI(this.fields[identifier], content[identifier]);
+ }
+ }.bind(this));
+ },
+
+ /**
+ * @private
+ */
+ _updateUI: function PDFDocumentProperties_updateUI(field, content) {
+ if (field && content !== undefined && content !== '') {
+ field.textContent = content;
+ }
+ },
+
+ /**
+ * @private
+ */
+ _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)');
+ }
+ },
+
+ /**
+ * @private
+ */
+ _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}}');
+ }
+ };
+
+ return PDFDocumentProperties;
+})();
diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js
index 0b3f3d596..2714d79f6 100644
--- a/web/secondary_toolbar.js
+++ b/web/secondary_toolbar.js
@@ -25,7 +25,6 @@ var SecondaryToolbar = {
initialize: function secondaryToolbarInitialize(options) {
this.toolbar = options.toolbar;
- this.documentProperties = options.documentProperties;
this.buttonContainer = this.toolbar.firstElementChild;
// Define the toolbar buttons.
@@ -115,7 +114,7 @@ var SecondaryToolbar = {
},
documentPropertiesClick: function secondaryToolbarDocumentPropsClick(evt) {
- this.documentProperties.open();
+ PDFViewerApplication.pdfDocumentProperties.open();
this.close();
},
diff --git a/web/viewer.html b/web/viewer.html
index 70144eb9f..e7dad912b 100644
--- a/web/viewer.html
+++ b/web/viewer.html
@@ -86,7 +86,7 @@ http://sourceforge.net/adobe/cmap/wiki/License/
-
+
diff --git a/web/viewer.js b/web/viewer.js
index 33e11f1d5..2cc02e566 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -19,7 +19,7 @@
PDFHistory, Preferences, SidebarView, ViewHistory, Stats,
PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar,
PasswordPrompt, PDFPresentationMode, HandTool, Promise,
- DocumentProperties, PDFOutlineView, PDFAttachmentView,
+ PDFDocumentProperties, PDFOutlineView, PDFAttachmentView,
OverlayManager, PDFFindController, PDFFindBar, getVisibleElements,
watchScroll, PDFViewer, PDFRenderingQueue, PresentationModeState,
RenderingStates, DEFAULT_SCALE, UNKNOWN_SCALE,
@@ -88,7 +88,7 @@ var mozL10n = document.mozL10n || document.webL10n;
//#include hand_tool.js
//#include overlay_manager.js
//#include password_prompt.js
-//#include document_properties.js
+//#include pdf_document_properties.js
//#include pdf_viewer.js
//#include pdf_thumbnail_viewer.js
//#include pdf_outline_view.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,25 @@ var PDFViewerApplication = {
toggleHandTool: document.getElementById('toggleHandTool')
});
+ this.pdfDocumentProperties = new PDFDocumentProperties({
+ overlayName: 'documentPropertiesOverlay',
+ closeButton: document.getElementById('documentPropertiesClose'),
+ fields: {
+ 'fileName': document.getElementById('fileNameField'),
+ 'fileSize': document.getElementById('fileSizeField'),
+ 'title': document.getElementById('titleField'),
+ 'author': document.getElementById('authorField'),
+ 'subject': document.getElementById('subjectField'),
+ 'keywords': document.getElementById('keywordsField'),
+ 'creationDate': document.getElementById('creationDateField'),
+ 'modificationDate': document.getElementById('modificationDateField'),
+ 'creator': document.getElementById('creatorField'),
+ 'producer': document.getElementById('producerField'),
+ 'version': document.getElementById('versionField'),
+ 'pageCount': document.getElementById('pageCountField')
+ }
+ });
+
SecondaryToolbar.initialize({
toolbar: document.getElementById('secondaryToolbar'),
toggleButton: document.getElementById('secondaryToolbarToggle'),
@@ -185,7 +206,6 @@ var PDFViewerApplication = {
lastPage: document.getElementById('lastPage'),
pageRotateCw: document.getElementById('pageRotateCw'),
pageRotateCcw: document.getElementById('pageRotateCcw'),
- documentProperties: DocumentProperties,
documentPropertiesButton: document.getElementById('documentProperties')
});
@@ -216,23 +236,6 @@ var PDFViewerApplication = {
passwordCancel: document.getElementById('passwordCancel')
});
- DocumentProperties.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 +413,8 @@ var PDFViewerApplication = {
pdfDataRangeTransport);
if (args.length) {
- DocumentProperties.setFileSize(args.length);
+ PDFViewerApplication.pdfDocumentProperties
+ .setFileSize(args.length);
}
break;
case 'range':
@@ -556,7 +560,7 @@ var PDFViewerApplication = {
);
if (args && args.length) {
- DocumentProperties.setFileSize(args.length);
+ PDFViewerApplication.pdfDocumentProperties.setFileSize(args.length);
}
},
@@ -853,9 +857,7 @@ var PDFViewerApplication = {
this.pdfDocument = pdfDocument;
- DocumentProperties.url = this.url;
- DocumentProperties.pdfDocument = pdfDocument;
- DocumentProperties.resolveDataAvailable();
+ this.pdfDocumentProperties.setDocumentAndUrl(pdfDocument, this.url);
var downloadedPromise = pdfDocument.getDownloadInfo().then(function() {
self.downloadComplete = true;