| OLD | NEW |
| (Empty) |
| 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 }; | |
| OLD | NEW |