| OLD | NEW |
| 1 // Copyright 2014 The ChromeOS IME Authors. All Rights Reserved. | 1 // Copyright 2014 The ChromeOS IME Authors. All Rights Reserved. |
| 2 // limitations under the License. | 2 // limitations under the License. |
| 3 // See the License for the specific language governing permissions and | 3 // See the License for the specific language governing permissions and |
| 4 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 4 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 5 // distributed under the License is distributed on an "AS-IS" BASIS, | 5 // distributed under the License is distributed on an "AS-IS" BASIS, |
| 6 // Unless required by applicable law or agreed to in writing, software | 6 // Unless required by applicable law or agreed to in writing, software |
| 7 // | 7 // |
| 8 // http://www.apache.org/licenses/LICENSE-2.0 | 8 // http://www.apache.org/licenses/LICENSE-2.0 |
| 9 // | 9 // |
| 10 // You may obtain a copy of the License at | 10 // You may obtain a copy of the License at |
| 11 // you may not use this file except in compliance with the License. | 11 // you may not use this file except in compliance with the License. |
| 12 // Licensed under the Apache License, Version 2.0 (the "License"); | 12 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 13 // | 13 // |
| 14 goog.provide('i18n.input.chrome.inputview.Controller'); | 14 goog.provide('i18n.input.chrome.inputview.Controller'); |
| 15 | 15 |
| 16 goog.require('goog.Disposable'); | 16 goog.require('goog.Disposable'); |
| 17 goog.require('goog.array'); | 17 goog.require('goog.array'); |
| 18 goog.require('goog.async.Delay'); | 18 goog.require('goog.async.Delay'); |
| 19 goog.require('goog.dom'); | 19 goog.require('goog.dom'); |
| 20 goog.require('goog.dom.classlist'); | 20 goog.require('goog.dom.classlist'); |
| 21 goog.require('goog.events.EventHandler'); | 21 goog.require('goog.events.EventHandler'); |
| 22 goog.require('goog.events.EventType'); | 22 goog.require('goog.events.EventType'); |
| 23 goog.require('goog.i18n.bidi'); | 23 goog.require('goog.i18n.bidi'); |
| 24 goog.require('goog.object'); | 24 goog.require('goog.object'); |
| 25 goog.require('i18n.input.chrome.DataSource'); | 25 goog.require('i18n.input.chrome.DataSource'); |
| 26 goog.require('i18n.input.chrome.Statistics'); |
| 26 goog.require('i18n.input.chrome.inputview.Adapter'); | 27 goog.require('i18n.input.chrome.inputview.Adapter'); |
| 27 goog.require('i18n.input.chrome.inputview.CandidatesInfo'); | 28 goog.require('i18n.input.chrome.inputview.CandidatesInfo'); |
| 28 goog.require('i18n.input.chrome.inputview.ConditionName'); | 29 goog.require('i18n.input.chrome.inputview.ConditionName'); |
| 29 goog.require('i18n.input.chrome.inputview.Css'); | 30 goog.require('i18n.input.chrome.inputview.Css'); |
| 30 goog.require('i18n.input.chrome.inputview.KeyboardContainer'); | 31 goog.require('i18n.input.chrome.inputview.KeyboardContainer'); |
| 31 goog.require('i18n.input.chrome.inputview.M17nModel'); | 32 goog.require('i18n.input.chrome.inputview.M17nModel'); |
| 32 goog.require('i18n.input.chrome.inputview.Model'); | 33 goog.require('i18n.input.chrome.inputview.Model'); |
| 33 goog.require('i18n.input.chrome.inputview.PerfTracker'); | 34 goog.require('i18n.input.chrome.inputview.PerfTracker'); |
| 34 goog.require('i18n.input.chrome.inputview.ReadyState'); | 35 goog.require('i18n.input.chrome.inputview.ReadyState'); |
| 35 goog.require('i18n.input.chrome.inputview.Settings'); | 36 goog.require('i18n.input.chrome.inputview.Settings'); |
| 36 goog.require('i18n.input.chrome.inputview.SizeSpec'); | 37 goog.require('i18n.input.chrome.inputview.SizeSpec'); |
| 37 goog.require('i18n.input.chrome.inputview.SoundController'); | 38 goog.require('i18n.input.chrome.inputview.SoundController'); |
| 38 goog.require('i18n.input.chrome.inputview.SpecNodeName'); | 39 goog.require('i18n.input.chrome.inputview.SpecNodeName'); |
| 39 goog.require('i18n.input.chrome.inputview.StateType'); | 40 goog.require('i18n.input.chrome.inputview.StateType'); |
| 40 goog.require('i18n.input.chrome.inputview.Statistics'); | |
| 41 goog.require('i18n.input.chrome.inputview.SwipeDirection'); | 41 goog.require('i18n.input.chrome.inputview.SwipeDirection'); |
| 42 goog.require('i18n.input.chrome.inputview.elements.ElementType'); | 42 goog.require('i18n.input.chrome.inputview.elements.ElementType'); |
| 43 goog.require('i18n.input.chrome.inputview.elements.content.Candidate'); | 43 goog.require('i18n.input.chrome.inputview.elements.content.Candidate'); |
| 44 goog.require('i18n.input.chrome.inputview.elements.content.CandidateView'); | 44 goog.require('i18n.input.chrome.inputview.elements.content.CandidateView'); |
| 45 goog.require('i18n.input.chrome.inputview.elements.content.ExpandedCandidateView
'); | 45 goog.require('i18n.input.chrome.inputview.elements.content.ExpandedCandidateView
'); |
| 46 goog.require('i18n.input.chrome.inputview.elements.content.MenuView'); | 46 goog.require('i18n.input.chrome.inputview.elements.content.MenuView'); |
| 47 goog.require('i18n.input.chrome.inputview.events.EventType'); | 47 goog.require('i18n.input.chrome.inputview.events.EventType'); |
| 48 goog.require('i18n.input.chrome.inputview.events.KeyCodes'); | 48 goog.require('i18n.input.chrome.inputview.events.KeyCodes'); |
| 49 goog.require('i18n.input.chrome.inputview.handler.PointerHandler'); | 49 goog.require('i18n.input.chrome.inputview.handler.PointerHandler'); |
| 50 goog.require('i18n.input.chrome.inputview.util'); | 50 goog.require('i18n.input.chrome.inputview.util'); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 passwordLayout, name) { | 95 passwordLayout, name) { |
| 96 /** | 96 /** |
| 97 * The model. | 97 * The model. |
| 98 * | 98 * |
| 99 * @type {!i18n.input.chrome.inputview.Model} | 99 * @type {!i18n.input.chrome.inputview.Model} |
| 100 * @private | 100 * @private |
| 101 */ | 101 */ |
| 102 this.model_ = new i18n.input.chrome.inputview.Model(); | 102 this.model_ = new i18n.input.chrome.inputview.Model(); |
| 103 | 103 |
| 104 /** @private {!i18n.input.chrome.inputview.PerfTracker} */ | 104 /** @private {!i18n.input.chrome.inputview.PerfTracker} */ |
| 105 this.perfTracker_ = new i18n.input.chrome.inputview.PerfTracker(); | 105 this.perfTracker_ = new i18n.input.chrome.inputview.PerfTracker( |
| 106 PerfTracker.TickName.HTML_LOADED); |
| 106 | 107 |
| 107 /** | 108 /** |
| 108 * The layout map. | 109 * The layout map. |
| 109 * | 110 * |
| 110 * @type {!Object.<string, !Object>} | 111 * @type {!Object.<string, !Object>} |
| 111 * @private | 112 * @private |
| 112 */ | 113 */ |
| 113 this.layoutDataMap_ = {}; | 114 this.layoutDataMap_ = {}; |
| 114 | 115 |
| 115 /** | 116 /** |
| (...skipping 25 matching lines...) Expand all Loading... |
| 141 * | 142 * |
| 142 * @type {!i18n.input.chrome.inputview.handler.PointerHandler} | 143 * @type {!i18n.input.chrome.inputview.handler.PointerHandler} |
| 143 * @private | 144 * @private |
| 144 */ | 145 */ |
| 145 this.pointerHandler_ = new i18n.input.chrome.inputview.handler. | 146 this.pointerHandler_ = new i18n.input.chrome.inputview.handler. |
| 146 PointerHandler(); | 147 PointerHandler(); |
| 147 | 148 |
| 148 /** | 149 /** |
| 149 * The statistics object for recording metrics values. | 150 * The statistics object for recording metrics values. |
| 150 * | 151 * |
| 151 * @type {!i18n.input.chrome.inputview.Statistics} | 152 * @type {!i18n.input.chrome.Statistics} |
| 152 * @private | 153 * @private |
| 153 */ | 154 */ |
| 154 this.statistics_ = i18n.input.chrome.inputview.Statistics.getInstance(); | 155 this.statistics_ = i18n.input.chrome.Statistics.getInstance(); |
| 155 | 156 |
| 156 /** @private {!i18n.input.chrome.inputview.ReadyState} */ | 157 /** @private {!i18n.input.chrome.inputview.ReadyState} */ |
| 157 this.readyState_ = new i18n.input.chrome.inputview.ReadyState(); | 158 this.readyState_ = new i18n.input.chrome.inputview.ReadyState(); |
| 158 | 159 |
| 159 /** @private {!i18n.input.chrome.inputview.Adapter} */ | 160 /** @private {!i18n.input.chrome.inputview.Adapter} */ |
| 160 this.adapter_ = new i18n.input.chrome.inputview.Adapter(this.readyState_); | 161 this.adapter_ = new i18n.input.chrome.inputview.Adapter(this.readyState_); |
| 161 | 162 |
| 162 /** @private {!i18n.input.chrome.inputview.KeyboardContainer} */ | 163 /** @private {!i18n.input.chrome.inputview.KeyboardContainer} */ |
| 163 this.container_ = new i18n.input.chrome.inputview.KeyboardContainer( | 164 this.container_ = new i18n.input.chrome.inputview.KeyboardContainer( |
| 164 this.adapter_); | 165 this.adapter_); |
| 165 this.container_.render(); | 166 this.container_.render(); |
| 166 | 167 |
| 167 /** @private {!i18n.input.chrome.inputview.SoundController} */ | 168 /** @private {!i18n.input.chrome.inputview.SoundController} */ |
| 168 this.soundController_ = new SoundController(false); | 169 this.soundController_ = new SoundController(false); |
| 169 | 170 |
| 170 /** | 171 /** |
| 171 * The context type and keyset mapping group by input method id. | 172 * The context type and keyset mapping group by input method id. |
| 172 * key: input method id. | 173 * key: input method id. |
| 173 * value: Object | 174 * value: Object |
| 174 * key: context type string. | 175 * key: context type string. |
| 175 * value: keyset string. | 176 * value: keyset string. |
| 176 * | 177 * |
| 177 * @private {!Object.<string, !Object.<string, string>>} | 178 * @private {!Object.<string, !Object.<string, string>>} |
| 178 */ | 179 */ |
| 179 this.contextTypeToKeysetMap_ = {}; | 180 this.contextTypeToKeysetMap_ = {}; |
| 180 | 181 |
| 182 /** |
| 183 * The stats map for input view closing. |
| 184 * |
| 185 * @type {!Object.<string, !Array.<number>>} |
| 186 * @private |
| 187 */ |
| 188 this.statsForClosing_ = {}; |
| 189 |
| 190 /** |
| 191 * The last height sent to window.resizeTo to avoid multiple equivalent calls. |
| 192 * |
| 193 * @private {number} |
| 194 */ |
| 195 this.lastResizeHeight_ = -1; |
| 196 |
| 197 /** |
| 198 * The activate (show) time stamp for statistics. |
| 199 * |
| 200 * @type {Date} |
| 201 * @private |
| 202 */ |
| 203 this.showTimeStamp_ = new Date(); |
| 204 |
| 181 this.initialize(keyset, languageCode, passwordLayout, name); | 205 this.initialize(keyset, languageCode, passwordLayout, name); |
| 182 /** | 206 /** |
| 183 * The suggestions. | 207 * The suggestions. |
| 184 * Note: sets a default empty result to avoid null check. | 208 * Note: sets a default empty result to avoid null check. |
| 185 * | 209 * |
| 186 * @private {!i18n.input.chrome.inputview.CandidatesInfo} | 210 * @private {!i18n.input.chrome.inputview.CandidatesInfo} |
| 187 */ | 211 */ |
| 188 this.candidatesInfo_ = i18n.input.chrome.inputview.CandidatesInfo.getEmpty(); | 212 this.candidatesInfo_ = i18n.input.chrome.inputview.CandidatesInfo.getEmpty(); |
| 189 | 213 |
| 190 this.registerEventHandler_(); | 214 this.registerEventHandler_(); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 var settings = this.model_.settings; | 453 var settings = this.model_.settings; |
| 430 if (goog.isDef(e.msg['autoSpace'])) { | 454 if (goog.isDef(e.msg['autoSpace'])) { |
| 431 settings.autoSpace = e.msg['autoSpace']; | 455 settings.autoSpace = e.msg['autoSpace']; |
| 432 } | 456 } |
| 433 if (goog.isDef(e.msg['autoCapital'])) { | 457 if (goog.isDef(e.msg['autoCapital'])) { |
| 434 settings.autoCapital = e.msg['autoCapital']; | 458 settings.autoCapital = e.msg['autoCapital']; |
| 435 } | 459 } |
| 436 if (goog.isDef(e.msg['candidatesNavigation'])) { | 460 if (goog.isDef(e.msg['candidatesNavigation'])) { |
| 437 settings.candidatesNavigation = e.msg['candidatesNavigation']; | 461 settings.candidatesNavigation = e.msg['candidatesNavigation']; |
| 438 } | 462 } |
| 439 if (goog.isDef(e.msg['supportCompact'])) { | |
| 440 settings.supportCompact = e.msg['supportCompact']; | |
| 441 } | |
| 442 if (goog.isDef(e.msg[Name.KEYSET])) { | 463 if (goog.isDef(e.msg[Name.KEYSET])) { |
| 443 this.contextTypeToKeysetMap_[this.currentInputMethod_][ | 464 this.contextTypeToKeysetMap_[this.currentInputMethod_][ |
| 444 ContextType.DEFAULT] = e.msg[Name.KEYSET]; | 465 ContextType.DEFAULT] = e.msg[Name.KEYSET]; |
| 445 } | 466 } |
| 446 if (goog.isDef(e.msg['enableLongPress'])) { | 467 if (goog.isDef(e.msg['enableLongPress'])) { |
| 447 settings.enableLongPress = e.msg['enableLongPress']; | 468 settings.enableLongPress = e.msg['enableLongPress']; |
| 448 } | 469 } |
| 449 if (goog.isDef(e.msg['doubleSpacePeriod'])) { | 470 if (goog.isDef(e.msg['doubleSpacePeriod'])) { |
| 450 settings.doubleSpacePeriod = e.msg['doubleSpacePeriod']; | 471 settings.doubleSpacePeriod = e.msg['doubleSpacePeriod']; |
| 451 } | 472 } |
| 452 if (goog.isDef(e.msg['soundOnKeypress'])) { | 473 if (goog.isDef(e.msg['soundOnKeypress'])) { |
| 453 settings.soundOnKeypress = e.msg['soundOnKeypress']; | 474 settings.soundOnKeypress = e.msg['soundOnKeypress']; |
| 454 this.soundController_.setEnabled(settings.soundOnKeypress); | 475 this.soundController_.setEnabled(settings.soundOnKeypress); |
| 455 } | 476 } |
| 456 this.perfTracker_.tick(PerfTracker.TickName.BACKGROUND_SETTINGS_FETCHED); | 477 this.perfTracker_.tick(PerfTracker.TickName.BACKGROUND_SETTINGS_FETCHED); |
| 478 this.model_.stateManager.contextType = this.adapter_.getContextType(); |
| 457 var isPassword = this.adapter_.isPasswordBox(); | 479 var isPassword = this.adapter_.isPasswordBox(); |
| 458 this.switchToKeySet(this.getActiveKeyset_()); | 480 this.switchToKeySet(this.getActiveKeyset_()); |
| 459 }; | 481 }; |
| 460 | 482 |
| 461 | 483 |
| 462 /** | 484 /** |
| 463 * Callback for setting ready. | 485 * Callback for setting ready. |
| 464 * | 486 * |
| 465 * @private | 487 * @private |
| 466 */ | 488 */ |
| 467 Controller.prototype.onSettingsReady_ = function() { | 489 Controller.prototype.onSettingsReady_ = function() { |
| 468 if (this.isSettingReady) { | 490 if (this.isSettingReady) { |
| 469 return; | 491 return; |
| 470 } | 492 } |
| 471 | 493 |
| 472 this.isSettingReady = true; | 494 this.isSettingReady = true; |
| 473 var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; | 495 var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; |
| 474 if (this.adapter_.isA11yMode) { | 496 if (this.adapter_.isA11yMode) { |
| 475 keysetMap[ContextType.PASSWORD] = keysetMap[ContextType.DEFAULT] = | 497 keysetMap[ContextType.PASSWORD] = keysetMap[ContextType.DEFAULT] = |
| 476 util.getConfigName(keysetMap[ContextType.DEFAULT]); | 498 util.getConfigName(keysetMap[ContextType.DEFAULT]); |
| 477 } else { | 499 } else { |
| 478 var preferredKeyset = /** @type {string} */ (this.model_.settings. | 500 var preferredKeyset = /** @type {string} */ (this.model_.settings. |
| 479 getPreference(util.getConfigName( | 501 getPreference(util.getConfigName( |
| 480 keysetMap[ContextType.DEFAULT]))); | 502 keysetMap[ContextType.DEFAULT]))); |
| 481 if (preferredKeyset) { | 503 if (preferredKeyset) { |
| 482 keysetMap[ContextType.PASSWORD] = keysetMap[ContextType.DEFAULT] = | 504 keysetMap[ContextType.PASSWORD] = keysetMap[ContextType.DEFAULT] = |
| 483 preferredKeyset; | 505 preferredKeyset; |
| 484 } | 506 } |
| 485 } | 507 } |
| 508 if (!this.adapter_.isExperimental && keysetMap[ContextType.DEFAULT] == |
| 509 'zhuyin.compact.qwerty') { |
| 510 keysetMap[ContextType.DEFAULT] = 'zhuyin'; |
| 511 } |
| 486 this.maybeCreateViews_(); | 512 this.maybeCreateViews_(); |
| 487 this.switchToKeySet(this.getActiveKeyset_()); | 513 this.switchToKeySet(this.getActiveKeyset_()); |
| 488 }; | 514 }; |
| 489 | 515 |
| 490 | 516 |
| 491 /** | 517 /** |
| 492 * Gets the data for spatial module. | 518 * Gets the data for spatial module. |
| 493 * | 519 * |
| 494 * @param {!content.SoftKey} key . | 520 * @param {!content.SoftKey} key . |
| 495 * @param {number} x The x-offset of the touch point. | 521 * @param {number} x The x-offset of the touch point. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 * | 577 * |
| 552 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . | 578 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . |
| 553 * @private | 579 * @private |
| 554 */ | 580 */ |
| 555 Controller.prototype.onPointerEvent_ = function(e) { | 581 Controller.prototype.onPointerEvent_ = function(e) { |
| 556 if ((this.adapter_.isChromeVoxOn || !this.model_.settings.enableLongPress) && | 582 if ((this.adapter_.isChromeVoxOn || !this.model_.settings.enableLongPress) && |
| 557 e.type == EventType.LONG_PRESS) { | 583 e.type == EventType.LONG_PRESS) { |
| 558 return; | 584 return; |
| 559 } | 585 } |
| 560 | 586 |
| 587 if (e.type == EventType.POINTER_UP) { |
| 588 this.stopBackspaceAutoRepeat_(); |
| 589 } |
| 590 |
| 561 if (e.view) { | 591 if (e.view) { |
| 562 this.handlePointerAction_(e.view, e); | 592 this.handlePointerAction_(e.view, e); |
| 563 } else { | 593 } else { |
| 564 var tabbableKeysets = [ | 594 var tabbableKeysets = [ |
| 565 Controller.HANDWRITING_VIEW_CODE_, | 595 Controller.HANDWRITING_VIEW_CODE_, |
| 566 Controller.EMOJI_VIEW_CODE_]; | 596 Controller.EMOJI_VIEW_CODE_]; |
| 567 if (goog.array.contains(tabbableKeysets, this.currentKeyset_)) { | 597 if (goog.array.contains(tabbableKeysets, this.currentKeyset_)) { |
| 568 this.resetAll_(); | 598 this.resetAll_(); |
| 569 this.switchToKeySet(this.container_.currentKeysetView.fromKeyset); | 599 this.switchToKeySet(this.container_.currentKeysetView.fromKeyset); |
| 570 } | 600 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 case CommandEnum.SWITCH_IME: | 653 case CommandEnum.SWITCH_IME: |
| 624 var inputMethodId = opt_arg; | 654 var inputMethodId = opt_arg; |
| 625 if (inputMethodId) { | 655 if (inputMethodId) { |
| 626 this.adapter_.switchToInputMethod(inputMethodId); | 656 this.adapter_.switchToInputMethod(inputMethodId); |
| 627 } | 657 } |
| 628 break; | 658 break; |
| 629 | 659 |
| 630 case CommandEnum.SWITCH_KEYSET: | 660 case CommandEnum.SWITCH_KEYSET: |
| 631 var keyset = opt_arg; | 661 var keyset = opt_arg; |
| 632 if (keyset) { | 662 if (keyset) { |
| 633 this.statistics_.recordSwitch(keyset); | 663 this.recordStatsForClosing_( |
| 664 'InputMethod.VirtualKeyboard.LayoutSwitch', 1, 25, 25); |
| 634 this.switchToKeySet(keyset); | 665 this.switchToKeySet(keyset); |
| 635 } | 666 } |
| 636 break; | 667 break; |
| 637 case CommandEnum.OPEN_EMOJI: | 668 case CommandEnum.OPEN_EMOJI: |
| 638 this.switchToKeySet(Controller.EMOJI_VIEW_CODE_); | 669 this.switchToKeySet(Controller.EMOJI_VIEW_CODE_); |
| 639 break; | 670 break; |
| 640 | 671 |
| 641 case CommandEnum.OPEN_HANDWRITING: | 672 case CommandEnum.OPEN_HANDWRITING: |
| 642 // TODO: remember handwriting keyset. | 673 // TODO: remember handwriting keyset. |
| 643 this.switchToKeySet(Controller.HANDWRITING_VIEW_CODE_); | 674 this.switchToKeySet(Controller.HANDWRITING_VIEW_CODE_); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 659 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . | 690 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . |
| 660 * @private | 691 * @private |
| 661 */ | 692 */ |
| 662 Controller.prototype.handlePointerAction_ = function(view, e) { | 693 Controller.prototype.handlePointerAction_ = function(view, e) { |
| 663 if (e.type == i18n.input.chrome.inputview.events.EventType.SWIPE) { | 694 if (e.type == i18n.input.chrome.inputview.events.EventType.SWIPE) { |
| 664 e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e); | 695 e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e); |
| 665 this.handleSwipeAction_(view, e); | 696 this.handleSwipeAction_(view, e); |
| 666 } | 697 } |
| 667 switch (view.type) { | 698 switch (view.type) { |
| 668 case ElementType.BACK_BUTTON: | 699 case ElementType.BACK_BUTTON: |
| 700 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { |
| 701 view.setHighlighted(false); |
| 702 } else if (e.type == EventType.POINTER_DOWN || |
| 703 e.type == EventType.POINTER_OVER) { |
| 704 view.setHighlighted(true); |
| 705 } |
| 669 if (e.type == EventType.POINTER_UP) { | 706 if (e.type == EventType.POINTER_UP) { |
| 670 this.switchToKeySet(this.container_.currentKeysetView.fromKeyset); | 707 this.switchToKeySet(this.container_.currentKeysetView.fromKeyset); |
| 708 this.clearCandidates_(); |
| 671 } | 709 } |
| 672 return; | 710 return; |
| 673 case ElementType.EXPAND_CANDIDATES: | 711 case ElementType.EXPAND_CANDIDATES: |
| 674 if (e.type == EventType.POINTER_UP) { | 712 if (e.type == EventType.POINTER_UP) { |
| 675 this.showCandidates_(this.candidatesInfo_.source, | 713 this.showCandidates_(this.candidatesInfo_.source, |
| 676 this.candidatesInfo_.candidates, | 714 this.candidatesInfo_.candidates, |
| 677 Controller.CandidatesOperation.EXPAND); | 715 Controller.CandidatesOperation.EXPAND); |
| 678 } | 716 } |
| 679 return; | 717 return; |
| 680 case ElementType.SHRINK_CANDIDATES: | 718 case ElementType.SHRINK_CANDIDATES: |
| 681 if (e.type == EventType.POINTER_UP) { | 719 if (e.type == EventType.POINTER_UP) { |
| 682 this.showCandidates_(this.candidatesInfo_.source, | 720 this.showCandidates_(this.candidatesInfo_.source, |
| 683 this.candidatesInfo_.candidates, | 721 this.candidatesInfo_.candidates, |
| 684 Controller.CandidatesOperation.SHRINK); | 722 Controller.CandidatesOperation.SHRINK); |
| 685 } | 723 } |
| 686 return; | 724 return; |
| 687 case ElementType.CANDIDATE: | 725 case ElementType.CANDIDATE: |
| 688 view = /** @type {!Candidate} */ (view); | 726 view = /** @type {!Candidate} */ (view); |
| 689 if (e.type == EventType.POINTER_UP) { | 727 if (e.type == EventType.POINTER_UP) { |
| 690 if (view.candidateType == CandidateType.CANDIDATE) { | 728 if (view.candidateType == CandidateType.CANDIDATE) { |
| 691 this.adapter_.selectCandidate(view.candidate); | 729 this.adapter_.selectCandidate(view.candidate); |
| 692 } else if (view.candidateType == CandidateType.NUMBER) { | 730 } else if (view.candidateType == CandidateType.NUMBER) { |
| 693 this.adapter_.commitText(view.candidate[Name.CANDIDATE]); | 731 this.adapter_.commitText(view.candidate[Name.CANDIDATE]); |
| 694 } | 732 } |
| 695 this.container_.cleanStroke(); | 733 this.container_.cleanStroke(); |
| 734 this.soundController_.onKeyUp(ElementType.CANDIDATE); |
| 696 } | 735 } |
| 697 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { | 736 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { |
| 698 view.setHighlighted(false); | 737 view.setHighlighted(false); |
| 699 } else if (e.type == EventType.POINTER_DOWN || | 738 } else if (e.type == EventType.POINTER_DOWN || |
| 700 e.type == EventType.POINTER_OVER) { | 739 e.type == EventType.POINTER_OVER) { |
| 701 view.setHighlighted(true); | 740 view.setHighlighted(true); |
| 702 } | 741 } |
| 703 return; | 742 return; |
| 704 | 743 |
| 705 case ElementType.ALTDATA_VIEW: | 744 case ElementType.ALTDATA_VIEW: |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 break; | 836 break; |
| 798 case ElementType.CANDIDATES_PAGE_DOWN: | 837 case ElementType.CANDIDATES_PAGE_DOWN: |
| 799 if (e.type == EventType.POINTER_UP) { | 838 if (e.type == EventType.POINTER_UP) { |
| 800 this.container_.expandedCandidateView.pageDown(); | 839 this.container_.expandedCandidateView.pageDown(); |
| 801 } | 840 } |
| 802 break; | 841 break; |
| 803 case ElementType.CHARACTER_KEY: | 842 case ElementType.CHARACTER_KEY: |
| 804 key = /** @type {!content.CharacterKey} */ (softKey); | 843 key = /** @type {!content.CharacterKey} */ (softKey); |
| 805 if (e.type == EventType.LONG_PRESS) { | 844 if (e.type == EventType.LONG_PRESS) { |
| 806 this.container_.altDataView.show( | 845 this.container_.altDataView.show( |
| 807 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_)); | 846 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_), |
| 847 this.adapter_.isExperimental); |
| 808 } else if (e.type == EventType.POINTER_UP) { | 848 } else if (e.type == EventType.POINTER_UP) { |
| 809 this.model_.stateManager.triggerChording(); | 849 this.model_.stateManager.triggerChording(); |
| 810 var ch = key.getActiveCharacter(); | 850 var ch = key.getActiveCharacter(); |
| 811 this.adapter_.sendKeyDownAndUpEvent(ch, key.id, key.keyCode, | 851 this.adapter_.sendKeyDownAndUpEvent(ch, key.id, key.keyCode, |
| 812 this.getSpatialData_(key, e.x, e.y)); | 852 this.getSpatialData_(key, e.x, e.y)); |
| 813 this.clearUnstickyState_(); | 853 this.clearUnstickyState_(); |
| 814 key.flickerredCharacter = ''; | 854 key.flickerredCharacter = ''; |
| 815 } | 855 } |
| 816 break; | 856 break; |
| 817 | 857 |
| 818 case ElementType.MODIFIER_KEY: | 858 case ElementType.MODIFIER_KEY: |
| 819 key = /** @type {!content.ModifierKey} */ (softKey); | 859 key = /** @type {!content.ModifierKey} */ (softKey); |
| 820 var isStateEnabled = this.model_.stateManager.hasState(key.toState); | 860 var isStateEnabled = this.model_.stateManager.hasState(key.toState); |
| 821 var isChording = this.model_.stateManager.isChording(key.toState); | 861 var isChording = this.model_.stateManager.isChording(key.toState); |
| 822 if (e.type == EventType.POINTER_DOWN) { | 862 if (e.type == EventType.POINTER_DOWN) { |
| 823 this.changeState_(key.toState, !isStateEnabled, true); | 863 this.changeState_(key.toState, !isStateEnabled, true, false); |
| 824 this.model_.stateManager.setKeyDown(key.toState, true); | 864 this.model_.stateManager.setKeyDown(key.toState, true); |
| 825 } else if (e.type == EventType.POINTER_UP || e.type == EventType. | 865 } else if (e.type == EventType.POINTER_UP || e.type == EventType. |
| 826 POINTER_OUT) { | 866 POINTER_OUT) { |
| 827 if (isChording) { | 867 if (isChording) { |
| 828 this.changeState_(key.toState, false, false); | 868 this.changeState_(key.toState, false, false); |
| 829 } else if (key.toState != StateType.CAPSLOCK && | 869 } else if (key.toState == StateType.CAPSLOCK) { |
| 830 this.model_.stateManager.isKeyDown(key.toState)) { | 870 this.changeState_(key.toState, isStateEnabled, true, true); |
| 871 } else if (this.model_.stateManager.isKeyDown(key.toState)) { |
| 831 this.changeState_(key.toState, isStateEnabled, false); | 872 this.changeState_(key.toState, isStateEnabled, false); |
| 832 } | 873 } |
| 833 this.model_.stateManager.setKeyDown(key.toState, false); | 874 this.model_.stateManager.setKeyDown(key.toState, false); |
| 834 } else if (e.type == EventType.DOUBLE_CLICK) { | 875 } else if (e.type == EventType.DOUBLE_CLICK) { |
| 835 this.changeState_(key.toState, isStateEnabled, true); | 876 this.changeState_(key.toState, isStateEnabled, true, true); |
| 836 } else if (e.type == EventType.LONG_PRESS) { | 877 } else if (e.type == EventType.LONG_PRESS) { |
| 837 if (!isChording) { | 878 if (!isChording) { |
| 838 this.changeState_(key.toState, true, true); | 879 this.changeState_(key.toState, true, true, true); |
| 839 this.model_.stateManager.setKeyDown(key.toState, false); | 880 this.model_.stateManager.setKeyDown(key.toState, false); |
| 840 } | 881 } |
| 841 } | 882 } |
| 842 break; | 883 break; |
| 843 | 884 |
| 844 case ElementType.BACKSPACE_KEY: | 885 case ElementType.BACKSPACE_KEY: |
| 845 key = /** @type {!content.FunctionalKey} */ (softKey); | 886 key = /** @type {!content.FunctionalKey} */ (softKey); |
| 846 if (e.type == EventType.POINTER_DOWN) { | 887 if (e.type == EventType.POINTER_DOWN) { |
| 847 this.backspaceTick_(); | 888 this.backspaceTick_(); |
| 848 } else if (e.type == EventType.POINTER_UP || e.type == EventType. | 889 } else if (e.type == EventType.POINTER_UP || e.type == EventType. |
| 849 POINTER_OUT) { | 890 POINTER_OUT) { |
| 850 this.stopBackspaceAutoRepeat_(); | 891 this.stopBackspaceAutoRepeat_(); |
| 851 this.adapter_.sendKeyUpEvent('\u0008', KeyCodes.BACKSPACE); | 892 this.adapter_.sendKeyUpEvent('\u0008', KeyCodes.BACKSPACE); |
| 852 } | 893 } |
| 853 break; | 894 break; |
| 854 | 895 |
| 855 case ElementType.TAB_KEY: | 896 case ElementType.TAB_KEY: |
| 856 key = /** @type {!content.FunctionalKey} */ (softKey); | 897 key = /** @type {!content.FunctionalKey} */ (softKey); |
| 857 if (e.type == EventType.POINTER_DOWN) { | 898 if (e.type == EventType.POINTER_DOWN) { |
| 858 this.adapter_.sendKeyDownEvent('\u0009', KeyCodes.TAB); | 899 this.adapter_.sendKeyDownEvent('\u0009', KeyCodes.TAB); |
| 859 } else if (e.type == EventType.POINTER_UP) { | 900 } else if (e.type == EventType.POINTER_UP) { |
| 860 this.adapter_.sendKeyUpEvent('\u0009', KeyCodes.TAB); | 901 this.adapter_.sendKeyUpEvent('\u0009', KeyCodes.TAB); |
| 861 } | 902 } |
| 862 break; | 903 break; |
| 863 | 904 |
| 864 case ElementType.ENTER_KEY: | 905 case ElementType.ENTER_KEY: |
| 865 key = /** @type {!content.FunctionalKey} */ (softKey); | 906 key = /** @type {!content.FunctionalKey} */ (softKey); |
| 866 if (e.type == EventType.POINTER_DOWN) { | 907 if (e.type == EventType.POINTER_UP) { |
| 867 this.adapter_.sendKeyDownEvent('\u000D', KeyCodes.ENTER); | 908 this.adapter_.sendKeyDownAndUpEvent('\u000D', KeyCodes.ENTER); |
| 868 } else if (e.type == EventType.POINTER_UP) { | |
| 869 this.adapter_.sendKeyUpEvent('\u000D', KeyCodes.ENTER); | |
| 870 } | 909 } |
| 871 break; | 910 break; |
| 872 | 911 |
| 873 case ElementType.ARROW_UP: | 912 case ElementType.ARROW_UP: |
| 874 if (e.type == EventType.POINTER_DOWN) { | 913 if (e.type == EventType.POINTER_DOWN) { |
| 875 this.adapter_.sendKeyDownEvent('', KeyCodes.ARROW_UP); | 914 this.adapter_.sendKeyDownEvent('', KeyCodes.ARROW_UP); |
| 876 } else if (e.type == EventType.POINTER_UP) { | 915 } else if (e.type == EventType.POINTER_UP) { |
| 877 this.adapter_.sendKeyUpEvent('', KeyCodes.ARROW_UP); | 916 this.adapter_.sendKeyUpEvent('', KeyCodes.ARROW_UP); |
| 878 } | 917 } |
| 879 break; | 918 break; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 KeyCodes.SPACE); | 957 KeyCodes.SPACE); |
| 919 this.clearUnstickyState_(); | 958 this.clearUnstickyState_(); |
| 920 } else if (e.type == EventType.DOUBLE_CLICK && doubleSpacePeriod) { | 959 } else if (e.type == EventType.DOUBLE_CLICK && doubleSpacePeriod) { |
| 921 this.adapter_.doubleClickOnSpaceKey(); | 960 this.adapter_.doubleClickOnSpaceKey(); |
| 922 } | 961 } |
| 923 break; | 962 break; |
| 924 | 963 |
| 925 case ElementType.SWITCHER_KEY: | 964 case ElementType.SWITCHER_KEY: |
| 926 key = /** @type {!content.SwitcherKey} */ (softKey); | 965 key = /** @type {!content.SwitcherKey} */ (softKey); |
| 927 if (e.type == EventType.POINTER_UP) { | 966 if (e.type == EventType.POINTER_UP) { |
| 928 this.statistics_.recordSwitch(key.toKeyset); | 967 this.recordStatsForClosing_( |
| 968 'InputMethod.VirtualKeyboard.LayoutSwitch', 1, 25, 25); |
| 929 if (this.isSubKeyset_(key.toKeyset, this.currentKeyset_)) { | 969 if (this.isSubKeyset_(key.toKeyset, this.currentKeyset_)) { |
| 930 this.model_.stateManager.reset(); | 970 this.model_.stateManager.reset(); |
| 931 this.container_.update(); | 971 this.container_.update(); |
| 932 this.updateContextModifierState_(); | 972 this.updateContextModifierState_(); |
| 933 this.container_.menuView.hide(); | 973 this.container_.menuView.hide(); |
| 934 } else { | 974 } else { |
| 935 this.resetAll_(); | 975 this.resetAll_(); |
| 936 } | 976 } |
| 937 // Switch to the specific keyboard. | 977 // Switch to the specific keyboard. |
| 938 this.switchToKeySet(key.toKeyset); | 978 this.switchToKeySet(key.toKeyset); |
| 939 if (key.record) { | 979 if (key.record) { |
| 940 this.model_.settings.savePreference( | 980 this.model_.settings.savePreference( |
| 941 util.getConfigName(key.toKeyset), | 981 util.getConfigName(key.toKeyset), |
| 942 key.toKeyset); | 982 key.toKeyset); |
| 943 } | 983 } |
| 944 } | 984 } |
| 945 break; | 985 break; |
| 946 | 986 |
| 947 case ElementType.COMPACT_KEY: | 987 case ElementType.COMPACT_KEY: |
| 948 key = /** @type {!content.CompactKey} */ (softKey); | 988 key = /** @type {!content.CompactKey} */ (softKey); |
| 949 if (e.type == EventType.LONG_PRESS) { | 989 if (e.type == EventType.LONG_PRESS) { |
| 950 this.container_.altDataView.show( | 990 this.container_.altDataView.show( |
| 951 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_)); | 991 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_), |
| 992 this.adapter_.isExperimental); |
| 952 } else if (e.type == EventType.POINTER_UP) { | 993 } else if (e.type == EventType.POINTER_UP) { |
| 953 this.model_.stateManager.triggerChording(); | 994 this.model_.stateManager.triggerChording(); |
| 954 this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0, | 995 this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0, |
| 955 this.getSpatialData_(key, e.x, e.y)); | 996 this.getSpatialData_(key, e.x, e.y)); |
| 956 this.clearUnstickyState_(); | 997 this.clearUnstickyState_(); |
| 957 key.flickerredCharacter = ''; | 998 key.flickerredCharacter = ''; |
| 958 } | 999 } |
| 959 break; | 1000 break; |
| 960 | 1001 |
| 961 case ElementType.HIDE_KEYBOARD_KEY: | 1002 case ElementType.HIDE_KEYBOARD_KEY: |
| 1003 var defaultKeyset = this.getActiveKeyset_(); |
| 962 if (e.type == EventType.POINTER_UP) { | 1004 if (e.type == EventType.POINTER_UP) { |
| 963 this.adapter_.hideKeyboard(); | 1005 this.adapter_.hideKeyboard(); |
| 964 } | 1006 } |
| 1007 if (this.currentKeyset_ != defaultKeyset) { |
| 1008 this.switchToKeySet(defaultKeyset); |
| 1009 } |
| 965 break; | 1010 break; |
| 966 | 1011 |
| 967 case ElementType.MENU_KEY: | 1012 case ElementType.MENU_KEY: |
| 968 key = /** @type {!content.MenuKey} */ (softKey); | 1013 key = /** @type {!content.MenuKey} */ (softKey); |
| 969 if (e.type == EventType.POINTER_DOWN) { | 1014 if (e.type == EventType.POINTER_DOWN) { |
| 970 var isCompact = this.currentKeyset_.indexOf('compact') != -1; | 1015 var isCompact = this.currentKeyset_.indexOf('compact') != -1; |
| 971 var remappedKeyset = this.getRemappedKeyset_(this.currentKeyset_); | 1016 var defaultKeyset = this.contextTypeToKeysetMap_[ |
| 972 var keysetData = this.keysetDataMap_[remappedKeyset]; | 1017 this.currentInputMethod_][ContextType.DEFAULT]; |
| 973 var enableCompact = !this.adapter_.isA11yMode && | 1018 var enableCompact = !this.adapter_.isA11yMode && goog.array.contains( |
| 974 !!keysetData[SpecNodeName.HAS_COMPACT_KEYBOARD] && | 1019 util.KEYSETS_HAVE_COMPACT, defaultKeyset.split(/\./)[0]); |
| 975 this.model_.settings.supportCompact; | 1020 if (defaultKeyset == 'zhuyin' && !this.adapter_.isExperimental || |
| 1021 this.languageCode_ == 'ko') { |
| 1022 // Hides 'switch to compact' for zhuyin when not in experimental env. |
| 1023 enableCompact = false; |
| 1024 } |
| 976 var self = this; | 1025 var self = this; |
| 977 var currentKeyset = this.currentKeyset_; | |
| 978 var hasHwt = !this.adapter_.isPasswordBox() && | 1026 var hasHwt = !this.adapter_.isPasswordBox() && |
| 979 !Controller.DISABLE_HWT && goog.object.contains( | 1027 !Controller.DISABLE_HWT && goog.object.contains( |
| 980 InputToolCode, this.getHwtInputToolCode_()); | 1028 InputToolCode, this.getHwtInputToolCode_()) && |
| 1029 this.languageCode_ != 'ko'; |
| 981 var enableSettings = this.shouldEnableSettings() && | 1030 var enableSettings = this.shouldEnableSettings() && |
| 982 window.inputview && inputview.openSettings; | 1031 !!window.inputview && !!inputview.openSettings; |
| 983 this.adapter_.getInputMethods(function(inputMethods) { | 1032 this.adapter_.getInputMethods(function(inputMethods) { |
| 984 this.container_.menuView.show(key, currentKeyset, isCompact, | 1033 this.container_.menuView.show(key, defaultKeyset, isCompact, |
| 985 enableCompact, this.currentInputMethod_, inputMethods, hasHwt, | 1034 enableCompact, this.currentInputMethod_, inputMethods, hasHwt, |
| 986 enableSettings, this.adapter_.isExperimental); | 1035 enableSettings, this.adapter_.isExperimental); |
| 987 }.bind(this)); | 1036 }.bind(this)); |
| 988 } | 1037 } |
| 989 break; | 1038 break; |
| 990 | 1039 |
| 991 case ElementType.GLOBE_KEY: | 1040 case ElementType.GLOBE_KEY: |
| 992 if (e.type == EventType.POINTER_UP) { | 1041 if (e.type == EventType.POINTER_UP) { |
| 993 this.adapter_.clearModifierStates(); | 1042 this.adapter_.clearModifierStates(); |
| 994 this.adapter_.setModifierState( | 1043 this.adapter_.setModifierState( |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 this.container_.update(); | 1076 this.container_.update(); |
| 1028 }; | 1077 }; |
| 1029 | 1078 |
| 1030 | 1079 |
| 1031 /** | 1080 /** |
| 1032 * Stops the auto-repeat for backspace. | 1081 * Stops the auto-repeat for backspace. |
| 1033 * | 1082 * |
| 1034 * @private | 1083 * @private |
| 1035 */ | 1084 */ |
| 1036 Controller.prototype.stopBackspaceAutoRepeat_ = function() { | 1085 Controller.prototype.stopBackspaceAutoRepeat_ = function() { |
| 1037 goog.dispose(this.backspaceAutoRepeat_); | 1086 if (this.backspaceAutoRepeat_) { |
| 1038 this.backspaceAutoRepeat_ = null; | 1087 goog.dispose(this.backspaceAutoRepeat_); |
| 1039 this.adapter_.sendKeyUpEvent('\u0008', KeyCodes.BACKSPACE); | 1088 this.backspaceAutoRepeat_ = null; |
| 1040 this.backspaceRepeated_ = 0; | 1089 this.adapter_.sendKeyUpEvent('\u0008', KeyCodes.BACKSPACE); |
| 1090 this.backspaceRepeated_ = 0; |
| 1091 } |
| 1041 }; | 1092 }; |
| 1042 | 1093 |
| 1043 | 1094 |
| 1044 /** | 1095 /** |
| 1045 * The tick for the backspace key. | 1096 * The tick for the backspace key. |
| 1046 * | 1097 * |
| 1047 * @private | 1098 * @private |
| 1048 */ | 1099 */ |
| 1049 Controller.prototype.backspaceTick_ = function() { | 1100 Controller.prototype.backspaceTick_ = function() { |
| 1050 if (this.backspaceRepeated_ >= Controller.BACKSPACE_REPEAT_LIMIT_) { | 1101 if (this.backspaceRepeated_ >= Controller.BACKSPACE_REPEAT_LIMIT_) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1065 }; | 1116 }; |
| 1066 | 1117 |
| 1067 | 1118 |
| 1068 /** | 1119 /** |
| 1069 * Callback for VISIBILITY_CHANGE. | 1120 * Callback for VISIBILITY_CHANGE. |
| 1070 * | 1121 * |
| 1071 * @private | 1122 * @private |
| 1072 */ | 1123 */ |
| 1073 Controller.prototype.onVisibilityChange_ = function() { | 1124 Controller.prototype.onVisibilityChange_ = function() { |
| 1074 if (!this.adapter_.isVisible) { | 1125 if (!this.adapter_.isVisible) { |
| 1126 for (var name in this.statsForClosing_) { |
| 1127 var stat = this.statsForClosing_[name]; |
| 1128 this.statistics_.recordValue(name, stat[0], stat[1], stat[2]); |
| 1129 } |
| 1130 this.statistics_.recordValue('InputMethod.VirtualKeyboard.Duration', |
| 1131 Math.floor((new Date() - this.showTimeStamp_) / 1000), 4096, 50); |
| 1132 this.statsForClosing_ = {}; |
| 1133 this.showTimeStamp_ = new Date(); |
| 1075 this.resetAll_(); | 1134 this.resetAll_(); |
| 1076 } | 1135 } |
| 1077 }; | 1136 }; |
| 1078 | 1137 |
| 1079 | 1138 |
| 1080 /** | 1139 /** |
| 1081 * Resets the whole keyboard include clearing candidates, | 1140 * Resets the whole keyboard include clearing candidates, |
| 1082 * reset modifier state, etc. | 1141 * reset modifier state, etc. |
| 1083 * | 1142 * |
| 1084 * @private | 1143 * @private |
| 1085 */ | 1144 */ |
| 1086 Controller.prototype.resetAll_ = function() { | 1145 Controller.prototype.resetAll_ = function() { |
| 1087 this.clearCandidates_(); | 1146 this.clearCandidates_(); |
| 1147 this.container_.cleanStroke(); |
| 1088 this.container_.candidateView.hideNumberRow(); | 1148 this.container_.candidateView.hideNumberRow(); |
| 1089 this.model_.stateManager.reset(); | 1149 this.model_.stateManager.reset(); |
| 1090 this.container_.update(); | 1150 this.container_.update(); |
| 1091 this.updateContextModifierState_(); | 1151 this.updateContextModifierState_(); |
| 1092 this.deadKey_ = ''; | 1152 this.deadKey_ = ''; |
| 1093 this.resize(); | 1153 this.resize(); |
| 1094 this.container_.expandedCandidateView.close(); | 1154 this.container_.expandedCandidateView.close(); |
| 1095 this.container_.menuView.hide(); | 1155 this.container_.menuView.hide(); |
| 1096 }; | 1156 }; |
| 1097 | 1157 |
| 1098 | 1158 |
| 1099 /** | 1159 /** |
| 1100 * Callback when the context is changed. | 1160 * Callback when the context is changed. |
| 1101 * | 1161 * |
| 1102 * @private | 1162 * @private |
| 1103 */ | 1163 */ |
| 1104 Controller.prototype.onContextFocus_ = function() { | 1164 Controller.prototype.onContextFocus_ = function() { |
| 1105 this.resetAll_(); | 1165 this.resetAll_(); |
| 1166 this.model_.stateManager.contextType = this.adapter_.getContextType(); |
| 1106 this.switchToKeySet(this.getActiveKeyset_()); | 1167 this.switchToKeySet(this.getActiveKeyset_()); |
| 1107 }; | 1168 }; |
| 1108 | 1169 |
| 1109 | 1170 |
| 1110 /** | 1171 /** |
| 1111 * Callback when surrounding text is changed. | 1172 * Callback when surrounding text is changed. |
| 1112 * | 1173 * |
| 1113 * @param {!i18n.input.chrome.inputview.events.SurroundingTextChangedEvent} e . | 1174 * @param {!i18n.input.chrome.inputview.events.SurroundingTextChangedEvent} e . |
| 1114 * @private | 1175 * @private |
| 1115 */ | 1176 */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1130 }; | 1191 }; |
| 1131 | 1192 |
| 1132 | 1193 |
| 1133 /** | 1194 /** |
| 1134 * Callback for Context blurs. | 1195 * Callback for Context blurs. |
| 1135 * | 1196 * |
| 1136 * @private | 1197 * @private |
| 1137 */ | 1198 */ |
| 1138 Controller.prototype.onContextBlur_ = function() { | 1199 Controller.prototype.onContextBlur_ = function() { |
| 1139 this.clearCandidates_(); | 1200 this.clearCandidates_(); |
| 1201 this.container_.cleanStroke(); |
| 1140 this.deadKey_ = ''; | 1202 this.deadKey_ = ''; |
| 1141 this.container_.menuView.hide(); | 1203 this.container_.menuView.hide(); |
| 1142 }; | 1204 }; |
| 1143 | 1205 |
| 1144 | 1206 |
| 1145 /** | 1207 /** |
| 1146 * Backspace key is down. | 1208 * Backspace key is down. |
| 1147 * | 1209 * |
| 1148 * @private | 1210 * @private |
| 1149 */ | 1211 */ |
| 1150 Controller.prototype.backspaceDown_ = function() { | 1212 Controller.prototype.backspaceDown_ = function() { |
| 1151 if (this.container_.hasStrokesOnCanvas()) { | 1213 if (this.container_.hasStrokesOnCanvas()) { |
| 1152 this.clearCandidates_(); | 1214 this.clearCandidates_(); |
| 1153 this.container_.cleanStroke(); | 1215 this.container_.cleanStroke(); |
| 1154 } else { | 1216 } else { |
| 1155 this.adapter_.sendKeyDownEvent('\u0008', KeyCodes.BACKSPACE); | 1217 this.adapter_.sendKeyDownEvent('\u0008', KeyCodes.BACKSPACE); |
| 1156 } | 1218 } |
| 1219 this.recordStatsForClosing_( |
| 1220 'InputMethod.VirtualKeyboard.BackspaceCount', 1, 4095, 4096); |
| 1221 this.statistics_.recordEnum('InputMethod.VirtualKeyboard.BackspaceOnLayout', |
| 1222 this.statistics_.getLayoutType(this.currentKeyset_, |
| 1223 this.adapter_.isA11yMode), |
| 1224 i18n.input.chrome.Statistics.LayoutTypes.MAX); |
| 1157 }; | 1225 }; |
| 1158 | 1226 |
| 1159 | 1227 |
| 1160 /** | 1228 /** |
| 1161 * Callback for state change. | 1229 * Callback for state change. |
| 1162 * | 1230 * |
| 1163 * @param {StateType} stateType The state type. | 1231 * @param {StateType} stateType The state type. |
| 1164 * @param {boolean} enable True to enable the state. | 1232 * @param {boolean} enable True to enable the state. |
| 1165 * @param {boolean} isSticky True to make the state sticky. | 1233 * @param {boolean} isSticky True to make the state sticky. |
| 1234 * @param {boolean=} opt_isFinalSticky . |
| 1166 * @private | 1235 * @private |
| 1167 */ | 1236 */ |
| 1168 Controller.prototype.changeState_ = function(stateType, enable, isSticky) { | 1237 Controller.prototype.changeState_ = function(stateType, enable, isSticky, |
| 1238 opt_isFinalSticky) { |
| 1169 if (stateType == StateType.ALTGR) { | 1239 if (stateType == StateType.ALTGR) { |
| 1170 var code = KeyCodes.ALT_RIGHT; | 1240 var code = KeyCodes.ALT_RIGHT; |
| 1171 if (enable) { | 1241 if (enable) { |
| 1172 this.adapter_.sendKeyDownEvent('', code); | 1242 this.adapter_.sendKeyDownEvent('', code); |
| 1173 } else { | 1243 } else { |
| 1174 this.adapter_.sendKeyUpEvent('', code); | 1244 this.adapter_.sendKeyUpEvent('', code); |
| 1175 } | 1245 } |
| 1176 } | 1246 } |
| 1177 if (stateType == StateType.SHIFT) { | 1247 if (stateType == StateType.SHIFT) { |
| 1178 this.shiftForAutoCapital_ = false; | 1248 this.shiftForAutoCapital_ = false; |
| 1179 } | 1249 } |
| 1180 var isEnabledBefore = this.model_.stateManager.hasState(stateType); | 1250 var isEnabledBefore = this.model_.stateManager.hasState(stateType); |
| 1181 var isStickyBefore = this.model_.stateManager.isSticky(stateType); | 1251 var isStickyBefore = this.model_.stateManager.isSticky(stateType); |
| 1182 this.model_.stateManager.setState(stateType, enable); | 1252 this.model_.stateManager.setState(stateType, enable); |
| 1183 this.model_.stateManager.setSticky(stateType, isSticky); | 1253 this.model_.stateManager.setSticky(stateType, isSticky); |
| 1184 if (isEnabledBefore != enable || isStickyBefore != isSticky) { | 1254 var isFinalSticky = goog.isDef(opt_isFinalSticky) ? opt_isFinalSticky : |
| 1255 false; |
| 1256 var isFinalStikcyBefore = this.model_.stateManager.isFinalSticky(stateType); |
| 1257 this.model_.stateManager.setFinalSticky(stateType, isFinalSticky); |
| 1258 if (isEnabledBefore != enable || isStickyBefore != isSticky || |
| 1259 isFinalStikcyBefore != isFinalSticky) { |
| 1185 this.container_.update(); | 1260 this.container_.update(); |
| 1186 } | 1261 } |
| 1187 }; | 1262 }; |
| 1188 | 1263 |
| 1189 | 1264 |
| 1190 /** | 1265 /** |
| 1191 * Updates the modifier state for context. | 1266 * Updates the modifier state for context. |
| 1192 * | 1267 * |
| 1193 * @private | 1268 * @private |
| 1194 */ | 1269 */ |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 Controller.prototype.switchToKeySet = function(keyset) { | 1436 Controller.prototype.switchToKeySet = function(keyset) { |
| 1362 if (!this.isSettingReady) { | 1437 if (!this.isSettingReady) { |
| 1363 return; | 1438 return; |
| 1364 } | 1439 } |
| 1365 | 1440 |
| 1366 var lastKeysetView = this.container_.currentKeysetView; | 1441 var lastKeysetView = this.container_.currentKeysetView; |
| 1367 var ret = this.container_.switchToKeyset(this.getRemappedKeyset_(keyset), | 1442 var ret = this.container_.switchToKeyset(this.getRemappedKeyset_(keyset), |
| 1368 this.title_, this.adapter_.isPasswordBox(), this.adapter_.isA11yMode, | 1443 this.title_, this.adapter_.isPasswordBox(), this.adapter_.isA11yMode, |
| 1369 keyset, this.currentKeyset_, this.languageCode_); | 1444 keyset, this.currentKeyset_, this.languageCode_); |
| 1370 | 1445 |
| 1371 // Update the keyset of current context type. | 1446 if (!this.isSubKeyset_(this.currentKeyset_, keyset)) { |
| 1372 this.contextTypeToKeysetMap_[this.currentInputMethod_][ | 1447 // If it is the sub keyset switching, don't record it. |
| 1373 this.adapter_.getContextType()] = keyset; | 1448 // Update the keyset of current context type. |
| 1449 this.contextTypeToKeysetMap_[this.currentInputMethod_][ |
| 1450 this.adapter_.getContextType()] = keyset; |
| 1451 } |
| 1374 | 1452 |
| 1375 if (ret) { | 1453 if (ret) { |
| 1376 this.updateLanguageState_(this.currentKeyset_, keyset); | 1454 this.updateLanguageState_(this.currentKeyset_, keyset); |
| 1377 // Deactivate the last keyset view instance. | 1455 // Deactivate the last keyset view instance. |
| 1378 if (lastKeysetView) { | 1456 if (lastKeysetView) { |
| 1379 lastKeysetView.deactivate(this.currentKeyset_); | 1457 lastKeysetView.deactivate(this.currentKeyset_); |
| 1380 } | 1458 } |
| 1381 this.currentKeyset_ = keyset; | 1459 this.currentKeyset_ = keyset; |
| 1382 | 1460 |
| 1383 this.resize(Controller.DEV); | 1461 this.resize(Controller.DEV); |
| 1384 this.statistics_.setCurrentLayout(keyset); | 1462 this.statistics_.recordLayout(keyset, this.adapter_.isA11yMode); |
| 1385 // Activate the current key set view instance. | 1463 // Activate the current key set view instance. |
| 1386 this.container_.currentKeysetView.activate(keyset); | 1464 this.container_.currentKeysetView.activate(keyset); |
| 1387 this.perfTracker_.tick(PerfTracker.TickName.KEYBOARD_SHOWN); | 1465 this.perfTracker_.tick(PerfTracker.TickName.KEYBOARD_SHOWN); |
| 1388 this.perfTracker_.stop(); | 1466 this.perfTracker_.stop(); |
| 1389 } else { | 1467 } else { |
| 1390 this.loadResource_(keyset); | 1468 this.loadResource_(keyset); |
| 1391 } | 1469 } |
| 1392 }; | 1470 }; |
| 1393 | 1471 |
| 1394 | 1472 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 widthPercent = spec.HORIZONTAL; | 1534 widthPercent = spec.HORIZONTAL; |
| 1457 } | 1535 } |
| 1458 } else { | 1536 } else { |
| 1459 widthPercent = spec.VERTICAL; | 1537 widthPercent = spec.VERTICAL; |
| 1460 } | 1538 } |
| 1461 candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT; | 1539 candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT; |
| 1462 } | 1540 } |
| 1463 | 1541 |
| 1464 var viewportSize = goog.dom.getViewportSize(); | 1542 var viewportSize = goog.dom.getViewportSize(); |
| 1465 if (viewportSize.height != height && !opt_ignoreWindowResize) { | 1543 if (viewportSize.height != height && !opt_ignoreWindowResize) { |
| 1466 window.resizeTo(screen.width, height); | 1544 if (this.lastResizeHeight_ != height) { |
| 1545 this.lastResizeHeight_ = height; |
| 1546 window.resizeTo(screen.width, height); |
| 1547 } |
| 1467 return; | 1548 return; |
| 1468 } | 1549 } |
| 1469 | 1550 |
| 1470 this.container_.resize(screen.width, height, widthPercent, | 1551 this.container_.resize(screen.width, height, widthPercent, |
| 1471 candidateViewHeight); | 1552 candidateViewHeight); |
| 1472 if (this.container_.currentKeysetView) { | 1553 if (this.container_.currentKeysetView) { |
| 1473 this.isKeyboardReady = true; | 1554 this.isKeyboardReady = true; |
| 1474 } | 1555 } |
| 1475 }; | 1556 }; |
| 1476 | 1557 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 * | 1619 * |
| 1539 * @param {string} keyset The keyboard keyset. | 1620 * @param {string} keyset The keyboard keyset. |
| 1540 * @param {string} languageCode The language code for this keyboard. | 1621 * @param {string} languageCode The language code for this keyboard. |
| 1541 * @param {string} passwordLayout The layout for password box. | 1622 * @param {string} passwordLayout The layout for password box. |
| 1542 * @param {string} title The title for this keyboard. | 1623 * @param {string} title The title for this keyboard. |
| 1543 */ | 1624 */ |
| 1544 Controller.prototype.initialize = function(keyset, languageCode, passwordLayout, | 1625 Controller.prototype.initialize = function(keyset, languageCode, passwordLayout, |
| 1545 title) { | 1626 title) { |
| 1546 this.perfTracker_.restart(); | 1627 this.perfTracker_.restart(); |
| 1547 this.adapter_.getCurrentInputMethod(function(currentInputMethod) { | 1628 this.adapter_.getCurrentInputMethod(function(currentInputMethod) { |
| 1629 // TODO: remove this hack as soon as the manifest is fixed in chromium. |
| 1630 if (languageCode == 'ko') { |
| 1631 if (currentInputMethod.indexOf('hangul_2set') > 0) { |
| 1632 keyset = 'm17n:ko_2set'; |
| 1633 } |
| 1634 } |
| 1548 this.languageCode_ = languageCode; | 1635 this.languageCode_ = languageCode; |
| 1549 this.currentInputMethod_ = currentInputMethod; | 1636 this.currentInputMethod_ = currentInputMethod; |
| 1550 var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; | 1637 var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; |
| 1551 if (!keySetMap) { | 1638 if (!keySetMap) { |
| 1552 keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {}; | 1639 keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {}; |
| 1553 } | 1640 } |
| 1554 keySetMap[ContextType.PASSWORD] = passwordLayout; | 1641 keySetMap[ContextType.PASSWORD] = passwordLayout; |
| 1555 keySetMap[ContextType.DEFAULT] = keyset; | 1642 keySetMap[ContextType.DEFAULT] = keyset; |
| 1556 | 1643 |
| 1557 this.title_ = title; | 1644 this.title_ = title; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 | 1721 |
| 1635 /** | 1722 /** |
| 1636 * Updates the compact pinyin to set the inputcode for english and pinyin. | 1723 * Updates the compact pinyin to set the inputcode for english and pinyin. |
| 1637 * | 1724 * |
| 1638 * @param {string} fromRawKeyset . | 1725 * @param {string} fromRawKeyset . |
| 1639 * @param {string} toRawKeyset . | 1726 * @param {string} toRawKeyset . |
| 1640 * @private | 1727 * @private |
| 1641 */ | 1728 */ |
| 1642 Controller.prototype.updateLanguageState_ = | 1729 Controller.prototype.updateLanguageState_ = |
| 1643 function(fromRawKeyset, toRawKeyset) { | 1730 function(fromRawKeyset, toRawKeyset) { |
| 1644 if (fromRawKeyset == 'pinyin-zh-CN.en.compact.qwerty' && | 1731 var toggle = false; |
| 1645 toRawKeyset.indexOf('en.compact') == -1) { | 1732 var toggleState = false; |
| 1646 this.adapter_.toggleLanguageState(true); | 1733 // Deal with the switch logic to/from English within the compact layout. |
| 1647 } else if (fromRawKeyset.indexOf('en.compact') == -1 && | 1734 if (fromRawKeyset.indexOf('en.compact') * |
| 1648 toRawKeyset == 'pinyin-zh-CN.en.compact.qwerty') { | 1735 toRawKeyset.indexOf('en.compact') < 0) { // Switches between non-en/en. |
| 1649 this.adapter_.toggleLanguageState(false); | 1736 toggle = true; |
| 1650 } else if (goog.array.contains( | 1737 toggleState = toRawKeyset.indexOf('en.compact') == -1; |
| 1651 i18n.input.chrome.inputview.util.KEYSETS_HAVE_EN_SWTICHER, | 1738 } else if (fromRawKeyset.indexOf(toRawKeyset) == 0 && |
| 1652 toRawKeyset)) { | 1739 fromRawKeyset.indexOf('.compact') > 0 || |
| 1653 this.adapter_.toggleLanguageState(true); | 1740 fromRawKeyset && toRawKeyset.indexOf(fromRawKeyset) == 0 && |
| 1654 this.model_.stateManager.isEnMode = false; | 1741 toRawKeyset.indexOf('.compact') > 0) { |
| 1742 // Switch between full/compact layouts, reset the default button and |
| 1743 // language. |
| 1744 toggle = true; |
| 1745 toggleState = true; |
| 1746 } |
| 1747 if (toggle) { |
| 1748 this.adapter_.toggleLanguageState(toggleState); |
| 1749 this.model_.stateManager.isEnMode = !toggleState; |
| 1655 this.container_.currentKeysetView.update(); | 1750 this.container_.currentKeysetView.update(); |
| 1656 } | 1751 } |
| 1657 }; | 1752 }; |
| 1753 |
| 1754 |
| 1755 /** |
| 1756 * Records the stats which will be reported when input view is closing. |
| 1757 * |
| 1758 * @param {string} name The metrics name. |
| 1759 * @param {number} count The count value for histogram. |
| 1760 * @param {number} max . |
| 1761 * @param {number} bucketCount . |
| 1762 * @private |
| 1763 */ |
| 1764 Controller.prototype.recordStatsForClosing_ = function( |
| 1765 name, count, max, bucketCount) { |
| 1766 if (!this.statsForClosing_[name]) { |
| 1767 this.statsForClosing_[name] = [count, max, bucketCount]; |
| 1768 } else { |
| 1769 this.statsForClosing_[name][0] += count; |
| 1770 this.statsForClosing_[name][1] = max; |
| 1771 this.statsForClosing_[name][2] = bucketCount; |
| 1772 } |
| 1773 }; |
| 1658 }); // goog.scope | 1774 }); // goog.scope |
| OLD | NEW |