bootstrap3-rails 3.1.1 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1eda9ae23dd3f5a5fc4c69009531a21d2f200606
4
- data.tar.gz: 22159ded6d5b520a038dabf3279a1b35a60d7294
3
+ metadata.gz: f51f9934299de2e7ca6dc4b36e2d794fa0c8c5fb
4
+ data.tar.gz: 3bb47b1e4f6781545433dc7765e9d630ccfe9663
5
5
  SHA512:
6
- metadata.gz: 8d263547c17fa24e300d29b73a5d293b06cbe5062d7dd6d60c54a1e625dfc9ff1944ee85f9c1208a66d1a9f7430d320805ddab2e3361f76bc9ce1c060b3498be
7
- data.tar.gz: ab561a17b2a77f01c0f1b50194f342b5bb9f8578d1e938ba1388ce3d1da31db4c605f688fd431167e2dec3237d841fd365378a791bcbb42d96dc007362cdeacc
6
+ metadata.gz: 069cff399c70b46934c0c67afd8bfb5814380adfe22ba3e66607a788ff92fb0539c4d18e8c959bc67c5eb228a74c1947a816f0c1044d28410d61fe9e8c45f06b
7
+ data.tar.gz: a6be8e4e1173431934d259396a13d0677776f085907c738882486d511a4e7afae34a1d678b548a98aa0b9ca5a603ceb2bf42a30675f8dac7386e624d02b365de
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Bootstrap3::Rails
2
2
 
3
- Easily add [Bootstrap v3.1.1](https://github.com/twbs/bootstrap/) to your Rails application using the asset pipeline.
3
+ Easily add [Bootstrap v3.2.0](https://github.com/twbs/bootstrap/) to your Rails application using the asset pipeline.
4
4
 
5
- More informations about Bootstrap v3.1.1 on (http://getbootstrap.com/).
5
+ More informations about Bootstrap v3.2.0 on (http://getbootstrap.com/).
6
6
 
7
7
  ## Installation
8
8
 
@@ -1,5 +1,5 @@
1
1
  module Bootstrap3
2
2
  module Rails
3
- VERSION = "3.1.1"
3
+ VERSION = "3.2.0"
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Bootstrap v3.1.1 (http://getbootstrap.com)
2
+ * Bootstrap v3.2.0 (http://getbootstrap.com)
3
3
  * Copyright 2011-2014 Twitter, Inc.
4
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
5
  */
@@ -7,7 +7,7 @@
7
7
  if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') }
8
8
 
9
9
  /* ========================================================================
10
- * Bootstrap: transition.js v3.1.1
10
+ * Bootstrap: transition.js v3.2.0
11
11
  * http://getbootstrap.com/javascript/#transitions
12
12
  * ========================================================================
13
13
  * Copyright 2011-2014 Twitter, Inc.
@@ -25,10 +25,10 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
25
25
  var el = document.createElement('bootstrap')
26
26
 
27
27
  var transEndEventNames = {
28
- 'WebkitTransition' : 'webkitTransitionEnd',
29
- 'MozTransition' : 'transitionend',
30
- 'OTransition' : 'oTransitionEnd otransitionend',
31
- 'transition' : 'transitionend'
28
+ WebkitTransition : 'webkitTransitionEnd',
29
+ MozTransition : 'transitionend',
30
+ OTransition : 'oTransitionEnd otransitionend',
31
+ transition : 'transitionend'
32
32
  }
33
33
 
34
34
  for (var name in transEndEventNames) {
@@ -42,8 +42,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
42
42
 
43
43
  // http://blog.alexmaccaw.com/css-transitions
44
44
  $.fn.emulateTransitionEnd = function (duration) {
45
- var called = false, $el = this
46
- $(this).one($.support.transition.end, function () { called = true })
45
+ var called = false
46
+ var $el = this
47
+ $(this).one('bsTransitionEnd', function () { called = true })
47
48
  var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
48
49
  setTimeout(callback, duration)
49
50
  return this
@@ -51,12 +52,22 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
51
52
 
52
53
  $(function () {
53
54
  $.support.transition = transitionEnd()
55
+
56
+ if (!$.support.transition) return
57
+
58
+ $.event.special.bsTransitionEnd = {
59
+ bindType: $.support.transition.end,
60
+ delegateType: $.support.transition.end,
61
+ handle: function (e) {
62
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
63
+ }
64
+ }
54
65
  })
55
66
 
56
67
  }(jQuery);
57
68
 
58
69
  /* ========================================================================
59
- * Bootstrap: alert.js v3.1.1
70
+ * Bootstrap: alert.js v3.2.0
60
71
  * http://getbootstrap.com/javascript/#alerts
61
72
  * ========================================================================
62
73
  * Copyright 2011-2014 Twitter, Inc.
@@ -75,6 +86,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
75
86
  $(el).on('click', dismiss, this.close)
76
87
  }
77
88
 
89
+ Alert.VERSION = '3.2.0'
90
+
78
91
  Alert.prototype.close = function (e) {
79
92
  var $this = $(this)
80
93
  var selector = $this.attr('data-target')
@@ -99,12 +112,13 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
99
112
  $parent.removeClass('in')
100
113
 
101
114
  function removeElement() {
102
- $parent.trigger('closed.bs.alert').remove()
115
+ // detach from parent, fire event then clean up data
116
+ $parent.detach().trigger('closed.bs.alert').remove()
103
117
  }
104
118
 
105
119
  $.support.transition && $parent.hasClass('fade') ?
106
120
  $parent
107
- .one($.support.transition.end, removeElement)
121
+ .one('bsTransitionEnd', removeElement)
108
122
  .emulateTransitionEnd(150) :
109
123
  removeElement()
110
124
  }
@@ -113,9 +127,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
113
127
  // ALERT PLUGIN DEFINITION
114
128
  // =======================
115
129
 
116
- var old = $.fn.alert
117
-
118
- $.fn.alert = function (option) {
130
+ function Plugin(option) {
119
131
  return this.each(function () {
120
132
  var $this = $(this)
121
133
  var data = $this.data('bs.alert')
@@ -125,6 +137,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
125
137
  })
126
138
  }
127
139
 
140
+ var old = $.fn.alert
141
+
142
+ $.fn.alert = Plugin
128
143
  $.fn.alert.Constructor = Alert
129
144
 
130
145
 
@@ -145,7 +160,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
145
160
  }(jQuery);
146
161
 
147
162
  /* ========================================================================
148
- * Bootstrap: button.js v3.1.1
163
+ * Bootstrap: button.js v3.2.0
149
164
  * http://getbootstrap.com/javascript/#buttons
150
165
  * ========================================================================
151
166
  * Copyright 2011-2014 Twitter, Inc.
@@ -165,6 +180,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
165
180
  this.isLoading = false
166
181
  }
167
182
 
183
+ Button.VERSION = '3.2.0'
184
+
168
185
  Button.DEFAULTS = {
169
186
  loadingText: 'loading...'
170
187
  }
@@ -177,9 +194,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
177
194
 
178
195
  state = state + 'Text'
179
196
 
180
- if (!data.resetText) $el.data('resetText', $el[val]())
197
+ if (data.resetText == null) $el.data('resetText', $el[val]())
181
198
 
182
- $el[val](data[state] || this.options[state])
199
+ $el[val](data[state] == null ? this.options[state] : data[state])
183
200
 
184
201
  // push to event loop to allow forms to submit
185
202
  setTimeout($.proxy(function () {
@@ -213,9 +230,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
213
230
  // BUTTON PLUGIN DEFINITION
214
231
  // ========================
215
232
 
216
- var old = $.fn.button
217
-
218
- $.fn.button = function (option) {
233
+ function Plugin(option) {
219
234
  return this.each(function () {
220
235
  var $this = $(this)
221
236
  var data = $this.data('bs.button')
@@ -228,6 +243,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
228
243
  })
229
244
  }
230
245
 
246
+ var old = $.fn.button
247
+
248
+ $.fn.button = Plugin
231
249
  $.fn.button.Constructor = Button
232
250
 
233
251
 
@@ -243,17 +261,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
243
261
  // BUTTON DATA-API
244
262
  // ===============
245
263
 
246
- $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
264
+ $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
247
265
  var $btn = $(e.target)
248
266
  if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
249
- $btn.button('toggle')
267
+ Plugin.call($btn, 'toggle')
250
268
  e.preventDefault()
251
269
  })
252
270
 
253
271
  }(jQuery);
254
272
 
255
273
  /* ========================================================================
256
- * Bootstrap: carousel.js v3.1.1
274
+ * Bootstrap: carousel.js v3.2.0
257
275
  * http://getbootstrap.com/javascript/#carousel
258
276
  * ========================================================================
259
277
  * Copyright 2011-2014 Twitter, Inc.
@@ -268,7 +286,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
268
286
  // =========================
269
287
 
270
288
  var Carousel = function (element, options) {
271
- this.$element = $(element)
289
+ this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
272
290
  this.$indicators = this.$element.find('.carousel-indicators')
273
291
  this.options = options
274
292
  this.paused =
@@ -278,17 +296,29 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
278
296
  this.$items = null
279
297
 
280
298
  this.options.pause == 'hover' && this.$element
281
- .on('mouseenter', $.proxy(this.pause, this))
282
- .on('mouseleave', $.proxy(this.cycle, this))
299
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
300
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
283
301
  }
284
302
 
303
+ Carousel.VERSION = '3.2.0'
304
+
285
305
  Carousel.DEFAULTS = {
286
306
  interval: 5000,
287
307
  pause: 'hover',
288
308
  wrap: true
289
309
  }
290
310
 
291
- Carousel.prototype.cycle = function (e) {
311
+ Carousel.prototype.keydown = function (e) {
312
+ switch (e.which) {
313
+ case 37: this.prev(); break
314
+ case 39: this.next(); break
315
+ default: return
316
+ }
317
+
318
+ e.preventDefault()
319
+ }
320
+
321
+ Carousel.prototype.cycle = function (e) {
292
322
  e || (this.paused = false)
293
323
 
294
324
  this.interval && clearInterval(this.interval)
@@ -300,20 +330,18 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
300
330
  return this
301
331
  }
302
332
 
303
- Carousel.prototype.getActiveIndex = function () {
304
- this.$active = this.$element.find('.item.active')
305
- this.$items = this.$active.parent().children()
306
-
307
- return this.$items.index(this.$active)
333
+ Carousel.prototype.getItemIndex = function (item) {
334
+ this.$items = item.parent().children('.item')
335
+ return this.$items.index(item || this.$active)
308
336
  }
309
337
 
310
338
  Carousel.prototype.to = function (pos) {
311
339
  var that = this
312
- var activeIndex = this.getActiveIndex()
340
+ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
313
341
 
314
342
  if (pos > (this.$items.length - 1) || pos < 0) return
315
343
 
316
- if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) })
344
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
317
345
  if (activeIndex == pos) return this.pause().cycle()
318
346
 
319
347
  return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
@@ -355,11 +383,15 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
355
383
  $next = this.$element.find('.item')[fallback]()
356
384
  }
357
385
 
358
- if ($next.hasClass('active')) return this.sliding = false
386
+ if ($next.hasClass('active')) return (this.sliding = false)
359
387
 
360
- var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })
361
- this.$element.trigger(e)
362
- if (e.isDefaultPrevented()) return
388
+ var relatedTarget = $next[0]
389
+ var slideEvent = $.Event('slide.bs.carousel', {
390
+ relatedTarget: relatedTarget,
391
+ direction: direction
392
+ })
393
+ this.$element.trigger(slideEvent)
394
+ if (slideEvent.isDefaultPrevented()) return
363
395
 
364
396
  this.sliding = true
365
397
 
@@ -367,30 +399,31 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
367
399
 
368
400
  if (this.$indicators.length) {
369
401
  this.$indicators.find('.active').removeClass('active')
370
- this.$element.one('slid.bs.carousel', function () {
371
- var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
372
- $nextIndicator && $nextIndicator.addClass('active')
373
- })
402
+ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
403
+ $nextIndicator && $nextIndicator.addClass('active')
374
404
  }
375
405
 
406
+ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
376
407
  if ($.support.transition && this.$element.hasClass('slide')) {
377
408
  $next.addClass(type)
378
409
  $next[0].offsetWidth // force reflow
379
410
  $active.addClass(direction)
380
411
  $next.addClass(direction)
381
412
  $active
382
- .one($.support.transition.end, function () {
413
+ .one('bsTransitionEnd', function () {
383
414
  $next.removeClass([type, direction].join(' ')).addClass('active')
384
415
  $active.removeClass(['active', direction].join(' '))
385
416
  that.sliding = false
386
- setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)
417
+ setTimeout(function () {
418
+ that.$element.trigger(slidEvent)
419
+ }, 0)
387
420
  })
388
421
  .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
389
422
  } else {
390
423
  $active.removeClass('active')
391
424
  $next.addClass('active')
392
425
  this.sliding = false
393
- this.$element.trigger('slid.bs.carousel')
426
+ this.$element.trigger(slidEvent)
394
427
  }
395
428
 
396
429
  isCycling && this.cycle()
@@ -402,9 +435,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
402
435
  // CAROUSEL PLUGIN DEFINITION
403
436
  // ==========================
404
437
 
405
- var old = $.fn.carousel
406
-
407
- $.fn.carousel = function (option) {
438
+ function Plugin(option) {
408
439
  return this.each(function () {
409
440
  var $this = $(this)
410
441
  var data = $this.data('bs.carousel')
@@ -418,6 +449,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
418
449
  })
419
450
  }
420
451
 
452
+ var old = $.fn.carousel
453
+
454
+ $.fn.carousel = Plugin
421
455
  $.fn.carousel.Constructor = Carousel
422
456
 
423
457
 
@@ -434,15 +468,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
434
468
  // =================
435
469
 
436
470
  $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
437
- var $this = $(this), href
438
- var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
471
+ var href
472
+ var $this = $(this)
473
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
474
+ if (!$target.hasClass('carousel')) return
439
475
  var options = $.extend({}, $target.data(), $this.data())
440
476
  var slideIndex = $this.attr('data-slide-to')
441
477
  if (slideIndex) options.interval = false
442
478
 
443
- $target.carousel(options)
479
+ Plugin.call($target, options)
444
480
 
445
- if (slideIndex = $this.attr('data-slide-to')) {
481
+ if (slideIndex) {
446
482
  $target.data('bs.carousel').to(slideIndex)
447
483
  }
448
484
 
@@ -452,14 +488,14 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
452
488
  $(window).on('load', function () {
453
489
  $('[data-ride="carousel"]').each(function () {
454
490
  var $carousel = $(this)
455
- $carousel.carousel($carousel.data())
491
+ Plugin.call($carousel, $carousel.data())
456
492
  })
457
493
  })
458
494
 
459
495
  }(jQuery);
460
496
 
461
497
  /* ========================================================================
462
- * Bootstrap: collapse.js v3.1.1
498
+ * Bootstrap: collapse.js v3.2.0
463
499
  * http://getbootstrap.com/javascript/#collapse
464
500
  * ========================================================================
465
501
  * Copyright 2011-2014 Twitter, Inc.
@@ -482,6 +518,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
482
518
  if (this.options.toggle) this.toggle()
483
519
  }
484
520
 
521
+ Collapse.VERSION = '3.2.0'
522
+
485
523
  Collapse.DEFAULTS = {
486
524
  toggle: true
487
525
  }
@@ -503,7 +541,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
503
541
  if (actives && actives.length) {
504
542
  var hasData = actives.data('bs.collapse')
505
543
  if (hasData && hasData.transitioning) return
506
- actives.collapse('hide')
544
+ Plugin.call(actives, 'hide')
507
545
  hasData || actives.data('bs.collapse', null)
508
546
  }
509
547
 
@@ -511,18 +549,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
511
549
 
512
550
  this.$element
513
551
  .removeClass('collapse')
514
- .addClass('collapsing')
515
- [dimension](0)
552
+ .addClass('collapsing')[dimension](0)
516
553
 
517
554
  this.transitioning = 1
518
555
 
519
556
  var complete = function () {
520
557
  this.$element
521
558
  .removeClass('collapsing')
522
- .addClass('collapse in')
523
- [dimension]('auto')
559
+ .addClass('collapse in')[dimension]('')
524
560
  this.transitioning = 0
525
- this.$element.trigger('shown.bs.collapse')
561
+ this.$element
562
+ .trigger('shown.bs.collapse')
526
563
  }
527
564
 
528
565
  if (!$.support.transition) return complete.call(this)
@@ -530,9 +567,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
530
567
  var scrollSize = $.camelCase(['scroll', dimension].join('-'))
531
568
 
532
569
  this.$element
533
- .one($.support.transition.end, $.proxy(complete, this))
534
- .emulateTransitionEnd(350)
535
- [dimension](this.$element[0][scrollSize])
570
+ .one('bsTransitionEnd', $.proxy(complete, this))
571
+ .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
536
572
  }
537
573
 
538
574
  Collapse.prototype.hide = function () {
@@ -544,9 +580,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
544
580
 
545
581
  var dimension = this.dimension()
546
582
 
547
- this.$element
548
- [dimension](this.$element[dimension]())
549
- [0].offsetHeight
583
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
550
584
 
551
585
  this.$element
552
586
  .addClass('collapsing')
@@ -567,7 +601,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
567
601
 
568
602
  this.$element
569
603
  [dimension](0)
570
- .one($.support.transition.end, $.proxy(complete, this))
604
+ .one('bsTransitionEnd', $.proxy(complete, this))
571
605
  .emulateTransitionEnd(350)
572
606
  }
573
607
 
@@ -579,9 +613,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
579
613
  // COLLAPSE PLUGIN DEFINITION
580
614
  // ==========================
581
615
 
582
- var old = $.fn.collapse
583
-
584
- $.fn.collapse = function (option) {
616
+ function Plugin(option) {
585
617
  return this.each(function () {
586
618
  var $this = $(this)
587
619
  var data = $this.data('bs.collapse')
@@ -593,6 +625,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
593
625
  })
594
626
  }
595
627
 
628
+ var old = $.fn.collapse
629
+
630
+ $.fn.collapse = Plugin
596
631
  $.fn.collapse.Constructor = Collapse
597
632
 
598
633
 
@@ -608,11 +643,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
608
643
  // COLLAPSE DATA-API
609
644
  // =================
610
645
 
611
- $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
612
- var $this = $(this), href
646
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
647
+ var href
648
+ var $this = $(this)
613
649
  var target = $this.attr('data-target')
614
650
  || e.preventDefault()
615
- || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
651
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
616
652
  var $target = $(target)
617
653
  var data = $target.data('bs.collapse')
618
654
  var option = data ? 'toggle' : $this.data()
@@ -620,17 +656,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
620
656
  var $parent = parent && $(parent)
621
657
 
622
658
  if (!data || !data.transitioning) {
623
- if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
659
+ if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
624
660
  $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
625
661
  }
626
662
 
627
- $target.collapse(option)
663
+ Plugin.call($target, option)
628
664
  })
629
665
 
630
666
  }(jQuery);
631
667
 
632
668
  /* ========================================================================
633
- * Bootstrap: dropdown.js v3.1.1
669
+ * Bootstrap: dropdown.js v3.2.0
634
670
  * http://getbootstrap.com/javascript/#dropdowns
635
671
  * ========================================================================
636
672
  * Copyright 2011-2014 Twitter, Inc.
@@ -645,11 +681,13 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
645
681
  // =========================
646
682
 
647
683
  var backdrop = '.dropdown-backdrop'
648
- var toggle = '[data-toggle=dropdown]'
684
+ var toggle = '[data-toggle="dropdown"]'
649
685
  var Dropdown = function (element) {
650
686
  $(element).on('click.bs.dropdown', this.toggle)
651
687
  }
652
688
 
689
+ Dropdown.VERSION = '3.2.0'
690
+
653
691
  Dropdown.prototype.toggle = function (e) {
654
692
  var $this = $(this)
655
693
 
@@ -671,11 +709,11 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
671
709
 
672
710
  if (e.isDefaultPrevented()) return
673
711
 
712
+ $this.trigger('focus')
713
+
674
714
  $parent
675
715
  .toggleClass('open')
676
716
  .trigger('shown.bs.dropdown', relatedTarget)
677
-
678
- $this.focus()
679
717
  }
680
718
 
681
719
  return false
@@ -695,12 +733,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
695
733
  var isActive = $parent.hasClass('open')
696
734
 
697
735
  if (!isActive || (isActive && e.keyCode == 27)) {
698
- if (e.which == 27) $parent.find(toggle).focus()
699
- return $this.click()
736
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
737
+ return $this.trigger('click')
700
738
  }
701
739
 
702
740
  var desc = ' li:not(.divider):visible a'
703
- var $items = $parent.find('[role=menu]' + desc + ', [role=listbox]' + desc)
741
+ var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
704
742
 
705
743
  if (!$items.length) return
706
744
 
@@ -710,10 +748,11 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
710
748
  if (e.keyCode == 40 && index < $items.length - 1) index++ // down
711
749
  if (!~index) index = 0
712
750
 
713
- $items.eq(index).focus()
751
+ $items.eq(index).trigger('focus')
714
752
  }
715
753
 
716
754
  function clearMenus(e) {
755
+ if (e && e.which === 3) return
717
756
  $(backdrop).remove()
718
757
  $(toggle).each(function () {
719
758
  var $parent = getParent($(this))
@@ -730,7 +769,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
730
769
 
731
770
  if (!selector) {
732
771
  selector = $this.attr('href')
733
- selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
772
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
734
773
  }
735
774
 
736
775
  var $parent = selector && $(selector)
@@ -742,9 +781,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
742
781
  // DROPDOWN PLUGIN DEFINITION
743
782
  // ==========================
744
783
 
745
- var old = $.fn.dropdown
746
-
747
- $.fn.dropdown = function (option) {
784
+ function Plugin(option) {
748
785
  return this.each(function () {
749
786
  var $this = $(this)
750
787
  var data = $this.data('bs.dropdown')
@@ -754,6 +791,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
754
791
  })
755
792
  }
756
793
 
794
+ var old = $.fn.dropdown
795
+
796
+ $.fn.dropdown = Plugin
757
797
  $.fn.dropdown.Constructor = Dropdown
758
798
 
759
799
 
@@ -773,12 +813,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
773
813
  .on('click.bs.dropdown.data-api', clearMenus)
774
814
  .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
775
815
  .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
776
- .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu], [role=listbox]', Dropdown.prototype.keydown)
816
+ .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
777
817
 
778
818
  }(jQuery);
779
819
 
780
820
  /* ========================================================================
781
- * Bootstrap: modal.js v3.1.1
821
+ * Bootstrap: modal.js v3.2.0
782
822
  * http://getbootstrap.com/javascript/#modals
783
823
  * ========================================================================
784
824
  * Copyright 2011-2014 Twitter, Inc.
@@ -793,10 +833,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
793
833
  // ======================
794
834
 
795
835
  var Modal = function (element, options) {
796
- this.options = options
797
- this.$element = $(element)
798
- this.$backdrop =
799
- this.isShown = null
836
+ this.options = options
837
+ this.$body = $(document.body)
838
+ this.$element = $(element)
839
+ this.$backdrop =
840
+ this.isShown = null
841
+ this.scrollbarWidth = 0
800
842
 
801
843
  if (this.options.remote) {
802
844
  this.$element
@@ -807,6 +849,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
807
849
  }
808
850
  }
809
851
 
852
+ Modal.VERSION = '3.2.0'
853
+
810
854
  Modal.DEFAULTS = {
811
855
  backdrop: true,
812
856
  keyboard: true,
@@ -814,7 +858,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
814
858
  }
815
859
 
816
860
  Modal.prototype.toggle = function (_relatedTarget) {
817
- return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
861
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
818
862
  }
819
863
 
820
864
  Modal.prototype.show = function (_relatedTarget) {
@@ -827,6 +871,10 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
827
871
 
828
872
  this.isShown = true
829
873
 
874
+ this.checkScrollbar()
875
+ this.$body.addClass('modal-open')
876
+
877
+ this.setScrollbar()
830
878
  this.escape()
831
879
 
832
880
  this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
@@ -835,7 +883,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
835
883
  var transition = $.support.transition && that.$element.hasClass('fade')
836
884
 
837
885
  if (!that.$element.parent().length) {
838
- that.$element.appendTo(document.body) // don't move modals dom position
886
+ that.$element.appendTo(that.$body) // don't move modals dom position
839
887
  }
840
888
 
841
889
  that.$element
@@ -856,11 +904,11 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
856
904
 
857
905
  transition ?
858
906
  that.$element.find('.modal-dialog') // wait for modal to slide in
859
- .one($.support.transition.end, function () {
860
- that.$element.focus().trigger(e)
907
+ .one('bsTransitionEnd', function () {
908
+ that.$element.trigger('focus').trigger(e)
861
909
  })
862
910
  .emulateTransitionEnd(300) :
863
- that.$element.focus().trigger(e)
911
+ that.$element.trigger('focus').trigger(e)
864
912
  })
865
913
  }
866
914
 
@@ -875,6 +923,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
875
923
 
876
924
  this.isShown = false
877
925
 
926
+ this.$body.removeClass('modal-open')
927
+
928
+ this.resetScrollbar()
878
929
  this.escape()
879
930
 
880
931
  $(document).off('focusin.bs.modal')
@@ -886,7 +937,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
886
937
 
887
938
  $.support.transition && this.$element.hasClass('fade') ?
888
939
  this.$element
889
- .one($.support.transition.end, $.proxy(this.hideModal, this))
940
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
890
941
  .emulateTransitionEnd(300) :
891
942
  this.hideModal()
892
943
  }
@@ -896,7 +947,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
896
947
  .off('focusin.bs.modal') // guard against infinite focus loop
897
948
  .on('focusin.bs.modal', $.proxy(function (e) {
898
949
  if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
899
- this.$element.focus()
950
+ this.$element.trigger('focus')
900
951
  }
901
952
  }, this))
902
953
  }
@@ -915,7 +966,6 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
915
966
  var that = this
916
967
  this.$element.hide()
917
968
  this.backdrop(function () {
918
- that.removeBackdrop()
919
969
  that.$element.trigger('hidden.bs.modal')
920
970
  })
921
971
  }
@@ -926,13 +976,14 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
926
976
  }
927
977
 
928
978
  Modal.prototype.backdrop = function (callback) {
979
+ var that = this
929
980
  var animate = this.$element.hasClass('fade') ? 'fade' : ''
930
981
 
931
982
  if (this.isShown && this.options.backdrop) {
932
983
  var doAnimate = $.support.transition && animate
933
984
 
934
985
  this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
935
- .appendTo(document.body)
986
+ .appendTo(this.$body)
936
987
 
937
988
  this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
938
989
  if (e.target !== e.currentTarget) return
@@ -949,31 +1000,56 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
949
1000
 
950
1001
  doAnimate ?
951
1002
  this.$backdrop
952
- .one($.support.transition.end, callback)
1003
+ .one('bsTransitionEnd', callback)
953
1004
  .emulateTransitionEnd(150) :
954
1005
  callback()
955
1006
 
956
1007
  } else if (!this.isShown && this.$backdrop) {
957
1008
  this.$backdrop.removeClass('in')
958
1009
 
1010
+ var callbackRemove = function () {
1011
+ that.removeBackdrop()
1012
+ callback && callback()
1013
+ }
959
1014
  $.support.transition && this.$element.hasClass('fade') ?
960
1015
  this.$backdrop
961
- .one($.support.transition.end, callback)
1016
+ .one('bsTransitionEnd', callbackRemove)
962
1017
  .emulateTransitionEnd(150) :
963
- callback()
1018
+ callbackRemove()
964
1019
 
965
1020
  } else if (callback) {
966
1021
  callback()
967
1022
  }
968
1023
  }
969
1024
 
1025
+ Modal.prototype.checkScrollbar = function () {
1026
+ if (document.body.clientWidth >= window.innerWidth) return
1027
+ this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
1028
+ }
1029
+
1030
+ Modal.prototype.setScrollbar = function () {
1031
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
1032
+ if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
1033
+ }
1034
+
1035
+ Modal.prototype.resetScrollbar = function () {
1036
+ this.$body.css('padding-right', '')
1037
+ }
1038
+
1039
+ Modal.prototype.measureScrollbar = function () { // thx walsh
1040
+ var scrollDiv = document.createElement('div')
1041
+ scrollDiv.className = 'modal-scrollbar-measure'
1042
+ this.$body.append(scrollDiv)
1043
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
1044
+ this.$body[0].removeChild(scrollDiv)
1045
+ return scrollbarWidth
1046
+ }
1047
+
970
1048
 
971
1049
  // MODAL PLUGIN DEFINITION
972
1050
  // =======================
973
1051
 
974
- var old = $.fn.modal
975
-
976
- $.fn.modal = function (option, _relatedTarget) {
1052
+ function Plugin(option, _relatedTarget) {
977
1053
  return this.each(function () {
978
1054
  var $this = $(this)
979
1055
  var data = $this.data('bs.modal')
@@ -985,6 +1061,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
985
1061
  })
986
1062
  }
987
1063
 
1064
+ var old = $.fn.modal
1065
+
1066
+ $.fn.modal = Plugin
988
1067
  $.fn.modal.Constructor = Modal
989
1068
 
990
1069
 
@@ -1003,26 +1082,24 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1003
1082
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
1004
1083
  var $this = $(this)
1005
1084
  var href = $this.attr('href')
1006
- var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
1085
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
1007
1086
  var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1008
1087
 
1009
1088
  if ($this.is('a')) e.preventDefault()
1010
1089
 
1011
- $target
1012
- .modal(option, this)
1013
- .one('hide', function () {
1014
- $this.is(':visible') && $this.focus()
1090
+ $target.one('show.bs.modal', function (showEvent) {
1091
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
1092
+ $target.one('hidden.bs.modal', function () {
1093
+ $this.is(':visible') && $this.trigger('focus')
1015
1094
  })
1095
+ })
1096
+ Plugin.call($target, option, this)
1016
1097
  })
1017
1098
 
1018
- $(document)
1019
- .on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
1020
- .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })
1021
-
1022
1099
  }(jQuery);
1023
1100
 
1024
1101
  /* ========================================================================
1025
- * Bootstrap: tooltip.js v3.1.1
1102
+ * Bootstrap: tooltip.js v3.2.0
1026
1103
  * http://getbootstrap.com/javascript/#tooltip
1027
1104
  * Inspired by the original jQuery.tipsy by Jason Frame
1028
1105
  * ========================================================================
@@ -1048,23 +1125,30 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1048
1125
  this.init('tooltip', element, options)
1049
1126
  }
1050
1127
 
1128
+ Tooltip.VERSION = '3.2.0'
1129
+
1051
1130
  Tooltip.DEFAULTS = {
1052
1131
  animation: true,
1053
1132
  placement: 'top',
1054
1133
  selector: false,
1055
- template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1134
+ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1056
1135
  trigger: 'hover focus',
1057
1136
  title: '',
1058
1137
  delay: 0,
1059
1138
  html: false,
1060
- container: false
1139
+ container: false,
1140
+ viewport: {
1141
+ selector: 'body',
1142
+ padding: 0
1143
+ }
1061
1144
  }
1062
1145
 
1063
1146
  Tooltip.prototype.init = function (type, element, options) {
1064
- this.enabled = true
1065
- this.type = type
1066
- this.$element = $(element)
1067
- this.options = this.getOptions(options)
1147
+ this.enabled = true
1148
+ this.type = type
1149
+ this.$element = $(element)
1150
+ this.options = this.getOptions(options)
1151
+ this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
1068
1152
 
1069
1153
  var triggers = this.options.trigger.split(' ')
1070
1154
 
@@ -1117,7 +1201,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1117
1201
 
1118
1202
  Tooltip.prototype.enter = function (obj) {
1119
1203
  var self = obj instanceof this.constructor ?
1120
- obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
1204
+ obj : $(obj.currentTarget).data('bs.' + this.type)
1205
+
1206
+ if (!self) {
1207
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1208
+ $(obj.currentTarget).data('bs.' + this.type, self)
1209
+ }
1121
1210
 
1122
1211
  clearTimeout(self.timeout)
1123
1212
 
@@ -1132,7 +1221,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1132
1221
 
1133
1222
  Tooltip.prototype.leave = function (obj) {
1134
1223
  var self = obj instanceof this.constructor ?
1135
- obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
1224
+ obj : $(obj.currentTarget).data('bs.' + this.type)
1225
+
1226
+ if (!self) {
1227
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1228
+ $(obj.currentTarget).data('bs.' + this.type, self)
1229
+ }
1136
1230
 
1137
1231
  clearTimeout(self.timeout)
1138
1232
 
@@ -1151,12 +1245,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1151
1245
  if (this.hasContent() && this.enabled) {
1152
1246
  this.$element.trigger(e)
1153
1247
 
1154
- if (e.isDefaultPrevented()) return
1155
- var that = this;
1248
+ var inDom = $.contains(document.documentElement, this.$element[0])
1249
+ if (e.isDefaultPrevented() || !inDom) return
1250
+ var that = this
1156
1251
 
1157
1252
  var $tip = this.tip()
1158
1253
 
1254
+ var tipId = this.getUID(this.type)
1255
+
1159
1256
  this.setContent()
1257
+ $tip.attr('id', tipId)
1258
+ this.$element.attr('aria-describedby', tipId)
1160
1259
 
1161
1260
  if (this.options.animation) $tip.addClass('fade')
1162
1261
 
@@ -1172,6 +1271,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1172
1271
  .detach()
1173
1272
  .css({ top: 0, left: 0, display: 'block' })
1174
1273
  .addClass(placement)
1274
+ .data('bs.' + this.type, this)
1175
1275
 
1176
1276
  this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1177
1277
 
@@ -1180,18 +1280,14 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1180
1280
  var actualHeight = $tip[0].offsetHeight
1181
1281
 
1182
1282
  if (autoPlace) {
1183
- var $parent = this.$element.parent()
1184
-
1185
1283
  var orgPlacement = placement
1186
- var docScroll = document.documentElement.scrollTop || document.body.scrollTop
1187
- var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
1188
- var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
1189
- var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left
1190
-
1191
- placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
1192
- placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
1193
- placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
1194
- placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
1284
+ var $parent = this.$element.parent()
1285
+ var parentDim = this.getPosition($parent)
1286
+
1287
+ placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
1288
+ placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
1289
+ placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
1290
+ placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
1195
1291
  placement
1196
1292
 
1197
1293
  $tip
@@ -1202,22 +1298,21 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1202
1298
  var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1203
1299
 
1204
1300
  this.applyPlacement(calculatedOffset, placement)
1205
- this.hoverState = null
1206
1301
 
1207
- var complete = function() {
1302
+ var complete = function () {
1208
1303
  that.$element.trigger('shown.bs.' + that.type)
1304
+ that.hoverState = null
1209
1305
  }
1210
1306
 
1211
1307
  $.support.transition && this.$tip.hasClass('fade') ?
1212
1308
  $tip
1213
- .one($.support.transition.end, complete)
1309
+ .one('bsTransitionEnd', complete)
1214
1310
  .emulateTransitionEnd(150) :
1215
1311
  complete()
1216
1312
  }
1217
1313
  }
1218
1314
 
1219
1315
  Tooltip.prototype.applyPlacement = function (offset, placement) {
1220
- var replace
1221
1316
  var $tip = this.tip()
1222
1317
  var width = $tip[0].offsetWidth
1223
1318
  var height = $tip[0].offsetHeight
@@ -1251,29 +1346,20 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1251
1346
  var actualHeight = $tip[0].offsetHeight
1252
1347
 
1253
1348
  if (placement == 'top' && actualHeight != height) {
1254
- replace = true
1255
1349
  offset.top = offset.top + height - actualHeight
1256
1350
  }
1257
1351
 
1258
- if (/bottom|top/.test(placement)) {
1259
- var delta = 0
1352
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
1260
1353
 
1261
- if (offset.left < 0) {
1262
- delta = offset.left * -2
1263
- offset.left = 0
1354
+ if (delta.left) offset.left += delta.left
1355
+ else offset.top += delta.top
1264
1356
 
1265
- $tip.offset(offset)
1266
-
1267
- actualWidth = $tip[0].offsetWidth
1268
- actualHeight = $tip[0].offsetHeight
1269
- }
1357
+ var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
1358
+ var arrowPosition = delta.left ? 'left' : 'top'
1359
+ var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
1270
1360
 
1271
- this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
1272
- } else {
1273
- this.replaceArrow(actualHeight - height, actualHeight, 'top')
1274
- }
1275
-
1276
- if (replace) $tip.offset(offset)
1361
+ $tip.offset(offset)
1362
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
1277
1363
  }
1278
1364
 
1279
1365
  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
@@ -1293,6 +1379,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1293
1379
  var $tip = this.tip()
1294
1380
  var e = $.Event('hide.bs.' + this.type)
1295
1381
 
1382
+ this.$element.removeAttr('aria-describedby')
1383
+
1296
1384
  function complete() {
1297
1385
  if (that.hoverState != 'in') $tip.detach()
1298
1386
  that.$element.trigger('hidden.bs.' + that.type)
@@ -1306,7 +1394,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1306
1394
 
1307
1395
  $.support.transition && this.$tip.hasClass('fade') ?
1308
1396
  $tip
1309
- .one($.support.transition.end, complete)
1397
+ .one('bsTransitionEnd', complete)
1310
1398
  .emulateTransitionEnd(150) :
1311
1399
  complete()
1312
1400
 
@@ -1317,7 +1405,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1317
1405
 
1318
1406
  Tooltip.prototype.fixTitle = function () {
1319
1407
  var $e = this.$element
1320
- if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
1408
+ if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
1321
1409
  $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1322
1410
  }
1323
1411
  }
@@ -1326,12 +1414,15 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1326
1414
  return this.getTitle()
1327
1415
  }
1328
1416
 
1329
- Tooltip.prototype.getPosition = function () {
1330
- var el = this.$element[0]
1331
- return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
1332
- width: el.offsetWidth,
1333
- height: el.offsetHeight
1334
- }, this.$element.offset())
1417
+ Tooltip.prototype.getPosition = function ($element) {
1418
+ $element = $element || this.$element
1419
+ var el = $element[0]
1420
+ var isBody = el.tagName == 'BODY'
1421
+ return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
1422
+ scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
1423
+ width: isBody ? $(window).width() : $element.outerWidth(),
1424
+ height: isBody ? $(window).height() : $element.outerHeight()
1425
+ }, isBody ? { top: 0, left: 0 } : $element.offset())
1335
1426
  }
1336
1427
 
1337
1428
  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
@@ -1339,6 +1430,35 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1339
1430
  placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1340
1431
  placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
1341
1432
  /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
1433
+
1434
+ }
1435
+
1436
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
1437
+ var delta = { top: 0, left: 0 }
1438
+ if (!this.$viewport) return delta
1439
+
1440
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
1441
+ var viewportDimensions = this.getPosition(this.$viewport)
1442
+
1443
+ if (/right|left/.test(placement)) {
1444
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
1445
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
1446
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
1447
+ delta.top = viewportDimensions.top - topEdgeOffset
1448
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
1449
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
1450
+ }
1451
+ } else {
1452
+ var leftEdgeOffset = pos.left - viewportPadding
1453
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
1454
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
1455
+ delta.left = viewportDimensions.left - leftEdgeOffset
1456
+ } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
1457
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
1458
+ }
1459
+ }
1460
+
1461
+ return delta
1342
1462
  }
1343
1463
 
1344
1464
  Tooltip.prototype.getTitle = function () {
@@ -1352,12 +1472,18 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1352
1472
  return title
1353
1473
  }
1354
1474
 
1475
+ Tooltip.prototype.getUID = function (prefix) {
1476
+ do prefix += ~~(Math.random() * 1000000)
1477
+ while (document.getElementById(prefix))
1478
+ return prefix
1479
+ }
1480
+
1355
1481
  Tooltip.prototype.tip = function () {
1356
- return this.$tip = this.$tip || $(this.options.template)
1482
+ return (this.$tip = this.$tip || $(this.options.template))
1357
1483
  }
1358
1484
 
1359
1485
  Tooltip.prototype.arrow = function () {
1360
- return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
1486
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
1361
1487
  }
1362
1488
 
1363
1489
  Tooltip.prototype.validate = function () {
@@ -1381,7 +1507,15 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1381
1507
  }
1382
1508
 
1383
1509
  Tooltip.prototype.toggle = function (e) {
1384
- var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
1510
+ var self = this
1511
+ if (e) {
1512
+ self = $(e.currentTarget).data('bs.' + this.type)
1513
+ if (!self) {
1514
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
1515
+ $(e.currentTarget).data('bs.' + this.type, self)
1516
+ }
1517
+ }
1518
+
1385
1519
  self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1386
1520
  }
1387
1521
 
@@ -1394,9 +1528,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1394
1528
  // TOOLTIP PLUGIN DEFINITION
1395
1529
  // =========================
1396
1530
 
1397
- var old = $.fn.tooltip
1398
-
1399
- $.fn.tooltip = function (option) {
1531
+ function Plugin(option) {
1400
1532
  return this.each(function () {
1401
1533
  var $this = $(this)
1402
1534
  var data = $this.data('bs.tooltip')
@@ -1408,6 +1540,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1408
1540
  })
1409
1541
  }
1410
1542
 
1543
+ var old = $.fn.tooltip
1544
+
1545
+ $.fn.tooltip = Plugin
1411
1546
  $.fn.tooltip.Constructor = Tooltip
1412
1547
 
1413
1548
 
@@ -1422,7 +1557,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1422
1557
  }(jQuery);
1423
1558
 
1424
1559
  /* ========================================================================
1425
- * Bootstrap: popover.js v3.1.1
1560
+ * Bootstrap: popover.js v3.2.0
1426
1561
  * http://getbootstrap.com/javascript/#popovers
1427
1562
  * ========================================================================
1428
1563
  * Copyright 2011-2014 Twitter, Inc.
@@ -1442,11 +1577,13 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1442
1577
 
1443
1578
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1444
1579
 
1580
+ Popover.VERSION = '3.2.0'
1581
+
1445
1582
  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
1446
1583
  placement: 'right',
1447
1584
  trigger: 'click',
1448
1585
  content: '',
1449
- template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1586
+ template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1450
1587
  })
1451
1588
 
1452
1589
 
@@ -1467,7 +1604,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1467
1604
  var content = this.getContent()
1468
1605
 
1469
1606
  $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1470
- $tip.find('.popover-content')[ // we use append for html objects to maintain js events
1607
+ $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
1471
1608
  this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
1472
1609
  ](content)
1473
1610
 
@@ -1493,7 +1630,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1493
1630
  }
1494
1631
 
1495
1632
  Popover.prototype.arrow = function () {
1496
- return this.$arrow = this.$arrow || this.tip().find('.arrow')
1633
+ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
1497
1634
  }
1498
1635
 
1499
1636
  Popover.prototype.tip = function () {
@@ -1505,9 +1642,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1505
1642
  // POPOVER PLUGIN DEFINITION
1506
1643
  // =========================
1507
1644
 
1508
- var old = $.fn.popover
1509
-
1510
- $.fn.popover = function (option) {
1645
+ function Plugin(option) {
1511
1646
  return this.each(function () {
1512
1647
  var $this = $(this)
1513
1648
  var data = $this.data('bs.popover')
@@ -1519,6 +1654,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1519
1654
  })
1520
1655
  }
1521
1656
 
1657
+ var old = $.fn.popover
1658
+
1659
+ $.fn.popover = Plugin
1522
1660
  $.fn.popover.Constructor = Popover
1523
1661
 
1524
1662
 
@@ -1533,7 +1671,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1533
1671
  }(jQuery);
1534
1672
 
1535
1673
  /* ========================================================================
1536
- * Bootstrap: scrollspy.js v3.1.1
1674
+ * Bootstrap: scrollspy.js v3.2.0
1537
1675
  * http://getbootstrap.com/javascript/#scrollspy
1538
1676
  * ========================================================================
1539
1677
  * Copyright 2011-2014 Twitter, Inc.
@@ -1548,36 +1686,48 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1548
1686
  // ==========================
1549
1687
 
1550
1688
  function ScrollSpy(element, options) {
1551
- var href
1552
1689
  var process = $.proxy(this.process, this)
1553
1690
 
1554
- this.$element = $(element).is('body') ? $(window) : $(element)
1555
1691
  this.$body = $('body')
1556
- this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
1692
+ this.$scrollElement = $(element).is('body') ? $(window) : $(element)
1557
1693
  this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
1558
- this.selector = (this.options.target
1559
- || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1560
- || '') + ' .nav li > a'
1561
- this.offsets = $([])
1562
- this.targets = $([])
1694
+ this.selector = (this.options.target || '') + ' .nav li > a'
1695
+ this.offsets = []
1696
+ this.targets = []
1563
1697
  this.activeTarget = null
1698
+ this.scrollHeight = 0
1564
1699
 
1700
+ this.$scrollElement.on('scroll.bs.scrollspy', process)
1565
1701
  this.refresh()
1566
1702
  this.process()
1567
1703
  }
1568
1704
 
1705
+ ScrollSpy.VERSION = '3.2.0'
1706
+
1569
1707
  ScrollSpy.DEFAULTS = {
1570
1708
  offset: 10
1571
1709
  }
1572
1710
 
1711
+ ScrollSpy.prototype.getScrollHeight = function () {
1712
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
1713
+ }
1714
+
1573
1715
  ScrollSpy.prototype.refresh = function () {
1574
- var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
1716
+ var offsetMethod = 'offset'
1717
+ var offsetBase = 0
1575
1718
 
1576
- this.offsets = $([])
1577
- this.targets = $([])
1719
+ if (!$.isWindow(this.$scrollElement[0])) {
1720
+ offsetMethod = 'position'
1721
+ offsetBase = this.$scrollElement.scrollTop()
1722
+ }
1723
+
1724
+ this.offsets = []
1725
+ this.targets = []
1726
+ this.scrollHeight = this.getScrollHeight()
1578
1727
 
1579
1728
  var self = this
1580
- var $targets = this.$body
1729
+
1730
+ this.$body
1581
1731
  .find(this.selector)
1582
1732
  .map(function () {
1583
1733
  var $el = $(this)
@@ -1587,7 +1737,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1587
1737
  return ($href
1588
1738
  && $href.length
1589
1739
  && $href.is(':visible')
1590
- && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
1740
+ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
1591
1741
  })
1592
1742
  .sort(function (a, b) { return a[0] - b[0] })
1593
1743
  .each(function () {
@@ -1598,15 +1748,19 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1598
1748
 
1599
1749
  ScrollSpy.prototype.process = function () {
1600
1750
  var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1601
- var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
1602
- var maxScroll = scrollHeight - this.$scrollElement.height()
1751
+ var scrollHeight = this.getScrollHeight()
1752
+ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
1603
1753
  var offsets = this.offsets
1604
1754
  var targets = this.targets
1605
1755
  var activeTarget = this.activeTarget
1606
1756
  var i
1607
1757
 
1758
+ if (this.scrollHeight != scrollHeight) {
1759
+ this.refresh()
1760
+ }
1761
+
1608
1762
  if (scrollTop >= maxScroll) {
1609
- return activeTarget != (i = targets.last()[0]) && this.activate(i)
1763
+ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
1610
1764
  }
1611
1765
 
1612
1766
  if (activeTarget && scrollTop <= offsets[0]) {
@@ -1617,7 +1771,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1617
1771
  activeTarget != targets[i]
1618
1772
  && scrollTop >= offsets[i]
1619
1773
  && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1620
- && this.activate( targets[i] )
1774
+ && this.activate(targets[i])
1621
1775
  }
1622
1776
  }
1623
1777
 
@@ -1649,9 +1803,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1649
1803
  // SCROLLSPY PLUGIN DEFINITION
1650
1804
  // ===========================
1651
1805
 
1652
- var old = $.fn.scrollspy
1653
-
1654
- $.fn.scrollspy = function (option) {
1806
+ function Plugin(option) {
1655
1807
  return this.each(function () {
1656
1808
  var $this = $(this)
1657
1809
  var data = $this.data('bs.scrollspy')
@@ -1662,6 +1814,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1662
1814
  })
1663
1815
  }
1664
1816
 
1817
+ var old = $.fn.scrollspy
1818
+
1819
+ $.fn.scrollspy = Plugin
1665
1820
  $.fn.scrollspy.Constructor = ScrollSpy
1666
1821
 
1667
1822
 
@@ -1677,17 +1832,17 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1677
1832
  // SCROLLSPY DATA-API
1678
1833
  // ==================
1679
1834
 
1680
- $(window).on('load', function () {
1835
+ $(window).on('load.bs.scrollspy.data-api', function () {
1681
1836
  $('[data-spy="scroll"]').each(function () {
1682
1837
  var $spy = $(this)
1683
- $spy.scrollspy($spy.data())
1838
+ Plugin.call($spy, $spy.data())
1684
1839
  })
1685
1840
  })
1686
1841
 
1687
1842
  }(jQuery);
1688
1843
 
1689
1844
  /* ========================================================================
1690
- * Bootstrap: tab.js v3.1.1
1845
+ * Bootstrap: tab.js v3.2.0
1691
1846
  * http://getbootstrap.com/javascript/#tabs
1692
1847
  * ========================================================================
1693
1848
  * Copyright 2011-2014 Twitter, Inc.
@@ -1705,6 +1860,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1705
1860
  this.element = $(element)
1706
1861
  }
1707
1862
 
1863
+ Tab.VERSION = '3.2.0'
1864
+
1708
1865
  Tab.prototype.show = function () {
1709
1866
  var $this = this.element
1710
1867
  var $ul = $this.closest('ul:not(.dropdown-menu)')
@@ -1712,7 +1869,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1712
1869
 
1713
1870
  if (!selector) {
1714
1871
  selector = $this.attr('href')
1715
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1872
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
1716
1873
  }
1717
1874
 
1718
1875
  if ($this.parent('li').hasClass('active')) return
@@ -1728,7 +1885,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1728
1885
 
1729
1886
  var $target = $(selector)
1730
1887
 
1731
- this.activate($this.parent('li'), $ul)
1888
+ this.activate($this.closest('li'), $ul)
1732
1889
  this.activate($target, $target.parent(), function () {
1733
1890
  $this.trigger({
1734
1891
  type: 'shown.bs.tab',
@@ -1767,7 +1924,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1767
1924
 
1768
1925
  transition ?
1769
1926
  $active
1770
- .one($.support.transition.end, next)
1927
+ .one('bsTransitionEnd', next)
1771
1928
  .emulateTransitionEnd(150) :
1772
1929
  next()
1773
1930
 
@@ -1778,9 +1935,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1778
1935
  // TAB PLUGIN DEFINITION
1779
1936
  // =====================
1780
1937
 
1781
- var old = $.fn.tab
1782
-
1783
- $.fn.tab = function ( option ) {
1938
+ function Plugin(option) {
1784
1939
  return this.each(function () {
1785
1940
  var $this = $(this)
1786
1941
  var data = $this.data('bs.tab')
@@ -1790,6 +1945,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1790
1945
  })
1791
1946
  }
1792
1947
 
1948
+ var old = $.fn.tab
1949
+
1950
+ $.fn.tab = Plugin
1793
1951
  $.fn.tab.Constructor = Tab
1794
1952
 
1795
1953
 
@@ -1807,13 +1965,13 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1807
1965
 
1808
1966
  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1809
1967
  e.preventDefault()
1810
- $(this).tab('show')
1968
+ Plugin.call($(this), 'show')
1811
1969
  })
1812
1970
 
1813
1971
  }(jQuery);
1814
1972
 
1815
1973
  /* ========================================================================
1816
- * Bootstrap: affix.js v3.1.1
1974
+ * Bootstrap: affix.js v3.2.0
1817
1975
  * http://getbootstrap.com/javascript/#affix
1818
1976
  * ========================================================================
1819
1977
  * Copyright 2011-2014 Twitter, Inc.
@@ -1829,7 +1987,8 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1829
1987
 
1830
1988
  var Affix = function (element, options) {
1831
1989
  this.options = $.extend({}, Affix.DEFAULTS, options)
1832
- this.$window = $(window)
1990
+
1991
+ this.$target = $(this.options.target)
1833
1992
  .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
1834
1993
  .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
1835
1994
 
@@ -1841,16 +2000,19 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1841
2000
  this.checkPosition()
1842
2001
  }
1843
2002
 
1844
- Affix.RESET = 'affix affix-top affix-bottom'
2003
+ Affix.VERSION = '3.2.0'
2004
+
2005
+ Affix.RESET = 'affix affix-top affix-bottom'
1845
2006
 
1846
2007
  Affix.DEFAULTS = {
1847
- offset: 0
2008
+ offset: 0,
2009
+ target: window
1848
2010
  }
1849
2011
 
1850
2012
  Affix.prototype.getPinnedOffset = function () {
1851
2013
  if (this.pinnedOffset) return this.pinnedOffset
1852
2014
  this.$element.removeClass(Affix.RESET).addClass('affix')
1853
- var scrollTop = this.$window.scrollTop()
2015
+ var scrollTop = this.$target.scrollTop()
1854
2016
  var position = this.$element.offset()
1855
2017
  return (this.pinnedOffset = position.top - scrollTop)
1856
2018
  }
@@ -1863,14 +2025,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1863
2025
  if (!this.$element.is(':visible')) return
1864
2026
 
1865
2027
  var scrollHeight = $(document).height()
1866
- var scrollTop = this.$window.scrollTop()
2028
+ var scrollTop = this.$target.scrollTop()
1867
2029
  var position = this.$element.offset()
1868
2030
  var offset = this.options.offset
1869
2031
  var offsetTop = offset.top
1870
2032
  var offsetBottom = offset.bottom
1871
2033
 
1872
- if (this.affixed == 'top') position.top += scrollTop
1873
-
1874
2034
  if (typeof offset != 'object') offsetBottom = offsetTop = offset
1875
2035
  if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
1876
2036
  if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
@@ -1880,7 +2040,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1880
2040
  offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
1881
2041
 
1882
2042
  if (this.affixed === affix) return
1883
- if (this.unpin) this.$element.css('top', '')
2043
+ if (this.unpin != null) this.$element.css('top', '')
1884
2044
 
1885
2045
  var affixType = 'affix' + (affix ? '-' + affix : '')
1886
2046
  var e = $.Event(affixType + '.bs.affix')
@@ -1898,7 +2058,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1898
2058
  .trigger($.Event(affixType.replace('affix', 'affixed')))
1899
2059
 
1900
2060
  if (affix == 'bottom') {
1901
- this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() })
2061
+ this.$element.offset({
2062
+ top: scrollHeight - this.$element.height() - offsetBottom
2063
+ })
1902
2064
  }
1903
2065
  }
1904
2066
 
@@ -1906,9 +2068,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1906
2068
  // AFFIX PLUGIN DEFINITION
1907
2069
  // =======================
1908
2070
 
1909
- var old = $.fn.affix
1910
-
1911
- $.fn.affix = function (option) {
2071
+ function Plugin(option) {
1912
2072
  return this.each(function () {
1913
2073
  var $this = $(this)
1914
2074
  var data = $this.data('bs.affix')
@@ -1919,6 +2079,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1919
2079
  })
1920
2080
  }
1921
2081
 
2082
+ var old = $.fn.affix
2083
+
2084
+ $.fn.affix = Plugin
1922
2085
  $.fn.affix.Constructor = Affix
1923
2086
 
1924
2087
 
@@ -1944,7 +2107,7 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1944
2107
  if (data.offsetBottom) data.offset.bottom = data.offsetBottom
1945
2108
  if (data.offsetTop) data.offset.top = data.offsetTop
1946
2109
 
1947
- $spy.affix(data)
2110
+ Plugin.call($spy, data)
1948
2111
  })
1949
2112
  })
1950
2113