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