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 8e29bd7264820031d34e55bef0a10285f947ba2a..f0f497958c6ef3d6f6131a10f0fa1ab6caa98312 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 |
@@ -17,8 +17,8 @@ goog.require('goog.Disposable'); |
goog.require('goog.Timer'); |
goog.require('goog.array'); |
goog.require('goog.async.Delay'); |
-goog.require('goog.dom'); |
goog.require('goog.dom.classlist'); |
+goog.require('goog.events.Event'); |
goog.require('goog.events.EventHandler'); |
goog.require('goog.events.EventType'); |
goog.require('goog.i18n.bidi'); |
@@ -460,7 +460,42 @@ Controller.prototype.registerEventHandler_ = function() { |
this.onSettingsReady_). |
listen(this.adapter_, Type.UPDATE_SETTINGS, this.onUpdateSettings_). |
listen(this.adapter_, Type.FRONT_TOGGLE_LANGUAGE_STATE, |
- this.onUpdateToggleLanguateState_); |
+ this.onUpdateToggleLanguateState_). |
+ listen(this.adapter_, Type.VOICE_STATE_CHANGE, this.onVoiceStateChange_); |
+}; |
+ |
+ |
+/** |
+ * Handler for voice module state change. |
+ * |
+ * @param {!i18n.input.chrome.message.Event} e . |
+ * @private |
+ */ |
+Controller.prototype.onVoiceStateChange_ = function(e) { |
+ var elem = this.container_.getElement(); |
+ if (!e.msg[Name.VOICE_STATE]) { |
+ this.container_.candidateView.switchToIcon( |
+ CandidateView.IconType.VOICE, true); |
+ this.container_.voiceView.stop(); |
+ } |
+}; |
+ |
+ |
+/** |
+ * Sets the default keyset for context types. |
+ * |
+ * @param {string} newKeyset . |
+ * @private |
+ */ |
+Controller.prototype.setDefaultKeyset_ = function(newKeyset) { |
+ var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; |
+ for (var context in keysetMap) { |
+ if (context != ContextType.DEFAULT && |
+ keysetMap[context] == keysetMap[ContextType.DEFAULT]) { |
+ keysetMap[context] = newKeyset; |
+ } |
+ } |
+ keysetMap[ContextType.DEFAULT] = this.initialKeyset_ = newKeyset; |
}; |
@@ -482,8 +517,7 @@ Controller.prototype.onUpdateSettings_ = function(e) { |
settings.candidatesNavigation = e.msg['candidatesNavigation']; |
} |
if (goog.isDef(e.msg[Name.KEYSET])) { |
- this.contextTypeToKeysetMap_[this.currentInputMethod_][ |
- ContextType.DEFAULT] = this.initialKeyset_ = e.msg[Name.KEYSET]; |
+ this.setDefaultKeyset_(e.msg[Name.KEYSET]); |
} |
if (goog.isDef(e.msg['enableLongPress'])) { |
settings.enableLongPress = e.msg['enableLongPress']; |
@@ -497,7 +531,7 @@ Controller.prototype.onUpdateSettings_ = function(e) { |
} |
this.perfTracker_.tick(PerfTracker.TickName.BACKGROUND_SETTINGS_FETCHED); |
this.model_.stateManager.contextType = this.adapter_.contextType; |
- this.switchToKeyset(this.getActiveKeyset_()); |
+ this.maybeCreateViews_(); |
}; |
@@ -513,22 +547,22 @@ Controller.prototype.onSettingsReady_ = function() { |
this.isSettingReady = true; |
var keysetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; |
+ var newKeyset = ''; |
if (this.adapter_.isA11yMode) { |
- keysetMap[ContextType.PASSWORD] = keysetMap[ContextType.DEFAULT] = |
- util.getConfigName(keysetMap[ContextType.DEFAULT]); |
+ newKeyset = util.getConfigName(keysetMap[ContextType.DEFAULT]); |
} else { |
- var preferredKeyset = /** @type {string} */ (this.model_.settings. |
+ newKeyset = /** @type {string} */ (this.model_.settings. |
getPreference(util.getConfigName(keysetMap[ContextType.DEFAULT]))); |
- if (preferredKeyset) { |
- keysetMap[ContextType.PASSWORD] = keysetMap[ContextType.DEFAULT] = |
- preferredKeyset; |
- } |
} |
if (!this.adapter_.isExperimental && keysetMap[ContextType.DEFAULT] == |
'zhuyin.compact.qwerty') { |
- keysetMap[ContextType.DEFAULT] = 'zhuyin'; |
+ newKeyset = 'zhuyin'; |
} |
- this.initialKeyset_ = keysetMap[ContextType.DEFAULT]; |
+ if (newKeyset) { |
+ this.setDefaultKeyset_(newKeyset); |
+ } |
+ // Loads resources in case the default keyset is changed. |
+ this.loadAllResources_(); |
this.maybeCreateViews_(); |
}; |
@@ -740,6 +774,12 @@ Controller.prototype.executeCommand_ = function(command, opt_arg) { |
* @private |
*/ |
Controller.prototype.handlePointerAction_ = function(view, e) { |
+ // Listen for DOUBLE_CLICK as well to capture secondary taps on the spacebar. |
+ if (e.type == EventType.POINTER_UP || e.type == EventType.DOUBLE_CLICK) { |
+ this.recordStatsForClosing_( |
+ 'InputMethod.VirtualKeyboard.TapCount', 1, 4095, 4096); |
+ } |
+ |
if (e.type == i18n.input.chrome.inputview.events.EventType.SWIPE) { |
e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e); |
this.handleSwipeAction_(view, e); |
@@ -814,10 +854,10 @@ Controller.prototype.handlePointerAction_ = function(view, e) { |
case ElementType.MENU_ITEM: |
view = /** @type {!content.MenuItem} */ (view); |
if (e.type == EventType.CLICK) { |
- this.resetAll_(); |
this.executeCommand_.apply(this, view.getCommand()); |
this.container_.menuView.hide(); |
this.soundController_.onKeyUp(view.type); |
+ this.resetAll_(); |
} |
view.setHighlighted(e.type == EventType.POINTER_DOWN || |
e.type == EventType.POINTER_OVER); |
@@ -834,7 +874,7 @@ Controller.prototype.handlePointerAction_ = function(view, e) { |
return; |
case ElementType.EMOJI_KEY: |
- if (e.type == EventType.POINTER_UP) { |
+ if (e.type == EventType.CLICK) { |
if (!this.container_.currentKeysetView.isDragging && view.text != '') { |
this.adapter_.commitText(view.text); |
this.soundController_.onKeyUp(view.type); |
@@ -843,7 +883,35 @@ Controller.prototype.handlePointerAction_ = function(view, e) { |
return; |
case ElementType.HWT_PRIVACY_GOT_IT: |
- this.adapter_.sendHwtPrivacyConfirmMessage(); |
+ // Broadcasts the handwriting privacy confirmed message to let canvas |
+ // view handle it. |
+ this.adapter_.dispatchEvent(new goog.events.Event( |
+ Type.HWT_PRIVACY_GOT_IT)); |
+ return; |
+ |
+ case ElementType.VOICE_PRIVACY_GOT_IT: |
+ // Broadcasts the voice privacy confirmed message to let voice |
+ // view handle it. |
+ this.adapter_.dispatchEvent(new goog.events.Event( |
+ Type.VOICE_PRIVACY_GOT_IT)); |
+ return; |
+ |
+ case ElementType.VOICE_BTN: |
+ if (e.type == EventType.CLICK) { |
+ this.container_.candidateView.switchToIcon( |
+ CandidateView.IconType.VOICE, false); |
+ this.container_.voiceView.start(); |
+ } |
+ return; |
+ |
+ |
+ case ElementType.VOICE_VIEW: |
+ if (e.type == EventType.POINTER_UP) { |
+ this.adapter_.sendVoiceViewStateChange(false); |
+ this.container_.candidateView.switchToIcon( |
+ CandidateView.IconType.VOICE, true); |
+ this.container_.voiceView.stop(); |
+ } |
return; |
case ElementType.SOFT_KEY_VIEW: |
@@ -900,8 +968,7 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) { |
key = /** @type {!content.CharacterKey} */ (softKey); |
if (e.type == EventType.LONG_PRESS) { |
this.container_.altDataView.show( |
- key, goog.i18n.bidi.isRtlLanguage(this.languageCode_), |
- this.adapter_.isExperimental); |
+ key, goog.i18n.bidi.isRtlLanguage(this.languageCode_)); |
} else if (e.type == EventType.POINTER_UP) { |
this.model_.stateManager.triggerChording(); |
var ch = key.getActiveCharacter(); |
@@ -1046,8 +1113,7 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) { |
key = /** @type {!content.CompactKey} */ (softKey); |
if (e.type == EventType.LONG_PRESS) { |
this.container_.altDataView.show( |
- key, goog.i18n.bidi.isRtlLanguage(this.languageCode_), |
- this.adapter_.isExperimental); |
+ key, goog.i18n.bidi.isRtlLanguage(this.languageCode_)); |
} else if (e.type == EventType.POINTER_UP) { |
this.model_.stateManager.triggerChording(); |
var ch = key.getActiveCharacter(); |
@@ -1069,9 +1135,9 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) { |
var defaultKeyset = this.getActiveKeyset_(); |
if (e.type == EventType.POINTER_UP) { |
this.adapter_.hideKeyboard(); |
- } |
- if (this.currentKeyset_ != defaultKeyset) { |
- this.switchToKeyset(defaultKeyset); |
+ if (this.currentKeyset_ != defaultKeyset) { |
+ this.switchToKeyset(defaultKeyset); |
+ } |
} |
break; |
@@ -1093,8 +1159,7 @@ Controller.prototype.handlePointerEventForSoftKey_ = function(softKey, e) { |
var self = this; |
var hasHwt = !this.adapter_.isPasswordBox() && |
!Controller.DISABLE_HWT && goog.object.contains( |
- InputToolCode, this.getHwtInputToolCode_()) && |
- this.languageCode_ != 'ko'; |
+ InputToolCode, this.getHwtInputToolCode_()); |
var hasEmoji = !this.adapter_.isPasswordBox(); |
var enableSettings = this.shouldEnableSettings() && |
!!window.inputview && !!inputview.openSettings; |
@@ -1221,6 +1286,7 @@ Controller.prototype.resetAll_ = function() { |
this.resize(); |
this.container_.expandedCandidateView.close(); |
this.container_.menuView.hide(); |
+ this.container_.altDataView.hide(); |
}; |
@@ -1265,7 +1331,6 @@ Controller.prototype.onSurroundingTextChanged_ = function(e) { |
* @private |
*/ |
Controller.prototype.onContextBlur_ = function() { |
- this.clearCandidates_(); |
this.container_.cleanStroke(); |
this.deadKey_ = ''; |
this.container_.menuView.hide(); |
@@ -1436,8 +1501,14 @@ Controller.prototype.clearCandidates_ = function() { |
if (this.container_.currentKeysetView) { |
this.container_.currentKeysetView.setVisible(true); |
} |
- this.container_.candidateView.switchToIcon(CandidateView.IconType.BACK, |
- Controller.HANDWRITING_VIEW_CODE_ == this.currentKeyset_); |
+ if (this.currentKeyset_ == Controller.HANDWRITING_VIEW_CODE_) { |
+ this.container_.candidateView.switchToIcon( |
+ CandidateView.IconType.BACK, true); |
+ } else { |
+ this.container_.candidateView.switchToIcon(CandidateView.IconType.VOICE, |
+ this.currentKeyset_ != Controller.EMOJI_VIEW_CODE_ && |
+ this.adapter_.isExperimental); |
+ } |
}; |
@@ -1502,21 +1573,28 @@ Controller.prototype.maybeCreateViews_ = function() { |
return; |
} |
- var activeKeyset = this.getActiveKeyset_(); |
+ // Emoji is temp keyset which is delay loaded. So active keyset can be 'us' |
+ // while current keyset is 'emoji'. To make sure delay load can work |
+ // correctly, here need to create/switch to 'emoji' instead of 'us'. |
+ var activeKeyset = (this.currentKeyset_ == Controller.EMOJI_VIEW_CODE_) ? |
+ this.currentKeyset_ : this.getActiveKeyset_(); |
var remappedActiveKeyset = this.getRemappedKeyset_(activeKeyset); |
+ var created = false; |
if (this.keysetDataMap_[remappedActiveKeyset]) { |
this.createView_(remappedActiveKeyset); |
this.switchToKeyset(activeKeyset); |
+ created = true; |
} |
// Async creating the non-active keysets to reduce the latency of showing the |
// active keyset. |
- goog.Timer.callOnce((function() { |
- for (var keyset in this.keysetDataMap_) { |
- if (keyset != remappedActiveKeyset) { |
+ var keyLen = Object.keys(this.keysetDataMap_).length; |
+ if (created && keyLen > 1 || !created && keyLen > 0) { |
+ goog.Timer.callOnce((function() { |
+ for (var keyset in this.keysetDataMap_) { |
this.createView_(keyset); |
} |
- } |
- }).bind(this)); |
+ }).bind(this)); |
+ } |
}; |
@@ -1546,15 +1624,18 @@ Controller.prototype.switchToKeyset = function(keyset) { |
keyset; |
} |
this.updateLanguageState_(this.currentKeyset_, keyset); |
+ this.currentKeyset_ = keyset; |
this.resize(Controller.DEV); |
this.statistics_.recordLayout(keyset, this.adapter_.isA11yMode); |
- this.currentKeyset_ = keyset; |
this.perfTracker_.tick(PerfTracker.TickName.KEYBOARD_SHOWN); |
this.perfTracker_.stop(); |
} else { |
// Sets the current keyset for delay switching. |
- this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] = |
- this.currentKeyset_ = keyset; |
+ this.currentKeyset_ = keyset; |
+ if (keyset != Controller.EMOJI_VIEW_CODE_) { // Emoji is temp keyset. |
+ this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] = |
+ keyset; |
+ } |
this.loadResource_(keyset); |
} |
}; |
@@ -1584,12 +1665,15 @@ Controller.prototype.onConfigLoaded_ = function(e) { |
} |
var layoutId = data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT]; |
+ if (this.adapter_.isQPInputView && layoutId == 'compactkbd-qwerty') { |
+ layoutId = 'm-' + layoutId; |
+ data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT] = layoutId; |
+ } |
var layoutData = this.layoutDataMap_[layoutId]; |
if (layoutData) { |
this.maybeCreateViews_(); |
} else { |
- this.model_.loadLayout(data[i18n.input.chrome.inputview.SpecNodeName. |
- LAYOUT]); |
+ this.model_.loadLayout(layoutId); |
} |
}; |
@@ -1603,10 +1687,17 @@ Controller.prototype.resize = function(opt_ignoreWindowResize) { |
var height; |
var widthPercent; |
var candidateViewHeight; |
- var isHorizontal = screen.width > screen.height; |
+ var isLandScape = screen.width > screen.height; |
+ if (isLandScape) { |
+ goog.dom.classlist.addRemove(this.container_.getElement(), |
+ Css.PORTRAIT, Css.LANDSCAPE); |
+ } else { |
+ goog.dom.classlist.addRemove(this.container_.getElement(), |
+ Css.LANDSCAPE, Css.PORTRAIT); |
+ } |
var isWideScreen = (Math.min(screen.width, screen.height) / Math.max( |
screen.width, screen.height)) < 0.6; |
- this.model_.stateManager.covariance.update(isWideScreen, isHorizontal, |
+ this.model_.stateManager.covariance.update(isWideScreen, isLandScape, |
this.adapter_.isA11yMode); |
if (this.adapter_.isA11yMode) { |
height = SizeSpec.A11Y_HEIGHT; |
@@ -1620,20 +1711,19 @@ Controller.prototype.resize = function(opt_ignoreWindowResize) { |
var spec = data && data[SpecNodeName.WIDTH_PERCENT] || |
SizeSpec.NON_A11Y_WIDTH_PERCENT; |
height = SizeSpec.NON_A11Y_HEIGHT; |
- if (isHorizontal) { |
+ if (isLandScape) { |
if (isWideScreen) { |
- widthPercent = spec.LANDSCAPE_WIDE_SCREEN; |
+ widthPercent = spec['LANDSCAPE_WIDE_SCREEN']; |
} else { |
- widthPercent = spec.LANDSCAPE; |
+ widthPercent = spec['LANDSCAPE']; |
} |
} else { |
- widthPercent = spec.PORTRAIT; |
+ widthPercent = spec['PORTRAIT']; |
} |
candidateViewHeight = SizeSpec.NON_A11Y_CANDIDATE_VIEW_HEIGHT; |
} |
- var viewportSize = goog.dom.getViewportSize(); |
- if (viewportSize.height != height && !opt_ignoreWindowResize) { |
+ if (window.innerHeight != height && !opt_ignoreWindowResize) { |
if (this.lastResizeHeight_ != height) { |
this.lastResizeHeight_ = height; |
window.resizeTo(screen.width, height); |
@@ -1673,7 +1763,7 @@ Controller.prototype.loadAllResources_ = function() { |
*/ |
Controller.prototype.getRemappedKeyset_ = function(keyset) { |
if (goog.array.contains(util.KEYSETS_USE_US, keyset)) { |
- return 'us'; |
+ return 'us-ltr'; |
} |
var match = keyset.match(/^(.*)-rtl$/); |
if (match && goog.array.contains(util.KEYSETS_USE_US, match[1])) { |
@@ -1729,10 +1819,7 @@ Controller.prototype.initialize = function(keyset, languageCode, passwordLayout, |
} |
this.languageCode_ = languageCode; |
this.currentInputMethod_ = currentInputMethod; |
- var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_]; |
- if (!keySetMap) { |
- keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {}; |
- } |
+ var keySetMap = this.contextTypeToKeysetMap_[this.currentInputMethod_] = {}; |
keySetMap[ContextType.PASSWORD] = passwordLayout; |
keySetMap[ContextType.DEFAULT] = keyset; |
@@ -1832,12 +1919,11 @@ Controller.prototype.updateLanguageState_ = |
toRawKeyset.indexOf('en.compact') < 0) { // Switches between non-en/en. |
toggle = true; |
toggleState = toRawKeyset.indexOf('en.compact') == -1; |
- } else if (goog.array.contains(util.KEYSETS_HAVE_EN_SWTICHER, |
- toRawKeyset) && |
- fromRawKeyset.indexOf(toRawKeyset) == 0 && |
- fromRawKeyset.indexOf('.compact') > 0 || |
- fromRawKeyset && toRawKeyset.indexOf(fromRawKeyset) == 0 && |
- toRawKeyset.indexOf('.compact') > 0) { |
+ } else if (fromRawKeyset.indexOf(toRawKeyset) == 0 && |
+ fromRawKeyset.indexOf('.compact') > 0 && |
+ goog.array.contains(util.KEYSETS_HAVE_EN_SWTICHER, toRawKeyset) || |
+ fromRawKeyset && toRawKeyset.indexOf(fromRawKeyset) == 0 && |
+ toRawKeyset.indexOf('.compact') > 0) { |
// Switch between full/compact layouts, reset the default button and |
// language. |
toggle = true; |