| Index: chrome/browser/resources/ntp_search/new_tab.js
|
| diff --git a/chrome/browser/resources/ntp_search/new_tab.js b/chrome/browser/resources/ntp_search/new_tab.js
|
| index 35ac874fe785ba9a3fe14a8f8245f83677c95042..c5266292181e6d1cbd514ce22e2bd1f5d7a1736e 100644
|
| --- a/chrome/browser/resources/ntp_search/new_tab.js
|
| +++ b/chrome/browser/resources/ntp_search/new_tab.js
|
| @@ -37,7 +37,7 @@ cr.define('ntp', function() {
|
| * @type {number}
|
| * @const
|
| */
|
| - var HEIGHT_FOR_BOTTOM_PANEL = 550;
|
| + var HEIGHT_FOR_BOTTOM_PANEL = 558;
|
|
|
| /**
|
| * The Bottom Panel width required to show 6 cols of Tiles, which is used
|
| @@ -158,10 +158,10 @@ cr.define('ntp', function() {
|
| tilePages: undefined,
|
|
|
| /**
|
| - * The Apps page.
|
| - * @type {!Element|undefined}
|
| + * A list of all 'apps-page' elements.
|
| + * @type {!NodeList|undefined}
|
| */
|
| - appsPage: undefined,
|
| + appsPages: undefined,
|
|
|
| /**
|
| * The Most Visited page.
|
| @@ -229,7 +229,8 @@ cr.define('ntp', function() {
|
| // Request data on the apps so we can fill them in.
|
| // Note that this is kicked off asynchronously. 'getAppsCallback' will
|
| // be invoked at some point after this function returns.
|
| - chrome.send('getApps');
|
| + if (!ntp.ntp5)
|
| + chrome.send('getApps');
|
| } else if (this.shownPage == loadTimeData.getInteger('apps_page_id')) {
|
| // No apps page.
|
| this.setShownPage_(
|
| @@ -237,6 +238,7 @@ cr.define('ntp', function() {
|
| }
|
|
|
| this.tilePages = this.pageList.getElementsByClassName('tile-page');
|
| + this.appsPages = this.pageList.getElementsByClassName('apps-page');
|
|
|
| // Initialize the cardSlider without any cards at the moment.
|
| this.sliderFrame = cardSliderFrame;
|
| @@ -303,11 +305,6 @@ cr.define('ntp', function() {
|
| this.mostVisitedPage = page;
|
| }
|
|
|
| - if (typeof ntp.AppsPage != 'undefined' &&
|
| - page instanceof ntp.AppsPage) {
|
| - this.appsPage = page;
|
| - }
|
| -
|
| if (typeof ntp.RecentlyClosedPage != 'undefined' &&
|
| page instanceof ntp.RecentlyClosedPage) {
|
| this.recentlyClosedPage = page;
|
| @@ -341,7 +338,7 @@ cr.define('ntp', function() {
|
| assert(app, 'trying to move an app that doesn\'t exist');
|
| app.remove(false);
|
|
|
| - this.appsPage.insertApp(appData, false);
|
| + this.appsPages[appData.page_index].insertApp(appData, false);
|
| },
|
|
|
| /**
|
| @@ -392,26 +389,31 @@ cr.define('ntp', function() {
|
| getAppsCallback: function(data) {
|
| assert(loadTimeData.getBoolean('showApps'));
|
|
|
| - var page = this.appsPage;
|
| - var state = page && page.getTileRepositioningState();
|
| - if (state) {
|
| - if (state.isRemoving)
|
| - page.animateTileRemoval(state.index, data);
|
| - else
|
| - page.animateTileRestoration(state.index, data);
|
| + var startTime = Date.now();
|
|
|
| - page.resetTileRepositioningState();
|
| - return;
|
| - }
|
| + // Remember this to select the correct card when done rebuilding.
|
| + var prevCurrentCard = this.cardSlider.currentCard;
|
|
|
| - var startTime = Date.now();
|
| + // Make removal of pages and dots as quick as possible with less DOM
|
| + // operations, reflows, or repaints. We set currentCard = 0 and remove
|
| + // from the end to not encounter any auto-magic card selections in the
|
| + // process and we hide the card slider throughout.
|
| + this.cardSlider.currentCard = 0;
|
|
|
| - if (page)
|
| - page.removeAllTiles();
|
| + // Clear any existing apps pages and dots.
|
| + // TODO(rbyers): It might be nice to preserve animation of dots after an
|
| + // uninstall. Could we re-use the existing page and dot elements? It
|
| + // seems unfortunate to have Chrome send us the entire apps list after an
|
| + // uninstall.
|
| + while (this.appsPages.length > 0)
|
| + this.removeTilePageAndDot_(this.appsPages[this.appsPages.length - 1]);
|
|
|
| // Get the array of apps and add any special synthesized entries
|
| var apps = data.apps;
|
|
|
| + // Get a list of page names
|
| + var pageNames = data.appPageNames;
|
| +
|
| // Sort by launch ordinal
|
| apps.sort(function(a, b) {
|
| return a.app_launch_ordinal > b.app_launch_ordinal ? 1 :
|
| @@ -421,17 +423,39 @@ cr.define('ntp', function() {
|
| // An app to animate (in case it was just installed).
|
| var highlightApp;
|
|
|
| + // If there are any pages after the apps, add new pages before them.
|
| + var lastAppsPage = (this.appsPages.length > 0) ?
|
| + this.appsPages[this.appsPages.length - 1] : null;
|
| + var lastAppsPageIndex = (lastAppsPage != null) ?
|
| + Array.prototype.indexOf.call(this.tilePages, lastAppsPage) : -1;
|
| + var nextPageAfterApps = lastAppsPageIndex != -1 ?
|
| + this.tilePages[lastAppsPageIndex + 1] : null;
|
| +
|
| // Add the apps, creating pages as necessary
|
| - this.appendTilePage(new ntp.AppsPage(),
|
| - loadTimeData.getString('appDefaultPageName'));
|
| for (var i = 0; i < apps.length; i++) {
|
| var app = apps[i];
|
| + var pageIndex = app.page_index || 0;
|
| + while (pageIndex >= this.appsPages.length) {
|
| + var pageName = loadTimeData.getString('appDefaultPageName');
|
| + if (this.appsPages.length < pageNames.length)
|
| + pageName = pageNames[this.appsPages.length];
|
| +
|
| + var origPageCount = this.appsPages.length;
|
| + this.appendTilePage(new ntp.AppsPage(), pageName, nextPageAfterApps);
|
| + // Confirm that appsPages is a live object, updated when a new page is
|
| + // added (otherwise we'd have an infinite loop)
|
| + assert(this.appsPages.length == origPageCount + 1,
|
| + 'expected new page');
|
| + }
|
| +
|
| if (app.id == this.highlightAppId)
|
| highlightApp = app;
|
| else
|
| - this.appsPage.insertApp(app, false);
|
| + this.appsPages[pageIndex].insertApp(app, false);
|
| }
|
|
|
| + this.cardSlider.currentCard = prevCurrentCard;
|
| +
|
| if (highlightApp)
|
| this.appAdded(highlightApp, true);
|
|
|
| @@ -439,6 +463,7 @@ cr.define('ntp', function() {
|
|
|
| // Tell the slider about the pages and mark the current page.
|
| this.updateSliderCards();
|
| + this.cardSlider.currentCardValue.navigationDot.classList.add('selected');
|
|
|
| if (!this.appsLoaded_) {
|
| this.appsLoaded_ = true;
|
| @@ -464,15 +489,24 @@ cr.define('ntp', function() {
|
|
|
| var pageIndex = appData.page_index || 0;
|
|
|
| + if (pageIndex >= this.appsPages.length) {
|
| + while (pageIndex >= this.appsPages.length) {
|
| + this.appendTilePage(new ntp.AppsPage(),
|
| + loadTimeData.getString('appDefaultPageName'));
|
| + }
|
| + this.updateSliderCards();
|
| + }
|
| +
|
| + var page = this.appsPages[pageIndex];
|
| var app = $(appData.id);
|
| if (app) {
|
| app.replaceAppData(appData);
|
| } else if (opt_highlight) {
|
| - this.appsPage.insertAndHighlightApp(appData);
|
| + page.insertAndHighlightApp(appData);
|
| this.setShownPage_(loadTimeData.getInteger('apps_page_id'),
|
| appData.page_index);
|
| } else {
|
| - this.appsPage.insertApp(appData, false);
|
| + page.insertApp(appData, false);
|
| }
|
| },
|
|
|
| @@ -498,15 +532,21 @@ cr.define('ntp', function() {
|
| this.tilePages.length - 1));
|
| this.cardSlider.setCards(Array.prototype.slice.call(this.tilePages),
|
| pageNo);
|
| - switch (this.shownPage) {
|
| - case loadTimeData.getInteger('apps_page_id'):
|
| - this.cardSlider.selectCardByValue(this.appsPage);
|
| - break;
|
| - case loadTimeData.getInteger('most_visited_page_id'):
|
| - if (this.mostVisitedPage)
|
| - this.cardSlider.selectCardByValue(this.mostVisitedPage);
|
| - break;
|
| - }
|
| +
|
| + assert(this.mostVisitedPage, 'Most Visited Page not found');
|
| + // NTP pages are not sticky anymore, so we should always select the Most
|
| + // Visited page when loading the card slider.
|
| + this.cardSlider.selectCardByValue(this.mostVisitedPage);
|
| + },
|
| +
|
| + /**
|
| + * Returns the index of the given apps page.
|
| + * @param {AppsPage} page The AppsPage we wish to find.
|
| + * @return {number} The index of |page| or -1 if it is not in the
|
| + * collection.
|
| + */
|
| + getAppsPageIndex: function(page) {
|
| + return Array.prototype.indexOf.call(this.appsPages, page);
|
| },
|
|
|
| /**
|
| @@ -521,7 +561,8 @@ cr.define('ntp', function() {
|
| // reflect user actions).
|
| if (!this.isStartingUp_()) {
|
| if (page.classList.contains('apps-page')) {
|
| - this.setShownPage_(loadTimeData.getInteger('apps_page_id'), 0);
|
| + this.setShownPage_(loadTimeData.getInteger('apps_page_id'),
|
| + this.getAppsPageIndex(page));
|
| } else if (page.classList.contains('most-visited-page')) {
|
| this.setShownPage_(
|
| loadTimeData.getInteger('most_visited_page_id'), 0);
|
| @@ -680,8 +721,8 @@ cr.define('ntp', function() {
|
| * card-slider-frame, it should be handled here in NewTabView. Otherwise,
|
| * it should be handled in TilePage.
|
| *
|
| - * @param {boolean=} opt_animate Whether the layout should be animated.
|
| - * @param {ntp.TilePage=} opt_page Alternative TilePage to calculate layout.
|
| + * @param {boolean} opt_animate Whether the layout should be animated.
|
| + * @param {ntp.TilePage} opt_page Alternative TilePage to calculate layout.
|
| */
|
| layout: function(opt_animate, opt_page) {
|
| opt_animate = typeof opt_animate == 'undefined' ? false : opt_animate;
|
| @@ -769,16 +810,23 @@ cr.define('ntp', function() {
|
| loadTimeData.getString('mostvisited'));
|
| chrome.send('getMostVisited');
|
|
|
| + var recentlyClosed = new ntp.RecentlyClosedPage();
|
| + newTabView.appendTilePage(recentlyClosed,
|
| + loadTimeData.getString('recentlyclosed'));
|
| + chrome.send('getRecentlyClosedTabs');
|
| +
|
| + var devices = new ntp.OtherDevicesPage();
|
| + newTabView.appendTilePage(devices, loadTimeData.getString('otherSessions'));
|
| + chrome.send('getForeignSessions');
|
| +
|
| doWhenAllSectionsReady(function() {
|
| // Tell the slider about the pages.
|
| newTabView.updateSliderCards();
|
| newTabView.onReady();
|
| -
|
| // Restore the visibility only after calling updateSliderCards to avoid
|
| // flickering, otherwise for a small fraction of a second the Page List is
|
| // partially rendered.
|
| $('bottom-panel').style.visibility = 'visible';
|
| -
|
| if (loadTimeData.valueExists('serverpromo')) {
|
| var promo = loadTimeData.getString('serverpromo');
|
| var tags = ['IMG'];
|
| @@ -952,18 +1000,18 @@ cr.define('ntp', function() {
|
| newTabView.recentlyClosedPage.setDataList(dataList);
|
| }
|
|
|
| - function setMostVisitedPages(dataList, hasBlacklistedUrls) {
|
| + function setMostVisitedPages(data, hasBlacklistedUrls) {
|
| var page = newTabView.mostVisitedPage;
|
| var state = page.getTileRepositioningState();
|
| if (state) {
|
| if (state.isRemoving)
|
| - page.animateTileRemoval(state.index, dataList);
|
| + page.animateTileRemoval(state.index, data);
|
| else
|
| - page.animateTileRestoration(state.index, dataList);
|
| + page.animateTileRestoration(state.index, data);
|
|
|
| page.resetTileRepositioningState();
|
| } else {
|
| - page.setDataList(dataList);
|
| + page.setDataList(data);
|
| cr.dispatchSimpleEvent(document, 'sectionready', true, true);
|
| }
|
| }
|
| @@ -1021,6 +1069,10 @@ cr.define('ntp', function() {
|
| return newTabView.getAppsCallback.apply(newTabView, arguments);
|
| }
|
|
|
| + function getAppsPageIndex() {
|
| + return newTabView.getAppsPageIndex.apply(newTabView, arguments);
|
| + }
|
| +
|
| function getCardSlider() {
|
| return newTabView.cardSlider;
|
| }
|
| @@ -1045,12 +1097,17 @@ cr.define('ntp', function() {
|
| appRemoved: appRemoved,
|
| appsPrefChangeCallback: appsPrefChangeCallback,
|
| getAppsCallback: getAppsCallback,
|
| + getAppsPageIndex: getAppsPageIndex,
|
| getCardSlider: getCardSlider,
|
| getContentWidth: getContentWidth,
|
| getThumbnailUrl: getThumbnailUrl,
|
| incrementHoveredThumbnailCount: incrementHoveredThumbnailCount,
|
| layout: layout,
|
| logTimeToClickAndHoverCount: logTimeToClickAndHoverCount,
|
| + // This property is being used to disable NTP5 features that are not ready
|
| + // yet. Right now this is being used just to disable Apps page.
|
| + // TODO(pedrosimonetti): Remove this property after porting Apps Page.
|
| + ntp5: true,
|
| NtpFollowAction: NtpFollowAction,
|
| onLoad: onLoad,
|
| setAppToBeHighlighted: setAppToBeHighlighted,
|
|
|