1 // Copyright 2014 The ChromeOS IME Authors. All Rights Reserved.
2 // limitations under the License.
3 // See the License for the specific language governing permissions and
4 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5 // distributed under the License is distributed on an "AS-IS" BASIS,
6 // Unless required by applicable law or agreed to in writing, software
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // You may obtain a copy of the License at
11 // you may not use this file except in compliance with the License.
12 // Licensed under the Apache License, Version 2.0 (the "License");
14 goog.provide('i18n.input.chrome.inputview.content.util');
16 goog.require('goog.array');
17 goog.require('i18n.input.chrome.inputview.Css');
18 goog.require('i18n.input.chrome.inputview.Direction');
19 goog.require('i18n.input.chrome.inputview.SpecNodeName');
20 goog.require('i18n.input.chrome.inputview.StateType');
21 goog.require('i18n.input.chrome.inputview.elements.ElementType');
23 goog.scope(function() {
24 var ElementType = i18n.input.chrome.inputview.elements.ElementType;
25 var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName;
29 * The prefix of the key id.
34 i18n.input.chrome.inputview.content.util.keyIdPrefix_ = 'sk-';
38 * Creates the hide keyboard key.
40 * @return {!Object} The hide keyboard key.
42 i18n.input.chrome.inputview.content.util.createHideKeyboardKey = function() {
44 spec[SpecNodeName.ICON_CSS_CLASS] =
45 i18n.input.chrome.inputview.Css.HIDE_KEYBOARD_ICON;
46 spec[SpecNodeName.TYPE] = ElementType.HIDE_KEYBOARD_KEY;
47 spec[SpecNodeName.ID] = 'HideKeyboard';
48 return i18n.input.chrome.inputview.content.util.createKey(spec);
53 * Creates a shift key.
55 * @param {boolean} isLeft True if this is the left shift key.
56 * @param {boolean=} opt_supportSticky True if support sticky shift key.
57 * @return {!Object} The shift key.
59 i18n.input.chrome.inputview.content.util.createShiftKey = function(isLeft,
62 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.SHIFT;
63 spec[SpecNodeName.ICON_CSS_CLASS] =
64 i18n.input.chrome.inputview.Css.SHIFT_ICON;
65 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
66 spec[SpecNodeName.ID] = isLeft ? 'ShiftLeft' : 'ShiftRight';
67 spec[SpecNodeName.SUPPORT_STICKY] = !!opt_supportSticky;
68 return i18n.input.chrome.inputview.content.util.createKey(spec);
73 * Creates a globe key.
75 * @return {!Object} The globe key.
77 i18n.input.chrome.inputview.content.util.createGlobeKey = function() {
79 spec[SpecNodeName.ICON_CSS_CLASS] =
80 i18n.input.chrome.inputview.Css.GLOBE_ICON;
81 spec[SpecNodeName.TYPE] = ElementType.GLOBE_KEY;
82 spec[SpecNodeName.ID] = 'Globe';
83 return i18n.input.chrome.inputview.content.util.createKey(spec);
90 * @param {string=} opt_toKeyset The compact keyboard id.
91 * @return {!Object} The menu key.
93 i18n.input.chrome.inputview.content.util.createMenuKey = function(
96 spec[SpecNodeName.ICON_CSS_CLASS] =
97 i18n.input.chrome.inputview.Css.MENU_ICON;
98 spec[SpecNodeName.TO_KEYSET] = opt_toKeyset;
99 spec[SpecNodeName.TYPE] = ElementType.MENU_KEY;
100 spec[SpecNodeName.ID] = 'Menu';
101 return i18n.input.chrome.inputview.content.util.createKey(spec);
106 * Create the Emoji switch key.
108 * @param {string} id The emoji key id.
109 * @param {number} toKeyset The keyset that the tabbar represents.
110 * @param {i18n.input.chrome.inputview.Css}
111 * iconCssClass The icon css for the tabbar.
112 * @return {!Object} The emoji key.
114 i18n.input.chrome.inputview.content.util.createTabBarKey =
115 function(id, toKeyset, iconCssClass) {
117 spec[SpecNodeName.ICON_CSS_CLASS] = iconCssClass;
118 spec[SpecNodeName.TYPE] = ElementType.TAB_BAR_KEY;
119 spec[SpecNodeName.ID] = id;
120 spec[SpecNodeName.TO_KEYSET] = toKeyset;
121 return i18n.input.chrome.inputview.content.util.createKey(spec);
126 * Create the indicator
128 * @param {string} id The indicator id.
129 * @return {!Object} The indicator.
131 i18n.input.chrome.inputview.content.util.createPageIndicator =
134 spec[SpecNodeName.TYPE] = ElementType.PAGE_INDICATOR;
135 spec[SpecNodeName.ID] = id;
136 return i18n.input.chrome.inputview.content.util.createKey(spec);
141 * Create the back key for emoji
143 * @return {!Object} The back key.
145 i18n.input.chrome.inputview.content.util.createBackKey = function() {
147 spec[SpecNodeName.ICON_CSS_CLASS] =
148 i18n.input.chrome.inputview.Css.EMOJI_BACK;
149 spec[SpecNodeName.TYPE] = ElementType.BACK_BUTTON;
150 spec[SpecNodeName.ID] = 'backkey';
151 return i18n.input.chrome.inputview.content.util.createKey(spec);
156 * Creates a ctrl key.
158 * @return {!Object} The ctrl key.
160 i18n.input.chrome.inputview.content.util.createCtrlKey = function() {
162 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.CTRL;
163 spec[SpecNodeName.NAME] = 'ctrl';
164 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
165 spec[SpecNodeName.ID] = 'ControlLeft';
166 return i18n.input.chrome.inputview.content.util.createKey(spec);
173 * @return {!Object} The alt key.
175 i18n.input.chrome.inputview.content.util.createAltKey = function() {
177 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.ALT;
178 spec[SpecNodeName.NAME] = 'alt';
179 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
180 spec[SpecNodeName.ID] = 'AltLeft';
181 return i18n.input.chrome.inputview.content.util.createKey(spec);
186 * Creates a altgr key.
188 * @return {!Object} The altgr key.
190 i18n.input.chrome.inputview.content.util.createAltgrKey = function() {
192 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.ALTGR;
193 spec[SpecNodeName.NAME] = 'alt gr';
194 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
195 spec[SpecNodeName.ID] = 'AltRight';
196 return i18n.input.chrome.inputview.content.util.createKey(spec);
201 * Creates a key used to switch to english.
203 * @return {!Object} The enSwitcher key.
205 i18n.input.chrome.inputview.content.util.createEnSwitcherKey =
208 spec[SpecNodeName.TYPE] = ElementType.EN_SWITCHER;
209 spec[SpecNodeName.ID] = 'enSwitcher';
210 return i18n.input.chrome.inputview.content.util.createKey(spec);
215 * Creates a capslock key.
217 * @return {!Object} The capslock key.
219 i18n.input.chrome.inputview.content.util.createCapslockKey = function() {
221 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.CAPSLOCK;
222 spec[SpecNodeName.NAME] = 'caps lock';
223 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
224 spec[SpecNodeName.ID] = 'OsLeft';
225 return i18n.input.chrome.inputview.content.util.createKey(spec);
230 * Creates a enter key.
232 * @return {!Object} The enter key.
234 i18n.input.chrome.inputview.content.util.createEnterKey = function() {
236 spec[SpecNodeName.ICON_CSS_CLASS] =
237 i18n.input.chrome.inputview.Css.ENTER_ICON;
238 spec[SpecNodeName.TYPE] = ElementType.ENTER_KEY;
239 spec[SpecNodeName.ID] = 'Enter';
240 return i18n.input.chrome.inputview.content.util.createKey(spec);
247 * @return {!Object} The tab key.
249 i18n.input.chrome.inputview.content.util.createTabKey = function() {
251 spec[SpecNodeName.ICON_CSS_CLASS] = i18n.input.chrome.inputview.Css.TAB_ICON;
252 spec[SpecNodeName.TYPE] = ElementType.TAB_KEY;
253 spec[SpecNodeName.ID] = 'Tab';
254 return i18n.input.chrome.inputview.content.util.createKey(spec);
259 * Creates a backspace key.
261 * @return {!Object} The backspace key.
263 i18n.input.chrome.inputview.content.util.createBackspaceKey = function() {
265 spec[SpecNodeName.ICON_CSS_CLASS] =
266 i18n.input.chrome.inputview.Css.BACKSPACE_ICON;
267 spec[SpecNodeName.TYPE] = ElementType.BACKSPACE_KEY;
268 spec[SpecNodeName.ID] = 'Backspace';
269 return i18n.input.chrome.inputview.content.util.createKey(spec);
274 * Creates a space key.
276 * @return {!Object} The space key.
278 i18n.input.chrome.inputview.content.util.createSpaceKey = function() {
280 spec[SpecNodeName.NAME] = ' ';
281 spec[SpecNodeName.TYPE] = ElementType.SPACE_KEY;
282 spec[SpecNodeName.ID] = 'Space';
283 return i18n.input.chrome.inputview.content.util.createKey(spec);
288 * Create an IME switch key.
290 * @param {string} id .
291 * @param {string} name .
292 * @param {string} css .
293 * @return {!Object} The JP IME switch key.
295 i18n.input.chrome.inputview.content.util.createIMESwitchKey =
296 function(id, name, css) {
298 spec[SpecNodeName.NAME] = name;
299 spec[SpecNodeName.TYPE] = ElementType.IME_SWITCH;
300 spec[SpecNodeName.ID] = id;
301 spec[SpecNodeName.TEXT_CSS_CLASS] = css;
302 return i18n.input.chrome.inputview.content.util.createKey(spec);
307 * Creates a normal key.
309 * @param {!Object} spec The specification.
310 * @return {!Object} The normal key.
312 i18n.input.chrome.inputview.content.util.createNormalKey = function(spec) {
313 spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY;
314 return i18n.input.chrome.inputview.content.util.createKey(spec);
319 * Creates an arrow key.
321 * @param {!i18n.input.chrome.inputview.Direction} direction The direction.
322 * @return {!Object} The arrow key.
324 i18n.input.chrome.inputview.content.util.createArrowKey = function(direction) {
326 spec[SpecNodeName.ICON_CSS_CLASS] =
327 i18n.input.chrome.inputview.Css.ARROW_KEY + ' ';
328 if (direction == i18n.input.chrome.inputview.Direction.UP) {
329 spec[SpecNodeName.ID] = 'ArrowUp';
330 spec[SpecNodeName.ICON_CSS_CLASS] += i18n.input.chrome.inputview.Css.UP_KEY;
331 spec[SpecNodeName.TYPE] = ElementType.ARROW_UP;
332 } else if (direction == i18n.input.chrome.inputview.Direction.DOWN) {
333 spec[SpecNodeName.ID] = 'ArrowDown';
334 spec[SpecNodeName.ICON_CSS_CLASS] +=
335 i18n.input.chrome.inputview.Css.DOWN_KEY;
336 spec[SpecNodeName.TYPE] = ElementType.ARROW_DOWN;
337 } else if (direction == i18n.input.chrome.inputview.Direction.LEFT) {
338 spec[SpecNodeName.ID] = 'ArrowLeft';
339 spec[SpecNodeName.ICON_CSS_CLASS] +=
340 i18n.input.chrome.inputview.Css.LEFT_KEY;
341 spec[SpecNodeName.TYPE] = ElementType.ARROW_LEFT;
342 } else if (direction == i18n.input.chrome.inputview.Direction.RIGHT) {
343 spec[SpecNodeName.ID] = 'ArrowRight';
344 spec[SpecNodeName.ICON_CSS_CLASS] +=
345 i18n.input.chrome.inputview.Css.RIGHT_KEY;
346 spec[SpecNodeName.TYPE] = ElementType.ARROW_RIGHT;
348 return i18n.input.chrome.inputview.content.util.createKey(spec);
353 * Creates a soft key.
355 * @param {!Object} spec The specification.
356 * @return {!Object} The soft key.
358 i18n.input.chrome.inputview.content.util.createKey = function(spec) {
360 for (var key in spec) {
361 newSpec[key] = spec[key];
370 * The physical key codes.
372 * @type {!Array.<string>}
374 i18n.input.chrome.inputview.content.util.KEY_CODES_101 = [
426 * The physical key codes for 102 keyboard.
428 * @type {!Array.<string>}
430 i18n.input.chrome.inputview.content.util.KEY_CODES_102 = [
483 * Creates the key data.
485 * @param {!Array.<!Array.<string>>} keyCharacters The key characters.
486 * @param {string} viewIdPrefix The prefix of the view.
487 * @param {boolean} is102 True if it is a 102 keyboard.
488 * @param {boolean} hasAltGrKey True if there is altgr key.
489 * @param {!Array.<!Array.<number>>=} opt_keyCodes The key codes.
490 * @param {string=} opt_compactKeyboardId The compact keyboard id.
491 * @return {!Object} The key data.
493 i18n.input.chrome.inputview.content.util.createData = function(keyCharacters,
494 viewIdPrefix, is102, hasAltGrKey, opt_keyCodes, opt_compactKeyboardId) {
497 var keyCodes = opt_keyCodes || [];
498 var keyIds = is102 ? i18n.input.chrome.inputview.content.util.KEY_CODES_102 :
499 i18n.input.chrome.inputview.content.util.KEY_CODES_101;
500 for (var i = 0; i < keyCharacters.length - 1; i++) {
502 spec[SpecNodeName.ID] = keyIds[i];
503 spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY;
504 spec[SpecNodeName.CHARACTERS] = keyCharacters[i];
505 spec[SpecNodeName.KEY_CODE] = keyCodes[i];
506 var key = i18n.input.chrome.inputview.content.util.createKey(spec);
510 i18n.input.chrome.inputview.content.util.insertModifierKeys_(keyList,
511 is102, opt_compactKeyboardId);
512 for (var i = 0; i < keyList.length; i++) {
513 var key = keyList[i];
514 mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + i;
516 var layout = is102 ? '102kbd' : '101kbd';
518 result[SpecNodeName.KEY_LIST] = keyList;
519 result[SpecNodeName.MAPPING] = mapping;
520 result[SpecNodeName.LAYOUT] = layout;
521 result[SpecNodeName.HAS_ALTGR_KEY] = hasAltGrKey;
522 result[SpecNodeName.SHOW_MENU_KEY] = true;
528 * Creates a switcher key which will switch between keyboards.
530 * @param {string} id The id.
531 * @param {string} name The name.
532 * @param {string|undefined} toKeyset The id of keyset this swicher key should
534 * @param {string} toKeysetName The name of the keyset.
535 * @param {string=} opt_iconCssClass The css class for the icon.
536 * @param {boolean=} opt_record True to record and next time the keyset will
538 * @return {!Object} The switcher key.
540 i18n.input.chrome.inputview.content.util.createSwitcherKey = function(
541 id, name, toKeyset, toKeysetName, opt_iconCssClass, opt_record) {
543 spec[SpecNodeName.ID] = id;
544 spec[SpecNodeName.NAME] = name;
545 spec[SpecNodeName.TO_KEYSET] = toKeyset;
546 spec[SpecNodeName.TO_KEYSET_NAME] = toKeysetName;
547 spec[SpecNodeName.ICON_CSS_CLASS] = opt_iconCssClass;
548 spec[SpecNodeName.TYPE] = ElementType.SWITCHER_KEY;
549 spec[SpecNodeName.RECORD] = !!opt_record;
550 return i18n.input.chrome.inputview.content.util.createKey(spec);
555 * Inserts modifier keys into the key list.
557 * @param {!Array.<!Object>} keyList The key list.
558 * @param {boolean} is102 True if it is a 102 keyboard.
559 * @param {string=} opt_compactKeyboardId The compact keyboard id.
562 i18n.input.chrome.inputview.content.util.insertModifierKeys_ = function(
563 keyList, is102, opt_compactKeyboardId) {
564 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
565 createBackspaceKey(), 13);
566 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
568 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
569 createCapslockKey(), is102 ? 27 : 28);
570 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
571 createEnterKey(), 40);
572 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
573 createShiftKey(true), 41);
574 keyList.push(i18n.input.chrome.inputview.content.util.createShiftKey(false));
575 i18n.input.chrome.inputview.content.util.addLastRowKeys(
576 keyList, is102, opt_compactKeyboardId);
581 * Inserts modifier keys into the key list.
583 * @param {!Array.<!Object>} keyList The key list.
584 * @param {boolean} is102 True if it is a 102 keyboard.
585 * @param {string=} opt_compactKeyboardId The compact keyboard id.
587 i18n.input.chrome.inputview.content.util.addLastRowKeys =
588 function(keyList, is102, opt_compactKeyboardId) {
589 keyList.push(i18n.input.chrome.inputview.content.util.createGlobeKey());
590 keyList.push(i18n.input.chrome.inputview.content.util.createMenuKey(
591 opt_compactKeyboardId));
592 keyList.push(i18n.input.chrome.inputview.content.util.createCtrlKey());
593 keyList.push(i18n.input.chrome.inputview.content.util.createAltKey());
594 keyList.push(i18n.input.chrome.inputview.content.util.createSpaceKey());
595 keyList.push(i18n.input.chrome.inputview.content.util.createEnSwitcherKey());
596 keyList.push(i18n.input.chrome.inputview.content.util.createAltgrKey());
597 keyList.push(i18n.input.chrome.inputview.content.util.createArrowKey(
598 i18n.input.chrome.inputview.Direction.LEFT));
599 keyList.push(i18n.input.chrome.inputview.content.util.createArrowKey(
600 i18n.input.chrome.inputview.Direction.RIGHT));
601 keyList.push(i18n.input.chrome.inputview.content.util.
602 createHideKeyboardKey());