bootstrap.js 61.8 KB
Newer Older
XhmikosR's avatar
XhmikosR committed
1001
  }
1002

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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


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

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

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

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

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

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


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

1160
1161
  Tooltip.TRANSITION_DURATION = 150

XhmikosR's avatar
XhmikosR committed
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
1199
  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))
      }
    }
1200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

XhmikosR's avatar
XhmikosR committed
1485
  }
1486

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

1594

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

1687

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

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

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

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

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

1708

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

1869

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

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

Chris Rebert's avatar
Chris Rebert committed
1878

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

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

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

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

1899

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

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

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

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

1912
1913
  Tab.TRANSITION_DURATION = 150

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

XhmikosR's avatar
XhmikosR committed
1999
2000
  $.fn.tab             = Plugin
  $.fn.tab.Constructor = Tab
For faster browsing, not all history is shown. View entire blame