[ Index ]
 

Code source de DokuWiki 2006-11-06

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/scripts/ -> domTT.js (source)

   1  /** $Id: domTT.js 1951 2005-07-17 16:22:34Z dallen $ */
   2  // {{{ license
   3  
   4  /*
   5   * Copyright 2002-2005 Dan Allen, Mojavelinux.com (dan.allen@mojavelinux.com)
   6   *
   7   * Licensed under the Apache License, Version 2.0 (the "License");
   8   * you may not use this file except in compliance with the License.
   9   * You may obtain a copy of the License at
  10   *
  11   *      http://www.apache.org/licenses/LICENSE-2.0
  12   *
  13   * Unless required by applicable law or agreed to in writing, software
  14   * distributed under the License is distributed on an "AS IS" BASIS,
  15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16   * See the License for the specific language governing permissions and
  17   * limitations under the License.
  18   */
  19  
  20  // }}}
  21  // {{{ intro
  22  
  23  /**
  24   * Title: DOM Tooltip Library
  25   * Version: 0.7.1
  26   *
  27   * Summary:
  28   * Allows developers to add custom tooltips to the webpages.  Tooltips are
  29   * generated using the domTT_activate() function and customized by setting
  30   * a handful of options.
  31   *
  32   * Maintainer: Dan Allen <dan.allen@mojavelinux.com>
  33   * Contributors:
  34   *         Josh Gross <josh@jportalhome.com>
  35   *        Jason Rust <jason@rustyparts.com>
  36   *
  37   * License: Apache 2.0
  38   * However, if you use this library, you earn the position of official bug
  39   * reporter :) Please post questions or problem reports to the newsgroup:
  40   *
  41   *   http://groups-beta.google.com/group/dom-tooltip
  42   *
  43   * If you are doing this for commercial work, perhaps you could send me a few
  44   * Starbucks Coffee gift dollars or PayPal bucks to encourage future
  45   * developement (NOT REQUIRED).  E-mail me for my snail mail address.
  46  
  47   *
  48   * Homepage: http://www.mojavelinux.com/projects/domtooltip/
  49   *
  50   * Newsgroup: http://groups-beta.google.com/group/dom-tooltip
  51   *
  52   * Freshmeat Project: http://freshmeat.net/projects/domtt/?topic_id=92
  53   *
  54   * Updated: 2005/07/16
  55   *
  56   * Supported Browsers:
  57   * Mozilla (Gecko), IE 5.5+, IE on Mac, Safari, Konqueror, Opera 7
  58   *
  59   * Usage:
  60   * Please see the HOWTO documentation.
  61  **/
  62  
  63  // }}}
  64  // {{{ settings (editable)
  65  
  66  // IE mouse events seem to be off by 2 pixels
  67  var domTT_offsetX = (domLib_isIE ? -2 : 0);
  68  var domTT_offsetY = (domLib_isIE ? 4 : 2);
  69  var domTT_direction = 'southeast';
  70  var domTT_mouseHeight = domLib_isIE ? 13 : 19;
  71  var domTT_closeLink = 'X';
  72  var domTT_closeAction = 'hide';
  73  var domTT_activateDelay = 500;
  74  var domTT_maxWidth = false;
  75  var domTT_styleClass = 'domTT';
  76  var domTT_fade = 'neither';
  77  var domTT_lifetime = 0;
  78  var domTT_grid = 0;
  79  var domTT_trailDelay = 200;
  80  var domTT_useGlobalMousePosition = true;
  81  var domTT_screenEdgeDetection = true;
  82  var domTT_screenEdgePadding = 4;
  83  var domTT_oneOnly = false;
  84  var domTT_draggable = false;
  85  if (typeof(domTT_dragEnabled) == 'undefined')
  86  {
  87      domTT_dragEnabled = false;
  88  }
  89  
  90  // }}}
  91  // {{{ globals (DO NOT EDIT)
  92  
  93  var domTT_predefined = new Hash();
  94  // tooltips are keyed on both the tip id and the owner id,
  95  // since events can originate on either object
  96  var domTT_tooltips = new Hash();
  97  var domTT_lastOpened = 0;
  98  
  99  // }}}
 100  // {{{ document.onmousemove
 101  
 102  if (domLib_useLibrary && domTT_useGlobalMousePosition)
 103  {
 104      var domTT_mousePosition = new Hash();
 105      document.onmousemove = function(in_event)
 106      {
 107          if (typeof(in_event) == 'undefined')
 108          {
 109              in_event = event;
 110          }
 111  
 112          domTT_mousePosition = domLib_getEventPosition(in_event);
 113          if (domTT_dragEnabled && domTT_dragMouseDown)
 114          {
 115              domTT_dragUpdate(in_event);
 116          }
 117      };
 118  }
 119  
 120  // }}}
 121  // {{{ domTT_activate()
 122  
 123  function domTT_activate(in_this, in_event)
 124  {
 125      if (!domLib_useLibrary) { return false; }
 126  
 127      // make sure in_event is set (for IE, some cases we have to use window.event)
 128      if (typeof(in_event) == 'undefined')
 129      {
 130          in_event = window.event;
 131      }
 132  
 133      var owner = document.body;
 134      // we have an active event so get the owner
 135      if (in_event.type.match(/key|mouse|click|contextmenu/i))
 136      {
 137          // make sure we have nothing higher than the body element
 138          if (in_this.nodeType && in_this.nodeType != document.DOCUMENT_NODE)
 139          {
 140              var owner = in_this;
 141          }
 142      }
 143      // non active event (make sure we were passed a string id)
 144      else
 145      {
 146          if (typeof(in_this) != 'object' && !(owner = domTT_tooltips.get(in_this)))
 147          {
 148              owner = document.body.appendChild(document.createElement('div'));
 149              owner.style.display = 'none';
 150              owner.id = in_this;
 151          }
 152      }
 153  
 154      // make sure the owner has a unique id
 155      if (!owner.id)
 156      {
 157          owner.id = '__autoId' + domLib_autoId++;
 158      }
 159  
 160      // see if we should only be openning one tip at a time
 161      // NOTE: this is not "perfect" yet since it really steps on any other
 162      // tip working on fade out or delayed close, but it get's the job done
 163      if (domTT_oneOnly && domTT_lastOpened)
 164      {
 165          domTT_deactivate(domTT_lastOpened);
 166      }
 167  
 168      domTT_lastOpened = owner.id;
 169  
 170      var tooltip = domTT_tooltips.get(owner.id);
 171      if (tooltip)
 172      {
 173          if (tooltip.get('eventType') != in_event.type)
 174          {
 175              if (tooltip.get('type') == 'greasy')
 176              {
 177                  tooltip.set('closeAction', 'destroy');
 178                  domTT_deactivate(owner.id);
 179              }
 180              else if (tooltip.get('status') != 'inactive')
 181              {
 182                  return owner.id;
 183              }
 184          }
 185          else
 186          {
 187              if (tooltip.get('status') == 'inactive')
 188              {
 189                  tooltip.set('status', 'pending');
 190                  tooltip.set('activateTimeout', domLib_setTimeout(domTT_runShow, tooltip.get('delay'), [owner.id, in_event]));
 191  
 192                  return owner.id;
 193              }
 194              // either pending or active, let it be
 195              else
 196              {
 197                  return owner.id;
 198              }
 199          }
 200      }
 201  
 202      // setup the default options hash
 203      var options = new Hash(
 204          'caption',        '',
 205          'content',        '',
 206          'clearMouse',    true,
 207          'closeAction',    domTT_closeAction,
 208          'closeLink',    domTT_closeLink,
 209          'delay',        domTT_activateDelay,
 210          'direction',    domTT_direction,
 211          'draggable',    domTT_draggable,
 212          'fade',            domTT_fade,
 213          'fadeMax',        100,
 214          'grid',            domTT_grid,
 215          'id',            '[domTT]' + owner.id,
 216          'inframe',        false,
 217          'lifetime',        domTT_lifetime,
 218          'offsetX',        domTT_offsetX,
 219          'offsetY',        domTT_offsetY,
 220          'parent',        document.body,
 221          'position',        'absolute',
 222          'styleClass',    domTT_styleClass,
 223          'type',            'greasy',
 224          'trail',        false,
 225          'lazy',            false
 226      );
 227  
 228      // load in the options from the function call
 229      for (var i = 2; i < arguments.length; i += 2)
 230      {
 231          // load in predefined
 232          if (arguments[i] == 'predefined')
 233          {
 234              var predefinedOptions = domTT_predefined.get(arguments[i + 1]);
 235              for (var j in predefinedOptions.elementData)
 236              {
 237                  options.set(j, predefinedOptions.get(j));
 238              }
 239          }
 240          // set option
 241          else
 242          {
 243              options.set(arguments[i], arguments[i + 1]);
 244          }
 245      }
 246  
 247      options.set('eventType', in_event.type);
 248  
 249      // immediately set the status text if provided
 250      if (options.has('statusText'))
 251      {
 252          try { window.status = options.get('statusText'); } catch(e) {}
 253      }
 254  
 255      // if we didn't give content...assume we just wanted to change the status and return
 256      if (!options.has('content') || options.get('content') == '' || options.get('content') == null)
 257      {
 258          if (typeof(owner.onmouseout) != 'function')
 259          {
 260              owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
 261          }
 262  
 263          return owner.id;
 264      }
 265  
 266      options.set('owner', owner);
 267  
 268      domTT_create(options);
 269  
 270      // determine the show delay
 271      options.set('delay', in_event.type.match(/click|mousedown|contextmenu/i) ? 0 : parseInt(options.get('delay')));
 272      domTT_tooltips.set(owner.id, options);
 273      domTT_tooltips.set(options.get('id'), options);
 274      options.set('status', 'pending');
 275      options.set('activateTimeout', domLib_setTimeout(domTT_runShow, options.get('delay'), [owner.id, in_event]));
 276  
 277      return owner.id;
 278  };
 279  
 280  // }}}
 281  // {{{ domTT_create()
 282  
 283  function domTT_create(in_options)
 284  {
 285      var tipOwner = in_options.get('owner');
 286      var parentObj = in_options.get('parent');
 287      var parentDoc = parentObj.ownerDocument || parentObj.document;
 288  
 289      // create the tooltip and hide it
 290      var tipObj = parentObj.appendChild(parentDoc.createElement('div'));
 291      tipObj.style.position = 'absolute';
 292      tipObj.style.left = '0px';
 293      tipObj.style.top = '0px';
 294      tipObj.style.visibility = 'hidden';
 295      tipObj.id = in_options.get('id');
 296      tipObj.className = in_options.get('styleClass');
 297  
 298      // content of tip as object
 299      var content;
 300      var tableLayout = false;
 301  
 302      if (in_options.get('caption') || (in_options.get('type') == 'sticky' && in_options.get('caption') !== false))
 303      {
 304          tableLayout = true;
 305          // layout the tip with a hidden formatting table
 306          var tipLayoutTable = tipObj.appendChild(parentDoc.createElement('table'));
 307          tipLayoutTable.style.borderCollapse = 'collapse';
 308          if (domLib_isKHTML)
 309          {
 310              tipLayoutTable.cellSpacing = 0;
 311          }
 312  
 313          var tipLayoutTbody = tipLayoutTable.appendChild(parentDoc.createElement('tbody'));
 314  
 315          var numCaptionCells = 0;
 316          var captionRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
 317          var captionCell = captionRow.appendChild(parentDoc.createElement('td'));
 318          captionCell.style.padding = '0px';
 319          var caption = captionCell.appendChild(parentDoc.createElement('div'));
 320          caption.className = 'caption';
 321          if (domLib_isIE50)
 322          {
 323              caption.style.height = '100%';
 324          }
 325  
 326          if (in_options.get('caption').nodeType)
 327          {
 328              caption.appendChild(in_options.get('caption').cloneNode(1));
 329          }
 330          else
 331          {
 332              caption.innerHTML = in_options.get('caption');
 333          }
 334  
 335          if (in_options.get('type') == 'sticky')
 336          {
 337              var numCaptionCells = 2;
 338              var closeLinkCell = captionRow.appendChild(parentDoc.createElement('td'));
 339              closeLinkCell.style.padding = '0px';
 340              var closeLink = closeLinkCell.appendChild(parentDoc.createElement('div'));
 341              closeLink.className = 'caption';
 342              if (domLib_isIE50)
 343              {
 344                  closeLink.style.height = '100%';
 345              }
 346  
 347              closeLink.style.textAlign = 'right';
 348              closeLink.style.cursor = domLib_stylePointer;
 349              // merge the styles of the two cells
 350              closeLink.style.borderLeftWidth = caption.style.borderRightWidth = '0px';
 351              closeLink.style.paddingLeft = caption.style.paddingRight = '0px';
 352              closeLink.style.marginLeft = caption.style.marginRight = '0px';
 353              if (in_options.get('closeLink').nodeType)
 354              {
 355                  closeLink.appendChild(in_options.get('closeLink').cloneNode(1));
 356              }
 357              else
 358              {
 359                  closeLink.innerHTML = in_options.get('closeLink');
 360              }
 361  
 362              closeLink.onclick = function() { domTT_deactivate(tipOwner.id); };
 363              closeLink.onmousedown = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = event; } in_event.cancelBubble = true; };
 364              // MacIE has to have a newline at the end and must be made with createTextNode()
 365              if (domLib_isMacIE)
 366              {
 367                  closeLinkCell.appendChild(parentDoc.createTextNode("\n"));
 368              }
 369          }
 370  
 371          // MacIE has to have a newline at the end and must be made with createTextNode()
 372          if (domLib_isMacIE)
 373          {
 374              captionCell.appendChild(parentDoc.createTextNode("\n"));
 375          }
 376  
 377          var contentRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
 378          var contentCell = contentRow.appendChild(parentDoc.createElement('td'));
 379          contentCell.style.padding = '0px';
 380          if (numCaptionCells)
 381          {
 382              if (domLib_isIE || domLib_isOpera)
 383              {
 384                  contentCell.colSpan = numCaptionCells;
 385              }
 386              else
 387              {
 388                  contentCell.setAttribute('colspan', numCaptionCells);
 389              }
 390          }
 391  
 392          content = contentCell.appendChild(parentDoc.createElement('div'));
 393          if (domLib_isIE50)
 394          {
 395              content.style.height = '100%';
 396          }
 397      }
 398      else
 399      {
 400          content = tipObj.appendChild(parentDoc.createElement('div'));
 401      }
 402  
 403      content.className = 'contents';
 404  
 405      if (in_options.get('content').nodeType)
 406      {
 407          content.appendChild(in_options.get('content').cloneNode(1));
 408      }
 409      else
 410      {
 411          content.innerHTML = in_options.get('content');
 412      }
 413  
 414      // adjust the width if specified
 415      if (in_options.has('width'))
 416      {
 417          tipObj.style.width = parseInt(in_options.get('width')) + 'px';
 418      }
 419  
 420      // check if we are overridding the maxWidth
 421      // if the browser supports maxWidth, the global setting will be ignored (assume stylesheet)
 422      var maxWidth = domTT_maxWidth;
 423      if (in_options.has('maxWidth'))
 424      {
 425          if ((maxWidth = in_options.get('maxWidth')) === false)
 426          {
 427              tipObj.style.maxWidth = domLib_styleNoMaxWidth;
 428          }
 429          else
 430          {
 431              maxWidth = parseInt(in_options.get('maxWidth'));
 432              tipObj.style.maxWidth = maxWidth + 'px';
 433          }
 434      }
 435  
 436      // HACK: fix lack of maxWidth in CSS for KHTML and IE
 437      if (maxWidth !== false && (domLib_isIE || domLib_isKHTML) && tipObj.offsetWidth > maxWidth)
 438      {
 439          tipObj.style.width = maxWidth + 'px';
 440      }
 441  
 442      in_options.set('offsetWidth', tipObj.offsetWidth);
 443      in_options.set('offsetHeight', tipObj.offsetHeight);
 444  
 445      // konqueror miscalcuates the width of the containing div when using the layout table based on the
 446      // border size of the containing div
 447      if (domLib_isKonq && tableLayout && !tipObj.style.width)
 448      {
 449          var left = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-left-width');
 450          var right = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-right-width');
 451          
 452          left = left.substring(left.indexOf(':') + 2, left.indexOf(';'));
 453          right = right.substring(right.indexOf(':') + 2, right.indexOf(';'));
 454          var correction = 2 * ((left ? parseInt(left) : 0) + (right ? parseInt(right) : 0));
 455          tipObj.style.width = (tipObj.offsetWidth - correction) + 'px';
 456      }
 457  
 458      // if a width is not set on an absolutely positioned object, both IE and Opera
 459      // will attempt to wrap when it spills outside of body...we cannot have that
 460      if (domLib_isIE || domLib_isOpera)
 461      {
 462          if (!tipObj.style.width)
 463          {
 464              // HACK: the correction here is for a border
 465              tipObj.style.width = (tipObj.offsetWidth - 2) + 'px';
 466          }
 467  
 468          // HACK: the correction here is for a border
 469          tipObj.style.height = (tipObj.offsetHeight - 2) + 'px';
 470      }
 471  
 472      // store placement offsets from event position
 473      var offsetX, offsetY;
 474  
 475      // tooltip floats
 476      if (in_options.get('position') == 'absolute' && !(in_options.has('x') && in_options.has('y')))
 477      {
 478          // determine the offset relative to the pointer
 479          switch (in_options.get('direction'))
 480          {
 481              case 'northeast':
 482                  offsetX = in_options.get('offsetX');
 483                  offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
 484              break;
 485              case 'northwest':
 486                  offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
 487                  offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
 488              break;
 489              case 'north':
 490                  offsetX = 0 - parseInt(tipObj.offsetWidth/2);
 491                  offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
 492              break;
 493              case 'southwest':
 494                  offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
 495                  offsetY = in_options.get('offsetY');
 496              break;
 497              case 'southeast':
 498                  offsetX = in_options.get('offsetX');
 499                  offsetY = in_options.get('offsetY');
 500              break;
 501              case 'south':
 502                  offsetX = 0 - parseInt(tipObj.offsetWidth/2);
 503                  offsetY = in_options.get('offsetY');
 504              break;
 505          }
 506  
 507          // if we are in an iframe, get the offsets of the iframe in the parent document
 508          if (in_options.get('inframe'))
 509          {
 510              var iframeObj = domLib_getIFrameReference(window);
 511              if (iframeObj)
 512              {
 513                  var frameOffsets = domLib_getOffsets(iframeObj);
 514                  offsetX += frameOffsets.get('left');
 515                  offsetY += frameOffsets.get('top');
 516              }
 517          }
 518      }
 519      // tooltip is fixed
 520      else
 521      {
 522          offsetX = 0;
 523          offsetY = 0;
 524          in_options.set('trail', false);
 525      }
 526  
 527      // set the direction-specific offsetX/Y
 528      in_options.set('offsetX', offsetX);
 529      in_options.set('offsetY', offsetY);
 530      if (in_options.get('clearMouse') && in_options.get('direction').indexOf('south') != -1)
 531      {
 532          in_options.set('mouseOffset', domTT_mouseHeight);
 533      }
 534      else
 535      {
 536          in_options.set('mouseOffset', 0);
 537      }
 538  
 539      if (domLib_canFade && typeof(Fadomatic) == 'function')
 540      {
 541          if (in_options.get('fade') != 'neither')
 542          {
 543              var fadeHandler = new Fadomatic(tipObj, 10, 0, 0, in_options.get('fadeMax'));
 544              in_options.set('fadeHandler', fadeHandler);
 545          }
 546      }
 547      else
 548      {
 549          in_options.set('fade', 'neither');
 550      }
 551  
 552      // setup mouse events
 553      if (in_options.get('trail') && typeof(tipOwner.onmousemove) != 'function')
 554      {
 555          tipOwner.onmousemove = function(in_event) { domTT_mousemove(this, in_event); };
 556      }
 557  
 558      if (typeof(tipOwner.onmouseout) != 'function')
 559      {
 560          tipOwner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
 561      }
 562  
 563      if (in_options.get('type') == 'sticky')
 564      {
 565          if (in_options.get('position') == 'absolute' && domTT_dragEnabled && in_options.get('draggable'))
 566          {
 567              if (domLib_isIE)
 568              {
 569                  captionRow.onselectstart = function() { return false; };
 570              }
 571  
 572              // setup drag
 573              captionRow.onmousedown = function(in_event) { domTT_dragStart(tipObj, in_event);  };
 574              captionRow.onmousemove = function(in_event) { domTT_dragUpdate(in_event); };
 575              captionRow.onmouseup = function() { domTT_dragStop(); };
 576          }
 577      }
 578      else if (in_options.get('type') == 'velcro')
 579      {
 580          tipObj.onmouseout = function(in_event) { if (typeof(in_event) == 'undefined') { in_event = event; } if (!domLib_isDescendantOf(in_event[domLib_eventTo], tipObj)) { domTT_deactivate(tipOwner.id); }};
 581      }
 582  
 583      if (in_options.get('position') == 'relative')
 584      {
 585          tipObj.style.position = 'relative';
 586      }
 587  
 588      in_options.set('node', tipObj);
 589      in_options.set('status', 'inactive');
 590  };
 591  
 592  // }}}
 593  // {{{ domTT_show()
 594  
 595  // in_id is either tip id or the owner id
 596  function domTT_show(in_id, in_event)
 597  {
 598      // should always find one since this call would be cancelled if tip was killed
 599      var tooltip = domTT_tooltips.get(in_id);
 600      var status = tooltip.get('status');
 601      var tipObj = tooltip.get('node');
 602  
 603      if (tooltip.get('position') == 'absolute')
 604      {
 605          var mouseX, mouseY;
 606  
 607          if (tooltip.has('x') && tooltip.has('y'))
 608          {
 609              mouseX = tooltip.get('x');
 610              mouseY = tooltip.get('y');
 611          }
 612          else if (!domTT_useGlobalMousePosition || status == 'active' || tooltip.get('delay') == 0)
 613          {
 614              var eventPosition = domLib_getEventPosition(in_event);
 615              var eventX = eventPosition.get('x');
 616              var eventY = eventPosition.get('y');
 617              if (tooltip.get('inframe'))
 618              {
 619                  eventX -= eventPosition.get('scrollX');
 620                  eventY -= eventPosition.get('scrollY');
 621              }
 622  
 623              // only move tip along requested trail axis when updating position
 624              if (status == 'active' && tooltip.get('trail') !== true)
 625              {
 626                  var trail = tooltip.get('trail');
 627                  if (trail == 'x')
 628                  {
 629                      mouseX = eventX;
 630                      mouseY = tooltip.get('mouseY');
 631                  }
 632                  else if (trail == 'y')
 633                  {
 634                      mouseX = tooltip.get('mouseX');
 635                      mouseY = eventY;
 636                  }
 637              }
 638              else
 639              {
 640                  mouseX = eventX;
 641                  mouseY = eventY;
 642              }
 643          }
 644          else
 645          {
 646              mouseX = domTT_mousePosition.get('x');
 647              mouseY = domTT_mousePosition.get('y');
 648              if (tooltip.get('inframe'))
 649              {
 650                  mouseX -= domTT_mousePosition.get('scrollX');
 651                  mouseY -= domTT_mousePosition.get('scrollY');
 652              }
 653          }
 654  
 655          // we are using a grid for updates
 656          if (tooltip.get('grid'))
 657          {
 658              // if this is not a mousemove event or it is a mousemove event on an active tip and
 659              // the movement is bigger than the grid
 660              if (in_event.type != 'mousemove' || (status == 'active' && (Math.abs(tooltip.get('lastX') - mouseX) > tooltip.get('grid') || Math.abs(tooltip.get('lastY') - mouseY) > tooltip.get('grid'))))
 661              {
 662                  tooltip.set('lastX', mouseX);
 663                  tooltip.set('lastY', mouseY);
 664              }
 665              // did not satisfy the grid movement requirement
 666              else
 667              {
 668                  return false;
 669              }
 670          }
 671  
 672          // mouseX and mouseY store the last acknowleged mouse position,
 673          // good for trailing on one axis
 674          tooltip.set('mouseX', mouseX);
 675          tooltip.set('mouseY', mouseY);
 676  
 677          var coordinates;
 678          if (domTT_screenEdgeDetection)
 679          {
 680              coordinates = domTT_correctEdgeBleed(
 681                  tooltip.get('offsetWidth'),
 682                  tooltip.get('offsetHeight'),
 683                  mouseX,
 684                  mouseY,
 685                  tooltip.get('offsetX'),
 686                  tooltip.get('offsetY'),
 687                  tooltip.get('mouseOffset'),
 688                  tooltip.get('inframe') ? window.parent : window
 689              );
 690          }
 691          else
 692          {
 693              coordinates = {
 694                  'x' : mouseX + tooltip.get('offsetX'),
 695                  'y' : mouseY + tooltip.get('offsetY') + tooltip.get('mouseOffset')
 696              };
 697          }
 698  
 699          // update the position
 700          tipObj.style.left = coordinates.x + 'px';
 701          tipObj.style.top = coordinates.y + 'px';
 702  
 703          // increase the tip zIndex so it goes over previously shown tips
 704          tipObj.style.zIndex = domLib_zIndex++;
 705      }
 706  
 707      // if tip is not active, active it now and check for a fade in
 708      if (status == 'pending')
 709      {
 710          // unhide the tooltip
 711          tooltip.set('status', 'active');
 712          tipObj.style.display = '';
 713          tipObj.style.visibility = 'visible';
 714  
 715          var fade = tooltip.get('fade');
 716          if (fade != 'neither')
 717          {
 718              var fadeHandler = tooltip.get('fadeHandler');
 719              if (fade == 'out' || fade == 'both')
 720              {
 721                  fadeHandler.haltFade();
 722                  if (fade == 'out')
 723                  {
 724                      fadeHandler.halt();
 725                  }
 726              }
 727  
 728              if (fade == 'in' || fade == 'both')
 729              {
 730                  fadeHandler.fadeIn();
 731              }
 732          }
 733  
 734          if (tooltip.get('type') == 'greasy' && tooltip.get('lifetime') != 0)
 735          {
 736              tooltip.set('lifetimeTimeout', domLib_setTimeout(domTT_runDeactivate, tooltip.get('lifetime'), [tipObj.id]));
 737          }
 738      }
 739  
 740      if (tooltip.get('position') == 'absolute')
 741      {
 742          domLib_detectCollisions(tipObj);
 743      }
 744  }
 745  
 746  // }}}
 747  // {{{ domTT_close()
 748  
 749  // in_handle can either be an child object of the tip, the tip id or the owner id
 750  function domTT_close(in_handle)
 751  {
 752      var id;
 753      if (typeof(in_handle) == 'object' && in_handle.nodeType)
 754      {
 755          var obj = in_handle;
 756          while (!obj.id || !domTT_tooltips.get(obj.id))
 757          {
 758              obj = obj.parentNode;
 759      
 760              if (obj.nodeType != document.ELEMENT_NODE) { return; }
 761          }
 762  
 763          id = obj.id;
 764      }
 765      else
 766      {
 767          id = in_handle;
 768      }
 769  
 770      domTT_deactivate(id);
 771  }
 772  
 773  // }}}
 774  // {{{ domTT_deactivate()
 775  
 776  // in_id is either the tip id or the owner id
 777  function domTT_deactivate(in_id)
 778  {
 779      var tooltip = domTT_tooltips.get(in_id);
 780      if (tooltip)
 781      {
 782          var status = tooltip.get('status');
 783          if (status == 'pending')
 784          {
 785              // cancel the creation of this tip if it is still pending
 786              domLib_clearTimeout(tooltip.get('activateTimeout'));
 787              tooltip.set('status', 'inactive');
 788          }
 789          else if (status == 'active')
 790          {
 791              if (tooltip.get('lifetime'))
 792              {
 793                  domLib_clearTimeout(tooltip.get('lifetimeTimeout'));
 794              }
 795  
 796              var tipObj = tooltip.get('node');
 797              if (tooltip.get('closeAction') == 'hide')
 798              {
 799                  var fade = tooltip.get('fade');
 800                  if (fade != 'neither')
 801                  {
 802                      var fadeHandler = tooltip.get('fadeHandler');
 803                      if (fade == 'out' || fade == 'both')
 804                      {
 805                          fadeHandler.fadeOut();
 806                      }
 807                      else
 808                      {
 809                          fadeHandler.hide();
 810                      }
 811                  }
 812                  else
 813                  {
 814                      tipObj.style.display = 'none';
 815                  }
 816              }
 817              else
 818              {
 819                  tooltip.get('parent').removeChild(tipObj);
 820                  domTT_tooltips.remove(tooltip.get('owner').id);
 821                  domTT_tooltips.remove(tooltip.get('id'));
 822              }
 823  
 824              tooltip.set('status', 'inactive');
 825              // unhide all of the selects that are owned by this object
 826              domLib_detectCollisions(tipObj, true); 
 827          }
 828      }
 829  }
 830  
 831  // }}}
 832  // {{{ domTT_mouseout()
 833  
 834  function domTT_mouseout(in_owner, in_event)
 835  {
 836      if (!domLib_useLibrary) { return false; }
 837  
 838      if (typeof(in_event) == 'undefined')
 839      {
 840          in_event = event;
 841      }
 842  
 843      var toChild = domLib_isDescendantOf(in_event[domLib_eventTo], in_owner);
 844      var tooltip = domTT_tooltips.get(in_owner.id);
 845      if (tooltip && (tooltip.get('type') == 'greasy' || tooltip.get('status') != 'active'))
 846      {
 847          // deactivate tip if exists and we moved away from the owner
 848          if (!toChild)
 849          {
 850              domTT_deactivate(in_owner.id);
 851              try { window.status = window.defaultStatus; } catch(e) {}
 852          }
 853      }
 854      else if (!toChild)
 855      {
 856          try { window.status = window.defaultStatus; } catch(e) {}
 857      }
 858  }
 859  
 860  // }}}
 861  // {{{ domTT_mousemove()
 862  
 863  function domTT_mousemove(in_owner, in_event)
 864  {
 865      if (!domLib_useLibrary) { return false; }
 866  
 867      if (typeof(in_event) == 'undefined')
 868      {
 869          in_event = event;
 870      }
 871  
 872      var tooltip = domTT_tooltips.get(in_owner.id);
 873      if (tooltip && tooltip.get('trail') && tooltip.get('status') == 'active')
 874      {
 875          // see if we are trailing lazy
 876          if (tooltip.get('lazy'))
 877          {
 878              domLib_setTimeout(domTT_runShow, domTT_trailDelay, [in_owner.id, in_event]);
 879          }
 880          else
 881          {
 882              domTT_show(in_owner.id, in_event);
 883          }
 884      }
 885  }
 886  
 887  // }}}
 888  // {{{ domTT_addPredefined()
 889  
 890  function domTT_addPredefined(in_id)
 891  {
 892      var options = new Hash();
 893      for (var i = 1; i < arguments.length; i += 2)
 894      {
 895          options.set(arguments[i], arguments[i + 1]);
 896      }
 897  
 898      domTT_predefined.set(in_id, options);
 899  }
 900  
 901  // }}}
 902  // {{{ domTT_correctEdgeBleed()
 903  
 904  function domTT_correctEdgeBleed(in_width, in_height, in_x, in_y, in_offsetX, in_offsetY, in_mouseOffset, in_window)
 905  {
 906      var win, doc;
 907      var bleedRight, bleedBottom;
 908      var pageHeight, pageWidth, pageYOffset, pageXOffset;
 909  
 910      var x = in_x + in_offsetX;
 911      var y = in_y + in_offsetY + in_mouseOffset;
 912  
 913      win = (typeof(in_window) == 'undefined' ? window : in_window);
 914  
 915      // Gecko and IE swaps values of clientHeight, clientWidth properties when
 916      // in standards compliance mode from documentElement to document.body
 917      doc = ((domLib_standardsMode && (domLib_isIE || domLib_isGecko)) ? win.document.documentElement : win.document.body);
 918  
 919      // for IE in compliance mode
 920      if (domLib_isIE)
 921      {
 922          pageHeight = doc.clientHeight;
 923          pageWidth = doc.clientWidth;
 924          pageYOffset = doc.scrollTop;
 925          pageXOffset = doc.scrollLeft;
 926      }
 927      else
 928      {
 929          pageHeight = doc.clientHeight;
 930          pageWidth = doc.clientWidth;
 931  
 932          if (domLib_isKHTML)
 933          {
 934              pageHeight = win.innerHeight;
 935          }
 936  
 937          pageYOffset = win.pageYOffset;
 938          pageXOffset = win.pageXOffset;
 939      }
 940  
 941      // we are bleeding off the right, move tip over to stay on page
 942      // logic: take x position, add width and subtract from effective page width
 943      if ((bleedRight = (x - pageXOffset) + in_width - (pageWidth - domTT_screenEdgePadding)) > 0)
 944      {
 945          x -= bleedRight;
 946      }
 947  
 948      // we are bleeding to the left, move tip over to stay on page
 949      // if tip doesn't fit, we will go back to bleeding off the right
 950      // logic: take x position and check if less than edge padding
 951      if ((x - pageXOffset) < domTT_screenEdgePadding)
 952      {
 953          x = domTT_screenEdgePadding + pageXOffset;
 954      }
 955  
 956      // if we are bleeding off the bottom, flip to north
 957      // logic: take y position, add height and subtract from effective page height
 958      if ((bleedBottom = (y - pageYOffset) + in_height - (pageHeight - domTT_screenEdgePadding)) > 0)
 959      {
 960          y = in_y - in_height - in_offsetY;
 961      }
 962  
 963      // if we are bleeding off the top, flip to south
 964      // if tip doesn't fit, we will go back to bleeding off the bottom
 965      // logic: take y position and check if less than edge padding
 966      if ((y - pageYOffset) < domTT_screenEdgePadding)
 967      {
 968          y = in_y + domTT_mouseHeight + in_offsetY;
 969      }
 970  
 971      return {'x' : x, 'y' : y};
 972  }
 973  
 974  // }}}
 975  // {{{ domTT_isActive()
 976  
 977  // in_id is either the tip id or the owner id
 978  function domTT_isActive(in_id)
 979  {
 980      var tooltip = domTT_tooltips.get(in_id);
 981      if (!tooltip || tooltip.get('status') != 'active')
 982      {
 983          return false;
 984      }
 985      else
 986      {
 987          return true;
 988      }
 989  }
 990  
 991  // }}}
 992  // {{{ domTT_runXXX()
 993  
 994  // All of these domMenu_runXXX() methods are used by the event handling sections to
 995  // avoid the circular memory leaks caused by inner functions
 996  function domTT_runDeactivate(args) { domTT_deactivate(args[0]); }
 997  function domTT_runShow(args) { domTT_show(args[0], args[1]); }
 998  
 999  // }}}
1000  // {{{ domTT_replaceTitles()
1001  
1002  function domTT_replaceTitles(in_decorator)
1003  {
1004      var elements = domLib_getElementsByClass('tooltip');
1005      for (var i = 0; i < elements.length; i++)
1006      {
1007          if (elements[i].title)
1008          {
1009              var content;
1010              if (typeof(in_decorator) == 'function')
1011              {
1012                  content = in_decorator(elements[i]);
1013              }
1014              else
1015              {
1016                  content = elements[i].title;
1017              }
1018  
1019              content = content.replace(new RegExp('\'', 'g'), '\\\'');
1020              elements[i].onmouseover = new Function('in_event', "domTT_activate(this, in_event, 'content', '" + content + "')");
1021              elements[i].title = '';
1022          }
1023      }
1024  }
1025  
1026  // }}}
1027  // {{{ domTT_update()
1028  
1029  // Allow authors to update the contents of existing tips using the DOM
1030  function domTT_update(handle, content, type)
1031  {
1032      // type defaults to 'content', can also be 'caption'
1033      if (typeof(type) == 'undefined')
1034      {
1035          type = 'content';
1036      }
1037  
1038      var tip = domTT_tooltips.get(handle);
1039      if (!tip)
1040      {
1041          return;
1042      }
1043  
1044      var tipObj = tip.get('node');
1045      var updateNode;
1046      if (type == 'content')
1047      {
1048          // <div class="contents">...
1049          updateNode = tipObj.firstChild;
1050          if (updateNode.className != 'contents')
1051          {
1052              // <table><tbody><tr>...</tr><tr><td><div class="contents">...
1053              updateNode = updateNode.firstChild.firstChild.nextSibling.firstChild.firstChild;
1054          }
1055      }
1056      else
1057      {
1058          updateNode = tipObj.firstChild;
1059          if (updateNode.className == 'contents')
1060          {
1061              // missing caption
1062              return;
1063          }
1064  
1065          // <table><tbody><tr><td><div class="caption">...
1066          updateNode = updateNode.firstChild.firstChild.firstChild.firstChild;
1067      }
1068  
1069      // TODO: allow for a DOM node as content
1070      updateNode.innerHTML = content;
1071  }
1072  
1073  // }}}
1074  


Généré le : Tue Apr 3 20:47:31 2007 par Balluche grâce à PHPXref 0.7