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

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

Issue 512583002: [Local NTP] Implement style updates for Material Design (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
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 BLACKLIST_BUTTON_INNER: 'mv-x-inner',
31 DARK: 'dark', 32 DARK: 'dark',
32 DEFAULT_THEME: 'default-theme', 33 DEFAULT_THEME: 'default-theme',
33 DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide', 34 DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide',
34 DOT: 'dot', 35 DOT: 'dot',
35 FAKEBOX_DISABLE: 'fakebox-disable', // Makes fakebox non-interactive 36 FAKEBOX_DISABLE: 'fakebox-disable', // Makes fakebox non-interactive
36 FAKEBOX_FOCUS: 'fakebox-focused', // Applies focus styles to the fakebox 37 FAKEBOX_FOCUS: 'fakebox-focused', // Applies focus styles to the fakebox
37 // Applies drag focus style to the fakebox 38 // Applies drag focus style to the fakebox
38 FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused', 39 FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused',
39 FAVICON: 'mv-favicon', 40 FAVICON: 'mv-favicon',
40 FAVICON_FALLBACK: 'mv-favicon-fallback', 41 FAVICON_FALLBACK: 'mv-favicon-fallback',
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 /** 170 /**
170 * True if a page has been blacklisted and we're waiting on the 171 * True if a page has been blacklisted and we're waiting on the
171 * onmostvisitedchange callback. See onMostVisitedChange() for how this 172 * onmostvisitedchange callback. See onMostVisitedChange() for how this
172 * is used. 173 * is used.
173 * @type {boolean} 174 * @type {boolean}
174 */ 175 */
175 var isBlacklisting = false; 176 var isBlacklisting = false;
176 177
177 178
178 /** 179 /**
179 * Stores whether the current theme has a dark background.
180 * @type {boolean}
181 */
182 var isBackgroundDark = false;
183
184
185 /**
186 * Current number of tiles columns shown based on the window width, including 180 * Current number of tiles columns shown based on the window width, including
187 * those that just contain filler. 181 * those that just contain filler.
188 * @type {number} 182 * @type {number}
189 */ 183 */
190 var numColumnsShown = 0; 184 var numColumnsShown = 0;
191 185
192 186
193 /** 187 /**
194 * A flag to indicate Most Visited changed caused by user action. If true, then 188 * A flag to indicate Most Visited changed caused by user action. If true, then
195 * in onMostVisitedChange() tiles remain visible so no flickering occurs. 189 * in onMostVisitedChange() tiles remain visible so no flickering occurs.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 255
262 /** 256 /**
263 * The filename for a most visited iframe src which shows a thumbnail image. 257 * The filename for a most visited iframe src which shows a thumbnail image.
264 * @type {string} 258 * @type {string}
265 * @const 259 * @const
266 */ 260 */
267 var MOST_VISITED_THUMBNAIL_IFRAME = 'thumbnail.html'; 261 var MOST_VISITED_THUMBNAIL_IFRAME = 'thumbnail.html';
268 262
269 263
270 /** 264 /**
265 * The color of the title in RRGGBBAA format.
266 * @type {string}
Mathieu 2014/08/27 14:54:53 string|null ?
huangs 2014/08/27 18:13:52 Done.
267 */
268 var titleColor = null;
269
270
271 /**
271 * Hide most visited tiles for at most this many milliseconds while painting. 272 * Hide most visited tiles for at most this many milliseconds while painting.
272 * @type {number} 273 * @type {number}
273 * @const 274 * @const
274 */ 275 */
275 var MOST_VISITED_PAINT_TIMEOUT_MSEC = 500; 276 var MOST_VISITED_PAINT_TIMEOUT_MSEC = 500;
276 277
277 278
278 /** 279 /**
279 * A Tile is either a rendering of a Most Visited page or "filler" used to 280 * A Tile is either a rendering of a Most Visited page or "filler" used to
280 * pad out the section when not enough pages exist. 281 * pad out the section when not enough pages exist.
(...skipping 18 matching lines...) Expand all
299 300
300 /** @type {Element|undefined} */ 301 /** @type {Element|undefined} */
301 this.thumbnailElem = opt_thumbnailElem; 302 this.thumbnailElem = opt_thumbnailElem;
302 303
303 /** @type {number|undefined} */ 304 /** @type {number|undefined} */
304 this.rid = opt_rid; 305 this.rid = opt_rid;
305 } 306 }
306 307
307 308
308 /** 309 /**
309 * Determines whether a theme should be considered to have dark background. 310 * Determines whether a theme should be considered to have dark background.
Mathieu 2014/08/27 14:54:53 Mention that you are now looking at the text color
huangs 2014/08/27 18:13:52 Updated comment. The text color portion is implem
310 * @param {ThemeBackgroundInfo} info Theme background information. 311 * @param {ThemeBackgroundInfo|undefined} info Theme background information.
311 * @return {boolean} Whether the theme has dark background. 312 * @return {boolean} Whether the theme has dark background.
312 * @private 313 * @private
313 */ 314 */
314 function getIsBackgroundDark(info) { 315 function getIsBackgroundDark(info) {
315 if (info.imageUrl) 316 if (!info)
316 return true; 317 return false;
317 var rgba = info.backgroundColorRgba; 318 var rgba = info.textColorRgba;
318 var luminance = 0.3 * rgba[0] + 0.59 * rgba[1] + 0.11 * rgba[2]; 319 var luminance = 0.3 * rgba[0] + 0.59 * rgba[1] + 0.11 * rgba[2];
319 return luminance < 128; 320 return luminance >= 128;
320 } 321 }
321 322
322 323
323 /** 324 /**
324 * Updates the NTP based on the current theme. 325 * Updates the NTP based on the current theme.
325 * @private 326 * @private
326 */ 327 */
327 function renderTheme() { 328 function renderTheme() {
329 var fakeboxText = $(IDS.FAKEBOX_TEXT);
330 fakeboxText.innerHTML = '';
331 if (NTP_DESIGN.showFakeboxHint &&
332 configData.translatedStrings.searchboxPlaceholder) {
333 fakeboxText.textContent = configData.translatedStrings.searchboxPlaceholder;
334 }
335
328 var info = ntpApiHandle.themeBackgroundInfo; 336 var info = ntpApiHandle.themeBackgroundInfo;
337 var isBackgroundDark = getIsBackgroundDark(info);
338 ntpContents.classList.toggle(CLASSES.DARK, isBackgroundDark);
329 if (!info) { 339 if (!info) {
330 isBackgroundDark = false; 340 titleColor = NTP_DESIGN.titleColor;
331 return; 341 return;
332 } 342 }
333 343
334 isBackgroundDark = getIsBackgroundDark(info); 344 if (!info.usingDefaultTheme && info.textColorRgba) {
335 ntpContents.classList.toggle(CLASSES.DARK, isBackgroundDark); 345 titleColor = convertToRRGGBBAAColor(info.textColorRgba);
346 } else {
347 titleColor = isBackgroundDark ?
348 NTP_DESIGN.titleColorAgainstDark : NTP_DESIGN.titleColor;
349 }
336 350
337 var background = [convertToRGBAColor(info.backgroundColorRgba), 351 var background = [convertToRGBAColor(info.backgroundColorRgba),
338 info.imageUrl, 352 info.imageUrl,
339 info.imageTiling, 353 info.imageTiling,
340 info.imageHorizontalAlignment, 354 info.imageHorizontalAlignment,
341 info.imageVerticalAlignment].join(' ').trim(); 355 info.imageVerticalAlignment].join(' ').trim();
356
342 document.body.style.background = background; 357 document.body.style.background = background;
343 document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo); 358 document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo);
344 updateThemeAttribution(info.attributionUrl); 359 updateThemeAttribution(info.attributionUrl);
345 setCustomThemeStyle(info); 360 setCustomThemeStyle(info);
346 } 361 }
347 362
348 363
349 /** 364 /**
350 * Updates the NTP based on the current theme, then rerenders all tiles. 365 * Updates the NTP based on the current theme, then rerenders all tiles.
351 * @private 366 * @private
352 */ 367 */
353 function onThemeChange() { 368 function onThemeChange() {
354 renderTheme(); 369 renderTheme();
355 tilesContainer.innerHTML = ''; 370 tilesContainer.innerHTML = '';
356 renderAndShowTiles(); 371 renderAndShowTiles();
357 } 372 }
358 373
359 374
360 /** 375 /**
361 * Updates the NTP style according to theme. 376 * Updates the NTP style according to theme.
362 * @param {Object=} opt_themeInfo The information about the theme. If it is 377 * @param {Object=} opt_themeInfo The information about the theme. If it is
363 * omitted the style will be reverted to the default. 378 * omitted the style will be reverted to the default.
364 * @private 379 * @private
365 */ 380 */
366 function setCustomThemeStyle(opt_themeInfo) { 381 function setCustomThemeStyle(opt_themeInfo) {
367 var customStyleElement = $(IDS.CUSTOM_THEME_STYLE); 382 var customStyleElement = $(IDS.CUSTOM_THEME_STYLE);
368 var head = document.head; 383 var head = document.head;
369
370 if (opt_themeInfo && !opt_themeInfo.usingDefaultTheme) { 384 if (opt_themeInfo && !opt_themeInfo.usingDefaultTheme) {
371 ntpContents.classList.remove(CLASSES.DEFAULT_THEME); 385 ntpContents.classList.remove(CLASSES.DEFAULT_THEME);
372 var themeStyle = 386 var themeStyle =
373 '#attribution {' + 387 '#attribution {' +
374 ' color: ' + convertToRGBAColor(opt_themeInfo.textColorLightRgba) + ';' + 388 ' color: ' + convertToRGBAColor(opt_themeInfo.textColorLightRgba) + ';' +
375 '}' + 389 '}' +
376 '#mv-msg {' + 390 '#mv-msg {' +
377 ' color: ' + convertToRGBAColor(opt_themeInfo.textColorRgba) + ';' + 391 ' color: ' + convertToRGBAColor(opt_themeInfo.textColorRgba) + ';' +
378 '}' + 392 '}' +
379 '#mv-notice-links span {' + 393 '#mv-notice-links span {' +
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 * @private 451 * @private
438 */ 452 */
439 function setAttributionVisibility_(show) { 453 function setAttributionVisibility_(show) {
440 if (attribution) { 454 if (attribution) {
441 attribution.style.display = show ? '' : 'none'; 455 attribution.style.display = show ? '' : 'none';
442 } 456 }
443 } 457 }
444 458
445 459
446 /** 460 /**
461 * Converts an Array of color components into RRGGBBAA format.
462 * @param {Array.<number>} color Array of rgba color components.
463 * @return {string} Color string in RRGGBBAA format.
464 * @private
465 */
466 function convertToRRGGBBAAColor(color) {
467 return color.map(function(t) {
468 return ('0' + t.toString(16)).slice(-2); // To 2-digit, 0-padded hex.
469 }).join('');
470 }
471
472
473 /**
447 * Converts an Array of color components into RGBA format "rgba(R,G,B,A)". 474 * Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
448 * @param {Array.<number>} color Array of rgba color components. 475 * @param {Array.<number>} color Array of rgba color components.
449 * @return {string} CSS color in RGBA format. 476 * @return {string} CSS color in RGBA format.
450 * @private 477 * @private
451 */ 478 */
452 function convertToRGBAColor(color) { 479 function convertToRGBAColor(color) {
453 return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' + 480 return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' +
454 color[3] / 255 + ')'; 481 color[3] / 255 + ')';
455 } 482 }
456 483
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 605
579 /** 606 /**
580 * Builds a URL to display a most visited tile title in an iframe. 607 * Builds a URL to display a most visited tile title in an iframe.
581 * @param {number} rid The restricted ID. 608 * @param {number} rid The restricted ID.
582 * @param {number} position The position of the iframe in the UI. 609 * @param {number} position The position of the iframe in the UI.
583 * @return {string} An URL to display the most visited title in an iframe. 610 * @return {string} An URL to display the most visited title in an iframe.
584 */ 611 */
585 function getMostVisitedTitleIframeUrl(rid, position) { 612 function getMostVisitedTitleIframeUrl(rid, position) {
586 var url = 'chrome-search://most-visited/' + 613 var url = 'chrome-search://most-visited/' +
587 encodeURIComponent(MOST_VISITED_TITLE_IFRAME); 614 encodeURIComponent(MOST_VISITED_TITLE_IFRAME);
588 var titleColor = isBackgroundDark ? NTP_DESIGN.titleColorAgainstDark :
589 NTP_DESIGN.titleColor;
590 var params = [ 615 var params = [
591 'rid=' + encodeURIComponent(rid), 616 'rid=' + encodeURIComponent(rid),
592 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily), 617 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily),
593 'fs=' + encodeURIComponent(NTP_DESIGN.fontSize), 618 'fs=' + encodeURIComponent(NTP_DESIGN.fontSize),
594 'c=' + encodeURIComponent(titleColor), 619 'c=' + encodeURIComponent(titleColor),
595 'pos=' + encodeURIComponent(position)]; 620 'pos=' + encodeURIComponent(position)];
596 if (NTP_DESIGN.titleTextAlign) 621 if (NTP_DESIGN.titleTextAlign)
597 params.push('ta=' + encodeURIComponent(NTP_DESIGN.titleTextAlign)); 622 params.push('ta=' + encodeURIComponent(NTP_DESIGN.titleTextAlign));
598 if (NTP_DESIGN.titleTextFade) 623 if (NTP_DESIGN.titleTextFade)
599 params.push('tf=' + encodeURIComponent(NTP_DESIGN.titleTextFade)); 624 params.push('tf=' + encodeURIComponent(NTP_DESIGN.titleTextFade));
(...skipping 25 matching lines...) Expand all
625 /** 650 /**
626 * Creates a Tile with the specified page data. If no data is provided, a 651 * Creates a Tile with the specified page data. If no data is provided, a
627 * filler Tile is created. 652 * filler Tile is created.
628 * @param {Object} page The page data. 653 * @param {Object} page The page data.
629 * @param {number} position The position of the tile. 654 * @param {number} position The position of the tile.
630 * @return {Tile} The new Tile. 655 * @return {Tile} The new Tile.
631 */ 656 */
632 function createTile(page, position) { 657 function createTile(page, position) {
633 var tileElem = document.createElement('div'); 658 var tileElem = document.createElement('div');
634 tileElem.classList.add(CLASSES.TILE); 659 tileElem.classList.add(CLASSES.TILE);
660 // Prevent tile from being selected (and highlighted) when 'X' is clicked.
661 tileElem.addEventListener('mousedown', function(e) {
Mathieu 2014/08/27 14:54:53 Seems to me like it's going to prevent more than w
huangs 2014/08/27 18:13:52 It's not just "X", but also any area outside of <i
662 e.preventDefault();
663 });
635 var innerElem = createAndAppendElement(tileElem, 'div', CLASSES.TILE_INNER); 664 var innerElem = createAndAppendElement(tileElem, 'div', CLASSES.TILE_INNER);
636 665
637 if (page) { 666 if (page) {
638 var rid = page.rid; 667 var rid = page.rid;
639 tileElem.classList.add(CLASSES.PAGE); 668 tileElem.classList.add(CLASSES.PAGE);
640 669
641 var navigateFunction = function(e) { 670 var navigateFunction = function(e) {
642 e.preventDefault(); 671 e.preventDefault();
643 ntpApiHandle.navigateContentWindow(rid, getDispositionFromEvent(e)); 672 ntpApiHandle.navigateContentWindow(rid, getDispositionFromEvent(e));
644 }; 673 };
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 thumbnailElem.tabIndex = '-1'; 716 thumbnailElem.tabIndex = '-1';
688 // Keep this ID here. See comment above. 717 // Keep this ID here. See comment above.
689 thumbnailElem.id = 'thumb-' + rid; 718 thumbnailElem.id = 'thumb-' + rid;
690 thumbnailElem.className = CLASSES.THUMBNAIL; 719 thumbnailElem.className = CLASSES.THUMBNAIL;
691 thumbnailElem.src = getMostVisitedThumbnailIframeUrl(rid, position); 720 thumbnailElem.src = getMostVisitedThumbnailIframeUrl(rid, position);
692 innerElem.appendChild(thumbnailElem); 721 innerElem.appendChild(thumbnailElem);
693 722
694 // The button used to blacklist this page. 723 // The button used to blacklist this page.
695 var blacklistButton = createAndAppendElement( 724 var blacklistButton = createAndAppendElement(
696 innerElem, 'div', CLASSES.BLACKLIST_BUTTON); 725 innerElem, 'div', CLASSES.BLACKLIST_BUTTON);
726 createAndAppendElement(
727 blacklistButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
697 var blacklistFunction = generateBlacklistFunction(rid); 728 var blacklistFunction = generateBlacklistFunction(rid);
698 blacklistButton.addEventListener('click', blacklistFunction); 729 blacklistButton.addEventListener('click', blacklistFunction);
699 blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip; 730 blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip;
700 731
701 // A helper mask on top of the tile that is used to create hover border 732 // A helper mask on top of the tile that is used to create hover border
702 // and/or to darken the thumbnail on focus. 733 // and/or to darken the thumbnail on focus.
703 var maskElement = createAndAppendElement( 734 var maskElement = createAndAppendElement(
704 innerElem, 'div', CLASSES.THUMBNAIL_MASK); 735 innerElem, 'div', CLASSES.THUMBNAIL_MASK);
705 736
706 // When a tile is focused, have delete also blacklist the page. 737 // When a tile is focused, have delete also blacklist the page.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 notification.scrollTop; 781 notification.scrollTop;
751 notification.classList.add(CLASSES.DELAYED_HIDE_NOTIFICATION); 782 notification.classList.add(CLASSES.DELAYED_HIDE_NOTIFICATION);
752 } 783 }
753 784
754 785
755 /** 786 /**
756 * Hides the blacklist notification. 787 * Hides the blacklist notification.
757 */ 788 */
758 function hideNotification() { 789 function hideNotification() {
759 notification.classList.add(CLASSES.HIDE_NOTIFICATION); 790 notification.classList.add(CLASSES.HIDE_NOTIFICATION);
791 notification.classList.remove(CLASSES.DELAYED_HIDE_NOTIFICATION);
760 } 792 }
761 793
762 794
763 /** 795 /**
764 * Handles a click on the notification undo link by hiding the notification and 796 * Handles a click on the notification undo link by hiding the notification and
765 * informing Chrome. 797 * informing Chrome.
766 */ 798 */
767 function onUndo() { 799 function onUndo() {
768 userInitiatedMostVisitedChange = true; 800 userInitiatedMostVisitedChange = true;
769 hideNotification(); 801 hideNotification();
770 var lastBlacklistedRID = lastBlacklistedTile.rid; 802 var lastBlacklistedRID = lastBlacklistedTile.rid;
771 if (typeof lastBlacklistedRID != 'undefined') 803 if (typeof lastBlacklistedRID != 'undefined')
772 ntpApiHandle.undoMostVisitedDeletion(lastBlacklistedRID); 804 ntpApiHandle.undoMostVisitedDeletion(lastBlacklistedRID);
773 } 805 }
774 806
775 807
776 /** 808 /**
777 * Handles a click on the restore all notification link by hiding the 809 * Handles a click on the restore all notification link by hiding the
778 * notification and informing Chrome. 810 * notification and informing Chrome.
779 */ 811 */
780 function onRestoreAll() { 812 function onRestoreAll() {
781 userInitiatedMostVisitedChange = true; 813 userInitiatedMostVisitedChange = true;
782 hideNotification(); 814 hideNotification();
783 ntpApiHandle.undoAllMostVisitedDeletions(); 815 ntpApiHandle.undoAllMostVisitedDeletions();
784 } 816 }
785 817
786 818
787 /** 819 /**
788 * Resizes elements because the number of tile columns may need to change in 820 * Recomputes the number of tile columns, and width of various contents based
789 * response to resizing. Also shows or hides extra tiles tiles according to the 821 * on the width of the window.
790 * new width of the page. 822 * @return {boolean} Whether the number of tile columns has changed.
791 */ 823 */
792 function onResize() { 824 function updateContentWidth() {
793 var tileRequiredWidth = NTP_DESIGN.tileWidth + NTP_DESIGN.tileMargin; 825 var tileRequiredWidth = NTP_DESIGN.tileWidth + NTP_DESIGN.tileMargin;
794 // If innerWidth is zero, then use the maximum snap size. 826 // If innerWidth is zero, then use the maximum snap size.
795 var maxSnapSize = MAX_NUM_COLUMNS * tileRequiredWidth - 827 var maxSnapSize = MAX_NUM_COLUMNS * tileRequiredWidth -
796 NTP_DESIGN.tileMargin + MIN_TOTAL_HORIZONTAL_PADDING; 828 NTP_DESIGN.tileMargin + MIN_TOTAL_HORIZONTAL_PADDING;
797 var innerWidth = window.innerWidth || maxSnapSize; 829 var innerWidth = window.innerWidth || maxSnapSize;
798 // Each tile has left and right margins that sum to NTP_DESIGN.tileMargin. 830 // Each tile has left and right margins that sum to NTP_DESIGN.tileMargin.
799 var availableWidth = innerWidth + NTP_DESIGN.tileMargin - 831 var availableWidth = innerWidth + NTP_DESIGN.tileMargin -
800 MIN_TOTAL_HORIZONTAL_PADDING; 832 MIN_TOTAL_HORIZONTAL_PADDING;
801 var newNumColumns = Math.floor(availableWidth / tileRequiredWidth); 833 var newNumColumns = Math.floor(availableWidth / tileRequiredWidth);
802 if (newNumColumns < MIN_NUM_COLUMNS) 834 if (newNumColumns < MIN_NUM_COLUMNS)
803 newNumColumns = MIN_NUM_COLUMNS; 835 newNumColumns = MIN_NUM_COLUMNS;
804 else if (newNumColumns > MAX_NUM_COLUMNS) 836 else if (newNumColumns > MAX_NUM_COLUMNS)
805 newNumColumns = MAX_NUM_COLUMNS; 837 newNumColumns = MAX_NUM_COLUMNS;
806 838
807 if (numColumnsShown != newNumColumns) { 839 if (numColumnsShown === newNumColumns)
808 numColumnsShown = newNumColumns; 840 return false;
809 var tilesContainerWidth = numColumnsShown * tileRequiredWidth; 841
810 tilesContainer.style.width = tilesContainerWidth + 'px'; 842 numColumnsShown = newNumColumns;
811 if (fakebox) { 843 var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
812 fakebox.style.width = // -2 to account for border. 844 tilesContainer.style.width = tilesContainerWidth + 'px';
813 (tilesContainerWidth - NTP_DESIGN.tileMargin - 2) + 'px'; 845 if (fakebox) {
814 } 846 // -2 to account for border.
847 var fakeboxWidth = (tilesContainerWidth - NTP_DESIGN.tileMargin - 2);
848 fakebox.style.width = fakeboxWidth + 'px';
849 }
850 return true;
851 }
852
853
854 /**
855 * Resizes elements because the number of tile columns may need to change in
856 * response to resizing. Also shows or hides extra tiles tiles according to the
857 * new width of the page.
858 */
859 function onResize() {
860 if (updateContentWidth()) {
815 // Render without clearing tiles. 861 // Render without clearing tiles.
816 renderAndShowTiles(); 862 renderAndShowTiles();
817 } 863 }
818 } 864 }
819 865
820 866
821 /** 867 /**
822 * Returns the tile corresponding to the specified page RID. 868 * Returns the tile corresponding to the specified page RID.
823 * @param {number} rid The page RID being looked up. 869 * @param {number} rid The page RID being looked up.
824 * @return {Tile} The corresponding tile. 870 * @return {Tile} The corresponding tile.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 1039
994 if (configData.isGooglePage) { 1040 if (configData.isGooglePage) {
995 var logo = document.createElement('div'); 1041 var logo = document.createElement('div');
996 logo.id = IDS.LOGO; 1042 logo.id = IDS.LOGO;
997 1043
998 fakebox = document.createElement('div'); 1044 fakebox = document.createElement('div');
999 fakebox.id = IDS.FAKEBOX; 1045 fakebox.id = IDS.FAKEBOX;
1000 var fakeboxHtml = []; 1046 var fakeboxHtml = [];
1001 fakeboxHtml.push('<input id="' + IDS.FAKEBOX_INPUT + 1047 fakeboxHtml.push('<input id="' + IDS.FAKEBOX_INPUT +
1002 '" autocomplete="off" tabindex="-1" aria-hidden="true">'); 1048 '" autocomplete="off" tabindex="-1" aria-hidden="true">');
1003 if (NTP_DESIGN.showFakeboxHint && 1049 fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '"></div>');
1004 configData.translatedStrings.searchboxPlaceholder) {
1005 fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '">' +
1006 configData.translatedStrings.searchboxPlaceholder + '</div>');
1007 }
1008 fakeboxHtml.push('<div id="cursor"></div>'); 1050 fakeboxHtml.push('<div id="cursor"></div>');
1009 fakebox.innerHTML = fakeboxHtml.join(''); 1051 fakebox.innerHTML = fakeboxHtml.join('');
1010 1052
1011 ntpContents.insertBefore(fakebox, ntpContents.firstChild); 1053 ntpContents.insertBefore(fakebox, ntpContents.firstChild);
1012 ntpContents.insertBefore(logo, ntpContents.firstChild); 1054 ntpContents.insertBefore(logo, ntpContents.firstChild);
1013 } else { 1055 } else {
1014 document.body.classList.add(CLASSES.NON_GOOGLE_PAGE); 1056 document.body.classList.add(CLASSES.NON_GOOGLE_PAGE);
1015 } 1057 }
1016 1058
1059 // Hide notifications after fade out, so we can't focus on links via keyboard.
1060 notification.addEventListener('webkitTransitionEnd', hideNotification);
1061
1017 var notificationMessage = $(IDS.NOTIFICATION_MESSAGE); 1062 var notificationMessage = $(IDS.NOTIFICATION_MESSAGE);
1018 notificationMessage.textContent = 1063 notificationMessage.textContent =
1019 configData.translatedStrings.thumbnailRemovedNotification; 1064 configData.translatedStrings.thumbnailRemovedNotification;
1020 1065
1021 var undoLink = $(IDS.UNDO_LINK); 1066 var undoLink = $(IDS.UNDO_LINK);
1022 undoLink.addEventListener('click', onUndo); 1067 undoLink.addEventListener('click', onUndo);
1023 registerKeyHandler(undoLink, KEYCODE.ENTER, onUndo); 1068 registerKeyHandler(undoLink, KEYCODE.ENTER, onUndo);
1024 undoLink.textContent = configData.translatedStrings.undoThumbnailRemove; 1069 undoLink.textContent = configData.translatedStrings.undoThumbnailRemove;
1025 1070
1026 var restoreAllLink = $(IDS.RESTORE_ALL_LINK); 1071 var restoreAllLink = $(IDS.RESTORE_ALL_LINK);
1027 restoreAllLink.addEventListener('click', onRestoreAll); 1072 restoreAllLink.addEventListener('click', onRestoreAll);
1028 registerKeyHandler(restoreAllLink, KEYCODE.ENTER, onUndo); 1073 registerKeyHandler(restoreAllLink, KEYCODE.ENTER, onUndo);
1029 restoreAllLink.textContent = 1074 restoreAllLink.textContent =
1030 configData.translatedStrings.restoreThumbnailsShort; 1075 configData.translatedStrings.restoreThumbnailsShort;
1031 1076
1032 $(IDS.ATTRIBUTION_TEXT).textContent = 1077 $(IDS.ATTRIBUTION_TEXT).textContent =
1033 configData.translatedStrings.attributionIntro; 1078 configData.translatedStrings.attributionIntro;
1034 1079
1035 var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON); 1080 var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON);
1081 createAndAppendElement(
1082 notificationCloseButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
1036 notificationCloseButton.addEventListener('click', hideNotification); 1083 notificationCloseButton.addEventListener('click', hideNotification);
1037 1084
1038 window.addEventListener('resize', onResize); 1085 window.addEventListener('resize', onResize);
1039 onResize(); 1086 updateContentWidth();
1040 1087
1041 var topLevelHandle = getEmbeddedSearchApiHandle(); 1088 var topLevelHandle = getEmbeddedSearchApiHandle();
1042 1089
1043 ntpApiHandle = topLevelHandle.newTabPage; 1090 ntpApiHandle = topLevelHandle.newTabPage;
1044 ntpApiHandle.onthemechange = onThemeChange; 1091 ntpApiHandle.onthemechange = onThemeChange;
1045 ntpApiHandle.onmostvisitedchange = onMostVisitedChange; 1092 ntpApiHandle.onmostvisitedchange = onMostVisitedChange;
1046 1093
1047 ntpApiHandle.oninputstart = onInputStart; 1094 ntpApiHandle.oninputstart = onInputStart;
1048 ntpApiHandle.oninputcancel = restoreNtp; 1095 ntpApiHandle.oninputcancel = restoreNtp;
1049 1096
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 1157
1111 return { 1158 return {
1112 init: init, 1159 init: init,
1113 listen: listen 1160 listen: listen
1114 }; 1161 };
1115 } 1162 }
1116 1163
1117 if (!window.localNTPUnitTest) { 1164 if (!window.localNTPUnitTest) {
1118 LocalNTP().listen(); 1165 LocalNTP().listen();
1119 } 1166 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698