| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 */ | 49 */ |
| 50 var bookmarksPage; | 50 var bookmarksPage; |
| 51 | 51 |
| 52 /** | 52 /** |
| 53 * The 'dots-list' element. | 53 * The 'dots-list' element. |
| 54 * @type {!Element|undefined} | 54 * @type {!Element|undefined} |
| 55 */ | 55 */ |
| 56 var dotList; | 56 var dotList; |
| 57 | 57 |
| 58 /** | 58 /** |
| 59 * A list of all 'dots' elements. | |
| 60 * @type {!NodeList|undefined} | |
| 61 */ | |
| 62 var dots; | |
| 63 | |
| 64 /** | |
| 65 * The left and right paging buttons. | 59 * The left and right paging buttons. |
| 66 * @type {!Element|undefined} | 60 * @type {!Element|undefined} |
| 67 */ | 61 */ |
| 68 var pageSwitcherStart; | 62 var pageSwitcherStart; |
| 69 var pageSwitcherEnd; | 63 var pageSwitcherEnd; |
| 70 | 64 |
| 71 /** | 65 /** |
| 72 * The 'trash' element. Note that technically this is unnecessary, | 66 * The 'trash' element. Note that technically this is unnecessary, |
| 73 * JavaScript creates the object for us based on the id. But I don't want | 67 * JavaScript creates the object for us based on the id. But I don't want |
| 74 * to rely on the ID being the same, and JSCompiler doesn't know about it. | 68 * to rely on the ID being the same, and JSCompiler doesn't know about it. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 dotList = getRequiredElement('dot-list'); | 132 dotList = getRequiredElement('dot-list'); |
| 139 pageList = getRequiredElement('page-list'); | 133 pageList = getRequiredElement('page-list'); |
| 140 trash = getRequiredElement('trash'); | 134 trash = getRequiredElement('trash'); |
| 141 new ntp4.Trash(trash); | 135 new ntp4.Trash(trash); |
| 142 | 136 |
| 143 shownPage = templateData['shown_page_type']; | 137 shownPage = templateData['shown_page_type']; |
| 144 shownPageIndex = templateData['shown_page_index']; | 138 shownPageIndex = templateData['shown_page_index']; |
| 145 | 139 |
| 146 // When a new app has been installed, we will be opened with a hash value | 140 // When a new app has been installed, we will be opened with a hash value |
| 147 // that corresponds to the new app ID. | 141 // that corresponds to the new app ID. |
| 148 var hash = location.hash; | 142 highlightAppId = getAndClearAppIDHash(); |
| 149 if (hash && hash.indexOf('#app-id=') == 0) { | |
| 150 highlightAppId = hash.split('=')[1]; | |
| 151 // Clear the hash so if the user bookmarks this page, they'll just get | |
| 152 // chrome://newtab/. | |
| 153 window.history.replaceState({}, '', '/'); | |
| 154 } | |
| 155 | 143 |
| 156 // Request data on the apps so we can fill them in. | 144 // Request data on the apps so we can fill them in. |
| 157 // Note that this is kicked off asynchronously. 'getAppsCallback' will be | 145 // Note that this is kicked off asynchronously. 'getAppsCallback' will be |
| 158 // invoked at some point after this function returns. | 146 // invoked at some point after this function returns. |
| 159 chrome.send('getApps'); | 147 chrome.send('getApps'); |
| 160 | 148 |
| 161 // Prevent touch events from triggering any sort of native scrolling | 149 // Prevent touch events from triggering any sort of native scrolling |
| 162 document.addEventListener('touchmove', function(e) { | 150 document.addEventListener('touchmove', function(e) { |
| 163 e.preventDefault(); | 151 e.preventDefault(); |
| 164 }, true); | 152 }, true); |
| 165 | 153 |
| 166 dots = dotList.getElementsByClassName('dot'); | |
| 167 tilePages = pageList.getElementsByClassName('tile-page'); | 154 tilePages = pageList.getElementsByClassName('tile-page'); |
| 168 appsPages = pageList.getElementsByClassName('apps-page'); | 155 appsPages = pageList.getElementsByClassName('apps-page'); |
| 169 | 156 |
| 170 pageSwitcherStart = getRequiredElement('page-switcher-start'); | 157 pageSwitcherStart = getRequiredElement('page-switcher-start'); |
| 171 ntp4.initializePageSwitcher(pageSwitcherStart); | 158 ntp4.initializePageSwitcher(pageSwitcherStart); |
| 172 pageSwitcherEnd = getRequiredElement('page-switcher-end'); | 159 pageSwitcherEnd = getRequiredElement('page-switcher-end'); |
| 173 ntp4.initializePageSwitcher(pageSwitcherEnd); | 160 ntp4.initializePageSwitcher(pageSwitcherEnd); |
| 174 | 161 |
| 175 // Initialize the cardSlider without any cards at the moment | 162 // Initialize the cardSlider without any cards at the moment |
| 176 var sliderFrame = getRequiredElement('card-slider-frame'); | 163 var sliderFrame = getRequiredElement('card-slider-frame'); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 * @param {string} id The identifier name. | 220 * @param {string} id The identifier name. |
| 234 * @return {!Element} the Element. | 221 * @return {!Element} the Element. |
| 235 */ | 222 */ |
| 236 function getRequiredElement(id) { | 223 function getRequiredElement(id) { |
| 237 var element = document.getElementById(id); | 224 var element = document.getElementById(id); |
| 238 assert(element, 'Missing required element: ' + id); | 225 assert(element, 'Missing required element: ' + id); |
| 239 return element; | 226 return element; |
| 240 } | 227 } |
| 241 | 228 |
| 242 /** | 229 /** |
| 230 * Gets the app ID stored in the hash of the URL, and resets the hash to |
| 231 * empty. If there is not an app-id in the hash, does nothing. |
| 232 * @return {String} The value of the app-id query string parameter. |
| 233 */ |
| 234 function getAndClearAppIDHash() { |
| 235 var hash = location.hash; |
| 236 if (hash.indexOf('#app-id=') == 0) { |
| 237 var appID = hash.split('=')[1]; |
| 238 // Clear the hash so if the user bookmarks this page, they'll just get |
| 239 // chrome://newtab/. |
| 240 window.history.replaceState({}, '', '/'); |
| 241 return appID; |
| 242 } |
| 243 return ''; |
| 244 } |
| 245 |
| 246 /** |
| 243 * Callback invoked by chrome with the apps available. | 247 * Callback invoked by chrome with the apps available. |
| 244 * | 248 * |
| 245 * Note that calls to this function can occur at any time, not just in | 249 * Note that calls to this function can occur at any time, not just in |
| 246 * response to a getApps request. For example, when a user installs/uninstalls | 250 * response to a getApps request. For example, when a user installs/uninstalls |
| 247 * an app on another synchronized devices. | 251 * an app on another synchronized devices. |
| 248 * @param {Object} data An object with all the data on available | 252 * @param {Object} data An object with all the data on available |
| 249 * applications. | 253 * applications. |
| 250 */ | 254 */ |
| 251 function getAppsCallback(data) { | 255 function getAppsCallback(data) { |
| 252 var startTime = Date.now(); | 256 var startTime = Date.now(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 if (app.id == highlightAppId) { | 314 if (app.id == highlightAppId) { |
| 311 highlightApp = app; | 315 highlightApp = app; |
| 312 highlightAppId = null; | 316 highlightAppId = null; |
| 313 } else { | 317 } else { |
| 314 appsPages[pageIndex].appendApp(app); | 318 appsPages[pageIndex].appendApp(app); |
| 315 } | 319 } |
| 316 } | 320 } |
| 317 | 321 |
| 318 ntp4.AppsPage.setPromo(data.showPromo ? data : null); | 322 ntp4.AppsPage.setPromo(data.showPromo ? data : null); |
| 319 | 323 |
| 320 // Tell the slider about the pages | 324 // Tell the slider about the pages. |
| 321 updateSliderCards(); | 325 updateSliderCards(); |
| 322 | 326 |
| 323 if (highlightApp) | 327 if (highlightApp) |
| 324 appAdded(highlightApp); | 328 appAdded(highlightApp, true); |
| 325 | 329 |
| 326 // Mark the current page | 330 // Mark the current page. |
| 327 dots[cardSlider.currentCard].classList.add('selected'); | 331 cardSlider.currentCardValue.navigationDot.classList.add('selected'); |
| 328 logEvent('apps.layout: ' + (Date.now() - startTime)); | 332 logEvent('apps.layout: ' + (Date.now() - startTime)); |
| 329 | 333 |
| 330 document.documentElement.classList.remove('starting-up'); | 334 document.documentElement.classList.remove('starting-up'); |
| 331 } | 335 } |
| 332 | 336 |
| 333 /** | 337 /** |
| 334 * Called by chrome when a new app has been added to chrome. | 338 * Called by chrome when a new app has been added to chrome. |
| 335 * @param {Object} app A data structure full of relevant information for the | 339 * @param {Object} app A data structure full of relevant information for the |
| 336 * app. | 340 * app. |
| 337 */ | 341 */ |
| 338 function appAdded(app) { | 342 function appAdded(app, opt_highlight) { |
| 343 // If the page is already open when a new app is installed, the hash will |
| 344 // be set once again. |
| 345 var appID = getAndClearAppIDHash(); |
| 346 if (appID == app.id) |
| 347 opt_highlight = true; |
| 348 |
| 339 var pageIndex = app.page_index || 0; | 349 var pageIndex = app.page_index || 0; |
| 350 |
| 351 if (pageIndex >= appsPages.length) { |
| 352 while (pageIndex >= appsPages.length) { |
| 353 appendAppsPage(new ntp4.AppsPage(), ''); |
| 354 } |
| 355 updateSliderCards(); |
| 356 } |
| 357 |
| 340 var page = appsPages[pageIndex]; | 358 var page = appsPages[pageIndex]; |
| 341 cardSlider.selectCardByValue(page); | 359 if (opt_highlight) |
| 360 cardSlider.selectCardByValue(page); |
| 342 page.appendApp(app, true); | 361 page.appendApp(app, true); |
| 343 } | 362 } |
| 344 | 363 |
| 345 /** | 364 /** |
| 346 * Called by chrome when an existing app has been removed/uninstalled from | 365 * Called by chrome when an existing app has been removed/uninstalled from |
| 347 * chrome. | 366 * chrome. |
| 348 * @param {Object} appData A data structure full of relevant information for | 367 * @param {Object} appData A data structure full of relevant information for |
| 349 * the app. | 368 * the app. |
| 350 */ | 369 */ |
| 351 function appRemoved(appData) { | 370 function appRemoved(appData) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 */ | 413 */ |
| 395 function updateSliderCards() { | 414 function updateSliderCards() { |
| 396 var pageNo = cardSlider.currentCard; | 415 var pageNo = cardSlider.currentCard; |
| 397 if (pageNo >= tilePages.length) | 416 if (pageNo >= tilePages.length) |
| 398 pageNo = tilePages.length - 1; | 417 pageNo = tilePages.length - 1; |
| 399 var pageArray = []; | 418 var pageArray = []; |
| 400 for (var i = 0; i < tilePages.length; i++) | 419 for (var i = 0; i < tilePages.length; i++) |
| 401 pageArray[i] = tilePages[i]; | 420 pageArray[i] = tilePages[i]; |
| 402 cardSlider.setCards(pageArray, pageNo); | 421 cardSlider.setCards(pageArray, pageNo); |
| 403 | 422 |
| 404 if (shownPage == templateData['most_visited_page_id']) | 423 if (shownPage == templateData['most_visited_page_id']) { |
| 405 cardSlider.selectCardByValue(mostVisitedPage); | 424 cardSlider.selectCardByValue(mostVisitedPage); |
| 406 else if (shownPage == templateData['apps_page_id']) | 425 } else if (shownPage == templateData['apps_page_id']) { |
| 407 cardSlider.selectCardByValue(appsPages[shownPageIndex]); | 426 cardSlider.selectCardByValue( |
| 408 else if (shownPage == templateData['bookmarks_page_id']) | 427 appsPages[Math.min(shownPageIndex, appsPages.length - 1)]); |
| 428 } else if (shownPage == templateData['bookmarks_page_id']) { |
| 409 cardSlider.selectCardByValue(bookmarksPage); | 429 cardSlider.selectCardByValue(bookmarksPage); |
| 430 } |
| 410 } | 431 } |
| 411 | 432 |
| 412 /** | 433 /** |
| 413 * Appends a tile page (for bookmarks or most visited). | 434 * Appends a tile page (for bookmarks or most visited). |
| 414 * | 435 * |
| 415 * @param {TilePage} page The page element. | 436 * @param {TilePage} page The page element. |
| 416 * @param {string} title The title of the tile page. | 437 * @param {string} title The title of the tile page. |
| 417 */ | 438 */ |
| 418 function appendTilePage(page, title) { | 439 function appendTilePage(page, title) { |
| 419 pageList.appendChild(page); | 440 pageList.appendChild(page); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 $('footer').classList.add('showing-trash-mode'); | 503 $('footer').classList.add('showing-trash-mode'); |
| 483 } | 504 } |
| 484 | 505 |
| 485 /** | 506 /** |
| 486 * Invoked whenever some app is released | 507 * Invoked whenever some app is released |
| 487 * @param {Grabber.Event} e The Grabber RELEASE event. | 508 * @param {Grabber.Event} e The Grabber RELEASE event. |
| 488 */ | 509 */ |
| 489 function leaveRearrangeMode(e) { | 510 function leaveRearrangeMode(e) { |
| 490 var tempPage = document.querySelector('.tile-page.temporary'); | 511 var tempPage = document.querySelector('.tile-page.temporary'); |
| 491 var dot = tempPage.navigationDot; | 512 var dot = tempPage.navigationDot; |
| 492 if (!tempPage.tileCount) { | 513 if (!tempPage.tileCount && tempPage != cardSlider.currentCardValue) { |
| 493 dot.animateRemove(); | 514 dot.animateRemove(); |
| 494 tempPage.parentNode.removeChild(tempPage); | 515 tempPage.parentNode.removeChild(tempPage); |
| 495 updateSliderCards(); | 516 updateSliderCards(); |
| 496 } else { | 517 } else { |
| 497 tempPage.classList.remove('temporary'); | 518 tempPage.classList.remove('temporary'); |
| 498 saveAppPageName(tempPage, ''); | 519 saveAppPageName(tempPage, ''); |
| 499 } | 520 } |
| 500 | 521 |
| 501 $('footer').classList.remove('showing-trash-mode'); | 522 $('footer').classList.remove('showing-trash-mode'); |
| 502 } | 523 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 shownPageIndex = 0; | 644 shownPageIndex = 0; |
| 624 } else { | 645 } else { |
| 625 console.error('unknown page selected'); | 646 console.error('unknown page selected'); |
| 626 } | 647 } |
| 627 chrome.send('pageSelected', [shownPage, shownPageIndex]); | 648 chrome.send('pageSelected', [shownPage, shownPageIndex]); |
| 628 | 649 |
| 629 // Update the active dot | 650 // Update the active dot |
| 630 var curDot = dotList.getElementsByClassName('selected')[0]; | 651 var curDot = dotList.getElementsByClassName('selected')[0]; |
| 631 if (curDot) | 652 if (curDot) |
| 632 curDot.classList.remove('selected'); | 653 curDot.classList.remove('selected'); |
| 633 var newPageIndex = e.cardSlider.currentCard; | 654 page.navigationDot.classList.add('selected'); |
| 634 dots[newPageIndex].classList.add('selected'); | |
| 635 updatePageSwitchers(); | 655 updatePageSwitchers(); |
| 636 } | 656 } |
| 637 | 657 |
| 638 /** | 658 /** |
| 639 * Timeout ID. | 659 * Timeout ID. |
| 640 * @type {number} | 660 * @type {number} |
| 641 */ | 661 */ |
| 642 var notificationTimeout_ = 0; | 662 var notificationTimeout_ = 0; |
| 643 | 663 |
| 644 /** | 664 /** |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 // TODO(estade): update the content handlers to use ntp namespace instead of | 766 // TODO(estade): update the content handlers to use ntp namespace instead of |
| 747 // making these global. | 767 // making these global. |
| 748 var assert = ntp4.assert; | 768 var assert = ntp4.assert; |
| 749 var getAppsCallback = ntp4.getAppsCallback; | 769 var getAppsCallback = ntp4.getAppsCallback; |
| 750 var appsPrefChangeCallback = ntp4.appsPrefChangeCallback; | 770 var appsPrefChangeCallback = ntp4.appsPrefChangeCallback; |
| 751 var themeChanged = ntp4.themeChanged; | 771 var themeChanged = ntp4.themeChanged; |
| 752 var recentlyClosedTabs = ntp4.setRecentlyClosedTabs; | 772 var recentlyClosedTabs = ntp4.setRecentlyClosedTabs; |
| 753 var setMostVisitedPages = ntp4.setMostVisitedPages; | 773 var setMostVisitedPages = ntp4.setMostVisitedPages; |
| 754 | 774 |
| 755 document.addEventListener('DOMContentLoaded', ntp4.initialize); | 775 document.addEventListener('DOMContentLoaded', ntp4.initialize); |
| OLD | NEW |