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 |