Index: chrome/browser/resources/ntp4/page_list_view.js |
diff --git a/chrome/browser/resources/ntp4/page_list_view.js b/chrome/browser/resources/ntp4/page_list_view.js |
index a5065b12ff35217dad3cde04fba1ee714c689a1f..6749145652abd875ad7eb06ba729bb7ef652f910 100644 |
--- a/chrome/browser/resources/ntp4/page_list_view.js |
+++ b/chrome/browser/resources/ntp4/page_list_view.js |
@@ -29,34 +29,36 @@ cr.define('ntp4', function() { |
PageListView.prototype = { |
/** |
- * The CardSlider object to use for changing app pages. |
- * @type {CardSlider|undefined} |
+ * A list of all 'apps-page' elements. |
+ * @type {!NodeList|undefined} |
*/ |
- cardSlider: undefined, |
+ appsPages: undefined, |
/** |
- * The frame div for cardSlider. |
- * @type {!Element|undefined} |
+ * The CardSlider object to use for changing app pages. |
+ * @type {CardSlider|undefined} |
*/ |
- sliderFrame: undefined, |
+ cardSlider: undefined, |
/** |
- * The 'page-list' element. |
+ * The 'dots-list' element. |
* @type {!Element|undefined} |
*/ |
- pageList: undefined, |
+ dotList: undefined, |
/** |
- * A list of all 'tile-page' elements. |
- * @type {!NodeList|undefined} |
+ * EventTracker for managing event listeners for page events. |
+ * @type {!EventTracker} |
*/ |
- tilePages: undefined, |
+ eventTracker: new EventTracker, |
/** |
- * A list of all 'apps-page' elements. |
- * @type {!NodeList|undefined} |
+ * If non-null, this is the ID of the app to highlight to the user the next |
+ * time getAppsCallback runs. "Highlight" in this case means to switch to |
+ * the page and run the new tile animation. |
+ * @type {String} |
*/ |
- appsPages: undefined, |
+ highlightAppId: null, |
/** |
* The Most Visited page. |
@@ -65,10 +67,10 @@ cr.define('ntp4', function() { |
mostVisitedPage: undefined, |
/** |
- * The 'dots-list' element. |
+ * The 'page-list' element. |
* @type {!Element|undefined} |
*/ |
- dotList: undefined, |
+ pageList: undefined, |
/** |
* The left and right paging buttons. |
@@ -78,14 +80,6 @@ cr.define('ntp4', function() { |
pageSwitcherEnd: undefined, |
/** |
- * The 'trash' element. Note that technically this is unnecessary, |
- * JavaScript creates the object for us based on the id. But I don't want |
- * to rely on the ID being the same, and JSCompiler doesn't know about it. |
- * @type {!Element|undefined} |
- */ |
- trash: undefined, |
- |
- /** |
* The type of page that is currently shown. The value is a numerical ID. |
* @type {number} |
*/ |
@@ -99,18 +93,24 @@ cr.define('ntp4', function() { |
shownPageIndex: 0, |
/** |
- * EventTracker for managing event listeners for page events. |
- * @type {!EventTracker} |
+ * The frame div for this.cardSlider. |
+ * @type {!Element|undefined} |
*/ |
- eventTracker: new EventTracker, |
+ sliderFrame: undefined, |
/** |
- * If non-null, this is the ID of the app to highlight to the user the next |
- * time getAppsCallback runs. "Highlight" in this case means to switch to |
- * the page and run the new tile animation. |
- * @type {String} |
+ * A list of all 'tile-page' elements. |
+ * @type {!NodeList|undefined} |
*/ |
- highlightAppId: null, |
+ tilePages: undefined, |
+ |
+ /** |
+ * The 'trash' element. Note that technically this is unnecessary, |
+ * JavaScript creates the object for us based on the id. But I don't want |
+ * to rely on the ID being the same, and JSCompiler doesn't know about it. |
+ * @type {!Element|undefined} |
+ */ |
+ trash: undefined, |
/** |
* Initializes page list view. |
@@ -183,13 +183,104 @@ cr.define('ntp4', function() { |
}, |
/** |
+ * Called by chrome when a new app has been added to chrome or has been |
+ * enabled if previously disabled. |
+ * @param {Object} appData A data structure full of relevant information for |
+ * the app. |
+ */ |
+ appAdded: function(appData, opt_highlight) { |
+ if (appData.id == this.highlightAppId) { |
+ opt_highlight = true; |
+ this.highlightAppId = null; |
+ } |
+ |
+ var pageIndex = appData.page_index || 0; |
+ this.ensureAppsPageAtIndex_(pageIndex); |
+ |
+ var page = this.appsPages[pageIndex]; |
+ var app = $(appData.id); |
+ if (app) |
+ app.replaceAppData(appData); |
+ else |
+ page.appendApp(appData, opt_highlight); |
+ }, |
+ |
+ /** |
+ * Called by chrome when an existing app has been disabled or |
+ * removed/uninstalled from chrome. |
+ * @param {Object} appData A data structure full of relevant information for |
+ * the app. |
+ * @param {boolean} isUninstall True if the app is being uninstalled; |
+ * false if the app is being disabled. |
+ */ |
+ appRemoved: function(appData, isUninstall, fromPage) { |
+ var app = $(appData.id); |
+ assert(app, 'trying to remove an app that doesn\'t exist'); |
+ |
+ if (!isUninstall) { |
+ app.replaceAppData(appData); |
+ } else { |
+ // Unset the ID immediately, because the app is already gone. But leave |
+ // the tile on the page as it animates out. |
+ app.id = ''; |
+ // If the uninstall was from this page, run the blipout animation and |
+ // remove the tile in the webkitAnimationEnd handler in apps_page.js. |
+ // Otherwise delete the tile without auto-deleting the page to avoid |
+ // re-deleting the same page (or the page that slid in to take its |
+ // place). |
+ if (fromPage) { |
+ app.classList.add('removing-tile-contents'); |
+ } else { |
+ var tilePage = app.tile.tilePage; |
+ app.tile.remove(false, true); |
+ this.removeAppsPageIfEmpty(tilePage, false, true); |
+ } |
+ } |
+ }, |
+ |
+ /** |
+ * Re-order apps on this invactive page when an active NTP gets re-ordered. |
+ * @param {Object} data Position hashmap ordered by app id with indices: |
+ * {id => {page_index: ##, app_launch_index: ##}} |
+ */ |
+ appsReordered: function(data) { |
+ var pages = Object.keys(data); |
+ for (var i = 0; i < pages.length; ++i) { |
+ var page = data[pages[i]]; |
+ var indices = Object.keys(page); |
+ for (var j = 0; j < indices.length; ++j) { |
+ var app = $(page[indices[j]]); |
+ if (i != this.getAppsPageIndex(app.tile.tilePage) || |
+ j != app.tile.index) { |
+ var tile = app.tile.remove(false, true); |
+ this.ensureAppsPageAtIndex_(i); |
+ var appsPage = this.appsPages[i]; |
+ appsPage.addTileAt(tile.firstChild, j); |
+ if (appsPage.classList.contains('selected-card')) |
+ app.loadIcon(); |
+ } |
+ } |
+ } |
+ for (var i = 0; i < this.appsPages.length; ++i) { |
+ // If a page is now empty, remove it and move backward one in our |
+ // array-like object as it is a live NodeList and the length/indice |
+ // change when you update it. Otherwise, reuse cleanupDrag() to |
+ // re-position the tiles like when a user is done dragging. |
+ if (this.removeAppsPageIfEmpty(this.appsPages[i], false, true)) |
+ --i; |
+ else |
+ this.appsPages[i].cleanupDrag(); |
+ } |
+ }, |
+ |
+ /** |
* Appends a tile page. |
* |
* @param {TilePage} page The page element. |
* @param {string} title The title of the tile page. |
* @param {bool} titleIsEditable If true, the title can be changed. |
* @param {TilePage} opt_refNode Optional reference node to insert in front |
Evan Stade
2011/12/02 00:53:24
never end your sentences in a preposition. This sh
Dan Beam
2011/12/02 01:25:11
I read this part too late, damn it, lol.
"I need
|
- * of. |
+ * of. |
* When opt_refNode is falsey, |page| will just be appended to the end of |
* the page list. |
*/ |
@@ -197,6 +288,21 @@ cr.define('ntp4', function() { |
// When opt_refNode is falsey, insertBefore acts just like appendChild. |
this.pageList.insertBefore(page, opt_refNode); |
+ if (!document.documentElement.classList.contains('starting-up')) { |
+ // If we're inserting a card in front of the current card, add 1 to the |
+ // current index to adjust for the new card in the order. |
+ var index = Array.prototype.indexOf.call(this.tilePages, page); |
+ if (typeof this.cardSlider.currentCard != 'undefined' && |
+ index <= this.cardSlider.currentCard) { |
+ this.cardSlider.currentCard += 1; |
+ } |
+ if (page instanceof ntp4.AppsPage && |
+ this.shownPage == templateData['apps_page_id'] && |
+ this.getAppsPageIndex(page) <= this.shownPageIndex) { |
+ this.shownPageIndex += 1; |
+ } |
+ } |
+ |
// Remember special MostVisitedPage. |
if (typeof ntp4.MostVisitedPage != 'undefined' && |
page instanceof ntp4.MostVisitedPage) { |
@@ -221,21 +327,90 @@ cr.define('ntp4', function() { |
}, |
/** |
- * Called by chrome when an existing app has been disabled or |
- * removed/uninstalled from chrome. |
- * @param {Object} appData A data structure full of relevant information for |
- * the app. |
- * @param {boolean} isUninstall True if the app is being uninstalled; |
- * false if the app is being disabled. |
+ * Callback invoked by chrome whenever an app preference changes. |
+ * @param {Object} data An object with all the data on available |
+ * applications. |
*/ |
- appRemoved: function(appData, isUninstall) { |
- var app = $(appData.id); |
- assert(app, 'trying to remove an app that doesn\'t exist'); |
+ appsPrefChangedCallback: function(data) { |
+ for (var i = 0; i < data.apps.length; ++i) { |
+ var el = $(data.apps[i].id); |
+ // There won't be an element when the temporary page is first saved on a |
+ // drop on a new apps page. |
+ if (el) |
+ el.appData = data.apps[i]; |
+ } |
- if (!isUninstall) |
- app.replaceAppData(appData); |
- else |
- app.remove(); |
+ // Set the App dot names. Skip dots that don't belong to apps pages. |
+ var dots = this.dotList.getElementsByClassName('dot'); |
+ var firstAppDot = this.getTilePageIndex(this.appsPages[0]); |
+ for (var i = 0; i < this.appsPages.length; ++i) { |
+ dots[firstAppDot + i].displayTitle = data.appsPageNames[i] || ''; |
+ } |
+ }, |
+ |
+ /** |
+ * Handler for CARD_CHANGED on cardSlider. |
+ * @param {Event} e The CARD_CHANGED event. |
+ * @private |
+ */ |
+ cardChangedHandler_: function(e) { |
+ var page = e.cardSlider.currentCardValue; |
+ |
+ // Don't change shownPage until startup is done (and page changes actually |
+ // reflect user actions). |
+ if (!document.documentElement.classList.contains('starting-up')) { |
+ var prevPage = this.shownPage; |
+ var prevIndex = this.shownPageIndex; |
+ if (page.classList.contains('apps-page')) { |
+ this.shownPage = templateData['apps_page_id']; |
+ this.shownPageIndex = this.getAppsPageIndex(page); |
+ } else if (page.classList.contains('most-visited-page')) { |
+ this.shownPage = templateData['most_visited_page_id']; |
+ this.shownPageIndex = 0; |
+ } else { |
+ console.error('unknown page selected'); |
+ } |
+ if (prevPage != this.shownPage || prevIndex != this.shownPageIndex) |
+ chrome.send('pageSelected', [this.shownPage, this.shownPageIndex]); |
+ } |
+ |
+ // Update the active dot |
+ var curDot = this.dotList.getElementsByClassName('selected')[0]; |
+ if (curDot) |
+ curDot.classList.remove('selected'); |
+ page.navigationDot.classList.add('selected'); |
+ this.updatePageSwitchers(); |
+ }, |
+ |
+ /** |
+ * Ensure there is an apps page at the given |index|. If index is smaller |
+ * than the current number of apps pages, additional apps pages will be |
+ * created. |
+ * @param {number} index An apps page index to ensure exists. |
+ */ |
+ ensureAppsPageAtIndex_: function(index) { |
+ if (index >= this.appsPages.length) { |
+ var pageName = localStrings.getString('appDefaultPageName'); |
+ while (index >= this.appsPages.length) |
+ this.appendTilePage(new ntp4.AppsPage(), pageName, true); |
+ this.updateSliderCards(); |
+ } |
+ }, |
+ |
+ /** |
+ * Called whenever tiles should be re-arranging themselves out of the way |
+ * of a moving or insert tile. |
+ */ |
+ enterRearrangeMode: function() { |
+ var tempPage = new ntp4.AppsPage(); |
+ tempPage.classList.add('temporary'); |
+ var pageName = localStrings.getString('appDefaultPageName'); |
+ this.appendTilePage(tempPage, pageName, true); |
+ this.updateSliderCards(); |
+ this.updatePageSwitchers(); |
+ |
+ if (ntp4.getCurrentlyDraggingTile().firstChild.canBeRemoved()) |
+ $('footer').classList.add('showing-trash-mode'); |
}, |
/** |
@@ -257,19 +432,16 @@ cr.define('ntp4', function() { |
// uninstall. |
while (this.appsPages.length > 0) { |
var page = this.appsPages[0]; |
- var dot = page.navigationDot; |
this.eventTracker.remove(page); |
- page.tearDown(); |
- page.parentNode.removeChild(page); |
- dot.parentNode.removeChild(dot); |
+ this.removeTilePage(page); |
} |
// 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; |
+ var pageNames = data.appsPageNames; |
function stringListIsEmpty(list) { |
for (var i = 0; i < list.length; i++) { |
@@ -326,115 +498,84 @@ cr.define('ntp4', function() { |
}, |
/** |
- * Called by chrome when a new app has been added to chrome or has been |
- * enabled if previously disabled. |
- * @param {Object} appData A data structure full of relevant information for |
- * the app. |
+ * 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. |
*/ |
- appAdded: function(appData, opt_highlight) { |
- if (appData.id == this.highlightAppId) { |
- opt_highlight = true; |
- this.highlightAppId = null; |
- } |
- |
- var pageIndex = appData.page_index || 0; |
- |
- if (pageIndex >= this.appsPages.length) { |
- while (pageIndex >= this.appsPages.length) { |
- this.appendTilePage(new ntp4.AppsPage(), |
- localStrings.getString('appDefaultPageName'), |
- true); |
- } |
- this.updateSliderCards(); |
- } |
- |
- var page = this.appsPages[pageIndex]; |
- var app = $(appData.id); |
- if (app) |
- app.replaceAppData(appData); |
- else |
- page.appendApp(appData, opt_highlight); |
+ getAppsPageIndex: function(page) { |
+ return Array.prototype.indexOf.call(this.appsPages, page); |
}, |
/** |
- * Callback invoked by chrome whenever an app preference changes. |
- * @param {Object} data An object with all the data on available |
- * applications. |
+ * Returns the index of a given tile page. |
+ * @param {TilePage} page The TilePage we wish to find. |
+ * @return {number} The index of |page| or -1 if it is not in the |
+ * collection. |
*/ |
- appsPrefChangedCallback: function(data) { |
- for (var i = 0; i < data.apps.length; ++i) { |
- $(data.apps[i].id).appData = data.apps[i]; |
- } |
- |
- // Set the App dot names. Skip the first dot (Most Visited). |
- var dots = this.dotList.getElementsByClassName('dot'); |
- var start = this.mostVisitedPage ? 1 : 0; |
- for (var i = start; i < dots.length; ++i) { |
- dots[i].displayTitle = data.appPageNames[i - start] || ''; |
- } |
+ getTilePageIndex: function(page) { |
+ return Array.prototype.indexOf.call(this.tilePages, page); |
}, |
/** |
- * Invoked whenever the pages in apps-page-list have changed so that |
- * the Slider knows about the new elements. |
+ * Invoked whenever some app is released |
*/ |
- updateSliderCards: function() { |
- var pageNo = Math.min(this.cardSlider.currentCard, |
- this.tilePages.length - 1); |
- this.cardSlider.setCards(Array.prototype.slice.call(this.tilePages), |
- pageNo); |
- switch (this.shownPage) { |
- case templateData['apps_page_id']: |
- this.cardSlider.selectCardByValue( |
- this.appsPages[Math.min(this.shownPageIndex, |
- this.appsPages.length - 1)]); |
- break; |
- case templateData['most_visited_page_id']: |
- if (this.mostVisitedPage) |
- this.cardSlider.selectCardByValue(this.mostVisitedPage); |
- break; |
+ leaveRearrangeMode: function() { |
+ var tempPage = document.querySelector('.tile-page.temporary'); |
+ // If there's a temp page and it wasn't removed for being empty. |
+ if (tempPage && !this.removeAppsPageIfEmpty(tempPage, true)) { |
+ this.saveAppsPageName(tempPage, tempPage.navigationDot.displayTitle); |
+ tempPage.classList.remove('temporary'); |
} |
+ |
+ $('footer').classList.remove('showing-trash-mode'); |
}, |
/** |
- * Called whenever tiles should be re-arranging themselves out of the way |
- * of a moving or insert tile. |
+ * Move to a non-empty page before/while we delete an empty one. |
+ * @param {Element} appsPage An empty apps page that we want to move off of |
+ * (probably because it's empty). |
+ * @param {=boolean} animate Whether we should animate or not. |
+ * @param {=function} callback A callback to be executed when the move is |
+ * done. |
*/ |
- enterRearrangeMode: function() { |
- var tempPage = new ntp4.AppsPage(); |
- tempPage.classList.add('temporary'); |
- this.appendTilePage(tempPage, |
- localStrings.getString('appDefaultPageName'), |
- true); |
- var tempIndex = Array.prototype.indexOf.call(this.tilePages, tempPage); |
- if (this.cardSlider.currentCard >= tempIndex) |
- this.cardSlider.currentCard += 1; |
- this.updateSliderCards(); |
- |
- if (ntp4.getCurrentlyDraggingTile().firstChild.canBeRemoved()) |
- $('footer').classList.add('showing-trash-mode'); |
+ moveOffEmptyAppsPage: function(appsPage, opt_animate, opt_callback) { |
+ assert(appsPage instanceof ntp4.AppsPage, |
+ '|appsPage| is really an AppsPage'); |
+ // Select the page further toward the end than the empty |appsPage|. If |
+ // the empty |appsPage| is at the end, the apps page before it will be |
+ // selected. |
+ var index = this.getAppsPageIndex(appsPage); |
+ assert(index >= 0, '|appsPage| is in this.appsPages'); |
+ var direction = (index == this.appsPages.length - 1 ? -1 : 1); |
+ this.cardSlider.selectCard(this.cardSlider.currentCard + direction, |
+ opt_animate, opt_callback); |
}, |
/** |
- * Invoked whenever some app is released |
+ * Handler for key events on the page. Ctrl-Arrow will switch the visible |
+ * page. |
+ * @param {Event} e The KeyboardEvent. |
+ * @private |
*/ |
- leaveRearrangeMode: function() { |
- var tempPage = document.querySelector('.tile-page.temporary'); |
- var dot = tempPage.navigationDot; |
- if (!tempPage.tileCount && tempPage != this.cardSlider.currentCardValue) { |
- dot.animateRemove(); |
- var tempIndex = Array.prototype.indexOf.call(this.tilePages, tempPage); |
- if (this.cardSlider.currentCard > tempIndex) |
- this.cardSlider.currentCard -= 1; |
- tempPage.parentNode.removeChild(tempPage); |
- this.updateSliderCards(); |
- } else { |
- tempPage.classList.remove('temporary'); |
- this.saveAppPageName(tempPage, |
- localStrings.getString('appDefaultPageName')); |
- } |
+ onDocKeyDown_: function(e) { |
+ if (!e.ctrlKey || e.altKey || e.metaKey || e.shiftKey) |
+ return; |
- $('footer').classList.remove('showing-trash-mode'); |
+ var direction = 0; |
+ if (e.keyIdentifier == 'Left') |
+ direction = -1; |
+ else if (e.keyIdentifier == 'Right') |
+ direction = 1; |
+ else |
+ return; |
+ |
+ var cardIndex = |
+ (this.cardSlider.currentCard + direction + |
+ this.cardSlider.cardCount) % this.cardSlider.cardCount; |
+ this.cardSlider.selectCard(cardIndex, true); |
+ |
+ e.stopPropagation(); |
}, |
/** |
@@ -451,6 +592,84 @@ cr.define('ntp4', function() { |
}, |
/** |
+ * Window resize handler. |
+ * @private |
+ */ |
+ onWindowResize_: function(e) { |
+ this.cardSlider.resize(this.sliderFrame.offsetWidth); |
+ this.updatePageSwitchers(); |
+ }, |
+ |
+ /** |
+ * Utility function to remove both a tile page and corresponding nav dot. |
+ * NOTE: If |animated| is true, this function will return before the |
+ * animation is finished. |
+ * @param {Element} appsPage An apps page to be removed if it has no tiles. |
+ * @param {=boolean} opt_animate An optional param to animate the removal. |
+ * @param {=boolean} opt_dontSave Whether we should notify other NTPs this |
+ * page was deleted (defaults to yes). |
+ * @returns {boolean} If the page was removed. |
+ */ |
+ removeAppsPageIfEmpty: function(appsPage, opt_animate, opt_dontSave) { |
+ if (appsPage && appsPage.tileCount === 0) { |
+ var whenDone = function() { |
+ if (!opt_dontSave) { |
+ chrome.send('deleteAppsPage', |
+ [this.getAppsPageIndex(appsPage), |
+ appsPage.classList.contains('temporary')]); |
+ } |
+ this.removeTilePage(appsPage, opt_animate); |
+ this.updateSliderCards(); |
+ this.updatePageSwitchers(); |
+ }; |
+ if (appsPage == this.cardSlider.currentCardValue) |
+ this.moveOffEmptyAppsPage(appsPage, opt_animate, whenDone.bind(this)); |
+ else |
+ whenDone.call(this); |
+ return true; |
+ } |
+ return false; |
+ }, |
+ |
+ /** |
+ * Removes a page and navigation dot (if the navdot exists). |
+ * @param {Element} page The page to be removed. |
+ * @param {boolean} animate If the removal should be animated. |
+ */ |
+ removeTilePage: function(page, animate) { |
+ if (!document.documentElement.classList.contains('starting-up')) { |
+ // If the card being deleted is before the current card, keep the same |
+ // spot in the list by removing 1 from the current card index. |
+ var index = Array.prototype.indexOf.call(this.tilePages, page); |
+ if (index < this.cardSlider.currentCard) { |
+ this.cardSlider.currentCard -= 1; |
+ } |
+ // If the page we're about to delete is in front of the current page, |
+ // remove 1 from the shown page index. |
+ if (page instanceof ntp4.AppsPage && |
+ this.shownPage == templateData['apps_page_id'] && |
+ this.getAppsPageIndex(page) < this.shownPageIndex) { |
+ this.shownPageIndex -= 1; |
+ } |
+ } |
+ if (page.navigationDot) |
+ page.navigationDot.remove(animate); |
+ page.remove(); |
+ }, |
+ |
+ /* |
+ * Save the name of an app page. |
+ * Store the app page name into the preferences store. |
+ * @param {AppsPage} appsPage The app page for which we wish to save. |
+ * @param {string} name The name of the page. |
+ */ |
+ saveAppsPageName: function(appsPage, name) { |
+ var index = this.getAppsPageIndex(appsPage); |
+ assert(index != -1); |
+ chrome.send('saveAppsPageName', [name, index]); |
+ }, |
+ |
+ /** |
* Adjusts the size and position of the page switchers according to the |
* layout of the current card. |
*/ |
@@ -488,64 +707,40 @@ cr.define('ntp4', function() { |
}, |
/** |
- * Returns the index of the given page. |
- * @param {AppsPage} page The AppsPage for we wish to find. |
- * @return {number} The index of |page|, or -1 if it is not here. |
- */ |
- getAppsPageIndex: function(page) { |
- return Array.prototype.indexOf.call(this.appsPages, page); |
- }, |
- |
- /** |
- * Handler for CARD_CHANGED on cardSlider. |
- * @param {Event} e The CARD_CHANGED event. |
- * @private |
+ * Invoked whenever the pages in apps-page-list have changed so that |
+ * the Slider knows about the new elements. |
*/ |
- cardChangedHandler_: function(e) { |
- var page = e.cardSlider.currentCardValue; |
- |
- // Don't change shownPage until startup is done (and page changes actually |
- // reflect user actions). |
- if (!document.documentElement.classList.contains('starting-up')) { |
- if (page.classList.contains('apps-page')) { |
- this.shownPage = templateData['apps_page_id']; |
- this.shownPageIndex = this.getAppsPageIndex(page); |
- } else if (page.classList.contains('most-visited-page')) { |
- this.shownPage = templateData['most_visited_page_id']; |
- this.shownPageIndex = 0; |
- } else { |
- console.error('unknown page selected'); |
- } |
- chrome.send('pageSelected', [this.shownPage, this.shownPageIndex]); |
+ updateSliderCards: function() { |
+ var index = -1; |
+ var prevPage = this.shownPage; |
+ var prevIndex = this.shownPageIndex; |
+ var tiles = Array.prototype.slice.call(this.tilePages); |
+ // It doesn't hurt to clamp value this every time, even if it's only |
+ // applicable to apps. It helps self-heal strange / un-expected data, i.e. |
+ // going from an apps page to the most visited page directly without |
+ // setting this.shownPageIndex = 0 somehow. |
+ this.shownPageIndex = Math.max(0, Math.min(this.shownPageIndex, |
+ this.appsPages.length - 1)); |
+ switch (this.shownPage) { |
+ case templateData['apps_page_id']: |
+ index = tiles.indexOf(this.appsPages[this.shownPageIndex]); |
+ break; |
+ case templateData['most_visited_page_id']: |
+ index = tiles.indexOf(this.mostVisitedPage); |
+ break; |
} |
- |
- // Update the active dot |
- var curDot = this.dotList.getElementsByClassName('selected')[0]; |
- if (curDot) |
- curDot.classList.remove('selected'); |
- page.navigationDot.classList.add('selected'); |
- this.updatePageSwitchers(); |
- }, |
- |
- /* |
- * Save the name of an app page. |
- * Store the app page name into the preferences store. |
- * @param {AppsPage} appPage The app page for which we wish to save. |
- * @param {string} name The name of the page. |
- */ |
- saveAppPageName: function(appPage, name) { |
- var index = this.getAppsPageIndex(appPage); |
- assert(index != -1); |
- chrome.send('saveAppPageName', [name, index]); |
- }, |
- |
- /** |
- * Window resize handler. |
- * @private |
- */ |
- onWindowResize_: function(e) { |
- this.cardSlider.resize(this.sliderFrame.offsetWidth); |
- this.updatePageSwitchers(); |
+ // If shownPage was saved as a page that's now disabled or the shownPage |
+ // doesn't exist any more, index will be -1. Change to the preferred |
+ // default page (first apps pane) in this case. |
+ if (index < 0) { |
+ this.shownPage = templateData['apps_page_id']; |
+ index = tiles.indexOf(this.appsPages[0]); |
+ } |
+ // Set the new cards and index. |
+ this.cardSlider.setCards(tiles, index); |
+ // If we got new page or index, update the pref. |
+ if (prevIndex != this.shownPageIndex || prevPage != this.shownPage) |
+ chrome.send('pageSelected', [this.shownPage, this.shownPageIndex]); |
}, |
/** |
@@ -562,32 +757,6 @@ cr.define('ntp4', function() { |
} |
} |
}, |
- |
- /** |
- * Handler for key events on the page. Ctrl-Arrow will switch the visible |
- * page. |
- * @param {Event} e The KeyboardEvent. |
- * @private |
- */ |
- onDocKeyDown_: function(e) { |
- if (!e.ctrlKey || e.altKey || e.metaKey || e.shiftKey) |
- return; |
- |
- var direction = 0; |
- if (e.keyIdentifier == 'Left') |
- direction = -1; |
- else if (e.keyIdentifier == 'Right') |
- direction = 1; |
- else |
- return; |
- |
- var cardIndex = |
- (this.cardSlider.currentCard + direction + |
- this.cardSlider.cardCount) % this.cardSlider.cardCount; |
- this.cardSlider.selectCard(cardIndex, true); |
- |
- e.stopPropagation(); |
- } |
}; |
return { |