| 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.Timer'); | 17 goog.require('goog.Timer'); |
| 18 goog.require('goog.array'); | 18 goog.require('goog.array'); |
| 19 goog.require('goog.async.Delay'); | 19 goog.require('goog.async.Delay'); |
| 20 goog.require('goog.dom.classlist'); | 20 goog.require('goog.dom.classlist'); |
| 21 goog.require('goog.events.Event'); | 21 goog.require('goog.events.Event'); |
| 22 goog.require('goog.events.EventHandler'); | 22 goog.require('goog.events.EventHandler'); |
| 23 goog.require('goog.events.EventType'); | 23 goog.require('goog.events.EventType'); |
| 24 goog.require('goog.events.KeyCodes'); | 24 goog.require('goog.events.KeyCodes'); |
| 25 goog.require('goog.fx.easing'); |
| 25 goog.require('goog.i18n.bidi'); | 26 goog.require('goog.i18n.bidi'); |
| 27 goog.require('goog.math.Coordinate'); |
| 26 goog.require('goog.object'); | 28 goog.require('goog.object'); |
| 27 goog.require('i18n.input.chrome.DataSource'); | 29 goog.require('i18n.input.chrome.DataSource'); |
| 30 goog.require('i18n.input.chrome.ElementType'); |
| 31 goog.require('i18n.input.chrome.FeatureName'); |
| 28 goog.require('i18n.input.chrome.Statistics'); | 32 goog.require('i18n.input.chrome.Statistics'); |
| 33 goog.require('i18n.input.chrome.events.KeyCodes'); |
| 29 goog.require('i18n.input.chrome.inputview.Adapter'); | 34 goog.require('i18n.input.chrome.inputview.Adapter'); |
| 30 goog.require('i18n.input.chrome.inputview.CandidatesInfo'); | 35 goog.require('i18n.input.chrome.inputview.CandidatesInfo'); |
| 31 goog.require('i18n.input.chrome.inputview.ConditionName'); | 36 goog.require('i18n.input.chrome.inputview.ConditionName'); |
| 32 goog.require('i18n.input.chrome.inputview.Css'); | 37 goog.require('i18n.input.chrome.inputview.Css'); |
| 33 goog.require('i18n.input.chrome.inputview.FeatureName'); | |
| 34 goog.require('i18n.input.chrome.inputview.KeyboardContainer'); | 38 goog.require('i18n.input.chrome.inputview.KeyboardContainer'); |
| 35 goog.require('i18n.input.chrome.inputview.M17nModel'); | 39 goog.require('i18n.input.chrome.inputview.M17nModel'); |
| 36 goog.require('i18n.input.chrome.inputview.Model'); | 40 goog.require('i18n.input.chrome.inputview.Model'); |
| 37 goog.require('i18n.input.chrome.inputview.PerfTracker'); | 41 goog.require('i18n.input.chrome.inputview.PerfTracker'); |
| 38 goog.require('i18n.input.chrome.inputview.ReadyState'); | 42 goog.require('i18n.input.chrome.inputview.ReadyState'); |
| 39 goog.require('i18n.input.chrome.inputview.Settings'); | 43 goog.require('i18n.input.chrome.inputview.Settings'); |
| 40 goog.require('i18n.input.chrome.inputview.SizeSpec'); | 44 goog.require('i18n.input.chrome.inputview.SizeSpec'); |
| 41 goog.require('i18n.input.chrome.inputview.SpecNodeName'); | 45 goog.require('i18n.input.chrome.inputview.SpecNodeName'); |
| 42 goog.require('i18n.input.chrome.inputview.StateType'); | 46 goog.require('i18n.input.chrome.inputview.StateType'); |
| 43 goog.require('i18n.input.chrome.inputview.SwipeDirection'); | 47 goog.require('i18n.input.chrome.inputview.SwipeDirection'); |
| 44 goog.require('i18n.input.chrome.inputview.elements.ElementType'); | |
| 45 goog.require('i18n.input.chrome.inputview.elements.content.Candidate'); | 48 goog.require('i18n.input.chrome.inputview.elements.content.Candidate'); |
| 46 goog.require('i18n.input.chrome.inputview.elements.content.CandidateView'); | 49 goog.require('i18n.input.chrome.inputview.elements.content.CandidateView'); |
| 47 goog.require('i18n.input.chrome.inputview.elements.content.ExpandedCandidateView
'); | 50 goog.require('i18n.input.chrome.inputview.elements.content.ExpandedCandidateView
'); |
| 48 goog.require('i18n.input.chrome.inputview.elements.content.MenuView'); | 51 goog.require('i18n.input.chrome.inputview.elements.content.MenuView'); |
| 49 goog.require('i18n.input.chrome.inputview.events.EventType'); | 52 goog.require('i18n.input.chrome.inputview.events.EventType'); |
| 50 goog.require('i18n.input.chrome.inputview.events.KeyCodes'); | |
| 51 goog.require('i18n.input.chrome.inputview.handler.PointerHandler'); | 53 goog.require('i18n.input.chrome.inputview.handler.PointerHandler'); |
| 52 goog.require('i18n.input.chrome.inputview.util'); | 54 goog.require('i18n.input.chrome.inputview.util'); |
| 53 goog.require('i18n.input.chrome.message.ContextType'); | 55 goog.require('i18n.input.chrome.message.ContextType'); |
| 54 goog.require('i18n.input.chrome.message.Name'); | 56 goog.require('i18n.input.chrome.message.Name'); |
| 55 goog.require('i18n.input.chrome.message.Type'); | 57 goog.require('i18n.input.chrome.message.Type'); |
| 56 goog.require('i18n.input.chrome.sounds.SoundController'); | 58 goog.require('i18n.input.chrome.sounds.SoundController'); |
| 57 goog.require('i18n.input.lang.InputToolCode'); | 59 goog.require('i18n.input.lang.InputToolCode'); |
| 58 | 60 |
| 59 | 61 |
| 60 | 62 |
| 61 goog.scope(function() { | 63 goog.scope(function() { |
| 62 var CandidateType = i18n.input.chrome.inputview.elements.content.Candidate.Type; | 64 var CandidateType = i18n.input.chrome.inputview.elements.content.Candidate.Type; |
| 63 var CandidateView = i18n.input.chrome.inputview.elements.content.CandidateView; | 65 var CandidateView = i18n.input.chrome.inputview.elements.content.CandidateView; |
| 64 var ConditionName = i18n.input.chrome.inputview.ConditionName; | 66 var ConditionName = i18n.input.chrome.inputview.ConditionName; |
| 65 var ContextType = i18n.input.chrome.message.ContextType; | 67 var ContextType = i18n.input.chrome.message.ContextType; |
| 66 var Css = i18n.input.chrome.inputview.Css; | 68 var Css = i18n.input.chrome.inputview.Css; |
| 67 var ElementType = i18n.input.chrome.inputview.elements.ElementType; | 69 var ElementType = i18n.input.chrome.ElementType; |
| 68 var EventType = i18n.input.chrome.inputview.events.EventType; | 70 var EventType = i18n.input.chrome.inputview.events.EventType; |
| 69 var ExpandedCandidateView = i18n.input.chrome.inputview.elements.content. | 71 var ExpandedCandidateView = i18n.input.chrome.inputview.elements.content. |
| 70 ExpandedCandidateView; | 72 ExpandedCandidateView; |
| 71 var FeatureName = i18n.input.chrome.inputview.FeatureName; | 73 var FeatureName = i18n.input.chrome.FeatureName; |
| 72 var InputToolCode = i18n.input.lang.InputToolCode; | 74 var InputToolCode = i18n.input.lang.InputToolCode; |
| 73 var KeyCodes = i18n.input.chrome.inputview.events.KeyCodes; | 75 var KeyCodes = i18n.input.chrome.events.KeyCodes; |
| 74 var MenuView = i18n.input.chrome.inputview.elements.content.MenuView; | 76 var MenuView = i18n.input.chrome.inputview.elements.content.MenuView; |
| 75 var Name = i18n.input.chrome.message.Name; | 77 var Name = i18n.input.chrome.message.Name; |
| 76 var PerfTracker = i18n.input.chrome.inputview.PerfTracker; | 78 var PerfTracker = i18n.input.chrome.inputview.PerfTracker; |
| 77 var SizeSpec = i18n.input.chrome.inputview.SizeSpec; | 79 var SizeSpec = i18n.input.chrome.inputview.SizeSpec; |
| 78 var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName; | 80 var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName; |
| 79 var StateType = i18n.input.chrome.inputview.StateType; | 81 var StateType = i18n.input.chrome.inputview.StateType; |
| 80 var SoundController = i18n.input.chrome.sounds.SoundController; | 82 var SoundController = i18n.input.chrome.sounds.SoundController; |
| 81 var Type = i18n.input.chrome.message.Type; | 83 var Type = i18n.input.chrome.message.Type; |
| 82 var events = i18n.input.chrome.inputview.events; | 84 var events = i18n.input.chrome.inputview.events; |
| 83 var util = i18n.input.chrome.inputview.util; | 85 var util = i18n.input.chrome.inputview.util; |
| 84 | 86 |
| 85 | 87 |
| 88 /** |
| 89 * Time in milliseconds after which backspace will start autorepeating. |
| 90 * @const {number} |
| 91 */ |
| 92 var BACKSPACE_REPEAT_START_TIME_MS = 300; |
| 93 |
| 94 |
| 95 /** |
| 96 * Minimum time, in milliseconds, after which backspace can repeat. This |
| 97 * prevents deleting entire pages in a go. |
| 98 * @const {number} |
| 99 */ |
| 100 var MINIMUM_BACKSPACE_REPEAT_TIME_MS = 25; |
| 101 |
| 102 |
| 103 /** |
| 104 * Maximum time, in milliseconds, after which the backspace can repeat. |
| 105 * @const {number} |
| 106 */ |
| 107 var MAXIMUM_BACKSPACE_REPEAT_TIME_MS = 75; |
| 108 |
| 109 |
| 110 /** |
| 111 * The limit for backspace repeat for speeding up. |
| 112 * The backspace repeat beyond this limit will have the maximum speed. |
| 113 * @const {number} |
| 114 */ |
| 115 var BACKSPACE_REPEAT_LIMIT = 255; |
| 116 |
| 117 |
| 118 /** |
| 119 * The time, in milliseconds, that the gesture preview window lingers before |
| 120 * being dismissed. |
| 121 * |
| 122 * @const {number} |
| 123 */ |
| 124 var GESTURE_PREVIEW_LINGER_TIME_MS = 250; |
| 125 |
| 126 |
| 127 /** |
| 128 * The maximum distance from the top of the keyboard that a gesture can move |
| 129 * before it cancels the gesture typing gesture. |
| 130 * |
| 131 * @const {number} |
| 132 */ |
| 133 var MAXIMUM_DISTANCE_FROM_TOP_FOR_GESTURES = 40; |
| 134 |
| 135 |
| 136 /** |
| 137 * The hotrod customized layout code. |
| 138 * |
| 139 * @const {string} |
| 140 */ |
| 141 var HOTROD_DEFAULT_KEYSET = 'hotrod'; |
| 142 |
| 143 |
| 86 | 144 |
| 87 /** | 145 /** |
| 88 * The controller of the input view keyboard. | 146 * The controller of the input view keyboard. |
| 89 * | 147 * |
| 90 * @param {string} keyset The keyboard keyset. | 148 * @param {string} keyset The keyboard keyset. |
| 91 * @param {string} languageCode The language code for this keyboard. | 149 * @param {string} languageCode The language code for this keyboard. |
| 92 * @param {string} passwordLayout The layout for password box. | 150 * @param {string} passwordLayout The layout for password box. |
| 93 * @param {string} name The input tool name. | 151 * @param {string} name The input tool name. |
| 94 * @constructor | 152 * @constructor |
| 95 * @extends {goog.Disposable} | 153 * @extends {goog.Disposable} |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 /** @private {!i18n.input.chrome.inputview.ReadyState} */ | 235 /** @private {!i18n.input.chrome.inputview.ReadyState} */ |
| 178 this.readyState_ = new i18n.input.chrome.inputview.ReadyState(); | 236 this.readyState_ = new i18n.input.chrome.inputview.ReadyState(); |
| 179 | 237 |
| 180 /** @private {!i18n.input.chrome.inputview.Adapter} */ | 238 /** @private {!i18n.input.chrome.inputview.Adapter} */ |
| 181 this.adapter_ = new i18n.input.chrome.inputview.Adapter(this.readyState_); | 239 this.adapter_ = new i18n.input.chrome.inputview.Adapter(this.readyState_); |
| 182 | 240 |
| 183 /** @private {!SoundController} */ | 241 /** @private {!SoundController} */ |
| 184 this.soundController_ = new SoundController(false); | 242 this.soundController_ = new SoundController(false); |
| 185 | 243 |
| 186 /** | 244 /** |
| 187 * Whether or not to commit the next gesture result. | 245 * Whether or not the candidates were last set by gesture typing. |
| 188 * | 246 * |
| 189 * @private {boolean} | 247 * @private {boolean} |
| 190 */ | 248 */ |
| 191 this.commitNextGestureResult_ = false; | 249 this.candidatesSetByGestureTyping_ = false; |
| 192 | 250 |
| 193 /** @private {!i18n.input.chrome.inputview.KeyboardContainer} */ | 251 /** @private {!i18n.input.chrome.inputview.KeyboardContainer} */ |
| 194 this.container_ = new i18n.input.chrome.inputview.KeyboardContainer( | 252 this.container_ = new i18n.input.chrome.inputview.KeyboardContainer( |
| 195 this.adapter_, this.soundController_); | 253 this.adapter_, this.soundController_); |
| 196 | 254 |
| 197 /** | 255 /** |
| 198 * The context type and keyset mapping group by input method id. | 256 * The context type and keyset mapping group by input method id. |
| 199 * key: input method id. | 257 * key: input method id. |
| 200 * value: Object | 258 * value: Object |
| 201 * key: context type string. | 259 * key: context type string. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 /** | 307 /** |
| 250 * The suggestions. | 308 * The suggestions. |
| 251 * Note: sets a default empty result to avoid null check. | 309 * Note: sets a default empty result to avoid null check. |
| 252 * | 310 * |
| 253 * @private {!i18n.input.chrome.inputview.CandidatesInfo} | 311 * @private {!i18n.input.chrome.inputview.CandidatesInfo} |
| 254 */ | 312 */ |
| 255 this.candidatesInfo_ = i18n.input.chrome.inputview.CandidatesInfo.getEmpty(); | 313 this.candidatesInfo_ = i18n.input.chrome.inputview.CandidatesInfo.getEmpty(); |
| 256 | 314 |
| 257 this.registerEventHandler_(); | 315 this.registerEventHandler_(); |
| 258 }; | 316 }; |
| 259 goog.inherits(i18n.input.chrome.inputview.Controller, | 317 goog.inherits(i18n.input.chrome.inputview.Controller, goog.Disposable); |
| 260 goog.Disposable); | |
| 261 var Controller = i18n.input.chrome.inputview.Controller; | 318 var Controller = i18n.input.chrome.inputview.Controller; |
| 319 var Statistics = i18n.input.chrome.Statistics; |
| 320 |
| 321 /** |
| 322 * @define {boolean} Flag to disable delayed loading of non active keyset. It |
| 323 * should only be used in testing. |
| 324 */ |
| 325 Controller.DISABLE_DELAY_LOADING_FOR_TEST = false; |
| 262 | 326 |
| 263 | 327 |
| 264 /** | 328 /** |
| 265 * @define {boolean} Flag to disable handwriting. | 329 * @define {boolean} Flag to disable handwriting. |
| 266 */ | 330 */ |
| 267 Controller.DISABLE_HWT = false; | 331 Controller.DISABLE_HWT = false; |
| 268 | 332 |
| 269 | 333 |
| 270 /** | 334 /** |
| 271 * A flag to indicate whether the shift is for auto capital. | 335 * A flag to indicate whether the shift is for auto capital. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 293 /** | 357 /** |
| 294 * The emoji view code, use the code can switch to emoji. | 358 * The emoji view code, use the code can switch to emoji. |
| 295 * | 359 * |
| 296 * @const {string} | 360 * @const {string} |
| 297 * @private | 361 * @private |
| 298 */ | 362 */ |
| 299 Controller.EMOJI_VIEW_CODE_ = 'emoji'; | 363 Controller.EMOJI_VIEW_CODE_ = 'emoji'; |
| 300 | 364 |
| 301 | 365 |
| 302 /** | 366 /** |
| 303 * The limitation for backspace repeat time to avoid unexpected | |
| 304 * problem that backspace is held all the time. | |
| 305 * | |
| 306 * @private {number} | |
| 307 */ | |
| 308 Controller.BACKSPACE_REPEAT_LIMIT_ = 255; | |
| 309 | |
| 310 | |
| 311 /** | |
| 312 * The repeated times of the backspace. | 367 * The repeated times of the backspace. |
| 313 * | 368 * |
| 314 * @private {number} | 369 * @private {number} |
| 315 */ | 370 */ |
| 316 Controller.prototype.backspaceRepeated_ = 0; | 371 Controller.prototype.backspaceRepeated_ = 0; |
| 317 | 372 |
| 318 | 373 |
| 319 /** | 374 /** |
| 320 * The handwriting input tool code suffix. | 375 * The handwriting input tool code suffix. |
| 321 * | 376 * |
| 322 * @const {string} | 377 * @const {string} |
| 323 * @private | 378 * @private |
| 324 */ | 379 */ |
| 325 Controller.HANDWRITING_CODE_SUFFIX_ = '-t-i0-handwrit'; | 380 Controller.HANDWRITING_CODE_SUFFIX_ = '-t-i0-handwrit'; |
| 326 | 381 |
| 327 | 382 |
| 328 /** | 383 /** |
| 329 * The US English compact layout prefix. | 384 * The US English compact layout qwerty code. |
| 330 * | 385 * |
| 331 * @const {string} | 386 * @const {string} |
| 332 * @private | 387 * @private |
| 333 */ | 388 */ |
| 334 Controller.US_COMPACT_PREFIX_ = 'us.compact'; | 389 Controller.US_COMPACT_QWERTY_CODE_ = 'us.compact.qwerty'; |
| 335 | 390 |
| 336 | 391 |
| 337 /** | 392 /** |
| 338 * Time threshold between samples sent to the back end. | 393 * Time threshold between samples sent to the back end. |
| 339 * | 394 * |
| 340 * @const {number} | 395 * @const {number} |
| 341 */ | 396 */ |
| 342 Controller.SUBSAMPLING_TIME_THRESHOLD = 100; | 397 Controller.SUBSAMPLING_TIME_THRESHOLD = 100; |
| 343 | 398 |
| 344 | 399 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 } | 665 } |
| 611 if (goog.isDef(e.msg['doubleSpacePeriod'])) { | 666 if (goog.isDef(e.msg['doubleSpacePeriod'])) { |
| 612 settings.doubleSpacePeriod = e.msg['doubleSpacePeriod']; | 667 settings.doubleSpacePeriod = e.msg['doubleSpacePeriod']; |
| 613 } | 668 } |
| 614 if (goog.isDef(e.msg['soundOnKeypress'])) { | 669 if (goog.isDef(e.msg['soundOnKeypress'])) { |
| 615 settings.soundOnKeypress = e.msg['soundOnKeypress']; | 670 settings.soundOnKeypress = e.msg['soundOnKeypress']; |
| 616 this.soundController_.setEnabled(settings.soundOnKeypress); | 671 this.soundController_.setEnabled(settings.soundOnKeypress); |
| 617 } | 672 } |
| 618 if (goog.isDef(e.msg['gestureEditing'])) { | 673 if (goog.isDef(e.msg['gestureEditing'])) { |
| 619 settings.gestureEditing = e.msg['gestureEditing']; | 674 settings.gestureEditing = e.msg['gestureEditing']; |
| 620 var enabled = settings.gestureEditing && !this.adapter_.isA11yMode; | 675 var enabled = settings.gestureEditing && !this.adapter_.isA11yMode && |
| 676 !this.adapter_.isHotrod && |
| 677 !this.adapter_.isFloatingVirtualKeyboardEnabled(); |
| 621 this.container_.swipeView.enabled = enabled; | 678 this.container_.swipeView.enabled = enabled; |
| 622 this.container_.selectView.setSettingsEnabled(enabled); | 679 this.container_.selectView.setSettingsEnabled(enabled); |
| 623 } | 680 } |
| 624 if (goog.isDef(e.msg['gestureTyping'])) { | 681 if (goog.isDef(e.msg['gestureTyping'])) { |
| 625 settings.gestureTyping = e.msg['gestureTyping']; | 682 settings.gestureTyping = e.msg['gestureTyping']; |
| 626 } else { | 683 } else { |
| 627 settings.gestureTyping = false; | 684 settings.gestureTyping = false; |
| 628 } | 685 } |
| 629 this.perfTracker_.tick(PerfTracker.TickName.BACKGROUND_SETTINGS_FETCHED); | 686 this.perfTracker_.tick(PerfTracker.TickName.BACKGROUND_SETTINGS_FETCHED); |
| 630 this.model_.stateManager.contextType = this.adapter_.contextType; | 687 this.model_.stateManager.contextType = this.adapter_.contextType; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 654 | 711 |
| 655 this.isSettingReady = true; | 712 this.isSettingReady = true; |
| 656 // Don't render container twice. | 713 // Don't render container twice. |
| 657 if (!this.container_.isInDocument()) { | 714 if (!this.container_.isInDocument()) { |
| 658 this.container_.render(); | 715 this.container_.render(); |
| 659 } | 716 } |
| 660 var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; | 717 var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; |
| 661 var newKeyset = ''; | 718 var newKeyset = ''; |
| 662 if (this.adapter_.isA11yMode) { | 719 if (this.adapter_.isA11yMode) { |
| 663 newKeyset = util.getConfigName(keysetMap[ContextType.DEFAULT]); | 720 newKeyset = util.getConfigName(keysetMap[ContextType.DEFAULT]); |
| 721 } else if (this.adapter_.isHotrod) { |
| 722 newKeyset = HOTROD_DEFAULT_KEYSET; |
| 664 } else { | 723 } else { |
| 665 newKeyset = /** @type {string} */ (this.model_.settings. | 724 newKeyset = /** @type {string} */ (this.model_.settings. |
| 666 getPreference(util.getConfigName(keysetMap[ContextType.DEFAULT]))); | 725 getPreference(util.getConfigName(keysetMap[ContextType.DEFAULT]))); |
| 667 } | 726 } |
| 668 if (!this.adapter_.features.isEnabled(FeatureName.EXPERIMENTAL) && | 727 |
| 669 keysetMap[ContextType.DEFAULT] == | |
| 670 'zhuyin.compact.qwerty') { | |
| 671 newKeyset = 'zhuyin'; | |
| 672 } | |
| 673 if (newKeyset) { | 728 if (newKeyset) { |
| 674 this.setDefaultKeyset_(newKeyset); | 729 this.setDefaultKeyset_(newKeyset); |
| 675 } | 730 } |
| 676 this.container_.selectView.setSettingsEnabled( | 731 this.container_.selectView.setSettingsEnabled( |
| 677 this.model_.settings.gestureEditing && !this.adapter_.isA11yMode); | 732 this.model_.settings.gestureEditing && !this.adapter_.isA11yMode && |
| 733 !this.adapter_.isHotrod); |
| 678 // Loads resources in case the default keyset is changed. | 734 // Loads resources in case the default keyset is changed. |
| 679 this.loadAllResources_(); | 735 this.loadAllResources_(); |
| 680 this.maybeCreateViews_(); | 736 this.maybeCreateViews_(); |
| 681 }; | 737 }; |
| 682 | 738 |
| 683 | 739 |
| 684 /** | 740 /** |
| 685 * Returns whether or not the gesture typing feature is enabled. | 741 * Returns whether or not the gesture typing feature is enabled. |
| 686 * | 742 * |
| 687 * @return {boolean} | 743 * @return {boolean} |
| 688 * @private | 744 * @private |
| 689 */ | 745 */ |
| 690 Controller.prototype.gestureTypingEnabled_ = function() { | 746 Controller.prototype.gestureTypingEnabled_ = function() { |
| 691 return this.isKeysetUSCompact_ && this.model_.settings.gestureTyping && | 747 return this.isKeysetUSCompact_ && this.model_.settings.gestureTyping && |
| 692 !this.adapter_.isA11yMode && !this.adapter_.isChromeVoxOn; | 748 !this.adapter_.isA11yMode && !this.adapter_.isHotrod && |
| 749 !this.adapter_.isChromeVoxOn && |
| 750 !this.adapter_.isPasswordBox() && |
| 751 !this.adapter_.isFloatingVirtualKeyboardEnabled() && |
| 752 !this.container_.altDataView.isVisible() && |
| 753 !this.container_.menuView.isVisible() && |
| 754 !this.container_.voiceView.isVisible(); |
| 693 }; | 755 }; |
| 694 | 756 |
| 695 | 757 |
| 696 /** | 758 /** |
| 697 * Returns the time threshold for subsampling, in ms. | 759 * Returns the time threshold for subsampling, in ms. |
| 698 * | 760 * |
| 699 * @return {number} | 761 * @return {number} |
| 700 * @private | 762 * @private |
| 701 */ | 763 */ |
| 702 Controller.prototype.subsamplingThreshold_ = function() { | 764 Controller.prototype.subsamplingThreshold_ = function() { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 | 803 |
| 742 | 804 |
| 743 /** | 805 /** |
| 744 * Gets the key content. | 806 * Gets the key content. |
| 745 * | 807 * |
| 746 * @param {!i18n.input.chrome.inputview.elements.content.SoftKey} key . | 808 * @param {!i18n.input.chrome.inputview.elements.content.SoftKey} key . |
| 747 * @return {string} . | 809 * @return {string} . |
| 748 * @private | 810 * @private |
| 749 */ | 811 */ |
| 750 Controller.prototype.getKeyContent_ = function(key) { | 812 Controller.prototype.getKeyContent_ = function(key) { |
| 751 if (key.type == i18n.input.chrome.inputview.elements.ElementType. | 813 if (key.type == i18n.input.chrome.ElementType. |
| 752 CHARACTER_KEY) { | 814 CHARACTER_KEY) { |
| 753 key = /** @type {!i18n.input.chrome.inputview.elements.content. | 815 key = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 754 CharacterKey} */ (key); | 816 CharacterKey} */ (key); |
| 755 return key.getActiveCharacter(); | 817 return key.getActiveCharacter(); |
| 756 } | 818 } |
| 757 if (key.type == i18n.input.chrome.inputview.elements.ElementType. | 819 if (key.type == i18n.input.chrome.ElementType. |
| 758 COMPACT_KEY) { | 820 COMPACT_KEY) { |
| 759 key = /** @type {!i18n.input.chrome.inputview.elements.content. | 821 key = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 760 FunctionalKey} */ (key); | 822 FunctionalKey} */ (key); |
| 761 return key.text; | 823 return key.text; |
| 762 } | 824 } |
| 763 return ''; | 825 return ''; |
| 764 }; | 826 }; |
| 765 | 827 |
| 766 | 828 |
| 767 /** | 829 /** |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 if (!opt_force && currentTime - this.lastPointTime_ < | 888 if (!opt_force && currentTime - this.lastPointTime_ < |
| 827 this.subsamplingThreshold_()) { | 889 this.subsamplingThreshold_()) { |
| 828 return; | 890 return; |
| 829 } else { | 891 } else { |
| 830 this.lastPointTime_ = currentTime; | 892 this.lastPointTime_ = currentTime; |
| 831 } | 893 } |
| 832 var lastStroke = this.container_.gestureCanvasView.getLastStroke(); | 894 var lastStroke = this.container_.gestureCanvasView.getLastStroke(); |
| 833 if (lastStroke) { | 895 if (lastStroke) { |
| 834 // This call will set up the necessary callbacks the decoder will use to | 896 // This call will set up the necessary callbacks the decoder will use to |
| 835 // communicate back to this class. | 897 // communicate back to this class. |
| 836 this.adapter_.sendGestureEvent(lastStroke.points); | 898 this.adapter_.sendGestureEvent(lastStroke.getPoints()); |
| 837 } | 899 } |
| 838 }; | 900 }; |
| 839 | 901 |
| 840 | 902 |
| 841 /** | 903 /** |
| 842 * Handles the drag events. Generally, this will forward the event details to | 904 * Handles the drag events. Generally, this will forward the event details to |
| 843 * the components that handle drawing, decoding, etc. | 905 * the components that handle drawing, decoding, etc. |
| 844 * | 906 * |
| 845 * @param {!i18n.input.chrome.inputview.events.DragEvent} e . | 907 * @param {!i18n.input.chrome.inputview.events.DragEvent} e . |
| 846 * @private | 908 * @private |
| 847 */ | 909 */ |
| 848 Controller.prototype.onDragEvent_ = function(e) { | 910 Controller.prototype.onDragEvent_ = function(e) { |
| 849 if (this.gestureTypingEnabled_() && e.type == EventType.DRAG && | 911 if (this.gestureTypingEnabled_() && e.type == EventType.DRAG && |
| 850 !this.container_.swipeView.isVisible()) { | 912 !this.container_.swipeView.isVisible()) { |
| 913 // Conveniently, the DragEvent has coordinates relative to the gesture |
| 914 // canvas view, so we can test it's y coordinate in order to determine if |
| 915 // we're off the canvas. |
| 916 if (e.y + MAXIMUM_DISTANCE_FROM_TOP_FOR_GESTURES < 0) { |
| 917 this.container_.gestureCanvasView.clear(); |
| 918 this.container_.gesturePreviewWindow.hide(); |
| 919 this.clearCandidates_(); |
| 920 return; |
| 921 } |
| 851 this.container_.gestureCanvasView.addPoint(e); | 922 this.container_.gestureCanvasView.addPoint(e); |
| 852 if (e.view && this.container_.gestureCanvasView.isGesturing) { | 923 if (e.view && this.container_.gestureCanvasView.isGesturing) { |
| 853 // Ensure the last touched key is not highlighted. | 924 // Ensure the last touched key is not highlighted. |
| 854 e.view.setHighlighted(false); | 925 if (e.view.type != ElementType.MODIFIER_KEY) { |
| 926 e.view.setHighlighted(false); |
| 927 } |
| 855 this.maybeSendLastStroke_(); | 928 this.maybeSendLastStroke_(); |
| 929 // Reposition the gesture preview window to follow the user's touch point. |
| 930 if (this.container_.gesturePreviewWindow && |
| 931 this.container_.gestureCanvasView.isActiveIdentifier( |
| 932 e.identifier)) { |
| 933 this.container_.gesturePreviewWindow.reposition( |
| 934 new goog.math.Coordinate(e.x, e.y)); |
| 935 } |
| 856 } | 936 } |
| 857 return; | |
| 858 } | 937 } |
| 859 }; | 938 }; |
| 860 | 939 |
| 861 | 940 |
| 862 /** | 941 /** |
| 863 * Handles the swipe action. | 942 * Handles the swipe action. |
| 864 * | 943 * |
| 865 * @param {!i18n.input.chrome.inputview.elements.Element} view The view, for | 944 * @param {!i18n.input.chrome.inputview.elements.Element} view The view, for |
| 866 * swipe event, the view would be the soft key which starts the swipe. | 945 * swipe event, the view would be the soft key which starts the swipe. |
| 867 * @param {!i18n.input.chrome.inputview.events.SwipeEvent} e The swipe event. | 946 * @param {!i18n.input.chrome.inputview.events.SwipeEvent} e The swipe event. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 this.currentKeyset_; | 1021 this.currentKeyset_; |
| 943 // TODO: remember handwriting keyset. | 1022 // TODO: remember handwriting keyset. |
| 944 this.switchToKeyset(Controller.HANDWRITING_VIEW_CODE_); | 1023 this.switchToKeyset(Controller.HANDWRITING_VIEW_CODE_); |
| 945 break; | 1024 break; |
| 946 | 1025 |
| 947 case CommandEnum.OPEN_SETTING: | 1026 case CommandEnum.OPEN_SETTING: |
| 948 if (window.inputview) { | 1027 if (window.inputview) { |
| 949 inputview.openSettings(); | 1028 inputview.openSettings(); |
| 950 } | 1029 } |
| 951 break; | 1030 break; |
| 952 | |
| 953 case CommandEnum.FLOATING: | |
| 954 if (inputview.setMode) { | |
| 955 inputview.setMode('FLOATING'); | |
| 956 this.adapter_.isFloating = true; | |
| 957 this.container_.candidateView.setFloatingVKButtonsVisible(true); | |
| 958 this.resize(); | |
| 959 setTimeout(function() { | |
| 960 var x = Math.floor((screen.width - window.innerWidth) / 2); | |
| 961 window.moveTo(x, window.screenY); | |
| 962 }, 0); | |
| 963 } | |
| 964 break; | |
| 965 | |
| 966 case CommandEnum.DOCKING: | |
| 967 if (inputview.setMode) { | |
| 968 inputview.setMode('FULL_WIDTH'); | |
| 969 this.adapter_.isFloating = false; | |
| 970 this.container_.candidateView.setFloatingVKButtonsVisible(false); | |
| 971 } | |
| 972 break; | |
| 973 | |
| 974 } | 1031 } |
| 975 }; | 1032 }; |
| 976 | 1033 |
| 977 | 1034 |
| 1035 /** |
| 1036 * Returns the gesture typing event type for a given candidate ID. |
| 1037 * |
| 1038 * @param {number} candidateID The candidate ID to convert. |
| 1039 * @return {?i18n.input.chrome.Statistics.GestureTypingEvent} The gesture |
| 1040 * typing event type for the given candidate. Null if the candidate was not |
| 1041 * found. |
| 1042 * @private |
| 1043 */ |
| 1044 Controller.prototype.getGestureEventTypeForCandidateID_ = |
| 1045 function(candidateID) { |
| 1046 if (candidateID == 0) { |
| 1047 return Statistics.GestureTypingEvent.REPLACED_0; |
| 1048 } else if (candidateID == 1) { |
| 1049 return Statistics.GestureTypingEvent.REPLACED_1; |
| 1050 } else if (candidateID >= 2) { |
| 1051 return Statistics.GestureTypingEvent.REPLACED_2; |
| 1052 } |
| 1053 return null; |
| 1054 }; |
| 1055 |
| 1056 |
| 978 /** | 1057 /** |
| 979 * Handles the pointer action. | 1058 * Handles the pointer action. |
| 980 * | 1059 * |
| 981 * @param {!i18n.input.chrome.inputview.elements.Element} view The view. | 1060 * @param {!i18n.input.chrome.inputview.elements.Element} view The view. |
| 982 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . | 1061 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . |
| 983 * @private | 1062 * @private |
| 984 */ | 1063 */ |
| 985 Controller.prototype.handlePointerAction_ = function(view, e) { | 1064 Controller.prototype.handlePointerAction_ = function(view, e) { |
| 986 if (this.gestureTypingEnabled_() && !this.container_.swipeView.isVisible()) { | 1065 if (this.gestureTypingEnabled_() && !this.container_.swipeView.isVisible()) { |
| 987 if (e.type == EventType.POINTER_DOWN) { | 1066 if (e.type == EventType.POINTER_DOWN) { |
| 1067 // Do some clean up before starting a new stroke. |
| 1068 this.container_.gestureCanvasView.removeEmptyStrokes(); |
| 988 this.container_.gestureCanvasView.startStroke(e); | 1069 this.container_.gestureCanvasView.startStroke(e); |
| 989 view.setHighlighted(false); | 1070 if (view.type != ElementType.MODIFIER_KEY) { |
| 1071 view.setHighlighted(false); |
| 1072 } |
| 990 } | 1073 } |
| 991 | 1074 |
| 992 // Determine if the gestureCanvasView was handling a gesture before calling | 1075 // Determine if the gestureCanvasView was handling a gesture before calling |
| 993 // endStroke, as it ends the current gesture. | 1076 // endStroke, as it ends the current gesture. |
| 994 var wasGesturing = this.container_.gestureCanvasView.isGesturing; | 1077 var wasGesturing = this.container_.gestureCanvasView.isGesturing; |
| 995 if (e.type == EventType.POINTER_UP && wasGesturing) { | 1078 if (e.type == EventType.POINTER_UP && wasGesturing) { |
| 996 this.container_.gestureCanvasView.endStroke(e); | 1079 this.container_.gestureCanvasView.endStroke(e); |
| 997 this.maybeSendLastStroke_(true); | 1080 this.maybeSendLastStroke_(true); |
| 998 this.commitNextGestureResult_ = true; | |
| 999 } | 1081 } |
| 1000 | 1082 |
| 1001 // Do not trigger other activities when gesturing. | 1083 // Do not trigger other activities when gesturing. |
| 1002 if (wasGesturing) { | 1084 if (wasGesturing) { |
| 1003 if (e.type == EventType.POINTER_OVER) { | 1085 if (view.type != ElementType.MODIFIER_KEY && |
| 1086 (e.type == EventType.POINTER_OVER || |
| 1087 e.type == EventType.POINTER_OUT)) { |
| 1004 view.setHighlighted(false); | 1088 view.setHighlighted(false); |
| 1005 } | 1089 } |
| 1006 return; | 1090 return; |
| 1007 } | 1091 } |
| 1008 } | 1092 } |
| 1009 | 1093 |
| 1010 // Listen for DOUBLE_CLICK as well to capture secondary taps on the spacebar. | 1094 // Listen for DOUBLE_CLICK as well to capture secondary taps on the spacebar. |
| 1011 if (e.type == EventType.POINTER_UP || e.type == EventType.DOUBLE_CLICK) { | 1095 if (e.type == EventType.POINTER_UP || e.type == EventType.DOUBLE_CLICK) { |
| 1012 this.recordStatsForClosing_( | 1096 this.recordStatsForClosing_( |
| 1013 'InputMethod.VirtualKeyboard.TapCount', 1, 4095, 4096); | 1097 'InputMethod.VirtualKeyboard.TapCount', 1, 4095, 4096); |
| 1014 } | 1098 } |
| 1015 | 1099 |
| 1016 if (e.type == EventType.SWIPE) { | 1100 if (e.type == EventType.SWIPE) { |
| 1017 e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e); | 1101 e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e); |
| 1018 this.handleSwipeAction_(view, e); | 1102 this.handleSwipeAction_(view, e); |
| 1019 } | 1103 } |
| 1020 switch (view.type) { | 1104 switch (view.type) { |
| 1021 case ElementType.KEYBOARD_CONTAINER_VIEW: | 1105 case ElementType.HOTROD_SWITCHER_KEY: |
| 1022 if (e.type == EventType.POINTER_DOWN) { | |
| 1023 var tabbableKeysets = [ | |
| 1024 Controller.HANDWRITING_VIEW_CODE_, | |
| 1025 Controller.EMOJI_VIEW_CODE_]; | |
| 1026 if (goog.array.contains(tabbableKeysets, this.currentKeyset_)) { | |
| 1027 this.resetAll(); | |
| 1028 this.switchToKeyset(this.container_.currentKeysetView.fromKeyset); | |
| 1029 } | |
| 1030 } | |
| 1031 return; | |
| 1032 case ElementType.BACK_BUTTON: | 1106 case ElementType.BACK_BUTTON: |
| 1033 case ElementType.BACK_TO_KEYBOARD: | 1107 case ElementType.BACK_TO_KEYBOARD: |
| 1108 if (view.type == ElementType.HOTROD_SWITCHER_KEY && |
| 1109 !this.adapter_.isHotrod) { |
| 1110 return; |
| 1111 } |
| 1034 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { | 1112 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { |
| 1035 view.setHighlighted(false); | 1113 view.setHighlighted(false); |
| 1036 } else if (e.type == EventType.POINTER_DOWN || | 1114 } else if (e.type == EventType.POINTER_DOWN || |
| 1037 e.type == EventType.POINTER_OVER) { | 1115 e.type == EventType.POINTER_OVER) { |
| 1038 view.setHighlighted(true); | 1116 view.setHighlighted(true); |
| 1039 } | 1117 } |
| 1040 if (e.type == EventType.POINTER_UP) { | 1118 if (e.type == EventType.POINTER_UP) { |
| 1041 this.switchToKeyset(this.container_.currentKeysetView.fromKeyset); | 1119 var backToKeyset = this.container_.currentKeysetView.fromKeyset; |
| 1120 if (view.type == ElementType.HOTROD_SWITCHER_KEY && |
| 1121 this.adapter_.isHotrod) { |
| 1122 backToKeyset = Controller.US_COMPACT_QWERTY_CODE_; |
| 1123 } |
| 1124 this.switchToKeyset(backToKeyset); |
| 1042 this.clearCandidates_(); | 1125 this.clearCandidates_(); |
| 1043 this.soundController_.onKeyUp(view.type); | 1126 this.soundController_.onKeyUp(view.type); |
| 1044 } | 1127 } |
| 1045 return; | 1128 return; |
| 1046 case ElementType.EXPAND_CANDIDATES: | 1129 case ElementType.EXPAND_CANDIDATES: |
| 1047 if (e.type == EventType.POINTER_UP) { | 1130 if (e.type == EventType.POINTER_UP) { |
| 1048 this.showCandidates_(this.candidatesInfo_.source, | 1131 this.showCandidates_(this.candidatesInfo_.source, |
| 1049 this.candidatesInfo_.candidates, | 1132 this.candidatesInfo_.candidates, |
| 1050 Controller.CandidatesOperation.EXPAND); | 1133 Controller.CandidatesOperation.EXPAND); |
| 1051 this.soundController_.onKeyUp(view.type); | 1134 this.soundController_.onKeyUp(view.type); |
| 1052 } | 1135 } |
| 1053 return; | 1136 return; |
| 1054 case ElementType.SHRINK_CANDIDATES: | 1137 case ElementType.SHRINK_CANDIDATES: |
| 1055 if (e.type == EventType.POINTER_UP) { | 1138 if (e.type == EventType.POINTER_UP) { |
| 1056 this.showCandidates_(this.candidatesInfo_.source, | 1139 this.showCandidates_(this.candidatesInfo_.source, |
| 1057 this.candidatesInfo_.candidates, | 1140 this.candidatesInfo_.candidates, |
| 1058 Controller.CandidatesOperation.SHRINK); | 1141 Controller.CandidatesOperation.SHRINK); |
| 1059 this.soundController_.onKeyUp(view.type); | 1142 this.soundController_.onKeyUp(view.type); |
| 1060 } | 1143 } |
| 1061 return; | 1144 return; |
| 1062 case ElementType.CANDIDATE: | 1145 case ElementType.CANDIDATE: |
| 1063 view = /** @type {!i18n.input.chrome.inputview.elements.content. | 1146 view = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 1064 Candidate} */ (view); | 1147 Candidate} */ (view); |
| 1065 if (view.candidateType == CandidateType.TOOLTIP) | 1148 if (view.candidateType == CandidateType.TOOLTIP) |
| 1066 return; | 1149 return; |
| 1067 if (e.type == EventType.POINTER_UP) { | 1150 if (e.type == EventType.POINTER_UP) { |
| 1068 if (view.candidateType == CandidateType.CANDIDATE) { | 1151 if (view.candidateType == CandidateType.CANDIDATE) { |
| 1069 this.adapter_.selectCandidate(view.candidate); | 1152 this.adapter_.selectCandidate(view.candidate); |
| 1153 if (this.candidatesSetByGestureTyping_) { |
| 1154 var type = this.getGestureEventTypeForCandidateID_( |
| 1155 view.candidate[Name.CANDIDATE_ID]); |
| 1156 if (type) { |
| 1157 this.statistics_.recordEnum( |
| 1158 Statistics.GESTURE_TYPING_METRIC_NAME, |
| 1159 type, |
| 1160 Statistics.GestureTypingEvent.MAX); |
| 1161 } |
| 1162 } |
| 1070 } else if (view.candidateType == CandidateType.NUMBER) { | 1163 } else if (view.candidateType == CandidateType.NUMBER) { |
| 1071 this.adapter_.sendKeyDownAndUpEvent( | 1164 this.adapter_.sendKeyDownAndUpEvent( |
| 1072 view.candidate[Name.CANDIDATE], ''); | 1165 view.candidate[Name.CANDIDATE], ''); |
| 1073 } | 1166 } |
| 1074 this.container_.cleanStroke(); | 1167 this.container_.cleanStroke(); |
| 1075 this.soundController_.onKeyUp(ElementType.CANDIDATE); | 1168 this.soundController_.onKeyUp(ElementType.CANDIDATE); |
| 1076 } | 1169 } |
| 1077 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { | 1170 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { |
| 1078 view.setHighlighted(false); | 1171 view.setHighlighted(false); |
| 1079 } else if (e.type == EventType.POINTER_DOWN || | 1172 } else if (e.type == EventType.POINTER_DOWN || |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1092 view.triggeredBy.keyCode, | 1185 view.triggeredBy.keyCode, |
| 1093 {'sources': [ch.toLowerCase()], 'possibilities': [1]}); | 1186 {'sources': [ch.toLowerCase()], 'possibilities': [1]}); |
| 1094 } | 1187 } |
| 1095 view.hide(); | 1188 view.hide(); |
| 1096 this.clearUnstickyState_(); | 1189 this.clearUnstickyState_(); |
| 1097 this.soundController_.onKeyUp(view.type); | 1190 this.soundController_.onKeyUp(view.type); |
| 1098 } | 1191 } |
| 1099 return; | 1192 return; |
| 1100 | 1193 |
| 1101 case ElementType.MENU_ITEM: | 1194 case ElementType.MENU_ITEM: |
| 1195 if (this.adapter_.isHotrod) { |
| 1196 // Disable menu items in hotrod. Fix this if hotrod needs i18n support. |
| 1197 return; |
| 1198 } |
| 1102 view = /** @type {!i18n.input.chrome.inputview.elements.content. | 1199 view = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 1103 MenuItem} */ (view); | 1200 MenuItem} */ (view); |
| 1104 if (e.type == EventType.POINTER_UP) { | 1201 if (e.type == EventType.POINTER_UP) { |
| 1105 this.executeCommand_.apply(this, view.getCommand()); | 1202 this.executeCommand_.apply(this, view.getCommand()); |
| 1106 this.container_.menuView.hide(); | 1203 this.container_.menuView.hide(); |
| 1107 this.soundController_.onKeyUp(view.type); | 1204 this.soundController_.onKeyUp(view.type); |
| 1108 this.resetAll(); | 1205 this.resetAll(); |
| 1109 } | 1206 } |
| 1110 view.setHighlighted(e.type == EventType.POINTER_DOWN || | 1207 view.setHighlighted(e.type == EventType.POINTER_DOWN || |
| 1111 e.type == EventType.POINTER_OVER); | 1208 e.type == EventType.POINTER_OVER); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 case ElementType.DRAG: | 1264 case ElementType.DRAG: |
| 1168 if (e.type == EventType.POINTER_DOWN && this.container_.floatingView) { | 1265 if (e.type == EventType.POINTER_DOWN && this.container_.floatingView) { |
| 1169 this.container_.floatingView.show(); | 1266 this.container_.floatingView.show(); |
| 1170 } | 1267 } |
| 1171 return; | 1268 return; |
| 1172 case ElementType.FLOATING_VIEW: | 1269 case ElementType.FLOATING_VIEW: |
| 1173 if (e.type == EventType.POINTER_UP && this.container_.floatingView) { | 1270 if (e.type == EventType.POINTER_UP && this.container_.floatingView) { |
| 1174 this.container_.floatingView.hide(); | 1271 this.container_.floatingView.hide(); |
| 1175 } | 1272 } |
| 1176 return; | 1273 return; |
| 1177 case ElementType.RESIZE: | |
| 1178 if (e.type == EventType.POINTER_UP) { | |
| 1179 goog.dom.classlist.toggle(this.container_.getElement(), Css.SMALL); | |
| 1180 this.resize(); | |
| 1181 } | |
| 1182 return; | |
| 1183 case ElementType.CUT: | 1274 case ElementType.CUT: |
| 1184 case ElementType.COPY: | 1275 case ElementType.COPY: |
| 1185 case ElementType.PASTE: | 1276 case ElementType.PASTE: |
| 1186 case ElementType.BOLD: | 1277 case ElementType.BOLD: |
| 1187 case ElementType.ITALICS: | 1278 case ElementType.ITALICS: |
| 1188 case ElementType.UNDERLINE: | 1279 case ElementType.UNDERLINE: |
| 1189 case ElementType.REDO: | 1280 case ElementType.REDO: |
| 1190 case ElementType.UNDO: | 1281 case ElementType.UNDO: |
| 1191 case ElementType.SELECT_ALL: | 1282 case ElementType.SELECT_ALL: |
| 1192 view.setHighlighted(e.type == EventType.POINTER_DOWN || | 1283 view.setHighlighted(e.type == EventType.POINTER_DOWN || |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 } else if (e.type == EventType.POINTER_UP) { | 1460 } else if (e.type == EventType.POINTER_UP) { |
| 1370 this.adapter_.sendKeyUpEvent('', KeyCodes.ARROW_RIGHT); | 1461 this.adapter_.sendKeyUpEvent('', KeyCodes.ARROW_RIGHT); |
| 1371 } | 1462 } |
| 1372 break; | 1463 break; |
| 1373 case ElementType.EN_SWITCHER: | 1464 case ElementType.EN_SWITCHER: |
| 1374 if (e.type == EventType.POINTER_UP) { | 1465 if (e.type == EventType.POINTER_UP) { |
| 1375 key = /** @type {!i18n.input.chrome.inputview.elements.content. | 1466 key = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 1376 EnSwitcherKey} */ (softKey); | 1467 EnSwitcherKey} */ (softKey); |
| 1377 this.adapter_.toggleLanguageState(this.model_.stateManager.isEnMode); | 1468 this.adapter_.toggleLanguageState(this.model_.stateManager.isEnMode); |
| 1378 this.model_.stateManager.isEnMode = !this.model_.stateManager.isEnMode; | 1469 this.model_.stateManager.isEnMode = !this.model_.stateManager.isEnMode; |
| 1379 key.update(); | 1470 if (!this.updateToggleLanguageKeyset_()) { |
| 1471 key.update(); |
| 1472 } |
| 1380 } | 1473 } |
| 1381 break; | 1474 break; |
| 1382 case ElementType.SPACE_KEY: | 1475 case ElementType.SPACE_KEY: |
| 1383 key = /** @type {!i18n.input.chrome.inputview.elements.content. | 1476 key = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 1384 SpaceKey} */ (softKey); | 1477 SpaceKey} */ (softKey); |
| 1385 var doubleSpacePeriod = this.model_.settings.doubleSpacePeriod && | 1478 var doubleSpacePeriod = this.model_.settings.doubleSpacePeriod && |
| 1386 this.currentKeyset_ != Controller.HANDWRITING_VIEW_CODE_ && | 1479 this.currentKeyset_ != Controller.HANDWRITING_VIEW_CODE_ && |
| 1387 this.currentKeyset_ != Controller.EMOJI_VIEW_CODE_; | 1480 this.currentKeyset_ != Controller.EMOJI_VIEW_CODE_; |
| 1388 if (e.type == EventType.POINTER_UP || (!doubleSpacePeriod && e.type == | 1481 if (e.type == EventType.POINTER_UP || (!doubleSpacePeriod && e.type == |
| 1389 EventType.DOUBLE_CLICK_END)) { | 1482 EventType.DOUBLE_CLICK_END)) { |
| 1390 this.adapter_.sendKeyDownAndUpEvent(key.getCharacter(), | 1483 this.adapter_.sendKeyDownAndUpEvent(key.getCharacter(), |
| 1391 KeyCodes.SPACE); | 1484 KeyCodes.SPACE); |
| 1392 this.clearUnstickyState_(); | 1485 this.clearUnstickyState_(); |
| 1393 } else if (e.type == EventType.DOUBLE_CLICK && doubleSpacePeriod) { | 1486 } else if (e.type == EventType.DOUBLE_CLICK && doubleSpacePeriod) { |
| 1394 this.adapter_.doubleClickOnSpaceKey(); | 1487 this.adapter_.doubleClickOnSpaceKey(); |
| 1395 } | 1488 } |
| 1396 if (this.returnToLetterKeysetOnSpace_) { | 1489 if (this.returnToLetterKeysetOnSpace_) { |
| 1397 // Return to the letter keyset. | 1490 // Return to the letter keyset. |
| 1398 this.switchToKeyset(key.toKeyset); | 1491 this.switchToKeyset(key.toKeyset); |
| 1399 this.returnToLetterKeysetOnSpace_ = false; | 1492 this.returnToLetterKeysetOnSpace_ = false; |
| 1400 } | 1493 } |
| 1494 var isHwt = Controller.HANDWRITING_VIEW_CODE_ == this.currentKeyset_; |
| 1495 if (isHwt) { |
| 1496 this.container_.cleanStroke(); |
| 1497 } |
| 1401 break; | 1498 break; |
| 1402 | 1499 |
| 1403 case ElementType.SWITCHER_KEY: | 1500 case ElementType.SWITCHER_KEY: |
| 1404 key = /** @type {!i18n.input.chrome.inputview.elements.content. | 1501 key = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 1405 SwitcherKey} */ (softKey); | 1502 SwitcherKey} */ (softKey); |
| 1406 if (e.type == EventType.POINTER_UP) { | 1503 if (e.type == EventType.POINTER_UP) { |
| 1407 this.recordStatsForClosing_( | 1504 this.recordStatsForClosing_( |
| 1408 'InputMethod.VirtualKeyboard.LayoutSwitch', 1, 25, 25); | 1505 'InputMethod.VirtualKeyboard.LayoutSwitch', 1, 25, 25); |
| 1409 if (this.isSubKeyset_(key.toKeyset, this.currentKeyset_)) { | 1506 if (this.isSubKeyset_(key.toKeyset, this.currentKeyset_)) { |
| 1410 this.model_.stateManager.reset(); | 1507 this.model_.stateManager.reset(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1429 key = /** @type {!i18n.input.chrome.inputview.elements.content. | 1526 key = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 1430 CompactKey} */(softKey); | 1527 CompactKey} */(softKey); |
| 1431 if (e.type == EventType.LONG_PRESS) { | 1528 if (e.type == EventType.LONG_PRESS) { |
| 1432 this.container_.altDataView.show( | 1529 this.container_.altDataView.show( |
| 1433 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_), | 1530 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_), |
| 1434 e.identifier); | 1531 e.identifier); |
| 1435 } else if (e.type == EventType.POINTER_UP) { | 1532 } else if (e.type == EventType.POINTER_UP) { |
| 1436 this.model_.stateManager.triggerChording(); | 1533 this.model_.stateManager.triggerChording(); |
| 1437 var ch = key.getActiveCharacter(); | 1534 var ch = key.getActiveCharacter(); |
| 1438 if (ch.length == 1) { | 1535 if (ch.length == 1) { |
| 1439 this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0, | 1536 if (this.currentKeyset_.indexOf('symbol') != -1) { |
| 1537 this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), |
| 1538 KeyCodes.SYMBOL, 0, this.getSpatialData_(key, e.x, e.y)); |
| 1539 } |
| 1540 else { |
| 1541 this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0, |
| 1440 this.getSpatialData_(key, e.x, e.y)); | 1542 this.getSpatialData_(key, e.x, e.y)); |
| 1543 } |
| 1441 } else if (ch.length > 1) { | 1544 } else if (ch.length > 1) { |
| 1442 // Some compact keys contains more than 1 characters, such as '.com', | 1545 // Some compact keys contains more than 1 characters, such as '.com', |
| 1443 // 'http://', etc. Those keys should trigger a direct commit text | 1546 // 'http://', etc. Those keys should trigger a direct commit text |
| 1444 // instead of key events. | 1547 // instead of key events. |
| 1445 this.adapter_.commitText(ch); | 1548 this.adapter_.commitText(ch); |
| 1446 } | 1549 } |
| 1447 this.clearUnstickyState_(); | 1550 this.clearUnstickyState_(); |
| 1448 key.flickerredCharacter = ''; | 1551 key.flickerredCharacter = ''; |
| 1449 if (this.currentKeyset_.indexOf('symbol') != -1) { | 1552 if (this.currentKeyset_.indexOf('symbol') != -1) { |
| 1450 // If this is the symbol keyset, a space as the next input should | 1553 // If this is the symbol keyset, a space as the next input should |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1468 key = /** @type {!i18n.input.chrome.inputview.elements.content. | 1571 key = /** @type {!i18n.input.chrome.inputview.elements.content. |
| 1469 MenuKey} */ (softKey); | 1572 MenuKey} */ (softKey); |
| 1470 if (e.type == EventType.POINTER_DOWN) { | 1573 if (e.type == EventType.POINTER_DOWN) { |
| 1471 var isCompact = this.currentKeyset_.indexOf('compact') != -1; | 1574 var isCompact = this.currentKeyset_.indexOf('compact') != -1; |
| 1472 // Gets the default full keyboard instead of default keyset because | 1575 // Gets the default full keyboard instead of default keyset because |
| 1473 // the default keyset can be a compact keyset which would cause problem | 1576 // the default keyset can be a compact keyset which would cause problem |
| 1474 // in MenuView.show(). | 1577 // in MenuView.show(). |
| 1475 var defaultFullKeyset = this.initialKeyset_.split(/\./)[0]; | 1578 var defaultFullKeyset = this.initialKeyset_.split(/\./)[0]; |
| 1476 var enableCompact = !this.adapter_.isA11yMode && goog.array.contains( | 1579 var enableCompact = !this.adapter_.isA11yMode && goog.array.contains( |
| 1477 util.KEYSETS_HAVE_COMPACT, defaultFullKeyset); | 1580 util.KEYSETS_HAVE_COMPACT, defaultFullKeyset); |
| 1478 if (defaultFullKeyset == 'zhuyin' && | 1581 if (this.languageCode_ == 'ko') { |
| 1479 !this.adapter_.features.isEnabled(FeatureName.EXPERIMENTAL) || | |
| 1480 this.languageCode_ == 'ko') { | |
| 1481 // Hides 'switch to compact' for zhuyin when not in experimental env. | |
| 1482 enableCompact = false; | 1582 enableCompact = false; |
| 1483 } | 1583 } |
| 1484 var hasHwt = !this.adapter_.isPasswordBox() && | 1584 var hasHwt = !this.adapter_.isPasswordBox() && |
| 1485 !Controller.DISABLE_HWT && goog.object.contains( | 1585 !Controller.DISABLE_HWT && goog.object.contains( |
| 1486 InputToolCode, this.getHwtInputToolCode_()); | 1586 InputToolCode, this.getHwtInputToolCode_()); |
| 1487 var hasEmoji = !this.adapter_.isPasswordBox(); | 1587 var hasEmoji = !this.adapter_.isPasswordBox(); |
| 1488 var enableSettings = this.shouldEnableSettings() && | 1588 var enableSettings = this.shouldEnableSettings() && |
| 1489 !!window.inputview && !!inputview.openSettings; | 1589 !!window.inputview && !!inputview.openSettings; |
| 1490 var enableFVK = this.adapter_.isFloatingVirtualKeyboardEnabled(); | |
| 1491 this.adapter_.getInputMethods(function(inputMethods) { | 1590 this.adapter_.getInputMethods(function(inputMethods) { |
| 1492 this.container_.menuView.show(key, defaultFullKeyset, isCompact, | 1591 this.container_.menuView.show(key, defaultFullKeyset, isCompact, |
| 1493 enableCompact, this.currentInputMethod_, inputMethods, hasHwt, | 1592 enableCompact, this.currentInputMethod_, inputMethods, hasHwt, |
| 1494 enableSettings, hasEmoji, this.adapter_.isA11yMode, enableFVK, | 1593 enableSettings, hasEmoji, this.adapter_.isA11yMode); |
| 1495 this.adapter_.isFloating); | |
| 1496 }.bind(this)); | 1594 }.bind(this)); |
| 1497 } | 1595 } |
| 1498 break; | 1596 break; |
| 1499 | 1597 |
| 1500 case ElementType.GLOBE_KEY: | 1598 case ElementType.GLOBE_KEY: |
| 1501 if (e.type == EventType.POINTER_UP) { | 1599 if (e.type == EventType.POINTER_UP) { |
| 1502 this.adapter_.clearModifierStates(); | 1600 this.adapter_.clearModifierStates(); |
| 1503 this.adapter_.setModifierState( | 1601 this.adapter_.setModifierState( |
| 1504 i18n.input.chrome.inputview.StateType.ALT, true); | 1602 i18n.input.chrome.inputview.StateType.ALT, true); |
| 1505 this.adapter_.sendKeyDownAndUpEvent( | 1603 this.adapter_.sendKeyDownAndUpEvent( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 } | 1651 } |
| 1554 }; | 1652 }; |
| 1555 | 1653 |
| 1556 | 1654 |
| 1557 /** | 1655 /** |
| 1558 * The tick for the backspace key. | 1656 * The tick for the backspace key. |
| 1559 * | 1657 * |
| 1560 * @private | 1658 * @private |
| 1561 */ | 1659 */ |
| 1562 Controller.prototype.backspaceTick_ = function() { | 1660 Controller.prototype.backspaceTick_ = function() { |
| 1563 if (this.backspaceRepeated_ >= Controller.BACKSPACE_REPEAT_LIMIT_) { | |
| 1564 this.stopBackspaceAutoRepeat_(); | |
| 1565 return; | |
| 1566 } | |
| 1567 this.backspaceRepeated_++; | 1661 this.backspaceRepeated_++; |
| 1568 this.backspaceDown_(); | 1662 this.backspaceDown_(); |
| 1569 this.soundController_.onKeyRepeat(ElementType.BACKSPACE_KEY); | 1663 this.soundController_.onKeyRepeat(ElementType.BACKSPACE_KEY); |
| 1570 | 1664 |
| 1571 if (this.backspaceAutoRepeat_) { | 1665 if (this.backspaceAutoRepeat_) { |
| 1572 this.backspaceAutoRepeat_.start(75); | 1666 var delay = MINIMUM_BACKSPACE_REPEAT_TIME_MS; |
| 1667 if (this.backspaceRepeated_ <= BACKSPACE_REPEAT_LIMIT) { |
| 1668 var ease = goog.fx.easing.easeOut( |
| 1669 this.backspaceRepeated_ / BACKSPACE_REPEAT_LIMIT); |
| 1670 var delta = MAXIMUM_BACKSPACE_REPEAT_TIME_MS - |
| 1671 MINIMUM_BACKSPACE_REPEAT_TIME_MS; |
| 1672 delay = MAXIMUM_BACKSPACE_REPEAT_TIME_MS - (delta * ease); |
| 1673 } |
| 1674 this.backspaceAutoRepeat_.start(delay); |
| 1573 } else { | 1675 } else { |
| 1574 this.backspaceAutoRepeat_ = new goog.async.Delay( | 1676 this.backspaceAutoRepeat_ = new goog.async.Delay( |
| 1575 goog.bind(this.backspaceTick_, this), 300); | 1677 goog.bind(this.backspaceTick_, this), |
| 1678 BACKSPACE_REPEAT_START_TIME_MS); |
| 1576 this.backspaceAutoRepeat_.start(); | 1679 this.backspaceAutoRepeat_.start(); |
| 1577 } | 1680 } |
| 1578 }; | 1681 }; |
| 1579 | 1682 |
| 1580 | 1683 |
| 1581 /** | 1684 /** |
| 1582 * Callback for VISIBILITY_CHANGE. | 1685 * Callback for VISIBILITY_CHANGE. |
| 1583 * | 1686 * |
| 1584 * @private | 1687 * @private |
| 1585 */ | 1688 */ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1606 this.clearCandidates_(); | 1709 this.clearCandidates_(); |
| 1607 this.container_.cleanStroke(); | 1710 this.container_.cleanStroke(); |
| 1608 this.model_.stateManager.reset(); | 1711 this.model_.stateManager.reset(); |
| 1609 this.container_.update(); | 1712 this.container_.update(); |
| 1610 this.updateContextModifierState_(); | 1713 this.updateContextModifierState_(); |
| 1611 this.resize(); | 1714 this.resize(); |
| 1612 this.container_.expandedCandidateView.close(); | 1715 this.container_.expandedCandidateView.close(); |
| 1613 this.container_.menuView.hide(); | 1716 this.container_.menuView.hide(); |
| 1614 this.container_.swipeView.reset(); | 1717 this.container_.swipeView.reset(); |
| 1615 this.container_.altDataView.hide(); | 1718 this.container_.altDataView.hide(); |
| 1616 this.container_.gesturePreviewView.hide(); | 1719 if (this.container_.gesturePreviewWindow) { |
| 1720 this.container_.gesturePreviewWindow.hide(); |
| 1721 } |
| 1617 if (this.container_.floatingView) { | 1722 if (this.container_.floatingView) { |
| 1618 this.container_.floatingView.hide(); | 1723 this.container_.floatingView.hide(); |
| 1619 } | 1724 } |
| 1725 this.stopBackspaceAutoRepeat_(); |
| 1620 }; | 1726 }; |
| 1621 | 1727 |
| 1622 | 1728 |
| 1623 /** | 1729 /** |
| 1624 * Returns whether the toolbar should be shown. | 1730 * Returns whether the toolbar should be shown. |
| 1625 * | 1731 * |
| 1626 * @return {boolean} | 1732 * @return {boolean} |
| 1627 * @private | 1733 * @private |
| 1628 */ | 1734 */ |
| 1629 Controller.prototype.shouldShowToolBar_ = function() { | 1735 Controller.prototype.shouldShowToolBar_ = function() { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1648 /** | 1754 /** |
| 1649 * Callback when surrounding text is changed. | 1755 * Callback when surrounding text is changed. |
| 1650 * | 1756 * |
| 1651 * @param {!i18n.input.chrome.inputview.events.SurroundingTextChangedEvent} e . | 1757 * @param {!i18n.input.chrome.inputview.events.SurroundingTextChangedEvent} e . |
| 1652 * @private | 1758 * @private |
| 1653 */ | 1759 */ |
| 1654 Controller.prototype.onSurroundingTextChanged_ = function(e) { | 1760 Controller.prototype.onSurroundingTextChanged_ = function(e) { |
| 1655 if (!this.model_.settings.autoCapital || !e.text) { | 1761 if (!this.model_.settings.autoCapital || !e.text) { |
| 1656 return; | 1762 return; |
| 1657 } | 1763 } |
| 1658 | 1764 var textBeforeCursor = e.textBeforeCursor.replace(/\u00a0/g, ' '); |
| 1659 var isShiftEnabled = this.model_.stateManager.hasState(StateType.SHIFT); | 1765 var isShiftEnabled = this.model_.stateManager.hasState(StateType.SHIFT); |
| 1660 var needAutoCap = this.model_.settings.autoCapital && | 1766 var needAutoCap = this.model_.settings.autoCapital && |
| 1661 util.needAutoCap(e.text); | 1767 util.needAutoCap(textBeforeCursor); |
| 1662 if (needAutoCap && !isShiftEnabled) { | 1768 if (needAutoCap && !isShiftEnabled) { |
| 1663 this.changeState_(StateType.SHIFT, true, false); | 1769 this.changeState_(StateType.SHIFT, true, false); |
| 1664 this.shiftForAutoCapital_ = true; | 1770 this.shiftForAutoCapital_ = true; |
| 1665 } else if (!needAutoCap && this.shiftForAutoCapital_) { | 1771 } else if (!needAutoCap && this.shiftForAutoCapital_) { |
| 1666 this.changeState_(StateType.SHIFT, false, false); | 1772 this.changeState_(StateType.SHIFT, false, false); |
| 1667 } | 1773 } |
| 1668 }; | 1774 }; |
| 1669 | 1775 |
| 1670 | 1776 |
| 1671 /** | 1777 /** |
| 1672 * Callback for Context blurs. | 1778 * Callback for Context blurs. |
| 1673 * | 1779 * |
| 1674 * @private | 1780 * @private |
| 1675 */ | 1781 */ |
| 1676 Controller.prototype.onContextBlur_ = function() { | 1782 Controller.prototype.onContextBlur_ = function() { |
| 1677 this.container_.cleanStroke(); | 1783 this.container_.cleanStroke(); |
| 1678 this.container_.menuView.hide(); | 1784 this.container_.menuView.hide(); |
| 1785 this.stopBackspaceAutoRepeat_(); |
| 1679 }; | 1786 }; |
| 1680 | 1787 |
| 1681 | 1788 |
| 1682 /** | 1789 /** |
| 1683 * Backspace key is down. | 1790 * Backspace key is down. |
| 1684 * | 1791 * |
| 1685 * @private | 1792 * @private |
| 1686 */ | 1793 */ |
| 1687 Controller.prototype.backspaceDown_ = function() { | 1794 Controller.prototype.backspaceDown_ = function() { |
| 1688 if (this.container_.hasStrokesOnCanvas()) { | 1795 if (this.container_.hasStrokesOnCanvas()) { |
| 1689 this.clearCandidates_(); | 1796 this.clearCandidates_(); |
| 1690 this.container_.cleanStroke(); | 1797 this.container_.cleanStroke(); |
| 1691 } else { | 1798 } else { |
| 1692 this.adapter_.sendKeyDownEvent('\u0008', KeyCodes.BACKSPACE); | 1799 this.adapter_.sendKeyDownEvent('\u0008', KeyCodes.BACKSPACE); |
| 1693 } | 1800 } |
| 1694 this.recordStatsForClosing_( | 1801 this.recordStatsForClosing_( |
| 1695 'InputMethod.VirtualKeyboard.BackspaceCount', 1, 4095, 4096); | 1802 'InputMethod.VirtualKeyboard.BackspaceCount', 1, 4095, 4096); |
| 1696 this.statistics_.recordEnum('InputMethod.VirtualKeyboard.BackspaceOnLayout', | 1803 this.statistics_.recordEnum('InputMethod.VirtualKeyboard.BackspaceOnLayout', |
| 1697 this.statistics_.getLayoutType(this.currentKeyset_, | 1804 this.statistics_.getLayoutType(this.currentKeyset_, |
| 1698 this.adapter_.isA11yMode), | 1805 this.adapter_.isA11yMode), |
| 1699 i18n.input.chrome.Statistics.LayoutTypes.MAX); | 1806 Statistics.LayoutTypes.MAX); |
| 1700 }; | 1807 }; |
| 1701 | 1808 |
| 1702 | 1809 |
| 1703 /** | 1810 /** |
| 1704 * Callback for state change. | 1811 * Callback for state change. |
| 1705 * | 1812 * |
| 1706 * @param {StateType} stateType The state type. | 1813 * @param {StateType} stateType The state type. |
| 1707 * @param {boolean} enable True to enable the state. | 1814 * @param {boolean} enable True to enable the state. |
| 1708 * @param {boolean} isSticky True to make the state sticky. | 1815 * @param {boolean} isSticky True to make the state sticky. |
| 1709 * @param {boolean=} opt_isFinalSticky . | 1816 * @param {boolean=} opt_isFinalSticky . |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 */ | 1874 */ |
| 1768 Controller.prototype.onCandidatesBack_ = function(e) { | 1875 Controller.prototype.onCandidatesBack_ = function(e) { |
| 1769 this.candidatesInfo_ = new i18n.input.chrome.inputview.CandidatesInfo( | 1876 this.candidatesInfo_ = new i18n.input.chrome.inputview.CandidatesInfo( |
| 1770 e.source, e.candidates); | 1877 e.source, e.candidates); |
| 1771 this.showCandidates_(e.source, e.candidates, Controller.CandidatesOperation. | 1878 this.showCandidates_(e.source, e.candidates, Controller.CandidatesOperation. |
| 1772 NONE); | 1879 NONE); |
| 1773 }; | 1880 }; |
| 1774 | 1881 |
| 1775 | 1882 |
| 1776 /** | 1883 /** |
| 1884 * Converts a word to shifted or all-caps based on the current shift state. |
| 1885 * |
| 1886 * @param {string} word The word to potentially convert. |
| 1887 * @return {string} The converted word. |
| 1888 * @private |
| 1889 */ |
| 1890 Controller.prototype.convertToShifted_ = function(word) { |
| 1891 if (this.model_.stateManager.getState() == StateType.SHIFT) { |
| 1892 if (this.model_.stateManager.isSticky(StateType.SHIFT) && |
| 1893 this.model_.stateManager.isFinalSticky(StateType.SHIFT)) { |
| 1894 word = word.toUpperCase(); |
| 1895 } else { |
| 1896 word = word.charAt(0).toUpperCase() + word.slice(1); |
| 1897 } |
| 1898 } |
| 1899 return word; |
| 1900 }; |
| 1901 |
| 1902 |
| 1903 /** |
| 1777 * Callback for gestures results event. | 1904 * Callback for gestures results event. |
| 1778 * | 1905 * |
| 1779 * @param {!i18n.input.chrome.DataSource.GesturesBackEvent} e . | 1906 * @param {!i18n.input.chrome.DataSource.GesturesBackEvent} e . |
| 1780 * @private | 1907 * @private |
| 1781 */ | 1908 */ |
| 1782 Controller.prototype.onGesturesBack_ = function(e) { | 1909 Controller.prototype.onGesturesBack_ = function(e) { |
| 1783 if (!this.commitNextGestureResult_ && | 1910 var response = e.response; |
| 1784 goog.array.equals(e.results, this.gestureResultsCache_)) { | 1911 this.stopBackspaceAutoRepeat_(); |
| 1912 if (!response.commit && |
| 1913 goog.array.equals(response.results, this.gestureResultsCache_)) { |
| 1785 // If gesture results have not updated, do not transmit to the UI. | 1914 // If gesture results have not updated, do not transmit to the UI. |
| 1786 return; | 1915 return; |
| 1787 } else { | 1916 } else { |
| 1788 this.gestureResultsCache_ = e.results; | 1917 this.gestureResultsCache_ = response.results; |
| 1789 } | 1918 } |
| 1790 var bestResult = e.results[0]; | 1919 var bestResult = this.convertToShifted_(response.results[0]); |
| 1791 if (this.container_.gesturePreviewView) { | 1920 if (this.container_.gesturePreviewWindow && |
| 1792 this.container_.gesturePreviewView.show(bestResult); | 1921 this.container_.gestureCanvasView.isGesturing) { |
| 1922 this.container_.gesturePreviewWindow.show(bestResult); |
| 1793 } | 1923 } |
| 1794 // TODO: Resolve a race where multiple decoder results return after this flag | 1924 if (response.commit) { |
| 1795 // is set to true. | |
| 1796 if (this.commitNextGestureResult_) { | |
| 1797 // Commit the best result. | 1925 // Commit the best result. |
| 1798 this.adapter_.commitGestureResult(bestResult); | 1926 this.adapter_.commitGestureResult( |
| 1799 this.commitNextGestureResult_ = false; | 1927 bestResult, this.adapter_.isGoogleDocument()); |
| 1800 this.gestureResultsCache_ = []; | 1928 this.gestureResultsCache_ = []; |
| 1929 this.statistics_.recordEnum( |
| 1930 Statistics.GESTURE_TYPING_METRIC_NAME, |
| 1931 Statistics.GestureTypingEvent.TYPED, |
| 1932 Statistics.GestureTypingEvent.MAX); |
| 1933 if (this.container_.gesturePreviewWindow) { |
| 1934 new goog.async.Delay( |
| 1935 goog.bind(this.container_.gesturePreviewWindow.hide, |
| 1936 this.container_.gesturePreviewWindow), |
| 1937 GESTURE_PREVIEW_LINGER_TIME_MS).start(); |
| 1938 } |
| 1801 } | 1939 } |
| 1802 this.showGestureCandidates_(e.results.slice(1)); | 1940 this.showGestureCandidates_(response.results.slice(1)); |
| 1803 }; | 1941 }; |
| 1804 | 1942 |
| 1805 | 1943 |
| 1806 /** | 1944 /** |
| 1807 * Shows the gesture results as candidates. | 1945 * Shows the gesture results as candidates. |
| 1808 * | 1946 * |
| 1809 * @param {!Array<string>} results The gesture results to show. | 1947 * @param {!Array<string>} results The gesture results to show. |
| 1810 * @private | 1948 * @private |
| 1811 */ | 1949 */ |
| 1812 Controller.prototype.showGestureCandidates_ = function(results) { | 1950 Controller.prototype.showGestureCandidates_ = function(results) { |
| 1813 // Convert the results to the candidate format. | 1951 // Convert the results to the candidate format. |
| 1814 var candidates = []; | 1952 var candidates = []; |
| 1815 for (var i = 0; i < results.length; ++i) { | 1953 for (var i = 0; i < results.length; ++i) { |
| 1816 var candidate = {}; | 1954 var candidate = {}; |
| 1817 candidate[Name.CANDIDATE] = results[i]; | 1955 var result = this.convertToShifted_(results[i]); |
| 1956 candidate[Name.CANDIDATE] = result; |
| 1818 candidate[Name.CANDIDATE_ID] = i; | 1957 candidate[Name.CANDIDATE_ID] = i; |
| 1819 candidate[Name.IS_EMOJI] = false; | 1958 candidate[Name.IS_EMOJI] = false; |
| 1820 candidate[Name.MATCHED_LENGTHS] = 0; | 1959 candidate[Name.MATCHED_LENGTHS] = 0; |
| 1821 candidates.push(candidate); | 1960 candidates.push(candidate); |
| 1822 } | 1961 } |
| 1823 // The source is empty as this is a gesture and not a series of key presses. | 1962 // The source is empty as this is a gesture and not a series of key presses. |
| 1824 this.showCandidates_('', candidates, Controller.CandidatesOperation.NONE); | 1963 this.showCandidates_( |
| 1964 '', candidates, Controller.CandidatesOperation.NONE, true); |
| 1825 }; | 1965 }; |
| 1826 | 1966 |
| 1827 | 1967 |
| 1828 /** | 1968 /** |
| 1829 * Shows the candidates to the candidate view. | 1969 * Shows the candidates to the candidate view. |
| 1830 * | 1970 * |
| 1831 * @param {string} source The source text. | 1971 * @param {string} source The source text. |
| 1832 * @param {!Array.<!Object>} candidates The candidate text list. | 1972 * @param {!Array.<!Object>} candidates The candidate text list. |
| 1833 * @param {Controller.CandidatesOperation} operation . | 1973 * @param {Controller.CandidatesOperation} operation . |
| 1974 * @param {boolean=} opt_fromGestures Whether or not the candidates are being |
| 1975 * set by gesture typing. |
| 1834 * @private | 1976 * @private |
| 1835 */ | 1977 */ |
| 1836 Controller.prototype.showCandidates_ = function(source, candidates, | 1978 Controller.prototype.showCandidates_ = function(source, candidates, |
| 1837 operation) { | 1979 operation, opt_fromGestures) { |
| 1838 var state = !!source ? ExpandedCandidateView.State.COMPLETION_CORRECTION : | 1980 var state = !!source ? ExpandedCandidateView.State.COMPLETION_CORRECTION : |
| 1839 ExpandedCandidateView.State.PREDICTION; | 1981 ExpandedCandidateView.State.PREDICTION; |
| 1840 var expandView = this.container_.expandedCandidateView; | 1982 var expandView = this.container_.expandedCandidateView; |
| 1841 var expand = false; | 1983 var expand = false; |
| 1842 if (operation == Controller.CandidatesOperation.NONE) { | 1984 if (operation == Controller.CandidatesOperation.NONE) { |
| 1843 expand = expandView.state == state; | 1985 expand = expandView.state == state; |
| 1844 } else { | 1986 } else { |
| 1845 expand = operation == Controller.CandidatesOperation.EXPAND; | 1987 expand = operation == Controller.CandidatesOperation.EXPAND; |
| 1846 } | 1988 } |
| 1847 | 1989 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1876 this.container_.candidateView.candidateCount); | 2018 this.container_.candidateView.candidateCount); |
| 1877 this.container_.candidateView.switchToIcon(CandidateView.IconType. | 2019 this.container_.candidateView.switchToIcon(CandidateView.IconType. |
| 1878 SHRINK_CANDIDATES, true); | 2020 SHRINK_CANDIDATES, true); |
| 1879 } else { | 2021 } else { |
| 1880 expandView.state = ExpandedCandidateView.State.NONE; | 2022 expandView.state = ExpandedCandidateView.State.NONE; |
| 1881 expandView.setVisible(false); | 2023 expandView.setVisible(false); |
| 1882 this.container_.candidateView.switchToIcon(CandidateView.IconType. | 2024 this.container_.candidateView.switchToIcon(CandidateView.IconType. |
| 1883 SHRINK_CANDIDATES, false); | 2025 SHRINK_CANDIDATES, false); |
| 1884 this.container_.currentKeysetView.setVisible(true); | 2026 this.container_.currentKeysetView.setVisible(true); |
| 1885 } | 2027 } |
| 2028 this.candidatesSetByGestureTyping_ = !!opt_fromGestures; |
| 1886 }; | 2029 }; |
| 1887 | 2030 |
| 1888 | 2031 |
| 1889 /** | 2032 /** |
| 1890 * Clears candidates. | 2033 * Clears candidates. |
| 1891 * | 2034 * |
| 1892 * @private | 2035 * @private |
| 1893 */ | 2036 */ |
| 1894 Controller.prototype.clearCandidates_ = function() { | 2037 Controller.prototype.clearCandidates_ = function() { |
| 1895 this.candidatesInfo_ = i18n.input.chrome.inputview.CandidatesInfo.getEmpty(); | 2038 this.candidatesInfo_ = i18n.input.chrome.inputview.CandidatesInfo.getEmpty(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1984 var created = false; | 2127 var created = false; |
| 1985 if (this.keysetDataMap_[remappedActiveKeyset]) { | 2128 if (this.keysetDataMap_[remappedActiveKeyset]) { |
| 1986 this.createView_(remappedActiveKeyset); | 2129 this.createView_(remappedActiveKeyset); |
| 1987 this.switchToKeyset(activeKeyset); | 2130 this.switchToKeyset(activeKeyset); |
| 1988 created = true; | 2131 created = true; |
| 1989 } | 2132 } |
| 1990 // Async creating the non-active keysets to reduce the latency of showing the | 2133 // Async creating the non-active keysets to reduce the latency of showing the |
| 1991 // active keyset. | 2134 // active keyset. |
| 1992 var keyLen = Object.keys(this.keysetDataMap_).length; | 2135 var keyLen = Object.keys(this.keysetDataMap_).length; |
| 1993 if (created && keyLen > 1 || !created && keyLen > 0) { | 2136 if (created && keyLen > 1 || !created && keyLen > 0) { |
| 1994 goog.Timer.callOnce((function() { | 2137 if (Controller.DISABLE_DELAY_LOADING_FOR_TEST) { |
| 1995 for (var keyset in this.keysetDataMap_) { | 2138 for (var keyset in this.keysetDataMap_) { |
| 1996 this.createView_(keyset); | 2139 this.createView_(keyset); |
| 1997 } | 2140 } |
| 1998 }).bind(this)); | 2141 } else { |
| 2142 goog.Timer.callOnce((function() { |
| 2143 for (var keyset in this.keysetDataMap_) { |
| 2144 this.createView_(keyset); |
| 2145 } |
| 2146 }).bind(this)); |
| 2147 } |
| 1999 } | 2148 } |
| 2000 }; | 2149 }; |
| 2001 | 2150 |
| 2002 | 2151 |
| 2003 /** | 2152 /** |
| 2004 * Switch to a specific keyboard. | 2153 * Switch to a specific keyboard. |
| 2005 * | 2154 * |
| 2006 * @param {string} keyset The keyset name. | 2155 * @param {string} keyset The keyset name. |
| 2007 */ | 2156 */ |
| 2008 Controller.prototype.switchToKeyset = function(keyset) { | 2157 Controller.prototype.switchToKeyset = function(keyset) { |
| 2009 if (!this.isSettingReady || this.adapter_.isSwitching()) { | 2158 if (!this.isSettingReady || this.adapter_.isSwitching()) { |
| 2010 return; | 2159 return; |
| 2011 } | 2160 } |
| 2012 | 2161 |
| 2013 var contextType = this.adapter_.contextType; | 2162 var contextType = this.adapter_.contextType; |
| 2014 var ret = this.container_.switchToKeyset(this.getRemappedKeyset_(keyset), | 2163 var ret = this.container_.switchToKeyset(this.getRemappedKeyset_(keyset), |
| 2015 this.title_, this.adapter_.isPasswordBox(), this.adapter_.isA11yMode, | 2164 this.title_, this.adapter_.isPasswordBox(), this.adapter_.isA11yMode, |
| 2016 keyset, this.contextTypeToLastKeysetMap_[contextType] || | 2165 keyset, this.contextTypeToLastKeysetMap_[contextType] || |
| 2017 this.getActiveKeyset_(), this.languageCode_); | 2166 this.getActiveKeyset_(), this.languageCode_); |
| 2018 | 2167 |
| 2168 // If it is the sub keyset switching, emoji, or in hotrod mode, don't record |
| 2169 // the keyset. |
| 2170 if (!this.isSubKeyset_(this.currentKeyset_, keyset) && |
| 2171 keyset != Controller.EMOJI_VIEW_CODE_ && |
| 2172 !this.adapter_.isHotrod) { |
| 2173 // Update the keyset of current context type. |
| 2174 this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] = |
| 2175 keyset; |
| 2176 } |
| 2177 |
| 2019 if (ret) { | 2178 if (ret) { |
| 2020 if (!this.isSubKeyset_(this.currentKeyset_, keyset) && | |
| 2021 keyset != Controller.EMOJI_VIEW_CODE_) { | |
| 2022 // If it is the sub keyset switching, or emoji, don't record it. | |
| 2023 // Update the keyset of current context type. | |
| 2024 this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] = | |
| 2025 keyset; | |
| 2026 } | |
| 2027 this.updateLanguageState_(this.currentKeyset_, keyset); | 2179 this.updateLanguageState_(this.currentKeyset_, keyset); |
| 2028 this.currentKeyset_ = keyset; | 2180 this.currentKeyset_ = keyset; |
| 2029 this.resize(Controller.DEV); | 2181 this.resize(Controller.DEV); |
| 2030 this.statistics_.recordLayout(keyset, this.adapter_.isA11yMode); | 2182 this.statistics_.recordLayout(keyset, this.adapter_.isA11yMode); |
| 2031 this.perfTracker_.tick(PerfTracker.TickName.KEYBOARD_SHOWN); | 2183 this.perfTracker_.tick(PerfTracker.TickName.KEYBOARD_SHOWN); |
| 2032 this.perfTracker_.stop(); | 2184 this.perfTracker_.stop(); |
| 2033 } else { | 2185 } else { |
| 2034 // Sets the current keyset for delay switching. | 2186 // Sets the current keyset for delay switching. |
| 2035 this.currentKeyset_ = keyset; | 2187 this.currentKeyset_ = keyset; |
| 2036 if (keyset != Controller.EMOJI_VIEW_CODE_) { // Emoji is temp keyset. | |
| 2037 this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] = | |
| 2038 keyset; | |
| 2039 } | |
| 2040 this.loadResource_(keyset); | 2188 this.loadResource_(keyset); |
| 2041 } | 2189 } |
| 2042 | 2190 |
| 2043 // TODO: The 'us' part of this code is a workaround an issue where other xkb | 2191 // TODO: The 'us' part of this code is a workaround an issue where other xkb |
| 2044 // languages seem to be sharing options between each other. | 2192 // languages seem to be sharing options between each other. |
| 2045 this.isKeysetUSCompact_ = | 2193 this.isKeysetUSCompact_ = |
| 2046 this.currentKeyset_.indexOf(Controller.US_COMPACT_PREFIX_) >= 0; | 2194 this.currentKeyset_.indexOf(Controller.US_COMPACT_QWERTY_CODE_) >= 0; |
| 2047 // If we're switching to a new keyset, we don't want spacebar to trigger | 2195 // If we're switching to a new keyset, we don't want spacebar to trigger |
| 2048 // another keyset switch. | 2196 // another keyset switch. |
| 2049 this.returnToLetterKeysetOnSpace_ = false; | 2197 this.returnToLetterKeysetOnSpace_ = false; |
| 2198 if (this.gestureTypingEnabled_()) { |
| 2199 this.container_.gestureCanvasView.clear(); |
| 2200 } |
| 2050 }; | 2201 }; |
| 2051 | 2202 |
| 2052 | 2203 |
| 2053 /** | 2204 /** |
| 2054 * Callback when the configuration is loaded. | 2205 * Callback when the configuration is loaded. |
| 2055 * | 2206 * |
| 2056 * @param {!i18n.input.chrome.inputview.events.ConfigLoadedEvent} e The event. | 2207 * @param {!i18n.input.chrome.inputview.events.ConfigLoadedEvent} e The event. |
| 2057 * @private | 2208 * @private |
| 2058 */ | 2209 */ |
| 2059 Controller.prototype.onConfigLoaded_ = function(e) { | 2210 Controller.prototype.onConfigLoaded_ = function(e) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2123 if (isWideScreen) { | 2274 if (isWideScreen) { |
| 2124 widthPercent = spec['LANDSCAPE_WIDE_SCREEN']; | 2275 widthPercent = spec['LANDSCAPE_WIDE_SCREEN']; |
| 2125 } else { | 2276 } else { |
| 2126 widthPercent = spec['LANDSCAPE']; | 2277 widthPercent = spec['LANDSCAPE']; |
| 2127 } | 2278 } |
| 2128 } else { | 2279 } else { |
| 2129 widthPercent = spec['PORTRAIT']; | 2280 widthPercent = spec['PORTRAIT']; |
| 2130 } | 2281 } |
| 2131 candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT; | 2282 candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT; |
| 2132 } | 2283 } |
| 2133 width = this.adapter_.isFloating ? | 2284 var isFloatingMode = this.adapter_.isFloatingVirtualKeyboardEnabled(); |
| 2285 width = isFloatingMode ? |
| 2134 Math.floor(screen.width * widthPercent) : screen.width; | 2286 Math.floor(screen.width * widthPercent) : screen.width; |
| 2135 widthPercent = this.adapter_.isFloating ? 1.0 : widthPercent; | 2287 widthPercent = isFloatingMode ? 1.0 : widthPercent; |
| 2136 if (goog.dom.classlist.contains(this.container_.getElement(), Css.SMALL)) { | 2288 |
| 2137 height = SizeSpec.SMALL_SIZE_HEIGHT; | 2289 // Floating virtual keyboard needs to be placed in the bottom of screen and |
| 2138 width = SizeSpec.SMALL_SIZE_WIDTH; | 2290 // centered when initially shows up. innerHeight == 0 is used as heuristic to |
| 2139 candidateViewHeight = SizeSpec.SMALL_SIZE_CANDIDATE_VIEW_HEIGHT; | 2291 // check if keyboard is showing up for the first time. |
| 2292 if (isFloatingMode && window.innerHeight == 0) { |
| 2293 window.moveTo((screen.width - width) / 2, screen.height - height); |
| 2140 } | 2294 } |
| 2141 | 2295 |
| 2142 if ((window.innerHeight != height || window.innerWidth != width) && | 2296 if ((window.innerHeight != height || window.innerWidth != width) && |
| 2143 !opt_preventResizeTo) { | 2297 !opt_preventResizeTo) { |
| 2144 if (this.lastResizeHeight_ != height || window.innerWidth != width) { | 2298 if (this.lastResizeHeight_ != height || window.innerWidth != width) { |
| 2145 this.lastResizeHeight_ = height; | 2299 this.lastResizeHeight_ = height; |
| 2146 window.resizeTo(width, height); | 2300 window.resizeTo(width, height); |
| 2147 } | 2301 } |
| 2148 return; | 2302 return; |
| 2149 } | 2303 } |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2392 * Handles language state changing event. | 2546 * Handles language state changing event. |
| 2393 * | 2547 * |
| 2394 * @param {!events.MessageEvent} e . | 2548 * @param {!events.MessageEvent} e . |
| 2395 * @private | 2549 * @private |
| 2396 */ | 2550 */ |
| 2397 Controller.prototype.onUpdateToggleLanguageState_ = function(e) { | 2551 Controller.prototype.onUpdateToggleLanguageState_ = function(e) { |
| 2398 if (this.adapter_.isA11yMode || this.currentKeyset_.indexOf('.compact') < 0) { | 2552 if (this.adapter_.isA11yMode || this.currentKeyset_.indexOf('.compact') < 0) { |
| 2399 // e.msg value means whether is Chinese mode now. | 2553 // e.msg value means whether is Chinese mode now. |
| 2400 if (this.model_.stateManager.isEnMode == e.msg) { | 2554 if (this.model_.stateManager.isEnMode == e.msg) { |
| 2401 this.model_.stateManager.isEnMode = !e.msg; | 2555 this.model_.stateManager.isEnMode = !e.msg; |
| 2556 this.updateToggleLanguageKeyset_(); |
| 2402 this.container_.currentKeysetView.update(); | 2557 this.container_.currentKeysetView.update(); |
| 2403 } | 2558 } |
| 2404 } else { | 2559 } else { |
| 2405 var pos = this.currentKeyset_.indexOf('en.compact'); | 2560 var pos = this.currentKeyset_.indexOf('en.compact'); |
| 2406 var toKeyset; | 2561 var toKeyset; |
| 2407 if (pos > 0) { // Means en mode | 2562 if (pos > 0) { // Means en mode |
| 2408 if (e.msg) { // Needs switch cn mode | 2563 if (e.msg) { // Needs switch cn mode |
| 2409 toKeyset = this.currentKeyset_.replace('en.compact', 'compact'); | 2564 toKeyset = this.currentKeyset_.replace('en.compact', 'compact'); |
| 2410 } | 2565 } |
| 2411 } else { | 2566 } else { |
| 2412 if (!e.msg) { // Needs switch en mode | 2567 if (!e.msg) { // Needs switch en mode |
| 2413 toKeyset = this.currentKeyset_.replace('compact', 'en.compact'); | 2568 toKeyset = this.currentKeyset_.replace('compact', 'en.compact'); |
| 2414 } | 2569 } |
| 2415 } | 2570 } |
| 2416 if (toKeyset) { | 2571 if (toKeyset) { |
| 2417 this.resetAll(); | 2572 this.resetAll(); |
| 2418 this.switchToKeyset(toKeyset); | 2573 this.switchToKeyset(toKeyset); |
| 2419 } | 2574 } |
| 2420 } | 2575 } |
| 2421 }; | 2576 }; |
| 2577 |
| 2578 |
| 2579 /** |
| 2580 * Update keyset when language state changes. |
| 2581 * |
| 2582 * @return {boolean} |
| 2583 * @private |
| 2584 */ |
| 2585 Controller.prototype.updateToggleLanguageKeyset_ = function() { |
| 2586 var pos = this.currentKeyset_.indexOf('.us'); |
| 2587 var toKeyset; |
| 2588 if (pos > 0) { |
| 2589 toKeyset = this.currentKeyset_.replace('.us', ''); |
| 2590 if (goog.array.contains(util.KEYSETS_SWITCH_WITH_US, toKeyset)) { |
| 2591 this.switchToKeyset(toKeyset); |
| 2592 return true; |
| 2593 } |
| 2594 } |
| 2595 else if (goog.array.contains(util.KEYSETS_SWITCH_WITH_US, |
| 2596 this.currentKeyset_)) { |
| 2597 toKeyset = this.currentKeyset_ + '.us'; |
| 2598 this.switchToKeyset(toKeyset); |
| 2599 return true; |
| 2600 } |
| 2601 return false; |
| 2602 }; |
| 2603 |
| 2422 }); // goog.scope | 2604 }); // goog.scope |
| OLD | NEW |