From ba85a7bc4f2022854b645ee1d134bee762ad0e2c Mon Sep 17 00:00:00 2001 From: Erik Bernhardson Date: Mon, 30 Dec 2013 12:03:50 -0800 Subject: [PATCH] Respect sizing from user-supplied class A user-supplied class provided to tipsy that affects the height or width of the flyout breaks tipsys positioning. Adjust tipsy to apply the user-supplied class earlier so its css rules are taken into account during positioning. Also clean up trailing whitespace. Change-Id: I08854d80f57286129f19cb14566f84ed3c7fa21c --- resources/jquery.tipsy/jquery.tipsy.js | 76 ++++++++++++++------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/resources/jquery.tipsy/jquery.tipsy.js b/resources/jquery.tipsy/jquery.tipsy.js index 6e47c60404..f920e8b032 100644 --- a/resources/jquery.tipsy/jquery.tipsy.js +++ b/resources/jquery.tipsy/jquery.tipsy.js @@ -8,46 +8,53 @@ (function($) { - function maybeCall(thing, ctx) { - return (typeof thing == 'function') ? (thing.call(ctx)) : thing; - }; - + function maybeCall(thing, ctx) { + return (typeof thing == 'function') ? (thing.call(ctx)) : thing; + } + function fixTitle($ele) { if ($ele.attr('title') || typeof($ele.attr('original-title')) != 'string') { $ele.attr('original-title', $ele.attr('title') || '').removeAttr('title'); } } - + function Tipsy(element, options) { this.$element = $(element); this.options = options; this.enabled = true; fixTitle(this.$element); } - + Tipsy.prototype = { show: function() { var title = this.getTitle(); if (title && this.enabled) { var $tip = this.tip(); - + $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity if (this.options.className) { $tip.addClass(maybeCall(this.options.className, this.$element[0])); } $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body); - + var pos = $.extend({}, this.$element.offset(), { width: this.$element[0].offsetWidth, height: this.$element[0].offsetHeight }); - - var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight; + var gravity = (typeof this.options.gravity == 'function') ? this.options.gravity.call(this.$element[0]) : this.options.gravity; - + + // Attach css classes before checking height/width so they + // can be applied. + $tip.addClass('tipsy-' + gravity); + if (this.options.className) { + $tip.addClass(maybeCall(this.options.className, this.$element[0])); + } + + var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight; var tp; switch (gravity.charAt(0)) { case 'n': @@ -63,7 +70,7 @@ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; break; } - + if (gravity.length == 2) { if (gravity.charAt(1) == 'w') { if (this.options.center) { @@ -79,9 +86,8 @@ } } } - - $tip.css(tp).addClass('tipsy-' + gravity); - + $tip.css(tp); + if (this.options.fade) { $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}, 100); } else { @@ -89,7 +95,7 @@ } } }, - + hide: function() { if (this.options.fade) { this.tip().stop().fadeOut(100, function() { $(this).remove(); }); @@ -97,7 +103,7 @@ this.tip().remove(); } }, - + getTitle: function() { var title, $e = this.$element, o = this.options; fixTitle($e); @@ -109,14 +115,14 @@ title = ('' + title).replace(/(^\s*|\s*$)/, ""); return title || o.fallback; }, - + tip: function() { if (!this.$tip) { this.$tip = $('
').html('
'); } return this.$tip; }, - + validate: function() { if (!this.$element[0].parentNode) { this.hide(); @@ -124,22 +130,22 @@ this.options = null; } }, - + enable: function() { this.enabled = true; }, disable: function() { this.enabled = false; }, toggleEnabled: function() { this.enabled = !this.enabled; } }; - + $.fn.tipsy = function(options) { - + if (options === true) { return this.data('tipsy'); } else if (typeof options == 'string') { return this.data('tipsy')[options](); } - + options = $.extend({}, $.fn.tipsy.defaults, options); - + function get(ele) { var tipsy = $.data(ele, 'tipsy'); if (!tipsy) { @@ -148,7 +154,7 @@ } return tipsy; } - + function enter() { var tipsy = get(this); tipsy.hoverState = 'in'; @@ -158,7 +164,7 @@ setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); } }; - + function leave() { var tipsy = get(this); tipsy.hoverState = 'out'; @@ -168,20 +174,20 @@ setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); } }; - + if (!options.live) this.each(function() { get(this); }); - + if (options.trigger != 'manual') { var 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.tipsy.defaults = { className: null, delayIn: 0, @@ -197,7 +203,7 @@ title: 'title', trigger: 'hover' }; - + // Overwrite this method to provide options on a per-element basis. // For example, you could store the gravity in a 'tipsy-gravity' attribute: // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); @@ -205,13 +211,13 @@ $.fn.tipsy.elementOptions = function(ele, options) { return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; }; - + $.fn.tipsy.autoNS = function() { return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; }; - + $.fn.tipsy.autoWE = function() { return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; }; - + })(jQuery); -- 2.20.1