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 // TODO(rltoscano): Move data/* into print_preview.data namespace
7 var localStrings
= new LocalStrings(templateData
);
9 <include src
="component.js"/>
10 <include src
="print_preview_focus_manager.js"/>
12 cr
.define('print_preview', function() {
16 * Container class for Chromium's print preview.
18 * @extends {print_preview.Component}
20 function PrintPreview() {
21 print_preview
.Component
.call(this);
24 * Used to communicate with Chromium's print system.
25 * @type {!print_preview.NativeLayer}
28 this.nativeLayer_
= new print_preview
.NativeLayer();
31 * Event target that contains information about the logged in user.
32 * @type {!print_preview.UserInfo}
35 this.userInfo_
= new print_preview
.UserInfo();
39 * @type {!print_preview.AppState}
42 this.appState_
= new print_preview
.AppState();
45 * Data model that holds information about the document to print.
46 * @type {!print_preview.DocumentInfo}
49 this.documentInfo_
= new print_preview
.DocumentInfo();
52 * Data store which holds print destinations.
53 * @type {!print_preview.DestinationStore}
56 this.destinationStore_
= new print_preview
.DestinationStore(
57 this.nativeLayer_
, this.userInfo_
, this.appState_
);
60 * Storage of the print ticket used to create the print job.
61 * @type {!print_preview.PrintTicketStore}
64 this.printTicketStore_
= new print_preview
.PrintTicketStore(
65 this.destinationStore_
, this.appState_
, this.documentInfo_
);
68 * Holds the print and cancel buttons and renders some document statistics.
69 * @type {!print_preview.PrintHeader}
72 this.printHeader_
= new print_preview
.PrintHeader(
73 this.printTicketStore_
, this.destinationStore_
);
74 this.addChild(this.printHeader_
);
77 * Component used to search for print destinations.
78 * @type {!print_preview.DestinationSearch}
81 this.destinationSearch_
= new print_preview
.DestinationSearch(
82 this.destinationStore_
, this.userInfo_
);
83 this.addChild(this.destinationSearch_
);
86 * Component that renders the print destination.
87 * @type {!print_preview.DestinationSettings}
90 this.destinationSettings_
= new print_preview
.DestinationSettings(
91 this.destinationStore_
);
92 this.addChild(this.destinationSettings_
);
95 * Component that renders UI for entering in page range.
96 * @type {!print_preview.PageSettings}
99 this.pageSettings_
= new print_preview
.PageSettings(
100 this.printTicketStore_
.pageRange
);
101 this.addChild(this.pageSettings_
);
104 * Component that renders the copies settings.
105 * @type {!print_preview.CopiesSettings}
108 this.copiesSettings_
= new print_preview
.CopiesSettings(
109 this.printTicketStore_
.copies
, this.printTicketStore_
.collate
);
110 this.addChild(this.copiesSettings_
);
113 * Component that renders the media size settings.
114 * @type {!print_preview.MediaSizeSettings}
117 this.mediaSizeSettings_
=
118 new print_preview
.MediaSizeSettings(this.printTicketStore_
.mediaSize
);
119 this.addChild(this.mediaSizeSettings_
);
122 * Component that renders the layout settings.
123 * @type {!print_preview.LayoutSettings}
126 this.layoutSettings_
=
127 new print_preview
.LayoutSettings(this.printTicketStore_
.landscape
);
128 this.addChild(this.layoutSettings_
);
131 * Component that renders the color options.
132 * @type {!print_preview.ColorSettings}
135 this.colorSettings_
=
136 new print_preview
.ColorSettings(this.printTicketStore_
.color
);
137 this.addChild(this.colorSettings_
);
140 * Component that renders a select box for choosing margin settings.
141 * @type {!print_preview.MarginSettings}
144 this.marginSettings_
=
145 new print_preview
.MarginSettings(this.printTicketStore_
.marginsType
);
146 this.addChild(this.marginSettings_
);
149 * Component that renders miscellaneous print options.
150 * @type {!print_preview.OtherOptionsSettings}
153 this.otherOptionsSettings_
= new print_preview
.OtherOptionsSettings(
154 this.printTicketStore_
.duplex
,
155 this.printTicketStore_
.fitToPage
,
156 this.printTicketStore_
.cssBackground
,
157 this.printTicketStore_
.selectionOnly
,
158 this.printTicketStore_
.headerFooter
);
159 this.addChild(this.otherOptionsSettings_
);
162 * Component that renders the advanced options button.
163 * @type {!print_preview.AdvancedOptionsSettings}
166 this.advancedOptionsSettings_
= new print_preview
.AdvancedOptionsSettings(
167 this.destinationStore_
);
168 this.addChild(this.advancedOptionsSettings_
);
171 * Component used to search for print destinations.
172 * @type {!print_preview.AdvancedSettings}
175 this.advancedSettings_
= new print_preview
.AdvancedSettings(
176 this.printTicketStore_
);
177 this.addChild(this.advancedSettings_
);
180 * Component representing more/less settings button.
181 * @type {!print_preview.MoreSettings}
184 var settingsSections
= [
185 this.destinationSettings_
,
187 this.copiesSettings_
,
188 this.mediaSizeSettings_
,
189 this.layoutSettings_
,
190 this.marginSettings_
,
192 this.otherOptionsSettings_
,
193 this.advancedOptionsSettings_
];
194 this.moreSettings_
= new print_preview
.MoreSettings(
195 this.destinationStore_
, settingsSections
);
196 this.addChild(this.moreSettings_
);
199 * Area of the UI that holds the print preview.
200 * @type {!print_preview.PreviewArea}
203 this.previewArea_
= new print_preview
.PreviewArea(this.destinationStore_
,
204 this.printTicketStore_
,
207 this.addChild(this.previewArea_
);
210 * Interface to the Google Cloud Print API. Null if Google Cloud Print
211 * integration is disabled.
212 * @type {cloudprint.CloudPrintInterface}
215 this.cloudPrintInterface_
= null;
218 * Whether in kiosk mode where print preview can print automatically without
219 * user intervention. See http://crbug.com/31395. Print will start when
220 * both the print ticket has been initialized, and an initial printer has
225 this.isInKioskAutoPrintMode_
= false;
228 * Whether Print Preview is in App Kiosk mode, basically, use only printers
229 * available for the device.
233 this.isInAppKioskMode_
= false;
236 * Whether Print with System Dialog option is available.
240 this.isSystemDialogAvailable_
= false;
243 * State of the print preview UI.
244 * @type {print_preview.PrintPreview.UiState_}
247 this.uiState_
= PrintPreview
.UiState_
.INITIALIZING
;
250 * Whether document preview generation is in progress.
254 this.isPreviewGenerationInProgress_
= true;
257 * Whether to show system dialog before next printing.
261 this.showSystemDialogBeforeNextPrint_
= false;
265 * States of the print preview.
269 PrintPreview
.UiState_
= {
270 INITIALIZING
: 'initializing',
272 OPENING_PDF_PREVIEW
: 'opening-pdf-preview',
273 OPENING_CLOUD_PRINT_DIALOG
: 'opening-cloud-print-dialog',
274 OPENING_NATIVE_PRINT_DIALOG
: 'opening-native-print-dialog',
275 PRINTING
: 'printing',
276 FILE_SELECTION
: 'file-selection',
282 * What can happen when print preview tries to print.
286 PrintPreview
.PrintAttemptResult_
= {
287 NOT_READY
: 'not-ready',
289 READY_WAITING_FOR_PREVIEW
: 'ready-waiting-for-preview'
292 PrintPreview
.prototype = {
293 __proto__
: print_preview
.Component
.prototype,
295 /** Sets up the page and print preview by getting the printer list. */
296 initialize: function() {
297 this.decorate($('print-preview'));
298 i18nTemplate
.process(document
, templateData
);
299 if (!this.previewArea_
.hasCompatiblePlugin
) {
300 this.setIsEnabled_(false);
302 this.nativeLayer_
.startGetInitialSettings();
303 print_preview
.PrintPreviewFocusManager
.getInstance().initialize();
304 cr
.ui
.FocusOutlineManager
.forDocument(document
);
308 enterDocument: function() {
309 // Native layer events.
312 print_preview
.NativeLayer
.EventType
.INITIAL_SETTINGS_SET
,
313 this.onInitialSettingsSet_
.bind(this));
316 print_preview
.NativeLayer
.EventType
.CLOUD_PRINT_ENABLE
,
317 this.onCloudPrintEnable_
.bind(this));
320 print_preview
.NativeLayer
.EventType
.PRINT_TO_CLOUD
,
321 this.onPrintToCloud_
.bind(this));
324 print_preview
.NativeLayer
.EventType
.FILE_SELECTION_CANCEL
,
325 this.onFileSelectionCancel_
.bind(this));
328 print_preview
.NativeLayer
.EventType
.FILE_SELECTION_COMPLETE
,
329 this.onFileSelectionComplete_
.bind(this));
332 print_preview
.NativeLayer
.EventType
.SETTINGS_INVALID
,
333 this.onSettingsInvalid_
.bind(this));
336 print_preview
.NativeLayer
.EventType
.DISABLE_SCALING
,
337 this.onDisableScaling_
.bind(this));
340 print_preview
.NativeLayer
.EventType
.PRIVET_PRINT_FAILED
,
341 this.onPrivetPrintFailed_
.bind(this));
344 print_preview
.NativeLayer
.EventType
.MANIPULATE_SETTINGS_FOR_TEST
,
345 this.onManipulateSettingsForTest_
.bind(this));
348 $('system-dialog-link'),
350 this.openSystemPrintDialog_
.bind(this));
352 $('cloud-print-dialog-link'),
354 this.onCloudPrintDialogLinkClick_
.bind(this));
356 $('open-pdf-in-preview-link'),
358 this.onOpenPdfInPreviewLinkClick_
.bind(this));
362 print_preview
.PreviewArea
.EventType
.PREVIEW_GENERATION_IN_PROGRESS
,
363 this.onPreviewGenerationInProgress_
.bind(this));
366 print_preview
.PreviewArea
.EventType
.PREVIEW_GENERATION_DONE
,
367 this.onPreviewGenerationDone_
.bind(this));
370 print_preview
.PreviewArea
.EventType
.PREVIEW_GENERATION_FAIL
,
371 this.onPreviewGenerationFail_
.bind(this));
374 print_preview
.PreviewArea
.EventType
.OPEN_SYSTEM_DIALOG_CLICK
,
375 this.openSystemPrintDialog_
.bind(this));
378 this.destinationStore_
,
379 print_preview
.DestinationStore
.EventType
.
380 SELECTED_DESTINATION_CAPABILITIES_READY
,
381 this.printIfReady_
.bind(this));
383 this.destinationStore_
,
384 print_preview
.DestinationStore
.EventType
.DESTINATION_SELECT
,
385 this.onDestinationSelect_
.bind(this));
387 this.destinationStore_
,
388 print_preview
.DestinationStore
.EventType
.DESTINATION_SEARCH_DONE
,
389 this.onDestinationSearchDone_
.bind(this));
393 print_preview
.PrintHeader
.EventType
.PRINT_BUTTON_CLICK
,
394 this.onPrintButtonClick_
.bind(this));
397 print_preview
.PrintHeader
.EventType
.CANCEL_BUTTON_CLICK
,
398 this.onCancelButtonClick_
.bind(this));
400 this.tracker
.add(window
, 'keydown', this.onKeyDown_
.bind(this));
403 this.destinationSettings_
,
404 print_preview
.DestinationSettings
.EventType
.CHANGE_BUTTON_ACTIVATE
,
405 this.onDestinationChangeButtonActivate_
.bind(this));
408 this.destinationSearch_
,
409 print_preview
.DestinationSearch
.EventType
.MANAGE_CLOUD_DESTINATIONS
,
410 this.onManageCloudDestinationsActivated_
.bind(this));
412 this.destinationSearch_
,
413 print_preview
.DestinationSearch
.EventType
.MANAGE_LOCAL_DESTINATIONS
,
414 this.onManageLocalDestinationsActivated_
.bind(this));
416 this.destinationSearch_
,
417 print_preview
.DestinationSearch
.EventType
.ADD_ACCOUNT
,
418 this.onCloudPrintSignInActivated_
.bind(this, true /*addAccount*/));
420 this.destinationSearch_
,
421 print_preview
.DestinationSearch
.EventType
.SIGN_IN
,
422 this.onCloudPrintSignInActivated_
.bind(this, false /*addAccount*/));
424 this.destinationSearch_
,
425 print_preview
.DestinationListItem
.EventType
.REGISTER_PROMO_CLICKED
,
426 this.onCloudPrintRegisterPromoClick_
.bind(this));
429 this.advancedOptionsSettings_
,
430 print_preview
.AdvancedOptionsSettings
.EventType
.BUTTON_ACTIVATED
,
431 this.onAdvancedOptionsButtonActivated_
.bind(this));
433 // TODO(rltoscano): Move no-destinations-promo into its own component
434 // instead being part of PrintPreview.
436 this.getChildElement('#no-destinations-promo .close-button'),
438 this.onNoDestinationsPromoClose_
.bind(this));
440 this.getChildElement('#no-destinations-promo .not-now-button'),
442 this.onNoDestinationsPromoClose_
.bind(this));
444 this.getChildElement('#no-destinations-promo .add-printer-button'),
446 this.onNoDestinationsPromoClick_
.bind(this));
450 decorateInternal: function() {
451 this.printHeader_
.decorate($('print-header'));
452 this.destinationSearch_
.decorate($('destination-search'));
453 this.destinationSettings_
.decorate($('destination-settings'));
454 this.pageSettings_
.decorate($('page-settings'));
455 this.copiesSettings_
.decorate($('copies-settings'));
456 this.mediaSizeSettings_
.decorate($('media-size-settings'));
457 this.layoutSettings_
.decorate($('layout-settings'));
458 this.colorSettings_
.decorate($('color-settings'));
459 this.marginSettings_
.decorate($('margin-settings'));
460 this.otherOptionsSettings_
.decorate($('other-options-settings'));
461 this.advancedOptionsSettings_
.decorate($('advanced-options-settings'));
462 this.advancedSettings_
.decorate($('advanced-settings'));
463 this.moreSettings_
.decorate($('more-settings'));
464 this.previewArea_
.decorate($('preview-area'));
466 setIsVisible($('open-pdf-in-preview-link'), cr
.isMac
);
470 * Sets whether the controls in the print preview are enabled.
471 * @param {boolean} isEnabled Whether the controls in the print preview are
475 setIsEnabled_: function(isEnabled
) {
476 $('system-dialog-link').disabled
= !isEnabled
;
477 $('cloud-print-dialog-link').disabled
= !isEnabled
;
478 $('open-pdf-in-preview-link').disabled
= !isEnabled
;
479 this.printHeader_
.isEnabled
= isEnabled
;
480 this.destinationSettings_
.isEnabled
= isEnabled
;
481 this.pageSettings_
.isEnabled
= isEnabled
;
482 this.copiesSettings_
.isEnabled
= isEnabled
;
483 this.mediaSizeSettings_
.isEnabled
= isEnabled
;
484 this.layoutSettings_
.isEnabled
= isEnabled
;
485 this.colorSettings_
.isEnabled
= isEnabled
;
486 this.marginSettings_
.isEnabled
= isEnabled
;
487 this.otherOptionsSettings_
.isEnabled
= isEnabled
;
488 this.advancedOptionsSettings_
.isEnabled
= isEnabled
;
492 * Prints the document or launches a pdf preview on the local system.
493 * @param {boolean} isPdfPreview Whether to launch the pdf preview.
496 printDocumentOrOpenPdfPreview_: function(isPdfPreview
) {
497 assert(this.uiState_
== PrintPreview
.UiState_
.READY
,
498 'Print document request received when not in ready state: ' +
501 this.uiState_
= PrintPreview
.UiState_
.OPENING_PDF_PREVIEW
;
502 } else if (this.destinationStore_
.selectedDestination
.id
==
503 print_preview
.Destination
.GooglePromotedId
.SAVE_AS_PDF
) {
504 this.uiState_
= PrintPreview
.UiState_
.FILE_SELECTION
;
506 this.uiState_
= PrintPreview
.UiState_
.PRINTING
;
508 this.setIsEnabled_(false);
509 this.printHeader_
.isCancelButtonEnabled
= true;
510 var printAttemptResult
= this.printIfReady_();
511 if (printAttemptResult
== PrintPreview
.PrintAttemptResult_
.PRINTED
||
512 printAttemptResult
==
513 PrintPreview
.PrintAttemptResult_
.READY_WAITING_FOR_PREVIEW
) {
514 if ((this.destinationStore_
.selectedDestination
.isLocal
&&
515 !this.destinationStore_
.selectedDestination
.isPrivet
&&
516 this.destinationStore_
.selectedDestination
.id
!=
517 print_preview
.Destination
.GooglePromotedId
.SAVE_AS_PDF
) ||
518 this.uiState_
== PrintPreview
.UiState_
.OPENING_PDF_PREVIEW
) {
519 // Hide the dialog for now. The actual print command will be issued
520 // when the preview generation is done.
521 this.nativeLayer_
.startHideDialog();
527 * Attempts to print if needed and if ready.
528 * @return {PrintPreview.PrintAttemptResult_} Attempt result.
531 printIfReady_: function() {
533 (this.uiState_
== PrintPreview
.UiState_
.PRINTING
||
534 this.uiState_
== PrintPreview
.UiState_
.OPENING_PDF_PREVIEW
||
535 this.uiState_
== PrintPreview
.UiState_
.FILE_SELECTION
||
536 this.uiState_
== PrintPreview
.UiState_
.OPENING_CLOUD_PRINT_DIALOG
||
537 this.isInKioskAutoPrintMode_
) &&
538 this.destinationStore_
.selectedDestination
&&
539 this.destinationStore_
.selectedDestination
.capabilities
;
541 return PrintPreview
.PrintAttemptResult_
.NOT_READY
;
543 if (this.isPreviewGenerationInProgress_
) {
544 return PrintPreview
.PrintAttemptResult_
.READY_WAITING_FOR_PREVIEW
;
546 assert(this.printTicketStore_
.isTicketValid(),
547 'Trying to print with invalid ticket');
548 if (this.uiState_
== PrintPreview
.UiState_
.OPENING_CLOUD_PRINT_DIALOG
) {
549 this.nativeLayer_
.startShowCloudPrintDialog(
550 this.printTicketStore_
.pageRange
.getPageNumberSet().size
);
552 this.nativeLayer_
.startPrint(
553 this.destinationStore_
.selectedDestination
,
554 this.printTicketStore_
,
555 this.cloudPrintInterface_
,
557 this.uiState_
== PrintPreview
.UiState_
.OPENING_PDF_PREVIEW
,
558 this.showSystemDialogBeforeNextPrint_
);
559 this.showSystemDialogBeforeNextPrint_
= false;
561 return PrintPreview
.PrintAttemptResult_
.PRINTED
;
565 * Closes the print preview.
570 this.uiState_
= PrintPreview
.UiState_
.CLOSING
;
571 this.nativeLayer_
.startCloseDialog();
575 * Opens the native system print dialog after disabling all controls.
578 openSystemPrintDialog_: function() {
579 if (!this.shouldShowSystemDialogLink_())
582 this.showSystemDialogBeforeNextPrint_
= true;
583 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/);
586 setIsVisible($('system-dialog-throbber'), true);
587 this.setIsEnabled_(false);
588 this.uiState_
= PrintPreview
.UiState_
.OPENING_NATIVE_PRINT_DIALOG
;
589 this.nativeLayer_
.startShowSystemDialog();
593 * Called when the native layer has initial settings to set. Sets the
594 * initial settings of the print preview and begins fetching print
596 * @param {Event} event Contains the initial print preview settings
597 * persisted through the session.
600 onInitialSettingsSet_: function(event
) {
601 assert(this.uiState_
== PrintPreview
.UiState_
.INITIALIZING
,
602 'Updating initial settings when not in initializing state: ' +
604 this.uiState_
= PrintPreview
.UiState_
.READY
;
606 var settings
= event
.initialSettings
;
607 this.isInKioskAutoPrintMode_
= settings
.isInKioskAutoPrintMode
;
608 this.isInAppKioskMode_
= settings
.isInAppKioskMode
;
610 // The following components must be initialized in this order.
612 settings
.serializedAppStateStr
,
613 settings
.systemDefaultDestinationId
);
614 this.documentInfo_
.init(
615 settings
.isDocumentModifiable
,
616 settings
.documentTitle
,
617 settings
.documentHasSelection
);
618 this.printTicketStore_
.init(
619 settings
.thousandsDelimeter
,
620 settings
.decimalDelimeter
,
622 settings
.selectionOnly
);
623 this.destinationStore_
.init(settings
.isInAppKioskMode
);
624 this.appState_
.setInitialized();
626 $('document-title').innerText
= settings
.documentTitle
;
627 this.isSystemDialogAvailable_
= !settings
.hidePrintWithSystemDialogLink
&&
628 !settings
.isInAppKioskMode
;
629 setIsVisible($('system-dialog-link'), this.shouldShowSystemDialogLink_());
633 * Calls when the native layer enables Google Cloud Print integration.
634 * Fetches the user's cloud printers.
635 * @param {Event} event Contains the base URL of the Google Cloud Print
639 onCloudPrintEnable_: function(event
) {
640 this.cloudPrintInterface_
= new cloudprint
.CloudPrintInterface(
641 event
.baseCloudPrintUrl
,
646 this.cloudPrintInterface_
,
647 cloudprint
.CloudPrintInterface
.EventType
.SUBMIT_DONE
,
648 this.onCloudPrintSubmitDone_
.bind(this));
650 this.cloudPrintInterface_
,
651 cloudprint
.CloudPrintInterface
.EventType
.SEARCH_FAILED
,
652 this.onCloudPrintError_
.bind(this));
654 this.cloudPrintInterface_
,
655 cloudprint
.CloudPrintInterface
.EventType
.SUBMIT_FAILED
,
656 this.onCloudPrintError_
.bind(this));
658 this.cloudPrintInterface_
,
659 cloudprint
.CloudPrintInterface
.EventType
.PRINTER_FAILED
,
660 this.onCloudPrintError_
.bind(this));
662 this.cloudPrintInterface_
,
663 cloudprint
.CloudPrintInterface
.EventType
.
664 UPDATE_PRINTER_TOS_ACCEPTANCE_FAILED
,
665 this.onCloudPrintError_
.bind(this));
667 this.destinationStore_
.setCloudPrintInterface(this.cloudPrintInterface_
);
668 if (this.destinationSearch_
.getIsVisible()) {
669 this.destinationStore_
.startLoadCloudDestinations();
674 * Called from the native layer when ready to print to Google Cloud Print.
675 * @param {Event} event Contains the body to send in the HTTP request.
678 onPrintToCloud_: function(event
) {
679 assert(this.uiState_
== PrintPreview
.UiState_
.PRINTING
,
680 'Document ready to be sent to the cloud when not in printing ' +
681 'state: ' + this.uiState_
);
682 assert(this.cloudPrintInterface_
!= null,
683 'Google Cloud Print is not enabled');
684 this.cloudPrintInterface_
.submit(
685 this.destinationStore_
.selectedDestination
,
686 this.printTicketStore_
,
692 * Called from the native layer when the user cancels the save-to-pdf file
696 onFileSelectionCancel_: function() {
697 assert(this.uiState_
== PrintPreview
.UiState_
.FILE_SELECTION
,
698 'File selection cancelled when not in file-selection state: ' +
700 this.setIsEnabled_(true);
701 this.uiState_
= PrintPreview
.UiState_
.READY
;
705 * Called from the native layer when save-to-pdf file selection is complete.
708 onFileSelectionComplete_: function() {
709 assert(this.uiState_
== PrintPreview
.UiState_
.FILE_SELECTION
,
710 'File selection completed when not in file-selection state: ' +
712 this.previewArea_
.showCustomMessage(
713 localStrings
.getString('printingToPDFInProgress'));
714 this.uiState_
= PrintPreview
.UiState_
.PRINTING
;
718 * Called after successfully submitting a job to Google Cloud Print.
719 * @param {!Event} event Contains the ID of the submitted print job.
722 onCloudPrintSubmitDone_: function(event
) {
723 assert(this.uiState_
== PrintPreview
.UiState_
.PRINTING
,
724 'Submited job to Google Cloud Print but not in printing state ' +
726 if (this.destinationStore_
.selectedDestination
.id
==
727 print_preview
.Destination
.GooglePromotedId
.FEDEX
) {
728 this.nativeLayer_
.startForceOpenNewTab(
729 'https://www.google.com/cloudprint/fedexcode.html?jobid=' +
736 * Called when there was an error communicating with Google Cloud print.
737 * Displays an error message in the print header.
738 * @param {!Event} event Contains the error message.
741 onCloudPrintError_: function(event
) {
742 if (event
.status
== 403) {
743 if (!this.isInAppKioskMode_
) {
744 this.destinationSearch_
.showCloudPrintPromo();
746 } else if (event
.status
== 0) {
747 return; // Ignore, the system does not have internet connectivity.
749 this.printHeader_
.setErrorMessage(event
.message
);
751 if (event
.status
== 200) {
752 console
.error('Google Cloud Print Error: (' + event
.errorCode
+ ') ' +
755 console
.error('Google Cloud Print Error: HTTP status ' + event
.status
);
760 * Called when the preview area's preview generation is in progress.
763 onPreviewGenerationInProgress_: function() {
764 this.isPreviewGenerationInProgress_
= true;
768 * Called when the preview area's preview generation is complete.
771 onPreviewGenerationDone_: function() {
772 this.isPreviewGenerationInProgress_
= false;
773 this.printHeader_
.isPrintButtonEnabled
= true;
774 this.nativeLayer_
.previewReadyForTest();
775 this.printIfReady_();
779 * Called when the preview area's preview failed to load.
782 onPreviewGenerationFail_: function() {
783 this.isPreviewGenerationInProgress_
= false;
784 this.printHeader_
.isPrintButtonEnabled
= false;
785 if (this.uiState_
== PrintPreview
.UiState_
.PRINTING
) {
786 this.nativeLayer_
.startCancelPendingPrint();
787 } else if (this.uiState_
==
788 PrintPreview
.UiState_
.OPENING_CLOUD_PRINT_DIALOG
) {
789 this.uiState_
= PrintPreview
.UiState_
.READY
;
794 * Called when the 'Open pdf in preview' link is clicked. Launches the pdf
798 onOpenPdfInPreviewLinkClick_: function() {
799 assert(this.uiState_
== PrintPreview
.UiState_
.READY
,
800 'Trying to open pdf in preview when not in ready state: ' +
802 setIsVisible($('open-preview-app-throbber'), true);
803 this.previewArea_
.showCustomMessage(
804 localStrings
.getString('openingPDFInPreview'));
805 this.printDocumentOrOpenPdfPreview_(true /*isPdfPreview*/);
809 * Called when the print header's print button is clicked. Prints the
813 onPrintButtonClick_: function() {
814 assert(this.uiState_
== PrintPreview
.UiState_
.READY
,
815 'Trying to print when not in ready state: ' + this.uiState_
);
816 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/);
820 * Called when the print header's cancel button is clicked. Closes the
824 onCancelButtonClick_: function() {
829 * Called when the register promo for Cloud Print is clicked.
832 onCloudPrintRegisterPromoClick_: function(e
) {
833 var devicesUrl
= 'chrome://devices/register?id=' + e
.destination
.id
;
834 this.nativeLayer_
.startForceOpenNewTab(devicesUrl
);
835 this.destinationStore_
.waitForRegister(e
.destination
.id
);
839 * Consume escape key presses and ctrl + shift + p. Delegate everything else
840 * to the preview area.
841 * @param {KeyboardEvent} e The keyboard event.
844 onKeyDown_: function(e
) {
845 // Escape key closes the dialog.
846 if (e
.keyCode
== 27 && !e
.shiftKey
&& !e
.ctrlKey
&& !e
.altKey
&&
848 <if expr
="toolkit_views">
849 // On the toolkit_views environment, ESC key is handled by C++-side
850 // instead of JS-side.
853 <if expr
="not toolkit_views">
860 // On Mac, Cmd- should close the print dialog.
861 if (cr
.isMac
&& e
.keyCode
== 189 && e
.metaKey
) {
867 // Ctrl + Shift + p / Mac equivalent.
868 if (e
.keyCode
== 80) {
869 if ((cr
.isMac
&& e
.metaKey
&& e
.altKey
&& !e
.shiftKey
&& !e
.ctrlKey
) ||
870 (!cr
.isMac
&& e
.shiftKey
&& e
.ctrlKey
&& !e
.altKey
&& !e
.metaKey
)) {
871 this.openSystemPrintDialog_();
877 if (e
.keyCode
== 13 /*enter*/ &&
878 !document
.querySelector('.overlay:not([hidden])') &&
879 this.destinationStore_
.selectedDestination
&&
880 this.printTicketStore_
.isTicketValid()) {
881 assert(this.uiState_
== PrintPreview
.UiState_
.READY
,
882 'Trying to print when not in ready state: ' + this.uiState_
);
883 var activeElementTag
= document
.activeElement
?
884 document
.activeElement
.tagName
.toUpperCase() : '';
885 if (activeElementTag
!= 'BUTTON' && activeElementTag
!= 'SELECT') {
886 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/);
892 // Pass certain directional keyboard events to the PDF viewer.
893 this.previewArea_
.handleDirectionalKeyEvent(e
);
897 * Called when native layer receives invalid settings for a print request.
900 onSettingsInvalid_: function() {
901 this.uiState_
= PrintPreview
.UiState_
.ERROR
;
902 console
.error('Invalid settings error reported from native layer');
903 this.previewArea_
.showCustomMessage(
904 localStrings
.getString('invalidPrinterSettings'));
908 * Called when the destination settings' change button is activated.
909 * Displays the destination search component.
912 onDestinationChangeButtonActivate_: function() {
913 this.destinationSearch_
.setIsVisible(true);
914 this.destinationStore_
.startLoadCloudDestinations();
915 this.destinationStore_
.startLoadLocalDestinations();
916 this.destinationStore_
.startLoadPrivetDestinations();
920 * Called when the destination settings' change button is activated.
921 * Displays the destination search component.
924 onAdvancedOptionsButtonActivated_: function() {
925 this.advancedSettings_
.showForDestination(
926 this.destinationStore_
.selectedDestination
);
930 * Called when the destination search dispatches manage cloud destinations
931 * event. Calls corresponding native layer method.
934 onManageCloudDestinationsActivated_: function() {
935 this.nativeLayer_
.startManageCloudDestinations();
939 * Called when the destination search dispatches manage local destinations
940 * event. Calls corresponding native layer method.
943 onManageLocalDestinationsActivated_: function() {
944 this.nativeLayer_
.startManageLocalDestinations();
948 * Called when the user wants to sign in to Google Cloud Print. Calls the
949 * corresponding native layer event.
950 * @param {boolean} addAccount Whether to open an 'add a new account' or
951 * default sign in page.
954 onCloudPrintSignInActivated_: function(addAccount
) {
955 this.nativeLayer_
.startCloudPrintSignIn(addAccount
);
959 * Called when the native layer dispatches a DISABLE_SCALING event. Resets
960 * fit-to-page selection and updates document info.
963 onDisableScaling_: function() {
964 this.printTicketStore_
.fitToPage
.updateValue(null);
965 this.documentInfo_
.updateIsScalingDisabled(true);
969 * Called when privet printing fails.
970 * @param {Event} event Event object representing the failure.
973 onPrivetPrintFailed_: function(event
) {
974 console
.error('Privet printing failed with error code ' +
976 this.printHeader_
.setErrorMessage(
977 localStrings
.getString('couldNotPrint'));
981 * Called when the print preview settings need to be changed for testing.
982 * @param {Event} event Event object that contains the option that is to
983 * be changed and what to set that option.
986 onManipulateSettingsForTest_: function(event
) {
987 if ('selectSaveAsPdfDestination' in event
.settings
) {
988 this.saveAsPdfForTest_(); // No parameters.
989 } else if ('layoutSettings' in event
.settings
) {
990 this.setLayoutSettingsForTest_(event
.settings
.layoutSettings
.portrait
);
991 } else if ('pageRange' in event
.settings
) {
992 this.setPageRangeForTest_(event
.settings
.pageRange
);
993 } else if ('headersAndFooters' in event
.settings
) {
994 this.setHeadersAndFootersForTest_(event
.settings
.headersAndFooters
);
995 } else if ('backgroundColorsAndImages' in event
.settings
) {
996 this.setBackgroundColorsAndImagesForTest_(
997 event
.settings
.backgroundColorsAndImages
);
998 } else if ('margins' in event
.settings
) {
999 this.setMarginsForTest_(event
.settings
.margins
);
1004 * Called by onManipulateSettingsForTest_(). Sets the print destination
1008 saveAsPdfForTest_: function() {
1009 if (this.destinationStore_
.selectedDestination
&&
1010 print_preview
.Destination
.GooglePromotedId
.SAVE_AS_PDF
==
1011 this.destinationStore_
.selectedDestination
.id
) {
1012 this.nativeLayer_
.previewReadyForTest();
1016 var destinations
= this.destinationStore_
.destinations();
1017 var pdfDestination
= null;
1018 for (var i
= 0; i
< destinations
.length
; i
++) {
1019 if (destinations
[i
].id
==
1020 print_preview
.Destination
.GooglePromotedId
.SAVE_AS_PDF
) {
1021 pdfDestination
= destinations
[i
];
1027 this.destinationStore_
.selectDestination(pdfDestination
);
1029 this.nativeLayer_
.previewFailedForTest();
1033 * Called by onManipulateSettingsForTest_(). Sets the layout settings to
1034 * either portrait or landscape.
1035 * @param {boolean} portrait Whether to use portrait page layout;
1036 * if false: landscape.
1039 setLayoutSettingsForTest_: function(portrait
) {
1040 var combobox
= document
.querySelector('.layout-settings-select');
1041 if (combobox
.value
== 'portrait') {
1042 this.nativeLayer_
.previewReadyForTest();
1044 combobox
.value
= 'landscape';
1045 this.layoutSettings_
.onSelectChange_();
1050 * Called by onManipulateSettingsForTest_(). Sets the page range for
1051 * for the print preview settings.
1052 * @param {string} pageRange Sets the page range to the desired value(s).
1053 * Ex: "1-5,9" means pages 1 through 5 and page 9 will be printed.
1056 setPageRangeForTest_: function(pageRange
) {
1057 var textbox
= document
.querySelector('.page-settings-custom-input');
1058 if (textbox
.value
== pageRange
) {
1059 this.nativeLayer_
.previewReadyForTest();
1061 textbox
.value
= pageRange
;
1062 document
.querySelector('.page-settings-custom-radio').click();
1067 * Called by onManipulateSettings_(). Checks or unchecks the headers and
1068 * footers option on print preview.
1069 * @param {boolean} headersAndFooters Whether the "Headers and Footers"
1070 * checkbox should be checked.
1073 setHeadersAndFootersForTest_: function(headersAndFooters
) {
1074 var checkbox
= document
.querySelector('.header-footer-checkbox');
1075 if (headersAndFooters
== checkbox
.checked
)
1076 this.nativeLayer_
.previewReadyForTest();
1082 * Called by onManipulateSettings_(). Checks or unchecks the background
1083 * colors and images option on print preview.
1084 * @param {boolean} backgroundColorsAndImages If true, the checkbox should
1085 * be checked. Otherwise it should be unchecked.
1088 setBackgroundColorsAndImagesForTest_: function(backgroundColorsAndImages
) {
1089 var checkbox
= document
.querySelector('.css-background-checkbox');
1090 if (backgroundColorsAndImages
== checkbox
.checked
)
1091 this.nativeLayer_
.previewReadyForTest();
1097 * Called by onManipulateSettings_(). Sets the margin settings
1098 * that are desired. Custom margin settings aren't currently supported.
1099 * @param {number} margins The desired margins combobox index. Must be
1100 * a valid index or else the test fails.
1103 setMarginsForTest_: function(margins
) {
1104 var combobox
= document
.querySelector('.margin-settings-select');
1105 if (margins
== combobox
.selectedIndex
) {
1106 this.nativeLayer_
.previewReadyForTest();
1107 } else if (margins
>= 0 && margins
< combobox
.length
) {
1108 combobox
.selectedIndex
= margins
;
1109 this.marginSettings_
.onSelectChange_();
1111 this.nativeLayer_
.previewFailedForTest();
1116 * Returns true if "Print using system dialog" link should be shown for
1117 * current destination.
1118 * @return {boolean} Returns true if link should be shown.
1120 shouldShowSystemDialogLink_: function() {
1121 if (!this.isSystemDialogAvailable_
)
1125 var selectedDest
= this.destinationStore_
.selectedDestination
;
1126 return selectedDest
&&
1127 selectedDest
.origin
== print_preview
.Destination
.Origin
.LOCAL
&&
1129 print_preview
.Destination
.GooglePromotedId
.SAVE_AS_PDF
;
1133 * Called when the open-cloud-print-dialog link is clicked. Opens the Google
1134 * Cloud Print web dialog.
1137 onCloudPrintDialogLinkClick_: function() {
1138 assert(this.uiState_
== PrintPreview
.UiState_
.READY
,
1139 'Opening Google Cloud Print dialog when not in ready state: ' +
1141 setIsVisible($('cloud-print-dialog-throbber'), true);
1142 this.setIsEnabled_(false);
1143 this.uiState_
= PrintPreview
.UiState_
.OPENING_CLOUD_PRINT_DIALOG
;
1144 this.printIfReady_();
1148 * Called when a print destination is selected. Shows/hides the "Print with
1149 * Cloud Print" link in the navbar.
1152 onDestinationSelect_: function() {
1153 var selectedDest
= this.destinationStore_
.selectedDestination
;
1155 $('cloud-print-dialog-link'),
1156 selectedDest
&& !cr
.isChromeOS
&& !selectedDest
.isLocal
);
1158 $('system-dialog-link'),
1159 this.shouldShowSystemDialogLink_());
1160 if (selectedDest
&& this.isInKioskAutoPrintMode_
) {
1161 this.onPrintButtonClick_();
1166 * Called when the destination store loads a group of destinations. Shows
1167 * a promo on Chrome OS if the user has no print destinations promoting
1168 * Google Cloud Print.
1171 onDestinationSearchDone_: function() {
1172 var isPromoVisible
= cr
.isChromeOS
&&
1173 this.cloudPrintInterface_
&&
1174 this.userInfo_
.activeUser
&&
1175 !this.appState_
.isGcpPromoDismissed
&&
1176 !this.destinationStore_
.isLocalDestinationsSearchInProgress
&&
1177 !this.destinationStore_
.isCloudDestinationsSearchInProgress
&&
1178 this.destinationStore_
.hasOnlyDefaultCloudDestinations();
1179 setIsVisible(this.getChildElement('#no-destinations-promo'),
1181 if (isPromoVisible
) {
1182 new print_preview
.GcpPromoMetricsContext().record(
1183 print_preview
.Metrics
.GcpPromoBucket
.PROMO_SHOWN
);
1188 * Called when the close button on the no-destinations-promotion is clicked.
1189 * Hides the promotion.
1192 onNoDestinationsPromoClose_: function() {
1193 new print_preview
.GcpPromoMetricsContext().record(
1194 print_preview
.Metrics
.GcpPromoBucket
.PROMO_CLOSED
);
1195 setIsVisible(this.getChildElement('#no-destinations-promo'), false);
1196 this.appState_
.persistIsGcpPromoDismissed(true);
1200 * Called when the no-destinations promotion link is clicked. Opens the
1201 * Google Cloud Print management page and closes the print preview.
1204 onNoDestinationsPromoClick_: function() {
1205 new print_preview
.GcpPromoMetricsContext().record(
1206 print_preview
.Metrics
.GcpPromoBucket
.PROMO_CLICKED
);
1207 this.appState_
.persistIsGcpPromoDismissed(true);
1208 window
.open(this.cloudPrintInterface_
.baseUrl
+ '?user=' +
1209 this.userInfo_
.activeUser
+ '#printers');
1216 PrintPreview
: PrintPreview
1220 // Pull in all other scripts in a single shot.
1221 <include src
="common/overlay.js"/>
1222 <include src
="common/search_box.js"/>
1223 <include src
="common/search_bubble.js"/>
1225 <include src
="data/page_number_set.js"/>
1226 <include src
="data/destination.js"/>
1227 <include src
="data/local_parsers.js"/>
1228 <include src
="data/cloud_parsers.js"/>
1229 <include src
="data/destination_store.js"/>
1230 <include src
="data/margins.js"/>
1231 <include src
="data/document_info.js"/>
1232 <include src
="data/printable_area.js"/>
1233 <include src
="data/measurement_system.js"/>
1234 <include src
="data/print_ticket_store.js"/>
1235 <include src
="data/coordinate2d.js"/>
1236 <include src
="data/size.js"/>
1237 <include src
="data/capabilities_holder.js"/>
1238 <include src
="data/user_info.js"/>
1239 <include src
="data/app_state.js"/>
1241 <include src
="data/ticket_items/ticket_item.js"/>
1243 <include src
="data/ticket_items/custom_margins.js"/>
1244 <include src
="data/ticket_items/collate.js"/>
1245 <include src
="data/ticket_items/color.js"/>
1246 <include src
="data/ticket_items/copies.js"/>
1247 <include src
="data/ticket_items/duplex.js"/>
1248 <include src
="data/ticket_items/header_footer.js"/>
1249 <include src
="data/ticket_items/media_size.js"/>
1250 <include src
="data/ticket_items/landscape.js"/>
1251 <include src
="data/ticket_items/margins_type.js"/>
1252 <include src
="data/ticket_items/page_range.js"/>
1253 <include src
="data/ticket_items/fit_to_page.js"/>
1254 <include src
="data/ticket_items/css_background.js"/>
1255 <include src
="data/ticket_items/selection_only.js"/>
1256 <include src
="data/ticket_items/vendor_items.js"/>
1258 <include src
="native_layer.js"/>
1259 <include src
="print_preview_animations.js"/>
1260 <include src
="cloud_print_interface.js"/>
1261 <include src
="print_preview_utils.js"/>
1262 <include src
="print_header.js"/>
1263 <include src
="metrics.js"/>
1265 <include src
="settings/settings_section.js"/>
1266 <include src
="settings/page_settings.js"/>
1267 <include src
="settings/copies_settings.js"/>
1268 <include src
="settings/media_size_settings.js"/>
1269 <include src
="settings/layout_settings.js"/>
1270 <include src
="settings/color_settings.js"/>
1271 <include src
="settings/margin_settings.js"/>
1272 <include src
="settings/destination_settings.js"/>
1273 <include src
="settings/other_options_settings.js"/>
1274 <include src
="settings/advanced_options_settings.js"/>
1275 <include src
="settings/advanced_settings/advanced_settings.js"/>
1276 <include src
="settings/advanced_settings/advanced_settings_item.js"/>
1277 <include src
="settings/more_settings.js"/>
1279 <include src
="previewarea/margin_control.js"/>
1280 <include src
="previewarea/margin_control_container.js"/>
1281 <include src
="../pdf/pdf_scripting_api.js" />
1282 <include src
="previewarea/preview_area.js"/>
1283 <include src
="preview_generator.js"/>
1285 <include src
="search/destination_list.js"/>
1286 <include src
="search/cloud_destination_list.js"/>
1287 <include src
="search/recent_destination_list.js"/>
1288 <include src
="search/destination_list_item.js"/>
1289 <include src
="search/destination_search.js"/>
1290 <include src
="search/fedex_tos.js"/>
1292 window
.addEventListener('DOMContentLoaded', function() {
1293 printPreview
= new print_preview
.PrintPreview();
1294 printPreview
.initialize();