add web portal framework for TestAPI
[releng.git] / utils / test / testapi / 3rd_party / static / testapi-ui / assets / lib / bootstrap / js / scrollspy.js
1 /* ========================================================================
2  * Bootstrap: scrollspy.js v3.3.2
3  * http://getbootstrap.com/javascript/#scrollspy
4  * ========================================================================
5  * Copyright 2011-2015 Twitter, Inc.
6  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7  * ======================================================================== */
8
9
10 +function ($) {
11   'use strict';
12
13   // SCROLLSPY CLASS DEFINITION
14   // ==========================
15
16   function ScrollSpy(element, options) {
17     var process  = $.proxy(this.process, this)
18
19     this.$body          = $('body')
20     this.$scrollElement = $(element).is('body') ? $(window) : $(element)
21     this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
22     this.selector       = (this.options.target || '') + ' .nav li > a'
23     this.offsets        = []
24     this.targets        = []
25     this.activeTarget   = null
26     this.scrollHeight   = 0
27
28     this.$scrollElement.on('scroll.bs.scrollspy', process)
29     this.refresh()
30     this.process()
31   }
32
33   ScrollSpy.VERSION  = '3.3.2'
34
35   ScrollSpy.DEFAULTS = {
36     offset: 10
37   }
38
39   ScrollSpy.prototype.getScrollHeight = function () {
40     return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
41   }
42
43   ScrollSpy.prototype.refresh = function () {
44     var offsetMethod = 'offset'
45     var offsetBase   = 0
46
47     if (!$.isWindow(this.$scrollElement[0])) {
48       offsetMethod = 'position'
49       offsetBase   = this.$scrollElement.scrollTop()
50     }
51
52     this.offsets = []
53     this.targets = []
54     this.scrollHeight = this.getScrollHeight()
55
56     var self     = this
57
58     this.$body
59       .find(this.selector)
60       .map(function () {
61         var $el   = $(this)
62         var href  = $el.data('target') || $el.attr('href')
63         var $href = /^#./.test(href) && $(href)
64
65         return ($href
66           && $href.length
67           && $href.is(':visible')
68           && [[$href[offsetMethod]().top + offsetBase, href]]) || null
69       })
70       .sort(function (a, b) { return a[0] - b[0] })
71       .each(function () {
72         self.offsets.push(this[0])
73         self.targets.push(this[1])
74       })
75   }
76
77   ScrollSpy.prototype.process = function () {
78     var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
79     var scrollHeight = this.getScrollHeight()
80     var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
81     var offsets      = this.offsets
82     var targets      = this.targets
83     var activeTarget = this.activeTarget
84     var i
85
86     if (this.scrollHeight != scrollHeight) {
87       this.refresh()
88     }
89
90     if (scrollTop >= maxScroll) {
91       return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
92     }
93
94     if (activeTarget && scrollTop < offsets[0]) {
95       this.activeTarget = null
96       return this.clear()
97     }
98
99     for (i = offsets.length; i--;) {
100       activeTarget != targets[i]
101         && scrollTop >= offsets[i]
102         && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
103         && this.activate(targets[i])
104     }
105   }
106
107   ScrollSpy.prototype.activate = function (target) {
108     this.activeTarget = target
109
110     this.clear()
111
112     var selector = this.selector +
113         '[data-target="' + target + '"],' +
114         this.selector + '[href="' + target + '"]'
115
116     var active = $(selector)
117       .parents('li')
118       .addClass('active')
119
120     if (active.parent('.dropdown-menu').length) {
121       active = active
122         .closest('li.dropdown')
123         .addClass('active')
124     }
125
126     active.trigger('activate.bs.scrollspy')
127   }
128
129   ScrollSpy.prototype.clear = function () {
130     $(this.selector)
131       .parentsUntil(this.options.target, '.active')
132       .removeClass('active')
133   }
134
135
136   // SCROLLSPY PLUGIN DEFINITION
137   // ===========================
138
139   function Plugin(option) {
140     return this.each(function () {
141       var $this   = $(this)
142       var data    = $this.data('bs.scrollspy')
143       var options = typeof option == 'object' && option
144
145       if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
146       if (typeof option == 'string') data[option]()
147     })
148   }
149
150   var old = $.fn.scrollspy
151
152   $.fn.scrollspy             = Plugin
153   $.fn.scrollspy.Constructor = ScrollSpy
154
155
156   // SCROLLSPY NO CONFLICT
157   // =====================
158
159   $.fn.scrollspy.noConflict = function () {
160     $.fn.scrollspy = old
161     return this
162   }
163
164
165   // SCROLLSPY DATA-API
166   // ==================
167
168   $(window).on('load.bs.scrollspy.data-api', function () {
169     $('[data-spy="scroll"]').each(function () {
170       var $spy = $(this)
171       Plugin.call($spy, $spy.data())
172     })
173   })
174
175 }(jQuery);