Chromium Code Reviews| 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 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 | 40 |
| 41 /** | 41 /** |
| 42 * Currently logged in users (identified by email) mapped to the Google | 42 * Currently logged in users (identified by email) mapped to the Google |
| 43 * session index. | 43 * session index. |
| 44 * @type {!Object.<string, number>} | 44 * @type {!Object.<string, number>} |
| 45 * @private | 45 * @private |
| 46 */ | 46 */ |
| 47 this.userSessionIndex_ = {}; | 47 this.userSessionIndex_ = {}; |
| 48 | 48 |
| 49 /** | 49 /** |
| 50 * Last received XSRF token. Sent as a parameter in every request. | 50 * Stores last received XSRF tokens for each user account. Sent as |
| 51 * @type {string} | 51 * a parameter with every request. |
| 52 * @type {!Object.<string, string>} | |
| 52 * @private | 53 * @private |
| 53 */ | 54 */ |
| 54 this.xsrfToken_ = ''; | 55 this.xsrfTokens_ = {}; |
| 55 | 56 |
| 56 /** | 57 /** |
| 57 * Pending requests delayed until we get access token. | 58 * Pending requests delayed until we get access token. |
| 58 * @type {!Array.<!CloudPrintRequest>} | 59 * @type {!Array.<!CloudPrintRequest>} |
| 59 * @private | 60 * @private |
| 60 */ | 61 */ |
| 61 this.requestQueue_ = []; | 62 this.requestQueue_ = []; |
| 62 | 63 |
| 63 /** | 64 /** |
| 64 * Outstanding cloud destination search requests. | 65 * Outstanding cloud destination search requests. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 | 169 |
| 169 /** | 170 /** |
| 170 * Sends Google Cloud Print search API request. | 171 * Sends Google Cloud Print search API request. |
| 171 * @param {print_preview.Destination.Origin=} opt_origin When specified, | 172 * @param {print_preview.Destination.Origin=} opt_origin When specified, |
| 172 * searches destinations for {@code opt_origin} only, otherwise starts | 173 * searches destinations for {@code opt_origin} only, otherwise starts |
| 173 * searches for all origins. | 174 * searches for all origins. |
| 174 */ | 175 */ |
| 175 search: function(opt_origin) { | 176 search: function(opt_origin) { |
| 176 var origins = | 177 var origins = |
| 177 opt_origin && [opt_origin] || CloudPrintInterface.CLOUD_ORIGINS_; | 178 opt_origin && [opt_origin] || CloudPrintInterface.CLOUD_ORIGINS_; |
| 178 // Terminate outstanding search requests for all requested origins. | 179 this.abortSearchRequests_(origins); |
| 179 this.outstandingCloudSearchRequests_ = | |
| 180 this.outstandingCloudSearchRequests_.filter(function(request) { | |
| 181 if (origins.indexOf(request.origin) >= 0) { | |
| 182 request.xhr.abort(); | |
| 183 return false; | |
| 184 } | |
| 185 return true; | |
| 186 }); | |
| 187 this.search_(true, origins); | 180 this.search_(true, origins); |
| 188 this.search_(false, origins); | 181 this.search_(false, origins); |
| 189 }, | 182 }, |
| 190 | 183 |
| 191 /** | 184 /** |
| 192 * Sends Google Cloud Print search API requests. | 185 * Sends Google Cloud Print search API requests. |
| 193 * @param {boolean} isRecent Whether to search for only recently used | 186 * @param {boolean} isRecent Whether to search for only recently used |
| 194 * printers. | 187 * printers. |
| 195 * @param {!Array.<!print_preview.Destination.Origin>} origins Origins to | 188 * @param {!Array.<!print_preview.Destination.Origin>} origins Origins to |
| 196 * search printers for. | 189 * search printers for. |
| 197 * @private | 190 * @private |
| 198 */ | 191 */ |
| 199 search_: function(isRecent, origins) { | 192 search_: function(isRecent, origins) { |
| 200 var params = [ | 193 var params = [ |
| 201 new HttpParam('connection_status', 'ALL'), | 194 new HttpParam('connection_status', 'ALL'), |
| 202 new HttpParam('client', 'chrome'), | 195 new HttpParam('client', 'chrome'), |
| 203 new HttpParam('use_cdd', 'true') | 196 new HttpParam('use_cdd', 'true') |
| 204 ]; | 197 ]; |
| 205 if (isRecent) { | 198 if (isRecent) { |
| 206 params.push(new HttpParam('q', '^recent')); | 199 params.push(new HttpParam('q', '^recent')); |
| 207 } | 200 } |
| 208 origins.forEach(function(origin) { | 201 origins.forEach(function(origin) { |
| 209 var cpRequest = | 202 var cpRequest = this.buildRequest_( |
| 210 this.buildRequest_('GET', 'search', params, origin, | 203 'GET', |
| 211 this.onSearchDone_.bind(this, isRecent)); | 204 'search', |
| 205 params, | |
| 206 origin, | |
| 207 this.userInfo_.activeUser, | |
|
Toscano
2014/04/11 04:24:00
Hmm, seems like a hidden contract that the search
Aleksey Shlyapnikov
2014/04/11 19:09:29
Done.
| |
| 208 this.onSearchDone_.bind(this, isRecent)); | |
| 212 this.outstandingCloudSearchRequests_.push(cpRequest); | 209 this.outstandingCloudSearchRequests_.push(cpRequest); |
| 213 this.sendOrQueueRequest_(cpRequest); | 210 this.sendOrQueueRequest_(cpRequest); |
| 214 }, this); | 211 }, this); |
| 215 }, | 212 }, |
| 216 | 213 |
| 217 /** | 214 /** |
| 218 * Sends a Google Cloud Print submit API request. | 215 * Sends a Google Cloud Print submit API request. |
| 219 * @param {!print_preview.Destination} destination Cloud destination to | 216 * @param {!print_preview.Destination} destination Cloud destination to |
| 220 * print to. | 217 * print to. |
| 221 * @param {!print_preview.PrintTicketStore} printTicketStore Contains the | 218 * @param {!print_preview.PrintTicketStore} printTicketStore Contains the |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 234 new HttpParam('printerid', destination.id), | 231 new HttpParam('printerid', destination.id), |
| 235 new HttpParam('contentType', 'dataUrl'), | 232 new HttpParam('contentType', 'dataUrl'), |
| 236 new HttpParam('title', documentInfo.title), | 233 new HttpParam('title', documentInfo.title), |
| 237 new HttpParam('ticket', | 234 new HttpParam('ticket', |
| 238 printTicketStore.createPrintTicket(destination)), | 235 printTicketStore.createPrintTicket(destination)), |
| 239 new HttpParam('content', 'data:application/pdf;base64,' + data), | 236 new HttpParam('content', 'data:application/pdf;base64,' + data), |
| 240 new HttpParam('tag', | 237 new HttpParam('tag', |
| 241 '__google__chrome_version=' + chromeVersion), | 238 '__google__chrome_version=' + chromeVersion), |
| 242 new HttpParam('tag', '__google__os=' + navigator.platform) | 239 new HttpParam('tag', '__google__os=' + navigator.platform) |
| 243 ]; | 240 ]; |
| 244 var cpRequest = this.buildRequest_('POST', 'submit', params, | 241 var cpRequest = this.buildRequest_( |
| 245 destination.origin, | 242 'POST', |
| 246 this.onSubmitDone_.bind(this)); | 243 'submit', |
| 244 params, | |
| 245 destination.origin, | |
| 246 destination.account, | |
| 247 this.onSubmitDone_.bind(this)); | |
| 247 this.sendOrQueueRequest_(cpRequest); | 248 this.sendOrQueueRequest_(cpRequest); |
| 248 }, | 249 }, |
| 249 | 250 |
| 250 /** | 251 /** |
| 251 * Sends a Google Cloud Print printer API request. | 252 * Sends a Google Cloud Print printer API request. |
| 252 * @param {string} printerId ID of the printer to lookup. | 253 * @param {string} printerId ID of the printer to lookup. |
| 253 * @param {!print_preview.Destination.Origin} origin Origin of the printer. | 254 * @param {!print_preview.Destination.Origin} origin Origin of the printer. |
| 255 * @param {string=} account Account this printer is registered for. When | |
| 256 * provided for COOKIES {@code origin}, and users sessions are still not | |
| 257 * known, will be checked against the response (both success and failure | |
| 258 * to get printer) and, if the active user account is not the one | |
| 259 * requested, {@code account} is activated and printer request reissued. | |
| 254 */ | 260 */ |
| 255 printer: function(printerId, origin) { | 261 printer: function(printerId, origin, account) { |
| 256 var params = [ | 262 var params = [ |
| 257 new HttpParam('printerid', printerId), | 263 new HttpParam('printerid', printerId), |
| 258 new HttpParam('use_cdd', 'true'), | 264 new HttpParam('use_cdd', 'true'), |
| 259 new HttpParam('printer_connection_status', 'true') | 265 new HttpParam('printer_connection_status', 'true') |
| 260 ]; | 266 ]; |
| 261 var cpRequest = | 267 this.sendOrQueueRequest_(this.buildRequest_( |
| 262 this.buildRequest_('GET', 'printer', params, origin, | 268 'GET', |
| 263 this.onPrinterDone_.bind(this, printerId)); | 269 'printer', |
| 264 this.sendOrQueueRequest_(cpRequest); | 270 params, |
| 271 origin, | |
| 272 account, | |
| 273 this.onPrinterDone_.bind(this, printerId))); | |
| 265 }, | 274 }, |
| 266 | 275 |
| 267 /** | 276 /** |
| 268 * Sends a Google Cloud Print update API request to accept (or reject) the | 277 * Sends a Google Cloud Print update API request to accept (or reject) the |
| 269 * terms-of-service of the given printer. | 278 * terms-of-service of the given printer. |
| 270 * @param {string} printerId ID of the printer to accept the | 279 * @param {!print_preview.Destination} destination Destination to accept ToS |
| 271 * terms-of-service for. | 280 * for. |
| 272 * @param {!print_preview.Destination.Origin} origin Origin of the printer. | 281 * @param {boolean} isAccepted Whether the user accepted ToS or not. |
| 273 * @param {boolean} isAccepted Whether the user accepted the | |
| 274 * terms-of-service. | |
| 275 */ | 282 */ |
| 276 updatePrinterTosAcceptance: function(printerId, origin, isAccepted) { | 283 updatePrinterTosAcceptance: function(destination, isAccepted) { |
| 277 var params = [ | 284 var params = [ |
| 278 new HttpParam('printerid', printerId), | 285 new HttpParam('printerid', destination.id), |
| 279 new HttpParam('is_tos_accepted', isAccepted) | 286 new HttpParam('is_tos_accepted', isAccepted) |
| 280 ]; | 287 ]; |
| 281 var cpRequest = | 288 var cpRequest = this.buildRequest_( |
| 282 this.buildRequest_('POST', 'update', params, origin, | 289 'POST', |
| 283 this.onUpdatePrinterTosAcceptanceDone_.bind(this)); | 290 'update', |
| 291 params, | |
|
Vitaly Buka (NO REVIEWS)
2014/04/11 02:32:57
inconsistent
Aleksey Shlyapnikov
2014/04/11 19:09:29
Done.
| |
| 292 destination.origin, | |
| 293 destination.account, | |
| 294 this.onUpdatePrinterTosAcceptanceDone_.bind(this)); | |
| 284 this.sendOrQueueRequest_(cpRequest); | 295 this.sendOrQueueRequest_(cpRequest); |
| 285 }, | 296 }, |
| 286 | 297 |
| 287 /** | 298 /** |
| 288 * Adds event listeners to relevant events. | 299 * Adds event listeners to relevant events. |
| 289 * @private | 300 * @private |
| 290 */ | 301 */ |
| 291 addEventListeners_: function() { | 302 addEventListeners_: function() { |
| 292 this.tracker_.add( | 303 this.tracker_.add( |
| 293 this.nativeLayer_, | 304 this.nativeLayer_, |
| 294 print_preview.NativeLayer.EventType.ACCESS_TOKEN_READY, | 305 print_preview.NativeLayer.EventType.ACCESS_TOKEN_READY, |
| 295 this.onAccessTokenReady_.bind(this)); | 306 this.onAccessTokenReady_.bind(this)); |
| 307 this.tracker_.add( | |
| 308 this.userInfo_, | |
| 309 print_preview.UserInfo.EventType.ACTIVE_USER_CHANGED, | |
| 310 this.onActiveUserChanged_.bind(this)); | |
| 296 }, | 311 }, |
| 297 | 312 |
| 298 /** | 313 /** |
| 299 * Builds request to the Google Cloud Print API. | 314 * Builds request to the Google Cloud Print API. |
| 300 * @param {string} method HTTP method of the request. | 315 * @param {string} method HTTP method of the request. |
| 301 * @param {string} action Google Cloud Print action to perform. | 316 * @param {string} action Google Cloud Print action to perform. |
| 302 * @param {Array.<!HttpParam>} params HTTP parameters to include in the | 317 * @param {Array.<!HttpParam>} params HTTP parameters to include in the |
| 303 * request. | 318 * request. |
| 304 * @param {!print_preview.Destination.Origin} origin Origin for destination. | 319 * @param {!print_preview.Destination.Origin} origin Origin for destination. |
| 320 * @param {?string} account Account the request is sent for. Can be | |
| 321 * {@code null} or empty string if the request is not cookie bound or | |
| 322 * is sent on behalf of the primary user. | |
| 305 * @param {function(number, Object, !print_preview.Destination.Origin)} | 323 * @param {function(number, Object, !print_preview.Destination.Origin)} |
| 306 * callback Callback to invoke when request completes. | 324 * callback Callback to invoke when request completes. |
| 307 * @return {!CloudPrintRequest} Partially prepared request. | 325 * @return {!CloudPrintRequest} Partially prepared request. |
| 308 * @private | 326 * @private |
| 309 */ | 327 */ |
| 310 buildRequest_: function(method, action, params, origin, callback) { | 328 buildRequest_: function(method, action, params, origin, account, callback) { |
| 311 var url = this.baseUrl_ + '/' + action + '?xsrf='; | 329 var url = this.baseUrl_ + '/' + action + '?xsrf='; |
| 312 if (origin == print_preview.Destination.Origin.COOKIES) { | 330 if (origin == print_preview.Destination.Origin.COOKIES) { |
| 313 if (!this.xsrfToken_) { | 331 var xsrfToken = this.xsrfTokens_[account]; |
| 332 if (!xsrfToken) { | |
| 314 // TODO(rltoscano): Should throw an error if not a read-only action or | 333 // TODO(rltoscano): Should throw an error if not a read-only action or |
| 315 // issue an xsrf token request. | 334 // issue an xsrf token request. |
| 316 } else { | 335 } else { |
| 317 url = url + this.xsrfToken_; | 336 url = url + xsrfToken; |
| 318 } | 337 } |
| 319 params = params || []; | 338 if (account) { |
| 320 if (this.userInfo_.activeUser) { | 339 var index = this.userSessionIndex_[account] || 0; |
| 321 var index = this.userSessionIndex_[this.userInfo_.activeUser] || 0; | |
| 322 if (index > 0) { | 340 if (index > 0) { |
| 323 params.push(new HttpParam('user', index)); | 341 url += '&user=' + index; |
| 324 } | 342 } |
| 325 } | 343 } |
| 326 } | 344 } |
| 327 var body = null; | 345 var body = null; |
| 328 if (params) { | 346 if (params) { |
| 329 if (method == 'GET') { | 347 if (method == 'GET') { |
| 330 url = params.reduce(function(partialUrl, param) { | 348 url = params.reduce(function(partialUrl, param) { |
| 331 return partialUrl + '&' + param.name + '=' + | 349 return partialUrl + '&' + param.name + '=' + |
| 332 encodeURIComponent(param.value); | 350 encodeURIComponent(param.value); |
| 333 }, url); | 351 }, url); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 349 } | 367 } |
| 350 | 368 |
| 351 var xhr = new XMLHttpRequest(); | 369 var xhr = new XMLHttpRequest(); |
| 352 xhr.open(method, url, true); | 370 xhr.open(method, url, true); |
| 353 xhr.withCredentials = | 371 xhr.withCredentials = |
| 354 (origin == print_preview.Destination.Origin.COOKIES); | 372 (origin == print_preview.Destination.Origin.COOKIES); |
| 355 for (var header in headers) { | 373 for (var header in headers) { |
| 356 xhr.setRequestHeader(header, headers[header]); | 374 xhr.setRequestHeader(header, headers[header]); |
| 357 } | 375 } |
| 358 | 376 |
| 359 return new CloudPrintRequest(xhr, body, origin, callback); | 377 return new CloudPrintRequest(xhr, body, origin, account, callback); |
| 360 }, | 378 }, |
| 361 | 379 |
| 362 /** | 380 /** |
| 363 * Sends a request to the Google Cloud Print API or queues if it needs to | 381 * Sends a request to the Google Cloud Print API or queues if it needs to |
| 364 * wait OAuth2 access token. | 382 * wait OAuth2 access token. |
| 365 * @param {!CloudPrintRequest} request Request to send or queue. | 383 * @param {!CloudPrintRequest} request Request to send or queue. |
| 366 * @private | 384 * @private |
| 367 */ | 385 */ |
| 368 sendOrQueueRequest_: function(request) { | 386 sendOrQueueRequest_: function(request) { |
| 369 if (request.origin == print_preview.Destination.Origin.COOKIES) { | 387 if (request.origin == print_preview.Destination.Origin.COOKIES) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 400 errorEvent.message = request.result['message']; | 418 errorEvent.message = request.result['message']; |
| 401 } else { | 419 } else { |
| 402 errorEvent.errorCode = 0; | 420 errorEvent.errorCode = 0; |
| 403 errorEvent.message = ''; | 421 errorEvent.message = ''; |
| 404 } | 422 } |
| 405 errorEvent.origin = request.origin; | 423 errorEvent.origin = request.origin; |
| 406 return errorEvent; | 424 return errorEvent; |
| 407 }, | 425 }, |
| 408 | 426 |
| 409 /** | 427 /** |
| 428 * Updates user info and session index from the {@code request} response. | |
| 429 * @param {!CloudPrintRequest} request Request to extract user info from. | |
| 430 * @private | |
| 431 */ | |
| 432 setUsers_: function(request) { | |
| 433 if (request.origin == print_preview.Destination.Origin.COOKIES) { | |
| 434 var activeUser = request.result['request']['user']; | |
|
Toscano
2014/04/11 04:24:00
Maybe move this to right above line 440 since it's
Aleksey Shlyapnikov
2014/04/11 19:09:29
Done.
| |
| 435 var users = request.result['request']['users'] || []; | |
| 436 this.userSessionIndex_ = {}; | |
| 437 for (var i = 0; i < users.length; i++) { | |
| 438 this.userSessionIndex_[users[i]] = i; | |
| 439 } | |
| 440 this.userInfo_.setUsers(activeUser, users); | |
| 441 } | |
| 442 }, | |
| 443 | |
| 444 /** | |
| 445 * Terminates search requests for requested {@code origins}. | |
| 446 * @param {!Array.<print_preview.Destination.Origin>} origins Origins | |
| 447 * to terminate search requests for. | |
| 448 * @private | |
| 449 */ | |
| 450 abortSearchRequests_: function(origins) { | |
| 451 this.outstandingCloudSearchRequests_ = | |
| 452 this.outstandingCloudSearchRequests_.filter(function(request) { | |
| 453 if (origins.indexOf(request.origin) >= 0) { | |
| 454 request.xhr.abort(); | |
| 455 return false; | |
| 456 } | |
| 457 return true; | |
| 458 }); | |
| 459 }, | |
| 460 | |
| 461 /** | |
| 462 * Called when active user account changes. Terminates all outstanding | |
| 463 * cookie based search requests. | |
| 464 * @private | |
| 465 */ | |
| 466 onActiveUserChanged_: function() { | |
| 467 this.abortSearchRequests_([print_preview.Destination.Origin.COOKIES]); | |
|
Toscano
2014/04/11 04:24:00
Hmm, wouldn't it be simpler to only abort if and o
Aleksey Shlyapnikov
2014/04/11 19:09:29
The thing is, search request reply _is_ the source
Toscano
2014/04/12 02:09:08
But wait, how can you change the user if the first
Aleksey Shlyapnikov
2014/04/12 03:44:03
It's assumed that all search requests issued under
| |
| 468 }, | |
| 469 | |
| 470 /** | |
| 410 * Called when a native layer receives access token. | 471 * Called when a native layer receives access token. |
| 411 * @param {Event} evt Contains the authentication type and access token. | 472 * @param {Event} evt Contains the authentication type and access token. |
| 412 * @private | 473 * @private |
| 413 */ | 474 */ |
| 414 onAccessTokenReady_: function(event) { | 475 onAccessTokenReady_: function(event) { |
| 415 // TODO(vitalybuka): remove when other Origins implemented. | 476 // TODO(vitalybuka): remove when other Origins implemented. |
| 416 assert(event.authType == print_preview.Destination.Origin.DEVICE); | 477 assert(event.authType == print_preview.Destination.Origin.DEVICE); |
| 417 this.requestQueue_ = this.requestQueue_.filter(function(request) { | 478 this.requestQueue_ = this.requestQueue_.filter(function(request) { |
| 418 assert(request.origin == print_preview.Destination.Origin.DEVICE); | 479 assert(request.origin == print_preview.Destination.Origin.DEVICE); |
| 419 if (request.origin != event.authType) { | 480 if (request.origin != event.authType) { |
| 420 return true; | 481 return true; |
| 421 } | 482 } |
| 422 if (event.accessToken) { | 483 if (event.accessToken) { |
| 423 request.xhr.setRequestHeader('Authorization', | 484 request.xhr.setRequestHeader('Authorization', |
| 424 'Bearer ' + event.accessToken); | 485 'Bearer ' + event.accessToken); |
| 425 this.sendRequest_(request); | 486 this.sendRequest_(request); |
| 426 } else { // No valid token. | 487 } else { // No valid token. |
| 427 // Without abort status does not exists. | 488 // Without abort status does not exist. |
| 428 request.xhr.abort(); | 489 request.xhr.abort(); |
| 429 request.callback(request); | 490 request.callback(request); |
| 430 } | 491 } |
| 431 return false; | 492 return false; |
| 432 }, this); | 493 }, this); |
| 433 }, | 494 }, |
| 434 | 495 |
| 435 /** | 496 /** |
| 436 * Called when the ready-state of a XML http request changes. | 497 * Called when the ready-state of a XML http request changes. |
| 437 * Calls the successCallback with the result or dispatches an ERROR event. | 498 * Calls the successCallback with the result or dispatches an ERROR event. |
| 438 * @param {!CloudPrintRequest} request Request that was changed. | 499 * @param {!CloudPrintRequest} request Request that was changed. |
| 439 * @private | 500 * @private |
| 440 */ | 501 */ |
| 441 onReadyStateChange_: function(request) { | 502 onReadyStateChange_: function(request) { |
| 442 if (request.xhr.readyState == 4) { | 503 if (request.xhr.readyState == 4) { |
| 443 if (request.xhr.status == 200) { | 504 if (request.xhr.status == 200) { |
| 444 request.result = JSON.parse(request.xhr.responseText); | 505 request.result = JSON.parse(request.xhr.responseText); |
| 445 if (request.origin == print_preview.Destination.Origin.COOKIES && | 506 if (request.origin == print_preview.Destination.Origin.COOKIES && |
| 446 request.result['success']) { | 507 request.result['success'] && |
| 447 this.xsrfToken_ = request.result['xsrf_token']; | 508 request.account) { |
| 509 this.xsrfTokens_[request.account] = request.result['xsrf_token']; | |
| 448 } | 510 } |
| 449 } | 511 } |
| 450 request.status = request.xhr.status; | 512 request.status = request.xhr.status; |
| 451 request.callback(request); | 513 request.callback(request); |
| 452 } | 514 } |
| 453 }, | 515 }, |
| 454 | 516 |
| 455 /** | 517 /** |
| 456 * Called when the search request completes. | 518 * Called when the search request completes. |
| 457 * @param {boolean} isRecent Whether the search request was for recent | 519 * @param {boolean} isRecent Whether the search request was for recent |
| 458 * destinations. | 520 * destinations. |
| 459 * @param {!CloudPrintRequest} request Request that has been completed. | 521 * @param {!CloudPrintRequest} request Request that has been completed. |
| 460 * @private | 522 * @private |
| 461 */ | 523 */ |
| 462 onSearchDone_: function(isRecent, request) { | 524 onSearchDone_: function(isRecent, request) { |
| 525 var lastRequestForThisOrigin = true; | |
| 463 this.outstandingCloudSearchRequests_ = | 526 this.outstandingCloudSearchRequests_ = |
| 464 this.outstandingCloudSearchRequests_.filter(function(item) { | 527 this.outstandingCloudSearchRequests_.filter(function(item) { |
| 528 if (item != request && item.origin == request.origin) { | |
| 529 lastRequestForThisOrigin = false; | |
| 530 } | |
| 465 return item != request; | 531 return item != request; |
| 466 }); | 532 }); |
| 533 var activeUser = ''; | |
| 534 if (request.origin == print_preview.Destination.Origin.COOKIES) { | |
| 535 activeUser = request.result['request']['user']; | |
| 536 } | |
| 537 var event = null; | |
| 467 if (request.xhr.status == 200 && request.result['success']) { | 538 if (request.xhr.status == 200 && request.result['success']) { |
| 468 var activeUser = ''; | 539 // Extract printers. |
| 469 if (request.origin == print_preview.Destination.Origin.COOKIES) { | |
| 470 activeUser = request.result['request']['user']; | |
| 471 } | |
| 472 var printerListJson = request.result['printers'] || []; | 540 var printerListJson = request.result['printers'] || []; |
| 473 var printerList = []; | 541 var printerList = []; |
| 474 printerListJson.forEach(function(printerJson) { | 542 printerListJson.forEach(function(printerJson) { |
| 475 try { | 543 try { |
| 476 printerList.push(cloudprint.CloudDestinationParser.parse( | 544 printerList.push(cloudprint.CloudDestinationParser.parse( |
|
Vitaly Buka (NO REVIEWS)
2014/04/11 02:32:57
maybe extractPrinters_
Aleksey Shlyapnikov
2014/04/11 19:09:29
This is the only place printer list is parsed, I'd
| |
| 477 printerJson, request.origin, activeUser)); | 545 printerJson, request.origin, activeUser)); |
| 478 } catch (err) { | 546 } catch (err) { |
| 479 console.error('Unable to parse cloud print destination: ' + err); | 547 console.error('Unable to parse cloud print destination: ' + err); |
| 480 } | 548 } |
| 481 }); | 549 }); |
| 482 var searchDoneEvent = | 550 // Extract users. |
| 483 new Event(CloudPrintInterface.EventType.SEARCH_DONE); | 551 this.setUsers_(request); |
|
Vitaly Buka (NO REVIEWS)
2014/04/11 02:32:57
setUsers_ -> extractUsers_
Aleksey Shlyapnikov
2014/04/11 19:09:29
It updates userInfo_ state, not just extracts user
| |
| 484 searchDoneEvent.printers = printerList; | 552 // Dispatch SEARCH_DONE event. |
| 485 searchDoneEvent.origin = request.origin; | 553 event = new Event(CloudPrintInterface.EventType.SEARCH_DONE); |
| 486 searchDoneEvent.isRecent = isRecent; | 554 event.origin = request.origin; |
| 487 if (request.origin == print_preview.Destination.Origin.COOKIES) { | 555 event.printers = printerList; |
| 488 var users = request.result['request']['users'] || []; | 556 event.isRecent = isRecent; |
| 489 this.userSessionIndex_ = {}; | |
| 490 for (var i = 0; i < users.length; i++) { | |
| 491 this.userSessionIndex_[users[i]] = i; | |
| 492 } | |
| 493 this.userInfo_.setUsers(activeUser, users); | |
| 494 } | |
| 495 this.dispatchEvent(searchDoneEvent); | |
| 496 } else { | 557 } else { |
| 497 var errorEvent = this.createErrorEvent_( | 558 event = this.createErrorEvent_( |
| 498 CloudPrintInterface.EventType.SEARCH_FAILED, request); | 559 CloudPrintInterface.EventType.SEARCH_FAILED, |
| 499 this.dispatchEvent(errorEvent); | 560 request); |
| 500 } | 561 } |
| 562 event.user = activeUser; | |
| 563 event.searchDone = lastRequestForThisOrigin; | |
| 564 this.dispatchEvent(event); | |
| 501 }, | 565 }, |
| 502 | 566 |
| 503 /** | 567 /** |
| 504 * Called when the submit request completes. | 568 * Called when the submit request completes. |
| 505 * @param {!CloudPrintRequest} request Request that has been completed. | 569 * @param {!CloudPrintRequest} request Request that has been completed. |
| 506 * @private | 570 * @private |
| 507 */ | 571 */ |
| 508 onSubmitDone_: function(request) { | 572 onSubmitDone_: function(request) { |
| 509 if (request.xhr.status == 200 && request.result['success']) { | 573 if (request.xhr.status == 200 && request.result['success']) { |
| 510 var submitDoneEvent = new Event( | 574 var submitDoneEvent = new Event( |
| 511 CloudPrintInterface.EventType.SUBMIT_DONE); | 575 CloudPrintInterface.EventType.SUBMIT_DONE); |
| 512 submitDoneEvent.jobId = request.result['job']['id']; | 576 submitDoneEvent.jobId = request.result['job']['id']; |
| 513 this.dispatchEvent(submitDoneEvent); | 577 this.dispatchEvent(submitDoneEvent); |
| 514 } else { | 578 } else { |
| 515 var errorEvent = this.createErrorEvent_( | 579 var errorEvent = this.createErrorEvent_( |
| 516 CloudPrintInterface.EventType.SUBMIT_FAILED, request); | 580 CloudPrintInterface.EventType.SUBMIT_FAILED, request); |
| 517 this.dispatchEvent(errorEvent); | 581 this.dispatchEvent(errorEvent); |
| 518 } | 582 } |
| 519 }, | 583 }, |
| 520 | 584 |
| 521 /** | 585 /** |
| 522 * Called when the printer request completes. | 586 * Called when the printer request completes. |
| 523 * @param {string} destinationId ID of the destination that was looked up. | 587 * @param {string} destinationId ID of the destination that was looked up. |
| 524 * @param {!CloudPrintRequest} request Request that has been completed. | 588 * @param {!CloudPrintRequest} request Request that has been completed. |
| 525 * @private | 589 * @private |
| 526 */ | 590 */ |
| 527 onPrinterDone_: function(destinationId, request) { | 591 onPrinterDone_: function(destinationId, request) { |
| 592 // Special handling of the first printer request. It does not matter at | |
| 593 // this point, whether printer was found or not. | |
| 594 if (request.origin == print_preview.Destination.Origin.COOKIES && | |
| 595 request.account && | |
| 596 request.result['request']['user'] && | |
| 597 request.result['request']['users'] && | |
| 598 request.account != request.result['request']['user']) { | |
| 599 var users = request.result['request']['users']; | |
|
Toscano
2014/04/11 04:24:00
Let's keep user parsing logic in place. Why not th
Aleksey Shlyapnikov
2014/04/11 19:09:29
Done.
On 2014/04/11 04:24:00, Toscano wrote:
| |
| 600 // In case the user account is known, but not the primary one, | |
| 601 // activate it. | |
| 602 if (users.indexOf(request.account) > 0) { | |
| 603 this.setUsers_(request); | |
| 604 this.userInfo_.activeUser = request.account; | |
| 605 // Repeat the request for the newly activated account. | |
| 606 this.printer( | |
| 607 request.result['request']['params']['printerid'], | |
| 608 request.origin, | |
| 609 request.account); | |
| 610 // Stop processing this request, wait for the new response. | |
| 611 return; | |
| 612 } | |
| 613 } | |
| 614 // Process response. | |
| 528 if (request.xhr.status == 200 && request.result['success']) { | 615 if (request.xhr.status == 200 && request.result['success']) { |
| 529 var activeUser = ''; | 616 var activeUser = ''; |
| 530 if (request.origin == print_preview.Destination.Origin.COOKIES) { | 617 if (request.origin == print_preview.Destination.Origin.COOKIES) { |
| 531 activeUser = request.result['request']['user']; | 618 activeUser = request.result['request']['user']; |
| 532 } | 619 } |
| 533 var printerJson = request.result['printers'][0]; | 620 var printerJson = request.result['printers'][0]; |
| 534 var printer; | 621 var printer; |
| 535 try { | 622 try { |
| 536 printer = cloudprint.CloudDestinationParser.parse( | 623 printer = cloudprint.CloudDestinationParser.parse( |
| 537 printerJson, request.origin, activeUser); | 624 printerJson, request.origin, activeUser); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 567 this.dispatchEvent(errorEvent); | 654 this.dispatchEvent(errorEvent); |
| 568 } | 655 } |
| 569 } | 656 } |
| 570 }; | 657 }; |
| 571 | 658 |
| 572 /** | 659 /** |
| 573 * Data structure that holds data for Cloud Print requests. | 660 * Data structure that holds data for Cloud Print requests. |
| 574 * @param {!XMLHttpRequest} xhr Partially prepared http request. | 661 * @param {!XMLHttpRequest} xhr Partially prepared http request. |
| 575 * @param {string} body Data to send with POST requests. | 662 * @param {string} body Data to send with POST requests. |
| 576 * @param {!print_preview.Destination.Origin} origin Origin for destination. | 663 * @param {!print_preview.Destination.Origin} origin Origin for destination. |
| 664 * @param {?string} account Account the request is sent for. Can be | |
| 665 * {@code null} or empty string if the request is not cookie bound or | |
| 666 * is sent on behalf of the primary user. | |
|
Toscano
2014/04/11 04:24:00
If it's nullable, maybe it should be opt_account?
Aleksey Shlyapnikov
2014/04/11 19:09:29
I don't see the benefit of optional here, it's a p
| |
| 577 * @param {function(!CloudPrintRequest)} callback Callback to invoke when | 667 * @param {function(!CloudPrintRequest)} callback Callback to invoke when |
| 578 * request completes. | 668 * request completes. |
| 579 * @constructor | 669 * @constructor |
| 580 */ | 670 */ |
| 581 function CloudPrintRequest(xhr, body, origin, callback) { | 671 function CloudPrintRequest(xhr, body, origin, account, callback) { |
| 582 /** | 672 /** |
| 583 * Partially prepared http request. | 673 * Partially prepared http request. |
| 584 * @type {!XMLHttpRequest} | 674 * @type {!XMLHttpRequest} |
| 585 */ | 675 */ |
| 586 this.xhr = xhr; | 676 this.xhr = xhr; |
| 587 | 677 |
| 588 /** | 678 /** |
| 589 * Data to send with POST requests. | 679 * Data to send with POST requests. |
| 590 * @type {string} | 680 * @type {string} |
| 591 */ | 681 */ |
| 592 this.body = body; | 682 this.body = body; |
| 593 | 683 |
| 594 /** | 684 /** |
| 595 * Origin for destination. | 685 * Origin for destination. |
| 596 * @type {!print_preview.Destination.Origin} | 686 * @type {!print_preview.Destination.Origin} |
| 597 */ | 687 */ |
| 598 this.origin = origin; | 688 this.origin = origin; |
| 599 | 689 |
| 600 /** | 690 /** |
| 691 * User account this request is expected to be executed for. | |
| 692 * @type {?string} | |
| 693 */ | |
| 694 this.account = account; | |
| 695 | |
| 696 /** | |
| 601 * Callback to invoke when request completes. | 697 * Callback to invoke when request completes. |
| 602 * @type {function(!CloudPrintRequest)} | 698 * @type {function(!CloudPrintRequest)} |
| 603 */ | 699 */ |
| 604 this.callback = callback; | 700 this.callback = callback; |
| 605 | 701 |
| 606 /** | 702 /** |
| 607 * Result for requests. | 703 * Result for requests. |
| 608 * @type {Object} JSON response. | 704 * @type {Object} JSON response. |
| 609 */ | 705 */ |
| 610 this.result = null; | 706 this.result = null; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 628 * @type {string} | 724 * @type {string} |
| 629 */ | 725 */ |
| 630 this.value = value; | 726 this.value = value; |
| 631 }; | 727 }; |
| 632 | 728 |
| 633 // Export | 729 // Export |
| 634 return { | 730 return { |
| 635 CloudPrintInterface: CloudPrintInterface | 731 CloudPrintInterface: CloudPrintInterface |
| 636 }; | 732 }; |
| 637 }); | 733 }); |
| OLD | NEW |