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 * Create the key which leads to keyboard from emoji/hwt.
158 * @return {!Object} The back key.
160 i18n.input.chrome.inputview.content.util.createBackToKeyboardKey = function() {
162 spec[SpecNodeName.ICON_CSS_CLASS] =
163 i18n.input.chrome.inputview.Css.BACK_TO_KEYBOARD_ICON;
164 spec[SpecNodeName.TYPE] = ElementType.BACK_TO_KEYBOARD;
165 spec[SpecNodeName.ID] = 'backToKeyboard';
166 return i18n.input.chrome.inputview.content.util.createKey(spec);
171 * Creates a ctrl key.
173 * @return {!Object} The ctrl key.
175 i18n.input.chrome.inputview.content.util.createCtrlKey = function() {
177 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.CTRL;
178 spec[SpecNodeName.NAME] = 'ctrl';
179 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
180 spec[SpecNodeName.ID] = 'ControlLeft';
181 return i18n.input.chrome.inputview.content.util.createKey(spec);
188 * @return {!Object} The alt key.
190 i18n.input.chrome.inputview.content.util.createAltKey = function() {
192 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.ALT;
193 spec[SpecNodeName.NAME] = 'alt';
194 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
195 spec[SpecNodeName.ID] = 'AltLeft';
196 return i18n.input.chrome.inputview.content.util.createKey(spec);
201 * Creates a altgr key.
203 * @return {!Object} The altgr key.
205 i18n.input.chrome.inputview.content.util.createAltgrKey = function() {
207 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.ALTGR;
208 spec[SpecNodeName.NAME] = 'alt gr';
209 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
210 spec[SpecNodeName.ID] = 'AltRight';
211 return i18n.input.chrome.inputview.content.util.createKey(spec);
216 * Creates a key used to switch to english.
218 * @return {!Object} The enSwitcher key.
220 i18n.input.chrome.inputview.content.util.createEnSwitcherKey =
223 spec[SpecNodeName.TYPE] = ElementType.EN_SWITCHER;
224 spec[SpecNodeName.ID] = 'enSwitcher';
225 return i18n.input.chrome.inputview.content.util.createKey(spec);
230 * Creates a capslock key.
232 * @return {!Object} The capslock key.
234 i18n.input.chrome.inputview.content.util.createCapslockKey = function() {
236 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.CAPSLOCK;
237 spec[SpecNodeName.NAME] = 'caps lock';
238 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;
239 spec[SpecNodeName.ID] = 'OsLeft';
240 return i18n.input.chrome.inputview.content.util.createKey(spec);
245 * Creates a enter key.
247 * @return {!Object} The enter key.
249 i18n.input.chrome.inputview.content.util.createEnterKey = function() {
251 spec[SpecNodeName.ICON_CSS_CLASS] =
252 i18n.input.chrome.inputview.Css.ENTER_ICON;
253 spec[SpecNodeName.TYPE] = ElementType.ENTER_KEY;
254 spec[SpecNodeName.ID] = 'Enter';
255 return i18n.input.chrome.inputview.content.util.createKey(spec);
262 * @return {!Object} The tab key.
264 i18n.input.chrome.inputview.content.util.createTabKey = function() {
266 spec[SpecNodeName.ICON_CSS_CLASS] = i18n.input.chrome.inputview.Css.TAB_ICON;
267 spec[SpecNodeName.TYPE] = ElementType.TAB_KEY;
268 spec[SpecNodeName.ID] = 'Tab';
269 return i18n.input.chrome.inputview.content.util.createKey(spec);
274 * Creates a backspace key.
276 * @return {!Object} The backspace key.
278 i18n.input.chrome.inputview.content.util.createBackspaceKey = function() {
280 spec[SpecNodeName.ICON_CSS_CLASS] =
281 i18n.input.chrome.inputview.Css.BACKSPACE_ICON;
282 spec[SpecNodeName.TYPE] = ElementType.BACKSPACE_KEY;
283 spec[SpecNodeName.ID] = 'Backspace';
284 return i18n.input.chrome.inputview.content.util.createKey(spec);
289 * Creates a space key.
291 * @return {!Object} The space key.
293 i18n.input.chrome.inputview.content.util.createSpaceKey = function() {
295 spec[SpecNodeName.NAME] = ' ';
296 spec[SpecNodeName.TYPE] = ElementType.SPACE_KEY;
297 spec[SpecNodeName.ID] = 'Space';
298 return i18n.input.chrome.inputview.content.util.createKey(spec);
303 * Create an IME switch key.
305 * @param {string} id .
306 * @param {string} name .
307 * @param {string} css .
308 * @return {!Object} The JP IME switch key.
310 i18n.input.chrome.inputview.content.util.createIMESwitchKey =
311 function(id, name, css) {
313 spec[SpecNodeName.NAME] = name;
314 spec[SpecNodeName.TYPE] = ElementType.IME_SWITCH;
315 spec[SpecNodeName.ID] = id;
316 spec[SpecNodeName.TEXT_CSS_CLASS] = css;
317 return i18n.input.chrome.inputview.content.util.createKey(spec);
322 * Creates a normal key.
324 * @param {!Object} spec The specification.
325 * @return {!Object} The normal key.
327 i18n.input.chrome.inputview.content.util.createNormalKey = function(spec) {
328 spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY;
329 return i18n.input.chrome.inputview.content.util.createKey(spec);
334 * Creates an arrow key.
336 * @param {!i18n.input.chrome.inputview.Direction} direction The direction.
337 * @return {!Object} The arrow key.
339 i18n.input.chrome.inputview.content.util.createArrowKey = function(direction) {
341 spec[SpecNodeName.ICON_CSS_CLASS] =
342 i18n.input.chrome.inputview.Css.ARROW_KEY + ' ';
343 if (direction == i18n.input.chrome.inputview.Direction.UP) {
344 spec[SpecNodeName.ID] = 'ArrowUp';
345 spec[SpecNodeName.ICON_CSS_CLASS] += i18n.input.chrome.inputview.Css.UP_KEY;
346 spec[SpecNodeName.TYPE] = ElementType.ARROW_UP;
347 } else if (direction == i18n.input.chrome.inputview.Direction.DOWN) {
348 spec[SpecNodeName.ID] = 'ArrowDown';
349 spec[SpecNodeName.ICON_CSS_CLASS] +=
350 i18n.input.chrome.inputview.Css.DOWN_KEY;
351 spec[SpecNodeName.TYPE] = ElementType.ARROW_DOWN;
352 } else if (direction == i18n.input.chrome.inputview.Direction.LEFT) {
353 spec[SpecNodeName.ID] = 'ArrowLeft';
354 spec[SpecNodeName.ICON_CSS_CLASS] +=
355 i18n.input.chrome.inputview.Css.LEFT_KEY;
356 spec[SpecNodeName.TYPE] = ElementType.ARROW_LEFT;
357 } else if (direction == i18n.input.chrome.inputview.Direction.RIGHT) {
358 spec[SpecNodeName.ID] = 'ArrowRight';
359 spec[SpecNodeName.ICON_CSS_CLASS] +=
360 i18n.input.chrome.inputview.Css.RIGHT_KEY;
361 spec[SpecNodeName.TYPE] = ElementType.ARROW_RIGHT;
363 return i18n.input.chrome.inputview.content.util.createKey(spec);
368 * Creates a soft key.
370 * @param {!Object} spec The specification.
371 * @return {!Object} The soft key.
373 i18n.input.chrome.inputview.content.util.createKey = function(spec) {
375 for (var key in spec) {
376 newSpec[key] = spec[key];
385 * The physical key codes.
387 * @type {!Array.<string>}
389 i18n.input.chrome.inputview.content.util.KEY_CODES_101 = [
441 * The physical key codes for 102 keyboard.
443 * @type {!Array.<string>}
445 i18n.input.chrome.inputview.content.util.KEY_CODES_102 = [
498 * Creates the key data.
500 * @param {!Array.<!Array.<string>>} keyCharacters The key characters.
501 * @param {string} viewIdPrefix The prefix of the view.
502 * @param {boolean} is102 True if it is a 102 keyboard.
503 * @param {boolean} hasAltGrKey True if there is altgr key.
504 * @param {!Array.<!Array.<number>>=} opt_keyCodes The key codes.
505 * @param {string=} opt_compactKeyboardId The compact keyboard id.
506 * @return {!Object} The key data.
508 i18n.input.chrome.inputview.content.util.createData = function(keyCharacters,
509 viewIdPrefix, is102, hasAltGrKey, opt_keyCodes, opt_compactKeyboardId) {
512 var keyCodes = opt_keyCodes || [];
513 var keyIds = is102 ? i18n.input.chrome.inputview.content.util.KEY_CODES_102 :
514 i18n.input.chrome.inputview.content.util.KEY_CODES_101;
515 // The keys shows the shift character in Default state. In material design,
516 // Only the first 11 keys will show shift character.
517 var keysShowShift = 11;
518 for (var i = 0; i < keyCharacters.length - 1; i++) {
520 spec[SpecNodeName.ID] = keyIds[i];
521 spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY;
522 spec[SpecNodeName.CHARACTERS] = keyCharacters[i];
523 spec[SpecNodeName.KEY_CODE] = keyCodes[i];
524 if (i < keysShowShift) {
525 spec[SpecNodeName.ENABLE_SHIFT_RENDERING] = true;
527 var key = i18n.input.chrome.inputview.content.util.createKey(spec);
531 i18n.input.chrome.inputview.content.util.insertModifierKeys_(keyList,
532 is102, opt_compactKeyboardId);
533 for (var i = 0; i < keyList.length; i++) {
534 var key = keyList[i];
535 mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + i;
537 var layout = is102 ? '102kbd' : '101kbd';
539 result[SpecNodeName.KEY_LIST] = keyList;
540 result[SpecNodeName.MAPPING] = mapping;
541 result[SpecNodeName.LAYOUT] = layout;
542 result[SpecNodeName.HAS_ALTGR_KEY] = hasAltGrKey;
543 result[SpecNodeName.SHOW_MENU_KEY] = true;
549 * Creates a switcher key which will switch between keyboards.
551 * @param {string} id The id.
552 * @param {string} name The name.
553 * @param {string|undefined} toKeyset The id of keyset this swicher key should
555 * @param {string} toKeysetName The name of the keyset.
556 * @param {string=} opt_iconCssClass The css class for the icon.
557 * @param {boolean=} opt_record True to record and next time the keyset will
559 * @return {!Object} The switcher key.
561 i18n.input.chrome.inputview.content.util.createSwitcherKey = function(
562 id, name, toKeyset, toKeysetName, opt_iconCssClass, opt_record) {
564 spec[SpecNodeName.ID] = id;
565 spec[SpecNodeName.NAME] = name;
566 spec[SpecNodeName.TO_KEYSET] = toKeyset;
567 spec[SpecNodeName.TO_KEYSET_NAME] = toKeysetName;
568 spec[SpecNodeName.ICON_CSS_CLASS] = opt_iconCssClass;
569 spec[SpecNodeName.TYPE] = ElementType.SWITCHER_KEY;
570 spec[SpecNodeName.RECORD] = !!opt_record;
571 return i18n.input.chrome.inputview.content.util.createKey(spec);
576 * Inserts modifier keys into the key list.
578 * @param {!Array.<!Object>} keyList The key list.
579 * @param {boolean} is102 True if it is a 102 keyboard.
580 * @param {string=} opt_compactKeyboardId The compact keyboard id.
583 i18n.input.chrome.inputview.content.util.insertModifierKeys_ = function(
584 keyList, is102, opt_compactKeyboardId) {
585 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
586 createBackspaceKey(), 13);
587 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
589 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
590 createCapslockKey(), is102 ? 27 : 28);
591 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
592 createEnterKey(), 40);
593 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.
594 createShiftKey(true), 41);
595 keyList.push(i18n.input.chrome.inputview.content.util.createShiftKey(false));
596 i18n.input.chrome.inputview.content.util.addLastRowKeys(
597 keyList, is102, opt_compactKeyboardId);
602 * Inserts modifier keys into the key list.
604 * @param {!Array.<!Object>} keyList The key list.
605 * @param {boolean} is102 True if it is a 102 keyboard.
606 * @param {string=} opt_compactKeyboardId The compact keyboard id.
608 i18n.input.chrome.inputview.content.util.addLastRowKeys =
609 function(keyList, is102, opt_compactKeyboardId) {
610 keyList.push(i18n.input.chrome.inputview.content.util.createGlobeKey());
611 keyList.push(i18n.input.chrome.inputview.content.util.createMenuKey(
612 opt_compactKeyboardId));
613 keyList.push(i18n.input.chrome.inputview.content.util.createCtrlKey());
614 keyList.push(i18n.input.chrome.inputview.content.util.createAltKey());
615 keyList.push(i18n.input.chrome.inputview.content.util.createSpaceKey());
616 keyList.push(i18n.input.chrome.inputview.content.util.createEnSwitcherKey());
617 keyList.push(i18n.input.chrome.inputview.content.util.createAltgrKey());
618 keyList.push(i18n.input.chrome.inputview.content.util.createArrowKey(
619 i18n.input.chrome.inputview.Direction.LEFT));
620 keyList.push(i18n.input.chrome.inputview.content.util.createArrowKey(
621 i18n.input.chrome.inputview.Direction.RIGHT));
622 keyList.push(i18n.input.chrome.inputview.content.util.
623 createHideKeyboardKey());