summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/catapult/third_party/polymer2/bower_components/iron-range-behavior/iron-range-behavior.html
blob: 92f4e5590679f31b4a067fe25a17d556747f3137 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<link rel="import" href="../polymer/polymer.html">

<script>
  /**
   * `iron-range-behavior` provides the behavior for something with a minimum to
   * maximum range.
   *
   * @demo demo/index.html
   * @polymerBehavior
   */
  Polymer.IronRangeBehavior = {

    properties: {

      /**
       * The number that represents the current value.
       */
      value: {type: Number, value: 0, notify: true, reflectToAttribute: true},

      /**
       * The number that indicates the minimum value of the range.
       */
      min: {type: Number, value: 0, notify: true},

      /**
       * The number that indicates the maximum value of the range.
       */
      max: {type: Number, value: 100, notify: true},

      /**
       * Specifies the value granularity of the range's value.
       */
      step: {type: Number, value: 1, notify: true},

      /**
       * Returns the ratio of the value.
       */
      ratio: {type: Number, value: 0, readOnly: true, notify: true},
    },

    observers: ['_update(value, min, max, step)'],

    _calcRatio: function(value) {
      return (this._clampValue(value) - this.min) / (this.max - this.min);
    },

    _clampValue: function(value) {
      return Math.min(this.max, Math.max(this.min, this._calcStep(value)));
    },

    _calcStep: function(value) {
      // polymer/issues/2493
      value = parseFloat(value);

      if (!this.step) {
        return value;
      }

      var numSteps = Math.round((value - this.min) / this.step);
      if (this.step < 1) {
        /**
         * For small values of this.step, if we calculate the step using
         * `Math.round(value / step) * step` we may hit a precision point issue
         * eg. 0.1 * 0.2 =  0.020000000000000004
         * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
         *
         * as a work around we can divide by the reciprocal of `step`
         */
        return numSteps / (1 / this.step) + this.min;
      } else {
        return numSteps * this.step + this.min;
      }
    },

    _validateValue: function() {
      var v = this._clampValue(this.value);
      this.value = this.oldValue = isNaN(v) ? this.oldValue : v;
      return this.value !== v;
    },

    _update: function() {
      this._validateValue();
      this._setRatio(this._calcRatio(this.value) * 100);
    }

  };
</script>