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