1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * This class is a base class of each input method implementation.
10 var IMEBase = function() {};
12 onActivate: function() {},
13 onDeactivated: function() {},
14 onFocus: function(context) {},
15 onBlur: function(contextID) {},
16 onInputContextUpdate: function(context) {},
17 onKeyEvent: function(context, engine, keyData) { return false; },
18 onCandidateClicked: function(candidateID, button) {},
19 onMenuItemActivated: function(name) {},
20 onSurroundingTextChanged: function(text, focus, anchor) {},
21 onReset: function(engineID) {}
25 * This class provides simple identity input methods.
28 var IdentityIME = function() {};
29 IdentityIME.prototype = new IMEBase();
32 * This class provides an IME which capitalize given character.
35 var ToUpperIME = function() {};
36 ToUpperIME.prototype = new IMEBase();
39 * @param {Object} context A context object passed from input.ime.onFocus.
40 * @param {string} engine An engine ID.
41 * @param {Object} keyData A keyevent object passed from input.ime.onKeyEvent.
42 * @return {boolean} True on the key event is consumed.
44 ToUpperIME.prototype.onKeyEvent = function(context, engine, keyData) {
45 if (keyData.type == 'keydown' && /^[a-zA-Z]$/.test(keyData.key)) {
46 chrome.input.ime.commitText({
47 contextID: context.contextID,
48 text: keyData.key.toUpperCase()
56 * This class provide an IME which sneds message with API argument.
59 var APIArgumentIME = function() {};
60 APIArgumentIME.prototype = new IMEBase();
63 * @param {Object} context A context object passed from input.ime.onFocus.
64 * @param {string} engine An engine ID.
65 * @param {Object} keyData A keyevent object passed from input.ime.onKeyEvent.
66 * @return {boolean} True on the key event is consumed.
68 APIArgumentIME.prototype.onKeyEvent = function(context, engine, keyData) {
69 chrome.test.sendMessage('onKeyEvent:' +
70 (keyData.extensionId || '') + ':' +
74 keyData.ctrlKey + ':' +
75 keyData.altKey + ':' +
76 keyData.shiftKey + ':' +
82 * This class listens the event from chrome.input.ime and forwards it to the
86 var EngineBridge = function() {};
87 EngineBridge.prototype = {
90 * Map from engineID to actual engine instance.
97 * A current active engineID.
104 * A input context currently focused.
108 focusedContext_: null,
111 * Called from chrome.input.ime.onActivate.
115 onActivate_: function(engineID) {
116 this.activeEngine_ = engineID;
117 this.engineInstance_[engineID].onActivate();
118 chrome.test.sendMessage('onActivate');
122 * Called from chrome.input.ime.onDeactivated.
126 onDeactivated_: function(engineID) {
127 if (this.engineInstance_[engineID])
128 this.engineInstance_[engineID].onDeactivated();
129 this.activeEngine_ = null;
130 chrome.test.sendMessage('onDeactivated');
134 * Called from chrome.input.ime.onFocus.
138 onFocus_: function(context) {
139 this.focusedContext_ = context;
140 if (this.activeEngine_)
141 this.engineInstance_[this.activeEngine_].onFocus(context);
142 chrome.test.sendMessage('onFocus:' + context.type);
146 * Called from chrome.input.ime.onBlur.
150 onBlur_: function(contextID) {
151 if (this.activeEngine_)
152 this.engineInstance_[this.activeEngine_].onBlur(contextID);
153 this.focusedContext_ = null;
154 chrome.test.sendMessage('onBlur');
158 * Called from chrome.input.ime.onInputContextUpdate.
162 onInputContextUpdate_: function(context) {
163 this.focusedContext_ = context;
164 if (this.activeEngine_)
165 this.engineInstance_[this.activeEngine_].onInputContextUpdate(context);
166 chrome.test.sendMessage('onInputContextUpdate');
170 * Called from chrome.input.ime.onKeyEvent.
173 * @return {boolean} True on the key event is consumed.
175 onKeyEvent_: function(engineID, keyData) {
176 chrome.test.sendMessage('onKeyEvent');
177 if (this.engineInstance_[engineID])
178 return this.engineInstance_[engineID].onKeyEvent(
179 this.focusedContext_, this.activeEngine_, keyData);
184 * Called from chrome.input.ime.onCandidateClicked.
188 onCandidateClicked_: function(engineID, candidateID, button) {
189 if (this.engineInstance_[engineID])
190 this.engineInstance_[engineID].onCandidateClicked(candidateID, button);
191 chrome.test.sendMessage('onCandidateClicked');
195 * Called from chrome.input.ime.onMenuItemActivated.
199 onMenuItemActivated_: function(engineID, name) {
200 this.engineInstance_[engineID].onMenuItemActivated(name);
201 chrome.test.sendMessage('onMenuItemActivated');
205 * Called from chrome.input.ime.onSurroundingTextChanged.
209 onSurroundingTextChanged_: function(engineID, object) {
210 this.engineInstance_[engineID].onSurroundingTextChanged(
211 object.text, object.focus, object.anchor);
212 chrome.test.sendMessage('onSurroundingTextChanged');
216 * Called from chrome.input.ime.onReset.
220 onReset_: function(engineID) {
221 this.engineInstance_[engineID].onReset(engineID);
222 chrome.test.sendMessage('onReset');
226 * Add engine instance for |engineID|.
229 addEngine: function(engineID, engine) {
230 this.engineInstance_[engineID] = engine;
234 * Returns active engine ID. Returns null if there is no active engine.
236 * @return {string} An string which identify the engine.
238 getActiveEngineID: function() {
239 return this.activeEngine_;
243 * Returns currently focused context ID. Returns null if there is no focused
246 * @return {strine} An string which identify the context.
248 getFocusedContextID: function () {
249 return this.focusedContext_;
253 * Initialize EngineBridge by binding with chrome event.
256 Initialize: function() {
257 chrome.input.ime.onActivate.addListener(this.onActivate_.bind(this));
258 chrome.input.ime.onDeactivated.addListener(this.onDeactivated_.bind(this));
259 chrome.input.ime.onFocus.addListener(this.onFocus_.bind(this));
260 chrome.input.ime.onBlur.addListener(this.onBlur_.bind(this));
261 chrome.input.ime.onInputContextUpdate.addListener(
262 this.onInputContextUpdate_.bind(this));
263 chrome.input.ime.onKeyEvent.addListener(this. onKeyEvent_.bind(this));
264 chrome.input.ime.onCandidateClicked.addListener(
265 this.onCandidateClicked_.bind(this));
266 chrome.input.ime.onMenuItemActivated.addListener(
267 this.onMenuItemActivated_.bind(this));
268 chrome.input.ime.onSurroundingTextChanged.addListener(
269 this.onSurroundingTextChanged_.bind(this));
270 chrome.input.ime.onReset.addListener(this.onReset_.bind(this));
274 var engineBridge = new EngineBridge();
275 engineBridge.Initialize();
276 engineBridge.addEngine('IdentityIME', new IdentityIME());
277 engineBridge.addEngine('ToUpperIME', new ToUpperIME());
278 engineBridge.addEngine('APIArgumentIME', new APIArgumentIME());
279 chrome.test.sendMessage('ReadyToUseImeEvent');