Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: chrome/browser/resources/image_loader/request.js

Issue 25458002: Migrate to Styx thumbnails in Files App. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/image_loader/manifest.json ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 'use strict'; 5 'use strict';
6 6
7 /** 7 /**
8 * Creates and starts downloading and then resizing of the image. Finally, 8 * Creates and starts downloading and then resizing of the image. Finally,
9 * returns the image using the callback. 9 * returns the image using the callback.
10 * 10 *
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 48
49 /** 49 /**
50 * MIME type of the fetched image. 50 * MIME type of the fetched image.
51 * @type {string} 51 * @type {string}
52 * @private 52 * @private
53 */ 53 */
54 this.contentType_ = null; 54 this.contentType_ = null;
55 55
56 /** 56 /**
57 * Used to download remote images using http:// or https:// protocols. 57 * Used to download remote images using http:// or https:// protocols.
58 * @type {XMLHttpRequest} 58 * @type {AuthorizedXHR}
59 * @private 59 * @private
60 */ 60 */
61 this.xhr_ = new XMLHttpRequest(); 61 this.xhr_ = new AuthorizedXHR();
62 62
63 /** 63 /**
64 * Temporary canvas used to resize and compress the image. 64 * Temporary canvas used to resize and compress the image.
65 * @type {HTMLCanvasElement} 65 * @type {HTMLCanvasElement}
66 * @private 66 * @private
67 */ 67 */
68 this.canvas_ = document.createElement('canvas'); 68 this.canvas_ = document.createElement('canvas');
69 69
70 /** 70 /**
71 * @type {CanvasRenderingContext2D} 71 * @type {CanvasRenderingContext2D}
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 this.image_.onerror = onFailure; 187 this.image_.onerror = onFailure;
188 188
189 // Download data urls directly since they are not supported by XmlHttpRequest. 189 // Download data urls directly since they are not supported by XmlHttpRequest.
190 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/); 190 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/);
191 if (dataUrlMatches) { 191 if (dataUrlMatches) {
192 this.image_.src = this.request_.url; 192 this.image_.src = this.request_.url;
193 this.contentType_ = dataUrlMatches[1]; 193 this.contentType_ = dataUrlMatches[1];
194 return; 194 return;
195 } 195 }
196 196
197 // Download using an xhr request. 197 // Fetch the image via authorized XHR and parse it.
198 this.xhr_.responseType = 'blob'; 198 var parseImage = function(contentType, blob) {
199
200 this.xhr_.onerror = this.image_.onerror;
201 this.xhr_.onload = function() {
202 if (this.xhr_.status != 200) {
203 this.image_.onerror();
204 return;
205 }
206
207 // Process returned data, including the mime type.
208 this.contentType_ = this.xhr_.getResponseHeader('Content-Type');
209 var reader = new FileReader(); 199 var reader = new FileReader();
210 reader.onerror = this.image_.onerror; 200 reader.onerror = onFailure;
211 reader.onload = function(e) { 201 reader.onload = function(e) {
212 this.image_.src = e.target.result; 202 this.image_.src = e.target.result;
213 }.bind(this); 203 }.bind(this);
214 204
215 // Load the data to the image as a data url. 205 // Load the data to the image as a data url.
216 reader.readAsDataURL(this.xhr_.response); 206 reader.readAsDataURL(blob);
207 }.bind(this);
208
209 // Request raw data via XHR.
210 this.xhr_.load(this.request_.url, parseImage, onFailure);
211 };
212
213 /**
214 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers.
215 * @constructor
216 */
217 function AuthorizedXHR() {
218 this.xhr_ = null;
219 this.aborted_ = false;
220 }
221
222 /**
223 * Aborts the current request (if running).
224 */
225 AuthorizedXHR.prototype.abort = function() {
226 this.aborted_ = true;
227 if (this.xhr_)
228 this.xhr_.abort();
229 };
230
231 /**
232 * Loads an image using a OAuth2 token. If it fails, then tries to retry with
233 * a refreshed OAuth2 token.
234 *
235 * @param {string} url URL to the resource to be fetched.
236 * @param {function(string, Blob}) onSuccess Success callback with the content
237 * type and the fetched data.
238 * @param {function()} onFailure Failure callback.
239 */
240 AuthorizedXHR.prototype.load = function(url, onSuccess, onFailure) {
241 this.aborted_ = false;
242
243 // Do not call any callbacks when aborting.
244 var onMaybeSuccess = function(contentType, response) {
245 if (!this.aborted_)
246 onSuccess(contentType, response);
247 }.bind(this);
248 var onMaybeFailure = function(opt_code) {
249 if (!this.aborted_)
250 onFailure();
251 }.bind(this);
252
253 // Fetches the access token and makes an authorized call. If refresh is true,
254 // then forces refreshing the access token.
255 var requestTokenAndCall = function(refresh, onInnerSuccess, onInnerFailure) {
256 chrome.fileBrowserPrivate.requestAccessToken(refresh, function(token) {
257 if (this.aborted_)
258 return;
259 if (!token) {
260 onInnerFailure();
261 return;
262 }
263 this.xhr_ = AuthorizedXHR.loadWithToken_(
264 token, url, onInnerSuccess, onInnerFailure);
265 }.bind(this));
266 }.bind(this);
267
268 // Refreshes the access token and retries the request.
269 var maybeRetryCall = function(code) {
270 if (this.aborted_)
271 return;
272 requestTokenAndCall(true, onMaybeSuccess, onMaybeFailure);
273 }.bind(this);
274
275 // Make the request with reusing the current token. If it fails, then retry.
276 requestTokenAndCall(false, onMaybeSuccess, maybeRetryCall);
277 };
278
279 /**
280 * Fetches data using authorized XmlHttpRequest with the provided OAuth2 token.
281 * If the token is invalid, the request will fail.
282 *
283 * @param {string} token OAuth2 token to be injected to the request.
284 * @param {string} url URL to the resource to be fetched.
285 * @param {function(string, Blob}) onSuccess Success callback with the content
286 * type and the fetched data.
287 * @param {function(number=)} onFailure Failure callback with the error code
288 * if available.
289 * @private
290 */
291 AuthorizedXHR.loadWithToken_ = function(token, url, onSuccess, onFailure) {
292 var xhr = new XMLHttpRequest();
293 xhr.responseType = 'blob';
294
295 xhr.onreadystatechange = function() {
296 if (xhr.readyState != 4)
297 return;
298 if (xhr.status != 200) {
299 onFailure(xhr.status);
300 return;
301 }
302 var contentType = xhr.getResponseHeader('Content-Type');
303 onSuccess(contentType, xhr.response);
217 }.bind(this); 304 }.bind(this);
218 305
219 // Perform a xhr request. 306 // Perform a xhr request.
220 try { 307 try {
221 this.xhr_.open('GET', this.request_.url, true); 308 xhr.open('GET', url, true);
222 this.xhr_.send(); 309 xhr.setRequestHeader('Authorization', 'Bearer ' + token);
310 xhr.send();
223 } catch (e) { 311 } catch (e) {
224 this.image_.onerror(); 312 onFailure();
225 } 313 }
226 }; 314 };
227 315
228 /** 316 /**
229 * Sends the resized image via the callback. If the image has been changed, 317 * Sends the resized image via the callback. If the image has been changed,
230 * then packs the canvas contents, otherwise sends the raw image data. 318 * then packs the canvas contents, otherwise sends the raw image data.
231 * 319 *
232 * @param {boolean} imageChanged Whether the image has been changed. 320 * @param {boolean} imageChanged Whether the image has been changed.
233 * @private 321 * @private
234 */ 322 */
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 * @private 411 * @private
324 */ 412 */
325 Request.prototype.cleanup_ = function() { 413 Request.prototype.cleanup_ = function() {
326 this.image_.onerror = function() {}; 414 this.image_.onerror = function() {};
327 this.image_.onload = function() {}; 415 this.image_.onload = function() {};
328 416
329 // Transparent 1x1 pixel gif, to force garbage collecting. 417 // Transparent 1x1 pixel gif, to force garbage collecting.
330 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' + 418 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' +
331 'ABAAEAAAICTAEAOw=='; 419 'ABAAEAAAICTAEAOw==';
332 420
333 this.xhr_.onerror = function() {};
334 this.xhr_.onload = function() {}; 421 this.xhr_.onload = function() {};
335 this.xhr_.abort(); 422 this.xhr_.abort();
336 423
337 // Dispose memory allocated by Canvas. 424 // Dispose memory allocated by Canvas.
338 this.canvas_.width = 0; 425 this.canvas_.width = 0;
339 this.canvas_.height = 0; 426 this.canvas_.height = 0;
340 }; 427 };
OLDNEW
« no previous file with comments | « chrome/browser/resources/image_loader/manifest.json ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698