1 // Copyright (c) 2011 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.
6 // Network status constants.
7 const StatusConnected
= 'connected';
8 const StatusDisconnected
= 'disconnected';
9 const StatusConnecting
= 'connecting';
10 const StatusError
= 'error';
12 const NetworkOther
= 'other';
14 // Setup css canvas 'spinner-circle'
18 var ctx
= document
.getCSSCanvasContext('2d', 'spinner-circle', 2 * r
, 2 * r
);
20 ctx
.lineWidth
= lineWidth
;
21 ctx
.lineCap
= 'round';
22 ctx
.lineJoin
= 'round';
24 ctx
.strokeStyle
= '#4e73c7';
26 ctx
.moveTo(lineWidth
/ 2, r
- lineWidth
/ 2);
27 ctx
.arc(r
, r
, r
- lineWidth
/ 2, Math
.PI
, Math
.PI
* 3 / 2);
32 * Sends "connect" using the 'action' WebUI message.
34 function sendConnect(index
, passphrase
, identity
, auto_connect
) {
40 auto_connect
? '1' : '0']);
43 var networkMenuItemProto
= (function() {
44 var networkMenuItem
= cr
.doc
.createElement('div');
45 networkMenuItem
.innerHTML
= '<div class="network-menu-item">' +
46 '<div class="network-label-icon">' +
47 '<div class="network-label"></div>' +
48 '<div class="network-icon hidden"></div>' +
50 '<div class="network-status hidden"></div>' +
51 '<div class="hidden"></div>' +
53 return networkMenuItem
;
56 var NetworkMenuItem
= cr
.ui
.define(function() {
57 return networkMenuItemProto
.cloneNode(true);
60 NetworkMenuItem
.prototype = {
61 __proto__
: MenuItem
.prototype,
65 autoConnectCheckbox
: null,
72 return this.firstElementChild
.firstElementChild
.firstElementChild
;
80 return this.label_
.nextElementSibling
;
84 * The status area element.
88 return this.firstElementChild
.firstElementChild
.nextElementSibling
;
92 * The action area container element.
96 return this.status_
.nextElementSibling
;
100 * Set status message.
101 * @param {string} message The message to display in status area.
104 setStatus_: function(message
) {
106 this.status_
.textContent
= message
;
107 this.status_
.classList
.remove('hidden');
109 this.status_
.classList
.add('hidden');
115 * @param {string} icon Source url for the icon image.
118 setIcon_: function(icon
) {
120 this.icon_
.style
.backgroundImage
= 'url(' + icon
+ ')';
121 this.icon_
.classList
.remove('hidden');
123 this.icon_
.classList
.add('hidden');
131 handleConnect_ : function(e
) {
132 var index
= this.menu_
.getMenuItemIndexOf(this);
133 if (this.ssidEdit
&& this.passwordEdit
) {
134 if (this.ssidEdit
.value
) {
136 this.passwordEdit
.value
,
138 this.autoConnectCheckbox
.checked
);
140 } else if (this.passwordEdit
) {
141 if (this.passwordEdit
.value
) {
143 this.passwordEdit
.value
, '', this.autoConnectCheckbox
.checked
);
146 if (this.attrs
.remembered
) {
147 sendConnect(index
, this.attrs
.passphrase
, '', this.attrs
.auto_connect
);
149 sendConnect(index
, '', '', this.autoConnectCheckbox
.checked
);
155 * Handle keydown event in ssid edit.
158 handleSsidEditKeydown_: function(e
) {
159 if (e
.target
== this.ssidEdit
&&
160 e
.keyIdentifier
== 'Enter') {
161 this.passwordEdit
.focus();
166 * Handle keydown event in password edit.
169 handlePassEditKeydown_: function(e
) {
170 if (e
.target
== this.passwordEdit
&&
171 e
.keyIdentifier
== 'Enter') {
172 this.handleConnect_();
177 * Returns whether action area is visible.
180 isActionVisible_: function() {
181 return !this.action_
.classList
.contains('hidden');
185 * Show/hide action area.
188 showAction_: function(show
) {
189 var visible
= this.isActionVisible_();
190 if (show
&& !visible
) {
191 this.action_
.classList
.remove('hidden');
192 } else if (!show
&& visible
) {
193 this.action_
.classList
.add('hidden');
198 * Add network name edit to action area.
201 addSsidEdit_: function() {
202 this.ssidEdit
= this.ownerDocument
.createElement('input');
203 this.ssidEdit
.type
= 'text';
204 this.ssidEdit
.placeholder
= localStrings
.getString('ssid_prompt');
205 this.ssidEdit
.pattern
= '^\\S+$';
206 this.ssidEdit
.addEventListener('keydown',
207 this.handleSsidEditKeydown_
.bind(this));
209 var box
= this.ownerDocument
.createElement('div');
210 box
.appendChild(this.ssidEdit
);
211 this.action_
.appendChild(box
);
215 * Add password edit to action area.
218 addPasswordEdit_: function() {
219 this.passwordEdit
= this.ownerDocument
.createElement('input');
220 this.passwordEdit
.type
= 'password';
221 this.passwordEdit
.placeholder
= localStrings
.getString('pass_prompt');
222 this.passwordEdit
.pattern
= '^\\S+$';
223 this.passwordEdit
.addEventListener('keydown',
224 this.handlePassEditKeydown_
.bind(this));
226 var box
= this.ownerDocument
.createElement('div');
227 box
.appendChild(this.passwordEdit
);
228 this.action_
.appendChild(box
);
232 * Add auto-connect this network check box to action area.
235 addAutoConnectCheckbox_: function() {
236 this.autoConnectCheckbox
= this.ownerDocument
.createElement('input');
237 this.autoConnectCheckbox
.type
= 'checkbox';
238 this.autoConnectCheckbox
.checked
= this.attrs
.auto_connect
;
240 var autoConnectSpan
= this.ownerDocument
.createElement('span');
241 autoConnectSpan
.textContent
=
242 localStrings
.getString('auto_connect_this_network');
244 var autoConnectLabel
= this.ownerDocument
.createElement('label');
245 autoConnectLabel
.appendChild(this.autoConnectCheckbox
);
246 autoConnectLabel
.appendChild(autoConnectSpan
);
248 this.action_
.appendChild(autoConnectLabel
);
252 * Internal method to initiailze the MenuItem.
255 initMenuItem_: function() {
256 // *TODO: eliminate code duplication with menu.js
257 // MenuItem.prototype.initMenuItem_();
258 var attrs
= this.attrs
;
259 this.classList
.add(attrs
.type
);
260 this.menu_
.addHandlers(this, this);
262 //////// NetworkMenuItem specific code:
263 // TODO: Handle specific types of network, connecting icon.
264 this.label_
.textContent
= attrs
.label
;
266 if (attrs
.network_type
== NetworkOther
) {
268 this.addPasswordEdit_();
269 this.addAutoConnectCheckbox_();
270 } else if (attrs
.status
&& attrs
.status
!= 'unknown') {
271 if (attrs
.status
== StatusConnected
) {
272 this.setStatus_(attrs
.ip_address
);
273 } else if (attrs
.status
== StatusConnecting
) {
274 this.setStatus_(attrs
.message
);
276 this.icon_
.classList
.add('spinner');
277 this.icon_
.classList
.remove('hidden');
278 } else if (attrs
.status
== StatusError
) {
279 this.setStatus_(attrs
.message
);
280 this.setIcon_('chrome://theme/IDR_WARNING');
282 var button
= this.ownerDocument
.createElement('button');
283 button
.textContent
= localStrings
.getString('reconnect');
284 button
.addEventListener('click', this.handleConnect_
.bind(this));
285 var box
= this.ownerDocument
.createElement('div');
286 box
.appendChild(button
);
287 this.action_
.appendChild(box
);
289 this.showAction_(true);
292 if (attrs
.need_passphrase
) {
293 this.addPasswordEdit_();
296 this.addAutoConnectCheckbox_();
298 //////// End NetworkMenuItem specifi code
301 this.label_
.style
.font
= attrs
.font
;
303 var baseFont
= attrs
.font
.replace(/bold/, '').replace(/italic/, '');
304 this.status_
.style
.font
= baseFont
;
305 this.action_
.style
.font
= baseFont
;
310 activate: function() {
311 // Close action area and connect if it is visible.
312 if (this.isActionVisible_()) {
313 this.showAction_(false);
314 this.handleConnect_();
318 // Show action area for encrypted network and 'other' network.
319 if ((this.attrs
.network_type
== NetworkOther
||
320 this.attrs
.status
== StatusDisconnected
) &&
321 this.attrs
.need_passphrase
&&
322 !this.isActionVisible_()) {
323 this.showAction_(true);
327 MenuItem
.prototype.activate
.call(this);
332 var NetworkMenu
= cr
.ui
.define('div');
334 NetworkMenu
.prototype = {
335 __proto__
: Menu
.prototype,
338 createMenuItem: function(attrs
) {
339 if (attrs
.type
== 'command') {
340 return new NetworkMenuItem();
342 return new MenuItem();
347 onClick_: function(event
, item
) {
348 // If item is a NetworkMenuItem, it must have at least one of the following.
349 if (item
.autoConnectCheckbox
|| item
.ssidEdit
|| item
.passwordEdit
) {
350 // Ignore clicks other than on the NetworkMenuItem itself.
351 if (event
.target
== item
.autoConnectCheckbox
||
352 event
.target
== item
.autoConnectCheckbox
.nextElementSibling
||
353 event
.target
== item
.ssidEdit
||
354 event
.target
== item
.passwordEdit
) {
359 Menu
.prototype.onClick_
.call(this, event
, item
);