active_frontend 12.2.0 → 12.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/fonts/gotham/gotham-bold.woff +0 -0
  3. data/app/assets/fonts/gotham/gotham-book.woff +0 -0
  4. data/app/assets/fonts/gotham/gotham-light.woff +0 -0
  5. data/app/assets/fonts/gotham/gotham-medium.woff +0 -0
  6. data/app/assets/fonts/gotham/gotham-rounded-bold.woff +0 -0
  7. data/app/assets/fonts/gotham/gotham-rounded-book.woff +0 -0
  8. data/app/assets/fonts/gotham/gotham-rounded-light.woff +0 -0
  9. data/app/assets/fonts/gotham/gotham-rounded-medium.woff +0 -0
  10. data/lib/active_frontend/version.rb +1 -1
  11. data/vendor/assets/javascripts/_affix.js +4 -4
  12. data/vendor/assets/javascripts/_alert.js +1 -1
  13. data/vendor/assets/javascripts/_animation.js +14 -14
  14. data/vendor/assets/javascripts/_button.js +1 -1
  15. data/vendor/assets/javascripts/_carousel.js +5 -5
  16. data/vendor/assets/javascripts/_chart.js +713 -280
  17. data/vendor/assets/javascripts/_collapse.js +6 -6
  18. data/vendor/assets/javascripts/_dropdown.js +47 -43
  19. data/vendor/assets/javascripts/_inputmask.js +6 -4
  20. data/vendor/assets/javascripts/_map.js +136 -88
  21. data/vendor/assets/javascripts/_modal.js +136 -42
  22. data/vendor/assets/javascripts/_popover.js +2 -7
  23. data/vendor/assets/javascripts/_scrollspy.js +16 -19
  24. data/vendor/assets/javascripts/_slider.js +156 -85
  25. data/vendor/assets/javascripts/_tab.js +5 -3
  26. data/vendor/assets/javascripts/_tooltip.js +73 -31
  27. data/vendor/assets/stylesheets/_header.scss +3 -1
  28. data/vendor/assets/stylesheets/_typography.scss +8 -40
  29. metadata +10 -34
  30. data/app/assets/fonts/gotham/regular/gotham-bold.eot +0 -0
  31. data/app/assets/fonts/gotham/regular/gotham-bold.svg +0 -2066
  32. data/app/assets/fonts/gotham/regular/gotham-bold.ttf +0 -0
  33. data/app/assets/fonts/gotham/regular/gotham-bold.woff +0 -0
  34. data/app/assets/fonts/gotham/regular/gotham-book.eot +0 -0
  35. data/app/assets/fonts/gotham/regular/gotham-book.svg +0 -631
  36. data/app/assets/fonts/gotham/regular/gotham-book.ttf +0 -0
  37. data/app/assets/fonts/gotham/regular/gotham-book.woff +0 -0
  38. data/app/assets/fonts/gotham/regular/gotham-light.eot +0 -0
  39. data/app/assets/fonts/gotham/regular/gotham-light.svg +0 -635
  40. data/app/assets/fonts/gotham/regular/gotham-light.ttf +0 -0
  41. data/app/assets/fonts/gotham/regular/gotham-light.woff +0 -0
  42. data/app/assets/fonts/gotham/regular/gotham-medium.eot +0 -0
  43. data/app/assets/fonts/gotham/regular/gotham-medium.svg +0 -629
  44. data/app/assets/fonts/gotham/regular/gotham-medium.ttf +0 -0
  45. data/app/assets/fonts/gotham/regular/gotham-medium.woff +0 -0
  46. data/app/assets/fonts/gotham/round/gothamrnd-bold.eot +0 -0
  47. data/app/assets/fonts/gotham/round/gothamrnd-bold.svg +0 -3528
  48. data/app/assets/fonts/gotham/round/gothamrnd-bold.ttf +0 -0
  49. data/app/assets/fonts/gotham/round/gothamrnd-bold.woff +0 -0
  50. data/app/assets/fonts/gotham/round/gothamrnd-book.eot +0 -0
  51. data/app/assets/fonts/gotham/round/gothamrnd-book.svg +0 -3654
  52. data/app/assets/fonts/gotham/round/gothamrnd-book.ttf +0 -0
  53. data/app/assets/fonts/gotham/round/gothamrnd-book.woff +0 -0
  54. data/app/assets/fonts/gotham/round/gothamrnd-light.eot +0 -0
  55. data/app/assets/fonts/gotham/round/gothamrnd-light.svg +0 -3503
  56. data/app/assets/fonts/gotham/round/gothamrnd-light.ttf +0 -0
  57. data/app/assets/fonts/gotham/round/gothamrnd-light.woff +0 -0
  58. data/app/assets/fonts/gotham/round/gothamrnd-medium.eot +0 -0
  59. data/app/assets/fonts/gotham/round/gothamrnd-medium.svg +0 -3659
  60. data/app/assets/fonts/gotham/round/gothamrnd-medium.ttf +0 -0
  61. data/app/assets/fonts/gotham/round/gothamrnd-medium.woff +0 -0
@@ -5,10 +5,15 @@
5
5
  // ======================
6
6
 
7
7
  var Modal = function (element, options) {
8
- this.options = options
9
- this.$element = $(element)
10
- this.$backdrop =
11
- this.isShown = null
8
+ this.options = options
9
+ this.$body = $(document.body)
10
+ this.$element = $(element)
11
+ this.$dialog = this.$element.find('.modal-dialog')
12
+ this.$backdrop = null
13
+ this.isShown = null
14
+ this.originalBodyPad = null
15
+ this.scrollbarWidth = 0
16
+ this.ignoreBackdropClick = false
12
17
 
13
18
  if (this.options.remote) {
14
19
  this.$element
@@ -19,6 +24,11 @@
19
24
  }
20
25
  }
21
26
 
27
+ Modal.VERSION = '3.3.6'
28
+
29
+ Modal.TRANSITION_DURATION = 300
30
+ Modal.BACKDROP_TRANSITION_DURATION = 150
31
+
22
32
  Modal.DEFAULTS = {
23
33
  backdrop: true,
24
34
  keyboard: true,
@@ -26,7 +36,7 @@
26
36
  }
27
37
 
28
38
  Modal.prototype.toggle = function (_relatedTarget) {
29
- return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
39
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
30
40
  }
31
41
 
32
42
  Modal.prototype.show = function (_relatedTarget) {
@@ -39,40 +49,51 @@
39
49
 
40
50
  this.isShown = true
41
51
 
52
+ this.checkScrollbar()
53
+ this.setScrollbar()
54
+ this.$body.addClass('modal-open')
55
+
42
56
  this.escape()
57
+ this.resize()
43
58
 
44
59
  this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
45
60
 
61
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
62
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
63
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
64
+ })
65
+ })
66
+
46
67
  this.backdrop(function () {
47
68
  var transition = $.support.transition && that.$element.hasClass('fade')
48
69
 
49
70
  if (!that.$element.parent().length) {
50
- that.$element.appendTo(document.body) // don't move modals dom position
71
+ that.$element.appendTo(that.$body) // don't move modals dom position
51
72
  }
52
73
 
53
74
  that.$element
54
75
  .show()
55
76
  .scrollTop(0)
56
77
 
78
+ that.adjustDialog()
79
+
57
80
  if (transition) {
58
81
  that.$element[0].offsetWidth // force reflow
59
82
  }
60
83
 
61
- that.$element
62
- .addClass('in')
63
- .attr('aria-hidden', false)
84
+ that.$element.addClass('in')
64
85
 
65
86
  that.enforceFocus()
66
87
 
67
88
  var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
68
89
 
69
90
  transition ?
70
- that.$element.find('.modal-dialog') // wait for modal to slide in
71
- .one($.support.transition.end, function () {
72
- that.$element.focus().trigger(e)
91
+ that.$dialog // wait for modal to slide in
92
+ .one('bsTransitionEnd', function () {
93
+ that.$element.trigger('focus').trigger(e)
73
94
  })
74
- .emulateTransitionEnd(300) :
75
- that.$element.focus().trigger(e)
95
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
96
+ that.$element.trigger('focus').trigger(e)
76
97
  })
77
98
  }
78
99
 
@@ -88,18 +109,21 @@
88
109
  this.isShown = false
89
110
 
90
111
  this.escape()
112
+ this.resize()
91
113
 
92
114
  $(document).off('focusin.bs.modal')
93
115
 
94
116
  this.$element
95
117
  .removeClass('in')
96
- .attr('aria-hidden', true)
97
118
  .off('click.dismiss.bs.modal')
119
+ .off('mouseup.dismiss.bs.modal')
120
+
121
+ this.$dialog.off('mousedown.dismiss.bs.modal')
98
122
 
99
123
  $.support.transition && this.$element.hasClass('fade') ?
100
124
  this.$element
101
- .one($.support.transition.end, $.proxy(this.hideModal, this))
102
- .emulateTransitionEnd(300) :
125
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
126
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
103
127
  this.hideModal()
104
128
  }
105
129
 
@@ -108,18 +132,26 @@
108
132
  .off('focusin.bs.modal') // guard against infinite focus loop
109
133
  .on('focusin.bs.modal', $.proxy(function (e) {
110
134
  if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
111
- this.$element.focus()
135
+ this.$element.trigger('focus')
112
136
  }
113
137
  }, this))
114
138
  }
115
139
 
116
140
  Modal.prototype.escape = function () {
117
141
  if (this.isShown && this.options.keyboard) {
118
- this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
142
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
119
143
  e.which == 27 && this.hide()
120
144
  }, this))
121
145
  } else if (!this.isShown) {
122
- this.$element.off('keyup.dismiss.bs.modal')
146
+ this.$element.off('keydown.dismiss.bs.modal')
147
+ }
148
+ }
149
+
150
+ Modal.prototype.resize = function () {
151
+ if (this.isShown) {
152
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
153
+ } else {
154
+ $(window).off('resize.bs.modal')
123
155
  }
124
156
  }
125
157
 
@@ -127,7 +159,9 @@
127
159
  var that = this
128
160
  this.$element.hide()
129
161
  this.backdrop(function () {
130
- that.removeBackdrop()
162
+ that.$body.removeClass('modal-open')
163
+ that.resetAdjustments()
164
+ that.resetScrollbar()
131
165
  that.$element.trigger('hidden.bs.modal')
132
166
  })
133
167
  }
@@ -138,19 +172,25 @@
138
172
  }
139
173
 
140
174
  Modal.prototype.backdrop = function (callback) {
175
+ var that = this
141
176
  var animate = this.$element.hasClass('fade') ? 'fade' : ''
142
177
 
143
178
  if (this.isShown && this.options.backdrop) {
144
179
  var doAnimate = $.support.transition && animate
145
180
 
146
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
147
- .appendTo(document.body)
181
+ this.$backdrop = $(document.createElement('div'))
182
+ .addClass('modal-backdrop ' + animate)
183
+ .appendTo(this.$body)
148
184
 
149
185
  this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
186
+ if (this.ignoreBackdropClick) {
187
+ this.ignoreBackdropClick = false
188
+ return
189
+ }
150
190
  if (e.target !== e.currentTarget) return
151
191
  this.options.backdrop == 'static'
152
- ? this.$element[0].focus.call(this.$element[0])
153
- : this.hide.call(this)
192
+ ? this.$element[0].focus()
193
+ : this.hide()
154
194
  }, this))
155
195
 
156
196
  if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
@@ -161,31 +201,84 @@
161
201
 
162
202
  doAnimate ?
163
203
  this.$backdrop
164
- .one($.support.transition.end, callback)
165
- .emulateTransitionEnd(150) :
204
+ .one('bsTransitionEnd', callback)
205
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
166
206
  callback()
167
207
 
168
208
  } else if (!this.isShown && this.$backdrop) {
169
209
  this.$backdrop.removeClass('in')
170
210
 
211
+ var callbackRemove = function () {
212
+ that.removeBackdrop()
213
+ callback && callback()
214
+ }
171
215
  $.support.transition && this.$element.hasClass('fade') ?
172
216
  this.$backdrop
173
- .one($.support.transition.end, callback)
174
- .emulateTransitionEnd(150) :
175
- callback()
217
+ .one('bsTransitionEnd', callbackRemove)
218
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
219
+ callbackRemove()
176
220
 
177
221
  } else if (callback) {
178
222
  callback()
179
223
  }
180
224
  }
181
225
 
226
+ // these following methods are used to handle overflowing modals
227
+
228
+ Modal.prototype.handleUpdate = function () {
229
+ this.adjustDialog()
230
+ }
231
+
232
+ Modal.prototype.adjustDialog = function () {
233
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
234
+
235
+ this.$element.css({
236
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
237
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
238
+ })
239
+ }
240
+
241
+ Modal.prototype.resetAdjustments = function () {
242
+ this.$element.css({
243
+ paddingLeft: '',
244
+ paddingRight: ''
245
+ })
246
+ }
247
+
248
+ Modal.prototype.checkScrollbar = function () {
249
+ var fullWindowWidth = window.innerWidth
250
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
251
+ var documentElementRect = document.documentElement.getBoundingClientRect()
252
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
253
+ }
254
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
255
+ this.scrollbarWidth = this.measureScrollbar()
256
+ }
257
+
258
+ Modal.prototype.setScrollbar = function () {
259
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
260
+ this.originalBodyPad = document.body.style.paddingRight || ''
261
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
262
+ }
263
+
264
+ Modal.prototype.resetScrollbar = function () {
265
+ this.$body.css('padding-right', this.originalBodyPad)
266
+ }
267
+
268
+ Modal.prototype.measureScrollbar = function () { // thx walsh
269
+ var scrollDiv = document.createElement('div')
270
+ scrollDiv.className = 'modal-scrollbar-measure'
271
+ this.$body.append(scrollDiv)
272
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
273
+ this.$body[0].removeChild(scrollDiv)
274
+ return scrollbarWidth
275
+ }
276
+
182
277
 
183
278
  // MODAL PLUGIN DEFINITION
184
279
  // =======================
185
280
 
186
- var old = $.fn.modal
187
-
188
- $.fn.modal = function (option, _relatedTarget) {
281
+ function Plugin(option, _relatedTarget) {
189
282
  return this.each(function () {
190
283
  var $this = $(this)
191
284
  var data = $this.data('bs.modal')
@@ -197,6 +290,9 @@
197
290
  })
198
291
  }
199
292
 
293
+ var old = $.fn.modal
294
+
295
+ $.fn.modal = Plugin
200
296
  $.fn.modal.Constructor = Modal
201
297
 
202
298
 
@@ -215,20 +311,18 @@
215
311
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
216
312
  var $this = $(this)
217
313
  var href = $this.attr('href')
218
- var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
314
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
219
315
  var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
220
316
 
221
317
  if ($this.is('a')) e.preventDefault()
222
318
 
223
- $target
224
- .modal(option, this)
225
- .one('hide', function () {
226
- $this.is(':visible') && $this.focus()
319
+ $target.one('show.bs.modal', function (showEvent) {
320
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
321
+ $target.one('hidden.bs.modal', function () {
322
+ $this.is(':visible') && $this.trigger('focus')
227
323
  })
324
+ })
325
+ Plugin.call($target, option, this)
228
326
  })
229
327
 
230
- $(document)
231
- .on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
232
- .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })
233
-
234
328
  }(jQuery);
@@ -10,7 +10,7 @@
10
10
 
11
11
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
12
12
 
13
- Popover.VERSION = '3.3.2'
13
+ Popover.VERSION = '3.3.6'
14
14
 
15
15
  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
16
16
  placement: 'right',
@@ -66,11 +66,6 @@
66
66
  return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
67
67
  }
68
68
 
69
- Popover.prototype.tip = function () {
70
- if (!this.$tip) this.$tip = $(this.options.template)
71
- return this.$tip
72
- }
73
-
74
69
 
75
70
  // POPOVER PLUGIN DEFINITION
76
71
  // =========================
@@ -81,7 +76,7 @@
81
76
  var data = $this.data('bs.popover')
82
77
  var options = typeof option == 'object' && option
83
78
 
84
- if (!data && option == 'destroy') return
79
+ if (!data && /destroy|hide/.test(option)) return
85
80
  if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
86
81
  if (typeof option == 'string') data[option]()
87
82
  })
@@ -5,10 +5,8 @@
5
5
  // ==========================
6
6
 
7
7
  function ScrollSpy(element, options) {
8
- var process = $.proxy(this.process, this)
9
-
10
- this.$body = $('body')
11
- this.$scrollElement = $(element).is('body') ? $(window) : $(element)
8
+ this.$body = $(document.body)
9
+ this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
12
10
  this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
13
11
  this.selector = (this.options.target || '') + ' .nav li > a'
14
12
  this.offsets = []
@@ -16,12 +14,12 @@
16
14
  this.activeTarget = null
17
15
  this.scrollHeight = 0
18
16
 
19
- this.$scrollElement.on('scroll.bs.scrollspy', process)
17
+ this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
20
18
  this.refresh()
21
19
  this.process()
22
20
  }
23
21
 
24
- ScrollSpy.VERSION = '3.3.2'
22
+ ScrollSpy.VERSION = '3.3.6'
25
23
 
26
24
  ScrollSpy.DEFAULTS = {
27
25
  offset: 10
@@ -32,20 +30,19 @@
32
30
  }
33
31
 
34
32
  ScrollSpy.prototype.refresh = function () {
35
- var offsetMethod = 'offset'
36
- var offsetBase = 0
33
+ var that = this
34
+ var offsetMethod = 'offset'
35
+ var offsetBase = 0
36
+
37
+ this.offsets = []
38
+ this.targets = []
39
+ this.scrollHeight = this.getScrollHeight()
37
40
 
38
41
  if (!$.isWindow(this.$scrollElement[0])) {
39
42
  offsetMethod = 'position'
40
43
  offsetBase = this.$scrollElement.scrollTop()
41
44
  }
42
45
 
43
- this.offsets = []
44
- this.targets = []
45
- this.scrollHeight = this.getScrollHeight()
46
-
47
- var self = this
48
-
49
46
  this.$body
50
47
  .find(this.selector)
51
48
  .map(function () {
@@ -60,8 +57,8 @@
60
57
  })
61
58
  .sort(function (a, b) { return a[0] - b[0] })
62
59
  .each(function () {
63
- self.offsets.push(this[0])
64
- self.targets.push(this[1])
60
+ that.offsets.push(this[0])
61
+ that.targets.push(this[1])
65
62
  })
66
63
  }
67
64
 
@@ -90,7 +87,7 @@
90
87
  for (i = offsets.length; i--;) {
91
88
  activeTarget != targets[i]
92
89
  && scrollTop >= offsets[i]
93
- && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
90
+ && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
94
91
  && this.activate(targets[i])
95
92
  }
96
93
  }
@@ -101,8 +98,8 @@
101
98
  this.clear()
102
99
 
103
100
  var selector = this.selector +
104
- '[data-target="' + target + '"],' +
105
- this.selector + '[href="' + target + '"]'
101
+ '[data-target="' + target + '"],' +
102
+ this.selector + '[href="' + target + '"]'
106
103
 
107
104
  var active = $(selector)
108
105
  .parents('li')
@@ -1,4 +1,4 @@
1
- (function(root, factory) {
1
+ (function(factory) {
2
2
  if(typeof define === "function" && define.amd) {
3
3
  define(["jquery"], factory);
4
4
  }
@@ -12,10 +12,10 @@
12
12
  }
13
13
  module.exports = factory(jQuery);
14
14
  }
15
- else {
16
- root.Slider = factory(root.jQuery);
15
+ else if(window) {
16
+ window.Slider = factory(window.jQuery);
17
17
  }
18
- }(this, function($) {
18
+ }(function($) {
19
19
  // Reference to Slider constructor
20
20
  var Slider;
21
21
 
@@ -174,25 +174,26 @@
174
174
  linear: {
175
175
  toValue: function(percentage) {
176
176
  var rawValue = percentage/100 * (this.options.max - this.options.min);
177
+ var shouldAdjustWithBase = true;
177
178
  if (this.options.ticks_positions.length > 0) {
178
179
  var minv, maxv, minp, maxp = 0;
179
- for (var i = 0; i < this.options.ticks_positions.length; i++) {
180
+ for (var i = 1; i < this.options.ticks_positions.length; i++) {
180
181
  if (percentage <= this.options.ticks_positions[i]) {
181
- minv = (i > 0) ? this.options.ticks[i-1] : 0;
182
- minp = (i > 0) ? this.options.ticks_positions[i-1] : 0;
182
+ minv = this.options.ticks[i-1];
183
+ minp = this.options.ticks_positions[i-1];
183
184
  maxv = this.options.ticks[i];
184
185
  maxp = this.options.ticks_positions[i];
185
186
 
186
187
  break;
187
188
  }
188
189
  }
189
- if (i > 0) {
190
- var partialPercentage = (percentage - minp) / (maxp - minp);
191
- rawValue = minv + partialPercentage * (maxv - minv);
192
- }
190
+ var partialPercentage = (percentage - minp) / (maxp - minp);
191
+ rawValue = minv + partialPercentage * (maxv - minv);
192
+ shouldAdjustWithBase = false;
193
193
  }
194
194
 
195
- var value = this.options.min + Math.round(rawValue / this.options.step) * this.options.step;
195
+ var adjustment = shouldAdjustWithBase ? this.options.min : 0;
196
+ var value = adjustment + Math.round(rawValue / this.options.step) * this.options.step;
196
197
  if (value < this.options.min) {
197
198
  return this.options.min;
198
199
  } else if (value > this.options.max) {
@@ -282,8 +283,8 @@
282
283
  offset: null,
283
284
  size: null,
284
285
  percentage: null,
285
- inDrag: null,
286
- over: null
286
+ inDrag: false,
287
+ over: false
287
288
  };
288
289
 
289
290
 
@@ -383,14 +384,33 @@
383
384
 
384
385
  sliderMinHandle = document.createElement("div");
385
386
  sliderMinHandle.className = "slider-handle min-slider-handle";
387
+ sliderMinHandle.setAttribute('role', 'slider');
388
+ sliderMinHandle.setAttribute('aria-valuemin', this.options.min);
389
+ sliderMinHandle.setAttribute('aria-valuemax', this.options.max);
386
390
 
387
391
  sliderMaxHandle = document.createElement("div");
388
392
  sliderMaxHandle.className = "slider-handle max-slider-handle";
393
+ sliderMaxHandle.setAttribute('role', 'slider');
394
+ sliderMaxHandle.setAttribute('aria-valuemin', this.options.min);
395
+ sliderMaxHandle.setAttribute('aria-valuemax', this.options.max);
389
396
 
390
397
  sliderTrack.appendChild(sliderTrackLow);
391
398
  sliderTrack.appendChild(sliderTrackSelection);
392
399
  sliderTrack.appendChild(sliderTrackHigh);
393
400
 
401
+ /* Add aria-labelledby to handle's */
402
+ var isLabelledbyArray = Array.isArray(this.options.labelledby);
403
+ if (isLabelledbyArray && this.options.labelledby[0]) {
404
+ sliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby[0]);
405
+ }
406
+ if (isLabelledbyArray && this.options.labelledby[1]) {
407
+ sliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby[1]);
408
+ }
409
+ if (!isLabelledbyArray && this.options.labelledby) {
410
+ sliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby);
411
+ sliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby);
412
+ }
413
+
394
414
  /* Create ticks */
395
415
  this.ticks = [];
396
416
  if (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {
@@ -415,8 +435,10 @@
415
435
 
416
436
  for (i = 0; i < this.options.ticks_labels.length; i++) {
417
437
  var label = document.createElement('div');
438
+ var noTickPositionsSpecified = this.options.ticks_positions.length === 0;
439
+ var tickLabelsIndex = (this.options.reversed && noTickPositionsSpecified) ? (this.options.ticks_labels.length - (i + 1)) : i;
418
440
  label.className = 'slider-tick-label';
419
- label.innerHTML = this.options.ticks_labels[i];
441
+ label.innerHTML = this.options.ticks_labels[tickLabelsIndex];
420
442
 
421
443
  this.tickLabels.push(label);
422
444
  this.tickLabelContainer.appendChild(label);
@@ -439,14 +461,17 @@
439
461
  /* Create tooltip elements */
440
462
  var sliderTooltip = document.createElement("div");
441
463
  sliderTooltip.className = "tooltip tooltip-main";
464
+ sliderTooltip.setAttribute('role', 'presentation');
442
465
  createAndAppendTooltipSubElements(sliderTooltip);
443
466
 
444
467
  var sliderTooltipMin = document.createElement("div");
445
468
  sliderTooltipMin.className = "tooltip tooltip-min";
469
+ sliderTooltipMin.setAttribute('role', 'presentation');
446
470
  createAndAppendTooltipSubElements(sliderTooltipMin);
447
471
 
448
472
  var sliderTooltipMax = document.createElement("div");
449
473
  sliderTooltipMax.className = "tooltip tooltip-max";
474
+ sliderTooltipMax.setAttribute('role', 'presentation');
450
475
  createAndAppendTooltipSubElements(sliderTooltipMax);
451
476
 
452
477
 
@@ -619,6 +644,10 @@
619
644
  }
620
645
  this.sliderElem.addEventListener("mousedown", this.mousedown, false);
621
646
 
647
+ // Bind window handlers
648
+ this.resize = this._resize.bind(this);
649
+ window.addEventListener("resize", this.resize, false);
650
+
622
651
 
623
652
  // Bind tooltip-related handlers
624
653
  if(this.options.tooltip === 'hide') {
@@ -649,6 +678,7 @@
649
678
  } else {
650
679
  this.disable();
651
680
  }
681
+
652
682
  }
653
683
 
654
684
 
@@ -695,7 +725,8 @@
695
725
  ticks_snap_bounds: 0,
696
726
  scale: 'linear',
697
727
  focus: false,
698
- tooltip_position: null
728
+ tooltip_position: null,
729
+ labelledby: null
699
730
  },
700
731
 
701
732
  getElement: function() {
@@ -824,14 +855,14 @@
824
855
  return this;
825
856
  },
826
857
 
827
- off: function(evt, callback) {
828
- if($) {
829
- this.$element.off(evt, callback);
830
- this.$sliderElem.off(evt, callback);
831
- } else {
832
- this._unbindNonQueryEventHandler(evt, callback);
833
- }
834
- },
858
+ off: function(evt, callback) {
859
+ if($) {
860
+ this.$element.off(evt, callback);
861
+ this.$sliderElem.off(evt, callback);
862
+ } else {
863
+ this._unbindNonQueryEventHandler(evt, callback);
864
+ }
865
+ },
835
866
 
836
867
  getAttribute: function(attribute) {
837
868
  if(attribute) {
@@ -872,21 +903,31 @@
872
903
 
873
904
  ********************************/
874
905
  _removeSliderEventHandlers: function() {
875
- // Remove event listeners from handle1
906
+ // Remove keydown event listeners
876
907
  this.handle1.removeEventListener("keydown", this.handle1Keydown, false);
877
- this.handle1.removeEventListener("focus", this.showTooltip, false);
878
- this.handle1.removeEventListener("blur", this.hideTooltip, false);
879
-
880
- // Remove event listeners from handle2
881
908
  this.handle2.removeEventListener("keydown", this.handle2Keydown, false);
882
- this.handle2.removeEventListener("focus", this.handle2Keydown, false);
883
- this.handle2.removeEventListener("blur", this.handle2Keydown, false);
909
+
910
+ if (this.showTooltip) {
911
+ this.handle1.removeEventListener("focus", this.showTooltip, false);
912
+ this.handle2.removeEventListener("focus", this.showTooltip, false);
913
+ }
914
+ if (this.hideTooltip) {
915
+ this.handle1.removeEventListener("blur", this.hideTooltip, false);
916
+ this.handle2.removeEventListener("blur", this.hideTooltip, false);
917
+ }
884
918
 
885
919
  // Remove event listeners from sliderElem
886
- this.sliderElem.removeEventListener("mouseenter", this.showTooltip, false);
887
- this.sliderElem.removeEventListener("mouseleave", this.hideTooltip, false);
920
+ if (this.showTooltip) {
921
+ this.sliderElem.removeEventListener("mouseenter", this.showTooltip, false);
922
+ }
923
+ if (this.hideTooltip) {
924
+ this.sliderElem.removeEventListener("mouseleave", this.hideTooltip, false);
925
+ }
888
926
  this.sliderElem.removeEventListener("touchstart", this.mousedown, false);
889
927
  this.sliderElem.removeEventListener("mousedown", this.mousedown, false);
928
+
929
+ // Remove window event listener
930
+ window.removeEventListener("resize", this.resize, false);
890
931
  },
891
932
  _bindNonQueryEventHandler: function(evt, callback) {
892
933
  if(this.eventToCallbackMap[evt] === undefined) {
@@ -894,17 +935,17 @@
894
935
  }
895
936
  this.eventToCallbackMap[evt].push(callback);
896
937
  },
897
- _unbindNonQueryEventHandler: function(evt, callback) {
898
- var callbacks = this.eventToCallbackMap[evt];
899
- if(callbacks !== undefined) {
900
- for (var i = 0; i < callbacks.length; i++) {
901
- if (callbacks[i] === callback) {
902
- callbacks.splice(i, 1);
903
- break;
904
- }
905
- }
906
- }
907
- },
938
+ _unbindNonQueryEventHandler: function(evt, callback) {
939
+ var callbacks = this.eventToCallbackMap[evt];
940
+ if(callbacks !== undefined) {
941
+ for (var i = 0; i < callbacks.length; i++) {
942
+ if (callbacks[i] === callback) {
943
+ callbacks.splice(i, 1);
944
+ break;
945
+ }
946
+ }
947
+ }
948
+ },
908
949
  _cleanUpEventCallbacksMap: function() {
909
950
  var eventNames = Object.keys(this.eventToCallbackMap);
910
951
  for(var i = 0; i < eventNames.length; i++) {
@@ -943,12 +984,13 @@
943
984
  }
944
985
 
945
986
  this.handle1.style[this.stylePos] = positionPercentages[0]+'%';
987
+ this.handle1.setAttribute('aria-valuenow', this._state.value[0]);
988
+
946
989
  this.handle2.style[this.stylePos] = positionPercentages[1]+'%';
990
+ this.handle2.setAttribute('aria-valuenow', this._state.value[1]);
947
991
 
948
992
  /* Position ticks and labels */
949
993
  if (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {
950
- var maxTickValue = Math.max.apply(Math, this.options.ticks);
951
- var minTickValue = Math.min.apply(Math, this.options.ticks);
952
994
 
953
995
  var styleSize = this.options.orientation === 'vertical' ? 'height' : 'width';
954
996
  var styleMargin = this.options.orientation === 'vertical' ? 'marginTop' : 'marginLeft';
@@ -957,7 +999,10 @@
957
999
  if (this.tickLabelContainer) {
958
1000
  var extraMargin = 0;
959
1001
  if (this.options.ticks_positions.length === 0) {
960
- this.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px';
1002
+ if (this.options.orientation !== 'vertical') {
1003
+ this.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px';
1004
+ }
1005
+
961
1006
  extraMargin = this.tickLabelContainer.offsetHeight;
962
1007
  } else {
963
1008
  /* Chidren are position absolute, calculate height by finding the max offsetHeight of a child */
@@ -973,8 +1018,11 @@
973
1018
  }
974
1019
  for (var i = 0; i < this.options.ticks.length; i++) {
975
1020
 
976
- var percentage = this.options.ticks_positions[i] ||
977
- 100 * (this.options.ticks[i] - minTickValue) / (maxTickValue - minTickValue);
1021
+ var percentage = this.options.ticks_positions[i] || this._toPercentage(this.options.ticks[i]);
1022
+
1023
+ if (this.options.reversed) {
1024
+ percentage = 100 - percentage;
1025
+ }
978
1026
 
979
1027
  this.ticks[i].style[this.stylePos] = percentage + '%';
980
1028
 
@@ -993,49 +1041,18 @@
993
1041
  if (this.tickLabels[i]) {
994
1042
  this.tickLabels[i].style[styleSize] = labelSize + 'px';
995
1043
 
996
- if (this.options.ticks_positions[i] !== undefined) {
1044
+ if (this.options.orientation !== 'vertical' && this.options.ticks_positions[i] !== undefined) {
997
1045
  this.tickLabels[i].style.position = 'absolute';
998
- this.tickLabels[i].style[this.stylePos] = this.options.ticks_positions[i] + '%';
1046
+ this.tickLabels[i].style[this.stylePos] = percentage + '%';
999
1047
  this.tickLabels[i].style[styleMargin] = -labelSize/2 + 'px';
1048
+ } else if (this.options.orientation === 'vertical') {
1049
+ this.tickLabels[i].style['marginLeft'] = this.sliderElem.offsetWidth + 'px';
1050
+ this.tickLabelContainer.style['marginTop'] = this.sliderElem.offsetWidth / 2 * -1 + 'px';
1000
1051
  }
1001
1052
  }
1002
1053
  }
1003
1054
  }
1004
1055
 
1005
- if (this.options.orientation === 'vertical') {
1006
- this.trackLow.style.top = '0';
1007
- this.trackLow.style.height = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1008
-
1009
- this.trackSelection.style.top = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1010
- this.trackSelection.style.height = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';
1011
-
1012
- this.trackHigh.style.bottom = '0';
1013
- this.trackHigh.style.height = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';
1014
- }
1015
- else {
1016
- this.trackLow.style.left = '0';
1017
- this.trackLow.style.width = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1018
-
1019
- this.trackSelection.style.left = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1020
- this.trackSelection.style.width = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';
1021
-
1022
- this.trackHigh.style.right = '0';
1023
- this.trackHigh.style.width = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';
1024
-
1025
- var offset_min = this.tooltip_min.getBoundingClientRect();
1026
- var offset_max = this.tooltip_max.getBoundingClientRect();
1027
-
1028
- if (offset_min.right > offset_max.left) {
1029
- this._removeClass(this.tooltip_max, 'top');
1030
- this._addClass(this.tooltip_max, 'bottom');
1031
- this.tooltip_max.style.top = 18 + 'px';
1032
- } else {
1033
- this._removeClass(this.tooltip_max, 'bottom');
1034
- this._addClass(this.tooltip_max, 'top');
1035
- this.tooltip_max.style.top = this.tooltip_min.style.top;
1036
- }
1037
- }
1038
-
1039
1056
  var formattedTooltipVal;
1040
1057
 
1041
1058
  if (this.options.range) {
@@ -1087,6 +1104,60 @@
1087
1104
  this._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px');
1088
1105
  }
1089
1106
  }
1107
+
1108
+ if (this.options.orientation === 'vertical') {
1109
+ this.trackLow.style.top = '0';
1110
+ this.trackLow.style.height = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1111
+
1112
+ this.trackSelection.style.top = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1113
+ this.trackSelection.style.height = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';
1114
+
1115
+ this.trackHigh.style.bottom = '0';
1116
+ this.trackHigh.style.height = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';
1117
+ }
1118
+ else {
1119
+ this.trackLow.style.left = '0';
1120
+ this.trackLow.style.width = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1121
+
1122
+ this.trackSelection.style.left = Math.min(positionPercentages[0], positionPercentages[1]) +'%';
1123
+ this.trackSelection.style.width = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';
1124
+
1125
+ this.trackHigh.style.right = '0';
1126
+ this.trackHigh.style.width = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';
1127
+
1128
+ var offset_min = this.tooltip_min.getBoundingClientRect();
1129
+ var offset_max = this.tooltip_max.getBoundingClientRect();
1130
+
1131
+ if (this.options.tooltip_position === 'bottom') {
1132
+ if (offset_min.right > offset_max.left) {
1133
+ this._removeClass(this.tooltip_max, 'bottom');
1134
+ this._addClass(this.tooltip_max, 'top');
1135
+ this.tooltip_max.style.top = '';
1136
+ this.tooltip_max.style.bottom = 22 + 'px';
1137
+ } else {
1138
+ this._removeClass(this.tooltip_max, 'top');
1139
+ this._addClass(this.tooltip_max, 'bottom');
1140
+ this.tooltip_max.style.top = this.tooltip_min.style.top;
1141
+ this.tooltip_max.style.bottom = '';
1142
+ }
1143
+ } else {
1144
+ if (offset_min.right > offset_max.left) {
1145
+ this._removeClass(this.tooltip_max, 'top');
1146
+ this._addClass(this.tooltip_max, 'bottom');
1147
+ this.tooltip_max.style.top = 18 + 'px';
1148
+ } else {
1149
+ this._removeClass(this.tooltip_max, 'bottom');
1150
+ this._addClass(this.tooltip_max, 'top');
1151
+ this.tooltip_max.style.top = this.tooltip_min.style.top;
1152
+ }
1153
+ }
1154
+ }
1155
+ },
1156
+ _resize: function (ev) {
1157
+ /*jshint unused:false*/
1158
+ this._state.offset = this._offset(this.sliderElem);
1159
+ this._state.size = this.sliderElem[this.sizePos];
1160
+ this._layout();
1090
1161
  },
1091
1162
  _removeProperty: function(element, prop) {
1092
1163
  if (element.style.removeProperty) {