Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3915)

Unified Diff: chrome/browser/resources/shared/js/cr/ui/card_slider.js

Issue 9116037: [NTP4] Make TilePage and CardSlider evented to simplify code and fix page switcher bug (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: found one more bug when you leave a tab while mousing over page switcher Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/resources/ntp4/tile_page.js ('k') | chrome/browser/ui/webui/ntp/app_launcher_handler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/shared/js/cr/ui/card_slider.js
diff --git a/chrome/browser/resources/shared/js/cr/ui/card_slider.js b/chrome/browser/resources/shared/js/cr/ui/card_slider.js
index 72951ffc815b334a4bc895aee6cc9a1b05c50b55..4a9ee0bfc921c08d2055e9ac745f64ead9677c9c 100644
--- a/chrome/browser/resources/shared/js/cr/ui/card_slider.js
+++ b/chrome/browser/resources/shared/js/cr/ui/card_slider.js
@@ -58,7 +58,7 @@ cr.define('cr.ui', function() {
* @type {number}
* @private
*/
- this.currentCard_ = 0;
+ this.currentCard_ = -1;
/**
* @type {number}
@@ -73,15 +73,6 @@ cr.define('cr.ui', function() {
this.touchHandler_ = new cr.ui.TouchHandler(this.container_);
}
- /**
- * Events fired by the slider.
- * Events are fired at the container.
- */
- CardSlider.EventType = {
- // Fired when the user slides to another card.
- CARD_CHANGED: 'cardSlider:card_changed'
- };
-
/**
* The time to transition between cards when animating. Measured in ms.
@@ -132,7 +123,7 @@ cr.define('cr.ui', function() {
this.frame_.addEventListener('mousewheel',
this.onMouseWheel_.bind(this));
this.container_.addEventListener(
- 'webkitTransitionEnd', this.onAnimationTransitioned_.bind(this));
+ 'webkitTransitionEnd', this.onWebkitTransitionEnd_.bind(this));
// Also support touch events in case a touch screen happens to be
// available. Ideally we would support touch events whenever they
@@ -299,14 +290,134 @@ cr.define('cr.ui', function() {
},
/**
- * A handler for the animations ending their transition.
+ * Handles the ends of -webkit-transitions on -webkit-transform (animated
+ * card switches).
+ * @param {Event} e The webkitTransitionEnd event.
* @private
*/
- onAnimationTransitioned_: function(event) {
- if (event.target.id == 'page-list') {
- cr.dispatchSimpleEvent(this.currentCardValue, 'cardSelectionCompleted',
- true, true);
+ onWebkitTransitionEnd_: function(e) {
+ // Ignore irrelevant transitions that might bubble up.
+ if (e.target !== this.container_ ||
+ e.propertyName != '-webkit-transform') {
+ return;
}
+ this.fireChangeEndedEvent_(true);
+ },
+
+ /**
+ * Dispatches a simple event to tell subscribers we're done moving to the
+ * newly selected card.
+ * @param {boolean} wasAnimated whether or not the change was animated.
+ * @private
+ */
+ fireChangeEndedEvent_: function(wasAnimated) {
+ var e = document.createEvent('Event');
+ e.initEvent('cardSlider:card_change_ended', true, true);
+ e.cardSlider = this;
+ e.changedTo = this.currentCard_;
+ e.wasAnimated = wasAnimated;
+ this.container_.dispatchEvent(e);
+ },
+
+ /**
+ * Add a card to the card slider at a particular index. If the card being
+ * added is inserted in front of the current card, cardSlider.currentCard
+ * will be adjusted accordingly (to current card + 1).
+ * @param {!Node} card A card that will be added to the card slider.
+ * @param {number} index An index at which the given |card| should be
+ * inserted. Must be positive and less than the number of cards.
+ */
+ addCardAtIndex: function(card, index) {
+ assert(card instanceof Node, '|card| isn\'t a Node');
+ this.assertValidIndex_(index);
+ this.cards_ = Array.prototype.concat.call(
+ this.cards_.slice(0, index), card, this.cards_.slice(index));
+
+ if (this.currentCard_ == -1)
+ this.currentCard_ = 0;
+ else if (index <= this.currentCard_)
+ this.selectCard(this.currentCard_ + 1, false, true);
+
+ this.fireAddedEvent_(card, index);
+ },
+
+ /**
+ * Append a card to the end of the list.
+ * @param {!Node} card A card to add at the end of the card slider.
+ */
+ appendCard: function(card) {
+ assert(card instanceof Node, '|card| isn\'t a Node');
+ this.cards_.push(card);
+ this.fireAddedEvent_(card, this.cards_.length - 1);
+ },
+
+ /**
+ * Dispatches a simple event to tell interested subscribers that a card was
+ * added to this card slider.
+ * @param {Node} card The recently added card.
+ * @param {number} index The position of the newly added card.
+ * @private
+ */
+ fireAddedEvent_: function(card, index) {
+ this.assertValidIndex_(index);
+ var e = document.createEvent('Event');
+ e.initEvent('cardSlider:card_added', true, true);
+ e.addedIndex = index;
+ e.addedCard = card;
+ this.container_.dispatchEvent(e);
+ },
+
+ /**
+ * Removes a card by index from the card slider. If the card to be removed
+ * is the current card or in front of the current card, the current card
+ * will be updated (to current card - 1).
+ * @param {!Node} card A card to be removed.
+ */
+ removeCard: function(card) {
+ assert(card instanceof Node, '|card| isn\'t a Node');
+ this.removeCardAtIndex(this.cards_.indexOf(card));
+ },
+
+ /**
+ * Removes a card by index from the card slider. If the card to be removed
+ * is the current card or in front of the current card, the current card
+ * will be updated (to current card - 1).
+ * @param {number} index The index of the tile that should be removed.
+ */
+ removeCardAtIndex: function(index) {
+ this.assertValidIndex_(index);
+ var removed = this.cards_.splice(index, 1).pop();
+
+ if (this.cards_.length == 0)
+ this.currentCard_ = -1;
+ else if (index < this.currentCard_)
+ this.selectCard(this.currentCard_ - 1, false, true);
+
+ this.fireRemovedEvent_(removed, index);
+ },
+
+ /**
+ * Dispatches a cardSlider:card_removed event so interested subscribers know
+ * when a card was removed from this card slider.
+ * @param {Node} card The recently removed card.
+ * @param {number} index The index of the card before it was removed.
+ * @private
+ */
+ fireRemovedEvent_: function(card, index) {
+ var e = document.createEvent('Event');
+ e.initEvent('cardSlider:card_removed', true, true);
+ e.removedCard = card;
+ e.removedIndex = index;
+ this.container_.dispatchEvent(e);
+ },
+
+ /**
+ * Checks the the given |index| exists in this.cards_.
+ * @param {number} index An index to check.
+ * @private
+ */
+ assertValidIndex_: function(index) {
+ assert(index >= 0 && index < this.cards_.length);
},
/**
@@ -315,27 +426,30 @@ cr.define('cr.ui', function() {
* @param {number} newCardIndex Index of card to show.
* @param {boolean=} opt_animate If true will animate transition from
* current position to new position.
+ * @param {boolean=} opt_dontNotify If true, don't tell subscribers that
+ * we've changed cards.
*/
- selectCard: function(newCardIndex, opt_animate) {
- var previousCard = this.currentCardValue;
+ selectCard: function(newCardIndex, opt_animate, opt_dontNotify) {
+ this.assertValidIndex_(newCardIndex);
+ var previousCard = this.currentCardValue;
var isChangingCard =
!this.cards_[newCardIndex].classList.contains('selected-card');
if (isChangingCard) {
- previousCard.classList.remove('selected-card');
- // If we have a new card index and it is valid then update the left
- // position and current card index.
+ if (previousCard)
+ previousCard.classList.remove('selected-card');
this.currentCard_ = newCardIndex;
this.currentCardValue.classList.add('selected-card');
}
- this.transformToCurrentCard_(opt_animate);
+ var willTransitionHappen = this.transformToCurrentCard_(opt_animate);
- if (isChangingCard) {
+ if (isChangingCard && !opt_dontNotify) {
var event = document.createEvent('Event');
- event.initEvent(CardSlider.EventType.CARD_CHANGED, true, true);
+ event.initEvent('cardSlider:card_changed', true, true);
event.cardSlider = this;
+ event.wasAnimated = !!opt_animate;
this.container_.dispatchEvent(event);
// We also dispatch an event on the cards themselves.
@@ -346,6 +460,13 @@ cr.define('cr.ui', function() {
cr.dispatchSimpleEvent(this.currentCardValue, 'cardselected',
true, true);
}
+
+ // If we're not changing, animated, or transitioning, fire a
+ // cardSlider:card_change_ended event right away.
+ if ((!isChangingCard || !opt_animate || !willTransitionHappen) &&
+ !opt_dontNotify) {
+ this.fireChangeEndedEvent_(false);
+ }
},
/**
@@ -364,13 +485,20 @@ cr.define('cr.ui', function() {
* animate to that card or snap to it.
* @param {boolean=} opt_animate If true will animate transition from
* current position to new position.
+ * @return {boolean} Whether or not a transformation was necessary.
* @private
*/
transformToCurrentCard_: function(opt_animate) {
+ var prevLeft = this.currentLeft_;
this.currentLeft_ = -this.cardWidth_ *
(isRTL() ? this.cards_.length - this.currentCard - 1 :
this.currentCard);
+ // If there's no change, return something to let the caller know there
+ // won't be a transition occuring.
+ if (prevLeft == this.currentLeft_)
+ return false;
+
// Animate to the current card, which will either transition if the
// current card is new, or reset the existing card if we didn't drag
// enough to change cards.
@@ -381,6 +509,8 @@ cr.define('cr.ui', function() {
}
this.container_.style.WebkitTransition = transition;
this.translateTo_(this.currentLeft_);
+
+ return true;
},
/**
« no previous file with comments | « chrome/browser/resources/ntp4/tile_page.js ('k') | chrome/browser/ui/webui/ntp/app_launcher_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698