PageRenderTime 20ms CodeModel.GetById 9ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/media/com_bootstrap/js/bootstrap-tooltip.js

https://bitbucket.org/organicdevelopment/com_bootstrap
JavaScript | 275 lines | 193 code | 59 blank | 23 comment | 38 complexity | a0015785d9e69af7cbfb238e9a0c28cf MD5 | raw file
  1/* ===========================================================
  2 * bootstrap-tooltip.js v2.1.1
  3 * http://twitter.github.com/bootstrap/javascript.html#tooltips
  4 * Inspired by the original jQuery.tipsy by Jason Frame
  5 * ===========================================================
  6 * Copyright 2012 Twitter, Inc.
  7 *
  8 * Licensed under the Apache License, Version 2.0 (the "License");
  9 * you may not use this file except in compliance with the License.
 10 * You may obtain a copy of the License at
 11 *
 12 * http://www.apache.org/licenses/LICENSE-2.0
 13 *
 14 * Unless required by applicable law or agreed to in writing, software
 15 * distributed under the License is distributed on an "AS IS" BASIS,
 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 17 * See the License for the specific language governing permissions and
 18 * limitations under the License.
 19 * ========================================================== */
 20
 21
 22!function ($) {
 23
 24  "use strict"; // jshint ;_;
 25
 26
 27 /* TOOLTIP PUBLIC CLASS DEFINITION
 28  * =============================== */
 29
 30  var Tooltip = function (element, options) {
 31    this.init('tooltip', element, options)
 32  }
 33
 34  Tooltip.prototype = {
 35
 36    constructor: Tooltip
 37
 38  , init: function (type, element, options) {
 39      var eventIn
 40        , eventOut
 41
 42      this.type = type
 43      this.$element = $(element)
 44      this.options = this.getOptions(options)
 45      this.enabled = true
 46
 47      if (this.options.trigger == 'click') {
 48        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
 49      } else if (this.options.trigger != 'manual') {
 50        eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
 51        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
 52        this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
 53        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
 54      }
 55
 56      this.options.selector ?
 57        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
 58        this.fixTitle()
 59    }
 60
 61  , getOptions: function (options) {
 62      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
 63
 64      if (options.delay && typeof options.delay == 'number') {
 65        options.delay = {
 66          show: options.delay
 67        , hide: options.delay
 68        }
 69      }
 70
 71      return options
 72    }
 73
 74  , enter: function (e) {
 75      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
 76
 77      if (!self.options.delay || !self.options.delay.show) return self.show()
 78
 79      clearTimeout(this.timeout)
 80      self.hoverState = 'in'
 81      this.timeout = setTimeout(function() {
 82        if (self.hoverState == 'in') self.show()
 83      }, self.options.delay.show)
 84    }
 85
 86  , leave: function (e) {
 87      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
 88
 89      if (this.timeout) clearTimeout(this.timeout)
 90      if (!self.options.delay || !self.options.delay.hide) return self.hide()
 91
 92      self.hoverState = 'out'
 93      this.timeout = setTimeout(function() {
 94        if (self.hoverState == 'out') self.hide()
 95      }, self.options.delay.hide)
 96    }
 97
 98  , show: function () {
 99      var $tip
100        , inside
101        , pos
102        , actualWidth
103        , actualHeight
104        , placement
105        , tp
106
107      if (this.hasContent() && this.enabled) {
108        $tip = this.tip()
109        this.setContent()
110
111        if (this.options.animation) {
112          $tip.addClass('fade')
113        }
114
115        placement = typeof this.options.placement == 'function' ?
116          this.options.placement.call(this, $tip[0], this.$element[0]) :
117          this.options.placement
118
119        inside = /in/.test(placement)
120
121        $tip
122          .remove()
123          .css({ top: 0, left: 0, display: 'block' })
124          .appendTo(inside ? this.$element : document.body)
125
126        pos = this.getPosition(inside)
127
128        actualWidth = $tip[0].offsetWidth
129        actualHeight = $tip[0].offsetHeight
130
131        switch (inside ? placement.split(' ')[1] : placement) {
132          case 'bottom':
133            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
134            break
135          case 'top':
136            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
137            break
138          case 'left':
139            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
140            break
141          case 'right':
142            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
143            break
144        }
145
146        $tip
147          .css(tp)
148          .addClass(placement)
149          .addClass('in')
150      }
151    }
152
153  , setContent: function () {
154      var $tip = this.tip()
155        , title = this.getTitle()
156
157      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
158      $tip.removeClass('fade in top bottom left right')
159    }
160
161  , hide: function () {
162      var that = this
163        , $tip = this.tip()
164
165      $tip.removeClass('in')
166
167      function removeWithAnimation() {
168        var timeout = setTimeout(function () {
169          $tip.off($.support.transition.end).remove()
170        }, 500)
171
172        $tip.one($.support.transition.end, function () {
173          clearTimeout(timeout)
174          $tip.remove()
175        })
176      }
177
178      $.support.transition && this.$tip.hasClass('fade') ?
179        removeWithAnimation() :
180        $tip.remove()
181
182      return this
183    }
184
185  , fixTitle: function () {
186      var $e = this.$element
187      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
188        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
189      }
190    }
191
192  , hasContent: function () {
193      return this.getTitle()
194    }
195
196  , getPosition: function (inside) {
197      return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
198        width: this.$element[0].offsetWidth
199      , height: this.$element[0].offsetHeight
200      })
201    }
202
203  , getTitle: function () {
204      var title
205        , $e = this.$element
206        , o = this.options
207
208      title = $e.attr('data-original-title')
209        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
210
211      return title
212    }
213
214  , tip: function () {
215      return this.$tip = this.$tip || $(this.options.template)
216    }
217
218  , validate: function () {
219      if (!this.$element[0].parentNode) {
220        this.hide()
221        this.$element = null
222        this.options = null
223      }
224    }
225
226  , enable: function () {
227      this.enabled = true
228    }
229
230  , disable: function () {
231      this.enabled = false
232    }
233
234  , toggleEnabled: function () {
235      this.enabled = !this.enabled
236    }
237
238  , toggle: function () {
239      this[this.tip().hasClass('in') ? 'hide' : 'show']()
240    }
241
242  , destroy: function () {
243      this.hide().$element.off('.' + this.type).removeData(this.type)
244    }
245
246  }
247
248
249 /* TOOLTIP PLUGIN DEFINITION
250  * ========================= */
251
252  $.fn.tooltip = function ( option ) {
253    return this.each(function () {
254      var $this = $(this)
255        , data = $this.data('tooltip')
256        , options = typeof option == 'object' && option
257      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
258      if (typeof option == 'string') data[option]()
259    })
260  }
261
262  $.fn.tooltip.Constructor = Tooltip
263
264  $.fn.tooltip.defaults = {
265    animation: true
266  , placement: 'top'
267  , selector: false
268  , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
269  , trigger: 'hover'
270  , title: ''
271  , delay: 0
272  , html: true
273  }
274
275}(window.jQuery);