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

Side by Side Diff: chrome/browser/resources/local_ntp/most_visited_single.js

Issue 2693143002: Cleanup in NTP single-iframe (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « no previous file | 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 2015 The Chromium Authors. All rights reserved. 1 /* Copyright 2015 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 // Single iframe for NTP tiles. 5 // Single iframe for NTP tiles.
6 (function() { 6 (function() {
7 'use strict'; 7 'use strict';
8 8
9 9
10 /** 10 /**
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 }); 322 });
323 }; 323 };
324 324
325 325
326 /** 326 /**
327 * Returns whether the given URL has a known, safe scheme. 327 * Returns whether the given URL has a known, safe scheme.
328 * @param {string} url URL to check. 328 * @param {string} url URL to check.
329 */ 329 */
330 var isSchemeAllowed = function(url) { 330 var isSchemeAllowed = function(url) {
331 return url.startsWith('http://') || url.startsWith('https://') || 331 return url.startsWith('http://') || url.startsWith('https://') ||
332 url.startsWith('ftp://') || url.startsWith('file://') || 332 url.startsWith('ftp://') || url.startsWith('chrome-extension://');
333 url.startsWith('chrome-extension://');
334 }; 333 };
335 334
336 335
337 /** 336 /**
338 * Renders a MostVisited tile to the DOM. 337 * Renders a MostVisited tile to the DOM.
339 * @param {object} data Object containing rid, url, title, favicon, thumbnail. 338 * @param {object} data Object containing rid, url, title, favicon, thumbnail.
340 * data is null if you want to construct an empty tile. 339 * data is null if you want to construct an empty tile.
341 */ 340 */
342 var renderTile = function(data) { 341 var renderTile = function(data) {
343 var tile = document.createElement('a'); 342 var tile = document.createElement('a');
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 title.style.direction = data.direction || 'ltr'; 416 title.style.direction = data.direction || 'ltr';
418 if (NUM_TITLE_LINES > 1) { 417 if (NUM_TITLE_LINES > 1) {
419 title.classList.add('multiline'); 418 title.classList.add('multiline');
420 } 419 }
421 420
422 // We keep track of the outcome of loading possible thumbnails for this 421 // We keep track of the outcome of loading possible thumbnails for this
423 // tile. Possible values: 422 // tile. Possible values:
424 // - null: waiting for load/error 423 // - null: waiting for load/error
425 // - false: error 424 // - false: error
426 // - a string: URL that loaded correctly. 425 // - a string: URL that loaded correctly.
427 // This is populated by acceptImage/rejectImage and loadBestImage 426 // This is populated by imageLoaded/imageLoadFailed, and selectBestImage
428 // decides the best one to load. 427 // selects the best one to display.
429 var results = []; 428 var results = [];
430 var thumb = tile.querySelector('.mv-thumb'); 429 var thumb = tile.querySelector('.mv-thumb');
431 var img = document.createElement('img'); 430 var img = document.createElement('img');
432 var loaded = false; 431 var loaded = false;
433 432
434 var loadBestImage = function() { 433 var selectBestImage = function() {
435 if (loaded) { 434 if (loaded) {
436 return; 435 return;
437 } 436 }
437 // |results| is ordered from best candidate to worst.
438 for (var i = 0; i < results.length; ++i) { 438 for (var i = 0; i < results.length; ++i) {
439 if (results[i] === null) { 439 if (results[i] === null) {
440 // A better candidate is still waiting to be loaded; defer.
440 return; 441 return;
441 } 442 }
442 if (results[i] != false) { 443 if (results[i] != false) {
444 // This is the best (non-failed) candidate. Use it!
443 img.src = results[i]; 445 img.src = results[i];
444 loaded = true; 446 loaded = true;
445 return; 447 return;
446 } 448 }
447 } 449 }
450 // If we get here, then all candidates failed to load.
448 thumb.classList.add('failed-img'); 451 thumb.classList.add('failed-img');
449 thumb.removeChild(img); 452 thumb.removeChild(img);
453 // Usually we count the load once the img element gets either a 'load' or
454 // an 'error' event. Since we have removed the img element, instead count
455 // the load here.
450 countLoad(); 456 countLoad();
451 }; 457 };
452 458
453 var acceptImage = function(idx, url) { 459 var imageLoaded = function(idx, url) {
454 return function(ev) { 460 return function(ev) {
455 results[idx] = url; 461 results[idx] = url;
456 loadBestImage(); 462 selectBestImage();
457 }; 463 };
458 }; 464 };
459 465
460 var rejectImage = function(idx) { 466 var imageLoadFailed = function(idx) {
461 return function(ev) { 467 return function(ev) {
462 results[idx] = false; 468 results[idx] = false;
463 loadBestImage(); 469 selectBestImage();
464 }; 470 };
465 }; 471 };
466 472
467 img.title = data.title; 473 img.title = data.title;
468 img.classList.add('thumbnail'); 474 img.classList.add('thumbnail');
469 loadedCounter += 1; 475 loadedCounter += 1;
470 img.addEventListener('load', countLoad); 476 img.addEventListener('load', countLoad);
471 img.addEventListener('error', countLoad); 477 img.addEventListener('error', countLoad);
472 img.addEventListener('error', function(ev) { 478 img.addEventListener('error', function(ev) {
473 thumb.classList.add('failed-img'); 479 thumb.classList.add('failed-img');
474 thumb.removeChild(img); 480 thumb.removeChild(img);
475 }); 481 });
476 thumb.appendChild(img); 482 thumb.appendChild(img);
477 483
478 if (data.thumbnailUrl) { 484 if (data.thumbnailUrl) {
479 img.src = data.thumbnailUrl; 485 img.src = data.thumbnailUrl;
480 } else { 486 } else {
481 // Get all thumbnailUrls for the tile. 487 // Get all thumbnailUrls for the tile.
482 // They are ordered from best one to be used to worst. 488 // They are ordered from best one to be used to worst.
483 for (var i = 0; i < data.thumbnailUrls.length; ++i) { 489 for (var i = 0; i < data.thumbnailUrls.length; ++i) {
484 results.push(null); 490 results.push(null);
485 } 491 }
486 for (var i = 0; i < data.thumbnailUrls.length; ++i) { 492 for (var i = 0; i < data.thumbnailUrls.length; ++i) {
487 if (data.thumbnailUrls[i]) { 493 if (data.thumbnailUrls[i]) {
488 var image = new Image(); 494 var image = new Image();
489 image.src = data.thumbnailUrls[i]; 495 image.src = data.thumbnailUrls[i];
490 image.onload = acceptImage(i, data.thumbnailUrls[i]); 496 image.onload = imageLoaded(i, data.thumbnailUrls[i]);
491 image.onerror = rejectImage(i); 497 image.onerror = imageLoadFailed(i);
492 } else { 498 } else {
493 rejectImage(i)(null); 499 imageLoadFailed(i)(/*ev=*/null);
494 } 500 }
495 } 501 }
496 } 502 }
497 503
498 var favicon = tile.querySelector('.mv-favicon'); 504 var favicon = tile.querySelector('.mv-favicon');
499 if (data.faviconUrl) { 505 if (data.faviconUrl) {
500 var fi = document.createElement('img'); 506 var fi = document.createElement('img');
501 fi.src = data.faviconUrl; 507 fi.src = data.faviconUrl;
502 // Set the title to empty so screen readers won't say the image name. 508 // Set the title to empty so screen readers won't say the image name.
503 fi.title = ''; 509 fi.title = '';
(...skipping 14 matching lines...) Expand all
518 blacklistTile(tile); 524 blacklistTile(tile);
519 ev.preventDefault(); 525 ev.preventDefault();
520 ev.stopPropagation(); 526 ev.stopPropagation();
521 }); 527 });
522 528
523 return tile; 529 return tile;
524 }; 530 };
525 531
526 532
527 /** 533 /**
528 * Do some initialization and parses the query arguments passed to the iframe. 534 * Does some initialization and parses the query arguments passed to the iframe.
529 */ 535 */
530 var init = function() { 536 var init = function() {
531 // Creates a new DOM element to hold the tiles. 537 // Create a new DOM element to hold the tiles. The tiles will be added
538 // one-by-one via addTile, and the whole thing will be inserted into the page
539 // in showTiles, after the parent has sent us the 'show' message, and all
540 // thumbnails and favicons have loaded.
532 tiles = document.createElement('div'); 541 tiles = document.createElement('div');
533 542
534 // Parse query arguments. 543 // Parse query arguments.
535 var query = window.location.search.substring(1).split('&'); 544 var query = window.location.search.substring(1).split('&');
536 queryArgs = {}; 545 queryArgs = {};
537 for (var i = 0; i < query.length; ++i) { 546 for (var i = 0; i < query.length; ++i) {
538 var val = query[i].split('='); 547 var val = query[i].split('=');
539 if (val[0] == '') continue; 548 if (val[0] == '') continue;
540 queryArgs[decodeURIComponent(val[0])] = decodeURIComponent(val[1]); 549 queryArgs[decodeURIComponent(val[0])] = decodeURIComponent(val[1]);
541 } 550 }
(...skipping 11 matching lines...) Expand all
553 var html = document.querySelector('html'); 562 var html = document.querySelector('html');
554 html.dir = 'rtl'; 563 html.dir = 'rtl';
555 } 564 }
556 565
557 window.addEventListener('message', handlePostMessage); 566 window.addEventListener('message', handlePostMessage);
558 }; 567 };
559 568
560 569
561 window.addEventListener('DOMContentLoaded', init); 570 window.addEventListener('DOMContentLoaded', init);
562 })(); 571 })();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698