Ignore:
Timestamp:
Oct 11, 2012, 11:29:28 PM (12 years ago)
Author:
rvelices
Message:

upgrade cluetip version from 1.0.7 to 1.2.6

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/themes/default/js/plugins/jquery.cluetip.js

    r9553 r18610  
    1 /*
    2  * jQuery clueTip plugin
    3  * Version 1.0.7  (January 28, 2010)
    4  * @requires jQuery v1.3+
     1/*!
     2 * jQuery clueTip plugin v1.2.6
    53 *
     4 * Date: Sun Sep 09 22:07:58 2012 EDT
     5 * Requires: jQuery v1.3+
     6 *
     7 * Copyright 2012, Karl Swedberg
    68 * Dual licensed under the MIT and GPL licenses:
    79 * http://www.opensource.org/licenses/mit-license.php
    810 * http://www.gnu.org/licenses/gpl.html
    911 *
    10  */
    11  
    12 /*
    13  *
    14  * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
    1512 *
    1613 * Examples can be found at http://plugins.learningjquery.com/cluetip/demo/
     
    1815*/
    1916
    20 ;(function($) {
    21   $.cluetip = {version: '1.0.6'};
    22   var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $cluetipWait, $dropShadow, imgCount;
    23  
     17(function($) {
     18
     19  $.cluetip = {
     20    version: '1.2.6',
     21
     22    // the HTML that will be used for the tooltip
     23    template: ['<div>',
     24      '<div class="cluetip-outer">',
     25        '<h3 class="cluetip-title ui-widget-header ui-cluetip-header"></h3>',
     26        '<div class="cluetip-inner ui-widget-content ui-cluetip-content"></div>',
     27      '</div>',
     28      '<div class="cluetip-extra"></div>',
     29    '</div>'].join(''),
     30
     31    /* clueTip setup
     32     *  the setup options are applied each time .cluetip() is called,
     33     *  BUT only if <div id="cluetip"> is not already in the document
     34    */
     35    setup: {
     36      // method to be used for inserting the clueTip into the DOM.
     37      // Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
     38      insertionType: 'appendTo',
     39      // element in the DOM the plugin will reference when inserting the clueTip.
     40      insertionElement: 'body'
     41    },
     42
     43    /*
     44     * clueTip options
     45     *
     46     * each one can be explicitly overridden by changing its value.
     47     * for example: $.cluetip.defaults.width = 200;
     48     *         or: $.fn.cluetip.defaults.width = 200; // for compatibility with previous clueTip versions
     49     * would change the default width for all clueTips to 200.
     50     *
     51     * each one can also be overridden by passing an options map to the cluetip method.
     52     * for example: $('a.example').cluetip({width: 200});
     53     * would change the default width to 200 for clueTips invoked by a link with class of "example"
     54     *
     55    */
     56    defaults: {
     57      multiple:         false,    // Allow a new tooltip to be created for each .cluetip() call
     58      width:            275,      // The width of the clueTip
     59      height:           'auto',   // The height of the clueTip
     60      cluezIndex:       97,       // Sets the z-index style property of the clueTip
     61      positionBy:       'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'topBottom', fixed'
     62      topOffset:        15,       // Number of px to offset clueTip from top of invoking element
     63      leftOffset:       15,       // Number of px to offset clueTip from left of invoking element
     64      snapToEdge:       false,    // For bottomTop and topBottom, snap to the top or bottom of the element.
     65      local:            false,    // Whether to use content from the same page for the clueTip's body
     66      localPrefix:      null,     // string to be prepended to the tip attribute if local is true
     67      localIdSuffix:    null,     // string to be appended to the cluetip content element's id if local is true
     68      hideLocal:        true,     // If local option is set to true, this determines whether local content
     69                                  // to be shown in clueTip should be hidden at its original location
     70      attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
     71      titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
     72      splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
     73                                  // within the clueTip body. more info below [6]
     74      escapeTitle:      false,    // whether to html escape the title attribute
     75      showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
     76      cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
     77      hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
     78      waitImage:        true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
     79      cursor:           'help',
     80      arrows:           false,    // if true, displays arrow on appropriate side of clueTip
     81      dropShadow:       true,     // set to false if you don't want the drop-shadow effect on the clueTip
     82      dropShadowSteps:  6,        // adjusts the size of the drop shadow
     83      sticky:           false,    // keep visible until manually closed
     84      mouseOutClose:    false,    // close when clueTip is moused out: false, 'cluetip', 'link', 'both'
     85      delayedClose:     50,        // close clueTip on a timed delay
     86      activation:       'hover',  // set to 'click' to force user to click to show clueTip
     87                                  // set to 'focus' to show on focus of a form element and hide on blur
     88      clickThrough:     true,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
     89                                  // even if href and tipAttribute are equal
     90      tracking:         false,    // if true, clueTip will track mouse movement (experimental)
     91      closePosition:    'top',    // location of close text for sticky cluetips; can be 'top', 'bottom', 'title' or 'none'
     92      closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
     93      truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs
     94
     95      // effect and speed for opening clueTips
     96      fx: {
     97                        open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
     98                        openSpeed:  ''
     99      },
     100
     101      // settings for when hoverIntent plugin is used
     102      hoverIntent: {
     103                        sensitivity:  3,
     104                        interval:     50,
     105                        timeout:      0
     106      },
     107
     108      // short-circuit function to run just before clueTip is shown.
     109      onActivate:       function(e) {return true;},
     110      // function to run just after clueTip is shown.
     111      onShow:           function(ct, ci){},
     112      // function to run just after clueTip is hidden.
     113      onHide:           function(ct, ci){},
     114      // whether to cache results of ajax request to avoid unnecessary hits to server
     115      ajaxCache:        true,
     116
     117      // process data retrieved via xhr before it's displayed
     118      ajaxProcess:      function(data) {
     119                          data = data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, '').replace(/<(link|meta)[^>]+>/g,'');
     120                          return data;
     121      },
     122
     123      // can pass in standard $.ajax() parameters. Callback functions, such as beforeSend,
     124      // will be queued first within the default callbacks.
     125      // The only exception is error, which overrides the default
     126      ajaxSettings: {
     127                        // error: function(ct, ci) { /* override default error callback */ },
     128                        // beforeSend: function(ct, ci) { /* called first within default beforeSend callback */ },
     129                        dataType: 'html'
     130      },
     131      debug: false
     132
     133    }
     134  };
     135  var $cluetipWait,
     136      standardClasses = 'cluetip ui-widget ui-widget-content ui-cluetip',
     137      caches = {},
     138      counter = 0,
     139      imgCount = 0;
     140
     141  // use $.fn.prop() if available (jQuery 1.6+); otherwise, $.fn.attr()
     142  $.fn.attrProp = $.fn.prop || $.fn.attr;
     143
     144  // .cluetip() method
    24145  $.fn.cluetip = function(js, options) {
     146    var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $dropShadow;
    25147    if (typeof js == 'object') {
    26148      options = js;
     
    28150    }
    29151    if (js == 'destroy') {
    30       return this.removeData('thisInfo').unbind('.cluetip');
     152      var data = this.data('cluetip');
     153      if ( data ) {
     154        $(data.selector).remove();
     155        $.removeData(this, 'title');
     156        $.removeData(this, 'cluetip');
     157        $.removeData(this, 'cluetipMoc');
     158      }
     159      $(document).unbind('.cluetip');
     160      return this.unbind('.cluetip');
    31161    }
    32     return this.each(function(index) {
    33       var link = this, $this = $(this);
    34      
    35       // support metadata plugin (v1.0 and 2.0)
    36       var opts = $.extend(true, {}, $.fn.cluetip.defaults, options || {}, $.metadata ? $this.metadata() : $.meta ? $this.data() : {});
    37 
    38       // start out with no contents (for ajax activation)
    39       var cluetipContents = false;
    40       var cluezIndex = +opts.cluezIndex;
    41       $this.data('thisInfo', {title: link.title, zIndex: cluezIndex});
    42       var isActive = false, closeOnDelay = 0;
    43 
    44       // create the cluetip divs
    45       if (!$('#cluetip').length) {
    46         $(['<div id="cluetip">',
    47           '<div id="cluetip-outer">',
    48             '<h3 id="cluetip-title"></h3>',
    49             '<div id="cluetip-inner"></div>',
    50           '</div>',
    51           '<div id="cluetip-extra"></div>',
    52           '<div id="cluetip-arrows" class="cluetip-arrows"></div>',
    53         '</div>'].join(''))
    54         [insertionType](insertionElement).hide();
    55        
    56         $cluetip = $('#cluetip').css({position: 'absolute'});
    57         $cluetipOuter = $('#cluetip-outer').css({position: 'relative', zIndex: cluezIndex});
    58         $cluetipInner = $('#cluetip-inner');
    59         $cluetipTitle = $('#cluetip-title');       
    60         $cluetipArrows = $('#cluetip-arrows');
    61         $cluetipWait = $('<div id="cluetip-waitimage"></div>')
    62           .css({position: 'absolute'}).insertBefore($cluetip).hide();
    63       }
    64       var dropShadowSteps = (opts.dropShadow) ? +opts.dropShadowSteps : 0;
    65       if (!$dropShadow) {
    66         $dropShadow = $([]);
    67         for (var i=0; i < dropShadowSteps; i++) {
    68           $dropShadow = $dropShadow.add($('<div></div>').css({zIndex: cluezIndex-1, opacity:.1, top: 1+i, left: 1+i}));
    69         }
    70         $dropShadow.css({position: 'absolute', backgroundColor: '#000'})
    71         .prependTo($cluetip);
    72       }
    73       var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
     162
     163    // merge per-call options with defaults
     164    options = $.extend(true, {}, $.cluetip.defaults, options || {});
     165
     166    /** =create cluetip divs **/
     167    counter++;
     168    var cluezIndex,
     169        cluetipId = $.cluetip.backCompat || !options.multiple ? 'cluetip' : 'cluetip-' + counter,
     170        cluetipSelector = '#' + cluetipId,
     171        prefix = $.cluetip.backCompat ? '#' : '.',
     172        insertionType = $.cluetip.setup.insertionType,
     173        insertionElement = $.cluetip.setup.insertionElement || 'body';
     174
     175    insertionType = (/appendTo|prependTo|insertBefore|insertAfter/).test(insertionType) ? insertionType : 'appendTo';
     176    $cluetip = $(cluetipSelector);
     177    if (!$cluetip.length) {
     178
     179      $cluetip = $($.cluetip.template)
     180      [insertionType](insertionElement)
     181      .attr('id', cluetipId)
     182      .css({position: 'absolute', display: 'none'});
     183
     184      cluezIndex = +options.cluezIndex;
     185      $cluetipOuter = $cluetip.find(prefix + 'cluetip-outer').css({position: 'relative', zIndex: cluezIndex});
     186      $cluetipInner = $cluetip.find(prefix + 'cluetip-inner');
     187      $cluetipTitle = $cluetip.find(prefix + 'cluetip-title');
     188
     189      $cluetip.bind('mouseenter mouseleave', function(event) {
     190        $(this).data('entered', event.type === 'mouseenter');
     191      });
     192    }
     193
     194    $cluetipWait = $('#cluetip-waitimage');
     195    if (!$cluetipWait.length && options.waitImage) {
     196      $cluetipWait = $('<div></div>').attr('id', 'cluetip-waitimage').css({position: 'absolute'});
     197      $cluetipWait.insertBefore($cluetip).hide();
     198    }
     199
     200
     201    var cluetipPadding = (parseInt($cluetip.css('paddingLeft'), 10) || 0) + (parseInt($cluetip.css('paddingRight'), 10) || 0);
     202
     203
     204    this.each(function(index) {
     205      var link = this,
     206          $link = $(this),
     207          // support metadata plugin (v1.0 and 2.0)
     208          opts = $.extend(true, {}, options, $.metadata ? $link.metadata() : $.meta ? $link.data() : $link.data('cluetip') || {}),
     209          // start out with no contents (for ajax activation)
     210          cluetipContents = false,
     211          isActive = false,
     212          closeOnDelay = null,
     213          tipAttribute = opts[opts.attribute] ||
     214            ( opts.attribute == 'href' ? $link.attr(opts.attribute) : $link.attrProp(opts.attribute) || $link.attr(opts.attribute) ),
     215          ctClass = opts.cluetipClass;
     216
     217      cluezIndex = +opts.cluezIndex;
     218      $link.data('cluetip', {title: link.title, zIndex: cluezIndex, selector: cluetipSelector});
     219
     220      if (opts.arrows && !$cluetip.find('.cluetip-arrows').length) {
     221        $cluetip.append('<div class="cluetip-arrows ui-state-default"></div>');
     222      }
     223
    74224      if (!tipAttribute && !opts.splitTitle && !js) {
    75225        return true;
     
    77227      // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip
    78228      if (opts.local && opts.localPrefix) {tipAttribute = opts.localPrefix + tipAttribute;}
    79       if (opts.local && opts.hideLocal) { $(tipAttribute + ':first').hide(); }
     229      if (opts.local && opts.hideLocal && tipAttribute) { $(tipAttribute + ':first').hide(); }
     230
    80231      var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
    81232      // vertical measurement variables
    82233      var tipHeight, wHeight,
    83234          defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
    84       var sTop, linkTop, posY, tipY, mouseY, baseline;
     235      var sTop, linkTop, linkBottom, posY, tipY, mouseY, baseline;
    85236      // horizontal measurement variables
    86237      var tipInnerWidth = parseInt(opts.width, 10) || 275,
    87           tipWidth = tipInnerWidth + (parseInt($cluetip.css('paddingLeft'),10)||0) + (parseInt($cluetip.css('paddingRight'),10)||0) + dropShadowSteps,
     238          tipWidth = tipInnerWidth + cluetipPadding + opts.dropShadowSteps,
    88239          linkWidth = this.offsetWidth,
    89240          linkLeft, posX, tipX, mouseX, winWidth;
    90            
     241
    91242      // parse the title
    92243      var tipParts;
    93       var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
     244      var tipTitle = (opts.attribute != 'title') ? $link.attrProp(opts.titleAttribute) || '' : '';
    94245      if (opts.splitTitle) {
    95         if (tipTitle == undefined) {tipTitle = '';}
    96246        tipParts = tipTitle.split(opts.splitTitle);
    97         tipTitle = tipParts.shift();
     247        tipTitle = opts.showTitle || tipParts[0] === '' ? tipParts.shift() : '';
    98248      }
    99249      if (opts.escapeTitle) {
    100250        tipTitle = tipTitle.replace(/&/g,'&amp;').replace(/>/g,'&gt;').replace(/</g,'&lt;');
    101251      }
    102      
     252
    103253      var localContent;
    104254      function returnFalse() { return false; }
    105255
    106 /***************************************     
     256      // Keep track of mouse entered state on link
     257      $link.bind('mouseenter mouseleave', function(event) {
     258        var data = $link.data('cluetip');
     259        data.entered = event.type === 'entered';
     260        $link.data('cluetip', data);
     261      });
     262
     263/***************************************
    107264* ACTIVATION
    108265****************************************/
    109    
     266
    110267//activate clueTip
    111268    var activate = function(event) {
    112       if (!opts.onActivate($this)) {
     269      var pY, ajaxMergedSettings, cacheKey,
     270          continueOn = opts.onActivate.call(link, event);
     271
     272      if (continueOn === false) {
    113273        return false;
    114274      }
     275
    115276      isActive = true;
     277
     278      // activate function may get called after an initialization of a
     279      // different target so need to re-get the Correct Cluetip object here
     280      $cluetip = $(cluetipSelector).css({position: 'absolute'});
     281      $cluetipOuter = $cluetip.find(prefix + 'cluetip-outer');
     282      $cluetipInner = $cluetip.find(prefix + 'cluetip-inner');
     283      $cluetipTitle = $cluetip.find(prefix + 'cluetip-title');
     284      $cluetipArrows = $cluetip.find(prefix + 'cluetip-arrows');
    116285      $cluetip.removeClass().css({width: tipInnerWidth});
    117       if (tipAttribute == $this.attr('href')) {
    118         $this.css('cursor', opts.cursor);
     286      if (tipAttribute == $link.attr('href')) {
     287        $link.css('cursor', opts.cursor);
    119288      }
    120289      if (opts.hoverClass) {
    121         $this.addClass(opts.hoverClass);
    122       }
    123       linkTop = posY = $this.offset().top;
    124       linkLeft = $this.offset().left;
    125       mouseX = event.pageX;
    126       mouseY = event.pageY;
     290        $link.addClass(opts.hoverClass);
     291      }
     292      linkTop = posY = $link.offset().top;
     293      linkBottom = linkTop + $link.innerHeight();
     294      linkLeft = $link.offset().left;
     295
     296      // FIX: (bug 4412)
     297      linkWidth = $link.innerWidth();
     298      if ( event.type == focus ) {
     299        // in focus event, no mouse position is available; this is needed with bottomTop:
     300        mouseX = linkLeft +  ( linkWidth / 2 ) + lOffset;
     301        $cluetip.css({left: posX});
     302        mouseY = posY + tOffset;
     303      } else {
     304        mouseX = event.pageX;
     305        mouseY = event.pageY;
     306      }
     307      //END OF FIX
     308
    127309      if (link.tagName.toLowerCase() != 'area') {
    128310        sTop = $(document).scrollTop();
     
    134316        $cluetip.css({left: posX});
    135317      } else {
    136         posX = (linkWidth > linkLeft && linkLeft > tipWidth)
    137           || linkLeft + linkWidth + tipWidth + lOffset > winWidth
    138           ? linkLeft - tipWidth - lOffset
    139           : linkWidth + linkLeft + lOffset;
     318        posX = (linkWidth > linkLeft && linkLeft > tipWidth) ||
     319          linkLeft + linkWidth + tipWidth + lOffset > winWidth ?
     320          linkLeft - tipWidth - lOffset :
     321          linkWidth + linkLeft + lOffset;
    140322        if (link.tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
    141           if (mouseX + 20 + tipWidth > winWidth) { 
    142             $cluetip.addClass(' cluetip-' + ctClass);
     323          if (mouseX + 20 + tipWidth > winWidth) {
     324            $cluetip.addClass('cluetip-' + ctClass);
    143325            posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) :  mouseX - (tipWidth/2);
    144326          } else {
     
    146328          }
    147329        }
    148         var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
    149         $cluetip.css({
    150           left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0),
    151           zIndex: $this.data('thisInfo').zIndex
    152         });
    153         $cluetipArrows.css({zIndex: $this.data('thisInfo').zIndex+1});
    154       }
    155         wHeight = $(window).height();
     330        pY = posX < 0 ? event.pageY + tOffset : event.pageY;
     331        if (posX < 0 || opts.positionBy == 'bottomTop'  || opts.positionBy == 'topBottom') {
     332          posX = (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0);
     333        }
     334      }
     335
     336      $cluetipArrows.css({zIndex: $link.data('cluetip').zIndex+1});
     337      $cluetip.css({
     338        left: posX,
     339        zIndex: $link.data('cluetip').zIndex
     340      });
     341      wHeight = $(window).height();
    156342
    157343/***************************************
     
    166352      }
    167353/***************************************
    168 * load the title attribute only (or user-selected attribute). 
     354* load the title attribute only (or user-selected attribute).
    169355* clueTip title is the string before the first delimiter
    170356* subsequent delimiters place clueTip body text on separate lines
     
    177363          for (var i=1; i < tpl; i++){
    178364            $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
    179           }         
     365          }
    180366        }
    181367        cluetipShow(pY);
    182368      }
    183369/***************************************
    184 * load external file via ajax         
     370* load external file via ajax
    185371***************************************/
    186372
    187       else if (!opts.local && tipAttribute.indexOf('#') !== 0) {
    188         if (/\.(jpe?g|tiff?|gif|png)$/i.test(tipAttribute)) {
     373      else if ( !opts.local && tipAttribute.indexOf('#') !== 0 ) {
     374        if (/\.(jpe?g|tiff?|gif|png)(?:\?.*)?$/i.test(tipAttribute)) {
    189375          $cluetipInner.html('<img src="' + tipAttribute + '" alt="' + tipTitle + '" />');
    190           cluetipShow(pY);
    191         } else if (cluetipContents && opts.ajaxCache) {
    192           $cluetipInner.html(cluetipContents);
    193376          cluetipShow(pY);
    194377        } else {
     
    197380              optionSuccess = opts.ajaxSettings.success,
    198381              optionComplete = opts.ajaxSettings.complete;
     382
     383          cacheKey = getCacheKey(tipAttribute, opts.ajaxSettings.data);
     384
    199385          var ajaxSettings = {
    200             cache: false, // force requested page not to be cached by browser
     386            cache: opts.ajaxCache, // force requested page not to be cached by browser
    201387            url: tipAttribute,
    202             beforeSend: function(xhr) {
    203               if (optionBeforeSend) {optionBeforeSend.call(link, xhr, $cluetip, $cluetipInner);}
     388            beforeSend: function(xhr, settings) {
     389              if (optionBeforeSend) {optionBeforeSend.call(link, xhr, $cluetip, $cluetipInner, settings);}
    204390              $cluetipOuter.children().empty();
    205391              if (opts.waitImage) {
    206392                $cluetipWait
    207                 .css({top: mouseY+20, left: mouseX+20, zIndex: $this.data('thisInfo').zIndex-1})
     393                .css({top: mouseY+20, left: mouseX+20, zIndex: $link.data('cluetip').zIndex-1})
    208394                .show();
    209395              }
    210396            },
    211397            error: function(xhr, textStatus) {
     398              if ( options.ajaxCache && !caches[cacheKey] ) {
     399                caches[cacheKey] = {status: 'error', textStatus: textStatus, xhr: xhr};
     400              }
     401
    212402              if (isActive) {
    213403                if (optionError) {
    214404                  optionError.call(link, xhr, textStatus, $cluetip, $cluetipInner);
    215405                } else {
    216                   $cluetipInner.html('<i>sorry, the contents could not be loaded</i>'); 
     406                  $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');
    217407                }
    218408              }
    219409            },
    220             success: function(data, textStatus) {       
     410            success: function(data, textStatus, xhr) {
     411              if ( options.ajaxCache && !caches[cacheKey] ) {
     412                caches[cacheKey] = {status: 'success', data: data, textStatus: textStatus, xhr: xhr};
     413              }
     414
    221415              cluetipContents = opts.ajaxProcess.call(link, data);
     416
     417              // allow for changing the title based on data returned by xhr
     418              if ( typeof cluetipContents == 'object' && cluetipContents !== null ) {
     419                tipTitle = cluetipContents.title;
     420                cluetipContents = cluetipContents.content;
     421              }
     422
    222423              if (isActive) {
    223                 if (optionSuccess) {optionSuccess.call(link, data, textStatus, $cluetip, $cluetipInner);}
     424                if (optionSuccess) {
     425                  optionSuccess.call(link, data, textStatus, $cluetip, $cluetipInner);
     426                }
    224427                $cluetipInner.html(cluetipContents);
     428
    225429              }
    226430            },
    227431            complete: function(xhr, textStatus) {
    228               if (optionComplete) {optionComplete.call(link, xhr, textStatus, $cluetip, $cluetipInner);}
     432              if (optionComplete) {
     433                optionComplete.call(link, xhr, textStatus, $cluetip, $cluetipInner);
     434              }
    229435              var imgs = $cluetipInner[0].getElementsByTagName('img');
    230436              imgCount = imgs.length;
     
    235441              }
    236442              if (imgCount && !$.browser.opera) {
    237                 $(imgs).bind('load error', function() {
     443                $(imgs).bind('load.ct error.ct', function() {
    238444                  imgCount--;
    239                   if (imgCount<1) {
     445                  if (imgCount === 0) {
    240446                    $cluetipWait.hide();
     447                    $(imgs).unbind('.ct');
    241448                    if (isActive) { cluetipShow(pY); }
    242449                  }
    243                 }); 
     450                });
    244451              } else {
    245452                $cluetipWait.hide();
    246453                if (isActive) { cluetipShow(pY); }
    247               } 
     454              }
    248455            }
    249456          };
    250           var ajaxMergedSettings = $.extend(true, {}, opts.ajaxSettings, ajaxSettings);
    251          
    252           $.ajax(ajaxMergedSettings);
    253         }
    254 
     457
     458          ajaxMergedSettings = $.extend(true, {}, opts.ajaxSettings, ajaxSettings);
     459
     460          if ( caches[cacheKey] ) {
     461            cachedAjax( caches[cacheKey], ajaxMergedSettings );
     462          } else {
     463            $.ajax(ajaxMergedSettings);
     464          }
     465        }
     466      }
    255467/***************************************
    256468* load an element from the same page
    257469***************************************/
    258       } else if (opts.local) {
    259        
    260         var $localContent = $(tipAttribute + (/#\S+$/.test(tipAttribute) ? '' : ':eq(' + index + ')')).clone(true).show();
     470      else if (opts.local) {
     471        var $localContent = $(tipAttribute + (/^#\S+$/.test(tipAttribute) ? '' : ':eq(' + index + ')')).clone(true).show();
     472        if (opts.localIdSuffix) {
     473          $localContent.attr('id', $localContent[0].id + opts.localIdSuffix);
     474        }
    261475        $cluetipInner.html($localContent);
    262476        cluetipShow(pY);
     
    266480// get dimensions and options for cluetip and prepare it to be shown
    267481    var cluetipShow = function(bpY) {
     482      var $closeLink, dynamicClasses, heightDiff,
     483          titleHTML = tipTitle || opts.showTitle && '&nbsp;',
     484          bgY = '', direction = '', insufficientX = false;
     485      var stickyClose = {
     486        bottom: function($cLink) {
     487          $cLink.appendTo($cluetipInner);
     488        },
     489        top: function($cLink) {
     490          $cLink.prependTo($cluetipInner);
     491        },
     492        title: function($cLink) {
     493          $cLink.prependTo($cluetipTitle);
     494        }
     495      };
     496
    268497      $cluetip.addClass('cluetip-' + ctClass);
    269       if (opts.truncate) { 
     498      if (opts.truncate) {
    270499        var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...';
    271500        $cluetipInner.html($truncloaded);
    272501      }
    273       function doNothing() {}; //empty function
    274       tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html('&nbsp;') : $cluetipTitle.hide();
     502
     503      if (titleHTML) {
     504        $cluetipTitle.show().html(titleHTML);
     505      } else {
     506        $cluetipTitle.hide();
     507      }
     508
    275509      if (opts.sticky) {
    276         var $closeLink = $('<div id="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
    277         (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
    278         $closeLink.bind('click.cluetip', function() {
    279           cluetipClose();
    280           return false;
    281         });
     510        if (stickyClose[opts.closePosition]) {
     511          $closeLink = $('<div class="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
     512          stickyClose[opts.closePosition]( $closeLink );
     513          $closeLink.bind('click.cluetip', function() {
     514            cluetipClose();
     515            return false;
     516          });
     517        }
    282518        if (opts.mouseOutClose) {
    283           $cluetip.bind('mouseleave.cluetip', function() {
    284             cluetipClose();
    285           });
    286         } else {
    287           $cluetip.unbind('mouseleave.cluetip');
    288         }
    289       }
    290 // now that content is loaded, finish the positioning
    291       var direction = '';
    292       $cluetipOuter.css({zIndex: $this.data('thisInfo').zIndex, overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
    293       tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10);   
     519          $link.unbind('mouseleave.cluetipMoc');
     520          $cluetip.unbind('mouseleave.cluetipMoc');
     521          if (opts.mouseOutClose == 'both' || opts.mouseOutClose == 'cluetip' || opts.mouseOutClose === true) { // true implies 'cluetip' for backwards compatability
     522            $cluetip.bind('mouseleave.cluetipMoc', mouseOutClose);
     523          }
     524          if (opts.mouseOutClose == 'both' || opts.mouseOutClose == 'link') {
     525            $link.bind('mouseleave.cluetipMoc', mouseOutClose);
     526          }
     527        }
     528      }
     529
     530// now that content is loaded, finish the positioning
     531      $cluetipOuter.css({zIndex: $link.data('cluetip').zIndex, overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
     532      tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10);
    294533      tipY = posY;
    295534      baseline = sTop + wHeight;
     535      insufficientX = (posX < mouseX && (Math.max(posX, 0) + tipWidth > mouseX));
    296536      if (opts.positionBy == 'fixed') {
    297537        tipY = posY - opts.dropShadowSteps + tOffset;
    298       } else if ( (posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
    299         if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) {
    300           tipY = mouseY - tipHeight - tOffset;
    301           direction = 'top';
    302         } else {
    303           tipY = mouseY + tOffset;
    304           direction = 'bottom';
     538      } else if (opts.positionBy == 'topBottom' || opts.positionBy == 'bottomTop' || insufficientX) {
     539        if (opts.positionBy == 'topBottom') {
     540          if (posY + tipHeight + tOffset < baseline && mouseY - sTop < tipHeight + tOffset) {
     541            direction = 'bottom';
     542          } else {
     543            direction = 'top';
     544          }
     545        } else if (opts.positionBy == 'bottomTop' || insufficientX) {
     546          if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) {
     547            direction = 'top';
     548          } else {
     549            direction = 'bottom';
     550          }
     551        }
     552        // We should now have a direction. Compute tipY
     553        if (opts.snapToEdge) {
     554          if (direction == 'top') {
     555            tipY = linkTop - tipHeight - tOffset;
     556          } else if (direction == 'bottom') {
     557            tipY = linkBottom + tOffset;
     558          }
     559        } else {
     560          if (direction == 'top') {
     561            tipY = mouseY - tipHeight - tOffset;
     562          } else if (direction == 'bottom') {
     563            tipY = mouseY + tOffset;
     564          }
    305565        }
    306566      } else if ( posY + tipHeight + tOffset > baseline ) {
    307567        tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
    308       } else if ($this.css('display') == 'block' || link.tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
     568      } else if ($link.css('display') == 'block' || link.tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
    309569        tipY = bpY - tOffset;
    310570      } else {
    311571        tipY = posY - opts.dropShadowSteps;
    312572      }
    313       if (direction == '') {
    314         posX < linkLeft ? direction = 'left' : direction = 'right';
    315       }
    316       $cluetip.css({top: tipY + 'px'}).removeClass().addClass('clue-' + direction + '-' + ctClass).addClass(' cluetip-' + ctClass);
    317       if (opts.arrows) { // set up arrow positioning to align with element
    318         var bgY = (posY - tipY - opts.dropShadowSteps);
    319         $cluetipArrows.css({top: (/(left|right)/.test(direction) && posX >=0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : ''}).show();
     573      if (direction === '') {
     574        direction = posX < linkLeft ? 'left' :  'right';
     575      }
     576      // add classes
     577      dynamicClasses = ' clue-' + direction + '-' + ctClass + ' cluetip-' + ctClass;
     578      if (ctClass == 'rounded') {
     579        dynamicClasses += ' ui-corner-all';
     580      }
     581      $cluetip.css({top: tipY + 'px'}).attrProp({'className': standardClasses + dynamicClasses});
     582      // set up arrow positioning to align with element
     583      if (opts.arrows) {
     584        if ( /(left|right)/.test(direction) ) {
     585          heightDiff = $cluetip.height() - $cluetipArrows.height();
     586          bgY = posX >= 0 && bpY > 0 ? (posY - tipY - opts.dropShadowSteps) : 0;
     587          bgY = heightDiff > bgY ? bgY : heightDiff;
     588          bgY += 'px';
     589        }
     590        $cluetipArrows.css({top: bgY}).show();
    320591      } else {
    321592        $cluetipArrows.hide();
     
    323594
    324595// (first hide, then) ***SHOW THE CLUETIP***
    325       $dropShadow.hide();
    326       $cluetip.hide()[opts.fx.open](opts.fx.openSpeed || 0);
    327       if (opts.dropShadow) { $dropShadow.css({height: tipHeight, width: tipInnerWidth, zIndex: $this.data('thisInfo').zIndex-1}).show(); }
     596      // handle dropshadow divs first
     597      $dropShadow = createDropShadows($cluetip, opts);
     598      if ($dropShadow && $dropShadow.length) {
     599        $dropShadow.hide().css({height: tipHeight, width: tipInnerWidth, zIndex: $link.data('cluetip').zIndex-1}).show();
     600      }
     601
     602      if (!closeOnDelay) {
     603        $cluetip.hide();
     604      }
     605      clearTimeout(closeOnDelay);
     606      closeOnDelay = null;
     607
     608      // show the cluetip
     609      $cluetip[opts.fx.open](opts.fx.openSpeed || 0);
     610
    328611      if ($.fn.bgiframe) { $cluetip.bgiframe(); }
    329       // delayed close (not fully tested)
    330       if (opts.delayedClose > 0) {
    331         closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
    332       }
     612
    333613      // trigger the optional onShow function
    334614      opts.onShow.call(link, $cluetip, $cluetipInner);
     
    342622      $cluetipWait.hide();
    343623      if (!opts.sticky || (/click|toggle/).test(opts.activation) ) {
    344         cluetipClose();
    345         clearTimeout(closeOnDelay);       
    346       }
     624        // delayed close (not fully tested)
     625        if (opts.delayedClose > 0) {
     626          clearTimeout(closeOnDelay);
     627          closeOnDelay = null;
     628          closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
     629        }
     630      }
     631
    347632      if (opts.hoverClass) {
    348         $this.removeClass(opts.hoverClass);
     633        $link.removeClass(opts.hoverClass);
    349634      }
    350635    };
    351 // close cluetip and reset some things
    352     var cluetipClose = function() {
    353       $cluetipOuter
    354       .parent().hide().removeClass();
    355       opts.onHide.call(link, $cluetip, $cluetipInner);
    356       $this.removeClass('cluetip-clicked');
    357       if (tipTitle) {
    358         $this.attr(opts.titleAttribute, tipTitle);
    359       }
    360       $this.css('cursor','');
     636
     637    // close cluetip and reset some things
     638    var cluetipClose = function(el) {
     639      var $closer = el && el.data('cluetip') ? el : $link,
     640          ct = $closer.data('cluetip') && $closer.data('cluetip').selector,
     641          ctSelector = ct || 'div.cluetip',
     642          $cluetip = $(ctSelector),
     643          $cluetipInner = $cluetip.find(prefix + 'cluetip-inner'),
     644          $cluetipArrows = $cluetip.find(prefix + 'cluetip-arrows');
     645
     646      $cluetip.hide().removeClass();
     647      opts.onHide.call($closer[0], $cluetip, $cluetipInner);
     648
     649      if (ct) {
     650        $closer.removeClass('cluetip-clicked');
     651        $closer.css('cursor','');
     652      }
     653      if (ct && tipTitle) {
     654        $closer.attrProp(opts.titleAttribute, tipTitle);
     655      }
     656
    361657      if (opts.arrows) {
    362658        $cluetipArrows.css({top: ''});
     
    364660    };
    365661
    366     $(document).bind('hideCluetip', function(e) {
    367       cluetipClose();
     662    // Check to see if we should be closing by checking where the user is hovering.
     663    // We do a short 50ms delay for two reasons: to prevent flicker, and to allow the user time to hover on other element
     664    var mouseOutClose = function() {
     665      var el = this;
     666      clearTimeout(closeOnDelay);
     667      closeOnDelay = setTimeout(function() {
     668        var linkOver = $link.data('cluetip').entered,
     669            cluetipOver = $cluetip.data('entered'),
     670            entered = false;
     671
     672        if ( opts.mouseOutClose == 'both' && (linkOver || cluetipOver) ) {
     673          entered = true;
     674        }
     675        // true implies 'cluetip' for backwards compatibility
     676        else if ( (opts.mouseOutClose === true || opts.mouseOutClose == 'cluetip') && cluetipOver) {
     677          entered = true;
     678        }
     679        else if (opts.mouseOutClose == 'link' && linkOver) {
     680          entered = true;
     681        }
     682
     683        if ( !entered ) {
     684          // All checks pass, close the cluetip
     685          cluetipClose.call(el);
     686        }
     687
     688      }, opts.delayedClose);
     689    };
     690
     691    $(document).unbind('hideCluetip.cluetip').bind('hideCluetip.cluetip', function(e) {
     692      cluetipClose( $(e.target) );
    368693    });
    369694/***************************************
     
    372697  // activate by click
    373698      if ( (/click|toggle/).test(opts.activation) ) {
    374         $this.bind('click.cluetip', function(event) {
    375           if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
     699        $link.bind('click.cluetip', function(event) {
     700          if ($cluetip.is(':hidden') || !$link.is('.cluetip-clicked')) {
    376701            activate(event);
    377702            $('.cluetip-clicked').removeClass('cluetip-clicked');
    378             $this.addClass('cluetip-clicked');
     703            $link.addClass('cluetip-clicked');
    379704          } else {
    380705            inactivate(event);
    381706          }
    382           this.blur();
    383707          return false;
    384708        });
    385   // activate by focus; inactivate by blur   
     709  // activate by focus; inactivate by blur
    386710      } else if (opts.activation == 'focus') {
    387         $this.bind('focus.cluetip', function(event) {
     711        $link.bind('focus.cluetip', function(event) {
     712          $link.attrProp('title','');
    388713          activate(event);
    389714        });
    390         $this.bind('blur.cluetip', function(event) {
     715        $link.bind('blur.cluetip', function(event) {
     716          $link.attrProp('title', $link.data('cluetip').title);
    391717          inactivate(event);
    392718        });
    393719  // activate by hover
    394720      } else {
     721
    395722        // clicking is returned false if clickThrough option is set to false
    396         $this[opts.clickThrough ? 'unbind' : 'bind']('click', returnFalse);
     723        $link[opts.clickThrough ? 'unbind' : 'bind']('click.cluetip', returnFalse);
     724
    397725        //set up mouse tracking
    398726        var mouseTracks = function(evt) {
    399           if (opts.tracking == true) {
     727          if (opts.tracking) {
    400728            var trackX = posX - evt.pageX;
    401729            var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
    402             $this.bind('mousemove.cluetip', function(evt) {
     730            $link.bind('mousemove.cluetip', function(evt) {
    403731              $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY });
    404732            });
    405733          }
    406734        };
     735
    407736        if ($.fn.hoverIntent && opts.hoverIntent) {
    408           $this.hoverIntent({
     737          $link.hoverIntent({
    409738            sensitivity: opts.hoverIntent.sensitivity,
    410             interval: opts.hoverIntent.interval, 
     739            interval: opts.hoverIntent.interval,
    411740            over: function(event) {
    412741              activate(event);
    413742              mouseTracks(event);
    414             },
    415             timeout: opts.hoverIntent.timeout, 
    416             out: function(event) {inactivate(event); $this.unbind('mousemove.cluetip');}
    417           });           
     743            },
     744            timeout: opts.hoverIntent.timeout,
     745            out: function(event) {
     746              inactivate(event);
     747              $link.unbind('mousemove.cluetip');
     748            }
     749          });
    418750        } else {
    419           $this.bind('mouseenter.cluetip', function(event) {
     751          $link.bind('mouseenter.cluetip', function(event) {
    420752            activate(event);
    421753            mouseTracks(event);
     
    423755          .bind('mouseleave.cluetip', function(event) {
    424756            inactivate(event);
    425             $this.unbind('mousemove.cluetip');
     757            $link.unbind('mousemove.cluetip');
    426758          });
    427759        }
    428         $this.bind('mouseover.cluetip', function(event) {
    429           $this.attr('title','');
     760
     761        $link.bind('mouseover.cluetip', function(event) {
     762          $link.attrProp('title','');
    430763        }).bind('mouseleave.cluetip', function(event) {
    431           $this.attr('title', $this.data('thisInfo').title);
     764          $link.attrProp('title', $link.data('cluetip').title);
    432765        });
    433766      }
    434     });
     767
     768      // trigger a cached Ajax response
     769      function cachedAjax(info, settings) {
     770        var status = info.status;
     771        settings.beforeSend(info.xhr, settings);
     772        if ( status == 'error' ) {
     773          settings[status](info.xhr, info.textStatus);
     774        } else if (status == 'success') {
     775          settings[status](info.data, info.textStatus, info.xhr);
     776        }
     777        settings.complete(info.xhr, settings.textStatus);
     778      }
     779
     780    }); // end this.each
     781
     782    /** =private functions
     783    ************************************************************/
     784    //empty function
     785    function doNothing() {}
     786
     787    // create a string to be used as an identifier for ajax caches
     788    function getCacheKey(url, data) {
     789      var cacheKey = url || '';
     790      data = data || '';
     791
     792      if (typeof data == 'object') {
     793        $.each(data, function(key, val) {
     794          cacheKey += '-' + key + '-' + val;
     795        });
     796      } else if (typeof data == 'string') {
     797        cacheKey += data;
     798      }
     799
     800      return cacheKey;
     801    }
     802
     803    /** =create dropshadow divs **/
     804
     805    function createDropShadows($cluetip, options, newDropShadow) {
     806      var dsStyle = '',
     807          dropShadowSteps = (options.dropShadow && options.dropShadowSteps) ? +options.dropShadowSteps : 0;
     808
     809      if ($.support.boxShadow) {
     810        if ( dropShadowSteps ) {
     811          dsStyle = '1px 1px ' + dropShadowSteps + 'px rgba(0,0,0,0.5)';
     812        }
     813        var dsOffsets = dropShadowSteps === 0 ? '0 0 ' : '1px 1px ';
     814        $cluetip.css($.support.boxShadow, dsStyle);
     815        return false;
     816      }
     817      var oldDropShadow = $cluetip.find('.cluetip-drop-shadow');
     818      if (dropShadowSteps == oldDropShadow.length) {
     819        return oldDropShadow;
     820      }
     821      oldDropShadow.remove();
     822      var dropShadows = [];
     823      for (var i=0; i < dropShadowSteps;) {
     824        dropShadows[i++] = '<div style="top:' + i + 'px;left:' + i + 'px;"></div>';
     825      }
     826
     827      newDropShadow = $(dropShadows.join(''))
     828      .css({
     829        position: 'absolute',
     830        backgroundColor: '#000',
     831        zIndex: cluezIndex -1,
     832        opacity: 0.1
     833      })
     834      .addClass('cluetip-drop-shadow')
     835      .prependTo($cluetip);
     836      return newDropShadow;
     837
     838    }
     839
     840    return this;
    435841  };
    436  
    437 /*
    438  * options for clueTip
    439  *
    440  * each one can be explicitly overridden by changing its value.
    441  * for example: $.fn.cluetip.defaults.width = 200;
    442  * would change the default width for all clueTips to 200.
    443  *
    444  * each one can also be overridden by passing an options map to the cluetip method.
    445  * for example: $('a.example').cluetip({width: 200});
    446  * would change the default width to 200 for clueTips invoked by a link with class of "example"
    447  *
    448  */
    449  
    450   $.fn.cluetip.defaults = {  // set up default options
    451     width:            275,      // The width of the clueTip
    452     height:           'auto',   // The height of the clueTip
    453     cluezIndex:       97,       // Sets the z-index style property of the clueTip
    454     positionBy:       'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
    455     topOffset:        15,       // Number of px to offset clueTip from top of invoking element
    456     leftOffset:       15,       // Number of px to offset clueTip from left of invoking element
    457     local:            false,    // Whether to use content from the same page for the clueTip's body
    458     localPrefix:      null,       // string to be prepended to the tip attribute if local is true
    459     hideLocal:        true,     // If local option is set to true, this determines whether local content
    460                                 // to be shown in clueTip should be hidden at its original location
    461     attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
    462     titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
    463     splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
    464                                 // within the clueTip body. more info below [6]
    465     escapeTitle:      false,    // whether to html escape the title attribute
    466     showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
    467     cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
    468     hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
    469     waitImage:        true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
    470     cursor:           'help',
    471     arrows:           false,    // if true, displays arrow on appropriate side of clueTip
    472     dropShadow:       true,     // set to false if you don't want the drop-shadow effect on the clueTip
    473     dropShadowSteps:  6,        // adjusts the size of the drop shadow
    474     sticky:           false,    // keep visible until manually closed
    475     mouseOutClose:    false,    // close when clueTip is moused out
    476     activation:       'hover',  // set to 'click' to force user to click to show clueTip
    477                                 // set to 'focus' to show on focus of a form element and hide on blur
    478     clickThrough:     false,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
    479                                 // even if href and tipAttribute are equal
    480     tracking:         false,    // if true, clueTip will track mouse movement (experimental)
    481     delayedClose:     0,        // close clueTip on a timed delay (experimental)
    482     closePosition:    'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
    483     closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
    484     truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs
    485    
    486     // effect and speed for opening clueTips
    487     fx: {             
    488                       open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
    489                       openSpeed:  ''
    490     },     
    491 
    492     // settings for when hoverIntent plugin is used             
    493     hoverIntent: {   
    494                       sensitivity:  3,
    495                                   interval:     50,
    496                                   timeout:      0
    497     },
    498 
    499     // short-circuit function to run just before clueTip is shown.
    500     onActivate:       function(e) {return true;},
    501     // function to run just after clueTip is shown.
    502     onShow:           function(ct, ci){},
    503     // function to run just after clueTip is hidden.
    504     onHide:           function(ct, ci){},
    505     // whether to cache results of ajax request to avoid unnecessary hits to server   
    506     ajaxCache:        true, 
    507 
    508     // process data retrieved via xhr before it's displayed
    509     ajaxProcess:      function(data) {
    510                         data = data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, '').replace(/<(link|meta)[^>]+>/g,'');
    511                         return data;
    512     },               
    513 
    514     // can pass in standard $.ajax() parameters. Callback functions, such as beforeSend,
    515     // will be queued first within the default callbacks.
    516     // The only exception is error, which overrides the default
    517     ajaxSettings: {
    518                       // error: function(ct, ci) { /* override default error callback */ }
    519                       // beforeSend: function(ct, ci) { /* called first within default beforeSend callback }
    520                       dataType: 'html'
    521     },
    522     debug: false
    523   };
    524 
    525 
    526 /*
    527  * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
    528  *
    529  * @example $.cluetip.setup({
    530  *   insertionType: 'prependTo',
    531  *   insertionElement: '#container'
    532  * });
    533  *
    534  * @property
    535  * @name $.cluetip.setup
    536  * @type Map
    537  * @cat Plugins/tooltip
    538  * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
    539  * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
    540  *
    541  */
    542    
    543   var insertionType = 'appendTo', insertionElement = 'body';
    544 
    545   $.cluetip.setup = function(options) {
    546     if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
    547       insertionType = options.insertionType;
     842
     843  (function() {
     844    $.support = $.support || {};
     845    // check support for CSS3 properties (currently only boxShadow)
     846    var div = document.createElement('div'),
     847        divStyle = div.style,
     848        styleProps = ['boxShadow'],
     849        prefixes = ['moz', 'Moz', 'webkit', 'o'];
     850
     851    for (var i=0, sl = styleProps.length; i < sl; i++) {
     852      var prop = styleProps[i],
     853          uProp = prop.charAt(0).toUpperCase() + prop.slice(1);
     854
     855      if ( typeof divStyle[ prop ] !== 'undefined' ) {
     856        $.support[ prop ] = prop;
     857      } else {
     858        for (var j=0, pl = prefixes.length; j < pl; j++) {
     859
     860          if (typeof divStyle[ prefixes[j] + uProp ] !== 'undefined') {
     861            $.support[ prop ] = prefixes[j] + uProp;
     862            break;
     863          }
     864        }
     865      }
    548866    }
    549     if (options && options.insertionElement) {
    550       insertionElement = options.insertionElement;
    551     }
    552   };
    553  
     867    div = null;
     868  })();
     869
     870  $.fn.cluetip.defaults = $.cluetip.defaults;
     871
    554872})(jQuery);
Note: See TracChangeset for help on using the changeset viewer.