c40ec86cada837573b008f17ca880531f48a450c
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / print_preview / native_layer.js
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.
4
5 cr.define('print_preview', function() {
6   'use strict';
7
8   /**
9    * An interface to the native Chromium printing system layer.
10    * @constructor
11    * @extends {cr.EventTarget}
12    */
13   function NativeLayer() {
14     cr.EventTarget.call(this);
15
16     // Bind global handlers
17     global['setInitialSettings'] = this.onSetInitialSettings_.bind(this);
18     global['setUseCloudPrint'] = this.onSetUseCloudPrint_.bind(this);
19     global['setPrinters'] = this.onSetPrinters_.bind(this);
20     global['updateWithPrinterCapabilities'] =
21         this.onUpdateWithPrinterCapabilities_.bind(this);
22     global['failedToGetPrinterCapabilities'] =
23         this.onFailedToGetPrinterCapabilities_.bind(this);
24     global['failedToGetPrivetPrinterCapabilities'] =
25       this.onFailedToGetPrivetPrinterCapabilities_.bind(this);
26     global['reloadPrintersList'] = this.onReloadPrintersList_.bind(this);
27     global['printToCloud'] = this.onPrintToCloud_.bind(this);
28     global['fileSelectionCancelled'] =
29         this.onFileSelectionCancelled_.bind(this);
30     global['fileSelectionCompleted'] =
31         this.onFileSelectionCompleted_.bind(this);
32     global['printPreviewFailed'] = this.onPrintPreviewFailed_.bind(this);
33     global['invalidPrinterSettings'] =
34         this.onInvalidPrinterSettings_.bind(this);
35     global['onDidGetDefaultPageLayout'] =
36         this.onDidGetDefaultPageLayout_.bind(this);
37     global['onDidGetPreviewPageCount'] =
38         this.onDidGetPreviewPageCount_.bind(this);
39     global['onDidPreviewPage'] = this.onDidPreviewPage_.bind(this);
40     global['updatePrintPreview'] = this.onUpdatePrintPreview_.bind(this);
41     global['printScalingDisabledForSourcePDF'] =
42         this.onPrintScalingDisabledForSourcePDF_.bind(this);
43     global['onDidGetAccessToken'] = this.onDidGetAccessToken_.bind(this);
44     global['autoCancelForTesting'] = this.autoCancelForTesting_.bind(this);
45     global['onPrivetPrinterChanged'] = this.onPrivetPrinterChanged_.bind(this);
46     global['onPrivetCapabilitiesSet'] =
47       this.onPrivetCapabilitiesSet_.bind(this);
48     global['onPrivetPrintFailed'] = this.onPrivetPrintFailed_.bind(this);
49   };
50
51   /**
52    * Event types dispatched from the Chromium native layer.
53    * @enum {string}
54    * @const
55    */
56   NativeLayer.EventType = {
57     ACCESS_TOKEN_READY: 'print_preview.NativeLayer.ACCESS_TOKEN_READY',
58     CAPABILITIES_SET: 'print_preview.NativeLayer.CAPABILITIES_SET',
59     CLOUD_PRINT_ENABLE: 'print_preview.NativeLayer.CLOUD_PRINT_ENABLE',
60     DESTINATIONS_RELOAD: 'print_preview.NativeLayer.DESTINATIONS_RELOAD',
61     DISABLE_SCALING: 'print_preview.NativeLayer.DISABLE_SCALING',
62     FILE_SELECTION_CANCEL: 'print_preview.NativeLayer.FILE_SELECTION_CANCEL',
63     FILE_SELECTION_COMPLETE:
64         'print_preview.NativeLayer.FILE_SELECTION_COMPLETE',
65     GET_CAPABILITIES_FAIL: 'print_preview.NativeLayer.GET_CAPABILITIES_FAIL',
66     INITIAL_SETTINGS_SET: 'print_preview.NativeLayer.INITIAL_SETTINGS_SET',
67     LOCAL_DESTINATIONS_SET: 'print_preview.NativeLayer.LOCAL_DESTINATIONS_SET',
68     PAGE_COUNT_READY: 'print_preview.NativeLayer.PAGE_COUNT_READY',
69     PAGE_LAYOUT_READY: 'print_preview.NativeLayer.PAGE_LAYOUT_READY',
70     PAGE_PREVIEW_READY: 'print_preview.NativeLayer.PAGE_PREVIEW_READY',
71     PREVIEW_GENERATION_DONE:
72         'print_preview.NativeLayer.PREVIEW_GENERATION_DONE',
73     PREVIEW_GENERATION_FAIL:
74         'print_preview.NativeLayer.PREVIEW_GENERATION_FAIL',
75     PRINT_TO_CLOUD: 'print_preview.NativeLayer.PRINT_TO_CLOUD',
76     SETTINGS_INVALID: 'print_preview.NativeLayer.SETTINGS_INVALID',
77     PRIVET_PRINTER_CHANGED: 'print_preview.NativeLayer.PRIVET_PRINTER_CHANGED',
78     PRIVET_CAPABILITIES_SET:
79         'print_preview.NativeLayer.PRIVET_CAPABILITIES_SET',
80     PRIVET_PRINT_FAILED: 'print_preview.NativeLayer.PRIVET_PRINT_FAILED'
81   };
82
83   /**
84    * Constant values matching printing::DuplexMode enum.
85    * @enum {number}
86    */
87   NativeLayer.DuplexMode = {
88     SIMPLEX: 0,
89     LONG_EDGE: 1,
90     UNKNOWN_DUPLEX_MODE: -1
91   };
92
93   /**
94    * Enumeration of color modes used by Chromium.
95    * @enum {number}
96    * @private
97    */
98   NativeLayer.ColorMode_ = {
99     GRAY: 1,
100     COLOR: 2
101   };
102
103   /**
104    * Version of the serialized state of the print preview.
105    * @type {number}
106    * @const
107    * @private
108    */
109   NativeLayer.SERIALIZED_STATE_VERSION_ = 1;
110
111   NativeLayer.prototype = {
112     __proto__: cr.EventTarget.prototype,
113
114     /**
115      * Requests access token for cloud print requests.
116      * @param {string} authType type of access token.
117      */
118     startGetAccessToken: function(authType) {
119       chrome.send('getAccessToken', [authType]);
120     },
121
122     /** Gets the initial settings to initialize the print preview with. */
123     startGetInitialSettings: function() {
124       chrome.send('getInitialSettings');
125     },
126
127     /**
128      * Requests the system's local print destinations. A LOCAL_DESTINATIONS_SET
129      * event will be dispatched in response.
130      */
131     startGetLocalDestinations: function() {
132       chrome.send('getPrinters');
133     },
134
135     /**
136      * Requests the network's privet print destinations. A number of
137      * PRIVET_PRINTER_CHANGED events will be fired in response, followed by a
138      * PRIVET_SEARCH_ENDED.
139      */
140     startGetPrivetDestinations: function() {
141       chrome.send('getPrivetPrinters');
142     },
143
144     /**
145      * Requests that the privet print stack stop searching for privet print
146      * destinations.
147      */
148     stopGetPrivetDestinations: function() {
149       chrome.send('stopGetPrivetPrinters');
150     },
151
152     /**
153      * Requests the privet destination's printing capabilities. A
154      * PRIVET_CAPABILITIES_SET event will be dispatched in response.
155      * @param {string} destinationId ID of the destination.
156      */
157     startGetPrivetDestinationCapabilities: function(destinationId) {
158       chrome.send('getPrivetPrinterCapabilities', [destinationId]);
159     },
160
161     /**
162      * Requests the destination's printing capabilities. A CAPABILITIES_SET
163      * event will be dispatched in response.
164      * @param {string} destinationId ID of the destination.
165      */
166     startGetLocalDestinationCapabilities: function(destinationId) {
167       chrome.send('getPrinterCapabilities', [destinationId]);
168     },
169
170     /**
171      * Requests that a preview be generated. The following events may be
172      * dispatched in response:
173      *   - PAGE_COUNT_READY
174      *   - PAGE_LAYOUT_READY
175      *   - PAGE_PREVIEW_READY
176      *   - PREVIEW_GENERATION_DONE
177      *   - PREVIEW_GENERATION_FAIL
178      * @param {print_preview.Destination} destination Destination to print to.
179      * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the
180      *     state of the print ticket.
181      * @param {!print_preview.DocumentInfo} documentInfo Document data model.
182      * @param {number} ID of the preview request.
183      */
184     startGetPreview: function(
185         destination, printTicketStore, documentInfo, requestId) {
186       assert(printTicketStore.isTicketValidForPreview(),
187              'Trying to generate preview when ticket is not valid');
188
189       var ticket = {
190         'pageRange': printTicketStore.pageRange.getDocumentPageRanges(),
191         'landscape': printTicketStore.landscape.getValue(),
192         'color': printTicketStore.color.getValue() ?
193             NativeLayer.ColorMode_.COLOR : NativeLayer.ColorMode_.GRAY,
194         'headerFooterEnabled': printTicketStore.headerFooter.getValue(),
195         'marginsType': printTicketStore.marginsType.getValue(),
196         'isFirstRequest': requestId == 0,
197         'requestID': requestId,
198         'previewModifiable': documentInfo.isModifiable,
199         'printToPDF':
200             destination != null &&
201             destination.id ==
202                 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
203         'printWithCloudPrint': destination != null && !destination.isLocal,
204         'printWithPrivet': destination != null && destination.isPrivet,
205         'deviceName': destination == null ? 'foo' : destination.id,
206         'generateDraftData': documentInfo.isModifiable,
207         'fitToPageEnabled': printTicketStore.fitToPage.getValue(),
208
209         // NOTE: Even though the following fields don't directly relate to the
210         // preview, they still need to be included.
211         'duplex': printTicketStore.duplex.getValue() ?
212             NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,
213         'copies': printTicketStore.copies.getValueAsNumber(),
214         'collate': printTicketStore.collate.getValue(),
215         'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(),
216         'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue()
217       };
218
219       // Set 'cloudPrintID' only if the destination is not local.
220       if (destination && !destination.isLocal) {
221         ticket['cloudPrintID'] = destination.id;
222       }
223
224       if (printTicketStore.marginsType.isCapabilityAvailable() &&
225           printTicketStore.marginsType.getValue() ==
226               print_preview.ticket_items.MarginsType.Value.CUSTOM) {
227         var customMargins = printTicketStore.customMargins.getValue();
228         var orientationEnum =
229             print_preview.ticket_items.CustomMargins.Orientation;
230         ticket['marginsCustom'] = {
231           'marginTop': customMargins.get(orientationEnum.TOP),
232           'marginRight': customMargins.get(orientationEnum.RIGHT),
233           'marginBottom': customMargins.get(orientationEnum.BOTTOM),
234           'marginLeft': customMargins.get(orientationEnum.LEFT)
235         };
236       }
237
238       chrome.send(
239           'getPreview',
240           [JSON.stringify(ticket),
241            requestId > 0 ? documentInfo.pageCount : -1,
242            documentInfo.isModifiable]);
243     },
244
245     /**
246      * Requests that the document be printed.
247      * @param {!print_preview.Destination} destination Destination to print to.
248      * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the
249      *     state of the print ticket.
250      * @param {print_preview.CloudPrintInterface} cloudPrintInterface Interface
251      *     to Google Cloud Print.
252      * @param {!print_preview.DocumentInfo} documentInfo Document data model.
253      * @param {boolean=} opt_isOpenPdfInPreview Whether to open the PDF in the
254      *     system's preview application.
255      */
256     startPrint: function(destination, printTicketStore, cloudPrintInterface,
257                          documentInfo, opt_isOpenPdfInPreview) {
258       assert(printTicketStore.isTicketValid(),
259              'Trying to print when ticket is not valid');
260
261       var ticket = {
262         'pageRange': printTicketStore.pageRange.getDocumentPageRanges(),
263         'pageCount': printTicketStore.pageRange.getPageNumberSet().size,
264         'landscape': printTicketStore.landscape.getValue(),
265         'color': printTicketStore.color.getValue() ?
266             NativeLayer.ColorMode_.COLOR : NativeLayer.ColorMode_.GRAY,
267         'headerFooterEnabled': printTicketStore.headerFooter.getValue(),
268         'marginsType': printTicketStore.marginsType.getValue(),
269         'generateDraftData': true, // TODO(rltoscano): What should this be?
270         'duplex': printTicketStore.duplex.getValue() ?
271             NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,
272         'copies': printTicketStore.copies.getValueAsNumber(),
273         'collate': printTicketStore.collate.getValue(),
274         'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(),
275         'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue(),
276         'previewModifiable': documentInfo.isModifiable,
277         'printToPDF': destination.id ==
278             print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
279         'printWithCloudPrint': !destination.isLocal,
280         'printWithPrivet': destination.isPrivet,
281         'deviceName': destination.id,
282         'isFirstRequest': false,
283         'requestID': -1,
284         'fitToPageEnabled': printTicketStore.fitToPage.getValue(),
285         'pageWidth': documentInfo.pageSize.width,
286         'pageHeight': documentInfo.pageSize.height
287       };
288
289       if (!destination.isLocal) {
290         // We can't set cloudPrintID if the destination is "Print with Cloud
291         // Print" because the native system will try to print to Google Cloud
292         // Print with this ID instead of opening a Google Cloud Print dialog.
293         ticket['cloudPrintID'] = destination.id;
294       }
295
296       if (printTicketStore.marginsType.isCapabilityAvailable() &&
297           printTicketStore.marginsType.isValueEqual(
298               print_preview.ticket_items.MarginsType.Value.CUSTOM)) {
299         var customMargins = printTicketStore.customMargins.getValue();
300         var orientationEnum =
301             print_preview.ticket_items.CustomMargins.Orientation;
302         ticket['marginsCustom'] = {
303           'marginTop': customMargins.get(orientationEnum.TOP),
304           'marginRight': customMargins.get(orientationEnum.RIGHT),
305           'marginBottom': customMargins.get(orientationEnum.BOTTOM),
306           'marginLeft': customMargins.get(orientationEnum.LEFT)
307         };
308       }
309
310       if (destination.isPrivet) {
311         ticket['ticket'] = printTicketStore.createPrintTicket(destination);
312         ticket['capabilities'] = JSON.stringify(destination.capabilities);
313       }
314
315       if (opt_isOpenPdfInPreview) {
316         ticket['OpenPDFInPreview'] = true;
317       }
318
319       chrome.send('print', [JSON.stringify(ticket)]);
320     },
321
322     /** Requests that the current pending print request be cancelled. */
323     startCancelPendingPrint: function() {
324       chrome.send('cancelPendingPrintRequest');
325     },
326
327     /** Shows the system's native printing dialog. */
328     startShowSystemDialog: function() {
329       chrome.send('showSystemDialog');
330     },
331
332     /** Shows Google Cloud Print's web-based print dialog.
333      * @param {number} pageCount Number of pages to print.
334      */
335     startShowCloudPrintDialog: function(pageCount) {
336       chrome.send('printWithCloudPrintDialog', [pageCount]);
337     },
338
339     /** Closes the print preview dialog. */
340     startCloseDialog: function() {
341       chrome.send('closePrintPreviewDialog');
342       chrome.send('DialogClose');
343     },
344
345     /** Hide the print preview dialog and allow the native layer to close it. */
346     startHideDialog: function() {
347       chrome.send('hidePreview');
348     },
349
350     /**
351      * Opens the Google Cloud Print sign-in dialog. The DESTINATIONS_RELOAD
352      * event will be dispatched in response.
353      */
354     startCloudPrintSignIn: function() {
355       chrome.send('signIn');
356     },
357
358     /** Navigates the user to the system printer settings interface. */
359     startManageLocalDestinations: function() {
360       chrome.send('manageLocalPrinters');
361     },
362
363     /** Navigates the user to the Google Cloud Print management page. */
364     startManageCloudDestinations: function() {
365       chrome.send('manageCloudPrinters');
366     },
367
368     /** Forces browser to open a new tab with the given URL address. */
369     startForceOpenNewTab: function(url) {
370       chrome.send('forceOpenNewTab', [url]);
371     },
372
373     /**
374      * @param {!Object} initialSettings Object containing all initial settings.
375      */
376     onSetInitialSettings_: function(initialSettings) {
377       var numberFormatSymbols =
378           print_preview.MeasurementSystem.parseNumberFormat(
379               initialSettings['numberFormat']);
380       var unitType = print_preview.MeasurementSystem.UnitType.IMPERIAL;
381       if (initialSettings['measurementSystem'] != null) {
382         unitType = initialSettings['measurementSystem'];
383       }
384
385       var nativeInitialSettings = new print_preview.NativeInitialSettings(
386           initialSettings['printAutomaticallyInKioskMode'] || false,
387           initialSettings['hidePrintWithSystemDialogLink'] || false,
388           numberFormatSymbols[0] || ',',
389           numberFormatSymbols[1] || '.',
390           unitType,
391           initialSettings['previewModifiable'] || false,
392           initialSettings['initiatorTitle'] || '',
393           initialSettings['documentHasSelection'] || false,
394           initialSettings['shouldPrintSelectionOnly'] || false,
395           initialSettings['printerName'] || null,
396           initialSettings['appState'] || null);
397
398       var initialSettingsSetEvent = new Event(
399           NativeLayer.EventType.INITIAL_SETTINGS_SET);
400       initialSettingsSetEvent.initialSettings = nativeInitialSettings;
401       this.dispatchEvent(initialSettingsSetEvent);
402     },
403
404     /**
405      * Turn on the integration of Cloud Print.
406      * @param {string} cloudPrintURL The URL to use for cloud print servers.
407      * @private
408      */
409     onSetUseCloudPrint_: function(cloudPrintURL) {
410       var cloudPrintEnableEvent = new Event(
411           NativeLayer.EventType.CLOUD_PRINT_ENABLE);
412       cloudPrintEnableEvent.baseCloudPrintUrl = cloudPrintURL;
413       this.dispatchEvent(cloudPrintEnableEvent);
414     },
415
416     /**
417      * Updates the print preview with local printers.
418      * Called from PrintPreviewHandler::SetupPrinterList().
419      * @param {Array} printers Array of printer info objects.
420      * @private
421      */
422     onSetPrinters_: function(printers) {
423       var localDestsSetEvent = new Event(
424           NativeLayer.EventType.LOCAL_DESTINATIONS_SET);
425       localDestsSetEvent.destinationInfos = printers;
426       this.dispatchEvent(localDestsSetEvent);
427     },
428
429     /**
430      * Called when native layer gets settings information for a requested local
431      * destination.
432      * @param {Object} settingsInfo printer setting information.
433      * @private
434      */
435     onUpdateWithPrinterCapabilities_: function(settingsInfo) {
436       var capsSetEvent = new Event(NativeLayer.EventType.CAPABILITIES_SET);
437       capsSetEvent.settingsInfo = settingsInfo;
438       this.dispatchEvent(capsSetEvent);
439     },
440
441     /**
442      * Called when native layer gets settings information for a requested local
443      * destination.
444      * @param {string} printerId printer affected by error.
445      * @private
446      */
447     onFailedToGetPrinterCapabilities_: function(destinationId) {
448       var getCapsFailEvent = new Event(
449           NativeLayer.EventType.GET_CAPABILITIES_FAIL);
450       getCapsFailEvent.destinationId = destinationId;
451       getCapsFailEvent.destinationOrigin =
452           print_preview.Destination.Origin.LOCAL;
453       this.dispatchEvent(getCapsFailEvent);
454     },
455
456     /**
457      * Called when native layer gets settings information for a requested privet
458      * destination.
459      * @param {string} printerId printer affected by error.
460      * @private
461      */
462     onFailedToGetPrivetPrinterCapabilities_: function(destinationId) {
463       var getCapsFailEvent = new Event(
464           NativeLayer.EventType.GET_CAPABILITIES_FAIL);
465       getCapsFailEvent.destinationId = destinationId;
466       getCapsFailEvent.destinationOrigin =
467           print_preview.Destination.Origin.PRIVET;
468       this.dispatchEvent(getCapsFailEvent);
469     },
470
471     /** Reloads the printer list. */
472     onReloadPrintersList_: function() {
473       cr.dispatchSimpleEvent(this, NativeLayer.EventType.DESTINATIONS_RELOAD);
474     },
475
476     /**
477      * Called from the C++ layer.
478      * Take the PDF data handed to us and submit it to the cloud, closing the
479      * print preview dialog once the upload is successful.
480      * @param {string} data Data to send as the print job.
481      * @private
482      */
483     onPrintToCloud_: function(data) {
484       var printToCloudEvent = new Event(
485           NativeLayer.EventType.PRINT_TO_CLOUD);
486       printToCloudEvent.data = data;
487       this.dispatchEvent(printToCloudEvent);
488     },
489
490     /**
491      * Called from PrintPreviewUI::OnFileSelectionCancelled to notify the print
492      * preview dialog regarding the file selection cancel event.
493      * @private
494      */
495     onFileSelectionCancelled_: function() {
496       cr.dispatchSimpleEvent(this, NativeLayer.EventType.FILE_SELECTION_CANCEL);
497     },
498
499     /**
500      * Called from PrintPreviewUI::OnFileSelectionCompleted to notify the print
501      * preview dialog regarding the file selection completed event.
502      * @private
503      */
504     onFileSelectionCompleted_: function() {
505       // If the file selection is completed and the dialog is not already closed
506       // it means that a pending print to pdf request exists.
507       cr.dispatchSimpleEvent(
508           this, NativeLayer.EventType.FILE_SELECTION_COMPLETE);
509     },
510
511     /**
512      * Display an error message when print preview fails.
513      * Called from PrintPreviewMessageHandler::OnPrintPreviewFailed().
514      * @private
515      */
516     onPrintPreviewFailed_: function() {
517       cr.dispatchSimpleEvent(
518           this, NativeLayer.EventType.PREVIEW_GENERATION_FAIL);
519     },
520
521     /**
522      * Display an error message when encountered invalid printer settings.
523      * Called from PrintPreviewMessageHandler::OnInvalidPrinterSettings().
524      * @private
525      */
526     onInvalidPrinterSettings_: function() {
527       cr.dispatchSimpleEvent(this, NativeLayer.EventType.SETTINGS_INVALID);
528     },
529
530     /**
531      * @param {{contentWidth: number, contentHeight: number, marginLeft: number,
532      *          marginRight: number, marginTop: number, marginBottom: number,
533      *          printableAreaX: number, printableAreaY: number,
534      *          printableAreaWidth: number, printableAreaHeight: number}}
535      *          pageLayout Specifies default page layout details in points.
536      * @param {boolean} hasCustomPageSizeStyle Indicates whether the previewed
537      *     document has a custom page size style.
538      * @private
539      */
540     onDidGetDefaultPageLayout_: function(pageLayout, hasCustomPageSizeStyle) {
541       var pageLayoutChangeEvent = new Event(
542           NativeLayer.EventType.PAGE_LAYOUT_READY);
543       pageLayoutChangeEvent.pageLayout = pageLayout;
544       pageLayoutChangeEvent.hasCustomPageSizeStyle = hasCustomPageSizeStyle;
545       this.dispatchEvent(pageLayoutChangeEvent);
546     },
547
548     /**
549      * Update the page count and check the page range.
550      * Called from PrintPreviewUI::OnDidGetPreviewPageCount().
551      * @param {number} pageCount The number of pages.
552      * @param {number} previewResponseId The preview request id that resulted in
553      *      this response.
554      * @private
555      */
556     onDidGetPreviewPageCount_: function(pageCount, previewResponseId) {
557       var pageCountChangeEvent = new Event(
558           NativeLayer.EventType.PAGE_COUNT_READY);
559       pageCountChangeEvent.pageCount = pageCount;
560       pageCountChangeEvent.previewResponseId = previewResponseId;
561       this.dispatchEvent(pageCountChangeEvent);
562     },
563
564     /**
565      * Notification that a print preview page has been rendered.
566      * Check if the settings have changed and request a regeneration if needed.
567      * Called from PrintPreviewUI::OnDidPreviewPage().
568      * @param {number} pageNumber The page number, 0-based.
569      * @param {number} previewUid Preview unique identifier.
570      * @param {number} previewResponseId The preview request id that resulted in
571      *     this response.
572      * @private
573      */
574     onDidPreviewPage_: function(pageNumber, previewUid, previewResponseId) {
575       var pagePreviewGenEvent = new Event(
576           NativeLayer.EventType.PAGE_PREVIEW_READY);
577       pagePreviewGenEvent.pageIndex = pageNumber;
578       pagePreviewGenEvent.previewUid = previewUid;
579       pagePreviewGenEvent.previewResponseId = previewResponseId;
580       this.dispatchEvent(pagePreviewGenEvent);
581     },
582
583     /**
584      * Notification that access token is ready.
585      * @param {string} authType Type of access token.
586      * @param {string} accessToken Access token.
587      * @private
588      */
589     onDidGetAccessToken_: function(authType, accessToken) {
590       var getAccessTokenEvent = new Event(
591           NativeLayer.EventType.ACCESS_TOKEN_READY);
592       getAccessTokenEvent.authType = authType;
593       getAccessTokenEvent.accessToken = accessToken;
594       this.dispatchEvent(getAccessTokenEvent);
595     },
596
597     /**
598      * Update the print preview when new preview data is available.
599      * Create the PDF plugin as needed.
600      * Called from PrintPreviewUI::PreviewDataIsAvailable().
601      * @param {number} previewUid Preview unique identifier.
602      * @param {number} previewResponseId The preview request id that resulted in
603      *     this response.
604      * @private
605      */
606     onUpdatePrintPreview_: function(previewUid, previewResponseId) {
607       var previewGenDoneEvent = new Event(
608           NativeLayer.EventType.PREVIEW_GENERATION_DONE);
609       previewGenDoneEvent.previewUid = previewUid;
610       previewGenDoneEvent.previewResponseId = previewResponseId;
611       this.dispatchEvent(previewGenDoneEvent);
612     },
613
614     /**
615      * Updates the fit to page option state based on the print scaling option of
616      * source pdf. PDF's have an option to enable/disable print scaling. When we
617      * find out that the print scaling option is disabled for the source pdf, we
618      * uncheck the fitToPage_ to page checkbox. This function is called from C++
619      * code.
620      * @private
621      */
622     onPrintScalingDisabledForSourcePDF_: function() {
623       cr.dispatchSimpleEvent(this, NativeLayer.EventType.DISABLE_SCALING);
624     },
625
626     /**
627      * Simulates a user click on the print preview dialog cancel button. Used
628      * only for testing.
629      * @private
630      */
631     autoCancelForTesting_: function() {
632       var properties = {view: window, bubbles: true, cancelable: true};
633       var click = new MouseEvent('click', properties);
634       document.querySelector('#print-header .cancel').dispatchEvent(click);
635     },
636
637     /**
638      * @param {{serviceName: string, name: string}} printer Specifies
639      *     information about the printer that was added.
640      * @private
641      */
642     onPrivetPrinterChanged_: function(printer) {
643       var privetPrinterChangedEvent =
644             new Event(NativeLayer.EventType.PRIVET_PRINTER_CHANGED);
645       privetPrinterChangedEvent.printer = printer;
646       this.dispatchEvent(privetPrinterChangedEvent);
647     },
648
649     /**
650      * @param {Object} printer Specifies information about the printer that was
651      *    added.
652      * @private
653      */
654     onPrivetCapabilitiesSet_: function(printer, capabilities) {
655       var privetCapabilitiesSetEvent =
656             new Event(NativeLayer.EventType.PRIVET_CAPABILITIES_SET);
657       privetCapabilitiesSetEvent.printer = printer;
658       privetCapabilitiesSetEvent.capabilities = capabilities;
659       this.dispatchEvent(privetCapabilitiesSetEvent);
660     },
661
662     /**
663      * @param {string} http_error The HTTP response code or -1 if not an HTTP
664      *    error.
665      * @private
666      */
667     onPrivetPrintFailed_: function(http_error) {
668       var privetPrintFailedEvent =
669             new Event(NativeLayer.EventType.PRIVET_PRINT_FAILED);
670       privetPrintFailedEvent.httpError = http_error;
671       this.dispatchEvent(privetPrintFailedEvent);
672     }
673   };
674
675   /**
676    * Initial settings retrieved from the native layer.
677    * @param {boolean} isInKioskAutoPrintMode Whether the print preview should be
678    *     in auto-print mode.
679    * @param {string} thousandsDelimeter Character delimeter of thousands digits.
680    * @param {string} decimalDelimeter Character delimeter of the decimal point.
681    * @param {!print_preview.MeasurementSystem.UnitType} unitType Unit type of
682    *     local machine's measurement system.
683    * @param {boolean} isDocumentModifiable Whether the document to print is
684    *     modifiable.
685    * @param {string} documentTitle Title of the document.
686    * @param {boolean} documentHasSelection Whether the document has selected
687    *     content.
688    * @param {boolean} selectionOnly Whether only selected content should be
689    *     printed.
690    * @param {?string} systemDefaultDestinationId ID of the system default
691    *     destination.
692    * @param {?string} serializedAppStateStr Serialized app state.
693    * @constructor
694    */
695   function NativeInitialSettings(
696       isInKioskAutoPrintMode,
697       hidePrintWithSystemDialogLink,
698       thousandsDelimeter,
699       decimalDelimeter,
700       unitType,
701       isDocumentModifiable,
702       documentTitle,
703       documentHasSelection,
704       selectionOnly,
705       systemDefaultDestinationId,
706       serializedAppStateStr) {
707
708     /**
709      * Whether the print preview should be in auto-print mode.
710      * @type {boolean}
711      * @private
712      */
713     this.isInKioskAutoPrintMode_ = isInKioskAutoPrintMode;
714
715     /**
716      * Whether we should hide the link which shows the system print dialog.
717      * @type {boolean}
718      * @private
719      */
720     this.hidePrintWithSystemDialogLink_ = hidePrintWithSystemDialogLink;
721
722     /**
723      * Character delimeter of thousands digits.
724      * @type {string}
725      * @private
726      */
727     this.thousandsDelimeter_ = thousandsDelimeter;
728
729     /**
730      * Character delimeter of the decimal point.
731      * @type {string}
732      * @private
733      */
734     this.decimalDelimeter_ = decimalDelimeter;
735
736     /**
737      * Unit type of local machine's measurement system.
738      * @type {string}
739      * @private
740      */
741     this.unitType_ = unitType;
742
743     /**
744      * Whether the document to print is modifiable.
745      * @type {boolean}
746      * @private
747      */
748     this.isDocumentModifiable_ = isDocumentModifiable;
749
750     /**
751      * Title of the document.
752      * @type {string}
753      * @private
754      */
755     this.documentTitle_ = documentTitle;
756
757     /**
758      * Whether the document has selection.
759      * @type {string}
760      * @private
761      */
762     this.documentHasSelection_ = documentHasSelection;
763
764     /**
765      * Whether selection only should be printed.
766      * @type {string}
767      * @private
768      */
769     this.selectionOnly_ = selectionOnly;
770
771     /**
772      * ID of the system default destination.
773      * @type {?string}
774      * @private
775      */
776     this.systemDefaultDestinationId_ = systemDefaultDestinationId;
777
778     /**
779      * Serialized app state.
780      * @type {?string}
781      * @private
782      */
783     this.serializedAppStateStr_ = serializedAppStateStr;
784   };
785
786   NativeInitialSettings.prototype = {
787     /**
788      * @return {boolean} Whether the print preview should be in auto-print mode.
789      */
790     get isInKioskAutoPrintMode() {
791       return this.isInKioskAutoPrintMode_;
792     },
793
794     /**
795      * @return {boolean} Whether we should hide the link which shows the
796            system print dialog.
797      */
798     get hidePrintWithSystemDialogLink() {
799       return this.hidePrintWithSystemDialogLink_;
800     },
801
802     /** @return {string} Character delimeter of thousands digits. */
803     get thousandsDelimeter() {
804       return this.thousandsDelimeter_;
805     },
806
807     /** @return {string} Character delimeter of the decimal point. */
808     get decimalDelimeter() {
809       return this.decimalDelimeter_;
810     },
811
812     /**
813      * @return {!print_preview.MeasurementSystem.UnitType} Unit type of local
814      *     machine's measurement system.
815      */
816     get unitType() {
817       return this.unitType_;
818     },
819
820     /** @return {boolean} Whether the document to print is modifiable. */
821     get isDocumentModifiable() {
822       return this.isDocumentModifiable_;
823     },
824
825     /** @return {string} Document title. */
826     get documentTitle() {
827       return this.documentTitle_;
828     },
829
830     /** @return {bool} Whether the document has selection. */
831     get documentHasSelection() {
832       return this.documentHasSelection_;
833     },
834
835     /** @return {bool} Whether selection only should be printed. */
836     get selectionOnly() {
837       return this.selectionOnly_;
838     },
839
840     /** @return {?string} ID of the system default destination. */
841     get systemDefaultDestinationId() {
842       return this.systemDefaultDestinationId_;
843     },
844
845     /** @return {?string} Serialized app state. */
846     get serializedAppStateStr() {
847       return this.serializedAppStateStr_;
848     }
849   };
850
851   // Export
852   return {
853     NativeInitialSettings: NativeInitialSettings,
854     NativeLayer: NativeLayer
855   };
856 });