1;(function ($, window) { 2 "use strict"; 3 4 var $body, 5 $tipper, 6 pos; 7 8 /** 9 * @options 10 * @param delay [int] <0> "Hover delay" 11 * @param direction [string] <'top'> "Tooltip direction" 12 * @param follow [boolean] <false> "Flag to follow mouse" 13 * @param formatter [function] <$.noop> "Text format function" 14 * @param margin [int] <15> "Tooltip margin" 15 * @param match [boolean] <false> "Flag to match mouse position" 16 */ 17 var options = { 18 delay: 0, 19 direction: "top", 20 follow: false, 21 formatter: $.noop, 22 margin: 15, 23 match: false 24 }; 25 26 var pub = { 27 28 /** 29 * @method 30 * @name defaults 31 * @description Sets default plugin options 32 * @param opts [object] <{}> "Options object" 33 * @example $.tipper("defaults", opts); 34 */ 35 defaults: function(opts) { 36 options = $.extend(options, opts || {}); 37 return $(this); 38 }, 39 40 /** 41 * @method 42 * @name destroy 43 * @description Removes instance of plugin 44 * @example $(".target").tipper("destroy"); 45 */ 46 destroy: function() { 47 return $(this).trigger("mouseleave.tipper") 48 .off(".tipper") 49 .removeClass("tipper-attached"); 50 } 51 }; 52 53 54 /** 55 * @method private 56 * @name _init 57 * @description Initializes plugin 58 * @param opts [object] "Initialization options" 59 */ 60 function _init(opts) { 61 options.formatter = _format; 62 63 $body = $("body"); 64 65 return $(this).not(".tipper-attached") 66 .addClass("tipper-attached") 67 .on("mouseenter.tipper", $.extend({}, options, opts || {}), _build); 68 } 69 70 /** 71 * @method private 72 * @name _build 73 * @description Builds target instance 74 * @param e [object] "Event data" 75 */ 76 function _build(e) { 77 var $target = $(this), 78 data = $.extend(true, {}, e.data, $target.data("tipper-options")); 79 80 data.$target = $target; 81 pos = { 82 left: e.pageX, 83 top: e.pageY 84 }; 85 86 if (data.delay) { 87 _clearTimer(data.timer); 88 89 data.timer = setTimeout(function() { 90 _doBuild(data.$target, data); 91 }, data.delay); 92 } else { 93 _doBuild(data.$target, data); 94 } 95 96 data.$target.one("mouseleave.tipper", data, _onMouseOut); 97 98 if (!data.follow && data.match) { 99 data.$target.on("mousemove.tipper", data, _onMouseMove) 100 .trigger("mousemove"); 101 } 102 } 103 104 /** 105 * @method private 106 * @name _doBuild 107 * @description Builds target instance 108 * @param $target [jQuery object] "Target element" 109 * @param data [object] "Instance data" 110 */ 111 function _doBuild($target, data) { 112 var html = ''; 113 114 html += '<div class="tipper ' + data.direction + '">'; 115 html += '<div class="tipper-content">'; 116 html += data.formatter.apply($body, [$target]); 117 html += '<span class="tipper-caret"></span>'; 118 html += '</div>'; 119 html += '</div>'; 120 121 data.$target = $target; 122 data.$tipper = $(html); 123 124 $body.append(data.$tipper); 125 126 data.$content = data.$tipper.find(".tipper-content"); 127 data.$caret = data.$tipper.find(".tipper-caret"); 128 data.offset = $target.offset(); 129 data.height = $target.outerHeight(); 130 data.width = $target.outerWidth(); 131 132 data.tipperPos = {}; 133 data.caretPos = {}; 134 data.contentPos = {}; 135 136 var caretHeight = data.$caret.outerHeight(true), 137 caretWidth = data.$caret.outerWidth(true), 138 contentHeight = data.$content.outerHeight(true), 139 contentWidth = data.$content.outerWidth(true); 140 141 // position content 142 if (data.direction === "right" || data.direction === "left") { 143 data.caretPos.top = (contentHeight - caretHeight) / 2; 144 data.contentPos.top = -contentHeight / 2; 145 if (data.direction === "right") { 146 data.contentPos.left = data.margin; 147 } else if (data.direction === "left") { 148 data.contentPos.left = -(contentWidth + data.margin); 149 } 150 } else { 151 data.caretPos.left = (contentWidth - caretWidth) / 2; 152 data.contentPos.left = -contentWidth / 2; 153 154 if (data.direction === "bottom") { 155 data.contentPos.top = data.margin; 156 } else if (data.direction === "top") { 157 data.contentPos.top = -(contentHeight + data.margin); 158 } 159 } 160 161 // modify dom 162 data.$content.css(data.contentPos); 163 data.$caret.css(data.caretPos); 164 165 // Position tipper 166 if (data.follow) { 167 data.$target.on("mousemove.tipper", data, _onMouseMove) 168 .trigger("mousemove"); 169 } else if (data.match) { 170 if (data.direction === "right" || data.direction === "left") { 171 data.tipperPos.top = pos.top; 172 if (data.direction === "right") { 173 data.tipperPos.left = data.offset.left + data.width; 174 } else if (data.direction === "left") { 175 data.tipperPos.left = data.offset.left; 176 } 177 } else { 178 data.tipperPos.left = pos.left; 179 if (data.direction === "bottom") { 180 data.tipperPos.top = data.offset.top + data.height; 181 } else if (data.direction === "top") { 182 data.tipperPos.top = data.offset.top; 183 } 184 } 185 186 data.$tipper.css(data.tipperPos); 187 } else { 188 if (data.direction === "right" || data.direction === "left") { 189 data.tipperPos.top = data.offset.top + (data.height / 2); 190 if (data.direction === "right") { 191 data.tipperPos.left = data.offset.left + data.width; 192 } else if (data.direction === "left") { 193 data.tipperPos.left = data.offset.left; 194 } 195 } else {
196 data.tipperPos.left = data.offset.left + (data.width / 2); 197 if (data.direction === "bottom") { 198 data.tipperPos.top = data.offset.top + data.height; 199 } else if (data.direction === "top") { 200 data.tipperPos.top = data.offset.top; 201 } 202 } 203 204 data.$tipper.css(data.tipperPos); 205 } 206 } 207 208 /** 209 * @method private 210 * @name _format 211 * @description Formats tooltip text 212 * @param $target [jQuery object] "Target element" 213 * @return [string] "Formatted text" 214 */ 215 function _format($target) { 216 return $target.data("title"); 217 } 218 219 /** 220 * @method private 221 * @name _onMouseMove 222 * @description Handles mousemove event 223 * @param e [object] "Event data" 224 */ 225 function _onMouseMove(e) { 226 var data = e.data; 227 228 pos = { 229 left: e.pageX, 230 top: e.pageY 231 }; 232 233 if (data.follow && typeof data.$tipper !== "undefined") { 234 data.$tipper.css({ left: pos.left, top: pos.top }); 235 } 236 } 237 238 /** 239 * @method private 240 * @name _onMouseOut 241 * @description Handles mouseout event 242 * @param e [object] "Event data" 243 */ 244 function _onMouseOut(e) { 245 var data = e.data; 246 247 _clearTimer(data.timer); 248 249 if (typeof data.$tipper !== "undefined") { 250 data.$tipper.remove(); 251 data.$target.off("mousemove.tipper mouseleave.tipper"); 252 } 253 } 254 255 /** 256 * @method private 257 * @name _clearTimer 258 * @description Clears active timer 259 * @param timer [] "Timer" 260 */ 261 function _clearTimer(timer) { 262 if (timer) { 263 clearTimeout(timer); 264 timer = null; 265 } 266 } 267 268 $.fn.tipper = function(method) { 269 if (pub[method]) { 270 return pub[method].apply(this, Array.prototype.slice.call(arguments, 1)); 271 } else if (typeof method === 'object' || !method) { 272 return _init.apply(this, arguments); 273 } 274 return this; 275 }; 276 277 $.tipper = function(method) { 278 if (method === "defaults") { 279 pub.defaults.apply(this, Array.prototype.slice.call(arguments, 1)); 280 } 281 }; 282})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.