Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: third_party/google_input_tools/src/chrome/os/inputview/controller.js

Issue 1257313003: Update Google Input Tools (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing images. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 var InputToolCode = i18n.input.lang.InputToolCode; 72 var InputToolCode = i18n.input.lang.InputToolCode;
73 var KeyCodes = i18n.input.chrome.inputview.events.KeyCodes; 73 var KeyCodes = i18n.input.chrome.inputview.events.KeyCodes;
74 var MenuView = i18n.input.chrome.inputview.elements.content.MenuView; 74 var MenuView = i18n.input.chrome.inputview.elements.content.MenuView;
75 var Name = i18n.input.chrome.message.Name; 75 var Name = i18n.input.chrome.message.Name;
76 var PerfTracker = i18n.input.chrome.inputview.PerfTracker; 76 var PerfTracker = i18n.input.chrome.inputview.PerfTracker;
77 var SizeSpec = i18n.input.chrome.inputview.SizeSpec; 77 var SizeSpec = i18n.input.chrome.inputview.SizeSpec;
78 var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName; 78 var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName;
79 var StateType = i18n.input.chrome.inputview.StateType; 79 var StateType = i18n.input.chrome.inputview.StateType;
80 var SoundController = i18n.input.chrome.sounds.SoundController; 80 var SoundController = i18n.input.chrome.sounds.SoundController;
81 var Type = i18n.input.chrome.message.Type; 81 var Type = i18n.input.chrome.message.Type;
82 var events = i18n.input.chrome.inputview.events;
82 var util = i18n.input.chrome.inputview.util; 83 var util = i18n.input.chrome.inputview.util;
83 84
84 85
85 86
86 /** 87 /**
87 * The controller of the input view keyboard. 88 * The controller of the input view keyboard.
88 * 89 *
89 * @param {string} keyset The keyboard keyset. 90 * @param {string} keyset The keyboard keyset.
90 * @param {string} languageCode The language code for this keyboard. 91 * @param {string} languageCode The language code for this keyboard.
91 * @param {string} passwordLayout The layout for password box. 92 * @param {string} passwordLayout The layout for password box.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 176
176 /** @private {!i18n.input.chrome.inputview.ReadyState} */ 177 /** @private {!i18n.input.chrome.inputview.ReadyState} */
177 this.readyState_ = new i18n.input.chrome.inputview.ReadyState(); 178 this.readyState_ = new i18n.input.chrome.inputview.ReadyState();
178 179
179 /** @private {!i18n.input.chrome.inputview.Adapter} */ 180 /** @private {!i18n.input.chrome.inputview.Adapter} */
180 this.adapter_ = new i18n.input.chrome.inputview.Adapter(this.readyState_); 181 this.adapter_ = new i18n.input.chrome.inputview.Adapter(this.readyState_);
181 182
182 /** @private {!SoundController} */ 183 /** @private {!SoundController} */
183 this.soundController_ = new SoundController(false); 184 this.soundController_ = new SoundController(false);
184 185
186 /**
187 * Whether or not to commit the next gesture result.
188 *
189 * @private {boolean}
190 */
191 this.commitNextGestureResult_ = false;
192
185 /** @private {!i18n.input.chrome.inputview.KeyboardContainer} */ 193 /** @private {!i18n.input.chrome.inputview.KeyboardContainer} */
186 this.container_ = new i18n.input.chrome.inputview.KeyboardContainer( 194 this.container_ = new i18n.input.chrome.inputview.KeyboardContainer(
187 this.adapter_, this.soundController_); 195 this.adapter_, this.soundController_);
188 this.container_.render();
189 196
190 /** 197 /**
191 * The context type and keyset mapping group by input method id. 198 * The context type and keyset mapping group by input method id.
192 * key: input method id. 199 * key: input method id.
193 * value: Object 200 * value: Object
194 * key: context type string. 201 * key: context type string.
195 * value: keyset string. 202 * value: keyset string.
196 * 203 *
197 * @private {!Object.<string, !Object.<string, string>>} 204 * @private {!Object.<string, !Object.<string, string>>}
198 */ 205 */
(...skipping 11 matching lines...) Expand all
210 217
211 /** 218 /**
212 * The stats map for input view closing. 219 * The stats map for input view closing.
213 * 220 *
214 * @type {!Object.<string, !Array.<number>>} 221 * @type {!Object.<string, !Array.<number>>}
215 * @private 222 * @private
216 */ 223 */
217 this.statsForClosing_ = {}; 224 this.statsForClosing_ = {};
218 225
219 /** 226 /**
227 * The time the last point was accepted.
228 *
229 * @private {number}
230 */
231 this.lastPointTime_ = 0;
232
233 /**
220 * The last height sent to window.resizeTo to avoid multiple equivalent calls. 234 * The last height sent to window.resizeTo to avoid multiple equivalent calls.
221 * 235 *
222 * @private {number} 236 * @private {number}
223 */ 237 */
224 this.lastResizeHeight_ = -1; 238 this.lastResizeHeight_ = -1;
225 239
226 /** 240 /**
227 * The activate (show) time stamp for statistics. 241 * The activate (show) time stamp for statistics.
228 * 242 *
229 * @type {Date} 243 * @type {Date}
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 /** 319 /**
306 * The handwriting input tool code suffix. 320 * The handwriting input tool code suffix.
307 * 321 *
308 * @const {string} 322 * @const {string}
309 * @private 323 * @private
310 */ 324 */
311 Controller.HANDWRITING_CODE_SUFFIX_ = '-t-i0-handwrit'; 325 Controller.HANDWRITING_CODE_SUFFIX_ = '-t-i0-handwrit';
312 326
313 327
314 /** 328 /**
329 * The US English compact layout prefix.
330 *
331 * @const {string}
332 * @private
333 */
334 Controller.US_COMPACT_PREFIX_ = 'us.compact';
335
336
337 /**
338 * Time threshold between samples sent to the back end.
339 *
340 * @const {number}
341 */
342 Controller.SUBSAMPLING_TIME_THRESHOLD = 100;
343
344
345 /**
315 * True if the settings is loaded. 346 * True if the settings is loaded.
316 * 347 *
317 * @type {boolean} 348 * @type {boolean}
318 */ 349 */
319 Controller.prototype.isSettingReady = false; 350 Controller.prototype.isSettingReady = false;
320 351
321 352
322 /** 353 /**
323 * True if the keyboard is set up. 354 * True if the keyboard is set up.
324 * Note: This flag is only used for automation testing. 355 * Note: This flag is only used for automation testing.
325 * 356 *
326 * @type {boolean} 357 * @type {boolean}
327 */ 358 */
328 Controller.prototype.isKeyboardReady = false; 359 Controller.prototype.isKeyboardReady = false;
329 360
330 361
331 /** 362 /**
363 * True if the current keyset is the US english compact layout.
364 *
365 * @type {boolean}
366 * @private
367 */
368 Controller.prototype.isKeysetUSCompact_ = false;
369
370
371 /**
332 * The auto repeat timer for backspace hold. 372 * The auto repeat timer for backspace hold.
333 * 373 *
334 * @type {goog.async.Delay} 374 * @type {goog.async.Delay}
335 * @private 375 * @private
336 */ 376 */
337 Controller.prototype.backspaceAutoRepeat_; 377 Controller.prototype.backspaceAutoRepeat_;
338 378
339 379
340 /** 380 /**
341 * The initial keyset determined by inputview url and/or settings. 381 * The initial keyset determined by inputview url and/or settings.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 /** 465 /**
426 * The input tool name. 466 * The input tool name.
427 * 467 *
428 * @type {string} 468 * @type {string}
429 * @private 469 * @private
430 */ 470 */
431 Controller.prototype.title_; 471 Controller.prototype.title_;
432 472
433 473
434 /** 474 /**
475 * Whether to return to the standard character keyset after space is touched.
476 *
477 * @type {boolean}
478 * @private
479 */
480 Controller.prototype.returnToLetterKeysetOnSpace_ = false;
481
482
483 /**
484 * A cache of the previous gesture results.
485 *
486 * @private {!Array.<string>}
487 */
488 Controller.prototype.gestureResultsCache_;
489
490
491 /**
435 * Registers event handlers. 492 * Registers event handlers.
436 * @private 493 * @private
437 */ 494 */
438 Controller.prototype.registerEventHandler_ = function() { 495 Controller.prototype.registerEventHandler_ = function() {
439 this.handler_. 496 this.handler_.
440 listen(this.model_, 497 listen(this.model_,
441 EventType.LAYOUT_LOADED, 498 EventType.LAYOUT_LOADED,
442 this.onLayoutLoaded_). 499 this.onLayoutLoaded_).
443 listen(this.model_, 500 listen(this.model_,
444 EventType.CONFIG_LOADED, 501 EventType.CONFIG_LOADED,
(...skipping 14 matching lines...) Expand all
459 ], this.onPointerEvent_). 516 ], this.onPointerEvent_).
460 listen(this.pointerHandler_, 517 listen(this.pointerHandler_,
461 EventType.DRAG, 518 EventType.DRAG,
462 this.onDragEvent_). 519 this.onDragEvent_).
463 listen(window, goog.events.EventType.RESIZE, this.resize). 520 listen(window, goog.events.EventType.RESIZE, this.resize).
464 listen(this.adapter_, 521 listen(this.adapter_,
465 EventType.SURROUNDING_TEXT_CHANGED, this.onSurroundingTextChanged_). 522 EventType.SURROUNDING_TEXT_CHANGED, this.onSurroundingTextChanged_).
466 listen(this.adapter_, 523 listen(this.adapter_,
467 i18n.input.chrome.DataSource.EventType.CANDIDATES_BACK, 524 i18n.input.chrome.DataSource.EventType.CANDIDATES_BACK,
468 this.onCandidatesBack_). 525 this.onCandidatesBack_).
526 listen(this.adapter_,
527 i18n.input.chrome.DataSource.EventType.GESTURES_BACK,
528 this.onGesturesBack_).
469 listen(this.adapter_, EventType.URL_CHANGED, this.onURLChanged_). 529 listen(this.adapter_, EventType.URL_CHANGED, this.onURLChanged_).
470 listen(this.adapter_, EventType.CONTEXT_FOCUS, this.onContextFocus_). 530 listen(this.adapter_, EventType.CONTEXT_FOCUS, this.onContextFocus_).
471 listen(this.adapter_, EventType.CONTEXT_BLUR, this.onContextBlur_). 531 listen(this.adapter_, EventType.CONTEXT_BLUR, this.onContextBlur_).
472 listen(this.adapter_, EventType.VISIBILITY_CHANGE, 532 listen(this.adapter_, EventType.VISIBILITY_CHANGE,
473 this.onVisibilityChange_). 533 this.onVisibilityChange_).
474 listen(this.adapter_, EventType.SETTINGS_READY, this.onSettingsReady_). 534 listen(this.adapter_, EventType.SETTINGS_READY, this.onSettingsReady_).
475 listen(this.adapter_, Type.UPDATE_SETTINGS, this.onUpdateSettings_). 535 listen(this.adapter_, EventType.UPDATE_SETTINGS, this.onUpdateSettings_).
476 listen(this.adapter_, Type.FRONT_TOGGLE_LANGUAGE_STATE, 536 listen(this.adapter_, EventType.FRONT_TOGGLE_LANGUAGE_STATE,
477 this.onUpdateToggleLanguateState_). 537 this.onUpdateToggleLanguageState_).
478 listen(this.adapter_, Type.VOICE_STATE_CHANGE, this.onVoiceStateChange_). 538 listen(this.adapter_, EventType.VOICE_STATE_CHANGE,
539 this.onVoiceStateChange_).
479 listen(this.adapter_, EventType.REFRESH, this.onRefresh_); 540 listen(this.adapter_, EventType.REFRESH, this.onRefresh_);
480 }; 541 };
481 542
482 543
483 /** 544 /**
484 * Handler for voice module state change. 545 * Handler for voice module state change.
485 * 546 *
486 * @param {!i18n.input.chrome.message.Event} e . 547 * @param {!events.MessageEvent} e .
487 * @private 548 * @private
488 */ 549 */
489 Controller.prototype.onVoiceStateChange_ = function(e) { 550 Controller.prototype.onVoiceStateChange_ = function(e) {
490 if (!e.msg[Name.VOICE_STATE]) { 551 if (!e.msg[Name.VOICE_STATE]) {
491 this.container_.candidateView.switchToIcon( 552 this.container_.candidateView.switchToIcon(
492 CandidateView.IconType.VOICE, true); 553 CandidateView.IconType.VOICE, true);
493 this.container_.voiceView.stop(); 554 this.container_.voiceView.stop();
494 } 555 }
495 }; 556 };
496 557
(...skipping 22 matching lines...) Expand all
519 keysetMap[context] = newKeyset; 580 keysetMap[context] = newKeyset;
520 } 581 }
521 } 582 }
522 keysetMap[ContextType.DEFAULT] = this.initialKeyset_ = newKeyset; 583 keysetMap[ContextType.DEFAULT] = this.initialKeyset_ = newKeyset;
523 }; 584 };
524 585
525 586
526 /** 587 /**
527 * Callback for updating settings. 588 * Callback for updating settings.
528 * 589 *
529 * @param {!i18n.input.chrome.message.Event} e . 590 * @param {!events.MessageEvent} e .
530 * @private 591 * @private
531 */ 592 */
532 Controller.prototype.onUpdateSettings_ = function(e) { 593 Controller.prototype.onUpdateSettings_ = function(e) {
533 var settings = this.model_.settings; 594 var settings = this.model_.settings;
534 if (goog.isDef(e.msg['autoSpace'])) { 595 if (goog.isDef(e.msg['autoSpace'])) {
535 settings.autoSpace = e.msg['autoSpace']; 596 settings.autoSpace = e.msg['autoSpace'];
536 } 597 }
537 if (goog.isDef(e.msg['autoCapital'])) { 598 if (goog.isDef(e.msg['autoCapital'])) {
538 settings.autoCapital = e.msg['autoCapital']; 599 settings.autoCapital = e.msg['autoCapital'];
539 } 600 }
540 if (goog.isDef(e.msg['candidatesNavigation'])) { 601 if (goog.isDef(e.msg['candidatesNavigation'])) {
541 settings.candidatesNavigation = e.msg['candidatesNavigation']; 602 settings.candidatesNavigation = e.msg['candidatesNavigation'];
542 this.container_.candidateView.setNavigation(settings.candidatesNavigation); 603 this.container_.candidateView.setNavigation(settings.candidatesNavigation);
543 } 604 }
544 if (goog.isDef(e.msg[Name.KEYSET])) { 605 if (goog.isDef(e.msg[Name.KEYSET])) {
545 this.setDefaultKeyset_(e.msg[Name.KEYSET]); 606 this.setDefaultKeyset_(e.msg[Name.KEYSET]);
546 } 607 }
547 if (goog.isDef(e.msg['enableLongPress'])) { 608 if (goog.isDef(e.msg['enableLongPress'])) {
548 settings.enableLongPress = e.msg['enableLongPress']; 609 settings.enableLongPress = e.msg['enableLongPress'];
549 } 610 }
550 if (goog.isDef(e.msg['doubleSpacePeriod'])) { 611 if (goog.isDef(e.msg['doubleSpacePeriod'])) {
551 settings.doubleSpacePeriod = e.msg['doubleSpacePeriod']; 612 settings.doubleSpacePeriod = e.msg['doubleSpacePeriod'];
552 } 613 }
553 if (goog.isDef(e.msg['soundOnKeypress'])) { 614 if (goog.isDef(e.msg['soundOnKeypress'])) {
554 settings.soundOnKeypress = e.msg['soundOnKeypress']; 615 settings.soundOnKeypress = e.msg['soundOnKeypress'];
555 this.soundController_.setEnabled(settings.soundOnKeypress); 616 this.soundController_.setEnabled(settings.soundOnKeypress);
556 } 617 }
618 if (goog.isDef(e.msg['gestureEditing'])) {
619 settings.gestureEditing = e.msg['gestureEditing'];
620 var enabled = settings.gestureEditing && !this.adapter_.isA11yMode;
621 this.container_.swipeView.enabled = enabled;
622 this.container_.selectView.setSettingsEnabled(enabled);
623 }
624 if (goog.isDef(e.msg['gestureTyping'])) {
625 settings.gestureTyping = e.msg['gestureTyping'];
626 } else {
627 settings.gestureTyping = false;
628 }
557 this.perfTracker_.tick(PerfTracker.TickName.BACKGROUND_SETTINGS_FETCHED); 629 this.perfTracker_.tick(PerfTracker.TickName.BACKGROUND_SETTINGS_FETCHED);
558 this.model_.stateManager.contextType = this.adapter_.contextType; 630 this.model_.stateManager.contextType = this.adapter_.contextType;
559 this.maybeCreateViews_(); 631 this.maybeCreateViews_();
560 }; 632 };
561 633
562 634
563 /** 635 /**
564 * Callback for url changed. 636 * Callback for url changed.
565 * 637 *
566 * @private 638 * @private
567 */ 639 */
568 Controller.prototype.onURLChanged_ = function() { 640 Controller.prototype.onURLChanged_ = function() {
569 this.container_.candidateView.setToolbarVisible(this.shouldShowToolBar_()); 641 this.container_.candidateView.setToolbarVisible(this.shouldShowToolBar_());
570 }; 642 };
571 643
572 644
573 /** 645 /**
574 * Callback for setting ready. 646 * Callback for setting ready.
575 * 647 *
576 * @private 648 * @private
577 */ 649 */
578 Controller.prototype.onSettingsReady_ = function() { 650 Controller.prototype.onSettingsReady_ = function() {
579 if (this.isSettingReady) { 651 if (this.isSettingReady) {
580 return; 652 return;
581 } 653 }
582 654
583 this.isSettingReady = true; 655 this.isSettingReady = true;
656 // Don't render container twice.
657 if (!this.container_.isInDocument()) {
658 this.container_.render();
659 }
584 var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; 660 var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_];
585 var newKeyset = ''; 661 var newKeyset = '';
586 if (this.adapter_.isA11yMode) { 662 if (this.adapter_.isA11yMode) {
587 newKeyset = util.getConfigName(keysetMap[ContextType.DEFAULT]); 663 newKeyset = util.getConfigName(keysetMap[ContextType.DEFAULT]);
588 } else { 664 } else {
589 newKeyset = /** @type {string} */ (this.model_.settings. 665 newKeyset = /** @type {string} */ (this.model_.settings.
590 getPreference(util.getConfigName(keysetMap[ContextType.DEFAULT]))); 666 getPreference(util.getConfigName(keysetMap[ContextType.DEFAULT])));
591 } 667 }
592 if (!this.adapter_.features.isEnabled(FeatureName.EXPERIMENTAL) && 668 if (!this.adapter_.features.isEnabled(FeatureName.EXPERIMENTAL) &&
593 keysetMap[ContextType.DEFAULT] == 669 keysetMap[ContextType.DEFAULT] ==
594 'zhuyin.compact.qwerty') { 670 'zhuyin.compact.qwerty') {
595 newKeyset = 'zhuyin'; 671 newKeyset = 'zhuyin';
596 } 672 }
597 if (newKeyset) { 673 if (newKeyset) {
598 this.setDefaultKeyset_(newKeyset); 674 this.setDefaultKeyset_(newKeyset);
599 } 675 }
600 this.container_.selectView.setVisible( 676 this.container_.selectView.setSettingsEnabled(
601 this.adapter_.features.isEnabled(FeatureName.GESTURE_SELECTION)); 677 this.model_.settings.gestureEditing && !this.adapter_.isA11yMode);
602 // Loads resources in case the default keyset is changed. 678 // Loads resources in case the default keyset is changed.
603 this.loadAllResources_(); 679 this.loadAllResources_();
604 this.maybeCreateViews_(); 680 this.maybeCreateViews_();
605 }; 681 };
606 682
607 683
608 /** 684 /**
685 * Returns whether or not the gesture typing feature is enabled.
686 *
687 * @return {boolean}
688 * @private
689 */
690 Controller.prototype.gestureTypingEnabled_ = function() {
691 return this.isKeysetUSCompact_ && this.model_.settings.gestureTyping &&
692 !this.adapter_.isA11yMode && !this.adapter_.isChromeVoxOn;
693 };
694
695
696 /**
697 * Returns the time threshold for subsampling, in ms.
698 *
699 * @return {number}
700 * @private
701 */
702 Controller.prototype.subsamplingThreshold_ = function() {
703 return Controller.SUBSAMPLING_TIME_THRESHOLD;
704 };
705
706
707 /**
609 * Gets the data for spatial module. 708 * Gets the data for spatial module.
610 * 709 *
611 * @param {!i18n.input.chrome.inputview.elements.content.SoftKey} key . 710 * @param {!i18n.input.chrome.inputview.elements.content.SoftKey} key .
612 * @param {number} x The x-offset of the touch point. 711 * @param {number} x The x-offset of the touch point.
613 * @param {number} y The y-offset of the touch point. 712 * @param {number} y The y-offset of the touch point.
614 * @return {!Object} . 713 * @return {!Object} .
615 * @private 714 * @private
616 */ 715 */
617 Controller.prototype.getSpatialData_ = function(key, x, y) { 716 Controller.prototype.getSpatialData_ = function(key, x, y) {
618 var items = []; 717 var items = [];
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 this.stopBackspaceAutoRepeat_(); 807 this.stopBackspaceAutoRepeat_();
709 } 808 }
710 809
711 if (e.view) { 810 if (e.view) {
712 this.handlePointerAction_(e.view, e); 811 this.handlePointerAction_(e.view, e);
713 } 812 }
714 }; 813 };
715 814
716 815
717 /** 816 /**
817 * Sends the last stroke from the gesture canvas view to the gesture decoder, if
818 * the last point was added past a time threshold.
819 *
820 * @param {boolean=} opt_force Whether or not to force send the gesture event.
821 * @private
822 */
823 Controller.prototype.maybeSendLastStroke_ = function(opt_force) {
824 // Subsample by returning early if the previous point was added too recently.
825 var currentTime = Date.now();
826 if (!opt_force && currentTime - this.lastPointTime_ <
827 this.subsamplingThreshold_()) {
828 return;
829 } else {
830 this.lastPointTime_ = currentTime;
831 }
832 var lastStroke = this.container_.gestureCanvasView.getLastStroke();
833 if (lastStroke) {
834 // This call will set up the necessary callbacks the decoder will use to
835 // communicate back to this class.
836 this.adapter_.sendGestureEvent(lastStroke.points);
837 }
838 };
839
840
841 /**
718 * Handles the drag events. Generally, this will forward the event details to 842 * Handles the drag events. Generally, this will forward the event details to
719 * the components that handle drawing, decoding, etc. 843 * the components that handle drawing, decoding, etc.
720 * 844 *
721 * @param {!i18n.input.chrome.inputview.events.DragEvent} e . 845 * @param {!i18n.input.chrome.inputview.events.DragEvent} e .
722 * @private 846 * @private
723 */ 847 */
724 Controller.prototype.onDragEvent_ = function(e) { 848 Controller.prototype.onDragEvent_ = function(e) {
725 if (this.adapter_.isGestureTypingEnabled() && e.type == EventType.DRAG) { 849 if (this.gestureTypingEnabled_() && e.type == EventType.DRAG &&
850 !this.container_.swipeView.isVisible()) {
726 this.container_.gestureCanvasView.addPoint(e); 851 this.container_.gestureCanvasView.addPoint(e);
852 if (e.view && this.container_.gestureCanvasView.isGesturing) {
853 // Ensure the last touched key is not highlighted.
854 e.view.setHighlighted(false);
855 this.maybeSendLastStroke_();
856 }
727 return; 857 return;
728 } 858 }
729 }; 859 };
730 860
731 861
732 /** 862 /**
733 * Handles the swipe action. 863 * Handles the swipe action.
734 * 864 *
735 * @param {!i18n.input.chrome.inputview.elements.Element} view The view, for 865 * @param {!i18n.input.chrome.inputview.elements.Element} view The view, for
736 * swipe event, the view would be the soft key which starts the swipe. 866 * swipe event, the view would be the soft key which starts the swipe.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 this.currentKeyset_; 942 this.currentKeyset_;
813 // TODO: remember handwriting keyset. 943 // TODO: remember handwriting keyset.
814 this.switchToKeyset(Controller.HANDWRITING_VIEW_CODE_); 944 this.switchToKeyset(Controller.HANDWRITING_VIEW_CODE_);
815 break; 945 break;
816 946
817 case CommandEnum.OPEN_SETTING: 947 case CommandEnum.OPEN_SETTING:
818 if (window.inputview) { 948 if (window.inputview) {
819 inputview.openSettings(); 949 inputview.openSettings();
820 } 950 }
821 break; 951 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
822 } 974 }
823 }; 975 };
824 976
825 977
826 /** 978 /**
827 * Handles the pointer action. 979 * Handles the pointer action.
828 * 980 *
829 * @param {!i18n.input.chrome.inputview.elements.Element} view The view. 981 * @param {!i18n.input.chrome.inputview.elements.Element} view The view.
830 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . 982 * @param {!i18n.input.chrome.inputview.events.PointerEvent} e .
831 * @private 983 * @private
832 */ 984 */
833 Controller.prototype.handlePointerAction_ = function(view, e) { 985 Controller.prototype.handlePointerAction_ = function(view, e) {
834 if (this.adapter_.isGestureTypingEnabled() && 986 if (this.gestureTypingEnabled_() && !this.container_.swipeView.isVisible()) {
835 e.type == EventType.POINTER_DOWN) { 987 if (e.type == EventType.POINTER_DOWN) {
836 this.container_.gestureCanvasView.startStroke(e); 988 this.container_.gestureCanvasView.startStroke(e);
837 } 989 view.setHighlighted(false);
990 }
838 991
839 if (this.adapter_.isGestureTypingEnabled() && 992 // Determine if the gestureCanvasView was handling a gesture before calling
840 e.type == EventType.POINTER_UP) { 993 // endStroke, as it ends the current gesture.
841 this.container_.gestureCanvasView.endStroke(e); 994 var wasGesturing = this.container_.gestureCanvasView.isGesturing;
842 } 995 if (e.type == EventType.POINTER_UP && wasGesturing) {
996 this.container_.gestureCanvasView.endStroke(e);
997 this.maybeSendLastStroke_(true);
998 this.commitNextGestureResult_ = true;
999 }
843 1000
844 // Do not trigger other actives when gesturing. 1001 // Do not trigger other activities when gesturing.
845 if (this.adapter_.isGestureTypingEnabled() && 1002 if (wasGesturing) {
846 this.container_.gestureCanvasView.isGesturing) { 1003 if (e.type == EventType.POINTER_OVER) {
847 return; 1004 view.setHighlighted(false);
1005 }
1006 return;
1007 }
848 } 1008 }
849 1009
850 // Listen for DOUBLE_CLICK as well to capture secondary taps on the spacebar. 1010 // Listen for DOUBLE_CLICK as well to capture secondary taps on the spacebar.
851 if (e.type == EventType.POINTER_UP || e.type == EventType.DOUBLE_CLICK) { 1011 if (e.type == EventType.POINTER_UP || e.type == EventType.DOUBLE_CLICK) {
852 this.recordStatsForClosing_( 1012 this.recordStatsForClosing_(
853 'InputMethod.VirtualKeyboard.TapCount', 1, 4095, 4096); 1013 'InputMethod.VirtualKeyboard.TapCount', 1, 4095, 4096);
854 } 1014 }
855 1015
856 if (e.type == EventType.SWIPE) { 1016 if (e.type == EventType.SWIPE) {
857 e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e); 1017 e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 if (e.type == EventType.POINTER_UP) { 1055 if (e.type == EventType.POINTER_UP) {
896 this.showCandidates_(this.candidatesInfo_.source, 1056 this.showCandidates_(this.candidatesInfo_.source,
897 this.candidatesInfo_.candidates, 1057 this.candidatesInfo_.candidates,
898 Controller.CandidatesOperation.SHRINK); 1058 Controller.CandidatesOperation.SHRINK);
899 this.soundController_.onKeyUp(view.type); 1059 this.soundController_.onKeyUp(view.type);
900 } 1060 }
901 return; 1061 return;
902 case ElementType.CANDIDATE: 1062 case ElementType.CANDIDATE:
903 view = /** @type {!i18n.input.chrome.inputview.elements.content. 1063 view = /** @type {!i18n.input.chrome.inputview.elements.content.
904 Candidate} */ (view); 1064 Candidate} */ (view);
1065 if (view.candidateType == CandidateType.TOOLTIP)
1066 return;
905 if (e.type == EventType.POINTER_UP) { 1067 if (e.type == EventType.POINTER_UP) {
906 if (view.candidateType == CandidateType.CANDIDATE) { 1068 if (view.candidateType == CandidateType.CANDIDATE) {
907 this.adapter_.selectCandidate(view.candidate); 1069 this.adapter_.selectCandidate(view.candidate);
908 } else if (view.candidateType == CandidateType.NUMBER) { 1070 } else if (view.candidateType == CandidateType.NUMBER) {
909 this.adapter_.commitText(view.candidate[Name.CANDIDATE]); 1071 this.adapter_.sendKeyDownAndUpEvent(
1072 view.candidate[Name.CANDIDATE], '');
910 } 1073 }
911 this.container_.cleanStroke(); 1074 this.container_.cleanStroke();
912 this.soundController_.onKeyUp(ElementType.CANDIDATE); 1075 this.soundController_.onKeyUp(ElementType.CANDIDATE);
913 } 1076 }
914 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { 1077 if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) {
915 view.setHighlighted(false); 1078 view.setHighlighted(false);
916 } else if (e.type == EventType.POINTER_DOWN || 1079 } else if (e.type == EventType.POINTER_DOWN ||
917 e.type == EventType.POINTER_OVER) { 1080 e.type == EventType.POINTER_OVER) {
918 view.setHighlighted(true); 1081 view.setHighlighted(true);
919 } 1082 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 if (!this.container_.currentKeysetView.isDragging && view.text != '') { 1127 if (!this.container_.currentKeysetView.isDragging && view.text != '') {
965 this.adapter_.commitText(view.text); 1128 this.adapter_.commitText(view.text);
966 this.soundController_.onKeyUp(view.type); 1129 this.soundController_.onKeyUp(view.type);
967 } 1130 }
968 } 1131 }
969 return; 1132 return;
970 1133
971 case ElementType.HWT_PRIVACY_GOT_IT: 1134 case ElementType.HWT_PRIVACY_GOT_IT:
972 // Broadcasts the handwriting privacy confirmed message to let canvas 1135 // Broadcasts the handwriting privacy confirmed message to let canvas
973 // view handle it. 1136 // view handle it.
974 this.adapter_.dispatchEvent(new goog.events.Event( 1137 if (e.type == EventType.POINTER_UP) {
975 Type.HWT_PRIVACY_GOT_IT)); 1138 this.adapter_.dispatchEvent(new goog.events.Event(
1139 Type.HWT_PRIVACY_GOT_IT));
1140 }
976 return; 1141 return;
977 1142
978 case ElementType.VOICE_PRIVACY_GOT_IT: 1143 case ElementType.VOICE_PRIVACY_GOT_IT:
979 // Broadcasts the voice privacy confirmed message to let voice 1144 // Broadcasts the voice privacy confirmed message to let voice
980 // view handle it. 1145 // view handle it.
981 this.adapter_.dispatchEvent(new goog.events.Event( 1146 if (e.type == EventType.POINTER_UP) {
982 Type.VOICE_PRIVACY_GOT_IT)); 1147 this.adapter_.dispatchEvent(new goog.events.Event(
1148 Type.VOICE_PRIVACY_GOT_IT));
1149 }
983 return; 1150 return;
984 1151
985 case ElementType.VOICE_VIEW: 1152 case ElementType.VOICE_VIEW:
986 if (e.type == EventType.POINTER_UP) { 1153 if (e.type == EventType.POINTER_UP) {
987 this.adapter_.sendVoiceViewStateChange(false); 1154 this.adapter_.sendVoiceViewStateChange(false);
988 this.container_.candidateView.switchToIcon( 1155 this.container_.candidateView.switchToIcon(
989 CandidateView.IconType.VOICE, true); 1156 CandidateView.IconType.VOICE, true);
990 this.container_.voiceView.stop(); 1157 this.container_.voiceView.stop();
991 } 1158 }
992 return; 1159 return;
993 case ElementType.SWIPE_VIEW: 1160 case ElementType.SWIPE_VIEW:
994 this.stopBackspaceAutoRepeat_(); 1161 this.stopBackspaceAutoRepeat_();
995 if (e.type == EventType.POINTER_UP || 1162 if (e.type == EventType.POINTER_UP ||
996 e.type == EventType.POINTER_OUT) { 1163 e.type == EventType.POINTER_OUT) {
997 this.clearUnstickyState_(); 1164 this.clearUnstickyState_();
998 } 1165 }
999 return; 1166 return;
1167 case ElementType.DRAG:
1168 if (e.type == EventType.POINTER_DOWN && this.container_.floatingView) {
1169 this.container_.floatingView.show();
1170 }
1171 return;
1172 case ElementType.FLOATING_VIEW:
1173 if (e.type == EventType.POINTER_UP && this.container_.floatingView) {
1174 this.container_.floatingView.hide();
1175 }
1176 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;
1000 case ElementType.CUT: 1183 case ElementType.CUT:
1001 case ElementType.COPY: 1184 case ElementType.COPY:
1002 case ElementType.PASTE: 1185 case ElementType.PASTE:
1003 case ElementType.BOLD: 1186 case ElementType.BOLD:
1004 case ElementType.ITALICS: 1187 case ElementType.ITALICS:
1005 case ElementType.UNDERLINE: 1188 case ElementType.UNDERLINE:
1006 case ElementType.REDO: 1189 case ElementType.REDO:
1007 case ElementType.UNDO: 1190 case ElementType.UNDO:
1008 case ElementType.SELECT_ALL: 1191 case ElementType.SELECT_ALL:
1009 view.setHighlighted(e.type == EventType.POINTER_DOWN || 1192 view.setHighlighted(e.type == EventType.POINTER_DOWN ||
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 key = /** @type {!i18n.input.chrome.inputview.elements.content. 1310 key = /** @type {!i18n.input.chrome.inputview.elements.content.
1128 FunctionalKey} */(softKey); 1311 FunctionalKey} */(softKey);
1129 if (e.type == EventType.POINTER_DOWN) { 1312 if (e.type == EventType.POINTER_DOWN) {
1130 this.backspaceTick_(); 1313 this.backspaceTick_();
1131 } else if (e.type == EventType.POINTER_UP || e.type == EventType. 1314 } else if (e.type == EventType.POINTER_UP || e.type == EventType.
1132 POINTER_OUT) { 1315 POINTER_OUT) {
1133 if (!this.container_.swipeView.isVisible()) { 1316 if (!this.container_.swipeView.isVisible()) {
1134 this.stopBackspaceAutoRepeat_(); 1317 this.stopBackspaceAutoRepeat_();
1135 } 1318 }
1136 } 1319 }
1320 this.returnToLetterKeysetOnSpace_ = false;
1137 break; 1321 break;
1138 1322
1139 case ElementType.TAB_KEY: 1323 case ElementType.TAB_KEY:
1140 key = /** @type {!i18n.input.chrome.inputview.elements.content. 1324 key = /** @type {!i18n.input.chrome.inputview.elements.content.
1141 FunctionalKey} */ (softKey); 1325 FunctionalKey} */ (softKey);
1142 if (e.type == EventType.POINTER_DOWN) { 1326 if (e.type == EventType.POINTER_DOWN) {
1143 this.adapter_.sendKeyDownEvent('\u0009', KeyCodes.TAB); 1327 this.adapter_.sendKeyDownEvent('\u0009', KeyCodes.TAB);
1144 } else if (e.type == EventType.POINTER_UP) { 1328 } else if (e.type == EventType.POINTER_UP) {
1145 this.adapter_.sendKeyUpEvent('\u0009', KeyCodes.TAB); 1329 this.adapter_.sendKeyUpEvent('\u0009', KeyCodes.TAB);
1146 } 1330 }
1331 this.returnToLetterKeysetOnSpace_ = false;
1147 break; 1332 break;
1148 1333
1149 case ElementType.ENTER_KEY: 1334 case ElementType.ENTER_KEY:
1150 key = /** @type {!i18n.input.chrome.inputview.elements.content. 1335 key = /** @type {!i18n.input.chrome.inputview.elements.content.
1151 FunctionalKey} */ (softKey); 1336 FunctionalKey} */ (softKey);
1152 if (e.type == EventType.POINTER_UP) { 1337 if (e.type == EventType.POINTER_UP) {
1153 this.adapter_.sendKeyDownAndUpEvent('\u000D', KeyCodes.ENTER); 1338 this.adapter_.sendKeyDownAndUpEvent('\u000D', KeyCodes.ENTER);
1154 } 1339 }
1155 break; 1340 break;
1156 1341
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 this.currentKeyset_ != Controller.HANDWRITING_VIEW_CODE_ && 1386 this.currentKeyset_ != Controller.HANDWRITING_VIEW_CODE_ &&
1202 this.currentKeyset_ != Controller.EMOJI_VIEW_CODE_; 1387 this.currentKeyset_ != Controller.EMOJI_VIEW_CODE_;
1203 if (e.type == EventType.POINTER_UP || (!doubleSpacePeriod && e.type == 1388 if (e.type == EventType.POINTER_UP || (!doubleSpacePeriod && e.type ==
1204 EventType.DOUBLE_CLICK_END)) { 1389 EventType.DOUBLE_CLICK_END)) {
1205 this.adapter_.sendKeyDownAndUpEvent(key.getCharacter(), 1390 this.adapter_.sendKeyDownAndUpEvent(key.getCharacter(),
1206 KeyCodes.SPACE); 1391 KeyCodes.SPACE);
1207 this.clearUnstickyState_(); 1392 this.clearUnstickyState_();
1208 } else if (e.type == EventType.DOUBLE_CLICK && doubleSpacePeriod) { 1393 } else if (e.type == EventType.DOUBLE_CLICK && doubleSpacePeriod) {
1209 this.adapter_.doubleClickOnSpaceKey(); 1394 this.adapter_.doubleClickOnSpaceKey();
1210 } 1395 }
1396 if (this.returnToLetterKeysetOnSpace_) {
1397 // Return to the letter keyset.
1398 this.switchToKeyset(key.toKeyset);
1399 this.returnToLetterKeysetOnSpace_ = false;
1400 }
1211 break; 1401 break;
1212 1402
1213 case ElementType.SWITCHER_KEY: 1403 case ElementType.SWITCHER_KEY:
1214 key = /** @type {!i18n.input.chrome.inputview.elements.content. 1404 key = /** @type {!i18n.input.chrome.inputview.elements.content.
1215 SwitcherKey} */ (softKey); 1405 SwitcherKey} */ (softKey);
1216 if (e.type == EventType.POINTER_UP) { 1406 if (e.type == EventType.POINTER_UP) {
1217 this.recordStatsForClosing_( 1407 this.recordStatsForClosing_(
1218 'InputMethod.VirtualKeyboard.LayoutSwitch', 1, 25, 25); 1408 'InputMethod.VirtualKeyboard.LayoutSwitch', 1, 25, 25);
1219 if (this.isSubKeyset_(key.toKeyset, this.currentKeyset_)) { 1409 if (this.isSubKeyset_(key.toKeyset, this.currentKeyset_)) {
1220 this.model_.stateManager.reset(); 1410 this.model_.stateManager.reset();
1221 this.container_.update(); 1411 this.container_.update();
1222 this.updateContextModifierState_(); 1412 this.updateContextModifierState_();
1223 this.container_.menuView.hide(); 1413 this.container_.menuView.hide();
1224 } else { 1414 } else {
1225 this.resetAll(); 1415 this.resetAll();
1226 } 1416 }
1227 // Switch to the specific keyboard. 1417 // Switch to the specific keyboard.
1228 this.switchToKeyset(key.toKeyset); 1418 this.switchToKeyset(key.toKeyset);
1229 if (key.record) { 1419 if (key.record) {
1230 this.model_.settings.savePreference( 1420 this.model_.settings.savePreference(
1231 util.getConfigName(key.toKeyset), 1421 util.getConfigName(key.toKeyset),
1232 key.toKeyset); 1422 key.toKeyset);
1233 } 1423 }
1234 } 1424 }
1425 this.returnToLetterKeysetOnSpace_ = false;
1235 break; 1426 break;
1236 1427
1237 case ElementType.COMPACT_KEY: 1428 case ElementType.COMPACT_KEY:
1238 key = /** @type {!i18n.input.chrome.inputview.elements.content. 1429 key = /** @type {!i18n.input.chrome.inputview.elements.content.
1239 CompactKey} */(softKey); 1430 CompactKey} */(softKey);
1240 if (e.type == EventType.LONG_PRESS) { 1431 if (e.type == EventType.LONG_PRESS) {
1241 this.container_.altDataView.show( 1432 this.container_.altDataView.show(
1242 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_), 1433 key, goog.i18n.bidi.isRtlLanguage(this.languageCode_),
1243 e.identifier); 1434 e.identifier);
1244 } else if (e.type == EventType.POINTER_UP) { 1435 } else if (e.type == EventType.POINTER_UP) {
1245 this.model_.stateManager.triggerChording(); 1436 this.model_.stateManager.triggerChording();
1246 var ch = key.getActiveCharacter(); 1437 var ch = key.getActiveCharacter();
1247 if (ch.length == 1) { 1438 if (ch.length == 1) {
1248 this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0, 1439 this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0,
1249 this.getSpatialData_(key, e.x, e.y)); 1440 this.getSpatialData_(key, e.x, e.y));
1250 } else if (ch.length > 1) { 1441 } else if (ch.length > 1) {
1251 // Some compact keys contains more than 1 characters, such as '.com', 1442 // Some compact keys contains more than 1 characters, such as '.com',
1252 // 'http://', etc. Those keys should trigger a direct commit text 1443 // 'http://', etc. Those keys should trigger a direct commit text
1253 // instead of key events. 1444 // instead of key events.
1254 this.adapter_.commitText(ch); 1445 this.adapter_.commitText(ch);
1255 } 1446 }
1256 this.clearUnstickyState_(); 1447 this.clearUnstickyState_();
1257 key.flickerredCharacter = ''; 1448 key.flickerredCharacter = '';
1449 if (this.currentKeyset_.indexOf('symbol') != -1) {
1450 // If this is the symbol keyset, a space as the next input should
1451 // switch us to the standard keyset.
1452 this.returnToLetterKeysetOnSpace_ = true;
1453 }
1258 } 1454 }
1259 break; 1455 break;
1260 1456
1261 case ElementType.HIDE_KEYBOARD_KEY: 1457 case ElementType.HIDE_KEYBOARD_KEY:
1262 var defaultKeyset = this.getActiveKeyset_(); 1458 var defaultKeyset = this.getActiveKeyset_();
1263 if (e.type == EventType.POINTER_UP) { 1459 if (e.type == EventType.POINTER_UP) {
1264 this.adapter_.hideKeyboard(); 1460 this.adapter_.hideKeyboard();
1265 if (this.currentKeyset_ != defaultKeyset) { 1461 if (this.currentKeyset_ != defaultKeyset) {
1266 this.switchToKeyset(defaultKeyset); 1462 this.switchToKeyset(defaultKeyset);
1267 } 1463 }
(...skipping 16 matching lines...) Expand all
1284 this.languageCode_ == 'ko') { 1480 this.languageCode_ == 'ko') {
1285 // Hides 'switch to compact' for zhuyin when not in experimental env. 1481 // Hides 'switch to compact' for zhuyin when not in experimental env.
1286 enableCompact = false; 1482 enableCompact = false;
1287 } 1483 }
1288 var hasHwt = !this.adapter_.isPasswordBox() && 1484 var hasHwt = !this.adapter_.isPasswordBox() &&
1289 !Controller.DISABLE_HWT && goog.object.contains( 1485 !Controller.DISABLE_HWT && goog.object.contains(
1290 InputToolCode, this.getHwtInputToolCode_()); 1486 InputToolCode, this.getHwtInputToolCode_());
1291 var hasEmoji = !this.adapter_.isPasswordBox(); 1487 var hasEmoji = !this.adapter_.isPasswordBox();
1292 var enableSettings = this.shouldEnableSettings() && 1488 var enableSettings = this.shouldEnableSettings() &&
1293 !!window.inputview && !!inputview.openSettings; 1489 !!window.inputview && !!inputview.openSettings;
1490 var enableFVK = this.adapter_.isFloatingVirtualKeyboardEnabled();
1294 this.adapter_.getInputMethods(function(inputMethods) { 1491 this.adapter_.getInputMethods(function(inputMethods) {
1295 this.container_.menuView.show(key, defaultFullKeyset, isCompact, 1492 this.container_.menuView.show(key, defaultFullKeyset, isCompact,
1296 enableCompact, this.currentInputMethod_, inputMethods, hasHwt, 1493 enableCompact, this.currentInputMethod_, inputMethods, hasHwt,
1297 enableSettings, hasEmoji, this.adapter_.isA11yMode); 1494 enableSettings, hasEmoji, this.adapter_.isA11yMode, enableFVK,
1495 this.adapter_.isFloating);
1298 }.bind(this)); 1496 }.bind(this));
1299 } 1497 }
1300 break; 1498 break;
1301 1499
1302 case ElementType.GLOBE_KEY: 1500 case ElementType.GLOBE_KEY:
1303 if (e.type == EventType.POINTER_UP) { 1501 if (e.type == EventType.POINTER_UP) {
1304 this.adapter_.clearModifierStates(); 1502 this.adapter_.clearModifierStates();
1305 this.adapter_.setModifierState( 1503 this.adapter_.setModifierState(
1306 i18n.input.chrome.inputview.StateType.ALT, true); 1504 i18n.input.chrome.inputview.StateType.ALT, true);
1307 this.adapter_.sendKeyDownAndUpEvent( 1505 this.adapter_.sendKeyDownAndUpEvent(
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 this.clearCandidates_(); 1606 this.clearCandidates_();
1409 this.container_.cleanStroke(); 1607 this.container_.cleanStroke();
1410 this.model_.stateManager.reset(); 1608 this.model_.stateManager.reset();
1411 this.container_.update(); 1609 this.container_.update();
1412 this.updateContextModifierState_(); 1610 this.updateContextModifierState_();
1413 this.resize(); 1611 this.resize();
1414 this.container_.expandedCandidateView.close(); 1612 this.container_.expandedCandidateView.close();
1415 this.container_.menuView.hide(); 1613 this.container_.menuView.hide();
1416 this.container_.swipeView.reset(); 1614 this.container_.swipeView.reset();
1417 this.container_.altDataView.hide(); 1615 this.container_.altDataView.hide();
1616 this.container_.gesturePreviewView.hide();
1617 if (this.container_.floatingView) {
1618 this.container_.floatingView.hide();
1619 }
1418 }; 1620 };
1419 1621
1420 1622
1421 /** 1623 /**
1422 * Returns whether the toolbar should be shown. 1624 * Returns whether the toolbar should be shown.
1423 * 1625 *
1424 * @return {boolean} 1626 * @return {boolean}
1425 * @private 1627 * @private
1426 */ 1628 */
1427 Controller.prototype.shouldShowToolBar_ = function() { 1629 Controller.prototype.shouldShowToolBar_ = function() {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 */ 1767 */
1566 Controller.prototype.onCandidatesBack_ = function(e) { 1768 Controller.prototype.onCandidatesBack_ = function(e) {
1567 this.candidatesInfo_ = new i18n.input.chrome.inputview.CandidatesInfo( 1769 this.candidatesInfo_ = new i18n.input.chrome.inputview.CandidatesInfo(
1568 e.source, e.candidates); 1770 e.source, e.candidates);
1569 this.showCandidates_(e.source, e.candidates, Controller.CandidatesOperation. 1771 this.showCandidates_(e.source, e.candidates, Controller.CandidatesOperation.
1570 NONE); 1772 NONE);
1571 }; 1773 };
1572 1774
1573 1775
1574 /** 1776 /**
1777 * Callback for gestures results event.
1778 *
1779 * @param {!i18n.input.chrome.DataSource.GesturesBackEvent} e .
1780 * @private
1781 */
1782 Controller.prototype.onGesturesBack_ = function(e) {
1783 if (!this.commitNextGestureResult_ &&
1784 goog.array.equals(e.results, this.gestureResultsCache_)) {
1785 // If gesture results have not updated, do not transmit to the UI.
1786 return;
1787 } else {
1788 this.gestureResultsCache_ = e.results;
1789 }
1790 var bestResult = e.results[0];
1791 if (this.container_.gesturePreviewView) {
1792 this.container_.gesturePreviewView.show(bestResult);
1793 }
1794 // TODO: Resolve a race where multiple decoder results return after this flag
1795 // is set to true.
1796 if (this.commitNextGestureResult_) {
1797 // Commit the best result.
1798 this.adapter_.commitGestureResult(bestResult);
1799 this.commitNextGestureResult_ = false;
1800 this.gestureResultsCache_ = [];
1801 }
1802 this.showGestureCandidates_(e.results.slice(1));
1803 };
1804
1805
1806 /**
1807 * Shows the gesture results as candidates.
1808 *
1809 * @param {!Array<string>} results The gesture results to show.
1810 * @private
1811 */
1812 Controller.prototype.showGestureCandidates_ = function(results) {
1813 // Convert the results to the candidate format.
1814 var candidates = [];
1815 for (var i = 0; i < results.length; ++i) {
1816 var candidate = {};
1817 candidate[Name.CANDIDATE] = results[i];
1818 candidate[Name.CANDIDATE_ID] = i;
1819 candidate[Name.IS_EMOJI] = false;
1820 candidate[Name.MATCHED_LENGTHS] = 0;
1821 candidates.push(candidate);
1822 }
1823 // The source is empty as this is a gesture and not a series of key presses.
1824 this.showCandidates_('', candidates, Controller.CandidatesOperation.NONE);
1825 };
1826
1827
1828 /**
1575 * Shows the candidates to the candidate view. 1829 * Shows the candidates to the candidate view.
1576 * 1830 *
1577 * @param {string} source The source text. 1831 * @param {string} source The source text.
1578 * @param {!Array.<!Object>} candidates The candidate text list. 1832 * @param {!Array.<!Object>} candidates The candidate text list.
1579 * @param {Controller.CandidatesOperation} operation . 1833 * @param {Controller.CandidatesOperation} operation .
1580 * @private 1834 * @private
1581 */ 1835 */
1582 Controller.prototype.showCandidates_ = function(source, candidates, 1836 Controller.prototype.showCandidates_ = function(source, candidates,
1583 operation) { 1837 operation) {
1584 var state = !!source ? ExpandedCandidateView.State.COMPLETION_CORRECTION : 1838 var state = !!source ? ExpandedCandidateView.State.COMPLETION_CORRECTION :
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 this.container_.candidateView.clearCandidates(); 1896 this.container_.candidateView.clearCandidates();
1643 this.container_.expandedCandidateView.close(); 1897 this.container_.expandedCandidateView.close();
1644 this.container_.expandedCandidateView.state = ExpandedCandidateView.State. 1898 this.container_.expandedCandidateView.state = ExpandedCandidateView.State.
1645 NONE; 1899 NONE;
1646 if (this.container_.currentKeysetView) { 1900 if (this.container_.currentKeysetView) {
1647 this.container_.currentKeysetView.setVisible(true); 1901 this.container_.currentKeysetView.setVisible(true);
1648 } 1902 }
1649 1903
1650 if (this.currentKeyset_ == Controller.HANDWRITING_VIEW_CODE_ || 1904 if (this.currentKeyset_ == Controller.HANDWRITING_VIEW_CODE_ ||
1651 this.currentKeyset_ == Controller.EMOJI_VIEW_CODE_) { 1905 this.currentKeyset_ == Controller.EMOJI_VIEW_CODE_) {
1652 if (!this.adapter_.isQPInputView) { 1906 this.container_.candidateView.switchToIcon(
1653 this.container_.candidateView.switchToIcon( 1907 CandidateView.IconType.VOICE, false);
1654 CandidateView.IconType.BACK, true); 1908 this.container_.candidateView.switchToIcon(
1655 } else { 1909 CandidateView.IconType.EXPAND_CANDIDATES, false);
1656 this.container_.candidateView.switchToIcon(
1657 CandidateView.IconType.VOICE, false);
1658 this.container_.candidateView.switchToIcon(
1659 CandidateView.IconType.EXPAND_CANDIDATES, false);
1660 }
1661 } else { 1910 } else {
1662 this.container_.candidateView.switchToIcon(CandidateView.IconType.VOICE, 1911 this.container_.candidateView.switchToIcon(CandidateView.IconType.VOICE,
1663 this.adapter_.isVoiceInputEnabled); 1912 this.adapter_.isVoiceInputEnabled);
1664 } 1913 }
1665 }; 1914 };
1666 1915
1667 1916
1668 /** 1917 /**
1669 * Callback when the layout is loaded. 1918 * Callback when the layout is loaded.
1670 * 1919 *
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1781 this.statistics_.recordLayout(keyset, this.adapter_.isA11yMode); 2030 this.statistics_.recordLayout(keyset, this.adapter_.isA11yMode);
1782 this.perfTracker_.tick(PerfTracker.TickName.KEYBOARD_SHOWN); 2031 this.perfTracker_.tick(PerfTracker.TickName.KEYBOARD_SHOWN);
1783 this.perfTracker_.stop(); 2032 this.perfTracker_.stop();
1784 } else { 2033 } else {
1785 // Sets the current keyset for delay switching. 2034 // Sets the current keyset for delay switching.
1786 this.currentKeyset_ = keyset; 2035 this.currentKeyset_ = keyset;
1787 if (keyset != Controller.EMOJI_VIEW_CODE_) { // Emoji is temp keyset. 2036 if (keyset != Controller.EMOJI_VIEW_CODE_) { // Emoji is temp keyset.
1788 this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] = 2037 this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] =
1789 keyset; 2038 keyset;
1790 } 2039 }
1791 if (this.adapter_.isQPInputView && 2040 this.loadResource_(keyset);
1792 goog.array.contains(Controller.MATERIAL_KEYSETS_, keyset)) {
1793 this.loadResource_('m-' + keyset);
1794 } else {
1795 this.loadResource_(keyset);
1796 }
1797 } 2041 }
2042
2043 // 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.
2045 this.isKeysetUSCompact_ =
2046 this.currentKeyset_.indexOf(Controller.US_COMPACT_PREFIX_) >= 0;
2047 // If we're switching to a new keyset, we don't want spacebar to trigger
2048 // another keyset switch.
2049 this.returnToLetterKeysetOnSpace_ = false;
1798 }; 2050 };
1799 2051
1800 2052
1801 /** 2053 /**
1802 * Callback when the configuration is loaded. 2054 * Callback when the configuration is loaded.
1803 * 2055 *
1804 * @param {!i18n.input.chrome.inputview.events.ConfigLoadedEvent} e The event. 2056 * @param {!i18n.input.chrome.inputview.events.ConfigLoadedEvent} e The event.
1805 * @private 2057 * @private
1806 */ 2058 */
1807 Controller.prototype.onConfigLoaded_ = function(e) { 2059 Controller.prototype.onConfigLoaded_ = function(e) {
1808 if (this.isDisposed()) { 2060 if (this.isDisposed()) {
1809 return; 2061 return;
1810 } 2062 }
1811 var data = e.data; 2063 var data = e.data;
1812 var keyboardCode = data[i18n.input.chrome.inputview.SpecNodeName.ID]; 2064 var keyboardCode = data[i18n.input.chrome.inputview.SpecNodeName.ID];
1813 this.keysetDataMap_[keyboardCode] = data; 2065 this.keysetDataMap_[keyboardCode] = data;
1814 this.perfTracker_.tick(PerfTracker.TickName.KEYSET_LOADED); 2066 this.perfTracker_.tick(PerfTracker.TickName.KEYSET_LOADED);
1815 var context = data[i18n.input.chrome.inputview.SpecNodeName.ON_CONTEXT]; 2067 var context = data[i18n.input.chrome.inputview.SpecNodeName.ON_CONTEXT];
1816 if (context && !this.adapter_.isA11yMode) { 2068 if (context && !this.adapter_.isA11yMode) {
1817 var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; 2069 var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_];
1818 if (!keySetMap) { 2070 if (!keySetMap) {
1819 keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {}; 2071 keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {};
1820 } 2072 }
1821 keySetMap[context] = keyboardCode; 2073 keySetMap[context] = keyboardCode;
1822 } 2074 }
1823 2075
1824 var layoutId = data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT]; 2076 var layoutId = data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT];
1825 if (this.adapter_.isQPInputView) { 2077 data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT] = layoutId;
1826 layoutId = 'm-' + layoutId;
1827 data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT] = layoutId;
1828 }
1829 var layoutData = this.layoutDataMap_[layoutId]; 2078 var layoutData = this.layoutDataMap_[layoutId];
1830 if (layoutData) { 2079 if (layoutData) {
1831 this.maybeCreateViews_(); 2080 this.maybeCreateViews_();
1832 } else { 2081 } else {
1833 this.model_.loadLayout(layoutId); 2082 this.model_.loadLayout(layoutId);
1834 } 2083 }
1835 }; 2084 };
1836 2085
1837 2086
1838 /** 2087 /**
1839 * Resizes the whole UI. 2088 * Resizes the whole UI.
1840 * 2089 *
1841 * @param {boolean=} opt_ignoreWindowResize . 2090 * @param {boolean=} opt_preventResizeTo True if prevent calling
2091 * window.resizeTo. Used in tests and local UI debug.
1842 */ 2092 */
1843 Controller.prototype.resize = function(opt_ignoreWindowResize) { 2093 Controller.prototype.resize = function(opt_preventResizeTo) {
1844 var height; 2094 var height;
2095 var width;
1845 var widthPercent; 2096 var widthPercent;
1846 var candidateViewHeight; 2097 var candidateViewHeight;
1847 var isLandScape = screen.width > screen.height; 2098 var isLandScape = screen.width > screen.height;
1848 if (isLandScape) { 2099 if (isLandScape) {
1849 goog.dom.classlist.addRemove(this.container_.getElement(), 2100 goog.dom.classlist.addRemove(this.container_.getElement(),
1850 Css.PORTRAIT, Css.LANDSCAPE); 2101 Css.PORTRAIT, Css.LANDSCAPE);
1851 } else { 2102 } else {
1852 goog.dom.classlist.addRemove(this.container_.getElement(), 2103 goog.dom.classlist.addRemove(this.container_.getElement(),
1853 Css.LANDSCAPE, Css.PORTRAIT); 2104 Css.LANDSCAPE, Css.PORTRAIT);
1854 } 2105 }
(...skipping 17 matching lines...) Expand all
1872 if (isWideScreen) { 2123 if (isWideScreen) {
1873 widthPercent = spec['LANDSCAPE_WIDE_SCREEN']; 2124 widthPercent = spec['LANDSCAPE_WIDE_SCREEN'];
1874 } else { 2125 } else {
1875 widthPercent = spec['LANDSCAPE']; 2126 widthPercent = spec['LANDSCAPE'];
1876 } 2127 }
1877 } else { 2128 } else {
1878 widthPercent = spec['PORTRAIT']; 2129 widthPercent = spec['PORTRAIT'];
1879 } 2130 }
1880 candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT; 2131 candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT;
1881 } 2132 }
2133 width = this.adapter_.isFloating ?
2134 Math.floor(screen.width * widthPercent) : screen.width;
2135 widthPercent = this.adapter_.isFloating ? 1.0 : widthPercent;
2136 if (goog.dom.classlist.contains(this.container_.getElement(), Css.SMALL)) {
2137 height = SizeSpec.SMALL_SIZE_HEIGHT;
2138 width = SizeSpec.SMALL_SIZE_WIDTH;
2139 candidateViewHeight = SizeSpec.SMALL_SIZE_CANDIDATE_VIEW_HEIGHT;
2140 }
1882 2141
1883 if (window.innerHeight != height && !opt_ignoreWindowResize) { 2142 if ((window.innerHeight != height || window.innerWidth != width) &&
1884 if (this.lastResizeHeight_ != height) { 2143 !opt_preventResizeTo) {
2144 if (this.lastResizeHeight_ != height || window.innerWidth != width) {
1885 this.lastResizeHeight_ = height; 2145 this.lastResizeHeight_ = height;
1886 window.resizeTo(screen.width, height); 2146 window.resizeTo(width, height);
1887 } 2147 }
1888 return; 2148 return;
1889 } 2149 }
1890 2150
1891 this.container_.setContainerSize(screen.width, height, widthPercent, 2151 this.container_.setContainerSize(width, height, widthPercent,
1892 candidateViewHeight); 2152 candidateViewHeight);
1893 this.container_.candidateView.setToolbarVisible(this.shouldShowToolBar_()); 2153 this.container_.candidateView.setToolbarVisible(this.shouldShowToolBar_());
1894 if (this.container_.currentKeysetView) { 2154 if (this.container_.currentKeysetView) {
1895 this.isKeyboardReady = true; 2155 this.isKeyboardReady = true;
1896 } 2156 }
2157
2158 // Transmit the new layout to the decoder.
2159 if (this.gestureTypingEnabled_()) {
2160 this.adapter_.sendKeyboardLayout(
2161 this.container_.currentKeysetView.getKeyboardLayoutForGesture());
2162 }
1897 }; 2163 };
1898 2164
1899 2165
1900 /** 2166 /**
1901 * Loads the resources, for currentKeyset, passwdKeyset, handwriting, 2167 * Loads the resources, for currentKeyset, passwdKeyset, handwriting,
1902 * emoji, etc. 2168 * emoji, etc.
1903 * 2169 *
1904 * @private 2170 * @private
1905 */ 2171 */
1906 Controller.prototype.loadAllResources_ = function() { 2172 Controller.prototype.loadAllResources_ = function() {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 title) { 2235 title) {
1970 this.perfTracker_.restart(); 2236 this.perfTracker_.restart();
1971 this.adapter_.getCurrentInputMethod(function(currentInputMethod) { 2237 this.adapter_.getCurrentInputMethod(function(currentInputMethod) {
1972 // TODO: remove this hack as soon as the manifest is fixed in chromium. 2238 // TODO: remove this hack as soon as the manifest is fixed in chromium.
1973 if (languageCode == 'ko') { 2239 if (languageCode == 'ko') {
1974 if (currentInputMethod.indexOf('hangul_2set') > 0) { 2240 if (currentInputMethod.indexOf('hangul_2set') > 0) {
1975 keyset = 'm17n:ko_2set'; 2241 keyset = 'm17n:ko_2set';
1976 } 2242 }
1977 } 2243 }
1978 this.languageCode_ = languageCode; 2244 this.languageCode_ = languageCode;
1979 this.currentInputMethod_ = currentInputMethod; 2245 // If can't get the current input method, set the original keyset as
2246 // current input method.
2247 this.currentInputMethod_ = currentInputMethod || keyset;
1980 var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; 2248 var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_];
1981 if (!keySetMap) { 2249 if (!keySetMap) {
1982 keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {}; 2250 keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {};
1983 } 2251 }
1984 keySetMap[ContextType.PASSWORD] = passwordLayout; 2252 keySetMap[ContextType.PASSWORD] = passwordLayout;
1985 keySetMap[ContextType.DEFAULT] = keyset; 2253 keySetMap[ContextType.DEFAULT] = keyset;
1986 2254
1987 this.initialKeyset_ = keyset; 2255 this.initialKeyset_ = keyset;
1988 this.title_ = title; 2256 this.title_ = title;
1989 this.isSettingReady = false; 2257 this.isSettingReady = false;
1990 this.model_.settings = new i18n.input.chrome.inputview.Settings(); 2258 this.model_.settings = new i18n.input.chrome.inputview.Settings();
1991 this.model_.stateManager.isEnMode = false; 2259 this.model_.stateManager.isEnMode = false;
1992 this.adapter_.initialize(languageCode ? languageCode.split('-')[0] : ''); 2260 this.adapter_.initialize();
1993 this.loadAllResources_(); 2261 this.loadAllResources_();
1994 this.switchToKeyset(this.getActiveKeyset_()); 2262 this.switchToKeyset(this.getActiveKeyset_());
1995 2263
1996 // Set language attribute and font of body. 2264 // Set language attribute and font of body.
1997 document.body.setAttribute('lang', this.languageCode_); 2265 document.body.setAttribute('lang', this.languageCode_);
1998 goog.dom.classlist.add(document.body, Css.FONT); 2266 goog.dom.classlist.add(document.body, Css.FONT);
1999 }.bind(this)); 2267 }.bind(this));
2000 }; 2268 };
2001 2269
2002 2270
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 this.statsForClosing_[name][0] += count; 2384 this.statsForClosing_[name][0] += count;
2117 this.statsForClosing_[name][1] = max; 2385 this.statsForClosing_[name][1] = max;
2118 this.statsForClosing_[name][2] = bucketCount; 2386 this.statsForClosing_[name][2] = bucketCount;
2119 } 2387 }
2120 }; 2388 };
2121 2389
2122 2390
2123 /** 2391 /**
2124 * Handles language state changing event. 2392 * Handles language state changing event.
2125 * 2393 *
2126 * @param {!i18n.input.chrome.message.Event} e . 2394 * @param {!events.MessageEvent} e .
2127 * @private 2395 * @private
2128 */ 2396 */
2129 Controller.prototype.onUpdateToggleLanguateState_ = function(e) { 2397 Controller.prototype.onUpdateToggleLanguageState_ = function(e) {
2130 if (this.adapter_.isA11yMode || this.currentKeyset_.indexOf('.compact') < 0) { 2398 if (this.adapter_.isA11yMode || this.currentKeyset_.indexOf('.compact') < 0) {
2131 // e.msg value means whether is Chinese mode now. 2399 // e.msg value means whether is Chinese mode now.
2132 if (this.model_.stateManager.isEnMode == e.msg) { 2400 if (this.model_.stateManager.isEnMode == e.msg) {
2133 this.model_.stateManager.isEnMode = !e.msg; 2401 this.model_.stateManager.isEnMode = !e.msg;
2134 this.container_.currentKeysetView.update(); 2402 this.container_.currentKeysetView.update();
2135 } 2403 }
2136 } else { 2404 } else {
2137 var pos = this.currentKeyset_.indexOf('en.compact'); 2405 var pos = this.currentKeyset_.indexOf('en.compact');
2138 var toKeyset; 2406 var toKeyset;
2139 if (pos > 0) { // Means en mode 2407 if (pos > 0) { // Means en mode
2140 if (e.msg) { // Needs switch cn mode 2408 if (e.msg) { // Needs switch cn mode
2141 toKeyset = this.currentKeyset_.replace('en.compact', 'compact'); 2409 toKeyset = this.currentKeyset_.replace('en.compact', 'compact');
2142 } 2410 }
2143 } else { 2411 } else {
2144 if (!e.msg) { // Needs switch en mode 2412 if (!e.msg) { // Needs switch en mode
2145 toKeyset = this.currentKeyset_.replace('compact', 'en.compact'); 2413 toKeyset = this.currentKeyset_.replace('compact', 'en.compact');
2146 } 2414 }
2147 } 2415 }
2148 if (toKeyset) { 2416 if (toKeyset) {
2149 this.resetAll(); 2417 this.resetAll();
2150 this.switchToKeyset(toKeyset); 2418 this.switchToKeyset(toKeyset);
2151 } 2419 }
2152 } 2420 }
2153 }; 2421 };
2154 }); // goog.scope 2422 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698