// 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;
}
},
});
})();