/* global define:false, require:false */ define([ 'jquery', 'link' ], function($) { "use strict"; // Don't include this in the top-level define block so the build doesn't break. require(['link!../../static/projects/finch/css/tooltip'],function(){}); $.tooltip = $.fn.tooltip = function tooltip(opts) { if (this.jquery) { var tooltips = $([]); this.each(function(i,e){tooltips.push(tooltip($.extend({}, opts, {"anchor": e}))[0]);}); return tooltips; } opts = $.extend({}, { "content": " ", "style": "info", "position": "southeast", "offset": [5, 5], "anchor": "cursor" }, opts); if (typeof opts.anchor === "string" && opts.anchor !== "cursor") { return $(opts.anchor).tooltip(opts); } // if anchor is a DOM Element if (opts.anchor.nodeType) { opts.anchor = $(opts.anchor); } var $tt = $("
").addClass("w-tooltip").html(opts.content).appendTo($("body")); var $tooltipPoint = $("
  
"); if (opts.style) { $tt.addClass("w-tooltip-" + opts.style); } if (opts.hideicon) { $tt.addClass("w-tooltip-noicon"); } if (opts.anchor === "cursor") { $tt.css({"position": "fixed"}); $("body").bind("mousemove", function(e) { if (!$tt.hasClass("active")) { return; } // First, check if we should change position. var tooltipRightEdge = parseInt(e.clientX + $tt.width(), 10); // If this tooltip will go off the right of the screen, change its direction. // Give a decent buffer amount based on the width of the tooltip so it isn't // right up against the egde of the screen. var current_position = opts.position; if (tooltipRightEdge > ($("body").width() / 2) + $tt.width()) { current_position = "southwest"; } if (e.clientY > $("body").height() - $tt.width()*0.75) { current_position = current_position.replace("south", "north"); } if (current_position.match(/(top|north)/i)) { $tt.css({ bottom: ($(window).height() - e.clientY + opts.offset[1]) + "px", top: "" }); } else { $tt.css({ top: (e.clientY + opts.offset[1]) + "px", bottom: "" }); } if (current_position.match(/(left|west)/i)) { $tt.css({ right: ($(window).width() - e.clientX + opts.offset[0]) + "px", left: "" }); } else { $tt.css({ left: (e.clientX + opts.offset[0]) + "px", right: "" }); } }); } else if (opts.showTip) { $tt.append($tooltipPoint); opts.tipOffset = opts.tipOffset || [0, 0]; } $tt.reposition = function reposition() { var newPosition = 0; var oldPosition = 0; if (opts.anchor === "cursor") { // nothing to do return; } else if (opts.anchor && opts.anchor.constructor === Array) { $tt.css({"position": "absolute"}); if (opts.position.match(/(top|north)/i)) { $tt.css("bottom", ($("body").height() - opts.anchor[1] + opts.offset[1]) + "px"); } else { $tt.css("top", (opts.anchor[1] + opts.offset[1]) + "px"); } if (opts.position.match(/(left|west)/i)) { $tt.css("right", ($("body").width() - opts.anchor[0] + opts.offset[0]) + "px"); } else { $tt.css("left", (opts.anchor[0] + opts.offset[0]) + "px"); } if (opts.showTip) { repositionTip(0, opts); } } else if (opts.anchor && opts.anchor.jquery) { $tt.css({"position": "absolute"}); var anchorPosition = opts.anchor.offset(); if (opts.position.match(/(top|north)/i)) { $tt.css("bottom", ($("body").height() - anchorPosition.top + opts.anchor.outerHeight() + opts.offset[1]) + "px"); } else { $tt.css("top", (anchorPosition.top + opts.anchor.outerHeight() + opts.offset[1]) + "px"); } if (opts.position.match(/(left|west)/i)) { $tt.css("right", $("body").width() - anchorPosition.left + opts.offset[0] + "px"); } else if (opts.position.match(/center/i)) { $tt.css("left", anchorPosition.left - ($tt.outerWidth()/2) + opts.offset[0] + "px"); } else { // Define minimum and maximum pixel location for bubble left. var minLeft = Math.abs(parseInt($tt.css("margin-left"), 10)); var maxLeft = $("body").width() - minLeft; // Calculate the new position of the tooltip and save a copy for later. newPosition = anchorPosition.left + opts.anchor.outerWidth() + opts.offset[0]; oldPosition = newPosition; // If need be, reposition. if (newPosition < minLeft) { newPosition = minLeft; } else if (newPosition > maxLeft) { newPosition = maxLeft; } // Apply the positioning to the tooltip. $tt.css("left", newPosition + "px"); } if (opts.showTip) { repositionTip(newPosition - oldPosition, opts); } } else { throw (["Unsupported tooltip definition", opts]); } }; $tt.updateOffset = function updateOffset(offset) { if (opts.offset !== offset) { opts.offset = offset; $tt.reposition(); } }; var repositionTip = function (shiftAmount, opts) { var ttWidth = $tt.width(), ttPaddingLeft = parseInt($tt.css("padding-left"), 10), anchorLeft = opts.anchor.offset().left, ttLeft = parseInt($tt.css("left"), 10), iconWidth = opts.anchor.width(), tipPosition = anchorLeft - ttLeft + (iconWidth/4); // If the tooltip is too far to the right, make it point on the corner. if (tipPosition > ttWidth + ttPaddingLeft) { tipPosition = ttWidth + ttPaddingLeft; } // Apply the positioning to the tooltip tip. $tooltipPoint.css("left", tipPosition + "px"); }; var windowResizeHandler = function(){ $tt.reposition(); }; $(window).resize(windowResizeHandler); $tt.reposition(); return $tt; }; return $.tooltip; });