Best Python code snippet using molotov_python
print_preview.js
Source:print_preview.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 be3// found in the LICENSE file.4// TODO(rltoscano): Move data/* into print_preview.data namespace5<include src="component.js">6<include src="print_preview_focus_manager.js">7cr.define('print_preview', function() {8 'use strict';9 /**10 * Container class for Chromium's print preview.11 * @constructor12 * @extends {print_preview.Component}13 */14 function PrintPreview() {15 print_preview.Component.call(this);16 /**17 * Used to communicate with Chromium's print system.18 * @type {!print_preview.NativeLayer}19 * @private20 */21 this.nativeLayer_ = new print_preview.NativeLayer();22 /**23 * Event target that contains information about the logged in user.24 * @type {!print_preview.UserInfo}25 * @private26 */27 this.userInfo_ = new print_preview.UserInfo();28 /**29 * Application state.30 * @type {!print_preview.AppState}31 * @private32 */33 this.appState_ = new print_preview.AppState();34 /**35 * Data model that holds information about the document to print.36 * @type {!print_preview.DocumentInfo}37 * @private38 */39 this.documentInfo_ = new print_preview.DocumentInfo();40 /**41 * Data store which holds print destinations.42 * @type {!print_preview.DestinationStore}43 * @private44 */45 this.destinationStore_ = new print_preview.DestinationStore(46 this.nativeLayer_, this.userInfo_, this.appState_);47 /**48 * Data store which holds printer sharing invitations.49 * @type {!print_preview.InvitationStore}50 * @private51 */52 this.invitationStore_ = new print_preview.InvitationStore(this.userInfo_);53 /**54 * Storage of the print ticket used to create the print job.55 * @type {!print_preview.PrintTicketStore}56 * @private57 */58 this.printTicketStore_ = new print_preview.PrintTicketStore(59 this.destinationStore_, this.appState_, this.documentInfo_);60 /**61 * Holds the print and cancel buttons and renders some document statistics.62 * @type {!print_preview.PrintHeader}63 * @private64 */65 this.printHeader_ = new print_preview.PrintHeader(66 this.printTicketStore_, this.destinationStore_);67 this.addChild(this.printHeader_);68 /**69 * Component used to search for print destinations.70 * @type {!print_preview.DestinationSearch}71 * @private72 */73 this.destinationSearch_ = new print_preview.DestinationSearch(74 this.destinationStore_, this.invitationStore_, this.userInfo_);75 this.addChild(this.destinationSearch_);76 /**77 * Component that renders the print destination.78 * @type {!print_preview.DestinationSettings}79 * @private80 */81 this.destinationSettings_ = new print_preview.DestinationSettings(82 this.destinationStore_);83 this.addChild(this.destinationSettings_);84 /**85 * Component that renders UI for entering in page range.86 * @type {!print_preview.PageSettings}87 * @private88 */89 this.pageSettings_ = new print_preview.PageSettings(90 this.printTicketStore_.pageRange);91 this.addChild(this.pageSettings_);92 /**93 * Component that renders the copies settings.94 * @type {!print_preview.CopiesSettings}95 * @private96 */97 this.copiesSettings_ = new print_preview.CopiesSettings(98 this.printTicketStore_.copies, this.printTicketStore_.collate);99 this.addChild(this.copiesSettings_);100 /**101 * Component that renders the media size settings.102 * @type {!print_preview.MediaSizeSettings}103 * @private104 */105 this.mediaSizeSettings_ =106 new print_preview.MediaSizeSettings(this.printTicketStore_.mediaSize);107 this.addChild(this.mediaSizeSettings_);108 /**109 * Component that renders the layout settings.110 * @type {!print_preview.LayoutSettings}111 * @private112 */113 this.layoutSettings_ =114 new print_preview.LayoutSettings(this.printTicketStore_.landscape);115 this.addChild(this.layoutSettings_);116 /**117 * Component that renders the color options.118 * @type {!print_preview.ColorSettings}119 * @private120 */121 this.colorSettings_ =122 new print_preview.ColorSettings(this.printTicketStore_.color);123 this.addChild(this.colorSettings_);124 /**125 * Component that renders a select box for choosing margin settings.126 * @type {!print_preview.MarginSettings}127 * @private128 */129 this.marginSettings_ =130 new print_preview.MarginSettings(this.printTicketStore_.marginsType);131 this.addChild(this.marginSettings_);132 /**133 * Component that renders the DPI settings.134 * @type {!print_preview.DpiSettings}135 * @private136 */137 this.dpiSettings_ =138 new print_preview.DpiSettings(this.printTicketStore_.dpi);139 this.addChild(this.dpiSettings_);140 /**141 * Component that renders miscellaneous print options.142 * @type {!print_preview.OtherOptionsSettings}143 * @private144 */145 this.otherOptionsSettings_ = new print_preview.OtherOptionsSettings(146 this.printTicketStore_.duplex,147 this.printTicketStore_.fitToPage,148 this.printTicketStore_.cssBackground,149 this.printTicketStore_.selectionOnly,150 this.printTicketStore_.headerFooter);151 this.addChild(this.otherOptionsSettings_);152 /**153 * Component that renders the advanced options button.154 * @type {!print_preview.AdvancedOptionsSettings}155 * @private156 */157 this.advancedOptionsSettings_ = new print_preview.AdvancedOptionsSettings(158 this.printTicketStore_.vendorItems, this.destinationStore_);159 this.addChild(this.advancedOptionsSettings_);160 /**161 * Component used to search for print destinations.162 * @type {!print_preview.AdvancedSettings}163 * @private164 */165 this.advancedSettings_ = new print_preview.AdvancedSettings(166 this.printTicketStore_);167 this.addChild(this.advancedSettings_);168 var settingsSections = [169 this.destinationSettings_,170 this.pageSettings_,171 this.copiesSettings_,172 this.mediaSizeSettings_,173 this.layoutSettings_,174 this.marginSettings_,175 this.colorSettings_,176 this.dpiSettings_,177 this.otherOptionsSettings_,178 this.advancedOptionsSettings_];179 /**180 * Component representing more/less settings button.181 * @type {!print_preview.MoreSettings}182 * @private183 */184 this.moreSettings_ = new print_preview.MoreSettings(185 this.destinationStore_, settingsSections);186 this.addChild(this.moreSettings_);187 /**188 * Area of the UI that holds the print preview.189 * @type {!print_preview.PreviewArea}190 * @private191 */192 this.previewArea_ = new print_preview.PreviewArea(this.destinationStore_,193 this.printTicketStore_,194 this.nativeLayer_,195 this.documentInfo_);196 this.addChild(this.previewArea_);197 /**198 * Interface to the Google Cloud Print API. Null if Google Cloud Print199 * integration is disabled.200 * @type {cloudprint.CloudPrintInterface}201 * @private202 */203 this.cloudPrintInterface_ = null;204 /**205 * Whether in kiosk mode where print preview can print automatically without206 * user intervention. See http://crbug.com/31395. Print will start when207 * both the print ticket has been initialized, and an initial printer has208 * been selected.209 * @type {boolean}210 * @private211 */212 this.isInKioskAutoPrintMode_ = false;213 /**214 * Whether Print Preview is in App Kiosk mode, basically, use only printers215 * available for the device.216 * @type {boolean}217 * @private218 */219 this.isInAppKioskMode_ = false;220 /**221 * Whether Print with System Dialog link should be hidden. Overrides the222 * default rules for System dialog link visibility.223 * @type {boolean}224 * @private225 */226 this.hideSystemDialogLink_ = true;227 /**228 * State of the print preview UI.229 * @type {print_preview.PrintPreview.UiState_}230 * @private231 */232 this.uiState_ = PrintPreview.UiState_.INITIALIZING;233 /**234 * Whether document preview generation is in progress.235 * @type {boolean}236 * @private237 */238 this.isPreviewGenerationInProgress_ = true;239 /**240 * Whether to show system dialog before next printing.241 * @type {boolean}242 * @private243 */244 this.showSystemDialogBeforeNextPrint_ = false;245 };246 /**247 * States of the print preview.248 * @enum {string}249 * @private250 */251 PrintPreview.UiState_ = {252 INITIALIZING: 'initializing',253 READY: 'ready',254 OPENING_PDF_PREVIEW: 'opening-pdf-preview',255 OPENING_NATIVE_PRINT_DIALOG: 'opening-native-print-dialog',256 PRINTING: 'printing',257 FILE_SELECTION: 'file-selection',258 CLOSING: 'closing',259 ERROR: 'error'260 };261 /**262 * What can happen when print preview tries to print.263 * @enum {string}264 * @private265 */266 PrintPreview.PrintAttemptResult_ = {267 NOT_READY: 'not-ready',268 PRINTED: 'printed',269 READY_WAITING_FOR_PREVIEW: 'ready-waiting-for-preview'270 };271 PrintPreview.prototype = {272 __proto__: print_preview.Component.prototype,273 /** Sets up the page and print preview by getting the printer list. */274 initialize: function() {275 this.decorate($('print-preview'));276 if (!this.previewArea_.hasCompatiblePlugin) {277 this.setIsEnabled_(false);278 }279 this.nativeLayer_.startGetInitialSettings();280 print_preview.PrintPreviewFocusManager.getInstance().initialize();281 cr.ui.FocusOutlineManager.forDocument(document);282 },283 /** @override */284 enterDocument: function() {285 // Native layer events.286 this.tracker.add(287 this.nativeLayer_,288 print_preview.NativeLayer.EventType.INITIAL_SETTINGS_SET,289 this.onInitialSettingsSet_.bind(this));290 this.tracker.add(291 this.nativeLayer_,292 print_preview.NativeLayer.EventType.CLOUD_PRINT_ENABLE,293 this.onCloudPrintEnable_.bind(this));294 this.tracker.add(295 this.nativeLayer_,296 print_preview.NativeLayer.EventType.PRINT_TO_CLOUD,297 this.onPrintToCloud_.bind(this));298 this.tracker.add(299 this.nativeLayer_,300 print_preview.NativeLayer.EventType.FILE_SELECTION_CANCEL,301 this.onFileSelectionCancel_.bind(this));302 this.tracker.add(303 this.nativeLayer_,304 print_preview.NativeLayer.EventType.FILE_SELECTION_COMPLETE,305 this.onFileSelectionComplete_.bind(this));306 this.tracker.add(307 this.nativeLayer_,308 print_preview.NativeLayer.EventType.SETTINGS_INVALID,309 this.onSettingsInvalid_.bind(this));310 this.tracker.add(311 this.nativeLayer_,312 print_preview.NativeLayer.EventType.PRINT_PRESET_OPTIONS,313 this.onPrintPresetOptionsFromDocument_.bind(this));314 this.tracker.add(315 this.nativeLayer_,316 print_preview.NativeLayer.EventType.PRIVET_PRINT_FAILED,317 this.onPrivetPrintFailed_.bind(this));318 this.tracker.add(319 this.nativeLayer_,320 print_preview.NativeLayer.EventType.MANIPULATE_SETTINGS_FOR_TEST,321 this.onManipulateSettingsForTest_.bind(this));322 if ($('system-dialog-link')) {323 this.tracker.add(324 $('system-dialog-link'),325 'click',326 this.openSystemPrintDialog_.bind(this));327 }328 if ($('open-pdf-in-preview-link')) {329 this.tracker.add(330 $('open-pdf-in-preview-link'),331 'click',332 this.onOpenPdfInPreviewLinkClick_.bind(this));333 }334 this.tracker.add(335 this.previewArea_,336 print_preview.PreviewArea.EventType.PREVIEW_GENERATION_IN_PROGRESS,337 this.onPreviewGenerationInProgress_.bind(this));338 this.tracker.add(339 this.previewArea_,340 print_preview.PreviewArea.EventType.PREVIEW_GENERATION_DONE,341 this.onPreviewGenerationDone_.bind(this));342 this.tracker.add(343 this.previewArea_,344 print_preview.PreviewArea.EventType.PREVIEW_GENERATION_FAIL,345 this.onPreviewGenerationFail_.bind(this));346 this.tracker.add(347 this.previewArea_,348 print_preview.PreviewArea.EventType.OPEN_SYSTEM_DIALOG_CLICK,349 this.openSystemPrintDialog_.bind(this));350 this.tracker.add(351 this.destinationStore_,352 print_preview.DestinationStore.EventType.353 SELECTED_DESTINATION_CAPABILITIES_READY,354 this.printIfReady_.bind(this));355 this.tracker.add(356 this.destinationStore_,357 print_preview.DestinationStore.EventType.DESTINATION_SELECT,358 this.onDestinationSelect_.bind(this));359 this.tracker.add(360 this.destinationStore_,361 print_preview.DestinationStore.EventType.DESTINATION_SEARCH_DONE,362 this.onDestinationSearchDone_.bind(this));363 this.tracker.add(364 this.printHeader_,365 print_preview.PrintHeader.EventType.PRINT_BUTTON_CLICK,366 this.onPrintButtonClick_.bind(this));367 this.tracker.add(368 this.printHeader_,369 print_preview.PrintHeader.EventType.CANCEL_BUTTON_CLICK,370 this.onCancelButtonClick_.bind(this));371 this.tracker.add(window, 'keydown', this.onKeyDown_.bind(this));372 this.previewArea_.setPluginKeyEventCallback(this.onKeyDown_.bind(this));373 this.tracker.add(374 this.destinationSettings_,375 print_preview.DestinationSettings.EventType.CHANGE_BUTTON_ACTIVATE,376 this.onDestinationChangeButtonActivate_.bind(this));377 this.tracker.add(378 this.destinationSearch_,379 print_preview.DestinationSearch.EventType.MANAGE_CLOUD_DESTINATIONS,380 this.onManageCloudDestinationsActivated_.bind(this));381 this.tracker.add(382 this.destinationSearch_,383 print_preview.DestinationSearch.EventType.MANAGE_LOCAL_DESTINATIONS,384 this.onManageLocalDestinationsActivated_.bind(this));385 this.tracker.add(386 this.destinationSearch_,387 print_preview.DestinationSearch.EventType.ADD_ACCOUNT,388 this.onCloudPrintSignInActivated_.bind(this, true /*addAccount*/));389 this.tracker.add(390 this.destinationSearch_,391 print_preview.DestinationSearch.EventType.SIGN_IN,392 this.onCloudPrintSignInActivated_.bind(this, false /*addAccount*/));393 this.tracker.add(394 this.destinationSearch_,395 print_preview.DestinationListItem.EventType.REGISTER_PROMO_CLICKED,396 this.onCloudPrintRegisterPromoClick_.bind(this));397 this.tracker.add(398 this.advancedOptionsSettings_,399 print_preview.AdvancedOptionsSettings.EventType.BUTTON_ACTIVATED,400 this.onAdvancedOptionsButtonActivated_.bind(this));401 // TODO(rltoscano): Move no-destinations-promo into its own component402 // instead being part of PrintPreview.403 this.tracker.add(404 this.getChildElement('#no-destinations-promo .close-button'),405 'click',406 this.onNoDestinationsPromoClose_.bind(this));407 this.tracker.add(408 this.getChildElement('#no-destinations-promo .not-now-button'),409 'click',410 this.onNoDestinationsPromoClose_.bind(this));411 this.tracker.add(412 this.getChildElement('#no-destinations-promo .add-printer-button'),413 'click',414 this.onNoDestinationsPromoClick_.bind(this));415 },416 /** @override */417 decorateInternal: function() {418 this.printHeader_.decorate($('print-header'));419 this.destinationSearch_.decorate($('destination-search'));420 this.destinationSettings_.decorate($('destination-settings'));421 this.pageSettings_.decorate($('page-settings'));422 this.copiesSettings_.decorate($('copies-settings'));423 this.mediaSizeSettings_.decorate($('media-size-settings'));424 this.layoutSettings_.decorate($('layout-settings'));425 this.colorSettings_.decorate($('color-settings'));426 this.marginSettings_.decorate($('margin-settings'));427 this.dpiSettings_.decorate($('dpi-settings'));428 this.otherOptionsSettings_.decorate($('other-options-settings'));429 this.advancedOptionsSettings_.decorate($('advanced-options-settings'));430 this.advancedSettings_.decorate($('advanced-settings'));431 this.moreSettings_.decorate($('more-settings'));432 this.previewArea_.decorate($('preview-area'));433 },434 /**435 * Sets whether the controls in the print preview are enabled.436 * @param {boolean} isEnabled Whether the controls in the print preview are437 * enabled.438 * @private439 */440 setIsEnabled_: function(isEnabled) {441 if ($('system-dialog-link'))442 $('system-dialog-link').classList.toggle('disabled', !isEnabled);443 if ($('open-pdf-in-preview-link'))444 $('open-pdf-in-preview-link').classList.toggle('disabled', !isEnabled);445 this.printHeader_.isEnabled = isEnabled;446 this.destinationSettings_.isEnabled = isEnabled;447 this.pageSettings_.isEnabled = isEnabled;448 this.copiesSettings_.isEnabled = isEnabled;449 this.mediaSizeSettings_.isEnabled = isEnabled;450 this.layoutSettings_.isEnabled = isEnabled;451 this.colorSettings_.isEnabled = isEnabled;452 this.marginSettings_.isEnabled = isEnabled;453 this.dpiSettings_.isEnabled = isEnabled;454 this.otherOptionsSettings_.isEnabled = isEnabled;455 this.advancedOptionsSettings_.isEnabled = isEnabled;456 },457 /**458 * Prints the document or launches a pdf preview on the local system.459 * @param {boolean} isPdfPreview Whether to launch the pdf preview.460 * @private461 */462 printDocumentOrOpenPdfPreview_: function(isPdfPreview) {463 assert(this.uiState_ == PrintPreview.UiState_.READY,464 'Print document request received when not in ready state: ' +465 this.uiState_);466 if (isPdfPreview) {467 this.uiState_ = PrintPreview.UiState_.OPENING_PDF_PREVIEW;468 } else if (this.destinationStore_.selectedDestination.id ==469 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {470 this.uiState_ = PrintPreview.UiState_.FILE_SELECTION;471 } else {472 this.uiState_ = PrintPreview.UiState_.PRINTING;473 }474 this.setIsEnabled_(false);475 this.printHeader_.isCancelButtonEnabled = true;476 var printAttemptResult = this.printIfReady_();477 if (printAttemptResult == PrintPreview.PrintAttemptResult_.PRINTED ||478 printAttemptResult ==479 PrintPreview.PrintAttemptResult_.READY_WAITING_FOR_PREVIEW) {480 if ((this.destinationStore_.selectedDestination.isLocal &&481 !this.destinationStore_.selectedDestination.isPrivet &&482 !this.destinationStore_.selectedDestination.isExtension &&483 this.destinationStore_.selectedDestination.id !=484 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) ||485 this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW) {486 // Hide the dialog for now. The actual print command will be issued487 // when the preview generation is done.488 this.nativeLayer_.startHideDialog();489 }490 }491 },492 /**493 * Attempts to print if needed and if ready.494 * @return {PrintPreview.PrintAttemptResult_} Attempt result.495 * @private496 */497 printIfReady_: function() {498 var okToPrint =499 (this.uiState_ == PrintPreview.UiState_.PRINTING ||500 this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW ||501 this.uiState_ == PrintPreview.UiState_.FILE_SELECTION ||502 this.isInKioskAutoPrintMode_) &&503 this.destinationStore_.selectedDestination &&504 this.destinationStore_.selectedDestination.capabilities;505 if (!okToPrint) {506 return PrintPreview.PrintAttemptResult_.NOT_READY;507 }508 if (this.isPreviewGenerationInProgress_) {509 return PrintPreview.PrintAttemptResult_.READY_WAITING_FOR_PREVIEW;510 }511 assert(this.printTicketStore_.isTicketValid(),512 'Trying to print with invalid ticket');513 if (getIsVisible(this.moreSettings_.getElement())) {514 new print_preview.PrintSettingsUiMetricsContext().record(515 this.moreSettings_.isExpanded ?516 print_preview.Metrics.PrintSettingsUiBucket.517 PRINT_WITH_SETTINGS_EXPANDED :518 print_preview.Metrics.PrintSettingsUiBucket.519 PRINT_WITH_SETTINGS_COLLAPSED);520 }521 this.nativeLayer_.startPrint(522 this.destinationStore_.selectedDestination,523 this.printTicketStore_,524 this.cloudPrintInterface_,525 this.documentInfo_,526 this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW,527 this.showSystemDialogBeforeNextPrint_);528 this.showSystemDialogBeforeNextPrint_ = false;529 return PrintPreview.PrintAttemptResult_.PRINTED;530 },531 /**532 * Closes the print preview.533 * @private534 */535 close_: function() {536 this.exitDocument();537 this.uiState_ = PrintPreview.UiState_.CLOSING;538 this.nativeLayer_.startCloseDialog();539 },540 /**541 * Opens the native system print dialog after disabling all controls.542 * @private543 */544 openSystemPrintDialog_: function() {545 if (!this.shouldShowSystemDialogLink_())546 return;547 if ($('system-dialog-link').classList.contains('disabled'))548 return;549 if (cr.isWindows) {550 this.showSystemDialogBeforeNextPrint_ = true;551 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/);552 return;553 }554 setIsVisible(getRequiredElement('system-dialog-throbber'), true);555 this.setIsEnabled_(false);556 this.uiState_ = PrintPreview.UiState_.OPENING_NATIVE_PRINT_DIALOG;557 this.nativeLayer_.startShowSystemDialog();558 },559 /**560 * Called when the native layer has initial settings to set. Sets the561 * initial settings of the print preview and begins fetching print562 * destinations.563 * @param {Event} event Contains the initial print preview settings564 * persisted through the session.565 * @private566 */567 onInitialSettingsSet_: function(event) {568 assert(this.uiState_ == PrintPreview.UiState_.INITIALIZING,569 'Updating initial settings when not in initializing state: ' +570 this.uiState_);571 this.uiState_ = PrintPreview.UiState_.READY;572 var settings = event.initialSettings;573 this.isInKioskAutoPrintMode_ = settings.isInKioskAutoPrintMode;574 this.isInAppKioskMode_ = settings.isInAppKioskMode;575 // The following components must be initialized in this order.576 this.appState_.init(577 settings.serializedAppStateStr,578 settings.systemDefaultDestinationId);579 this.documentInfo_.init(580 settings.isDocumentModifiable,581 settings.documentTitle,582 settings.documentHasSelection);583 this.printTicketStore_.init(584 settings.thousandsDelimeter,585 settings.decimalDelimeter,586 settings.unitType,587 settings.selectionOnly);588 this.destinationStore_.init(settings.isInAppKioskMode);589 this.appState_.setInitialized();590 $('document-title').innerText = settings.documentTitle;591 this.hideSystemDialogLink_ = settings.hidePrintWithSystemDialogLink ||592 settings.isInAppKioskMode;593 if ($('system-dialog-link')) {594 setIsVisible($('system-dialog-link'),595 this.shouldShowSystemDialogLink_());596 }597 },598 /**599 * Calls when the native layer enables Google Cloud Print integration.600 * Fetches the user's cloud printers.601 * @param {Event} event Contains the base URL of the Google Cloud Print602 * service.603 * @private604 */605 onCloudPrintEnable_: function(event) {606 this.cloudPrintInterface_ = new cloudprint.CloudPrintInterface(607 event.baseCloudPrintUrl,608 this.nativeLayer_,609 this.userInfo_,610 event.appKioskMode);611 this.tracker.add(612 this.cloudPrintInterface_,613 cloudprint.CloudPrintInterface.EventType.SUBMIT_DONE,614 this.onCloudPrintSubmitDone_.bind(this));615 this.tracker.add(616 this.cloudPrintInterface_,617 cloudprint.CloudPrintInterface.EventType.SEARCH_FAILED,618 this.onCloudPrintError_.bind(this));619 this.tracker.add(620 this.cloudPrintInterface_,621 cloudprint.CloudPrintInterface.EventType.SUBMIT_FAILED,622 this.onCloudPrintError_.bind(this));623 this.tracker.add(624 this.cloudPrintInterface_,625 cloudprint.CloudPrintInterface.EventType.PRINTER_FAILED,626 this.onCloudPrintError_.bind(this));627 this.tracker.add(628 this.cloudPrintInterface_,629 cloudprint.CloudPrintInterface.EventType.630 UPDATE_PRINTER_TOS_ACCEPTANCE_FAILED,631 this.onCloudPrintError_.bind(this));632 this.destinationStore_.setCloudPrintInterface(this.cloudPrintInterface_);633 this.invitationStore_.setCloudPrintInterface(this.cloudPrintInterface_);634 if (this.destinationSearch_.getIsVisible()) {635 this.destinationStore_.startLoadCloudDestinations();636 this.invitationStore_.startLoadingInvitations();637 }638 },639 /**640 * Called from the native layer when ready to print to Google Cloud Print.641 * @param {Event} event Contains the body to send in the HTTP request.642 * @private643 */644 onPrintToCloud_: function(event) {645 assert(this.uiState_ == PrintPreview.UiState_.PRINTING,646 'Document ready to be sent to the cloud when not in printing ' +647 'state: ' + this.uiState_);648 assert(this.cloudPrintInterface_ != null,649 'Google Cloud Print is not enabled');650 this.cloudPrintInterface_.submit(651 this.destinationStore_.selectedDestination,652 this.printTicketStore_,653 this.documentInfo_,654 event.data);655 },656 /**657 * Called from the native layer when the user cancels the save-to-pdf file658 * selection dialog.659 * @private660 */661 onFileSelectionCancel_: function() {662 assert(this.uiState_ == PrintPreview.UiState_.FILE_SELECTION,663 'File selection cancelled when not in file-selection state: ' +664 this.uiState_);665 this.setIsEnabled_(true);666 this.uiState_ = PrintPreview.UiState_.READY;667 },668 /**669 * Called from the native layer when save-to-pdf file selection is complete.670 * @private671 */672 onFileSelectionComplete_: function() {673 assert(this.uiState_ == PrintPreview.UiState_.FILE_SELECTION,674 'File selection completed when not in file-selection state: ' +675 this.uiState_);676 this.previewArea_.showCustomMessage(677 loadTimeData.getString('printingToPDFInProgress'));678 this.uiState_ = PrintPreview.UiState_.PRINTING;679 },680 /**681 * Called after successfully submitting a job to Google Cloud Print.682 * @param {!Event} event Contains the ID of the submitted print job.683 * @private684 */685 onCloudPrintSubmitDone_: function(event) {686 assert(this.uiState_ == PrintPreview.UiState_.PRINTING,687 'Submited job to Google Cloud Print but not in printing state ' +688 this.uiState_);689 if (this.destinationStore_.selectedDestination.id ==690 print_preview.Destination.GooglePromotedId.FEDEX) {691 this.nativeLayer_.startForceOpenNewTab(692 'https://www.google.com/cloudprint/fedexcode.html?jobid=' +693 event.jobId);694 }695 this.close_();696 },697 /**698 * Called when there was an error communicating with Google Cloud print.699 * Displays an error message in the print header.700 * @param {!Event} event Contains the error message.701 * @private702 */703 onCloudPrintError_: function(event) {704 if (event.status == 403) {705 if (!this.isInAppKioskMode_) {706 this.destinationSearch_.showCloudPrintPromo();707 }708 } else if (event.status == 0) {709 return; // Ignore, the system does not have internet connectivity.710 } else {711 this.printHeader_.setErrorMessage(event.message);712 }713 if (event.status == 200) {714 console.error('Google Cloud Print Error: (' + event.errorCode + ') ' +715 event.message);716 } else {717 console.error('Google Cloud Print Error: HTTP status ' + event.status);718 }719 },720 /**721 * Called when the preview area's preview generation is in progress.722 * @private723 */724 onPreviewGenerationInProgress_: function() {725 this.isPreviewGenerationInProgress_ = true;726 },727 /**728 * Called when the preview area's preview generation is complete.729 * @private730 */731 onPreviewGenerationDone_: function() {732 this.isPreviewGenerationInProgress_ = false;733 this.printHeader_.isPrintButtonEnabled = true;734 this.nativeLayer_.previewReadyForTest();735 this.printIfReady_();736 },737 /**738 * Called when the preview area's preview failed to load.739 * @private740 */741 onPreviewGenerationFail_: function() {742 this.isPreviewGenerationInProgress_ = false;743 this.printHeader_.isPrintButtonEnabled = false;744 if (this.uiState_ == PrintPreview.UiState_.PRINTING)745 this.nativeLayer_.startCancelPendingPrint();746 },747 /**748 * Called when the 'Open pdf in preview' link is clicked. Launches the pdf749 * preview app.750 * @private751 */752 onOpenPdfInPreviewLinkClick_: function() {753 if ($('open-pdf-in-preview-link').classList.contains('disabled'))754 return;755 assert(this.uiState_ == PrintPreview.UiState_.READY,756 'Trying to open pdf in preview when not in ready state: ' +757 this.uiState_);758 setIsVisible(getRequiredElement('open-preview-app-throbber'), true);759 this.previewArea_.showCustomMessage(760 loadTimeData.getString('openingPDFInPreview'));761 this.printDocumentOrOpenPdfPreview_(true /*isPdfPreview*/);762 },763 /**764 * Called when the print header's print button is clicked. Prints the765 * document.766 * @private767 */768 onPrintButtonClick_: function() {769 assert(this.uiState_ == PrintPreview.UiState_.READY,770 'Trying to print when not in ready state: ' + this.uiState_);771 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/);772 },773 /**774 * Called when the print header's cancel button is clicked. Closes the775 * print dialog.776 * @private777 */778 onCancelButtonClick_: function() {779 this.close_();780 },781 /**782 * Called when the register promo for Cloud Print is clicked.783 * @private784 */785 onCloudPrintRegisterPromoClick_: function(e) {786 var devicesUrl = 'chrome://devices/register?id=' + e.destination.id;787 this.nativeLayer_.startForceOpenNewTab(devicesUrl);788 this.destinationStore_.waitForRegister(e.destination.id);789 },790 /**791 * Consume escape key presses and ctrl + shift + p. Delegate everything else792 * to the preview area.793 * @param {KeyboardEvent} e The keyboard event.794 * @private795 * @suppress {uselessCode}796 * Current compiler preprocessor leaves all the code inside all the <if>s,797 * so the compiler claims that code after first return is unreachable.798 */799 onKeyDown_: function(e) {800 // Escape key closes the dialog.801 if (e.keyCode == 27 && !e.shiftKey && !e.ctrlKey && !e.altKey &&802 !e.metaKey) {803 // On non-mac with toolkit-views, ESC key is handled by C++-side instead804 // of JS-side.805 if (cr.isMac) {806 this.close_();807 e.preventDefault();808 }809 return;810 }811 // On Mac, Cmd- should close the print dialog.812 if (cr.isMac && e.keyCode == 189 && e.metaKey) {813 this.close_();814 e.preventDefault();815 return;816 }817 // Ctrl + Shift + p / Mac equivalent.818 if (e.keyCode == 80) {819 if ((cr.isMac && e.metaKey && e.altKey && !e.shiftKey && !e.ctrlKey) ||820 (!cr.isMac && e.shiftKey && e.ctrlKey && !e.altKey && !e.metaKey)) {821 this.openSystemPrintDialog_();822 e.preventDefault();823 return;824 }825 }826 if (e.keyCode == 13 /*enter*/ &&827 !document.querySelector('.overlay:not([hidden])') &&828 this.destinationStore_.selectedDestination &&829 this.printTicketStore_.isTicketValid() &&830 this.printHeader_.isPrintButtonEnabled) {831 assert(this.uiState_ == PrintPreview.UiState_.READY,832 'Trying to print when not in ready state: ' + this.uiState_);833 var activeElementTag = document.activeElement.tagName.toUpperCase();834 if (activeElementTag != 'BUTTON' && activeElementTag != 'SELECT' &&835 activeElementTag != 'A') {836 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/);837 e.preventDefault();838 }839 return;840 }841 // Pass certain directional keyboard events to the PDF viewer.842 this.previewArea_.handleDirectionalKeyEvent(e);843 },844 /**845 * Called when native layer receives invalid settings for a print request.846 * @private847 */848 onSettingsInvalid_: function() {849 this.uiState_ = PrintPreview.UiState_.ERROR;850 console.error('Invalid settings error reported from native layer');851 this.previewArea_.showCustomMessage(852 loadTimeData.getString('invalidPrinterSettings'));853 },854 /**855 * Called when the destination settings' change button is activated.856 * Displays the destination search component.857 * @private858 */859 onDestinationChangeButtonActivate_: function() {860 this.destinationSearch_.setIsVisible(true);861 },862 /**863 * Called when the destination settings' change button is activated.864 * Displays the destination search component.865 * @private866 */867 onAdvancedOptionsButtonActivated_: function() {868 this.advancedSettings_.showForDestination(869 assert(this.destinationStore_.selectedDestination));870 },871 /**872 * Called when the destination search dispatches manage cloud destinations873 * event. Calls corresponding native layer method.874 * @private875 */876 onManageCloudDestinationsActivated_: function() {877 this.nativeLayer_.startManageCloudDestinations(this.userInfo_.activeUser);878 },879 /**880 * Called when the destination search dispatches manage local destinations881 * event. Calls corresponding native layer method.882 * @private883 */884 onManageLocalDestinationsActivated_: function() {885 this.nativeLayer_.startManageLocalDestinations();886 },887 /**888 * Called when the user wants to sign in to Google Cloud Print. Calls the889 * corresponding native layer event.890 * @param {boolean} addAccount Whether to open an 'add a new account' or891 * default sign in page.892 * @private893 */894 onCloudPrintSignInActivated_: function(addAccount) {895 this.nativeLayer_.startCloudPrintSignIn(addAccount);896 },897 /**898 * Updates printing options according to source document presets.899 * @param {Event} event Contains options from source document.900 * @private901 */902 onPrintPresetOptionsFromDocument_: function(event) {903 if (event.optionsFromDocument.disableScaling) {904 this.printTicketStore_.fitToPage.updateValue(null);905 this.documentInfo_.updateIsScalingDisabled(true);906 }907 if (event.optionsFromDocument.copies > 0 &&908 this.printTicketStore_.copies.isCapabilityAvailable()) {909 this.printTicketStore_.copies.updateValue(910 event.optionsFromDocument.copies);911 }912 if (event.optionsFromDocument.duplex >= 0 &&913 this.printTicketStore_.duplex.isCapabilityAvailable()) {914 this.printTicketStore_.duplex.updateValue(915 event.optionsFromDocument.duplex);916 }917 },918 /**919 * Called when privet printing fails.920 * @param {Event} event Event object representing the failure.921 * @private922 */923 onPrivetPrintFailed_: function(event) {924 console.error('Privet printing failed with error code ' +925 event.httpError);926 this.printHeader_.setErrorMessage(927 loadTimeData.getString('couldNotPrint'));928 },929 /**930 * Called when the print preview settings need to be changed for testing.931 * @param {Event} event Event object that contains the option that is to932 * be changed and what to set that option.933 * @private934 */935 onManipulateSettingsForTest_: function(event) {936 var settings =937 /** @type {print_preview.PreviewSettings} */(event.settings);938 if ('selectSaveAsPdfDestination' in settings) {939 this.saveAsPdfForTest_(); // No parameters.940 } else if ('layoutSettings' in settings) {941 this.setLayoutSettingsForTest_(settings.layoutSettings.portrait);942 } else if ('pageRange' in settings) {943 this.setPageRangeForTest_(settings.pageRange);944 } else if ('headersAndFooters' in settings) {945 this.setHeadersAndFootersForTest_(settings.headersAndFooters);946 } else if ('backgroundColorsAndImages' in settings) {947 this.setBackgroundColorsAndImagesForTest_(948 settings.backgroundColorsAndImages);949 } else if ('margins' in settings) {950 this.setMarginsForTest_(settings.margins);951 }952 },953 /**954 * Called by onManipulateSettingsForTest_(). Sets the print destination955 * as a pdf.956 * @private957 */958 saveAsPdfForTest_: function() {959 if (this.destinationStore_.selectedDestination &&960 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ==961 this.destinationStore_.selectedDestination.id) {962 this.nativeLayer_.previewReadyForTest();963 return;964 }965 var destinations = this.destinationStore_.destinations();966 var pdfDestination = null;967 for (var i = 0; i < destinations.length; i++) {968 if (destinations[i].id ==969 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {970 pdfDestination = destinations[i];971 break;972 }973 }974 if (pdfDestination)975 this.destinationStore_.selectDestination(pdfDestination);976 else977 this.nativeLayer_.previewFailedForTest();978 },979 /**980 * Called by onManipulateSettingsForTest_(). Sets the layout settings to981 * either portrait or landscape.982 * @param {boolean} portrait Whether to use portrait page layout;983 * if false: landscape.984 * @private985 */986 setLayoutSettingsForTest_: function(portrait) {987 var combobox = document.querySelector('.layout-settings-select');988 if (combobox.value == 'portrait') {989 this.nativeLayer_.previewReadyForTest();990 } else {991 combobox.value = 'landscape';992 this.layoutSettings_.onSelectChange_();993 }994 },995 /**996 * Called by onManipulateSettingsForTest_(). Sets the page range for997 * for the print preview settings.998 * @param {string} pageRange Sets the page range to the desired value(s).999 * Ex: "1-5,9" means pages 1 through 5 and page 9 will be printed.1000 * @private1001 */1002 setPageRangeForTest_: function(pageRange) {1003 var textbox = document.querySelector('.page-settings-custom-input');1004 if (textbox.value == pageRange) {1005 this.nativeLayer_.previewReadyForTest();1006 } else {1007 textbox.value = pageRange;1008 document.querySelector('.page-settings-custom-radio').click();1009 }1010 },1011 /**1012 * Called by onManipulateSettings_(). Checks or unchecks the headers and1013 * footers option on print preview.1014 * @param {boolean} headersAndFooters Whether the "Headers and Footers"1015 * checkbox should be checked.1016 * @private1017 */1018 setHeadersAndFootersForTest_: function(headersAndFooters) {1019 var checkbox = document.querySelector('.header-footer-checkbox');1020 if (headersAndFooters == checkbox.checked)1021 this.nativeLayer_.previewReadyForTest();1022 else1023 checkbox.click();1024 },1025 /**1026 * Called by onManipulateSettings_(). Checks or unchecks the background1027 * colors and images option on print preview.1028 * @param {boolean} backgroundColorsAndImages If true, the checkbox should1029 * be checked. Otherwise it should be unchecked.1030 * @private1031 */1032 setBackgroundColorsAndImagesForTest_: function(backgroundColorsAndImages) {1033 var checkbox = document.querySelector('.css-background-checkbox');1034 if (backgroundColorsAndImages == checkbox.checked)1035 this.nativeLayer_.previewReadyForTest();1036 else1037 checkbox.click();1038 },1039 /**1040 * Called by onManipulateSettings_(). Sets the margin settings1041 * that are desired. Custom margin settings aren't currently supported.1042 * @param {number} margins The desired margins combobox index. Must be1043 * a valid index or else the test fails.1044 * @private1045 */1046 setMarginsForTest_: function(margins) {1047 var combobox = document.querySelector('.margin-settings-select');1048 if (margins == combobox.selectedIndex) {1049 this.nativeLayer_.previewReadyForTest();1050 } else if (margins >= 0 && margins < combobox.length) {1051 combobox.selectedIndex = margins;1052 this.marginSettings_.onSelectChange_();1053 } else {1054 this.nativeLayer_.previewFailedForTest();1055 }1056 },1057 /**1058 * Returns true if "Print using system dialog" link should be shown for1059 * current destination.1060 * @return {boolean} Returns true if link should be shown.1061 */1062 shouldShowSystemDialogLink_: function() {1063 if (cr.isChromeOS || this.hideSystemDialogLink_)1064 return false;1065 if (!cr.isWindows)1066 return true;1067 var selectedDest = this.destinationStore_.selectedDestination;1068 return !!selectedDest &&1069 selectedDest.origin == print_preview.Destination.Origin.LOCAL &&1070 selectedDest.id !=1071 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF;1072 },1073 /**1074 * Called when a print destination is selected. Shows/hides the "Print with1075 * Cloud Print" link in the navbar.1076 * @private1077 */1078 onDestinationSelect_: function() {1079 if ($('system-dialog-link')) {1080 setIsVisible($('system-dialog-link'),1081 this.shouldShowSystemDialogLink_());1082 }1083 if (this.destinationStore_.selectedDestination &&1084 this.isInKioskAutoPrintMode_) {1085 this.onPrintButtonClick_();1086 }1087 },1088 /**1089 * Called when the destination store loads a group of destinations. Shows1090 * a promo on Chrome OS if the user has no print destinations promoting1091 * Google Cloud Print.1092 * @private1093 */1094 onDestinationSearchDone_: function() {1095 var isPromoVisible = cr.isChromeOS &&1096 this.cloudPrintInterface_ &&1097 this.userInfo_.activeUser &&1098 !this.appState_.isGcpPromoDismissed &&1099 !this.destinationStore_.isLocalDestinationSearchInProgress &&1100 !this.destinationStore_.isCloudDestinationSearchInProgress &&1101 this.destinationStore_.hasOnlyDefaultCloudDestinations();1102 setIsVisible(this.getChildElement('#no-destinations-promo'),1103 isPromoVisible);1104 if (isPromoVisible) {1105 new print_preview.GcpPromoMetricsContext().record(1106 print_preview.Metrics.GcpPromoBucket.PROMO_SHOWN);1107 }1108 },1109 /**1110 * Called when the close button on the no-destinations-promotion is clicked.1111 * Hides the promotion.1112 * @private1113 */1114 onNoDestinationsPromoClose_: function() {1115 new print_preview.GcpPromoMetricsContext().record(1116 print_preview.Metrics.GcpPromoBucket.PROMO_CLOSED);1117 setIsVisible(this.getChildElement('#no-destinations-promo'), false);1118 this.appState_.persistIsGcpPromoDismissed(true);1119 },1120 /**1121 * Called when the no-destinations promotion link is clicked. Opens the1122 * Google Cloud Print management page and closes the print preview.1123 * @private1124 */1125 onNoDestinationsPromoClick_: function() {1126 new print_preview.GcpPromoMetricsContext().record(1127 print_preview.Metrics.GcpPromoBucket.PROMO_CLICKED);1128 this.appState_.persistIsGcpPromoDismissed(true);1129 window.open(this.cloudPrintInterface_.baseUrl + '?user=' +1130 this.userInfo_.activeUser + '#printers');1131 this.close_();1132 }1133 };1134 // Export1135 return {1136 PrintPreview: PrintPreview1137 };1138});1139// Pull in all other scripts in a single shot.1140<include src="common/overlay.js">1141<include src="common/search_box.js">1142<include src="common/search_bubble.js">1143<include src="data/page_number_set.js">1144<include src="data/destination.js">1145<include src="data/local_parsers.js">1146<include src="data/cloud_parsers.js">1147<include src="data/destination_store.js">1148<include src="data/invitation.js">1149<include src="data/invitation_store.js">1150<include src="data/margins.js">1151<include src="data/document_info.js">1152<include src="data/printable_area.js">1153<include src="data/measurement_system.js">1154<include src="data/print_ticket_store.js">1155<include src="data/coordinate2d.js">1156<include src="data/size.js">1157<include src="data/capabilities_holder.js">1158<include src="data/user_info.js">1159<include src="data/app_state.js">1160<include src="data/ticket_items/ticket_item.js">1161<include src="data/ticket_items/custom_margins.js">1162<include src="data/ticket_items/collate.js">1163<include src="data/ticket_items/color.js">1164<include src="data/ticket_items/copies.js">1165<include src="data/ticket_items/dpi.js">1166<include src="data/ticket_items/duplex.js">1167<include src="data/ticket_items/header_footer.js">1168<include src="data/ticket_items/media_size.js">1169<include src="data/ticket_items/landscape.js">1170<include src="data/ticket_items/margins_type.js">1171<include src="data/ticket_items/page_range.js">1172<include src="data/ticket_items/fit_to_page.js">1173<include src="data/ticket_items/css_background.js">1174<include src="data/ticket_items/selection_only.js">1175<include src="data/ticket_items/vendor_items.js">1176<include src="native_layer.js">1177<include src="print_preview_animations.js">1178<include src="cloud_print_interface.js">1179<include src="print_preview_utils.js">1180<include src="print_header.js">1181<include src="metrics.js">1182<include src="settings/settings_section.js">1183<include src="settings/settings_section_select.js">1184<include src="settings/page_settings.js">1185<include src="settings/copies_settings.js">1186<include src="settings/dpi_settings.js">1187<include src="settings/media_size_settings.js">1188<include src="settings/layout_settings.js">1189<include src="settings/color_settings.js">1190<include src="settings/margin_settings.js">1191<include src="settings/destination_settings.js">1192<include src="settings/other_options_settings.js">1193<include src="settings/advanced_options_settings.js">1194<include src="settings/advanced_settings/advanced_settings.js">1195<include src="settings/advanced_settings/advanced_settings_item.js">1196<include src="settings/more_settings.js">1197<include src="previewarea/margin_control.js">1198<include src="previewarea/margin_control_container.js">1199<include src="../pdf/pdf_scripting_api.js">1200<include src="previewarea/preview_area.js">1201<include src="preview_generator.js">1202<include src="search/destination_list.js">1203<include src="search/cloud_destination_list.js">1204<include src="search/recent_destination_list.js">1205<include src="search/destination_list_item.js">1206<include src="search/destination_search.js">1207<include src="search/fedex_tos.js">1208<include src="search/provisional_destination_resolver.js">1209window.addEventListener('DOMContentLoaded', function() {1210 printPreview = new print_preview.PrintPreview();1211 printPreview.initialize();...
native_layer.js
Source: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 be3// found in the LICENSE file.4cr.exportPath('print_preview');5/**6 * @typedef {{selectSaveAsPdfDestination: boolean,7 * layoutSettings.portrait: boolean,8 * pageRange: string,9 * headersAndFooters: boolean,10 * backgroundColorsAndImages: boolean,11 * margins: number}}12 * @see chrome/browser/printing/print_preview_pdf_generated_browsertest.cc13 */14print_preview.PreviewSettings;15cr.define('print_preview', function() {16 'use strict';17 /**18 * An interface to the native Chromium printing system layer.19 * @constructor20 * @extends {cr.EventTarget}21 */22 function NativeLayer() {23 cr.EventTarget.call(this);24 // Bind global handlers25 global.setInitialSettings = this.onSetInitialSettings_.bind(this);26 global.setUseCloudPrint = this.onSetUseCloudPrint_.bind(this);27 global.setPrinters = this.onSetPrinters_.bind(this);28 global.updateWithPrinterCapabilities =29 this.onUpdateWithPrinterCapabilities_.bind(this);30 global.failedToGetPrinterCapabilities =31 this.onFailedToGetPrinterCapabilities_.bind(this);32 global.failedToGetPrivetPrinterCapabilities =33 this.onFailedToGetPrivetPrinterCapabilities_.bind(this);34 global.failedToGetExtensionPrinterCapabilities =35 this.onFailedToGetExtensionPrinterCapabilities_.bind(this);36 global.reloadPrintersList = this.onReloadPrintersList_.bind(this);37 global.printToCloud = this.onPrintToCloud_.bind(this);38 global.fileSelectionCancelled =39 this.onFileSelectionCancelled_.bind(this);40 global.fileSelectionCompleted =41 this.onFileSelectionCompleted_.bind(this);42 global.printPreviewFailed = this.onPrintPreviewFailed_.bind(this);43 global.invalidPrinterSettings =44 this.onInvalidPrinterSettings_.bind(this);45 global.onDidGetDefaultPageLayout =46 this.onDidGetDefaultPageLayout_.bind(this);47 global.onDidGetPreviewPageCount =48 this.onDidGetPreviewPageCount_.bind(this);49 global.onDidPreviewPage = this.onDidPreviewPage_.bind(this);50 global.updatePrintPreview = this.onUpdatePrintPreview_.bind(this);51 global.onDidGetAccessToken = this.onDidGetAccessToken_.bind(this);52 global.autoCancelForTesting = this.autoCancelForTesting_.bind(this);53 global.onPrivetPrinterChanged = this.onPrivetPrinterChanged_.bind(this);54 global.onPrivetCapabilitiesSet =55 this.onPrivetCapabilitiesSet_.bind(this);56 global.onPrivetPrintFailed = this.onPrivetPrintFailed_.bind(this);57 global.onExtensionPrintersAdded =58 this.onExtensionPrintersAdded_.bind(this);59 global.onExtensionCapabilitiesSet =60 this.onExtensionCapabilitiesSet_.bind(this);61 global.onEnableManipulateSettingsForTest =62 this.onEnableManipulateSettingsForTest_.bind(this);63 global.printPresetOptionsFromDocument =64 this.onPrintPresetOptionsFromDocument_.bind(this);65 global.onProvisionalPrinterResolved =66 this.onProvisionalDestinationResolved_.bind(this);67 global.failedToResolveProvisionalPrinter =68 this.failedToResolveProvisionalDestination_.bind(this);69 };70 /**71 * Event types dispatched from the Chromium native layer.72 * @enum {string}73 * @const74 */75 NativeLayer.EventType = {76 ACCESS_TOKEN_READY: 'print_preview.NativeLayer.ACCESS_TOKEN_READY',77 CAPABILITIES_SET: 'print_preview.NativeLayer.CAPABILITIES_SET',78 CLOUD_PRINT_ENABLE: 'print_preview.NativeLayer.CLOUD_PRINT_ENABLE',79 DESTINATIONS_RELOAD: 'print_preview.NativeLayer.DESTINATIONS_RELOAD',80 DISABLE_SCALING: 'print_preview.NativeLayer.DISABLE_SCALING',81 FILE_SELECTION_CANCEL: 'print_preview.NativeLayer.FILE_SELECTION_CANCEL',82 FILE_SELECTION_COMPLETE:83 'print_preview.NativeLayer.FILE_SELECTION_COMPLETE',84 GET_CAPABILITIES_FAIL: 'print_preview.NativeLayer.GET_CAPABILITIES_FAIL',85 INITIAL_SETTINGS_SET: 'print_preview.NativeLayer.INITIAL_SETTINGS_SET',86 LOCAL_DESTINATIONS_SET: 'print_preview.NativeLayer.LOCAL_DESTINATIONS_SET',87 MANIPULATE_SETTINGS_FOR_TEST:88 'print_preview.NativeLayer.MANIPULATE_SETTINGS_FOR_TEST',89 PAGE_COUNT_READY: 'print_preview.NativeLayer.PAGE_COUNT_READY',90 PAGE_LAYOUT_READY: 'print_preview.NativeLayer.PAGE_LAYOUT_READY',91 PAGE_PREVIEW_READY: 'print_preview.NativeLayer.PAGE_PREVIEW_READY',92 PREVIEW_GENERATION_DONE:93 'print_preview.NativeLayer.PREVIEW_GENERATION_DONE',94 PREVIEW_GENERATION_FAIL:95 'print_preview.NativeLayer.PREVIEW_GENERATION_FAIL',96 PRINT_TO_CLOUD: 'print_preview.NativeLayer.PRINT_TO_CLOUD',97 SETTINGS_INVALID: 'print_preview.NativeLayer.SETTINGS_INVALID',98 PRIVET_PRINTER_CHANGED: 'print_preview.NativeLayer.PRIVET_PRINTER_CHANGED',99 PRIVET_CAPABILITIES_SET:100 'print_preview.NativeLayer.PRIVET_CAPABILITIES_SET',101 PRIVET_PRINT_FAILED: 'print_preview.NativeLayer.PRIVET_PRINT_FAILED',102 EXTENSION_PRINTERS_ADDED:103 'print_preview.NativeLayer.EXTENSION_PRINTERS_ADDED',104 EXTENSION_CAPABILITIES_SET:105 'print_preview.NativeLayer.EXTENSION_CAPABILITIES_SET',106 PRINT_PRESET_OPTIONS: 'print_preview.NativeLayer.PRINT_PRESET_OPTIONS',107 PROVISIONAL_DESTINATION_RESOLVED:108 'print_preview.NativeLayer.PROVISIONAL_DESTINATION_RESOLVED'109 };110 /**111 * Constant values matching printing::DuplexMode enum.112 * @enum {number}113 */114 NativeLayer.DuplexMode = {115 SIMPLEX: 0,116 LONG_EDGE: 1,117 UNKNOWN_DUPLEX_MODE: -1118 };119 /**120 * Enumeration of color modes used by Chromium.121 * @enum {number}122 * @private123 */124 NativeLayer.ColorMode_ = {125 GRAY: 1,126 COLOR: 2127 };128 /**129 * Version of the serialized state of the print preview.130 * @type {number}131 * @const132 * @private133 */134 NativeLayer.SERIALIZED_STATE_VERSION_ = 1;135 NativeLayer.prototype = {136 __proto__: cr.EventTarget.prototype,137 /**138 * Requests access token for cloud print requests.139 * @param {string} authType type of access token.140 */141 startGetAccessToken: function(authType) {142 chrome.send('getAccessToken', [authType]);143 },144 /** Gets the initial settings to initialize the print preview with. */145 startGetInitialSettings: function() {146 chrome.send('getInitialSettings');147 },148 /**149 * Requests the system's local print destinations. A LOCAL_DESTINATIONS_SET150 * event will be dispatched in response.151 */152 startGetLocalDestinations: function() {153 chrome.send('getPrinters');154 },155 /**156 * Requests the network's privet print destinations. A number of157 * PRIVET_PRINTER_CHANGED events will be fired in response, followed by a158 * PRIVET_SEARCH_ENDED.159 */160 startGetPrivetDestinations: function() {161 chrome.send('getPrivetPrinters');162 },163 /**164 * Requests that the privet print stack stop searching for privet print165 * destinations.166 */167 stopGetPrivetDestinations: function() {168 chrome.send('stopGetPrivetPrinters');169 },170 /**171 * Requests the privet destination's printing capabilities. A172 * PRIVET_CAPABILITIES_SET event will be dispatched in response.173 * @param {string} destinationId ID of the destination.174 */175 startGetPrivetDestinationCapabilities: function(destinationId) {176 chrome.send('getPrivetPrinterCapabilities', [destinationId]);177 },178 /**179 * Requests that extension system dispatches an event requesting the list of180 * extension managed printers.181 */182 startGetExtensionDestinations: function() {183 chrome.send('getExtensionPrinters');184 },185 /**186 * Requests an extension destination's printing capabilities. A187 * EXTENSION_CAPABILITIES_SET event will be dispatched in response.188 * @param {string} destinationId The ID of the destination whose189 * capabilities are requested.190 */191 startGetExtensionDestinationCapabilities: function(destinationId) {192 chrome.send('getExtensionPrinterCapabilities', [destinationId]);193 },194 /**195 * Requests the destination's printing capabilities. A CAPABILITIES_SET196 * event will be dispatched in response.197 * @param {string} destinationId ID of the destination.198 */199 startGetLocalDestinationCapabilities: function(destinationId) {200 chrome.send('getPrinterCapabilities', [destinationId]);201 },202 /**203 * Requests Chrome to resolve provisional extension destination by granting204 * the provider extension access to the printer. Chrome will respond with205 * the resolved destination properties by calling206 * {@code onProvisionalPrinterResolved}, or in case of an error207 * {@code failedToResolveProvisionalPrinter}208 * @param {string} provisionalDestinationId209 */210 grantExtensionPrinterAccess: function(provisionalDestinationId) {211 chrome.send('grantExtensionPrinterAccess', [provisionalDestinationId]);212 },213 /**214 * @param {!print_preview.Destination} destination Destination to print to.215 * @param {!print_preview.ticket_items.Color} color Color ticket item.216 * @return {number} Native layer color model.217 * @private218 */219 getNativeColorModel_: function(destination, color) {220 // For non-local printers native color model is ignored anyway.221 var option = destination.isLocal ? color.getSelectedOption() : null;222 var nativeColorModel = parseInt(option ? option.vendor_id : null, 10);223 if (isNaN(nativeColorModel)) {224 return color.getValue() ?225 NativeLayer.ColorMode_.COLOR : NativeLayer.ColorMode_.GRAY;226 }227 return nativeColorModel;228 },229 /**230 * Requests that a preview be generated. The following events may be231 * dispatched in response:232 * - PAGE_COUNT_READY233 * - PAGE_LAYOUT_READY234 * - PAGE_PREVIEW_READY235 * - PREVIEW_GENERATION_DONE236 * - PREVIEW_GENERATION_FAIL237 * @param {print_preview.Destination} destination Destination to print to.238 * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the239 * state of the print ticket.240 * @param {!print_preview.DocumentInfo} documentInfo Document data model.241 * @param {number} requestId ID of the preview request.242 */243 startGetPreview: function(244 destination, printTicketStore, documentInfo, requestId) {245 assert(printTicketStore.isTicketValidForPreview(),246 'Trying to generate preview when ticket is not valid');247 var ticket = {248 'pageRange': printTicketStore.pageRange.getDocumentPageRanges(),249 'mediaSize': printTicketStore.mediaSize.getValue(),250 'landscape': printTicketStore.landscape.getValue(),251 'color': this.getNativeColorModel_(destination, printTicketStore.color),252 'headerFooterEnabled': printTicketStore.headerFooter.getValue(),253 'marginsType': printTicketStore.marginsType.getValue(),254 'isFirstRequest': requestId == 0,255 'requestID': requestId,256 'previewModifiable': documentInfo.isModifiable,257 'printToPDF':258 destination != null &&259 destination.id ==260 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,261 'printWithCloudPrint': destination != null && !destination.isLocal,262 'printWithPrivet': destination != null && destination.isPrivet,263 'printWithExtension': destination != null && destination.isExtension,264 'deviceName': destination == null ? 'foo' : destination.id,265 'generateDraftData': documentInfo.isModifiable,266 'fitToPageEnabled': printTicketStore.fitToPage.getValue(),267 // NOTE: Even though the following fields don't directly relate to the268 // preview, they still need to be included.269 'duplex': printTicketStore.duplex.getValue() ?270 NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,271 'copies': 1,272 'collate': true,273 'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(),274 'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue()275 };276 // Set 'cloudPrintID' only if the destination is not local.277 if (destination && !destination.isLocal) {278 ticket['cloudPrintID'] = destination.id;279 }280 if (printTicketStore.marginsType.isCapabilityAvailable() &&281 printTicketStore.marginsType.getValue() ==282 print_preview.ticket_items.MarginsType.Value.CUSTOM) {283 var customMargins = printTicketStore.customMargins.getValue();284 var orientationEnum =285 print_preview.ticket_items.CustomMargins.Orientation;286 ticket['marginsCustom'] = {287 'marginTop': customMargins.get(orientationEnum.TOP),288 'marginRight': customMargins.get(orientationEnum.RIGHT),289 'marginBottom': customMargins.get(orientationEnum.BOTTOM),290 'marginLeft': customMargins.get(orientationEnum.LEFT)291 };292 }293 chrome.send(294 'getPreview',295 [JSON.stringify(ticket),296 requestId > 0 ? documentInfo.pageCount : -1,297 documentInfo.isModifiable]);298 },299 /**300 * Requests that the document be printed.301 * @param {!print_preview.Destination} destination Destination to print to.302 * @param {!print_preview.PrintTicketStore} printTicketStore Used to get the303 * state of the print ticket.304 * @param {cloudprint.CloudPrintInterface} cloudPrintInterface Interface305 * to Google Cloud Print.306 * @param {!print_preview.DocumentInfo} documentInfo Document data model.307 * @param {boolean=} opt_isOpenPdfInPreview Whether to open the PDF in the308 * system's preview application.309 * @param {boolean=} opt_showSystemDialog Whether to open system dialog for310 * advanced settings.311 */312 startPrint: function(destination, printTicketStore, cloudPrintInterface,313 documentInfo, opt_isOpenPdfInPreview,314 opt_showSystemDialog) {315 assert(printTicketStore.isTicketValid(),316 'Trying to print when ticket is not valid');317 assert(!opt_showSystemDialog || (cr.isWindows && destination.isLocal),318 'Implemented for Windows only');319 var ticket = {320 'pageRange': printTicketStore.pageRange.getDocumentPageRanges(),321 'mediaSize': printTicketStore.mediaSize.getValue(),322 'pageCount': printTicketStore.pageRange.getPageNumberSet().size,323 'landscape': printTicketStore.landscape.getValue(),324 'color': this.getNativeColorModel_(destination, printTicketStore.color),325 'headerFooterEnabled': printTicketStore.headerFooter.getValue(),326 'marginsType': printTicketStore.marginsType.getValue(),327 'generateDraftData': true, // TODO(rltoscano): What should this be?328 'duplex': printTicketStore.duplex.getValue() ?329 NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,330 'copies': printTicketStore.copies.getValueAsNumber(),331 'collate': printTicketStore.collate.getValue(),332 'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(),333 'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue(),334 'previewModifiable': documentInfo.isModifiable,335 'printToPDF': destination.id ==336 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,337 'printWithCloudPrint': !destination.isLocal,338 'printWithPrivet': destination.isPrivet,339 'printWithExtension': destination.isExtension,340 'deviceName': destination.id,341 'isFirstRequest': false,342 'requestID': -1,343 'fitToPageEnabled': printTicketStore.fitToPage.getValue(),344 'pageWidth': documentInfo.pageSize.width,345 'pageHeight': documentInfo.pageSize.height,346 'showSystemDialog': opt_showSystemDialog347 };348 if (!destination.isLocal) {349 // We can't set cloudPrintID if the destination is "Print with Cloud350 // Print" because the native system will try to print to Google Cloud351 // Print with this ID instead of opening a Google Cloud Print dialog.352 ticket['cloudPrintID'] = destination.id;353 }354 if (printTicketStore.marginsType.isCapabilityAvailable() &&355 printTicketStore.marginsType.isValueEqual(356 print_preview.ticket_items.MarginsType.Value.CUSTOM)) {357 var customMargins = printTicketStore.customMargins.getValue();358 var orientationEnum =359 print_preview.ticket_items.CustomMargins.Orientation;360 ticket['marginsCustom'] = {361 'marginTop': customMargins.get(orientationEnum.TOP),362 'marginRight': customMargins.get(orientationEnum.RIGHT),363 'marginBottom': customMargins.get(orientationEnum.BOTTOM),364 'marginLeft': customMargins.get(orientationEnum.LEFT)365 };366 }367 if (destination.isPrivet || destination.isExtension) {368 ticket['ticket'] = printTicketStore.createPrintTicket(destination);369 ticket['capabilities'] = JSON.stringify(destination.capabilities);370 }371 if (opt_isOpenPdfInPreview) {372 ticket['OpenPDFInPreview'] = true;373 }374 chrome.send('print', [JSON.stringify(ticket)]);375 },376 /** Requests that the current pending print request be cancelled. */377 startCancelPendingPrint: function() {378 chrome.send('cancelPendingPrintRequest');379 },380 /** Shows the system's native printing dialog. */381 startShowSystemDialog: function() {382 assert(!cr.isWindows);383 chrome.send('showSystemDialog');384 },385 /** Closes the print preview dialog. */386 startCloseDialog: function() {387 chrome.send('closePrintPreviewDialog');388 chrome.send('dialogClose');389 },390 /** Hide the print preview dialog and allow the native layer to close it. */391 startHideDialog: function() {392 chrome.send('hidePreview');393 },394 /**395 * Opens the Google Cloud Print sign-in tab. The DESTINATIONS_RELOAD event396 * will be dispatched in response.397 * @param {boolean} addAccount Whether to open an 'add a new account' or398 * default sign in page.399 */400 startCloudPrintSignIn: function(addAccount) {401 chrome.send('signIn', [addAccount]);402 },403 /** Navigates the user to the system printer settings interface. */404 startManageLocalDestinations: function() {405 chrome.send('manageLocalPrinters');406 },407 /**408 * Navigates the user to the Google Cloud Print management page.409 * @param {?string} user Email address of the user to open the management410 * page for (user must be currently logged in, indeed) or {@code null}411 * to open this page for the primary user.412 */413 startManageCloudDestinations: function(user) {414 chrome.send('manageCloudPrinters', [user || '']);415 },416 /** Forces browser to open a new tab with the given URL address. */417 startForceOpenNewTab: function(url) {418 chrome.send('forceOpenNewTab', [url]);419 },420 /**421 * @param {!Object} initialSettings Object containing all initial settings.422 */423 onSetInitialSettings_: function(initialSettings) {424 var numberFormatSymbols =425 print_preview.MeasurementSystem.parseNumberFormat(426 initialSettings['numberFormat']);427 var unitType = print_preview.MeasurementSystem.UnitType.IMPERIAL;428 if (initialSettings['measurementSystem'] != null) {429 unitType = initialSettings['measurementSystem'];430 }431 var nativeInitialSettings = new print_preview.NativeInitialSettings(432 initialSettings['printAutomaticallyInKioskMode'] || false,433 initialSettings['appKioskMode'] || false,434 initialSettings['hidePrintWithSystemDialogLink'] || false,435 numberFormatSymbols[0] || ',',436 numberFormatSymbols[1] || '.',437 unitType,438 initialSettings['previewModifiable'] || false,439 initialSettings['initiatorTitle'] || '',440 initialSettings['documentHasSelection'] || false,441 initialSettings['shouldPrintSelectionOnly'] || false,442 initialSettings['printerName'] || null,443 initialSettings['appState'] || null);444 var initialSettingsSetEvent = new Event(445 NativeLayer.EventType.INITIAL_SETTINGS_SET);446 initialSettingsSetEvent.initialSettings = nativeInitialSettings;447 this.dispatchEvent(initialSettingsSetEvent);448 },449 /**450 * Turn on the integration of Cloud Print.451 * @param {{cloudPrintURL: string, appKioskMode: string}} settings452 * cloudPrintUrl: The URL to use for cloud print servers.453 * @private454 */455 onSetUseCloudPrint_: function(settings) {456 var cloudPrintEnableEvent = new Event(457 NativeLayer.EventType.CLOUD_PRINT_ENABLE);458 cloudPrintEnableEvent.baseCloudPrintUrl = settings['cloudPrintUrl'] || '';459 cloudPrintEnableEvent.appKioskMode = settings['appKioskMode'] || false;460 this.dispatchEvent(cloudPrintEnableEvent);461 },462 /**463 * Updates the print preview with local printers.464 * Called from PrintPreviewHandler::SetupPrinterList().465 * @param {Array} printers Array of printer info objects.466 * @private467 */468 onSetPrinters_: function(printers) {469 var localDestsSetEvent = new Event(470 NativeLayer.EventType.LOCAL_DESTINATIONS_SET);471 localDestsSetEvent.destinationInfos = printers;472 this.dispatchEvent(localDestsSetEvent);473 },474 /**475 * Called when native layer gets settings information for a requested local476 * destination.477 * @param {Object} settingsInfo printer setting information.478 * @private479 */480 onUpdateWithPrinterCapabilities_: function(settingsInfo) {481 var capsSetEvent = new Event(NativeLayer.EventType.CAPABILITIES_SET);482 capsSetEvent.settingsInfo = settingsInfo;483 this.dispatchEvent(capsSetEvent);484 },485 /**486 * Called when native layer gets settings information for a requested local487 * destination.488 * @param {string} destinationId Printer affected by error.489 * @private490 */491 onFailedToGetPrinterCapabilities_: function(destinationId) {492 var getCapsFailEvent = new Event(493 NativeLayer.EventType.GET_CAPABILITIES_FAIL);494 getCapsFailEvent.destinationId = destinationId;495 getCapsFailEvent.destinationOrigin =496 print_preview.Destination.Origin.LOCAL;497 this.dispatchEvent(getCapsFailEvent);498 },499 /**500 * Called when native layer gets settings information for a requested privet501 * destination.502 * @param {string} destinationId Printer affected by error.503 * @private504 */505 onFailedToGetPrivetPrinterCapabilities_: function(destinationId) {506 var getCapsFailEvent = new Event(507 NativeLayer.EventType.GET_CAPABILITIES_FAIL);508 getCapsFailEvent.destinationId = destinationId;509 getCapsFailEvent.destinationOrigin =510 print_preview.Destination.Origin.PRIVET;511 this.dispatchEvent(getCapsFailEvent);512 },513 /**514 * Called when native layer fails to get settings information for a515 * requested extension destination.516 * @param {string} destinationId Printer affected by error.517 * @private518 */519 onFailedToGetExtensionPrinterCapabilities_: function(destinationId) {520 var getCapsFailEvent = new Event(521 NativeLayer.EventType.GET_CAPABILITIES_FAIL);522 getCapsFailEvent.destinationId = destinationId;523 getCapsFailEvent.destinationOrigin =524 print_preview.Destination.Origin.EXTENSION;525 this.dispatchEvent(getCapsFailEvent);526 },527 /** Reloads the printer list. */528 onReloadPrintersList_: function() {529 cr.dispatchSimpleEvent(this, NativeLayer.EventType.DESTINATIONS_RELOAD);530 },531 /**532 * Called from the C++ layer.533 * Take the PDF data handed to us and submit it to the cloud, closing the534 * print preview dialog once the upload is successful.535 * @param {string} data Data to send as the print job.536 * @private537 */538 onPrintToCloud_: function(data) {539 var printToCloudEvent = new Event(540 NativeLayer.EventType.PRINT_TO_CLOUD);541 printToCloudEvent.data = data;542 this.dispatchEvent(printToCloudEvent);543 },544 /**545 * Called from PrintPreviewUI::OnFileSelectionCancelled to notify the print546 * preview dialog regarding the file selection cancel event.547 * @private548 */549 onFileSelectionCancelled_: function() {550 cr.dispatchSimpleEvent(this, NativeLayer.EventType.FILE_SELECTION_CANCEL);551 },552 /**553 * Called from PrintPreviewUI::OnFileSelectionCompleted to notify the print554 * preview dialog regarding the file selection completed event.555 * @private556 */557 onFileSelectionCompleted_: function() {558 // If the file selection is completed and the dialog is not already closed559 // it means that a pending print to pdf request exists.560 cr.dispatchSimpleEvent(561 this, NativeLayer.EventType.FILE_SELECTION_COMPLETE);562 },563 /**564 * Display an error message when print preview fails.565 * Called from PrintPreviewMessageHandler::OnPrintPreviewFailed().566 * @private567 */568 onPrintPreviewFailed_: function() {569 cr.dispatchSimpleEvent(570 this, NativeLayer.EventType.PREVIEW_GENERATION_FAIL);571 },572 /**573 * Display an error message when encountered invalid printer settings.574 * Called from PrintPreviewMessageHandler::OnInvalidPrinterSettings().575 * @private576 */577 onInvalidPrinterSettings_: function() {578 cr.dispatchSimpleEvent(this, NativeLayer.EventType.SETTINGS_INVALID);579 },580 /**581 * @param {{contentWidth: number, contentHeight: number, marginLeft: number,582 * marginRight: number, marginTop: number, marginBottom: number,583 * printableAreaX: number, printableAreaY: number,584 * printableAreaWidth: number, printableAreaHeight: number}}585 * pageLayout Specifies default page layout details in points.586 * @param {boolean} hasCustomPageSizeStyle Indicates whether the previewed587 * document has a custom page size style.588 * @private589 */590 onDidGetDefaultPageLayout_: function(pageLayout, hasCustomPageSizeStyle) {591 var pageLayoutChangeEvent = new Event(592 NativeLayer.EventType.PAGE_LAYOUT_READY);593 pageLayoutChangeEvent.pageLayout = pageLayout;594 pageLayoutChangeEvent.hasCustomPageSizeStyle = hasCustomPageSizeStyle;595 this.dispatchEvent(pageLayoutChangeEvent);596 },597 /**598 * Update the page count and check the page range.599 * Called from PrintPreviewUI::OnDidGetPreviewPageCount().600 * @param {number} pageCount The number of pages.601 * @param {number} previewResponseId The preview request id that resulted in602 * this response.603 * @private604 */605 onDidGetPreviewPageCount_: function(pageCount, previewResponseId) {606 var pageCountChangeEvent = new Event(607 NativeLayer.EventType.PAGE_COUNT_READY);608 pageCountChangeEvent.pageCount = pageCount;609 pageCountChangeEvent.previewResponseId = previewResponseId;610 this.dispatchEvent(pageCountChangeEvent);611 },612 /**613 * Notification that a print preview page has been rendered.614 * Check if the settings have changed and request a regeneration if needed.615 * Called from PrintPreviewUI::OnDidPreviewPage().616 * @param {number} pageNumber The page number, 0-based.617 * @param {number} previewUid Preview unique identifier.618 * @param {number} previewResponseId The preview request id that resulted in619 * this response.620 * @private621 */622 onDidPreviewPage_: function(pageNumber, previewUid, previewResponseId) {623 var pagePreviewGenEvent = new Event(624 NativeLayer.EventType.PAGE_PREVIEW_READY);625 pagePreviewGenEvent.pageIndex = pageNumber;626 pagePreviewGenEvent.previewUid = previewUid;627 pagePreviewGenEvent.previewResponseId = previewResponseId;628 this.dispatchEvent(pagePreviewGenEvent);629 },630 /**631 * Notification that access token is ready.632 * @param {string} authType Type of access token.633 * @param {string} accessToken Access token.634 * @private635 */636 onDidGetAccessToken_: function(authType, accessToken) {637 var getAccessTokenEvent = new Event(638 NativeLayer.EventType.ACCESS_TOKEN_READY);639 getAccessTokenEvent.authType = authType;640 getAccessTokenEvent.accessToken = accessToken;641 this.dispatchEvent(getAccessTokenEvent);642 },643 /**644 * Update the print preview when new preview data is available.645 * Create the PDF plugin as needed.646 * Called from PrintPreviewUI::PreviewDataIsAvailable().647 * @param {number} previewUid Preview unique identifier.648 * @param {number} previewResponseId The preview request id that resulted in649 * this response.650 * @private651 */652 onUpdatePrintPreview_: function(previewUid, previewResponseId) {653 var previewGenDoneEvent = new Event(654 NativeLayer.EventType.PREVIEW_GENERATION_DONE);655 previewGenDoneEvent.previewUid = previewUid;656 previewGenDoneEvent.previewResponseId = previewResponseId;657 this.dispatchEvent(previewGenDoneEvent);658 },659 /**660 * Updates print preset options from source PDF document.661 * Called from PrintPreviewUI::OnSetOptionsFromDocument().662 * @param {{disableScaling: boolean, copies: number,663 * duplex: number}} options Specifies664 * printing options according to source document presets.665 * @private666 */667 onPrintPresetOptionsFromDocument_: function(options) {668 var printPresetOptionsEvent = new Event(669 NativeLayer.EventType.PRINT_PRESET_OPTIONS);670 printPresetOptionsEvent.optionsFromDocument = options;671 this.dispatchEvent(printPresetOptionsEvent);672 },673 /**674 * Simulates a user click on the print preview dialog cancel button. Used675 * only for testing.676 * @private677 */678 autoCancelForTesting_: function() {679 var properties = {view: window, bubbles: true, cancelable: true};680 var click = new MouseEvent('click', properties);681 document.querySelector('#print-header .cancel').dispatchEvent(click);682 },683 /**684 * @param {{serviceName: string, name: string}} printer Specifies685 * information about the printer that was added.686 * @private687 */688 onPrivetPrinterChanged_: function(printer) {689 var privetPrinterChangedEvent =690 new Event(NativeLayer.EventType.PRIVET_PRINTER_CHANGED);691 privetPrinterChangedEvent.printer = printer;692 this.dispatchEvent(privetPrinterChangedEvent);693 },694 /**695 * @param {Object} printer Specifies information about the printer that was696 * added.697 * @private698 */699 onPrivetCapabilitiesSet_: function(printer, capabilities) {700 var privetCapabilitiesSetEvent =701 new Event(NativeLayer.EventType.PRIVET_CAPABILITIES_SET);702 privetCapabilitiesSetEvent.printer = printer;703 privetCapabilitiesSetEvent.capabilities = capabilities;704 this.dispatchEvent(privetCapabilitiesSetEvent);705 },706 /**707 * @param {string} http_error The HTTP response code or -1 if not an HTTP708 * error.709 * @private710 */711 onPrivetPrintFailed_: function(http_error) {712 var privetPrintFailedEvent =713 new Event(NativeLayer.EventType.PRIVET_PRINT_FAILED);714 privetPrintFailedEvent.httpError = http_error;715 this.dispatchEvent(privetPrintFailedEvent);716 },717 /**718 * @param {Array<!{extensionId: string,719 * extensionName: string,720 * id: string,721 * name: string,722 * description: (string|undefined),723 * provisional: (boolean|undefined)}>} printers The list724 * containing information about printers added by an extension.725 * @param {boolean} done Whether this is the final list of extension726 * managed printers.727 */728 onExtensionPrintersAdded_: function(printers, done) {729 var event = new Event(NativeLayer.EventType.EXTENSION_PRINTERS_ADDED);730 event.printers = printers;731 event.done = done;732 this.dispatchEvent(event);733 },734 /**735 * Called when an extension responds to a request for an extension printer736 * capabilities.737 * @param {string} printerId The printer's ID.738 * @param {!Object} capabilities The reported printer capabilities.739 */740 onExtensionCapabilitiesSet_: function(printerId,741 capabilities) {742 var event = new Event(NativeLayer.EventType.EXTENSION_CAPABILITIES_SET);743 event.printerId = printerId;744 event.capabilities = capabilities;745 this.dispatchEvent(event);746 },747 /**748 * Called when Chrome reports that attempt to resolve a provisional749 * destination failed.750 * @param {string} destinationId The provisional destination ID.751 * @private752 */753 failedToResolveProvisionalDestination_: function(destinationId) {754 var evt = new Event(755 NativeLayer.EventType.PROVISIONAL_DESTINATION_RESOLVED);756 evt.provisionalId = destinationId;757 evt.destination = null;758 this.dispatchEvent(evt);759 },760 /**761 * Called when Chrome reports that a provisional destination has been762 * successfully resolved.763 * Currently used only for extension provided destinations.764 * @param {string} provisionalDestinationId The provisional destination id.765 * @param {!{extensionId: string,766 * extensionName: string,767 * id: string,768 * name: string,769 * description: (string|undefined)}} destinationInfo The resolved770 * destination info.771 * @private772 */773 onProvisionalDestinationResolved_: function(provisionalDestinationId,774 destinationInfo) {775 var evt = new Event(776 NativeLayer.EventType.PROVISIONAL_DESTINATION_RESOLVED);777 evt.provisionalId = provisionalDestinationId;778 evt.destination = destinationInfo;779 this.dispatchEvent(evt);780 },781 /**782 * Allows for onManipulateSettings to be called783 * from the native layer.784 * @private785 */786 onEnableManipulateSettingsForTest_: function() {787 global.onManipulateSettingsForTest =788 this.onManipulateSettingsForTest_.bind(this);789 },790 /**791 * Dispatches an event to print_preview.js to change792 * a particular setting for print preview.793 * @param {!print_preview.PreviewSettings} settings Object containing the794 * value to be changed and that value should be set to.795 * @private796 */797 onManipulateSettingsForTest_: function(settings) {798 var manipulateSettingsEvent =799 new Event(NativeLayer.EventType.MANIPULATE_SETTINGS_FOR_TEST);800 manipulateSettingsEvent.settings = settings;801 this.dispatchEvent(manipulateSettingsEvent);802 },803 /**804 * Sends a message to the test, letting it know that an805 * option has been set to a particular value and that the change has806 * finished modifying the preview area.807 */808 previewReadyForTest: function() {809 if (global.onManipulateSettingsForTest)810 chrome.send('UILoadedForTest');811 },812 /**813 * Notifies the test that the option it tried to change814 * had not been changed successfully.815 */816 previewFailedForTest: function() {817 if (global.onManipulateSettingsForTest)818 chrome.send('UIFailedLoadingForTest');819 }820 };821 /**822 * Initial settings retrieved from the native layer.823 * @param {boolean} isInKioskAutoPrintMode Whether the print preview should be824 * in auto-print mode.825 * @param {boolean} isInAppKioskMode Whether the print preview is in App Kiosk826 * mode.827 * @param {string} thousandsDelimeter Character delimeter of thousands digits.828 * @param {string} decimalDelimeter Character delimeter of the decimal point.829 * @param {!print_preview.MeasurementSystem.UnitType} unitType Unit type of830 * local machine's measurement system.831 * @param {boolean} isDocumentModifiable Whether the document to print is832 * modifiable.833 * @param {string} documentTitle Title of the document.834 * @param {boolean} documentHasSelection Whether the document has selected835 * content.836 * @param {boolean} selectionOnly Whether only selected content should be837 * printed.838 * @param {?string} systemDefaultDestinationId ID of the system default839 * destination.840 * @param {?string} serializedAppStateStr Serialized app state.841 * @constructor842 */843 function NativeInitialSettings(844 isInKioskAutoPrintMode,845 isInAppKioskMode,846 hidePrintWithSystemDialogLink,847 thousandsDelimeter,848 decimalDelimeter,849 unitType,850 isDocumentModifiable,851 documentTitle,852 documentHasSelection,853 selectionOnly,854 systemDefaultDestinationId,855 serializedAppStateStr) {856 /**857 * Whether the print preview should be in auto-print mode.858 * @type {boolean}859 * @private860 */861 this.isInKioskAutoPrintMode_ = isInKioskAutoPrintMode;862 /**863 * Whether the print preview should switch to App Kiosk mode.864 * @type {boolean}865 * @private866 */867 this.isInAppKioskMode_ = isInAppKioskMode;868 /**869 * Whether we should hide the link which shows the system print dialog.870 * @type {boolean}871 * @private872 */873 this.hidePrintWithSystemDialogLink_ = hidePrintWithSystemDialogLink;874 /**875 * Character delimeter of thousands digits.876 * @type {string}877 * @private878 */879 this.thousandsDelimeter_ = thousandsDelimeter;880 /**881 * Character delimeter of the decimal point.882 * @type {string}883 * @private884 */885 this.decimalDelimeter_ = decimalDelimeter;886 /**887 * Unit type of local machine's measurement system.888 * @type {string}889 * @private890 */891 this.unitType_ = unitType;892 /**893 * Whether the document to print is modifiable.894 * @type {boolean}895 * @private896 */897 this.isDocumentModifiable_ = isDocumentModifiable;898 /**899 * Title of the document.900 * @type {string}901 * @private902 */903 this.documentTitle_ = documentTitle;904 /**905 * Whether the document has selection.906 * @type {string}907 * @private908 */909 this.documentHasSelection_ = documentHasSelection;910 /**911 * Whether selection only should be printed.912 * @type {string}913 * @private914 */915 this.selectionOnly_ = selectionOnly;916 /**917 * ID of the system default destination.918 * @type {?string}919 * @private920 */921 this.systemDefaultDestinationId_ = systemDefaultDestinationId;922 /**923 * Serialized app state.924 * @type {?string}925 * @private926 */927 this.serializedAppStateStr_ = serializedAppStateStr;928 };929 NativeInitialSettings.prototype = {930 /**931 * @return {boolean} Whether the print preview should be in auto-print mode.932 */933 get isInKioskAutoPrintMode() {934 return this.isInKioskAutoPrintMode_;935 },936 /**937 * @return {boolean} Whether the print preview should switch to App Kiosk938 * mode.939 */940 get isInAppKioskMode() {941 return this.isInAppKioskMode_;942 },943 /**944 * @return {boolean} Whether we should hide the link which shows the945 system print dialog.946 */947 get hidePrintWithSystemDialogLink() {948 return this.hidePrintWithSystemDialogLink_;949 },950 /** @return {string} Character delimeter of thousands digits. */951 get thousandsDelimeter() {952 return this.thousandsDelimeter_;953 },954 /** @return {string} Character delimeter of the decimal point. */955 get decimalDelimeter() {956 return this.decimalDelimeter_;957 },958 /**959 * @return {!print_preview.MeasurementSystem.UnitType} Unit type of local960 * machine's measurement system.961 */962 get unitType() {963 return this.unitType_;964 },965 /** @return {boolean} Whether the document to print is modifiable. */966 get isDocumentModifiable() {967 return this.isDocumentModifiable_;968 },969 /** @return {string} Document title. */970 get documentTitle() {971 return this.documentTitle_;972 },973 /** @return {boolean} Whether the document has selection. */974 get documentHasSelection() {975 return this.documentHasSelection_;976 },977 /** @return {boolean} Whether selection only should be printed. */978 get selectionOnly() {979 return this.selectionOnly_;980 },981 /** @return {?string} ID of the system default destination. */982 get systemDefaultDestinationId() {983 return this.systemDefaultDestinationId_;984 },985 /** @return {?string} Serialized app state. */986 get serializedAppStateStr() {987 return this.serializedAppStateStr_;988 }989 };990 // Export991 return {992 NativeInitialSettings: NativeInitialSettings,993 NativeLayer: NativeLayer994 };...
print_ticket_store.js
Source:print_ticket_store.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 be3// found in the LICENSE file.4cr.define('print_preview', function() {5 'use strict';6 // TODO(rltoscano): Maybe clear print ticket when destination changes. Or7 // better yet, carry over any print ticket state that is possible. I.e. if8 // destination changes, the new destination might not support duplex anymore,9 // so we should clear the ticket's isDuplexEnabled state.10 /**11 * Storage of the print ticket and document statistics. Dispatches events when12 * the contents of the print ticket or document statistics change. Also13 * handles validation of the print ticket against destination capabilities and14 * against the document.15 * @param {!print_preview.DestinationStore} destinationStore Used to16 * understand which printer is selected.17 * @param {!print_preview.AppState} appState Print preview application state.18 * @param {!print_preview.DocumentInfo} documentInfo Document data model.19 * @constructor20 * @extends {cr.EventTarget}21 */22 function PrintTicketStore(destinationStore, appState, documentInfo) {23 cr.EventTarget.call(this);24 /**25 * Destination store used to understand which printer is selected.26 * @type {!print_preview.DestinationStore}27 * @private28 */29 this.destinationStore_ = destinationStore;30 /**31 * App state used to persist and load ticket values.32 * @type {!print_preview.AppState}33 * @private34 */35 this.appState_ = appState;36 /**37 * Information about the document to print.38 * @type {!print_preview.DocumentInfo}39 * @private40 */41 this.documentInfo_ = documentInfo;42 /**43 * Printing capabilities of Chromium and the currently selected destination.44 * @type {!print_preview.CapabilitiesHolder}45 * @private46 */47 this.capabilitiesHolder_ = new print_preview.CapabilitiesHolder();48 /**49 * Current measurement system. Used to work with margin measurements.50 * @type {!print_preview.MeasurementSystem}51 * @private52 */53 this.measurementSystem_ = new print_preview.MeasurementSystem(54 ',', '.', print_preview.MeasurementSystem.UnitType.IMPERIAL);55 /**56 * Collate ticket item.57 * @type {!print_preview.ticket_items.Collate}58 * @private59 */60 this.collate_ = new print_preview.ticket_items.Collate(61 this.appState_, this.destinationStore_);62 /**63 * Color ticket item.64 * @type {!print_preview.ticket_items.Color}65 * @private66 */67 this.color_ = new print_preview.ticket_items.Color(68 this.appState_, this.destinationStore_);69 /**70 * Copies ticket item.71 * @type {!print_preview.ticket_items.Copies}72 * @private73 */74 this.copies_ =75 new print_preview.ticket_items.Copies(this.destinationStore_);76 /**77 * DPI ticket item.78 * @type {!print_preview.ticket_items.Dpi}79 * @private80 */81 this.dpi_ = new print_preview.ticket_items.Dpi(82 this.appState_, this.destinationStore_);83 /**84 * Duplex ticket item.85 * @type {!print_preview.ticket_items.Duplex}86 * @private87 */88 this.duplex_ = new print_preview.ticket_items.Duplex(89 this.appState_, this.destinationStore_);90 /**91 * Page range ticket item.92 * @type {!print_preview.ticket_items.PageRange}93 * @private94 */95 this.pageRange_ =96 new print_preview.ticket_items.PageRange(this.documentInfo_);97 /**98 * Custom margins ticket item.99 * @type {!print_preview.ticket_items.CustomMargins}100 * @private101 */102 this.customMargins_ = new print_preview.ticket_items.CustomMargins(103 this.appState_, this.documentInfo_);104 /**105 * Margins type ticket item.106 * @type {!print_preview.ticket_items.MarginsType}107 * @private108 */109 this.marginsType_ = new print_preview.ticket_items.MarginsType(110 this.appState_, this.documentInfo_, this.customMargins_);111 /**112 * Media size ticket item.113 * @type {!print_preview.ticket_items.MediaSize}114 * @private115 */116 this.mediaSize_ = new print_preview.ticket_items.MediaSize(117 this.appState_,118 this.destinationStore_,119 this.documentInfo_,120 this.marginsType_,121 this.customMargins_);122 /**123 * Landscape ticket item.124 * @type {!print_preview.ticket_items.Landscape}125 * @private126 */127 this.landscape_ = new print_preview.ticket_items.Landscape(128 this.appState_,129 this.destinationStore_,130 this.documentInfo_,131 this.marginsType_,132 this.customMargins_);133 /**134 * Header-footer ticket item.135 * @type {!print_preview.ticket_items.HeaderFooter}136 * @private137 */138 this.headerFooter_ = new print_preview.ticket_items.HeaderFooter(139 this.appState_,140 this.documentInfo_,141 this.marginsType_,142 this.customMargins_);143 /**144 * Fit-to-page ticket item.145 * @type {!print_preview.ticket_items.FitToPage}146 * @private147 */148 this.fitToPage_ = new print_preview.ticket_items.FitToPage(149 this.documentInfo_, this.destinationStore_);150 /**151 * Print CSS backgrounds ticket item.152 * @type {!print_preview.ticket_items.CssBackground}153 * @private154 */155 this.cssBackground_ = new print_preview.ticket_items.CssBackground(156 this.appState_, this.documentInfo_);157 /**158 * Print selection only ticket item.159 * @type {!print_preview.ticket_items.SelectionOnly}160 * @private161 */162 this.selectionOnly_ =163 new print_preview.ticket_items.SelectionOnly(this.documentInfo_);164 /**165 * Vendor ticket items.166 * @type {!print_preview.ticket_items.VendorItems}167 * @private168 */169 this.vendorItems_ = new print_preview.ticket_items.VendorItems(170 this.appState_, this.destinationStore_);171 /**172 * Keeps track of event listeners for the print ticket store.173 * @type {!EventTracker}174 * @private175 */176 this.tracker_ = new EventTracker();177 /**178 * Whether the print preview has been initialized.179 * @type {boolean}180 * @private181 */182 this.isInitialized_ = false;183 this.addEventListeners_();184 };185 /**186 * Event types dispatched by the print ticket store.187 * @enum {string}188 */189 PrintTicketStore.EventType = {190 CAPABILITIES_CHANGE: 'print_preview.PrintTicketStore.CAPABILITIES_CHANGE',191 DOCUMENT_CHANGE: 'print_preview.PrintTicketStore.DOCUMENT_CHANGE',192 INITIALIZE: 'print_preview.PrintTicketStore.INITIALIZE',193 TICKET_CHANGE: 'print_preview.PrintTicketStore.TICKET_CHANGE'194 };195 PrintTicketStore.prototype = {196 __proto__: cr.EventTarget.prototype,197 /**198 * Whether the print preview has been initialized.199 * @type {boolean}200 */201 get isInitialized() {202 return this.isInitialized_;203 },204 get collate() {205 return this.collate_;206 },207 get color() {208 return this.color_;209 },210 get copies() {211 return this.copies_;212 },213 get cssBackground() {214 return this.cssBackground_;215 },216 get customMargins() {217 return this.customMargins_;218 },219 get dpi() {220 return this.dpi_;221 },222 get duplex() {223 return this.duplex_;224 },225 get fitToPage() {226 return this.fitToPage_;227 },228 get headerFooter() {229 return this.headerFooter_;230 },231 get mediaSize() {232 return this.mediaSize_;233 },234 get landscape() {235 return this.landscape_;236 },237 get marginsType() {238 return this.marginsType_;239 },240 get pageRange() {241 return this.pageRange_;242 },243 get selectionOnly() {244 return this.selectionOnly_;245 },246 get vendorItems() {247 return this.vendorItems_;248 },249 /**250 * @return {!print_preview.MeasurementSystem} Measurement system of the251 * local system.252 */253 get measurementSystem() {254 return this.measurementSystem_;255 },256 /**257 * Initializes the print ticket store. Dispatches an INITIALIZE event.258 * @param {string} thousandsDelimeter Delimeter of the thousands place.259 * @param {string} decimalDelimeter Delimeter of the decimal point.260 * @param {!print_preview.MeasurementSystem.UnitType} unitType Type of unit261 * of the local measurement system.262 * @param {boolean} selectionOnly Whether only selected content should be263 * printed.264 */265 init: function(266 thousandsDelimeter, decimalDelimeter, unitType, selectionOnly) {267 this.measurementSystem_.setSystem(thousandsDelimeter, decimalDelimeter,268 unitType);269 this.selectionOnly_.updateValue(selectionOnly);270 // Initialize ticket with user's previous values.271 if (this.appState_.hasField(272 print_preview.AppState.Field.IS_COLOR_ENABLED)) {273 this.color_.updateValue(274 /** @type {!Object} */(this.appState_.getField(275 print_preview.AppState.Field.IS_COLOR_ENABLED)));276 }277 if (this.appState_.hasField(print_preview.AppState.Field.DPI)) {278 this.dpi_.updateValue(279 /** @type {!Object} */(this.appState_.getField(280 print_preview.AppState.Field.DPI)));281 }282 if (this.appState_.hasField(283 print_preview.AppState.Field.IS_DUPLEX_ENABLED)) {284 this.duplex_.updateValue(285 /** @type {!Object} */(this.appState_.getField(286 print_preview.AppState.Field.IS_DUPLEX_ENABLED)));287 }288 if (this.appState_.hasField(print_preview.AppState.Field.MEDIA_SIZE)) {289 this.mediaSize_.updateValue(290 /** @type {!Object} */(this.appState_.getField(291 print_preview.AppState.Field.MEDIA_SIZE)));292 }293 if (this.appState_.hasField(294 print_preview.AppState.Field.IS_LANDSCAPE_ENABLED)) {295 this.landscape_.updateValue(296 /** @type {!Object} */(this.appState_.getField(297 print_preview.AppState.Field.IS_LANDSCAPE_ENABLED)));298 }299 // Initialize margins after landscape because landscape may reset margins.300 if (this.appState_.hasField(print_preview.AppState.Field.MARGINS_TYPE)) {301 this.marginsType_.updateValue(302 /** @type {!Object} */(this.appState_.getField(303 print_preview.AppState.Field.MARGINS_TYPE)));304 }305 if (this.appState_.hasField(306 print_preview.AppState.Field.CUSTOM_MARGINS)) {307 this.customMargins_.updateValue(308 /** @type {!Object} */(this.appState_.getField(309 print_preview.AppState.Field.CUSTOM_MARGINS)));310 }311 if (this.appState_.hasField(312 print_preview.AppState.Field.IS_HEADER_FOOTER_ENABLED)) {313 this.headerFooter_.updateValue(314 /** @type {!Object} */(this.appState_.getField(315 print_preview.AppState.Field.IS_HEADER_FOOTER_ENABLED)));316 }317 if (this.appState_.hasField(318 print_preview.AppState.Field.IS_COLLATE_ENABLED)) {319 this.collate_.updateValue(320 /** @type {!Object} */(this.appState_.getField(321 print_preview.AppState.Field.IS_COLLATE_ENABLED)));322 }323 if (this.appState_.hasField(324 print_preview.AppState.Field.IS_CSS_BACKGROUND_ENABLED)) {325 this.cssBackground_.updateValue(326 /** @type {!Object} */(this.appState_.getField(327 print_preview.AppState.Field.IS_CSS_BACKGROUND_ENABLED)));328 }329 if (this.appState_.hasField(330 print_preview.AppState.Field.VENDOR_OPTIONS)) {331 this.vendorItems_.updateValue(332 /** @type {!Object<string>} */(this.appState_.getField(333 print_preview.AppState.Field.VENDOR_OPTIONS)));334 }335 },336 /**337 * @return {boolean} {@code true} if the stored print ticket is valid,338 * {@code false} otherwise.339 */340 isTicketValid: function() {341 return this.isTicketValidForPreview() &&342 (!this.copies_.isCapabilityAvailable() || this.copies_.isValid()) &&343 (!this.pageRange_.isCapabilityAvailable() ||344 this.pageRange_.isValid());345 },346 /** @return {boolean} Whether the ticket is valid for preview generation. */347 isTicketValidForPreview: function() {348 return (!this.marginsType_.isCapabilityAvailable() ||349 !this.marginsType_.isValueEqual(350 print_preview.ticket_items.MarginsType.Value.CUSTOM) ||351 this.customMargins_.isValid());352 },353 /**354 * Creates an object that represents a Google Cloud Print print ticket.355 * @param {!print_preview.Destination} destination Destination to print to.356 * @return {!Object} Google Cloud Print print ticket.357 */358 createPrintTicket: function(destination) {359 assert(!destination.isLocal ||360 destination.isPrivet || destination.isExtension,361 'Trying to create a Google Cloud Print print ticket for a local ' +362 ' non-privet and non-extension destination');363 assert(destination.capabilities,364 'Trying to create a Google Cloud Print print ticket for a ' +365 'destination with no print capabilities');366 var cjt = {367 version: '1.0',368 print: {}369 };370 if (this.collate.isCapabilityAvailable() && this.collate.isUserEdited()) {371 cjt.print.collate = {collate: this.collate.getValue()};372 }373 if (this.color.isCapabilityAvailable() && this.color.isUserEdited()) {374 var selectedOption = this.color.getSelectedOption();375 if (!selectedOption) {376 console.error('Could not find correct color option');377 } else {378 cjt.print.color = {type: selectedOption.type};379 if (selectedOption.hasOwnProperty('vendor_id')) {380 cjt.print.color.vendor_id = selectedOption.vendor_id;381 }382 }383 }384 if (this.copies.isCapabilityAvailable() && this.copies.isUserEdited()) {385 cjt.print.copies = {copies: this.copies.getValueAsNumber()};386 }387 if (this.duplex.isCapabilityAvailable() && this.duplex.isUserEdited()) {388 cjt.print.duplex =389 {type: this.duplex.getValue() ? 'LONG_EDGE' : 'NO_DUPLEX'};390 }391 if (this.mediaSize.isCapabilityAvailable()) {392 var value = this.mediaSize.getValue();393 cjt.print.media_size = {394 width_microns: value.width_microns,395 height_microns: value.height_microns,396 is_continuous_feed: value.is_continuous_feed,397 vendor_id: value.vendor_id398 };399 }400 if (!this.landscape.isCapabilityAvailable()) {401 // In this case "orientation" option is hidden from user, so user can't402 // adjust it for page content, see Landscape.isCapabilityAvailable().403 // We can improve results if we set AUTO here.404 if (this.landscape.hasOption('AUTO'))405 cjt.print.page_orientation = { type: 'AUTO' };406 } else if (this.landscape.isUserEdited()) {407 cjt.print.page_orientation =408 {type: this.landscape.getValue() ? 'LANDSCAPE' : 'PORTRAIT'};409 }410 if (this.dpi.isCapabilityAvailable()) {411 var value = this.dpi.getValue();412 cjt.print.dpi = {413 horizontal_dpi: value.horizontal_dpi,414 vertical_dpi: value.vertical_dpi,415 vendor_id: value.vendor_id416 };417 }418 if (this.vendorItems.isCapabilityAvailable() &&419 this.vendorItems.isUserEdited()) {420 var items = this.vendorItems.ticketItems;421 cjt.print.vendor_ticket_item = [];422 for (var itemId in items) {423 if (items.hasOwnProperty(itemId)) {424 cjt.print.vendor_ticket_item.push(425 {id: itemId, value: items[itemId]});426 }427 }428 }429 return JSON.stringify(cjt);430 },431 /**432 * Adds event listeners for the print ticket store.433 * @private434 */435 addEventListeners_: function() {436 this.tracker_.add(437 this.destinationStore_,438 print_preview.DestinationStore.EventType.DESTINATION_SELECT,439 this.onDestinationSelect_.bind(this));440 this.tracker_.add(441 this.destinationStore_,442 print_preview.DestinationStore.EventType.443 SELECTED_DESTINATION_CAPABILITIES_READY,444 this.onSelectedDestinationCapabilitiesReady_.bind(this));445 this.tracker_.add(446 this.destinationStore_,447 print_preview.DestinationStore.EventType.448 CACHED_SELECTED_DESTINATION_INFO_READY,449 this.onSelectedDestinationCapabilitiesReady_.bind(this));450 // TODO(rltoscano): Print ticket store shouldn't be re-dispatching these451 // events, the consumers of the print ticket store events should listen452 // for the events from document info instead. Will move this when453 // consumers are all migrated.454 this.tracker_.add(455 this.documentInfo_,456 print_preview.DocumentInfo.EventType.CHANGE,457 this.onDocumentInfoChange_.bind(this));458 },459 /**460 * Called when the destination selected.461 * @private462 */463 onDestinationSelect_: function() {464 // Reset user selection for certain ticket items.465 if (this.capabilitiesHolder_.get() != null) {466 this.customMargins_.updateValue(null);467 if (this.marginsType_.getValue() ==468 print_preview.ticket_items.MarginsType.Value.CUSTOM) {469 this.marginsType_.updateValue(470 print_preview.ticket_items.MarginsType.Value.DEFAULT);471 }472 this.vendorItems_.updateValue({});473 }474 },475 /**476 * Called when the capabilities of the selected destination are ready.477 * @private478 */479 onSelectedDestinationCapabilitiesReady_: function() {480 var caps = assert(481 this.destinationStore_.selectedDestination.capabilities);482 var isFirstUpdate = this.capabilitiesHolder_.get() == null;483 this.capabilitiesHolder_.set(caps);484 if (isFirstUpdate) {485 this.isInitialized_ = true;486 cr.dispatchSimpleEvent(this, PrintTicketStore.EventType.INITIALIZE);487 } else {488 cr.dispatchSimpleEvent(489 this, PrintTicketStore.EventType.CAPABILITIES_CHANGE);490 }491 },492 /**493 * Called when document data model has changed. Dispatches a print ticket494 * store event.495 * @private496 */497 onDocumentInfoChange_: function() {498 cr.dispatchSimpleEvent(this, PrintTicketStore.EventType.DOCUMENT_CHANGE);499 },500 };501 // Export502 return {503 PrintTicketStore: PrintTicketStore504 };...
print_header.js
Source:print_header.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 be3// found in the LICENSE file.4cr.define('print_preview', function() {5 'use strict';6 /**7 * Creates a PrintHeader object. This object encapsulates all the elements8 * and logic related to the top part of the left pane in print_preview.html.9 * @param {!print_preview.PrintTicketStore} printTicketStore Used to read10 * information about the document.11 * @param {!print_preview.DestinationStore} destinationStore Used to get the12 * selected destination.13 * @constructor14 * @extends {print_preview.Component}15 */16 function PrintHeader(printTicketStore, destinationStore) {17 print_preview.Component.call(this);18 /**19 * Used to read information about the document.20 * @type {!print_preview.PrintTicketStore}21 * @private22 */23 this.printTicketStore_ = printTicketStore;24 /**25 * Used to get the selected destination.26 * @type {!print_preview.DestinationStore}27 * @private28 */29 this.destinationStore_ = destinationStore;30 /**31 * Whether the component is enabled.32 * @type {boolean}33 * @private34 */35 this.isEnabled_ = true;36 /**37 * Whether the print button is enabled.38 * @type {boolean}39 * @private40 */41 this.isPrintButtonEnabled_ = true;42 };43 /**44 * Event types dispatched by the print header.45 * @enum {string}46 */47 PrintHeader.EventType = {48 PRINT_BUTTON_CLICK: 'print_preview.PrintHeader.PRINT_BUTTON_CLICK',49 CANCEL_BUTTON_CLICK: 'print_preview.PrintHeader.CANCEL_BUTTON_CLICK'50 };51 PrintHeader.prototype = {52 __proto__: print_preview.Component.prototype,53 set isEnabled(isEnabled) {54 this.isEnabled_ = isEnabled;55 this.updatePrintButtonEnabledState_();56 this.isCancelButtonEnabled = isEnabled;57 },58 get isPrintButtonEnabled() {59 return !this.getChildElement('button.print').disabled;60 },61 set isPrintButtonEnabled(isEnabled) {62 this.isPrintButtonEnabled_ = isEnabled;63 this.updatePrintButtonEnabledState_();64 },65 set isCancelButtonEnabled(isEnabled) {66 this.getChildElement('button.cancel').disabled = !isEnabled;67 },68 /** @param {string} message Error message to display in the print header. */69 setErrorMessage: function(message) {70 var summaryEl = this.getChildElement('.summary');71 summaryEl.innerHTML = '';72 summaryEl.textContent = message;73 this.getChildElement('button.print').classList.toggle('loading', false);74 this.getChildElement('button.cancel').classList.toggle('loading', false);75 },76 /** @override */77 decorateInternal: function() {78 cr.ui.reverseButtonStrips(this.getElement());79 },80 /** @override */81 enterDocument: function() {82 print_preview.Component.prototype.enterDocument.call(this);83 // User events84 this.tracker.add(85 this.getChildElement('button.cancel'),86 'click',87 this.onCancelButtonClick_.bind(this));88 this.tracker.add(89 this.getChildElement('button.print'),90 'click',91 this.onPrintButtonClick_.bind(this));92 // Data events.93 this.tracker.add(94 this.printTicketStore_,95 print_preview.PrintTicketStore.EventType.INITIALIZE,96 this.onTicketChange_.bind(this));97 this.tracker.add(98 this.printTicketStore_,99 print_preview.PrintTicketStore.EventType.DOCUMENT_CHANGE,100 this.onTicketChange_.bind(this));101 this.tracker.add(102 this.printTicketStore_,103 print_preview.PrintTicketStore.EventType.TICKET_CHANGE,104 this.onTicketChange_.bind(this));105 this.tracker.add(106 this.destinationStore_,107 print_preview.DestinationStore.EventType.DESTINATION_SELECT,108 this.onDestinationSelect_.bind(this));109 this.tracker.add(110 this.printTicketStore_.copies,111 print_preview.ticket_items.TicketItem.EventType.CHANGE,112 this.onTicketChange_.bind(this));113 this.tracker.add(114 this.printTicketStore_.duplex,115 print_preview.ticket_items.TicketItem.EventType.CHANGE,116 this.onTicketChange_.bind(this));117 this.tracker.add(118 this.printTicketStore_.pageRange,119 print_preview.ticket_items.TicketItem.EventType.CHANGE,120 this.onTicketChange_.bind(this));121 },122 /**123 * Updates Print Button state.124 * @private125 */126 updatePrintButtonEnabledState_: function() {127 this.getChildElement('button.print').disabled =128 this.destinationStore_.selectedDestination == null ||129 !this.isEnabled_ ||130 !this.isPrintButtonEnabled_ ||131 !this.printTicketStore_.isTicketValid();132 },133 /**134 * Updates the summary element based on the currently selected user options.135 * @private136 */137 updateSummary_: function() {138 if (!this.printTicketStore_.isTicketValid()) {139 this.getChildElement('.summary').innerHTML = '';140 return;141 }142 var summaryLabel =143 loadTimeData.getString('printPreviewSheetsLabelSingular');144 var pagesLabel = loadTimeData.getString('printPreviewPageLabelPlural');145 var saveToPdf = this.destinationStore_.selectedDestination &&146 this.destinationStore_.selectedDestination.id ==147 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF;148 if (saveToPdf) {149 summaryLabel = loadTimeData.getString('printPreviewPageLabelSingular');150 }151 var numPages = this.printTicketStore_.pageRange.getPageNumberSet().size;152 var numSheets = numPages;153 if (!saveToPdf && this.printTicketStore_.duplex.getValue()) {154 numSheets = Math.ceil(numPages / 2);155 }156 var copies = this.printTicketStore_.copies.getValueAsNumber();157 numSheets *= copies;158 numPages *= copies;159 if (numSheets > 1) {160 summaryLabel = saveToPdf ? pagesLabel :161 loadTimeData.getString('printPreviewSheetsLabelPlural');162 }163 var html;164 var label;165 if (numPages != numSheets) {166 html = loadTimeData.getStringF('printPreviewSummaryFormatLong',167 '<b>' + numSheets + '</b>',168 '<b>' + summaryLabel + '</b>',169 numPages,170 pagesLabel);171 label = loadTimeData.getStringF('printPreviewSummaryFormatLong',172 numSheets, summaryLabel,173 numPages, pagesLabel);174 } else {175 html = loadTimeData.getStringF('printPreviewSummaryFormatShort',176 '<b>' + numSheets + '</b>',177 '<b>' + summaryLabel + '</b>');178 label = loadTimeData.getStringF('printPreviewSummaryFormatShort',179 numSheets, summaryLabel);180 }181 // Removing extra spaces from within the string.182 html = html.replace(/\s{2,}/g, ' ');183 var summary = this.getChildElement('.summary');184 summary.innerHTML = html;185 summary.setAttribute('aria-label', label);186 },187 /**188 * Called when the print button is clicked. Dispatches a PRINT_DOCUMENT189 * common event.190 * @private191 */192 onPrintButtonClick_: function() {193 if (this.destinationStore_.selectedDestination.id !=194 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {195 this.getChildElement('button.print').classList.add('loading');196 this.getChildElement('button.cancel').classList.add('loading');197 this.getChildElement('.summary').innerHTML =198 loadTimeData.getString('printing');199 }200 cr.dispatchSimpleEvent(this, PrintHeader.EventType.PRINT_BUTTON_CLICK);201 },202 /**203 * Called when the cancel button is clicked. Dispatches a204 * CLOSE_PRINT_PREVIEW event.205 * @private206 */207 onCancelButtonClick_: function() {208 cr.dispatchSimpleEvent(this, PrintHeader.EventType.CANCEL_BUTTON_CLICK);209 },210 /**211 * Called when a new destination is selected. Updates the text on the print212 * button.213 * @private214 */215 onDestinationSelect_: function() {216 var isSaveLabel = this.destinationStore_.selectedDestination &&217 (this.destinationStore_.selectedDestination.id ==218 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ||219 this.destinationStore_.selectedDestination.id ==220 print_preview.Destination.GooglePromotedId.DOCS);221 this.getChildElement('button.print').textContent =222 loadTimeData.getString(isSaveLabel ? 'saveButton' : 'printButton');223 if (this.destinationStore_.selectedDestination) {224 this.getChildElement('button.print').focus();225 }226 },227 /**228 * Called when the print ticket has changed. Disables the print button if229 * any of the settings are invalid.230 * @private231 */232 onTicketChange_: function() {233 this.updatePrintButtonEnabledState_();234 this.updateSummary_();235 if (document.activeElement == null ||236 document.activeElement == document.body) {237 this.getChildElement('button.print').focus();238 }239 }240 };241 // Export242 return {243 PrintHeader: PrintHeader244 };...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!