| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of html; | 5 part of html; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Works with KeyboardEvent and KeyEvent to determine how to expose information | 8 * Works with KeyboardEvent and KeyEvent to determine how to expose information |
| 9 * about Key(board)Events. This class functions like an EventListenerList, and | 9 * about Key(board)Events. This class functions like an EventListenerList, and |
| 10 * provides a consistent interface for the Dart | 10 * provides a consistent interface for the Dart |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 case KeyCode.SINGLE_QUOTE: | 252 case KeyCode.SINGLE_QUOTE: |
| 253 return 39; // ' | 253 return 39; // ' |
| 254 } | 254 } |
| 255 return event.keyCode; | 255 return event.keyCode; |
| 256 } | 256 } |
| 257 | 257 |
| 258 /** | 258 /** |
| 259 * Returns true if the key fires a keypress event in the current browser. | 259 * Returns true if the key fires a keypress event in the current browser. |
| 260 */ | 260 */ |
| 261 bool _firesKeyPressEvent(KeyEvent event) { | 261 bool _firesKeyPressEvent(KeyEvent event) { |
| 262 if (!_Device.isIE && !_Device.isWebKit) { | 262 if (!Device.isIE && !Device.isWebKit) { |
| 263 return true; | 263 return true; |
| 264 } | 264 } |
| 265 | 265 |
| 266 if (_Device.userAgent.contains('Mac') && event.altKey) { | 266 if (Device.userAgent.contains('Mac') && event.altKey) { |
| 267 return KeyCode.isCharacterKey(event.keyCode); | 267 return KeyCode.isCharacterKey(event.keyCode); |
| 268 } | 268 } |
| 269 | 269 |
| 270 // Alt but not AltGr which is represented as Alt+Ctrl. | 270 // Alt but not AltGr which is represented as Alt+Ctrl. |
| 271 if (event.altKey && !event.ctrlKey) { | 271 if (event.altKey && !event.ctrlKey) { |
| 272 return false; | 272 return false; |
| 273 } | 273 } |
| 274 | 274 |
| 275 // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress. | 275 // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress. |
| 276 if (!event.shiftKey && | 276 if (!event.shiftKey && |
| 277 (_keyDownList.last.keyCode == KeyCode.CTRL || | 277 (_keyDownList.last.keyCode == KeyCode.CTRL || |
| 278 _keyDownList.last.keyCode == KeyCode.ALT || | 278 _keyDownList.last.keyCode == KeyCode.ALT || |
| 279 _Device.userAgent.contains('Mac') && | 279 Device.userAgent.contains('Mac') && |
| 280 _keyDownList.last.keyCode == KeyCode.META)) { | 280 _keyDownList.last.keyCode == KeyCode.META)) { |
| 281 return false; | 281 return false; |
| 282 } | 282 } |
| 283 | 283 |
| 284 // Some keys with Ctrl/Shift do not issue keypress in WebKit. | 284 // Some keys with Ctrl/Shift do not issue keypress in WebKit. |
| 285 if (_Device.isWebKit && event.ctrlKey && event.shiftKey && ( | 285 if (Device.isWebKit && event.ctrlKey && event.shiftKey && ( |
| 286 event.keyCode == KeyCode.BACKSLASH || | 286 event.keyCode == KeyCode.BACKSLASH || |
| 287 event.keyCode == KeyCode.OPEN_SQUARE_BRACKET || | 287 event.keyCode == KeyCode.OPEN_SQUARE_BRACKET || |
| 288 event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET || | 288 event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET || |
| 289 event.keyCode == KeyCode.TILDE || | 289 event.keyCode == KeyCode.TILDE || |
| 290 event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH || | 290 event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH || |
| 291 event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA || | 291 event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA || |
| 292 event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH || | 292 event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH || |
| 293 event.keyCode == KeyCode.APOSTROPHE || | 293 event.keyCode == KeyCode.APOSTROPHE || |
| 294 event.keyCode == KeyCode.SINGLE_QUOTE)) { | 294 event.keyCode == KeyCode.SINGLE_QUOTE)) { |
| 295 return false; | 295 return false; |
| 296 } | 296 } |
| 297 | 297 |
| 298 switch (event.keyCode) { | 298 switch (event.keyCode) { |
| 299 case KeyCode.ENTER: | 299 case KeyCode.ENTER: |
| 300 // IE9 does not fire keypress on ENTER. | 300 // IE9 does not fire keypress on ENTER. |
| 301 return !_Device.isIE; | 301 return !Device.isIE; |
| 302 case KeyCode.ESC: | 302 case KeyCode.ESC: |
| 303 return !_Device.isWebKit; | 303 return !Device.isWebKit; |
| 304 } | 304 } |
| 305 | 305 |
| 306 return KeyCode.isCharacterKey(event.keyCode); | 306 return KeyCode.isCharacterKey(event.keyCode); |
| 307 } | 307 } |
| 308 | 308 |
| 309 /** | 309 /** |
| 310 * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and | 310 * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and |
| 311 * Opera all use). | 311 * Opera all use). |
| 312 */ | 312 */ |
| 313 int _normalizeKeyCodes(KeyboardEvent event) { | 313 int _normalizeKeyCodes(KeyboardEvent event) { |
| 314 // Note: This may change once we get input about non-US keyboards. | 314 // Note: This may change once we get input about non-US keyboards. |
| 315 if (_Device.isFirefox) { | 315 if (Device.isFirefox) { |
| 316 switch(event.keyCode) { | 316 switch(event.keyCode) { |
| 317 case KeyCode.FF_EQUALS: | 317 case KeyCode.FF_EQUALS: |
| 318 return KeyCode.EQUALS; | 318 return KeyCode.EQUALS; |
| 319 case KeyCode.FF_SEMICOLON: | 319 case KeyCode.FF_SEMICOLON: |
| 320 return KeyCode.SEMICOLON; | 320 return KeyCode.SEMICOLON; |
| 321 case KeyCode.MAC_FF_META: | 321 case KeyCode.MAC_FF_META: |
| 322 return KeyCode.META; | 322 return KeyCode.META; |
| 323 case KeyCode.WIN_KEY_FF_LINUX: | 323 case KeyCode.WIN_KEY_FF_LINUX: |
| 324 return KeyCode.WIN_KEY; | 324 return KeyCode.WIN_KEY; |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 return event.keyCode; | 327 return event.keyCode; |
| 328 } | 328 } |
| 329 | 329 |
| 330 /** Handle keydown events. */ | 330 /** Handle keydown events. */ |
| 331 void processKeyDown(KeyboardEvent e) { | 331 void processKeyDown(KeyboardEvent e) { |
| 332 // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window | 332 // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window |
| 333 // before we've caught a key-up event. If the last-key was one of these | 333 // before we've caught a key-up event. If the last-key was one of these |
| 334 // we reset the state. | 334 // we reset the state. |
| 335 if (_keyDownList.length > 0 && | 335 if (_keyDownList.length > 0 && |
| 336 (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey || | 336 (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey || |
| 337 _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey || | 337 _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey || |
| 338 _Device.userAgent.contains('Mac') && | 338 Device.userAgent.contains('Mac') && |
| 339 _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) { | 339 _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) { |
| 340 _keyDownList = []; | 340 _keyDownList = []; |
| 341 } | 341 } |
| 342 | 342 |
| 343 var event = new KeyEvent(e); | 343 var event = new KeyEvent(e); |
| 344 event._shadowKeyCode = _normalizeKeyCodes(event); | 344 event._shadowKeyCode = _normalizeKeyCodes(event); |
| 345 // Technically a "keydown" event doesn't have a charCode. This is | 345 // Technically a "keydown" event doesn't have a charCode. This is |
| 346 // calculated nonetheless to provide us with more information in giving | 346 // calculated nonetheless to provide us with more information in giving |
| 347 // as much information as possible on keypress about keycode and also | 347 // as much information as possible on keypress about keycode and also |
| 348 // charCode. | 348 // charCode. |
| 349 event._shadowCharCode = _findCharCodeKeyDown(event); | 349 event._shadowCharCode = _findCharCodeKeyDown(event); |
| 350 if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode && | 350 if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode && |
| 351 !_firesKeyPressEvent(event)) { | 351 !_firesKeyPressEvent(event)) { |
| 352 // Some browsers have quirks not firing keypress events where all other | 352 // Some browsers have quirks not firing keypress events where all other |
| 353 // browsers do. This makes them more consistent. | 353 // browsers do. This makes them more consistent. |
| 354 processKeyPress(event); | 354 processKeyPress(event); |
| 355 } | 355 } |
| 356 _keyDownList.add(event); | 356 _keyDownList.add(event); |
| 357 _dispatch(event); | 357 _dispatch(event); |
| 358 } | 358 } |
| 359 | 359 |
| 360 /** Handle keypress events. */ | 360 /** Handle keypress events. */ |
| 361 void processKeyPress(KeyboardEvent event) { | 361 void processKeyPress(KeyboardEvent event) { |
| 362 var e = new KeyEvent(event); | 362 var e = new KeyEvent(event); |
| 363 // IE reports the character code in the keyCode field for keypress events. | 363 // IE reports the character code in the keyCode field for keypress events. |
| 364 // There are two exceptions however, Enter and Escape. | 364 // There are two exceptions however, Enter and Escape. |
| 365 if (_Device.isIE) { | 365 if (Device.isIE) { |
| 366 if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) { | 366 if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) { |
| 367 e._shadowCharCode = 0; | 367 e._shadowCharCode = 0; |
| 368 } else { | 368 } else { |
| 369 e._shadowCharCode = e.keyCode; | 369 e._shadowCharCode = e.keyCode; |
| 370 } | 370 } |
| 371 } else if (_Device.isOpera) { | 371 } else if (Device.isOpera) { |
| 372 // Opera reports the character code in the keyCode field. | 372 // Opera reports the character code in the keyCode field. |
| 373 e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0; | 373 e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0; |
| 374 } | 374 } |
| 375 // Now we guestimate about what the keycode is that was actually | 375 // Now we guestimate about what the keycode is that was actually |
| 376 // pressed, given previous keydown information. | 376 // pressed, given previous keydown information. |
| 377 e._shadowKeyCode = _determineKeyCodeForKeypress(e); | 377 e._shadowKeyCode = _determineKeyCodeForKeypress(e); |
| 378 | 378 |
| 379 // Correct the key value for certain browser-specific quirks. | 379 // Correct the key value for certain browser-specific quirks. |
| 380 if (e._shadowKeyIdentifier != null && | 380 if (e._shadowKeyIdentifier != null && |
| 381 _keyIdentifier.containsKey(e._shadowKeyIdentifier)) { | 381 _keyIdentifier.containsKey(e._shadowKeyIdentifier)) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 401 _keyDownList.where((element) => element != toRemove).toList(); | 401 _keyDownList.where((element) => element != toRemove).toList(); |
| 402 } else if (_keyDownList.length > 0) { | 402 } else if (_keyDownList.length > 0) { |
| 403 // This happens when we've reached some international keyboard case we | 403 // This happens when we've reached some international keyboard case we |
| 404 // haven't accounted for or we haven't correctly eliminated all browser | 404 // haven't accounted for or we haven't correctly eliminated all browser |
| 405 // inconsistencies. Filing bugs on when this is reached is welcome! | 405 // inconsistencies. Filing bugs on when this is reached is welcome! |
| 406 _keyDownList.removeLast(); | 406 _keyDownList.removeLast(); |
| 407 } | 407 } |
| 408 _dispatch(e); | 408 _dispatch(e); |
| 409 } | 409 } |
| 410 } | 410 } |
| OLD | NEW |