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 |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a23dd520436d093ad65f188281eb85bc1de94e1e |
--- /dev/null |
+++ b/chrome/browser/resources/ntp4/page_list_view.js |
@@ -0,0 +1,734 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @fileoverview PageListView implementation. |
+ * PageListView manages page list, dot list, switcher buttons and glue apps |
+ * pages with backend. |
+ */ |
+ |
+cr.define('ntp4', function() { |
+ 'use strict'; |
+ |
+ /** |
+ * Object for accessing localized strings. |
+ * @type {!LocalStrings} |
+ */ |
+ var localStrings = new LocalStrings; |
+ |
+ /** |
+ * Current live PageListView instance. |
+ * @type {!Object|undefined} |
+ */ |
+ var instance; |
Evan Stade
2011/11/07 23:59:20
I don't like the restriction that this class shoul
xiyuan
2011/11/08 21:09:18
Done.
|
+ |
+ /** |
+ * Creates a PageListView object. |
+ * @constructor |
+ * @extends {Object} |
+ */ |
+ function PageListView() { |
+ } |
+ |
+ PageListView.getInstance = function() { |
+ return instance; |
+ } |
+ |
+ PageListView.prototype = { |
+ /** |
+ * The CardSlider object to use for changing app pages. |
+ * @type {CardSlider|undefined} |
+ */ |
+ cardSlider: undefined, |
+ |
+ /** |
+ * The frame div for cardSlider. |
+ * @type {!Element|undefined} |
+ */ |
+ sliderFrame: undefined, |
+ |
+ /** |
+ * The 'page-list' element. |
+ * @type {!Element|undefined} |
+ */ |
+ pageList: undefined, |
+ |
+ /** |
+ * A list of all 'tile-page' elements. |
+ * @type {!NodeList|undefined} |
+ */ |
+ tilePages: undefined, |
+ |
+ /** |
+ * A list of all 'apps-page' elements. |
+ * @type {!NodeList|undefined} |
+ */ |
+ appsPages: undefined, |
+ |
+ /** |
+ * The Most Visited page. |
+ * @type {!Element|undefined} |
+ */ |
+ mostVisitedPage: undefined, |
+ |
+ /** |
+ * The Bookmarks page. |
+ * @type {!Element|undefined} |
+ */ |
+ bookmarksPage: undefined, |
+ |
+ /** |
+ * The 'dots-list' element. |
+ * @type {!Element|undefined} |
+ */ |
+ dotList: undefined, |
+ |
+ /** |
+ * The left and right paging buttons. |
+ * @type {!Element|undefined} |
+ */ |
+ pageSwitcherStart: undefined, |
+ 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} |
+ */ |
+ shownPage: 0, |
+ |
+ /** |
+ * The index of the page that is currently shown, within the page type. |
+ * For example if the third Apps page is showing, this will be 2. |
+ * @type {number} |
+ */ |
+ shownPageIndex: 0, |
+ |
+ /** |
+ * EventTracker for managing event listeners for page events. |
+ * @type {!EventTracker} |
+ */ |
+ eventTracker: new EventTracker, |
+ |
+ /** |
+ * 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} |
+ */ |
+ highlightAppId: null, |
+ |
+ /** |
+ * Initializes page list view. |
+ */ |
+ initialize: function() { |
+ instance = this; |
+ |
+ this.pageList = getRequiredElement('page-list'); |
+ |
+ this.dotList = getRequiredElement('dot-list'); |
+ cr.ui.decorate(this.dotList, ntp4.DotList); |
+ |
+ this.trash = getRequiredElement('trash'); |
+ new ntp4.Trash(this.trash); |
+ |
+ this.pageSwitcherStart = $('page-switcher-start'); |
+ if (this.pageSwitcherStart) |
+ ntp4.initializePageSwitcher(this.pageSwitcherStart); |
+ |
+ this.pageSwitcherEnd = $('page-switcher-end'); |
+ if (this.pageSwitcherEnd) |
+ ntp4.initializePageSwitcher(this.pageSwitcherEnd); |
+ |
+ this.shownPage = templateData['shown_page_type']; |
+ this.shownPageIndex = templateData['shown_page_index']; |
+ |
+ // 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'); |
+ |
+ document.addEventListener('keydown', this.onDocKeyDown.bind(this)); |
+ // Prevent touch events from triggering any sort of native scrolling |
+ document.addEventListener('touchmove', function(e) { |
+ e.preventDefault(); |
+ }, true); |
+ |
+ 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 = getRequiredElement('card-slider-frame'); |
+ this.cardSlider = new CardSlider(this.sliderFrame, this.pageList, |
+ this.sliderFrame.offsetWidth); |
+ this.cardSlider.initialize(); |
+ |
+ // Ensure the slider is resized appropriately with the window |
+ window.addEventListener('resize', this.onWindowResize_.bind(this)); |
+ |
+ // Handle the page being changed |
+ this.pageList.addEventListener( |
+ CardSlider.EventType.CARD_CHANGED, |
+ this.cardChangedHandler.bind(this)); |
+ }, |
+ |
+ /** |
+ * Appends a tile page (for bookmarks or most visited). |
+ * |
+ * @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 |
+ * of. |
+ * When opt_refNode is falsey, |page| will just be appended to the end of |
+ * the page list. |
+ */ |
+ appendTilePage: function(page, title, titleIsEditable, opt_refNode) { |
+ // If no opt_refNode given, use bookmarksPage (if any). |
+ if (!opt_refNode) |
+ opt_refNode = this.bookmarksPage; |
+ |
+ // When opt_refNode is falsey, insertBefore acts just like appendChild. |
+ this.pageList.insertBefore(page, opt_refNode); |
+ |
+ // Remember special MostVisitedPage and BookmarksPage. |
+ if (typeof ntp4.MostVisitedPage != 'undefined' && |
+ page instanceof ntp4.MostVisitedPage) { |
+ assert(this.tilePages.length == 1, |
+ 'MostVisitedPage should be added as first tile page'); |
+ this.mostVisitedPage = page; |
+ } |
+ if (typeof ntp4.BookmarksPage != 'undefined' && |
+ page instanceof ntp4.BookmarksPage) { |
+ this.bookmarksPage = page; |
+ } |
+ |
+ // If we're appending an AppsPage and it's a temporary page, animate it. |
+ var animate = page instanceof ntp4.AppsPage && |
+ page.classList.contains('temporary'); |
+ // Make a deep copy of the dot template to add a new one. |
+ var newDot = new ntp4.NavDot(page, title, titleIsEditable, animate); |
+ page.navigationDot = newDot; |
+ this.dotList.insertBefore(newDot, opt_refNode ? opt_refNode.navigationDot |
+ : null); |
+ // Set a tab index on the first dot. |
+ if (this.dotList.dots.length == 1) |
+ newDot.tabIndex = 3; |
+ |
+ this.eventTracker.add(page, 'pagelayout', this.onPageLayout_.bind(this)); |
+ }, |
+ |
+ /** |
+ * Callback invoked by chrome with the apps available. |
+ * |
+ * Note that calls to this function can occur at any time, not just in |
+ * response to a getApps request. For example, when a user |
+ * installs/uninstalls an app on another synchronized devices. |
+ * @param {Object} data An object with all the data on available |
+ * applications. |
+ */ |
+ getAppsCallback: function(data) { |
+ var startTime = Date.now(); |
+ |
+ // 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) { |
+ var page = this.appsPages[0]; |
+ var dot = page.navigationDot; |
+ |
+ this.eventTracker.remove(page); |
+ page.tearDown(); |
+ page.parentNode.removeChild(page); |
+ dot.parentNode.removeChild(dot); |
+ } |
+ |
+ // 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; |
+ |
+ function stringListIsEmpty(list) { |
+ for (var i = 0; i < list.length; i++) { |
+ if (list[i]) |
+ return false; |
+ } |
+ return true; |
+ } |
+ |
+ // Sort by launch index |
+ apps.sort(function(a, b) { |
+ return a.app_launch_index - b.app_launch_index; |
+ }); |
+ |
+ // An app to animate (in case it was just installed). |
+ var highlightApp; |
+ |
+ // Add the apps, creating pages as necessary |
+ 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 = localStrings.getString('appDefaultPageName'); |
+ if (this.appsPages.length < pageNames.length) |
+ pageName = pageNames[this.appsPages.length]; |
+ |
+ var origPageCount = this.appsPages.length; |
+ this.appendTilePage(new ntp4.AppsPage(), pageName, true); |
+ // 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.appsPages[pageIndex].appendApp(app); |
+ } |
+ |
+ ntp4.AppsPage.setPromo(data.showPromo ? data : null); |
+ |
+ // Tell the slider about the pages. |
+ this.updateSliderCards(); |
+ |
+ if (highlightApp) |
+ this.appAdded(highlightApp, true); |
+ |
+ // Mark the current page. |
+ this.cardSlider.currentCardValue.navigationDot.classList.add('selected'); |
+ logEvent('apps.layout: ' + (Date.now() - startTime)); |
+ |
+ document.documentElement.classList.remove('starting-up'); |
+ }, |
+ |
+ /** |
+ * 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; |
+ |
+ 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); |
+ }, |
+ |
+ /** |
+ * Callback invoked by chrome whenever an app preference changes. |
+ * @param {Object} data An object with all the data on available |
+ * applications. |
+ */ |
+ appsPrefChangeCallback: 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 and last dots (Most Visited and |
+ // Bookmarks). |
+ var dots = this.dotList.getElementsByClassName('dot'); |
+ // TODO(csilv): Remove this calcluation if/when we remove the flag for |
+ // for the bookmarks page. |
+ var start = this.mostVisitedPage ? 1 : 0; |
+ var length = this.bookmarksPage ? dots.length - 1 : dots.length; |
+ for (var i = start; i < length; ++i) { |
+ dots[i].displayTitle = data.appPageNames[i - start] || ''; |
+ } |
+ }, |
+ |
+ /** |
+ * Invoked whenever the pages in apps-page-list have changed so that |
+ * the Slider knows about the new elements. |
+ */ |
+ 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['bookmarks_page_id']: |
+ if (this.bookmarksPage) |
+ this.cardSlider.selectCardByValue(this.bookmarksPage); |
+ break; |
+ case templateData['most_visited_page_id']: |
+ if (this.mostVisitedPage) |
+ this.cardSlider.selectCardByValue(this.mostVisitedPage); |
+ break; |
+ } |
+ }, |
+ |
+ /** |
+ * 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'); |
+ 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'); |
+ }, |
+ |
+ /** |
+ * Invoked whenever some app is released |
+ * @param {Grabber.Event} e The Grabber RELEASE event. |
+ */ |
+ leaveRearrangeMode: function(e) { |
+ 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')); |
+ } |
+ |
+ $('footer').classList.remove('showing-trash-mode'); |
+ }, |
+ |
+ /** |
+ * Callback for the 'pagelayout' event. |
+ * @param {Event} e The event. |
+ */ |
+ onPageLayout_: function(e) { |
+ if (Array.prototype.indexOf.call(this.tilePages, e.currentTarget) != |
+ this.cardSlider.currentCard) { |
+ return; |
+ } |
+ |
+ this.updatePageSwitchers(); |
+ }, |
+ |
+ /** |
+ * Adjusts the size and position of the page switchers according to the |
+ * layout of the current card. |
+ */ |
+ updatePageSwitchers: function() { |
+ if (!this.pageSwitcherStart || !this.pageSwitcherEnd) |
+ return; |
+ |
+ var page = this.cardSlider.currentCardValue; |
+ |
+ this.pageSwitcherStart.hidden = !page || |
+ (this.cardSlider.currentCard == 0); |
+ this.pageSwitcherEnd.hidden = !page || |
+ (this.cardSlider.currentCard == this.cardSlider.cardCount - 1); |
+ |
+ if (!page) |
+ return; |
+ |
+ var pageSwitcherLeft = isRTL() ? this.pageSwitcherEnd |
+ : this.pageSwitcherStart; |
+ var pageSwitcherRight = isRTL() ? this.pageSwitcherStart |
+ : this.pageSwitcherEnd; |
+ var scrollbarWidth = page.scrollbarWidth; |
+ pageSwitcherLeft.style.width = |
+ (page.sideMargin + 13) + 'px'; |
+ pageSwitcherLeft.style.left = '0'; |
+ pageSwitcherRight.style.width = |
+ (page.sideMargin - scrollbarWidth + 13) + 'px'; |
+ pageSwitcherRight.style.right = scrollbarWidth + 'px'; |
+ |
+ var offsetTop = page.querySelector('.tile-page-content').offsetTop + 'px'; |
+ pageSwitcherLeft.style.top = offsetTop; |
+ pageSwitcherRight.style.top = offsetTop; |
+ pageSwitcherLeft.style.paddingBottom = offsetTop; |
+ pageSwitcherRight.style.paddingBottom = offsetTop; |
+ }, |
+ |
+ /** |
+ * 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. |
+ */ |
+ 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 if (page.classList.contains('bookmarks-page')) { |
+ this.shownPage = templateData['bookmarks_page_id']; |
+ this.shownPageIndex = 0; |
+ } else { |
+ console.error('unknown page selected'); |
+ } |
+ 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(); |
+ }, |
+ |
+ /* |
+ * 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(); |
+ }, |
+ |
+ /** |
+ * Handler for key events on the page. Ctrl-Arrow will switch the visible |
+ * page. |
+ * @param {Event} e The KeyboardEvent. |
+ */ |
+ 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(); |
+ } |
+ }; |
+ |
+ /** |
+ * Simple common assertion API |
+ * @param {*} condition The condition to test. Note that this may be used to |
+ * test whether a value is defined or not, and we don't want to force a |
+ * cast to Boolean. |
+ * @param {string=} opt_message A message to use in any error. |
+ */ |
+ function assert(condition, opt_message) { |
Evan Stade
2011/11/07 23:59:20
some of these functions should go in util.js
xiyuan
2011/11/08 21:09:18
Done. Moved assert, getRequiredEleemnt and isRTL i
|
+ 'use strict'; |
+ if (!condition) { |
+ var msg = 'Assertion failed'; |
+ if (opt_message) |
+ msg = msg + ': ' + opt_message; |
+ throw new Error(msg); |
+ } |
+ } |
+ |
+ /** |
+ * Get an element that's known to exist by its ID. We use this instead of just |
+ * calling getElementById and not checking the result because this lets us |
+ * satisfy the JSCompiler type system. |
+ * @param {string} id The identifier name. |
+ * @return {!Element} the Element. |
+ */ |
+ function getRequiredElement(id) { |
+ var element = document.getElementById(id); |
+ assert(element, 'Missing required element: ' + id); |
+ return element; |
+ } |
+ |
+ /** |
+ * Wrapper to forward the callback to corresponding PageListView member. |
+ */ |
+ function getAppsCallback(data) { |
+ instance.getAppsCallback(data); |
+ } |
+ |
+ /** |
+ * Wrapper to forward the callback to corresponding PageListView member. |
+ */ |
+ function appAdded(appData, opt_highlight) { |
+ instance.appAdded(appData, opt_highlight); |
+ } |
+ |
+ /** |
+ * Sets that an app should be highlighted if it is added. Called right before |
+ * appAdded for new installs. |
+ */ |
+ function setAppToBeHighlighted(appId) { |
+ instance.highlightAppId = appId; |
+ } |
+ |
+ /** |
+ * 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. |
+ */ |
+ function appRemoved(appData, isUninstall) { |
+ var app = $(appData.id); |
+ assert(app, 'trying to remove an app that doesn\'t exist'); |
+ |
+ if (!isUninstall) |
+ app.replaceAppData(appData); |
+ else |
+ app.remove(); |
+ } |
+ |
+ /** |
+ * Wrapper to forward the callback to corresponding PageListView member. |
+ */ |
+ function appsPrefChangeCallback(data) { |
+ instance.appsPrefChangedCallback(data); |
+ } |
+ |
+ /** |
+ * Listener for offline status change events. Updates apps that are |
+ * not offline-enabled to be grayscale if the browser is offline. |
+ */ |
+ function updateOfflineEnabledApps() { |
+ var apps = document.querySelectorAll('.app'); |
+ for (var i = 0; i < apps.length; ++i) { |
+ if (apps[i].appData.enabled && !apps[i].appData.offline_enabled) { |
+ apps[i].setIcon(); |
+ apps[i].loadIcon(); |
+ } |
+ } |
+ } |
+ |
+ function getCardSlider() { |
+ return instance.cardSlider; |
+ } |
+ |
+ /** |
+ * Wrapper to forward the callback to corresponding PageListView member. |
+ */ |
+ function enterRearrangeMode() { |
+ instance.enterRearrangeMode(); |
+ } |
+ |
+ /** |
+ * Wrapper to forward the callback to corresponding PageListView member. |
+ */ |
+ function leaveRearrangeMode(e) { |
+ instance.leaveRearrangeMode(e); |
+ } |
+ |
+ /** |
+ * Check the directionality of the page. |
+ * @return {boolean} True if Chrome is running an RTL UI. |
+ */ |
+ function isRTL() { |
+ return document.documentElement.dir == 'rtl'; |
+ } |
+ |
+ /** |
+ * Wrapper to forward the callback to corresponding PageListView member. |
+ */ |
+ function getAppsPageIndex(page) { |
+ instance.getAppsPageIndex(page); |
+ } |
+ |
+ /** |
+ * Wrapper to forward the callback to corresponding PageListView member. |
+ */ |
+ function saveAppPageName(appPage, name) { |
+ instance.saveAppPageName(appPage, name); |
+ } |
+ |
+ return { |
+ appAdded: appAdded, |
+ appendTilePage: appendTilePage, |
+ appRemoved: appRemoved, |
+ appsPrefChangeCallback: appsPrefChangeCallback, |
+ assert: assert, |
+ enterRearrangeMode: enterRearrangeMode, |
+ getAppsCallback: getAppsCallback, |
+ getAppsPageIndex: getAppsPageIndex, |
+ getCardSlider: getCardSlider, |
+ getRequiredElement: getRequiredElement, |
+ isRTL: isRTL, |
+ leaveRearrangeMode: leaveRearrangeMode, |
+ saveAppPageName: saveAppPageName, |
+ setAppToBeHighlighted: setAppToBeHighlighted, |
+ updateOfflineEnabledApps: updateOfflineEnabledApps, |
+ PageListView: PageListView |
+ }; |
+}); |
+ |
+var appendTilePage = ntp4.appendTilePage; |
Evan Stade
2011/11/07 23:59:20
are you planning to use all of this in the aura ho
xiyuan
2011/11/08 21:09:18
I only need appsPrefChangeCallback and getAppsCall
|
+var appsPrefChangeCallback = ntp4.appsPrefChangeCallback; |
+var assert = ntp4.assert; |
+var getAppsCallback = ntp4.getAppsCallback; |
+var getRequiredElement = ntp4.getRequiredElement; |
+ |
+window.addEventListener('online', ntp4.updateOfflineEnabledApps); |
+window.addEventListener('offline', ntp4.updateOfflineEnabledApps); |