bootstrap.js 62 KB
Newer Older
XhmikosR's avatar
XhmikosR committed
1001
1002
1003
1004
  Modal.prototype.hideModal = function () {
    var that = this
    this.$element.hide()
    this.backdrop(function () {
Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1005
1006
      that.$body.removeClass('modal-open')
      that.resetScrollbar()
XhmikosR's avatar
XhmikosR committed
1007
1008
1009
      that.$element.trigger('hidden.bs.modal')
    })
  }
1010

XhmikosR's avatar
XhmikosR committed
1011
1012
1013
1014
  Modal.prototype.removeBackdrop = function () {
    this.$backdrop && this.$backdrop.remove()
    this.$backdrop = null
  }
1015

XhmikosR's avatar
XhmikosR committed
1016
1017
1018
  Modal.prototype.backdrop = function (callback) {
    var that = this
    var animate = this.$element.hasClass('fade') ? 'fade' : ''
1019

XhmikosR's avatar
XhmikosR committed
1020
1021
    if (this.isShown && this.options.backdrop) {
      var doAnimate = $.support.transition && animate
1022

XhmikosR's avatar
XhmikosR committed
1023
      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
1024
1025
1026
1027
1028
1029
1030
        .prependTo(this.$element)
        .on('click.dismiss.bs.modal', $.proxy(function (e) {
          if (e.target !== e.currentTarget) return
          this.options.backdrop == 'static'
            ? this.$element[0].focus.call(this.$element[0])
            : this.hide.call(this)
        }, this))
1031

XhmikosR's avatar
XhmikosR committed
1032
      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
1033

XhmikosR's avatar
XhmikosR committed
1034
      this.$backdrop.addClass('in')
1035

XhmikosR's avatar
XhmikosR committed
1036
      if (!callback) return
1037

XhmikosR's avatar
XhmikosR committed
1038
1039
1040
      doAnimate ?
        this.$backdrop
          .one('bsTransitionEnd', callback)
1041
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1042
        callback()
1043

XhmikosR's avatar
XhmikosR committed
1044
1045
    } else if (!this.isShown && this.$backdrop) {
      this.$backdrop.removeClass('in')
Chris Rebert's avatar
Chris Rebert committed
1046

XhmikosR's avatar
XhmikosR committed
1047
1048
1049
      var callbackRemove = function () {
        that.removeBackdrop()
        callback && callback()
Chris Rebert's avatar
Chris Rebert committed
1050
      }
XhmikosR's avatar
XhmikosR committed
1051
1052
1053
      $.support.transition && this.$element.hasClass('fade') ?
        this.$backdrop
          .one('bsTransitionEnd', callbackRemove)
1054
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1055
        callbackRemove()
1056

XhmikosR's avatar
XhmikosR committed
1057
1058
    } else if (callback) {
      callback()
Chris Rebert's avatar
Chris Rebert committed
1059
    }
XhmikosR's avatar
XhmikosR committed
1060
  }
1061

XhmikosR's avatar
XhmikosR committed
1062
  Modal.prototype.checkScrollbar = function () {
Mark Otto's avatar
grunt    
Mark Otto committed
1063
    this.scrollbarWidth = this.measureScrollbar()
XhmikosR's avatar
XhmikosR committed
1064
  }
fat's avatar
build    
fat committed
1065

XhmikosR's avatar
XhmikosR committed
1066
1067
1068
1069
  Modal.prototype.setScrollbar = function () {
    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
    if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
  }
fat's avatar
build    
fat committed
1070

XhmikosR's avatar
XhmikosR committed
1071
1072
1073
  Modal.prototype.resetScrollbar = function () {
    this.$body.css('padding-right', '')
  }
fat's avatar
build    
fat committed
1074

XhmikosR's avatar
XhmikosR committed
1075
  Modal.prototype.measureScrollbar = function () { // thx walsh
Mark Otto's avatar
grunt    
Mark Otto committed
1076
    if (document.body.clientWidth >= window.innerWidth) return 0
XhmikosR's avatar
XhmikosR committed
1077
1078
1079
1080
1081
1082
1083
    var scrollDiv = document.createElement('div')
    scrollDiv.className = 'modal-scrollbar-measure'
    this.$body.append(scrollDiv)
    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
    this.$body[0].removeChild(scrollDiv)
    return scrollbarWidth
  }
1084
1085


XhmikosR's avatar
XhmikosR committed
1086
1087
  // MODAL PLUGIN DEFINITION
  // =======================
fat's avatar
fat committed
1088

XhmikosR's avatar
XhmikosR committed
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
  function Plugin(option, _relatedTarget) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.modal')
      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
      if (typeof option == 'string') data[option](_relatedTarget)
      else if (options.show) data.show(_relatedTarget)
    })
  }
1100

XhmikosR's avatar
XhmikosR committed
1101
  var old = $.fn.modal
Mark Otto's avatar
Mark Otto committed
1102

XhmikosR's avatar
XhmikosR committed
1103
1104
  $.fn.modal             = Plugin
  $.fn.modal.Constructor = Modal
1105
1106


XhmikosR's avatar
XhmikosR committed
1107
1108
  // MODAL NO CONFLICT
  // =================
1109

XhmikosR's avatar
XhmikosR committed
1110
1111
1112
1113
  $.fn.modal.noConflict = function () {
    $.fn.modal = old
    return this
  }
1114
1115


XhmikosR's avatar
XhmikosR committed
1116
1117
  // MODAL DATA-API
  // ==============
1118

XhmikosR's avatar
XhmikosR committed
1119
1120
1121
1122
1123
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
    var $this   = $(this)
    var href    = $this.attr('href')
    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1124

XhmikosR's avatar
XhmikosR committed
1125
    if ($this.is('a')) e.preventDefault()
1126

XhmikosR's avatar
XhmikosR committed
1127
1128
1129
1130
    $target.one('show.bs.modal', function (showEvent) {
      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
      $target.one('hidden.bs.modal', function () {
        $this.is(':visible') && $this.trigger('focus')
Mark Otto's avatar
grunt    
Mark Otto committed
1131
      })
Mark Otto's avatar
Mark Otto committed
1132
    })
XhmikosR's avatar
XhmikosR committed
1133
    Plugin.call($target, option, this)
Jacob Thornton's avatar
Jacob Thornton committed
1134
  })
1135

XhmikosR's avatar
XhmikosR committed
1136
}(jQuery);
1137

1138
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1139
 * Bootstrap: tooltip.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1140
 * http://getbootstrap.com/javascript/#tooltip
1141
 * Inspired by the original jQuery.tipsy by Jason Frame
1142
 * ========================================================================
1143
 * Copyright 2011-2014 Twitter, Inc.
1144
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1145
 * ======================================================================== */
1146
1147


XhmikosR's avatar
XhmikosR committed
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
+function ($) {
  'use strict';

  // TOOLTIP PUBLIC CLASS DEFINITION
  // ===============================

  var Tooltip = function (element, options) {
    this.type       =
    this.options    =
    this.enabled    =
    this.timeout    =
    this.hoverState =
    this.$element   = null

    this.init('tooltip', element, options)
  }

Mark Otto's avatar
Mark Otto committed
1165
  Tooltip.VERSION  = '3.2.0'
XhmikosR's avatar
XhmikosR committed
1166

1167
1168
  Tooltip.TRANSITION_DURATION = 150

XhmikosR's avatar
XhmikosR committed
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
  Tooltip.DEFAULTS = {
    animation: true,
    placement: 'top',
    selector: false,
    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
    trigger: 'hover focus',
    title: '',
    delay: 0,
    html: false,
    container: false,
    viewport: {
      selector: 'body',
      padding: 0
    }
  }

  Tooltip.prototype.init = function (type, element, options) {
    this.enabled   = true
    this.type      = type
    this.$element  = $(element)
    this.options   = this.getOptions(options)
    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)

    var triggers = this.options.trigger.split(' ')

    for (var i = triggers.length; i--;) {
      var trigger = triggers[i]

      if (trigger == 'click') {
        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
      } else if (trigger != 'manual') {
        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'

        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
      }
    }
1207

XhmikosR's avatar
XhmikosR committed
1208
1209
1210
1211
    this.options.selector ?
      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
      this.fixTitle()
  }
1212

XhmikosR's avatar
XhmikosR committed
1213
1214
1215
  Tooltip.prototype.getDefaults = function () {
    return Tooltip.DEFAULTS
  }
1216

XhmikosR's avatar
XhmikosR committed
1217
1218
  Tooltip.prototype.getOptions = function (options) {
    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1219

XhmikosR's avatar
XhmikosR committed
1220
1221
1222
1223
    if (options.delay && typeof options.delay == 'number') {
      options.delay = {
        show: options.delay,
        hide: options.delay
1224
1225
      }
    }
1226

XhmikosR's avatar
XhmikosR committed
1227
1228
    return options
  }
Jacob Thornton's avatar
Jacob Thornton committed
1229

XhmikosR's avatar
XhmikosR committed
1230
1231
1232
  Tooltip.prototype.getDelegateOptions = function () {
    var options  = {}
    var defaults = this.getDefaults()
1233

XhmikosR's avatar
XhmikosR committed
1234
1235
1236
    this._options && $.each(this._options, function (key, value) {
      if (defaults[key] != value) options[key] = value
    })
fat's avatar
rebuild    
fat committed
1237

XhmikosR's avatar
XhmikosR committed
1238
1239
    return options
  }
Jacob Thornton's avatar
Jacob Thornton committed
1240

XhmikosR's avatar
XhmikosR committed
1241
1242
1243
  Tooltip.prototype.enter = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget).data('bs.' + this.type)
Mark Otto's avatar
Mark Otto committed
1244

XhmikosR's avatar
XhmikosR committed
1245
1246
1247
1248
1249
    if (self && self.$tip && self.$tip.is(':visible')) {
      self.hoverState = 'in'
      return
    }

XhmikosR's avatar
XhmikosR committed
1250
1251
1252
    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
Mark Otto's avatar
Mark Otto committed
1253
    }
1254

XhmikosR's avatar
XhmikosR committed
1255
    clearTimeout(self.timeout)
1256

XhmikosR's avatar
XhmikosR committed
1257
    self.hoverState = 'in'
1258

XhmikosR's avatar
XhmikosR committed
1259
    if (!self.options.delay || !self.options.delay.show) return self.show()
1260

XhmikosR's avatar
XhmikosR committed
1261
1262
1263
1264
    self.timeout = setTimeout(function () {
      if (self.hoverState == 'in') self.show()
    }, self.options.delay.show)
  }
1265

XhmikosR's avatar
XhmikosR committed
1266
1267
1268
  Tooltip.prototype.leave = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget).data('bs.' + this.type)
Mark Otto's avatar
Mark Otto committed
1269

XhmikosR's avatar
XhmikosR committed
1270
1271
1272
    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
Mark Otto's avatar
Mark Otto committed
1273
    }
1274

XhmikosR's avatar
XhmikosR committed
1275
    clearTimeout(self.timeout)
fat's avatar
fat committed
1276

XhmikosR's avatar
XhmikosR committed
1277
    self.hoverState = 'out'
1278

XhmikosR's avatar
XhmikosR committed
1279
    if (!self.options.delay || !self.options.delay.hide) return self.hide()
1280

XhmikosR's avatar
XhmikosR committed
1281
1282
1283
1284
    self.timeout = setTimeout(function () {
      if (self.hoverState == 'out') self.hide()
    }, self.options.delay.hide)
  }
1285

XhmikosR's avatar
XhmikosR committed
1286
1287
  Tooltip.prototype.show = function () {
    var e = $.Event('show.bs.' + this.type)
Chris Rebert's avatar
Chris Rebert committed
1288

XhmikosR's avatar
XhmikosR committed
1289
1290
    if (this.hasContent() && this.enabled) {
      this.$element.trigger(e)
fat's avatar
fat committed
1291

Heinrich Fenkart's avatar
Heinrich Fenkart committed
1292
      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
XhmikosR's avatar
XhmikosR committed
1293
1294
      if (e.isDefaultPrevented() || !inDom) return
      var that = this
1295

XhmikosR's avatar
XhmikosR committed
1296
      var $tip = this.tip()
fat's avatar
fat committed
1297

XhmikosR's avatar
XhmikosR committed
1298
      var tipId = this.getUID(this.type)
fat's avatar
fat committed
1299

XhmikosR's avatar
XhmikosR committed
1300
1301
1302
      this.setContent()
      $tip.attr('id', tipId)
      this.$element.attr('aria-describedby', tipId)
1303

XhmikosR's avatar
XhmikosR committed
1304
      if (this.options.animation) $tip.addClass('fade')
1305

XhmikosR's avatar
XhmikosR committed
1306
1307
1308
      var placement = typeof this.options.placement == 'function' ?
        this.options.placement.call(this, $tip[0], this.$element[0]) :
        this.options.placement
1309

XhmikosR's avatar
XhmikosR committed
1310
1311
1312
      var autoToken = /\s?auto?\s?/i
      var autoPlace = autoToken.test(placement)
      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1313

XhmikosR's avatar
XhmikosR committed
1314
1315
1316
1317
1318
      $tip
        .detach()
        .css({ top: 0, left: 0, display: 'block' })
        .addClass(placement)
        .data('bs.' + this.type, this)
fat's avatar
fat committed
1319

XhmikosR's avatar
XhmikosR committed
1320
      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1321

XhmikosR's avatar
XhmikosR committed
1322
1323
1324
      var pos          = this.getPosition()
      var actualWidth  = $tip[0].offsetWidth
      var actualHeight = $tip[0].offsetHeight
Chris Rebert's avatar
Chris Rebert committed
1325

XhmikosR's avatar
XhmikosR committed
1326
1327
      if (autoPlace) {
        var orgPlacement = placement
Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1328
1329
        var $container   = this.options.container ? $(this.options.container) : this.$element.parent()
        var containerDim = this.getPosition($container)
Chris Rebert's avatar
Chris Rebert committed
1330

Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1331
1332
1333
1334
        placement = placement == 'bottom' && pos.top   + pos.height          + actualHeight - containerDim.scroll > containerDim.height ? 'top'    :
                    placement == 'top'    && pos.top   - containerDim.scroll - actualHeight < containerDim.top                          ? 'bottom' :
                    placement == 'right'  && pos.right + actualWidth         > containerDim.width                                       ? 'left'   :
                    placement == 'left'   && pos.left  - actualWidth         < containerDim.left                                        ? 'right'  :
XhmikosR's avatar
XhmikosR committed
1335
                    placement
fat's avatar
fat committed
1336

1337
        $tip
XhmikosR's avatar
XhmikosR committed
1338
          .removeClass(orgPlacement)
1339
          .addClass(placement)
XhmikosR's avatar
XhmikosR committed
1340
      }
1341

XhmikosR's avatar
XhmikosR committed
1342
      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1343

XhmikosR's avatar
XhmikosR committed
1344
      this.applyPlacement(calculatedOffset, placement)
fat's avatar
fat committed
1345

XhmikosR's avatar
XhmikosR committed
1346
1347
1348
1349
      var complete = function () {
        that.$element.trigger('shown.bs.' + that.type)
        that.hoverState = null
      }
fat's avatar
fat committed
1350

XhmikosR's avatar
XhmikosR committed
1351
1352
1353
      $.support.transition && this.$tip.hasClass('fade') ?
        $tip
          .one('bsTransitionEnd', complete)
1354
          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1355
1356
1357
        complete()
    }
  }
fat's avatar
fat committed
1358

XhmikosR's avatar
XhmikosR committed
1359
1360
1361
1362
  Tooltip.prototype.applyPlacement = function (offset, placement) {
    var $tip   = this.tip()
    var width  = $tip[0].offsetWidth
    var height = $tip[0].offsetHeight
fat's avatar
fat committed
1363

XhmikosR's avatar
XhmikosR committed
1364
1365
1366
    // manually read margins because getBoundingClientRect includes difference
    var marginTop = parseInt($tip.css('margin-top'), 10)
    var marginLeft = parseInt($tip.css('margin-left'), 10)
fat's avatar
fat committed
1367

XhmikosR's avatar
XhmikosR committed
1368
1369
1370
    // we must check for NaN for ie 8/9
    if (isNaN(marginTop))  marginTop  = 0
    if (isNaN(marginLeft)) marginLeft = 0
fat's avatar
fat committed
1371

XhmikosR's avatar
XhmikosR committed
1372
1373
    offset.top  = offset.top  + marginTop
    offset.left = offset.left + marginLeft
fat's avatar
fat committed
1374

XhmikosR's avatar
XhmikosR committed
1375
1376
1377
1378
1379
1380
1381
1382
    // $.fn.offset doesn't round pixel values
    // so we use setOffset directly with our own function B-0
    $.offset.setOffset($tip[0], $.extend({
      using: function (props) {
        $tip.css({
          top: Math.round(props.top),
          left: Math.round(props.left)
        })
1383
      }
XhmikosR's avatar
XhmikosR committed
1384
    }, offset), 0)
1385

XhmikosR's avatar
XhmikosR committed
1386
    $tip.addClass('in')
fat's avatar
fat committed
1387

XhmikosR's avatar
XhmikosR committed
1388
1389
1390
    // check to see if placing tip in new offset caused the tip to resize itself
    var actualWidth  = $tip[0].offsetWidth
    var actualHeight = $tip[0].offsetHeight
fat's avatar
fat committed
1391

XhmikosR's avatar
XhmikosR committed
1392
1393
1394
    if (placement == 'top' && actualHeight != height) {
      offset.top = offset.top + height - actualHeight
    }
fat's avatar
fat committed
1395

XhmikosR's avatar
XhmikosR committed
1396
    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
fat's avatar
fat committed
1397

XhmikosR's avatar
XhmikosR committed
1398
1399
    if (delta.left) offset.left += delta.left
    else offset.top += delta.top
1400

Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1401
1402
1403
    var isVertical          = /top|bottom/.test(placement)
    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
1404

XhmikosR's avatar
XhmikosR committed
1405
    $tip.offset(offset)
Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1406
    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
XhmikosR's avatar
XhmikosR committed
1407
  }
1408

Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1409
1410
1411
1412
  Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
    this.arrow()
      .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
      .css(isHorizontal ? 'top' : 'left', '')
XhmikosR's avatar
XhmikosR committed
1413
  }
1414

XhmikosR's avatar
XhmikosR committed
1415
1416
1417
  Tooltip.prototype.setContent = function () {
    var $tip  = this.tip()
    var title = this.getTitle()
1418

XhmikosR's avatar
XhmikosR committed
1419
1420
1421
    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
    $tip.removeClass('fade in top bottom left right')
  }
1422

Heinrich Fenkart's avatar
Heinrich Fenkart committed
1423
  Tooltip.prototype.hide = function (callback) {
XhmikosR's avatar
XhmikosR committed
1424
1425
1426
    var that = this
    var $tip = this.tip()
    var e    = $.Event('hide.bs.' + this.type)
1427

XhmikosR's avatar
XhmikosR committed
1428
1429
    function complete() {
      if (that.hoverState != 'in') $tip.detach()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1430
1431
1432
      that.$element
        .removeAttr('aria-describedby')
        .trigger('hidden.bs.' + that.type)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1433
      callback && callback()
XhmikosR's avatar
XhmikosR committed
1434
    }
Jacob Thornton's avatar
Jacob Thornton committed
1435

XhmikosR's avatar
XhmikosR committed
1436
    this.$element.trigger(e)
1437

XhmikosR's avatar
XhmikosR committed
1438
    if (e.isDefaultPrevented()) return
1439

XhmikosR's avatar
XhmikosR committed
1440
    $tip.removeClass('in')
1441

XhmikosR's avatar
XhmikosR committed
1442
1443
1444
    $.support.transition && this.$tip.hasClass('fade') ?
      $tip
        .one('bsTransitionEnd', complete)
1445
        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1446
      complete()
1447

XhmikosR's avatar
XhmikosR committed
1448
    this.hoverState = null
1449

XhmikosR's avatar
XhmikosR committed
1450
1451
    return this
  }
1452

XhmikosR's avatar
XhmikosR committed
1453
1454
1455
1456
  Tooltip.prototype.fixTitle = function () {
    var $e = this.$element
    if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1457
    }
XhmikosR's avatar
XhmikosR committed
1458
  }
1459

XhmikosR's avatar
XhmikosR committed
1460
1461
1462
  Tooltip.prototype.hasContent = function () {
    return this.getTitle()
  }
1463

XhmikosR's avatar
XhmikosR committed
1464
1465
  Tooltip.prototype.getPosition = function ($element) {
    $element   = $element || this.$element
Mark Otto's avatar
grunt    
Mark Otto committed
1466

XhmikosR's avatar
XhmikosR committed
1467
1468
    var el     = $element[0]
    var isBody = el.tagName == 'BODY'
Mark Otto's avatar
grunt    
Mark Otto committed
1469

Mark Otto's avatar
grunt    
Mark Otto committed
1470
    var elRect    = el.getBoundingClientRect()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1471
1472
1473
1474
    if (elRect.width == null) {
      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
    }
Mark Otto's avatar
grunt    
Mark Otto committed
1475
1476
    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1477
    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
Mark Otto's avatar
grunt    
Mark Otto committed
1478
1479

    return $.extend({}, elRect, scroll, outerDims, elOffset)
XhmikosR's avatar
XhmikosR committed
1480
  }
1481

XhmikosR's avatar
XhmikosR committed
1482
1483
1484
1485
1486
  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
1487

XhmikosR's avatar
XhmikosR committed
1488
  }
1489

XhmikosR's avatar
XhmikosR committed
1490
1491
1492
  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
    var delta = { top: 0, left: 0 }
    if (!this.$viewport) return delta
1493

XhmikosR's avatar
XhmikosR committed
1494
1495
    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
    var viewportDimensions = this.getPosition(this.$viewport)
1496

XhmikosR's avatar
XhmikosR committed
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
    if (/right|left/.test(placement)) {
      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
      if (topEdgeOffset < viewportDimensions.top) { // top overflow
        delta.top = viewportDimensions.top - topEdgeOffset
      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
      }
    } else {
      var leftEdgeOffset  = pos.left - viewportPadding
      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
        delta.left = viewportDimensions.left - leftEdgeOffset
      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
1512
      }
Chris Rebert's avatar
Chris Rebert committed
1513
    }
fat's avatar
fat committed
1514

XhmikosR's avatar
XhmikosR committed
1515
1516
    return delta
  }
1517

XhmikosR's avatar
XhmikosR committed
1518
1519
1520
1521
  Tooltip.prototype.getTitle = function () {
    var title
    var $e = this.$element
    var o  = this.options
1522

XhmikosR's avatar
XhmikosR committed
1523
1524
    title = $e.attr('data-original-title')
      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
1525

XhmikosR's avatar
XhmikosR committed
1526
1527
    return title
  }
1528

XhmikosR's avatar
XhmikosR committed
1529
1530
1531
1532
1533
  Tooltip.prototype.getUID = function (prefix) {
    do prefix += ~~(Math.random() * 1000000)
    while (document.getElementById(prefix))
    return prefix
  }
1534

XhmikosR's avatar
XhmikosR committed
1535
1536
1537
  Tooltip.prototype.tip = function () {
    return (this.$tip = this.$tip || $(this.options.template))
  }
1538

XhmikosR's avatar
XhmikosR committed
1539
1540
1541
  Tooltip.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
  }
1542

XhmikosR's avatar
XhmikosR committed
1543
1544
1545
  Tooltip.prototype.enable = function () {
    this.enabled = true
  }
1546

XhmikosR's avatar
XhmikosR committed
1547
1548
1549
  Tooltip.prototype.disable = function () {
    this.enabled = false
  }
Mark Otto's avatar
Mark Otto committed
1550

XhmikosR's avatar
XhmikosR committed
1551
1552
1553
  Tooltip.prototype.toggleEnabled = function () {
    this.enabled = !this.enabled
  }
Chris Rebert's avatar
Chris Rebert committed
1554

XhmikosR's avatar
XhmikosR committed
1555
1556
1557
1558
1559
1560
1561
1562
  Tooltip.prototype.toggle = function (e) {
    var self = this
    if (e) {
      self = $(e.currentTarget).data('bs.' + this.type)
      if (!self) {
        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
        $(e.currentTarget).data('bs.' + this.type, self)
      }
Mark Otto's avatar
Mark Otto committed
1563
1564
    }

XhmikosR's avatar
XhmikosR committed
1565
1566
    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  }
1567

XhmikosR's avatar
XhmikosR committed
1568
  Tooltip.prototype.destroy = function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1569
    var that = this
XhmikosR's avatar
XhmikosR committed
1570
    clearTimeout(this.timeout)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1571
1572
1573
    this.hide(function () {
      that.$element.off('.' + that.type).removeData('bs.' + that.type)
    })
XhmikosR's avatar
XhmikosR committed
1574
  }
1575
1576


XhmikosR's avatar
XhmikosR committed
1577
1578
  // TOOLTIP PLUGIN DEFINITION
  // =========================
1579

XhmikosR's avatar
XhmikosR committed
1580
1581
1582
1583
1584
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.tooltip')
      var options = typeof option == 'object' && option
fat's avatar
fat committed
1585

XhmikosR's avatar
XhmikosR committed
1586
1587
1588
1589
1590
      if (!data && option == 'destroy') return
      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1591

XhmikosR's avatar
XhmikosR committed
1592
  var old = $.fn.tooltip
Mark Otto's avatar
Mark Otto committed
1593

XhmikosR's avatar
XhmikosR committed
1594
1595
  $.fn.tooltip             = Plugin
  $.fn.tooltip.Constructor = Tooltip
1596

1597

XhmikosR's avatar
XhmikosR committed
1598
1599
  // TOOLTIP NO CONFLICT
  // ===================
1600

XhmikosR's avatar
XhmikosR committed
1601
1602
1603
1604
  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }
1605

XhmikosR's avatar
XhmikosR committed
1606
}(jQuery);
1607

1608
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1609
 * Bootstrap: popover.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1610
 * http://getbootstrap.com/javascript/#popovers
1611
 * ========================================================================
1612
 * Copyright 2011-2014 Twitter, Inc.
1613
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1614
 * ======================================================================== */
1615
1616


XhmikosR's avatar
XhmikosR committed
1617
1618
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
1619

XhmikosR's avatar
XhmikosR committed
1620
1621
  // POPOVER PUBLIC CLASS DEFINITION
  // ===============================
1622

XhmikosR's avatar
XhmikosR committed
1623
1624
1625
  var Popover = function (element, options) {
    this.init('popover', element, options)
  }
fat's avatar
fat committed
1626

XhmikosR's avatar
XhmikosR committed
1627
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1628

Mark Otto's avatar
Mark Otto committed
1629
  Popover.VERSION  = '3.2.0'
1630

XhmikosR's avatar
XhmikosR committed
1631
1632
1633
1634
1635
1636
  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
    placement: 'right',
    trigger: 'click',
    content: '',
    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  })
fat's avatar
fat committed
1637
1638


XhmikosR's avatar
XhmikosR committed
1639
1640
  // NOTE: POPOVER EXTENDS tooltip.js
  // ================================
1641

XhmikosR's avatar
XhmikosR committed
1642
  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
fat's avatar
fat committed
1643

XhmikosR's avatar
XhmikosR committed
1644
  Popover.prototype.constructor = Popover
1645

XhmikosR's avatar
XhmikosR committed
1646
1647
1648
  Popover.prototype.getDefaults = function () {
    return Popover.DEFAULTS
  }
1649

XhmikosR's avatar
XhmikosR committed
1650
1651
1652
1653
  Popover.prototype.setContent = function () {
    var $tip    = this.tip()
    var title   = this.getTitle()
    var content = this.getContent()
1654

XhmikosR's avatar
XhmikosR committed
1655
    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
Mark Otto's avatar
grunt    
Mark Otto committed
1656
    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
XhmikosR's avatar
XhmikosR committed
1657
1658
      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
    ](content)
1659

XhmikosR's avatar
XhmikosR committed
1660
    $tip.removeClass('fade top bottom left right in')
1661

XhmikosR's avatar
XhmikosR committed
1662
1663
1664
1665
    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
    // this manually by checking the contents.
    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
  }
1666

XhmikosR's avatar
XhmikosR committed
1667
1668
1669
  Popover.prototype.hasContent = function () {
    return this.getTitle() || this.getContent()
  }
1670

XhmikosR's avatar
XhmikosR committed
1671
1672
1673
  Popover.prototype.getContent = function () {
    var $e = this.$element
    var o  = this.options
1674

XhmikosR's avatar
XhmikosR committed
1675
1676
1677
1678
1679
    return $e.attr('data-content')
      || (typeof o.content == 'function' ?
            o.content.call($e[0]) :
            o.content)
  }
fat's avatar
fat committed
1680

XhmikosR's avatar
XhmikosR committed
1681
1682
1683
  Popover.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
  }
1684

XhmikosR's avatar
XhmikosR committed
1685
1686
1687
1688
  Popover.prototype.tip = function () {
    if (!this.$tip) this.$tip = $(this.options.template)
    return this.$tip
  }
1689

1690

XhmikosR's avatar
XhmikosR committed
1691
1692
  // POPOVER PLUGIN DEFINITION
  // =========================
1693

XhmikosR's avatar
XhmikosR committed
1694
1695
1696
1697
1698
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.popover')
      var options = typeof option == 'object' && option
Chris Rebert's avatar
Chris Rebert committed
1699

XhmikosR's avatar
XhmikosR committed
1700
1701
1702
1703
1704
      if (!data && option == 'destroy') return
      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1705

XhmikosR's avatar
XhmikosR committed
1706
  var old = $.fn.popover
Mark Otto's avatar
Mark Otto committed
1707

XhmikosR's avatar
XhmikosR committed
1708
1709
  $.fn.popover             = Plugin
  $.fn.popover.Constructor = Popover
fat's avatar
fat committed
1710

1711

XhmikosR's avatar
XhmikosR committed
1712
1713
  // POPOVER NO CONFLICT
  // ===================
1714

XhmikosR's avatar
XhmikosR committed
1715
1716
1717
1718
  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }
1719

XhmikosR's avatar
XhmikosR committed
1720
}(jQuery);
1721

1722
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1723
 * Bootstrap: scrollspy.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1724
 * http://getbootstrap.com/javascript/#scrollspy
1725
 * ========================================================================
1726
 * Copyright 2011-2014 Twitter, Inc.
1727
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1728
 * ======================================================================== */
1729
1730


XhmikosR's avatar
XhmikosR committed
1731
1732
+function ($) {
  'use strict';
1733

XhmikosR's avatar
XhmikosR committed
1734
1735
  // SCROLLSPY CLASS DEFINITION
  // ==========================
1736

XhmikosR's avatar
XhmikosR committed
1737
1738
  function ScrollSpy(element, options) {
    var process  = $.proxy(this.process, this)
1739

XhmikosR's avatar
XhmikosR committed
1740
1741
1742
1743
1744
1745
1746
1747
    this.$body          = $('body')
    this.$scrollElement = $(element).is('body') ? $(window) : $(element)
    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
    this.selector       = (this.options.target || '') + ' .nav li > a'
    this.offsets        = []
    this.targets        = []
    this.activeTarget   = null
    this.scrollHeight   = 0
1748

XhmikosR's avatar
XhmikosR committed
1749
1750
1751
1752
    this.$scrollElement.on('scroll.bs.scrollspy', process)
    this.refresh()
    this.process()
  }
1753

Mark Otto's avatar
Mark Otto committed
1754
  ScrollSpy.VERSION  = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
1755

XhmikosR's avatar
XhmikosR committed
1756
1757
1758
  ScrollSpy.DEFAULTS = {
    offset: 10
  }
1759

XhmikosR's avatar
XhmikosR committed
1760
1761
1762
  ScrollSpy.prototype.getScrollHeight = function () {
    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
  }
Mark Otto's avatar
grunt    
Mark Otto committed
1763

XhmikosR's avatar
XhmikosR committed
1764
1765
1766
  ScrollSpy.prototype.refresh = function () {
    var offsetMethod = 'offset'
    var offsetBase   = 0
Mark Otto's avatar
grunt    
Mark Otto committed
1767

XhmikosR's avatar
XhmikosR committed
1768
1769
1770
1771
    if (!$.isWindow(this.$scrollElement[0])) {
      offsetMethod = 'position'
      offsetBase   = this.$scrollElement.scrollTop()
    }
Mark Otto's avatar
grunt    
Mark Otto committed
1772

XhmikosR's avatar
XhmikosR committed
1773
1774
1775
    this.offsets = []
    this.targets = []
    this.scrollHeight = this.getScrollHeight()
fat's avatar
fat committed
1776

XhmikosR's avatar
XhmikosR committed
1777
    var self     = this
XhmikosR's avatar
XhmikosR committed
1778

XhmikosR's avatar
XhmikosR committed
1779
1780
1781
1782
1783
1784
    this.$body
      .find(this.selector)
      .map(function () {
        var $el   = $(this)
        var href  = $el.data('target') || $el.attr('href')
        var $href = /^#./.test(href) && $(href)
1785

XhmikosR's avatar
XhmikosR committed
1786
1787
1788
        return ($href
          && $href.length
          && $href.is(':visible')
Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1789
          && $el.is(':visible')
XhmikosR's avatar
XhmikosR committed
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
      })
      .sort(function (a, b) { return a[0] - b[0] })
      .each(function () {
        self.offsets.push(this[0])
        self.targets.push(this[1])
      })
  }

  ScrollSpy.prototype.process = function () {
    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
    var scrollHeight = this.getScrollHeight()
    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
    var offsets      = this.offsets
    var targets      = this.targets
    var activeTarget = this.activeTarget
    var i

    if (this.scrollHeight != scrollHeight) {
      this.refresh()
Mark Otto's avatar
grunt    
Mark Otto committed
1810
1811
    }

XhmikosR's avatar
XhmikosR committed
1812
1813
1814
    if (scrollTop >= maxScroll) {
      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
    }
1815

XhmikosR's avatar
XhmikosR committed
1816
1817
    if (activeTarget && scrollTop <= offsets[0]) {
      return activeTarget != (i = targets[0]) && this.activate(i)
Chris Rebert's avatar
Chris Rebert committed
1818
    }
1819

XhmikosR's avatar
XhmikosR committed
1820
1821
1822
1823
1824
1825
1826
    for (i = offsets.length; i--;) {
      activeTarget != targets[i]
        && scrollTop >= offsets[i]
        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
        && this.activate(targets[i])
    }
  }
1827

XhmikosR's avatar
XhmikosR committed
1828
1829
  ScrollSpy.prototype.activate = function (target) {
    this.activeTarget = target
1830

XhmikosR's avatar
XhmikosR committed
1831
1832
1833
    $(this.selector)
      .parentsUntil(this.options.target, '.active')
      .removeClass('active')
1834

XhmikosR's avatar
XhmikosR committed
1835
1836
1837
    var selector = this.selector +
        '[data-target="' + target + '"],' +
        this.selector + '[href="' + target + '"]'
1838

XhmikosR's avatar
XhmikosR committed
1839
1840
1841
    var active = $(selector)
      .parents('li')
      .addClass('active')
1842

XhmikosR's avatar
XhmikosR committed
1843
1844
1845
1846
    if (active.parent('.dropdown-menu').length) {
      active = active
        .closest('li.dropdown')
        .addClass('active')
Chris Rebert's avatar
Chris Rebert committed
1847
    }
1848

XhmikosR's avatar
XhmikosR committed
1849
1850
    active.trigger('activate.bs.scrollspy')
  }
1851
1852


XhmikosR's avatar
XhmikosR committed
1853
1854
  // SCROLLSPY PLUGIN DEFINITION
  // ===========================
1855

XhmikosR's avatar
XhmikosR committed
1856
1857
1858
1859
1860
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.scrollspy')
      var options = typeof option == 'object' && option
Mark Otto's avatar
Mark Otto committed
1861

XhmikosR's avatar
XhmikosR committed
1862
1863
1864
1865
      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1866

XhmikosR's avatar
XhmikosR committed
1867
  var old = $.fn.scrollspy
1868

XhmikosR's avatar
XhmikosR committed
1869
1870
  $.fn.scrollspy             = Plugin
  $.fn.scrollspy.Constructor = ScrollSpy
1871

1872

XhmikosR's avatar
XhmikosR committed
1873
1874
  // SCROLLSPY NO CONFLICT
  // =====================
1875

XhmikosR's avatar
XhmikosR committed
1876
1877
1878
1879
  $.fn.scrollspy.noConflict = function () {
    $.fn.scrollspy = old
    return this
  }
1880

Chris Rebert's avatar
Chris Rebert committed
1881

XhmikosR's avatar
XhmikosR committed
1882
1883
  // SCROLLSPY DATA-API
  // ==================
Chris Rebert's avatar
Chris Rebert committed
1884

XhmikosR's avatar
XhmikosR committed
1885
1886
1887
1888
1889
  $(window).on('load.bs.scrollspy.data-api', function () {
    $('[data-spy="scroll"]').each(function () {
      var $spy = $(this)
      Plugin.call($spy, $spy.data())
    })
1890
  })
1891

XhmikosR's avatar
XhmikosR committed
1892
}(jQuery);
1893

1894
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1895
 * Bootstrap: tab.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1896
 * http://getbootstrap.com/javascript/#tabs
1897
 * ========================================================================
1898
 * Copyright 2011-2014 Twitter, Inc.
1899
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1900
 * ======================================================================== */
1901

1902

XhmikosR's avatar
XhmikosR committed
1903
1904
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
1905

XhmikosR's avatar
XhmikosR committed
1906
1907
  // TAB CLASS DEFINITION
  // ====================
1908

XhmikosR's avatar
XhmikosR committed
1909
1910
1911
  var Tab = function (element) {
    this.element = $(element)
  }
1912

Mark Otto's avatar
Mark Otto committed
1913
  Tab.VERSION = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
1914

1915
1916
  Tab.TRANSITION_DURATION = 150

XhmikosR's avatar
XhmikosR committed
1917
1918
1919
1920
  Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.data('target')
1921

XhmikosR's avatar
XhmikosR committed
1922
1923
1924
1925
    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }
1926

XhmikosR's avatar
XhmikosR committed
1927
    if ($this.parent('li').hasClass('active')) return
1928

XhmikosR's avatar
XhmikosR committed
1929
1930
1931
1932
    var previous = $ul.find('.active:last a')[0]
    var e        = $.Event('show.bs.tab', {
      relatedTarget: previous
    })
1933

XhmikosR's avatar
XhmikosR committed
1934
    $this.trigger(e)
1935

XhmikosR's avatar
XhmikosR committed
1936
    if (e.isDefaultPrevented()) return
1937

XhmikosR's avatar
XhmikosR committed
1938
    var $target = $(selector)
1939

XhmikosR's avatar
XhmikosR committed
1940
1941
1942
1943
1944
    this.activate($this.closest('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $this.trigger({
        type: 'shown.bs.tab',
        relatedTarget: previous
1945
      })
XhmikosR's avatar
XhmikosR committed
1946
1947
    })
  }
1948

XhmikosR's avatar
XhmikosR committed
1949
1950
1951
1952
  Tab.prototype.activate = function (element, container, callback) {
    var $active    = container.find('> .active')
    var transition = callback
      && $.support.transition
Mark Otto's avatar
grunt    
Mark Otto committed
1953
      && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
1954

XhmikosR's avatar
XhmikosR committed
1955
1956
1957
1958
1959
    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
        .removeClass('active')
1960

XhmikosR's avatar
XhmikosR committed
1961
1962
1963
1964
1965
1966
1967
      element.addClass('active')

      if (transition) {
        element[0].offsetWidth // reflow for transition
        element.addClass('in')
      } else {
        element.removeClass('fade')
1968
      }
1969

XhmikosR's avatar
XhmikosR committed
1970
1971
1972
      if (element.parent('.dropdown-menu')) {
        element.closest('li.dropdown').addClass('active')
      }
fat's avatar
fat committed
1973

XhmikosR's avatar
XhmikosR committed
1974
      callback && callback()
1975
    }
fat's avatar
fat committed
1976

Mark Otto's avatar
grunt    
Mark Otto committed
1977
    $active.length && transition ?
XhmikosR's avatar
XhmikosR committed
1978
1979
      $active
        .one('bsTransitionEnd', next)
1980
        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1981
      next()
1982

XhmikosR's avatar
XhmikosR committed
1983
1984
    $active.removeClass('in')
  }
1985
1986


XhmikosR's avatar
XhmikosR committed
1987
1988
  // TAB PLUGIN DEFINITION
  // =====================
fat's avatar
fat committed
1989

XhmikosR's avatar
XhmikosR committed
1990
1991
1992
1993
  function Plugin(option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.tab')
1994

XhmikosR's avatar
XhmikosR committed
1995
1996
1997
1998
      if (!data) $this.data('bs.tab', (data = new Tab(this)))
      if (typeof option == 'string') data[option]()
    })
  }
Mark Otto's avatar
Mark Otto committed
1999

XhmikosR's avatar
XhmikosR committed
2000
  var old = $.fn.tab
For faster browsing, not all history is shown. View entire blame