| // Copyright (c) 2012 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 Page switcher |
| * This is the class for the left and right navigation arrows that switch |
| * between pages. |
| */ |
| cr.define('ntp', function() { |
| |
| /** |
| * @constructor |
| * @extends {HTMLButtonElement} |
| */ |
| function PageSwitcher() {} |
| |
| PageSwitcher.prototype = { |
| __proto__: HTMLButtonElement.prototype, |
| |
| decorate: function(el) { |
| el.__proto__ = PageSwitcher.prototype; |
| |
| el.addEventListener('click', el.activate_); |
| |
| el.direction_ = el.id == 'page-switcher-start' ? -1 : 1; |
| |
| el.dragWrapper_ = new cr.ui.DragWrapper(el, el); |
| }, |
| |
| /** |
| * Activate the switcher (go to the next card). |
| * @private |
| */ |
| activate_: function() { |
| ntp.getCardSlider().selectCard(this.nextCardIndex_(), true); |
| }, |
| |
| /** |
| * Calculate the index of the card that this button will switch to. |
| * @private |
| */ |
| nextCardIndex_: function() { |
| const cardSlider = ntp.getCardSlider(); |
| const index = cardSlider.currentCard + this.direction_; |
| const numCards = cardSlider.cardCount - 1; |
| return Math.max(0, Math.min(index, numCards)); |
| }, |
| |
| /** |
| * Update the accessible label attribute of this button, based on the |
| * current position in the card slider and the names of the cards. |
| * @param {NodeList} dots The dot elements which display the names of the |
| * cards. |
| */ |
| updateButtonAccessibleLabel: function(dots) { |
| const currentIndex = ntp.getCardSlider().currentCard; |
| const nextCardIndex = this.nextCardIndex_(); |
| if (nextCardIndex == currentIndex) { |
| this.setAttribute('aria-label', ''); // No next card. |
| return; |
| } |
| |
| const currentDot = dots[currentIndex]; |
| const nextDot = dots[nextCardIndex]; |
| if (!currentDot || !nextDot) { |
| this.setAttribute('aria-label', ''); // Dots not initialised yet. |
| return; |
| } |
| |
| const currentPageTitle = currentDot.displayTitle; |
| const nextPageTitle = nextDot.displayTitle; |
| const msgName = (currentPageTitle == nextPageTitle) ? |
| 'page_switcher_same_title' : |
| 'page_switcher_change_title'; |
| const ariaLabel = loadTimeData.getStringF(msgName, nextPageTitle); |
| this.setAttribute('aria-label', ariaLabel); |
| }, |
| |
| shouldAcceptDrag: function(e) { |
| // Only allow page switching when a drop could happen on the page being |
| // switched to. |
| const nextPage = |
| ntp.getCardSlider().getCardAtIndex(this.nextCardIndex_()); |
| return nextPage.shouldAcceptDrag(e); |
| }, |
| |
| doDragEnter: function(e) { |
| this.scheduleDelayedSwitch_(e); |
| this.doDragOver(e); |
| }, |
| |
| doDragLeave: function(e) { |
| this.cancelDelayedSwitch_(); |
| }, |
| |
| doDragOver: function(e) { |
| e.preventDefault(); |
| const targetPage = ntp.getCardSlider().currentCardValue; |
| if (targetPage.shouldAcceptDrag(e)) |
| targetPage.setDropEffect(e.dataTransfer); |
| }, |
| |
| doDrop: function(e) { |
| e.stopPropagation(); |
| this.cancelDelayedSwitch_(); |
| |
| const tile = ntp.getCurrentlyDraggingTile(); |
| if (!tile) |
| return; |
| |
| const sourcePage = tile.tilePage; |
| const targetPage = ntp.getCardSlider().currentCardValue; |
| if (targetPage == sourcePage || !targetPage.shouldAcceptDrag(e)) |
| return; |
| |
| targetPage.appendDraggingTile(); |
| }, |
| |
| /** |
| * Starts a timer to activate the switcher. The timer repeats until |
| * cancelled by cancelDelayedSwitch_. |
| * @private |
| */ |
| scheduleDelayedSwitch_: function(e) { |
| // Stop switching when the next page can't be dropped onto. |
| const nextPage = |
| ntp.getCardSlider().getCardAtIndex(this.nextCardIndex_()); |
| if (!nextPage.shouldAcceptDrag(e)) |
| return; |
| |
| const self = this; |
| function navPageClearTimeout() { |
| self.activate_(); |
| self.dragNavTimeout_ = null; |
| self.scheduleDelayedSwitch_(e); |
| } |
| this.dragNavTimeout_ = window.setTimeout(navPageClearTimeout, 500); |
| }, |
| |
| /** |
| * Cancels the timer that activates the switcher while dragging. |
| * @private |
| */ |
| cancelDelayedSwitch_: function() { |
| if (this.dragNavTimeout_) { |
| window.clearTimeout(this.dragNavTimeout_); |
| this.dragNavTimeout_ = null; |
| } |
| }, |
| |
| }; |
| |
| /** @const */ |
| const initializePageSwitcher = PageSwitcher.prototype.decorate; |
| |
| return { |
| initializePageSwitcher: initializePageSwitcher, |
| PageSwitcher: PageSwitcher |
| }; |
| }); |