active_frontend 12.2.0 → 12.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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) {