Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * @fileoverview New tab page | |
| 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. | |
| 9 */ | |
| 10 | |
| 11 // Use an anonymous function to enable strict mode just for this file (which | |
| 12 // will be concatenated with other files when embedded in Chrome | |
| 13 cr.define('ntp', function() { | |
| 14 'use strict'; | |
| 15 | |
| 16 /** | |
| 17 * NewTabView instance. | |
| 18 * @type {!Object|undefined} | |
| 19 */ | |
| 20 var newTabView; | |
| 21 | |
| 22 /** | |
| 23 * The 'notification-container' element. | |
| 24 * @type {!Element|undefined} | |
| 25 */ | |
| 26 var notificationContainer; | |
| 27 | |
| 28 /** | |
| 29 * If non-null, an info bubble for showing messages to the user. It points at | |
| 30 * the Most Visited label, and is used to draw more attention to the | |
| 31 * navigation dot UI. | |
| 32 * @type {!Element|undefined} | |
| 33 */ | |
| 34 var infoBubble; | |
| 35 | |
| 36 /** | |
| 37 * If non-null, an bubble confirming that the user has signed into sync. It | |
| 38 * points at the login status at the top of the page. | |
| 39 * @type {!Element|undefined} | |
| 40 */ | |
| 41 var loginBubble; | |
| 42 | |
| 43 /** | |
| 44 * true if |loginBubble| should be shown. | |
| 45 * @type {Boolean} | |
| 46 */ | |
| 47 var shouldShowLoginBubble = false; | |
| 48 | |
| 49 /** | |
| 50 * The 'other-sessions-menu-button' element. | |
| 51 * @type {!Element|undefined} | |
| 52 */ | |
| 53 var otherSessionsButton; | |
| 54 | |
| 55 /** | |
| 56 * The time in milliseconds for most transitions. This should match what's | |
| 57 * in new_tab.css. Unfortunately there's no better way to try to time | |
| 58 * something to occur until after a transition has completed. | |
| 59 * @type {number} | |
| 60 * @const | |
| 61 */ | |
| 62 var DEFAULT_TRANSITION_TIME = 500; | |
| 63 | |
| 64 /** | |
| 65 * See description for these values in ntp_stats.h. | |
| 66 * @enum {number} | |
| 67 */ | |
| 68 var NtpFollowAction = { | |
| 69 CLICKED_TILE: 11, | |
| 70 CLICKED_OTHER_NTP_PANE: 12, | |
| 71 OTHER: 13 | |
| 72 }; | |
| 73 | |
| 74 /** | |
| 75 * Creates a NewTabView object. NewTabView extends PageListView with | |
| 76 * new tab UI specific logics. | |
| 77 * @constructor | |
| 78 * @extends {PageListView} | |
| 79 */ | |
| 80 function NewTabView() { | |
| 81 var pageSwitcherStart = null; | |
| 82 var pageSwitcherEnd = null; | |
| 83 if (loadTimeData.getValue('showApps')) { | |
| 84 pageSwitcherStart = getRequiredElement('page-switcher-start'); | |
| 85 pageSwitcherEnd = getRequiredElement('page-switcher-end'); | |
| 86 } | |
| 87 this.initialize(getRequiredElement('page-list'), | |
| 88 getRequiredElement('dot-list'), | |
| 89 getRequiredElement('card-slider-frame'), | |
| 90 getRequiredElement('trash'), | |
| 91 pageSwitcherStart, pageSwitcherEnd); | |
| 92 } | |
| 93 | |
| 94 NewTabView.prototype = { | |
| 95 __proto__: ntp.PageListView.prototype, | |
| 96 | |
| 97 /** @inheritDoc */ | |
| 98 appendTilePage: function(page, title, titleIsEditable, opt_refNode) { | |
| 99 ntp.PageListView.prototype.appendTilePage.apply(this, arguments); | |
| 100 | |
| 101 if (infoBubble) | |
| 102 window.setTimeout(infoBubble.reposition.bind(infoBubble), 0); | |
| 103 } | |
| 104 }; | |
| 105 | |
| 106 /** | |
| 107 * Invoked at startup once the DOM is available to initialize the app. | |
| 108 */ | |
| 109 function onLoad() { | |
| 110 sectionsToWaitFor = loadTimeData.getBoolean('showApps') ? 2 : 1; | |
| 111 if (loadTimeData.getBoolean('isSuggestionsPageEnabled')) | |
| 112 sectionsToWaitFor++; | |
| 113 measureNavDots(); | |
| 114 | |
| 115 // Load the current theme colors. | |
| 116 themeChanged(); | |
| 117 | |
| 118 newTabView = new NewTabView(); | |
| 119 | |
| 120 notificationContainer = getRequiredElement('notification-container'); | |
| 121 notificationContainer.addEventListener( | |
| 122 'webkitTransitionEnd', onNotificationTransitionEnd); | |
| 123 | |
| 124 cr.ui.decorate($('recently-closed-menu-button'), ntp.RecentMenuButton); | |
| 125 chrome.send('getRecentlyClosedTabs'); | |
| 126 | |
| 127 if (loadTimeData.getBoolean('showOtherSessionsMenu')) { | |
| 128 otherSessionsButton = getRequiredElement('other-sessions-menu-button'); | |
| 129 cr.ui.decorate(otherSessionsButton, ntp.OtherSessionsMenuButton); | |
| 130 otherSessionsButton.initialize(loadTimeData.getBoolean('isUserSignedIn')); | |
| 131 } | |
| 132 | |
| 133 var mostVisited = new ntp.MostVisitedPage(); | |
| 134 // Move the footer into the most visited page if we are in "bare minimum" | |
| 135 // mode. | |
| 136 if (document.body.classList.contains('bare-minimum')) | |
| 137 mostVisited.appendFooter(getRequiredElement('footer')); | |
| 138 newTabView.appendTilePage(mostVisited, | |
| 139 loadTimeData.getString('mostvisited'), | |
| 140 false); | |
| 141 chrome.send('getMostVisited'); | |
| 142 | |
| 143 if (loadTimeData.getBoolean('isSuggestionsPageEnabled')) { | |
| 144 var suggestions_script = document.createElement('script'); | |
| 145 suggestions_script.src = 'suggestions_page.js'; | |
| 146 suggestions_script.onload = function() { | |
| 147 newTabView.appendTilePage(new ntp.SuggestionsPage(), | |
| 148 loadTimeData.getString('suggestions'), | |
| 149 false, | |
| 150 (newTabView.appsPages.length > 0) ? | |
| 151 newTabView.appsPages[0] : null); | |
| 152 chrome.send('getSuggestions'); | |
| 153 cr.dispatchSimpleEvent(document, 'sectionready', true, true); | |
| 154 }; | |
| 155 document.querySelector('head').appendChild(suggestions_script); | |
| 156 } | |
| 157 | |
| 158 var webStoreLink = loadTimeData.getString('webStoreLink'); | |
| 159 var url = appendParam(webStoreLink, 'utm_source', 'chrome-ntp-launcher'); | |
| 160 $('chrome-web-store-link').href = url; | |
| 161 $('chrome-web-store-link').addEventListener('click', | |
| 162 onChromeWebStoreButtonClick); | |
| 163 | |
| 164 if (loadTimeData.getString('login_status_message')) { | |
| 165 loginBubble = new cr.ui.Bubble; | |
| 166 loginBubble.anchorNode = $('login-container'); | |
| 167 loginBubble.setArrowLocation(cr.ui.ArrowLocation.TOP_END); | |
| 168 loginBubble.bubbleAlignment = | |
| 169 cr.ui.BubbleAlignment.BUBBLE_EDGE_TO_ANCHOR_EDGE; | |
| 170 loginBubble.deactivateToDismissDelay = 2000; | |
| 171 loginBubble.setCloseButtonVisible(false); | |
| 172 | |
| 173 $('login-status-advanced').onclick = function() { | |
| 174 chrome.send('showAdvancedLoginUI'); | |
| 175 }; | |
| 176 $('login-status-dismiss').onclick = loginBubble.hide.bind(loginBubble); | |
| 177 | |
| 178 var bubbleContent = $('login-status-bubble-contents'); | |
| 179 loginBubble.content = bubbleContent; | |
| 180 | |
| 181 // The anchor node won't be updated until updateLogin is called so don't | |
| 182 // show the bubble yet. | |
| 183 shouldShowLoginBubble = true; | |
| 184 } | |
| 185 | |
| 186 var loginContainer = getRequiredElement('login-container'); | |
| 187 loginContainer.addEventListener('click', showSyncLoginUI); | |
| 188 chrome.send('initializeSyncLogin'); | |
| 189 | |
| 190 doWhenAllSectionsReady(function() { | |
| 191 | |
| 192 // TODO(xci) new! | |
| 193 // TODO(pedrosimonetti): find a better place to put this code. Every, | |
| 194 // card needs to call layout the first time is shown. | |
| 195 newTabView.cardSlider.currentCardValue.layout_(); | |
| 196 | |
| 197 // Tell the slider about the pages. | |
| 198 newTabView.updateSliderCards(); | |
| 199 // Mark the current page. | |
| 200 newTabView.cardSlider.currentCardValue.navigationDot.classList.add( | |
| 201 'selected'); | |
| 202 | |
| 203 if (loadTimeData.valueExists('serverpromo')) { | |
| 204 var promo = loadTimeData.getString('serverpromo'); | |
| 205 var tags = ['IMG']; | |
| 206 var attrs = { | |
| 207 src: function(node, value) { | |
| 208 return node.tagName == 'IMG' && | |
| 209 /^data\:image\/(?:png|gif|jpe?g)/.test(value); | |
| 210 }, | |
| 211 }; | |
| 212 showNotification(parseHtmlSubset(promo, tags, attrs), [], function() { | |
| 213 chrome.send('closeNotificationPromo'); | |
| 214 }, 60000); | |
| 215 chrome.send('notificationPromoViewed'); | |
| 216 } | |
| 217 | |
| 218 cr.dispatchSimpleEvent(document, 'ntpLoaded', true, true); | |
| 219 document.documentElement.classList.remove('starting-up'); | |
| 220 }); | |
| 221 } | |
| 222 | |
| 223 /** | |
| 224 * Launches the chrome web store app with the chrome-ntp-launcher | |
| 225 * source. | |
| 226 * @param {Event} e The click event. | |
| 227 */ | |
| 228 function onChromeWebStoreButtonClick(e) { | |
| 229 chrome.send('recordAppLaunchByURL', | |
| 230 [encodeURIComponent(this.href), | |
| 231 ntp.APP_LAUNCH.NTP_WEBSTORE_FOOTER]); | |
| 232 } | |
| 233 | |
| 234 /* | |
| 235 * The number of sections to wait on. | |
| 236 * @type {number} | |
| 237 */ | |
| 238 var sectionsToWaitFor = -1; | |
| 239 | |
| 240 /** | |
| 241 * Queued callbacks which lie in wait for all sections to be ready. | |
| 242 * @type {array} | |
| 243 */ | |
| 244 var readyCallbacks = []; | |
| 245 | |
| 246 /** | |
| 247 * Fired as each section of pages becomes ready. | |
| 248 * @param {Event} e Each page's synthetic DOM event. | |
| 249 */ | |
| 250 document.addEventListener('sectionready', function(e) { | |
| 251 if (--sectionsToWaitFor <= 0) { | |
| 252 while (readyCallbacks.length) { | |
| 253 readyCallbacks.shift()(); | |
| 254 } | |
| 255 } | |
| 256 }); | |
| 257 | |
| 258 /** | |
| 259 * This is used to simulate a fire-once event (i.e. $(document).ready() in | |
| 260 * jQuery or Y.on('domready') in YUI. If all sections are ready, the callback | |
| 261 * is fired right away. If all pages are not ready yet, the function is queued | |
| 262 * for later execution. | |
| 263 * @param {function} callback The work to be done when ready. | |
| 264 */ | |
| 265 function doWhenAllSectionsReady(callback) { | |
| 266 assert(typeof callback == 'function'); | |
| 267 if (sectionsToWaitFor > 0) | |
| 268 readyCallbacks.push(callback); | |
| 269 else | |
| 270 window.setTimeout(callback, 0); // Do soon after, but asynchronously. | |
| 271 } | |
| 272 | |
| 273 /** | |
| 274 * Fills in an invisible div with the 'Most Visited' string so that | |
| 275 * its length may be measured and the nav dots sized accordingly. | |
| 276 */ | |
| 277 function measureNavDots() { | |
| 278 var measuringDiv = $('fontMeasuringDiv'); | |
| 279 measuringDiv.textContent = loadTimeData.getString('mostvisited'); | |
| 280 // The 4 is for border and padding. | |
| 281 var pxWidth = Math.max(measuringDiv.clientWidth * 1.15 + 4, 80); | |
| 282 | |
| 283 var styleElement = document.createElement('style'); | |
| 284 styleElement.type = 'text/css'; | |
| 285 // max-width is used because if we run out of space, the nav dots will be | |
| 286 // shrunk. | |
| 287 styleElement.textContent = '.dot { max-width: ' + pxWidth + 'px; }'; | |
| 288 document.querySelector('head').appendChild(styleElement); | |
| 289 } | |
| 290 | |
| 291 function themeChanged(opt_hasAttribution) { | |
| 292 $('themecss').href = 'chrome://theme/css/new_tab_theme.css?' + Date.now(); | |
| 293 | |
| 294 if (typeof opt_hasAttribution != 'undefined') { | |
| 295 document.documentElement.setAttribute('hasattribution', | |
| 296 opt_hasAttribution); | |
| 297 } | |
| 298 | |
| 299 updateAttribution(); | |
| 300 } | |
| 301 | |
| 302 function setBookmarkBarAttached(attached) { | |
| 303 document.documentElement.setAttribute('bookmarkbarattached', attached); | |
| 304 } | |
| 305 | |
| 306 /** | |
| 307 * Attributes the attribution image at the bottom left. | |
| 308 */ | |
| 309 function updateAttribution() { | |
| 310 var attribution = $('attribution'); | |
| 311 if (document.documentElement.getAttribute('hasattribution') == 'true') { | |
| 312 $('attribution-img').src = | |
| 313 'chrome://theme/IDR_THEME_NTP_ATTRIBUTION?' + Date.now(); | |
| 314 attribution.hidden = false; | |
| 315 } else { | |
| 316 attribution.hidden = true; | |
| 317 } | |
| 318 } | |
| 319 | |
| 320 /** | |
| 321 * Timeout ID. | |
| 322 * @type {number} | |
| 323 */ | |
| 324 var notificationTimeout = 0; | |
| 325 | |
| 326 /** | |
| 327 * Shows the notification bubble. | |
| 328 * @param {string|Node} message The notification message or node to use as | |
| 329 * message. | |
| 330 * @param {Array.<{text: string, action: function()}>} links An array of | |
| 331 * records describing the links in the notification. Each record should | |
| 332 * have a 'text' attribute (the display string) and an 'action' attribute | |
| 333 * (a function to run when the link is activated). | |
| 334 * @param {Function} opt_closeHandler The callback invoked if the user | |
| 335 * manually dismisses the notification. | |
| 336 */ | |
| 337 function showNotification(message, links, opt_closeHandler, opt_timeout) { | |
| 338 window.clearTimeout(notificationTimeout); | |
| 339 | |
| 340 var span = document.querySelector('#notification > span'); | |
| 341 if (typeof message == 'string') { | |
| 342 span.textContent = message; | |
| 343 } else { | |
| 344 span.textContent = ''; // Remove all children. | |
| 345 span.appendChild(message); | |
| 346 } | |
| 347 | |
| 348 var linksBin = $('notificationLinks'); | |
| 349 linksBin.textContent = ''; | |
| 350 for (var i = 0; i < links.length; i++) { | |
| 351 var link = linksBin.ownerDocument.createElement('div'); | |
| 352 link.textContent = links[i].text; | |
| 353 link.action = links[i].action; | |
| 354 link.onclick = function() { | |
| 355 this.action(); | |
| 356 hideNotification(); | |
| 357 }; | |
| 358 link.setAttribute('role', 'button'); | |
| 359 link.setAttribute('tabindex', 0); | |
| 360 link.className = 'link-button'; | |
| 361 linksBin.appendChild(link); | |
| 362 } | |
| 363 | |
| 364 function closeFunc(e) { | |
| 365 if (opt_closeHandler) | |
| 366 opt_closeHandler(); | |
| 367 hideNotification(); | |
| 368 } | |
| 369 | |
| 370 document.querySelector('#notification button').onclick = closeFunc; | |
| 371 document.addEventListener('dragstart', closeFunc); | |
| 372 | |
| 373 notificationContainer.hidden = false; | |
| 374 showNotificationOnCurrentPage(); | |
| 375 | |
| 376 newTabView.cardSlider.frame.addEventListener( | |
| 377 'cardSlider:card_change_ended', onCardChangeEnded); | |
| 378 | |
| 379 var timeout = opt_timeout || 10000; | |
| 380 notificationTimeout = window.setTimeout(hideNotification, timeout); | |
| 381 } | |
| 382 | |
| 383 /** | |
| 384 * Hide the notification bubble. | |
| 385 */ | |
| 386 function hideNotification() { | |
| 387 notificationContainer.classList.add('inactive'); | |
| 388 | |
| 389 newTabView.cardSlider.frame.removeEventListener( | |
| 390 'cardSlider:card_change_ended', onCardChangeEnded); | |
| 391 } | |
| 392 | |
| 393 /** | |
| 394 * Happens when 1 or more consecutive card changes end. | |
| 395 * @param {Event} e The cardSlider:card_change_ended event. | |
| 396 */ | |
| 397 function onCardChangeEnded(e) { | |
| 398 // If we ended on the same page as we started, ignore. | |
| 399 if (newTabView.cardSlider.currentCardValue.notification) | |
| 400 return; | |
| 401 | |
| 402 // Hide the notification the old page. | |
| 403 notificationContainer.classList.add('card-changed'); | |
| 404 | |
| 405 showNotificationOnCurrentPage(); | |
| 406 } | |
| 407 | |
| 408 /** | |
| 409 * Move and show the notification on the current page. | |
| 410 */ | |
| 411 function showNotificationOnCurrentPage() { | |
| 412 var page = newTabView.cardSlider.currentCardValue; | |
| 413 doWhenAllSectionsReady(function() { | |
| 414 if (page != newTabView.cardSlider.currentCardValue) | |
| 415 return; | |
| 416 | |
| 417 // NOTE: This moves the notification to inside of the current page. | |
| 418 page.notification = notificationContainer; | |
| 419 | |
| 420 // Reveal the notification and instruct it to hide itself if ignored. | |
| 421 notificationContainer.classList.remove('inactive'); | |
| 422 | |
| 423 // Gives the browser time to apply this rule before we remove it (causing | |
| 424 // a transition). | |
| 425 window.setTimeout(function() { | |
| 426 notificationContainer.classList.remove('card-changed'); | |
| 427 }, 0); | |
| 428 }); | |
| 429 } | |
| 430 | |
| 431 /** | |
| 432 * When done fading out, set hidden to true so the notification can't be | |
| 433 * tabbed to or clicked. | |
| 434 * @param {Event} e The webkitTransitionEnd event. | |
| 435 */ | |
| 436 function onNotificationTransitionEnd(e) { | |
| 437 if (notificationContainer.classList.contains('inactive')) | |
| 438 notificationContainer.hidden = true; | |
| 439 } | |
| 440 | |
| 441 function setRecentlyClosedTabs(dataItems) { | |
| 442 $('recently-closed-menu-button').dataItems = dataItems; | |
| 443 } | |
| 444 | |
| 445 function setMostVisitedPages(data, hasBlacklistedUrls) { | |
| 446 newTabView.mostVisitedPage.data = data; | |
| 447 cr.dispatchSimpleEvent(document, 'sectionready', true, true); | |
| 448 } | |
| 449 | |
| 450 function setSuggestionsPages(data, hasBlacklistedUrls) { | |
| 451 newTabView.suggestionsPage.data = data; | |
| 452 } | |
| 453 | |
| 454 function getThumbnailUrl(url) { | |
| 455 return 'chrome://thumb/' + url; | |
| 456 } | |
| 457 | |
| 458 /** | |
| 459 * Set the dominant color for a node. This will be called in response to | |
| 460 * getFaviconDominantColor. The node represented by |id| better have a setter | |
| 461 * for stripeColor. | |
| 462 * @param {string} id The ID of a node. | |
| 463 * @param {string} color The color represented as a CSS string. | |
| 464 */ | |
| 465 function setStripeColor(id, color) { | |
| 466 var node = $(id); | |
| 467 if (node) | |
| 468 node.stripeColor = color; | |
| 469 } | |
| 470 | |
| 471 /** | |
| 472 * Updates the text displayed in the login container. If there is no text then | |
| 473 * the login container is hidden. | |
| 474 * @param {string} loginHeader The first line of text. | |
| 475 * @param {string} loginSubHeader The second line of text. | |
| 476 * @param {string} iconURL The url for the login status icon. If this is null | |
| 477 then the login status icon is hidden. | |
| 478 * @param {boolean} isUserSignedIn Indicates if the user is signed in or not. | |
| 479 */ | |
| 480 function updateLogin(loginHeader, loginSubHeader, iconURL, isUserSignedIn) { | |
| 481 if (loginHeader || loginSubHeader) { | |
| 482 $('login-container').hidden = false; | |
| 483 $('login-status-header').innerHTML = loginHeader; | |
| 484 $('login-status-sub-header').innerHTML = loginSubHeader; | |
| 485 $('card-slider-frame').classList.add('showing-login-area'); | |
| 486 | |
| 487 if (iconURL) { | |
| 488 $('login-status-header-container').style.backgroundImage = url(iconURL); | |
| 489 $('login-status-header-container').classList.add('login-status-icon'); | |
| 490 } else { | |
| 491 $('login-status-header-container').style.backgroundImage = 'none'; | |
| 492 $('login-status-header-container').classList.remove( | |
| 493 'login-status-icon'); | |
| 494 } | |
| 495 } else { | |
| 496 $('login-container').hidden = true; | |
| 497 $('card-slider-frame').classList.remove('showing-login-area'); | |
| 498 } | |
| 499 if (shouldShowLoginBubble) { | |
| 500 window.setTimeout(loginBubble.show.bind(loginBubble), 0); | |
| 501 chrome.send('loginMessageSeen'); | |
| 502 shouldShowLoginBubble = false; | |
| 503 } else if (loginBubble) { | |
| 504 loginBubble.reposition(); | |
| 505 } | |
| 506 if (otherSessionsButton) | |
| 507 otherSessionsButton.updateSignInState(isUserSignedIn); | |
| 508 } | |
| 509 | |
| 510 /** | |
| 511 * Show the sync login UI. | |
| 512 * @param {Event} e The click event. | |
| 513 */ | |
| 514 function showSyncLoginUI(e) { | |
| 515 var rect = e.currentTarget.getBoundingClientRect(); | |
| 516 chrome.send('showSyncLoginUI', | |
| 517 [rect.left, rect.top, rect.width, rect.height]); | |
| 518 } | |
| 519 | |
| 520 /** | |
| 521 * Wrappers to forward the callback to corresponding PageListView member. | |
| 522 */ | |
| 523 function appAdded() { | |
| 524 return newTabView.appAdded.apply(newTabView, arguments); | |
| 525 } | |
| 526 | |
| 527 function appMoved() { | |
| 528 return newTabView.appMoved.apply(newTabView, arguments); | |
| 529 } | |
| 530 | |
| 531 function appRemoved() { | |
| 532 return newTabView.appRemoved.apply(newTabView, arguments); | |
| 533 } | |
| 534 | |
| 535 function appsPrefChangeCallback() { | |
| 536 return newTabView.appsPrefChangedCallback.apply(newTabView, arguments); | |
| 537 } | |
| 538 | |
| 539 function appsReordered() { | |
| 540 return newTabView.appsReordered.apply(newTabView, arguments); | |
| 541 } | |
| 542 | |
| 543 function enterRearrangeMode() { | |
| 544 return newTabView.enterRearrangeMode.apply(newTabView, arguments); | |
| 545 } | |
| 546 | |
| 547 function setForeignSessions(sessionList, isTabSyncEnabled) { | |
| 548 if (otherSessionsButton) | |
| 549 otherSessionsButton.setForeignSessions(sessionList, isTabSyncEnabled); | |
| 550 } | |
| 551 | |
| 552 function getAppsCallback() { | |
| 553 return newTabView.getAppsCallback.apply(newTabView, arguments); | |
| 554 } | |
| 555 | |
| 556 function getAppsPageIndex() { | |
| 557 return newTabView.getAppsPageIndex.apply(newTabView, arguments); | |
| 558 } | |
| 559 | |
| 560 function getCardSlider() { | |
| 561 return newTabView.cardSlider; | |
| 562 } | |
| 563 | |
| 564 function leaveRearrangeMode() { | |
| 565 return newTabView.leaveRearrangeMode.apply(newTabView, arguments); | |
| 566 } | |
| 567 | |
| 568 function saveAppPageName() { | |
| 569 return newTabView.saveAppPageName.apply(newTabView, arguments); | |
| 570 } | |
| 571 | |
| 572 function setAppToBeHighlighted(appId) { | |
| 573 newTabView.highlightAppId = appId; | |
| 574 } | |
| 575 | |
| 576 // Return an object with all the exports | |
| 577 return { | |
| 578 appAdded: appAdded, | |
| 579 appMoved: appMoved, | |
| 580 appRemoved: appRemoved, | |
| 581 appsPrefChangeCallback: appsPrefChangeCallback, | |
| 582 enterRearrangeMode: enterRearrangeMode, | |
| 583 getAppsCallback: getAppsCallback, | |
| 584 getAppsPageIndex: getAppsPageIndex, | |
| 585 getCardSlider: getCardSlider, | |
| 586 onLoad: onLoad, | |
| 587 leaveRearrangeMode: leaveRearrangeMode, | |
| 588 NtpFollowAction: NtpFollowAction, | |
| 589 saveAppPageName: saveAppPageName, | |
| 590 setAppToBeHighlighted: setAppToBeHighlighted, | |
| 591 setBookmarkBarAttached: setBookmarkBarAttached, | |
| 592 setForeignSessions: setForeignSessions, | |
| 593 setMostVisitedPages: setMostVisitedPages, | |
| 594 setSuggestionsPages: setSuggestionsPages, | |
| 595 setRecentlyClosedTabs: setRecentlyClosedTabs, | |
| 596 getThumbnailUrl: getThumbnailUrl, | |
|
jeremycho_google
2012/07/31 03:09:16
Alphabetize.
pedrosimonetti2
2012/08/03 18:14:01
Done.
| |
| 597 setStripeColor: setStripeColor, | |
| 598 showNotification: showNotification, | |
| 599 themeChanged: themeChanged, | |
| 600 updateLogin: updateLogin | |
| 601 }; | |
| 602 }); | |
| 603 | |
| 604 document.addEventListener('DOMContentLoaded', ntp.onLoad); | |
| 605 | |
| 606 var toCssPx = cr.ui.toCssPx; | |
| OLD | NEW |