14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)'use strict';
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Progress center at the background page.
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @constructor
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)var ProgressCenter = function() {
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Current items managed by the progress center.
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @type {Array.<ProgressItem>}
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @private
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.items_ = [];
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  /**
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Map of progress ID and notification ID.
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @type {Object.<string, string>}
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   * @private
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   */
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.notifications_ = new ProgressCenter.Notifications_(
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.requestCancel.bind(this));
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  /**
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * List of panel UI managed by the progress center.
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @type {Array.<ProgressCenterPanel>}
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   * @private
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   */
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.panels_ = [];
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Object.seal(this);
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Notifications created by progress center.
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {function(string)} cancelCallback Callback to notify the progress
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *     center of cancel operation.
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @constructor
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @private
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenter.Notifications_ = function(cancelCallback) {
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * ID set of notifications that is progressing now.
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @type {Object.<string, ProgressCenter.Notifications_.NotificationState_>}
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @private
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.ids_ = {};
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Async queue.
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @type {AsyncUtil.Queue}
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @private
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.queue_ = new AsyncUtil.Queue();
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Callback to notify the progress center of cancel operation.
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @type {function(string)}
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @private
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.cancelCallback_ = cancelCallback;
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome.notifications.onButtonClicked.addListener(
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.onButtonClicked_.bind(this));
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome.notifications.onClosed.addListener(this.onClosed_.bind(this));
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Object.seal(this);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * State of notification.
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @enum {string}
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @const
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @private
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenter.Notifications_.NotificationState_ = Object.freeze({
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VISIBLE: 'visible',
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISMISSED: 'dismissed'
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)});
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Updates the notification according to the item.
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {ProgressCenterItem} item Item to contain new information.
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {boolean} newItemAcceptable Whether to accept new item or not.
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenter.Notifications_.prototype.updateItem = function(
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    item, newItemAcceptable) {
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var NotificationState = ProgressCenter.Notifications_.NotificationState_;
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var newlyAdded = !(item.id in this.ids_);
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If new item is not acceptable, just return.
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (newlyAdded && !newItemAcceptable)
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Update the ID map and return if we does not show a notification for the
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // item.
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (item.state === ProgressItemState.PROGRESSING) {
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (newlyAdded)
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.ids_[item.id] = NotificationState.VISIBLE;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    else if (this.ids_[item.id] === NotificationState.DISMISSED)
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // This notification is no longer tracked.
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var previousState = this.ids_[item.id];
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delete this.ids_[item.id];
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Clear notifications for complete or canceled items.
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (item.state === ProgressItemState.CANCELED ||
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        item.state === ProgressItemState.COMPLETED) {
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (previousState === NotificationState.VISIBLE) {
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        this.queue_.run(function(proceed) {
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          chrome.notifications.clear(item.id, proceed);
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        });
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create/update the notification with the item.
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.queue_.run(function(proceed) {
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var params = {
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      title: chrome.runtime.getManifest().name,
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      iconUrl: chrome.runtime.getURL('/common/images/icon96.png'),
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      type: item.state === ProgressItemState.PROGRESSING ? 'progress' : 'basic',
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      message: item.message,
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      buttons: item.cancelable ? [{title: str('CANCEL_LABEL')}] : undefined,
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      progress: item.state === ProgressItemState.PROGRESSING ?
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          item.progressRateInPercent : undefined,
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      priority: (item.state === ProgressItemState.ERROR || !item.quiet) ? 0 : -1
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    };
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (newlyAdded)
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      chrome.notifications.create(item.id, params, proceed);
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    else
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      chrome.notifications.update(item.id, params, proceed);
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }.bind(this));
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handles cancel button click.
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {string} id Item ID.
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @private
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenter.Notifications_.prototype.onButtonClicked_ = function(id) {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (id in this.ids_)
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.cancelCallback_(id);
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handles notification close.
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {string} id Item ID.
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @private
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenter.Notifications_.prototype.onClosed_ = function(id) {
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (id in this.ids_)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.ids_[id] = ProgressCenter.Notifications_.NotificationState_.DISMISSED;
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Updates the item in the progress center.
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * If the item has a new ID, the item is added to the item list.
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param {ProgressCenterItem} item Updated item.
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ProgressCenter.prototype.updateItem = function(item) {
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Update item.
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  var index = this.getItemIndex_(item.id);
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (item.state === ProgressItemState.PROGRESSING) {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (index === -1)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this.items_.push(item);
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this.items_[index] = item;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (index !== -1)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this.items_.splice(index, 1);
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Update panels.
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (var i = 0; i < this.panels_.length; i++) {
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.panels_[i].updateItem(item);
1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Update notifications.
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.notifications_.updateItem(item, !this.panels_.length);
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Requests to cancel the progress item.
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param {string} id Progress ID to be requested to cancel.
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ProgressCenter.prototype.requestCancel = function(id) {
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  var item = this.getItemById(id);
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (item && item.cancelCallback)
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    item.cancelCallback();
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Adds a panel UI to the notification center.
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {ProgressCenterPanel} panel Panel UI.
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenter.prototype.addPanel = function(panel) {
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (this.panels_.indexOf(panel) !== -1)
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Update the panel list.
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.panels_.push(panel);
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set the current items.
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (var i = 0; i < this.items_.length; i++)
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    panel.updateItem(this.items_[i]);
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Register the cancel callback.
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  panel.cancelCallback = this.requestCancel.bind(this);
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Removes a panel UI from the notification center.
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {ProgressCenterPanel} panel Panel UI.
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProgressCenter.prototype.removePanel = function(panel) {
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var index = this.panels_.indexOf(panel);
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (index === -1)
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.panels_.splice(index, 1);
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  panel.cancelCallback = null;
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If there is no panel, show the notifications.
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (this.panels_.length)
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (var i = 0; i < this.items_.length; i++)
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.notifications_.updateItem(this.items_[i], true);
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Obtains item by ID.
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param {string} id ID of progress item.
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return {ProgressCenterItem} Progress center item having the specified
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) *     ID. Null if the item is not found.
2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */
2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ProgressCenter.prototype.getItemById = function(id) {
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return this.items_[this.getItemIndex_(id)];
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)/**
2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Obtains item index that have the specifying ID.
2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param {string} id Item ID.
2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return {number} Item index. Returns -1 If the item is not found.
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @private
2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */
2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ProgressCenter.prototype.getItemIndex_ = function(id) {
2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (var i = 0; i < this.items_.length; i++) {
2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (this.items_[i].id === id)
2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return i;
2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return -1;
2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
259