OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |