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

Side by Side Diff: chrome/browser/resources/bluetooth_internals/device_table.js

Issue 2448713002: bluetooth: Add Device connection logic and accompanying user interface. (Closed)
Patch Set: Fix naming, merge upstream Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * Javascript for DeviceTable UI, served from chrome://bluetooth-internals/. 6 * Javascript for DeviceTable UI, served from chrome://bluetooth-internals/.
7 */ 7 */
8 8
9 cr.define('device_table', function() { 9 cr.define('device_table', function() {
10 var COLUMNS = {
11 NAME: 0,
12 ADDRESS: 1,
13 RSSI: 2,
14 SERVICES: 3,
15 CONNECTION_STATE: 4,
16 INSPECT_BUTTON: 5,
17 CONNECTION_ERROR: 6,
18 };
19
10 /** 20 /**
11 * A table that lists the devices and responds to changes in the given 21 * A table that lists the devices and responds to changes in the given
12 * DeviceCollection. 22 * DeviceCollection. Fires events for inspection requests from listed
23 * devices.
13 * @constructor 24 * @constructor
14 * @extends {HTMLTableElement} 25 * @extends {HTMLTableElement}
15 */ 26 */
16 var DeviceTable = cr.ui.define(function() { 27 var DeviceTable = cr.ui.define(function() {
17 /** @type {?Array<device_collection.Device>} 28 /** @type {?Array<device_collection.Device>}
18 * @private 29 * @private
19 */ 30 */
20 this.devices_ = null; 31 this.devices_ = null;
21 32
22 return document.importNode($('table-template').content.children[0], 33 return document.importNode($('table-template').content.children[0],
(...skipping 25 matching lines...) Expand all
48 this.devices_.addEventListener('sorted', this.redraw_.bind(this)); 59 this.devices_.addEventListener('sorted', this.redraw_.bind(this));
49 this.devices_.addEventListener('change', this.handleChange_.bind(this)); 60 this.devices_.addEventListener('change', this.handleChange_.bind(this));
50 this.devices_.addEventListener('splice', this.handleSplice_.bind(this)); 61 this.devices_.addEventListener('splice', this.handleSplice_.bind(this));
51 62
52 this.redraw_(); 63 this.redraw_();
53 }, 64 },
54 65
55 /** 66 /**
56 * Updates table row on change event of the device collection. 67 * Updates table row on change event of the device collection.
57 * @private 68 * @private
58 * @param {!CustomEvent} event 69 * @param {!Event} event
59 */ 70 */
60 handleChange_: function(event) { 71 handleChange_: function(event) {
61 this.updateRow_(this.devices_.item(event.index), event.index); 72 this.updateRow_(this.devices_.item(event.index), event.index);
62 }, 73 },
63 74
64 /** 75 /**
76 * Fires a inspect pressed event for the row |index|.
77 * @private
78 * @param {number} index
79 */
80 handleInspectBtn_: function(index) {
81 var event = new CustomEvent('inspectpressed', {
82 detail: {
83 address: this.devices_.item(index).address,
84 }
85 });
86 this.dispatchEvent(event);
87 },
88
89 /**
65 * Updates table row on splice event of the device collection. 90 * Updates table row on splice event of the device collection.
66 * @private 91 * @private
67 * @param {!CustomEvent} event 92 * @param {!Event} event
68 */ 93 */
69 handleSplice_: function(event) { 94 handleSplice_: function(event) {
70 event.removed.forEach(function() { 95 event.removed.forEach(function() {
71 this.body_.deleteRow(event.index); 96 this.body_.deleteRow(event.index);
72 }, this); 97 }, this);
73 98
74 event.added.forEach(function(device, index) { 99 event.added.forEach(function(device, index) {
75 this.insertRow_(device, event.index + index); 100 this.insertRow_(device, event.index + index);
76 }, this); 101 }, this);
77 }, 102 },
78 103
79 /** 104 /**
80 * Inserts a new row at |index| and updates it with info from |device|. 105 * Inserts a new row at |index| and updates it with info from |device|.
81 * @private 106 * @private
82 * @param {!device_collection.Device} device 107 * @param {!interfaces.BluetoothDevice.DeviceInfo} device
83 * @param {?number} index 108 * @param {?number} index
84 */ 109 */
85 insertRow_: function(device, index) { 110 insertRow_: function(device, index) {
86 var row = this.body_.insertRow(index); 111 var row = this.body_.insertRow(index);
87 row.id = device.info.address; 112 row.id = device.address;
88 113
89 for (var i = 0; i < this.headers_.length; i++) { 114 for (var i = 0; i < this.headers_.length; i++) {
90 row.insertCell(); 115 row.insertCell();
91 } 116 }
92 117
118 // Make two extra cells for the inspect button and connect errors.
119 var inspectCell = row.insertCell();
120
121 // TODO(crbug.com/663830): Replace connection error column with better
122 // notification system.
123 var connectErrorCell = row.insertCell();
124
125 var inspectButton = document.createElement('button');
126 inspectCell.appendChild(inspectButton);
127 inspectButton.addEventListener('click', function() {
128 this.handleInspectBtn_(row.sectionRowIndex);
129 }.bind(this));
130
93 this.updateRow_(device, row.sectionRowIndex); 131 this.updateRow_(device, row.sectionRowIndex);
94 }, 132 },
95 133
96 /** 134 /**
97 * Deletes and recreates the table using the cached |devices_|. 135 * Deletes and recreates the table using the cached |devices_|.
98 * @private 136 * @private
99 */ 137 */
100 redraw_: function() { 138 redraw_: function() {
101 this.removeChild(this.body_); 139 this.removeChild(this.body_);
102 this.appendChild(document.createElement('tbody')); 140 this.appendChild(document.createElement('tbody'));
103 this.body_ = this.tBodies[0]; 141 this.body_ = this.tBodies[0];
104 this.body_.classList.add('table-body'); 142 this.body_.classList.add('table-body');
105 143
106 for (var i = 0; i < this.devices_.length; i++) { 144 for (var i = 0; i < this.devices_.length; i++) {
107 this.insertRow_(this.devices_.item(i)); 145 this.insertRow_(this.devices_.item(i));
108 } 146 }
109 }, 147 },
110 148
111 /** 149 /**
112 * Updates the row at |index| with the info from |device|. 150 * Updates the row at |index| with the info from |device|.
113 * @private 151 * @private
114 * @param {!device_collection.Device} device 152 * @param {!interfaces.BluetoothDevice.DeviceInfo} device
115 * @param {number} index 153 * @param {number} index
116 */ 154 */
117 updateRow_: function(device, index) { 155 updateRow_: function(device, index) {
118 assert(this.body_.rows[index], 'Row ' + index + ' is not in the table.'); 156 assert(this.body_.rows[index], 'Row ' + index + ' is not in the table.');
dpapad 2016/11/10 19:05:02 var row = this.body_.rows[index]; assert(row, 'Row
mbrunson 2016/11/10 22:02:22 Done.
119 var row = this.body_.rows[index]; 157 var row = this.body_.rows[index];
120 158
121 row.classList.toggle('removed', device.removed); 159 row.classList.toggle('removed', device.removed);
122 160
161 var inspectButton = row.cells[COLUMNS.INSPECT_BUTTON].children[0];
162 inspectButton.disabled = false;
163 switch (device.connectionStatus) {
164 case 'disconnected':
165 inspectButton.textContent = 'Inspect';
166 break;
167 case 'connected':
168 inspectButton.textContent = 'Forget';
169 break;
170 case 'connecting':
171 inspectButton.disabled = true;
172 break;
173 default: assert('case not handled');
174 }
175
176 // TODO(crbug.com/663830): Replace connection error column with better
177 // notification system.
178 var connectErrorCell = row.cells[COLUMNS.CONNECTION_ERROR];
179 connectErrorCell.textContent = device.connectionMessage;
180
123 // Update the properties based on the header field path. 181 // Update the properties based on the header field path.
124 for (var i = 0; i < this.headers_.length; i++) { 182 for (var i = 0; i < this.headers_.length; i++) {
125 var header = this.headers_[i]; 183 var header = this.headers_[i];
126 var propName = header.dataset.field; 184 var propName = header.dataset.field;
127 185
128 var parts = propName.split('.'); 186 var parts = propName.split('.');
129 var obj = device.info; 187 var obj = device;
130 while (obj != null && parts.length > 0) { 188 while (obj != null && parts.length > 0) {
131 var part = parts.shift(); 189 var part = parts.shift();
132 obj = obj[part]; 190 obj = obj[part];
133 } 191 }
134 192
193 if (propName == 'is_gatt_connected') {
194 obj ? obj = 'Connected' : obj = 'Not Connected';
dpapad 2016/11/10 19:05:03 This usage of ternary operator is a bit odd boolea
mbrunson 2016/11/10 22:02:22 Done.
195 }
196
135 var cell = row.cells[i]; 197 var cell = row.cells[i];
136 cell.textContent = obj || 'Unknown'; 198 cell.textContent = (obj == null || obj == undefined) ? 'Unknown' : obj;
dpapad 2016/11/10 19:05:03 No need to check both for undefined and null, give
mbrunson 2016/11/10 22:02:22 Ah true. I forgot about the '=='/'===' thing with
137 cell.dataset.label = header.textContent; 199 cell.dataset.label = header.textContent;
138 } 200 }
139 }, 201 },
140 }; 202 };
141 203
142 return { 204 return {
143 DeviceTable: DeviceTable, 205 DeviceTable: DeviceTable,
144 }; 206 };
145 }); 207 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698