1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // TODO(rltoscano): Move data/* into print_preview.data namespace 6 7 <include src="component.js"> 8 <include src="print_preview_focus_manager.js"> 9 10 cr.define('print_preview', function() { 11 'use strict'; 12 13 /** 14 * Container class for Chromium's print preview. 15 * @constructor 16 * @extends {print_preview.Component} 17 */ 18 function PrintPreview() { 19 print_preview.Component.call(this); 20 21 /** 22 * Used to communicate with Chromium's print system. 23 * @type {!print_preview.NativeLayer} 24 * @private 25 */ 26 this.nativeLayer_ = new print_preview.NativeLayer(); 27 28 /** 29 * Event target that contains information about the logged in user. 30 * @type {!print_preview.UserInfo} 31 * @private 32 */ 33 this.userInfo_ = new print_preview.UserInfo(); 34 35 /** 36 * Application state. 37 * @type {!print_preview.AppState} 38 * @private 39 */ 40 this.appState_ = new print_preview.AppState(); 41 42 /** 43 * Data model that holds information about the document to print. 44 * @type {!print_preview.DocumentInfo} 45 * @private 46 */ 47 this.documentInfo_ = new print_preview.DocumentInfo(); 48 49 /** 50 * Data store which holds print destinations. 51 * @type {!print_preview.DestinationStore} 52 * @private 53 */ 54 this.destinationStore_ = new print_preview.DestinationStore( 55 this.nativeLayer_, this.userInfo_, this.appState_); 56 57 /** 58 * Data store which holds printer sharing invitations. 59 * @type {!print_preview.InvitationStore} 60 * @private 61 */ 62 this.invitationStore_ = new print_preview.InvitationStore(this.userInfo_); 63 64 /** 65 * Storage of the print ticket used to create the print job. 66 * @type {!print_preview.PrintTicketStore} 67 * @private 68 */ 69 this.printTicketStore_ = new print_preview.PrintTicketStore( 70 this.destinationStore_, this.appState_, this.documentInfo_); 71 72 /** 73 * Holds the print and cancel buttons and renders some document statistics. 74 * @type {!print_preview.PrintHeader} 75 * @private 76 */ 77 this.printHeader_ = new print_preview.PrintHeader( 78 this.printTicketStore_, this.destinationStore_); 79 this.addChild(this.printHeader_); 80 81 /** 82 * Component used to search for print destinations. 83 * @type {!print_preview.DestinationSearch} 84 * @private 85 */ 86 this.destinationSearch_ = new print_preview.DestinationSearch( 87 this.destinationStore_, this.invitationStore_, this.userInfo_); 88 this.addChild(this.destinationSearch_); 89 90 /** 91 * Component that renders the print destination. 92 * @type {!print_preview.DestinationSettings} 93 * @private 94 */ 95 this.destinationSettings_ = new print_preview.DestinationSettings( 96 this.destinationStore_); 97 this.addChild(this.destinationSettings_); 98 99 /** 100 * Component that renders UI for entering in page range. 101 * @type {!print_preview.PageSettings} 102 * @private 103 */ 104 this.pageSettings_ = new print_preview.PageSettings( 105 this.printTicketStore_.pageRange); 106 this.addChild(this.pageSettings_); 107 108 /** 109 * Component that renders the copies settings. 110 * @type {!print_preview.CopiesSettings} 111 * @private 112 */ 113 this.copiesSettings_ = new print_preview.CopiesSettings( 114 this.printTicketStore_.copies, this.printTicketStore_.collate); 115 this.addChild(this.copiesSettings_); 116 117 /** 118 * Component that renders the media size settings. 119 * @type {!print_preview.MediaSizeSettings} 120 * @private 121 */ 122 this.mediaSizeSettings_ = 123 new print_preview.MediaSizeSettings(this.printTicketStore_.mediaSize); 124 this.addChild(this.mediaSizeSettings_); 125 126 /** 127 * Component that renders the layout settings. 128 * @type {!print_preview.LayoutSettings} 129 * @private 130 */ 131 this.layoutSettings_ = 132 new print_preview.LayoutSettings(this.printTicketStore_.landscape); 133 this.addChild(this.layoutSettings_); 134 135 /** 136 * Component that renders the color options. 137 * @type {!print_preview.ColorSettings} 138 * @private 139 */ 140 this.colorSettings_ = 141 new print_preview.ColorSettings(this.printTicketStore_.color); 142 this.addChild(this.colorSettings_); 143 144 /** 145 * Component that renders a select box for choosing margin settings. 146 * @type {!print_preview.MarginSettings} 147 * @private 148 */ 149 this.marginSettings_ = 150 new print_preview.MarginSettings(this.printTicketStore_.marginsType); 151 this.addChild(this.marginSettings_); 152 153 /** 154 * Component that renders miscellaneous print options. 155 * @type {!print_preview.OtherOptionsSettings} 156 * @private 157 */ 158 this.otherOptionsSettings_ = new print_preview.OtherOptionsSettings( 159 this.printTicketStore_.duplex, 160 this.printTicketStore_.fitToPage, 161 this.printTicketStore_.cssBackground, 162 this.printTicketStore_.selectionOnly, 163 this.printTicketStore_.headerFooter); 164 this.addChild(this.otherOptionsSettings_); 165 166 /** 167 * Component that renders the advanced options button. 168 * @type {!print_preview.AdvancedOptionsSettings} 169 * @private 170 */ 171 this.advancedOptionsSettings_ = new print_preview.AdvancedOptionsSettings( 172 this.printTicketStore_.vendorItems, this.destinationStore_); 173 this.addChild(this.advancedOptionsSettings_); 174 175 /** 176 * Component used to search for print destinations. 177 * @type {!print_preview.AdvancedSettings} 178 * @private 179 */ 180 this.advancedSettings_ = new print_preview.AdvancedSettings( 181 this.printTicketStore_); 182 this.addChild(this.advancedSettings_); 183 184 /** 185 * Component representing more/less settings button. 186 * @type {!print_preview.MoreSettings} 187 * @private 188 */ 189 var settingsSections = [ 190 this.destinationSettings_, 191 this.pageSettings_, 192 this.copiesSettings_, 193 this.mediaSizeSettings_, 194 this.layoutSettings_, 195 this.marginSettings_, 196 this.colorSettings_, 197 this.otherOptionsSettings_, 198 this.advancedOptionsSettings_]; 199 this.moreSettings_ = new print_preview.MoreSettings( 200 this.destinationStore_, settingsSections); 201 this.addChild(this.moreSettings_); 202 203 /** 204 * Area of the UI that holds the print preview. 205 * @type {!print_preview.PreviewArea} 206 * @private 207 */ 208 this.previewArea_ = new print_preview.PreviewArea(this.destinationStore_, 209 this.printTicketStore_, 210 this.nativeLayer_, 211 this.documentInfo_); 212 this.addChild(this.previewArea_); 213 214 /** 215 * Interface to the Google Cloud Print API. Null if Google Cloud Print 216 * integration is disabled. 217 * @type {cloudprint.CloudPrintInterface} 218 * @private 219 */ 220 this.cloudPrintInterface_ = null; 221 222 /** 223 * Whether in kiosk mode where print preview can print automatically without 224 * user intervention. See http://crbug.com/31395. Print will start when 225 * both the print ticket has been initialized, and an initial printer has 226 * been selected. 227 * @type {boolean} 228 * @private 229 */ 230 this.isInKioskAutoPrintMode_ = false; 231 232 /** 233 * Whether Print Preview is in App Kiosk mode, basically, use only printers 234 * available for the device. 235 * @type {boolean} 236 * @private 237 */ 238 this.isInAppKioskMode_ = false; 239 240 /** 241 * Whether Print with System Dialog option is available. 242 * @type {boolean} 243 * @private 244 */ 245 this.isSystemDialogAvailable_ = false; 246 247 /** 248 * State of the print preview UI. 249 * @type {print_preview.PrintPreview.UiState_} 250 * @private 251 */ 252 this.uiState_ = PrintPreview.UiState_.INITIALIZING; 253 254 /** 255 * Whether document preview generation is in progress. 256 * @type {boolean} 257 * @private 258 */ 259 this.isPreviewGenerationInProgress_ = true; 260 261 /** 262 * Whether to show system dialog before next printing. 263 * @type {boolean} 264 * @private 265 */ 266 this.showSystemDialogBeforeNextPrint_ = false; 267 }; 268 269 /** 270 * States of the print preview. 271 * @enum {string} 272 * @private 273 */ 274 PrintPreview.UiState_ = { 275 INITIALIZING: 'initializing', 276 READY: 'ready', 277 OPENING_PDF_PREVIEW: 'opening-pdf-preview', 278 OPENING_CLOUD_PRINT_DIALOG: 'opening-cloud-print-dialog', 279 OPENING_NATIVE_PRINT_DIALOG: 'opening-native-print-dialog', 280 PRINTING: 'printing', 281 FILE_SELECTION: 'file-selection', 282 CLOSING: 'closing', 283 ERROR: 'error' 284 }; 285 286 /** 287 * What can happen when print preview tries to print. 288 * @enum {string} 289 * @private 290 */ 291 PrintPreview.PrintAttemptResult_ = { 292 NOT_READY: 'not-ready', 293 PRINTED: 'printed', 294 READY_WAITING_FOR_PREVIEW: 'ready-waiting-for-preview' 295 }; 296 297 PrintPreview.prototype = { 298 __proto__: print_preview.Component.prototype, 299 300 /** Sets up the page and print preview by getting the printer list. */ 301 initialize: function() { 302 this.decorate($('print-preview')); 303 if (!this.previewArea_.hasCompatiblePlugin) { 304 this.setIsEnabled_(false); 305 } 306 this.nativeLayer_.startGetInitialSettings(); 307 print_preview.PrintPreviewFocusManager.getInstance().initialize(); 308 cr.ui.FocusOutlineManager.forDocument(document); 309 }, 310 311 /** @override */ 312 enterDocument: function() { 313 // Native layer events. 314 this.tracker.add( 315 this.nativeLayer_, 316 print_preview.NativeLayer.EventType.INITIAL_SETTINGS_SET, 317 this.onInitialSettingsSet_.bind(this)); 318 this.tracker.add( 319 this.nativeLayer_, 320 print_preview.NativeLayer.EventType.CLOUD_PRINT_ENABLE, 321 this.onCloudPrintEnable_.bind(this)); 322 this.tracker.add( 323 this.nativeLayer_, 324 print_preview.NativeLayer.EventType.PRINT_TO_CLOUD, 325 this.onPrintToCloud_.bind(this)); 326 this.tracker.add( 327 this.nativeLayer_, 328 print_preview.NativeLayer.EventType.FILE_SELECTION_CANCEL, 329 this.onFileSelectionCancel_.bind(this)); 330 this.tracker.add( 331 this.nativeLayer_, 332 print_preview.NativeLayer.EventType.FILE_SELECTION_COMPLETE, 333 this.onFileSelectionComplete_.bind(this)); 334 this.tracker.add( 335 this.nativeLayer_, 336 print_preview.NativeLayer.EventType.SETTINGS_INVALID, 337 this.onSettingsInvalid_.bind(this)); 338 this.tracker.add( 339 this.nativeLayer_, 340 print_preview.NativeLayer.EventType.DISABLE_SCALING, 341 this.onDisableScaling_.bind(this)); 342 this.tracker.add( 343 this.nativeLayer_, 344 print_preview.NativeLayer.EventType.PRIVET_PRINT_FAILED, 345 this.onPrivetPrintFailed_.bind(this)); 346 this.tracker.add( 347 this.nativeLayer_, 348 print_preview.NativeLayer.EventType.MANIPULATE_SETTINGS_FOR_TEST, 349 this.onManipulateSettingsForTest_.bind(this)); 350 351 this.tracker.add( 352 $('system-dialog-link'), 353 'click', 354 this.openSystemPrintDialog_.bind(this)); 355 this.tracker.add( 356 $('cloud-print-dialog-link'), 357 'click', 358 this.onCloudPrintDialogLinkClick_.bind(this)); 359 if ($('open-pdf-in-preview-link')) { 360 this.tracker.add( 361 $('open-pdf-in-preview-link'), 362 'click', 363 this.onOpenPdfInPreviewLinkClick_.bind(this)); 364 } 365 366 this.tracker.add( 367 this.previewArea_, 368 print_preview.PreviewArea.EventType.PREVIEW_GENERATION_IN_PROGRESS, 369 this.onPreviewGenerationInProgress_.bind(this)); 370 this.tracker.add( 371 this.previewArea_, 372 print_preview.PreviewArea.EventType.PREVIEW_GENERATION_DONE, 373 this.onPreviewGenerationDone_.bind(this)); 374 this.tracker.add( 375 this.previewArea_, 376 print_preview.PreviewArea.EventType.PREVIEW_GENERATION_FAIL, 377 this.onPreviewGenerationFail_.bind(this)); 378 this.tracker.add( 379 this.previewArea_, 380 print_preview.PreviewArea.EventType.OPEN_SYSTEM_DIALOG_CLICK, 381 this.openSystemPrintDialog_.bind(this)); 382 383 this.tracker.add( 384 this.destinationStore_, 385 print_preview.DestinationStore.EventType. 386 SELECTED_DESTINATION_CAPABILITIES_READY, 387 this.printIfReady_.bind(this)); 388 this.tracker.add( 389 this.destinationStore_, 390 print_preview.DestinationStore.EventType.DESTINATION_SELECT, 391 this.onDestinationSelect_.bind(this)); 392 this.tracker.add( 393 this.destinationStore_, 394 print_preview.DestinationStore.EventType.DESTINATION_SEARCH_DONE, 395 this.onDestinationSearchDone_.bind(this)); 396 397 this.tracker.add( 398 this.printHeader_, 399 print_preview.PrintHeader.EventType.PRINT_BUTTON_CLICK, 400 this.onPrintButtonClick_.bind(this)); 401 this.tracker.add( 402 this.printHeader_, 403 print_preview.PrintHeader.EventType.CANCEL_BUTTON_CLICK, 404 this.onCancelButtonClick_.bind(this)); 405 406 this.tracker.add(window, 'keydown', this.onKeyDown_.bind(this)); 407 408 this.tracker.add( 409 this.destinationSettings_, 410 print_preview.DestinationSettings.EventType.CHANGE_BUTTON_ACTIVATE, 411 this.onDestinationChangeButtonActivate_.bind(this)); 412 413 this.tracker.add( 414 this.destinationSearch_, 415 print_preview.DestinationSearch.EventType.MANAGE_CLOUD_DESTINATIONS, 416 this.onManageCloudDestinationsActivated_.bind(this)); 417 this.tracker.add( 418 this.destinationSearch_, 419 print_preview.DestinationSearch.EventType.MANAGE_LOCAL_DESTINATIONS, 420 this.onManageLocalDestinationsActivated_.bind(this)); 421 this.tracker.add( 422 this.destinationSearch_, 423 print_preview.DestinationSearch.EventType.ADD_ACCOUNT, 424 this.onCloudPrintSignInActivated_.bind(this, true /*addAccount*/)); 425 this.tracker.add( 426 this.destinationSearch_, 427 print_preview.DestinationSearch.EventType.SIGN_IN, 428 this.onCloudPrintSignInActivated_.bind(this, false /*addAccount*/)); 429 this.tracker.add( 430 this.destinationSearch_, 431 print_preview.DestinationListItem.EventType.REGISTER_PROMO_CLICKED, 432 this.onCloudPrintRegisterPromoClick_.bind(this)); 433 434 this.tracker.add( 435 this.advancedOptionsSettings_, 436 print_preview.AdvancedOptionsSettings.EventType.BUTTON_ACTIVATED, 437 this.onAdvancedOptionsButtonActivated_.bind(this)); 438 439 // TODO(rltoscano): Move no-destinations-promo into its own component 440 // instead being part of PrintPreview. 441 this.tracker.add( 442 this.getChildElement('#no-destinations-promo .close-button'), 443 'click', 444 this.onNoDestinationsPromoClose_.bind(this)); 445 this.tracker.add( 446 this.getChildElement('#no-destinations-promo .not-now-button'), 447 'click', 448 this.onNoDestinationsPromoClose_.bind(this)); 449 this.tracker.add( 450 this.getChildElement('#no-destinations-promo .add-printer-button'), 451 'click', 452 this.onNoDestinationsPromoClick_.bind(this)); 453 }, 454 455 /** @override */ 456 decorateInternal: function() { 457 this.printHeader_.decorate($('print-header')); 458 this.destinationSearch_.decorate($('destination-search')); 459 this.destinationSettings_.decorate($('destination-settings')); 460 this.pageSettings_.decorate($('page-settings')); 461 this.copiesSettings_.decorate($('copies-settings')); 462 this.mediaSizeSettings_.decorate($('media-size-settings')); 463 this.layoutSettings_.decorate($('layout-settings')); 464 this.colorSettings_.decorate($('color-settings')); 465 this.marginSettings_.decorate($('margin-settings')); 466 this.otherOptionsSettings_.decorate($('other-options-settings')); 467 this.advancedOptionsSettings_.decorate($('advanced-options-settings')); 468 this.advancedSettings_.decorate($('advanced-settings')); 469 this.moreSettings_.decorate($('more-settings')); 470 this.previewArea_.decorate($('preview-area')); 471 }, 472 473 /** 474 * Sets whether the controls in the print preview are enabled. 475 * @param {boolean} isEnabled Whether the controls in the print preview are 476 * enabled. 477 * @private 478 */ 479 setIsEnabled_: function(isEnabled) { 480 $('system-dialog-link').disabled = !isEnabled; 481 $('cloud-print-dialog-link').disabled = !isEnabled; 482 if ($('open-pdf-in-preview-link')) { 483 $('open-pdf-in-preview-link').disabled = !isEnabled; 484 } 485 this.printHeader_.isEnabled = isEnabled; 486 this.destinationSettings_.isEnabled = isEnabled; 487 this.pageSettings_.isEnabled = isEnabled; 488 this.copiesSettings_.isEnabled = isEnabled; 489 this.mediaSizeSettings_.isEnabled = isEnabled; 490 this.layoutSettings_.isEnabled = isEnabled; 491 this.colorSettings_.isEnabled = isEnabled; 492 this.marginSettings_.isEnabled = isEnabled; 493 this.otherOptionsSettings_.isEnabled = isEnabled; 494 this.advancedOptionsSettings_.isEnabled = isEnabled; 495 }, 496 497 /** 498 * Prints the document or launches a pdf preview on the local system. 499 * @param {boolean} isPdfPreview Whether to launch the pdf preview. 500 * @private 501 */ 502 printDocumentOrOpenPdfPreview_: function(isPdfPreview) { 503 assert(this.uiState_ == PrintPreview.UiState_.READY, 504 'Print document request received when not in ready state: ' + 505 this.uiState_); 506 if (isPdfPreview) { 507 this.uiState_ = PrintPreview.UiState_.OPENING_PDF_PREVIEW; 508 } else if (this.destinationStore_.selectedDestination.id == 509 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) { 510 this.uiState_ = PrintPreview.UiState_.FILE_SELECTION; 511 } else { 512 this.uiState_ = PrintPreview.UiState_.PRINTING; 513 } 514 this.setIsEnabled_(false); 515 this.printHeader_.isCancelButtonEnabled = true; 516 var printAttemptResult = this.printIfReady_(); 517 if (printAttemptResult == PrintPreview.PrintAttemptResult_.PRINTED || 518 printAttemptResult == 519 PrintPreview.PrintAttemptResult_.READY_WAITING_FOR_PREVIEW) { 520 if ((this.destinationStore_.selectedDestination.isLocal && 521 !this.destinationStore_.selectedDestination.isPrivet && 522 this.destinationStore_.selectedDestination.id != 523 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) || 524 this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW) { 525 // Hide the dialog for now. The actual print command will be issued 526 // when the preview generation is done. 527 this.nativeLayer_.startHideDialog(); 528 } 529 } 530 }, 531 532 /** 533 * Attempts to print if needed and if ready. 534 * @return {PrintPreview.PrintAttemptResult_} Attempt result. 535 * @private 536 */ 537 printIfReady_: function() { 538 var okToPrint = 539 (this.uiState_ == PrintPreview.UiState_.PRINTING || 540 this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW || 541 this.uiState_ == PrintPreview.UiState_.FILE_SELECTION || 542 this.uiState_ == PrintPreview.UiState_.OPENING_CLOUD_PRINT_DIALOG || 543 this.isInKioskAutoPrintMode_) && 544 this.destinationStore_.selectedDestination && 545 this.destinationStore_.selectedDestination.capabilities; 546 if (!okToPrint) { 547 return PrintPreview.PrintAttemptResult_.NOT_READY; 548 } 549 if (this.isPreviewGenerationInProgress_) { 550 return PrintPreview.PrintAttemptResult_.READY_WAITING_FOR_PREVIEW; 551 } 552 assert(this.printTicketStore_.isTicketValid(), 553 'Trying to print with invalid ticket'); 554 if (this.uiState_ == PrintPreview.UiState_.OPENING_CLOUD_PRINT_DIALOG) { 555 this.nativeLayer_.startShowCloudPrintDialog( 556 this.printTicketStore_.pageRange.getPageNumberSet().size); 557 } else { 558 if (getIsVisible(this.moreSettings_.getElement())) { 559 new print_preview.PrintSettingsUiMetricsContext().record( 560 this.moreSettings_.isExpanded ? 561 print_preview.Metrics.PrintSettingsUiBucket. 562 PRINT_WITH_SETTINGS_EXPANDED : 563 print_preview.Metrics.PrintSettingsUiBucket. 564 PRINT_WITH_SETTINGS_COLLAPSED); 565 } 566 this.nativeLayer_.startPrint( 567 this.destinationStore_.selectedDestination, 568 this.printTicketStore_, 569 this.cloudPrintInterface_, 570 this.documentInfo_, 571 this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW, 572 this.showSystemDialogBeforeNextPrint_); 573 this.showSystemDialogBeforeNextPrint_ = false; 574 } 575 return PrintPreview.PrintAttemptResult_.PRINTED; 576 }, 577 578 /** 579 * Closes the print preview. 580 * @private 581 */ 582 close_: function() { 583 this.exitDocument(); 584 this.uiState_ = PrintPreview.UiState_.CLOSING; 585 this.nativeLayer_.startCloseDialog(); 586 }, 587 588 /** 589 * Opens the native system print dialog after disabling all controls. 590 * @private 591 */ 592 openSystemPrintDialog_: function() { 593 if (!this.shouldShowSystemDialogLink_()) 594 return; 595 if (cr.isWindows) { 596 this.showSystemDialogBeforeNextPrint_ = true; 597 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/); 598 return; 599 } 600 setIsVisible($('system-dialog-throbber'), true); 601 this.setIsEnabled_(false); 602 this.uiState_ = PrintPreview.UiState_.OPENING_NATIVE_PRINT_DIALOG; 603 this.nativeLayer_.startShowSystemDialog(); 604 }, 605 606 /** 607 * Called when the native layer has initial settings to set. Sets the 608 * initial settings of the print preview and begins fetching print 609 * destinations. 610 * @param {Event} event Contains the initial print preview settings 611 * persisted through the session. 612 * @private 613 */ 614 onInitialSettingsSet_: function(event) { 615 assert(this.uiState_ == PrintPreview.UiState_.INITIALIZING, 616 'Updating initial settings when not in initializing state: ' + 617 this.uiState_); 618 this.uiState_ = PrintPreview.UiState_.READY; 619 620 var settings = event.initialSettings; 621 this.isInKioskAutoPrintMode_ = settings.isInKioskAutoPrintMode; 622 this.isInAppKioskMode_ = settings.isInAppKioskMode; 623 624 // The following components must be initialized in this order. 625 this.appState_.init( 626 settings.serializedAppStateStr, 627 settings.systemDefaultDestinationId); 628 this.documentInfo_.init( 629 settings.isDocumentModifiable, 630 settings.documentTitle, 631 settings.documentHasSelection); 632 this.printTicketStore_.init( 633 settings.thousandsDelimeter, 634 settings.decimalDelimeter, 635 settings.unitType, 636 settings.selectionOnly); 637 this.destinationStore_.init(settings.isInAppKioskMode); 638 this.appState_.setInitialized(); 639 640 $('document-title').innerText = settings.documentTitle; 641 this.isSystemDialogAvailable_ = !settings.hidePrintWithSystemDialogLink && 642 !settings.isInAppKioskMode; 643 setIsVisible($('system-dialog-link'), this.shouldShowSystemDialogLink_()); 644 }, 645 646 /** 647 * Calls when the native layer enables Google Cloud Print integration. 648 * Fetches the user's cloud printers. 649 * @param {Event} event Contains the base URL of the Google Cloud Print 650 * service. 651 * @private 652 */ 653 onCloudPrintEnable_: function(event) { 654 this.cloudPrintInterface_ = new cloudprint.CloudPrintInterface( 655 event.baseCloudPrintUrl, 656 this.nativeLayer_, 657 this.userInfo_, 658 event.appKioskMode); 659 this.tracker.add( 660 this.cloudPrintInterface_, 661 cloudprint.CloudPrintInterface.EventType.SUBMIT_DONE, 662 this.onCloudPrintSubmitDone_.bind(this)); 663 this.tracker.add( 664 this.cloudPrintInterface_, 665 cloudprint.CloudPrintInterface.EventType.SEARCH_FAILED, 666 this.onCloudPrintError_.bind(this)); 667 this.tracker.add( 668 this.cloudPrintInterface_, 669 cloudprint.CloudPrintInterface.EventType.SUBMIT_FAILED, 670 this.onCloudPrintError_.bind(this)); 671 this.tracker.add( 672 this.cloudPrintInterface_, 673 cloudprint.CloudPrintInterface.EventType.PRINTER_FAILED, 674 this.onCloudPrintError_.bind(this)); 675 this.tracker.add( 676 this.cloudPrintInterface_, 677 cloudprint.CloudPrintInterface.EventType. 678 UPDATE_PRINTER_TOS_ACCEPTANCE_FAILED, 679 this.onCloudPrintError_.bind(this)); 680 681 this.destinationStore_.setCloudPrintInterface(this.cloudPrintInterface_); 682 this.invitationStore_.setCloudPrintInterface(this.cloudPrintInterface_); 683 if (this.destinationSearch_.getIsVisible()) { 684 this.destinationStore_.startLoadCloudDestinations(); 685 this.invitationStore_.startLoadingInvitations(); 686 } 687 }, 688 689 /** 690 * Called from the native layer when ready to print to Google Cloud Print. 691 * @param {Event} event Contains the body to send in the HTTP request. 692 * @private 693 */ 694 onPrintToCloud_: function(event) { 695 assert(this.uiState_ == PrintPreview.UiState_.PRINTING, 696 'Document ready to be sent to the cloud when not in printing ' + 697 'state: ' + this.uiState_); 698 assert(this.cloudPrintInterface_ != null, 699 'Google Cloud Print is not enabled'); 700 this.cloudPrintInterface_.submit( 701 this.destinationStore_.selectedDestination, 702 this.printTicketStore_, 703 this.documentInfo_, 704 event.data); 705 }, 706 707 /** 708 * Called from the native layer when the user cancels the save-to-pdf file 709 * selection dialog. 710 * @private 711 */ 712 onFileSelectionCancel_: function() { 713 assert(this.uiState_ == PrintPreview.UiState_.FILE_SELECTION, 714 'File selection cancelled when not in file-selection state: ' + 715 this.uiState_); 716 this.setIsEnabled_(true); 717 this.uiState_ = PrintPreview.UiState_.READY; 718 }, 719 720 /** 721 * Called from the native layer when save-to-pdf file selection is complete. 722 * @private 723 */ 724 onFileSelectionComplete_: function() { 725 assert(this.uiState_ == PrintPreview.UiState_.FILE_SELECTION, 726 'File selection completed when not in file-selection state: ' + 727 this.uiState_); 728 this.previewArea_.showCustomMessage( 729 loadTimeData.getString('printingToPDFInProgress')); 730 this.uiState_ = PrintPreview.UiState_.PRINTING; 731 }, 732 733 /** 734 * Called after successfully submitting a job to Google Cloud Print. 735 * @param {!Event} event Contains the ID of the submitted print job. 736 * @private 737 */ 738 onCloudPrintSubmitDone_: function(event) { 739 assert(this.uiState_ == PrintPreview.UiState_.PRINTING, 740 'Submited job to Google Cloud Print but not in printing state ' + 741 this.uiState_); 742 if (this.destinationStore_.selectedDestination.id == 743 print_preview.Destination.GooglePromotedId.FEDEX) { 744 this.nativeLayer_.startForceOpenNewTab( 745 'https://www.google.com/cloudprint/fedexcode.html?jobid=' + 746 event.jobId); 747 } 748 this.close_(); 749 }, 750 751 /** 752 * Called when there was an error communicating with Google Cloud print. 753 * Displays an error message in the print header. 754 * @param {!Event} event Contains the error message. 755 * @private 756 */ 757 onCloudPrintError_: function(event) { 758 if (event.status == 403) { 759 if (!this.isInAppKioskMode_) { 760 this.destinationSearch_.showCloudPrintPromo(); 761 } 762 } else if (event.status == 0) { 763 return; // Ignore, the system does not have internet connectivity. 764 } else { 765 this.printHeader_.setErrorMessage(event.message); 766 } 767 if (event.status == 200) { 768 console.error('Google Cloud Print Error: (' + event.errorCode + ') ' + 769 event.message); 770 } else { 771 console.error('Google Cloud Print Error: HTTP status ' + event.status); 772 } 773 }, 774 775 /** 776 * Called when the preview area's preview generation is in progress. 777 * @private 778 */ 779 onPreviewGenerationInProgress_: function() { 780 this.isPreviewGenerationInProgress_ = true; 781 }, 782 783 /** 784 * Called when the preview area's preview generation is complete. 785 * @private 786 */ 787 onPreviewGenerationDone_: function() { 788 this.isPreviewGenerationInProgress_ = false; 789 this.printHeader_.isPrintButtonEnabled = true; 790 this.nativeLayer_.previewReadyForTest(); 791 this.printIfReady_(); 792 }, 793 794 /** 795 * Called when the preview area's preview failed to load. 796 * @private 797 */ 798 onPreviewGenerationFail_: function() { 799 this.isPreviewGenerationInProgress_ = false; 800 this.printHeader_.isPrintButtonEnabled = false; 801 if (this.uiState_ == PrintPreview.UiState_.PRINTING) { 802 this.nativeLayer_.startCancelPendingPrint(); 803 } else if (this.uiState_ == 804 PrintPreview.UiState_.OPENING_CLOUD_PRINT_DIALOG) { 805 this.uiState_ = PrintPreview.UiState_.READY; 806 } 807 }, 808 809 /** 810 * Called when the 'Open pdf in preview' link is clicked. Launches the pdf 811 * preview app. 812 * @private 813 */ 814 onOpenPdfInPreviewLinkClick_: function() { 815 assert(this.uiState_ == PrintPreview.UiState_.READY, 816 'Trying to open pdf in preview when not in ready state: ' + 817 this.uiState_); 818 setIsVisible($('open-preview-app-throbber'), true); 819 this.previewArea_.showCustomMessage( 820 loadTimeData.getString('openingPDFInPreview')); 821 this.printDocumentOrOpenPdfPreview_(true /*isPdfPreview*/); 822 }, 823 824 /** 825 * Called when the print header's print button is clicked. Prints the 826 * document. 827 * @private 828 */ 829 onPrintButtonClick_: function() { 830 assert(this.uiState_ == PrintPreview.UiState_.READY, 831 'Trying to print when not in ready state: ' + this.uiState_); 832 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/); 833 }, 834 835 /** 836 * Called when the print header's cancel button is clicked. Closes the 837 * print dialog. 838 * @private 839 */ 840 onCancelButtonClick_: function() { 841 this.close_(); 842 }, 843 844 /** 845 * Called when the register promo for Cloud Print is clicked. 846 * @private 847 */ 848 onCloudPrintRegisterPromoClick_: function(e) { 849 var devicesUrl = 'chrome://devices/register?id=' + e.destination.id; 850 this.nativeLayer_.startForceOpenNewTab(devicesUrl); 851 this.destinationStore_.waitForRegister(e.destination.id); 852 }, 853 854 /** 855 * Consume escape key presses and ctrl + shift + p. Delegate everything else 856 * to the preview area. 857 * @param {KeyboardEvent} e The keyboard event. 858 * @private 859 */ 860 onKeyDown_: function(e) { 861 // Escape key closes the dialog. 862 if (e.keyCode == 27 && !e.shiftKey && !e.ctrlKey && !e.altKey && 863 !e.metaKey) { 864 <if expr="toolkit_views"> 865 // On the toolkit_views environment, ESC key is handled by C++-side 866 // instead of JS-side. 867 return; 868 </if> 869 <if expr="not toolkit_views"> 870 this.close_(); 871 </if> 872 e.preventDefault(); 873 return; 874 } 875 876 // On Mac, Cmd- should close the print dialog. 877 if (cr.isMac && e.keyCode == 189 && e.metaKey) { 878 this.close_(); 879 e.preventDefault(); 880 return; 881 } 882 883 // Ctrl + Shift + p / Mac equivalent. 884 if (e.keyCode == 80) { 885 if ((cr.isMac && e.metaKey && e.altKey && !e.shiftKey && !e.ctrlKey) || 886 (!cr.isMac && e.shiftKey && e.ctrlKey && !e.altKey && !e.metaKey)) { 887 this.openSystemPrintDialog_(); 888 e.preventDefault(); 889 return; 890 } 891 } 892 893 if (e.keyCode == 13 /*enter*/ && 894 !document.querySelector('.overlay:not([hidden])') && 895 this.destinationStore_.selectedDestination && 896 this.printTicketStore_.isTicketValid()) { 897 assert(this.uiState_ == PrintPreview.UiState_.READY, 898 'Trying to print when not in ready state: ' + this.uiState_); 899 var activeElementTag = document.activeElement ? 900 document.activeElement.tagName.toUpperCase() : ''; 901 if (activeElementTag != 'BUTTON' && activeElementTag != 'SELECT') { 902 this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/); 903 e.preventDefault(); 904 } 905 return; 906 } 907 908 // Pass certain directional keyboard events to the PDF viewer. 909 this.previewArea_.handleDirectionalKeyEvent(e); 910 }, 911 912 /** 913 * Called when native layer receives invalid settings for a print request. 914 * @private 915 */ 916 onSettingsInvalid_: function() { 917 this.uiState_ = PrintPreview.UiState_.ERROR; 918 console.error('Invalid settings error reported from native layer'); 919 this.previewArea_.showCustomMessage( 920 loadTimeData.getString('invalidPrinterSettings')); 921 }, 922 923 /** 924 * Called when the destination settings' change button is activated. 925 * Displays the destination search component. 926 * @private 927 */ 928 onDestinationChangeButtonActivate_: function() { 929 this.destinationSearch_.setIsVisible(true); 930 }, 931 932 /** 933 * Called when the destination settings' change button is activated. 934 * Displays the destination search component. 935 * @private 936 */ 937 onAdvancedOptionsButtonActivated_: function() { 938 this.advancedSettings_.showForDestination( 939 this.destinationStore_.selectedDestination); 940 }, 941 942 /** 943 * Called when the destination search dispatches manage cloud destinations 944 * event. Calls corresponding native layer method. 945 * @private 946 */ 947 onManageCloudDestinationsActivated_: function() { 948 this.nativeLayer_.startManageCloudDestinations(); 949 }, 950 951 /** 952 * Called when the destination search dispatches manage local destinations 953 * event. Calls corresponding native layer method. 954 * @private 955 */ 956 onManageLocalDestinationsActivated_: function() { 957 this.nativeLayer_.startManageLocalDestinations(); 958 }, 959 960 /** 961 * Called when the user wants to sign in to Google Cloud Print. Calls the 962 * corresponding native layer event. 963 * @param {boolean} addAccount Whether to open an 'add a new account' or 964 * default sign in page. 965 * @private 966 */ 967 onCloudPrintSignInActivated_: function(addAccount) { 968 this.nativeLayer_.startCloudPrintSignIn(addAccount); 969 }, 970 971 /** 972 * Called when the native layer dispatches a DISABLE_SCALING event. Resets 973 * fit-to-page selection and updates document info. 974 * @private 975 */ 976 onDisableScaling_: function() { 977 this.printTicketStore_.fitToPage.updateValue(null); 978 this.documentInfo_.updateIsScalingDisabled(true); 979 }, 980 981 /** 982 * Called when privet printing fails. 983 * @param {Event} event Event object representing the failure. 984 * @private 985 */ 986 onPrivetPrintFailed_: function(event) { 987 console.error('Privet printing failed with error code ' + 988 event.httpError); 989 this.printHeader_.setErrorMessage( 990 loadTimeData.getString('couldNotPrint')); 991 }, 992 993 /** 994 * Called when the print preview settings need to be changed for testing. 995 * @param {Event} event Event object that contains the option that is to 996 * be changed and what to set that option. 997 * @private 998 */ 999 onManipulateSettingsForTest_: function(event) { 1000 if ('selectSaveAsPdfDestination' in event.settings) { 1001 this.saveAsPdfForTest_(); // No parameters. 1002 } else if ('layoutSettings' in event.settings) { 1003 this.setLayoutSettingsForTest_(event.settings.layoutSettings.portrait); 1004 } else if ('pageRange' in event.settings) { 1005 this.setPageRangeForTest_(event.settings.pageRange); 1006 } else if ('headersAndFooters' in event.settings) { 1007 this.setHeadersAndFootersForTest_(event.settings.headersAndFooters); 1008 } else if ('backgroundColorsAndImages' in event.settings) { 1009 this.setBackgroundColorsAndImagesForTest_( 1010 event.settings.backgroundColorsAndImages); 1011 } else if ('margins' in event.settings) { 1012 this.setMarginsForTest_(event.settings.margins); 1013 } 1014 }, 1015 1016 /** 1017 * Called by onManipulateSettingsForTest_(). Sets the print destination 1018 * as a pdf. 1019 * @private 1020 */ 1021 saveAsPdfForTest_: function() { 1022 if (this.destinationStore_.selectedDestination && 1023 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF == 1024 this.destinationStore_.selectedDestination.id) { 1025 this.nativeLayer_.previewReadyForTest(); 1026 return; 1027 } 1028 1029 var destinations = this.destinationStore_.destinations(); 1030 var pdfDestination = null; 1031 for (var i = 0; i < destinations.length; i++) { 1032 if (destinations[i].id == 1033 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) { 1034 pdfDestination = destinations[i]; 1035 break; 1036 } 1037 } 1038 1039 if (pdfDestination) 1040 this.destinationStore_.selectDestination(pdfDestination); 1041 else 1042 this.nativeLayer_.previewFailedForTest(); 1043 }, 1044 1045 /** 1046 * Called by onManipulateSettingsForTest_(). Sets the layout settings to 1047 * either portrait or landscape. 1048 * @param {boolean} portrait Whether to use portrait page layout; 1049 * if false: landscape. 1050 * @private 1051 */ 1052 setLayoutSettingsForTest_: function(portrait) { 1053 var combobox = document.querySelector('.layout-settings-select'); 1054 if (combobox.value == 'portrait') { 1055 this.nativeLayer_.previewReadyForTest(); 1056 } else { 1057 combobox.value = 'landscape'; 1058 this.layoutSettings_.onSelectChange_(); 1059 } 1060 }, 1061 1062 /** 1063 * Called by onManipulateSettingsForTest_(). Sets the page range for 1064 * for the print preview settings. 1065 * @param {string} pageRange Sets the page range to the desired value(s). 1066 * Ex: "1-5,9" means pages 1 through 5 and page 9 will be printed. 1067 * @private 1068 */ 1069 setPageRangeForTest_: function(pageRange) { 1070 var textbox = document.querySelector('.page-settings-custom-input'); 1071 if (textbox.value == pageRange) { 1072 this.nativeLayer_.previewReadyForTest(); 1073 } else { 1074 textbox.value = pageRange; 1075 document.querySelector('.page-settings-custom-radio').click(); 1076 } 1077 }, 1078 1079 /** 1080 * Called by onManipulateSettings_(). Checks or unchecks the headers and 1081 * footers option on print preview. 1082 * @param {boolean} headersAndFooters Whether the "Headers and Footers" 1083 * checkbox should be checked. 1084 * @private 1085 */ 1086 setHeadersAndFootersForTest_: function(headersAndFooters) { 1087 var checkbox = document.querySelector('.header-footer-checkbox'); 1088 if (headersAndFooters == checkbox.checked) 1089 this.nativeLayer_.previewReadyForTest(); 1090 else 1091 checkbox.click(); 1092 }, 1093 1094 /** 1095 * Called by onManipulateSettings_(). Checks or unchecks the background 1096 * colors and images option on print preview. 1097 * @param {boolean} backgroundColorsAndImages If true, the checkbox should 1098 * be checked. Otherwise it should be unchecked. 1099 * @private 1100 */ 1101 setBackgroundColorsAndImagesForTest_: function(backgroundColorsAndImages) { 1102 var checkbox = document.querySelector('.css-background-checkbox'); 1103 if (backgroundColorsAndImages == checkbox.checked) 1104 this.nativeLayer_.previewReadyForTest(); 1105 else 1106 checkbox.click(); 1107 }, 1108 1109 /** 1110 * Called by onManipulateSettings_(). Sets the margin settings 1111 * that are desired. Custom margin settings aren't currently supported. 1112 * @param {number} margins The desired margins combobox index. Must be 1113 * a valid index or else the test fails. 1114 * @private 1115 */ 1116 setMarginsForTest_: function(margins) { 1117 var combobox = document.querySelector('.margin-settings-select'); 1118 if (margins == combobox.selectedIndex) { 1119 this.nativeLayer_.previewReadyForTest(); 1120 } else if (margins >= 0 && margins < combobox.length) { 1121 combobox.selectedIndex = margins; 1122 this.marginSettings_.onSelectChange_(); 1123 } else { 1124 this.nativeLayer_.previewFailedForTest(); 1125 } 1126 }, 1127 1128 /** 1129 * Returns true if "Print using system dialog" link should be shown for 1130 * current destination. 1131 * @return {boolean} Returns true if link should be shown. 1132 */ 1133 shouldShowSystemDialogLink_: function() { 1134 if (!this.isSystemDialogAvailable_) 1135 return false; 1136 if (!cr.isWindows) 1137 return true; 1138 var selectedDest = this.destinationStore_.selectedDestination; 1139 return selectedDest && 1140 selectedDest.origin == print_preview.Destination.Origin.LOCAL && 1141 selectedDest.id != 1142 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF; 1143 }, 1144 1145 /** 1146 * Called when the open-cloud-print-dialog link is clicked. Opens the Google 1147 * Cloud Print web dialog. 1148 * @private 1149 */ 1150 onCloudPrintDialogLinkClick_: function() { 1151 assert(this.uiState_ == PrintPreview.UiState_.READY, 1152 'Opening Google Cloud Print dialog when not in ready state: ' + 1153 this.uiState_); 1154 setIsVisible($('cloud-print-dialog-throbber'), true); 1155 this.setIsEnabled_(false); 1156 this.uiState_ = PrintPreview.UiState_.OPENING_CLOUD_PRINT_DIALOG; 1157 this.printIfReady_(); 1158 }, 1159 1160 /** 1161 * Called when a print destination is selected. Shows/hides the "Print with 1162 * Cloud Print" link in the navbar. 1163 * @private 1164 */ 1165 onDestinationSelect_: function() { 1166 var selectedDest = this.destinationStore_.selectedDestination; 1167 setIsVisible( 1168 $('cloud-print-dialog-link'), 1169 selectedDest && !cr.isChromeOS && !selectedDest.isLocal); 1170 setIsVisible( 1171 $('system-dialog-link'), 1172 this.shouldShowSystemDialogLink_()); 1173 if (selectedDest && this.isInKioskAutoPrintMode_) { 1174 this.onPrintButtonClick_(); 1175 } 1176 }, 1177 1178 /** 1179 * Called when the destination store loads a group of destinations. Shows 1180 * a promo on Chrome OS if the user has no print destinations promoting 1181 * Google Cloud Print. 1182 * @private 1183 */ 1184 onDestinationSearchDone_: function() { 1185 var isPromoVisible = cr.isChromeOS && 1186 this.cloudPrintInterface_ && 1187 this.userInfo_.activeUser && 1188 !this.appState_.isGcpPromoDismissed && 1189 !this.destinationStore_.isLocalDestinationsSearchInProgress && 1190 !this.destinationStore_.isCloudDestinationsSearchInProgress && 1191 this.destinationStore_.hasOnlyDefaultCloudDestinations(); 1192 setIsVisible(this.getChildElement('#no-destinations-promo'), 1193 isPromoVisible); 1194 if (isPromoVisible) { 1195 new print_preview.GcpPromoMetricsContext().record( 1196 print_preview.Metrics.GcpPromoBucket.PROMO_SHOWN); 1197 } 1198 }, 1199 1200 /** 1201 * Called when the close button on the no-destinations-promotion is clicked. 1202 * Hides the promotion. 1203 * @private 1204 */ 1205 onNoDestinationsPromoClose_: function() { 1206 new print_preview.GcpPromoMetricsContext().record( 1207 print_preview.Metrics.GcpPromoBucket.PROMO_CLOSED); 1208 setIsVisible(this.getChildElement('#no-destinations-promo'), false); 1209 this.appState_.persistIsGcpPromoDismissed(true); 1210 }, 1211 1212 /** 1213 * Called when the no-destinations promotion link is clicked. Opens the 1214 * Google Cloud Print management page and closes the print preview. 1215 * @private 1216 */ 1217 onNoDestinationsPromoClick_: function() { 1218 new print_preview.GcpPromoMetricsContext().record( 1219 print_preview.Metrics.GcpPromoBucket.PROMO_CLICKED); 1220 this.appState_.persistIsGcpPromoDismissed(true); 1221 window.open(this.cloudPrintInterface_.baseUrl + '?user=' + 1222 this.userInfo_.activeUser + '#printers'); 1223 this.close_(); 1224 } 1225 }; 1226 1227 // Export 1228 return { 1229 PrintPreview: PrintPreview 1230 }; 1231 }); 1232 1233 // Pull in all other scripts in a single shot. 1234 <include src="common/overlay.js"> 1235 <include src="common/search_box.js"> 1236 <include src="common/search_bubble.js"> 1237 1238 <include src="data/page_number_set.js"> 1239 <include src="data/destination.js"> 1240 <include src="data/local_parsers.js"> 1241 <include src="data/cloud_parsers.js"> 1242 <include src="data/destination_store.js"> 1243 <include src="data/invitation.js"> 1244 <include src="data/invitation_store.js"> 1245 <include src="data/margins.js"> 1246 <include src="data/document_info.js"> 1247 <include src="data/printable_area.js"> 1248 <include src="data/measurement_system.js"> 1249 <include src="data/print_ticket_store.js"> 1250 <include src="data/coordinate2d.js"> 1251 <include src="data/size.js"> 1252 <include src="data/capabilities_holder.js"> 1253 <include src="data/user_info.js"> 1254 <include src="data/app_state.js"> 1255 1256 <include src="data/ticket_items/ticket_item.js"> 1257 1258 <include src="data/ticket_items/custom_margins.js"> 1259 <include src="data/ticket_items/collate.js"> 1260 <include src="data/ticket_items/color.js"> 1261 <include src="data/ticket_items/copies.js"> 1262 <include src="data/ticket_items/duplex.js"> 1263 <include src="data/ticket_items/header_footer.js"> 1264 <include src="data/ticket_items/media_size.js"> 1265 <include src="data/ticket_items/landscape.js"> 1266 <include src="data/ticket_items/margins_type.js"> 1267 <include src="data/ticket_items/page_range.js"> 1268 <include src="data/ticket_items/fit_to_page.js"> 1269 <include src="data/ticket_items/css_background.js"> 1270 <include src="data/ticket_items/selection_only.js"> 1271 <include src="data/ticket_items/vendor_items.js"> 1272 1273 <include src="native_layer.js"> 1274 <include src="print_preview_animations.js"> 1275 <include src="cloud_print_interface.js"> 1276 <include src="print_preview_utils.js"> 1277 <include src="print_header.js"> 1278 <include src="metrics.js"> 1279 1280 <include src="settings/settings_section.js"> 1281 <include src="settings/page_settings.js"> 1282 <include src="settings/copies_settings.js"> 1283 <include src="settings/media_size_settings.js"> 1284 <include src="settings/layout_settings.js"> 1285 <include src="settings/color_settings.js"> 1286 <include src="settings/margin_settings.js"> 1287 <include src="settings/destination_settings.js"> 1288 <include src="settings/other_options_settings.js"> 1289 <include src="settings/advanced_options_settings.js"> 1290 <include src="settings/advanced_settings/advanced_settings.js"> 1291 <include src="settings/advanced_settings/advanced_settings_item.js"> 1292 <include src="settings/more_settings.js"> 1293 1294 <include src="previewarea/margin_control.js"> 1295 <include src="previewarea/margin_control_container.js"> 1296 <include src="../pdf/pdf_scripting_api.js"> 1297 <include src="previewarea/preview_area.js"> 1298 <include src="preview_generator.js"> 1299 1300 <include src="search/destination_list.js"> 1301 <include src="search/cloud_destination_list.js"> 1302 <include src="search/recent_destination_list.js"> 1303 <include src="search/destination_list_item.js"> 1304 <include src="search/destination_search.js"> 1305 <include src="search/fedex_tos.js"> 1306 1307 window.addEventListener('DOMContentLoaded', function() { 1308 printPreview = new print_preview.PrintPreview(); 1309 printPreview.initialize(); 1310 }); 1311