Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: ui/webui/resources/cr_elements/slider/slider_host_behavior.js

Issue 1967913002: Material WebUI: cr-slider element for intelligent range mapping (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@KeyboardFinish
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 /**
6 * @fileoverview
7 * SliderHostBehavior handles data binding for paper-sliders that need to map
8 * the slider's values from a linear UI range to a range of real values. When
9 * the real value does not map exactly to a tick mark, it interpolates to the
10 * nearest tick.
11 *
12 * Sliders should be data bound as follows:
13 *
14 * <paper-slider
15 * value="[[getSliderIndexFromValue(
16 * path.to.property.value, listOfValidValues)]]"
17 * on-change="onSliderChange" on-value-change="onSliderValueChange"
18 * data-value-path="path.to.property.value"
19 * slider-tick-values="[[listOfValidValues]]">
20 * </paper-slider>
21 *
22 * In addition to the computed value binding and two events, this includes two
23 * new attributes:
24 * data-value-path: the path to the number value the slider should control
25 * slider-tick-values: an {!Array<number>} of the values the ticks represent
26 */
27
28 /**
29 * paper-slider with the required annotations.
30 * @constructor
31 * @extends {PaperSliderElement}
32 */
33 var SliderHostBehaviorSlider = function() {};
34 /** @type {!{valuePath: string}} */
35 SliderHostBehaviorSlider.prototype.dataset;
36 /** @type {!Array<number>} */
37 SliderHostBehaviorSlider.prototype.sliderTickValues;
38
39 /** @polymerBehavior */
40 var SliderHostBehavior = {
41 /**
42 * value-change is fired when the slider is first data-bound, so we can use
43 * this as a proxy for initialization.
44 * @param {!Event} e
45 */
46 onSliderValueChange: function(e) {
47 var slider = /** @type {!SliderHostBehaviorSlider} */(e.target);
48
49 // If the slider is already initialized, do nothing.
50 if (typeof slider.min != 'undefined' && typeof slider.max != 'undefined')
51 return;
52
53 // Asynchronously update so we can ensure all properties are bound.
54 this.async(this.initializeSlider_.bind(this, slider));
55 },
56
57 /**
58 * Sets the path to the value corresponding to the slider position in
59 * response to user action.
60 * @param {!Event} e Slider change event.
61 */
62 onSliderChange: function(e) {
63 var slider = /** @type {!SliderHostBehaviorSlider} */(e.target);
64 var index = slider.value;
65 var ticks = slider.sliderTickValues;
66 assert(index >= 0 && index < ticks.length);
67 this.set(slider.dataset.valuePath, ticks[index]);
68 },
69
70 /**
71 * Converts from raw values (what the ticks represent) to the slider index
72 * (where the pip should be positioned on the slider).
73 * @param {number} value Value to convert.
74 * @param {!Array<number>} ticks Array of values corresponding to ticks.
75 * @return {number}
76 */
77 getSliderIndexFromValue: function(value, ticks) {
78 // TODO
stevenjb 2016/05/11 16:37:41 TODO?
79 assert(!(typeof value != 'number' || Number.isNaN(value)))
80 //return undefined;
81 return this.findNearestIndex_(ticks, value);
82 },
83
84 /**
85 * Sets the min, max and value based on the availale ticks.
86 * @param {!PaperSliderElement} slider The slider, after data binding.
87 * @private
88 */
89 initializeSlider_: function(slider) {
90 var ticks = slider.sliderTickValues;
91 slider.min = 0;
92 slider.max = ticks.length - 1;
93
94 // Set the value in case it was originally out-of-bounds.
95 var value = /** @type {number|undefined} */(
96 this.get(slider.dataset.valuePath));
97 if (typeof value != 'undefined')
98 slider.value = this.getSliderIndexFromValue(value, ticks);
99 },
100
101 /**
102 * Returns the index of the item in |arr| closest to |value|. Same cost as
103 * Array.prototype.indexOf if an exact match exists.
104 * @param {!Array<number>} arr
105 * @param {number} value
106 * @return {number}
107 * @private
108 */
109 findNearestIndex_: function(arr, value) {
110 assert(arr.length);
111
112 // The common case has an exact match.
113 var closestIndex = arr.indexOf(value);
114 if (closestIndex != -1)
115 return closestIndex;
116
117 // No exact match. Find the element closest to |value|.
118 var minDifference = Number.MAX_VALUE;
119 for (var i = 0; i < arr.length; i++) {
120 var difference = Math.abs(arr[i] - value);
121 if (difference < minDifference) {
122 closestIndex = i;
123 minDifference = difference;
124 }
125 }
126
127 return closestIndex;
128 },
129 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698