vendor/assets/javascripts/bootstrap/bootstrap-twipsy.js in jombo-0.0.1.beta10 vs vendor/assets/javascripts/bootstrap/bootstrap-twipsy.js in jombo-0.0.1.beta11

- old
+ new

@@ -1,9 +1,9 @@ /* ========================================================== * bootstrap-twipsy.js v2.0.0 * http://twitter.github.com/bootstrap/javascript.html#twipsy - * Adapted from the original jQuery.tipsy by Jason Frame + * Inspired by 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. @@ -24,63 +24,126 @@ /* TWIPSY PUBLIC CLASS DEFINITION * ============================== */ var Twipsy = function ( element, options ) { - this.$element = $(element) - this.options = options - this.enabled = true - this.fixTitle() + this.init('twipsy', element, options) } Twipsy.prototype = { constructor: Twipsy - , show: function() { - var pos + , init: function ( type, element, options ) { + var eventIn + , eventOut + + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.enabled = true + + if (this.options.trigger != 'manual') { + eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus' + eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur' + this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut, 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, options, this.$element.data()) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay + , hide: options.delay + } + } + + return options + } + + , enter: function ( e ) { + var self = $(e.currentTarget)[this.type](this._options).data(this.type) + + if (!self.options.delay || !self.options.delay.show) { + self.show() + } else { + self.hoverState = 'in' + 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 (!self.options.delay || !self.options.delay.hide) { + self.hide() + } else { + setTimeout(function() { + self.hoverState = 'out' + if (self.hoverState == 'out') { + self.hide() + } + }, self.options.delay.hide) + } + } + + , show: function () { + var $tip + , inside + , pos , actualWidth , actualHeight , placement - , $tip , tp if (this.hasContent() && this.enabled) { $tip = this.tip() this.setContent() - if (this.options.animate) { + if (this.options.animation) { $tip.addClass('fade') } + placement = typeof this.options.placement == 'function' ? + thing.call(this, $tip[0], this.$element[0]) : + this.options.placement + + inside = /in/.test(placement) + $tip .remove() .css({ top: 0, left: 0, display: 'block' }) - .prependTo(document.body) + .prependTo(inside ? this.$element : document.body) - pos = $.extend({}, this.$element.offset(), { - width: this.$element[0].offsetWidth - , height: this.$element[0].offsetHeight - }) + pos = this.getPosition(inside) 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} + switch (inside ? placement.split(' ')[1] : placement) { + case 'bottom': + tp = {top: pos.top + pos.height, 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} + 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 - this.options.offset} + 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 + this.options.offset} + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} break } $tip .css(tp) @@ -93,202 +156,115 @@ var $tip = this.tip() $tip.find('.twipsy-inner').html(this.getTitle()) $tip[0].className = 'twipsy' } - , hide: function() { + , hide: function () { var that = this , $tip = this.tip() $tip.removeClass('in') - function removeElement () { - $tip.remove() + function removeWithAnimation() { + var timeout = setTimeout(function () { + $tip.off($.support.transition.end).remove() + }, 500) + + $tip.one($.support.transition.end, function () { + clearTimeout(timeout) + $tip.remove() + }) } $.support.transition && this.$tip.hasClass('fade') ? - $tip.bind( $.support.transition.end, removeElement) : - removeElement() + removeWithAnimation() : + $tip.remove() } - , fixTitle: function() { + , 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() { + , getPosition: function (inside) { + return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), { + width: this.$element[0].offsetWidth + , height: this.$element[0].offsetHeight + }) + } + + , getTitle: function () { var title , $e = this.$element , o = this.options - this.fixTitle() + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) - 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.toString().replace(/(^\s*|\s*$)/, "") - title = ('' + title).replace(/(^\s*|\s*$)/, "") - - return title + return title } - , tip: function() { - return this.$tip = this.$tip || $('<div class="twipsy" />').html(this.options.template) + , tip: function () { + return this.$tip = this.$tip || $(this.options.template) } - , validate: function() { + , validate: function () { if (!this.$element[0].parentNode) { this.hide() this.$element = null this.options = null } } - , enable: function() { + , enable: function () { this.enabled = true } - , disable: function() { + , disable: function () { this.enabled = false } - , toggleEnabled: function() { + , 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 = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('twipsy') + , options = typeof option == 'object' && option + if (!data) $this.data('twipsy', (data = new Twipsy(this, options))) + if (typeof option == 'string') data[option]() + }) } - $.fn.twipsy.initWith = function (options, Base, name) { - var twipsy - , binder - , eventIn - , eventOut + $.fn.twipsy.Constructor = Twipsy - 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 Base(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 + animation: true , delay: 0 - , placement: 'above' - , live: false - , offset: 0 + , selector: false + , placement: 'top' , trigger: 'hover' - , title: 'title' - , template: '<div class="twipsy-arrow"></div><div class="twipsy-inner"></div>' + , title: '' + , template: '<div class="twipsy"><div class="twipsy-arrow"></div><div class="twipsy-inner"></div></div>' } - $.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 ) +}( window.jQuery ) \ No newline at end of file