[ Index ]
 

Code source de DokuWiki 2006-11-06

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

title

Body

[fermer]

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

   1  /** $Id: domLib.js 1952 2005-07-17 16:24:05Z 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 Library Core
  25   * Version: 0.70
  26   *
  27   * Summary:
  28   * A set of commonly used functions that make it easier to create javascript
  29   * applications that rely on the DOM.
  30   *
  31   * Updated: 2005/05/17
  32   *
  33   * Maintainer: Dan Allen <dan.allen@mojavelinux.com>
  34   * Maintainer: Jason Rust <jrust@rustyparts.com>
  35   *
  36   * License: Apache 2.0
  37   */
  38  
  39  // }}}
  40  // {{{ global constants (DO NOT EDIT)
  41  
  42  // -- Browser Detection --
  43  var domLib_userAgent = navigator.userAgent.toLowerCase();
  44  var domLib_isMac = navigator.appVersion.indexOf('Mac') != -1;
  45  var domLib_isWin = domLib_userAgent.indexOf('windows') != -1;
  46  // NOTE: could use window.opera for detecting Opera
  47  var domLib_isOpera = domLib_userAgent.indexOf('opera') != -1;
  48  var domLib_isOpera7up = domLib_userAgent.match(/opera.(7|8)/i);
  49  var domLib_isSafari = domLib_userAgent.indexOf('safari') != -1;
  50  var domLib_isKonq = domLib_userAgent.indexOf('konqueror') != -1;
  51  // Both konqueror and safari use the khtml rendering engine
  52  var domLib_isKHTML = (domLib_isKonq || domLib_isSafari || domLib_userAgent.indexOf('khtml') != -1);
  53  var domLib_isIE = (!domLib_isKHTML && !domLib_isOpera && (domLib_userAgent.indexOf('msie 5') != -1 || domLib_userAgent.indexOf('msie 6') != -1 || domLib_userAgent.indexOf('msie 7') != -1));
  54  var domLib_isIE5up = domLib_isIE;
  55  var domLib_isIE50 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.0') != -1);
  56  var domLib_isIE55 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.5') != -1);
  57  var domLib_isIE5 = (domLib_isIE50 || domLib_isIE55);
  58  // safari and konq may use string "khtml, like gecko", so check for destinctive /
  59  var domLib_isGecko = domLib_userAgent.indexOf('gecko/') != -1;
  60  var domLib_isMacIE = (domLib_isIE && domLib_isMac);
  61  var domLib_isIE55up = domLib_isIE5up && !domLib_isIE50 && !domLib_isMacIE;
  62  var domLib_isIE6up = domLib_isIE55up && !domLib_isIE55;
  63  
  64  // -- Browser Abilities --
  65  var domLib_standardsMode = (document.compatMode && document.compatMode == 'CSS1Compat');
  66  var domLib_useLibrary = (domLib_isOpera7up || domLib_isKHTML || domLib_isIE5up || domLib_isGecko || domLib_isMacIE || document.defaultView);
  67  // fixed in Konq3.2
  68  var domLib_hasBrokenTimeout = (domLib_isMacIE || (domLib_isKonq && domLib_userAgent.match(/konqueror\/3.([2-9])/) === null));
  69  var domLib_canFade = (domLib_isGecko || domLib_isIE || domLib_isSafari || domLib_isOpera);
  70  var domLib_canDrawOverSelect = (domLib_isMac || domLib_isOpera || domLib_isGecko);
  71  var domLib_canDrawOverFlash = (domLib_isMac || domLib_isWin);
  72  
  73  // -- Event Variables --
  74  var domLib_eventTarget = domLib_isIE ? 'srcElement' : 'currentTarget';
  75  var domLib_eventButton = domLib_isIE ? 'button' : 'which';
  76  var domLib_eventTo = domLib_isIE ? 'toElement' : 'relatedTarget';
  77  var domLib_stylePointer = domLib_isIE ? 'hand' : 'pointer';
  78  // NOTE: a bug exists in Opera that prevents maxWidth from being set to 'none', so we make it huge
  79  var domLib_styleNoMaxWidth = domLib_isOpera ? '10000px' : 'none';
  80  var domLib_hidePosition = '-1000px';
  81  var domLib_scrollbarWidth = 14;
  82  var domLib_autoId = 1;
  83  var domLib_zIndex = 100;
  84  
  85  // -- Detection --
  86  var domLib_collisionElements;
  87  var domLib_collisionsCached = false;
  88  
  89  var domLib_timeoutStateId = 0;
  90  var domLib_timeoutStates = new Hash();
  91  
  92  // }}}
  93  // {{{ DOM enhancements
  94  
  95  if (!document.ELEMENT_NODE)
  96  {
  97      document.ELEMENT_NODE = 1;
  98      document.ATTRIBUTE_NODE = 2;
  99      document.TEXT_NODE = 3;
 100      document.DOCUMENT_NODE = 9;
 101      document.DOCUMENT_FRAGMENT_NODE = 11;
 102  }
 103  
 104  function domLib_clone(obj)
 105  {
 106      var copy = {};
 107      for (var i in obj)
 108      {
 109          var value = obj[i];
 110          try
 111          {
 112              if (value !== null && typeof(value) == 'object' && value != window && !value.nodeType)
 113              {
 114                  copy[i] = domLib_clone(value);
 115              }
 116              else
 117              {
 118                  copy[i] = value;
 119              }
 120          }
 121          catch(e)
 122          {
 123              copy[i] = value;
 124          }
 125      }
 126  
 127      return copy;
 128  }
 129  
 130  // }}}
 131  // {{{ class Hash()
 132  
 133  function Hash()
 134  {
 135      this.length = 0;
 136      this.numericLength = 0; 
 137      this.elementData = [];
 138      for (var i = 0; i < arguments.length; i += 2)
 139      {
 140          if (typeof(arguments[i + 1]) != 'undefined')
 141          {
 142              this.elementData[arguments[i]] = arguments[i + 1];
 143              this.length++;
 144              if (arguments[i] == parseInt(arguments[i])) 
 145              {
 146                  this.numericLength++;
 147              }
 148          }
 149      }
 150  }
 151  
 152  // using prototype as opposed to inner functions saves on memory 
 153  Hash.prototype.get = function(in_key)
 154  {
 155      return this.elementData[in_key];
 156  };
 157  
 158  Hash.prototype.set = function(in_key, in_value)
 159  {
 160      if (typeof(in_value) != 'undefined')
 161      {
 162          if (typeof(this.elementData[in_key]) == 'undefined')
 163          {
 164              this.length++;
 165              if (in_key == parseInt(in_key)) 
 166              {
 167                  this.numericLength++;
 168              }
 169          }
 170  
 171          this.elementData[in_key] = in_value;
 172      return this.elementData[in_key];
 173      }
 174  
 175      return false;
 176  };
 177  
 178  Hash.prototype.remove = function(in_key)
 179  {
 180      var tmp_value;
 181      if (typeof(this.elementData[in_key]) != 'undefined')
 182      {
 183          this.length--;
 184          if (in_key == parseInt(in_key)) 
 185          {
 186              this.numericLength--;
 187          }
 188  
 189          tmp_value = this.elementData[in_key];
 190          delete this.elementData[in_key];
 191      }
 192  
 193      return tmp_value;
 194  };
 195  
 196  Hash.prototype.size = function()
 197  {
 198      return this.length;
 199  };
 200  
 201  Hash.prototype.has = function(in_key)
 202  {
 203      return typeof(this.elementData[in_key]) != 'undefined';
 204  };
 205  
 206  Hash.prototype.find = function(in_obj)
 207  {
 208      for (var tmp_key in this.elementData) 
 209      {
 210          if (this.elementData[tmp_key] == in_obj) 
 211          {
 212              return tmp_key;
 213          }
 214      }
 215  };
 216  
 217  Hash.prototype.merge = function(in_hash)
 218  {
 219      for (var tmp_key in in_hash.elementData) 
 220      {
 221          if (typeof(this.elementData[tmp_key]) == 'undefined') 
 222          {
 223              this.length++;
 224              if (tmp_key == parseInt(tmp_key)) 
 225              {
 226                  this.numericLength++;
 227              }
 228          }
 229  
 230          this.elementData[tmp_key] = in_hash.elementData[tmp_key];
 231      }
 232  };
 233  
 234  Hash.prototype.compare = function(in_hash)
 235  {
 236      if (this.length != in_hash.length) 
 237      {
 238          return false;
 239      }
 240  
 241      for (var tmp_key in this.elementData) 
 242      {
 243          if (this.elementData[tmp_key] != in_hash.elementData[tmp_key]) 
 244          {
 245              return false;
 246          }
 247      }
 248      
 249      return true;
 250  };
 251  
 252  // }}}
 253  // {{{ domLib_isDescendantOf()
 254  
 255  function domLib_isDescendantOf(in_object, in_ancestor)
 256  {
 257      if (in_object == in_ancestor)
 258      {
 259          return true;
 260      }
 261  
 262      while (in_object != document.documentElement)
 263      {
 264          try
 265          {
 266              if ((tmp_object = in_object.offsetParent) && tmp_object == in_ancestor)
 267              {
 268                  return true;
 269              }
 270              else if ((tmp_object = in_object.parentNode) == in_ancestor)
 271              {
 272                  return true;
 273              }
 274              else
 275              {
 276                  in_object = tmp_object;
 277              }
 278          }
 279          // in case we get some wierd error, just assume we haven't gone out yet
 280          catch(e)
 281          {
 282              return true;
 283          }
 284      }
 285  
 286      return false;
 287  }
 288  
 289  // }}}
 290  // {{{ domLib_detectCollisions()
 291  
 292  /**
 293   * For any given target element, determine if elements on the page
 294   * are colliding with it that do not obey the rules of z-index.
 295   */
 296  function domLib_detectCollisions(in_object, in_recover, in_useCache)
 297  {
 298      // the reason for the cache is that if the root menu is built before
 299      // the page is done loading, then it might not find all the elements.
 300      // so really the only time you don't use cache is when building the
 301      // menu as part of the page load
 302      if (!domLib_collisionsCached)
 303      {
 304          var tags = [];
 305  
 306          if (!domLib_canDrawOverFlash)
 307          {
 308              tags[tags.length] = 'object';
 309          }
 310  
 311          if (!domLib_canDrawOverSelect)
 312          {
 313              tags[tags.length] = 'select';
 314          }
 315  
 316          domLib_collisionElements = domLib_getElementsByTagNames(tags, true);
 317          domLib_collisionsCached = in_useCache;
 318      }
 319  
 320      // if we don't have a tip, then unhide selects
 321      if (in_recover)
 322      {
 323          for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++)
 324          {
 325              var thisElement = domLib_collisionElements[cnt];
 326  
 327              if (!thisElement.hideList)
 328              {
 329                  thisElement.hideList = new Hash();
 330              }
 331  
 332              thisElement.hideList.remove(in_object.id);
 333              if (!thisElement.hideList.length)
 334              {
 335                  domLib_collisionElements[cnt].style.visibility = 'visible';
 336                  if (domLib_isKonq)
 337                  {
 338                      domLib_collisionElements[cnt].style.display = '';
 339                  }
 340              }
 341          }
 342  
 343          return;
 344      }
 345      else if (domLib_collisionElements.length === 0)
 346      {
 347          return;
 348      }
 349  
 350      // okay, we have a tip, so hunt and destroy
 351      var objectOffsets = domLib_getOffsets(in_object);
 352  
 353      for (cnt = 0; cnt < domLib_collisionElements.length; cnt++)
 354      {
 355          thisElement = domLib_collisionElements[cnt];
 356  
 357          // if collision element is in active element, move on
 358          // WARNING: is this too costly?
 359          if (domLib_isDescendantOf(thisElement, in_object))
 360          {
 361              continue;
 362          }
 363  
 364          // konqueror only has trouble with multirow selects
 365          if (domLib_isKonq &&
 366              thisElement.tagName == 'SELECT' &&
 367              (thisElement.size <= 1 && !thisElement.multiple))
 368          {
 369              continue;
 370          }
 371  
 372          if (!thisElement.hideList)
 373          {
 374              thisElement.hideList = new Hash();
 375          }
 376  
 377          var selectOffsets = domLib_getOffsets(thisElement); 
 378          var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.get('leftCenter') - objectOffsets.get('leftCenter'), 2) + Math.pow(selectOffsets.get('topCenter') - objectOffsets.get('topCenter'), 2));
 379          var radiusSum = selectOffsets.get('radius') + objectOffsets.get('radius');
 380          // the encompassing circles are overlapping, get in for a closer look
 381          if (center2centerDistance < radiusSum)
 382          {
 383              // tip is left of select
 384              if ((objectOffsets.get('leftCenter') <= selectOffsets.get('leftCenter') && objectOffsets.get('right') < selectOffsets.get('left')) ||
 385              // tip is right of select
 386                  (objectOffsets.get('leftCenter') > selectOffsets.get('leftCenter') && objectOffsets.get('left') > selectOffsets.get('right')) ||
 387              // tip is above select
 388                  (objectOffsets.get('topCenter') <= selectOffsets.get('topCenter') && objectOffsets.get('bottom') < selectOffsets.get('top')) ||
 389              // tip is below select
 390                  (objectOffsets.get('topCenter') > selectOffsets.get('topCenter') && objectOffsets.get('top') > selectOffsets.get('bottom')))
 391              {
 392                  thisElement.hideList.remove(in_object.id);
 393                  if (!thisElement.hideList.length)
 394                  {
 395                      thisElement.style.visibility = 'visible';
 396                      if (domLib_isKonq)
 397                      {
 398                          thisElement.style.display = '';
 399                      }
 400                  }
 401              }
 402              else
 403              {
 404                  thisElement.hideList.set(in_object.id, true);
 405                  thisElement.style.visibility = 'hidden';
 406                  if (domLib_isKonq)
 407                  {
 408                      thisElement.style.display = 'none';
 409                  }
 410              }
 411          }
 412      }
 413  }
 414  
 415  // }}}
 416  // {{{ domLib_getOffsets()
 417  
 418  function domLib_getOffsets(in_object)
 419  {
 420      var originalObject = in_object;
 421      var originalWidth = in_object.offsetWidth;
 422      var originalHeight = in_object.offsetHeight;
 423      var offsetLeft = 0;
 424      var offsetTop = 0;
 425  
 426      while (in_object)
 427      {
 428          offsetLeft += in_object.offsetLeft;
 429          offsetTop += in_object.offsetTop;
 430          in_object = in_object.offsetParent;
 431      }
 432  
 433      // MacIE misreports the offsets (even with margin: 0 in body{}), still not perfect
 434      if (domLib_isMacIE) {
 435          offsetLeft += 10;
 436          offsetTop += 10;
 437      }
 438  
 439      return new Hash(
 440          'left',        offsetLeft,
 441          'top',        offsetTop,
 442          'right',    offsetLeft + originalWidth,
 443          'bottom',    offsetTop + originalHeight,
 444          'leftCenter',    offsetLeft + originalWidth/2,
 445          'topCenter',    offsetTop + originalHeight/2,
 446          'radius',    Math.max(originalWidth, originalHeight)    );
 447  }
 448  
 449  // }}}
 450  // {{{ domLib_setTimeout()
 451  
 452  function domLib_setTimeout(in_function, in_timeout, in_args)
 453  {
 454      if (typeof(in_args) == 'undefined')
 455      {
 456          in_args = [];
 457      }
 458  
 459      if (in_timeout == -1)
 460      {
 461          // timeout event is disabled
 462          return;
 463      }
 464      else if (in_timeout === 0)
 465      {
 466          in_function(in_args);
 467          return 0;
 468      }
 469  
 470      // must make a copy of the arguments so that we release the reference
 471      var args = domLib_clone(in_args);
 472  
 473      if (!domLib_hasBrokenTimeout)
 474      {
 475          return setTimeout(function() { in_function(args); }, in_timeout);
 476      }
 477      else
 478      {
 479          var id = domLib_timeoutStateId++;
 480          var data = new Hash();
 481          data.set('function', in_function);
 482          data.set('args', args);
 483          domLib_timeoutStates.set(id, data);
 484  
 485          data.set('timeoutId', setTimeout('domLib_timeoutStates.get(' + id + ').get(\'function\')(domLib_timeoutStates.get(' + id + ').get(\'args\')); domLib_timeoutStates.remove(' + id + ');', in_timeout));
 486          return id;
 487      }
 488  }
 489  
 490  // }}}
 491  // {{{ domLib_clearTimeout()
 492  
 493  function domLib_clearTimeout(in_id)
 494  {
 495      if (!domLib_hasBrokenTimeout)
 496      {
 497          clearTimeout(in_id);
 498      }
 499      else
 500      {
 501          if (domLib_timeoutStates.has(in_id))
 502          {
 503              clearTimeout(domLib_timeoutStates.get(in_id).get('timeoutId'));
 504              domLib_timeoutStates.remove(in_id);
 505          }
 506      }
 507  }
 508  
 509  // }}}
 510  // {{{ domLib_getEventPosition()
 511  
 512  function domLib_getEventPosition(in_eventObj)
 513  {
 514      var eventPosition = new Hash('x', 0, 'y', 0, 'scrollX', 0, 'scrollY', 0);
 515  
 516      // IE varies depending on standard compliance mode
 517      if (domLib_isIE)
 518      {
 519          var doc = (domLib_standardsMode ? document.documentElement : document.body);
 520          // NOTE: events may fire before the body has been loaded
 521          if (doc)
 522          {
 523              eventPosition.set('x', in_eventObj.clientX + doc.scrollLeft);
 524              eventPosition.set('y', in_eventObj.clientY + doc.scrollTop);
 525              eventPosition.set('scrollX', doc.scrollLeft);
 526              eventPosition.set('scrollY', doc.scrollTop);
 527          }
 528      }
 529      else
 530      {
 531          eventPosition.set('x', in_eventObj.pageX);
 532          eventPosition.set('y', in_eventObj.pageY);
 533          eventPosition.set('scrollX', in_eventObj.pageX - in_eventObj.clientX);
 534          eventPosition.set('scrollY', in_eventObj.pageY - in_eventObj.clientY);
 535      }
 536  
 537      return eventPosition;
 538  }
 539  
 540  // }}}
 541  // {{{ domLib_cancelBubble()
 542  
 543  function domLib_cancelBubble(in_event)
 544  {
 545      var eventObj = in_event ? in_event : window.event;
 546      eventObj.cancelBubble = true;
 547  }
 548  
 549  // }}}
 550  // {{{ domLib_getIFrameReference()
 551  
 552  function domLib_getIFrameReference(in_frame)
 553  {
 554      if (domLib_isGecko || domLib_isIE)
 555      {
 556          return in_frame.frameElement;
 557      }
 558      else
 559      {
 560          // we could either do it this way or require an id on the frame
 561          // equivalent to the name
 562          var name = in_frame.name;
 563          if (!name || !in_frame.parent)
 564          {
 565              return;
 566          }
 567  
 568          var candidates = in_frame.parent.document.getElementsByTagName('iframe');
 569          for (var i = 0; i < candidates.length; i++)
 570          {
 571              if (candidates[i].name == name)
 572              {
 573                  return candidates[i];
 574              }
 575          }
 576      }
 577  }
 578  
 579  // }}}
 580  // {{{ domLib_getElementsByClass()
 581  
 582  function domLib_getElementsByClass(in_class)
 583  {
 584      var elements = domLib_isIE5 ? document.all : document.getElementsByTagName('*');    
 585      var matches = [];    
 586      var cnt = 0;
 587      for (var i = 0; i < elements.length; i++)
 588      {
 589          if ((" " + elements[i].className + " ").indexOf(" " + in_class + " ") != -1)
 590          {
 591              matches[cnt++] = elements[i];
 592          }
 593      }
 594  
 595      return matches;
 596  }
 597  
 598  // }}}
 599  // {{{
 600  
 601  function domLib_getElementsByTagNames(in_list, in_excludeHidden)
 602  {
 603      var elements = [];
 604      for (var i = 0; i < in_list.length; i++)
 605      {
 606          var matches = document.getElementsByTagName(in_list[i]);
 607          for (var j = 0; j < matches.length; j++)
 608          {
 609              if (in_excludeHidden && domLib_getComputedStyle(matches[j], 'visibility') == 'hidden')
 610              {
 611                  continue;
 612              }
 613  
 614              elements[elements.length] = matches[j];    
 615          }
 616      }
 617  
 618      return elements;
 619  }
 620  
 621  // }}}
 622  // {{{
 623  
 624  function domLib_getComputedStyle(in_obj, in_property)
 625  {
 626      if (domLib_isIE)
 627      {
 628          var humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); });
 629          return eval('in_obj.currentStyle.' + humpBackProp);
 630      }
 631      // getComputedStyle() is broken in konqueror, so let's go for the style object
 632      else if (domLib_isKonq)
 633      {
 634          humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); });
 635          return eval('in_obj.style.' + in_property);
 636      }
 637      else
 638      {
 639          return document.defaultView.getComputedStyle(in_obj, null).getPropertyValue(in_property);
 640      }
 641  }
 642  
 643  // }}}
 644  // {{{ makeTrue()
 645  
 646  function makeTrue()
 647  {
 648      return true;
 649  }
 650  
 651  // }}}
 652  // {{{ makeFalse()
 653  
 654  function makeFalse()
 655  {
 656      return false;
 657  }
 658  
 659  // }}}
 660  


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