Home | History | Annotate | Download | only in elements
      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 {?Object.{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