• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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