Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 * cr-slider wraps a paper-slider. It maps the slider's values from a linear UI | |
| 8 * range to a range of real values. When |value| does not map exactly to a | |
| 9 * tick mark, it interpolates to the nearest tick. | |
| 10 * | |
| 11 * Unlike paper-slider, there is no distinction between value and | |
| 12 * immediateValue; when either changes, the |value| property is updated. | |
| 13 */ | |
| 14 Polymer({ | |
| 15 is: 'cr-slider', | |
| 16 | |
| 17 properties: { | |
| 18 /** The value the slider represents and controls. */ | |
| 19 value: { | |
| 20 type: Number, | |
| 21 notify: true, | |
| 22 observer: 'valueChanged_', | |
| 23 }, | |
| 24 | |
| 25 /** @type {!Array<number>} Values corresponding to each tick. */ | |
| 26 tickValues: Array, | |
| 27 | |
| 28 disabled: { | |
| 29 type: Boolean, | |
| 30 value: false, | |
| 31 reflectToAttribute: true, | |
| 32 }, | |
| 33 | |
| 34 snaps: { | |
| 35 type: Boolean, | |
| 36 value: false, | |
| 37 }, | |
| 38 | |
| 39 maxMarkers: Number, | |
|
Dan Beam
2016/05/17 19:35:45
where is this used?
michaelpg
2016/05/18 17:05:49
html for paper-slider
| |
| 40 }, | |
| 41 | |
| 42 observers: [ | |
| 43 'tickValuesChanged_(tickValues.*)', | |
| 44 ], | |
| 45 | |
| 46 /** | |
| 47 * Sets the |value| property to the value corresponding to the knob position | |
| 48 * after a user action. | |
| 49 * @private | |
| 50 */ | |
| 51 onSliderChange_: function() { | |
| 52 var index = this.$.slider.immediateValue; | |
| 53 this.value = this.tickValues[index]; | |
|
Dan Beam
2016/05/17 19:35:45
is this less clear?
this.value = this.tickValues[
michaelpg
2016/05/18 17:05:48
Done.
| |
| 54 }, | |
| 55 | |
| 56 /** | |
| 57 * Updates the slider settings and knob position for the new tick values. | |
| 58 * @private | |
| 59 */ | |
| 60 tickValuesChanged_: function() { | |
| 61 this.$.slider.max = this.tickValues.length - 1; | |
| 62 this.valueChanged_(); | |
| 63 }, | |
| 64 | |
| 65 /** | |
| 66 * Updates the knob position when |value| changes. If the knob is still being | |
| 67 * dragged, this instead forces |value| back to the current position. | |
| 68 * @private | |
| 69 */ | |
| 70 valueChanged_: function() { | |
| 71 if (typeof this.value == 'undefined' || | |
| 72 typeof this.tickValues == 'undefined') { | |
|
Dan Beam
2016/05/17 19:35:45
can't we just change how this observer is defined
michaelpg
2016/05/18 17:05:48
Done.
| |
| 73 return; | |
| 74 } | |
| 75 | |
| 76 if (this.$.slider.dragging && | |
| 77 this.value != this.tickValues[this.$.slider.immediateValue]) { | |
| 78 // The pref changed somewhere else (e.g., sync) but we're still holding | |
| 79 // the knob, so set the pref back to where we had it. | |
| 80 // Async so we don't confuse Polymer's data binding. | |
| 81 this.async(function() { | |
| 82 this.value = this.tickValues[this.$.slider.immediateValue]; | |
| 83 }); | |
| 84 return; | |
| 85 } | |
| 86 | |
| 87 // Convert from the public |value| to the slider index (where the knob | |
| 88 // should be positioned on the slider). | |
| 89 this.$.slider.value = this.findNearestIndex_(this.tickValues, this.value); | |
| 90 }, | |
| 91 | |
| 92 /** | |
| 93 * Returns the index of the item in |arr| closest to |value|. Same cost as | |
| 94 * Array.prototype.indexOf if an exact match exists. | |
| 95 * @param {!Array<number>} arr | |
| 96 * @param {number} value | |
| 97 * @return {number} | |
| 98 * @private | |
| 99 */ | |
| 100 findNearestIndex_: function(arr, value) { | |
|
Dan Beam
2016/05/17 19:35:45
why is findNearestIndex_ a separate method?
michaelpg
2016/05/18 17:05:49
mostly testability and documentability
| |
| 101 assert(arr.length); | |
| 102 | |
| 103 // The common case has an exact match. | |
| 104 var closestIndex = arr.indexOf(value); | |
| 105 if (closestIndex != -1) | |
| 106 return closestIndex; | |
|
Dan Beam
2016/05/17 19:35:45
why do you want to run both indexOf() and the loop
michaelpg
2016/05/18 17:05:48
like the comment says: 99.99% of the time indexOf
| |
| 107 | |
| 108 // No exact match. Find the element closest to |value|. | |
| 109 var minDifference = Number.MAX_VALUE; | |
| 110 for (var i = 0; i < arr.length; i++) { | |
| 111 var difference = Math.abs(arr[i] - value); | |
| 112 if (difference < minDifference) { | |
| 113 closestIndex = i; | |
| 114 minDifference = difference; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 return closestIndex; | |
| 119 }, | |
| 120 }); | |
| OLD | NEW |