Best Python code snippet using playwright-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 };...
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!