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 |