Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / paper-slider / paper-slider-extracted.js
blobbf973c7e26db0e421d7954ebaaf308fe66fa79ce
3 Polymer({
4 is: 'paper-slider',
6 behaviors: [
7 Polymer.IronA11yKeysBehavior,
8 Polymer.PaperInkyFocusBehavior,
9 Polymer.IronFormElementBehavior,
10 Polymer.IronRangeBehavior
13 properties: {
15 /**
16 * If true, the slider thumb snaps to tick marks evenly spaced based
17 * on the `step` property value.
19 snaps: {
20 type: Boolean,
21 value: false,
22 notify: true
25 /**
26 * If true, a pin with numeric value label is shown when the slider thumb
27 * is pressed. Use for settings for which users need to know the exact
28 * value of the setting.
30 pin: {
31 type: Boolean,
32 value: false,
33 notify: true
36 /**
37 * The number that represents the current secondary progress.
39 secondaryProgress: {
40 type: Number,
41 value: 0,
42 notify: true,
43 observer: '_secondaryProgressChanged'
46 /**
47 * If true, an input is shown and user can use it to set the slider value.
49 editable: {
50 type: Boolean,
51 value: false
54 /**
55 * The immediate value of the slider. This value is updated while the user
56 * is dragging the slider.
58 immediateValue: {
59 type: Number,
60 value: 0,
61 readOnly: true
64 /**
65 * The maximum number of markers
67 maxMarkers: {
68 type: Number,
69 value: 0,
70 notify: true,
71 observer: '_maxMarkersChanged'
74 /**
75 * If true, the knob is expanded
77 expand: {
78 type: Boolean,
79 value: false,
80 readOnly: true
83 /**
84 * True when the user is dragging the slider.
86 dragging: {
87 type: Boolean,
88 value: false,
89 readOnly: true
92 transiting: {
93 type: Boolean,
94 value: false,
95 readOnly: true
98 markers: {
99 type: Array,
100 readOnly: true,
101 value: []
105 observers: [
106 '_updateKnob(value, min, max, snaps, step)',
107 '_minChanged(min)',
108 '_maxChanged(max)',
109 '_valueChanged(value)',
110 '_immediateValueChanged(immediateValue)'
113 hostAttributes: {
114 role: 'slider',
115 tabindex: 0
118 keyBindings: {
119 'left down pagedown home': '_decrementKey',
120 'right up pageup end': '_incrementKey'
123 ready: function() {
124 // issue polymer/polymer#1305
125 this.async(function() {
126 this._updateKnob(this.value);
127 this._updateInputValue();
128 }, 1);
132 * Increases value by `step` but not above `max`.
133 * @method increment
135 increment: function() {
136 this.value = this._clampValue(this.value + this.step);
140 * Decreases value by `step` but not below `min`.
141 * @method decrement
143 decrement: function() {
144 this.value = this._clampValue(this.value - this.step);
147 _updateKnob: function(value) {
148 this._positionKnob(this._calcRatio(value));
151 _minChanged: function() {
152 this.setAttribute('aria-valuemin', this.min);
155 _maxChanged: function() {
156 this.setAttribute('aria-valuemax', this.max);
159 _valueChanged: function() {
160 this.setAttribute('aria-valuenow', this.value);
161 this.fire('value-change');
164 _immediateValueChanged: function() {
165 if (this.dragging) {
166 this.fire('immediate-value-change');
167 } else {
168 this.value = this.immediateValue;
170 this._updateInputValue();
173 _secondaryProgressChanged: function() {
174 this.secondaryProgress = this._clampValue(this.secondaryProgress);
177 _updateInputValue: function() {
178 if (this.editable) {
179 this.$$('#input').value = this.immediateValue.toString();
183 _expandKnob: function() {
184 this._setExpand(true);
187 _resetKnob: function() {
188 this.cancelDebouncer('expandKnob');
189 this._setExpand(false);
192 _positionKnob: function(ratio) {
193 this._setImmediateValue(this._calcStep(this._calcKnobPosition(ratio)));
194 this._setRatio(this._calcRatio(this.immediateValue));
196 this.$.sliderKnob.style.left = (this.ratio * 100) + '%';
199 _inputChange: function() {
200 this.value = this.$$('#input').value;
201 this.fire('change');
204 _calcKnobPosition: function(ratio) {
205 return (this.max - this.min) * ratio + this.min;
208 _onTrack: function(event) {
209 switch (event.detail.state) {
210 case 'start':
211 this._trackStart(event);
212 break;
213 case 'track':
214 this._trackX(event);
215 break;
216 case 'end':
217 this._trackEnd();
218 break;
222 _trackStart: function(event) {
223 this._w = this.$.sliderBar.offsetWidth;
224 this._x = this.ratio * this._w;
225 this._startx = this._x || 0;
226 this._minx = - this._startx;
227 this._maxx = this._w - this._startx;
228 this.$.sliderKnob.classList.add('dragging');
230 this._setDragging(true);
233 _trackX: function(e) {
234 if (!this.dragging) {
235 this._trackStart(e);
238 var dx = Math.min(this._maxx, Math.max(this._minx, e.detail.dx));
239 this._x = this._startx + dx;
241 var immediateValue = this._calcStep(this._calcKnobPosition(this._x / this._w));
242 this._setImmediateValue(immediateValue);
244 // update knob's position
245 var translateX = ((this._calcRatio(immediateValue) * this._w) - this._startx);
246 this.translate3d(translateX + 'px', 0, 0, this.$.sliderKnob);
249 _trackEnd: function() {
250 var s = this.$.sliderKnob.style;
252 this.$.sliderKnob.classList.remove('dragging');
253 this._setDragging(false);
254 this._resetKnob();
255 this.value = this.immediateValue;
257 s.transform = s.webkitTransform = '';
259 this.fire('change');
262 _knobdown: function(event) {
263 this._expandKnob();
265 // cancel selection
266 event.detail.sourceEvent.preventDefault();
268 // set the focus manually because we will called prevent default
269 this.focus();
272 _bardown: function(event) {
273 this._w = this.$.sliderBar.offsetWidth;
274 var rect = this.$.sliderBar.getBoundingClientRect();
275 var ratio = (event.detail.x - rect.left) / this._w;
276 var prevRatio = this.ratio;
278 this._setTransiting(true);
280 this._positionKnob(ratio);
282 this.debounce('expandKnob', this._expandKnob, 60);
284 // if the ratio doesn't change, sliderKnob's animation won't start
285 // and `_knobTransitionEnd` won't be called
286 // Therefore, we need to manually update the `transiting` state
288 if (prevRatio === this.ratio) {
289 this._setTransiting(false);
292 this.async(function() {
293 this.fire('change');
296 // cancel selection
297 event.detail.sourceEvent.preventDefault();
300 _knobTransitionEnd: function(event) {
301 if (event.target === this.$.sliderKnob) {
302 this._setTransiting(false);
306 _maxMarkersChanged: function(maxMarkers) {
307 var l = (this.max - this.min) / this.step;
308 if (!this.snaps && l > maxMarkers) {
309 this._setMarkers([]);
310 } else {
311 this._setMarkers(new Array(l));
315 _getClassNames: function() {
316 var classes = {};
318 classes.disabled = this.disabled;
319 classes.pin = this.pin;
320 classes.snaps = this.snaps;
321 classes.ring = this.immediateValue <= this.min;
322 classes.expand = this.expand;
323 classes.dragging = this.dragging;
324 classes.transiting = this.transiting;
325 classes.editable = this.editable;
327 return Object.keys(classes).filter(
328 function(className) {
329 return classes[className];
330 }).join(' ');
333 _incrementKey: function(event) {
334 if (event.detail.key === 'end') {
335 this.value = this.max;
336 } else {
337 this.increment();
339 this.fire('change');
342 _decrementKey: function(event) {
343 if (event.detail.key === 'home') {
344 this.value = this.min;
345 } else {
346 this.decrement();
348 this.fire('change');
353 * Fired when the slider's value changes.
355 * @event value-change
359 * Fired when the slider's immediateValue changes.
361 * @event immediate-value-change
365 * Fired when the slider's value changes due to user interaction.
367 * Changes to the slider's value due to changes in an underlying
368 * bound variable will not trigger this event.
370 * @event change