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

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

Issue 412073002: Local NTP: prevent tiles from reloading on resize by moving them into single <div>. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Using Barrier; cleaned up onResize(); comments. Created 6 years, 5 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/local_ntp/local_ntp.css ('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 5
6 /** 6 /**
7 * @fileoverview The local InstantExtended NTP. 7 * @fileoverview The local InstantExtended NTP.
8 */ 8 */
9 9
10 10
(...skipping 21 matching lines...) Expand all
32 // Applies drag focus style to the fakebox 32 // Applies drag focus style to the fakebox
33 FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused', 33 FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused',
34 FAVICON: 'mv-favicon', 34 FAVICON: 'mv-favicon',
35 HIDE_BLACKLIST_BUTTON: 'mv-x-hide', // hides blacklist button during animation 35 HIDE_BLACKLIST_BUTTON: 'mv-x-hide', // hides blacklist button during animation
36 HIDE_FAKEBOX_AND_LOGO: 'hide-fakebox-logo', 36 HIDE_FAKEBOX_AND_LOGO: 'hide-fakebox-logo',
37 HIDE_NOTIFICATION: 'mv-notice-hide', 37 HIDE_NOTIFICATION: 'mv-notice-hide',
38 // Vertically centers the most visited section for a non-Google provided page. 38 // Vertically centers the most visited section for a non-Google provided page.
39 NON_GOOGLE_PAGE: 'non-google-page', 39 NON_GOOGLE_PAGE: 'non-google-page',
40 PAGE: 'mv-page', // page tiles 40 PAGE: 'mv-page', // page tiles
41 PAGE_READY: 'mv-page-ready', // page tile when ready 41 PAGE_READY: 'mv-page-ready', // page tile when ready
42 ROW: 'mv-row', // tile row
43 RTL: 'rtl', // Right-to-left language text. 42 RTL: 'rtl', // Right-to-left language text.
44 THUMBNAIL: 'mv-thumb', 43 THUMBNAIL: 'mv-thumb',
45 THUMBNAIL_MASK: 'mv-mask', 44 THUMBNAIL_MASK: 'mv-mask',
46 TILE: 'mv-tile', 45 TILE: 'mv-tile',
47 TITLE: 'mv-title' 46 TITLE: 'mv-title'
48 }; 47 };
49 48
50 49
51 /** 50 /**
52 * Enum for HTML element ids. 51 * Enum for HTML element ids.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 161
163 /** 162 /**
164 * Current number of tiles columns shown based on the window width, including 163 * Current number of tiles columns shown based on the window width, including
165 * those that just contain filler. 164 * those that just contain filler.
166 * @type {number} 165 * @type {number}
167 */ 166 */
168 var numColumnsShown = 0; 167 var numColumnsShown = 0;
169 168
170 169
171 /** 170 /**
172 * True if the user initiated the current most visited change and false 171 * A counter that gets incremented by user action that triggers a call to
173 * otherwise. 172 * onMostVisitedChange(), where the counter then gets decremented.
174 * @type {boolean} 173 * @type {number}
175 */ 174 */
176 var userInitiatedMostVisitedChange = false; 175 var userInitiatedCounter = 0;
177 176
178 177
179 /** 178 /**
179 * A barrier to make tiles visible the moment all tiles are loaded.
180 * @type {Barrier}
181 */
182 var tileVisibilityBarrier = new Barrier(function() {
183 tilesContainer.hidden = false;
184 });
185
186
187 /**
180 * The browser embeddedSearch.newTabPage object. 188 * The browser embeddedSearch.newTabPage object.
181 * @type {Object} 189 * @type {Object}
182 */ 190 */
183 var ntpApiHandle; 191 var ntpApiHandle;
184 192
185 193
186 /** 194 /**
187 * The browser embeddedSearch.searchBox object. 195 * The browser embeddedSearch.searchBox object.
188 * @type {Object} 196 * @type {Object}
189 */ 197 */
(...skipping 16 matching lines...) Expand all
206 214
207 /** 215 /**
208 * Total tile width. Should be equal to mv-tile's width + 2 * border-width. 216 * Total tile width. Should be equal to mv-tile's width + 2 * border-width.
209 * @private {number} 217 * @private {number}
210 * @const 218 * @const
211 */ 219 */
212 var TILE_WIDTH = 140; 220 var TILE_WIDTH = 140;
213 221
214 222
215 /** 223 /**
216 * Margin between tiles. Should be equal to mv-tile's -webkit-margin-start. 224 * Margin between tiles. Should be equal to mv-tile's total horizontal margin.
217 * @private {number} 225 * @private {number}
218 * @const 226 * @const
219 */ 227 */
220 var TILE_MARGIN_START = 20; 228 var TILE_MARGIN = 20;
221 229
222 230
223 /** @type {number} @const */ 231 /** @type {number} @const */
224 var MAX_NUM_TILES_TO_SHOW = 8; 232 var MAX_NUM_TILES_TO_SHOW = 8;
225 233
226 234
227 /** @type {number} @const */ 235 /** @type {number} @const */
228 var MIN_NUM_COLUMNS = 2; 236 var MIN_NUM_COLUMNS = 2;
229 237
230 238
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 function Tile(elem, opt_rid) { 313 function Tile(elem, opt_rid) {
306 /** @type {Element} */ 314 /** @type {Element} */
307 this.elem = elem; 315 this.elem = elem;
308 316
309 /** @type {number|undefined} */ 317 /** @type {number|undefined} */
310 this.rid = opt_rid; 318 this.rid = opt_rid;
311 } 319 }
312 320
313 321
314 /** 322 /**
323 * A counter with a callback that gets executed on the 1-to-0 transition.
324 *
325 * @param {Function} callback The callback to be executed.
326 * @constructor
327 */
328 function Barrier(callback) {
329 /** @type {Function} */
330 this.callback = callback;
331
332 /** @private {number} */
333 this.count_ = 0;
334 }
335
336
337 /**
338 * Increments count of the Barrier.
339 */
340 Barrier.prototype.lock = function() {
341 ++this.count_;
342 };
343
344
345 /**
346 * Decrements count of the Barrier, and executes callback on 1-to-0 transition.
347 */
348 Barrier.prototype.release = function() {
349 if (this.count_ === 0) // Guards against underflow.
350 return;
351 --this.count_;
352 if (this.count_ === 0)
353 this.callback();
354 };
355
356
357 /**
315 * Updates the NTP based on the current theme. 358 * Updates the NTP based on the current theme.
316 * @private 359 * @private
317 */ 360 */
318 function onThemeChange() { 361 function onThemeChange() {
319 var info = ntpApiHandle.themeBackgroundInfo; 362 var info = ntpApiHandle.themeBackgroundInfo;
320 if (!info) 363 if (!info)
321 return; 364 return;
322 365
323 var background = [convertToRGBAColor(info.backgroundColorRgba), 366 var background = [convertToRGBAColor(info.backgroundColorRgba),
324 info.imageUrl, 367 info.imageUrl,
325 info.imageTiling, 368 info.imageTiling,
326 info.imageHorizontalAlignment, 369 info.imageHorizontalAlignment,
327 info.imageVerticalAlignment].join(' ').trim(); 370 info.imageVerticalAlignment].join(' ').trim();
328 document.body.style.background = background; 371 document.body.style.background = background;
329 document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo); 372 document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo);
330 updateThemeAttribution(info.attributionUrl); 373 updateThemeAttribution(info.attributionUrl);
331 setCustomThemeStyle(info); 374 setCustomThemeStyle(info);
375
332 renderTiles(); 376 renderTiles();
333 } 377 }
334 378
335 379
336 /** 380 /**
337 * Updates the NTP style according to theme. 381 * Updates the NTP style according to theme.
338 * @param {Object=} opt_themeInfo The information about the theme. If it is 382 * @param {Object=} opt_themeInfo The information about the theme. If it is
339 * omitted the style will be reverted to the default. 383 * omitted the style will be reverted to the default.
340 * @private 384 * @private
341 */ 385 */
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 function convertToRGBAColor(color) { 469 function convertToRGBAColor(color) {
426 return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' + 470 return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' +
427 color[3] / 255 + ')'; 471 color[3] / 255 + ')';
428 } 472 }
429 473
430 474
431 /** 475 /**
432 * Handles a new set of Most Visited page data. 476 * Handles a new set of Most Visited page data.
433 */ 477 */
434 function onMostVisitedChange() { 478 function onMostVisitedChange() {
435 var pages = ntpApiHandle.mostVisited;
436
437 if (isBlacklisting) { 479 if (isBlacklisting) {
438 // Trigger the blacklist animation and re-render the tiles when it 480 // Trigger the blacklist animation, which then triggers reloadAllTiles().
439 // completes.
440 var lastBlacklistedTileElement = lastBlacklistedTile.elem; 481 var lastBlacklistedTileElement = lastBlacklistedTile.elem;
441 lastBlacklistedTileElement.addEventListener( 482 lastBlacklistedTileElement.addEventListener(
442 'webkitTransitionEnd', blacklistAnimationDone); 483 'webkitTransitionEnd', blacklistAnimationDone);
443 lastBlacklistedTileElement.classList.add(CLASSES.BLACKLIST); 484 lastBlacklistedTileElement.classList.add(CLASSES.BLACKLIST);
444
445 } else { 485 } else {
446 // Otherwise render the tiles using the new data without animation. 486 reloadAllTiles();
447 tiles = [];
448 for (var i = 0; i < MAX_NUM_TILES_TO_SHOW; ++i) {
449 tiles.push(createTile(pages[i], i));
450 }
451 if (!userInitiatedMostVisitedChange) {
452 tilesContainer.hidden = true;
453 window.setTimeout(function() {
454 if (tilesContainer) {
455 tilesContainer.hidden = false;
456 }
457 }, MOST_VISITED_PAINT_TIMEOUT_MSEC);
458 }
459 renderTiles();
460 } 487 }
461 } 488 }
462 489
463 490
464 /** 491 /**
465 * Renders the current set of tiles. 492 * Handles the end of the blacklist animation by showing the notification and
493 * re-rendering the new set of tiles.
466 */ 494 */
467 function renderTiles() { 495 function blacklistAnimationDone() {
468 var rows = tilesContainer.children; 496 showNotification();
469 for (var i = 0; i < rows.length; ++i) { 497 isBlacklisting = false;
470 removeChildren(rows[i]); 498 tilesContainer.classList.remove(CLASSES.HIDE_BLACKLIST_BUTTON);
471 } 499 lastBlacklistedTile.elem.removeEventListener(
472 500 'webkitTransitionEnd', blacklistAnimationDone);
473 for (var i = 0, length = tiles.length; 501 // Need to call explicitly to re-render the tiles, since the initial
474 i < Math.min(length, numColumnsShown * NUM_ROWS); ++i) { 502 // onmostvisitedchange issued by the blacklist function only triggered
475 rows[Math.floor(i / numColumnsShown)].appendChild(tiles[i].elem); 503 // the animation.
476 } 504 reloadAllTiles();
477 } 505 }
478 506
479 507
480 /** 508 /**
481 * Shows most visited tiles if all child iframes are loaded, and hides them 509 * Fetches new data, creates, and renders tiles.
482 * otherwise.
483 */ 510 */
484 function updateMostVisitedVisibility() { 511 function reloadAllTiles() {
485 var iframes = tilesContainer.querySelectorAll('iframe'); 512 var pages = ntpApiHandle.mostVisited;
486 var ready = true; 513
487 for (var i = 0, numIframes = iframes.length; i < numIframes; i++) { 514 if (userInitiatedCounter === 0) {
488 if (iframes[i].hidden) { 515 // Temporarily hide titleContainer, then show when (1) timeout occurs, or
489 ready = false; 516 // when (2) all tiles finish loading (this uses tileVisibilityBarrier).
490 break; 517 tilesContainer.hidden = true;
491 } 518 window.setTimeout(function() {
519 if (tilesContainer) {
520 tilesContainer.hidden = false;
521 }
522 }, MOST_VISITED_PAINT_TIMEOUT_MSEC);
492 } 523 }
493 if (ready) { 524 userInitiatedCounter = Math.max(0, userInitiatedCounter - 1);
beaudoin 2014/07/24 22:09:15 The guarantee that this is called one for every us
huangs 2014/07/24 22:56:56 Done.
494 tilesContainer.hidden = false; 525
495 userInitiatedMostVisitedChange = false; 526 tiles = [];
527 // Increment barrier to guard against race conditions.
528 tileVisibilityBarrier.lock();
529 for (var i = 0; i < MAX_NUM_TILES_TO_SHOW; ++i) {
530 tiles.push(createTile(pages[i], i));
531 }
532 renderTiles();
533 tileVisibilityBarrier.release();
534 }
535
536
537 /**
538 * Adds the current list of tiles to DOM.
539 */
540 function renderTiles() {
541 removeChildren(tilesContainer);
542 var renderedList = tilesContainer.querySelectorAll('.mv-tile');
543 var size = Math.min(tiles.length, numColumnsShown * NUM_ROWS);
544 for (var i = 0; i < size; ++i) {
545 tilesContainer.appendChild(tiles[i].elem);
496 } 546 }
497 } 547 }
498 548
499 549
500 /** 550 /**
501 * Builds a URL to display a most visited tile component in an iframe. 551 * Builds a URL to display a most visited tile component in an iframe.
502 * @param {string} filename The desired most visited component filename. 552 * @param {string} filename The desired most visited component filename.
503 * @param {number} rid The restricted ID. 553 * @param {number} rid The restricted ID.
504 * @param {string} color The text color for text in the iframe. 554 * @param {string} color The text color for text in the iframe.
505 * @param {string} fontFamily The font family for text in the iframe. 555 * @param {string} fontFamily The font family for text in the iframe.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 // begins loading RIDs n, n+1, ..., n+k-1; after the second event, these get 606 // begins loading RIDs n, n+1, ..., n+k-1; after the second event, these get
557 // destroyed and a new set begins loading RIDs n+k, n+k+1, ..., n+2k-1. 607 // destroyed and a new set begins loading RIDs n+k, n+k+1, ..., n+2k-1.
558 // Now due to crbug.com/68841, Chrome incorrectly loads the content for the 608 // Now due to crbug.com/68841, Chrome incorrectly loads the content for the
559 // first set of iframes into the most recent set of iframes. 609 // first set of iframes into the most recent set of iframes.
560 // 610 //
561 // Giving iframes distinct ids seems to cause some invalidation and prevent 611 // Giving iframes distinct ids seems to cause some invalidation and prevent
562 // associating the incorrect data. 612 // associating the incorrect data.
563 // 613 //
564 // TODO(jered): Find and fix the root (probably Blink) bug. 614 // TODO(jered): Find and fix the root (probably Blink) bug.
565 615
616 // Keep this id here. See comment above.
617 titleElement.id = 'title-' + rid;
618 titleElement.className = CLASSES.TITLE;
619 titleElement.hidden = true;
620 tileVisibilityBarrier.lock();
621 titleElement.onload = function() {
622 titleElement.hidden = false;
623 tileVisibilityBarrier.release();
624 };
566 titleElement.src = getMostVisitedIframeUrl( 625 titleElement.src = getMostVisitedIframeUrl(
567 MOST_VISITED_TITLE_IFRAME, rid, MOST_VISITED_COLOR, 626 MOST_VISITED_TITLE_IFRAME, rid, MOST_VISITED_COLOR,
568 MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, position); 627 MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, position);
569
570 // Keep this id here. See comment above.
571 titleElement.id = 'title-' + rid;
572 titleElement.hidden = true;
573 titleElement.onload = function() {
574 titleElement.hidden = false;
575 updateMostVisitedVisibility();
576 };
577 titleElement.className = CLASSES.TITLE;
578 tileElement.appendChild(titleElement); 628 tileElement.appendChild(titleElement);
579 629
580 // The iframe which renders either a thumbnail or domain element. 630 // The iframe which renders either a thumbnail or domain element.
581 var thumbnailElement = document.createElement('iframe'); 631 var thumbnailElement = document.createElement('iframe');
582 thumbnailElement.tabIndex = '-1'; 632 thumbnailElement.tabIndex = '-1';
633 // Keep this id here. See comment above.
634 thumbnailElement.id = 'thumb-' + rid;
635 thumbnailElement.className = CLASSES.THUMBNAIL;
636 thumbnailElement.hidden = true;
637 tileVisibilityBarrier.lock();
638 thumbnailElement.onload = function() {
639 thumbnailElement.hidden = false;
640 tileElement.classList.add(CLASSES.PAGE_READY);
641 tileVisibilityBarrier.release();
642 };
583 thumbnailElement.src = getMostVisitedIframeUrl( 643 thumbnailElement.src = getMostVisitedIframeUrl(
584 MOST_VISITED_THUMBNAIL_IFRAME, rid, MOST_VISITED_COLOR, 644 MOST_VISITED_THUMBNAIL_IFRAME, rid, MOST_VISITED_COLOR,
585 MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, position); 645 MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, position);
586
587 // Keep this id here. See comment above.
588 thumbnailElement.id = 'thumb-' + rid;
589 thumbnailElement.hidden = true;
590 thumbnailElement.onload = function() {
591 thumbnailElement.hidden = false;
592 tileElement.classList.add(CLASSES.PAGE_READY);
593 updateMostVisitedVisibility();
594 };
595 thumbnailElement.className = CLASSES.THUMBNAIL;
596 tileElement.appendChild(thumbnailElement); 646 tileElement.appendChild(thumbnailElement);
597 647
598 // A mask to darken the thumbnail on focus. 648 // A mask to darken the thumbnail on focus.
599 var maskElement = createAndAppendElement( 649 var maskElement = createAndAppendElement(
600 tileElement, 'div', CLASSES.THUMBNAIL_MASK); 650 tileElement, 'div', CLASSES.THUMBNAIL_MASK);
601 651
602 // The button used to blacklist this page. 652 // The button used to blacklist this page.
603 var blacklistButton = createAndAppendElement( 653 var blacklistButton = createAndAppendElement(
604 tileElement, 'div', CLASSES.BLACKLIST_BUTTON); 654 tileElement, 'div', CLASSES.BLACKLIST_BUTTON);
605 var blacklistFunction = generateBlacklistFunction(rid); 655 var blacklistFunction = generateBlacklistFunction(rid);
(...skipping 22 matching lines...) Expand all
628 * is blacklisted. 678 * is blacklisted.
629 * @param {number} rid The RID of the page being blacklisted. 679 * @param {number} rid The RID of the page being blacklisted.
630 * @return {function(Event)} A function which handles the blacklisting of the 680 * @return {function(Event)} A function which handles the blacklisting of the
631 * page by updating state variables and notifying Chrome. 681 * page by updating state variables and notifying Chrome.
632 */ 682 */
633 function generateBlacklistFunction(rid) { 683 function generateBlacklistFunction(rid) {
634 return function(e) { 684 return function(e) {
635 // Prevent navigation when the page is being blacklisted. 685 // Prevent navigation when the page is being blacklisted.
636 e.stopPropagation(); 686 e.stopPropagation();
637 687
638 userInitiatedMostVisitedChange = true; 688 ++userInitiatedCounter;
639 isBlacklisting = true; 689 isBlacklisting = true;
640 tilesContainer.classList.add(CLASSES.HIDE_BLACKLIST_BUTTON); 690 tilesContainer.classList.add(CLASSES.HIDE_BLACKLIST_BUTTON);
641 lastBlacklistedTile = getTileByRid(rid); 691 lastBlacklistedTile = getTileByRid(rid);
642 ntpApiHandle.deleteMostVisitedItem(rid); 692 ntpApiHandle.deleteMostVisitedItem(rid);
643 }; 693 };
644 } 694 }
645 695
646 696
647 /** 697 /**
648 * Shows the blacklist notification and triggers a delay to hide it. 698 * Shows the blacklist notification and triggers a delay to hide it.
649 */ 699 */
650 function showNotification() { 700 function showNotification() {
651 notification.classList.remove(CLASSES.HIDE_NOTIFICATION); 701 notification.classList.remove(CLASSES.HIDE_NOTIFICATION);
652 notification.classList.remove(CLASSES.DELAYED_HIDE_NOTIFICATION); 702 notification.classList.remove(CLASSES.DELAYED_HIDE_NOTIFICATION);
653 notification.scrollTop; 703 notification.scrollTop;
654 notification.classList.add(CLASSES.DELAYED_HIDE_NOTIFICATION); 704 notification.classList.add(CLASSES.DELAYED_HIDE_NOTIFICATION);
655 } 705 }
656 706
657 707
658 /** 708 /**
659 * Hides the blacklist notification. 709 * Hides the blacklist notification.
660 */ 710 */
661 function hideNotification() { 711 function hideNotification() {
662 notification.classList.add(CLASSES.HIDE_NOTIFICATION); 712 notification.classList.add(CLASSES.HIDE_NOTIFICATION);
663 } 713 }
664 714
665 715
666 /** 716 /**
667 * Handles the end of the blacklist animation by showing the notification and
668 * re-rendering the new set of tiles.
669 */
670 function blacklistAnimationDone() {
671 showNotification();
672 isBlacklisting = false;
673 tilesContainer.classList.remove(CLASSES.HIDE_BLACKLIST_BUTTON);
674 lastBlacklistedTile.elem.removeEventListener(
675 'webkitTransitionEnd', blacklistAnimationDone);
676 // Need to call explicitly to re-render the tiles, since the initial
677 // onmostvisitedchange issued by the blacklist function only triggered
678 // the animation.
679 onMostVisitedChange();
680 }
681
682
683 /**
684 * Handles a click on the notification undo link by hiding the notification and 717 * Handles a click on the notification undo link by hiding the notification and
685 * informing Chrome. 718 * informing Chrome.
686 */ 719 */
687 function onUndo() { 720 function onUndo() {
688 userInitiatedMostVisitedChange = true; 721 ++userInitiatedCounter;
689 hideNotification(); 722 hideNotification();
690 var lastBlacklistedRID = lastBlacklistedTile.rid; 723 var lastBlacklistedRID = lastBlacklistedTile.rid;
691 if (typeof lastBlacklistedRID != 'undefined') 724 if (typeof lastBlacklistedRID != 'undefined')
692 ntpApiHandle.undoMostVisitedDeletion(lastBlacklistedRID); 725 ntpApiHandle.undoMostVisitedDeletion(lastBlacklistedRID);
693 } 726 }
694 727
695 728
696 /** 729 /**
697 * Handles a click on the restore all notification link by hiding the 730 * Handles a click on the restore all notification link by hiding the
698 * notification and informing Chrome. 731 * notification and informing Chrome.
699 */ 732 */
700 function onRestoreAll() { 733 function onRestoreAll() {
701 userInitiatedMostVisitedChange = true; 734 ++userInitiatedCounter;
702 hideNotification(); 735 hideNotification();
703 ntpApiHandle.undoAllMostVisitedDeletions(); 736 ntpApiHandle.undoAllMostVisitedDeletions();
704 } 737 }
705 738
706 739
707 /** 740 /**
708 * Re-renders the tiles if the number of columns has changed. As a temporary 741 * Resizes elements because the number of tile columns may need to change in
709 * fix for crbug/240510, updates the width of the fakebox and most visited tiles 742 * response resizing. Also shows or hides extra tiles beyond the bottommost row.
710 * container.
711 */ 743 */
712 function onResize() { 744 function onResize() {
713 // If innerWidth is zero, then use the maximum snap size. 745 // If innerWidth is zero, then use the maximum snap size.
714 var innerWidth = window.innerWidth || 820; 746 var innerWidth = window.innerWidth || 820;
715 747 // Each tile is has left and right margins that sum to TILE_MARGIN.
716 // These values should remain in sync with local_ntp.css. 748 var tileRequiredWidth = TILE_WIDTH + TILE_MARGIN;
717 // TODO(jeremycho): Delete once the root cause of crbug/240510 is resolved. 749 var availableWidth = innerWidth + TILE_MARGIN - MIN_TOTAL_HORIZONTAL_PADDING;
718 var setWidths = function(tilesContainerWidth) { 750 var newNumColumns = Math.floor(availableWidth / tileRequiredWidth);
751 newNumColumns =
752 Math.max(MIN_NUM_COLUMNS, Math.min(newNumColumns, MAX_NUM_COLUMNS));
753 if (numColumnsShown != newNumColumns) {
754 numColumnsShown = newNumColumns;
755 var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
719 tilesContainer.style.width = tilesContainerWidth + 'px'; 756 tilesContainer.style.width = tilesContainerWidth + 'px';
720 if (fakebox) 757 if (fakebox) // -2 to account for border.
721 fakebox.style.width = (tilesContainerWidth - 2) + 'px'; 758 fakebox.style.width = (tilesContainerWidth - TILE_MARGIN - 2) + 'px';
722 }; 759 // Shows only rendered tiles in the first NUM_ROWS rows.
723 if (innerWidth >= 820) 760 var renderedList = tilesContainer.querySelectorAll('.mv-tile');
724 setWidths(620); 761 var numVisible = Math.min(tiles.length, numColumnsShown * NUM_ROWS);
725 else if (innerWidth >= 660) 762 // Not using .hidden becomes it does not work for inline-block elements.
726 setWidths(460); 763 for (var i = 0; i < renderedList.length; ++i) {
727 else 764 renderedList[i].style.display = i < numVisible ? 'inline-block' : 'none';
728 setWidths(300); 765 }
729
730 var tileRequiredWidth = TILE_WIDTH + TILE_MARGIN_START;
731 // Adds margin-start to the available width to compensate the extra margin
732 // counted above for the first tile (which does not have a margin-start).
733 var availableWidth = innerWidth + TILE_MARGIN_START -
734 MIN_TOTAL_HORIZONTAL_PADDING;
735 var numColumnsToShow = Math.floor(availableWidth / tileRequiredWidth);
736 numColumnsToShow = Math.max(MIN_NUM_COLUMNS,
737 Math.min(MAX_NUM_COLUMNS, numColumnsToShow));
738 if (numColumnsToShow != numColumnsShown) {
739 numColumnsShown = numColumnsToShow;
740 renderTiles();
741 } 766 }
742 } 767 }
743 768
744 769
745 /** 770 /**
746 * Returns the tile corresponding to the specified page RID. 771 * Returns the tile corresponding to the specified page RID.
747 * @param {number} rid The page RID being looked up. 772 * @param {number} rid The page RID being looked up.
748 * @return {Tile} The corresponding tile. 773 * @return {Tile} The corresponding tile.
749 */ 774 */
750 function getTileByRid(rid) { 775 function getTileByRid(rid) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 * Prepares the New Tab Page by adding listeners, rendering the current 942 * Prepares the New Tab Page by adding listeners, rendering the current
918 * theme, the most visited pages section, and Google-specific elements for a 943 * theme, the most visited pages section, and Google-specific elements for a
919 * Google-provided page. 944 * Google-provided page.
920 */ 945 */
921 function init() { 946 function init() {
922 tilesContainer = $(IDS.TILES); 947 tilesContainer = $(IDS.TILES);
923 notification = $(IDS.NOTIFICATION); 948 notification = $(IDS.NOTIFICATION);
924 attribution = $(IDS.ATTRIBUTION); 949 attribution = $(IDS.ATTRIBUTION);
925 ntpContents = $(IDS.NTP_CONTENTS); 950 ntpContents = $(IDS.NTP_CONTENTS);
926 951
927 for (var i = 0; i < NUM_ROWS; i++) {
928 var row = document.createElement('div');
929 row.classList.add(CLASSES.ROW);
930 tilesContainer.appendChild(row);
931 }
932
933 if (configData.isGooglePage) { 952 if (configData.isGooglePage) {
934 var logo = document.createElement('div'); 953 var logo = document.createElement('div');
935 logo.id = IDS.LOGO; 954 logo.id = IDS.LOGO;
936 955
937 fakebox = document.createElement('div'); 956 fakebox = document.createElement('div');
938 fakebox.id = IDS.FAKEBOX; 957 fakebox.id = IDS.FAKEBOX;
939 fakebox.innerHTML = 958 fakebox.innerHTML =
940 '<input id="' + IDS.FAKEBOX_INPUT + 959 '<input id="' + IDS.FAKEBOX_INPUT +
941 '" autocomplete="off" tabindex="-1" aria-hidden="true">' + 960 '" autocomplete="off" tabindex="-1" aria-hidden="true">' +
942 '<div id=cursor></div>'; 961 '<div id="cursor"></div>';
943 962
944 ntpContents.insertBefore(fakebox, ntpContents.firstChild); 963 ntpContents.insertBefore(fakebox, ntpContents.firstChild);
945 ntpContents.insertBefore(logo, ntpContents.firstChild); 964 ntpContents.insertBefore(logo, ntpContents.firstChild);
946 } else { 965 } else {
947 document.body.classList.add(CLASSES.NON_GOOGLE_PAGE); 966 document.body.classList.add(CLASSES.NON_GOOGLE_PAGE);
948 } 967 }
949 968
950 var notificationMessage = $(IDS.NOTIFICATION_MESSAGE); 969 var notificationMessage = $(IDS.NOTIFICATION_MESSAGE);
951 notificationMessage.textContent = 970 notificationMessage.textContent =
952 configData.translatedStrings.thumbnailRemovedNotification; 971 configData.translatedStrings.thumbnailRemovedNotification;
953 var undoLink = $(IDS.UNDO_LINK); 972 var undoLink = $(IDS.UNDO_LINK);
954 undoLink.addEventListener('click', onUndo); 973 undoLink.addEventListener('click', onUndo);
955 registerKeyHandler(undoLink, KEYCODE.ENTER, onUndo); 974 registerKeyHandler(undoLink, KEYCODE.ENTER, onUndo);
956 undoLink.textContent = configData.translatedStrings.undoThumbnailRemove; 975 undoLink.textContent = configData.translatedStrings.undoThumbnailRemove;
957 var restoreAllLink = $(IDS.RESTORE_ALL_LINK); 976 var restoreAllLink = $(IDS.RESTORE_ALL_LINK);
958 restoreAllLink.addEventListener('click', onRestoreAll); 977 restoreAllLink.addEventListener('click', onRestoreAll);
959 registerKeyHandler(restoreAllLink, KEYCODE.ENTER, onUndo); 978 registerKeyHandler(restoreAllLink, KEYCODE.ENTER, onUndo);
960 restoreAllLink.textContent = 979 restoreAllLink.textContent =
961 configData.translatedStrings.restoreThumbnailsShort; 980 configData.translatedStrings.restoreThumbnailsShort;
962 $(IDS.ATTRIBUTION_TEXT).textContent = 981 $(IDS.ATTRIBUTION_TEXT).textContent =
963 configData.translatedStrings.attributionIntro; 982 configData.translatedStrings.attributionIntro;
964 983
965 var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON); 984 var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON);
966 notificationCloseButton.addEventListener('click', hideNotification); 985 notificationCloseButton.addEventListener('click', hideNotification);
967 986
968 userInitiatedMostVisitedChange = false;
969 window.addEventListener('resize', onResize); 987 window.addEventListener('resize', onResize);
970 onResize(); 988 onResize();
971 989
972 var topLevelHandle = getEmbeddedSearchApiHandle(); 990 var topLevelHandle = getEmbeddedSearchApiHandle();
973 991
974 ntpApiHandle = topLevelHandle.newTabPage; 992 ntpApiHandle = topLevelHandle.newTabPage;
975 ntpApiHandle.onthemechange = onThemeChange; 993 ntpApiHandle.onthemechange = onThemeChange;
976 ntpApiHandle.onmostvisitedchange = onMostVisitedChange; 994 ntpApiHandle.onmostvisitedchange = onMostVisitedChange;
977 995
978 ntpApiHandle.oninputstart = onInputStart; 996 ntpApiHandle.oninputstart = onInputStart;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 1058
1041 return { 1059 return {
1042 init: init, 1060 init: init,
1043 listen: listen 1061 listen: listen
1044 }; 1062 };
1045 } 1063 }
1046 1064
1047 if (!window.localNTPUnitTest) { 1065 if (!window.localNTPUnitTest) {
1048 LocalNTP().listen(); 1066 LocalNTP().listen();
1049 } 1067 }
OLDNEW
« no previous file with comments | « chrome/browser/resources/local_ntp/local_ntp.css ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698