Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / chromeos / network_menu.js
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.
4
5
6 // Network status constants.
7 const StatusConnected = 'connected';
8 const StatusDisconnected = 'disconnected';
9 const StatusConnecting = 'connecting';
10 const StatusError = 'error';
11
12 const NetworkOther = 'other';
13
14 // Setup css canvas 'spinner-circle'
15 (function() {
16   var lineWidth = 3;
17   var r = 8;
18   var ctx = document.getCSSCanvasContext('2d', 'spinner-circle', 2 * r, 2 * r);
19
20   ctx.lineWidth = lineWidth;
21   ctx.lineCap = 'round';
22   ctx.lineJoin = 'round';
23
24   ctx.strokeStyle = '#4e73c7';
25   ctx.beginPath();
26   ctx.moveTo(lineWidth / 2, r - lineWidth / 2);
27   ctx.arc(r, r, r - lineWidth / 2, Math.PI, Math.PI * 3 / 2);
28   ctx.stroke();
29 })();
30
31 /**
32  * Sends "connect" using the 'action' WebUI message.
33  */
34 function sendConnect(index, passphrase, identity, auto_connect) {
35   chrome.send('action',
36       ['connect',
37        String(index),
38        passphrase,
39        identity,
40        auto_connect ? '1' : '0']);
41 }
42
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>' +
49           '</div>' +
50           '<div class="network-status hidden"></div>' +
51           '<div class="hidden"></div>' +
52         '</div>';
53     return networkMenuItem;
54   })();
55
56 var NetworkMenuItem = cr.ui.define(function() {
57     return networkMenuItemProto.cloneNode(true);
58   });
59
60 NetworkMenuItem.prototype = {
61   __proto__: MenuItem.prototype,
62
63   ssidEdit: null,
64   passwordEdit: null,
65   autoConnectCheckbox: null,
66
67   /**
68    * The label element.
69    * @private
70    */
71   get label_() {
72     return this.firstElementChild.firstElementChild.firstElementChild;
73   },
74
75   /**
76    * The icon element.
77    * @private
78    */
79   get icon_() {
80     return this.label_.nextElementSibling;
81   },
82
83   /**
84    * The status area element.
85    * @private
86    */
87   get status_() {
88     return this.firstElementChild.firstElementChild.nextElementSibling;
89   },
90
91   /**
92    * The action area container element.
93    * @private
94    */
95   get action_() {
96     return this.status_.nextElementSibling;
97   },
98
99   /**
100    * Set status message.
101    * @param {string} message The message to display in status area.
102    * @private
103    */
104   setStatus_: function(message) {
105     if (message) {
106       this.status_.textContent = message;
107       this.status_.classList.remove('hidden');
108     } else {
109       this.status_.classList.add('hidden');
110     }
111   },
112
113   /**
114    * Set status icon.
115    * @param {string} icon Source url for the icon image.
116    * @private
117    */
118   setIcon_: function(icon) {
119     if (icon) {
120       this.icon_.style.backgroundImage = 'url(' + icon + ')';
121       this.icon_.classList.remove('hidden');
122     } else {
123       this.icon_.classList.add('hidden');
124     }
125   },
126
127   /**
128    * Handle reconnect.
129    * @private
130    */
131   handleConnect_ : function(e) {
132     var index = this.menu_.getMenuItemIndexOf(this);
133     if (this.ssidEdit && this.passwordEdit) {
134       if (this.ssidEdit.value) {
135         sendConnect(index,
136             this.passwordEdit.value,
137             this.ssidEdit.value,
138             this.autoConnectCheckbox.checked);
139       }
140     } else if (this.passwordEdit) {
141       if (this.passwordEdit.value) {
142         sendConnect(index,
143             this.passwordEdit.value, '', this.autoConnectCheckbox.checked);
144       }
145     } else {
146       if (this.attrs.remembered) {
147         sendConnect(index, this.attrs.passphrase, '', this.attrs.auto_connect);
148       } else {
149         sendConnect(index, '', '', this.autoConnectCheckbox.checked);
150       }
151     }
152   },
153
154   /**
155    * Handle keydown event in ssid edit.
156    * @private
157    */
158   handleSsidEditKeydown_: function(e) {
159     if (e.target == this.ssidEdit &&
160         e.keyIdentifier == 'Enter') {
161       this.passwordEdit.focus();
162     }
163   },
164
165   /**
166    * Handle keydown event in password edit.
167    * @private
168    */
169   handlePassEditKeydown_: function(e) {
170     if (e.target == this.passwordEdit &&
171         e.keyIdentifier == 'Enter') {
172       this.handleConnect_();
173     }
174   },
175
176   /**
177    * Returns whether action area is visible.
178    * @private
179    */
180   isActionVisible_: function() {
181     return !this.action_.classList.contains('hidden');
182   },
183
184   /**
185    * Show/hide action area.
186    * @private
187    */
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');
194     }
195   },
196
197   /**
198    * Add network name edit to action area.
199    * @private
200    */
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));
208
209     var box = this.ownerDocument.createElement('div');
210     box.appendChild(this.ssidEdit);
211     this.action_.appendChild(box);
212   },
213
214   /**
215    * Add password edit to action area.
216    * @private
217    */
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));
225
226     var box = this.ownerDocument.createElement('div');
227     box.appendChild(this.passwordEdit);
228     this.action_.appendChild(box);
229   },
230
231   /**
232    * Add auto-connect this network check box to action area.
233    * @private
234    */
235   addAutoConnectCheckbox_: function() {
236     this.autoConnectCheckbox = this.ownerDocument.createElement('input');
237     this.autoConnectCheckbox.type = 'checkbox';
238     this.autoConnectCheckbox.checked = this.attrs.auto_connect;
239
240     var autoConnectSpan = this.ownerDocument.createElement('span');
241     autoConnectSpan.textContent =
242         localStrings.getString('auto_connect_this_network');
243
244     var autoConnectLabel = this.ownerDocument.createElement('label');
245     autoConnectLabel.appendChild(this.autoConnectCheckbox);
246     autoConnectLabel.appendChild(autoConnectSpan);
247
248     this.action_.appendChild(autoConnectLabel);
249   },
250
251   /**
252    * Internal method to initiailze the MenuItem.
253    * @private
254    */
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);
261
262     //////// NetworkMenuItem specific code:
263     // TODO: Handle specific types of network, connecting icon.
264     this.label_.textContent = attrs.label;
265
266     if (attrs.network_type == NetworkOther) {
267       this.addSsidEdit_();
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);
275
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');
281
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);
288
289         this.showAction_(true);
290       }
291
292       if (attrs.need_passphrase) {
293         this.addPasswordEdit_();
294       }
295
296       this.addAutoConnectCheckbox_();
297     }
298     //////// End NetworkMenuItem specifi code
299
300     if (attrs.font) {
301       this.label_.style.font = attrs.font;
302
303       var baseFont = attrs.font.replace(/bold/, '').replace(/italic/, '');
304       this.status_.style.font = baseFont;
305       this.action_.style.font = baseFont;
306     }
307   },
308
309   /** @override */
310   activate: function() {
311     // Close action area and connect if it is visible.
312     if (this.isActionVisible_()) {
313       this.showAction_(false);
314       this.handleConnect_();
315       return;
316     }
317
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);
324       return;
325     }
326
327     MenuItem.prototype.activate.call(this);
328   }
329 };
330
331
332 var NetworkMenu = cr.ui.define('div');
333
334 NetworkMenu.prototype = {
335   __proto__: Menu.prototype,
336
337   /** @override */
338   createMenuItem: function(attrs) {
339     if (attrs.type == 'command') {
340       return new NetworkMenuItem();
341     } else {
342       return new MenuItem();
343     }
344   },
345
346   /** @override */
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) {
355         return;
356       }
357     }
358
359     Menu.prototype.onClick_.call(this, event, item);
360   },
361 };