Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / resources / gesture_config.js
bloba12c7833d5ba63bfef49763f157b71d10d9cd330
1 // Copyright (c) 2013 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.
5 // Redefine '$' here rather than including 'cr.js', since this is
6 // the only function needed.  This allows this file to be loaded
7 // in a browser directly for layout and some testing purposes.
8 var $ = function(id) { return document.getElementById(id); };
10 /**
11  * A generic WebUI for configuring preference values used by Chrome's gesture
12  * recognition systems.
13  * @param {string} title The user-visible title to display for the configuration
14  *    section.
15  * @param {string} prefix The prefix for the configuration fields.
16  * @param {!Object} fields An array of fields that contain the name of the pref
17  *    and user-visible labels.
18  */
19 function GeneralConfig(title, prefix, fields) {
20   this.title = title;
21   this.prefix = prefix;
22   this.fields = fields;
25 GeneralConfig.prototype = {
26   /**
27    * Sets up the form for configuring all the preference values.
28    */
29   buildAll: function() {
30     this.buildForm();
31     this.loadForm();
32     this.initForm();
33   },
35   /**
36    * Dynamically builds web-form based on the list of preferences.
37    */
38   buildForm: function() {
39     var buf = [];
41     var section = $('section-template').cloneNode(true);
42     section.removeAttribute('id');
43     var title = section.querySelector('.section-title');
44     title.textContent = this.title;
46     for (var i = 0; i < this.fields.length; i++) {
47       var field = this.fields[i];
49       var row = $('section-row-template').cloneNode(true);
50       row.removeAttribute('id');
52       var label = row.querySelector('.row-label');
53       var input = row.querySelector('.input');
54       var units = row.querySelector('.row-units');
55       var reset = row.querySelector('.row-reset');
57       label.setAttribute('for', field.key);
58       label.innerHTML = field.label;
59       input.id = field.key;
60       input.min = field.min || 0;
62       if (field.max)
63         input.max = field.max;
65       input.step = field.step || 'any';
67       if (field.units)
68         units.innerHTML = field.units;
70       reset.id = field.key + '-reset';
71       gesture_config.updateResetButton(reset, true);
73       section.querySelector('.section-properties').appendChild(row);
74     }
75     $('gesture-form').appendChild(section);
76   },
78   /**
79    * Initializes the form by adding appropriate event listeners to elements.
80    */
81   initForm: function() {
82     for (var i = 0; i < this.fields.length; i++) {
83       var field = this.fields[i];
84       var config = this;
85       $(field.key).onchange = (function(key) {
86         config.setPreferenceValue(key, $(key).value);
87         gesture_config.updateResetButton($(key + '-reset'), false);
88         gesture_config.updateResetAllButton(false);
89       }).bind(null, field.key);
90       $(field.key + '-reset').onclick = (function(key) {
91         config.resetPreferenceValue(key);
92       }).bind(null, field.key);
93     }
94   },
96   /**
97    * Requests preference values for all the relevant fields.
98    */
99   loadForm: function() {
100     for (var i = 0; i < this.fields.length; i++)
101       this.updatePreferenceValue(this.fields[i].key);
102   },
104   /**
105    * Handles processing of "Reset All" button.
106    * Causes all form values to be updated based on current preference values.
107    * @return {boolean} Returns false.
108    */
109   onReset: function() {
110     for (var i = 0; i < this.fields.length; i++) {
111       var field = this.fields[i];
112       this.resetPreferenceValue(field.key);
113     }
114     return false;
115   },
117   /**
118    * Requests a preference setting's value.
119    * This method is asynchronous; the result is provided by a call to
120    * updatePreferenceValueResult.
121    * @param {string} prefName The name of the preference value being requested.
122    */
123   updatePreferenceValue: function(prefName) {
124     chrome.send('updatePreferenceValue', [this.prefix + prefName]);
125   },
127   /**
128    * Sets a preference setting's value.
129    * @param {string} prefName The name of the preference value being set.
130    * @param {value} value The value to be associated with prefName.
131    */
132   setPreferenceValue: function(prefName, value) {
133     chrome.send('setPreferenceValue',
134         [this.prefix + prefName, parseFloat(value)]);
135   },
137   /**
138    * Resets a preference to its default value and get that callback
139    * to updatePreferenceValueResult with the new value of the preference.
140    * @param {string} prefName The name of the requested preference.
141    */
142   resetPreferenceValue: function(prefName) {
143     chrome.send('resetPreferenceValue', [this.prefix + prefName]);
144   }
148  * Returns a GeneralConfig for configuring gestures.* preferences.
149  * @return {object} A GeneralConfig object.
150  */
151 function GestureConfig() {
152   /** The title of the section for the gesture preferences. **/
153   /** @const */ var GESTURE_TITLE = 'Gesture Configuration';
155   /** Common prefix of gesture preferences. **/
156   /** @const */ var GESTURE_PREFIX = 'gesture.';
158   /** List of fields used to dynamically build form. **/
159   var GESTURE_FIELDS = [
160     {
161       key: 'fling_max_cancel_to_down_time_in_ms',
162       label: 'Maximum Cancel to Down Time for Tap Suppression',
163       units: 'milliseconds',
164     },
165     {
166       key: 'fling_max_tap_gap_time_in_ms',
167       label: 'Maximum Tap Gap Time for Tap Suppression',
168       units: 'milliseconds',
169     },
170     {
171       key: 'long_press_time_in_seconds',
172       label: 'Long Press Time',
173       units: 'seconds'
174     },
175     {
176       key: 'semi_long_press_time_in_seconds',
177       label: 'Semi Long Press Time',
178       units: 'seconds',
179       step: 0.1
180     },
181     {
182       key: 'show_press_delay_in_ms',
183       label: 'Delay before show press event is fired',
184       units: 'milliseconds',
185     },
186     {
187       key: 'max_seconds_between_double_click',
188       label: 'Maximum Double Click Interval',
189       units: 'seconds',
190       step: 0.1
191     },
192     {
193       key: 'max_separation_for_gesture_touches_in_pixels',
194       label: 'Maximum Separation for Gesture Touches',
195       units: 'pixels'
196     },
197     {
198       key: 'max_swipe_deviation_ratio',
199       label: 'Maximum Swipe Deviation',
200       units: ''
201     },
202     {
203       key: 'max_touch_down_duration_in_seconds_for_click',
204       label: 'Maximum Touch-Down Duration for Click',
205       units: 'seconds',
206       step: 0.1
207     },
208     {
209       key: 'max_touch_move_in_pixels_for_click',
210       label: 'Maximum Touch-Move for Click',
211       units: 'pixels'
212     },
213     {
214       key: 'max_distance_between_taps_for_double_tap',
215       label: 'Maximum Distance between two taps for Double Tap',
216       units: 'pixels'
217     },
218     {
219       key: 'min_distance_for_pinch_scroll_in_pixels',
220       label: 'Minimum Distance for Pinch Scroll',
221       units: 'pixels'
222     },
223     {
224       key: 'min_flick_speed_squared',
225       label: 'Minimum Flick Speed Squared',
226       units: '(pixels/sec.)<sup>2</sup>'
227     },
228     {
229       key: 'min_pinch_update_distance_in_pixels',
230       label: 'Minimum Pinch Update Distance',
231       units: 'pixels'
232     },
233     {
234       key: 'min_rail_break_velocity',
235       label: 'Minimum Rail-Break Velocity',
236       units: 'pixels/sec.'
237     },
238     {
239       key: 'min_scroll_delta_squared',
240       label: 'Minimum Scroll Delta Squared',
241       units: ''
242     },
243     {
244       key: 'min_scroll_successive_velocity_events',
245       label: 'Minimum Scroll Successive Velocity Events',
246       units: ''
247     },
248     {
249       key: 'scroll_prediction_seconds',
250       label: 'Scroll prediction interval<br>' +
251           '(Enable scroll prediction in ' +
252               '<a href="chrome://flags">chrome://flags</a>)',
253       units: 'seconds',
254       step: 0.01
255     },
256     {
257       key: 'min_swipe_speed',
258       label: 'Minimum Swipe Speed',
259       units: 'pixels/sec.'
260     },
261     {
262       key: 'min_touch_down_duration_in_seconds_for_click',
263       label: 'Minimum Touch-Down Duration for Click',
264       units: 'seconds',
265       step: 0.01
266     },
267     {
268       key: 'points_buffered_for_velocity',
269       label: 'Points Buffered for Velocity',
270       units: '',
271       step: 1
272     },
273     {
274       key: 'rail_break_proportion',
275       label: 'Rail-Break Proportion',
276       units: '%'
277     },
278     {
279       key: 'rail_start_proportion',
280       label: 'Rail-Start Proportion',
281       units: '%'
282     },
283     {
284       key: 'fling_acceleration_curve_coefficient_0',
285       label: 'Touchscreen Fling Acceleration',
286       units: 'x<sup>3</sup>',
287       min: '-1'
288     },
289     {
290       key: 'fling_acceleration_curve_coefficient_1',
291       label: '+',
292       units: 'x<sup>2</sup>',
293       min: '-1'
294     },
295     {
296       key: 'fling_acceleration_curve_coefficient_2',
297       label: '+',
298       units: 'x<sup>1</sup>',
299       min: '-1'
300     },
301     {
302       key: 'fling_acceleration_curve_coefficient_3',
303       label: '+',
304       units: 'x<sup>0</sup>',
305       min: '-1'
306     },
307     {
308       key: 'fling_velocity_cap',
309       label: 'Touchscreen Fling Velocity Cap',
310       units: 'pixels / second'
311     },
312     {
313       key: 'tab_scrub_activation_delay_in_ms',
314       label: 'Tab scrub auto activation delay, (-1 for never)',
315       units: 'milliseconds'
316     }
317   ];
319   return new GeneralConfig(GESTURE_TITLE, GESTURE_PREFIX, GESTURE_FIELDS);
323  * Returns a GeneralConfig for configuring overscroll.* preferences.
324  * @return {object} A GeneralConfig object.
325  */
326 function OverscrollConfig() {
327   /** @const */ var OVERSCROLL_TITLE = 'Overscroll Configuration';
329   /** @const */ var OVERSCROLL_PREFIX = 'overscroll.';
331   var OVERSCROLL_FIELDS = [
332     {
333       key: 'horizontal_threshold_complete',
334       label: 'Complete when overscrolled (horizontal)',
335       units: '%'
336     },
337     {
338       key: 'vertical_threshold_complete',
339       label: 'Complete when overscrolled (vertical)',
340       units: '%'
341     },
342     {
343       key: 'minimum_threshold_start_touchpad',
344       label: 'Start overscroll gesture (horizontal; touchpad)',
345       units: 'pixels'
346     },
347     {
348       key: 'minimum_threshold_start',
349       label: 'Start overscroll gesture (horizontal; touchscreen)',
350       units: 'pixels'
351     },
352     {
353       key: 'vertical_threshold_start',
354       label: 'Start overscroll gesture (vertical)',
355       units: 'pixels'
356     },
357     {
358       key: 'horizontal_resist_threshold',
359       label: 'Start resisting overscroll after (horizontal)',
360       units: 'pixels'
361     },
362     {
363       key: 'vertical_resist_threshold',
364       label: 'Start resisting overscroll after (vertical)',
365       units: 'pixels'
366     },
367   ];
369   return new GeneralConfig(OVERSCROLL_TITLE,
370                            OVERSCROLL_PREFIX,
371                            OVERSCROLL_FIELDS);
375  * Returns a GeneralConfig for configuring flingcurve.* preferences.
376  * @return {object} A GeneralConfig object.
377  */
378 function FlingConfig() {
379   /** @const */ var FLING_TITLE = 'Fling Configuration';
381   /** @const */ var FLING_PREFIX = 'flingcurve.';
383   var FLING_FIELDS = [
384     {
385       key: 'touchscreen_alpha',
386       label: 'Touchscreen fling deacceleration coefficients',
387       units: 'alpha',
388       min: '-inf'
389     },
390     {
391       key: 'touchscreen_beta',
392       label: '',
393       units: 'beta',
394       min: '-inf'
395     },
396     {
397       key: 'touchscreen_gamma',
398       label: '',
399       units: 'gamma',
400       min: '-inf'
401     },
402     {
403       key: 'touchpad_alpha',
404       label: 'Touchpad fling deacceleration coefficients',
405       units: 'alpha',
406       min: '-inf'
407     },
408     {
409       key: 'touchpad_beta',
410       label: '',
411       units: 'beta',
412       min: '-inf'
413     },
414     {
415       key: 'touchpad_gamma',
416       label: '',
417       units: 'gamma',
418       min: '-inf'
419     },
420   ];
422   return new GeneralConfig(FLING_TITLE, FLING_PREFIX, FLING_FIELDS);
426  * WebUI instance for configuring preference values related to gesture input.
427  */
428 window.gesture_config = {
429   /**
430    * Build and initialize the gesture configuration form.
431    */
432   initialize: function() {
433     var g = GestureConfig();
434     g.buildAll();
436     var o = OverscrollConfig();
437     o.buildAll();
439     var f = FlingConfig();
440     f.buildAll();
442     $('reset-all-button').onclick = function() {
443       g.onReset();
444       o.onReset();
445       f.onReset();
446     };
447   },
449   /**
450    * Checks if all gesture preferences are set to default by checking the status
451    * of the reset button associated with each preference.
452    * @return {boolean} True if all gesture preferences are set to default.
453    */
454   areAllPrefsSetToDefault: function() {
455     var resets = $('gesture-form').querySelectorAll('.row-reset');
456     for (var i = 0; i < resets.length; i++) {
457       if (!resets[i].disabled)
458         return false;
459     }
460     return true;
461   },
463   /**
464    * Updates the status and label of a preference reset button.
465    * @param {HTMLInputElement} resetButton Reset button for the preference.
466    * @param {boolean} isDefault Whether the preference is set to the default
467    *     value.
468    */
469   updateResetButton: function(resetButton, isDefault) {
470     /** @const */ var TITLE_DEFAULT = 'Default';
472     /** @const */ var TITLE_NOT_DEFAULT = 'Reset';
474     resetButton.innerHTML = isDefault ? TITLE_DEFAULT : TITLE_NOT_DEFAULT;
475     resetButton.disabled = isDefault;
476   },
478   /**
479    * Updates the status and label of "Reset All" button.
480    * @param {boolean} isDefault Whether all preference are set to their default
481    *     values.
482    */
483   updateResetAllButton: function(isDefault) {
484     /** @const */ var TITLE_DEFAULT = 'Everything is set to default';
486     /** @const */ var TITLE_NOT_DEFAULT = 'Reset All To Default';
488     var button = $('reset-all-button');
489     button.innerHTML = isDefault ? TITLE_DEFAULT : TITLE_NOT_DEFAULT;
490     button.disabled = isDefault;
491   },
493   /**
494    * Handle callback from call to updatePreferenceValue.
495    * @param {string} prefName The name of the requested preference value.
496    * @param {value} value The current value associated with prefName.
497    * @param {boolean} isDefault Whether the value is the default value.
498    */
499   updatePreferenceValueResult: function(prefName, value, isDefault) {
500     prefName = prefName.substring(prefName.indexOf('.') + 1);
501     $(prefName).value = value;
502     this.updateResetButton($(prefName + '-reset'), isDefault);
503     this.updateResetAllButton(this.areAllPrefsSetToDefault());
504   },
507 document.addEventListener('DOMContentLoaded', gesture_config.initialize);