Switch TestFrameNavigationObserver to DidCommitProvisionalLoadForFrame.
[chromium-blink-merge.git] / third_party / google_input_tools / src / chrome / os / inputview / util.js
blobc8ee4bd697ab642fbcdb17436b63980a730f8322
1 // Copyright 2014 The ChromeOS IME Authors. All Rights Reserved.
2 // limitations under the License.
3 // See the License for the specific language governing permissions and
4 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5 // distributed under the License is distributed on an "AS-IS" BASIS,
6 // Unless required by applicable law or agreed to in writing, software
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // You may obtain a copy of the License at
11 // you may not use this file except in compliance with the License.
12 // Licensed under the Apache License, Version 2.0 (the "License");
14 goog.provide('i18n.input.chrome.inputview.util');
16 goog.require('goog.string');
17 goog.require('goog.style');
20 goog.scope(function() {
21 var util = i18n.input.chrome.inputview.util;
24 /**
25 * The mapping between the real character and its replacement for display.
27 * @type {!Object.<string, string>}
29 util.DISPLAY_MAPPING = {
30 '\u0300' : '\u0060',
31 '\u0301' : '\u00B4',
32 '\u0302' : '\u02C6',
33 '\u0303' : '\u02DC',
34 '\u0304' : '\u02c9',
35 '\u0305' : '\u00AF',
36 '\u0306' : '\u02D8',
37 '\u0307' : '\u02D9',
38 '\u0308' : '\u00a8',
39 '\u0309' : '\u02C0',
40 '\u030A' : '\u02DA',
41 '\u030B' : '\u02DD',
42 '\u030C' : '\u02C7',
43 '\u030D' : '\u02C8',
44 '\u030E' : '\u0022',
45 '\u0327' : '\u00B8',
46 '\u0328' : '\u02DB',
47 '\u0345' : '\u037A',
48 '\u030F' : '\u030F\u0020',
49 '\u031B' : '\u031B\u0020',
50 '\u0323' : '\u0323\u0020'
54 /**
55 * The keysets using US keyboard layouts.
57 * @type {!Array.<string>}
59 util.KEYSETS_USE_US = [
60 'array',
61 'cangjie',
62 'dayi',
63 'jp_us',
64 'pinyin-zh-CN',
65 'pinyin-zh-TW',
66 'quick',
67 't13n',
68 'wubi'
72 /**
73 * The keysets that have en switcher key.
75 * @type {!Array.<string>}
77 util.KEYSETS_HAVE_EN_SWTICHER = [
78 // When other keysets that use us add the enswitcher key,
79 // should move them to this array.
80 'array',
81 'cangjie',
82 'dayi',
83 'pinyin-zh-CN',
84 'pinyin-zh-TW',
85 'quick',
86 'wubi',
87 'zhuyin'
91 /**
92 * The keysets that have compact keyset.
94 * @type {!Array.<string>}
96 util.KEYSETS_HAVE_COMPACT = [
97 'ca',
98 'ca-eng',
99 'de',
100 'dk',
101 'fi',
102 'fr',
103 'gb-extd',
104 'ie',
105 'is',
106 'nl',
107 'no',
108 'pinyin-zh-CN',
109 'se',
110 'us',
111 'zhuyin'
116 * A regular expression for the end of a sentence.
118 * @private {!RegExp}
120 util.END_SENTENCE_REGEX_ = /[\.\?!] +$/;
124 * The regex of characters support dead key.
126 * @type {!RegExp}
127 * @private
129 util.REGEX_CHARACTER_SUPPORT_DEADKEY_ =
130 /^[a-zA-ZæÆœŒΑΕΗΙΟΥΩαεηιυοωϒ]+$/;
134 * The regex of characters supported in language module.
136 * @type {!RegExp}
138 util.REGEX_LANGUAGE_MODEL_CHARACTERS =
139 /(?=[^\u00d7\u00f7])[a-z\-\'\u00c0-\u017F]/i;
143 * Splits a value to pieces according to the weights.
145 * @param {!Array.<number>} weightArray The weight array.
146 * @param {number} totalValue The total value.
147 * @return {!Array.<number>} The splitted values.
149 util.splitValue = function(weightArray, totalValue) {
150 if (weightArray.length == 0) {
151 return [];
154 if (weightArray.length == 1) {
155 return [totalValue];
158 var totalWeight = 0;
159 for (var i = 0; i < weightArray.length; i++) {
160 totalWeight += weightArray[i];
162 var tmp = totalValue / totalWeight;
163 var values = [];
164 var totalFlooredValue = 0;
165 var diffs = [];
166 for (var i = 0; i < weightArray.length; i++) {
167 var result = weightArray[i] * tmp;
168 values.push(result);
169 diffs.push(result - Math.floor(result));
170 totalFlooredValue += Math.floor(result);
172 var diff = totalValue - totalFlooredValue;
174 // Distributes the rest pixels to values who lose most.
175 for (var i = 0; i < diff; i++) {
176 var max = 0;
177 var index = 0;
178 for (var j = 0; j < diffs.length; j++) {
179 if (diffs[j] > max) {
180 max = diffs[j];
181 index = j;
184 values[index] += 1;
185 diffs[index] = 0;
187 for (var i = 0; i < values.length; i++) {
188 values[i] = Math.floor(values[i]);
190 return values;
195 * Gets the value of a property.
197 * @param {Element} elem The element.
198 * @param {string} property The property name.
199 * @return {number} The value.
201 util.getPropertyValue = function(elem, property) {
202 var value = goog.style.getComputedStyle(elem, property);
203 if (value) {
204 return parseInt(value.replace('px', ''), 10);
206 return 0;
211 * To upper case.
213 * @param {string} character The character.
214 * @return {string} The uppercase of the character.
216 util.toUpper = function(character) {
217 if (character == '\u00b5') {
218 return '\u00b5';
219 } else {
220 return character.toUpperCase();
226 * To lower case.
228 * @param {string} character The character.
229 * @return {string} The lower case of the character.
231 util.toLower = function(character) {
232 if (character == '\u0049') {
233 return '\u0131';
235 return character.toLowerCase();
240 * Is this character trigger commit.
242 * @param {string} character The character.
243 * @return {boolean} True to trigger commit.
245 util.isCommitCharacter = function(character) {
246 if (util.DISPLAY_MAPPING[character] ||
247 util.REGEX_LANGUAGE_MODEL_CHARACTERS.test(
248 character)) {
249 return false;
252 return true;
257 * Some unicode character can't be shown in the web page, use a replacement
258 * instead.
260 * @param {string} invisibleCharacter The character can't be shown.
261 * @return {string} The replacement.
263 util.getVisibleCharacter = function(invisibleCharacter) {
264 var map = util.DISPLAY_MAPPING;
265 if (map[invisibleCharacter]) {
266 return map[invisibleCharacter];
268 // For non-spacing marks (e.g. \u05b1), ChromeOS cannot display it correctly
269 // until there is a character before it to combine with.
270 if (/[\u0591-\u05cf]/.test(invisibleCharacter)) {
271 return '\u00a0' + invisibleCharacter;
273 return invisibleCharacter;
278 * Whether this is a letter key.
280 * @param {!Array.<string>} characters The characters.
281 * @return {boolean} True if this is a letter key.
283 util.isLetterKey = function(characters) {
284 if (characters[1] == util.toUpper(
285 characters[0]) || characters[1] == util.
286 toLower(characters[0])) {
287 return true;
289 return false;
294 * True if this character supports dead key combination.
296 * @param {string} character The character.
297 * @return {boolean} True if supports the dead key combination.
299 util.supportDeadKey = function(character) {
300 return util.REGEX_CHARACTER_SUPPORT_DEADKEY_.
301 test(character);
306 * True if we need to do the auto-capitalize.
308 * @param {string} text .
309 * @return {boolean} .
311 util.needAutoCap = function(text) {
312 if (goog.string.isEmptyOrWhitespace(text)) {
313 return false;
314 } else {
315 return util.END_SENTENCE_REGEX_.test(text);
321 * Returns the configuration file name from the keyboard code.
323 * @param {string} keyboardCode The keyboard code.
324 * @return {string} The config file name which contains the keyset.
326 util.getConfigName = function(keyboardCode) {
327 // Strips out all the suffixes in the keyboard code.
328 return keyboardCode.replace(/\..*$/, '');
333 * Checks that the word is a valid delete from the old to new context.
335 * @param {string} oldContext The old context.
336 * @param {string} newContext The new context.
337 * @param {string} deletionCandidate A possible word deletion.
339 * @return {boolean} Whether the deletion was valid.
341 util.isPossibleDelete = function(
342 oldContext, newContext, deletionCandidate) {
343 // Check that deletionCandidate exists in oldContext. We don't check if it's a
344 // tail since our heuristic may have trimmed whitespace.
345 var rootEnd = oldContext.lastIndexOf(deletionCandidate);
346 if (rootEnd != -1) {
347 // Check that remaining text in root persisted in newContext.
348 var root = oldContext.slice(0, rootEnd);
349 return root == newContext.slice(-rootEnd);
351 return false;
356 * Checks whether a letter deletion would cause the observed context transform.
358 * @param {string} oldContext The old context.
359 * @param {string} newContext The new context.
361 * @return {boolean} Whether the transform is valid.
363 util.isLetterDelete = function(oldContext, newContext) {
364 if (oldContext == '') {
365 return false;
367 // Handle buffer overflow.
368 if (oldContext.length == newContext.length) {
369 return util.isLetterDelete(oldContext, newContext.slice(1));
371 return oldContext.length == newContext.length + 1 &&
372 oldContext.indexOf(newContext) == 0;
377 * Checks whether a letter restoration would cause the observed context
378 * transform.
380 * @param {string} oldContext The old context.
381 * @param {string} newContext The new context.
383 * @return {boolean} Whether the transform is valid.
385 util.isLetterRestore = function(oldContext, newContext) {
386 return util.isLetterDelete(newContext, oldContext);
389 }); // goog.scope