Index: chrome/browser/resources/print_preview/preview_generator.js |
diff --git a/chrome/browser/resources/print_preview/preview_generator.js b/chrome/browser/resources/print_preview/preview_generator.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4787dc4f061bc07118bc0d6bc55fb6f05fc0bd2e |
--- /dev/null |
+++ b/chrome/browser/resources/print_preview/preview_generator.js |
@@ -0,0 +1,392 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+cr.define('print_preview', function() { |
+ 'use strict'; |
+ |
+ /** |
+ * Interface to the Chromium print preview generator. |
+ * @param {!print_preview.DestinationStore} destinationStore Used to get the |
+ * currently selected destination. |
+ * @param {!print_preview.PrintTicketStore} printTicketStore Used to read the |
+ * state of the ticket and write document information. |
+ * @param {!print_preview.NativeLayer} nativeLayer Used to communicate to |
+ * Chromium's preview rendering system. |
+ * @constructor |
+ * @extends {cr.EventTarget} |
+ */ |
+ function PreviewGenerator(destinationStore, printTicketStore, nativeLayer) { |
+ cr.EventTarget.call(this); |
+ |
+ /** |
+ * Used to get the currently selected destination. |
+ * @type {!print_preview.DestinationStore} |
+ * @private |
+ */ |
+ this.destinationStore_ = destinationStore; |
+ |
+ /** |
+ * Used to read the state of the ticket and write document information. |
+ * @type {!print_preview.PrintTicketStore} |
+ * @private |
+ */ |
+ this.printTicketStore_ = printTicketStore; |
+ |
+ /** |
+ * Interface to the Chromium native layer. |
+ * @type {!print_preview.NativeLayer} |
+ * @private |
+ */ |
+ this.nativeLayer_ = nativeLayer; |
+ |
+ /** |
+ * ID of current in-flight request. Requests that do not share this ID will |
+ * be ignored. |
+ * @type {number} |
+ * @private |
+ */ |
+ this.inFlightRequestId_ = -1; |
+ |
+ /** |
+ * Whether the previews are being generated in landscape mode. |
+ * @type {boolean} |
+ * @private |
+ */ |
+ this.isLandscapeEnabled_ = false; |
+ |
+ /** |
+ * Whether the previews are being generated with a header and footer. |
+ * @type {boolean} |
+ * @private |
+ */ |
+ this.isHeaderFooterEnabled_ = false; |
+ |
+ /** |
+ * Whether the previews are being generated in color. |
+ * @type {boolean} |
+ * @private |
+ */ |
+ this.isColorEnabled_ = false; |
+ |
+ /** |
+ * Whether the document should be fitted to the page. |
+ * @type {boolean} |
+ * @private |
+ */ |
+ this.isFitToPageEnabled_ = false; |
+ |
+ /** |
+ * Page number set used to generate the last preview. |
+ * @type {print_preview.PageNumberSet} |
+ * @private |
+ */ |
+ this.pageNumberSet_ = null; |
+ |
+ /** |
+ * Margins type used to generate the last preview. |
+ * @type {print_preview.ticket_items.MarginsType.Value} |
+ * @private |
+ */ |
+ this.marginsType_ = print_preview.ticket_items.MarginsType.Value.DEFAULT; |
+ |
+ /** |
+ * Destination that was selected for the last preview. |
+ * @type {print_preview.Destination} |
+ * @private |
+ */ |
+ this.selectedDestination_ = null; |
+ |
+ /** |
+ * Event tracker used to keep track of native layer events. |
+ * @type {!EventTracker} |
+ * @private |
+ */ |
+ this.tracker_ = new EventTracker(); |
+ |
+ this.addEventListeners_(); |
+ }; |
+ |
+ /** |
+ * Event types dispatched by the preview generator. |
+ * @enum {string} |
+ */ |
+ PreviewGenerator.EventType = { |
+ // Dispatched when the document can be printed. |
+ DOCUMENT_READY: 'print_preview.PreviewGenerator.DOCUMENT_READY', |
+ |
+ // Dispatched when a page preview is ready. The previewIndex field of the |
+ // event is the index of the page in the modified document, not the |
+ // original. So page 4 of the original document might be previewIndex = 0 of |
+ // the modified document. |
+ PAGE_READY: 'print_preview.PreviewGenerator.PAGE_READY', |
+ |
+ // Dispatched when the document preview starts to be generated. |
+ PREVIEW_START: 'print_preview.PreviewGenerator.PREVIEW_START', |
+ |
+ // Dispatched when the current print preview request fails. |
+ FAIL: 'print_preview.PreviewGenerator.FAIL' |
+ }; |
+ |
+ PreviewGenerator.prototype = { |
+ __proto__: cr.EventTarget.prototype, |
+ |
+ /** |
+ * Request that new preview be generated. A preview request will not be |
+ * generated if the print ticket has not changed sufficiently. |
+ * @return {boolean} Whether a new preview was actually requested. |
+ */ |
+ requestPreview: function() { |
+ if (!this.printTicketStore_.isTicketValidForPreview()) { |
+ return false; |
+ } |
+ if (!this.hasPreviewChanged_()) { |
+ // Changes to these ticket items might not trigger a new preview, but |
+ // they still need to be recorded. |
+ this.marginsType_ = this.printTicketStore_.getMarginsType(); |
+ return false; |
+ } |
+ this.isLandscapeEnabled_ = this.printTicketStore_.isLandscapeEnabled(); |
+ this.isHeaderFooterEnabled_ = |
+ this.printTicketStore_.isHeaderFooterEnabled(); |
+ this.isColorEnabled_ = this.printTicketStore_.isColorEnabled(); |
+ this.isFitToPageEnabled_ = this.printTicketStore_.isFitToPageEnabled(); |
+ this.pageNumberSet_ = this.printTicketStore_.getPageNumberSet(); |
+ this.marginsType_ = this.printTicketStore_.getMarginsType(); |
+ this.selectedDestination_ = this.destinationStore_.selectedDestination; |
+ |
+ this.inFlightRequestId_++; |
+ this.nativeLayer_.startGetPreview( |
+ this.destinationStore_.selectedDestination, |
+ this.printTicketStore_, |
+ this.inFlightRequestId_); |
+ return true; |
+ }, |
+ |
+ /** Removes all event listeners that the preview generator has attached. */ |
+ removeEventListeners: function() { |
+ this.tracker_.removeAll(); |
+ }, |
+ |
+ /** |
+ * Adds event listeners to the relevant native layer events. |
+ * @private |
+ */ |
+ addEventListeners_: function() { |
+ this.tracker_.add( |
+ this.nativeLayer_, |
+ print_preview.NativeLayer.EventType.PAGE_LAYOUT_READY, |
+ this.onPageLayoutReady_.bind(this)); |
+ this.tracker_.add( |
+ this.nativeLayer_, |
+ print_preview.NativeLayer.EventType.PAGE_COUNT_READY, |
+ this.onPageCountReady_.bind(this)); |
+ this.tracker_.add( |
+ this.nativeLayer_, |
+ print_preview.NativeLayer.EventType.PREVIEW_RELOAD, |
+ this.onPreviewReload_.bind(this)); |
+ this.tracker_.add( |
+ this.nativeLayer_, |
+ print_preview.NativeLayer.EventType.PAGE_PREVIEW_READY, |
+ this.onPagePreviewReady_.bind(this)); |
+ this.tracker_.add( |
+ this.nativeLayer_, |
+ print_preview.NativeLayer.EventType.PREVIEW_GENERATION_DONE, |
+ this.onPreviewGenerationDone_.bind(this)); |
+ this.tracker_.add( |
+ this.nativeLayer_, |
+ print_preview.NativeLayer.EventType.PREVIEW_GENERATION_FAIL, |
+ this.onPreviewGenerationFail_.bind(this)); |
+ }, |
+ |
+ /** |
+ * Dispatches a PAGE_READY event to signal that a page preview is ready. |
+ * @param {number} previewIndex Index of the page with respect to the pages |
+ * shown in the preview. E.g an index of 0 is the first displayed page, |
+ * but not necessarily the first original document page. |
+ * @param {number} pageNumber Number of the page with respect to the |
+ * document. A value of 3 means it's the third page of the original |
+ * document. |
+ * @param {string} previewUid Unique identifier of the preview. |
+ * @private |
+ */ |
+ dispatchPageReadyEvent_: function(previewIndex, pageNumber, previewUid) { |
+ var pageGenEvent = new cr.Event(PreviewGenerator.EventType.PAGE_READY); |
+ pageGenEvent.previewIndex = previewIndex; |
+ pageGenEvent.previewUrl = |
+ 'chrome://print/' + previewUid + '/' + (pageNumber - 1) + |
+ '/print.pdf'; |
+ this.dispatchEvent(pageGenEvent); |
+ }, |
+ |
+ /** |
+ * Dispatches a PREVIEW_START event. Signals that the preview should be |
+ * reloaded. |
+ * @param {string} previewUid Unique identifier of the preview. |
+ * @private |
+ */ |
+ dispatchPreviewStartEvent_: function(previewUid) { |
+ var previewStartEvent = new cr.Event( |
+ PreviewGenerator.EventType.PREVIEW_START); |
+ var index = -1; |
+ if (this.printTicketStore_.isDocumentModifiable) { |
+ index = 0; |
+ } |
+ previewStartEvent.previewUrl = |
+ 'chrome://print/' + previewUid + '/' + index + '/print.pdf'; |
+ this.dispatchEvent(previewStartEvent); |
+ }, |
+ |
+ /** |
+ * @return {boolean} Whether the print ticket has changed sufficiently to |
+ * determine whether a new preview request should be issued. |
+ * @private |
+ */ |
+ hasPreviewChanged_: function() { |
+ var ticketStore = this.printTicketStore_; |
+ return this.inFlightRequestId_ == -1 || |
+ ticketStore.isLandscapeEnabled() != this.isLandscapeEnabled_ || |
+ ticketStore.isHeaderFooterEnabled() != this.isHeaderFooterEnabled_ || |
+ ticketStore.isColorEnabled() != this.isColorEnabled_ || |
+ ticketStore.isFitToPageEnabled() != this.isFitToPageEnabled_ || |
+ !ticketStore.getPageNumberSet().equals(this.pageNumberSet_) || |
+ (ticketStore.getMarginsType() != this.marginsType_ && |
+ ticketStore.getMarginsType() != |
+ print_preview.ticket_items.MarginsType.Value.CUSTOM) || |
+ (ticketStore.getMarginsType() == |
+ print_preview.ticket_items.MarginsType.Value.CUSTOM && |
+ !ticketStore.getCustomMargins().equals( |
+ ticketStore.getDocumentMargins())) || |
+ (this.selectedDestination_ != |
+ this.destinationStore_.selectedDestination && |
+ (this.destinationStore_.selectedDestination.id == |
+ print_preview.Destination.GooglePromotedId.SAVE_AS_PDF || |
+ this.selectedDestination_.id == |
+ print_preview.Destination.GooglePromotedId.SAVE_AS_PDF)); |
+ }, |
+ |
+ /** |
+ * Called when the page layout of the document is ready. Always occurs |
+ * as a result of a preview request. |
+ * @param {cr.Event} event Contains layout info about the document. |
+ * @private |
+ */ |
+ onPageLayoutReady_: function(event) { |
+ // NOTE: A request ID is not specified, so assuming its for the current |
+ // in-flight request. |
+ |
+ var origin = new print_preview.Coordinate2d( |
+ event.pageLayout.printableAreaX, |
+ event.pageLayout.printableAreaY); |
+ var size = new print_preview.Size( |
+ event.pageLayout.printableAreaWidth, |
+ event.pageLayout.printableAreaHeight); |
+ |
+ var margins = new print_preview.Margins( |
+ Math.round(event.pageLayout.marginTop), |
+ Math.round(event.pageLayout.marginRight), |
+ Math.round(event.pageLayout.marginBottom), |
+ Math.round(event.pageLayout.marginLeft)); |
+ |
+ var o = print_preview.ticket_items.CustomMargins.Orientation; |
+ var pageSize = new print_preview.Size( |
+ event.pageLayout.contentWidth + |
+ margins.get(o.LEFT) + margins.get(o.RIGHT), |
+ event.pageLayout.contentHeight + |
+ margins.get(o.TOP) + margins.get(o.BOTTOM)); |
+ |
+ this.printTicketStore_.updateDocumentPageInfo( |
+ new print_preview.PrintableArea(origin, size), |
+ pageSize, |
+ event.hasCustomPageSizeStyle, |
+ margins); |
+ }, |
+ |
+ /** |
+ * Called when the document page count is received from the native layer. |
+ * Always occurs as a result of a preview request. |
+ * @param {cr.Event} event Contains the document's page count. |
+ * @private |
+ */ |
+ onPageCountReady_: function(event) { |
+ if (this.inFlightRequestId_ != event.previewResponseId) { |
+ return; // Ignore old response. |
+ } |
+ this.printTicketStore_.updatePageCount(event.pageCount); |
+ this.pageNumberSet_ = this.printTicketStore_.getPageNumberSet(); |
+ }, |
+ |
+ /** |
+ * Called when the print preview should be reloaded. |
+ * @param {cr.Event} event Contains the preview UID and request ID. |
+ * @private |
+ */ |
+ onPreviewReload_: function(event) { |
+ if (this.inFlightRequestId_ != event.previewResponseId) { |
+ return; // Ignore old response. |
+ } |
+ this.dispatchPreviewStartEvent_(event.previewUid); |
+ var pageNumberSet = this.printTicketStore_.getPageNumberSet(); |
+ for (var i = 0; i < pageNumberSet.size; i++) { |
+ var pageNumber = pageNumberSet.getPageNumberAt(i); |
+ this.dispatchPageReadyEvent_(i, pageNumber, event.previewUid); |
+ } |
+ cr.dispatchSimpleEvent(this, PreviewGenerator.EventType.DOCUMENT_READY); |
+ }, |
+ |
+ /** |
+ * Called when a page's preview has been generated. Dispatches a |
+ * PAGE_READY event. |
+ * @param {cr.Event} event Contains the page index and preview UID. |
+ * @private |
+ */ |
+ onPagePreviewReady_: function(event) { |
+ if (this.inFlightRequestId_ != event.previewResponseId) { |
+ return; // Ignore old response. |
+ } |
+ var pageNumber = event.pageIndex + 1; |
+ if (this.printTicketStore_.getPageNumberSet().hasPageNumber(pageNumber)) { |
+ var previewIndex = this.printTicketStore_.getPageNumberSet() |
+ .getPageNumberIndex(pageNumber); |
+ if (previewIndex == 0) { |
+ this.dispatchPreviewStartEvent_(event.previewUid); |
+ } |
+ this.dispatchPageReadyEvent_( |
+ previewIndex, pageNumber, event.previewUid); |
+ } |
+ }, |
+ |
+ /** |
+ * Called when the preview generation is complete. Dispatches a |
+ * DOCUMENT_READY event. |
+ * @param {cr.Event} event Contains the preview UID and response ID. |
+ * @private |
+ */ |
+ onPreviewGenerationDone_: function(event) { |
+ if (this.inFlightRequestId_ != event.previewResponseId) { |
+ return; // Ignore old response. |
+ } |
+ // Dispatch a PREVIEW_START event since non-modifiable documents don't |
+ // trigger PAGE_READY events. |
+ if (!this.printTicketStore_.isDocumentModifiable) { |
+ this.dispatchPreviewStartEvent_(event.previewUid); |
+ } |
+ cr.dispatchSimpleEvent(this, PreviewGenerator.EventType.DOCUMENT_READY); |
+ }, |
+ |
+ /** |
+ * Called when the preview generation fails. |
+ * @private |
+ */ |
+ onPreviewGenerationFail_: function() { |
+ // NOTE: No request ID is returned from Chromium so its assumed its the |
+ // current one. |
+ cr.dispatchSimpleEvent(this, PreviewGenerator.EventType.FAIL); |
+ } |
+ }; |
+ |
+ // Export |
+ return { |
+ PreviewGenerator: PreviewGenerator |
+ }; |
+}); |