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 |