Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 /** | 5 /** |
| 6 * @typedef {{ | 6 * @typedef {{ |
| 7 * cache: (boolean|undefined), | 7 * cache: (boolean|undefined), |
| 8 * priority: (number|undefined), | 8 * priority: (number|undefined), |
| 9 * taskId: number, | 9 * taskId: number, |
| 10 * timestamp: (number|undefined), | 10 * timestamp: (number|undefined), |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 // Download data urls directly since they are not supported by XmlHttpRequest. | 221 // Download data urls directly since they are not supported by XmlHttpRequest. |
| 222 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/); | 222 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/); |
| 223 if (dataUrlMatches) { | 223 if (dataUrlMatches) { |
| 224 this.image_.src = this.request_.url; | 224 this.image_.src = this.request_.url; |
| 225 this.contentType_ = dataUrlMatches[1]; | 225 this.contentType_ = dataUrlMatches[1]; |
| 226 return; | 226 return; |
| 227 } | 227 } |
| 228 | 228 |
| 229 // Fetch the image via authorized XHR and parse it. | 229 // Fetch the image via authorized XHR and parse it. |
| 230 var parseImage = function(contentType, blob) { | 230 var parseImage = function(contentType, blob) { |
| 231 if (contentType) | |
| 232 this.contentType_ = contentType; | |
| 233 | |
| 231 this.image_.src = URL.createObjectURL(blob); | 234 this.image_.src = URL.createObjectURL(blob); |
| 232 }.bind(this); | 235 }.bind(this); |
| 233 | 236 |
| 234 // Request raw data via XHR. | 237 // Request raw data via XHR. |
| 235 this.xhr_.load(this.request_.url, parseImage, onFailure); | 238 this.xhr_.load(this.request_.url, parseImage, onFailure); |
| 236 }; | 239 }; |
| 237 | 240 |
| 238 /** | 241 /** |
| 239 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers. | 242 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers. |
| 240 * @constructor | 243 * @constructor |
| 241 */ | 244 */ |
| 242 function AuthorizedXHR() { | 245 function AuthorizedXHR() { |
| 243 this.xhr_ = null; | 246 this.xhr_ = null; |
| 244 this.aborted_ = false; | 247 this.aborted_ = false; |
| 245 } | 248 } |
| 246 | 249 |
| 247 /** | 250 /** |
| 251 * A map which is used to estimate content type from extension. | |
| 252 * @enum {string} | |
| 253 */ | |
| 254 AuthorizedXHR.ExtensionContentTypeMap = { | |
| 255 gif: 'image/gif', | |
| 256 png: 'image/png', | |
| 257 svg: 'image/svg', | |
| 258 bmp: 'image/bmp', | |
| 259 jpg: 'image/jpeg', | |
| 260 jpeg: 'image/jpeg' | |
| 261 }; | |
| 262 | |
| 263 /** | |
| 248 * Aborts the current request (if running). | 264 * Aborts the current request (if running). |
| 249 */ | 265 */ |
| 250 AuthorizedXHR.prototype.abort = function() { | 266 AuthorizedXHR.prototype.abort = function() { |
| 251 this.aborted_ = true; | 267 this.aborted_ = true; |
| 252 if (this.xhr_) | 268 if (this.xhr_) |
| 253 this.xhr_.abort(); | 269 this.xhr_.abort(); |
| 254 }; | 270 }; |
| 255 | 271 |
| 256 /** | 272 /** |
| 257 * Loads an image using a OAuth2 token. If it fails, then tries to retry with | 273 * Loads an image using a OAuth2 token. If it fails, then tries to retry with |
| 258 * a refreshed OAuth2 token. | 274 * a refreshed OAuth2 token. |
| 259 * | 275 * |
| 260 * @param {string} url URL to the resource to be fetched. | 276 * @param {string} url URL to the resource to be fetched. |
| 261 * @param {function(string, Blob)} onSuccess Success callback with the content | 277 * @param {function(string, Blob)} onSuccess Success callback with the content |
| 262 * type and the fetched data. | 278 * type and the fetched data. |
| 263 * @param {function()} onFailure Failure callback. | 279 * @param {function()} onFailure Failure callback. |
| 264 */ | 280 */ |
| 265 AuthorizedXHR.prototype.load = function(url, onSuccess, onFailure) { | 281 AuthorizedXHR.prototype.load = function(url, onSuccess, onFailure) { |
| 266 this.aborted_ = false; | 282 this.aborted_ = false; |
| 267 | 283 |
| 268 // Do not call any callbacks when aborting. | 284 // Do not call any callbacks when aborting. |
| 269 var onMaybeSuccess = /** @type {function(string, Blob)} */ ( | 285 var onMaybeSuccess = /** @type {function(string, Blob)} */ ( |
| 270 function(contentType, response) { | 286 function(contentType, response) { |
| 287 // When content type is not available, try to estimate it from url. | |
| 288 if (!contentType) { | |
| 289 contentType = AuthorizedXHR.ExtensionContentTypeMap[ | |
| 290 this.extractExtension_(url)]; | |
|
fukino
2015/02/18 10:45:22
Is reading ExtensionContentTypeMap[null] intended?
yawano
2015/02/18 11:32:50
Yes. Intention is that undefined will be set when
| |
| 291 } | |
| 292 | |
| 271 if (!this.aborted_) | 293 if (!this.aborted_) |
| 272 onSuccess(contentType, response); | 294 onSuccess(contentType, response); |
| 273 }.bind(this)); | 295 }.bind(this)); |
| 274 | 296 |
| 275 var onMaybeFailure = /** @type {function(number=)} */ ( | 297 var onMaybeFailure = /** @type {function(number=)} */ ( |
| 276 function(opt_code) { | 298 function(opt_code) { |
| 277 if (!this.aborted_) | 299 if (!this.aborted_) |
| 278 onFailure(); | 300 onFailure(); |
| 279 }.bind(this)); | 301 }.bind(this)); |
| 280 | 302 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 311 onMaybeSuccess, | 333 onMaybeSuccess, |
| 312 onMaybeFailure); | 334 onMaybeFailure); |
| 313 return; | 335 return; |
| 314 } | 336 } |
| 315 | 337 |
| 316 // Make the request with reusing the current token. If it fails, then retry. | 338 // Make the request with reusing the current token. If it fails, then retry. |
| 317 requestTokenAndCall(false, onMaybeSuccess, maybeRetryCall); | 339 requestTokenAndCall(false, onMaybeSuccess, maybeRetryCall); |
| 318 }; | 340 }; |
| 319 | 341 |
| 320 /** | 342 /** |
| 343 * Extracts extension from url. | |
| 344 * @param {string} url Url. | |
| 345 * @return {?string} Extracted extensiion, e.g. png. | |
| 346 */ | |
| 347 AuthorizedXHR.prototype.extractExtension_ = function(url) { | |
| 348 var result = (/\.([a-zA-Z]+)$/i).exec(url); | |
| 349 return result ? result[1] : null; | |
|
fukino
2015/02/18 10:45:22
Returning '' for missing extension looks better fo
yawano
2015/02/18 11:32:50
Done.
| |
| 350 }; | |
| 351 | |
| 352 /** | |
| 321 * Fetches data using authorized XmlHttpRequest with the provided OAuth2 token. | 353 * Fetches data using authorized XmlHttpRequest with the provided OAuth2 token. |
| 322 * If the token is invalid, the request will fail. | 354 * If the token is invalid, the request will fail. |
| 323 * | 355 * |
| 324 * @param {?string} token OAuth2 token to be injected to the request. Null for | 356 * @param {?string} token OAuth2 token to be injected to the request. Null for |
| 325 * no token. | 357 * no token. |
| 326 * @param {string} url URL to the resource to be fetched. | 358 * @param {string} url URL to the resource to be fetched. |
| 327 * @param {function(string, Blob)} onSuccess Success callback with the content | 359 * @param {function(string, Blob)} onSuccess Success callback with the content |
| 328 * type and the fetched data. | 360 * type and the fetched data. |
| 329 * @param {function(number=)} onFailure Failure callback with the error code | 361 * @param {function(number=)} onFailure Failure callback with the error code |
| 330 * if available. | 362 * if available. |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' + | 502 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' + |
| 471 'ABAAEAAAICTAEAOw=='; | 503 'ABAAEAAAICTAEAOw=='; |
| 472 | 504 |
| 473 this.xhr_.onload = function() {}; | 505 this.xhr_.onload = function() {}; |
| 474 this.xhr_.abort(); | 506 this.xhr_.abort(); |
| 475 | 507 |
| 476 // Dispose memory allocated by Canvas. | 508 // Dispose memory allocated by Canvas. |
| 477 this.canvas_.width = 0; | 509 this.canvas_.width = 0; |
| 478 this.canvas_.height = 0; | 510 this.canvas_.height = 0; |
| 479 }; | 511 }; |
| OLD | NEW |