[js] lint : make it explicit that typeof is an operator, not a function.
Also, use === / !== except for null / undefined comparison
/*! * jquery.qtip. The jQuery tooltip plugin * * Copyright (c) 2009 Craig Thompson * http://craigsworks.com * * Licensed under MIT * http://www.opensource.org/licenses/mit-license.php * * Launch : February 2009 * Version : 1.0.0-rc3 * Released: Tuesday 12th May, 2009 - 00:00 * Debug: jquery.qtip.debug.js */(function($){// Implementation$.fn.qtip=function(options,blanket){vari,id,interfaces,opts,obj,command,config,api;// Return API / Interfaces if requestedif(typeofoptions=='string'){// Make sure API data exists if requestedif(typeof$(this).data('qtip')!=='object')$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.NO_TOOLTIP_PRESENT,false);// Return requested objectif(options=='api')return$(this).data('qtip').interfaces[$(this).data('qtip').current];elseif(options=='interfaces')return$(this).data('qtip').interfaces;}// Validate provided optionselse{// Set null options object if no options are providedif(!options)options={};// Sanitize option dataif(typeofoptions.content!=='object'||(options.content.jquery&&options.content.length>0))options.content={text:options.content};if(typeofoptions.content.title!=='object')options.content.title={text:options.content.title};if(typeofoptions.position!=='object')options.position={corner:options.position};if(typeofoptions.position.corner!=='object')options.position.corner={target:options.position.corner,tooltip:options.position.corner};if(typeofoptions.show!=='object')options.show={when:options.show};if(typeofoptions.show.when!=='object')options.show.when={event:options.show.when};if(typeofoptions.show.effect!=='object')options.show.effect={type:options.show.effect};if(typeofoptions.hide!=='object')options.hide={when:options.hide};if(typeofoptions.hide.when!=='object')options.hide.when={event:options.hide.when};if(typeofoptions.hide.effect!=='object')options.hide.effect={type:options.hide.effect};if(typeofoptions.style!=='object')options.style={name:options.style};options.style=sanitizeStyle(options.style);// Build main options objectopts=$.extend(true,{},$.fn.qtip.defaults,options);// Inherit all style properties into one syle object and include original optionsopts.style=buildStyle.call({options:opts},opts.style);opts.user=$.extend(true,{},options);};// Iterate each matched elementreturn$(this).each(function()// Return original elements as per jQuery guidelines{// Check for API commandsif(typeofoptions=='string'){command=options.toLowerCase();interfaces=$(this).qtip('interfaces');// Make sure API data exists$('.qtip').qtip('destroy')if(typeofinterfaces=='object'){// Check if API call is a BLANKET DESTROY commandif(blanket===true&&command=='destroy')while(interfaces.length>0)interfaces[interfaces.length-1].destroy();// API call is not a BLANKET DESTROY commandelse{// Check if supplied command effects this tooltip only (NOT BLANKET)if(blanket!==true)interfaces=[$(this).qtip('api')];// Execute command on chosen qTipsfor(i=0;i<interfaces.length;i++){// Destroy command doesn't require tooltip to be renderedif(command=='destroy')interfaces[i].destroy();// Only call API if tooltip is rendered and it wasn't a destroy callelseif(interfaces[i].status.rendered===true){if(command=='show')interfaces[i].show();elseif(command=='hide')interfaces[i].hide();elseif(command=='focus')interfaces[i].focus();elseif(command=='disable')interfaces[i].disable(true);elseif(command=='enable')interfaces[i].disable(false);};};};};}// No API commands, continue with qTip creationelse{// Create unique configuration objectconfig=$.extend(true,{},opts);config.hide.effect.length=opts.hide.effect.length;config.show.effect.length=opts.show.effect.length;// Sanitize target optionsif(config.position.container===false)config.position.container=$(document.body);if(config.position.target===false)config.position.target=$(this);if(config.show.when.target===false)config.show.when.target=$(this);if(config.hide.when.target===false)config.hide.when.target=$(this);// Determine tooltip ID (Reuse array slots if possible)id=$.fn.qtip.interfaces.length;for(i=0;i<id;i++){if(typeof$.fn.qtip.interfaces[i]=='undefined'){id=i;break;};};// Instantiate the tooltipobj=newqTip($(this),config,id);// Add API references$.fn.qtip.interfaces[id]=obj;// Check if element already has qTip data assignedif(typeof$(this).data('qtip')=='object'){// Set new current interface idif(typeof$(this).attr('qtip')==='undefined')$(this).data('qtip').current=$(this).data('qtip').interfaces.length;// Push new API interface onto interfaces array$(this).data('qtip').interfaces.push(obj);}// No qTip data is present, create nowelse$(this).data('qtip',{current:0,interfaces:[obj]});// If prerendering is disabled, create tooltip on showEventif(config.content.prerender===false&&config.show.when.event!==false&&config.show.ready!==true){config.show.when.target.bind(config.show.when.event+'.qtip-'+id+'-create',{qtip:id},function(event){// Retrieve API interface via passed qTip Idapi=$.fn.qtip.interfaces[event.data.qtip];// Unbind show event and cache mouse coordsapi.options.show.when.target.unbind(api.options.show.when.event+'.qtip-'+event.data.qtip+'-create');api.cache.mouse={x:event.pageX,y:event.pageY};// Render tooltip and start the event sequenceconstruct.call(api);api.options.show.when.target.trigger(api.options.show.when.event);});}// Prerendering is enabled, create tooltip nowelse{// Set mouse position cache to top left of the elementobj.cache.mouse={x:config.show.when.target.offset().left,y:config.show.when.target.offset().top};// Construct the tooltipconstruct.call(obj);}};});};// InstantiatorfunctionqTip(target,options,id){// Declare this referencevarself=this;// Setup class attributesself.id=id;self.options=options;self.status={animated:false,rendered:false,disabled:false,focused:false};self.elements={target:target.addClass(self.options.style.classes.target),tooltip:null,wrapper:null,content:null,contentWrapper:null,title:null,button:null,tip:null,bgiframe:null};self.cache={mouse:{},position:{},toggle:0};self.timers={};// Define exposed API methods$.extend(self,self.options.api,{show:function(event){varreturned,solo;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'show');// Only continue if element is visibleif(self.elements.tooltip.css('display')!=='none')returnself;// Clear animation queueself.elements.tooltip.stop(true,false);// Call API method and if return value is false, haltreturned=self.beforeShow.call(self,event);if(returned===false)returnself;// Define afterShow callback methodfunctionafterShow(){// Call API method and focus if it isn't staticif(self.options.position.type!=='static')self.focus();self.onShow.call(self,event);// Prevent antialias from disappearing in IE7 by removing filter attributeif($.browser.msie)self.elements.tooltip.get(0).style.removeAttribute('filter');};// Maintain toggle functionality if enabledself.cache.toggle=1;// Update tooltip position if it isn't staticif(self.options.position.type!=='static')self.updatePosition(event,(self.options.show.effect.length>0));// Hide other tooltips if tooltip is soloif(typeofself.options.show.solo=='object')solo=$(self.options.show.solo);elseif(self.options.show.solo===true)solo=$('div.qtip').not(self.elements.tooltip);if(solo)solo.each(function(){if($(this).qtip('api').status.rendered===true)$(this).qtip('api').hide();});// Show tooltipif(typeofself.options.show.effect.type=='function'){self.options.show.effect.type.call(self.elements.tooltip,self.options.show.effect.length);self.elements.tooltip.queue(function(){afterShow();$(this).dequeue();});}else{switch(self.options.show.effect.type.toLowerCase()){case'fade':self.elements.tooltip.fadeIn(self.options.show.effect.length,afterShow);break;case'slide':self.elements.tooltip.slideDown(self.options.show.effect.length,function(){afterShow();if(self.options.position.type!=='static')self.updatePosition(event,true);});break;case'grow':self.elements.tooltip.show(self.options.show.effect.length,afterShow);break;default:self.elements.tooltip.show(null,afterShow);break;};// Add active class to tooltipself.elements.tooltip.addClass(self.options.style.classes.active);};// Log event and returnreturn$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_SHOWN,'show');},hide:function(event){varreturned;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'hide');// Only continue if element is visibleelseif(self.elements.tooltip.css('display')==='none')returnself;// Stop show timer and animation queueclearTimeout(self.timers.show);self.elements.tooltip.stop(true,false);// Call API method and if return value is false, haltreturned=self.beforeHide.call(self,event);if(returned===false)returnself;// Define afterHide callback methodfunctionafterHide(){self.onHide.call(self,event);};// Maintain toggle functionality if enabledself.cache.toggle=0;// Hide tooltipif(typeofself.options.hide.effect.type=='function'){self.options.hide.effect.type.call(self.elements.tooltip,self.options.hide.effect.length);self.elements.tooltip.queue(function(){afterHide();$(this).dequeue();});}else{switch(self.options.hide.effect.type.toLowerCase()){case'fade':self.elements.tooltip.fadeOut(self.options.hide.effect.length,afterHide);break;case'slide':self.elements.tooltip.slideUp(self.options.hide.effect.length,afterHide);break;case'grow':self.elements.tooltip.hide(self.options.hide.effect.length,afterHide);break;default:self.elements.tooltip.hide(null,afterHide);break;};// Remove active class to tooltipself.elements.tooltip.removeClass(self.options.style.classes.active);};// Log event and returnreturn$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_HIDDEN,'hide');},updatePosition:function(event,animate){vari,target,tooltip,coords,mapName,imagePos,newPosition,ieAdjust,ie6Adjust,borderAdjust,mouseAdjust,offset,curPosition,returned// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'updatePosition');// If tooltip is static, returnelseif(self.options.position.type=='static')return$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.CANNOT_POSITION_STATIC,'updatePosition');// Define property objectstarget={position:{left:0,top:0},dimensions:{height:0,width:0},corner:self.options.position.corner.target};tooltip={position:self.getPosition(),dimensions:self.getDimensions(),corner:self.options.position.corner.tooltip};// Target is an HTML elementif(self.options.position.target!=='mouse'){// If the HTML element is AREA, calculate position manuallyif(self.options.position.target.get(0).nodeName.toLowerCase()=='area'){// Retrieve coordinates from coords attribute and parse into integerscoords=self.options.position.target.attr('coords').split(',');for(i=0;i<coords.length;i++)coords[i]=parseInt(coords[i]);// Setup target position objectmapName=self.options.position.target.parent('map').attr('name');imagePos=$('img[usemap="#'+mapName+'"]:first').offset();target.position={left:Math.floor(imagePos.left+coords[0]),top:Math.floor(imagePos.top+coords[1])};// Determine width and height of the areaswitch(self.options.position.target.attr('shape').toLowerCase()){case'rect':target.dimensions={width:Math.ceil(Math.abs(coords[2]-coords[0])),height:Math.ceil(Math.abs(coords[3]-coords[1]))};break;case'circle':target.dimensions={width:coords[2]+1,height:coords[2]+1};break;case'poly':target.dimensions={width:coords[0],height:coords[1]};for(i=0;i<coords.length;i++){if(i%2==0){if(coords[i]>target.dimensions.width)target.dimensions.width=coords[i];if(coords[i]<coords[0])target.position.left=Math.floor(imagePos.left+coords[i]);}else{if(coords[i]>target.dimensions.height)target.dimensions.height=coords[i];if(coords[i]<coords[1])target.position.top=Math.floor(imagePos.top+coords[i]);};};target.dimensions.width=target.dimensions.width-(target.position.left-imagePos.left);target.dimensions.height=target.dimensions.height-(target.position.top-imagePos.top);break;default:return$.fn.qtip.log.error.call(self,4,$.fn.qtip.constants.INVALID_AREA_SHAPE,'updatePosition');break;};// Adjust position by 2 pixels (Positioning bug?)target.dimensions.width-=2;target.dimensions.height-=2;}// Target is the documentelseif(self.options.position.target.add(document.body).length===1){target.position={left:$(document).scrollLeft(),top:$(document).scrollTop()};target.dimensions={height:$(window).height(),width:$(window).width()};}// Target is a regular HTML element, find position normallyelse{// Check if the target is another tooltip. If its animated, retrieve position from newPosition dataif(typeofself.options.position.target.attr('qtip')!=='undefined')target.position=self.options.position.target.qtip('api').cache.position;elsetarget.position=self.options.position.target.offset();// Setup dimensions objectstarget.dimensions={height:self.options.position.target.outerHeight(),width:self.options.position.target.outerWidth()};};// Calculate correct target corner positionnewPosition=$.extend({},target.position);if(target.corner.search(/right/i)!==-1)newPosition.left+=target.dimensions.width;if(target.corner.search(/bottom/i)!==-1)newPosition.top+=target.dimensions.height;if(target.corner.search(/((top|bottom)Middle)|center/)!==-1)newPosition.left+=(target.dimensions.width/2);if(target.corner.search(/((left|right)Middle)|center/)!==-1)newPosition.top+=(target.dimensions.height/2);}// Mouse is the target, set position to current mouse coordinateselse{// Setup target position and dimensions objectstarget.position=newPosition={left:self.cache.mouse.x,top:self.cache.mouse.y};target.dimensions={height:1,width:1};};// Calculate correct target corner positionif(tooltip.corner.search(/right/i)!==-1)newPosition.left-=tooltip.dimensions.width;if(tooltip.corner.search(/bottom/i)!==-1)newPosition.top-=tooltip.dimensions.height;if(tooltip.corner.search(/((top|bottom)Middle)|center/)!==-1)newPosition.left-=(tooltip.dimensions.width/2);if(tooltip.corner.search(/((left|right)Middle)|center/)!==-1)newPosition.top-=(tooltip.dimensions.height/2);// Setup IE adjustment variables (Pixel gap bugs)ieAdjust=($.browser.msie)?1:0;// And this is why I hate IE...ie6Adjust=($.browser.msie&&parseInt($.browser.version.charAt(0))===6)?1:0;// ...and even more so IE6!// Adjust for border radiusif(self.options.style.border.radius>0){if(tooltip.corner.search(/Left/)!==-1)newPosition.left-=self.options.style.border.radius;elseif(tooltip.corner.search(/Right/)!==-1)newPosition.left+=self.options.style.border.radius;if(tooltip.corner.search(/Top/)!==-1)newPosition.top-=self.options.style.border.radius;elseif(tooltip.corner.search(/Bottom/)!==-1)newPosition.top+=self.options.style.border.radius;};// IE only adjustments (Pixel perfect!)if(ieAdjust){if(tooltip.corner.search(/top/)!==-1)newPosition.top-=ieAdjustelseif(tooltip.corner.search(/bottom/)!==-1)newPosition.top+=ieAdjustif(tooltip.corner.search(/left/)!==-1)newPosition.left-=ieAdjustelseif(tooltip.corner.search(/right/)!==-1)newPosition.left+=ieAdjustif(tooltip.corner.search(/leftMiddle|rightMiddle/)!==-1)newPosition.top-=1};// If screen adjustment is enabled, apply adjustmentsif(self.options.position.adjust.screen===true)newPosition=screenAdjust.call(self,newPosition,target,tooltip);// If mouse is the target, prevent tooltip appearing directly under the mouseif(self.options.position.target==='mouse'&&self.options.position.adjust.mouse===true){if(self.options.position.adjust.screen===true&&self.elements.tip)mouseAdjust=self.elements.tip.attr('rel');elsemouseAdjust=self.options.position.corner.tooltip;newPosition.left+=(mouseAdjust.search(/right/i)!==-1)?-6:6;newPosition.top+=(mouseAdjust.search(/bottom/i)!==-1)?-6:6;}// Initiate bgiframe plugin in IE6 if tooltip overlaps a select box or object elementif(!self.elements.bgiframe&&$.browser.msie&&parseInt($.browser.version.charAt(0))==6){$('select, object').each(function(){offset=$(this).offset();offset.bottom=offset.top+$(this).height();offset.right=offset.left+$(this).width();if(newPosition.top+tooltip.dimensions.height>=offset.top&&newPosition.left+tooltip.dimensions.width>=offset.left)bgiframe.call(self);});};// Add user xy adjustmentsnewPosition.left+=self.options.position.adjust.x;newPosition.top+=self.options.position.adjust.y;// Set new tooltip position if its moved, animate if enabledcurPosition=self.getPosition();if(newPosition.left!=curPosition.left||newPosition.top!=curPosition.top){// Call API method and if return value is false, haltreturned=self.beforePositionUpdate.call(self,event);if(returned===false)returnself;// Cache new positionself.cache.position=newPosition;// Check if animation is enabledif(animate===true){// Set animated statusself.status.animated=true;// Animate and reset animated status on animation endself.elements.tooltip.animate(newPosition,200,'swing',function(){self.status.animated=false});}// Set new position via CSSelseself.elements.tooltip.css(newPosition);// Call API method and log event if its not a mouse moveself.onPositionUpdate.call(self,event);if(typeofevent!=='undefined'&&event.type&&event.type!=='mousemove')$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_POSITION_UPDATED,'updatePosition');};returnself;},updateWidth:function(newWidth){varhidden;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'updateWidth');// Make sure supplied width is a number and if not, returnelseif(newWidth&&typeofnewWidth!=='number')return$.fn.qtip.log.error.call(self,2,'newWidth must be of type number','updateWidth');// Setup elements which must be hidden during width updatehidden=self.elements.contentWrapper.siblings().add(self.elements.tip).add(self.elements.button);// Calculate the new width if one is not suppliedif(!newWidth){// Explicit width is setif(typeofself.options.style.width.value=='number')newWidth=self.options.style.width.value;// No width is set, proceed with auto detectionelse{// Set width to auto initally to determine new width and hide other elementsself.elements.tooltip.css({width:'auto'});hidden.hide();// Set position and zoom to defaults to prevent IE hasLayout bugif($.browser.msie)self.elements.wrapper.add(self.elements.contentWrapper.children()).css({zoom:'normal'});// Set the new widthnewWidth=self.getDimensions().width+1;// Make sure its within the maximum and minimum width boundriesif(!self.options.style.width.value){if(newWidth>self.options.style.width.max)newWidth=self.options.style.width.maxif(newWidth<self.options.style.width.min)newWidth=self.options.style.width.min};};};// Adjust newWidth by 1px if width is odd (IE6 rounding bug fix)if(newWidth%2!==0)newWidth-=1;// Set the new calculated width and unhide other elementsself.elements.tooltip.width(newWidth);hidden.show();// Set the border width, if enabledif(self.options.style.border.radius){self.elements.tooltip.find('.qtip-betweenCorners').each(function(i){$(this).width(newWidth-(self.options.style.border.radius*2));})};// IE only adjustmentsif($.browser.msie){// Reset position and zoom to give the wrapper layout (IE hasLayout bug)self.elements.wrapper.add(self.elements.contentWrapper.children()).css({zoom:'1'});// Set the new widthself.elements.wrapper.width(newWidth);// Adjust BGIframe height and width if enabledif(self.elements.bgiframe)self.elements.bgiframe.width(newWidth).height(self.getDimensions.height);};// Log event and returnreturn$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_WIDTH_UPDATED,'updateWidth');},updateStyle:function(name){vartip,borders,context,corner,coordinates;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'updateStyle');// Return if style is not defined or name is not a stringelseif(typeofname!=='string'||!$.fn.qtip.styles[name])return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.STYLE_NOT_DEFINED,'updateStyle');// Set the new style objectself.options.style=buildStyle.call(self,$.fn.qtip.styles[name],self.options.user.style);// Update initial styles of content and title elementsself.elements.content.css(jQueryStyle(self.options.style));if(self.options.content.title.text!==false)self.elements.title.css(jQueryStyle(self.options.style.title,true));// Update CSS border colourself.elements.contentWrapper.css({borderColor:self.options.style.border.color});// Update tip color if enabledif(self.options.style.tip.corner!==false){if($('<canvas>').get(0).getContext){// Retrieve canvas context and cleartip=self.elements.tooltip.find('.qtip-tip canvas:first');context=tip.get(0).getContext('2d');context.clearRect(0,0,300,300);// Draw new tipcorner=tip.parent('div[rel]:first').attr('rel');coordinates=calculateTip(corner,self.options.style.tip.size.width,self.options.style.tip.size.height);drawTip.call(self,tip,coordinates,self.options.style.tip.color||self.options.style.border.color);}elseif($.browser.msie){// Set new fillcolor attributetip=self.elements.tooltip.find('.qtip-tip [nodeName="shape"]');tip.attr('fillcolor',self.options.style.tip.color||self.options.style.border.color);};};// Update border colors if enabledif(self.options.style.border.radius>0){self.elements.tooltip.find('.qtip-betweenCorners').css({backgroundColor:self.options.style.border.color});if($('<canvas>').get(0).getContext){borders=calculateBorders(self.options.style.border.radius)self.elements.tooltip.find('.qtip-wrapper canvas').each(function(){// Retrieve canvas context and clearcontext=$(this).get(0).getContext('2d');context.clearRect(0,0,300,300);// Draw new bordercorner=$(this).parent('div[rel]:first').attr('rel')drawBorder.call(self,$(this),borders[corner],self.options.style.border.radius,self.options.style.border.color);});}elseif($.browser.msie){// Set new fillcolor attribute on each border cornerself.elements.tooltip.find('.qtip-wrapper [nodeName="arc"]').each(function(){$(this).attr('fillcolor',self.options.style.border.color)});};};// Log event and returnreturn$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_STYLE_UPDATED,'updateStyle');},updateContent:function(content,reposition){varparsedContent,images,loadedImages;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'updateContent');// Make sure content is defined before updateelseif(!content)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.NO_CONTENT_PROVIDED,'updateContent');// Call API method and set new content if a string is returnedparsedContent=self.beforeContentUpdate.call(self,content);if(typeofparsedContent=='string')content=parsedContent;elseif(parsedContent===false)return;// Set position and zoom to defaults to prevent IE hasLayout bugif($.browser.msie)self.elements.contentWrapper.children().css({zoom:'normal'});// Append new content if its a DOM array and show it if hiddenif(content.jquery&&content.length>0)content.clone(true).appendTo(self.elements.content).show();// Content is a regular string, insert the new contentelseself.elements.content.html(content);// Check if images need to be loaded before position is updated to prevent mis-positioningimages=self.elements.content.find('img[complete=false]');if(images.length>0){loadedImages=0;images.each(function(i){$('<img src="'+$(this).attr('src')+'" />').load(function(){if(++loadedImages==images.length)afterLoad();});});}elseafterLoad();functionafterLoad(){// Update the tooltip widthself.updateWidth();// If repositioning is enabled, update positionsif(reposition!==false){// Update position if tooltip isn't staticif(self.options.position.type!=='static')self.updatePosition(self.elements.tooltip.is(':visible'),true);// Reposition the tip if enabledif(self.options.style.tip.corner!==false)positionTip.call(self);};};// Call API method and log eventself.onContentUpdate.call(self);return$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_CONTENT_UPDATED,'loadContent');},loadContent:function(url,data,method){varreturned;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'loadContent');// Call API method and if return value is false, haltreturned=self.beforeContentLoad.call(self);if(returned===false)returnself;// Load content using specified request typeif(method=='post')$.post(url,data,setupContent);else$.get(url,data,setupContent);functionsetupContent(content){// Call API method and log eventself.onContentLoad.call(self);$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_CONTENT_LOADED,'loadContent');// Update the contentself.updateContent(content);};returnself;},updateTitle:function(content){// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'updateTitle');// Make sure content is defined before updateelseif(!content)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.NO_CONTENT_PROVIDED,'updateTitle');// Call API method and if return value is false, haltreturned=self.beforeTitleUpdate.call(self);if(returned===false)returnself;// Set the new content and reappend the button if enabledif(self.elements.button)self.elements.button=self.elements.button.clone(true);self.elements.title.html(content)if(self.elements.button)self.elements.title.prepend(self.elements.button);// Call API method and log eventself.onTitleUpdate.call(self);return$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_TITLE_UPDATED,'updateTitle');},focus:function(event){varcurIndex,newIndex,elemIndex,returned;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'focus');elseif(self.options.position.type=='static')return$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.CANNOT_FOCUS_STATIC,'focus');// Set z-index variablescurIndex=parseInt(self.elements.tooltip.css('z-index'));newIndex=6000+$('div.qtip[qtip]').length-1;// Only update the z-index if it has changed and tooltip is not already focusedif(!self.status.focused&&curIndex!==newIndex){// Call API method and if return value is false, haltreturned=self.beforeFocus.call(self,event);if(returned===false)returnself;// Loop through all other tooltips$('div.qtip[qtip]').not(self.elements.tooltip).each(function(){if($(this).qtip('api').status.rendered===true){elemIndex=parseInt($(this).css('z-index'));// Reduce all other tooltip z-index by 1if(typeofelemIndex=='number'&&elemIndex>-1)$(this).css({zIndex:parseInt($(this).css('z-index'))-1});// Set focused status to false$(this).qtip('api').status.focused=false;}})// Set the new z-index and set focus status to trueself.elements.tooltip.css({zIndex:newIndex});self.status.focused=true;// Call API method and log eventself.onFocus.call(self,event);$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_FOCUSED,'focus');};returnself;},disable:function(state){// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'disable');if(state){// Tooltip is not already disabled, proceedif(!self.status.disabled){// Set the disabled flag and log eventself.status.disabled=true;$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_DISABLED,'disable');}// Tooltip is already disabled, inform user via logelse$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.TOOLTIP_ALREADY_DISABLED,'disable');}else{// Tooltip is not already enabled, proceedif(self.status.disabled){// Reassign events, set disable status and logself.status.disabled=false;$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_ENABLED,'disable');}// Tooltip is already enabled, inform the user via logelse$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.TOOLTIP_ALREADY_ENABLED,'disable');};returnself;},destroy:function(){vari,returned,interfaces;// Call API method and if return value is false, haltreturned=self.beforeDestroy.call(self);if(returned===false)returnself;// Check if tooltip is renderedif(self.status.rendered){// Remove event handlers and remove elementself.options.show.when.target.unbind('mousemove.qtip',self.updatePosition);self.options.show.when.target.unbind('mouseout.qtip',self.hide);self.options.show.when.target.unbind(self.options.show.when.event+'.qtip');self.options.hide.when.target.unbind(self.options.hide.when.event+'.qtip');self.elements.tooltip.unbind(self.options.hide.when.event+'.qtip');self.elements.tooltip.unbind('mouseover.qtip',self.focus);self.elements.tooltip.remove();}// Tooltip isn't yet rendered, remove render eventelseself.options.show.when.target.unbind(self.options.show.when.event+'.qtip-create');// Check to make sure qTip data is present on target elementif(typeofself.elements.target.data('qtip')=='object'){// Remove API references from interfaces objectinterfaces=self.elements.target.data('qtip').interfaces;if(typeofinterfaces=='object'&&interfaces.length>0){// Remove API from interfaces arrayfor(i=0;i<interfaces.length-1;i++)if(interfaces[i].id==self.id)interfaces.splice(i,1)}}delete$.fn.qtip.interfaces[self.id];// Set qTip current id to previous tooltips API if availableif(typeofinterfaces=='object'&&interfaces.length>0)self.elements.target.data('qtip').current=interfaces.length-1;elseself.elements.target.removeData('qtip');// Call API method and log destroyself.onDestroy.call(self);$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_DESTROYED,'destroy');returnself.elements.target},getPosition:function(){varshow,offset;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'getPosition');show=(self.elements.tooltip.css('display')!=='none')?false:true;// Show and hide tooltip to make sure coordinates are returnedif(show)self.elements.tooltip.css({visiblity:'hidden'}).show();offset=self.elements.tooltip.offset();if(show)self.elements.tooltip.css({visiblity:'visible'}).hide();returnoffset;},getDimensions:function(){varshow,dimensions;// Make sure tooltip is rendered and if not, returnif(!self.status.rendered)return$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.TOOLTIP_NOT_RENDERED,'getDimensions');show=(!self.elements.tooltip.is(':visible'))?true:false;// Show and hide tooltip to make sure dimensions are returnedif(show)self.elements.tooltip.css({visiblity:'hidden'}).show();dimensions={height:self.elements.tooltip.outerHeight(),width:self.elements.tooltip.outerWidth()};if(show)self.elements.tooltip.css({visiblity:'visible'}).hide();returndimensions;}});};// Define priamry construct functionfunctionconstruct(){varself,adjust,content,url,data,method,tempLength;self=this;// Call API methodself.beforeRender.call(self);// Set rendered status to trueself.status.rendered=true;// Create initial tooltip elementsself.elements.tooltip='<div qtip="'+self.id+'" '+'class="qtip '+(self.options.style.classes.tooltip||self.options.style)+'"'+'style="display:none; -moz-border-radius:0; -webkit-border-radius:0; border-radius:0;'+'position:'+self.options.position.type+';">'+' <div class="qtip-wrapper" style="position:relative; overflow:hidden; text-align:left;">'+' <div class="qtip-contentWrapper" style="overflow:hidden;">'+' <div class="qtip-content '+self.options.style.classes.content+'"></div>'+'</div></div></div>';// Append to container elementself.elements.tooltip=$(self.elements.tooltip);self.elements.tooltip.appendTo(self.options.position.container)// Setup tooltip qTip dataself.elements.tooltip.data('qtip',{current:0,interfaces:[self]});// Setup element referencesself.elements.wrapper=self.elements.tooltip.children('div:first');self.elements.contentWrapper=self.elements.wrapper.children('div:first').css({background:self.options.style.background});self.elements.content=self.elements.contentWrapper.children('div:first').css(jQueryStyle(self.options.style));// Apply IE hasLayout fix to wrapper and content elementsif($.browser.msie)self.elements.wrapper.add(self.elements.content).css({zoom:1});// Setup tooltip attributesif(self.options.hide.when.event=='unfocus')self.elements.tooltip.attr('unfocus',true);// If an explicit width is set, updateWidth prior to setting content to prevent dirty renderingif(typeofself.options.style.width.value=='number')self.updateWidth();// Create borders and tips if supported by the browserif($('<canvas>').get(0).getContext||$.browser.msie){// Create borderif(self.options.style.border.radius>0)createBorder.call(self);elseself.elements.contentWrapper.css({border:self.options.style.border.width+'px solid '+self.options.style.border.color});// Create tip if enabledif(self.options.style.tip.corner!==false)createTip.call(self);}// Neither canvas or VML is supported, tips and borders cannot be drawn!else{// Set defined border widthself.elements.contentWrapper.css({border:self.options.style.border.width+'px solid '+self.options.style.border.color});// Reset border radius and tipself.options.style.border.radius=0;self.options.style.tip.corner=false;// Inform via log$.fn.qtip.log.error.call(self,2,$.fn.qtip.constants.CANVAS_VML_NOT_SUPPORTED,'render');};// Use the provided content string or DOM arrayif((typeofself.options.content.text=='string'&&self.options.content.text.length>0)||(self.options.content.text.jquery&&self.options.content.text.length>0))content=self.options.content.text;// Use title string for content if presentelseif(typeofself.elements.target.attr('title')=='string'&&self.elements.target.attr('title').length>0){content=self.elements.target.attr('title').replace("\\n",'<br />');self.elements.target.attr('title','');// Remove title attribute to prevent default tooltip showing}// No title is present, use alt attribute insteadelseif(typeofself.elements.target.attr('alt')=='string'&&self.elements.target.attr('alt').length>0){content=self.elements.target.attr('alt').replace("\\n",'<br />');self.elements.target.attr('alt','');// Remove alt attribute to prevent default tooltip showing}// No valid content was provided, inform via logelse{content=' ';$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.NO_VALID_CONTENT,'render');};// Set the tooltips content and create title if enabledif(self.options.content.title.text!==false)createTitle.call(self);self.updateContent(content);// Assign events and toggle tooltip with focusassignEvents.call(self);if(self.options.show.ready===true)self.show();// Retrieve ajax content if providedif(self.options.content.url!==false){url=self.options.content.url;data=self.options.content.data;method=self.options.content.method||'get';self.loadContent(url,data,method);};// Call API method and log eventself.onRender.call(self);$.fn.qtip.log.error.call(self,1,$.fn.qtip.constants.EVENT_RENDERED,'render');};// Create borders using canvas and VMLfunctioncreateBorder(){varself,i,width,radius,color,coordinates,containers,size,betweenWidth,betweenCorners,borderTop,borderBottom,borderCoord,sideWidth,vertWidth;self=this;// Destroy previous border elements, if presentself.elements.wrapper.find('.qtip-borderBottom, .qtip-borderTop').remove();// Setup local variableswidth=self.options.style.border.width;radius=self.options.style.border.radius;color=self.options.style.border.color||self.options.style.tip.color;// Calculate border coordinatescoordinates=calculateBorders(radius);// Create containers for the border shapescontainers={};for(iincoordinates){// Create shape containercontainers[i]='<div rel="'+i+'" style="'+((i.search(/Left/)!==-1)?'left':'right')+':0; '+'position:absolute; height:'+radius+'px; width:'+radius+'px; overflow:hidden; line-height:0.1px; font-size:1px">';// Canvas is supportedif($('<canvas>').get(0).getContext)containers[i]+='<canvas height="'+radius+'" width="'+radius+'" style="vertical-align: top"></canvas>';// No canvas, but if it's IE use VMLelseif($.browser.msie){size=radius*2+3;containers[i]+='<v:arc stroked="false" fillcolor="'+color+'" startangle="'+coordinates[i][0]+'" endangle="'+coordinates[i][1]+'" '+'style="width:'+size+'px; height:'+size+'px; margin-top:'+((i.search(/bottom/)!==-1)?-2:-1)+'px; '+'margin-left:'+((i.search(/Right/)!==-1)?coordinates[i][2]-3.5:-1)+'px; '+'vertical-align:top; display:inline-block; behavior:url(#default#VML)"></v:arc>';};containers[i]+='</div>';};// Create between corners elementsbetweenWidth=self.getDimensions().width-(Math.max(width,radius)*2);betweenCorners='<div class="qtip-betweenCorners" style="height:'+radius+'px; width:'+betweenWidth+'px; '+'overflow:hidden; background-color:'+color+'; line-height:0.1px; font-size:1px;">';// Create top border containerborderTop='<div class="qtip-borderTop" dir="ltr" style="height:'+radius+'px; '+'margin-left:'+radius+'px; line-height:0.1px; font-size:1px; padding:0;">'+containers['topLeft']+containers['topRight']+betweenCorners;self.elements.wrapper.prepend(borderTop);// Create bottom border containerborderBottom='<div class="qtip-borderBottom" dir="ltr" style="height:'+radius+'px; '+'margin-left:'+radius+'px; line-height:0.1px; font-size:1px; padding:0;">'+containers['bottomLeft']+containers['bottomRight']+betweenCorners;self.elements.wrapper.append(borderBottom);// Draw the borders if canvas were used (Delayed til after DOM creation)if($('<canvas>').get(0).getContext){self.elements.wrapper.find('canvas').each(function(){borderCoord=coordinates[$(this).parent('[rel]:first').attr('rel')];drawBorder.call(self,$(this),borderCoord,radius,color);})}// Create a phantom VML element (IE won't show the last created VML element otherwise)elseif($.browser.msie)self.elements.tooltip.append('<v:image style="behavior:url(#default#VML);"></v:image>');// Setup contentWrapper bordersideWidth=Math.max(radius,(radius+(width-radius)))vertWidth=Math.max(width-radius,0);self.elements.contentWrapper.css({border:'0px solid '+color,borderWidth:vertWidth+'px '+sideWidth+'px'})};// Border canvas draw methodfunctiondrawBorder(canvas,coordinates,radius,color){// Create cornervarcontext=canvas.get(0).getContext('2d');context.fillStyle=color;context.beginPath();context.arc(coordinates[0],coordinates[1],radius,0,Math.PI*2,false);context.fill();};// Create tip using canvas and VMLfunctioncreateTip(corner){varself,color,coordinates,coordsize,path;self=this;// Destroy previous tip, if there is oneif(self.elements.tip!==null)self.elements.tip.remove();// Setup color and corner valuescolor=self.options.style.tip.color||self.options.style.border.color;if(self.options.style.tip.corner===false)return;elseif(!corner)corner=self.options.style.tip.corner;// Calculate tip coordinatescoordinates=calculateTip(corner,self.options.style.tip.size.width,self.options.style.tip.size.height);// Create tip elementself.elements.tip='<div class="'+self.options.style.classes.tip+'" dir="ltr" rel="'+corner+'" style="position:absolute; '+'height:'+self.options.style.tip.size.height+'px; width:'+self.options.style.tip.size.width+'px; '+'margin:0 auto; line-height:0.1px; font-size:1px;">';// Use canvas element if supportedif($('<canvas>').get(0).getContext)self.elements.tip+='<canvas height="'+self.options.style.tip.size.height+'" width="'+self.options.style.tip.size.width+'"></canvas>';// Canvas not supported - Use VML (IE)elseif($.browser.msie){// Create coordize and tip path using tip coordinatescoordsize=self.options.style.tip.size.width+','+self.options.style.tip.size.height;path='m'+coordinates[0][0]+','+coordinates[0][1];path+=' l'+coordinates[1][0]+','+coordinates[1][1];path+=' '+coordinates[2][0]+','+coordinates[2][1];path+=' xe';// Create VML elementself.elements.tip+='<v:shape fillcolor="'+color+'" stroked="false" filled="true" path="'+path+'" coordsize="'+coordsize+'" '+'style="width:'+self.options.style.tip.size.width+'px; height:'+self.options.style.tip.size.height+'px; '+'line-height:0.1px; display:inline-block; behavior:url(#default#VML); '+'vertical-align:'+((corner.search(/top/)!==-1)?'bottom':'top')+'"></v:shape>';// Create a phantom VML element (IE won't show the last created VML element otherwise)self.elements.tip+='<v:image style="behavior:url(#default#VML);"></v:image>';// Prevent tooltip appearing above the content (IE z-index bug)self.elements.contentWrapper.css('position','relative');};// Attach new tip to tooltip elementself.elements.tooltip.prepend(self.elements.tip+'</div>');// Create element reference and draw the canvas tip (Delayed til after DOM creation)self.elements.tip=self.elements.tooltip.find('.'+self.options.style.classes.tip).eq(0);if($('<canvas>').get(0).getContext)drawTip.call(self,self.elements.tip.find('canvas:first'),coordinates,color);// Fix IE small tip bugif(corner.search(/top/)!==-1&&$.browser.msie&&parseInt($.browser.version.charAt(0))===6)self.elements.tip.css({marginTop:-4});// Set the tip positionpositionTip.call(self,corner);};// Canvas tip drawing methodfunctiondrawTip(canvas,coordinates,color){// Setup propertiesvarcontext=canvas.get(0).getContext('2d');context.fillStyle=color;// Create tipcontext.beginPath();context.moveTo(coordinates[0][0],coordinates[0][1]);context.lineTo(coordinates[1][0],coordinates[1][1]);context.lineTo(coordinates[2][0],coordinates[2][1]);context.fill();};functionpositionTip(corner){varself,ieAdjust,paddingCorner,paddingSize,newMargin;self=this;// Return if tips are disabled or tip is not yet renderedif(self.options.style.tip.corner===false||!self.elements.tip)return;if(!corner)corner=self.elements.tip.attr('rel');// Setup adjustment variablesieAdjust=positionAdjust=($.browser.msie)?1:0;// Set initial positionself.elements.tip.css(corner.match(/left|right|top|bottom/)[0],0);// Set position of tip to correct sideif(corner.search(/top|bottom/)!==-1){// Adjustments for IE6 - 0.5px border gap bugif($.browser.msie){if(parseInt($.browser.version.charAt(0))===6)positionAdjust=(corner.search(/top/)!==-1)?-3:1;elsepositionAdjust=(corner.search(/top/)!==-1)?1:2;};if(corner.search(/Middle/)!==-1)self.elements.tip.css({left:'50%',marginLeft:-(self.options.style.tip.size.width/2)});elseif(corner.search(/Left/)!==-1)self.elements.tip.css({left:self.options.style.border.radius-ieAdjust});elseif(corner.search(/Right/)!==-1)self.elements.tip.css({right:self.options.style.border.radius+ieAdjust});if(corner.search(/top/)!==-1)self.elements.tip.css({top:-positionAdjust});elseself.elements.tip.css({bottom:positionAdjust});}elseif(corner.search(/left|right/)!==-1){// Adjustments for IE6 - 0.5px border gap bugif($.browser.msie)positionAdjust=(parseInt($.browser.version.charAt(0))===6)?1:((corner.search(/left/)!==-1)?1:2);if(corner.search(/Middle/)!==-1)self.elements.tip.css({top:'50%',marginTop:-(self.options.style.tip.size.height/2)});elseif(corner.search(/Top/)!==-1)self.elements.tip.css({top:self.options.style.border.radius-ieAdjust});elseif(corner.search(/Bottom/)!==-1)self.elements.tip.css({bottom:self.options.style.border.radius+ieAdjust});if(corner.search(/left/)!==-1)self.elements.tip.css({left:-positionAdjust});elseself.elements.tip.css({right:positionAdjust});};// Adjust tooltip padding to compensate for tippaddingCorner='padding-'+corner.match(/left|right|top|bottom/)[0];paddingSize=self.options.style.tip.size[(paddingCorner.search(/left|right/)!==-1)?'width':'height'];self.elements.tooltip.css('padding',0);self.elements.tooltip.css(paddingCorner,paddingSize);// Match content margin to prevent gap bug in IE6 ONLYif($.browser.msie&&parseInt($.browser.version.charAt(0))==6){newMargin=parseInt(self.elements.tip.css('margin-top'))||0;newMargin+=parseInt(self.elements.content.css('margin-top'))||0;self.elements.tip.css({marginTop:newMargin});};};// Create title bar for contentfunctioncreateTitle(){varself=this;// Destroy previous title element, if presentif(self.elements.title!==null)self.elements.title.remove();// Create title elementself.elements.title=$('<div class="'+self.options.style.classes.title+'">').css(jQueryStyle(self.options.style.title,true)).css({zoom:($.browser.msie)?1:0}).prependTo(self.elements.contentWrapper);// Update title with contents if enabledif(self.options.content.title.text)self.updateTitle.call(self,self.options.content.title.text);// Create title close buttons if enabledif(self.options.content.title.button!==false&&typeofself.options.content.title.button=='string'){self.elements.button=$('<a class="'+self.options.style.classes.button+'" style="float:right; position: relative"></a>').css(jQueryStyle(self.options.style.button,true)).html(self.options.content.title.button).prependTo(self.elements.title).click(function(event){if(!self.status.disabled)self.hide(event)});};};// Assign hide and show eventsfunctionassignEvents(){varself,showTarget,hideTarget,inactiveEvents;self=this;// Setup event target variablesshowTarget=self.options.show.when.target;hideTarget=self.options.hide.when.target;// Add tooltip as a hideTarget is its fixedif(self.options.hide.fixed)hideTarget=hideTarget.add(self.elements.tooltip);// Check if the hide event is special 'inactive' typeif(self.options.hide.when.event=='inactive'){// Define events which reset the 'inactive' event handlerinactiveEvents=['click','dblclick','mousedown','mouseup','mousemove','mouseout','mouseenter','mouseleave','mouseover'];// Define 'inactive' event timer methodfunctioninactiveMethod(event){if(self.status.disabled===true)return;//Clear and reset the timerclearTimeout(self.timers.inactive);self.timers.inactive=setTimeout(function(){// Unassign 'inactive' events$(inactiveEvents).each(function(){hideTarget.unbind(this+'.qtip-inactive');self.elements.content.unbind(this+'.qtip-inactive');});// Hide the tooltipself.hide(event);},self.options.hide.delay);};}// Check if the tooltip is 'fixed'elseif(self.options.hide.fixed===true){self.elements.tooltip.bind('mouseover.qtip',function(){if(self.status.disabled===true)return;// Reset the hide timerclearTimeout(self.timers.hide);});};// Define show event methodfunctionshowMethod(event){if(self.status.disabled===true)return;// If set, hide tooltip when inactive for delay periodif(self.options.hide.when.event=='inactive'){// Assign each reset event$(inactiveEvents).each(function(){hideTarget.bind(this+'.qtip-inactive',inactiveMethod);self.elements.content.bind(this+'.qtip-inactive',inactiveMethod);});// Start the inactive timerinactiveMethod();};// Clear hide timersclearTimeout(self.timers.show);clearTimeout(self.timers.hide);// Start show timerself.timers.show=setTimeout(function(){self.show(event);},self.options.show.delay);};// Define hide event methodfunctionhideMethod(event){if(self.status.disabled===true)return;// Prevent hiding if tooltip is fixed and event target is the tooltipif(self.options.hide.fixed===true&&self.options.hide.when.event.search(/mouse(out|leave)/i)!==-1&&$(event.relatedTarget).parents('div.qtip[qtip]').length>0){// Prevent default and popagationevent.stopPropagation();event.preventDefault();// Reset the hide timerclearTimeout(self.timers.hide);returnfalse;};// Clear timers and stop animation queueclearTimeout(self.timers.show);clearTimeout(self.timers.hide);self.elements.tooltip.stop(true,true);// If tooltip has displayed, start hide timerself.timers.hide=setTimeout(function(){self.hide(event);},self.options.hide.delay);};// Both events and targets are identical, apply events using a toggleif((self.options.show.when.target.add(self.options.hide.when.target).length===1&&self.options.show.when.event==self.options.hide.when.event&&self.options.hide.when.event!=='inactive')||self.options.hide.when.event=='unfocus'){self.cache.toggle=0;// Use a toggle to prevent hide/show conflictsshowTarget.bind(self.options.show.when.event+'.qtip',function(event){if(self.cache.toggle==0)showMethod(event);elsehideMethod(event);});}// Events are not identical, bind normallyelse{showTarget.bind(self.options.show.when.event+'.qtip',showMethod);// If the hide event is not 'inactive', bind the hide methodif(self.options.hide.when.event!=='inactive')hideTarget.bind(self.options.hide.when.event+'.qtip',hideMethod);};// Focus the tooltip on mouseoverif(self.options.position.type.search(/(fixed|absolute)/)!==-1)self.elements.tooltip.bind('mouseover.qtip',self.focus);// If mouse is the target, update tooltip position on mousemoveif(self.options.position.target==='mouse'&&self.options.position.type!=='static'){showTarget.bind('mousemove.qtip',function(event){// Set the new mouse positions if adjustment is enabledself.cache.mouse={x:event.pageX,y:event.pageY};// Update the tooltip position only if the tooltip is visible and adjustment is enabledif(self.status.disabled===false&&self.options.position.adjust.mouse===true&&self.options.position.type!=='static'&&self.elements.tooltip.css('display')!=='none')self.updatePosition(event);});};};// Screen position adjustmentfunctionscreenAdjust(position,target,tooltip){varself,adjustedPosition,adjust,newCorner,overflow,corner;self=this;// Setup corner and adjustment variableif(tooltip.corner=='center')returntarget.position// TODO: 'center' corner adjustmentadjustedPosition=$.extend({},position);newCorner={x:false,y:false};// Define overflow propertiesoverflow={left:(adjustedPosition.left<$.fn.qtip.cache.screen.scroll.left),right:(adjustedPosition.left+tooltip.dimensions.width+2>=$.fn.qtip.cache.screen.width+$.fn.qtip.cache.screen.scroll.left),top:(adjustedPosition.top<$.fn.qtip.cache.screen.scroll.top),bottom:(adjustedPosition.top+tooltip.dimensions.height+2>=$.fn.qtip.cache.screen.height+$.fn.qtip.cache.screen.scroll.top)};// Determine new positioning propertiesadjust={left:(overflow.left&&(tooltip.corner.search(/right/i)!=-1||(tooltip.corner.search(/right/i)==-1&&!overflow.right))),right:(overflow.right&&(tooltip.corner.search(/left/i)!=-1||(tooltip.corner.search(/left/i)==-1&&!overflow.left))),top:(overflow.top&&tooltip.corner.search(/top/i)==-1),bottom:(overflow.bottom&&tooltip.corner.search(/bottom/i)==-1)};// Tooltip overflows off the left side of the screenif(adjust.left){if(self.options.position.target!=='mouse')adjustedPosition.left=target.position.left+target.dimensions.width;elseadjustedPosition.left=self.cache.mouse.xnewCorner.x='Left';}// Tooltip overflows off the right side of the screenelseif(adjust.right){if(self.options.position.target!=='mouse')adjustedPosition.left=target.position.left-tooltip.dimensions.width;elseadjustedPosition.left=self.cache.mouse.x-tooltip.dimensions.width;newCorner.x='Right';};// Tooltip overflows off the top of the screenif(adjust.top){if(self.options.position.target!=='mouse')adjustedPosition.top=target.position.top+target.dimensions.height;elseadjustedPosition.top=self.cache.mouse.ynewCorner.y='top';}// Tooltip overflows off the bottom of the screenelseif(adjust.bottom){if(self.options.position.target!=='mouse')adjustedPosition.top=target.position.top-tooltip.dimensions.height;elseadjustedPosition.top=self.cache.mouse.y-tooltip.dimensions.height;newCorner.y='bottom';};// Don't adjust if resulting position is negativeif(adjustedPosition.left<0){adjustedPosition.left=position.left;newCorner.x=false;};if(adjustedPosition.top<0){adjustedPosition.top=position.top;newCorner.y=false;};// Change tip corner if positioning has changed and tips are enabledif(self.options.style.tip.corner!==false){// Determine new corner propertiesadjustedPosition.corner=newString(tooltip.corner);if(newCorner.x!==false)adjustedPosition.corner=adjustedPosition.corner.replace(/Left|Right|Middle/,newCorner.x);if(newCorner.y!==false)adjustedPosition.corner=adjustedPosition.corner.replace(/top|bottom/,newCorner.y);// Adjust tip if position has changed and tips are enabledif(adjustedPosition.corner!==self.elements.tip.attr('rel'))createTip.call(self,adjustedPosition.corner);};returnadjustedPosition;};// Build a jQuery style object from supplied style objectfunctionjQueryStyle(style,sub){varstyleObj,i;styleObj=$.extend(true,{},style);for(iinstyleObj){if(sub===true&&i.search(/(tip|classes)/i)!==-1)deletestyleObj[i];elseif(!sub&&i.search(/(width|border|tip|title|classes|user)/i)!==-1)deletestyleObj[i];};returnstyleObj;};// Sanitize stylesfunctionsanitizeStyle(style){if(typeofstyle.tip!=='object')style.tip={corner:style.tip};if(typeofstyle.tip.size!=='object')style.tip.size={width:style.tip.size,height:style.tip.size};if(typeofstyle.border!=='object')style.border={width:style.border};if(typeofstyle.width!=='object')style.width={value:style.width};if(typeofstyle.width.max=='string')style.width.max=parseInt(style.width.max.replace(/([0-9]+)/i,"$1"));if(typeofstyle.width.min=='string')style.width.min=parseInt(style.width.min.replace(/([0-9]+)/i,"$1"));// Convert deprecated x and y tip values to width/heightif(typeofstyle.tip.size.x=='number'){style.tip.size.width=style.tip.size.x;deletestyle.tip.size.x;};if(typeofstyle.tip.size.y=='number'){style.tip.size.height=style.tip.size.y;deletestyle.tip.size.y;};returnstyle;};// Build styles recursively with inheritancefunctionbuildStyle(){varself,i,styleArray,styleExtend,finalStyle,ieAdjust;self=this;// Build style options from supplied argumentsstyleArray=[true,{}];for(i=0;i<arguments.length;i++)styleArray.push(arguments[i]);styleExtend=[$.extend.apply($,styleArray)];// Loop through each named style inheritancewhile(typeofstyleExtend[0].name=='string'){// Sanitize style data and append to extend arraystyleExtend.unshift(sanitizeStyle($.fn.qtip.styles[styleExtend[0].name]));};// Make sure resulting tooltip className represents final stylestyleExtend.unshift(true,{classes:{tooltip:'qtip-'+(arguments[0].name||'defaults')}},$.fn.qtip.styles.defaults);// Extend into a single style objectfinalStyle=$.extend.apply($,styleExtend);// Adjust tip size if needed (IE 1px adjustment bug fix)ieAdjust=($.browser.msie)?1:0;finalStyle.tip.size.width+=ieAdjust;finalStyle.tip.size.height+=ieAdjust;// Force even numbers for pixel precisionif(finalStyle.tip.size.width%2>0)finalStyle.tip.size.width+=1;if(finalStyle.tip.size.height%2>0)finalStyle.tip.size.height+=1;// Sanitize final styles tip corner valueif(finalStyle.tip.corner===true)finalStyle.tip.corner=(self.options.position.corner.tooltip==='center')?false:self.options.position.corner.tooltip;returnfinalStyle;};// Tip coordinates calculatorfunctioncalculateTip(corner,width,height){// Define tip coordinates in terms of height and width valuesvartips={bottomRight:[[0,0],[width,height],[width,0]],bottomLeft:[[0,0],[width,0],[0,height]],topRight:[[0,height],[width,0],[width,height]],topLeft:[[0,0],[0,height],[width,height]],topMiddle:[[0,height],[width/2,0],[width,height]],bottomMiddle:[[0,0],[width,0],[width/2,height]],rightMiddle:[[0,0],[width,height/2],[0,height]],leftMiddle:[[width,0],[width,height],[0,height/2]]};tips.leftTop=tips.bottomRight;tips.rightTop=tips.bottomLeft;tips.leftBottom=tips.topRight;tips.rightBottom=tips.topLeft;returntips[corner];};// Border coordinates calculatorfunctioncalculateBorders(radius){varborders;// Use canvas element if supportedif($('<canvas>').get(0).getContext){borders={topLeft:[radius,radius],topRight:[0,radius],bottomLeft:[radius,0],bottomRight:[0,0]};}// Canvas not supported - Use VML (IE)elseif($.browser.msie){borders={topLeft:[-90,90,0],topRight:[-90,90,-radius],bottomLeft:[90,270,0],bottomRight:[90,270,-radius]};};returnborders;};// BGIFRAME JQUERY PLUGIN ADAPTION// Special thanks to Brandon Aaron for this plugin// http://plugins.jquery.com/project/bgiframefunctionbgiframe(){varself,html,dimensions;self=this;dimensions=self.getDimensions();// Setup iframe HTML stringhtml='<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:false" '+'style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=\'0\'); border: 1px solid red; '+'height:'+dimensions.height+'px; width:'+dimensions.width+'px" />';// Append the new HTML and setup element referenceself.elements.bgiframe=self.elements.wrapper.prepend(html).children('.qtip-bgiframe:first');};// Assign cache and event initialisation on document load$(document).ready(function(){// Setup library cache with window scroll and dimensions of document$.fn.qtip.cache={screen:{scroll:{left:$(window).scrollLeft(),top:$(window).scrollTop()},width:$(window).width(),height:$(window).height()}};// Adjust positions of the tooltips on window resize or scroll if enabledvaradjustTimer;$(window).bind('resize scroll',function(event){clearTimeout(adjustTimer);adjustTimer=setTimeout(function(){// Readjust cached screen valuesif(event.type==='scroll')$.fn.qtip.cache.screen.scroll={left:$(window).scrollLeft(),top:$(window).scrollTop()};else{$.fn.qtip.cache.screen.width=$(window).width();$.fn.qtip.cache.screen.height=$(window).height();};for(i=0;i<$.fn.qtip.interfaces.length;i++){// Access current elements APIvarapi=$.fn.qtip.interfaces[i];// Update position if resize or scroll adjustments are enabledif(api.status.rendered===true&&(api.options.position.type!=='static'||api.options.position.adjust.scroll&&event.type==='scroll'||api.options.position.adjust.resize&&event.type==='resize')){// Queue the animation so positions are updated correctlyapi.updatePosition(event,true);}};},100);})// Hide unfocus toolipts on document mousedown$(document).bind('mousedown.qtip',function(event){if($(event.target).parents('div.qtip').length===0){$('.qtip[unfocus]').each(function(){varapi=$(this).qtip("api");// Only hide if its visible and not the tooltips targetif($(this).is(':visible')&&!api.status.disabled&&$(event.target).add(api.elements.target).length>1)api.hide(event);})};})});// Define qTip API interfaces array$.fn.qtip.interfaces=[]// Define log and constant place holders$.fn.qtip.log={error:function(){returnthis;}};$.fn.qtip.constants={};// Define configuration defaults$.fn.qtip.defaults={// Contentcontent:{prerender:false,text:false,url:false,data:null,title:{text:false,button:false}},// Positionposition:{target:false,corner:{target:'bottomRight',tooltip:'topLeft'},adjust:{x:0,y:0,mouse:true,screen:false,scroll:true,resize:true},type:'absolute',container:false},// Effectsshow:{when:{target:false,event:'mouseover'},effect:{type:'fade',length:100},delay:140,solo:false,ready:false},hide:{when:{target:false,event:'mouseout'},effect:{type:'fade',length:100},delay:0,fixed:false},// Callbacksapi:{beforeRender:function(){},onRender:function(){},beforePositionUpdate:function(){},onPositionUpdate:function(){},beforeShow:function(){},onShow:function(){},beforeHide:function(){},onHide:function(){},beforeContentUpdate:function(){},onContentUpdate:function(){},beforeContentLoad:function(){},onContentLoad:function(){},beforeTitleUpdate:function(){},onTitleUpdate:function(){},beforeDestroy:function(){},onDestroy:function(){},beforeFocus:function(){},onFocus:function(){}}};$.fn.qtip.styles={defaults:{background:'white',color:'#111',overflow:'hidden',textAlign:'left',width:{min:0,max:250},padding:'5px 9px',border:{width:1,radius:0,color:'#d3d3d3'},tip:{corner:false,color:false,size:{width:13,height:13},opacity:1},title:{background:'#e1e1e1',fontWeight:'bold',padding:'7px 12px'},button:{cursor:'pointer'},classes:{target:'',tip:'qtip-tip',title:'qtip-title',button:'qtip-button',content:'qtip-content',active:'qtip-active'}},cream:{border:{width:3,radius:0,color:'#F9E98E'},title:{background:'#F0DE7D',color:'#A27D35'},background:'#FBF7AA',color:'#A27D35',classes:{tooltip:'qtip-cream'}},light:{border:{width:3,radius:0,color:'#E2E2E2'},title:{background:'#f1f1f1',color:'#454545'},background:'white',color:'#454545',classes:{tooltip:'qtip-light'}},dark:{border:{width:3,radius:0,color:'#303030'},title:{background:'#404040',color:'#f3f3f3'},background:'#505050',color:'#f3f3f3',classes:{tooltip:'qtip-dark'}},red:{border:{width:3,radius:0,color:'#CE6F6F'},title:{background:'#f28279',color:'#9C2F2F'},background:'#F79992',color:'#9C2F2F',classes:{tooltip:'qtip-red'}},green:{border:{width:3,radius:0,color:'#A9DB66'},title:{background:'#b9db8c',color:'#58792E'},background:'#CDE6AC',color:'#58792E',classes:{tooltip:'qtip-green'}},blue:{border:{width:3,radius:0,color:'#ADD9ED'},title:{background:'#D0E9F5',color:'#5E99BD'},background:'#E5F6FE',color:'#4D9FBF',classes:{tooltip:'qtip-blue'}}};})(jQuery);