| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 cr.define('cloudprint', function() { | 5 cr.define('cloudprint', function() { |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * API to the Google Cloud Print service. | 9 * API to the Google Cloud Print service. |
| 10 * @param {string} baseUrl Base part of the Google Cloud Print service URL | 10 * @param {string} baseUrl Base part of the Google Cloud Print service URL |
| 11 * with no trailing slash. For example, | 11 * with no trailing slash. For example, |
| 12 * 'https://www.google.com/cloudprint'. | 12 * 'https://www.google.com/cloudprint'. |
| 13 * @param {!print_preview.NativeLayer} nativeLayer Native layer used to get |
| 14 * Auth2 tokens. |
| 13 * @constructor | 15 * @constructor |
| 14 * @extends {cr.EventTarget} | 16 * @extends {cr.EventTarget} |
| 15 */ | 17 */ |
| 16 function CloudPrintInterface(baseUrl) { | 18 function CloudPrintInterface(baseUrl, nativeLayer) { |
| 17 /** | 19 /** |
| 18 * The base URL of the Google Cloud Print API. | 20 * The base URL of the Google Cloud Print API. |
| 19 * @type {string} | 21 * @type {string} |
| 20 * @private | 22 * @private |
| 21 */ | 23 */ |
| 22 this.baseUrl_ = baseUrl; | 24 this.baseUrl_ = baseUrl; |
| 23 | 25 |
| 24 /** | 26 /** |
| 27 * Used to get Auth2 tokens. |
| 28 * @type {!print_preview.NativeLayer} |
| 29 * @private |
| 30 */ |
| 31 this.nativeLayer_ = nativeLayer; |
| 32 |
| 33 /** |
| 25 * Last received XSRF token. Sent as a parameter in every request. | 34 * Last received XSRF token. Sent as a parameter in every request. |
| 26 * @type {string} | 35 * @type {string} |
| 27 * @private | 36 * @private |
| 28 */ | 37 */ |
| 29 this.xsrfToken_ = ''; | 38 this.xsrfToken_ = ''; |
| 30 | 39 |
| 31 /** | 40 /** |
| 41 * Pending requests delayed until we get access token. |
| 42 * @type {!Array.<!CloudPrintRequest>} |
| 43 * @private |
| 44 */ |
| 45 this.requestQueue_ = []; |
| 46 |
| 47 /** |
| 32 * Number of outstanding cloud destination search requests. | 48 * Number of outstanding cloud destination search requests. |
| 33 * @type {number} | 49 * @type {number} |
| 34 * @private | 50 * @private |
| 35 */ | 51 */ |
| 36 this.outstandingCloudSearchRequestCount_ = 0; | 52 this.outstandingCloudSearchRequestCount_ = 0; |
| 53 |
| 54 /** |
| 55 * Event tracker used to keep track of native layer events. |
| 56 * @type {!EventTracker} |
| 57 * @private |
| 58 */ |
| 59 this.tracker_ = new EventTracker(); |
| 60 |
| 61 this.addEventListeners_(); |
| 37 }; | 62 }; |
| 38 | 63 |
| 39 /** | 64 /** |
| 40 * Event types dispatched by the interface. | 65 * Event types dispatched by the interface. |
| 41 * @enum {string} | 66 * @enum {string} |
| 42 */ | 67 */ |
| 43 CloudPrintInterface.EventType = { | 68 CloudPrintInterface.EventType = { |
| 44 PRINTER_DONE: 'cloudprint.CloudPrintInterface.PRINTER_DONE', | 69 PRINTER_DONE: 'cloudprint.CloudPrintInterface.PRINTER_DONE', |
| 45 PRINTER_FAILED: 'cloudprint.CloudPrintInterface.PRINTER_FAILED', | 70 PRINTER_FAILED: 'cloudprint.CloudPrintInterface.PRINTER_FAILED', |
| 46 SEARCH_DONE: 'cloudprint.CloudPrintInterface.SEARCH_DONE', | 71 SEARCH_DONE: 'cloudprint.CloudPrintInterface.SEARCH_DONE', |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 115 |
| 91 /** | 116 /** |
| 92 * Enumeration of JSON response fields from Google Cloud Print API. | 117 * Enumeration of JSON response fields from Google Cloud Print API. |
| 93 * @enum {string} | 118 * @enum {string} |
| 94 * @private | 119 * @private |
| 95 */ | 120 */ |
| 96 CloudPrintInterface.JsonFields_ = { | 121 CloudPrintInterface.JsonFields_ = { |
| 97 PRINTER: 'printer' | 122 PRINTER: 'printer' |
| 98 }; | 123 }; |
| 99 | 124 |
| 125 /** |
| 126 * Could Print origins used to search printers. |
| 127 * @type {!Array.<!print_preview.Destination.Origin>} |
| 128 * @const |
| 129 * @private |
| 130 */ |
| 131 CloudPrintInterface.CLOUD_ORIGINS_ = [ |
| 132 print_preview.Destination.Origin.COOKIES, |
| 133 print_preview.Destination.Origin.DEVICE |
| 134 // TODO(vitalybuka): Enable when implemented. |
| 135 // ready print_preview.Destination.Origin.PROFILE |
| 136 ]; |
| 137 |
| 100 CloudPrintInterface.prototype = { | 138 CloudPrintInterface.prototype = { |
| 101 __proto__: cr.EventTarget.prototype, | 139 __proto__: cr.EventTarget.prototype, |
| 102 | 140 |
| 103 /** @return {string} Base URL of the Google Cloud Print service. */ | 141 /** @return {string} Base URL of the Google Cloud Print service. */ |
| 104 get baseUrl() { | 142 get baseUrl() { |
| 105 return this.baseUrl_; | 143 return this.baseUrl_; |
| 106 }, | 144 }, |
| 107 | 145 |
| 108 /** | 146 /** |
| 109 * @return {boolean} Whether a search for cloud destinations is in progress. | 147 * @return {boolean} Whether a search for cloud destinations is in progress. |
| 110 */ | 148 */ |
| 111 get isCloudDestinationSearchInProgress() { | 149 get isCloudDestinationSearchInProgress() { |
| 112 return this.outstandingCloudSearchRequestCount_ > 0; | 150 return this.outstandingCloudSearchRequestCount_ > 0; |
| 113 }, | 151 }, |
| 114 | 152 |
| 115 /** | 153 /** |
| 116 * Sends a Google Cloud Print search API request. | 154 * Sends a Google Cloud Print search API request. |
| 117 * @param {boolean} isRecent Whether to search for only recently used | 155 * @param {boolean} isRecent Whether to search for only recently used |
| 118 * printers. | 156 * printers. |
| 119 */ | 157 */ |
| 120 search: function(isRecent) { | 158 search: function(isRecent) { |
| 121 var params = [ | 159 var params = [ |
| 122 new HttpParam('connection_status', 'ALL'), | 160 new HttpParam('connection_status', 'ALL'), |
| 123 new HttpParam('client', 'chrome'), | 161 new HttpParam('client', 'chrome'), |
| 124 new HttpParam('use_cdd', 'true') | 162 new HttpParam('use_cdd', 'true') |
| 125 ]; | 163 ]; |
| 126 if (isRecent) { | 164 if (isRecent) { |
| 127 params.push(new HttpParam('q', '^recent')); | 165 params.push(new HttpParam('q', '^recent')); |
| 128 } | 166 } |
| 129 ++this.outstandingCloudSearchRequestCount_; | 167 CloudPrintInterface.CLOUD_ORIGINS_.forEach(function(origin) { |
| 130 this.sendRequest_('GET', 'search', params, | 168 ++this.outstandingCloudSearchRequestCount_; |
| 131 this.onSearchDone_.bind(this, isRecent)); | 169 var cpRequest = |
| 170 this.buildRequest_('GET', 'search', params, origin, |
| 171 this.onSearchDone_.bind(this, isRecent)); |
| 172 this.sendOrQueueRequest_(cpRequest); |
| 173 }, this); |
| 132 }, | 174 }, |
| 133 | 175 |
| 134 /** | 176 /** |
| 135 * Sends a Google Cloud Print submit API request. | 177 * Sends a Google Cloud Print submit API request. |
| 136 * @param {!print_preview.Destination} destination Cloud destination to | 178 * @param {!print_preview.Destination} destination Cloud destination to |
| 137 * print to. | 179 * print to. |
| 138 * @param {!print_preview.PrintTicketStore} printTicketStore Contains the | 180 * @param {!print_preview.PrintTicketStore} printTicketStore Contains the |
| 139 * print ticket to print. | 181 * print ticket to print. |
| 140 * @param {string} data Base64 encoded data of the document. | 182 * @param {string} data Base64 encoded data of the document. |
| 141 */ | 183 */ |
| 142 submit: function(destination, printTicketStore, data) { | 184 submit: function(destination, printTicketStore, data) { |
| 143 var result = | 185 var result = |
| 144 CloudPrintInterface.VERSION_REGEXP_.exec(navigator.userAgent); | 186 CloudPrintInterface.VERSION_REGEXP_.exec(navigator.userAgent); |
| 145 var chromeVersion = 'unknown'; | 187 var chromeVersion = 'unknown'; |
| 146 if (result && result.length == 2) { | 188 if (result && result.length == 2) { |
| 147 chromeVersion = result[1]; | 189 chromeVersion = result[1]; |
| 148 } | 190 } |
| 149 var params = [ | 191 var params = [ |
| 150 new HttpParam('printerid', destination.id), | 192 new HttpParam('printerid', destination.id), |
| 151 new HttpParam('contentType', 'dataUrl'), | 193 new HttpParam('contentType', 'dataUrl'), |
| 152 new HttpParam('title', printTicketStore.getDocumentTitle()), | 194 new HttpParam('title', printTicketStore.getDocumentTitle()), |
| 153 new HttpParam('ticket', | 195 new HttpParam('ticket', |
| 154 this.createPrintTicket_(destination, printTicketStore)), | 196 this.createPrintTicket_(destination, printTicketStore)), |
| 155 new HttpParam('content', 'data:application/pdf;base64,' + data), | 197 new HttpParam('content', 'data:application/pdf;base64,' + data), |
| 156 new HttpParam('tag', | 198 new HttpParam('tag', |
| 157 '__google__chrome_version=' + chromeVersion), | 199 '__google__chrome_version=' + chromeVersion), |
| 158 new HttpParam('tag', '__google__os=' + navigator.platform) | 200 new HttpParam('tag', '__google__os=' + navigator.platform) |
| 159 ]; | 201 ]; |
| 160 this.sendRequest_('POST', 'submit', params, | 202 var cpRequest = this.buildRequest_('POST', 'submit', params, |
| 161 this.onSubmitDone_.bind(this)); | 203 destination.origin, |
| 204 this.onSubmitDone_.bind(this)); |
| 205 this.sendOrQueueRequest_(cpRequest); |
| 162 }, | 206 }, |
| 163 | 207 |
| 164 /** | 208 /** |
| 165 * Sends a Google Cloud Print printer API request. | 209 * Sends a Google Cloud Print printer API request. |
| 166 * @param {string} printerId ID of the printer to lookup. | 210 * @param {string} printerId ID of the printer to lookup. |
| 211 * @param {!print_preview.Destination.Origin} origin Origin of the printer. |
| 167 */ | 212 */ |
| 168 printer: function(printerId) { | 213 printer: function(printerId, origin) { |
| 169 var params = [ | 214 var params = [ |
| 170 new HttpParam('printerid', printerId), | 215 new HttpParam('printerid', printerId), |
| 171 new HttpParam('use_cdd', 'true') | 216 new HttpParam('use_cdd', 'true') |
| 172 ]; | 217 ]; |
| 173 this.sendRequest_('GET', 'printer', params, | 218 var cpRequest = |
| 174 this.onPrinterDone_.bind(this, printerId)); | 219 this.buildRequest_('GET', 'printer', params, origin, |
| 220 this.onPrinterDone_.bind(this, printerId)); |
| 221 this.sendOrQueueRequest_(cpRequest); |
| 175 }, | 222 }, |
| 176 | 223 |
| 177 /** | 224 /** |
| 178 * Sends a Google Cloud Print update API request to accept (or reject) the | 225 * Sends a Google Cloud Print update API request to accept (or reject) the |
| 179 * terms-of-service of the given printer. | 226 * terms-of-service of the given printer. |
| 180 * @param {string} printerId ID of the printer to accept the | 227 * @param {string} printerId ID of the printer to accept the |
| 181 * terms-of-service for. | 228 * terms-of-service for. |
| 229 * @param {!print_preview.Destination.Origin} origin Origin of the printer. |
| 182 * @param {boolean} isAccepted Whether the user accepted the | 230 * @param {boolean} isAccepted Whether the user accepted the |
| 183 * terms-of-service. | 231 * terms-of-service. |
| 184 */ | 232 */ |
| 185 updatePrinterTosAcceptance: function(printerId, isAccepted) { | 233 updatePrinterTosAcceptance: function(printerId, origin, isAccepted) { |
| 186 var params = [ | 234 var params = [ |
| 187 new HttpParam('printerid', printerId), | 235 new HttpParam('printerid', printerId), |
| 188 new HttpParam('is_tos_accepted', isAccepted) | 236 new HttpParam('is_tos_accepted', isAccepted) |
| 189 ]; | 237 ]; |
| 190 this.sendRequest_('POST', 'update', params, | 238 var cpRequest = |
| 191 this.onUpdatePrinterTosAcceptanceDone_.bind(this)); | 239 this.buildRequest_('POST', 'update', params, origin, |
| 240 this.onUpdatePrinterTosAcceptanceDone_.bind(this)); |
| 241 this.sendOrQueueRequest_(cpRequest); |
| 192 }, | 242 }, |
| 193 | 243 |
| 194 /** | 244 /** |
| 245 * Adds event listeners to the relevant native layer events. |
| 246 * @private |
| 247 */ |
| 248 addEventListeners_: function() { |
| 249 this.tracker_.add( |
| 250 this.nativeLayer_, |
| 251 print_preview.NativeLayer.EventType.ACCESS_TOKEN_READY, |
| 252 this.onAccessTokenReady_.bind(this)); |
| 253 }, |
| 254 |
| 255 /** |
| 195 * Creates an object that represents a Google Cloud Print print ticket. | 256 * Creates an object that represents a Google Cloud Print print ticket. |
| 196 * @param {!print_preview.Destination} destination Destination to print to. | 257 * @param {!print_preview.Destination} destination Destination to print to. |
| 197 * @param {!print_preview.PrintTicketStore} printTicketStore Used to create | 258 * @param {!print_preview.PrintTicketStore} printTicketStore Used to create |
| 198 * the state of the print ticket. | 259 * the state of the print ticket. |
| 199 * @return {!Object} Google Cloud Print print ticket. | 260 * @return {!Object} Google Cloud Print print ticket. |
| 200 * @private | 261 * @private |
| 201 */ | 262 */ |
| 202 createPrintTicket_: function(destination, printTicketStore) { | 263 createPrintTicket_: function(destination, printTicketStore) { |
| 203 assert(!destination.isLocal, | 264 assert(!destination.isLocal, |
| 204 'Trying to create a Google Cloud Print print ticket for a local ' + | 265 'Trying to create a Google Cloud Print print ticket for a local ' + |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 {type: pts.isDuplexEnabled() ? 'LONG_EDGE' : 'NO_DUPLEX'}; | 300 {type: pts.isDuplexEnabled() ? 'LONG_EDGE' : 'NO_DUPLEX'}; |
| 240 } | 301 } |
| 241 if (pts.hasOrientationCapability()) { | 302 if (pts.hasOrientationCapability()) { |
| 242 cjt.print.page_orientation = | 303 cjt.print.page_orientation = |
| 243 {type: pts.isLandscapeEnabled() ? 'LANDSCAPE' : 'PORTRAIT'}; | 304 {type: pts.isLandscapeEnabled() ? 'LANDSCAPE' : 'PORTRAIT'}; |
| 244 } | 305 } |
| 245 return JSON.stringify(cjt); | 306 return JSON.stringify(cjt); |
| 246 }, | 307 }, |
| 247 | 308 |
| 248 /** | 309 /** |
| 249 * Sends a request to the Google Cloud Print API. | 310 * Builds request to the Google Cloud Print API. |
| 250 * @param {string} method HTTP method of the request. | 311 * @param {string} method HTTP method of the request. |
| 251 * @param {string} action Google Cloud Print action to perform. | 312 * @param {string} action Google Cloud Print action to perform. |
| 252 * @param {Array.<!HttpParam>} params HTTP parameters to include in the | 313 * @param {Array.<!HttpParam>} params HTTP parameters to include in the |
| 253 * request. | 314 * request. |
| 254 * @param {function(number, Object)} callback Callback to invoke when | 315 * @param {!print_preview.Destination.Origin} origin Origin for destination. |
| 255 * request completes. | 316 * @param {function(number, Object, !print_preview.Destination.Origin)} |
| 317 * callback Callback to invoke when request completes. |
| 318 * @return {!CloudPrintRequest} Partially prepared request. |
| 319 * @private |
| 256 */ | 320 */ |
| 257 sendRequest_: function(method, action, params, callback) { | 321 buildRequest_: function(method, action, params, origin, callback) { |
| 258 if (!this.xsrfToken_) { | 322 var url = this.baseUrl_ + '/' + action + '?xsrf='; |
| 259 // TODO(rltoscano): Should throw an error if not a read-only action or | 323 if (origin == print_preview.Destination.Origin.COOKIES) { |
| 260 // issue an xsrf token request. | 324 if (!this.xsrfToken_) { |
| 325 // TODO(rltoscano): Should throw an error if not a read-only action or |
| 326 // issue an xsrf token request. |
| 327 } else { |
| 328 url = url + this.xsrfToken_; |
| 329 } |
| 261 } | 330 } |
| 262 var url = this.baseUrl_ + '/' + action + '?xsrf=' + this.xsrfToken_; | |
| 263 var body = null; | 331 var body = null; |
| 264 | |
| 265 if (params) { | 332 if (params) { |
| 266 if (method == 'GET') { | 333 if (method == 'GET') { |
| 267 url = params.reduce(function(partialUrl, param) { | 334 url = params.reduce(function(partialUrl, param) { |
| 268 return partialUrl + '&' + param.name + '=' + | 335 return partialUrl + '&' + param.name + '=' + |
| 269 encodeURIComponent(param.value); | 336 encodeURIComponent(param.value); |
| 270 }, url); | 337 }, url); |
| 271 } else if (method == 'POST') { | 338 } else if (method == 'POST') { |
| 272 body = params.reduce(function(partialBody, param) { | 339 body = params.reduce(function(partialBody, param) { |
| 273 return partialBody + 'Content-Disposition: form-data; name=\"' + | 340 return partialBody + 'Content-Disposition: form-data; name=\"' + |
| 274 param.name + '\"\r\n\r\n' + param.value + '\r\n--' + | 341 param.name + '\"\r\n\r\n' + param.value + '\r\n--' + |
| 275 CloudPrintInterface.MULTIPART_BOUNDARY_ + '\r\n'; | 342 CloudPrintInterface.MULTIPART_BOUNDARY_ + '\r\n'; |
| 276 }, '--' + CloudPrintInterface.MULTIPART_BOUNDARY_ + '\r\n'); | 343 }, '--' + CloudPrintInterface.MULTIPART_BOUNDARY_ + '\r\n'); |
| 277 } | 344 } |
| 278 } | 345 } |
| 279 | 346 |
| 280 var headers = {}; | 347 var headers = {}; |
| 281 headers['X-CloudPrint-Proxy'] = 'ChromePrintPreview'; | 348 headers['X-CloudPrint-Proxy'] = 'ChromePrintPreview'; |
| 282 if (method == 'GET') { | 349 if (method == 'GET') { |
| 283 headers['Content-Type'] = CloudPrintInterface.URL_ENCODED_CONTENT_TYPE_; | 350 headers['Content-Type'] = CloudPrintInterface.URL_ENCODED_CONTENT_TYPE_; |
| 284 } else if (method == 'POST') { | 351 } else if (method == 'POST') { |
| 285 headers['Content-Type'] = CloudPrintInterface.MULTIPART_CONTENT_TYPE_; | 352 headers['Content-Type'] = CloudPrintInterface.MULTIPART_CONTENT_TYPE_; |
| 286 } | 353 } |
| 287 | 354 |
| 288 var xhr = new XMLHttpRequest(); | 355 var xhr = new XMLHttpRequest(); |
| 289 xhr.onreadystatechange = | |
| 290 this.onReadyStateChange_.bind(this, xhr, callback); | |
| 291 xhr.open(method, url, true); | 356 xhr.open(method, url, true); |
| 292 xhr.withCredentials = true; | 357 xhr.withCredentials = |
| 358 (origin == print_preview.Destination.Origin.COOKIES); |
| 293 for (var header in headers) { | 359 for (var header in headers) { |
| 294 xhr.setRequestHeader(header, headers[header]); | 360 xhr.setRequestHeader(header, headers[header]); |
| 295 } | 361 } |
| 296 xhr.send(body); | 362 |
| 363 return new CloudPrintRequest(xhr, body, origin, callback); |
| 364 }, |
| 365 |
| 366 /** |
| 367 * Sends a request to the Google Cloud Print API or queues if it needs to |
| 368 * wait OAuth2 access token. |
| 369 * @param {!CloudPrintRequest} request Request to send or queue. |
| 370 * @private |
| 371 */ |
| 372 sendOrQueueRequest_: function(request) { |
| 373 if (request.origin == print_preview.Destination.Origin.COOKIES) { |
| 374 return this.sendRequest_(request); |
| 375 } else { |
| 376 this.requestQueue_.push(request); |
| 377 this.nativeLayer_.startGetAccessToken(request.origin); |
| 378 } |
| 379 }, |
| 380 |
| 381 /** |
| 382 * Sends a request to the Google Cloud Print API. |
| 383 * @param {!CloudPrintRequest} request Request to send. |
| 384 * @private |
| 385 */ |
| 386 sendRequest_: function(request) { |
| 387 request.xhr.onreadystatechange = |
| 388 this.onReadyStateChange_.bind(this, request); |
| 389 request.xhr.send(request.body); |
| 297 }, | 390 }, |
| 298 | 391 |
| 299 /** | 392 /** |
| 300 * Creates a Google Cloud Print interface error that is ready to dispatch. | 393 * Creates a Google Cloud Print interface error that is ready to dispatch. |
| 301 * @param {!CloudPrintInterface.EventType} type Type of the error. | 394 * @param {!CloudPrintInterface.EventType} type Type of the error. |
| 302 * @param {number} status HTTP status code of the failed request. | 395 * @param {!CloudPrintRequest} request Request that has been completed. |
| 303 * @param {Object} result JSON response of the request. {@code null} if | |
| 304 * status was not 200. | |
| 305 * @return {!cr.Event} Google Cloud Print interface error event. | 396 * @return {!cr.Event} Google Cloud Print interface error event. |
| 306 * @private | 397 * @private |
| 307 */ | 398 */ |
| 308 createErrorEvent_: function(type, status, result) { | 399 createErrorEvent_: function(type, request) { |
| 309 var errorEvent = new cr.Event(type); | 400 var errorEvent = new cr.Event(type); |
| 310 errorEvent.status = status; | 401 errorEvent.status = request.xhr.status; |
| 311 errorEvent.errorCode = status == 200 ? result['errorCode'] : 0; | 402 if (request.xhr.status == 200) { |
| 312 errorEvent.message = status == 200 ? result['message'] : ''; | 403 errorEvent.errorCode = request.result['errorCode']; |
| 404 errorEvent.message = request.result['message']; |
| 405 } else { |
| 406 errorEvent.errorCode = 0; |
| 407 errorEvent.message = ''; |
| 408 } |
| 409 errorEvent.origin = request.origin; |
| 313 return errorEvent; | 410 return errorEvent; |
| 314 }, | 411 }, |
| 315 | 412 |
| 316 /** | 413 /** |
| 414 * Called when a native layer receives access token. |
| 415 * @param {cr.Event} evt Contains the authetication type and access token. |
| 416 * @private |
| 417 */ |
| 418 onAccessTokenReady_: function(event) { |
| 419 // TODO(vitalybuka): remove when other Origins implemented. |
| 420 assert(event.authType == print_preview.Destination.Origin.DEVICE); |
| 421 this.requestQueue_ = this.requestQueue_.filter(function(request) { |
| 422 assert(request.origin == print_preview.Destination.Origin.DEVICE); |
| 423 if (request.origin != event.authType) { |
| 424 return true; |
| 425 } |
| 426 if (event.accessToken) { |
| 427 request.xhr.setRequestHeader('Authorization', |
| 428 'Bearer ' + event.accessToken); |
| 429 this.sendRequest_(request); |
| 430 } else { // No valid token. |
| 431 // Without abort status does not exists. |
| 432 request.xhr.abort(); |
| 433 request.callback(request); |
| 434 } |
| 435 return false; |
| 436 }, this); |
| 437 }, |
| 438 |
| 439 /** |
| 317 * Called when the ready-state of a XML http request changes. | 440 * Called when the ready-state of a XML http request changes. |
| 318 * Calls the successCallback with the result or dispatches an ERROR event. | 441 * Calls the successCallback with the result or dispatches an ERROR event. |
| 319 * @param {XMLHttpRequest} xhr XML http request that changed. | 442 * @param {!CloudPrintRequest} request Request that was changed. |
| 320 * @param {function(number, Object)} callback Callback to invoke when | |
| 321 * request completes. | |
| 322 * @private | 443 * @private |
| 323 */ | 444 */ |
| 324 onReadyStateChange_: function(xhr, callback) { | 445 onReadyStateChange_: function(request) { |
| 325 if (xhr.readyState == 4) { | 446 if (request.xhr.readyState == 4) { |
| 326 if (xhr.status == 200) { | 447 if (request.xhr.status == 200) { |
| 327 var result = JSON.parse(xhr.responseText); | 448 request.result = JSON.parse(request.xhr.responseText); |
| 328 if (result['success']) { | 449 if (request.origin == print_preview.Destination.Origin.COOKIES && |
| 329 this.xsrfToken_ = result['xsrf_token']; | 450 request.result['success']) { |
| 451 this.xsrfToken_ = request.result['xsrf_token']; |
| 330 } | 452 } |
| 331 } | 453 } |
| 332 callback(xhr.status, result); | 454 request.status = request.xhr.status; |
| 455 request.callback(request); |
| 333 } | 456 } |
| 334 }, | 457 }, |
| 335 | 458 |
| 336 /** | 459 /** |
| 337 * Called when the search request completes. | 460 * Called when the search request completes. |
| 338 * @param {boolean} isRecent Whether the search request was for recent | 461 * @param {boolean} isRecent Whether the search request was for recent |
| 339 * destinations. | 462 * destinations. |
| 340 * @param {number} status Status of the HTTP request. | 463 * @param {!CloudPrintRequest} request Request that has been completed. |
| 341 * @param {Object} result JSON response. | |
| 342 * @private | 464 * @private |
| 343 */ | 465 */ |
| 344 onSearchDone_: function(isRecent, status, result) { | 466 onSearchDone_: function(isRecent, request) { |
| 345 --this.outstandingCloudSearchRequestCount_; | 467 --this.outstandingCloudSearchRequestCount_; |
| 346 if (status == 200 && result['success']) { | 468 if (request.xhr.status == 200 && request.result['success']) { |
| 347 var printerListJson = result['printers'] || []; | 469 var printerListJson = request.result['printers'] || []; |
| 348 var printerList = []; | 470 var printerList = []; |
| 349 printerListJson.forEach(function(printerJson) { | 471 printerListJson.forEach(function(printerJson) { |
| 350 try { | 472 try { |
| 351 printerList.push( | 473 printerList.push( |
| 352 cloudprint.CloudDestinationParser.parse( | 474 cloudprint.CloudDestinationParser.parse(printerJson, |
| 353 printerJson, print_preview.Destination.Origin.COOKIES)); | 475 request.origin)); |
| 354 } catch (err) { | 476 } catch (err) { |
| 355 console.error('Unable to parse cloud print destination: ' + err); | 477 console.error('Unable to parse cloud print destination: ' + err); |
| 356 } | 478 } |
| 357 }); | 479 }); |
| 358 var searchDoneEvent = | 480 var searchDoneEvent = |
| 359 new cr.Event(CloudPrintInterface.EventType.SEARCH_DONE); | 481 new cr.Event(CloudPrintInterface.EventType.SEARCH_DONE); |
| 360 searchDoneEvent.printers = printerList; | 482 searchDoneEvent.printers = printerList; |
| 483 searchDoneEvent.origin = request.origin; |
| 361 searchDoneEvent.isRecent = isRecent; | 484 searchDoneEvent.isRecent = isRecent; |
| 362 searchDoneEvent.email = result['request']['user']; | 485 searchDoneEvent.email = request.result['request']['user']; |
| 363 this.dispatchEvent(searchDoneEvent); | 486 this.dispatchEvent(searchDoneEvent); |
| 364 } else { | 487 } else { |
| 365 var errorEvent = this.createErrorEvent_( | 488 var errorEvent = this.createErrorEvent_( |
| 366 CloudPrintInterface.EventType.SEARCH_FAILED, status, result); | 489 CloudPrintInterface.EventType.SEARCH_FAILED, request); |
| 367 this.dispatchEvent(errorEvent); | 490 this.dispatchEvent(errorEvent); |
| 368 } | 491 } |
| 369 }, | 492 }, |
| 370 | 493 |
| 371 /** | 494 /** |
| 372 * Called when the submit request completes. | 495 * Called when the submit request completes. |
| 373 * @param {number} status Status of the HTTP request. | 496 * @param {!CloudPrintRequest} request Request that has been completed. |
| 374 * @param {Object} result JSON response. | |
| 375 * @private | 497 * @private |
| 376 */ | 498 */ |
| 377 onSubmitDone_: function(status, result) { | 499 onSubmitDone_: function(request) { |
| 378 if (status == 200 && result['success']) { | 500 if (request.xhr.status == 200 && request.result['success']) { |
| 379 var submitDoneEvent = new cr.Event( | 501 var submitDoneEvent = new cr.Event( |
| 380 CloudPrintInterface.EventType.SUBMIT_DONE); | 502 CloudPrintInterface.EventType.SUBMIT_DONE); |
| 381 submitDoneEvent.jobId = result['job']['id']; | 503 submitDoneEvent.jobId = result['job']['id']; |
| 382 this.dispatchEvent(submitDoneEvent); | 504 this.dispatchEvent(submitDoneEvent); |
| 383 } else { | 505 } else { |
| 384 var errorEvent = this.createErrorEvent_( | 506 var errorEvent = this.createErrorEvent_( |
| 385 CloudPrintInterface.EventType.SUBMIT_FAILED, status, result); | 507 CloudPrintInterface.EventType.SUBMIT_FAILED, request); |
| 386 this.dispatchEvent(errorEvent); | 508 this.dispatchEvent(errorEvent); |
| 387 } | 509 } |
| 388 }, | 510 }, |
| 389 | 511 |
| 390 /** | 512 /** |
| 391 * Called when the printer request completes. | 513 * Called when the printer request completes. |
| 392 * @param {string} destinationId ID of the destination that was looked up. | 514 * @param {string} destinationId ID of the destination that was looked up. |
| 393 * @param {number} status Status of the HTTP request. | 515 * @param {!CloudPrintRequest} request Request that has been completed. |
| 394 * @param {Object} result JSON response. | |
| 395 * @private | 516 * @private |
| 396 */ | 517 */ |
| 397 onPrinterDone_: function(destinationId, status, result) { | 518 onPrinterDone_: function(destinationId, request) { |
| 398 if (status == 200 && result['success']) { | 519 if (request.xhr.status == 200 && request.result['success']) { |
| 399 var printerJson = result['printers'][0]; | 520 var printerJson = request.result['printers'][0]; |
| 400 var printer; | 521 var printer; |
| 401 try { | 522 try { |
| 402 printer = cloudprint.CloudDestinationParser.parse( | 523 printer = cloudprint.CloudDestinationParser.parse(printerJson, |
| 403 printerJson, print_preview.Destination.Origin.COOKIES); | 524 request.origin); |
| 404 } catch (err) { | 525 } catch (err) { |
| 405 console.error('Failed to parse cloud print destination: ' + | 526 console.error('Failed to parse cloud print destination: ' + |
| 406 JSON.stringify(printerJson)); | 527 JSON.stringify(printerJson)); |
| 407 return; | 528 return; |
| 408 } | 529 } |
| 409 var printerDoneEvent = | 530 var printerDoneEvent = |
| 410 new cr.Event(CloudPrintInterface.EventType.PRINTER_DONE); | 531 new cr.Event(CloudPrintInterface.EventType.PRINTER_DONE); |
| 411 printerDoneEvent.printer = printer; | 532 printerDoneEvent.printer = printer; |
| 412 this.dispatchEvent(printerDoneEvent); | 533 this.dispatchEvent(printerDoneEvent); |
| 413 } else { | 534 } else { |
| 414 var errorEvent = this.createErrorEvent_( | 535 var errorEvent = this.createErrorEvent_( |
| 415 CloudPrintInterface.EventType.PRINTER_FAILED, status, result); | 536 CloudPrintInterface.EventType.PRINTER_FAILED, request); |
| 416 errorEvent.destinationId = destinationId; | 537 errorEvent.destinationId = destinationId; |
| 417 errorEvent.destinationOrigin = print_preview.Destination.Origin.COOKIES; | 538 errorEvent.destinationOrigin = request.origin; |
| 418 this.dispatchEvent(errorEvent); | 539 this.dispatchEvent(errorEvent, request.origin); |
| 419 } | 540 } |
| 420 }, | 541 }, |
| 421 | 542 |
| 422 /** | 543 /** |
| 423 * Called when the update printer TOS acceptance request completes. | 544 * Called when the update printer TOS acceptance request completes. |
| 424 * @param {number} status Status of the HTTP request. | 545 * @param {!CloudPrintRequest} request Request that has been completed. |
| 425 * @param {Object} result JSON response. | |
| 426 * @private | 546 * @private |
| 427 */ | 547 */ |
| 428 onUpdatePrinterTosAcceptanceDone_: function(status, result) { | 548 onUpdatePrinterTosAcceptanceDone_: function(request) { |
| 429 if (status == 200 && result['success']) { | 549 if (request.xhr.status == 200 && request.result['success']) { |
| 430 // Do nothing. | 550 // Do nothing. |
| 431 } else { | 551 } else { |
| 432 var errorEvent = this.createErrorEvent_( | 552 var errorEvent = this.createErrorEvent_( |
| 433 CloudPrintInterface.EventType.SUBMIT_FAILED, status, result); | 553 CloudPrintInterface.EventType.SUBMIT_FAILED, request); |
| 434 this.dispatchEvent(errorEvent); | 554 this.dispatchEvent(errorEvent); |
| 435 } | 555 } |
| 436 } | 556 } |
| 437 }; | 557 }; |
| 438 | 558 |
| 439 /** | 559 /** |
| 560 * Data structure that holds data for Cloud Print requests. |
| 561 * @param {!XMLHttpRequest} xhr Partially prepared http request. |
| 562 * @param {string} body Data to send with POST requests. |
| 563 * @param {!print_preview.Destination.Origin} origin Origin for destination. |
| 564 * @param {function(!CloudPrintRequest)} callback Callback to invoke when |
| 565 * request completes. |
| 566 * @constructor |
| 567 */ |
| 568 function CloudPrintRequest(xhr, body, origin, callback) { |
| 569 /** |
| 570 * Partially prepared http request. |
| 571 * @type {!XMLHttpRequest} |
| 572 */ |
| 573 this.xhr = xhr; |
| 574 |
| 575 /** |
| 576 * Data to send with POST requests. |
| 577 * @type {string} |
| 578 */ |
| 579 this.body = body; |
| 580 |
| 581 /** |
| 582 * Origin for destination. |
| 583 * @type {!print_preview.Destination.Origin} |
| 584 */ |
| 585 this.origin = origin; |
| 586 |
| 587 /** |
| 588 * Callback to invoke when request completes. |
| 589 * @type {function(!CloudPrintRequest)} |
| 590 */ |
| 591 this.callback = callback; |
| 592 |
| 593 /** |
| 594 * Result for requests. |
| 595 * @type {Object} JSON response. |
| 596 */ |
| 597 this.result = null; |
| 598 }; |
| 599 |
| 600 /** |
| 440 * Data structure that represents an HTTP parameter. | 601 * Data structure that represents an HTTP parameter. |
| 441 * @param {string} name Name of the parameter. | 602 * @param {string} name Name of the parameter. |
| 442 * @param {string} value Value of the parameter. | 603 * @param {string} value Value of the parameter. |
| 443 * @constructor | 604 * @constructor |
| 444 */ | 605 */ |
| 445 function HttpParam(name, value) { | 606 function HttpParam(name, value) { |
| 446 /** | 607 /** |
| 447 * Name of the parameter. | 608 * Name of the parameter. |
| 448 * @type {string} | 609 * @type {string} |
| 449 */ | 610 */ |
| 450 this.name = name; | 611 this.name = name; |
| 451 | 612 |
| 452 /** | 613 /** |
| 453 * Name of the value. | 614 * Name of the value. |
| 454 * @type {string} | 615 * @type {string} |
| 455 */ | 616 */ |
| 456 this.value = value; | 617 this.value = value; |
| 457 }; | 618 }; |
| 458 | 619 |
| 459 // Export | 620 // Export |
| 460 return { | 621 return { |
| 461 CloudPrintInterface: CloudPrintInterface | 622 CloudPrintInterface: CloudPrintInterface |
| 462 }; | 623 }; |
| 463 }); | 624 }); |
| OLD | NEW |