PageSourceSearch

https://abs.org.sg/Sitefinity/WebsiteTemplates/Layout/App_Themes/Layout/js/offcanvas.js

js abs.org.sg collected 2026-09-24 08:47:23 UTC 10,235 bytes, 318 lines download raw bytes

1/* ========================================================================
2 * Bootstrap: offcanvas.js v3.1.3
3 * http://jasny.github.io/bootstrap/javascript/#offcanvas
4 * ========================================================================
5 * Copyright 2013-2014 Arnold Daniels
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
20+function ($) { "use strict";
21
22  // OFFCANVAS PUBLIC CLASS DEFINITION
23  // =================================
24
25  var OffCanvas = function (element, options) {
26    this.$element = $(element)
27    this.options  = $.extend({}, OffCanvas.DEFAULTS, options)
28    this.state    = null
29    this.placement = null
30    
31    if (this.options.recalc) {
32      this.calcClone()
33      $(window).on('resize', $.proxy(this.recalc, this))
34    }
35    
36    if (this.options.autohide)
37      $(document).on('click', $.proxy(this.autohide, this))
38
39    if (this.options.toggle) this.toggle()
40    
41    if (this.options.disablescrolling) {
42        this.options.disableScrolling = this.options.disablescrolling
43        delete this.options.disablescrolling
44    }
45  }
46
47  OffCanvas.DEFAULTS = {
48    toggle: true,
49    placement: 'auto',
50    autohide: true,
51    recalc: true,
52    disableScrolling: true
53  }
54
55  OffCanvas.prototype.offset = function () {
56    switch (this.placement) {
57      case 'left':
58      case 'right':  return this.$element.outerWidth()
59      case 'top':
60      case 'bottom': return this.$element.outerHeight()
61    }
62  }
63  
64  OffCanvas.prototype.calcPlacement = function () {
65    if (this.options.placement !== 'auto') {
66        this.placement = this.options.placement
67        return
68    }
69    
70    if (!this.$element.hasClass('in')) {
71      this.$element.css('visiblity', 'hidden !important').addClass('in')
72    } 
73    
74    var horizontal = $(window).width() / this.$element.width()
75    var vertical = $(window).height() / this.$element.height()
76        
77    var element = this.$element
78    function ab(a, b) {
79      if (element.css(b) === 'auto') return a
80      if (element.css(a) === 'auto') return b
81      
82      var size_a = parseInt(element.css(a), 10)
83      var size_b = parseInt(element.css(b), 10)
84  
85      return size_a > size_b ? b : a
86    }
87    
88    this.placement = horizontal >= vertical ? ab('left', 'right') : ab('top', 'bottom')
89      
90    if (this.$element.css('visibility') === 'hidden !important') {
91      this.$element.removeClass('in').css('visiblity', '')
92    }
93  }
94  
95  OffCanvas.prototype.opposite = function (placement) {
96    switch (placement) {
97      case 'top':    return 'bottom'
98      case 'left':   return 'right'
99      case 'bottom': return 'top'
100      case 'right':  return 'left'
101    }
102  }
103  
104  OffCanvas.prototype.getCanvasElements = function() {
105    // Return a set containing the canvas plus all fixed elements
106    var canvas = this.options.canvas ? $(this.options.canvas) : this.$element
107    
108    var fixed_elements = canvas.find('*').filter(function() {
109      return $(this).css('position') === 'fixed'
110    }).not(this.options.exclude)
111    
112    return canvas.add(fixed_elements)
113  }
114  
115  OffCanvas.prototype.slide = function (elements, offset, callback) {
116    // Use jQuery animation if CSS transitions aren't supported
117    if (!$.support.transition) {
118      var anim = {}
119      anim[this.placement] = "+=" + offset
120      return elements.animate(anim, 350, callback)
121    }
122
123    var placement = this.placement
124    var opposite = this.opposite(placement)
125    
126    elements.each(function() {
127      if ($(this).css(placement) !== 'auto')
128        $(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
129      
130      if ($(this).css(opposite) !== 'auto')
131        $(this).css(opposite, (parseInt($(this).css(opposite), 10) || 0) - offset)
132    })
133    
134    this.$element
135      .one($.support.transition.end, callback)
136      .emulateTransitionEnd(350)
137  }
138
139  OffCanvas.prototype.disableScrolling = function() {
140    var bodyWidth = $('body').width()
141    var prop = 'padding-' + this.opposite(this.placement)
142
143    if ($('body').data('offcanvas-style') === undefined) {
144      $('body').data('offcanvas-style', $('body').attr('style') || '')
145    }
146      
147    $('body').css('overflow', 'hidden')
148
149    if ($('body').width() > bodyWidth) {
150      var padding = parseInt($('body').css(prop), 10) + $('body').width() - bodyWidth
151      
152      setTimeout(function() {
153        $('body').css(prop, padding)
154      }, 1)
155    }
156  }
157
158  OffCanvas.prototype.show = function () {
159    if (this.state) return
160    
161    var startEvent = $.Event('show.bs.offcanvas')
162    this.$element.trigger(startEvent)
163    if (startEvent.isDefaultPrevented()) return
164
165    this.state = 'slide-in'
166    this.calcPlacement();
167    
168    var elements = this.getCanvasElements()
169    var placement = this.placement
170    var opposite = this.opposite(placement)
171    var offset = this.offset()
172
173    if (elements.index(this.$element) !== -1) {
174      $(this.$element).data('offcanvas-style', $(this.$element).attr('style') || '')
175      this.$element.css(placement, -1 * offset)
176      this.$element.css(placement); // Workaround: Need to get the CSS property for it to be applied before the next line of code
177    }
178
179    elements.addClass('canvas-sliding').each(function() {
180      if ($(this).data('offcanvas-style') === undefined) $(this).data('offcanvas-style', $(this).attr('style') || '')
181      if ($(this).css('position') === 'static') $(this).css('position', 'relative')
182      if (($(this).css(placement) === 'auto' || $(this).css(placement) === '0px') &&
183          ($(this).css(opposite) === 'auto' || $(this).css(opposite) === '0px')) {
184        $(this).css(placement, 0)
185      }
186    })
187    
188    if (this.options.disableScrolling) this.disableScrolling()
189    
190    var complete = function () {
191      if (this.state != 'slide-in') return
192      
193      this.state = 'slid'
194
195      elements.removeClass('canvas-sliding').addClass('canvas-slid')
196      this.$element.trigger('shown.bs.offcanvas')
197    }
198
199    setTimeout($.proxy(function() {
200      this.$element.addClass('in')
201      this.slide(elements, offset, $.proxy(complete, this))
202    }, this), 1)
203  }
204
205  OffCanvas.prototype.hide = function (fast) {
206    if (this.state !== 'slid') return
207
208    var startEvent = $.Event('hide.bs.offcanvas')
209    this.$element.trigger(startEvent)
210    if (startEvent.isDefaultPrevented()) return
211
212    this.state = 'slide-out'
213
214    var elements = $('.canvas-slid')
215    var placement = this.placement
216    var offset = -1 * this.offset()
217
218    var complete = function () {
219      if (this.state != 'slide-out') return
220      
221      this.state = null
222      this.placement = null
223      
224      this.$element.removeClass('in')
225      
226      elements.removeClass('canvas-sliding')
227      elements.add(this.$element).add('body').each(function() {
228        $(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
229      })
230
231      this.$element.trigger('hidden.bs.offcanvas')
232    }
233
234    elements.removeClass('canvas-slid').addClass('canvas-sliding')
235    
236    setTimeout($.proxy(function() {
237      this.slide(elements, offset, $.proxy(complete, this))
238    }, this), 1)
239  }
240
241  OffCanvas.prototype.toggle = function () {
242    if (this.state === 'slide-in' || this.state === 'slide-out') return
243    this[this.state === 'slid' ? 'hide' : 'show']()
244  }
245
246  OffCanvas.prototype.calcClone = function() {
247    this.$calcClone = this.$element.clone()
248      .html('')
249      .addClass('offcanvas-clone').removeClass('in')
250      .appendTo($('body'))
251  }
252
253  OffCanvas.prototype.recalc = function () {
254    if (this.$calcClone.css('display') === 'none' || (this.state !== 'slid' && this.state !== 'slide-in')) return
255    
256    this.state = null
257    this.placement = null
258    var elements = this.getCanvasElements()
259    
260    this.$element.removeClass('in')
261    
262    elements.removeClass('canvas-slid')
263    elements.add(this.$element).add('body').each(function() {
264      $(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
265    })
266  }
267  
268  OffCanvas.prototype.autohide = function (e) {
269    if ($(e.target).closest(this.$element).length === 0) this.hide()
270  }
271
272  // OFFCANVAS PLUGIN DEFINITION
273  // ==========================
274
275  var old = $.fn.offcanvas
276
277  $.fn.offcanvas = function (option) {
278    return this.each(function () {
279      var $this   = $(this)
280      var data    = $this.data('bs.offcanvas')
281      var options = $.extend({}, OffCanvas.DEFAULTS, $this.data(), typeof option === 'object' && option)
282
283      if (!data) $this.data('bs.offcanvas', (data = new OffCanvas(this, options)))
284      if (typeof option === 'string') data[option]()
285    })
286  }
287
288  $.fn.offcanvas.Constructor = OffCanvas
289
290
291  // OFFCANVAS NO CONFLICT
292  // ====================
293
294  $.fn.offcanvas.noConflict = function () {
295    $.fn.offcanvas = old
296    return this
297  }
298
299
300  // OFFCANVAS DATA-API
301  // =================
302
303  $(document).on('click.bs.offcanvas.data-api', '[data-toggle=offcanvas]', function (e) {
304    var $this   = $(this), href
305    var target  = $this.attr('data-target')
306        || e.preventDefault()
307        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
308    var $canvas = $(target)
309    var data    = $canvas.data('bs.offcanvas')
310    var option  = data ? 'toggle' : $this.data()
311
312    e.stopPropagation()
313
314    if (data) data.toggle()
315      else $canvas.offcanvas(option)
316  })
317
318}(window.jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.