﻿/*
* @name BeautyTips
* @desc a tooltips/baloon-help plugin for jQuery
*
* @author Jeff Robbins - Lullabot - http://www.lullabot.com
* @version 0.9.5-rc1  (5/20/2009)
*/
jQuery.bt = { version: "0.9.5-rc1" }; (function ($) { jQuery.fn.bt = function (content, options) { if (typeof content != "string") { var contentSelect = true; options = content; content = false; } else { var contentSelect = false; } if (jQuery.fn.hoverIntent && jQuery.bt.defaults.trigger == "hover") { jQuery.bt.defaults.trigger = "hoverIntent"; } return this.each(function (index) { var opts = jQuery.extend(false, jQuery.bt.defaults, jQuery.bt.options, options); opts.spikeLength = numb(opts.spikeLength); opts.spikeGirth = numb(opts.spikeGirth); opts.overlap = numb(opts.overlap); var ajaxTimeout = false; if (opts.killTitle) { $(this).find("[title]").andSelf().each(function () { if (!$(this).attr("bt-xTitle")) { $(this).attr("bt-xTitle", $(this).attr("title")).attr("title", ""); } }); } if (typeof opts.trigger == "string") { opts.trigger = [opts.trigger]; } if (opts.trigger[0] == "hoverIntent") { var hoverOpts = jQuery.extend(opts.hoverIntentOpts, { over: function () { this.btOn(); }, out: function () { this.btOff(); } }); $(this).hoverIntent(hoverOpts); } else { if (opts.trigger[0] == "hover") { $(this).hover(function () { this.btOn(); }, function () { this.btOff(); }); } else { if (opts.trigger[0] == "now") { if ($(this).hasClass("bt-active")) { this.btOff(); } else { this.btOn(); } } else { if (opts.trigger[0] == "none") { } else { if (opts.trigger.length > 1 && opts.trigger[0] != opts.trigger[1]) { $(this).bind(opts.trigger[0], function () { this.btOn(); }).bind(opts.trigger[1], function () { this.btOff(); }); } else { $(this).bind(opts.trigger[0], function () { if ($(this).hasClass("bt-active")) { this.btOff(); } else { this.btOn(); } }); } } } } } this.btOn = function () { if (typeof $(this).data("bt-box") == "object") { this.btOff(); } opts.preBuild.apply(this); $(jQuery.bt.vars.closeWhenOpenStack).btOff(); $(this).addClass("bt-active " + opts.activeClass); if (contentSelect && opts.ajaxPath == null) { if (opts.killTitle) { $(this).attr("title", $(this).attr("bt-xTitle")); } content = $.isFunction(opts.contentSelector) ? opts.contentSelector.apply(this) : eval(opts.contentSelector); if (opts.killTitle) { $(this).attr("title", ""); } } if (opts.ajaxPath != null && content == false) { if (typeof opts.ajaxPath == "object") { var url = eval(opts.ajaxPath[0]); url += opts.ajaxPath[1] ? " " + opts.ajaxPath[1] : ""; } else { var url = opts.ajaxPath; } var off = url.indexOf(" "); if (off >= 0) { var selector = url.slice(off, url.length); url = url.slice(0, off); } var cacheData = opts.ajaxCache ? $(document.body).data("btCache-" + url.replace(/\./g, "")) : null; if (typeof cacheData == "string") { content = selector ? $("<div/>").append(cacheData.replace(/<script(.|\s)*?\/script>/g, "")).find(selector) : cacheData; } else { var target = this; var ajaxOpts = jQuery.extend(false, { type: opts.ajaxType, data: opts.ajaxData, cache: opts.ajaxCache, url: url, complete: function (XMLHttpRequest, textStatus) { if (textStatus == "success" || textStatus == "notmodified") { if (opts.ajaxCache) { $(document.body).data("btCache-" + url.replace(/\./g, ""), XMLHttpRequest.responseText); } ajaxTimeout = false; content = selector ? $("<div/>").append(XMLHttpRequest.responseText.replace(/<script(.|\s)*?\/script>/g, "")).find(selector) : XMLHttpRequest.responseText; } else { if (textStatus == "timeout") { ajaxTimeout = true; } content = opts.ajaxError.replace(/%error/g, XMLHttpRequest.statusText); } if ($(target).hasClass("bt-active")) { target.btOn(); } } }, opts.ajaxOpts); jQuery.ajax(ajaxOpts); content = opts.ajaxLoading; } } var shadowMarginX = 0; var shadowMarginY = 0; var shadowShiftX = 0; var shadowShiftY = 0; if (opts.shadow && !shadowSupport()) { opts.shadow = false; jQuery.extend(opts, opts.noShadowOpts); } if (opts.shadow) { if (opts.shadowBlur > Math.abs(opts.shadowOffsetX)) { shadowMarginX = opts.shadowBlur * 2; } else { shadowMarginX = opts.shadowBlur + Math.abs(opts.shadowOffsetX); } shadowShiftX = (opts.shadowBlur - opts.shadowOffsetX) > 0 ? opts.shadowBlur - opts.shadowOffsetX : 0; if (opts.shadowBlur > Math.abs(opts.shadowOffsetY)) { shadowMarginY = opts.shadowBlur * 2; } else { shadowMarginY = opts.shadowBlur + Math.abs(opts.shadowOffsetY); } shadowShiftY = (opts.shadowBlur - opts.shadowOffsetY) > 0 ? opts.shadowBlur - opts.shadowOffsetY : 0; } if (opts.offsetParent) { var offsetParent = $(opts.offsetParent); var offsetParentPos = offsetParent.offset(); var pos = $(this).offset(); var top = numb(pos.top) - numb(offsetParentPos.top) + numb($(this).css("margin-top")) - shadowShiftY; var left = numb(pos.left) - numb(offsetParentPos.left) + numb($(this).css("margin-left")) - shadowShiftX; } else { var offsetParent = ($(this).css("position") == "absolute") ? $(this).parents().eq(0).offsetParent() : $(this).offsetParent(); var pos = $(this).btPosition(); var top = numb(pos.top) + numb($(this).css("margin-top")) - shadowShiftY; var left = numb(pos.left) + numb($(this).css("margin-left")) - shadowShiftX; } var width = $(this).btOuterWidth(); var height = $(this).outerHeight(); if (typeof content == "object") { var original = content; var clone = $(original).clone(true).show(); var origClones = $(original).data("bt-clones") || []; origClones.push(clone); $(original).data("bt-clones", origClones); $(clone).data("bt-orig", original); $(this).data("bt-content-orig", { original: original, clone: clone }); content = clone; } if (typeof content == "null" || content == "") { return; } var $text = $('<div class="bt-content"></div>').append(content).css({ padding: opts.padding, position: "absolute", width: (opts.shrinkToFit ? "auto" : opts.width), zIndex: opts.textzIndex, left: shadowShiftX, top: shadowShiftY }).css(opts.cssStyles); var $box = $('<div class="bt-wrapper"></div>').append($text).addClass(opts.cssClass).css({ position: "absolute", width: opts.width, zIndex: opts.wrapperzIndex, visibility: "hidden" }).appendTo(offsetParent); if (jQuery.fn.bgiframe) { $text.bgiframe(); $box.bgiframe(); } $(this).data("bt-box", $box); var scrollTop = numb($(document).scrollTop()); var scrollLeft = numb($(document).scrollLeft()); var docWidth = numb($(window).width()); var docHeight = numb($(window).height()); var winRight = scrollLeft + docWidth; var winBottom = scrollTop + docHeight; var space = new Object(); var thisOffset = $(this).offset(); space.top = thisOffset.top - scrollTop; space.bottom = docHeight - ((thisOffset + height) - scrollTop); space.left = thisOffset.left - scrollLeft; space.right = docWidth - ((thisOffset.left + width) - scrollLeft); var textOutHeight = numb($text.outerHeight()); var textOutWidth = numb($text.btOuterWidth()); if (opts.positions.constructor == String) { opts.positions = opts.positions.replace(/ /, "").split(","); } if (opts.positions[0] == "most") { var position = "top"; for (var pig in space) { position = space[pig] > space[position] ? pig : position; } } else { for (var x in opts.positions) { var position = opts.positions[x]; if ((position == "left" || position == "right") && space[position] > textOutWidth + opts.spikeLength) { break; } else { if ((position == "top" || position == "bottom") && space[position] > textOutHeight + opts.spikeLength) { break; } } } } var horiz = left + ((width - textOutWidth) * 0.5); var vert = top + ((height - textOutHeight) * 0.5); var points = new Array(); var textTop, textLeft, textRight, textBottom, textTopSpace, textBottomSpace, textLeftSpace, textRightSpace, crossPoint, textCenter, spikePoint; switch (position) { case "top": $text.css("margin-bottom", opts.spikeLength + "px"); $box.css({ top: (top - $text.outerHeight(true)) + opts.overlap, left: horiz }); textRightSpace = (winRight - opts.windowMargin) - ($text.offset().left + $text.btOuterWidth(true)); var xShift = shadowShiftX; if (textRightSpace < 0) { $box.css("left", (numb($box.css("left")) + textRightSpace) + "px"); xShift -= textRightSpace; } textLeftSpace = ($text.offset().left + numb($text.css("margin-left"))) - (scrollLeft + opts.windowMargin); if (textLeftSpace < 0) { $box.css("left", (numb($box.css("left")) - textLeftSpace) + "px"); xShift += textLeftSpace; } textTop = $text.btPosition().top + numb($text.css("margin-top")); textLeft = $text.btPosition().left + numb($text.css("margin-left")); textRight = textLeft + $text.btOuterWidth(); textBottom = textTop + $text.outerHeight(); textCenter = { x: textLeft + ($text.btOuterWidth() * opts.centerPointX), y: textTop + ($text.outerHeight() * opts.centerPointY) }; points[points.length] = spikePoint = { y: textBottom + opts.spikeLength, x: ((textRight - textLeft) * 0.5) + xShift, type: "spike" }; crossPoint = findIntersectX(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textBottom); crossPoint.x = crossPoint.x < textLeft + opts.spikeGirth / 2 + opts.cornerRadius ? textLeft + opts.spikeGirth / 2 + opts.cornerRadius : crossPoint.x; crossPoint.x = crossPoint.x > (textRight - opts.spikeGirth / 2) - opts.cornerRadius ? (textRight - opts.spikeGirth / 2) - opts.CornerRadius : crossPoint.x; points[points.length] = { x: crossPoint.x - (opts.spikeGirth / 2), y: textBottom, type: "join" }; points[points.length] = { x: textLeft, y: textBottom, type: "corner" }; points[points.length] = { x: textLeft, y: textTop, type: "corner" }; points[points.length] = { x: textRight, y: textTop, type: "corner" }; points[points.length] = { x: textRight, y: textBottom, type: "corner" }; points[points.length] = { x: crossPoint.x + (opts.spikeGirth / 2), y: textBottom, type: "join" }; points[points.length] = spikePoint; break; case "left": $text.css("margin-right", opts.spikeLength + "px"); $box.css({ top: vert + "px", left: ((left - $text.btOuterWidth(true)) + opts.overlap) + "px" }); textBottomSpace = (winBottom - opts.windowMargin) - ($text.offset().top + $text.outerHeight(true)); var yShift = shadowShiftY; if (textBottomSpace < 0) { $box.css("top", (numb($box.css("top")) + textBottomSpace) + "px"); yShift -= textBottomSpace; } textTopSpace = ($text.offset().top + numb($text.css("margin-top"))) - (scrollTop + opts.windowMargin); if (textTopSpace < 0) { $box.css("top", (numb($box.css("top")) - textTopSpace) + "px"); yShift += textTopSpace; } textTop = $text.btPosition().top + numb($text.css("margin-top")); textLeft = $text.btPosition().left + numb($text.css("margin-left")); textRight = textLeft + $text.btOuterWidth(); textBottom = textTop + $text.outerHeight(); textCenter = { x: textLeft + ($text.btOuterWidth() * opts.centerPointX), y: textTop + ($text.outerHeight() * opts.centerPointY) }; points[points.length] = spikePoint = { x: textRight + opts.spikeLength, y: ((textBottom - textTop) * 0.5) + yShift, type: "spike" }; crossPoint = findIntersectY(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textRight); crossPoint.y = crossPoint.y < textTop + opts.spikeGirth / 2 + opts.cornerRadius ? textTop + opts.spikeGirth / 2 + opts.cornerRadius : crossPoint.y; crossPoint.y = crossPoint.y > (textBottom - opts.spikeGirth / 2) - opts.cornerRadius ? (textBottom - opts.spikeGirth / 2) - opts.cornerRadius : crossPoint.y; points[points.length] = { x: textRight, y: crossPoint.y + opts.spikeGirth / 2, type: "join" }; points[points.length] = { x: textRight, y: textBottom, type: "corner" }; points[points.length] = { x: textLeft, y: textBottom, type: "corner" }; points[points.length] = { x: textLeft, y: textTop, type: "corner" }; points[points.length] = { x: textRight, y: textTop, type: "corner" }; points[points.length] = { x: textRight, y: crossPoint.y - opts.spikeGirth / 2, type: "join" }; points[points.length] = spikePoint; break; case "bottom": $text.css("margin-top", opts.spikeLength + "px"); $box.css({ top: (top + height) - opts.overlap, left: horiz }); textRightSpace = (winRight - opts.windowMargin) - ($text.offset().left + $text.btOuterWidth(true)); var xShift = shadowShiftX; if (textRightSpace < 0) { $box.css("left", (numb($box.css("left")) + textRightSpace) + "px"); xShift -= textRightSpace; } textLeftSpace = ($text.offset().left + numb($text.css("margin-left"))) - (scrollLeft + opts.windowMargin); if (textLeftSpace < 0) { $box.css("left", (numb($box.css("left")) - textLeftSpace) + "px"); xShift += textLeftSpace; } textTop = $text.btPosition().top + numb($text.css("margin-top")); textLeft = $text.btPosition().left + numb($text.css("margin-left")); textRight = textLeft + $text.btOuterWidth(); textBottom = textTop + $text.outerHeight(); textCenter = { x: textLeft + ($text.btOuterWidth() * opts.centerPointX), y: textTop + ($text.outerHeight() * opts.centerPointY) }; points[points.length] = spikePoint = { x: ((textRight - textLeft) * 0.5) + xShift, y: shadowShiftY, type: "spike" }; crossPoint = findIntersectX(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textTop); crossPoint.x = crossPoint.x < textLeft + opts.spikeGirth / 2 + opts.cornerRadius ? textLeft + opts.spikeGirth / 2 + opts.cornerRadius : crossPoint.x; crossPoint.x = crossPoint.x > (textRight - opts.spikeGirth / 2) - opts.cornerRadius ? (textRight - opts.spikeGirth / 2) - opts.cornerRadius : crossPoint.x; points[points.length] = { x: crossPoint.x + opts.spikeGirth / 2, y: textTop, type: "join" }; points[points.length] = { x: textRight, y: textTop, type: "corner" }; points[points.length] = { x: textRight, y: textBottom, type: "corner" }; points[points.length] = { x: textLeft, y: textBottom, type: "corner" }; points[points.length] = { x: textLeft, y: textTop, type: "corner" }; points[points.length] = { x: crossPoint.x - (opts.spikeGirth / 2), y: textTop, type: "join" }; points[points.length] = spikePoint; break; case "right": $text.css("margin-left", (opts.spikeLength + "px")); $box.css({ top: vert + "px", left: ((left + width) - opts.overlap) + "px" }); textBottomSpace = (winBottom - opts.windowMargin) - ($text.offset().top + $text.outerHeight(true)); var yShift = shadowShiftY; if (textBottomSpace < 0) { $box.css("top", (numb($box.css("top")) + textBottomSpace) + "px"); yShift -= textBottomSpace; } textTopSpace = ($text.offset().top + numb($text.css("margin-top"))) - (scrollTop + opts.windowMargin); if (textTopSpace < 0) { $box.css("top", (numb($box.css("top")) - textTopSpace) + "px"); yShift += textTopSpace; } textTop = $text.btPosition().top + numb($text.css("margin-top")); textLeft = $text.btPosition().left + numb($text.css("margin-left")); textRight = textLeft + $text.btOuterWidth(); textBottom = textTop + $text.outerHeight(); textCenter = { x: textLeft + ($text.btOuterWidth() * opts.centerPointX), y: textTop + ($text.outerHeight() * opts.centerPointY) }; points[points.length] = spikePoint = { x: shadowShiftX, y: ((textBottom - textTop) * 0.5) + yShift, type: "spike" }; crossPoint = findIntersectY(spikePoint.x, spikePoint.y, textCenter.x, textCenter.y, textLeft); crossPoint.y = crossPoint.y < textTop + opts.spikeGirth / 2 + opts.cornerRadius ? textTop + opts.spikeGirth / 2 + opts.cornerRadius : crossPoint.y; crossPoint.y = crossPoint.y > (textBottom - opts.spikeGirth / 2) - opts.cornerRadius ? (textBottom - opts.spikeGirth / 2) - opts.cornerRadius : crossPoint.y; points[points.length] = { x: textLeft, y: crossPoint.y - opts.spikeGirth / 2, type: "join" }; points[points.length] = { x: textLeft, y: textTop, type: "corner" }; points[points.length] = { x: textRight, y: textTop, type: "corner" }; points[points.length] = { x: textRight, y: textBottom, type: "corner" }; points[points.length] = { x: textLeft, y: textBottom, type: "corner" }; points[points.length] = { x: textLeft, y: crossPoint.y + opts.spikeGirth / 2, type: "join" }; points[points.length] = spikePoint; break; } var canvas = document.createElement("canvas"); $(canvas).attr("width", (numb($text.btOuterWidth(true)) + opts.strokeWidth * 2 + shadowMarginX)).attr("height", (numb($text.outerHeight(true)) + opts.strokeWidth * 2 + shadowMarginY)).appendTo($box).css({ position: "absolute", zIndex: opts.boxzIndex }); if (typeof G_vmlCanvasManager != "undefined") { canvas = G_vmlCanvasManager.initElement(canvas); } if (opts.cornerRadius > 0) { var newPoints = new Array(); var newPoint; for (var i = 0; i < points.length; i++) { if (points[i].type == "corner") { newPoint = betweenPoint(points[i], points[(i - 1) % points.length], opts.cornerRadius); newPoint.type = "arcStart"; newPoints[newPoints.length] = newPoint; newPoints[newPoints.length] = points[i]; newPoint = betweenPoint(points[i], points[(i + 1) % points.length], opts.cornerRadius); newPoint.type = "arcEnd"; newPoints[newPoints.length] = newPoint; } else { newPoints[newPoints.length] = points[i]; } } points = newPoints; } var ctx = canvas.getContext("2d"); if (opts.shadow && opts.shadowOverlap !== true) { var shadowOverlap = numb(opts.shadowOverlap); switch (position) { case "top": if (opts.shadowOffsetX + opts.shadowBlur - shadowOverlap > 0) { $box.css("top", (numb($box.css("top")) - (opts.shadowOffsetX + opts.shadowBlur - shadowOverlap))); } break; case "right": if (shadowShiftX - shadowOverlap > 0) { $box.css("left", (numb($box.css("left")) + shadowShiftX - shadowOverlap)); } break; case "bottom": if (shadowShiftY - shadowOverlap > 0) { $box.css("top", (numb($box.css("top")) + shadowShiftY - shadowOverlap)); } break; case "left": if (opts.shadowOffsetY + opts.shadowBlur - shadowOverlap > 0) { $box.css("left", (numb($box.css("left")) - (opts.shadowOffsetY + opts.shadowBlur - shadowOverlap))); } break; } } drawIt.apply(ctx, [points], opts.strokeWidth); ctx.fillStyle = opts.fill; if (opts.shadow) { ctx.shadowOffsetX = opts.shadowOffsetX; ctx.shadowOffsetY = opts.shadowOffsetY; ctx.shadowBlur = opts.shadowBlur; ctx.shadowColor = opts.shadowColor; } ctx.closePath(); ctx.fill(); if (opts.strokeWidth > 0) { ctx.shadowColor = "rgba(0, 0, 0, 0)"; ctx.lineWidth = opts.strokeWidth; ctx.strokeStyle = opts.strokeStyle; ctx.beginPath(); drawIt.apply(ctx, [points], opts.strokeWidth); ctx.closePath(); ctx.stroke(); } opts.preShow.apply(this, [$box[0]]); $box.css({ display: "none", visibility: "visible" }); opts.showTip.apply(this, [$box[0]]); if (opts.overlay) { var overlay = $('<div class="bt-overlay"></div>').css({ position: "absolute", backgroundColor: "blue", top: top, left: left, width: width, height: height, opacity: ".2" }).appendTo(offsetParent); $(this).data("overlay", overlay); } if ((opts.ajaxPath != null && opts.ajaxCache == false) || ajaxTimeout) { content = false; } if (opts.clickAnywhereToClose) { jQuery.bt.vars.clickAnywhereStack.push(this); $(document).click(jQuery.bt.docClick); } if (opts.closeWhenOthersOpen) { jQuery.bt.vars.closeWhenOpenStack.push(this); } opts.postShow.apply(this, [$box[0]]); }; this.btOff = function () { var box = $(this).data("bt-box"); opts.preHide.apply(this, [box]); var i = this; i.btCleanup = function () { var box = $(i).data("bt-box"); var contentOrig = $(i).data("bt-content-orig"); var overlay = $(i).data("bt-overlay"); if (typeof box == "object") { $(box).remove(); $(i).removeData("bt-box"); } if (typeof contentOrig == "object") { var clones = $(contentOrig.original).data("bt-clones"); $(contentOrig).data("bt-clones", arrayRemove(clones, contentOrig.clone)); } if (typeof overlay == "object") { $(overlay).remove(); $(i).removeData("bt-overlay"); } jQuery.bt.vars.clickAnywhereStack = arrayRemove(jQuery.bt.vars.clickAnywhereStack, i); jQuery.bt.vars.closeWhenOpenStack = arrayRemove(jQuery.bt.vars.closeWhenOpenStack, i); $(i).removeClass("bt-active " + opts.activeClass); opts.postHide.apply(i); }; opts.hideTip.apply(this, [box, i.btCleanup]); }; var refresh = this.btRefresh = function () { this.btOff(); this.btOn(); }; }); function drawIt(points, strokeWidth) { this.moveTo(points[0].x, points[0].y); for (i = 1; i < points.length; i++) { if (points[i - 1].type == "arcStart") { this.quadraticCurveTo(round5(points[i].x, strokeWidth), round5(points[i].y, strokeWidth), round5(points[(i + 1) % points.length].x, strokeWidth), round5(points[(i + 1) % points.length].y, strokeWidth)); i++; } else { this.lineTo(round5(points[i].x, strokeWidth), round5(points[i].y, strokeWidth)); } } } function round5(num, strokeWidth) { var ret; strokeWidth = numb(strokeWidth); if (strokeWidth % 2) { ret = num; } else { ret = Math.round(num - 0.5) + 0.5; } return ret; } function numb(num) { return parseInt(num) || 0; } function arrayRemove(arr, elem) { var x, newArr = new Array(); for (x in arr) { if (arr[x] != elem) { newArr.push(arr[x]); } } return newArr; } function canvasSupport() { var canvas_compatible = false; try { canvas_compatible = !!(document.createElement("canvas").getContext("2d")); } catch (e) { canvas_compatible = !!(document.createElement("canvas").getContext); } return canvas_compatible; } function shadowSupport() { try { var userAgent = navigator.userAgent.toLowerCase(); if (/webkit/.test(userAgent)) { return true; } else { if (/gecko|mozilla/.test(userAgent) && parseFloat(userAgent.match(/firefox\/(\d+(?:\.\d+)+)/)[1]) >= 3.1) { return true; } } } catch (err) { } return false; } function betweenPoint(point1, point2, dist) { var y, x; if (point1.x == point2.x) { y = point1.y < point2.y ? point1.y + dist : point1.y - dist; return { x: point1.x, y: y }; } else { if (point1.y == point2.y) { x = point1.x < point2.x ? point1.x + dist : point1.x - dist; return { x: x, y: point1.y }; } } } function centerPoint(arcStart, corner, arcEnd) { var x = corner.x == arcStart.x ? arcEnd.x : arcStart.x; var y = corner.y == arcStart.y ? arcEnd.y : arcStart.y; var startAngle, endAngle; if (arcStart.x < arcEnd.x) { if (arcStart.y > arcEnd.y) { startAngle = (Math.PI / 180) * 180; endAngle = (Math.PI / 180) * 90; } else { startAngle = (Math.PI / 180) * 90; endAngle = 0; } } else { if (arcStart.y > arcEnd.y) { startAngle = (Math.PI / 180) * 270; endAngle = (Math.PI / 180) * 180; } else { startAngle = 0; endAngle = (Math.PI / 180) * 270; } } return { x: x, y: y, type: "center", startAngle: startAngle, endAngle: endAngle }; } function findIntersect(r1x1, r1y1, r1x2, r1y2, r2x1, r2y1, r2x2, r2y2) { if (r2x1 == r2x2) { return findIntersectY(r1x1, r1y1, r1x2, r1y2, r2x1); } if (r2y1 == r2y2) { return findIntersectX(r1x1, r1y1, r1x2, r1y2, r2y1); } var r1m = (r1y1 - r1y2) / (r1x1 - r1x2); var r1b = r1y1 - (r1m * r1x1); var r2m = (r2y1 - r2y2) / (r2x1 - r2x2); var r2b = r2y1 - (r2m * r2x1); var x = (r2b - r1b) / (r1m - r2m); var y = r1m * x + r1b; return { x: x, y: y }; } function findIntersectY(r1x1, r1y1, r1x2, r1y2, x) { if (r1y1 == r1y2) { return { x: x, y: r1y1 }; } var r1m = (r1y1 - r1y2) / (r1x1 - r1x2); var r1b = r1y1 - (r1m * r1x1); var y = r1m * x + r1b; return { x: x, y: y }; } function findIntersectX(r1x1, r1y1, r1x2, r1y2, y) { if (r1x1 == r1x2) { return { x: r1x1, y: y }; } var r1m = (r1y1 - r1y2) / (r1x1 - r1x2); var r1b = r1y1 - (r1m * r1x1); var x = (y - r1b) / r1m; return { x: x, y: y }; } }; jQuery.fn.btPosition = function () { function num(elem, prop) { return elem[0] && parseInt(jQuery.curCSS(elem[0], prop, true), 10) || 0; } var left = 0, top = 0, results; if (this[0]) { var offsetParent = this.offsetParent(), offset = this.offset(), parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0} : offsetParent.offset(); offset.top -= num(this, "marginTop"); offset.left -= num(this, "marginLeft"); parentOffset.top += num(offsetParent, "borderTopWidth"); parentOffset.left += num(offsetParent, "borderLeftWidth"); results = { top: offset.top - parentOffset.top, left: offset.left - parentOffset.left }; } return results; }; jQuery.fn.btOuterWidth = function (margin) { function num(elem, prop) { return elem[0] && parseInt(jQuery.curCSS(elem[0], prop, true), 10) || 0; } return this["innerWidth"]() + num(this, "borderLeftWidth") + num(this, "borderRightWidth") + (margin ? num(this, "marginLeft") + num(this, "marginRight") : 0); }; jQuery.fn.btOn = function () { return this.each(function (index) { if (jQuery.isFunction(this.btOn)) { this.btOn(); } }); }; jQuery.fn.btOff = function () { return this.each(function (index) { if (jQuery.isFunction(this.btOff)) { this.btOff(); } }); }; jQuery.bt.vars = { clickAnywhereStack: [], closeWhenOpenStack: [] }; jQuery.bt.docClick = function (e) { if (!e) { var e = window.event; } if (!$(e.target).parents().andSelf().filter(".bt-wrapper, .bt-active").length && jQuery.bt.vars.clickAnywhereStack.length) { $(jQuery.bt.vars.clickAnywhereStack).btOff(); $(document).unbind("click", jQuery.bt.docClick); } }; jQuery.bt.defaults = { trigger: "hover", clickAnywhereToClose: true, closeWhenOthersOpen: false, shrinkToFit: false, width: "200px", padding: "10px", spikeGirth: 10, spikeLength: 15, overlap: 0, overlay: false, killTitle: true, textzIndex: 9999, boxzIndex: 9998, wrapperzIndex: 9997, offsetParent: null, positions: ["most"], fill: "rgb(255, 255, 102)", windowMargin: 10, strokeWidth: 1, strokeStyle: "#000", cornerRadius: 5, centerPointX: 0.5, centerPointY: 0.5, shadow: false, shadowOffsetX: 2, shadowOffsetY: 2, shadowBlur: 3, shadowColor: "#000", shadowOverlap: false, noShadowOpts: { strokeStyle: "#999" }, cssClass: "", cssStyles: {}, activeClass: "bt-active", contentSelector: "$(this).attr('title')", ajaxPath: null, ajaxError: "<strong>ERROR:</strong> <em>%error</em>", ajaxLoading: "<blink>Loading...</blink>", ajaxData: {}, ajaxType: "GET", ajaxCache: true, ajaxOpts: {}, preBuild: function () { }, preShow: function (box) { }, showTip: function (box) { $(box).show(); }, postShow: function (box) { }, preHide: function (box) { }, hideTip: function (box, callback) { $(box).hide(); callback(); }, postHide: function () { }, hoverIntentOpts: { interval: 300, timeout: 500} }; jQuery.bt.options = {}; })(jQuery);
