OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 var onResize = function() { |
6 * @fileoverview A simple virtual keyboard implementation. | |
7 */ | |
8 | |
9 /** | |
10 * The ratio of the row height to the font size. | |
11 * @type {number} | |
12 */ | |
13 /** @const */ var kFontSizeRatio = 3.5; | |
14 | |
15 /** | |
16 * Alias for document.getElementById. | |
17 * @param {string} id The ID of the element to find. | |
18 * @return {HTMLElement} The found element or null if not found. | |
19 */ | |
20 function $(id) { | |
21 return document.getElementById(id); | |
22 } | |
23 | |
24 /** | |
25 * Return the id attribute of the keyboard element for the given layout. | |
26 * @param {string} layout The keyboard layout. | |
27 * @return {string} The id attribute of the keyboard element. | |
28 */ | |
29 function getKeyboardId(layout) { | |
30 return 'keyboard_' + layout; | |
31 } | |
32 | |
33 /** | |
34 * Return the aspect ratio of the current keyboard. | |
35 * @return {number} The aspect ratio of the current keyboard. | |
36 */ | |
37 function getKeyboardAspect() { | |
38 return KEYBOARDS[currentKeyboardLayout]['aspect']; | |
39 } | |
40 | |
41 /** | |
42 * Calculate the height of the keyboard based on the size of the page. | |
43 * @return {number} The height of the keyboard in pixels. | |
44 */ | |
45 function getKeyboardHeight() { | |
46 var x = window.innerWidth; | 6 var x = window.innerWidth; |
47 var y = window.innerHeight; | 7 var y = window.innerHeight; |
48 return (x > getKeyboardAspect() * y) ? | 8 var height = (x > ASPECT_RATIO * y) ? y : Math.floor(x / ASPECT_RATIO); |
49 y : Math.floor(x / getKeyboardAspect()); | 9 keyboard.style.height = height + 'px'; |
50 } | 10 keyboard.style.width = Math.floor(ASPECT_RATIO * height) + 'px'; |
51 | 11 keyboard.style.fontSize = (height / FONT_SIZE_RATIO / ROW_LENGTH) + 'px'; |
52 /** | |
53 * Create a DOM of the keyboard rows for the given keyboard layout. | |
54 * Do nothing if the DOM is already created. | |
55 * @param {string} layout The keyboard layout for which rows are created. | |
56 * @param {Element} element The DOM Element to which rows are appended. | |
57 * @param {boolean} autoPadding True if padding needs to be added to both side | |
58 * of the rows that have less keys. | |
59 */ | |
60 function initRows(layout, element, autoPadding) { | |
61 var keyboard = KEYBOARDS[layout]; | |
62 if ('rows' in keyboard) { | |
63 return; | |
64 } | |
65 var def = keyboard['definition']; | |
66 var rows = []; | |
67 for (var i = 0; i < def.length; ++i) { | |
68 rows.push(new Row(i, def[i])); | |
69 } | |
70 keyboard['rows'] = rows; | |
71 | |
72 var maxRowLength = -1; | |
73 for (var i = 0; i < rows.length; ++i) { | |
74 if (rows[i].length > maxRowLength) { | |
75 maxRowLength = rows[i].length; | |
76 } | |
77 } | |
78 | |
79 // A div element which holds rows for the layout. | |
80 var rowsDiv = document.createElement('div'); | |
81 rowsDiv.className = 'rows'; | |
82 for (var i = 0; i < rows.length; ++i) { | |
83 var rowDiv = rows[i].makeDOM(); | |
84 if (autoPadding && rows[i].length < maxRowLength) { | |
85 var padding = 50 * (maxRowLength - rows[i].length) / maxRowLength; | |
86 rowDiv.style.paddingLeft = padding + '%'; | |
87 rowDiv.style.paddingRight = padding + '%'; | |
88 } | |
89 rowsDiv.appendChild(rowDiv); | |
90 rows[i].showMode(currentMode); | |
91 } | |
92 keyboard['rowsDiv'] = rowsDiv; | |
93 element.appendChild(rowsDiv); | |
94 } | |
95 | |
96 /** | |
97 * Create a DOM of the keyboard for the given keyboard layout. | |
98 * Do nothing if the DOM is already created. | |
99 * @param {string} layout The keyboard layout for which keyboard is created. | |
100 * @param {Element} element The DOM Element to which keyboard is appended. | |
101 */ | |
102 function initKeyboard(layout, element) { | |
103 var keyboard = KEYBOARDS[layout]; | |
104 if (!keyboard || keyboard['keyboardDiv']) { | |
105 return; | |
106 } | |
107 var keyboardDiv = document.createElement('div'); | |
108 keyboardDiv.id = getKeyboardId(layout); | |
109 keyboardDiv.className = 'keyboard'; | |
110 initRows(layout, keyboardDiv); | |
111 keyboard['keyboardDiv'] = keyboardDiv; | |
112 window.onresize(); | |
113 element.appendChild(keyboardDiv); | |
114 } | |
115 | |
116 /** | |
117 * Resize the keyboard according to the new window size. | |
118 */ | |
119 window.onresize = function() { | |
120 var keyboardDiv = KEYBOARDS[currentKeyboardLayout]['keyboardDiv']; | |
121 var height = getKeyboardHeight(); | |
122 keyboardDiv.style.height = height + 'px'; | |
123 var mainDiv = $('main'); | |
124 mainDiv.style.width = Math.floor(getKeyboardAspect() * height) + 'px'; | |
125 var rowsLength = KEYBOARDS[currentKeyboardLayout]['rows'].length; | |
126 keyboardDiv.style.fontSize = (height / kFontSizeRatio / rowsLength) + 'px'; | |
127 }; | 12 }; |
128 | 13 |
129 /** | 14 /** |
130 * Init the keyboard. | 15 * Send the given key to chrome. |
131 */ | 16 */ |
132 var mainDiv = null; | 17 function sendKey(key) { |
| 18 var keyIdentifier = key; |
133 | 19 |
134 /** | 20 // Fix up some keys to their respective identifiers for convenience. |
135 * Initialize keyboard. | 21 if (keyIdentifier == ' ') { |
136 */ | 22 keyIdentifier = 'Spacebar'; |
137 window.onload = function() { | 23 } |
138 var body = $('b'); | |
139 | 24 |
140 // Catch all unhandled touch events and prevent default, to prevent the | 25 var keyEvent = { |
141 // keyboard from responding to gestures like double tap. | 26 keyIdentifier: keyIdentifier |
142 function disableGestures(evt) { | 27 }; |
143 evt.preventDefault(); | |
144 } | |
145 body.addEventListener('touchstart', disableGestures); | |
146 body.addEventListener('touchmove', disableGestures); | |
147 body.addEventListener('touchend', disableGestures); | |
148 | 28 |
149 mainDiv = document.createElement('div'); | 29 sendKeyEvent(keyEvent); |
150 mainDiv.className = 'main'; | |
151 mainDiv.id = 'main'; | |
152 body.appendChild(mainDiv); | |
153 | |
154 initKeyboard(currentKeyboardLayout, mainDiv); | |
155 | |
156 window.onhashchange(); | |
157 }; | 30 }; |
158 | 31 |
159 /** | 32 addEventListener('WebComponentsReady', function() { |
160 * Switch the keyboard layout based on the current URL hash. | 33 keyboard.appendChild( |
161 */ | 34 keysets.content.body.firstElementChild.createInstance()); |
162 window.onhashchange = function() { | 35 }); |
163 var oldLayout = currentKeyboardLayout; | |
164 var newLayout = location.hash.replace(/^#/, ''); | |
165 if (oldLayout == newLayout) { | |
166 return; | |
167 } | |
168 | 36 |
169 if (KEYBOARDS[newLayout] === undefined) { | 37 addEventListener('resize', onResize); |
170 // Unsupported layout. | |
171 newLayout = 'us'; | |
172 } | |
173 currentKeyboardLayout = newLayout; | |
174 | 38 |
175 var mainDiv = $('main'); | 39 addEventListener('load', onResize); |
176 initKeyboard(currentKeyboardLayout, mainDiv); | |
177 | |
178 [newLayout, oldLayout].forEach(function(layout) { | |
179 var visible = (layout == newLayout); | |
180 var keyboardDiv = KEYBOARDS[layout]['keyboardDiv']; | |
181 keyboardDiv.className = visible ? 'keyboard' : 'nodisplay'; | |
182 var canvas = KEYBOARDS[layout]['canvas']; | |
183 if (canvas !== undefined) { | |
184 if (!visible) { | |
185 canvas.clear(); | |
186 } | |
187 } | |
188 if (visible) { | |
189 window.onresize(); | |
190 } | |
191 }); | |
192 }; | |
OLD | NEW |