1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview Page switcher 7 * This is the class for the left and right navigation arrows that switch 8 * between pages. 9 */ 10cr.define('ntp', function() { 11 12 function PageSwitcher() { 13 } 14 15 PageSwitcher.template = { 16 __proto__: HTMLButtonElement.prototype, 17 18 decorate: function(el) { 19 el.__proto__ = PageSwitcher.template; 20 21 el.addEventListener('click', el.activate_); 22 23 el.direction_ = el.id == 'page-switcher-start' ? -1 : 1; 24 25 el.dragWrapper_ = new cr.ui.DragWrapper(el, el); 26 }, 27 28 /** 29 * Activate the switcher (go to the next card). 30 * @private 31 */ 32 activate_: function() { 33 ntp.getCardSlider().selectCard(this.nextCardIndex_(), true); 34 }, 35 36 /** 37 * Calculate the index of the card that this button will switch to. 38 * @private 39 */ 40 nextCardIndex_: function() { 41 var cardSlider = ntp.getCardSlider(); 42 var index = cardSlider.currentCard + this.direction_; 43 var numCards = cardSlider.cardCount - 1; 44 return Math.max(0, Math.min(index, numCards)); 45 }, 46 47 /** 48 * Update the accessible label attribute of this button, based on the 49 * current position in the card slider and the names of the cards. 50 * @param {NodeList} dots The dot elements which display the names of the 51 * cards. 52 */ 53 updateButtonAccessibleLabel: function(dots) { 54 var currentIndex = ntp.getCardSlider().currentCard; 55 var nextCardIndex = this.nextCardIndex_(); 56 if (nextCardIndex == currentIndex) { 57 this.setAttribute('aria-label', ''); // No next card. 58 return; 59 } 60 61 var currentDot = dots[currentIndex]; 62 var nextDot = dots[nextCardIndex]; 63 if (!currentDot || !nextDot) { 64 this.setAttribute('aria-label', ''); // Dots not initialised yet. 65 return; 66 } 67 68 var currentPageTitle = currentDot.displayTitle; 69 var nextPageTitle = nextDot.displayTitle; 70 var msgName = (currentPageTitle == nextPageTitle) ? 71 'page_switcher_same_title' : 'page_switcher_change_title'; 72 var ariaLabel = loadTimeData.getStringF(msgName, nextPageTitle); 73 this.setAttribute('aria-label', ariaLabel); 74 }, 75 76 shouldAcceptDrag: function(e) { 77 // Only allow page switching when a drop could happen on the page being 78 // switched to. 79 var nextPage = ntp.getCardSlider().getCardAtIndex(this.nextCardIndex_()); 80 return nextPage.shouldAcceptDrag(e); 81 }, 82 83 doDragEnter: function(e) { 84 this.scheduleDelayedSwitch_(e); 85 this.doDragOver(e); 86 }, 87 88 doDragLeave: function(e) { 89 this.cancelDelayedSwitch_(); 90 }, 91 92 doDragOver: function(e) { 93 e.preventDefault(); 94 var targetPage = ntp.getCardSlider().currentCardValue; 95 if (targetPage.shouldAcceptDrag(e)) 96 targetPage.setDropEffect(e.dataTransfer); 97 }, 98 99 doDrop: function(e) { 100 e.stopPropagation(); 101 this.cancelDelayedSwitch_(); 102 103 var tile = ntp.getCurrentlyDraggingTile(); 104 if (!tile) 105 return; 106 107 var sourcePage = tile.tilePage; 108 var targetPage = ntp.getCardSlider().currentCardValue; 109 if (targetPage == sourcePage || !targetPage.shouldAcceptDrag(e)) 110 return; 111 112 targetPage.appendDraggingTile(); 113 }, 114 115 /** 116 * Starts a timer to activate the switcher. The timer repeats until 117 * cancelled by cancelDelayedSwitch_. 118 * @private 119 */ 120 scheduleDelayedSwitch_: function(e) { 121 // Stop switching when the next page can't be dropped onto. 122 var nextPage = ntp.getCardSlider().getCardAtIndex(this.nextCardIndex_()); 123 if (!nextPage.shouldAcceptDrag(e)) 124 return; 125 126 var self = this; 127 function navPageClearTimeout() { 128 self.activate_(); 129 self.dragNavTimeout_ = null; 130 self.scheduleDelayedSwitch_(e); 131 } 132 this.dragNavTimeout_ = window.setTimeout(navPageClearTimeout, 500); 133 }, 134 135 /** 136 * Cancels the timer that activates the switcher while dragging. 137 * @private 138 */ 139 cancelDelayedSwitch_: function() { 140 if (this.dragNavTimeout_) { 141 window.clearTimeout(this.dragNavTimeout_); 142 this.dragNavTimeout_ = null; 143 } 144 }, 145 146 }; 147 148 return { 149 initializePageSwitcher: PageSwitcher.template.decorate 150 }; 151}); 152