Index: chrome/browser/resources/bluetooth_internals/expandable_list.js |
diff --git a/chrome/browser/resources/bluetooth_internals/expandable_list.js b/chrome/browser/resources/bluetooth_internals/expandable_list.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e2d3be74e68da6c1f6b062d33d320f431c75e9c4 |
--- /dev/null |
+++ b/chrome/browser/resources/bluetooth_internals/expandable_list.js |
@@ -0,0 +1,126 @@ |
+// Copyright 2017 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. |
+ |
+/** |
+ * Javascript for ExpandableList and ExpandableListItem, served from |
+ * chrome://bluetooth-internals/. |
+ */ |
+ |
+cr.define('expandable_list', function() { |
+ /** @const */ var List = cr.ui.List; |
+ /** @const */ var ListItem = cr.ui.ListItem; |
+ |
+ /** |
+ * A list item that has expandable content that toggles when the item is |
+ * clicked. |
+ * @constructor |
+ */ |
+ var ExpandableListItem = cr.ui.define('li'); |
+ |
+ ExpandableListItem.prototype = { |
+ __proto__: ListItem.prototype, |
+ |
+ /** |
+ * Decorates the element as an expandable list item and caches the created |
+ * content holders for implementations. |
+ * @override |
+ */ |
+ decorate: function() { |
+ this.classList.add('expandable-list-item'); |
+ this.briefContent_ = document.createElement('div'); |
+ this.briefContent_.classList.add('brief-content'); |
+ this.briefContent_.addEventListener( |
+ 'click', this.toggleExpand_.bind(this)); |
+ this.appendChild(this.briefContent_); |
+ |
+ this.expandedContent_ = document.createElement('div'); |
+ this.expandedContent_.classList.add('expanded-content'); |
+ this.appendChild(this.expandedContent_); |
+ }, |
+ |
+ /** |
+ * Toggles the expanded class on the item. |
+ * @private |
+ */ |
+ toggleExpand_: function() { |
+ this.classList.toggle('expanded'); |
+ }, |
+ }; |
+ |
+ /** |
+ * A list that contains expandable list items. |
+ * @abstract |
+ * @constructor |
+ */ |
+ var ExpandableList = cr.ui.define('list'); |
+ |
+ ExpandableList.prototype = { |
+ __proto__: List.prototype, |
+ |
+ /** |
+ * Decorates element as an expandable list and caches references to layout |
+ * elements. |
+ * @override |
+ */ |
+ decorate: function() { |
+ List.prototype.decorate.call(this); |
+ this.classList.add('expandable-list'); |
+ |
+ this.emptyMessage_ = document.createElement('h3'); |
+ this.emptyMessage_.classList.add('empty-message'); |
+ this.emptyMessage_.hidden = true; |
+ this.insertBefore(this.emptyMessage_, this.firstChild); |
+ |
+ this.spinner_ = document.createElement('div'); |
+ this.spinner_.classList.add('spinner'); |
+ this.insertBefore(this.spinner_, this.firstChild); |
+ |
+ this.autoExpands = true; |
+ this.boundUpdateMessage_ = this.updateMessageDisplay_.bind(this); |
+ }, |
+ |
+ /** |
+ * Sets the data model of the list. |
+ * @param {cr.ui.ArrayDataModel} data |
+ */ |
+ setData: function(data) { |
+ if (this.dataModel) |
+ this.dataModel.removeEventListener('splice', this.boundUpdateMessage_); |
+ |
+ this.dataModel = data; |
+ this.dataModel.addEventListener('splice', this.boundUpdateMessage_); |
+ this.updateMessageDisplay_(); |
+ }, |
+ |
+ /** |
+ * Sets the empty message text. |
+ * @param {string} message |
+ */ |
+ setEmptyMessage: function(message) { |
+ this.emptyMessage_.textContent = message; |
+ }, |
+ |
+ /** |
+ * Sets the loading state of the list. If |loading| is true, the loading |
+ * spinner is dispayed. |
+ * @param {boolean} loading |
+ */ |
+ setLoading: function(loading) { |
+ this.spinner_.hidden = !loading; |
+ }, |
+ |
+ /** |
+ * Updates the display state of the empty message. If there are no items in |
+ * the data model, the empty message is displayed. |
+ */ |
+ updateMessageDisplay_: function() { |
+ this.emptyMessage_.hidden = this.dataModel.length > 0; |
+ }, |
+ }; |
+ |
+ return { |
+ ExpandableListItem: ExpandableListItem, |
+ ExpandableList: ExpandableList, |
+ } |
+}); |