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

Unified Diff: chrome/browser/resources/options2/chromeos/bluetooth_list_element.js

Issue 8895023: Options2: Pull the trigger. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: DIAF. Created 9 years 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/options2/chromeos/bluetooth_list_element.js
diff --git a/chrome/browser/resources/options2/chromeos/bluetooth_list_element.js b/chrome/browser/resources/options2/chromeos/bluetooth_list_element.js
new file mode 100644
index 0000000000000000000000000000000000000000..1b6ef82764c55c1cc87f872efc6a4a597cf1c08c
--- /dev/null
+++ b/chrome/browser/resources/options2/chromeos/bluetooth_list_element.js
@@ -0,0 +1,387 @@
+// Copyright (c) 2011 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.
+
+cr.define('options.system.bluetooth', function() {
+ /**
+ * Bluetooth settings constants.
+ */
+ function Constants() {}
+
+ /**
+ * Enumeration of supported device types. Each device type has an
+ * associated icon and CSS style.
+ * @enum {string}
+ */
+ Constants.DEVICE_TYPE = {
+ COMPUTER: 'computer',
+ HEADSET: 'headset',
+ KEYBOARD: 'input-keyboard',
+ MOUSE: 'input-mouse',
+ PHONE: 'phone',
+ };
+
+ /**
+ * Enumeration of possible states for a bluetooth device. The value
+ * associated with each state maps to a localized string in the global
+ * variable 'templateData'.
+ * @enum {string}
+ */
+ Constants.DEVICE_STATUS = {
+ CONNECTED: 'bluetoothDeviceConnected',
+ CONNECTING: 'bluetoothDeviceConnecting',
+ FAILED_PAIRING: 'bluetoothDeviceFailedPairing',
+ NOT_PAIRED: 'bluetoothDeviceNotPaired',
+ PAIRED: 'bluetoothDevicePaired'
+ };
+
+ /**
+ * Enumeration of possible states during pairing. The value associated
+ * with each state maps to a loalized string in the global variable
+ * 'tempateData'.
+ * @enum {string}
+ */
+ Constants.PAIRING = {
+ CONFIRM_PASSKEY: 'bluetoothConfirmPasskey',
+ ENTER_PASSKEY: 'bluetoothEnterPasskey',
+ FAILED_CONNECT_INSTRUCTIONS: 'bluetoothFailedPairingInstructions',
+ REMOTE_PASSKEY: 'bluetoothRemotePasskey'
+ };
+
+ /**
+ * Creates an element for storing a list of bluetooth devices.
+ * @param {Object=} opt_propertyBag Optional properties.
+ * @constructor
+ * @extends {HTMLDivElement}
+ */
+ var BluetoothListElement = cr.ui.define('div');
+
+ BluetoothListElement.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ },
+
+ /**
+ * Loads given list of bluetooth devices. This list will comprise of
+ * devices that are currently connected. New devices are discovered
+ * via the 'Find devices' button.
+ * @param {Array} devices An array of bluetooth devices.
+ */
+ load: function(devices) {
+ this.textContent = '';
+ for (var i = 0; i < devices.length; i++) {
+ if (this.isSupported_(devices[i]))
+ this.appendChild(new BluetoothItem(devices[i]));
+ }
+ },
+
+ /**
+ * Adds a bluetooth device to the list of available devices. A check is
+ * made to see if the device is already in the list, in which case the
+ * existing device is updated.
+ * @param {Object.<string,string>} device Description of the bluetooth
+ * device.
+ * @return {boolean} True if the devies was successfully added or updated.
+ */
+ appendDevice: function(device) {
+ if (!this.isSupported_(device))
+ return false;
+ var item = new BluetoothItem(device);
+ var existing = this.findDevice(device.address);
+ if (existing)
+ this.replaceChild(item, existing);
+ else
+ this.appendChild(item);
+ return true;
+ },
+
+ /**
+ * Scans the list of elements corresponding to discovered Bluetooth
+ * devices for one with a matching address.
+ * @param {string} address The address of the device.
+ * @return {Element|undefined} Element corresponding to the device address
+ * or undefined if no corresponding element is found.
+ */
+ findDevice: function(address) {
+ var candidate = this.firstChild;
+ while (candidate) {
+ if (candidate.data.address == address)
+ return candidate;
+ candidate = candidate.nextSibling;
+ }
+ },
+
+ /**
+ * Tests if the bluetooth device is supported based on the type of device.
+ * @param {Object.<string,string>} device Desription of the device.
+ * @return {boolean} true if the device is supported.
+ * @private
+ */
+ isSupported_: function(device) {
+ var target = device.icon;
+ for (var key in Constants.DEVICE_TYPE) {
+ if (Constants.DEVICE_TYPE[key] == target)
+ return true;
+ }
+ return false;
+ }
+ };
+
+ /**
+ * Creates an element in the list of bluetooth devices.
+ * @param {{name: string,
+ * address: string,
+ * icon: Constants.DEVICE_TYPE,
+ * paired: boolean,
+ * connected: boolean,
+ * pairing: string|undefined,
+ * passkey: number|undefined,
+ * entered: number|undefined}} device
+ * Decription of the bluetooth device.
+ * @constructor
+ */
+ function BluetoothItem(device) {
+ var el = $('bluetooth-item-template').cloneNode(true);
+ el.__proto__ = BluetoothItem.prototype;
+ el.removeAttribute('id');
+ el.hidden = false;
+ el.data = {};
+ for (var key in device)
+ el.data[key] = device[key];
+ el.decorate();
+ return el;
+ }
+
+ BluetoothItem.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ this.className = 'bluetooth-item';
+ this.connected = this.data.connected;
+ // Though strictly speaking, a connected device will also be paired,
+ // we are interested in tracking paired devices that are not connected.
+ this.paired = this.data.paired && !this.data.connected;
+ this.connecting = !!this.data.pairing;
+ this.addLabels_();
+ this.addButtons_();
+ },
+
+ /**
+ * Retrieves the descendent element with the matching class name.
+ * @param {string} className The class name for the target element.
+ * @return {Element|undefined} Returns the matching element if
+ * found and unique.
+ * @private
+ */
+ getNodeByClass_:function(className) {
+ var elements = this.getElementsByClassName(className);
+ if (elements && elements.length == 1)
+ return elements[0];
+ },
+
+ /**
+ * Sets the text content for an element.
+ * @param {string} className The class name of the target element.
+ * @param {string} label Text content for the element.
+ * @private
+ */
+ setLabel_: function(className, label) {
+ var el = this.getNodeByClass_(className);
+ el.textContent = label;
+ },
+
+ /**
+ * Adds an element containing the display name, status and device pairing
+ * instructions.
+ * @private
+ */
+ addLabels_: function() {
+ this.setLabel_('network-name-label', this.data.name);
+ var status;
+ if (this.data.connected)
+ status = Constants.DEVICE_STATUS.CONNECTED;
+ else if (this.data.pairing)
+ status = Constants.DEVICE_STATUS.CONNECTING;
+ if (status) {
+ var statusMessage = templateData[status];
+ if (statusMessage)
+ this.setLabel_('network-status-label', statusMessage);
+ if (this.connecting) {
+ var spinner = this.getNodeByClass_('inline-spinner');
+ spinner.hidden = false;
+ }
+ }
+ if (this.data.pairing)
+ this.addPairingInstructions_();
+ },
+
+ /**
+ * Adds instructions on how to complete the pairing process.
+ * @param {!Element} textDiv Target element for inserting the instructions.
+ * @private
+ */
+ addPairingInstructions_: function() {
+ var instructionsEl = this.getNodeByClass_('bluetooth-instructions');
+ var message = templateData[this.data.pairing];
+ var array = this.formatInstructions_(message);
+ for (var i = 0; i < array.length; i++) {
+ instructionsEl.appendChild(array[i]);
+ }
+ if (this.data.pairing == Constants.PAIRING.ENTER_PASSKEY) {
+ var input = this.ownerDocument.createElement('input');
+ input.type = 'text';
+ input.className = 'bluetooth-passkey-field';
+ instructionsEl.appendChild(input);
+ }
+ },
+
+ /**
+ * Formats the pairing instruction, which may contain labels for
+ * substitution. The label '%1' is replaced with the passkey, and '%2'
+ * is replaced with the name of the bluetooth device. Formatting of the
+ * passkey depends on the type of validation.
+ * @param {string} instructions The source instructions to format.
+ * @return {Array.<Element>} Array of formatted elements.
+ */
+ formatInstructions_: function(instructions) {
+ var array = [];
+ var index = instructions.indexOf('%');
+ if (index >= 0) {
+ array.push(this.createTextElement_(instructions.substring(0, index)));
+ var labelPlaceholder = instructions.charAt(index + 1);
+ // ... handle the placeholder
+ switch (labelPlaceholder) {
+ case '1':
+ array.push(this.createPasskeyElement_());
+ break;
+ case '2':
+ array.push(this.createTextElement_(this.data.name));
+ }
+ array = array.concat(this.formatInstructions_(instructions.substring(
+ index + 2)));
+ } else {
+ array.push(this.createTextElement_(instructions));
+ }
+ return array;
+ },
+
+ /**
+ * Formats an element for displaying the passkey.
+ * @return {Element} Element containing the passkey.
+ */
+ createPasskeyElement_: function() {
+ var passkeyEl = document.createElement('div');
+ if (this.data.pairing == Constants.PAIRING.REMOTE_PASSKEY) {
+ passkeyEl.className = 'bluetooth-remote-passkey';
+ var key = String(this.data.passkey);
+ var progress = this.data.entered;
+ for (var i = 0; i < key.length; i++) {
+ var keyEl = document.createElement('div');
+ keyEl.textContent = key.charAt(i);
+ keyEl.className = 'bluetooth-passkey-char';
+ if (i < progress)
+ keyEl.classList.add('key-typed');
+ passkeyEl.appendChild(keyEl);
+ }
+ // Add return key symbol.
+ var keyEl = document.createElement('div');
+ keyEl.className = 'bluetooth-passkey-char';
+ keyEl.textContent = '\u23ce';
+ passkeyEl.appendChild(keyEl);
+ } else {
+ passkeyEl.className = 'bluetooth-confirm-passkey';
+ passkeyEl.textContent = this.data.passkey;
+ }
+ return passkeyEl;
+ },
+
+ /**
+ * Adds a text element.
+ * @param {string} text The text content of the new element.
+ * @param {string=} opt_style Optional parameter for the CSS class for
+ * formatting the text element.
+ * @return {Element} Element containing the text.
+ */
+ createTextElement_: function(text, array, opt_style) {
+ var el = this.ownerDocument.createElement('span');
+ el.textContent = text;
+ if (opt_style)
+ el.className = opt_style;
+ return el;
+ },
+
+ /**
+ * Adds buttons for updating the connectivity of a device.
+ * @private.
+ */
+ addButtons_: function() {
+ var buttonsDiv = this.getNodeByClass_('bluetooth-button-group');
+ var buttonLabelKey = null;
+ var callbackType = null;
+ if (this.connected) {
+ buttonLabelKey = 'bluetoothDisconnectDevice';
+ callbackType = 'disconnect';
+ } else if (this.paired) {
+ buttonLabelKey = 'bluetoothForgetDevice';
+ callbackType = 'forget';
+ } else if (this.connecting) {
+ if (this.data.pairing == Constants.PAIRING.CONFIRM_PASSKEY) {
+ buttonLabelKey = 'bluetoothRejectPasskey';
+ callbackType = 'reject';
+ } else {
+ buttonLabelKey = 'bluetoothCancel';
+ callbackType = 'cancel';
+ }
+ } else {
+ buttonLabelKey = 'bluetoothConnectDevice';
+ callbackType = 'connect';
+ }
+ if (buttonLabelKey && callbackType) {
+ var buttonEl = this.ownerDocument.createElement('button');
+ buttonEl.textContent = localStrings.getString(buttonLabelKey);
+ var self = this;
+ var callback = function(e) {
+ chrome.send('updateBluetoothDevice',
+ [self.data.address, callbackType]);
+ }
+ buttonEl.addEventListener('click', callback);
+ buttonsDiv.appendChild(buttonEl);
+ }
+ if (this.data.pairing == Constants.PAIRING.CONFIRM_PASSKEY ||
+ this.data.pairing == Constants.PAIRING.ENTER_PASSKEY) {
+ var buttonEl = this.ownerDocument.createElement('button');
+ buttonEl.className = 'accept-pairing-button';
+ var msg = this.data.pairing == Constants.PAIRING.CONFIRM_PASSKEY ?
+ 'bluetoothAcceptPasskey' : 'bluetoothConnectDevice';
+ buttonEl.textContent = localStrings.getString(msg);
+ var self = this;
+ var callback = function(e) {
+ var passkey = self.data.passkey;
+ if (self.data.pairing == Constants.PAIRING.ENTER_PASSKEY) {
+ var passkeyField = self.getNodeByClass_('bluetooth-passkey-field');
+ passkey = passkeyField.value;
+ }
+ chrome.send('updateBluetoothDevice',
+ [self.data.address, 'connect', String(passkey)]);
+ }
+ buttonEl.addEventListener('click', callback);
+ buttonsDiv.insertBefore(buttonEl, buttonsDiv.firstChild);
+ }
+ this.appendChild(buttonsDiv);
+ }
+ };
+
+ cr.defineProperty(BluetoothItem, 'connected', cr.PropertyKind.BOOL_ATTR);
+
+ cr.defineProperty(BluetoothItem, 'paired', cr.PropertyKind.BOOL_ATTR);
+
+ cr.defineProperty(BluetoothItem, 'connecting', cr.PropertyKind.BOOL_ATTR);
+
+ return {
+ Constants: Constants,
+ BluetoothListElement: BluetoothListElement
+ };
+});

Powered by Google App Engine
This is Rietveld 408576698