[sql] Remove _HAS_EXCEPTIONS=0 from build info.
[chromium-blink-merge.git] / chrome / browser / resources / print_preview / preview_generator.js
blob597300f9fe351b7ed17228f95336fb390c8e6a61
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 cr.define('print_preview', function() {
6 'use strict';
8 /**
9 * Interface to the Chromium print preview generator.
10 * @param {!print_preview.DestinationStore} destinationStore Used to get the
11 * currently selected destination.
12 * @param {!print_preview.PrintTicketStore} printTicketStore Used to read the
13 * state of the ticket and write document information.
14 * @param {!print_preview.NativeLayer} nativeLayer Used to communicate to
15 * Chromium's preview rendering system.
16 * @param {!print_preview.DocumentInfo} documentInfo Document data model.
17 * @constructor
18 * @extends {cr.EventTarget}
20 function PreviewGenerator(
21 destinationStore, printTicketStore, nativeLayer, documentInfo) {
22 cr.EventTarget.call(this);
24 /**
25 * Used to get the currently selected destination.
26 * @type {!print_preview.DestinationStore}
27 * @private
29 this.destinationStore_ = destinationStore;
31 /**
32 * Used to read the state of the ticket and write document information.
33 * @type {!print_preview.PrintTicketStore}
34 * @private
36 this.printTicketStore_ = printTicketStore;
38 /**
39 * Interface to the Chromium native layer.
40 * @type {!print_preview.NativeLayer}
41 * @private
43 this.nativeLayer_ = nativeLayer;
45 /**
46 * Document data model.
47 * @type {!print_preview.DocumentInfo}
48 * @private
50 this.documentInfo_ = documentInfo;
52 /**
53 * ID of current in-flight request. Requests that do not share this ID will
54 * be ignored.
55 * @type {number}
56 * @private
58 this.inFlightRequestId_ = -1;
60 /**
61 * Media size to generate preview with. {@code null} indicates default size.
62 * @type {cp.cdd.MediaSizeTicketItem}
63 * @private
65 this.mediaSize_ = null;
67 /**
68 * Whether the previews are being generated in landscape mode.
69 * @type {boolean}
70 * @private
72 this.isLandscapeEnabled_ = false;
74 /**
75 * Whether the previews are being generated with a header and footer.
76 * @type {boolean}
77 * @private
79 this.isHeaderFooterEnabled_ = false;
81 /**
82 * Whether the previews are being generated in color.
83 * @type {boolean}
84 * @private
86 this.colorValue_ = false;
88 /**
89 * Whether the document should be fitted to the page.
90 * @type {boolean}
91 * @private
93 this.isFitToPageEnabled_ = false;
95 /**
96 * Page ranges setting used used to generate the last preview.
97 * @type {!Array<object<{from: number, to: number}>>}
98 * @private
100 this.pageRanges_ = null;
103 * Margins type used to generate the last preview.
104 * @type {!print_preview.ticket_items.MarginsType.Value}
105 * @private
107 this.marginsType_ = print_preview.ticket_items.MarginsType.Value.DEFAULT;
110 * Whether the document should have element CSS backgrounds printed.
111 * @type {boolean}
112 * @private
114 this.isCssBackgroundEnabled_ = false;
117 * Destination that was selected for the last preview.
118 * @type {print_preview.Destination}
119 * @private
121 this.selectedDestination_ = null;
124 * Event tracker used to keep track of native layer events.
125 * @type {!EventTracker}
126 * @private
128 this.tracker_ = new EventTracker();
130 this.addEventListeners_();
134 * Event types dispatched by the preview generator.
135 * @enum {string}
137 PreviewGenerator.EventType = {
138 // Dispatched when the document can be printed.
139 DOCUMENT_READY: 'print_preview.PreviewGenerator.DOCUMENT_READY',
141 // Dispatched when a page preview is ready. The previewIndex field of the
142 // event is the index of the page in the modified document, not the
143 // original. So page 4 of the original document might be previewIndex = 0 of
144 // the modified document.
145 PAGE_READY: 'print_preview.PreviewGenerator.PAGE_READY',
147 // Dispatched when the document preview starts to be generated.
148 PREVIEW_START: 'print_preview.PreviewGenerator.PREVIEW_START',
150 // Dispatched when the current print preview request fails.
151 FAIL: 'print_preview.PreviewGenerator.FAIL'
154 PreviewGenerator.prototype = {
155 __proto__: cr.EventTarget.prototype,
158 * Request that new preview be generated. A preview request will not be
159 * generated if the print ticket has not changed sufficiently.
160 * @return {boolean} Whether a new preview was actually requested.
162 requestPreview: function() {
163 if (!this.printTicketStore_.isTicketValidForPreview() ||
164 !this.printTicketStore_.isInitialized ||
165 !this.destinationStore_.selectedDestination) {
166 return false;
168 if (!this.hasPreviewChanged_()) {
169 // Changes to these ticket items might not trigger a new preview, but
170 // they still need to be recorded.
171 this.marginsType_ = this.printTicketStore_.marginsType.getValue();
172 return false;
174 this.mediaSize_ = this.printTicketStore_.mediaSize.getValue();
175 this.isLandscapeEnabled_ = this.printTicketStore_.landscape.getValue();
176 this.isHeaderFooterEnabled_ =
177 this.printTicketStore_.headerFooter.getValue();
178 this.colorValue_ = this.printTicketStore_.color.getValue();
179 this.isFitToPageEnabled_ = this.printTicketStore_.fitToPage.getValue();
180 this.pageRanges_ = this.printTicketStore_.pageRange.getPageRanges();
181 this.marginsType_ = this.printTicketStore_.marginsType.getValue();
182 this.isCssBackgroundEnabled_ =
183 this.printTicketStore_.cssBackground.getValue();
184 this.isSelectionOnlyEnabled_ =
185 this.printTicketStore_.selectionOnly.getValue();
186 this.selectedDestination_ = this.destinationStore_.selectedDestination;
188 this.inFlightRequestId_++;
189 this.nativeLayer_.startGetPreview(
190 this.destinationStore_.selectedDestination,
191 this.printTicketStore_,
192 this.documentInfo_,
193 this.inFlightRequestId_);
194 return true;
197 /** Removes all event listeners that the preview generator has attached. */
198 removeEventListeners: function() {
199 this.tracker_.removeAll();
203 * Adds event listeners to the relevant native layer events.
204 * @private
206 addEventListeners_: function() {
207 this.tracker_.add(
208 this.nativeLayer_,
209 print_preview.NativeLayer.EventType.PAGE_LAYOUT_READY,
210 this.onPageLayoutReady_.bind(this));
211 this.tracker_.add(
212 this.nativeLayer_,
213 print_preview.NativeLayer.EventType.PAGE_COUNT_READY,
214 this.onPageCountReady_.bind(this));
215 this.tracker_.add(
216 this.nativeLayer_,
217 print_preview.NativeLayer.EventType.PAGE_PREVIEW_READY,
218 this.onPagePreviewReady_.bind(this));
219 this.tracker_.add(
220 this.nativeLayer_,
221 print_preview.NativeLayer.EventType.PREVIEW_GENERATION_DONE,
222 this.onPreviewGenerationDone_.bind(this));
223 this.tracker_.add(
224 this.nativeLayer_,
225 print_preview.NativeLayer.EventType.PREVIEW_GENERATION_FAIL,
226 this.onPreviewGenerationFail_.bind(this));
230 * Dispatches a PAGE_READY event to signal that a page preview is ready.
231 * @param {number} previewIndex Index of the page with respect to the pages
232 * shown in the preview. E.g an index of 0 is the first displayed page,
233 * but not necessarily the first original document page.
234 * @param {number} pageNumber Number of the page with respect to the
235 * document. A value of 3 means it's the third page of the original
236 * document.
237 * @param {number} previewUid Unique identifier of the preview.
238 * @private
240 dispatchPageReadyEvent_: function(previewIndex, pageNumber, previewUid) {
241 var pageGenEvent = new Event(PreviewGenerator.EventType.PAGE_READY);
242 pageGenEvent.previewIndex = previewIndex;
243 pageGenEvent.previewUrl = 'chrome://print/' + previewUid.toString() +
244 '/' + (pageNumber - 1) + '/print.pdf';
245 this.dispatchEvent(pageGenEvent);
249 * Dispatches a PREVIEW_START event. Signals that the preview should be
250 * reloaded.
251 * @param {number} previewUid Unique identifier of the preview.
252 * @param {number} index Index of the first page of the preview.
253 * @private
255 dispatchPreviewStartEvent_: function(previewUid, index) {
256 var previewStartEvent = new Event(
257 PreviewGenerator.EventType.PREVIEW_START);
258 if (!this.documentInfo_.isModifiable) {
259 index = -1;
261 previewStartEvent.previewUrl = 'chrome://print/' +
262 previewUid.toString() + '/' + index + '/print.pdf';
263 this.dispatchEvent(previewStartEvent);
267 * @return {boolean} Whether the print ticket has changed sufficiently to
268 * determine whether a new preview request should be issued.
269 * @private
271 hasPreviewChanged_: function() {
272 var ticketStore = this.printTicketStore_;
273 return this.inFlightRequestId_ == -1 ||
274 !ticketStore.mediaSize.isValueEqual(this.mediaSize_) ||
275 !ticketStore.landscape.isValueEqual(this.isLandscapeEnabled_) ||
276 !ticketStore.headerFooter.isValueEqual(this.isHeaderFooterEnabled_) ||
277 !ticketStore.color.isValueEqual(this.colorValue_) ||
278 !ticketStore.fitToPage.isValueEqual(this.isFitToPageEnabled_) ||
279 this.pageRanges_ == null ||
280 !areRangesEqual(ticketStore.pageRange.getPageRanges(),
281 this.pageRanges_) ||
282 (!ticketStore.marginsType.isValueEqual(this.marginsType_) &&
283 !ticketStore.marginsType.isValueEqual(
284 print_preview.ticket_items.MarginsType.Value.CUSTOM)) ||
285 (ticketStore.marginsType.isValueEqual(
286 print_preview.ticket_items.MarginsType.Value.CUSTOM) &&
287 !ticketStore.customMargins.isValueEqual(
288 this.documentInfo_.margins)) ||
289 !ticketStore.cssBackground.isValueEqual(
290 this.isCssBackgroundEnabled_) ||
291 !ticketStore.selectionOnly.isValueEqual(
292 this.isSelectionOnlyEnabled_) ||
293 (this.selectedDestination_ !=
294 this.destinationStore_.selectedDestination);
298 * Called when the page layout of the document is ready. Always occurs
299 * as a result of a preview request.
300 * @param {Event} event Contains layout info about the document.
301 * @private
303 onPageLayoutReady_: function(event) {
304 // NOTE: A request ID is not specified, so assuming its for the current
305 // in-flight request.
307 var origin = new print_preview.Coordinate2d(
308 event.pageLayout.printableAreaX,
309 event.pageLayout.printableAreaY);
310 var size = new print_preview.Size(
311 event.pageLayout.printableAreaWidth,
312 event.pageLayout.printableAreaHeight);
314 var margins = new print_preview.Margins(
315 Math.round(event.pageLayout.marginTop),
316 Math.round(event.pageLayout.marginRight),
317 Math.round(event.pageLayout.marginBottom),
318 Math.round(event.pageLayout.marginLeft));
320 var o = print_preview.ticket_items.CustomMargins.Orientation;
321 var pageSize = new print_preview.Size(
322 event.pageLayout.contentWidth +
323 margins.get(o.LEFT) + margins.get(o.RIGHT),
324 event.pageLayout.contentHeight +
325 margins.get(o.TOP) + margins.get(o.BOTTOM));
327 this.documentInfo_.updatePageInfo(
328 new print_preview.PrintableArea(origin, size),
329 pageSize,
330 event.hasCustomPageSizeStyle,
331 margins);
335 * Called when the document page count is received from the native layer.
336 * Always occurs as a result of a preview request.
337 * @param {Event} event Contains the document's page count.
338 * @private
340 onPageCountReady_: function(event) {
341 if (this.inFlightRequestId_ != event.previewResponseId) {
342 return; // Ignore old response.
344 this.documentInfo_.updatePageCount(event.pageCount);
345 this.pageRanges_ = this.printTicketStore_.pageRange.getPageRanges();
349 * Called when a page's preview has been generated. Dispatches a
350 * PAGE_READY event.
351 * @param {Event} event Contains the page index and preview UID.
352 * @private
354 onPagePreviewReady_: function(event) {
355 if (this.inFlightRequestId_ != event.previewResponseId) {
356 return; // Ignore old response.
358 var pageNumber = event.pageIndex + 1;
359 var pageNumberSet = this.printTicketStore_.pageRange.getPageNumberSet();
360 if (pageNumberSet.hasPageNumber(pageNumber)) {
361 var previewIndex = pageNumberSet.getPageNumberIndex(pageNumber);
362 if (previewIndex == 0) {
363 this.dispatchPreviewStartEvent_(event.previewUid, event.pageIndex);
365 this.dispatchPageReadyEvent_(
366 previewIndex, pageNumber, event.previewUid);
371 * Called when the preview generation is complete. Dispatches a
372 * DOCUMENT_READY event.
373 * @param {Event} event Contains the preview UID and response ID.
374 * @private
376 onPreviewGenerationDone_: function(event) {
377 if (this.inFlightRequestId_ != event.previewResponseId) {
378 return; // Ignore old response.
380 // Dispatch a PREVIEW_START event since non-modifiable documents don't
381 // trigger PAGE_READY events.
382 if (!this.documentInfo_.isModifiable) {
383 this.dispatchPreviewStartEvent_(event.previewUid, 0);
385 cr.dispatchSimpleEvent(this, PreviewGenerator.EventType.DOCUMENT_READY);
389 * Called when the preview generation fails.
390 * @private
392 onPreviewGenerationFail_: function() {
393 // NOTE: No request ID is returned from Chromium so its assumed its the
394 // current one.
395 cr.dispatchSimpleEvent(this, PreviewGenerator.EventType.FAIL);
399 // Export
400 return {
401 PreviewGenerator: PreviewGenerator