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

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

Issue 1576613002: Update Google Input Tools. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing APIs, remove bade dependencies. Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: third_party/google_input_tools/src/chrome/os/inputview/controller.js
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/controller.js b/third_party/google_input_tools/src/chrome/os/inputview/controller.js
index 9c4d6ce0d9257ed2e216e19a5b2636c7ff44e3ac..3c52b078ddb6232dc123c5ffb94fd008487eb936 100644
--- a/third_party/google_input_tools/src/chrome/os/inputview/controller.js
+++ b/third_party/google_input_tools/src/chrome/os/inputview/controller.js
@@ -22,15 +22,19 @@ goog.require('goog.events.Event');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventType');
goog.require('goog.events.KeyCodes');
+goog.require('goog.fx.easing');
goog.require('goog.i18n.bidi');
+goog.require('goog.math.Coordinate');
goog.require('goog.object');
goog.require('i18n.input.chrome.DataSource');
+goog.require('i18n.input.chrome.ElementType');
+goog.require('i18n.input.chrome.FeatureName');
goog.require('i18n.input.chrome.Statistics');
+goog.require('i18n.input.chrome.events.KeyCodes');
goog.require('i18n.input.chrome.inputview.Adapter');
goog.require('i18n.input.chrome.inputview.CandidatesInfo');
goog.require('i18n.input.chrome.inputview.ConditionName');
goog.require('i18n.input.chrome.inputview.Css');
-goog.require('i18n.input.chrome.inputview.FeatureName');
goog.require('i18n.input.chrome.inputview.KeyboardContainer');
goog.require('i18n.input.chrome.inputview.M17nModel');
goog.require('i18n.input.chrome.inputview.Model');
@@ -41,13 +45,11 @@ goog.require('i18n.input.chrome.inputview.SizeSpec');
goog.require('i18n.input.chrome.inputview.SpecNodeName');
goog.require('i18n.input.chrome.inputview.StateType');
goog.require('i18n.input.chrome.inputview.SwipeDirection');
-goog.require('i18n.input.chrome.inputview.elements.ElementType');
goog.require('i18n.input.chrome.inputview.elements.content.Candidate');
goog.require('i18n.input.chrome.inputview.elements.content.CandidateView');
goog.require('i18n.input.chrome.inputview.elements.content.ExpandedCandidateView');
goog.require('i18n.input.chrome.inputview.elements.content.MenuView');
goog.require('i18n.input.chrome.inputview.events.EventType');
-goog.require('i18n.input.chrome.inputview.events.KeyCodes');
goog.require('i18n.input.chrome.inputview.handler.PointerHandler');
goog.require('i18n.input.chrome.inputview.util');
goog.require('i18n.input.chrome.message.ContextType');
@@ -64,13 +66,13 @@ var CandidateView = i18n.input.chrome.inputview.elements.content.CandidateView;
var ConditionName = i18n.input.chrome.inputview.ConditionName;
var ContextType = i18n.input.chrome.message.ContextType;
var Css = i18n.input.chrome.inputview.Css;
-var ElementType = i18n.input.chrome.inputview.elements.ElementType;
+var ElementType = i18n.input.chrome.ElementType;
var EventType = i18n.input.chrome.inputview.events.EventType;
var ExpandedCandidateView = i18n.input.chrome.inputview.elements.content.
ExpandedCandidateView;
-var FeatureName = i18n.input.chrome.inputview.FeatureName;
+var FeatureName = i18n.input.chrome.FeatureName;
var InputToolCode = i18n.input.lang.InputToolCode;
-var KeyCodes = i18n.input.chrome.inputview.events.KeyCodes;
+var KeyCodes = i18n.input.chrome.events.KeyCodes;
var MenuView = i18n.input.chrome.inputview.elements.content.MenuView;
var Name = i18n.input.chrome.message.Name;
var PerfTracker = i18n.input.chrome.inputview.PerfTracker;
@@ -83,6 +85,62 @@ var events = i18n.input.chrome.inputview.events;
var util = i18n.input.chrome.inputview.util;
+/**
+ * Time in milliseconds after which backspace will start autorepeating.
+ * @const {number}
+ */
+var BACKSPACE_REPEAT_START_TIME_MS = 300;
+
+
+/**
+ * Minimum time, in milliseconds, after which backspace can repeat. This
+ * prevents deleting entire pages in a go.
+ * @const {number}
+ */
+var MINIMUM_BACKSPACE_REPEAT_TIME_MS = 25;
+
+
+/**
+ * Maximum time, in milliseconds, after which the backspace can repeat.
+ * @const {number}
+ */
+var MAXIMUM_BACKSPACE_REPEAT_TIME_MS = 75;
+
+
+/**
+ * The limit for backspace repeat for speeding up.
+ * The backspace repeat beyond this limit will have the maximum speed.
+ * @const {number}
+ */
+var BACKSPACE_REPEAT_LIMIT = 255;
+
+
+/**
+ * The time, in milliseconds, that the gesture preview window lingers before
+ * being dismissed.
+ *
+ * @const {number}
+ */
+var GESTURE_PREVIEW_LINGER_TIME_MS = 250;
+
+
+/**
+ * The maximum distance from the top of the keyboard that a gesture can move
+ * before it cancels the gesture typing gesture.
+ *
+ * @const {number}
+ */
+var MAXIMUM_DISTANCE_FROM_TOP_FOR_GESTURES = 40;
+
+
+/**
+ * The hotrod customized layout code.
+ *
+ * @const {string}
+ */
+var HOTROD_DEFAULT_KEYSET = 'hotrod';
+
+
/**
* The controller of the input view keyboard.
@@ -184,11 +242,11 @@ i18n.input.chrome.inputview.Controller = function(keyset, languageCode,
this.soundController_ = new SoundController(false);
/**
- * Whether or not to commit the next gesture result.
+ * Whether or not the candidates were last set by gesture typing.
*
* @private {boolean}
*/
- this.commitNextGestureResult_ = false;
+ this.candidatesSetByGestureTyping_ = false;
/** @private {!i18n.input.chrome.inputview.KeyboardContainer} */
this.container_ = new i18n.input.chrome.inputview.KeyboardContainer(
@@ -256,9 +314,15 @@ i18n.input.chrome.inputview.Controller = function(keyset, languageCode,
this.registerEventHandler_();
};
-goog.inherits(i18n.input.chrome.inputview.Controller,
- goog.Disposable);
+goog.inherits(i18n.input.chrome.inputview.Controller, goog.Disposable);
var Controller = i18n.input.chrome.inputview.Controller;
+var Statistics = i18n.input.chrome.Statistics;
+
+/**
+ * @define {boolean} Flag to disable delayed loading of non active keyset. It
+ * should only be used in testing.
+ */
+Controller.DISABLE_DELAY_LOADING_FOR_TEST = false;
/**
@@ -300,15 +364,6 @@ Controller.EMOJI_VIEW_CODE_ = 'emoji';
/**
- * The limitation for backspace repeat time to avoid unexpected
- * problem that backspace is held all the time.
- *
- * @private {number}
- */
-Controller.BACKSPACE_REPEAT_LIMIT_ = 255;
-
-
-/**
* The repeated times of the backspace.
*
* @private {number}
@@ -326,12 +381,12 @@ Controller.HANDWRITING_CODE_SUFFIX_ = '-t-i0-handwrit';
/**
- * The US English compact layout prefix.
+ * The US English compact layout qwerty code.
*
* @const {string}
* @private
*/
-Controller.US_COMPACT_PREFIX_ = 'us.compact';
+Controller.US_COMPACT_QWERTY_CODE_ = 'us.compact.qwerty';
/**
@@ -617,7 +672,9 @@ Controller.prototype.onUpdateSettings_ = function(e) {
}
if (goog.isDef(e.msg['gestureEditing'])) {
settings.gestureEditing = e.msg['gestureEditing'];
- var enabled = settings.gestureEditing && !this.adapter_.isA11yMode;
+ var enabled = settings.gestureEditing && !this.adapter_.isA11yMode &&
+ !this.adapter_.isHotrod &&
+ !this.adapter_.isFloatingVirtualKeyboardEnabled();
this.container_.swipeView.enabled = enabled;
this.container_.selectView.setSettingsEnabled(enabled);
}
@@ -661,20 +718,19 @@ Controller.prototype.onSettingsReady_ = function() {
var newKeyset = '';
if (this.adapter_.isA11yMode) {
newKeyset = util.getConfigName(keysetMap[ContextType.DEFAULT]);
+ } else if (this.adapter_.isHotrod) {
+ newKeyset = HOTROD_DEFAULT_KEYSET;
} else {
newKeyset = /** @type {string} */ (this.model_.settings.
getPreference(util.getConfigName(keysetMap[ContextType.DEFAULT])));
}
- if (!this.adapter_.features.isEnabled(FeatureName.EXPERIMENTAL) &&
- keysetMap[ContextType.DEFAULT] ==
- 'zhuyin.compact.qwerty') {
- newKeyset = 'zhuyin';
- }
+
if (newKeyset) {
this.setDefaultKeyset_(newKeyset);
}
this.container_.selectView.setSettingsEnabled(
- this.model_.settings.gestureEditing && !this.adapter_.isA11yMode);
+ this.model_.settings.gestureEditing && !this.adapter_.isA11yMode &&
+ !this.adapter_.isHotrod);
// Loads resources in case the default keyset is changed.
this.loadAllResources_();
this.maybeCreateViews_();
@@ -689,7 +745,13 @@ Controller.prototype.onSettingsReady_ = function() {
*/
Controller.prototype.gestureTypingEnabled_ = function() {
return this.isKeysetUSCompact_ && this.model_.settings.gestureTyping &&
- !this.adapter_.isA11yMode && !this.adapter_.isChromeVoxOn;
+ !this.adapter_.isA11yMode && !this.adapter_.isHotrod &&
+ !this.adapter_.isChromeVoxOn &&
+ !this.adapter_.isPasswordBox() &&
+ !this.adapter_.isFloatingVirtualKeyboardEnabled() &&
+ !this.container_.altDataView.isVisible() &&
+ !this.container_.menuView.isVisible() &&
+ !this.container_.voiceView.isVisible();
};
@@ -748,13 +810,13 @@ Controller.prototype.getSpatialData_ = function(key, x, y) {
* @private
*/
Controller.prototype.getKeyContent_ = function(key) {
- if (key.type == i18n.input.chrome.inputview.elements.ElementType.
+ if (key.type == i18n.input.chrome.ElementType.
CHARACTER_KEY) {
key = /** @type {!i18n.input.chrome.inputview.elements.content.
CharacterKey} */ (key);
return key.getActiveCharacter();
}
- if (key.type == i18n.input.chrome.inputview.elements.ElementType.
+ if (key.type == i18n.input.chrome.ElementType.
COMPACT_KEY) {
key = /** @type {!i18n.input.chrome.inputview.elements.content.
FunctionalKey} */ (key);
@@ -833,7 +895,7 @@ Controller.prototype.maybeSendLastStroke_ = function(opt_force) {
if (lastStroke) {
// This call will set up the necessary callbacks the decoder will use to
// communicate back to this class.
- this.adapter_.sendGestureEvent(lastStroke.points);
+ this.adapter_.sendGestureEvent(lastStroke.getPoints());
}
};
@@ -848,13 +910,30 @@ Controller.prototype.maybeSendLastStroke_ = function(opt_force) {
Controller.prototype.onDragEvent_ = function(e) {
if (this.gestureTypingEnabled_() && e.type == EventType.DRAG &&
!this.container_.swipeView.isVisible()) {
+ // Conveniently, the DragEvent has coordinates relative to the gesture
+ // canvas view, so we can test it's y coordinate in order to determine if
+ // we're off the canvas.
+ if (e.y + MAXIMUM_DISTANCE_FROM_TOP_FOR_GESTURES < 0) {
+ this.container_.gestureCanvasView.clear();
+ this.container_.gesturePreviewWindow.hide();
+ this.clearCandidates_();
+ return;
+ }
this.container_.gestureCanvasView.addPoint(e);
if (e.view && this.container_.gestureCanvasView.isGesturing) {
// Ensure the last touched key is not highlighted.
- e.view.setHighlighted(false);
+ if (e.view.type != ElementType.MODIFIER_KEY) {
+ e.view.setHighlighted(false);
+ }
this.maybeSendLastStroke_();
+ // Reposition the gesture preview window to follow the user's touch point.
+ if (this.container_.gesturePreviewWindow &&
+ this.container_.gestureCanvasView.isActiveIdentifier(
+ e.identifier)) {
+ this.container_.gesturePreviewWindow.reposition(
+ new goog.math.Coordinate(e.x, e.y));
+ }
}
- return;
}
};
@@ -949,29 +1028,29 @@ Controller.prototype.executeCommand_ = function(command, opt_arg) {
inputview.openSettings();
}
break;
+ }
+};
- case CommandEnum.FLOATING:
- if (inputview.setMode) {
- inputview.setMode('FLOATING');
- this.adapter_.isFloating = true;
- this.container_.candidateView.setFloatingVKButtonsVisible(true);
- this.resize();
- setTimeout(function() {
- var x = Math.floor((screen.width - window.innerWidth) / 2);
- window.moveTo(x, window.screenY);
- }, 0);
- }
- break;
-
- case CommandEnum.DOCKING:
- if (inputview.setMode) {
- inputview.setMode('FULL_WIDTH');
- this.adapter_.isFloating = false;
- this.container_.candidateView.setFloatingVKButtonsVisible(false);
- }
- break;
+/**
+ * Returns the gesture typing event type for a given candidate ID.
+ *
+ * @param {number} candidateID The candidate ID to convert.
+ * @return {?i18n.input.chrome.Statistics.GestureTypingEvent} The gesture
+ * typing event type for the given candidate. Null if the candidate was not
+ * found.
+ * @private
+ */
+Controller.prototype.getGestureEventTypeForCandidateID_ =
+ function(candidateID) {
+ if (candidateID == 0) {
+ return Statistics.GestureTypingEvent.REPLACED_0;
+ } else if (candidateID == 1) {
+ return Statistics.GestureTypingEvent.REPLACED_1;
+ } else if (candidateID >= 2) {
+ return Statistics.GestureTypingEvent.REPLACED_2;
}
+ return null;
};
@@ -985,8 +1064,12 @@ Controller.prototype.executeCommand_ = function(command, opt_arg) {
Controller.prototype.handlePointerAction_ = function(view, e) {
if (this.gestureTypingEnabled_() && !this.container_.swipeView.isVisible()) {
if (e.type == EventType.POINTER_DOWN) {
+ // Do some clean up before starting a new stroke.
+ this.container_.gestureCanvasView.removeEmptyStrokes();
this.container_.gestureCanvasView.startStroke(e);
- view.setHighlighted(false);
+ if (view.type != ElementType.MODIFIER_KEY) {
+ view.setHighlighted(false);
+ }
}
// Determine if the gestureCanvasView was handling a gesture before calling
@@ -995,12 +1078,13 @@ Controller.prototype.handlePointerAction_ = function(view, e) {
if (e.type == EventType.POINTER_UP && wasGesturing) {
this.container_.gestureCanvasView.endStroke(e);
this.maybeSendLastStroke_(true);
- this.commitNextGestureResult_ = true;
}
// Do not trigger other activities when gesturing.
if (wasGesturing) {
- if (e.type == EventType.POINTER_OVER) {
+ if (view.type != ElementType.MODIFIER_KEY &&
+ (e.type == EventType.POINTER_OVER ||
+ e.type == EventType.POINTER_OUT)) {
view.setHighlighted(false);
}
return;
@@ -1018,19 +1102,13 @@ Controller.prototype.handlePointerAction_ = function(view, e) {
this.handleSwipeAction_(view, e);
}
switch (view.type) {
- case ElementType.KEYBOARD_CONTAINER_VIEW:
- if (e.type == EventType.POINTER_DOWN) {
- var tabbableKeysets = [
- Controller.HANDWRITING_VIEW_CODE_,
- Controller.EMOJI_VIEW_CODE_];
- if (goog.array.contains(tabbableKeysets, this.currentKeyset_)) {
- this.resetAll();
- this.switchToKeyset(this.container_.currentKeysetView.fromKeyset);
- }
- }
- return;
+ case ElementType.HOTROD_SWITCHER_KEY:
case ElementType.BACK_BUTTON:
case ElementType.BACK_TO_KEYBOARD:
+ if (view.type == ElementType.HOTROD_SWITCHER_KEY &&
+ !this.adapter_.isHotrod) {
+ return;
+ }
if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) {
view.setHighlighted(false);
} else if (e.type == EventType.POINTER_DOWN ||
@@ -1038,7 +1116,12 @@ Controller.prototype.handlePointerAction_ = function(view, e) {
view.setHighlighted(true);
}
if (e.type == EventType.POINTER_UP) {
- this.switchToKeyset(this.container_.currentKeysetView.fromKeyset);
+ var backToKeyset = this.container_.currentKeysetView.fromKeyset;
+ if (view.type == ElementType.HOTROD_SWITCHER_KEY &&
+ this.adapter_.isHotrod) {
+ backToKeyset = Controller.US_COMPACT_QWERTY_CODE_;
+ }
+ this.switchToKeyset(backToKeyset);
this.clearCandidates_();
this.soundController_.onKeyUp(view.type);
}
@@ -1067,6 +1150,16 @@ Controller.prototype.handlePointerAction_ = function(view, e) {
if (e.type == EventType.POINTER_UP) {
if (view.candidateType == CandidateType.CANDIDATE) {
this.adapter_.selectCandidate(view.candidate);
+ if (this.candidatesSetByGestureTyping_) {
+ var type = this.getGestureEventTypeForCandidateID_(
+ view.candidate[Name.CANDIDATE_ID]);
+ if (type) {
+ this.statistics_.recordEnum(
+ Statistics.GESTURE_TYPING_METRIC_NAME,
+ type,
+ Statistics.GestureTypingEvent.MAX);
+ }
+ }
} else if (view.candidateType == CandidateType.NUMBER) {
this.adapter_.sendKeyDownAndUpEvent(
view.candidate[Name.CANDIDATE], '');
@@ -1099,6 +1192,10 @@ Controller.prototype.handlePointerAction_ = function(view, e) {
return;
case ElementType.MENU_ITEM:
+ if (this.adapter_.isHotrod) {
+ // Disable menu items in hotrod. Fix this if hotrod needs i18n support.
+ return;
+ }
view = /** @type {!i18n.input.chrome.inputview.elements.content.
MenuItem} */ (view);
if (e.type == EventType.POINTER_UP) {
@@ -1174,12 +1271,6 @@ Controller.prototype.handlePointerAction_ = function(view, e) {
this.container_.floatingView.hide();
}
return;
- case ElementType.RESIZE:
- if (e.type == EventType.POINTER_UP) {
- goog.dom.classlist.toggle(this.container_.getElement(), Css.SMALL);
- this.resize();
- }
- return;
case ElementType.CUT:
case ElementType.COPY:
case ElementType.PASTE:
@@ -1376,7 +1467,9 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) {
EnSwitcherKey} */ (softKey);
this.adapter_.toggleLanguageState(this.model_.stateManager.isEnMode);
this.model_.stateManager.isEnMode = !this.model_.stateManager.isEnMode;
- key.update();
+ if (!this.updateToggleLanguageKeyset_()) {
+ key.update();
+ }
}
break;
case ElementType.SPACE_KEY:
@@ -1398,6 +1491,10 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) {
this.switchToKeyset(key.toKeyset);
this.returnToLetterKeysetOnSpace_ = false;
}
+ var isHwt = Controller.HANDWRITING_VIEW_CODE_ == this.currentKeyset_;
+ if (isHwt) {
+ this.container_.cleanStroke();
+ }
break;
case ElementType.SWITCHER_KEY:
@@ -1436,8 +1533,14 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) {
this.model_.stateManager.triggerChording();
var ch = key.getActiveCharacter();
if (ch.length == 1) {
- this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0,
+ if (this.currentKeyset_.indexOf('symbol') != -1) {
+ this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(),
+ KeyCodes.SYMBOL, 0, this.getSpatialData_(key, e.x, e.y));
+ }
+ else {
+ this.adapter_.sendKeyDownAndUpEvent(key.getActiveCharacter(), '', 0,
this.getSpatialData_(key, e.x, e.y));
+ }
} else if (ch.length > 1) {
// Some compact keys contains more than 1 characters, such as '.com',
// 'http://', etc. Those keys should trigger a direct commit text
@@ -1475,10 +1578,7 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) {
var defaultFullKeyset = this.initialKeyset_.split(/\./)[0];
var enableCompact = !this.adapter_.isA11yMode && goog.array.contains(
util.KEYSETS_HAVE_COMPACT, defaultFullKeyset);
- if (defaultFullKeyset == 'zhuyin' &&
- !this.adapter_.features.isEnabled(FeatureName.EXPERIMENTAL) ||
- this.languageCode_ == 'ko') {
- // Hides 'switch to compact' for zhuyin when not in experimental env.
+ if (this.languageCode_ == 'ko') {
enableCompact = false;
}
var hasHwt = !this.adapter_.isPasswordBox() &&
@@ -1487,12 +1587,10 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) {
var hasEmoji = !this.adapter_.isPasswordBox();
var enableSettings = this.shouldEnableSettings() &&
!!window.inputview && !!inputview.openSettings;
- var enableFVK = this.adapter_.isFloatingVirtualKeyboardEnabled();
this.adapter_.getInputMethods(function(inputMethods) {
this.container_.menuView.show(key, defaultFullKeyset, isCompact,
enableCompact, this.currentInputMethod_, inputMethods, hasHwt,
- enableSettings, hasEmoji, this.adapter_.isA11yMode, enableFVK,
- this.adapter_.isFloating);
+ enableSettings, hasEmoji, this.adapter_.isA11yMode);
}.bind(this));
}
break;
@@ -1560,19 +1658,24 @@ Controller.prototype.stopBackspaceAutoRepeat_ = function() {
* @private
*/
Controller.prototype.backspaceTick_ = function() {
- if (this.backspaceRepeated_ >= Controller.BACKSPACE_REPEAT_LIMIT_) {
- this.stopBackspaceAutoRepeat_();
- return;
- }
this.backspaceRepeated_++;
this.backspaceDown_();
this.soundController_.onKeyRepeat(ElementType.BACKSPACE_KEY);
if (this.backspaceAutoRepeat_) {
- this.backspaceAutoRepeat_.start(75);
+ var delay = MINIMUM_BACKSPACE_REPEAT_TIME_MS;
+ if (this.backspaceRepeated_ <= BACKSPACE_REPEAT_LIMIT) {
+ var ease = goog.fx.easing.easeOut(
+ this.backspaceRepeated_ / BACKSPACE_REPEAT_LIMIT);
+ var delta = MAXIMUM_BACKSPACE_REPEAT_TIME_MS -
+ MINIMUM_BACKSPACE_REPEAT_TIME_MS;
+ delay = MAXIMUM_BACKSPACE_REPEAT_TIME_MS - (delta * ease);
+ }
+ this.backspaceAutoRepeat_.start(delay);
} else {
this.backspaceAutoRepeat_ = new goog.async.Delay(
- goog.bind(this.backspaceTick_, this), 300);
+ goog.bind(this.backspaceTick_, this),
+ BACKSPACE_REPEAT_START_TIME_MS);
this.backspaceAutoRepeat_.start();
}
};
@@ -1613,10 +1716,13 @@ Controller.prototype.resetAll = function() {
this.container_.menuView.hide();
this.container_.swipeView.reset();
this.container_.altDataView.hide();
- this.container_.gesturePreviewView.hide();
+ if (this.container_.gesturePreviewWindow) {
+ this.container_.gesturePreviewWindow.hide();
+ }
if (this.container_.floatingView) {
this.container_.floatingView.hide();
}
+ this.stopBackspaceAutoRepeat_();
};
@@ -1655,10 +1761,10 @@ Controller.prototype.onSurroundingTextChanged_ = function(e) {
if (!this.model_.settings.autoCapital || !e.text) {
return;
}
-
+ var textBeforeCursor = e.textBeforeCursor.replace(/\u00a0/g, ' ');
var isShiftEnabled = this.model_.stateManager.hasState(StateType.SHIFT);
var needAutoCap = this.model_.settings.autoCapital &&
- util.needAutoCap(e.text);
+ util.needAutoCap(textBeforeCursor);
if (needAutoCap && !isShiftEnabled) {
this.changeState_(StateType.SHIFT, true, false);
this.shiftForAutoCapital_ = true;
@@ -1676,6 +1782,7 @@ Controller.prototype.onSurroundingTextChanged_ = function(e) {
Controller.prototype.onContextBlur_ = function() {
this.container_.cleanStroke();
this.container_.menuView.hide();
+ this.stopBackspaceAutoRepeat_();
};
@@ -1696,7 +1803,7 @@ Controller.prototype.backspaceDown_ = function() {
this.statistics_.recordEnum('InputMethod.VirtualKeyboard.BackspaceOnLayout',
this.statistics_.getLayoutType(this.currentKeyset_,
this.adapter_.isA11yMode),
- i18n.input.chrome.Statistics.LayoutTypes.MAX);
+ Statistics.LayoutTypes.MAX);
};
@@ -1774,32 +1881,63 @@ Controller.prototype.onCandidatesBack_ = function(e) {
/**
+ * Converts a word to shifted or all-caps based on the current shift state.
+ *
+ * @param {string} word The word to potentially convert.
+ * @return {string} The converted word.
+ * @private
+ */
+Controller.prototype.convertToShifted_ = function(word) {
+ if (this.model_.stateManager.getState() == StateType.SHIFT) {
+ if (this.model_.stateManager.isSticky(StateType.SHIFT) &&
+ this.model_.stateManager.isFinalSticky(StateType.SHIFT)) {
+ word = word.toUpperCase();
+ } else {
+ word = word.charAt(0).toUpperCase() + word.slice(1);
+ }
+ }
+ return word;
+};
+
+
+/**
* Callback for gestures results event.
*
* @param {!i18n.input.chrome.DataSource.GesturesBackEvent} e .
* @private
*/
Controller.prototype.onGesturesBack_ = function(e) {
- if (!this.commitNextGestureResult_ &&
- goog.array.equals(e.results, this.gestureResultsCache_)) {
+ var response = e.response;
+ this.stopBackspaceAutoRepeat_();
+ if (!response.commit &&
+ goog.array.equals(response.results, this.gestureResultsCache_)) {
// If gesture results have not updated, do not transmit to the UI.
return;
} else {
- this.gestureResultsCache_ = e.results;
+ this.gestureResultsCache_ = response.results;
}
- var bestResult = e.results[0];
- if (this.container_.gesturePreviewView) {
- this.container_.gesturePreviewView.show(bestResult);
+ var bestResult = this.convertToShifted_(response.results[0]);
+ if (this.container_.gesturePreviewWindow &&
+ this.container_.gestureCanvasView.isGesturing) {
+ this.container_.gesturePreviewWindow.show(bestResult);
}
- // TODO: Resolve a race where multiple decoder results return after this flag
- // is set to true.
- if (this.commitNextGestureResult_) {
+ if (response.commit) {
// Commit the best result.
- this.adapter_.commitGestureResult(bestResult);
- this.commitNextGestureResult_ = false;
+ this.adapter_.commitGestureResult(
+ bestResult, this.adapter_.isGoogleDocument());
this.gestureResultsCache_ = [];
+ this.statistics_.recordEnum(
+ Statistics.GESTURE_TYPING_METRIC_NAME,
+ Statistics.GestureTypingEvent.TYPED,
+ Statistics.GestureTypingEvent.MAX);
+ if (this.container_.gesturePreviewWindow) {
+ new goog.async.Delay(
+ goog.bind(this.container_.gesturePreviewWindow.hide,
+ this.container_.gesturePreviewWindow),
+ GESTURE_PREVIEW_LINGER_TIME_MS).start();
+ }
}
- this.showGestureCandidates_(e.results.slice(1));
+ this.showGestureCandidates_(response.results.slice(1));
};
@@ -1814,14 +1952,16 @@ Controller.prototype.showGestureCandidates_ = function(results) {
var candidates = [];
for (var i = 0; i < results.length; ++i) {
var candidate = {};
- candidate[Name.CANDIDATE] = results[i];
+ var result = this.convertToShifted_(results[i]);
+ candidate[Name.CANDIDATE] = result;
candidate[Name.CANDIDATE_ID] = i;
candidate[Name.IS_EMOJI] = false;
candidate[Name.MATCHED_LENGTHS] = 0;
candidates.push(candidate);
}
// The source is empty as this is a gesture and not a series of key presses.
- this.showCandidates_('', candidates, Controller.CandidatesOperation.NONE);
+ this.showCandidates_(
+ '', candidates, Controller.CandidatesOperation.NONE, true);
};
@@ -1831,10 +1971,12 @@ Controller.prototype.showGestureCandidates_ = function(results) {
* @param {string} source The source text.
* @param {!Array.<!Object>} candidates The candidate text list.
* @param {Controller.CandidatesOperation} operation .
+ * @param {boolean=} opt_fromGestures Whether or not the candidates are being
+ * set by gesture typing.
* @private
*/
Controller.prototype.showCandidates_ = function(source, candidates,
- operation) {
+ operation, opt_fromGestures) {
var state = !!source ? ExpandedCandidateView.State.COMPLETION_CORRECTION :
ExpandedCandidateView.State.PREDICTION;
var expandView = this.container_.expandedCandidateView;
@@ -1883,6 +2025,7 @@ Controller.prototype.showCandidates_ = function(source, candidates,
SHRINK_CANDIDATES, false);
this.container_.currentKeysetView.setVisible(true);
}
+ this.candidatesSetByGestureTyping_ = !!opt_fromGestures;
};
@@ -1991,11 +2134,17 @@ Controller.prototype.maybeCreateViews_ = function() {
// active keyset.
var keyLen = Object.keys(this.keysetDataMap_).length;
if (created && keyLen > 1 || !created && keyLen > 0) {
- goog.Timer.callOnce((function() {
+ if (Controller.DISABLE_DELAY_LOADING_FOR_TEST) {
for (var keyset in this.keysetDataMap_) {
this.createView_(keyset);
}
- }).bind(this));
+ } else {
+ goog.Timer.callOnce((function() {
+ for (var keyset in this.keysetDataMap_) {
+ this.createView_(keyset);
+ }
+ }).bind(this));
+ }
}
};
@@ -2016,14 +2165,17 @@ Controller.prototype.switchToKeyset = function(keyset) {
keyset, this.contextTypeToLastKeysetMap_[contextType] ||
this.getActiveKeyset_(), this.languageCode_);
+ // If it is the sub keyset switching, emoji, or in hotrod mode, don't record
+ // the keyset.
+ if (!this.isSubKeyset_(this.currentKeyset_, keyset) &&
+ keyset != Controller.EMOJI_VIEW_CODE_ &&
+ !this.adapter_.isHotrod) {
+ // Update the keyset of current context type.
+ this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] =
+ keyset;
+ }
+
if (ret) {
- if (!this.isSubKeyset_(this.currentKeyset_, keyset) &&
- keyset != Controller.EMOJI_VIEW_CODE_) {
- // If it is the sub keyset switching, or emoji, don't record it.
- // Update the keyset of current context type.
- this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] =
- keyset;
- }
this.updateLanguageState_(this.currentKeyset_, keyset);
this.currentKeyset_ = keyset;
this.resize(Controller.DEV);
@@ -2033,20 +2185,19 @@ Controller.prototype.switchToKeyset = function(keyset) {
} else {
// Sets the current keyset for delay switching.
this.currentKeyset_ = keyset;
- if (keyset != Controller.EMOJI_VIEW_CODE_) { // Emoji is temp keyset.
- this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] =
- keyset;
- }
this.loadResource_(keyset);
}
// TODO: The 'us' part of this code is a workaround an issue where other xkb
// languages seem to be sharing options between each other.
this.isKeysetUSCompact_ =
- this.currentKeyset_.indexOf(Controller.US_COMPACT_PREFIX_) >= 0;
+ this.currentKeyset_.indexOf(Controller.US_COMPACT_QWERTY_CODE_) >= 0;
// If we're switching to a new keyset, we don't want spacebar to trigger
// another keyset switch.
this.returnToLetterKeysetOnSpace_ = false;
+ if (this.gestureTypingEnabled_()) {
+ this.container_.gestureCanvasView.clear();
+ }
};
@@ -2130,13 +2281,16 @@ Controller.prototype.resize = function(opt_preventResizeTo) {
}
candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT;
}
- width = this.adapter_.isFloating ?
+ var isFloatingMode = this.adapter_.isFloatingVirtualKeyboardEnabled();
+ width = isFloatingMode ?
Math.floor(screen.width * widthPercent) : screen.width;
- widthPercent = this.adapter_.isFloating ? 1.0 : widthPercent;
- if (goog.dom.classlist.contains(this.container_.getElement(), Css.SMALL)) {
- height = SizeSpec.SMALL_SIZE_HEIGHT;
- width = SizeSpec.SMALL_SIZE_WIDTH;
- candidateViewHeight = SizeSpec.SMALL_SIZE_CANDIDATE_VIEW_HEIGHT;
+ widthPercent = isFloatingMode ? 1.0 : widthPercent;
+
+ // Floating virtual keyboard needs to be placed in the bottom of screen and
+ // centered when initially shows up. innerHeight == 0 is used as heuristic to
+ // check if keyboard is showing up for the first time.
+ if (isFloatingMode && window.innerHeight == 0) {
+ window.moveTo((screen.width - width) / 2, screen.height - height);
}
if ((window.innerHeight != height || window.innerWidth != width) &&
@@ -2399,6 +2553,7 @@ Controller.prototype.onUpdateToggleLanguageState_ = function(e) {
// e.msg value means whether is Chinese mode now.
if (this.model_.stateManager.isEnMode == e.msg) {
this.model_.stateManager.isEnMode = !e.msg;
+ this.updateToggleLanguageKeyset_();
this.container_.currentKeysetView.update();
}
} else {
@@ -2419,4 +2574,31 @@ Controller.prototype.onUpdateToggleLanguageState_ = function(e) {
}
}
};
+
+
+/**
+ * Update keyset when language state changes.
+ *
+ * @return {boolean}
+ * @private
+ */
+Controller.prototype.updateToggleLanguageKeyset_ = function() {
+ var pos = this.currentKeyset_.indexOf('.us');
+ var toKeyset;
+ if (pos > 0) {
+ toKeyset = this.currentKeyset_.replace('.us', '');
+ if (goog.array.contains(util.KEYSETS_SWITCH_WITH_US, toKeyset)) {
+ this.switchToKeyset(toKeyset);
+ return true;
+ }
+ }
+ else if (goog.array.contains(util.KEYSETS_SWITCH_WITH_US,
+ this.currentKeyset_)) {
+ toKeyset = this.currentKeyset_ + '.us';
+ this.switchToKeyset(toKeyset);
+ return true;
+ }
+ return false;
+};
+
}); // goog.scope

Powered by Google App Engine
This is Rietveld 408576698