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

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

Issue 473583002: [Local NTP] Implementing Material Design styling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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
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 5
6 /** 6 /**
7 * @fileoverview The local InstantExtended NTP. 7 * @fileoverview The local InstantExtended NTP.
8 */ 8 */
9 9
10 10
(...skipping 10 matching lines...) Expand all
21 21
22 /** 22 /**
23 * Enum for classnames. 23 * Enum for classnames.
24 * @enum {string} 24 * @enum {string}
25 * @const 25 * @const
26 */ 26 */
27 var CLASSES = { 27 var CLASSES = {
28 ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme 28 ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme
29 BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation 29 BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation
30 BLACKLIST_BUTTON: 'mv-x', 30 BLACKLIST_BUTTON: 'mv-x',
31 DARK: 'dark',
31 DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide', 32 DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide',
33 DOT: 'dot',
32 FAKEBOX_DISABLE: 'fakebox-disable', // Makes fakebox non-interactive 34 FAKEBOX_DISABLE: 'fakebox-disable', // Makes fakebox non-interactive
33 FAKEBOX_FOCUS: 'fakebox-focused', // Applies focus styles to the fakebox 35 FAKEBOX_FOCUS: 'fakebox-focused', // Applies focus styles to the fakebox
34 // Applies drag focus style to the fakebox 36 // Applies drag focus style to the fakebox
35 FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused', 37 FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused',
36 FAVICON: 'mv-favicon', 38 FAVICON: 'mv-favicon',
37 HIDE_BLACKLIST_BUTTON: 'mv-x-hide', // hides blacklist button during animation 39 HIDE_BLACKLIST_BUTTON: 'mv-x-hide', // hides blacklist button during animation
38 HIDE_FAKEBOX_AND_LOGO: 'hide-fakebox-logo', 40 HIDE_FAKEBOX_AND_LOGO: 'hide-fakebox-logo',
39 HIDE_NOTIFICATION: 'mv-notice-hide', 41 HIDE_NOTIFICATION: 'mv-notice-hide',
40 // Vertically centers the most visited section for a non-Google provided page. 42 // Vertically centers the most visited section for a non-Google provided page.
41 NON_GOOGLE_PAGE: 'non-google-page', 43 NON_GOOGLE_PAGE: 'non-google-page',
42 PAGE: 'mv-page', // page tiles 44 PAGE: 'mv-page', // page tiles
43 PAGE_READY: 'mv-page-ready', // page tile when ready 45 PAGE_READY: 'mv-page-ready', // page tile when ready
44 RTL: 'rtl', // Right-to-left language text. 46 RTL: 'rtl', // Right-to-left language text.
45 THUMBNAIL: 'mv-thumb', 47 THUMBNAIL: 'mv-thumb',
48 THUMBNAIL_FALLBACK: 'mv-thumb-fallback',
46 THUMBNAIL_MASK: 'mv-mask', 49 THUMBNAIL_MASK: 'mv-mask',
47 TILE: 'mv-tile', 50 TILE: 'mv-tile',
51 TILE_INNER: 'mv-tile-inner',
48 TITLE: 'mv-title' 52 TITLE: 'mv-title'
49 }; 53 };
50 54
51 55
52 /** 56 /**
53 * Enum for HTML element ids. 57 * Enum for HTML element ids.
54 * @enum {string} 58 * @enum {string}
55 * @const 59 * @const
56 */ 60 */
57 var IDS = { 61 var IDS = {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 /** 166 /**
163 * True if a page has been blacklisted and we're waiting on the 167 * True if a page has been blacklisted and we're waiting on the
164 * onmostvisitedchange callback. See onMostVisitedChange() for how this 168 * onmostvisitedchange callback. See onMostVisitedChange() for how this
165 * is used. 169 * is used.
166 * @type {boolean} 170 * @type {boolean}
167 */ 171 */
168 var isBlacklisting = false; 172 var isBlacklisting = false;
169 173
170 174
171 /** 175 /**
176 * Stores whether the current theme has a dark background.
177 * @type {boolean}
178 */
179 var isBackgroundDark = false;
180
181
182 /**
172 * Current number of tiles columns shown based on the window width, including 183 * Current number of tiles columns shown based on the window width, including
173 * those that just contain filler. 184 * those that just contain filler.
174 * @type {number} 185 * @type {number}
175 */ 186 */
176 var numColumnsShown = 0; 187 var numColumnsShown = 0;
177 188
178 189
179 /** 190 /**
180 * A flag to indicate Most Visited changed caused by user action. If true, then 191 * A flag to indicate Most Visited changed caused by user action. If true, then
181 * in onMostVisitedChange() tiles remain visible so no flickering occurs. 192 * in onMostVisitedChange() tiles remain visible so no flickering occurs.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 * @const 270 * @const
260 */ 271 */
261 var MOST_VISITED_PAINT_TIMEOUT_MSEC = 500; 272 var MOST_VISITED_PAINT_TIMEOUT_MSEC = 500;
262 273
263 274
264 /** 275 /**
265 * A Tile is either a rendering of a Most Visited page or "filler" used to 276 * A Tile is either a rendering of a Most Visited page or "filler" used to
266 * pad out the section when not enough pages exist. 277 * pad out the section when not enough pages exist.
267 * 278 *
268 * @param {Element} elem The element for rendering the tile. 279 * @param {Element} elem The element for rendering the tile.
280 * @param {Element=} opt_innerElem The element for contents of tile.
269 * @param {Element=} opt_titleElem The element for rendering the title. 281 * @param {Element=} opt_titleElem The element for rendering the title.
270 * @param {Element=} opt_thumbnailElem The element for rendering the thumbnail. 282 * @param {Element=} opt_thumbnailElem The element for rendering the thumbnail.
271 * @param {number=} opt_rid The RID for the corresponding Most Visited page. 283 * @param {number=} opt_rid The RID for the corresponding Most Visited page.
272 * Should only be left unspecified when creating a filler tile. 284 * Should only be left unspecified when creating a filler tile.
273 * @constructor 285 * @constructor
274 */ 286 */
275 function Tile(elem, opt_titleElem, opt_thumbnailElem, opt_rid) { 287 function Tile(elem, opt_innerElem, opt_titleElem, opt_thumbnailElem, opt_rid) {
276 /** @type {Element} */ 288 /** @type {Element} */
277 this.elem = elem; 289 this.elem = elem;
278 290
279 /** @type {Element|undefined} */ 291 /** @type {Element|undefined} */
292 this.innerElem = opt_innerElem;
293
294 /** @type {Element|undefined} */
280 this.titleElem = opt_titleElem; 295 this.titleElem = opt_titleElem;
281 296
282 /** @type {Element|undefined} */ 297 /** @type {Element|undefined} */
283 this.thumbnailElem = opt_thumbnailElem; 298 this.thumbnailElem = opt_thumbnailElem;
284 299
285 /** @type {number|undefined} */ 300 /** @type {number|undefined} */
286 this.rid = opt_rid; 301 this.rid = opt_rid;
287 } 302 }
288 303
289 304
290 /** 305 /**
306 * Determines whether a theme should be considered to have dark background.
307 * @param {ThemeBackgroundInfo} info Theme background information.
308 * @return {boolean} Whether the theme has dark background.
309 * @private
310 */
311 function getIsBackgroundDark(info) {
Mathieu 2014/08/13 20:09:29 rename to isThemeBackgroundDark?
huangs 2014/08/13 21:34:08 Inlined this into renderTheme(), since predominate
312 if (info.imageUrl)
313 return true;
314 var rgba = info.backgroundColorRgba;
315 var luminance = 0.3 * rgba[0] + 0.59 * rgba[1] + 0.11 * rgba[2];
316 return luminance < 128;
317 }
318
319
320 /**
291 * Updates the NTP based on the current theme. 321 * Updates the NTP based on the current theme.
292 * @private 322 * @private
293 */ 323 */
294 function onThemeChange() { 324 function renderTheme() {
295 var info = ntpApiHandle.themeBackgroundInfo; 325 var info = ntpApiHandle.themeBackgroundInfo;
296 if (!info) 326 if (!info) {
327 isBackgroundDark = false;
297 return; 328 return;
329 }
330
331 isBackgroundDark = getIsBackgroundDark(info);
332 ntpContents.classList.toggle(CLASSES.DARK, isBackgroundDark);
298 333
299 var background = [convertToRGBAColor(info.backgroundColorRgba), 334 var background = [convertToRGBAColor(info.backgroundColorRgba),
300 info.imageUrl, 335 info.imageUrl,
301 info.imageTiling, 336 info.imageTiling,
302 info.imageHorizontalAlignment, 337 info.imageHorizontalAlignment,
303 info.imageVerticalAlignment].join(' ').trim(); 338 info.imageVerticalAlignment].join(' ').trim();
304 document.body.style.background = background; 339 document.body.style.background = background;
305 document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo); 340 document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo);
306 updateThemeAttribution(info.attributionUrl); 341 updateThemeAttribution(info.attributionUrl);
307 setCustomThemeStyle(info); 342 setCustomThemeStyle(info);
343 }
308 344
345
346 /**
347 * Updates the NTP based on the current theme, then rerenders all tiles.
348 * @private
349 */
350 function onThemeChange() {
351 renderTheme();
309 tilesContainer.innerHTML = ''; 352 tilesContainer.innerHTML = '';
310 renderAndShowTiles(); 353 renderAndShowTiles();
311 } 354 }
312 355
313 356
314 /** 357 /**
315 * Updates the NTP style according to theme. 358 * Updates the NTP style according to theme.
316 * @param {Object=} opt_themeInfo The information about the theme. If it is 359 * @param {Object=} opt_themeInfo The information about the theme. If it is
317 * omitted the style will be reverted to the default. 360 * omitted the style will be reverted to the default.
318 * @private 361 * @private
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 color[3] / 255 + ')'; 448 color[3] / 255 + ')';
406 } 449 }
407 450
408 451
409 /** 452 /**
410 * Handles a new set of Most Visited page data. 453 * Handles a new set of Most Visited page data.
411 */ 454 */
412 function onMostVisitedChange() { 455 function onMostVisitedChange() {
413 if (isBlacklisting) { 456 if (isBlacklisting) {
414 // Trigger the blacklist animation, which then triggers reloadAllTiles(). 457 // Trigger the blacklist animation, which then triggers reloadAllTiles().
415 var lastBlacklistedTileElement = lastBlacklistedTile.elem; 458 var lastBlacklistedTileElem = lastBlacklistedTile.elem;
416 lastBlacklistedTileElement.addEventListener( 459 lastBlacklistedTileElem.addEventListener(
417 'webkitTransitionEnd', blacklistAnimationDone); 460 'webkitTransitionEnd', blacklistAnimationDone);
418 lastBlacklistedTileElement.classList.add(CLASSES.BLACKLIST); 461 lastBlacklistedTileElem.classList.add(CLASSES.BLACKLIST);
419 } else { 462 } else {
420 reloadAllTiles(); 463 reloadAllTiles();
421 } 464 }
422 } 465 }
423 466
424 467
425 /** 468 /**
426 * Handles the end of the blacklist animation by showing the notification and 469 * Handles the end of the blacklist animation by showing the notification and
427 * re-rendering the new set of tiles. 470 * re-rendering the new set of tiles.
428 */ 471 */
(...skipping 21 matching lines...) Expand all
450 tiles.push(createTile(pages[i], i)); 493 tiles.push(createTile(pages[i], i));
451 494
452 tilesContainer.innerHTML = ''; 495 tilesContainer.innerHTML = '';
453 renderAndShowTiles(); 496 renderAndShowTiles();
454 } 497 }
455 498
456 499
457 /** 500 /**
458 * Binds onload events for a tile's internal <iframe> elements. 501 * Binds onload events for a tile's internal <iframe> elements.
459 * @param {Tile} tile The main tile to bind events to. 502 * @param {Tile} tile The main tile to bind events to.
460 * @param {Barrier} tileVisibilityBarrier A barrier to make tile visible the 503 * @param {Barrier} tileVisibilityBarrier A barrier to make all tiles visible
461 * moment all tiles are loaded. 504 * the moment all tiles are loaded.
462 */ 505 */
463 function bindTileOnloadEvents(tile, tileVisibilityBarrier) { 506 function bindTileOnloadEvents(tile, tileVisibilityBarrier) {
464 if (tile.titleElem) { 507 if (tile.titleElem) {
465 tileVisibilityBarrier.add(); 508 tileVisibilityBarrier.add();
466 tile.titleElem.onload = function() { 509 tile.titleElem.onload = function() {
467 tile.titleElem.hidden = false;
468 tileVisibilityBarrier.remove(); 510 tileVisibilityBarrier.remove();
469 }; 511 };
470 } 512 }
471
472 if (tile.thumbnailElem) { 513 if (tile.thumbnailElem) {
473 tileVisibilityBarrier.add(); 514 tileVisibilityBarrier.add();
474 tile.thumbnailElem.onload = function() { 515 tile.thumbnailElem.onload = function() {
475 tile.thumbnailElem.hidden = false;
476 tile.elem.classList.add(CLASSES.PAGE_READY); 516 tile.elem.classList.add(CLASSES.PAGE_READY);
477 tileVisibilityBarrier.remove(); 517 tileVisibilityBarrier.remove();
478 }; 518 };
479 } 519 }
480 } 520 }
481 521
482 522
483 /** 523 /**
484 * Renders the current list of visible tiles to DOM, and hides tiles that are 524 * Renders the current list of visible tiles to DOM, and hides tiles that are
485 * already in the DOM but should not be seen. 525 * already in the DOM but should not be seen.
486 */ 526 */
487 function renderAndShowTiles() { 527 function renderAndShowTiles() {
488 var numExisting = tilesContainer.querySelectorAll('.' + CLASSES.TILE).length; 528 var numExisting = tilesContainer.querySelectorAll('.' + CLASSES.TILE).length;
489 // Only add visible tiles to the DOM, to avoid creating invisible tiles that 529 // Only add visible tiles to the DOM, to avoid creating invisible tiles that
490 // produce meaningless impression metrics. However, if a tile becomes 530 // produce meaningless impression metrics. However, if a tile becomes
491 // invisible then we leave it in DOM to prevent reload if it's shown again. 531 // invisible then we leave it in DOM to prevent reload if it's shown again.
492 var numDesired = Math.min(tiles.length, numColumnsShown * NUM_ROWS); 532 var numDesired = Math.min(tiles.length, numColumnsShown * NUM_ROWS);
493 533
494 // If we need to render new tiles, manage the visibility to hide intermediate 534 // If we need to render new tiles, manage the visibility to hide intermediate
495 // load states of the <iframe>s. 535 // load states of the <iframe>s.
496 if (numExisting < numDesired) { 536 if (numExisting < numDesired) {
497 var tileVisibilityBarrier = new Barrier(function() { 537 var showAll = function() {
498 tilesContainer.style.visibility = 'visible'; 538 for (var i = 0; i < numDesired; ++i) {
499 }); 539 if (tiles[i].titleElem || tiles[i].thumbnailElem)
540 tiles[i].elem.classList.add(CLASSES.PAGE_READY);
541 }
542 };
543 var tileVisibilityBarrier = new Barrier(showAll);
500 544
501 if (!userInitiatedMostVisitedChange) { 545 if (!userInitiatedMostVisitedChange) {
502 // Make titleContainer invisible, but still taking up space. 546 // Make titleContainer invisible, but still taking up space.
503 // titleContainer becomes visible again (1) on timeout, or (2) when all 547 // titleContainer becomes visible again (1) on timeout, or (2) when all
504 // tiles finish loading (using tileVisibilityBarrier). 548 // tiles finish loading (using tileVisibilityBarrier).
505 tilesContainer.style.visibility = 'hidden';
506 window.setTimeout(function() { 549 window.setTimeout(function() {
507 tileVisibilityBarrier.cancel(); 550 tileVisibilityBarrier.cancel();
508 tilesContainer.style.visibility = 'visible'; 551 showAll();
509 }, MOST_VISITED_PAINT_TIMEOUT_MSEC); 552 }, MOST_VISITED_PAINT_TIMEOUT_MSEC);
510 } 553 }
511 userInitiatedMostVisitedChange = false; 554 userInitiatedMostVisitedChange = false;
512 555
513 for (var i = numExisting; i < numDesired; ++i) { 556 for (var i = numExisting; i < numDesired; ++i) {
514 bindTileOnloadEvents(tiles[i], tileVisibilityBarrier); 557 bindTileOnloadEvents(tiles[i], tileVisibilityBarrier);
515 tilesContainer.appendChild(tiles[i].elem); 558 tilesContainer.appendChild(tiles[i].elem);
516 } 559 }
517 } 560 }
518 561
519 // Show only the desired tiles. Not using .hidden because it does not work for 562 // Show only the desired tiles. Note that .hidden does not work for
520 // inline-block elements. 563 // inline-block elements like tiles[i].elem.
521 for (var i = 0; i < numDesired; ++i) 564 for (var i = 0; i < numDesired; ++i)
522 tiles[i].elem.style.display = 'inline-block'; 565 tiles[i].elem.style.display = 'inline-block';
523 // If |numDesired| < |numExisting| then hide extra tiles (e.g., this occurs 566 // If |numDesired| < |numExisting| then hide extra tiles (e.g., this occurs
524 // when window is downsized). 567 // when window is downsized).
525 for (; i < numExisting; ++i) 568 for (; i < numExisting; ++i)
526 tiles[i].elem.style.display = 'none'; 569 tiles[i].elem.style.display = 'none';
527 } 570 }
528 571
529 572
530 /** 573 /**
531 * Builds a URL to display a most visited tile title in an iframe. 574 * Builds a URL to display a most visited tile title in an iframe.
532 * @param {number} rid The restricted ID. 575 * @param {number} rid The restricted ID.
533 * @param {number} position The position of the iframe in the UI. 576 * @param {number} position The position of the iframe in the UI.
534 * @return {string} An URL to display the most visited title in an iframe. 577 * @return {string} An URL to display the most visited title in an iframe.
535 */ 578 */
536 function getMostVisitedTitleIframeUrl(rid, position) { 579 function getMostVisitedTitleIframeUrl(rid, position) {
537 var url = 'chrome-search://most-visited/' + 580 var url = 'chrome-search://most-visited/' +
538 encodeURIComponent(MOST_VISITED_TITLE_IFRAME); 581 encodeURIComponent(MOST_VISITED_TITLE_IFRAME);
582 var titleColor = isBackgroundDark ? NTP_DESIGN.titleColorAgainstDark :
583 NTP_DESIGN.titleColor;
539 var params = [ 584 var params = [
540 'rid=' + encodeURIComponent(rid), 585 'rid=' + encodeURIComponent(rid),
541 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily), 586 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily),
542 'fs=' + encodeURIComponent(NTP_DESIGN.fontSize), 587 'fs=' + encodeURIComponent(NTP_DESIGN.fontSize),
543 'c=' + encodeURIComponent(NTP_DESIGN.titleColor), 588 'c=' + encodeURIComponent(titleColor),
544 'pos=' + encodeURIComponent(position)]; 589 'pos=' + encodeURIComponent(position)];
545 if (NTP_DESIGN.titleTextAlign) 590 if (NTP_DESIGN.titleTextAlign)
546 params.push('ta=' + encodeURIComponent(NTP_DESIGN.titleTextAlign)); 591 params.push('ta=' + encodeURIComponent(NTP_DESIGN.titleTextAlign));
547 if (NTP_DESIGN.titleTextFade) 592 if (NTP_DESIGN.titleTextFade)
548 params.push('tf=' + encodeURIComponent(NTP_DESIGN.titleTextFade)); 593 params.push('tf=' + encodeURIComponent(NTP_DESIGN.titleTextFade));
549 return url + '?' + params.join('&'); 594 return url + '?' + params.join('&');
550 } 595 }
551 596
552 597
553 /** 598 /**
554 * Builds a URL to display a most visited tile thumbnail in an iframe. 599 * Builds a URL to display a most visited tile thumbnail in an iframe.
555 * @param {number} rid The restricted ID. 600 * @param {number} rid The restricted ID.
556 * @param {number} position The position of the iframe in the UI. 601 * @param {number} position The position of the iframe in the UI.
557 * @return {string} An URL to display the most visited thumbnail in an iframe. 602 * @return {string} An URL to display the most visited thumbnail in an iframe.
558 */ 603 */
559 function getMostVisitedThumbnailIframeUrl(rid, position) { 604 function getMostVisitedThumbnailIframeUrl(rid, position) {
560 var url = 'chrome-search://most-visited/' + 605 var url = 'chrome-search://most-visited/' +
561 encodeURIComponent(MOST_VISITED_THUMBNAIL_IFRAME); 606 encodeURIComponent(MOST_VISITED_THUMBNAIL_IFRAME);
562 var params = [ 607 var params = [
563 'rid=' + encodeURIComponent(rid), 608 'rid=' + encodeURIComponent(rid),
564 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily), 609 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily),
565 'fs=' + encodeURIComponent(NTP_DESIGN.fontSize), 610 'fs=' + encodeURIComponent(NTP_DESIGN.fontSize),
566 'c=' + encodeURIComponent(NTP_DESIGN.thumbnailTextColor), 611 'c=' + encodeURIComponent(NTP_DESIGN.thumbnailTextColor),
567 'pos=' + encodeURIComponent(position)]; 612 'pos=' + encodeURIComponent(position)];
613 if (NTP_DESIGN.thumbnailFallback)
614 params.push('tfb=1');
568 return url + '?' + params.join('&'); 615 return url + '?' + params.join('&');
569 } 616 }
570 617
571 618
572 /** 619 /**
573 * Creates a Tile with the specified page data. If no data is provided, a 620 * Creates a Tile with the specified page data. If no data is provided, a
574 * filler Tile is created. 621 * filler Tile is created.
575 * @param {Object} page The page data. 622 * @param {Object} page The page data.
576 * @param {number} position The position of the tile. 623 * @param {number} position The position of the tile.
577 * @return {Tile} The new Tile. 624 * @return {Tile} The new Tile.
578 */ 625 */
579 function createTile(page, position) { 626 function createTile(page, position) {
580 var tileElement = document.createElement('div'); 627 var tileElem = document.createElement('div');
581 tileElement.classList.add(CLASSES.TILE); 628 tileElem.classList.add(CLASSES.TILE);
629 var innerElem = createAndAppendElement(tileElem, 'div', CLASSES.TILE_INNER);
582 630
583 if (page) { 631 if (page) {
584 var rid = page.rid; 632 var rid = page.rid;
585 tileElement.classList.add(CLASSES.PAGE); 633 tileElem.classList.add(CLASSES.PAGE);
586 634
587 var navigateFunction = function(e) { 635 var navigateFunction = function(e) {
588 e.preventDefault(); 636 e.preventDefault();
589 ntpApiHandle.navigateContentWindow(rid, getDispositionFromEvent(e)); 637 ntpApiHandle.navigateContentWindow(rid, getDispositionFromEvent(e));
590 }; 638 };
591 639
592 // The click handler for navigating to the page identified by the RID. 640 // The click handler for navigating to the page identified by the RID.
593 tileElement.addEventListener('click', navigateFunction); 641 tileElem.addEventListener('click', navigateFunction);
594 642
595 // Make thumbnails tab-accessible. 643 // Make thumbnails tab-accessible.
596 tileElement.setAttribute('tabindex', '1'); 644 tileElem.setAttribute('tabindex', '1');
597 registerKeyHandler(tileElement, KEYCODE.ENTER, navigateFunction); 645 registerKeyHandler(tileElem, KEYCODE.ENTER, navigateFunction);
598 646
599 // The iframe which renders the page title. 647 // The iframe which renders the page title.
600 var titleElement = document.createElement('iframe'); 648 var titleElem = document.createElement('iframe');
601 titleElement.tabIndex = '-1'; 649 titleElem.tabIndex = '-1';
602 650
603 // Why iframes have IDs: 651 // Why iframes have IDs:
604 // 652 //
605 // On navigating back to the NTP we see several onmostvisitedchange() events 653 // On navigating back to the NTP we see several onmostvisitedchange() events
606 // in series with incrementing RIDs. After the first event, a set of iframes 654 // in series with incrementing RIDs. After the first event, a set of iframes
607 // begins loading RIDs n, n+1, ..., n+k-1; after the second event, these get 655 // begins loading RIDs n, n+1, ..., n+k-1; after the second event, these get
608 // destroyed and a new set begins loading RIDs n+k, n+k+1, ..., n+2k-1. 656 // destroyed and a new set begins loading RIDs n+k, n+k+1, ..., n+2k-1.
609 // Now due to crbug.com/68841, Chrome incorrectly loads the content for the 657 // Now due to crbug.com/68841, Chrome incorrectly loads the content for the
610 // first set of iframes into the most recent set of iframes. 658 // first set of iframes into the most recent set of iframes.
611 // 659 //
612 // Giving iframes distinct ids seems to cause some invalidation and prevent 660 // Giving iframes distinct ids seems to cause some invalidation and prevent
613 // associating the incorrect data. 661 // associating the incorrect data.
614 // 662 //
615 // TODO(jered): Find and fix the root (probably Blink) bug. 663 // TODO(jered): Find and fix the root (probably Blink) bug.
616 664
617 // Keep this ID here. See comment above. 665 // Keep this ID here. See comment above.
618 titleElement.id = 'title-' + rid; 666 titleElem.id = 'title-' + rid;
619 titleElement.className = CLASSES.TITLE; 667 titleElem.className = CLASSES.TITLE;
620 titleElement.hidden = true; 668 titleElem.src = getMostVisitedTitleIframeUrl(rid, position);
621 titleElement.src = getMostVisitedTitleIframeUrl(rid, position); 669 innerElem.appendChild(titleElem);
622 tileElement.appendChild(titleElement); 670
671 // A fallback element for missing thumbnails.
672 if (NTP_DESIGN.thumbnailFallback) {
673 var fallbackElem = createAndAppendElement(
674 innerElem, 'div', CLASSES.THUMBNAIL_FALLBACK);
675 if (NTP_DESIGN.thumbnailFallback === THUMBNAIL_FALLBACK.DOT)
676 createAndAppendElement(fallbackElem, 'div', CLASSES.DOT);
677 }
623 678
624 // The iframe which renders either a thumbnail or domain element. 679 // The iframe which renders either a thumbnail or domain element.
625 var thumbnailElement = document.createElement('iframe'); 680 var thumbnailElem = document.createElement('iframe');
626 thumbnailElement.tabIndex = '-1'; 681 thumbnailElem.tabIndex = '-1';
627 // Keep this ID here. See comment above. 682 // Keep this ID here. See comment above.
628 thumbnailElement.id = 'thumb-' + rid; 683 thumbnailElem.id = 'thumb-' + rid;
629 thumbnailElement.className = CLASSES.THUMBNAIL; 684 thumbnailElem.className = CLASSES.THUMBNAIL;
630 thumbnailElement.hidden = true; 685 thumbnailElem.src = getMostVisitedThumbnailIframeUrl(rid, position);
631 thumbnailElement.src = getMostVisitedThumbnailIframeUrl(rid, position); 686 innerElem.appendChild(thumbnailElem);
632 tileElement.appendChild(thumbnailElement);
633
634 // A mask to darken the thumbnail on focus.
635 var maskElement = createAndAppendElement(
636 tileElement, 'div', CLASSES.THUMBNAIL_MASK);
637 687
638 // The button used to blacklist this page. 688 // The button used to blacklist this page.
639 var blacklistButton = createAndAppendElement( 689 var blacklistButton = createAndAppendElement(
640 tileElement, 'div', CLASSES.BLACKLIST_BUTTON); 690 innerElem, 'div', CLASSES.BLACKLIST_BUTTON);
641 var blacklistFunction = generateBlacklistFunction(rid); 691 var blacklistFunction = generateBlacklistFunction(rid);
642 blacklistButton.addEventListener('click', blacklistFunction); 692 blacklistButton.addEventListener('click', blacklistFunction);
643 blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip; 693 blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip;
644 694
695 // A helper mask on top of the tile that is used to create hover border
696 // and/or to darken the thumbnail on focus.
697 var maskElement = createAndAppendElement(
698 innerElem, 'div', CLASSES.THUMBNAIL_MASK);
699
645 // When a tile is focused, have delete also blacklist the page. 700 // When a tile is focused, have delete also blacklist the page.
646 registerKeyHandler(tileElement, KEYCODE.DELETE, blacklistFunction); 701 registerKeyHandler(tileElem, KEYCODE.DELETE, blacklistFunction);
647 702
648 // The page favicon, if any. 703 // The page favicon, if any.
649 var faviconUrl = page.faviconUrl; 704 var faviconUrl = page.faviconUrl;
650 if (faviconUrl) { 705 if (faviconUrl) {
651 var favicon = createAndAppendElement(tileElement, 'div', CLASSES.FAVICON); 706 var favicon = createAndAppendElement(innerElem, 'div', CLASSES.FAVICON);
652 favicon.style.backgroundImage = 'url(' + faviconUrl + ')'; 707 favicon.style.backgroundImage = 'url(' + faviconUrl + ')';
653 } 708 }
654 return new Tile(tileElement, titleElement, thumbnailElement, rid); 709 return new Tile(tileElem, innerElem, titleElem, thumbnailElem, rid);
655 } else { 710 } else {
656 return new Tile(tileElement); 711 return new Tile(tileElem);
657 } 712 }
658 } 713 }
659 714
660 715
661 /** 716 /**
662 * Generates a function to be called when the page with the corresponding RID 717 * Generates a function to be called when the page with the corresponding RID
663 * is blacklisted. 718 * is blacklisted.
664 * @param {number} rid The RID of the page being blacklisted. 719 * @param {number} rid The RID of the page being blacklisted.
665 * @return {function(Event)} A function which handles the blacklisting of the 720 * @return {function(Event)} A function which handles the blacklisting of the
666 * page by updating state variables and notifying Chrome. 721 * page by updating state variables and notifying Chrome.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 if (newNumColumns < MIN_NUM_COLUMNS) 795 if (newNumColumns < MIN_NUM_COLUMNS)
741 newNumColumns = MIN_NUM_COLUMNS; 796 newNumColumns = MIN_NUM_COLUMNS;
742 else if (newNumColumns > MAX_NUM_COLUMNS) 797 else if (newNumColumns > MAX_NUM_COLUMNS)
743 newNumColumns = MAX_NUM_COLUMNS; 798 newNumColumns = MAX_NUM_COLUMNS;
744 799
745 if (numColumnsShown != newNumColumns) { 800 if (numColumnsShown != newNumColumns) {
746 numColumnsShown = newNumColumns; 801 numColumnsShown = newNumColumns;
747 var tilesContainerWidth = numColumnsShown * tileRequiredWidth; 802 var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
748 tilesContainer.style.width = tilesContainerWidth + 'px'; 803 tilesContainer.style.width = tilesContainerWidth + 'px';
749 if (fakebox) { 804 if (fakebox) {
750 // -2 to account for border. 805 if (NTP_DESIGN.name === 'smallScreen1') {
751 fakebox.style.width = 806 // -2 to account for border.
752 (tilesContainerWidth - NTP_DESIGN.tileMargin - 2) + 'px'; 807 fakebox.style.width = (tilesContainerWidth - tileRequiredWidth -
808 NTP_DESIGN.tileMargin - 2) + 'px';
809 } else {
810 fakebox.style.width =
811 (tilesContainerWidth - NTP_DESIGN.tileMargin - 2) + 'px';
812 }
753 } 813 }
754 // Render without clearing tiles. 814 // Render without clearing tiles.
755 renderAndShowTiles(); 815 renderAndShowTiles();
756 } 816 }
757 } 817 }
758 818
759 819
760 /** 820 /**
761 * Returns the tile corresponding to the specified page RID. 821 * Returns the tile corresponding to the specified page RID.
762 * @param {number} rid The page RID being looked up. 822 * @param {number} rid The page RID being looked up.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 * Prepares the New Tab Page by adding listeners, rendering the current 983 * Prepares the New Tab Page by adding listeners, rendering the current
924 * theme, the most visited pages section, and Google-specific elements for a 984 * theme, the most visited pages section, and Google-specific elements for a
925 * Google-provided page. 985 * Google-provided page.
926 */ 986 */
927 function init() { 987 function init() {
928 tilesContainer = $(IDS.TILES); 988 tilesContainer = $(IDS.TILES);
929 notification = $(IDS.NOTIFICATION); 989 notification = $(IDS.NOTIFICATION);
930 attribution = $(IDS.ATTRIBUTION); 990 attribution = $(IDS.ATTRIBUTION);
931 ntpContents = $(IDS.NTP_CONTENTS); 991 ntpContents = $(IDS.NTP_CONTENTS);
932 992
993 NTP_DESIGN.classToAdd.forEach(function(v, idx) {
Mathieu 2014/08/13 20:09:29 would rather not have this.
huangs 2014/08/13 21:34:08 Deleted; injecting "classical" from local_ntp_sour
994 ntpContents.classList.add(v);
995 });
996
933 if (configData.isGooglePage) { 997 if (configData.isGooglePage) {
934 var logo = document.createElement('div'); 998 var logo = document.createElement('div');
935 logo.id = IDS.LOGO; 999 logo.id = IDS.LOGO;
936 1000
937 fakebox = document.createElement('div'); 1001 fakebox = document.createElement('div');
938 fakebox.id = IDS.FAKEBOX; 1002 fakebox.id = IDS.FAKEBOX;
939 fakebox.innerHTML = 1003 var fakeboxHtml = [];
940 '<input id="' + IDS.FAKEBOX_INPUT + 1004 fakeboxHtml.push('<input id="' + IDS.FAKEBOX_INPUT +
941 '" autocomplete="off" tabindex="-1" aria-hidden="true">' + 1005 '" autocomplete="off" tabindex="-1" aria-hidden="true">');
942 '<div id="cursor"></div>'; 1006 if (NTP_DESIGN.showFakeboxHint && configData.searchboxPlaceholder) {
1007 fakeboxHtml.push('<div id="fakebox-text">' +
1008 configData.searchboxPlaceholder + '</div>');
1009 }
1010 fakeboxHtml.push('<div id="cursor"></div>');
1011 fakebox.innerHTML = fakeboxHtml.join('');
943 1012
944 ntpContents.insertBefore(fakebox, ntpContents.firstChild); 1013 ntpContents.insertBefore(fakebox, ntpContents.firstChild);
945 ntpContents.insertBefore(logo, ntpContents.firstChild); 1014 ntpContents.insertBefore(logo, ntpContents.firstChild);
946 } else { 1015 } else {
947 document.body.classList.add(CLASSES.NON_GOOGLE_PAGE); 1016 document.body.classList.add(CLASSES.NON_GOOGLE_PAGE);
948 } 1017 }
949 1018
950 var notificationMessage = $(IDS.NOTIFICATION_MESSAGE); 1019 var notificationMessage = $(IDS.NOTIFICATION_MESSAGE);
951 notificationMessage.textContent = 1020 notificationMessage.textContent =
952 configData.translatedStrings.thumbnailRemovedNotification; 1021 configData.translatedStrings.thumbnailRemovedNotification;
(...skipping 23 matching lines...) Expand all
976 ntpApiHandle = topLevelHandle.newTabPage; 1045 ntpApiHandle = topLevelHandle.newTabPage;
977 ntpApiHandle.onthemechange = onThemeChange; 1046 ntpApiHandle.onthemechange = onThemeChange;
978 ntpApiHandle.onmostvisitedchange = onMostVisitedChange; 1047 ntpApiHandle.onmostvisitedchange = onMostVisitedChange;
979 1048
980 ntpApiHandle.oninputstart = onInputStart; 1049 ntpApiHandle.oninputstart = onInputStart;
981 ntpApiHandle.oninputcancel = restoreNtp; 1050 ntpApiHandle.oninputcancel = restoreNtp;
982 1051
983 if (ntpApiHandle.isInputInProgress) 1052 if (ntpApiHandle.isInputInProgress)
984 onInputStart(); 1053 onInputStart();
985 1054
986 onThemeChange(); 1055 renderTheme();
987 onMostVisitedChange(); 1056 onMostVisitedChange();
988 1057
989 searchboxApiHandle = topLevelHandle.searchBox; 1058 searchboxApiHandle = topLevelHandle.searchBox;
990 1059
991 if (fakebox) { 1060 if (fakebox) {
992 // Listener for updating the key capture state. 1061 // Listener for updating the key capture state.
993 document.body.onmousedown = function(event) { 1062 document.body.onmousedown = function(event) {
994 if (isFakeboxClick(event)) 1063 if (isFakeboxClick(event))
995 searchboxApiHandle.startCapturingKeyStrokes(); 1064 searchboxApiHandle.startCapturingKeyStrokes();
996 else if (isFakeboxFocused()) 1065 else if (isFakeboxFocused())
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 1112
1044 return { 1113 return {
1045 init: init, 1114 init: init,
1046 listen: listen 1115 listen: listen
1047 }; 1116 };
1048 } 1117 }
1049 1118
1050 if (!window.localNTPUnitTest) { 1119 if (!window.localNTPUnitTest) {
1051 LocalNTP().listen(); 1120 LocalNTP().listen();
1052 } 1121 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698