bootstrap.js 61.8 KB
Newer Older
1001

XhmikosR's avatar
XhmikosR committed
1002
1003
1004
1005
  Modal.prototype.removeBackdrop = function () {
    this.$backdrop && this.$backdrop.remove()
    this.$backdrop = null
  }
1006

XhmikosR's avatar
XhmikosR committed
1007
1008
1009
  Modal.prototype.backdrop = function (callback) {
    var that = this
    var animate = this.$element.hasClass('fade') ? 'fade' : ''
1010

XhmikosR's avatar
XhmikosR committed
1011
1012
    if (this.isShown && this.options.backdrop) {
      var doAnimate = $.support.transition && animate
1013

XhmikosR's avatar
XhmikosR committed
1014
1015
      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
        .appendTo(this.$body)
1016

Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1017
      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
XhmikosR's avatar
XhmikosR committed
1018
1019
1020
1021
1022
        if (e.target !== e.currentTarget) return
        this.options.backdrop == 'static'
          ? this.$element[0].focus.call(this.$element[0])
          : this.hide.call(this)
      }, this))
1023

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

XhmikosR's avatar
XhmikosR committed
1026
      this.$backdrop.addClass('in')
1027

XhmikosR's avatar
XhmikosR committed
1028
      if (!callback) return
1029

XhmikosR's avatar
XhmikosR committed
1030
1031
1032
      doAnimate ?
        this.$backdrop
          .one('bsTransitionEnd', callback)
1033
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1034
        callback()
1035

XhmikosR's avatar
XhmikosR committed
1036
1037
    } else if (!this.isShown && this.$backdrop) {
      this.$backdrop.removeClass('in')
Chris Rebert's avatar
Chris Rebert committed
1038

XhmikosR's avatar
XhmikosR committed
1039
1040
1041
      var callbackRemove = function () {
        that.removeBackdrop()
        callback && callback()
Chris Rebert's avatar
Chris Rebert committed
1042
      }
XhmikosR's avatar
XhmikosR committed
1043
1044
1045
      $.support.transition && this.$element.hasClass('fade') ?
        this.$backdrop
          .one('bsTransitionEnd', callbackRemove)
1046
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1047
        callbackRemove()
1048

XhmikosR's avatar
XhmikosR committed
1049
1050
    } else if (callback) {
      callback()
Chris Rebert's avatar
Chris Rebert committed
1051
    }
XhmikosR's avatar
XhmikosR committed
1052
  }
1053

XhmikosR's avatar
XhmikosR committed
1054
  Modal.prototype.checkScrollbar = function () {
Mark Otto's avatar
grunt    
Mark Otto committed
1055
    this.scrollbarWidth = this.measureScrollbar()
XhmikosR's avatar
XhmikosR committed
1056
  }
fat's avatar
build    
fat committed
1057

XhmikosR's avatar
XhmikosR committed
1058
1059
1060
1061
  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
1062

XhmikosR's avatar
XhmikosR committed
1063
1064
1065
  Modal.prototype.resetScrollbar = function () {
    this.$body.css('padding-right', '')
  }
fat's avatar
build    
fat committed
1066

XhmikosR's avatar
XhmikosR committed
1067
  Modal.prototype.measureScrollbar = function () { // thx walsh
Mark Otto's avatar
grunt    
Mark Otto committed
1068
    if (document.body.clientWidth >= window.innerWidth) return 0
XhmikosR's avatar
XhmikosR committed
1069
1070
1071
1072
1073
1074
1075
    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
  }
1076
1077


XhmikosR's avatar
XhmikosR committed
1078
1079
  // MODAL PLUGIN DEFINITION
  // =======================
fat's avatar
fat committed
1080

XhmikosR's avatar
XhmikosR committed
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
  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)
    })
  }
1092

XhmikosR's avatar
XhmikosR committed
1093
  var old = $.fn.modal
Mark Otto's avatar
Mark Otto committed
1094

XhmikosR's avatar
XhmikosR committed
1095
1096
  $.fn.modal             = Plugin
  $.fn.modal.Constructor = Modal
1097
1098


XhmikosR's avatar
XhmikosR committed
1099
1100
  // MODAL NO CONFLICT
  // =================
1101

XhmikosR's avatar
XhmikosR committed
1102
1103
1104
1105
  $.fn.modal.noConflict = function () {
    $.fn.modal = old
    return this
  }
1106
1107


XhmikosR's avatar
XhmikosR committed
1108
1109
  // MODAL DATA-API
  // ==============
1110

XhmikosR's avatar
XhmikosR committed
1111
1112
1113
1114
1115
  $(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())
1116

XhmikosR's avatar
XhmikosR committed
1117
    if ($this.is('a')) e.preventDefault()
1118

XhmikosR's avatar
XhmikosR committed
1119
1120
1121
1122
    $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
1123
      })
Mark Otto's avatar
Mark Otto committed
1124
    })
XhmikosR's avatar
XhmikosR committed
1125
    Plugin.call($target, option, this)
Jacob Thornton's avatar
Jacob Thornton committed
1126
  })
1127

XhmikosR's avatar
XhmikosR committed
1128
}(jQuery);
1129

1130
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1131
 * Bootstrap: tooltip.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1132
 * http://getbootstrap.com/javascript/#tooltip
1133
 * Inspired by the original jQuery.tipsy by Jason Frame
1134
 * ========================================================================
1135
 * Copyright 2011-2014 Twitter, Inc.
1136
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1137
 * ======================================================================== */
1138
1139


XhmikosR's avatar
XhmikosR committed
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
+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
1157
  Tooltip.VERSION  = '3.2.0'
XhmikosR's avatar
XhmikosR committed
1158

1159
1160
  Tooltip.TRANSITION_DURATION = 150

XhmikosR's avatar
XhmikosR committed
1161
1162
1163
1164
1165
1166
1167
1168
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
  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))
      }
    }
1199

XhmikosR's avatar
XhmikosR committed
1200
1201
1202
1203
    this.options.selector ?
      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
      this.fixTitle()
  }
1204

XhmikosR's avatar
XhmikosR committed
1205
1206
1207
  Tooltip.prototype.getDefaults = function () {
    return Tooltip.DEFAULTS
  }
1208

XhmikosR's avatar
XhmikosR committed
1209
1210
  Tooltip.prototype.getOptions = function (options) {
    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1211

XhmikosR's avatar
XhmikosR committed
1212
1213
1214
1215
    if (options.delay && typeof options.delay == 'number') {
      options.delay = {
        show: options.delay,
        hide: options.delay
1216
1217
      }
    }
1218

XhmikosR's avatar
XhmikosR committed
1219
1220
    return options
  }
Jacob Thornton's avatar
Jacob Thornton committed
1221

XhmikosR's avatar
XhmikosR committed
1222
1223
1224
  Tooltip.prototype.getDelegateOptions = function () {
    var options  = {}
    var defaults = this.getDefaults()
1225

XhmikosR's avatar
XhmikosR committed
1226
1227
1228
    this._options && $.each(this._options, function (key, value) {
      if (defaults[key] != value) options[key] = value
    })
fat's avatar
rebuild    
fat committed
1229

XhmikosR's avatar
XhmikosR committed
1230
1231
    return options
  }
Jacob Thornton's avatar
Jacob Thornton committed
1232

XhmikosR's avatar
XhmikosR committed
1233
1234
1235
  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
1236

XhmikosR's avatar
XhmikosR committed
1237
1238
1239
1240
1241
    if (self && self.$tip && self.$tip.is(':visible')) {
      self.hoverState = 'in'
      return
    }

XhmikosR's avatar
XhmikosR committed
1242
1243
1244
    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
Mark Otto's avatar
Mark Otto committed
1245
    }
1246

XhmikosR's avatar
XhmikosR committed
1247
    clearTimeout(self.timeout)
1248

XhmikosR's avatar
XhmikosR committed
1249
    self.hoverState = 'in'
1250

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

XhmikosR's avatar
XhmikosR committed
1253
1254
1255
1256
    self.timeout = setTimeout(function () {
      if (self.hoverState == 'in') self.show()
    }, self.options.delay.show)
  }
1257

XhmikosR's avatar
XhmikosR committed
1258
1259
1260
  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
1261

XhmikosR's avatar
XhmikosR committed
1262
1263
1264
    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
Mark Otto's avatar
Mark Otto committed
1265
    }
1266

XhmikosR's avatar
XhmikosR committed
1267
    clearTimeout(self.timeout)
fat's avatar
fat committed
1268

XhmikosR's avatar
XhmikosR committed
1269
    self.hoverState = 'out'
1270

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

XhmikosR's avatar
XhmikosR committed
1273
1274
1275
1276
    self.timeout = setTimeout(function () {
      if (self.hoverState == 'out') self.hide()
    }, self.options.delay.hide)
  }
1277

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

XhmikosR's avatar
XhmikosR committed
1281
1282
    if (this.hasContent() && this.enabled) {
      this.$element.trigger(e)
fat's avatar
fat committed
1283

Heinrich Fenkart's avatar
Heinrich Fenkart committed
1284
      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
XhmikosR's avatar
XhmikosR committed
1285
1286
      if (e.isDefaultPrevented() || !inDom) return
      var that = this
1287

XhmikosR's avatar
XhmikosR committed
1288
      var $tip = this.tip()
fat's avatar
fat committed
1289

XhmikosR's avatar
XhmikosR committed
1290
      var tipId = this.getUID(this.type)
fat's avatar
fat committed
1291

XhmikosR's avatar
XhmikosR committed
1292
1293
1294
      this.setContent()
      $tip.attr('id', tipId)
      this.$element.attr('aria-describedby', tipId)
1295

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

XhmikosR's avatar
XhmikosR committed
1298
1299
1300
      var placement = typeof this.options.placement == 'function' ?
        this.options.placement.call(this, $tip[0], this.$element[0]) :
        this.options.placement
1301

XhmikosR's avatar
XhmikosR committed
1302
1303
1304
      var autoToken = /\s?auto?\s?/i
      var autoPlace = autoToken.test(placement)
      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1305

XhmikosR's avatar
XhmikosR committed
1306
1307
1308
1309
1310
      $tip
        .detach()
        .css({ top: 0, left: 0, display: 'block' })
        .addClass(placement)
        .data('bs.' + this.type, this)
fat's avatar
fat committed
1311

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

XhmikosR's avatar
XhmikosR committed
1314
1315
1316
      var pos          = this.getPosition()
      var actualWidth  = $tip[0].offsetWidth
      var actualHeight = $tip[0].offsetHeight
Chris Rebert's avatar
Chris Rebert committed
1317

XhmikosR's avatar
XhmikosR committed
1318
1319
1320
1321
      if (autoPlace) {
        var orgPlacement = placement
        var $parent      = this.$element.parent()
        var parentDim    = this.getPosition($parent)
Chris Rebert's avatar
Chris Rebert committed
1322

XhmikosR's avatar
XhmikosR committed
1323
        placement = placement == 'bottom' && pos.top   + pos.height       + actualHeight - parentDim.scroll > parentDim.height ? 'top'    :
Mark Otto's avatar
grunt    
Mark Otto committed
1324
                    placement == 'top'    && pos.top   - parentDim.scroll - actualHeight < parentDim.top                       ? 'bottom' :
XhmikosR's avatar
XhmikosR committed
1325
1326
1327
                    placement == 'right'  && pos.right + actualWidth      > parentDim.width                                    ? 'left'   :
                    placement == 'left'   && pos.left  - actualWidth      < parentDim.left                                     ? 'right'  :
                    placement
fat's avatar
fat committed
1328

1329
        $tip
XhmikosR's avatar
XhmikosR committed
1330
          .removeClass(orgPlacement)
1331
          .addClass(placement)
XhmikosR's avatar
XhmikosR committed
1332
      }
1333

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

XhmikosR's avatar
XhmikosR committed
1336
      this.applyPlacement(calculatedOffset, placement)
fat's avatar
fat committed
1337

XhmikosR's avatar
XhmikosR committed
1338
1339
1340
1341
      var complete = function () {
        that.$element.trigger('shown.bs.' + that.type)
        that.hoverState = null
      }
fat's avatar
fat committed
1342

XhmikosR's avatar
XhmikosR committed
1343
1344
1345
      $.support.transition && this.$tip.hasClass('fade') ?
        $tip
          .one('bsTransitionEnd', complete)
1346
          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1347
1348
1349
        complete()
    }
  }
fat's avatar
fat committed
1350

XhmikosR's avatar
XhmikosR committed
1351
1352
1353
1354
  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
1355

XhmikosR's avatar
XhmikosR committed
1356
1357
1358
    // 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
1359

XhmikosR's avatar
XhmikosR committed
1360
1361
1362
    // we must check for NaN for ie 8/9
    if (isNaN(marginTop))  marginTop  = 0
    if (isNaN(marginLeft)) marginLeft = 0
fat's avatar
fat committed
1363

XhmikosR's avatar
XhmikosR committed
1364
1365
    offset.top  = offset.top  + marginTop
    offset.left = offset.left + marginLeft
fat's avatar
fat committed
1366

XhmikosR's avatar
XhmikosR committed
1367
1368
1369
1370
1371
1372
1373
1374
    // $.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)
        })
1375
      }
XhmikosR's avatar
XhmikosR committed
1376
    }, offset), 0)
1377

XhmikosR's avatar
XhmikosR committed
1378
    $tip.addClass('in')
fat's avatar
fat committed
1379

XhmikosR's avatar
XhmikosR committed
1380
1381
1382
    // 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
1383

XhmikosR's avatar
XhmikosR committed
1384
1385
1386
    if (placement == 'top' && actualHeight != height) {
      offset.top = offset.top + height - actualHeight
    }
fat's avatar
fat committed
1387

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

XhmikosR's avatar
XhmikosR committed
1390
1391
    if (delta.left) offset.left += delta.left
    else offset.top += delta.top
1392

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

XhmikosR's avatar
XhmikosR committed
1397
    $tip.offset(offset)
Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1398
    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
XhmikosR's avatar
XhmikosR committed
1399
  }
1400

Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1401
1402
1403
1404
  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
1405
  }
1406

XhmikosR's avatar
XhmikosR committed
1407
1408
1409
  Tooltip.prototype.setContent = function () {
    var $tip  = this.tip()
    var title = this.getTitle()
1410

XhmikosR's avatar
XhmikosR committed
1411
1412
1413
    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
    $tip.removeClass('fade in top bottom left right')
  }
1414

Heinrich Fenkart's avatar
Heinrich Fenkart committed
1415
  Tooltip.prototype.hide = function (callback) {
XhmikosR's avatar
XhmikosR committed
1416
1417
1418
    var that = this
    var $tip = this.tip()
    var e    = $.Event('hide.bs.' + this.type)
1419

XhmikosR's avatar
XhmikosR committed
1420
1421
    function complete() {
      if (that.hoverState != 'in') $tip.detach()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1422
1423
1424
      that.$element
        .removeAttr('aria-describedby')
        .trigger('hidden.bs.' + that.type)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1425
      callback && callback()
XhmikosR's avatar
XhmikosR committed
1426
    }
Jacob Thornton's avatar
Jacob Thornton committed
1427

XhmikosR's avatar
XhmikosR committed
1428
    this.$element.trigger(e)
1429

XhmikosR's avatar
XhmikosR committed
1430
    if (e.isDefaultPrevented()) return
1431

XhmikosR's avatar
XhmikosR committed
1432
    $tip.removeClass('in')
1433

XhmikosR's avatar
XhmikosR committed
1434
1435
1436
    $.support.transition && this.$tip.hasClass('fade') ?
      $tip
        .one('bsTransitionEnd', complete)
1437
        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1438
      complete()
1439

XhmikosR's avatar
XhmikosR committed
1440
    this.hoverState = null
1441

XhmikosR's avatar
XhmikosR committed
1442
1443
    return this
  }
1444

XhmikosR's avatar
XhmikosR committed
1445
1446
1447
1448
  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', '')
1449
    }
XhmikosR's avatar
XhmikosR committed
1450
  }
1451

XhmikosR's avatar
XhmikosR committed
1452
1453
1454
  Tooltip.prototype.hasContent = function () {
    return this.getTitle()
  }
1455

XhmikosR's avatar
XhmikosR committed
1456
1457
  Tooltip.prototype.getPosition = function ($element) {
    $element   = $element || this.$element
Mark Otto's avatar
grunt    
Mark Otto committed
1458

XhmikosR's avatar
XhmikosR committed
1459
1460
    var el     = $element[0]
    var isBody = el.tagName == 'BODY'
Mark Otto's avatar
grunt    
Mark Otto committed
1461
1462
    var isSvg  = window.SVGElement && el instanceof window.SVGElement

Mark Otto's avatar
grunt    
Mark Otto committed
1463
    var elRect    = el.getBoundingClientRect()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
1464
1465
1466
1467
    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
1468
1469
    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
Chris Rebert's avatar
Chris Rebert committed
1470
    var outerDims = isSvg ? {} : {
XhmikosR's avatar
XhmikosR committed
1471
1472
      width:  isBody ? $(window).width()  : $element.outerWidth(),
      height: isBody ? $(window).height() : $element.outerHeight()
Chris Rebert's avatar
Chris Rebert committed
1473
    }
Mark Otto's avatar
grunt    
Mark Otto committed
1474
1475

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

XhmikosR's avatar
XhmikosR committed
1478
1479
1480
1481
1482
  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   }
1483

XhmikosR's avatar
XhmikosR committed
1484
  }
1485

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

XhmikosR's avatar
XhmikosR committed
1490
1491
    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
    var viewportDimensions = this.getPosition(this.$viewport)
1492

XhmikosR's avatar
XhmikosR committed
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
    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
1508
      }
Chris Rebert's avatar
Chris Rebert committed
1509
    }
fat's avatar
fat committed
1510

XhmikosR's avatar
XhmikosR committed
1511
1512
    return delta
  }
1513

XhmikosR's avatar
XhmikosR committed
1514
1515
1516
1517
  Tooltip.prototype.getTitle = function () {
    var title
    var $e = this.$element
    var o  = this.options
1518

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

XhmikosR's avatar
XhmikosR committed
1522
1523
    return title
  }
1524

XhmikosR's avatar
XhmikosR committed
1525
1526
1527
1528
1529
  Tooltip.prototype.getUID = function (prefix) {
    do prefix += ~~(Math.random() * 1000000)
    while (document.getElementById(prefix))
    return prefix
  }
1530

XhmikosR's avatar
XhmikosR committed
1531
1532
1533
  Tooltip.prototype.tip = function () {
    return (this.$tip = this.$tip || $(this.options.template))
  }
1534

XhmikosR's avatar
XhmikosR committed
1535
1536
1537
  Tooltip.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
  }
1538

XhmikosR's avatar
XhmikosR committed
1539
1540
1541
  Tooltip.prototype.enable = function () {
    this.enabled = true
  }
1542

XhmikosR's avatar
XhmikosR committed
1543
1544
1545
  Tooltip.prototype.disable = function () {
    this.enabled = false
  }
Mark Otto's avatar
Mark Otto committed
1546

XhmikosR's avatar
XhmikosR committed
1547
1548
1549
  Tooltip.prototype.toggleEnabled = function () {
    this.enabled = !this.enabled
  }
Chris Rebert's avatar
Chris Rebert committed
1550

XhmikosR's avatar
XhmikosR committed
1551
1552
1553
1554
1555
1556
1557
1558
  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
1559
1560
    }

XhmikosR's avatar
XhmikosR committed
1561
1562
    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  }
1563

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


XhmikosR's avatar
XhmikosR committed
1573
1574
  // TOOLTIP PLUGIN DEFINITION
  // =========================
1575

XhmikosR's avatar
XhmikosR committed
1576
1577
1578
1579
1580
  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
1581

XhmikosR's avatar
XhmikosR committed
1582
1583
1584
1585
1586
      if (!data && option == 'destroy') return
      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1587

XhmikosR's avatar
XhmikosR committed
1588
  var old = $.fn.tooltip
Mark Otto's avatar
Mark Otto committed
1589

XhmikosR's avatar
XhmikosR committed
1590
1591
  $.fn.tooltip             = Plugin
  $.fn.tooltip.Constructor = Tooltip
1592

1593

XhmikosR's avatar
XhmikosR committed
1594
1595
  // TOOLTIP NO CONFLICT
  // ===================
1596

XhmikosR's avatar
XhmikosR committed
1597
1598
1599
1600
  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }
1601

XhmikosR's avatar
XhmikosR committed
1602
}(jQuery);
1603

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


XhmikosR's avatar
XhmikosR committed
1613
1614
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
1615

XhmikosR's avatar
XhmikosR committed
1616
1617
  // POPOVER PUBLIC CLASS DEFINITION
  // ===============================
1618

XhmikosR's avatar
XhmikosR committed
1619
1620
1621
  var Popover = function (element, options) {
    this.init('popover', element, options)
  }
fat's avatar
fat committed
1622

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

Mark Otto's avatar
Mark Otto committed
1625
  Popover.VERSION  = '3.2.0'
1626

XhmikosR's avatar
XhmikosR committed
1627
1628
1629
1630
1631
1632
  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
1633
1634


XhmikosR's avatar
XhmikosR committed
1635
1636
  // NOTE: POPOVER EXTENDS tooltip.js
  // ================================
1637

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

XhmikosR's avatar
XhmikosR committed
1640
  Popover.prototype.constructor = Popover
1641

XhmikosR's avatar
XhmikosR committed
1642
1643
1644
  Popover.prototype.getDefaults = function () {
    return Popover.DEFAULTS
  }
1645

XhmikosR's avatar
XhmikosR committed
1646
1647
1648
1649
  Popover.prototype.setContent = function () {
    var $tip    = this.tip()
    var title   = this.getTitle()
    var content = this.getContent()
1650

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

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

XhmikosR's avatar
XhmikosR committed
1658
1659
1660
1661
    // 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()
  }
1662

XhmikosR's avatar
XhmikosR committed
1663
1664
1665
  Popover.prototype.hasContent = function () {
    return this.getTitle() || this.getContent()
  }
1666

XhmikosR's avatar
XhmikosR committed
1667
1668
1669
  Popover.prototype.getContent = function () {
    var $e = this.$element
    var o  = this.options
1670

XhmikosR's avatar
XhmikosR committed
1671
1672
1673
1674
1675
    return $e.attr('data-content')
      || (typeof o.content == 'function' ?
            o.content.call($e[0]) :
            o.content)
  }
fat's avatar
fat committed
1676

XhmikosR's avatar
XhmikosR committed
1677
1678
1679
  Popover.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
  }
1680

XhmikosR's avatar
XhmikosR committed
1681
1682
1683
1684
  Popover.prototype.tip = function () {
    if (!this.$tip) this.$tip = $(this.options.template)
    return this.$tip
  }
1685

1686

XhmikosR's avatar
XhmikosR committed
1687
1688
  // POPOVER PLUGIN DEFINITION
  // =========================
1689

XhmikosR's avatar
XhmikosR committed
1690
1691
1692
1693
1694
  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
1695

XhmikosR's avatar
XhmikosR committed
1696
1697
1698
1699
1700
      if (!data && option == 'destroy') return
      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1701

XhmikosR's avatar
XhmikosR committed
1702
  var old = $.fn.popover
Mark Otto's avatar
Mark Otto committed
1703

XhmikosR's avatar
XhmikosR committed
1704
1705
  $.fn.popover             = Plugin
  $.fn.popover.Constructor = Popover
fat's avatar
fat committed
1706

1707

XhmikosR's avatar
XhmikosR committed
1708
1709
  // POPOVER NO CONFLICT
  // ===================
1710

XhmikosR's avatar
XhmikosR committed
1711
1712
1713
1714
  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }
1715

XhmikosR's avatar
XhmikosR committed
1716
}(jQuery);
1717

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


XhmikosR's avatar
XhmikosR committed
1727
1728
+function ($) {
  'use strict';
1729

XhmikosR's avatar
XhmikosR committed
1730
1731
  // SCROLLSPY CLASS DEFINITION
  // ==========================
1732

XhmikosR's avatar
XhmikosR committed
1733
1734
  function ScrollSpy(element, options) {
    var process  = $.proxy(this.process, this)
1735

XhmikosR's avatar
XhmikosR committed
1736
1737
1738
1739
1740
1741
1742
1743
    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
1744

XhmikosR's avatar
XhmikosR committed
1745
1746
1747
1748
    this.$scrollElement.on('scroll.bs.scrollspy', process)
    this.refresh()
    this.process()
  }
1749

Mark Otto's avatar
Mark Otto committed
1750
  ScrollSpy.VERSION  = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
1751

XhmikosR's avatar
XhmikosR committed
1752
1753
1754
  ScrollSpy.DEFAULTS = {
    offset: 10
  }
1755

XhmikosR's avatar
XhmikosR committed
1756
1757
1758
  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
1759

XhmikosR's avatar
XhmikosR committed
1760
1761
1762
  ScrollSpy.prototype.refresh = function () {
    var offsetMethod = 'offset'
    var offsetBase   = 0
Mark Otto's avatar
grunt    
Mark Otto committed
1763

XhmikosR's avatar
XhmikosR committed
1764
1765
1766
1767
    if (!$.isWindow(this.$scrollElement[0])) {
      offsetMethod = 'position'
      offsetBase   = this.$scrollElement.scrollTop()
    }
Mark Otto's avatar
grunt    
Mark Otto committed
1768

XhmikosR's avatar
XhmikosR committed
1769
1770
1771
    this.offsets = []
    this.targets = []
    this.scrollHeight = this.getScrollHeight()
fat's avatar
fat committed
1772

XhmikosR's avatar
XhmikosR committed
1773
    var self     = this
XhmikosR's avatar
XhmikosR committed
1774

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

XhmikosR's avatar
XhmikosR committed
1782
1783
1784
        return ($href
          && $href.length
          && $href.is(':visible')
Heinrich Fenkart's avatar
grunt    
Heinrich Fenkart committed
1785
          && $el.is(':visible')
XhmikosR's avatar
XhmikosR committed
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
          && [[$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
1806
1807
    }

XhmikosR's avatar
XhmikosR committed
1808
1809
1810
    if (scrollTop >= maxScroll) {
      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
    }
1811

XhmikosR's avatar
XhmikosR committed
1812
1813
    if (activeTarget && scrollTop <= offsets[0]) {
      return activeTarget != (i = targets[0]) && this.activate(i)
Chris Rebert's avatar
Chris Rebert committed
1814
    }
1815

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

XhmikosR's avatar
XhmikosR committed
1824
1825
  ScrollSpy.prototype.activate = function (target) {
    this.activeTarget = target
1826

XhmikosR's avatar
XhmikosR committed
1827
1828
1829
    $(this.selector)
      .parentsUntil(this.options.target, '.active')
      .removeClass('active')
1830

XhmikosR's avatar
XhmikosR committed
1831
1832
1833
    var selector = this.selector +
        '[data-target="' + target + '"],' +
        this.selector + '[href="' + target + '"]'
1834

XhmikosR's avatar
XhmikosR committed
1835
1836
1837
    var active = $(selector)
      .parents('li')
      .addClass('active')
1838

XhmikosR's avatar
XhmikosR committed
1839
1840
1841
1842
    if (active.parent('.dropdown-menu').length) {
      active = active
        .closest('li.dropdown')
        .addClass('active')
Chris Rebert's avatar
Chris Rebert committed
1843
    }
1844

XhmikosR's avatar
XhmikosR committed
1845
1846
    active.trigger('activate.bs.scrollspy')
  }
1847
1848


XhmikosR's avatar
XhmikosR committed
1849
1850
  // SCROLLSPY PLUGIN DEFINITION
  // ===========================
1851

XhmikosR's avatar
XhmikosR committed
1852
1853
1854
1855
1856
  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
1857

XhmikosR's avatar
XhmikosR committed
1858
1859
1860
1861
      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1862

XhmikosR's avatar
XhmikosR committed
1863
  var old = $.fn.scrollspy
1864

XhmikosR's avatar
XhmikosR committed
1865
1866
  $.fn.scrollspy             = Plugin
  $.fn.scrollspy.Constructor = ScrollSpy
1867

1868

XhmikosR's avatar
XhmikosR committed
1869
1870
  // SCROLLSPY NO CONFLICT
  // =====================
1871

XhmikosR's avatar
XhmikosR committed
1872
1873
1874
1875
  $.fn.scrollspy.noConflict = function () {
    $.fn.scrollspy = old
    return this
  }
1876

Chris Rebert's avatar
Chris Rebert committed
1877

XhmikosR's avatar
XhmikosR committed
1878
1879
  // SCROLLSPY DATA-API
  // ==================
Chris Rebert's avatar
Chris Rebert committed
1880

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

XhmikosR's avatar
XhmikosR committed
1888
}(jQuery);
1889

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

1898

XhmikosR's avatar
XhmikosR committed
1899
1900
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
1901

XhmikosR's avatar
XhmikosR committed
1902
1903
  // TAB CLASS DEFINITION
  // ====================
1904

XhmikosR's avatar
XhmikosR committed
1905
1906
1907
  var Tab = function (element) {
    this.element = $(element)
  }
1908

Mark Otto's avatar
Mark Otto committed
1909
  Tab.VERSION = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
1910

1911
1912
  Tab.TRANSITION_DURATION = 150

XhmikosR's avatar
XhmikosR committed
1913
1914
1915
1916
  Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.data('target')
1917

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

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

XhmikosR's avatar
XhmikosR committed
1925
1926
1927
1928
    var previous = $ul.find('.active:last a')[0]
    var e        = $.Event('show.bs.tab', {
      relatedTarget: previous
    })
1929

XhmikosR's avatar
XhmikosR committed
1930
    $this.trigger(e)
1931

XhmikosR's avatar
XhmikosR committed
1932
    if (e.isDefaultPrevented()) return
1933

XhmikosR's avatar
XhmikosR committed
1934
    var $target = $(selector)
1935

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

XhmikosR's avatar
XhmikosR committed
1945
1946
1947
1948
  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
1949
      && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
1950

XhmikosR's avatar
XhmikosR committed
1951
1952
1953
1954
1955
    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
        .removeClass('active')
1956

XhmikosR's avatar
XhmikosR committed
1957
1958
1959
1960
1961
1962
1963
      element.addClass('active')

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

XhmikosR's avatar
XhmikosR committed
1966
1967
1968
      if (element.parent('.dropdown-menu')) {
        element.closest('li.dropdown').addClass('active')
      }
fat's avatar
fat committed
1969

XhmikosR's avatar
XhmikosR committed
1970
      callback && callback()
1971
    }
fat's avatar
fat committed
1972

Mark Otto's avatar
grunt    
Mark Otto committed
1973
    $active.length && transition ?
XhmikosR's avatar
XhmikosR committed
1974
1975
      $active
        .one('bsTransitionEnd', next)
1976
        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
XhmikosR's avatar
XhmikosR committed
1977
      next()
1978

XhmikosR's avatar
XhmikosR committed
1979
1980
    $active.removeClass('in')
  }
1981
1982


XhmikosR's avatar
XhmikosR committed
1983
1984
  // TAB PLUGIN DEFINITION
  // =====================
fat's avatar
fat committed
1985

XhmikosR's avatar
XhmikosR committed
1986
1987
1988
1989
  function Plugin(option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.tab')
1990

XhmikosR's avatar
XhmikosR committed
1991
1992
1993
1994
      if (!data) $this.data('bs.tab', (data = new Tab(this)))
      if (typeof option == 'string') data[option]()
    })
  }
Mark Otto's avatar
Mark Otto committed
1995

XhmikosR's avatar
XhmikosR committed
1996
  var old = $.fn.tab
1997

XhmikosR's avatar
XhmikosR committed
1998
1999
  $.fn.tab             = Plugin
  $.fn.tab.Constructor = Tab
2000

For faster browsing, not all history is shown. View entire blame