src/pyams_skin/resources/js/ext/jquery-tipsy.js
changeset 566 a1707c607eec
parent 565 318533413200
child 567 bca1726b1d85
equal deleted inserted replaced
565:318533413200 566:a1707c607eec
     1 // tipsy, facebook style tooltips for jquery
       
     2 // version 1.0.0a
       
     3 // (c) 2008-2010 jason frame [jason@onehackoranother.com]
       
     4 // releated under the MIT license
       
     5 
       
     6 (function ($) {
       
     7 
       
     8 	function fixTitle($ele) {
       
     9 		if ($ele.attr('title') || typeof($ele.attr('original-title')) != 'string') {
       
    10 			$ele.attr('original-title', $ele.attr('title') || '').removeAttr('title');
       
    11 		}
       
    12 	}
       
    13 
       
    14 	function Tipsy(element, options) {
       
    15 		this.$element = $(element);
       
    16 		this.options = options;
       
    17 		this.enabled = true;
       
    18 		fixTitle(this.$element);
       
    19 	}
       
    20 
       
    21 	Tipsy.prototype = {
       
    22 		show: function () {
       
    23 			var title = this.getTitle();
       
    24 			if (title && this.enabled) {
       
    25 				var $tip = this.tip();
       
    26 
       
    27 				$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
       
    28 				$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
       
    29 				$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
       
    30 
       
    31 				var pos = $.extend({}, this.$element.offset(), {
       
    32 					width: this.$element[0].offsetWidth,
       
    33 					height: this.$element[0].offsetHeight
       
    34 				});
       
    35 
       
    36 				var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight;
       
    37 				var gravity = (typeof this.options.gravity == 'function')
       
    38 					? this.options.gravity.call(this.$element[0])
       
    39 					: this.options.gravity;
       
    40 				var offset = (typeof this.options.offset == 'function')
       
    41 					? this.options.offset.call(this.$element[0])
       
    42 					: this.options.offset;
       
    43 
       
    44 				var tp;
       
    45 				switch (gravity.charAt(0)) {
       
    46 					case 'n':
       
    47 						tp = {top: pos.top + pos.height + offset,
       
    48 							left: pos.left + pos.width / 2 - actualWidth / 2};
       
    49 						break;
       
    50 					case 's':
       
    51 						tp = {top: pos.top - actualHeight - offset,
       
    52 							left: pos.left + pos.width / 2 - actualWidth / 2};
       
    53 						break;
       
    54 					case 'e':
       
    55 						tp = {top: pos.top + pos.height / 2 - actualHeight / 2,
       
    56 							left: pos.left - actualWidth - offset};
       
    57 						break;
       
    58 					case 'w':
       
    59 						tp = {top: pos.top + pos.height / 2 - actualHeight / 2,
       
    60 							left: pos.left + pos.width + offset};
       
    61 						break;
       
    62 				}
       
    63 
       
    64 				if (gravity.length == 2) {
       
    65 					if (gravity.charAt(1) == 'w') {
       
    66 						tp.left = pos.width < 15 ? pos.left + (pos.width / 2) - 14
       
    67 							: pos.left + (pos.width / 2) - 14;
       
    68 					} else {
       
    69 						tp.left = pos.width < 15 ? pos.left + pos.width - actualWidth + (pos.width / 2) + 4
       
    70 							: pos.left + (pos.width / 2) - actualWidth + 14;
       
    71 					}
       
    72 				}
       
    73 
       
    74 				tp.left = Math.min(tp.left, $('html').width() - actualWidth - 10);
       
    75 
       
    76 				$tip.css(tp).addClass('tipsy-' + gravity);
       
    77 
       
    78 				if (this.options.fade) {
       
    79 					$tip.stop()
       
    80 						.css({
       
    81 								 opacity: 0,
       
    82 								 display: 'block',
       
    83 								 visibility: 'visible'
       
    84 							 })
       
    85 						.animate({
       
    86 									 opacity: this.options.opacity
       
    87 								 });
       
    88 				} else {
       
    89 					$tip.css({
       
    90 								 visibility: 'visible',
       
    91 								 opacity: this.options.opacity
       
    92 							 });
       
    93 				}
       
    94 			}
       
    95 		},
       
    96 
       
    97 		hide: function () {
       
    98 			if (this.options.fade) {
       
    99 				this.tip().stop().fadeOut(function () {
       
   100 					$(this).remove();
       
   101 				});
       
   102 			} else {
       
   103 				this.tip().remove();
       
   104 			}
       
   105 		},
       
   106 
       
   107 		getTitle: function () {
       
   108 			var title, $e = this.$element, o = this.options;
       
   109 			fixTitle($e);
       
   110 			var title, o = this.options;
       
   111 			if (typeof o.title == 'string') {
       
   112 				title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
       
   113 			} else if (typeof o.title == 'function') {
       
   114 				title = o.title.call($e[0]);
       
   115 			}
       
   116 			title = ('' + title).replace(/(^\s*|\s*$)/, "");
       
   117 			return title || o.fallback;
       
   118 		},
       
   119 
       
   120 		tip: function () {
       
   121 			if (!this.$tip) {
       
   122 				this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"/></div>');
       
   123 			}
       
   124 			return this.$tip;
       
   125 		},
       
   126 
       
   127 		validate: function () {
       
   128 			if (!this.$element[0].parentNode) {
       
   129 				this.hide();
       
   130 				this.$element = null;
       
   131 				this.options = null;
       
   132 			}
       
   133 		},
       
   134 
       
   135 		enable: function () {
       
   136 			this.enabled = true;
       
   137 		},
       
   138 		disable: function () {
       
   139 			this.enabled = false;
       
   140 		},
       
   141 		toggleEnabled: function () {
       
   142 			this.enabled = !this.enabled;
       
   143 		}
       
   144 	};
       
   145 
       
   146 	$.fn.tipsy = function (options) {
       
   147 
       
   148 		if (options === true) {
       
   149 			return this.data('tipsy');
       
   150 		} else if (typeof options == 'string') {
       
   151 			return this.data('tipsy')[options]();
       
   152 		}
       
   153 
       
   154 		options = $.extend({}, $.fn.tipsy.defaults, options);
       
   155 
       
   156 		function get(ele) {
       
   157 			var tipsy = $.data(ele, 'tipsy');
       
   158 			if (!tipsy) {
       
   159 				tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
       
   160 				$.data(ele, 'tipsy', tipsy);
       
   161 			}
       
   162 			return tipsy;
       
   163 		}
       
   164 
       
   165 		function enter() {
       
   166 			var tipsy = get(this);
       
   167 			tipsy.hoverState = 'in';
       
   168 			if (options.delayIn == 0) {
       
   169 				tipsy.show();
       
   170 			} else {
       
   171 				setTimeout(function () {
       
   172 					if (tipsy.hoverState == 'in') tipsy.show();
       
   173 				}, options.delayIn);
       
   174 			}
       
   175 		};
       
   176 
       
   177 		function leave() {
       
   178 			var tipsy = get(this);
       
   179 			tipsy.hoverState = 'out';
       
   180 			if (options.delayOut == 0) {
       
   181 				tipsy.hide();
       
   182 			} else {
       
   183 				setTimeout(function () {
       
   184 					if (tipsy.hoverState == 'out') tipsy.hide();
       
   185 				}, options.delayOut);
       
   186 			}
       
   187 		};
       
   188 
       
   189 		if (!options.live) this.each(function () {
       
   190 			get(this);
       
   191 		});
       
   192 
       
   193 		if (options.trigger != 'manual') {
       
   194 			var binder = options.live ? 'live' : 'bind',
       
   195 				eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
       
   196 				eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
       
   197 			this[binder](eventIn, enter)[binder](eventOut, leave);
       
   198 		}
       
   199 
       
   200 		return this;
       
   201 
       
   202 	};
       
   203 
       
   204 	$.fn.tipsy.defaults = {
       
   205 		delayIn: 0,
       
   206 		delayOut: 0,
       
   207 		fade: false,
       
   208 		fallback: '',
       
   209 		gravity: 'n',
       
   210 		html: false,
       
   211 		live: false,
       
   212 		offset: 0,
       
   213 		opacity: 0.8,
       
   214 		title: 'title',
       
   215 		trigger: 'hover'
       
   216 	};
       
   217 
       
   218 	// Overwrite this method to provide options on a per-element basis.
       
   219 	// For example, you could store the gravity in a 'tipsy-gravity' attribute:
       
   220 	// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
       
   221 	// (remember - do not modify 'options' in place!)
       
   222 	$.fn.tipsy.elementOptions = function (ele, options) {
       
   223 		return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
       
   224 	};
       
   225 
       
   226 	$.fn.tipsy.autoNS = function () {
       
   227 		return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
       
   228 	};
       
   229 
       
   230 	$.fn.tipsy.autoWE = function () {
       
   231 		return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
       
   232 	};
       
   233 
       
   234 })(jQuery);