1// Copyright 2014 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(function() { 6 var altKeys = {}; 7 var idMap = {}; 8 9 /** 10 * Creates a unique identifier based on the key provided. 11 * This identifier is of the form 'idHASH' where HASH is 12 * the concatenation of the keycodes of every character in the string. 13 * @param {string} key Key for which we want an identifier. 14 * @return {string} The unique id for key. 15 */ 16 function createId(key) { 17 var hash = key.split('').map( 18 // Returns the key code for the character. 19 function(character) { 20 return character.charCodeAt(0); 21 } 22 ).join(''); 23 return 'id' + hash; 24 } 25 26 Polymer('kb-altkey-data', { 27 28 /** 29 * Retrieves a list of alternative keys to display on a long-press. 30 * @param {string} char The base character. 31 * @param {boolean=} opt_force If true, force the creation of a list 32 * even if empty. Used when constructing a set of alternates for keys 33 * with hintTexts. 34 * @return {?{id: string, list: string}} 35 */ 36 getAltkeys: function(char, opt_force) { 37 var id = idMap[char]; 38 if (id) { 39 return { 40 'id': id, 41 'keys': altKeys[id] 42 }; 43 } 44 if (opt_force) { 45 return { 46 'id': createId(char), 47 'keys': [] 48 }; 49 } 50 }, 51 52 /** 53 * Registers lists of alternative keys displayed on a long-press. 54 * @param {Object.<string, Array.<string>>} data Mapping of characters to 55 * lists of alternatives. 56 */ 57 registerAltkeys: function(data) { 58 for (var key in data) { 59 var id = idMap[key]; 60 if (!id) 61 idMap[key] = id = createId(key); 62 altKeys[id] = data[key]; 63 } 64 }, 65 66 /** 67 * Creates a list of alternate candidates to display in a popup on a 68 * long-press. 69 * @param {string} char The base character. 70 * @param {number} maxLeftOffset Limits the number of candidates 71 * displayed to the left of the base character to prevent running 72 * past the left edge of the keyboard. 73 * @param {number} maxRightOffset Limits the number of candidates 74 * displayed to the right of the base character to prvent running 75 * past the right edge of the keyboard. 76 * @param {string=} opt_additionalKeys Optional list of additional keys 77 * to include in the candidates list. 78 */ 79 createAltkeySet: function(char, 80 maxLeftOffset, 81 maxRightOffset, 82 opt_additionalKeys) { 83 var altKeys = this.getAltkeys(char, true /* forced */); 84 if (altKeys) { 85 var list = altKeys.keys; 86 if (opt_additionalKeys) 87 list = opt_additionalKeys.split('').concat(list); 88 list = [char].concat(list); 89 90 var set = document.createElement('kb-altkey-set'); 91 // Candiates are approximately in decreasing order of usage, and are 92 // arranged in a single row in the popup display. To reduce the 93 // expected length of the drag gesture for selecting a candidate, 94 // more likely candidates are placed in the center of the popup, 95 // which is achieved by alternately appending and prepending 96 // candiates in the alternatives popup. 97 var prepend = false; 98 var leftOffset = 0; 99 var rightOffset = 0; 100 for (var i = 0; i < list.length; i++) { 101 var key = document.createElement('kb-altkey'); 102 key.textContent = list[i]; 103 if (prepend) { 104 set.insertBefore(key, set.firstChild); 105 leftOffset++; 106 } else { 107 set.appendChild(key); 108 rightOffset++; 109 } 110 prepend = !prepend; 111 // Verify that there is room remaining for an additional character. 112 if (leftOffset == maxLeftOffset && rightOffset == maxRightOffset) 113 break; 114 if (leftOffset == maxLeftOffset) 115 prepend = false; 116 else if (rightOffset == maxRightOffset) 117 prepend = true; 118 } 119 set.id = altKeys.id; 120 set.offset = leftOffset; 121 return set; 122 } 123 }, 124 125 }); 126})(); 127