15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @fileoverview PageListView implementation. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PageListView manages page list, dot list, switcher buttons and handles apps 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pages callbacks from backend. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that you need to have AppLauncherHandler in your WebUI to use this code. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cr.define('ntp', function() { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'use strict'; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Creates a PageListView object. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @constructor 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extends {Object} 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function PageListView() { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PageListView.prototype = { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The CardSlider object to use for changing app pages. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {CardSlider|undefined} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cardSlider: undefined, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The frame div for this.cardSlider. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Element|undefined} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sliderFrame: undefined, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The 'page-list' element. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Element|undefined} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageList: undefined, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A list of all 'tile-page' elements. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!NodeList|undefined} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tilePages: undefined, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A list of all 'apps-page' elements. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!NodeList|undefined} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appsPages: undefined, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Suggestions page. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Element|undefined} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) suggestionsPage: undefined, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Most Visited page. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Element|undefined} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mostVisitedPage: undefined, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The 'dots-list' element. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Element|undefined} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dotList: undefined, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The left and right paging buttons. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Element|undefined} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherStart: undefined, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherEnd: undefined, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The 'trash' element. Note that technically this is unnecessary, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * JavaScript creates the object for us based on the id. But I don't want 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to rely on the ID being the same, and JSCompiler doesn't know about it. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Element|undefined} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trash: undefined, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The type of page that is currently shown. The value is a numerical ID. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {number} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shownPage: 0, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The index of the page that is currently shown, within the page type. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For example if the third Apps page is showing, this will be 2. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {number} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shownPageIndex: 0, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * EventTracker for managing event listeners for page events. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!EventTracker} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eventTracker: new EventTracker, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If non-null, this is the ID of the app to highlight to the user the next 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * time getAppsCallback runs. "Highlight" in this case means to switch to 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the page and run the new tile animation. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {?string} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) highlightAppId: null, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initializes page list view. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!Element} pageList A DIV element to host all pages. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!Element} dotList An UL element to host nav dots. Each dot 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * represents a page. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!Element} cardSliderFrame The card slider frame that hosts 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pageList and switcher buttons. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!Element|undefined} opt_trash Optional trash element. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!Element|undefined} opt_pageSwitcherStart Optional start page 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * switcher button. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!Element|undefined} opt_pageSwitcherEnd Optional end page 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * switcher button. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize: function(pageList, dotList, cardSliderFrame, opt_trash, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_pageSwitcherStart, opt_pageSwitcherEnd) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageList = pageList; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.dotList = dotList; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.ui.decorate(this.dotList, ntp.DotList); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.trash = opt_trash; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.trash) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ntp.Trash(this.trash); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherStart = opt_pageSwitcherStart; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.pageSwitcherStart) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp.initializePageSwitcher(this.pageSwitcherStart); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherEnd = opt_pageSwitcherEnd; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.pageSwitcherEnd) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp.initializePageSwitcher(this.pageSwitcherEnd); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.shownPage = loadTimeData.getInteger('shown_page_type'); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.shownPageIndex = loadTimeData.getInteger('shown_page_index'); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loadTimeData.getBoolean('showApps')) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Request data on the apps so we can fill them in. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this is kicked off asynchronously. 'getAppsCallback' will 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be invoked at some point after this function returns. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome.send('getApps'); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No apps page. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.shownPage == loadTimeData.getInteger('apps_page_id')) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.setShownPage_( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loadTimeData.getInteger('most_visited_page_id'), 0); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.body.classList.add('bare-minimum'); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.addEventListener('keydown', this.onDocKeyDown_.bind(this)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tilePages = this.pageList.getElementsByClassName('tile-page'); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appsPages = this.pageList.getElementsByClassName('apps-page'); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the cardSlider without any cards at the moment. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.sliderFrame = cardSliderFrame; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider = new cr.ui.CardSlider(this.sliderFrame, this.pageList, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.sliderFrame.offsetWidth); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Prevent touch events from triggering any sort of native scrolling if 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // there are multiple cards in the slider frame. 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var cardSlider = this.cardSlider; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cardSliderFrame.addEventListener('touchmove', function(e) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cardSlider.cardCount <= 1) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) e.preventDefault(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, true); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle mousewheel events anywhere in the card slider, so that wheel 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // events on the page switchers will still scroll the page. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This listener must be added before the card slider is initialized, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because it needs to be called before the card slider's handler. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cardSliderFrame.addEventListener('mousewheel', function(e) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cardSlider.currentCardValue.handleMouseWheel(e)) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) e.preventDefault(); // Prevent default scroll behavior. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) e.stopImmediatePropagation(); // Prevent horizontal card flipping. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.initialize( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loadTimeData.getBoolean('isSwipeTrackingFromScrollEventsEnabled')); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle events from the card slider. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageList.addEventListener('cardSlider:card_changed', 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCardChanged_.bind(this)); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageList.addEventListener('cardSlider:card_added', 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCardAdded_.bind(this)); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageList.addEventListener('cardSlider:card_removed', 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCardRemoved_.bind(this)); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the slider is resized appropriately with the window. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window.addEventListener('resize', this.onWindowResize_.bind(this)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update apps when online state changes. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window.addEventListener('online', 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updateOfflineEnabledApps_.bind(this)); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window.addEventListener('offline', 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updateOfflineEnabledApps_.bind(this)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Appends a tile page. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {TilePage} page The page element. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} title The title of the tile page. 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {boolean} titleIsEditable If true, the title can be changed. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {TilePage} opt_refNode Optional reference node to insert in front 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * When opt_refNode is falsey, |page| will just be appended to the end of 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the page list. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appendTilePage: function(page, title, titleIsEditable, opt_refNode) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opt_refNode) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var refIndex = this.getTilePageIndex(opt_refNode); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.addCardAtIndex(page, refIndex); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.appendCard(page); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remember special MostVisitedPage. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (typeof ntp.MostVisitedPage != 'undefined' && 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page instanceof ntp.MostVisitedPage) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.tilePages.length == 1, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'MostVisitedPage should be added as first tile page'); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.mostVisitedPage = page; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (typeof ntp.SuggestionsPage != 'undefined' && 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page instanceof ntp.SuggestionsPage) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.suggestionsPage = page; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're appending an AppsPage and it's a temporary page, animate it. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var animate = page instanceof ntp.AppsPage && 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page.classList.contains('temporary'); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a deep copy of the dot template to add a new one. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var newDot = new ntp.NavDot(page, title, titleIsEditable, animate); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page.navigationDot = newDot; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.dotList.insertBefore(newDot, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_refNode ? opt_refNode.navigationDot : null); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set a tab index on the first dot. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.dotList.dots.length == 1) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newDot.tabIndex = 3; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.eventTracker.add(page, 'pagelayout', this.onPageLayout_.bind(this)); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called by chrome when an app has changed positions. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} appData The data for the app. This contains page and 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * position indices. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appMoved: function(appData) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(loadTimeData.getBoolean('showApps')); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var app = $(appData.id); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(app, 'trying to move an app that doesn\'t exist'); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app.remove(false); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appsPages[appData.page_index].insertApp(appData, false); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called by chrome when an existing app has been disabled or 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * removed/uninstalled from chrome. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} appData A data structure full of relevant information for 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the app. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {boolean} isUninstall True if the app is being uninstalled; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * false if the app is being disabled. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {boolean} fromPage True if the removal was from the current page. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appRemoved: function(appData, isUninstall, fromPage) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(loadTimeData.getBoolean('showApps')); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var app = $(appData.id); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(app, 'trying to remove an app that doesn\'t exist'); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!isUninstall) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app.replaceAppData(appData); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app.remove(!!fromPage); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} If the page is still starting up. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isStartingUp_: function() { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return document.documentElement.classList.contains('starting-up'); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Tracks whether apps have been loaded at least once. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {boolean} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appsLoaded_: false, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Callback invoked by chrome with the apps available. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note that calls to this function can occur at any time, not just in 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * response to a getApps request. For example, when a user 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * installs/uninstalls an app on another synchronized devices. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} data An object with all the data on available 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * applications. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getAppsCallback: function(data) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(loadTimeData.getBoolean('showApps')); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var startTime = Date.now(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remember this to select the correct card when done rebuilding. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var prevCurrentCard = this.cardSlider.currentCard; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make removal of pages and dots as quick as possible with less DOM 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operations, reflows, or repaints. We set currentCard = 0 and remove 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the end to not encounter any auto-magic card selections in the 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process and we hide the card slider throughout. 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.currentCard = 0; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear any existing apps pages and dots. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rbyers): It might be nice to preserve animation of dots after an 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uninstall. Could we re-use the existing page and dot elements? It 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // seems unfortunate to have Chrome send us the entire apps list after an 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uninstall. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (this.appsPages.length > 0) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.removeTilePageAndDot_(this.appsPages[this.appsPages.length - 1]); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the array of apps and add any special synthesized entries 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var apps = data.apps; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get a list of page names 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageNames = data.appPageNames; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function stringListIsEmpty(list) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < list.length; i++) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list[i]) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sort by launch ordinal 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apps.sort(function(a, b) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a.app_launch_ordinal > b.app_launch_ordinal ? 1 : 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.app_launch_ordinal < b.app_launch_ordinal ? -1 : 0; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An app to animate (in case it was just installed). 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var highlightApp; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are any pages after the apps, add new pages before them. 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var lastAppsPage = (this.appsPages.length > 0) ? 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appsPages[this.appsPages.length - 1] : null; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var lastAppsPageIndex = (lastAppsPage != null) ? 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Array.prototype.indexOf.call(this.tilePages, lastAppsPage) : -1; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var nextPageAfterApps = lastAppsPageIndex != -1 ? 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tilePages[lastAppsPageIndex + 1] : null; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the apps, creating pages as necessary 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < apps.length; i++) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var app = apps[i]; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageIndex = app.page_index || 0; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pageIndex >= this.appsPages.length) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageName = loadTimeData.getString('appDefaultPageName'); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.appsPages.length < pageNames.length) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageName = pageNames[this.appsPages.length]; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var origPageCount = this.appsPages.length; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appendTilePage(new ntp.AppsPage(), pageName, true, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextPageAfterApps); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Confirm that appsPages is a live object, updated when a new page is 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // added (otherwise we'd have an infinite loop) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.appsPages.length == origPageCount + 1, 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'expected new page'); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app.id == this.highlightAppId) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) highlightApp = app; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appsPages[pageIndex].insertApp(app, false); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.currentCard = prevCurrentCard; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (highlightApp) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appAdded(highlightApp, true); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logEvent('apps.layout: ' + (Date.now() - startTime)); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the slider about the pages and mark the current page. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updateSliderCards(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.currentCardValue.navigationDot.classList.add('selected'); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!this.appsLoaded_) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appsLoaded_ = true; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent(document, 'sectionready', true, true); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.updateAppLauncherPromoHiddenState_(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called by chrome when a new app has been added to chrome or has been 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * enabled if previously disabled. 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} appData A data structure full of relevant information for 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the app. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {boolean=} opt_highlight Whether the app about to be added should 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be highlighted. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appAdded: function(appData, opt_highlight) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(loadTimeData.getBoolean('showApps')); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (appData.id == this.highlightAppId) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_highlight = true; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.highlightAppId = null; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageIndex = appData.page_index || 0; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pageIndex >= this.appsPages.length) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pageIndex >= this.appsPages.length) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appendTilePage(new ntp.AppsPage(), 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loadTimeData.getString('appDefaultPageName'), 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updateSliderCards(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var page = this.appsPages[pageIndex]; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var app = $(appData.id); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app) { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app.replaceAppData(appData); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (opt_highlight) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page.insertAndHighlightApp(appData); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.setShownPage_(loadTimeData.getInteger('apps_page_id'), 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appData.page_index); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page.insertApp(appData, false); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Callback invoked by chrome whenever an app preference changes. 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} data An object with all the data on available 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * applications. 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appsPrefChangedCallback: function(data) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(loadTimeData.getBoolean('showApps')); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < data.apps.length; ++i) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) $(data.apps[i].id).appData = data.apps[i]; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the App dot names. Skip the first dot (Most Visited). 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var dots = this.dotList.getElementsByClassName('dot'); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var start = this.mostVisitedPage ? 1 : 0; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = start; i < dots.length; ++i) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dots[i].displayTitle = data.appPageNames[i - start] || ''; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Callback invoked by chrome whenever the app launcher promo pref changes. 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {boolean} show Identifies if we should show or hide the promo. 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) appLauncherPromoPrefChangeCallback: function(show) { 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) loadTimeData.overrideValues({showAppLauncherPromo: show}); 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.updateAppLauncherPromoHiddenState_(); 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }, 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /** 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Updates the hidden state of the app launcher promo based on the page 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * shown and load data content. 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) updateAppLauncherPromoHiddenState_: function() { 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) $('app-launcher-promo').hidden = 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !loadTimeData.getBoolean('showAppLauncherPromo') || 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.shownPage != loadTimeData.getInteger('apps_page_id'); 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }, 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /** 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Invoked whenever the pages in apps-page-list have changed so that 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Slider knows about the new elements. 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updateSliderCards: function() { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageNo = Math.max(0, Math.min(this.cardSlider.currentCard, 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tilePages.length - 1)); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.setCards(Array.prototype.slice.call(this.tilePages), 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageNo); 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The shownPage property was potentially saved from a previous webui that 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // didn't have the same set of pages as the current one. So we cascade 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // from suggestions, to most visited and then to apps because we can have 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // an page with apps only (e.g., chrome://apps) or one with only the most 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // visited, but not one with only suggestions. And we alwayd default to 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // most visited first when previously shown page is not availabel anymore. 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If most visited isn't there either, we go to apps. 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (this.shownPage == loadTimeData.getInteger('suggestions_page_id')) { 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (this.suggestionsPage) 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.cardSlider.selectCardByValue(this.suggestionsPage); 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.shownPage = loadTimeData.getInteger('most_visited_page_id'); 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (this.shownPage == loadTimeData.getInteger('most_visited_page_id')) { 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (this.mostVisitedPage) 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.cardSlider.selectCardByValue(this.mostVisitedPage); 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.shownPage = loadTimeData.getInteger('apps_page_id'); 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (this.shownPage == loadTimeData.getInteger('apps_page_id') && 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) loadTimeData.getBoolean('showApps')) { 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.cardSlider.selectCardByValue( 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.appsPages[Math.min(this.shownPageIndex, 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.appsPages.length - 1)]); 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (this.mostVisitedPage) { 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.shownPage = loadTimeData.getInteger('most_visited_page_id'); 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.cardSlider.selectCardByValue(this.mostVisitedPage); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called whenever tiles should be re-arranging themselves out of the way 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of a moving or insert tile. 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enterRearrangeMode: function() { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loadTimeData.getBoolean('showApps')) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var tempPage = new ntp.AppsPage(); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempPage.classList.add('temporary'); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageName = loadTimeData.getString('appDefaultPageName'); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appendTilePage(tempPage, pageName, true); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ntp.getCurrentlyDraggingTile().firstChild.canBeRemoved()) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) $('footer').classList.add('showing-trash-mode'); 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) $('footer-menu-container').style.minWidth = $('trash').offsetWidth - 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) $('chrome-web-store-link').offsetWidth + 'px'; 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.documentElement.classList.add('dragging-mode'); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Invoked whenever some app is released 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) leaveRearrangeMode: function() { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var tempPage = document.querySelector('.tile-page.temporary'); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tempPage) { 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var dot = tempPage.navigationDot; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tempPage.tileCount && 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempPage != this.cardSlider.currentCardValue) { 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.removeTilePageAndDot_(tempPage, true); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempPage.classList.remove('temporary'); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.saveAppPageName(tempPage, 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loadTimeData.getString('appDefaultPageName')); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) $('footer').classList.remove('showing-trash-mode'); 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) $('footer-menu-container').style.minWidth = ''; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.documentElement.classList.remove('dragging-mode'); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Callback for the 'pagelayout' event. 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e The event. 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onPageLayout_: function(e) { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Array.prototype.indexOf.call(this.tilePages, e.currentTarget) != 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.currentCard) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updatePageSwitchers(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adjusts the size and position of the page switchers according to the 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * layout of the current card, and updates the aria-label attributes of 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the page switchers. 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updatePageSwitchers: function() { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!this.pageSwitcherStart || !this.pageSwitcherEnd) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var page = this.cardSlider.currentCardValue; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherStart.hidden = !page || 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this.cardSlider.currentCard == 0); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherEnd.hidden = !page || 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this.cardSlider.currentCard == this.cardSlider.cardCount - 1); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!page) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageSwitcherLeft = isRTL() ? this.pageSwitcherEnd : 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherStart; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pageSwitcherRight = isRTL() ? this.pageSwitcherStart : 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherEnd; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var scrollbarWidth = page.scrollbarWidth; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherLeft.style.width = 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (page.sideMargin + 13) + 'px'; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherLeft.style.left = '0'; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherRight.style.width = 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (page.sideMargin - scrollbarWidth + 13) + 'px'; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherRight.style.right = scrollbarWidth + 'px'; 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var offsetTop = page.querySelector('.tile-page-content').offsetTop + 'px'; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherLeft.style.top = offsetTop; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherRight.style.top = offsetTop; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherLeft.style.paddingBottom = offsetTop; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pageSwitcherRight.style.paddingBottom = offsetTop; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the aria-label attributes of the two page switchers. 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherStart.updateButtonAccessibleLabel(this.dotList.dots); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageSwitcherEnd.updateButtonAccessibleLabel(this.dotList.dots); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the index of the given apps page. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {AppsPage} page The AppsPage we wish to find. 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {number} The index of |page| or -1 if it is not in the 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * collection. 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getAppsPageIndex: function(page) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Array.prototype.indexOf.call(this.appsPages, page); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handler for cardSlider:card_changed events from this.cardSlider. 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e The cardSlider:card_changed event. 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCardChanged_: function(e) { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var page = e.cardSlider.currentCardValue; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't change shownPage until startup is done (and page changes actually 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reflect user actions). 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!this.isStartingUp_()) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (page.classList.contains('apps-page')) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.setShownPage_(loadTimeData.getInteger('apps_page_id'), 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.getAppsPageIndex(page)); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (page.classList.contains('most-visited-page')) { 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.setShownPage_( 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loadTimeData.getInteger('most_visited_page_id'), 0); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (page.classList.contains('suggestions-page')) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.setShownPage_(loadTimeData.getInteger('suggestions_page_id'), 0); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) console.error('unknown page selected'); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the active dot 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var curDot = this.dotList.getElementsByClassName('selected')[0]; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curDot) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curDot.classList.remove('selected'); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page.navigationDot.classList.add('selected'); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updatePageSwitchers(); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Saves/updates the newly selected page to open when first loading the NTP. 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {number} shownPage The new shown page type. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {number} shownPageIndex The new shown page index. 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setShownPage_: function(shownPage, shownPageIndex) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(shownPageIndex >= 0); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.shownPage = shownPage; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.shownPageIndex = shownPageIndex; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome.send('pageSelected', [this.shownPage, this.shownPageIndex]); 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.updateAppLauncherPromoHiddenState_(); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Listen for card additions to update the page switchers or the current 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * card accordingly. 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e A card removed or added event. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCardAdded_: function(e) { 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the second arg passed to insertBefore is falsey, it acts just like 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appendChild. 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pageList.insertBefore(e.addedCard, this.tilePages[e.addedIndex]); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCardAddedOrRemoved_(); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Listen for card removals to update the page switchers or the current card 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * accordingly. 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e A card removed or added event. 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCardRemoved_: function(e) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) e.removedCard.parentNode.removeChild(e.removedCard); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCardAddedOrRemoved_(); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when a card is removed or added. 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCardAddedOrRemoved_: function() { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.isStartingUp_()) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without repositioning there were issues - http://crbug.com/133457. 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.repositionFrame(); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updatePageSwitchers(); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Save the name of an apps page. 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Store the apps page name into the preferences store. 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {AppsPage} appsPage The app page for which we wish to save. 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} name The name of the page. 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saveAppPageName: function(appPage, name) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var index = this.getAppsPageIndex(appPage); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(index != -1); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome.send('saveAppPageName', [name, index]); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Window resize handler. 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onWindowResize_: function(e) { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.resize(this.sliderFrame.offsetWidth); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.updatePageSwitchers(); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Listener for offline status change events. Updates apps that are 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * not offline-enabled to be grayscale if the browser is offline. 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updateOfflineEnabledApps_: function() { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var apps = document.querySelectorAll('.app'); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < apps.length; ++i) { 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (apps[i].appData.enabled && !apps[i].appData.offline_enabled) { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apps[i].setIcon(); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) apps[i].loadIcon(); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handler for key events on the page. Ctrl-Arrow will switch the visible 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * page. 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e The KeyboardEvent. 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onDocKeyDown_: function(e) { 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!e.ctrlKey || e.altKey || e.metaKey || e.shiftKey) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var direction = 0; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (e.keyIdentifier == 'Left') 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) direction = -1; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (e.keyIdentifier == 'Right') 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) direction = 1; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var cardIndex = 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this.cardSlider.currentCard + direction + 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.cardCount) % this.cardSlider.cardCount; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.selectCard(cardIndex, true); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) e.stopPropagation(); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the index of a given tile page. 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {TilePage} page The TilePage we wish to find. 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {number} The index of |page| or -1 if it is not in the 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * collection. 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getTilePageIndex: function(page) { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Array.prototype.indexOf.call(this.tilePages, page); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Removes a page and navigation dot (if the navdot exists). 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {TilePage} page The page to be removed. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {boolean=} opt_animate If the removal should be animated. 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) removeTilePageAndDot_: function(page, opt_animate) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (page.navigationDot) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page.navigationDot.remove(opt_animate); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cardSlider.removeCard(page); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PageListView: PageListView 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}); 813