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

Side by Side Diff: chrome/browser/resources/options2/chromeos/bluetooth_device_list.js

Issue 10809005: Options: Rename chrome/browser/resources/options2 -> chrome/browser/resources/options. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix. Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 cr.define('options.system.bluetooth', function() {
6 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
7 /** @const */ var DeletableItem = options.DeletableItem;
8 /** @const */ var DeletableItemList = options.DeletableItemList;
9
10 /**
11 * Bluetooth settings constants.
12 */
13 function Constants() {}
14
15 /**
16 * Creates a new bluetooth list item.
17 * @param {{name: string,
18 * address: string,
19 * paired: boolean,
20 * bonded: boolean,
21 * connected: boolean,
22 * pairing: string|undefined,
23 * passkey: number|undefined,
24 * entered: number|undefined}} device
25 * Description of the Bluetooth device.
26 * @constructor
27 * @extends {options.DeletableItem}
28 */
29 function BluetoothListItem(device) {
30 var el = cr.doc.createElement('div');
31 el.__proto__ = BluetoothListItem.prototype;
32 el.data = {};
33 for (var key in device)
34 el.data[key] = device[key];
35 el.decorate();
36 // Only show the close button for paired devices.
37 el.deletable = device.paired;
38 return el;
39 }
40
41 BluetoothListItem.prototype = {
42 __proto__: DeletableItem.prototype,
43
44 /**
45 * Description of the Bluetooth device.
46 * @type {{name: string,
47 * address: string,
48 * paired: boolean,
49 * bonded: boolean,
50 * connected: boolean,
51 * pairing: string|undefined,
52 * passkey: number|undefined,
53 * entered: number|undefined}}
54 */
55 data: null,
56
57 /** @inheritDoc */
58 decorate: function() {
59 DeletableItem.prototype.decorate.call(this);
60 var label = this.ownerDocument.createElement('div');
61 label.className = 'bluetooth-device-label';
62 this.classList.add('bluetooth-device');
63 this.connected = this.data.connected;
64 // Though strictly speaking, a connected device will also be paired, we
65 // are interested in tracking paired devices that are not connected.
66 this.paired = this.data.paired && !this.data.connected;
67 this.connecting = !!this.data.pairing;
68 var content = this.data.name;
69 // Update label for devices that are paired but not connected.
70 if (this.paired) {
71 content = content + ' (' +
72 loadTimeData.getString('bluetoothDeviceNotConnected') + ')';
73 }
74 label.textContent = content;
75 this.contentElement.appendChild(label);
76 },
77 };
78
79 /**
80 * Class for displaying a list of Bluetooth devices.
81 * @constructor
82 * @extends {options.DeletableItemList}
83 */
84 var BluetoothDeviceList = cr.ui.define('list');
85
86 BluetoothDeviceList.prototype = {
87 __proto__: DeletableItemList.prototype,
88
89 /**
90 * Height of a list entry in px.
91 * @type {number}
92 * @private
93 */
94 itemHeight_: 32,
95
96 /**
97 * Width of a list entry in px.
98 * @type {number}
99 * @private.
100 */
101 itemWidth_: 400,
102
103 /** @inheritDoc */
104 decorate: function() {
105 DeletableItemList.prototype.decorate.call(this);
106 // Force layout of all items even if not in the viewport to address
107 // calculation errors when the list is hidden. The impact on performance
108 // should be minimal given that the list is not expected to grow very
109 // large.
110 this.autoExpand = true;
111 this.addEventListener('blur', this.onBlur_);
112 this.clear();
113 },
114
115 /**
116 * When the list loses focus, unselect all items in the list.
117 * @private
118 */
119 onBlur_: function() {
120 // TODO(kevers): Should this be pushed up to the list class?
121 this.selectionModel.unselectAll();
122 },
123
124 /**
125 * Adds a bluetooth device to the list of available devices. A check is
126 * made to see if the device is already in the list, in which case the
127 * existing device is updated.
128 * @param {{name: string,
129 * address: string,
130 * paired: boolean,
131 * bonded: boolean,
132 * connected: boolean,
133 * pairing: string|undefined,
134 * passkey: number|undefined,
135 * entered: number|undefined}} device
136 * Description of the bluetooth device.
137 * @return {boolean} True if the devies was successfully added or updated.
138 */
139 appendDevice: function(device) {
140 var selectedDevice = this.getSelectedDevice_();
141 var index = this.find(device.address);
142 if (index == undefined) {
143 this.dataModel.push(device);
144 this.redraw();
145 } else {
146 this.dataModel.splice(index, 1, device);
147 this.redrawItem(index);
148 }
149 this.updateListVisibility_();
150 if (selectedDevice)
151 this.setSelectedDevice_(selectedDevice);
152 return true;
153 },
154
155 /**
156 * Forces a revailidation of the list content. Content added while the list
157 * is hidden is not properly rendered when the list becomes visible. In
158 * addition, deleting a single item from the list results in a stale cache
159 * requiring an invalidation.
160 * @param {String=} opt_selection Optional address of device to select
161 * after refreshing the list.
162 */
163 refresh: function(opt_selection) {
164 // TODO(kevers): Investigate if the root source of the problems can be
165 // fixed in cr.ui.list.
166 var selectedDevice = opt_selection ? opt_selection :
167 this.getSelectedDevice_();
168 this.invalidate();
169 this.redraw();
170 if (selectedDevice)
171 this.setSelectedDevice_(selectedDevice);
172 },
173
174 /**
175 * Retrieves the address of the selected device, or null if no device is
176 * selected.
177 * @return {?String} Address of selected device or null.
178 * @private
179 */
180 getSelectedDevice_: function() {
181 var selection = this.selectedItem;
182 if (selection)
183 return selection.address;
184 return null;
185 },
186
187 /**
188 * Selects the device with the matching address.
189 * @param {String} address The unique address of the device.
190 * @private
191 */
192 setSelectedDevice_: function(address) {
193 var index = this.find(address);
194 if (index != undefined)
195 this.selectionModel.selectRange(index, index);
196 },
197
198 /**
199 * Perges all devices from the list.
200 */
201 clear: function() {
202 this.dataModel = new ArrayDataModel([]);
203 this.redraw();
204 this.updateListVisibility_();
205 },
206
207 /**
208 * Returns the index of the list entry with the matching address.
209 * @param {string} address Unique address of the Bluetooth device.
210 * @return {number|undefined} Index of the matching entry or
211 * undefined if no match found.
212 */
213 find: function(address) {
214 var size = this.dataModel.length;
215 for (var i = 0; i < size; i++) {
216 var entry = this.dataModel.item(i);
217 if (entry.address == address)
218 return i;
219 }
220 },
221
222 /** @inheritDoc */
223 createItem: function(entry) {
224 return new BluetoothListItem(entry);
225 },
226
227 /**
228 * Overrides the default implementation, which is used to compute the
229 * size of an element in the list. The default implementation relies
230 * on adding a placeholder item to the list and fetching its size and
231 * position. This strategy does not work if an item is added to the list
232 * while it is hidden, as the computed metrics will all be zero in that
233 * case.
234 * @return {{height: number, marginTop: number, marginBottom: number,
235 * width: number, marginLeft: number, marginRight: number}}
236 * The height and width of the item, taking margins into account,
237 * and the margins themselves.
238 */
239 measureItem: function() {
240 return {
241 height: this.itemHeight_,
242 marginTop: 0,
243 marginBotton: 0,
244 width: this.itemWidth_,
245 marginLeft: 0,
246 marginRight: 0
247 };
248 },
249
250 /**
251 * Override the default implementation to return a predetermined size,
252 * which in turns allows proper layout of items even if the list is hidden.
253 * @return {height: number, width: number} Dimensions of a single item in
254 * the list of bluetooth device.
255 * @private.
256 */
257 getDefaultItemSize_: function() {
258 return {
259 height: this.itemHeight_,
260 width: this.itemWidth_
261 };
262 },
263
264 /**
265 * Override base implementation of handleClick_, which unconditionally
266 * removes the item. In this case, removal of the element is deferred
267 * pending confirmation from the Bluetooth adapter.
268 * @param {Event} e The click event object.
269 * @private
270 */
271 handleClick_: function(e) {
272 if (this.disabled)
273 return;
274
275 var target = e.target;
276 if (!target.classList.contains('row-delete-button'))
277 return;
278
279 var listItem = this.getListItemAncestor(target);
280 var selected = this.selectionModel.selectedIndexes;
281 var index = this.getIndexOfListItem(listItem);
282 if (selected.indexOf(index) == -1)
283 selected = [index];
284 for (var j = selected.length - 1; j >= 0; j--) {
285 var index = selected[j];
286 var item = this.getListItemByIndex(index);
287 if (item && item.deletable) {
288 // Device is busy until we hear back from the Bluetooth adapter.
289 // Prevent double removal request.
290 item.deletable = false;
291 // TODO(kevers): Provide visual feedback that the device is busy.
292
293 // Inform the bluetooth adapter that we are disconnecting or
294 // forgetting the device.
295 chrome.send('updateBluetoothDevice',
296 [item.data.address, item.connected ? 'disconnect' : 'forget']);
297 }
298 }
299 },
300
301 /** @inheritDoc */
302 deleteItemAtIndex: function(index) {
303 var selectedDevice = this.getSelectedDevice_();
304 this.dataModel.splice(index, 1);
305 this.refresh(selectedDevice);
306 this.updateListVisibility_();
307 },
308
309 /**
310 * If the list has an associated empty list placholder then update the
311 * visibility of the list and placeholder.
312 * @private
313 */
314 updateListVisibility_: function() {
315 var empty = this.dataModel.length == 0;
316 var listPlaceHolderID = this.id + '-empty-placeholder';
317 if ($(listPlaceHolderID)) {
318 if (this.hidden != empty) {
319 this.hidden = empty;
320 $(listPlaceHolderID).hidden = !empty;
321 this.refresh();
322 }
323 }
324 },
325 };
326
327 cr.defineProperty(BluetoothListItem, 'connected', cr.PropertyKind.BOOL_ATTR);
328
329 cr.defineProperty(BluetoothListItem, 'paired', cr.PropertyKind.BOOL_ATTR);
330
331 cr.defineProperty(BluetoothListItem, 'connecting', cr.PropertyKind.BOOL_ATTR);
332
333 return {
334 BluetoothListItem: BluetoothListItem,
335 BluetoothDeviceList: BluetoothDeviceList,
336 Constants: Constants
337 };
338 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698