bootstrap.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /* ============================================================
  2. * bootstrap-dropdown.js v2.1.1
  3. * http://twitter.github.com/bootstrap/javascript.html#dropdowns
  4. * ============================================================
  5. * Copyright 2012 Twitter, Inc.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * ============================================================ */
  19. !function ($) {
  20. "use strict"; // jshint ;_;
  21. /* DROPDOWN CLASS DEFINITION
  22. * ========================= */
  23. var toggle = '[data-toggle=dropdown]'
  24. , Dropdown = function (element) {
  25. var $el = $(element).on('click.dropdown.data-api', this.toggle)
  26. $('html').on('click.dropdown.data-api', function () {
  27. $el.parent().removeClass('open')
  28. })
  29. }
  30. Dropdown.prototype = {
  31. constructor: Dropdown
  32. , toggle: function (e) {
  33. var $this = $(this)
  34. , $parent
  35. , isActive
  36. if ($this.is('.disabled, :disabled')) return
  37. $parent = getParent($this)
  38. isActive = $parent.hasClass('open')
  39. clearMenus()
  40. if (!isActive) {
  41. $parent.toggleClass('open')
  42. $this.focus()
  43. }
  44. return false
  45. }
  46. , keydown: function (e) {
  47. var $this
  48. , $items
  49. , $active
  50. , $parent
  51. , isActive
  52. , index
  53. if (!/(38|40|27)/.test(e.keyCode)) return
  54. $this = $(this)
  55. e.preventDefault()
  56. e.stopPropagation()
  57. if ($this.is('.disabled, :disabled')) return
  58. $parent = getParent($this)
  59. isActive = $parent.hasClass('open')
  60. if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
  61. $items = $('[role=menu] li:not(.divider) a', $parent)
  62. if (!$items.length) return
  63. index = $items.index($items.filter(':focus'))
  64. if (e.keyCode == 38 && index > 0) index-- // up
  65. if (e.keyCode == 40 && index < $items.length - 1) index++ // down
  66. if (!~index) index = 0
  67. $items
  68. .eq(index)
  69. .focus()
  70. }
  71. }
  72. function clearMenus() {
  73. getParent($(toggle))
  74. .removeClass('open')
  75. }
  76. function getParent($this) {
  77. var selector = $this.attr('data-target')
  78. , $parent
  79. if (!selector) {
  80. selector = $this.attr('href')
  81. selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
  82. }
  83. $parent = $(selector)
  84. $parent.length || ($parent = $this.parent())
  85. return $parent
  86. }
  87. /* DROPDOWN PLUGIN DEFINITION
  88. * ========================== */
  89. $.fn.dropdown = function (option) {
  90. return this.each(function () {
  91. var $this = $(this)
  92. , data = $this.data('dropdown')
  93. if (!data) $this.data('dropdown', (data = new Dropdown(this)))
  94. if (typeof option == 'string') data[option].call($this)
  95. })
  96. }
  97. $.fn.dropdown.Constructor = Dropdown
  98. /* APPLY TO STANDARD DROPDOWN ELEMENTS
  99. * =================================== */
  100. $(function () {
  101. $('html')
  102. .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
  103. $('body')
  104. .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
  105. .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
  106. .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
  107. })
  108. }(window.jQuery);
  109. /* ========================================================
  110. * bootstrap-tab.js v2.1.1
  111. * http://twitter.github.com/bootstrap/javascript.html#tabs
  112. * ========================================================
  113. * Copyright 2012 Twitter, Inc.
  114. *
  115. * Licensed under the Apache License, Version 2.0 (the "License");
  116. * you may not use this file except in compliance with the License.
  117. * You may obtain a copy of the License at
  118. *
  119. * http://www.apache.org/licenses/LICENSE-2.0
  120. *
  121. * Unless required by applicable law or agreed to in writing, software
  122. * distributed under the License is distributed on an "AS IS" BASIS,
  123. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  124. * See the License for the specific language governing permissions and
  125. * limitations under the License.
  126. * ======================================================== */
  127. !function ($) {
  128. "use strict"; // jshint ;_;
  129. /* TAB CLASS DEFINITION
  130. * ==================== */
  131. var Tab = function (element) {
  132. this.element = $(element)
  133. }
  134. Tab.prototype = {
  135. constructor: Tab
  136. , show: function () {
  137. var $this = this.element
  138. , $ul = $this.closest('ul:not(.dropdown-menu)')
  139. , selector = $this.attr('data-target')
  140. , previous
  141. , $target
  142. , e
  143. if (!selector) {
  144. selector = $this.attr('href')
  145. selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
  146. }
  147. if ( $this.parent('li').hasClass('active') ) return
  148. previous = $ul.find('.active a').last()[0]
  149. e = $.Event('show', {
  150. relatedTarget: previous
  151. })
  152. $this.trigger(e)
  153. if (e.isDefaultPrevented()) return
  154. $target = $(selector)
  155. this.activate($this.parent('li'), $ul)
  156. this.activate($target, $target.parent(), function () {
  157. $this.trigger({
  158. type: 'shown'
  159. , relatedTarget: previous
  160. })
  161. })
  162. }
  163. , activate: function ( element, container, callback) {
  164. var $active = container.find('> .active')
  165. , transition = callback
  166. && $.support.transition
  167. && $active.hasClass('fade')
  168. function next() {
  169. $active
  170. .removeClass('active')
  171. .find('> .dropdown-menu > .active')
  172. .removeClass('active')
  173. element.addClass('active')
  174. if (transition) {
  175. element[0].offsetWidth // reflow for transition
  176. element.addClass('in')
  177. } else {
  178. element.removeClass('fade')
  179. }
  180. if ( element.parent('.dropdown-menu') ) {
  181. element.closest('li.dropdown').addClass('active')
  182. }
  183. callback && callback()
  184. }
  185. transition ?
  186. $active.one($.support.transition.end, next) :
  187. next()
  188. $active.removeClass('in')
  189. }
  190. }
  191. /* TAB PLUGIN DEFINITION
  192. * ===================== */
  193. $.fn.tab = function ( option ) {
  194. return this.each(function () {
  195. var $this = $(this)
  196. , data = $this.data('tab')
  197. if (!data) $this.data('tab', (data = new Tab(this)))
  198. if (typeof option == 'string') data[option]()
  199. })
  200. }
  201. $.fn.tab.Constructor = Tab
  202. /* TAB DATA-API
  203. * ============ */
  204. $(function () {
  205. $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
  206. e.preventDefault()
  207. $(this).tab('show')
  208. })
  209. })
  210. }(window.jQuery);
  211. /* ==========================================================
  212. * bootstrap-affix.js v2.1.1
  213. * http://twitter.github.com/bootstrap/javascript.html#affix
  214. * ==========================================================
  215. * Copyright 2012 Twitter, Inc.
  216. *
  217. * Licensed under the Apache License, Version 2.0 (the "License");
  218. * you may not use this file except in compliance with the License.
  219. * You may obtain a copy of the License at
  220. *
  221. * http://www.apache.org/licenses/LICENSE-2.0
  222. *
  223. * Unless required by applicable law or agreed to in writing, software
  224. * distributed under the License is distributed on an "AS IS" BASIS,
  225. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  226. * See the License for the specific language governing permissions and
  227. * limitations under the License.
  228. * ========================================================== */
  229. !function ($) {
  230. "use strict"; // jshint ;_;
  231. /* AFFIX CLASS DEFINITION
  232. * ====================== */
  233. var Affix = function (element, options) {
  234. this.options = $.extend({}, $.fn.affix.defaults, options)
  235. this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
  236. this.$element = $(element)
  237. this.checkPosition()
  238. }
  239. Affix.prototype.checkPosition = function () {
  240. if (!this.$element.is(':visible')) return
  241. var scrollHeight = $(document).height()
  242. , scrollTop = this.$window.scrollTop()
  243. , position = this.$element.offset()
  244. , offset = this.options.offset
  245. , offsetBottom = offset.bottom
  246. , offsetTop = offset.top
  247. , reset = 'affix affix-top affix-bottom'
  248. , affix
  249. if (typeof offset != 'object') offsetBottom = offsetTop = offset
  250. if (typeof offsetTop == 'function') offsetTop = offset.top()
  251. if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
  252. affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
  253. false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
  254. 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
  255. 'top' : false
  256. if (this.affixed === affix) return
  257. this.affixed = affix
  258. this.unpin = affix == 'bottom' ? position.top - scrollTop : null
  259. this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
  260. }
  261. /* AFFIX PLUGIN DEFINITION
  262. * ======================= */
  263. $.fn.affix = function (option) {
  264. return this.each(function () {
  265. var $this = $(this)
  266. , data = $this.data('affix')
  267. , options = typeof option == 'object' && option
  268. if (!data) $this.data('affix', (data = new Affix(this, options)))
  269. if (typeof option == 'string') data[option]()
  270. })
  271. }
  272. $.fn.affix.Constructor = Affix
  273. $.fn.affix.defaults = {
  274. offset: 0
  275. }
  276. /* AFFIX DATA-API
  277. * ============== */
  278. $(window).on('load', function () {
  279. $('[data-spy="affix"]').each(function () {
  280. var $spy = $(this)
  281. , data = $spy.data()
  282. data.offset = data.offset || {}
  283. data.offsetBottom && (data.offset.bottom = data.offsetBottom)
  284. data.offsetTop && (data.offset.top = data.offsetTop)
  285. $spy.affix(data)
  286. })
  287. })
  288. }(window.jQuery);