bootstrap.js 55.9 KB
Newer Older
1001
1002
1003
        this.$backdrop
          .one($.support.transition.end, callback)
          .emulateTransitionEnd(150) :
fat's avatar
fat committed
1004
        callback()
1005

fat's avatar
fat committed
1006
1007
1008
    } else if (callback) {
      callback()
    }
1009
1010
1011
  }


fat's avatar
fat committed
1012
1013
  // MODAL PLUGIN DEFINITION
  // =======================
1014

1015
1016
  var old = $.fn.modal

1017
1018
  $.fn.modal = function (option) {
    return this.each(function () {
fat's avatar
fat committed
1019
      var $this   = $(this)
Mark Otto's avatar
Mark Otto committed
1020
      var data    = $this.data('bs.modal')
fat's avatar
fat committed
1021
1022
      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

Mark Otto's avatar
Mark Otto committed
1023
      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
1024
1025
1026
1027
1028
1029
1030
1031
      if (typeof option == 'string') data[option]()
      else if (options.show) data.show()
    })
  }

  $.fn.modal.Constructor = Modal


fat's avatar
fat committed
1032
1033
  // MODAL NO CONFLICT
  // =================
1034
1035
1036
1037
1038
1039
1040

  $.fn.modal.noConflict = function () {
    $.fn.modal = old
    return this
  }


fat's avatar
fat committed
1041
1042
  // MODAL DATA-API
  // ==============
1043

Mark Otto's avatar
Mark Otto committed
1044
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
fat's avatar
fat committed
1045
1046
1047
1048
    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('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
1049

1050
    e.preventDefault()
1051

1052
1053
1054
    $target
      .modal(option)
      .one('hide', function () {
1055
        $this.is(':visible') && $this.focus()
1056
      })
Jacob Thornton's avatar
Jacob Thornton committed
1057
  })
1058

Jacob Thornton's avatar
Jacob Thornton committed
1059
1060
1061
1062
1063
  $(function () {
    var $body = $(document.body)
      .on('shown.bs.modal',  '.modal', function () { $body.addClass('modal-open') })
      .on('hidden.bs.modal', '.modal', function () { $body.removeClass('modal-open') })
  })
1064

1065
}(window.jQuery);
1066

1067
/* ========================================================================
1068
1069
1070
 * Bootstrap: tooltip.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#affix
 * Inspired by the original jQuery.tipsy by Jason Frame
1071
 * ========================================================================
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
1085
 * ======================================================================== */
1086
1087


1088
+function ($) { "use strict";
1089

1090
  // TOOLTIP PUBLIC CLASS DEFINITION
fat's avatar
fat committed
1091
  // ===============================
1092

1093
1094
1095
1096
1097
1098
1099
  var Tooltip = function (element, options) {
    this.type       =
    this.options    =
    this.enabled    =
    this.timeout    =
    this.hoverState =
    this.$element   = null
1100

1101
1102
    this.init('tooltip', element, options)
  }
1103

1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
  Tooltip.DEFAULTS = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
  , trigger: 'hover focus'
  , title: ''
  , delay: 0
  , html: false
  , container: false
  }
1115

1116
1117
1118
1119
1120
  Tooltip.prototype.init = function (type, element, options) {
    this.enabled  = true
    this.type     = type
    this.$element = $(element)
    this.options  = this.getOptions(options)
1121

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

1124
1125
    for (var i = triggers.length; i--;) {
      var trigger = triggers[i]
fat's avatar
fat committed
1126

1127
1128
1129
1130
1131
      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' : 'focus'
        var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
1132

1133
1134
1135
1136
        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))
      }
    }
1137

1138
1139
1140
    this.options.selector ?
      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
      this.fixTitle()
fat's avatar
fat committed
1141
  }
1142

1143
1144
  Tooltip.prototype.getDefaults = function () {
    return Tooltip.DEFAULTS
1145
  }
1146

1147
1148
  Tooltip.prototype.getOptions = function (options) {
    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1149

1150
1151
1152
1153
1154
1155
    if (options.delay && typeof options.delay == 'number') {
      options.delay = {
        show: options.delay
      , hide: options.delay
      }
    }
1156

1157
    return options
1158
  }
Jacob Thornton's avatar
Jacob Thornton committed
1159

1160
1161
1162
  Tooltip.prototype.enter = function (obj) {
    var defaults = this.getDefaults()
    var options  = {}
1163

1164
1165
1166
    this._options && $.each(this._options, function (key, value) {
      if (defaults[key] != value) options[key] = value
    })
fat's avatar
rebuild    
fat committed
1167

1168
1169
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget)[this.type](options).data('bs.' + this.type)
1170

1171
    clearTimeout(self.timeout)
1172

1173
    if (!self.options.delay || !self.options.delay.show) return self.show()
1174

1175
1176
1177
1178
    self.hoverState = 'in'
    self.timeout    = setTimeout(function () {
      if (self.hoverState == 'in') self.show()
    }, self.options.delay.show)
1179
  }
1180

1181
1182
1183
  Tooltip.prototype.leave = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget)[this.type](this._options).data('bs.' + this.type)
1184

1185
    clearTimeout(self.timeout)
fat's avatar
fat committed
1186

1187
    if (!self.options.delay || !self.options.delay.hide) return self.hide()
1188

1189
1190
1191
1192
    self.hoverState = 'out'
    self.timeout    = setTimeout(function () {
      if (self.hoverState == 'out') self.hide()
    }, self.options.delay.hide)
1193
  }
1194

1195
1196
  Tooltip.prototype.show = function () {
    var e = $.Event('show.bs.'+ this.type)
1197

1198
1199
    if (this.hasContent() && this.enabled) {
      this.$element.trigger(e)
1200

1201
      if (e.isDefaultPrevented()) return
1202

1203
      var $tip = this.tip()
fat's avatar
fat committed
1204

1205
      this.setContent()
fat's avatar
fat committed
1206

1207
      if (this.options.animation) $tip.addClass('fade')
fat's avatar
fat committed
1208

1209
1210
1211
      var placement = typeof this.options.placement == 'function' ?
        this.options.placement.call(this, $tip[0], this.$element[0]) :
        this.options.placement
1212

1213
1214
1215
      var autoToken = /\s?auto?\s?/i
      var autoPlace = autoToken.test(placement)
      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1216

1217
1218
1219
1220
      $tip
        .detach()
        .css({ top: 0, left: 0, display: 'block' })
        .addClass(placement)
1221

1222
      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1223

1224
1225
1226
      var pos          = this.getPosition()
      var actualWidth  = $tip[0].offsetWidth
      var actualHeight = $tip[0].offsetHeight
fat's avatar
fat committed
1227

1228
1229
      if (autoPlace) {
        var $parent = this.$element.parent()
1230

1231
1232
1233
1234
1235
        var orgPlacement = placement
        var docScroll    = document.documentElement.scrollTop || document.body.scrollTop
        var parentWidth  = this.options.container == 'body' ? window.innerWidth  : $parent.outerWidth()
        var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
        var parentLeft   = this.options.container == 'body' ? 0 : $parent.offset().left
fat's avatar
fat committed
1236

1237
1238
1239
1240
1241
        placement = placement == 'bottom' && pos.top   + pos.height  + actualHeight - docScroll > parentHeight  ? 'top'    :
                    placement == 'top'    && pos.top   - docScroll   - actualHeight < 0                         ? 'bottom' :
                    placement == 'right'  && pos.right + actualWidth > parentWidth                              ? 'left'   :
                    placement == 'left'   && pos.left  - actualWidth < parentLeft                               ? 'right'  :
                    placement
fat's avatar
fat committed
1242

1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
        $tip
          .removeClass(orgPlacement)
          .addClass(placement)
      }

      var tp = 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   }

      this.applyPlacement(tp, placement)
      this.$element.trigger('shown.bs.' + this.type)
fat's avatar
fat committed
1255
    }
1256
  }
fat's avatar
fat committed
1257

1258
1259
1260
1261
1262
  Tooltip.prototype.applyPlacement = function(offset, placement) {
    var replace
    var $tip   = this.tip()
    var width  = $tip[0].offsetWidth
    var height = $tip[0].offsetHeight
fat's avatar
fat committed
1263

1264
1265
1266
    // manually read margins because getBoundingClientRect includes difference
    offset.top  = offset.top  + parseInt($tip.css('margin-top'), 10)
    offset.left = offset.left + parseInt($tip.css('margin-left'), 10)
fat's avatar
fat committed
1267

1268
1269
1270
    $tip
      .offset(offset)
      .addClass('in')
fat's avatar
fat committed
1271

1272
1273
    var actualWidth  = $tip[0].offsetWidth
    var actualHeight = $tip[0].offsetHeight
fat's avatar
fat committed
1274

1275
1276
1277
    if (placement == 'top' && actualHeight != height) {
      replace = true
      offset.top  = offset.top + height - actualHeight
fat's avatar
fat committed
1278
1279
    }

1280
1281
    if (placement == 'bottom' || placement == 'top') {
      var delta = 0
1282

1283
1284
1285
      if (offset.left < 0){
        delta       = offset.left * -2
        offset.left = 0
fat's avatar
fat committed
1286

1287
        $tip.offset(offset)
1288

1289
1290
1291
        actualWidth  = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight
      }
1292

1293
1294
1295
1296
      this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
    } else {
      this.replaceArrow(actualHeight - height, actualHeight, 'top')
    }
1297

1298
    if (replace) $tip.offset(offset)
1299
  }
1300

1301
1302
  Tooltip.prototype.replaceArrow = function(delta, dimension, position) {
    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
fat's avatar
fat committed
1303
  }
1304

1305
1306
1307
  Tooltip.prototype.setContent = function () {
    var $tip  = this.tip()
    var title = this.getTitle()
1308

1309
1310
1311
    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
    $tip.removeClass('fade in top bottom left right')
  }
1312

1313
1314
1315
1316
  Tooltip.prototype.hide = function () {
    var that = this
    var $tip = this.tip()
    var e    = $.Event('hide.bs.' + this.type)
1317

Jacob Thornton's avatar
Jacob Thornton committed
1318
1319
    function complete() { $tip.detach() }

1320
    this.$element.trigger(e)
1321

1322
    if (e.isDefaultPrevented()) return
1323

1324
    $tip.removeClass('in')
1325

1326
1327
    $.support.transition && this.$tip.hasClass('fade') ?
      $tip
Jacob Thornton's avatar
Jacob Thornton committed
1328
        .one($.support.transition.end, complete)
1329
        .emulateTransitionEnd(150) :
Jacob Thornton's avatar
Jacob Thornton committed
1330
      complete()
1331

1332
    this.$element.trigger('hidden.bs.' + this.type)
1333

1334
    return this
1335
1336
  }

1337
1338
1339
1340
  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', '')
1341
    }
1342
  }
1343

1344
1345
1346
  Tooltip.prototype.hasContent = function () {
    return this.getTitle()
  }
1347

1348
1349
1350
1351
1352
1353
1354
  Tooltip.prototype.getPosition = function () {
    var el = this.$element[0]
    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
      width: el.offsetWidth
    , height: el.offsetHeight
    }, this.$element.offset())
  }
1355

1356
1357
1358
1359
  Tooltip.prototype.getTitle = function () {
    var title
    var $e = this.$element
    var o  = this.options
1360

1361
1362
    title = $e.attr('data-original-title')
      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
1363

1364
    return title
1365
  }
1366

1367
1368
1369
  Tooltip.prototype.tip = function () {
    return this.$tip = this.$tip || $(this.options.template)
  }
1370

1371
1372
1373
  Tooltip.prototype.arrow =function(){
    return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
  }
1374

1375
1376
1377
1378
1379
1380
1381
  Tooltip.prototype.validate = function () {
    if (!this.$element[0].parentNode) {
      this.hide()
      this.$element = null
      this.options  = null
    }
  }
1382

1383
1384
1385
  Tooltip.prototype.enable = function () {
    this.enabled = true
  }
1386

1387
1388
1389
  Tooltip.prototype.disable = function () {
    this.enabled = false
  }
1390

1391
1392
1393
  Tooltip.prototype.toggleEnabled = function () {
    this.enabled = !this.enabled
  }
Mark Otto's avatar
Mark Otto committed
1394

1395
1396
1397
1398
  Tooltip.prototype.toggle = function (e) {
    var self = e ? $(e.currentTarget)[this.type](this._options).data('bs.' + this.type) : this
    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  }
1399

1400
1401
  Tooltip.prototype.destroy = function () {
    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
fat's avatar
fat committed
1402
  }
1403
1404


1405
1406
  // TOOLTIP PLUGIN DEFINITION
  // =========================
1407

1408
  var old = $.fn.tooltip
1409

1410
  $.fn.tooltip = function (option) {
1411
    return this.each(function () {
1412
1413
1414
      var $this   = $(this)
      var data    = $this.data('bs.tooltip')
      var options = typeof option == 'object' && option
fat's avatar
fat committed
1415

1416
      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
1417
1418
1419
1420
      if (typeof option == 'string') data[option]()
    })
  }

1421
  $.fn.tooltip.Constructor = Tooltip
1422

1423

1424
1425
  // TOOLTIP NO CONFLICT
  // ===================
1426

1427
1428
  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
1429
1430
1431
    return this
  }

Mark Otto's avatar
Mark Otto committed
1432
}(window.jQuery);
1433

1434
/* ========================================================================
1435
1436
 * Bootstrap: popover.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#popovers
1437
 * ========================================================================
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
1451
 * ======================================================================== */
1452
1453


1454
+function ($) { "use strict";
1455

1456
  // POPOVER PUBLIC CLASS DEFINITION
1457
  // ===============================
fat's avatar
fat committed
1458

1459
1460
  var Popover = function (element, options) {
    this.init('popover', element, options)
1461
1462
  }

fat's avatar
fat committed
1463
1464
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')

1465
1466
1467
1468
1469
1470
  Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {
    placement: 'right'
  , trigger: 'click'
  , content: ''
  , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  })
1471

fat's avatar
fat committed
1472

1473
1474
  // NOTE: POPOVER EXTENDS tooltip.js
  // ================================
fat's avatar
fat committed
1475

1476
  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
1477

1478
  Popover.prototype.constructor = Popover
fat's avatar
fat committed
1479

1480
1481
1482
  Popover.prototype.getDefaults = function () {
    return Popover.DEFAULTS
  }
1483

1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
  Popover.prototype.setContent = function () {
    var $tip    = this.tip()
    var title   = this.getTitle()
    var content = this.getContent()

    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
    $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)

    $tip.removeClass('fade top bottom left right in')

    $tip.find('.popover-title:empty').hide()
1495
1496
  }

1497
1498
  Popover.prototype.hasContent = function () {
    return this.getTitle() || this.getContent()
1499
1500
  }

1501
1502
1503
  Popover.prototype.getContent = function () {
    var $e = this.$element
    var o  = this.options
1504

1505
1506
1507
1508
1509
    return $e.attr('data-content')
      || (typeof o.content == 'function' ?
            o.content.call($e[0]) :
            o.content)
  }
1510

1511
1512
1513
  Popover.prototype.tip = function () {
    if (!this.$tip) this.$tip = $(this.options.template)
    return this.$tip
fat's avatar
fat committed
1514
  }
1515

1516

1517
1518
  // POPOVER PLUGIN DEFINITION
  // =========================
1519

1520
  var old = $.fn.popover
1521

1522
1523
1524
1525
1526
  $.fn.popover = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.popover')
      var options = typeof option == 'object' && option
1527

1528
1529
1530
      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
1531
1532
  }

1533
  $.fn.popover.Constructor = Popover
fat's avatar
fat committed
1534

1535

1536
1537
  // POPOVER NO CONFLICT
  // ===================
1538

1539
1540
1541
1542
  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }
1543

1544
}(window.jQuery);
1545

1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
/* ========================================================================
 * Bootstrap: scrollspy.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#scrollspy
 * ========================================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */
1564
1565


1566
+function ($) { "use strict";
1567

1568
1569
  // SCROLLSPY CLASS DEFINITION
  // ==========================
1570

1571
1572
1573
  function ScrollSpy(element, options) {
    var href
    var process  = $.proxy(this.process, this)
1574

fat's avatar
fat committed
1575
    this.$element       = $(element).is('body') ? $(window) : $(element)
1576
    this.$body          = $('body')
fat's avatar
fat committed
1577
    this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
1578
1579
1580
1581
1582
1583
1584
    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
    this.selector       = (this.options.target
      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
      || '') + ' .nav li > a'
    this.offsets        = $([])
    this.targets        = $([])
    this.activeTarget   = null
1585

1586
1587
1588
    this.refresh()
    this.process()
  }
1589

1590
1591
1592
  ScrollSpy.DEFAULTS = {
    offset: 10
  }
1593

1594
  ScrollSpy.prototype.refresh = function () {
fat's avatar
fat committed
1595
1596
    var offsetMethod = this.$element[0] == window ? 'offset' : 'position'

1597
1598
    this.offsets = $([])
    this.targets = $([])
1599

1600
1601
1602
1603
1604
1605
1606
    var self     = this
    var $targets = this.$body
      .find(this.selector)
      .map(function () {
        var $el   = $(this)
        var href  = $el.data('target') || $el.attr('href')
        var $href = /^#\w/.test(href) && $(href)
1607

1608
1609
        return ($href
          && $href.length
fat's avatar
fat committed
1610
          && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
1611
1612
1613
1614
1615
1616
1617
      })
      .sort(function (a, b) { return a[0] - b[0] })
      .each(function () {
        self.offsets.push(this[0])
        self.targets.push(this[1])
      })
  }
1618

1619
1620
1621
1622
1623
1624
1625
1626
  ScrollSpy.prototype.process = function () {
    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
    var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
    var maxScroll    = scrollHeight - this.$scrollElement.height()
    var offsets      = this.offsets
    var targets      = this.targets
    var activeTarget = this.activeTarget
    var i
1627

1628
1629
1630
    if (scrollTop >= maxScroll) {
      return activeTarget != (i = targets.last()[0]) && this.activate(i)
    }
1631

1632
1633
1634
1635
1636
    for (i = offsets.length; i--;) {
      activeTarget != targets[i]
        && scrollTop >= offsets[i]
        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
        && this.activate( targets[i] )
1637
    }
1638
1639
  }

1640
1641
  ScrollSpy.prototype.activate = function (target) {
    this.activeTarget = target
1642

1643
1644
1645
    $(this.selector)
      .parents('.active')
      .removeClass('active')
1646

1647
1648
1649
    var selector = this.selector
      + '[data-target="' + target + '"],'
      + this.selector + '[href="' + target + '"]'
1650

1651
1652
1653
    var active = $(selector)
      .parents('li')
      .addClass('active')
1654

1655
1656
1657
1658
    if (active.parent('.dropdown-menu').length)  {
      active = active
        .closest('li.dropdown')
        .addClass('active')
1659
    }
1660

1661
1662
    active.trigger('activate')
  }
1663
1664


1665
1666
  // SCROLLSPY PLUGIN DEFINITION
  // ===========================
1667

1668
  var old = $.fn.scrollspy
1669

1670
1671
1672
1673
1674
  $.fn.scrollspy = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.scrollspy')
      var options = typeof option == 'object' && option
1675

1676
1677
1678
      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
      if (typeof option == 'string') data[option]()
    })
1679
1680
  }

1681
  $.fn.scrollspy.Constructor = ScrollSpy
1682
1683


1684
1685
1686
1687
1688
1689
  // SCROLLSPY NO CONFLICT
  // =====================

  $.fn.scrollspy.noConflict = function () {
    $.fn.scrollspy = old
    return this
1690
1691
1692
  }


1693
1694
  // SCROLLSPY DATA-API
  // ==================
1695

1696
1697
1698
1699
1700
1701
  $(window).on('load', function () {
    $('[data-spy="scroll"]').each(function () {
      var $spy = $(this)
      $spy.scrollspy($spy.data())
    })
  })
1702

1703
}(window.jQuery);
1704

1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
/* ========================================================================
 * Bootstrap: tab.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#tabs
 * ========================================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */
1723

1724

1725
1726
1727
1728
1729
1730
1731
+function ($) { "use strict";

  // TAB CLASS DEFINITION
  // ====================

  var Tab = function (element) {
    this.element = $(element)
1732
  }
1733

1734
1735
1736
1737
1738
1739
1740
1741
  Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.attr('data-target')

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1742
    }
1743

1744
    if ($this.parent('li').hasClass('active')) return
1745

1746
1747
1748
1749
    var previous = $ul.find('.active:last a')[0]
    var e        = $.Event('show.bs.tab', {
      relatedTarget: previous
    })
1750

1751
    $this.trigger(e)
1752

1753
    if (e.isDefaultPrevented()) return
1754

1755
    var $target = $(selector)
1756

1757
1758
1759
1760
1761
1762
1763
    this.activate($this.parent('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $this.trigger({
        type: 'shown.bs.tab'
      , relatedTarget: previous
      })
    })
1764
  }
1765

1766
1767
1768
1769
1770
  Tab.prototype.activate = function (element, container, callback) {
    var $active    = container.find('> .active')
    var transition = callback
      && $.support.transition
      && $active.hasClass('fade')
1771

1772
1773
1774
1775
1776
    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
        .removeClass('active')
1777

1778
      element.addClass('active')
1779

1780
1781
1782
1783
1784
1785
      if (transition) {
        element[0].offsetWidth // reflow for transition
        element.addClass('in')
      } else {
        element.removeClass('fade')
      }
1786

1787
1788
1789
      if (element.parent('.dropdown-menu')) {
        element.closest('li.dropdown').addClass('active')
      }
fat's avatar
fat committed
1790

1791
1792
      callback && callback()
    }
fat's avatar
fat committed
1793

1794
1795
1796
1797
1798
1799
1800
    transition ?
      $active
        .one($.support.transition.end, next)
        .emulateTransitionEnd(150) :
      next()

    $active.removeClass('in')
1801
1802
1803
  }


1804
1805
  // TAB PLUGIN DEFINITION
  // =====================
1806

1807
  var old = $.fn.tab
1808

1809
  $.fn.tab = function ( option ) {
1810
    return this.each(function () {
1811
1812
      var $this = $(this)
      var data  = $this.data('bs.tab')
fat's avatar
fat committed
1813

1814
      if (!data) $this.data('bs.tab', (data = new Tab(this)))
1815
1816
1817
1818
      if (typeof option == 'string') data[option]()
    })
  }

1819
  $.fn.tab.Constructor = Tab
1820
1821


1822
1823
  // TAB NO CONFLICT
  // ===============
1824

1825
1826
  $.fn.tab.noConflict = function () {
    $.fn.tab = old
1827
1828
1829
    return this
  }

1830
1831
1832
1833
1834
1835
1836
1837
1838

  // TAB DATA-API
  // ============

  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
    e.preventDefault()
    $(this).tab('show')
  })

1839
}(window.jQuery);
1840

1841
/* ========================================================================
1842
1843
 * Bootstrap: affix.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#affix
1844
 * ========================================================================
1845
 * Copyright 2012 Twitter, Inc.
Mark Otto's avatar
Mark Otto committed
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
1858
 * ======================================================================== */
Mark Otto's avatar
Mark Otto committed
1859
1860


1861
+function ($) { "use strict";
Mark Otto's avatar
Mark Otto committed
1862

1863
1864
  // AFFIX CLASS DEFINITION
  // ======================
Mark Otto's avatar
Mark Otto committed
1865

1866
1867
1868
1869
1870
  var Affix = function (element, options) {
    this.options = $.extend({}, Affix.DEFAULTS, options)
    this.$window = $(window)
      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
fat's avatar
fat committed
1871

1872
1873
1874
    this.$element = $(element)
    this.affixed  =
    this.unpin    = null
fat's avatar
fat committed
1875

1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
    this.checkPosition()
  }

  Affix.RESET = 'affix affix-top affix-bottom'

  Affix.DEFAULTS = {
    offset: 0
  }

  Affix.prototype.checkPositionWithEventLoop = function () {
    setTimeout($.proxy(this.checkPosition, this), 1)
  }

  Affix.prototype.checkPosition = function () {
    if (!this.$element.is(':visible')) return

    var scrollHeight = $(document).height()
    var scrollTop    = this.$window.scrollTop()
    var position     = this.$element.offset()
    var offset       = this.options.offset
    var offsetTop    = offset.top
    var offsetBottom = offset.bottom

    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
    if (typeof offsetTop == 'function')    offsetTop    = offset.top()
    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()

    var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :
                offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
                offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false

    if (this.affixed === affix) return
    if (this.unpin) this.$element.css('top', '')

    this.affixed = affix
    this.unpin   = affix == 'bottom' ? position.top - scrollTop : null

    this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))

    if (affix == 'bottom') {
      this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
1917
    }
Mark Otto's avatar
Mark Otto committed
1918
1919
  }

1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934

  // AFFIX PLUGIN DEFINITION
  // =======================

  var old = $.fn.affix

  $.fn.affix = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.affix')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
      if (typeof option == 'string') data[option]()
    })
1935
1936
  }

1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
  $.fn.affix.Constructor = Affix


  // AFFIX NO CONFLICT
  // =================

  $.fn.affix.noConflict = function () {
    $.fn.affix = old
    return this
  }


  // AFFIX DATA-API
  // ==============

  $(window).on('load', function () {
    $('[data-spy="affix"]').each(function () {
      var $spy = $(this)
      var data = $spy.data()

      data.offset = data.offset || {}

      if (data.offsetBottom) data.offset.bottom = data.offsetBottom
      if (data.offsetTop)    data.offset.top    = data.offsetTop

      $spy.affix(data)
    })
Mark Otto's avatar
Mark Otto committed
1964
1965
  })

1966
}(window.jQuery);
For faster browsing, not all history is shown. View entire blame