158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)'use strict';
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/**
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Progress center panel.
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {HTMLElement} element DOM Element of the process center panel.
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @constructor
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)var ProgressCenterPanel = function(element) {
14d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  /**
15d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * Root element of the progress center.
16d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @type {!HTMLElement}
17d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @private
18d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   */
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.element_ = element;
20d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
21d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  /**
22d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * Open view containing multiple progress items.
23d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @type {!HTMLElement}
24d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @private
25d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   */
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.openView_ = this.element_.querySelector('#progress-center-open-view');
27d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
28d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  /**
29d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * Close view that is a summarized progress item.
30d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @type {!HTMLElement}
31d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @private
32d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   */
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.closeView_ = this.element_.querySelector('#progress-center-close-view');
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /**
36d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * Toggle animation rule of the progress center.
37d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @type {!CSSKeyFrameRule}
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)   * @private
390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)   */
40d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  this.toggleAnimation_ = ProgressCenterPanel.getToggleAnimation_(
41d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      element.ownerDocument);
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  /**
44d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * Reset is requested but it is pending until the transition of progress bar
45d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * is complete.
46d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)   * @type {boolean}
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   * @private
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)   */
49d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  this.resetRequested_ = false;
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Callback to becalled with the ID of the progress item when the cancel
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * button is clicked.
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.cancelCallback = null;
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  Object.seal(this);
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Register event handlers.
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  element.addEventListener('click', this.onClick_.bind(this));
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  element.addEventListener(
62d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      'webkitAnimationEnd', this.onToggleAnimationEnd_.bind(this));
63d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  element.addEventListener(
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      'webkitTransitionEnd', this.onItemTransitionEnd_.bind(this));
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/**
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * Updates attributes of the item element.
690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * @param {!HTMLElement} element Element to be updated.
700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * @param {!ProgressCenterItem} item Progress center item.
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ProgressCenterPanel.updateItemElement_ = function(element, item) {
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Sets element attributes.
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  element.setAttribute('data-progress-id', item.id);
76d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  element.classList.toggle('error', item.state === ProgressItemState.ERROR);
77d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  element.classList.toggle('cancelable', item.cancelable);
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Only when the previousWidthRate is not NaN (when style width is already
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // set) and the progress rate increases, we use transition animation.
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var previousWidthRate =
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      parseInt(element.querySelector('.progress-track').style.width);
83f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)  var targetWidthRate = item.progressRateInPercent;
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var animation = !isNaN(previousWidthRate) &&
85f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)      previousWidthRate < targetWidthRate;
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (item.state === ProgressItemState.COMPLETED && animation) {
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // The attribute pre-complete means that the actual operation is already
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // done but the UI transition of progress bar is not complete.
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    element.setAttribute('pre-complete', '');
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    element.querySelector('label').textContent = item.message;
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // To commit the property change and to trigger the transition even if the
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // change is done synchronously, assign the width value asynchronously.
96f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)  var updateTrackWidth = function() {
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    var track = element.querySelector('.progress-track');
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    track.classList.toggle('animated', animation);
99f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)    track.style.width = targetWidthRate + '%';
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    track.hidden = false;
101f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)  };
102f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)  if (animation)
103f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)    setTimeout(updateTrackWidth);
104f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)  else
105f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)    updateTrackWidth();
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/**
109d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) * Obtains the toggle animation keyframes rule from the document.
110d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) * @param {HTMLDocument} document Document containing the rule.
111d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) * @return {CSSKeyFrameRules} Animation rule.
112d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) * @private
113d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) */
114d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)ProgressCenterPanel.getToggleAnimation_ = function(document) {
115d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  for (var i = 0; i < document.styleSheets.length; i++) {
116d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    var styleSheet = document.styleSheets[i];
117d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    for (var j = 0; j < styleSheet.cssRules.length; j++) {
118d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      var rule = styleSheet.cssRules[j];
119d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      if (rule.type === CSSRule.WEBKIT_KEYFRAMES_RULE &&
120d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)          rule.name === 'progress-center-toggle') {
121d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        return rule;
122d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      }
123d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    }
124d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  }
125d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  throw new Error('The progress-center-toggle rules is not found.');
126d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)};
127d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
128d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)/**
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * Updates an item to the progress center panel.
1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * @param {!ProgressCenterItem} item Item including new contents.
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenterPanel.prototype.updateItem = function(item) {
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If reset is requested, force to reset.
1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (this.resetRequested_)
1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    this.reset(true);
1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var itemElement = this.getItemElement_(item.id);
1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Check whether the item should be displayed or not by referring its state.
1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  switch (item.state) {
1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Should show the item.
1420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case ProgressItemState.PROGRESSING:
1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case ProgressItemState.ERROR:
1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      // If the item has not been added yet, create a new element and add it.
1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      if (!itemElement) {
1460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        itemElement = this.createNewItemElement_();
1470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        this.openView_.insertBefore(itemElement, this.openView_.firstNode);
1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      }
1490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      // Update the element by referring the item model.
1510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      ProgressCenterPanel.updateItemElement_(itemElement, item);
1520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      this.element_.hidden = false;
1530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      break;
1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Should not show the item.
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ProgressItemState.COMPLETED:
1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case ProgressItemState.CANCELED:
1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      // If itemElement is not shown, just break.
1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      if (!itemElement)
1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        break;
1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      // If the item is complete state, once update it because it may turn to
1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      // have the pre-complete attribute.
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (item.state === ProgressItemState.COMPLETED)
1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        ProgressCenterPanel.updateItemElement_(itemElement, item);
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      // If the item has the pre-complete attribute, keep showing it. Otherwise,
1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      // just remove it.
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (item.state !== ProgressItemState.COMPLETED ||
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          !itemElement.hasAttribute('pre-complete')) {
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        this.openView_.removeChild(itemElement);
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      }
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      break;
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Updates close showing summarized item.
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {!ProgressCenterItem} summarizedItem Item to be displayed in the close
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *     view.
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenterPanel.prototype.updateCloseView = function(summarizedItem) {
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.closeView_.classList.toggle('single', !summarizedItem.summarized);
184d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  ProgressCenterPanel.updateItemElement_(this.closeView_, summarizedItem);
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/**
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Remove all the items.
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * @param {boolean=} opt_force True if we force to reset and do not wait the
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) *    transition of progress bar. False otherwise. False is default.
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)ProgressCenterPanel.prototype.reset = function(opt_force) {
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!opt_force && this.element_.querySelector('[pre-complete]')) {
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    this.resetRequested_ = true;
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Clear the flag.
1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  this.resetRequested_ = false;
2000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Clear the all compete item.
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.openView_.innerHTML = '';
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Clear track width of close view.
205d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  this.closeView_.querySelector('.progress-track').style.width = '';
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Hide the progress center.
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.element_.hidden = true;
209d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  this.closeView_.querySelector('.progress-track').hidden = true;
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.element_.classList.remove('opened');
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/**
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Gets an item element having the specified ID.
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param {string} id progress item ID.
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @return {HTMLElement} Item element having the ID.
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @private
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ProgressCenterPanel.prototype.getItemElement_ = function(id) {
2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  var query = 'li[data-progress-id="' + id + '"]';
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return this.openView_.querySelector(query);
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/**
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Creates an item element.
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @return {HTMLElement} Created item element.
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @private
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ProgressCenterPanel.prototype.createNewItemElement_ = function() {
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var label = this.element_.ownerDocument.createElement('label');
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  label.className = 'label';
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var progressBarIndicator = this.element_.ownerDocument.createElement('div');
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  progressBarIndicator.className = 'progress-track';
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var progressBar = this.element_.ownerDocument.createElement('div');
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  progressBar.className = 'progress-bar';
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  progressBar.appendChild(progressBarIndicator);
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var cancelButton = this.element_.ownerDocument.createElement('button');
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cancelButton.className = 'cancel';
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  cancelButton.setAttribute('tabindex', '-1');
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var progressFrame = this.element_.ownerDocument.createElement('div');
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  progressFrame.className = 'progress-frame';
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  progressFrame.appendChild(progressBar);
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  progressFrame.appendChild(cancelButton);
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var itemElement = this.element_.ownerDocument.createElement('li');
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  itemElement.appendChild(label);
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  itemElement.appendChild(progressFrame);
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return itemElement;
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
257d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) * Handles the animation end event of the progress center.
258d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) * @param {Event} event Animation end event.
259d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) * @private
260d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) */
261d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)ProgressCenterPanel.prototype.onToggleAnimationEnd_ = function(event) {
262d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // Transition end of the root element's height.
263d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (event.target === this.element_ &&
264d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      event.animationName === 'progress-center-toggle') {
265d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    this.element_.classList.remove('animated');
266d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    return;
267d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  }
268d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)};
269d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
270d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)/**
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Handles the transition end event of items.
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {Event} event Transition end event.
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ProgressCenterPanel.prototype.onItemTransitionEnd_ = function(event) {
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var itemElement = event.target.parentNode.parentNode.parentNode;
2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!itemElement.hasAttribute('pre-complete') ||
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      event.propertyName !== 'width')
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
280d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (itemElement !== this.closeView_)
2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    this.openView_.removeChild(itemElement);
282d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  itemElement.removeAttribute('pre-complete');
283d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
2840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (this.resetRequested_)
2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    this.reset();
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Handles the click event.
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @param {Event} event Click event.
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ProgressCenterPanel.prototype.onClick_ = function(event) {
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Toggle button.
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (event.target.classList.contains('toggle') &&
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (!this.closeView_.classList.contains('single') ||
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       this.element_.classList.contains('opened'))) {
298d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
299d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    // If the progress center has already animated, just return.
300d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (this.element_.classList.contains('animated'))
301d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      return;
302d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
303d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    // Obtains current and target height.
304d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    var currentHeight;
305d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    var targetHeight;
306d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (this.element_.classList.contains('opened')) {
307d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      currentHeight = this.openView_.getBoundingClientRect().height;
308d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      targetHeight = this.closeView_.getBoundingClientRect().height;
309d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    } else {
310d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      currentHeight = this.closeView_.getBoundingClientRect().height;
311d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      targetHeight = this.openView_.getBoundingClientRect().height;
312d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    }
313d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
314d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    // Set styles for animation.
315d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    this.toggleAnimation_.cssRules[0].style.height = currentHeight + 'px';
316d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    this.toggleAnimation_.cssRules[1].style.height = targetHeight + 'px';
317d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    this.element_.classList.add('animated');
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    this.element_.classList.toggle('opened');
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Cancel button.
323d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (this.cancelCallback) {
324d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    var id = event.target.classList.contains('toggle') ?
325d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        this.closeView_.getAttribute('data-progress-id') :
326d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        event.target.parentNode.parentNode.getAttribute('data-progress-id');
327d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    this.cancelCallback(id);
328d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  }
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
330