| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 | /* =========================================================== * bootstrap-tooltip.js v2.3.1 * http://twitter.github.com/bootstrap/javascript.html#tooltips * Inspired by the original jQuery.tipsy by Jason Frame * =========================================================== * 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. * ========================================================== */!function ($) {  "use strict"; // jshint ;_; /* TOOLTIP PUBLIC CLASS DEFINITION  * =============================== */  var Tooltip = function (element, options) {    this.init('tooltip', element, options)  }  Tooltip.prototype = {    constructor: Tooltip  , init: function (type, element, options) {      var eventIn        , eventOut        , triggers        , trigger        , i      this.type = type      this.$element = $(element)      this.options = this.getOptions(options)      this.enabled = true      triggers = this.options.trigger.split(' ')      for (i = triggers.length; i--;) {        trigger = triggers[i]        if (trigger == 'click') {          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))        } else if (trigger != 'manual') {          eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'          eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'          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))        }      }      this.options.selector ?        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :        this.fixTitle()    }  , getOptions: function (options) {      options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)      if (options.delay && typeof options.delay == 'number') {        options.delay = {          show: options.delay        , hide: options.delay        }      }      return options    }  , enter: function (e) {      var defaults = $.fn[this.type].defaults        , options = {}        , self      this._options && $.each(this._options, function (key, value) {        if (defaults[key] != value) options[key] = value      }, this)      self = $(e.currentTarget)[this.type](options).data(this.type)      if (!self.options.delay || !self.options.delay.show) return self.show()      clearTimeout(this.timeout)      self.hoverState = 'in'      this.timeout = setTimeout(function() {        if (self.hoverState == 'in') self.show()      }, self.options.delay.show)    }  , leave: function (e) {      var self = $(e.currentTarget)[this.type](this._options).data(this.type)      if (this.timeout) clearTimeout(this.timeout)      if (!self.options.delay || !self.options.delay.hide) return self.hide()      self.hoverState = 'out'      this.timeout = setTimeout(function() {        if (self.hoverState == 'out') self.hide()      }, self.options.delay.hide)    }  , show: function () {      var $tip        , pos        , actualWidth        , actualHeight        , placement        , tp        , e = $.Event('show')      if (this.hasContent() && this.enabled) {        this.$element.trigger(e)        if (e.isDefaultPrevented()) return        $tip = this.tip()        this.setContent()        if (this.options.animation) {          $tip.addClass('fade')        }        placement = typeof this.options.placement == 'function' ?          this.options.placement.call(this, $tip[0], this.$element[0]) :          this.options.placement        $tip          .detach()          .css({ top: 0, left: 0, display: 'block' })        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)        pos = this.getPosition()        actualWidth = $tip[0].offsetWidth        actualHeight = $tip[0].offsetHeight        switch (placement) {          case 'bottom':            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}            break          case 'top':            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}            break          case 'left':            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}            break          case 'right':            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}            break        }        this.applyPlacement(tp, placement)        this.$element.trigger('shown')      }    }  , applyPlacement: function(offset, placement){      var $tip = this.tip()        , width = $tip[0].offsetWidth        , height = $tip[0].offsetHeight        , actualWidth        , actualHeight        , delta        , replace      $tip        .offset(offset)        .addClass(placement)        .addClass('in')      actualWidth = $tip[0].offsetWidth      actualHeight = $tip[0].offsetHeight      if (placement == 'top' && actualHeight != height) {        offset.top = offset.top + height - actualHeight        replace = true      }      if (placement == 'bottom' || placement == 'top') {        delta = 0        if (offset.left < 0){          delta = offset.left * -2          offset.left = 0          $tip.offset(offset)          actualWidth = $tip[0].offsetWidth          actualHeight = $tip[0].offsetHeight        }        this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')      } else {        this.replaceArrow(actualHeight - height, actualHeight, 'top')      }      if (replace) $tip.offset(offset)    }  , replaceArrow: function(delta, dimension, position){      this        .arrow()        .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')    }  , setContent: function () {      var $tip = this.tip()        , title = this.getTitle()      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)      $tip.removeClass('fade in top bottom left right')    }  , hide: function () {      var that = this        , $tip = this.tip()        , e = $.Event('hide')      this.$element.trigger(e)      if (e.isDefaultPrevented()) return      $tip.removeClass('in')      function removeWithAnimation() {        var timeout = setTimeout(function () {          $tip.off($.support.transition.end).detach()        }, 500)        $tip.one($.support.transition.end, function () {          clearTimeout(timeout)          $tip.detach()        })      }      $.support.transition && this.$tip.hasClass('fade') ?        removeWithAnimation() :        $tip.detach()      this.$element.trigger('hidden')      return this    }  , 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', '')      }    }  , hasContent: function () {      return this.getTitle()    }  , getPosition: function () {      var el = this.$element[0]      return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {        width: el.offsetWidth      , height: el.offsetHeight      }, this.$element.offset())    }  , getTitle: function () {      var title        , $e = this.$element        , o = this.options      title = $e.attr('data-original-title')        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)      return title    }  , tip: function () {      return this.$tip = this.$tip || $(this.options.template)    }  , arrow: function(){      return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")    }  , validate: function () {      if (!this.$element[0].parentNode) {        this.hide()        this.$element = null        this.options = null      }    }  , enable: function () {      this.enabled = true    }  , disable: function () {      this.enabled = false    }  , toggleEnabled: function () {      this.enabled = !this.enabled    }  , toggle: function (e) {      var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this      self.tip().hasClass('in') ? self.hide() : self.show()    }  , destroy: function () {      this.hide().$element.off('.' + this.type).removeData(this.type)    }  } /* TOOLTIP PLUGIN DEFINITION  * ========================= */  var old = $.fn.tooltip  $.fn.tooltip = function ( option ) {    return this.each(function () {      var $this = $(this)        , data = $this.data('tooltip')        , options = typeof option == 'object' && option      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))      if (typeof option == 'string') data[option]()    })  }  $.fn.tooltip.Constructor = Tooltip  $.fn.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  } /* TOOLTIP NO CONFLICT  * =================== */  $.fn.tooltip.noConflict = function () {    $.fn.tooltip = old    return this  }}(window.jQuery);
 |