/* ========================================================== * bootstrap-twipsy.js v2.0.0 * http://twitter.github.com/bootstrap/javascript.html#twipsy * Adapted from the original jQuery.tipsy by Jason Frame * ========================================================== * Copyright 2011 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" /* TWIPSY PUBLIC CLASS DEFINITION * ============================== */ var Twipsy = function ( element, options ) { this.$element = $(element) this.options = options this.enabled = true this.fixTitle() } Twipsy.prototype = { show: function() { var pos , actualWidth , actualHeight , placement , $tip , tp if (this.hasContent() && this.enabled) { $tip = this.tip() this.setContent() if (this.options.animate) { $tip.addClass('fade') } $tip .remove() .css({ top: 0, left: 0, display: 'block' }) .prependTo(document.body) pos = $.extend({}, this.$element.offset(), { width: this.$element[0].offsetWidth , height: this.$element[0].offsetHeight }) actualWidth = $tip[0].offsetWidth actualHeight = $tip[0].offsetHeight placement = maybeCall(this.options.placement, this, [ $tip[0], this.$element[0] ]) switch (placement) { case 'below': tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2} break case 'above': tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2} break case 'left': tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset} break case 'right': tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset} break } $tip .css(tp) .addClass(placement) .addClass('in') } } , setContent: function () { var $tip = this.tip() $tip.find('.twipsy-inner').html(this.getTitle()) $tip[0].className = 'twipsy' } , hide: function() { var that = this , $tip = this.tip() $tip.removeClass('in') function removeElement () { $tip.remove() } $.support.transition && this.$tip.hasClass('fade') ? $tip.bind( $.support.transition.end, removeElement) : removeElement() } , 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') || '').removeAttr('title') } } , hasContent: function () { return this.getTitle() } , getTitle: function() { var title , $e = this.$element , o = this.options this.fixTitle() if (typeof o.title == 'string') { title = $e.attr(o.title == 'title' ? 'data-original-title' : o.title) } else if (typeof o.title == 'function') { title = o.title.call($e[0]) } title = ('' + title).replace(/(^\s*|\s*$)/, "") return title } , tip: function() { return this.$tip = this.$tip || $('
').html(this.options.template) } , 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 () { this[this.tip().hasClass('in') ? 'hide' : 'show']() } } /* TWIPSY PRIVATE METHODS * ====================== */ function maybeCall ( thing, ctx, args ) { return typeof thing == 'function' ? thing.apply(ctx, args) : thing } /* TWIPSY PLUGIN DEFINITION * ======================== */ $.fn.twipsy = function (options) { $.fn.twipsy.initWith.call(this, options, Twipsy, 'twipsy') return this } $.fn.twipsy.initWith = function (options, Constructor, name) { var twipsy , binder , eventIn , eventOut if (typeof options == 'string') { return this.each(function (){ twipsy = $.data(this, name) if (twipsy) twipsy[options]() }) } options = $.extend({}, $.fn[name].defaults, options) if (options.delay && typeof options.delay == 'number') { options.delay = { show: options.delay , hide: options.delay } } function get(ele) { var twipsy = $.data(ele, name) if (!twipsy) { twipsy = new Constructor(ele, $.fn.twipsy.elementOptions(ele, options)) $.data(ele, name, twipsy) } return twipsy } function enter() { var twipsy = get(this) twipsy.hoverState = 'in' if (!options.delay || !options.delay.show) { twipsy.show() } else { twipsy.fixTitle() setTimeout(function() { if (twipsy.hoverState == 'in') { twipsy.show() } }, options.delay.show) } } function leave() { var twipsy = get(this) twipsy.hoverState = 'out' if (!options.delay || !options.delay.hide) { twipsy.hide() } else { setTimeout(function() { if (twipsy.hoverState == 'out') { twipsy.hide() } }, options.delay.hide) } } if (!options.live) { this.each(function() { get(this) }) } if (options.trigger != 'manual') { binder = options.live ? 'live' : 'bind' eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus' eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur' this[binder](eventIn, enter)[binder](eventOut, leave) } return this } $.fn.twipsy.Twipsy = Twipsy $.fn.twipsy.defaults = { animate: true , delay: 0 , placement: 'above' , live: false , offset: 0 , trigger: 'hover' , title: 'title' , template: '' } $.fn.twipsy.rejectAttrOptions = [ 'title' ] $.fn.twipsy.elementOptions = function(ele, options) { var data = $(ele).data() , rejects = $.fn.twipsy.rejectAttrOptions , i = rejects.length while (i--) { delete data[rejects[i]] } return $.extend({}, options, data) } }( window.jQuery || window.ender )