| // 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. |
| |
| |
| // Network status constants. |
| const StatusConnected = 'connected'; |
| const StatusDisconnected = 'disconnected'; |
| const StatusConnecting = 'connecting'; |
| const StatusError = 'error'; |
| |
| const NetworkOther = 'other'; |
| |
| // Setup css canvas 'spinner-circle' |
| (function() { |
| var lineWidth = 3; |
| var r = 8; |
| var ctx = document.getCSSCanvasContext('2d', 'spinner-circle', 2 * r, 2 * r); |
| |
| ctx.lineWidth = lineWidth; |
| ctx.lineCap = 'round'; |
| ctx.lineJoin = 'round'; |
| |
| ctx.strokeStyle = '#4e73c7'; |
| ctx.beginPath(); |
| ctx.moveTo(lineWidth / 2, r - lineWidth / 2); |
| ctx.arc(r, r, r - lineWidth / 2, Math.PI, Math.PI * 3 / 2); |
| ctx.stroke(); |
| })(); |
| |
| /** |
| * Sends "connect" using the 'action' WebUI message. |
| */ |
| function sendConnect(index, passphrase, identity, auto_connect) { |
| chrome.send('action', |
| ['connect', |
| String(index), |
| passphrase, |
| identity, |
| auto_connect ? '1' : '0']); |
| } |
| |
| var networkMenuItemProto = (function() { |
| var networkMenuItem = cr.doc.createElement('div'); |
| networkMenuItem.innerHTML = '<div class="network-menu-item">' + |
| '<div class="network-label-icon">' + |
| '<div class="network-label"></div>' + |
| '<div class="network-icon hidden"></div>' + |
| '</div>' + |
| '<div class="network-status hidden"></div>' + |
| '<div class="hidden"></div>' + |
| '</div>'; |
| return networkMenuItem; |
| })(); |
| |
| var NetworkMenuItem = cr.ui.define(function() { |
| return networkMenuItemProto.cloneNode(true); |
| }); |
| |
| NetworkMenuItem.prototype = { |
| __proto__: MenuItem.prototype, |
| |
| ssidEdit: null, |
| passwordEdit: null, |
| autoConnectCheckbox: null, |
| |
| /** |
| * The label element. |
| * @private |
| */ |
| get label_() { |
| return this.firstElementChild.firstElementChild.firstElementChild; |
| }, |
| |
| /** |
| * The icon element. |
| * @private |
| */ |
| get icon_() { |
| return this.label_.nextElementSibling; |
| }, |
| |
| /** |
| * The status area element. |
| * @private |
| */ |
| get status_() { |
| return this.firstElementChild.firstElementChild.nextElementSibling; |
| }, |
| |
| /** |
| * The action area container element. |
| * @private |
| */ |
| get action_() { |
| return this.status_.nextElementSibling; |
| }, |
| |
| /** |
| * Set status message. |
| * @param {string} message The message to display in status area. |
| * @private |
| */ |
| setStatus_: function(message) { |
| if (message) { |
| this.status_.textContent = message; |
| this.status_.classList.remove('hidden'); |
| } else { |
| this.status_.classList.add('hidden'); |
| } |
| }, |
| |
| /** |
| * Set status icon. |
| * @param {string} icon Source url for the icon image. |
| * @private |
| */ |
| setIcon_: function(icon) { |
| if (icon) { |
| this.icon_.style.backgroundImage = 'url(' + icon + ')'; |
| this.icon_.classList.remove('hidden'); |
| } else { |
| this.icon_.classList.add('hidden'); |
| } |
| }, |
| |
| /** |
| * Handle reconnect. |
| * @private |
| */ |
| handleConnect_ : function(e) { |
| var index = this.menu_.getMenuItemIndexOf(this); |
| if (this.ssidEdit && this.passwordEdit) { |
| if (this.ssidEdit.value) { |
| sendConnect(index, |
| this.passwordEdit.value, |
| this.ssidEdit.value, |
| this.autoConnectCheckbox.checked); |
| } |
| } else if (this.passwordEdit) { |
| if (this.passwordEdit.value) { |
| sendConnect(index, |
| this.passwordEdit.value, '', this.autoConnectCheckbox.checked); |
| } |
| } else { |
| if (this.attrs.remembered) { |
| sendConnect(index, this.attrs.passphrase, '', this.attrs.auto_connect); |
| } else { |
| sendConnect(index, '', '', this.autoConnectCheckbox.checked); |
| } |
| } |
| }, |
| |
| /** |
| * Handle keydown event in ssid edit. |
| * @private |
| */ |
| handleSsidEditKeydown_: function(e) { |
| if (e.target == this.ssidEdit && |
| e.keyIdentifier == 'Enter') { |
| this.passwordEdit.focus(); |
| } |
| }, |
| |
| /** |
| * Handle keydown event in password edit. |
| * @private |
| */ |
| handlePassEditKeydown_: function(e) { |
| if (e.target == this.passwordEdit && |
| e.keyIdentifier == 'Enter') { |
| this.handleConnect_(); |
| } |
| }, |
| |
| /** |
| * Returns whether action area is visible. |
| * @private |
| */ |
| isActionVisible_: function() { |
| return !this.action_.classList.contains('hidden'); |
| }, |
| |
| /** |
| * Show/hide action area. |
| * @private |
| */ |
| showAction_: function(show) { |
| var visible = this.isActionVisible_(); |
| if (show && !visible) { |
| this.action_.classList.remove('hidden'); |
| } else if (!show && visible) { |
| this.action_.classList.add('hidden'); |
| } |
| }, |
| |
| /** |
| * Add network name edit to action area. |
| * @private |
| */ |
| addSsidEdit_: function() { |
| this.ssidEdit = this.ownerDocument.createElement('input'); |
| this.ssidEdit.type = 'text'; |
| this.ssidEdit.placeholder = localStrings.getString('ssid_prompt'); |
| this.ssidEdit.pattern = '^\\S+$'; |
| this.ssidEdit.addEventListener('keydown', |
| this.handleSsidEditKeydown_.bind(this)); |
| |
| var box = this.ownerDocument.createElement('div'); |
| box.appendChild(this.ssidEdit); |
| this.action_.appendChild(box); |
| }, |
| |
| /** |
| * Add password edit to action area. |
| * @private |
| */ |
| addPasswordEdit_: function() { |
| this.passwordEdit = this.ownerDocument.createElement('input'); |
| this.passwordEdit.type = 'password'; |
| this.passwordEdit.placeholder = localStrings.getString('pass_prompt'); |
| this.passwordEdit.pattern = '^\\S+$'; |
| this.passwordEdit.addEventListener('keydown', |
| this.handlePassEditKeydown_.bind(this)); |
| |
| var box = this.ownerDocument.createElement('div'); |
| box.appendChild(this.passwordEdit); |
| this.action_.appendChild(box); |
| }, |
| |
| /** |
| * Add auto-connect this network check box to action area. |
| * @private |
| */ |
| addAutoConnectCheckbox_: function() { |
| this.autoConnectCheckbox = this.ownerDocument.createElement('input'); |
| this.autoConnectCheckbox.type = 'checkbox'; |
| this.autoConnectCheckbox.checked = this.attrs.auto_connect; |
| |
| var autoConnectSpan = this.ownerDocument.createElement('span'); |
| autoConnectSpan.textContent = |
| localStrings.getString('auto_connect_this_network'); |
| |
| var autoConnectLabel = this.ownerDocument.createElement('label'); |
| autoConnectLabel.appendChild(this.autoConnectCheckbox); |
| autoConnectLabel.appendChild(autoConnectSpan); |
| |
| this.action_.appendChild(autoConnectLabel); |
| }, |
| |
| /** |
| * Internal method to initiailze the MenuItem. |
| * @private |
| */ |
| initMenuItem_: function() { |
| // *TODO: eliminate code duplication with menu.js |
| // MenuItem.prototype.initMenuItem_(); |
| var attrs = this.attrs; |
| this.classList.add(attrs.type); |
| this.menu_.addHandlers(this, this); |
| |
| //////// NetworkMenuItem specific code: |
| // TODO: Handle specific types of network, connecting icon. |
| this.label_.textContent = attrs.label; |
| |
| if (attrs.network_type == NetworkOther) { |
| this.addSsidEdit_(); |
| this.addPasswordEdit_(); |
| this.addAutoConnectCheckbox_(); |
| } else if (attrs.status && attrs.status != 'unknown') { |
| if (attrs.status == StatusConnected) { |
| this.setStatus_(attrs.ip_address); |
| } else if (attrs.status == StatusConnecting) { |
| this.setStatus_(attrs.message); |
| |
| this.icon_.classList.add('spinner'); |
| this.icon_.classList.remove('hidden'); |
| } else if (attrs.status == StatusError) { |
| this.setStatus_(attrs.message); |
| this.setIcon_('chrome://theme/IDR_WARNING'); |
| |
| var button = this.ownerDocument.createElement('button'); |
| button.textContent = localStrings.getString('reconnect'); |
| button.addEventListener('click', this.handleConnect_.bind(this)); |
| var box = this.ownerDocument.createElement('div'); |
| box.appendChild(button); |
| this.action_.appendChild(box); |
| |
| this.showAction_(true); |
| } |
| |
| if (attrs.need_passphrase) { |
| this.addPasswordEdit_(); |
| } |
| |
| this.addAutoConnectCheckbox_(); |
| } |
| //////// End NetworkMenuItem specifi code |
| |
| if (attrs.font) { |
| this.label_.style.font = attrs.font; |
| |
| var base_font = attrs.font.replace(/bold/, '').replace(/italic/, ''); |
| this.status_.style.font = base_font; |
| this.action_.style.font = base_font; |
| } |
| }, |
| |
| /** @inheritDoc */ |
| activate: function() { |
| // Close action area and connect if it is visible. |
| if (this.isActionVisible_()) { |
| this.showAction_(false); |
| this.handleConnect_(); |
| return; |
| } |
| |
| // Show action area for encrypted network and 'other' network. |
| if ((this.attrs.network_type == NetworkOther || |
| this.attrs.status == StatusDisconnected) && |
| this.attrs.need_passphrase && |
| !this.isActionVisible_()) { |
| this.showAction_(true); |
| return; |
| } |
| |
| MenuItem.prototype.activate.call(this); |
| } |
| }; |
| |
| |
| var NetworkMenu = cr.ui.define('div'); |
| |
| NetworkMenu.prototype = { |
| __proto__: Menu.prototype, |
| |
| /** @inheritDoc */ |
| createMenuItem: function(attrs) { |
| if (attrs.type == 'command') { |
| return new NetworkMenuItem(); |
| } else { |
| return new MenuItem(); |
| } |
| }, |
| |
| /** @inheritDoc */ |
| onClick_: function(event, item) { |
| // If item is a NetworkMenuItem, it must have at least one of the following. |
| if (item.autoConnectCheckbox || item.ssidEdit || item.passwordEdit) { |
| // Ignore clicks other than on the NetworkMenuItem itself. |
| if (event.target == item.autoConnectCheckbox || |
| event.target == item.autoConnectCheckbox.nextElementSibling || |
| event.target == item.ssidEdit || |
| event.target == item.passwordEdit) { |
| return; |
| } |
| } |
| |
| Menu.prototype.onClick_.call(this, event, item); |
| }, |
| }; |