OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 * @fileoverview New tab page | 6 * @fileoverview New tab page |
7 * This is the main code for the new tab page used by touch-enabled Chrome | 7 * This is the main code for the new tab page used by touch-enabled Chrome |
8 * browsers. For now this is still a prototype. | 8 * browsers. For now this is still a prototype. |
9 */ | 9 */ |
10 | 10 |
11 /** | |
12 * @typedef {{direction: string, | |
13 * filler: (boolean|undefined), | |
14 * title: string, | |
15 * url: string}} | |
16 * @see chrome/browser/ui/webui/ntp/most_visited_handler.cc | |
17 */ | |
18 var PageData; | |
19 | |
20 // Use an anonymous function to enable strict mode just for this file (which | 11 // Use an anonymous function to enable strict mode just for this file (which |
21 // will be concatenated with other files when embedded in Chrome | 12 // will be concatenated with other files when embedded in Chrome |
22 cr.define('ntp', function() { | 13 cr.define('ntp', function() { |
23 'use strict'; | 14 'use strict'; |
24 | 15 |
25 /** | 16 /** |
26 * NewTabView instance. | 17 * NewTabView instance. |
27 * @type {!Object|undefined} | 18 * @type {!Object|undefined} |
28 */ | 19 */ |
29 var newTabView; | 20 var newTabView; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 if (promoBubble) | 110 if (promoBubble) |
120 window.setTimeout(promoBubble.reposition.bind(promoBubble), 0); | 111 window.setTimeout(promoBubble.reposition.bind(promoBubble), 0); |
121 } | 112 } |
122 }; | 113 }; |
123 | 114 |
124 /** | 115 /** |
125 * Invoked at startup once the DOM is available to initialize the app. | 116 * Invoked at startup once the DOM is available to initialize the app. |
126 */ | 117 */ |
127 function onLoad() { | 118 function onLoad() { |
128 sectionsToWaitFor = 0; | 119 sectionsToWaitFor = 0; |
129 if (loadTimeData.getBoolean('showMostvisited')) | |
130 sectionsToWaitFor++; | |
131 if (loadTimeData.getBoolean('showApps')) { | 120 if (loadTimeData.getBoolean('showApps')) { |
132 sectionsToWaitFor++; | 121 sectionsToWaitFor++; |
133 if (loadTimeData.getBoolean('showAppLauncherPromo')) { | 122 if (loadTimeData.getBoolean('showAppLauncherPromo')) { |
134 $('app-launcher-promo-close-button').addEventListener('click', | 123 $('app-launcher-promo-close-button').addEventListener('click', |
135 function() { chrome.send('stopShowingAppLauncherPromo'); }); | 124 function() { chrome.send('stopShowingAppLauncherPromo'); }); |
136 $('apps-promo-learn-more').addEventListener('click', | 125 $('apps-promo-learn-more').addEventListener('click', |
137 function() { chrome.send('onLearnMore'); }); | 126 function() { chrome.send('onLearnMore'); }); |
138 } | 127 } |
139 } | 128 } |
140 measureNavDots(); | 129 measureNavDots(); |
141 | 130 |
142 // Load the current theme colors. | 131 // Load the current theme colors. |
143 themeChanged(); | 132 themeChanged(); |
144 | 133 |
145 newTabView = new NewTabView(); | 134 newTabView = new NewTabView(); |
146 | 135 |
147 notificationContainer = getRequiredElement('notification-container'); | 136 notificationContainer = getRequiredElement('notification-container'); |
148 notificationContainer.addEventListener( | 137 notificationContainer.addEventListener( |
149 'webkitTransitionEnd', onNotificationTransitionEnd); | 138 'webkitTransitionEnd', onNotificationTransitionEnd); |
150 | 139 |
151 if (loadTimeData.getBoolean('showOtherSessionsMenu')) { | 140 if (loadTimeData.getBoolean('showOtherSessionsMenu')) { |
152 otherSessionsButton = /** @type {!ntp.OtherSessionsMenuButton} */( | 141 otherSessionsButton = /** @type {!ntp.OtherSessionsMenuButton} */( |
153 getRequiredElement('other-sessions-menu-button')); | 142 getRequiredElement('other-sessions-menu-button')); |
154 cr.ui.decorate(otherSessionsButton, ntp.OtherSessionsMenuButton); | 143 cr.ui.decorate(otherSessionsButton, ntp.OtherSessionsMenuButton); |
155 otherSessionsButton.initialize(loadTimeData.getBoolean('isUserSignedIn')); | 144 otherSessionsButton.initialize(loadTimeData.getBoolean('isUserSignedIn')); |
156 } else { | 145 } else { |
157 getRequiredElement('other-sessions-menu-button').hidden = true; | 146 getRequiredElement('other-sessions-menu-button').hidden = true; |
158 } | 147 } |
159 | 148 |
160 if (loadTimeData.getBoolean('showMostvisited')) { | |
161 var mostVisited = new ntp.MostVisitedPage(); | |
162 // Move the footer into the most visited page if we are in "bare minimum" | |
163 // mode. | |
164 if (document.body.classList.contains('bare-minimum')) | |
165 mostVisited.appendFooter(getRequiredElement('footer')); | |
166 newTabView.appendTilePage(mostVisited, | |
167 loadTimeData.getString('mostvisited'), | |
168 false); | |
169 chrome.send('getMostVisited'); | |
170 } | |
171 | |
172 if (!loadTimeData.getBoolean('showWebStoreIcon')) { | 149 if (!loadTimeData.getBoolean('showWebStoreIcon')) { |
173 var webStoreIcon = $('chrome-web-store-link'); | 150 var webStoreIcon = $('chrome-web-store-link'); |
174 // Not all versions of the NTP have a footer, so this may not exist. | 151 // Not all versions of the NTP have a footer, so this may not exist. |
175 if (webStoreIcon) | 152 if (webStoreIcon) |
176 webStoreIcon.hidden = true; | 153 webStoreIcon.hidden = true; |
177 } else { | 154 } else { |
178 var webStoreLink = loadTimeData.getString('webStoreLink'); | 155 var webStoreLink = loadTimeData.getString('webStoreLink'); |
179 var url = appendParam(webStoreLink, 'utm_source', 'chrome-ntp-launcher'); | 156 var url = appendParam(webStoreLink, 'utm_source', 'chrome-ntp-launcher'); |
180 $('chrome-web-store-link').href = url; | 157 $('chrome-web-store-link').href = url; |
181 $('chrome-web-store-link').addEventListener('click', | 158 $('chrome-web-store-link').addEventListener('click', |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 measuringDiv.textContent = loadTimeData.getString(id); | 311 measuringDiv.textContent = loadTimeData.getString(id); |
335 // The 4 is for border and padding. | 312 // The 4 is for border and padding. |
336 return Math.max(measuringDiv.clientWidth * 1.15 + 4, 80); | 313 return Math.max(measuringDiv.clientWidth * 1.15 + 4, 80); |
337 } | 314 } |
338 | 315 |
339 /** | 316 /** |
340 * Fills in an invisible div with the longest dot title string so that | 317 * Fills in an invisible div with the longest dot title string so that |
341 * its length may be measured and the nav dots sized accordingly. | 318 * its length may be measured and the nav dots sized accordingly. |
342 */ | 319 */ |
343 function measureNavDots() { | 320 function measureNavDots() { |
344 var pxWidth = measureNavDot('appDefaultPageName'); | |
345 if (loadTimeData.getBoolean('showMostvisited')) | |
346 pxWidth = Math.max(measureNavDot('mostvisited'), pxWidth); | |
347 | |
348 var styleElement = document.createElement('style'); | 321 var styleElement = document.createElement('style'); |
349 styleElement.type = 'text/css'; | 322 styleElement.type = 'text/css'; |
350 // max-width is used because if we run out of space, the nav dots will be | 323 // max-width is used because if we run out of space, the nav dots will be |
351 // shrunk. | 324 // shrunk. |
| 325 var pxWidth = measureNavDot('appDefaultPageName'); |
352 styleElement.textContent = '.dot { max-width: ' + pxWidth + 'px; }'; | 326 styleElement.textContent = '.dot { max-width: ' + pxWidth + 'px; }'; |
353 document.querySelector('head').appendChild(styleElement); | 327 document.querySelector('head').appendChild(styleElement); |
354 } | 328 } |
355 | 329 |
356 /** | 330 /** |
357 * Layout the footer so that the nav dots stay centered. | 331 * Layout the footer so that the nav dots stay centered. |
358 */ | 332 */ |
359 function layoutFooter() { | 333 function layoutFooter() { |
360 // We need the image to be loaded. | 334 // We need the image to be loaded. |
361 var logo = $('logo-img'); | 335 var logo = $('logo-img'); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 * When done fading out, set hidden to true so the notification can't be | 489 * When done fading out, set hidden to true so the notification can't be |
516 * tabbed to or clicked. | 490 * tabbed to or clicked. |
517 * @param {Event} e The webkitTransitionEnd event. | 491 * @param {Event} e The webkitTransitionEnd event. |
518 */ | 492 */ |
519 function onNotificationTransitionEnd(e) { | 493 function onNotificationTransitionEnd(e) { |
520 if (notificationContainer.classList.contains('inactive')) | 494 if (notificationContainer.classList.contains('inactive')) |
521 notificationContainer.hidden = true; | 495 notificationContainer.hidden = true; |
522 } | 496 } |
523 | 497 |
524 /** | 498 /** |
525 * @param {Array<PageData>} data | |
526 * @param {boolean} hasBlacklistedUrls | |
527 */ | |
528 function setMostVisitedPages(data, hasBlacklistedUrls) { | |
529 newTabView.mostVisitedPage.data = data; | |
530 cr.dispatchSimpleEvent(document, 'sectionready', true, true); | |
531 } | |
532 | |
533 /** | |
534 * Set the dominant color for a node. This will be called in response to | 499 * Set the dominant color for a node. This will be called in response to |
535 * getFaviconDominantColor. The node represented by |id| better have a setter | 500 * getFaviconDominantColor. The node represented by |id| better have a setter |
536 * for stripeColor. | 501 * for stripeColor. |
537 * @param {string} id The ID of a node. | 502 * @param {string} id The ID of a node. |
538 * @param {string} color The color represented as a CSS string. | 503 * @param {string} color The color represented as a CSS string. |
539 */ | 504 */ |
540 function setFaviconDominantColor(id, color) { | 505 function setFaviconDominantColor(id, color) { |
541 var node = $(id); | 506 var node = $(id); |
542 if (node) | 507 if (node) |
543 node.stripeColor = color; | 508 node.stripeColor = color; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 * Show the sync login UI. | 550 * Show the sync login UI. |
586 * @param {Event} e The click event. | 551 * @param {Event} e The click event. |
587 */ | 552 */ |
588 function showSyncLoginUI(e) { | 553 function showSyncLoginUI(e) { |
589 var rect = e.currentTarget.getBoundingClientRect(); | 554 var rect = e.currentTarget.getBoundingClientRect(); |
590 chrome.send('showSyncLoginUI', | 555 chrome.send('showSyncLoginUI', |
591 [rect.left, rect.top, rect.width, rect.height]); | 556 [rect.left, rect.top, rect.width, rect.height]); |
592 } | 557 } |
593 | 558 |
594 /** | 559 /** |
595 * Logs the time to click for the specified item. | |
596 * @param {string} item The item to log the time-to-click. | |
597 */ | |
598 function logTimeToClick(item) { | |
599 var timeToClick = Date.now() - startTime; | |
600 chrome.send('logTimeToClick', | |
601 ['NewTabPage.TimeToClick' + item, timeToClick]); | |
602 } | |
603 | |
604 /** | |
605 * Wrappers to forward the callback to corresponding PageListView member. | 560 * Wrappers to forward the callback to corresponding PageListView member. |
606 */ | 561 */ |
607 | 562 |
608 /** | 563 /** |
609 * Called by chrome when a new app has been added to chrome or has been | 564 * Called by chrome when a new app has been added to chrome or has been |
610 * enabled if previously disabled. | 565 * enabled if previously disabled. |
611 * @param {Object} appData A data structure full of relevant information for | 566 * @param {Object} appData A data structure full of relevant information for |
612 * the app. | 567 * the app. |
613 * @param {boolean=} opt_highlight Whether the app about to be added should | 568 * @param {boolean=} opt_highlight Whether the app about to be added should |
614 * be highlighted. | 569 * be highlighted. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 appMoved: appMoved, | 679 appMoved: appMoved, |
725 appRemoved: appRemoved, | 680 appRemoved: appRemoved, |
726 appsPrefChangeCallback: appsPrefChangeCallback, | 681 appsPrefChangeCallback: appsPrefChangeCallback, |
727 appLauncherPromoPrefChangeCallback: appLauncherPromoPrefChangeCallback, | 682 appLauncherPromoPrefChangeCallback: appLauncherPromoPrefChangeCallback, |
728 enterRearrangeMode: enterRearrangeMode, | 683 enterRearrangeMode: enterRearrangeMode, |
729 getAppsCallback: getAppsCallback, | 684 getAppsCallback: getAppsCallback, |
730 getAppsPageIndex: getAppsPageIndex, | 685 getAppsPageIndex: getAppsPageIndex, |
731 getCardSlider: getCardSlider, | 686 getCardSlider: getCardSlider, |
732 onLoad: onLoad, | 687 onLoad: onLoad, |
733 leaveRearrangeMode: leaveRearrangeMode, | 688 leaveRearrangeMode: leaveRearrangeMode, |
734 logTimeToClick: logTimeToClick, | |
735 NtpFollowAction: NtpFollowAction, | 689 NtpFollowAction: NtpFollowAction, |
736 saveAppPageName: saveAppPageName, | 690 saveAppPageName: saveAppPageName, |
737 setAppToBeHighlighted: setAppToBeHighlighted, | 691 setAppToBeHighlighted: setAppToBeHighlighted, |
738 setBookmarkBarAttached: setBookmarkBarAttached, | 692 setBookmarkBarAttached: setBookmarkBarAttached, |
739 setForeignSessions: setForeignSessions, | 693 setForeignSessions: setForeignSessions, |
740 setMostVisitedPages: setMostVisitedPages, | |
741 setFaviconDominantColor: setFaviconDominantColor, | 694 setFaviconDominantColor: setFaviconDominantColor, |
742 showNotification: showNotification, | 695 showNotification: showNotification, |
743 themeChanged: themeChanged, | 696 themeChanged: themeChanged, |
744 updateLogin: updateLogin | 697 updateLogin: updateLogin |
745 }; | 698 }; |
746 }); | 699 }); |
747 | 700 |
748 document.addEventListener('DOMContentLoaded', ntp.onLoad); | 701 document.addEventListener('DOMContentLoaded', ntp.onLoad); |
749 | 702 |
750 var toCssPx = cr.ui.toCssPx; | 703 var toCssPx = cr.ui.toCssPx; |
OLD | NEW |