2008-06-30 10:11:10 +02:00
/ *
* jQuery clueTip plugin
* Version 0.9 . 8 ( 05 / 22 / 2008 )
* @ requires jQuery v1 . 1.4 +
* @ requires Dimensions plugin ( for jQuery versions < 1.2 . 5 )
*
* Dual licensed under the MIT and GPL licenses :
* http : //www.opensource.org/licenses/mit-license.php
* http : //www.gnu.org/licenses/gpl.html
*
* /
; ( function ( $ ) { var $cluetip , $cluetipInner , $cluetipOuter , $cluetipTitle , $cluetipArrows , $dropShadow , imgCount ; $ . fn . cluetip = function ( js , options ) { if ( typeof js == 'object' ) { options = js ; js = null ; }
return this . each ( function ( index ) { var $this = $ ( this ) ; var opts = $ . extend ( false , { } , $ . fn . cluetip . defaults , options || { } , $ . metadata ? $this . metadata ( ) : $ . meta ? $this . data ( ) : { } ) ; var cluetipContents = false ; var cluezIndex = parseInt ( opts . cluezIndex , 10 ) - 1 ; var isActive = false , closeOnDelay = 0 ; if ( ! $ ( '#cluetip' ) . length ) { $cluetipInner = $ ( '<div id="cluetip-inner"></div>' ) ; $cluetipTitle = $ ( '<h3 id="cluetip-title"></h3>' ) ; $cluetipOuter = $ ( '<div id="cluetip-outer"></div>' ) . append ( $cluetipInner ) . prepend ( $cluetipTitle ) ; $cluetip = $ ( '<div id="cluetip"></div>' ) . css ( { zIndex : opts . cluezIndex } ) . append ( $cluetipOuter ) . append ( '<div id="cluetip-extra"></div>' ) [ insertionType ] ( insertionElement ) . hide ( ) ; $ ( '<div id="cluetip-waitimage"></div>' ) . css ( { position : 'absolute' , zIndex : cluezIndex - 1 } ) . insertBefore ( '#cluetip' ) . hide ( ) ; $cluetip . css ( { position : 'absolute' , zIndex : cluezIndex } ) ; $cluetipOuter . css ( { position : 'relative' , zIndex : cluezIndex + 1 } ) ; $cluetipArrows = $ ( '<div id="cluetip-arrows" class="cluetip-arrows"></div>' ) . css ( { zIndex : cluezIndex + 1 } ) . appendTo ( '#cluetip' ) ; }
var dropShadowSteps = ( opts . dropShadow ) ? + opts . dropShadowSteps : 0 ; if ( ! $dropShadow ) { $dropShadow = $ ( [ ] ) ; for ( var i = 0 ; i < dropShadowSteps ; i ++ ) { $dropShadow = $dropShadow . add ( $ ( '<div></div>' ) . css ( { zIndex : cluezIndex - i - 1 , opacity : . 1 , top : 1 + i , left : 1 + i } ) ) ; } ; $dropShadow . css ( { position : 'absolute' , backgroundColor : '#000' } ) . prependTo ( $cluetip ) ; }
var tipAttribute = $this . attr ( opts . attribute ) , ctClass = opts . cluetipClass ; if ( ! tipAttribute && ! opts . splitTitle && ! js ) return true ; if ( opts . local && opts . hideLocal ) { $ ( tipAttribute + ':first' ) . hide ( ) ; }
var tOffset = parseInt ( opts . topOffset , 10 ) , lOffset = parseInt ( opts . leftOffset , 10 ) ; var tipHeight , wHeight ; var defHeight = isNaN ( parseInt ( opts . height , 10 ) ) ? 'auto' : ( /\D/g ) . test ( opts . height ) ? opts . height : opts . height + 'px' ; var sTop , linkTop , posY , tipY , mouseY , baseline ; var tipInnerWidth = isNaN ( parseInt ( opts . width , 10 ) ) ? 275 : parseInt ( opts . width , 10 ) ; var tipWidth = tipInnerWidth + ( parseInt ( $cluetip . css ( 'paddingLeft' ) ) || 0 ) + ( parseInt ( $cluetip . css ( 'paddingRight' ) ) || 0 ) + dropShadowSteps ; var linkWidth = this . offsetWidth ; var linkLeft , posX , tipX , mouseX , winWidth ; var tipParts ; var tipTitle = ( opts . attribute != 'title' ) ? $this . attr ( opts . titleAttribute ) : '' ; if ( opts . splitTitle ) { if ( tipTitle == undefined ) { tipTitle = '' ; }
tipParts = tipTitle . split ( opts . splitTitle ) ; tipTitle = tipParts . shift ( ) ; }
var localContent ; var activate = function ( event ) { if ( ! opts . onActivate ( $this ) ) { return false ; }
isActive = true ; $cluetip . removeClass ( ) . css ( { width : tipInnerWidth } ) ; if ( tipAttribute == $this . attr ( 'href' ) ) { $this . css ( 'cursor' , opts . cursor ) ; }
$this . attr ( 'title' , '' ) ; if ( opts . hoverClass ) { $this . addClass ( opts . hoverClass ) ; }
linkTop = posY = $this . offset ( ) . top ; linkLeft = $this . offset ( ) . left ; mouseX = event . pageX ; mouseY = event . pageY ; if ( $this [ 0 ] . tagName . toLowerCase ( ) != 'area' ) { sTop = $ ( document ) . scrollTop ( ) ; winWidth = $ ( window ) . width ( ) ; }
if ( opts . positionBy == 'fixed' ) { posX = linkWidth + linkLeft + lOffset ; $cluetip . css ( { left : posX } ) ; } else { posX = ( linkWidth > linkLeft && linkLeft > tipWidth ) || linkLeft + linkWidth + tipWidth + lOffset > winWidth ? linkLeft - tipWidth - lOffset : linkWidth + linkLeft + lOffset ; if ( $this [ 0 ] . tagName . toLowerCase ( ) == 'area' || opts . positionBy == 'mouse' || linkWidth + tipWidth > winWidth ) { if ( mouseX + 20 + tipWidth > winWidth ) { $cluetip . addClass ( ' cluetip-' + ctClass ) ; posX = ( mouseX - tipWidth - lOffset ) >= 0 ? mouseX - tipWidth - lOffset - parseInt ( $cluetip . css ( 'marginLeft' ) , 10 ) + parseInt ( $cluetipInner . css ( 'marginRight' ) , 10 ) : mouseX - ( tipWidth / 2 ) ; } else { posX = mouseX + lOffset ; } }
var pY = posX < 0 ? event . pageY + tOffset : event . pageY ; $cluetip . css ( { left : ( posX > 0 && opts . positionBy != 'bottomTop' ) ? posX : ( mouseX + ( tipWidth / 2 ) > winWidth ) ? winWidth / 2 - tipWidth / 2 : Math . max ( mouseX - ( tipWidth / 2 ) , 0 ) } ) ; }
wHeight = $ ( window ) . height ( ) ; if ( js ) { $cluetipInner . html ( js ) ; cluetipShow ( pY ) ; }
else if ( tipParts ) { var tpl = tipParts . length ; for ( var i = 0 ; i < tpl ; i ++ ) { if ( i == 0 ) { $cluetipInner . html ( tipParts [ i ] ) ; } else { $cluetipInner . append ( '<div class="split-body">' + tipParts [ i ] + '</div>' ) ; } } ; cluetipShow ( pY ) ; }
else if ( ! opts . local && tipAttribute . indexOf ( '#' ) != 0 ) { if ( cluetipContents && opts . ajaxCache ) { $cluetipInner . html ( cluetipContents ) ; cluetipShow ( pY ) ; }
2013-05-30 17:48:22 +02:00
else { var ajaxSettings = opts . ajaxSettings ; ajaxSettings . url = tipAttribute ; ajaxSettings . beforeSend = function ( ) { $cluetipOuter . children ( ) . empty ( ) ; if ( opts . waitImage ) { $ ( '#cluetip-waitimage' ) . css ( { top : mouseY + 20 , left : mouseX + 20 } ) . show ( ) ; } } ; ajaxSettings . error = function ( ) { if ( isActive ) { $cluetipInner . html ( '<i>sorry, the contents could not be loaded</i>' ) ; } } ; ajaxSettings . success = function ( data ) { cluetipContents = opts . ajaxProcess ( data ) ; if ( isActive ) { $cluetipInner . html ( cluetipContents ) ; } } ; ajaxSettings . complete = function ( ) { imgCount = $ ( '#cluetip-inner img' ) . length ; $ ( '#cluetip-waitimage' ) . hide ( ) ; if ( isActive ) cluetipShow ( pY ) ; } ; $ . ajax ( ajaxSettings ) ; } } else if ( opts . local ) { var $localContent = $ ( tipAttribute + ':first' ) ; var localCluetip = $ . fn . wrapInner ? $localContent . wrapInner ( '<div></div>' ) . children ( ) . clone ( true ) : $localContent . html ( ) ; $ . fn . wrapInner ? $cluetipInner . empty ( ) . append ( localCluetip ) : $cluetipInner . html ( localCluetip ) ; cluetipShow ( pY ) ; } } ; var cluetipShow = function ( bpY ) { $cluetip . addClass ( 'cluetip-' + ctClass ) ; if ( opts . truncate ) { var $truncloaded = $cluetipInner . text ( ) . slice ( 0 , opts . truncate ) + '...' ; $cluetipInner . html ( $truncloaded ) ; }
2008-06-30 10:11:10 +02:00
function doNothing ( ) { } ; tipTitle ? $cluetipTitle . show ( ) . html ( tipTitle ) : ( opts . showTitle ) ? $cluetipTitle . show ( ) . html ( ' ' ) : $cluetipTitle . hide ( ) ; if ( opts . sticky ) { var $closeLink = $ ( '<div id="cluetip-close"><a href="#">' + opts . closeText + '</a></div>' ) ; ( opts . closePosition == 'bottom' ) ? $closeLink . appendTo ( $cluetipInner ) : ( opts . closePosition == 'title' ) ? $closeLink . prependTo ( $cluetipTitle ) : $closeLink . prependTo ( $cluetipInner ) ; $closeLink . click ( function ( ) { cluetipClose ( ) ; return false ; } ) ; if ( opts . mouseOutClose ) { if ( $ . fn . hoverIntent && opts . hoverIntent ) { $cluetip . hoverIntent ( { over : doNothing , timeout : opts . hoverIntent . timeout , out : function ( ) { $closeLink . trigger ( 'click' ) ; } } ) ; } else { $cluetip . hover ( doNothing , function ( ) { $closeLink . trigger ( 'click' ) ; } ) ; } } else { $cluetip . unbind ( 'mouseout' ) ; } }
var direction = '' ; $cluetipOuter . css ( { overflow : defHeight == 'auto' ? 'visible' : 'auto' , height : defHeight } ) ; tipHeight = defHeight == 'auto' ? Math . max ( $cluetip . outerHeight ( ) , $cluetip . height ( ) ) : parseInt ( defHeight , 10 ) ; tipY = posY ; baseline = sTop + wHeight ; if ( opts . positionBy == 'fixed' ) { tipY = posY - opts . dropShadowSteps + tOffset ; } else if ( ( posX < mouseX && Math . max ( posX , 0 ) + tipWidth > mouseX ) || opts . positionBy == 'bottomTop' ) { if ( posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset ) { tipY = mouseY - tipHeight - tOffset ; direction = 'top' ; } else { tipY = mouseY + tOffset ; direction = 'bottom' ; } } else if ( posY + tipHeight + tOffset > baseline ) { tipY = ( tipHeight >= wHeight ) ? sTop : baseline - tipHeight - tOffset ; } else if ( $this . css ( 'display' ) == 'block' || $this [ 0 ] . tagName . toLowerCase ( ) == 'area' || opts . positionBy == "mouse" ) { tipY = bpY - tOffset ; } else { tipY = posY - opts . dropShadowSteps ; }
if ( direction == '' ) { posX < linkLeft ? direction = 'left' : direction = 'right' ; }
$cluetip . css ( { top : tipY + 'px' } ) . removeClass ( ) . addClass ( 'clue-' + direction + '-' + ctClass ) . addClass ( ' cluetip-' + ctClass ) ; if ( opts . arrows ) { var bgY = ( posY - tipY - opts . dropShadowSteps ) ; $cluetipArrows . css ( { top : ( /(left|right)/ . test ( direction ) && posX >= 0 && bgY > 0 ) ? bgY + 'px' : /(left|right)/ . test ( direction ) ? 0 : '' } ) . show ( ) ; } else { $cluetipArrows . hide ( ) ; }
$dropShadow . hide ( ) ; $cluetip . hide ( ) [ opts . fx . open ] ( opts . fx . open != 'show' && opts . fx . openSpeed ) ; if ( opts . dropShadow ) $dropShadow . css ( { height : tipHeight , width : tipInnerWidth } ) . show ( ) ; if ( $ . fn . bgiframe ) { $cluetip . bgiframe ( ) ; }
if ( opts . delayedClose > 0 ) { closeOnDelay = setTimeout ( cluetipClose , opts . delayedClose ) ; }
opts . onShow ( $cluetip , $cluetipInner ) ; } ; var inactivate = function ( ) { isActive = false ; $ ( '#cluetip-waitimage' ) . hide ( ) ; if ( ! opts . sticky || ( /click|toggle/ ) . test ( opts . activation ) ) { cluetipClose ( ) ; clearTimeout ( closeOnDelay ) ; } ; if ( opts . hoverClass ) { $this . removeClass ( opts . hoverClass ) ; }
$ ( '.cluetip-clicked' ) . removeClass ( 'cluetip-clicked' ) ; } ; var cluetipClose = function ( ) { $cluetipOuter . parent ( ) . hide ( ) . removeClass ( ) . end ( ) . children ( ) . empty ( ) ; if ( tipTitle ) { $this . attr ( opts . titleAttribute , tipTitle ) ; }
$this . css ( 'cursor' , '' ) ; if ( opts . arrows ) $cluetipArrows . css ( { top : '' } ) ; } ; if ( ( /click|toggle/ ) . test ( opts . activation ) ) { $this . click ( function ( event ) { if ( $cluetip . is ( ':hidden' ) || ! $this . is ( '.cluetip-clicked' ) ) { activate ( event ) ; $ ( '.cluetip-clicked' ) . removeClass ( 'cluetip-clicked' ) ; $this . addClass ( 'cluetip-clicked' ) ; } else { inactivate ( event ) ; }
this . blur ( ) ; return false ; } ) ; } else if ( opts . activation == 'focus' ) { $this . focus ( function ( event ) { activate ( event ) ; } ) ; $this . blur ( function ( event ) { inactivate ( event ) ; } ) ; } else { $this . click ( function ( ) { if ( $this . attr ( 'href' ) && $this . attr ( 'href' ) == tipAttribute && ! opts . clickThrough ) { return false ; } } ) ; var mouseTracks = function ( evt ) { if ( opts . tracking == true ) { var trackX = posX - evt . pageX ; var trackY = tipY ? tipY - evt . pageY : posY - evt . pageY ; $this . mousemove ( function ( evt ) { $cluetip . css ( { left : evt . pageX + trackX , top : evt . pageY + trackY } ) ; } ) ; } } ; if ( $ . fn . hoverIntent && opts . hoverIntent ) { $this . mouseover ( function ( ) { $this . attr ( 'title' , '' ) ; } ) . hoverIntent ( { sensitivity : opts . hoverIntent . sensitivity , interval : opts . hoverIntent . interval , over : function ( event ) { activate ( event ) ; mouseTracks ( event ) ; } , timeout : opts . hoverIntent . timeout , out : function ( event ) { inactivate ( event ) ; $this . unbind ( 'mousemove' ) ; } } ) ; } else { $this . hover ( function ( event ) { activate ( event ) ; mouseTracks ( event ) ; } , function ( event ) { inactivate ( event ) ; $this . unbind ( 'mousemove' ) ; } ) ; } } } ) ; } ; $ . fn . cluetip . defaults = { width : 275 , height : 'auto' , cluezIndex : 97 , positionBy : 'auto' , topOffset : 15 , leftOffset : 15 , local : false , hideLocal : true , attribute : 'rel' , titleAttribute : 'title' , splitTitle : '' , showTitle : true , cluetipClass : 'default' , hoverClass : '' , waitImage : true , cursor : 'help' , arrows : false , dropShadow : true , dropShadowSteps : 6 , sticky : false , mouseOutClose : false , activation : 'hover' , clickThrough : false , tracking : false , delayedClose : 0 , closePosition : 'top' , closeText : 'Close' , truncate : 0 , fx : { open : 'show' , openSpeed : '' } , hoverIntent : { sensitivity : 3 , interval : 50 , timeout : 0 } , onActivate : function ( e ) { return true ; } , onShow : function ( ct , c ) { } , ajaxCache : true , ajaxProcess : function ( data ) { data = data . replace ( /<s(cript|tyle)(.|\s)*?\/s(cript|tyle)>/g , '' ) . replace ( /<(link|title)(.|\s)*?\/(link|title)>/g , '' ) ; return data ; } , ajaxSettings : { dataType : 'html' } , debug : false } ; var insertionType = 'appendTo' , insertionElement = 'body' ; $ . cluetip = { } ; $ . cluetip . setup = function ( options ) { if ( options && options . insertionType && ( options . insertionType ) . match ( /appendTo|prependTo|insertBefore|insertAfter/ ) ) { insertionType = options . insertionType ; }
if ( options && options . insertionElement ) { insertionElement = options . insertionElement ; } } ; } ) ( jQuery ) ;