| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| (function() { |
| var altKeys = {}; |
| var idMap = {}; |
| |
| /** |
| * Creates a unique identifier based on the key provided. |
| * This identifier is of the form 'idHASH' where HASH is |
| * the concatenation of the keycodes of every character in the string. |
| * @param {string} key Key for which we want an identifier. |
| * @return {string} The unique id for key. |
| */ |
| function createId(key) { |
| var hash = key.split('').map( |
| // Returns the key code for the character. |
| function(character) { |
| return character.charCodeAt(0); |
| } |
| ).join(''); |
| return 'id' + hash; |
| } |
| |
| Polymer('kb-altkey-data', { |
| |
| /** |
| * Retrieves a list of alternative keys to display on a long-press. |
| * @param {string} char The base character. |
| * @param {boolean=} opt_force If true, force the creation of a list |
| * even if empty. Used when constructing a set of alternates for keys |
| * with hintTexts. |
| * @return {?{id: string, list: string}} |
| */ |
| getAltkeys: function(char, opt_force) { |
| var id = idMap[char]; |
| if (id) { |
| return { |
| 'id': id, |
| 'keys': altKeys[id] |
| }; |
| } |
| if (opt_force) { |
| return { |
| 'id': createId(char), |
| 'keys': [] |
| }; |
| } |
| }, |
| |
| /** |
| * Registers lists of alternative keys displayed on a long-press. |
| * @param {Object.<string, Array.<string>>} data Mapping of characters to |
| * lists of alternatives. |
| */ |
| registerAltkeys: function(data) { |
| for (var key in data) { |
| var id = idMap[key]; |
| if (!id) |
| idMap[key] = id = createId(key); |
| altKeys[id] = data[key]; |
| } |
| }, |
| |
| /** |
| * Creates a list of alternate candidates to display in a popup on a |
| * long-press. |
| * @param {string} char The base character. |
| * @param {number} maxLeftOffset Limits the number of candidates |
| * displayed to the left of the base character to prevent running |
| * past the left edge of the keyboard. |
| * @param {number} maxRightOffset Limits the number of candidates |
| * displayed to the right of the base character to prvent running |
| * past the right edge of the keyboard. |
| * @param {string=} opt_additionalKeys Optional list of additional keys |
| * to include in the candidates list. |
| */ |
| createAltkeySet: function(char, |
| maxLeftOffset, |
| maxRightOffset, |
| opt_additionalKeys) { |
| var altKeys = this.getAltkeys(char, true /* forced */); |
| if (altKeys) { |
| var list = altKeys.keys; |
| if (opt_additionalKeys) |
| list = opt_additionalKeys.split('').concat(list); |
| list = [char].concat(list); |
| |
| var set = document.createElement('kb-altkey-set'); |
| // Candiates are approximately in decreasing order of usage, and are |
| // arranged in a single row in the popup display. To reduce the |
| // expected length of the drag gesture for selecting a candidate, |
| // more likely candidates are placed in the center of the popup, |
| // which is achieved by alternately appending and prepending |
| // candiates in the alternatives popup. |
| var prepend = false; |
| var leftOffset = 0; |
| var rightOffset = 0; |
| for (var i = 0; i < list.length; i++) { |
| var key = document.createElement('kb-altkey'); |
| key.textContent = list[i]; |
| if (prepend) { |
| set.insertBefore(key, set.firstChild); |
| leftOffset++; |
| } else { |
| set.appendChild(key); |
| rightOffset++; |
| } |
| prepend = !prepend; |
| // Verify that there is room remaining for an additional character. |
| if (leftOffset == maxLeftOffset && rightOffset == maxRightOffset) |
| break; |
| if (leftOffset == maxLeftOffset) |
| prepend = false; |
| else if (rightOffset == maxRightOffset) |
| prepend = true; |
| } |
| set.id = altKeys.id; |
| set.offset = leftOffset; |
| return set; |
| } |
| }, |
| |
| }); |
| })(); |