OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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. |
| 4 |
| 5 /** |
| 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; |
| 47 var y = window.innerHeight; |
| 48 return (x > getKeyboardAspect() * y) ? |
| 49 y : Math.floor(x / getKeyboardAspect()); |
| 50 } |
| 51 |
| 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 }; |
| 128 |
| 129 /** |
| 130 * Init the keyboard. |
| 131 */ |
| 132 var mainDiv = null; |
| 133 |
| 134 /** |
| 135 * Initialize keyboard. |
| 136 */ |
| 137 window.onload = function() { |
| 138 var body = $('b'); |
| 139 |
| 140 // Catch all unhandled touch events and prevent default, to prevent the |
| 141 // keyboard from responding to gestures like double tap. |
| 142 function disableGestures(evt) { |
| 143 evt.preventDefault(); |
| 144 } |
| 145 body.addEventListener('touchstart', disableGestures); |
| 146 body.addEventListener('touchmove', disableGestures); |
| 147 body.addEventListener('touchend', disableGestures); |
| 148 |
| 149 mainDiv = document.createElement('div'); |
| 150 mainDiv.className = 'main'; |
| 151 mainDiv.id = 'main'; |
| 152 body.appendChild(mainDiv); |
| 153 |
| 154 initKeyboard(currentKeyboardLayout, mainDiv); |
| 155 |
| 156 window.onhashchange(); |
| 157 }; |
| 158 |
| 159 /** |
| 160 * Switch the keyboard layout based on the current URL hash. |
| 161 */ |
| 162 window.onhashchange = function() { |
| 163 var oldLayout = currentKeyboardLayout; |
| 164 var newLayout = location.hash.replace(/^#/, ''); |
| 165 if (oldLayout == newLayout) { |
| 166 return; |
| 167 } |
| 168 |
| 169 if (KEYBOARDS[newLayout] === undefined) { |
| 170 // Unsupported layout. |
| 171 newLayout = 'us'; |
| 172 } |
| 173 currentKeyboardLayout = newLayout; |
| 174 |
| 175 var mainDiv = $('main'); |
| 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 |