Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview A simple virtual keyboard implementation. | 6 * @fileoverview A simple virtual keyboard implementation. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 var KEY_MODE = 'key'; | 9 var KEY_MODE = 'key'; |
| 10 var SHIFT_MODE = 'shift'; | 10 var SHIFT_MODE = 'shift'; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 | 85 |
| 86 /** | 86 /** |
| 87 * Send the given key to chrome, via the experimental extension API. | 87 * Send the given key to chrome, via the experimental extension API. |
| 88 * @param {string} key The key to send. | 88 * @param {string} key The key to send. |
| 89 * @param {string=} opt_type The type of event to send (keydown or keyup). If | 89 * @param {string=} opt_type The type of event to send (keydown or keyup). If |
| 90 * omitted send both keydown and keyup events. | 90 * omitted send both keydown and keyup events. |
| 91 * @return {void} | 91 * @return {void} |
| 92 */ | 92 */ |
| 93 function sendKey(key, type) { | 93 function sendKey(key, type) { |
| 94 var keyEvent = {'keyIdentifier': key}; | 94 var keyEvent = {'keyIdentifier': key}; |
| 95 if (!type || type == 'keydown') { | 95 if (!type || type == 'keydown' || type == 'keyup') { |
|
bryeung
2011/08/12 18:07:44
This if and the type parameter are now useless: ty
mazda
2011/08/16 09:45:50
Done.
| |
| 96 // A keypress event is automatically generated for printable characters | 96 // A keypress event is automatically generated for printable characters |
| 97 // immediately following the keydown event. | 97 // immediately following the keydown event. |
| 98 keyEvent.type = 'keydown'; | |
| 99 if (chrome.experimental) { | 98 if (chrome.experimental) { |
| 99 keyEvent.type = 'keydown'; | |
| 100 chrome.experimental.input.sendKeyboardEvent(keyEvent); | |
| 101 keyEvent.type = 'keyup'; | |
| 100 chrome.experimental.input.sendKeyboardEvent(keyEvent); | 102 chrome.experimental.input.sendKeyboardEvent(keyEvent); |
| 101 } | 103 } |
| 102 // Exit shift mode after pressing any key but space. | 104 // Exit shift mode after pressing any key but space. |
| 103 if (currentMode == SHIFT_MODE && key != 'Spacebar') { | 105 if (currentMode == SHIFT_MODE && key != 'Spacebar') { |
| 104 transitionMode(SHIFT_MODE); | 106 transitionMode(SHIFT_MODE); |
| 105 } | 107 } |
| 106 // Enter shift mode after typing a period for a new sentence. | 108 // Enter shift mode after typing a period for a new sentence. |
| 107 if (currentMode != SHIFT_MODE && key == '.') { | 109 if (currentMode != SHIFT_MODE && key == '.') { |
| 108 transitionMode(SHIFT_MODE); | 110 transitionMode(SHIFT_MODE); |
| 109 } | 111 } |
| 110 } | 112 } |
| 111 if (!type || type == 'keyup') { | |
| 112 keyEvent.type = 'keyup'; | |
| 113 if (chrome.experimental) { | |
| 114 chrome.experimental.input.sendKeyboardEvent(keyEvent); | |
| 115 } | |
| 116 } | |
| 117 } | 113 } |
| 118 | 114 |
| 119 /** | 115 /** |
| 120 * Add a child div element that represents the content of the given element. | 116 * Add a child div element that represents the content of the given element. |
| 121 * A child div element that represents a text content is added if | 117 * A child div element that represents a text content is added if |
| 122 * opt_textContent is given. Otherwise a child element that represents an image | 118 * opt_textContent is given. Otherwise a child element that represents an image |
| 123 * content is added. If the given element already has a child, the child element | 119 * content is added. If the given element already has a child, the child element |
| 124 * is modified. | 120 * is modified. |
| 125 * @param {Element} element The DOM Element to which the content is added. | 121 * @param {Element} element The DOM Element to which the content is added. |
| 126 * @param {string} opt_textContent The text to be inserted. | 122 * @param {string} opt_textContent The text to be inserted. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 148 /** | 144 /** |
| 149 * Set up the event handlers necessary to respond to mouse and touch events on | 145 * Set up the event handlers necessary to respond to mouse and touch events on |
| 150 * the virtual keyboard. | 146 * the virtual keyboard. |
| 151 * @param {BaseKey} key The BaseKey object corresponding to this key. | 147 * @param {BaseKey} key The BaseKey object corresponding to this key. |
| 152 * @param {Element} element The top-level DOM Element to set event handlers on. | 148 * @param {Element} element The top-level DOM Element to set event handlers on. |
| 153 * @param {function()} keyDownHandler The event handler called when the key is | 149 * @param {function()} keyDownHandler The event handler called when the key is |
| 154 * pressed. This will be called repeatedly when holding a repeating key. | 150 * pressed. This will be called repeatedly when holding a repeating key. |
| 155 * @param {function()=} opt_keyUpHandler The event handler called when the key | 151 * @param {function()=} opt_keyUpHandler The event handler called when the key |
| 156 * is released. This is only called once per actual key press. | 152 * is released. This is only called once per actual key press. |
| 157 */ | 153 */ |
| 158 function setupKeyEventHandlers(key, element, keyDownHandler, opt_keyUpHandler) { | 154 function setupKeyEventHandlers(key, element, keyDownHandler, opt_keyUpHandler) { |
|
bryeung
2011/08/12 18:07:44
This should no longer accept two handlers, as the
mazda
2011/08/16 09:45:50
Actually SymbolKey, ShfitKey and HideKeybaordKey a
| |
| 159 /** | 155 /** |
| 160 * Handle a key down event on the virtual key. | 156 * Handle a key down event on the virtual key. |
| 161 * @param {UIEvent} evt The UI event which triggered the key down. | 157 * @param {UIEvent} evt The UI event which triggered the key down. |
| 162 */ | 158 */ |
| 163 var downHandler = function(evt) { | 159 var downHandler = function(evt) { |
| 164 // Don't process a key down if the key is already down. | 160 // Don't process a key down if the key is already down. |
| 165 if (key.pressed) { | 161 if (key.pressed) { |
| 166 return; | 162 return; |
| 167 } | 163 } |
| 168 key.pressed = true; | 164 key.pressed = true; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 204 if (repeatKey.key == key) { | 200 if (repeatKey.key == key) { |
| 205 repeatKey.cancel(); | 201 repeatKey.cancel(); |
| 206 } | 202 } |
| 207 | 203 |
| 208 if (opt_keyUpHandler) { | 204 if (opt_keyUpHandler) { |
| 209 opt_keyUpHandler(); | 205 opt_keyUpHandler(); |
| 210 } | 206 } |
| 211 evt.preventDefault(); | 207 evt.preventDefault(); |
| 212 }; | 208 }; |
| 213 | 209 |
| 210 var outHandler = function(evt) { | |
| 211 // Reset key press state if the point goes out of the element. | |
| 212 key.pressed = false; | |
| 213 } | |
| 214 | |
| 214 // Setup mouse event handlers. | 215 // Setup mouse event handlers. |
| 215 element.addEventListener('mousedown', downHandler); | 216 element.addEventListener('mousedown', downHandler); |
| 216 element.addEventListener('mouseup', upHandler); | 217 element.addEventListener('mouseup', upHandler); |
| 217 element.addEventListener('mouseout', upHandler); | 218 element.addEventListener('mouseout', outHandler); |
| 218 | 219 |
| 219 // Setup touch handlers. | 220 // Setup touch handlers. |
| 220 element.addEventListener('touchstart', downHandler); | 221 element.addEventListener('touchstart', downHandler); |
| 221 element.addEventListener('touchend', upHandler); | 222 element.addEventListener('touchend', upHandler); |
| 223 // TODO(mazda): Add a handler for touchleave once Webkit supports it. | |
| 224 // element.addEventListener('touchleave', outHandler); | |
| 222 } | 225 } |
| 223 | 226 |
| 224 /** | 227 /** |
| 225 * Create closure for the sendKey function. | 228 * Create closure for the sendKey function. |
| 226 * @param {string} key The key paramater to sendKey. | 229 * @param {string} key The key paramater to sendKey. |
| 227 * @param {string=} type The type parameter to sendKey. | 230 * @param {string=} type The type parameter to sendKey. |
| 228 * @return {function()} A function which calls sendKey(key, type). | 231 * @return {function()} A function which calls sendKey(key, type). |
| 229 */ | 232 */ |
| 230 function sendKeyFunction(key, type) { | 233 function sendKeyFunction(key, type) { |
| 231 return function() { | 234 return function() { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 /** @inheritDoc */ | 358 /** @inheritDoc */ |
| 356 makeDOM: function(mode) { | 359 makeDOM: function(mode) { |
| 357 if (!this.modes_[mode]) { | 360 if (!this.modes_[mode]) { |
| 358 return null; | 361 return null; |
| 359 } | 362 } |
| 360 | 363 |
| 361 this.modeElements_[mode] = document.createElement('div'); | 364 this.modeElements_[mode] = document.createElement('div'); |
| 362 this.modeElements_[mode].className = 'key'; | 365 this.modeElements_[mode].className = 'key'; |
| 363 addContent(this.modeElements_[mode], this.modes_[mode].display); | 366 addContent(this.modeElements_[mode], this.modes_[mode].display); |
| 364 | 367 |
| 365 setupKeyEventHandlers(this, this.modeElements_[mode], | 368 setupKeyEventHandlers(this, this.modeElements_[mode], null, |
| 366 sendKeyFunction(this.modes_[mode].keyIdentifier, 'keydown'), | |
| 367 sendKeyFunction(this.modes_[mode].keyIdentifier, 'keyup')); | 369 sendKeyFunction(this.modes_[mode].keyIdentifier, 'keyup')); |
| 368 | 370 |
| 369 return this.modeElements_[mode]; | 371 return this.modeElements_[mode]; |
| 370 } | 372 } |
| 371 }; | 373 }; |
| 372 | 374 |
| 373 /** | 375 /** |
| 374 * A key which displays an SVG image. | 376 * A key which displays an SVG image. |
| 375 * @param {string} className The class that provides the image. | 377 * @param {string} className The class that provides the image. |
| 376 * @param {string} keyId The key identifier for the key. | 378 * @param {string} keyId The key identifier for the key. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 389 SvgKey.prototype = { | 391 SvgKey.prototype = { |
| 390 __proto__: BaseKey.prototype, | 392 __proto__: BaseKey.prototype, |
| 391 | 393 |
| 392 /** @inheritDoc */ | 394 /** @inheritDoc */ |
| 393 makeDOM: function(mode) { | 395 makeDOM: function(mode) { |
| 394 this.modeElements_[mode] = document.createElement('div'); | 396 this.modeElements_[mode] = document.createElement('div'); |
| 395 this.modeElements_[mode].className = 'key'; | 397 this.modeElements_[mode].className = 'key'; |
| 396 this.modeElements_[mode].classList.add(this.className_); | 398 this.modeElements_[mode].classList.add(this.className_); |
| 397 addContent(this.modeElements_[mode]); | 399 addContent(this.modeElements_[mode]); |
| 398 | 400 |
| 399 setupKeyEventHandlers(this, this.modeElements_[mode], | 401 if (this.repeat_) { |
| 400 sendKeyFunction(this.keyId_, 'keydown'), | 402 // send the key event on key down if key repeat is enabled |
| 401 sendKeyFunction(this.keyId_, 'keyup')); | 403 setupKeyEventHandlers(this, this.modeElements_[mode], |
| 404 sendKeyFunction(this.keyId_, 'keydown')); | |
|
bryeung
2011/08/12 18:07:44
Are you sure this behaviour matches Android?
Now,
mazda
2011/08/16 09:45:50
Yes, I checked that the delete key on Android keyb
| |
| 405 } else { | |
| 406 setupKeyEventHandlers(this, this.modeElements_[mode], null, | |
| 407 sendKeyFunction(this.keyId_, 'keyup')); | |
| 408 } | |
| 402 | 409 |
| 403 return this.modeElements_[mode]; | 410 return this.modeElements_[mode]; |
| 404 } | 411 } |
| 405 }; | 412 }; |
| 406 | 413 |
| 407 /** | 414 /** |
| 408 * A Key that remains the same through all modes. | 415 * A Key that remains the same through all modes. |
| 409 * @param {string} content The display text for the key. | 416 * @param {string} content The display text for the key. |
| 410 * @param {string} keyId The key identifier for the key. | 417 * @param {string} keyId The key identifier for the key. |
| 411 * @constructor | 418 * @constructor |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 422 SpecialKey.prototype = { | 429 SpecialKey.prototype = { |
| 423 __proto__: BaseKey.prototype, | 430 __proto__: BaseKey.prototype, |
| 424 | 431 |
| 425 /** @inheritDoc */ | 432 /** @inheritDoc */ |
| 426 makeDOM: function(mode) { | 433 makeDOM: function(mode) { |
| 427 this.modeElements_[mode] = document.createElement('div'); | 434 this.modeElements_[mode] = document.createElement('div'); |
| 428 this.modeElements_[mode].className = 'key'; | 435 this.modeElements_[mode].className = 'key'; |
| 429 this.modeElements_[mode].classList.add(this.className_); | 436 this.modeElements_[mode].classList.add(this.className_); |
| 430 addContent(this.modeElements_[mode], this.content_); | 437 addContent(this.modeElements_[mode], this.content_); |
| 431 | 438 |
| 432 setupKeyEventHandlers(this, this.modeElements_[mode], | 439 setupKeyEventHandlers(this, this.modeElements_[mode], null, |
| 433 sendKeyFunction(this.keyId_, 'keydown'), | |
| 434 sendKeyFunction(this.keyId_, 'keyup')); | 440 sendKeyFunction(this.keyId_, 'keyup')); |
| 435 | 441 |
| 436 return this.modeElements_[mode]; | 442 return this.modeElements_[mode]; |
| 437 } | 443 } |
| 438 }; | 444 }; |
| 439 | 445 |
| 440 /** | 446 /** |
| 441 * A shift key. | 447 * A shift key. |
| 442 * @constructor | 448 * @constructor |
| 443 * @extends {BaseKey} | 449 * @extends {BaseKey} |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 531 | 537 |
| 532 DotComKey.prototype = { | 538 DotComKey.prototype = { |
| 533 __proto__: BaseKey.prototype, | 539 __proto__: BaseKey.prototype, |
| 534 | 540 |
| 535 /** @inheritDoc */ | 541 /** @inheritDoc */ |
| 536 makeDOM: function(mode) { | 542 makeDOM: function(mode) { |
| 537 this.modeElements_[mode] = document.createElement('div'); | 543 this.modeElements_[mode] = document.createElement('div'); |
| 538 this.modeElements_[mode].className = 'key com'; | 544 this.modeElements_[mode].className = 'key com'; |
| 539 addContent(this.modeElements_[mode], '.com'); | 545 addContent(this.modeElements_[mode], '.com'); |
| 540 | 546 |
| 541 setupKeyEventHandlers(this, this.modeElements_[mode], | 547 setupKeyEventHandlers(this, this.modeElements_[mode], null, |
| 542 function() { | 548 function() { |
| 543 sendKey('.'); | 549 sendKey('.'); |
| 544 sendKey('c'); | 550 sendKey('c'); |
| 545 sendKey('o'); | 551 sendKey('o'); |
| 546 sendKey('m'); | 552 sendKey('m'); |
| 547 }); | 553 }); |
| 548 | 554 |
| 549 return this.modeElements_[mode]; | 555 return this.modeElements_[mode]; |
| 550 } | 556 } |
| 551 }; | 557 }; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 636 * @param {string} mode The mode to show. | 642 * @param {string} mode The mode to show. |
| 637 * @return {void} | 643 * @return {void} |
| 638 */ | 644 */ |
| 639 showMode: function(mode) { | 645 showMode: function(mode) { |
| 640 for (var i = 0; i < MODES.length; ++i) { | 646 for (var i = 0; i < MODES.length; ++i) { |
| 641 this.modeElements_[MODES[i]].style.display = 'none'; | 647 this.modeElements_[MODES[i]].style.display = 'none'; |
| 642 } | 648 } |
| 643 this.modeElements_[mode].style.display = '-webkit-box'; | 649 this.modeElements_[mode].style.display = '-webkit-box'; |
| 644 }, | 650 }, |
| 645 }; | 651 }; |
| OLD | NEW |