[ Index ]
 

Code source de vtiger CRM 5.0.2

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

title

Body

[fermer]

/include/js/ -> prototype.js (source)

   1  /*  Prototype JavaScript framework, version 1.4.0
   2   *  (c) 2005 Sam Stephenson <sam@conio.net>
   3   *
   4   *  Prototype is freely distributable under the terms of an MIT-style license.
   5   *  For details, see the Prototype web site: http://prototype.conio.net/
   6   *
   7  /*--------------------------------------------------------------------------*/
   8  
   9  var Prototype = {
  10  Version: '1.4.0',
  11  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
  12  
  13  emptyFunction: function() {},
  14  K: function(x) {return x}
  15  }
  16  
  17  var Class = {
  18  create: function() {
  19              return function() {
  20                  this.initialize.apply(this, arguments);
  21              }
  22          }
  23  }
  24  
  25  var Abstract = new Object();
  26  
  27  Object.extend = function(destination, source) {
  28      for (property in source) {
  29          destination[property] = source[property];
  30      }
  31      return destination;
  32  }
  33  
  34  Object.inspect = function(object) {
  35      try {
  36          if (object == undefined) return 'undefined';
  37          if (object == null) return 'null';
  38          return object.inspect ? object.inspect() : object.toString();
  39      } catch (e) {
  40          if (e instanceof RangeError) return '...';
  41          throw e;
  42      }
  43  }
  44  
  45  Function.prototype.bind = function() {
  46      var __method = this, args = $A(arguments), object = args.shift();
  47      return function() {
  48          return __method.apply(object, args.concat($A(arguments)));
  49      }
  50  }
  51  
  52  Function.prototype.bindAsEventListener = function(object) {
  53      var __method = this;
  54      return function(event) {
  55          return __method.call(object, event || window.event);
  56      }
  57  }
  58  
  59  Object.extend(Number.prototype, {
  60  toColorPart: function() {
  61  var digits = this.toString(16);
  62  if (this < 16) return '0' + digits;
  63  return digits;
  64  },
  65  
  66  succ: function() {
  67  return this + 1;
  68  },
  69  
  70  times: function(iterator) {
  71  $R(0, this, true).each(iterator);
  72  return this;
  73  }
  74  });
  75  
  76  var Try = {
  77  these: function() {
  78             var returnValue;
  79  
  80             for (var i = 0; i < arguments.length; i++) {
  81                 var lambda = arguments[i];
  82                 try {
  83                     returnValue = lambda();
  84                     break;
  85                 } catch (e) {}
  86             }
  87  
  88             return returnValue;
  89         }
  90  }
  91  
  92  /*--------------------------------------------------------------------------*/
  93  
  94  var PeriodicalExecuter = Class.create();
  95  PeriodicalExecuter.prototype = {
  96  initialize: function(callback, frequency) {
  97                  this.callback = callback;
  98                  this.frequency = frequency;
  99                  this.currentlyExecuting = false;
 100  
 101                  this.registerCallback();
 102              },
 103  
 104  registerCallback: function() {
 105                        setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
 106                    },
 107  
 108  onTimerEvent: function() {
 109                    if (!this.currentlyExecuting) {
 110                        try {
 111                            this.currentlyExecuting = true;
 112                            this.callback();
 113                        } finally {
 114                            this.currentlyExecuting = false;
 115                        }
 116                    }
 117                }
 118  }
 119  
 120  /*--------------------------------------------------------------------------*/
 121  
 122  function $() {
 123      var elements = new Array();
 124  
 125      for (var i = 0; i < arguments.length; i++) {
 126          var element = arguments[i];
 127          if (typeof element == 'string')
 128              element = document.getElementById(element);
 129  
 130          if (arguments.length == 1)
 131              return element;
 132  
 133          elements.push(element);
 134      }
 135  
 136      return elements;
 137  }
 138  Object.extend(String.prototype, {
 139  stripTags: function() {
 140  return this.replace(/<\/?[^>]+>/gi, '');
 141  },
 142  
 143  stripScripts: function() {
 144  return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
 145  },
 146  
 147  extractScripts: function() {
 148  var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
 149  var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
 150  return (this.match(matchAll) || []).map(function(scriptTag) {
 151      return (scriptTag.match(matchOne) || ['', ''])[1];
 152      });
 153  },
 154  
 155  evalScripts: function() {
 156  return this.extractScripts().map(eval);
 157  },
 158  
 159  escapeHTML: function() {
 160                  var div = document.createElement('div');
 161                  var text = document.createTextNode(this);
 162                  div.appendChild(text);
 163                  return div.innerHTML;
 164              },
 165  
 166  unescapeHTML: function() {
 167                    var div = document.createElement('div');
 168                    div.innerHTML = this.stripTags();
 169                    return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
 170                },
 171  
 172  toQueryParams: function() {
 173                     var pairs = this.match(/^\??(.*)$/)[1].split('&');
 174                     return pairs.inject({}, function(params, pairString) {
 175                             var pair = pairString.split('=');
 176                             params[pair[0]] = pair[1];
 177                             return params;
 178                             });
 179                 },
 180  
 181  toArray: function() {
 182               return this.split('');
 183           },
 184  
 185  camelize: function() {
 186                var oStringList = this.split('-');
 187                if (oStringList.length == 1) return oStringList[0];
 188  
 189                var camelizedString = this.indexOf('-') == 0
 190                    ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
 191                    : oStringList[0];
 192  
 193                for (var i = 1, len = oStringList.length; i < len; i++) {
 194                    var s = oStringList[i];
 195                    camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
 196                }
 197  
 198                return camelizedString;
 199            },
 200  
 201  inspect: function() {
 202               return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
 203           }
 204  });
 205  
 206  String.prototype.parseQuery = String.prototype.toQueryParams;
 207  
 208  var $break    = new Object();
 209  var $continue = new Object();
 210  
 211  var Enumerable = {
 212  each: function(iterator) {
 213            var index = 0;
 214            try {
 215                this._each(function(value) {
 216                        try {
 217                        iterator(value, index++);
 218                        } catch (e) {
 219                        if (e != $continue) throw e;
 220                        }
 221                        });
 222            } catch (e) {
 223                if (e != $break) throw e;
 224            }
 225        },
 226  
 227  all: function(iterator) {
 228           var result = true;
 229           this.each(function(value, index) {
 230                   result = result && !!(iterator || Prototype.K)(value, index);
 231                   if (!result) throw $break;
 232                   });
 233           return result;
 234       },
 235  
 236  any: function(iterator) {
 237           var result = true;
 238           this.each(function(value, index) {
 239                   if (result = !!(iterator || Prototype.K)(value, index))
 240                   throw $break;
 241                   });
 242           return result;
 243       },
 244  
 245  collect: function(iterator) {
 246               var results = [];
 247               this.each(function(value, index) {
 248                       results.push(iterator(value, index));
 249                       });
 250               return results;
 251           },
 252  
 253  detect: function (iterator) {
 254              var result;
 255              this.each(function(value, index) {
 256                      if (iterator(value, index)) {
 257                      result = value;
 258                      throw $break;
 259                      }
 260                      });
 261              return result;
 262          },
 263  
 264  findAll: function(iterator) {
 265               var results = [];
 266               this.each(function(value, index) {
 267                       if (iterator(value, index))
 268                       results.push(value);
 269                       });
 270               return results;
 271           },
 272  
 273  grep: function(pattern, iterator) {
 274            var results = [];
 275            this.each(function(value, index) {
 276                    var stringValue = value.toString();
 277                    if (stringValue.match(pattern))
 278                    results.push((iterator || Prototype.K)(value, index));
 279                    })
 280            return results;
 281        },
 282  
 283  include: function(object) {
 284               var found = false;
 285               this.each(function(value) {
 286                       if (value == object) {
 287                       found = true;
 288                       throw $break;
 289                       }
 290                       });
 291               return found;
 292           },
 293  
 294  inject: function(memo, iterator) {
 295              this.each(function(value, index) {
 296                      memo = iterator(memo, value, index);
 297                      });
 298              return memo;
 299          },
 300  
 301  invoke: function(method) {
 302              var args = $A(arguments).slice(1);
 303              return this.collect(function(value) {
 304                      return value[method].apply(value, args);
 305                      });
 306          },
 307  
 308  max: function(iterator) {
 309           var result;
 310           this.each(function(value, index) {
 311                   value = (iterator || Prototype.K)(value, index);
 312                   if (value >= (result || value))
 313                   result = value;
 314                   });
 315           return result;
 316       },
 317  
 318  min: function(iterator) {
 319           var result;
 320           this.each(function(value, index) {
 321                   value = (iterator || Prototype.K)(value, index);
 322                   if (value <= (result || value))
 323                   result = value;
 324                   });
 325           return result;
 326       },
 327  
 328  partition: function(iterator) {
 329                 var trues = [], falses = [];
 330                 this.each(function(value, index) {
 331                         ((iterator || Prototype.K)(value, index) ?
 332                          trues : falses).push(value);
 333                         });
 334                 return [trues, falses];
 335             },
 336  
 337  pluck: function(property) {
 338             var results = [];
 339             this.each(function(value, index) {
 340                     results.push(value[property]);
 341                     });
 342             return results;
 343         },
 344  
 345  reject: function(iterator) {
 346              var results = [];
 347              this.each(function(value, index) {
 348                      if (!iterator(value, index))
 349                      results.push(value);
 350                      });
 351              return results;
 352          },
 353  
 354  sortBy: function(iterator) {
 355              return this.collect(function(value, index) {
 356                      return {value: value, criteria: iterator(value, index)};
 357                      }).sort(function(left, right) {
 358                          var a = left.criteria, b = right.criteria;
 359                          return a < b ? -1 : a > b ? 1 : 0;
 360                          }).pluck('value');
 361          },
 362  
 363  toArray: function() {
 364               return this.collect(Prototype.K);
 365           },
 366  
 367  zip: function() {
 368           var iterator = Prototype.K, args = $A(arguments);
 369           if (typeof args.last() == 'function')
 370               iterator = args.pop();
 371  
 372           var collections = [this].concat(args).map($A);
 373           return this.map(function(value, index) {
 374                   iterator(value = collections.pluck(index));
 375                   return value;
 376                   });
 377       },
 378  
 379  inspect: function() {
 380               return '#<Enumerable:' + this.toArray().inspect() + '>';
 381           }
 382  }
 383  
 384  Object.extend(Enumerable, {
 385  map:     Enumerable.collect,
 386  find:    Enumerable.detect,
 387  select:  Enumerable.findAll,
 388  member:  Enumerable.include,
 389  entries: Enumerable.toArray
 390  });
 391  var $A = Array.from = function(iterable) {
 392      if (!iterable) return [];
 393      if (iterable.toArray) {
 394          return iterable.toArray();
 395      } else {
 396          var results = [];
 397          for (var i = 0; i < iterable.length; i++)
 398              results.push(iterable[i]);
 399          return results;
 400      }
 401  }
 402  
 403  Object.extend(Array.prototype, Enumerable);
 404  
 405  Array.prototype._reverse = Array.prototype.reverse;
 406  
 407  Object.extend(Array.prototype, {
 408  _each: function(iterator) {
 409  for (var i = 0; i < this.length; i++)
 410  iterator(this[i]);
 411  },
 412  
 413  clear: function() {
 414  this.length = 0;
 415  return this;
 416  },
 417  
 418  first: function() {
 419  return this[0];
 420  },
 421  
 422  last: function() {
 423  return this[this.length - 1];
 424  },
 425  
 426  compact: function() {
 427  return this.select(function(value) {
 428      return value != undefined || value != null;
 429      });
 430           },
 431  
 432  flatten: function() {
 433               return this.inject([], function(array, value) {
 434                       return array.concat(value.constructor == Array ?
 435                           value.flatten() : [value]);
 436                       });
 437           },
 438  
 439  without: function() {
 440               var values = $A(arguments);
 441               return this.select(function(value) {
 442                       return !values.include(value);
 443                       });
 444           },
 445  
 446  indexOf: function(object) {
 447               for (var i = 0; i < this.length; i++)
 448                   if (this[i] == object) return i;
 449               return -1;
 450           },
 451  
 452  reverse: function(inline) {
 453               return (inline !== false ? this : this.toArray())._reverse();
 454           },
 455  
 456  shift: function() {
 457             var result = this[0];
 458             for (var i = 0; i < this.length - 1; i++)
 459                 this[i] = this[i + 1];
 460             this.length--;
 461             return result;
 462         },
 463  
 464  inspect: function() {
 465               return '[' + this.map(Object.inspect).join(', ') + ']';
 466           }
 467  });
 468  var Hash = {
 469  _each: function(iterator) {
 470             for (key in this) {
 471                 var value = this[key];
 472                 if (typeof value == 'function') continue;
 473  
 474                 var pair = [key, value];
 475                 pair.key = key;
 476                 pair.value = value;
 477                 iterator(pair);
 478             }
 479         },
 480  
 481  keys: function() {
 482            return this.pluck('key');
 483        },
 484  
 485  values: function() {
 486              return this.pluck('value');
 487          },
 488  
 489  merge: function(hash) {
 490             return $H(hash).inject($H(this), function(mergedHash, pair) {
 491                     mergedHash[pair.key] = pair.value;
 492                     return mergedHash;
 493                     });
 494         },
 495  
 496  toQueryString: function() {
 497                     return this.map(function(pair) {
 498                             return pair.map(encodeURIComponent).join('=');
 499                             }).join('&');
 500                 },
 501  
 502  inspect: function() {
 503               return '#<Hash:{' + this.map(function(pair) {
 504                       return pair.map(Object.inspect).join(': ');
 505                       }).join(', ') + '}>';
 506           }
 507  }
 508  
 509  function $H(object) {
 510      var hash = Object.extend({}, object || {});
 511      Object.extend(hash, Enumerable);
 512      Object.extend(hash, Hash);
 513      return hash;
 514  }
 515  ObjectRange = Class.create();
 516  Object.extend(ObjectRange.prototype, Enumerable);
 517  Object.extend(ObjectRange.prototype, {
 518  initialize: function(start, end, exclusive) {
 519  this.start = start;
 520  this.end = end;
 521  this.exclusive = exclusive;
 522  },
 523  
 524  _each: function(iterator) {
 525  var value = this.start;
 526  do {
 527  iterator(value);
 528  value = value.succ();
 529  } while (this.include(value));
 530  },
 531  
 532  include: function(value) {
 533  if (value < this.start)
 534  return false;
 535  if (this.exclusive)
 536  return value < this.end;
 537  return value <= this.end;
 538  }
 539  });
 540  
 541  var $R = function(start, end, exclusive) {
 542      return new ObjectRange(start, end, exclusive);
 543  }
 544  
 545  var Ajax = {
 546  getTransport: function() {
 547                    return Try.these(
 548                            function() {return new ActiveXObject('Msxml2.XMLHTTP')},
 549                            function() {return new ActiveXObject('Microsoft.XMLHTTP')},
 550                            function() {return new XMLHttpRequest()}
 551                            ) || false;
 552                },
 553  
 554  activeRequestCount: 0
 555  }
 556  
 557  Ajax.Responders = {
 558  responders: [],
 559  
 560  _each: function(iterator) {
 561             this.responders._each(iterator);
 562         },
 563  
 564  register: function(responderToAdd) {
 565                if (!this.include(responderToAdd))
 566                    this.responders.push(responderToAdd);
 567            },
 568  
 569  unregister: function(responderToRemove) {
 570                  this.responders = this.responders.without(responderToRemove);
 571              },
 572  
 573  dispatch: function(callback, request, transport, json) {
 574                this.each(function(responder) {
 575                        if (responder[callback] && typeof responder[callback] == 'function') {
 576                        try {
 577                        responder[callback].apply(responder, [request, transport, json]);
 578                        } catch (e) {}
 579                        }
 580                        });
 581            }
 582  };
 583  
 584  Object.extend(Ajax.Responders, Enumerable);
 585  
 586  Ajax.Responders.register({
 587  onCreate: function() {
 588  Ajax.activeRequestCount++;
 589  },
 590  
 591  onComplete: function() {
 592  Ajax.activeRequestCount--;
 593  }
 594  });
 595  
 596  Ajax.Base = function() {};
 597  Ajax.Base.prototype = {
 598  setOptions: function(options) {
 599                  this.options = {
 600  method:       'post',
 601  asynchronous: true,
 602  parameters:   ''
 603                  }
 604                  Object.extend(this.options, options || {});
 605              },
 606  
 607  responseIsSuccess: function() {
 608                         return this.transport.status == undefined
 609                             || this.transport.status == 0
 610                             || (this.transport.status >= 200 && this.transport.status < 300);
 611                     },
 612  
 613  responseIsFailure: function() {
 614                         return !this.responseIsSuccess();
 615                     }
 616  }
 617  
 618  Ajax.Request = Class.create();
 619  Ajax.Request.Events =
 620  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
 621  
 622  Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
 623  initialize: function(url, options) {
 624  this.transport = Ajax.getTransport();
 625  this.setOptions(options);
 626  this.request(url);
 627  },
 628  
 629  request: function(url) {
 630  var parameters = this.options.parameters || '';
 631  if (parameters.length > 0) parameters += '&_=';
 632  
 633  try {
 634  this.url = url;
 635  if (this.options.method == 'get' && parameters.length > 0)
 636  this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
 637  
 638  Ajax.Responders.dispatch('onCreate', this, this.transport);
 639  
 640  this.transport.open(this.options.method, this.url,
 641      this.options.asynchronous);
 642  
 643  if (this.options.asynchronous) {
 644      this.transport.onreadystatechange = this.onStateChange.bind(this);
 645      setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
 646  }
 647  
 648  this.setRequestHeaders();
 649  
 650  var body = this.options.postBody ? this.options.postBody : parameters;
 651  this.transport.send(this.options.method == 'post' ? body : null);
 652  
 653  } catch (e) {
 654      this.dispatchException(e);
 655  }
 656  },
 657  
 658  setRequestHeaders: function() {
 659                         var requestHeaders =
 660                             ['X-Requested-With', 'XMLHttpRequest',
 661                         'X-Prototype-Version', Prototype.Version];
 662  
 663                         if (this.options.method == 'post') {
 664                             requestHeaders.push('Content-type',
 665                                     'application/x-www-form-urlencoded');
 666  
 667                             /* Force "Connection: close" for Mozilla browsers to work around
 668                              * a bug where XMLHttpReqeuest sends an incorrect Content-length
 669                              * header. See Mozilla Bugzilla #246651.
 670                              */
 671                             if (this.transport.overrideMimeType)
 672                                 requestHeaders.push('Connection', 'close');
 673                         }
 674  
 675                         if (this.options.requestHeaders)
 676                             requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
 677  
 678                         for (var i = 0; i < requestHeaders.length; i += 2)
 679                             this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
 680                     },
 681  
 682  onStateChange: function() {
 683                     var readyState = this.transport.readyState;
 684                     if (readyState != 1)
 685                         this.respondToReadyState(this.transport.readyState);
 686                 },
 687  
 688  header: function(name) {
 689              try {
 690                  return this.transport.getResponseHeader(name);
 691              } catch (e) {}
 692          },
 693  
 694  evalJSON: function() {
 695                try {
 696                    return eval(this.header('X-JSON'));
 697                } catch (e) {}
 698            },
 699  
 700  evalResponse: function() {
 701                    try {
 702                        return eval(this.transport.responseText);
 703                    } catch (e) {
 704                        this.dispatchException(e);
 705                    }
 706                },
 707  
 708  respondToReadyState: function(readyState) {
 709                           var event = Ajax.Request.Events[readyState];
 710                           var transport = this.transport, json = this.evalJSON();
 711  
 712                           if (event == 'Complete') {
 713                               try {
 714                                   (this.options['on' + this.transport.status]
 715                                    || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
 716                                    || Prototype.emptyFunction)(transport, json);
 717                               } catch (e) {
 718                                   this.dispatchException(e);
 719                               }
 720  
 721                               if ((this.header('Content-type') || '').match(/^text\/javascript/i))
 722                                   this.evalResponse();
 723                           }
 724  
 725                           try {
 726                               (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
 727                               Ajax.Responders.dispatch('on' + event, this, transport, json);
 728                           } catch (e) {
 729                               this.dispatchException(e);
 730                           }
 731  
 732                           /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
 733                           if (event == 'Complete')
 734                               this.transport.onreadystatechange = Prototype.emptyFunction;
 735                       },
 736  
 737  dispatchException: function(exception) {
 738                         (this.options.onException || Prototype.emptyFunction)(this, exception);
 739                         Ajax.Responders.dispatch('onException', this, exception);
 740                     }
 741  });
 742  
 743  Ajax.Updater = Class.create();
 744  
 745  Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
 746  initialize: function(container, url, options) {
 747  this.containers = {
 748  success: container.success ? $(container.success) : $(container),
 749  failure: container.failure ? $(container.failure) :
 750  (container.success ? null : $(container))
 751  }
 752  
 753  this.transport = Ajax.getTransport();
 754  this.setOptions(options);
 755  
 756  var onComplete = this.options.onComplete || Prototype.emptyFunction;
 757  this.options.onComplete = (function(transport, object) {
 758      this.updateContent();
 759      onComplete(transport, object);
 760      }).bind(this);
 761  
 762  this.request(url);
 763  },
 764  
 765  updateContent: function() {
 766  var receiver = this.responseIsSuccess() ?
 767      this.containers.success : this.containers.failure;
 768  var response = this.transport.responseText;
 769  
 770  if (!this.options.evalScripts)
 771      response = response.stripScripts();
 772  
 773  if (receiver) {
 774      if (this.options.insertion) {
 775          new this.options.insertion(receiver, response);
 776      } else {
 777          Element.update(receiver, response);
 778      }
 779  }
 780  
 781      if (this.responseIsSuccess()) {
 782          if (this.onComplete)
 783              setTimeout(this.onComplete.bind(this), 10);
 784      }
 785  }
 786  });
 787  
 788  Ajax.PeriodicalUpdater = Class.create();
 789  Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
 790  initialize: function(container, url, options) {
 791  this.setOptions(options);
 792  this.onComplete = this.options.onComplete;
 793  
 794  this.frequency = (this.options.frequency || 2);
 795  this.decay = (this.options.decay || 1);
 796  
 797  this.updater = {};
 798  this.container = container;
 799  this.url = url;
 800  
 801  this.start();
 802  },
 803  
 804  start: function() {
 805  this.options.onComplete = this.updateComplete.bind(this);
 806  this.onTimerEvent();
 807  },
 808  
 809  stop: function() {
 810  this.updater.onComplete = undefined;
 811  clearTimeout(this.timer);
 812  (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
 813        },
 814  
 815  updateComplete: function(request) {
 816                      if (this.options.decay) {
 817                          this.decay = (request.responseText == this.lastText ?
 818                                  this.decay * this.options.decay : 1);
 819  
 820                          this.lastText = request.responseText;
 821                      }
 822                      this.timer = setTimeout(this.onTimerEvent.bind(this),
 823                              this.decay * this.frequency * 1000);
 824                  },
 825  
 826  onTimerEvent: function() {
 827                    this.updater = new Ajax.Updater(this.container, this.url, this.options);
 828                }
 829  });
 830  document.getElementsByClassName = function(className, parentElement) {
 831      var children = ($(parentElement) || document.body).getElementsByTagName('*');
 832      return $A(children).inject([], function(elements, child) {
 833              if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
 834              elements.push(child);
 835              return elements;
 836              });
 837  }
 838  
 839  /*--------------------------------------------------------------------------*/
 840  
 841  if (!window.Element) {
 842      var Element = new Object();
 843  }
 844  
 845  Object.extend(Element, {
 846  visible: function(element) {
 847  return $(element).style.display != 'none';
 848  },
 849  
 850  toggle: function() {
 851  for (var i = 0; i < arguments.length; i++) {
 852  var element = $(arguments[i]);
 853  Element[Element.visible(element) ? 'hide' : 'show'](element);
 854  }
 855  },
 856  
 857  hide: function() {
 858  for (var i = 0; i < arguments.length; i++) {
 859  var element = $(arguments[i]);
 860  element.style.display = 'none';
 861  }
 862  },
 863  
 864  show: function() {
 865  for (var i = 0; i < arguments.length; i++) {
 866  var element = $(arguments[i]);
 867  element.style.display = '';
 868  }
 869  },
 870  
 871  remove: function(element) {
 872              element = $(element);
 873              element.parentNode.removeChild(element);
 874          },
 875  
 876  update: function(element, html) {
 877              $(element).innerHTML = html.stripScripts();
 878              setTimeout(function() {html.evalScripts()}, 10);
 879          },
 880  
 881  getHeight: function(element) {
 882                 element = $(element);
 883                 return element.offsetHeight;
 884             },
 885  
 886  classNames: function(element) {
 887                  return new Element.ClassNames(element);
 888              },
 889  
 890  hasClassName: function(element, className) {
 891                    if (!(element = $(element))) return;
 892                    return Element.classNames(element).include(className);
 893                },
 894  
 895  addClassName: function(element, className) {
 896                    if (!(element = $(element))) return;
 897                    return Element.classNames(element).add(className);
 898                },
 899  
 900  removeClassName: function(element, className) {
 901                       if (!(element = $(element))) return;
 902                       return Element.classNames(element).remove(className);
 903                   },
 904  
 905  // removes whitespace-only text node children
 906  cleanWhitespace: function(element) {
 907                       element = $(element);
 908                       for (var i = 0; i < element.childNodes.length; i++) {
 909                           var node = element.childNodes[i];
 910                           if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
 911                               Element.remove(node);
 912                       }
 913                   },
 914  
 915  empty: function(element) {
 916             return $(element).innerHTML.match(/^\s*$/);
 917         },
 918  
 919  scrollTo: function(element) {
 920                element = $(element);
 921                var x = element.x ? element.x : element.offsetLeft,
 922                y = element.y ? element.y : element.offsetTop;
 923                window.scrollTo(x, y);
 924            },
 925  
 926  getStyle: function(element, style) {
 927                element = $(element);
 928                var value = element.style[style.camelize()];
 929                if (!value) {
 930                    if (document.defaultView && document.defaultView.getComputedStyle) {
 931                        var css = document.defaultView.getComputedStyle(element, null);
 932                        value = css ? css.getPropertyValue(style) : null;
 933                    } else if (element.currentStyle) {
 934                        value = element.currentStyle[style.camelize()];
 935                    }
 936                }
 937  
 938                if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
 939                    if (Element.getStyle(element, 'position') == 'static') value = 'auto';
 940  
 941                return value == 'auto' ? null : value;
 942            },
 943  
 944  setStyle: function(element, style) {
 945                element = $(element);
 946                for (name in style)
 947                    element.style[name.camelize()] = style[name];
 948            },
 949  
 950  getDimensions: function(element) {
 951                     element = $(element);
 952                     if (Element.getStyle(element, 'display') != 'none')
 953                         return {width: element.offsetWidth, height: element.offsetHeight};
 954  
 955                     // All *Width and *Height properties give 0 on elements with display none,
 956                     // so enable the element temporarily
 957                     var els = element.style;
 958                     var originalVisibility = els.visibility;
 959                     var originalPosition = els.position;
 960                     els.visibility = 'hidden';
 961                     els.position = 'absolute';
 962                     els.display = '';
 963                     var originalWidth = element.clientWidth;
 964                     var originalHeight = element.clientHeight;
 965                     els.display = 'none';
 966                     els.position = originalPosition;
 967                     els.visibility = originalVisibility;
 968                     return {width: originalWidth, height: originalHeight};
 969                 },
 970  
 971  makePositioned: function(element) {
 972                      element = $(element);
 973                      var pos = Element.getStyle(element, 'position');
 974                      if (pos == 'static' || !pos) {
 975                          element._madePositioned = true;
 976                          element.style.position = 'relative';
 977                          // Opera returns the offset relative to the positioning context, when an
 978                          // element is position relative but top and left have not been defined
 979                          if (window.opera) {
 980                              element.style.top = 0;
 981                              element.style.left = 0;
 982                          }
 983                      }
 984                  },
 985  
 986  undoPositioned: function(element) {
 987                      element = $(element);
 988                      if (element._madePositioned) {
 989                          element._madePositioned = undefined;
 990                          element.style.position =
 991                              element.style.top =
 992                              element.style.left =
 993                              element.style.bottom =
 994                              element.style.right = '';
 995                      }
 996                  },
 997  
 998  makeClipping: function(element) {
 999                    element = $(element);
1000                    if (element._overflow) return;
1001                    element._overflow = element.style.overflow;
1002                    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
1003                        element.style.overflow = 'hidden';
1004                },
1005  
1006  undoClipping: function(element) {
1007                    element = $(element);
1008                    if (element._overflow) return;
1009                    element.style.overflow = element._overflow;
1010                    element._overflow = undefined;
1011                }
1012  });
1013  
1014  var Toggle = new Object();
1015  Toggle.display = Element.toggle;
1016  
1017  /*--------------------------------------------------------------------------*/
1018  
1019  Abstract.Insertion = function(adjacency) {
1020      this.adjacency = adjacency;
1021  }
1022  
1023  Abstract.Insertion.prototype = {
1024  initialize: function(element, content) {
1025                  this.element = $(element);
1026                  this.content = content.stripScripts();
1027  
1028                  if (this.adjacency && this.element.insertAdjacentHTML) {
1029                      try {
1030                          this.element.insertAdjacentHTML(this.adjacency, this.content);
1031                      } catch (e) {
1032                          if (this.element.tagName.toLowerCase() == 'tbody') {
1033                              this.insertContent(this.contentFromAnonymousTable());
1034                          } else {
1035                              throw e;
1036                          }
1037                      }
1038                  } else {
1039                      this.range = this.element.ownerDocument.createRange();
1040                      if (this.initializeRange) this.initializeRange();
1041                      this.insertContent([this.range.createContextualFragment(this.content)]);
1042                  }
1043  
1044                  setTimeout(function() {content.evalScripts()}, 10);
1045              },
1046  
1047  contentFromAnonymousTable: function() {
1048                                 var div = document.createElement('div');
1049                                 div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
1050                                 return $A(div.childNodes[0].childNodes[0].childNodes);
1051                             }
1052  }
1053  
1054  var Insertion = new Object();
1055  
1056  Insertion.Before = Class.create();
1057  Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
1058  initializeRange: function() {
1059  this.range.setStartBefore(this.element);
1060  },
1061  
1062  insertContent: function(fragments) {
1063  fragments.each((function(fragment) {
1064          this.element.parentNode.insertBefore(fragment, this.element);
1065          }).bind(this));
1066  }
1067  });
1068  
1069  Insertion.Top = Class.create();
1070  Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
1071  initializeRange: function() {
1072  this.range.selectNodeContents(this.element);
1073  this.range.collapse(true);
1074  },
1075  
1076  insertContent: function(fragments) {
1077  fragments.reverse(false).each((function(fragment) {
1078          this.element.insertBefore(fragment, this.element.firstChild);
1079          }).bind(this));
1080  }
1081  });
1082  
1083  Insertion.Bottom = Class.create();
1084  Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
1085  initializeRange: function() {
1086  this.range.selectNodeContents(this.element);
1087  this.range.collapse(this.element);
1088  },
1089  
1090  insertContent: function(fragments) {
1091  fragments.each((function(fragment) {
1092          this.element.appendChild(fragment);
1093          }).bind(this));
1094  }
1095  });
1096  
1097  Insertion.After = Class.create();
1098  Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
1099  initializeRange: function() {
1100  this.range.setStartAfter(this.element);
1101  },
1102  
1103  insertContent: function(fragments) {
1104  fragments.each((function(fragment) {
1105          this.element.parentNode.insertBefore(fragment,
1106              this.element.nextSibling);
1107          }).bind(this));
1108  }
1109  });
1110  
1111  /*--------------------------------------------------------------------------*/
1112  
1113  Element.ClassNames = Class.create();
1114  Element.ClassNames.prototype = {
1115  initialize: function(element) {
1116                  this.element = $(element);
1117              },
1118  
1119  _each: function(iterator) {
1120             this.element.className.split(/\s+/).select(function(name) {
1121                     return name.length > 0;
1122                     })._each(iterator);
1123         },
1124  
1125  set: function(className) {
1126           this.element.className = className;
1127       },
1128  
1129  add: function(classNameToAdd) {
1130           if (this.include(classNameToAdd)) return;
1131           this.set(this.toArray().concat(classNameToAdd).join(' '));
1132       },
1133  
1134  remove: function(classNameToRemove) {
1135              if (!this.include(classNameToRemove)) return;
1136              this.set(this.select(function(className) {
1137                          return className != classNameToRemove;
1138                          }).join(' '));
1139          },
1140  
1141  toString: function() {
1142                return this.toArray().join(' ');
1143            }
1144  }
1145  
1146  Object.extend(Element.ClassNames.prototype, Enumerable);
1147  var Field = {
1148  clear: function() {
1149             for (var i = 0; i < arguments.length; i++)
1150                 $(arguments[i]).value = '';
1151         },
1152  
1153  focus: function(element) {
1154             $(element).focus();
1155         },
1156  
1157  present: function() {
1158               for (var i = 0; i < arguments.length; i++)
1159                   if ($(arguments[i]).value == '') return false;
1160               return true;
1161           },
1162  
1163  select: function(element) {
1164              $(element).select();
1165          },
1166  
1167  activate: function(element) {
1168                element = $(element);
1169                element.focus();
1170                if (element.select)
1171                    element.select();
1172            }
1173  }
1174  
1175  /*--------------------------------------------------------------------------*/
1176  
1177  var Form = {
1178  serialize: function(form) {
1179                 var elements = Form.getElements($(form));
1180                 var queryComponents = new Array();
1181  
1182                 for (var i = 0; i < elements.length; i++) {
1183                     var queryComponent = Form.Element.serialize(elements[i]);
1184                     if (queryComponent)
1185                         queryComponents.push(queryComponent);
1186                 }
1187  
1188                 return queryComponents.join('&');
1189             },
1190  
1191  getElements: function(form) {
1192                   form = $(form);
1193                   var elements = new Array();
1194  
1195                   for (tagName in Form.Element.Serializers) {
1196                       var tagElements = form.getElementsByTagName(tagName);
1197                       for (var j = 0; j < tagElements.length; j++)
1198                           elements.push(tagElements[j]);
1199                   }
1200                   return elements;
1201               },
1202  
1203  getInputs: function(form, typeName, name) {
1204                 form = $(form);
1205                 var inputs = form.getElementsByTagName('input');
1206  
1207                 if (!typeName && !name)
1208                     return inputs;
1209  
1210                 var matchingInputs = new Array();
1211                 for (var i = 0; i < inputs.length; i++) {
1212                     var input = inputs[i];
1213                     if ((typeName && input.type != typeName) ||
1214                             (name && input.name != name))
1215                         continue;
1216                     matchingInputs.push(input);
1217                 }
1218  
1219                 return matchingInputs;
1220             },
1221  
1222  disable: function(form) {
1223               var elements = Form.getElements(form);
1224               for (var i = 0; i < elements.length; i++) {
1225                   var element = elements[i];
1226                   element.blur();
1227                   element.disabled = 'true';
1228               }
1229           },
1230  
1231  enable: function(form) {
1232              var elements = Form.getElements(form);
1233              for (var i = 0; i < elements.length; i++) {
1234                  var element = elements[i];
1235                  element.disabled = '';
1236              }
1237          },
1238  
1239  findFirstElement: function(form) {
1240                        return Form.getElements(form).find(function(element) {
1241                                return element.type != 'hidden' && !element.disabled &&
1242                                ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
1243                                });
1244                    },
1245  
1246  focusFirstElement: function(form) {
1247                         Field.activate(Form.findFirstElement(form));
1248                     },
1249  
1250  reset: function(form) {
1251             $(form).reset();
1252         }
1253  }
1254  
1255  Form.Element = {
1256  serialize: function(element) {
1257                 element = $(element);
1258                 var method = element.tagName.toLowerCase();
1259                 var parameter = Form.Element.Serializers[method](element);
1260  
1261                 if (parameter) {
1262                     var key = encodeURIComponent(parameter[0]);
1263                     if (key.length == 0) return;
1264  
1265                     if (parameter[1].constructor != Array)
1266                         parameter[1] = [parameter[1]];
1267  
1268                     return parameter[1].map(function(value) {
1269                             return key + '=' + encodeURIComponent(value);
1270                             }).join('&');
1271                 }
1272             },
1273  
1274  getValue: function(element) {
1275                element = $(element);
1276                var method = element.tagName.toLowerCase();
1277                var parameter = Form.Element.Serializers[method](element);
1278  
1279                if (parameter)
1280                    return parameter[1];
1281            }
1282  }
1283  
1284  Form.Element.Serializers = {
1285  input: function(element) {
1286             switch (element.type.toLowerCase()) {
1287                 case 'submit':
1288                 case 'hidden':
1289                 case 'password':
1290                 case 'text':
1291                     return Form.Element.Serializers.textarea(element);
1292                 case 'checkbox':
1293                 case 'radio':
1294                     return Form.Element.Serializers.inputSelector(element);
1295             }
1296             return false;
1297         },
1298  
1299  inputSelector: function(element) {
1300                     if (element.checked)
1301                         return [element.name, element.value];
1302                 },
1303  
1304  textarea: function(element) {
1305                return [element.name, element.value];
1306            },
1307  
1308  select: function(element) {
1309              return Form.Element.Serializers[element.type == 'select-one' ?
1310                  'selectOne' : 'selectMany'](element);
1311          },
1312  
1313  selectOne: function(element) {
1314                 var value = '', opt, index = element.selectedIndex;
1315                 if (index >= 0) {
1316                     opt = element.options[index];
1317                     value = opt.value;
1318                     if (!value && !('value' in opt))
1319                         value = opt.text;
1320                 }
1321                 return [element.name, value];
1322             },
1323  
1324  selectMany: function(element) {
1325                  var value = new Array();
1326                  for (var i = 0; i < element.length; i++) {
1327                      var opt = element.options[i];
1328                      if (opt.selected) {
1329                          var optValue = opt.value;
1330                          if (!optValue && !('value' in opt))
1331                              optValue = opt.text;
1332                          value.push(optValue);
1333                      }
1334                  }
1335                  return [element.name, value];
1336              }
1337  }
1338  
1339  /*--------------------------------------------------------------------------*/
1340  
1341  var $F = Form.Element.getValue;
1342  
1343  /*--------------------------------------------------------------------------*/
1344  
1345  Abstract.TimedObserver = function() {}
1346  Abstract.TimedObserver.prototype = {
1347  initialize: function(element, frequency, callback) {
1348                  this.frequency = frequency;
1349                  this.element   = $(element);
1350                  this.callback  = callback;
1351  
1352                  this.lastValue = this.getValue();
1353                  this.registerCallback();
1354              },
1355  
1356  registerCallback: function() {
1357                        setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
1358                    },
1359  
1360  onTimerEvent: function() {
1361                    var value = this.getValue();
1362                    if (this.lastValue != value) {
1363                        this.callback(this.element, value);
1364                        this.lastValue = value;
1365                    }
1366                }
1367  }
1368  
1369  Form.Element.Observer = Class.create();
1370  Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
1371  getValue: function() {
1372  return Form.Element.getValue(this.element);
1373  }
1374  });
1375  
1376  Form.Observer = Class.create();
1377  Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
1378  getValue: function() {
1379  return Form.serialize(this.element);
1380  }
1381  });
1382  
1383  /*--------------------------------------------------------------------------*/
1384  
1385  Abstract.EventObserver = function() {}
1386  Abstract.EventObserver.prototype = {
1387  initialize: function(element, callback) {
1388                  this.element  = $(element);
1389                  this.callback = callback;
1390  
1391                  this.lastValue = this.getValue();
1392                  if (this.element.tagName.toLowerCase() == 'form')
1393                      this.registerFormCallbacks();
1394                  else
1395                      this.registerCallback(this.element);
1396              },
1397  
1398  onElementEvent: function() {
1399                      var value = this.getValue();
1400                      if (this.lastValue != value) {
1401                          this.callback(this.element, value);
1402                          this.lastValue = value;
1403                      }
1404                  },
1405  
1406  registerFormCallbacks: function() {
1407                             var elements = Form.getElements(this.element);
1408                             for (var i = 0; i < elements.length; i++)
1409                                 this.registerCallback(elements[i]);
1410                         },
1411  
1412  registerCallback: function(element) {
1413                        if (element.type) {
1414                            switch (element.type.toLowerCase()) {
1415                                case 'checkbox':
1416                                case 'radio':
1417                                    Event.observe(element, 'click', this.onElementEvent.bind(this));
1418                                    break;
1419                                case 'password':
1420                                case 'text':
1421                                case 'textarea':
1422                                case 'select-one':
1423                                case 'select-multiple':
1424                                    Event.observe(element, 'change', this.onElementEvent.bind(this));
1425                                    break;
1426                            }
1427                        }
1428                    }
1429  }
1430  
1431  Form.Element.EventObserver = Class.create();
1432  Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1433  getValue: function() {
1434  return Form.Element.getValue(this.element);
1435  }
1436  });
1437  
1438  Form.EventObserver = Class.create();
1439  Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1440  getValue: function() {
1441  return Form.serialize(this.element);
1442  }
1443  });
1444  if (!window.Event) {
1445      var Event = new Object();
1446  }
1447  
1448  Object.extend(Event, {
1449  KEY_BACKSPACE: 8,
1450  KEY_TAB:       9,
1451  KEY_RETURN:   13,
1452  KEY_ESC:      27,
1453  KEY_LEFT:     37,
1454  KEY_UP:       38,
1455  KEY_RIGHT:    39,
1456  KEY_DOWN:     40,
1457  KEY_DELETE:   46,
1458  
1459  element: function(event) {
1460  return event.target || event.srcElement;
1461  },
1462  
1463  isLeftClick: function(event) {
1464  return (((event.which) && (event.which == 1)) ||
1465      ((event.button) && (event.button == 1)));
1466  },
1467  
1468  pointerX: function(event) {
1469  return event.pageX || (event.clientX +
1470      (document.documentElement.scrollLeft || document.body.scrollLeft));
1471            },
1472  
1473  pointerY: function(event) {
1474                return event.pageY || (event.clientY +
1475                        (document.documentElement.scrollTop || document.body.scrollTop));
1476            },
1477  
1478  stop: function(event) {
1479            if (event.preventDefault) {
1480                event.preventDefault();
1481                event.stopPropagation();
1482            } else {
1483                event.returnValue = false;
1484                event.cancelBubble = true;
1485            }
1486        },
1487  
1488  // find the first node with the given tagName, starting from the
1489  // node the event was triggered on; traverses the DOM upwards
1490  findElement: function(event, tagName) {
1491                   var element = Event.element(event);
1492                   while (element.parentNode && (!element.tagName ||
1493                               (element.tagName.toUpperCase() != tagName.toUpperCase())))
1494                       element = element.parentNode;
1495                   return element;
1496               },
1497  
1498  observers: false,
1499  
1500  _observeAndCache: function(element, name, observer, useCapture) {
1501                        if (!this.observers) this.observers = [];
1502                        if (element.addEventListener) {
1503                            this.observers.push([element, name, observer, useCapture]);
1504                            element.addEventListener(name, observer, useCapture);
1505                        } else if (element.attachEvent) {
1506                            this.observers.push([element, name, observer, useCapture]);
1507                            element.attachEvent('on' + name, observer);
1508                        }
1509                    },
1510  
1511  unloadCache: function() {
1512                   if (!Event.observers) return;
1513                   for (var i = 0; i < Event.observers.length; i++) {
1514                       Event.stopObserving.apply(this, Event.observers[i]);
1515                       Event.observers[i][0] = null;
1516                   }
1517                   Event.observers = false;
1518               },
1519  
1520  observe: function(element, name, observer, useCapture) {
1521               var element = $(element);
1522               useCapture = useCapture || false;
1523  
1524               if (name == 'keypress' &&
1525                       (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
1526                        || element.attachEvent))
1527                   name = 'keydown';
1528  
1529               this._observeAndCache(element, name, observer, useCapture);
1530           },
1531  
1532  stopObserving: function(element, name, observer, useCapture) {
1533                     var element = $(element);
1534                     useCapture = useCapture || false;
1535  
1536                     if (name == 'keypress' &&
1537                             (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
1538                              || element.detachEvent))
1539                         name = 'keydown';
1540  
1541                     if (element.removeEventListener) {
1542                         element.removeEventListener(name, observer, useCapture);
1543                     } else if (element.detachEvent) {
1544                         element.detachEvent('on' + name, observer);
1545                     }
1546                 }
1547  });
1548  
1549  /* prevent memory leaks in IE */
1550  Event.observe(window, 'unload', Event.unloadCache, false);
1551  var Position = {
1552      // set to true if needed, warning: firefox performance problems
1553      // NOT neeeded for page scrolling, only if draggable contained in
1554      // scrollable elements
1555  includeScrollOffsets: false,
1556  
1557                        // must be called before calling withinIncludingScrolloffset, every time the
1558                        // page is scrolled
1559  prepare: function() {
1560               this.deltaX =  window.pageXOffset
1561                   || document.documentElement.scrollLeft
1562                   || document.body.scrollLeft
1563                   || 0;
1564               this.deltaY =  window.pageYOffset
1565                   || document.documentElement.scrollTop
1566                   || document.body.scrollTop
1567                   || 0;
1568           },
1569  
1570  realOffset: function(element) {
1571                  var valueT = 0, valueL = 0;
1572                  do {
1573                      valueT += element.scrollTop  || 0;
1574                      valueL += element.scrollLeft || 0;
1575                      element = element.parentNode;
1576                  } while (element);
1577                  return [valueL, valueT];
1578              },
1579  
1580  cumulativeOffset: function(element) {
1581                        var valueT = 0, valueL = 0;
1582                        do {
1583                            valueT += element.offsetTop  || 0;
1584                            valueL += element.offsetLeft || 0;
1585                            element = element.offsetParent;
1586                        } while (element);
1587                        return [valueL, valueT];
1588                    },
1589  
1590  positionedOffset: function(element) {
1591                        var valueT = 0, valueL = 0;
1592                        do {
1593                            valueT += element.offsetTop  || 0;
1594                            valueL += element.offsetLeft || 0;
1595                            element = element.offsetParent;
1596                            if (element) {
1597                                p = Element.getStyle(element, 'position');
1598                                if (p == 'relative' || p == 'absolute') break;
1599                            }
1600                        } while (element);
1601                        return [valueL, valueT];
1602                    },
1603  
1604  offsetParent: function(element) {
1605                    if (element.offsetParent) return element.offsetParent;
1606                    if (element == document.body) return element;
1607  
1608                    while ((element = element.parentNode) && element != document.body)
1609                        if (Element.getStyle(element, 'position') != 'static')
1610                            return element;
1611  
1612                    return document.body;
1613                },
1614  
1615                // caches x/y coordinate pair to use with overlap
1616  within: function(element, x, y) {
1617              if (this.includeScrollOffsets)
1618                  return this.withinIncludingScrolloffsets(element, x, y);
1619              this.xcomp = x;
1620              this.ycomp = y;
1621              this.offset = this.cumulativeOffset(element);
1622  
1623              return (y >= this.offset[1] &&
1624                      y <  this.offset[1] + element.offsetHeight &&
1625                      x >= this.offset[0] &&
1626                      x <  this.offset[0] + element.offsetWidth);
1627          },
1628  
1629  withinIncludingScrolloffsets: function(element, x, y) {
1630                                    var offsetcache = this.realOffset(element);
1631  
1632                                    this.xcomp = x + offsetcache[0] - this.deltaX;
1633                                    this.ycomp = y + offsetcache[1] - this.deltaY;
1634                                    this.offset = this.cumulativeOffset(element);
1635  
1636                                    return (this.ycomp >= this.offset[1] &&
1637                                            this.ycomp <  this.offset[1] + element.offsetHeight &&
1638                                            this.xcomp >= this.offset[0] &&
1639                                            this.xcomp <  this.offset[0] + element.offsetWidth);
1640                                },
1641  
1642                                // within must be called directly before
1643  overlap: function(mode, element) {
1644               if (!mode) return 0;
1645               if (mode == 'vertical')
1646                   return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
1647                       element.offsetHeight;
1648               if (mode == 'horizontal')
1649                   return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
1650                       element.offsetWidth;
1651           },
1652  
1653  clone: function(source, target) {
1654             source = $(source);
1655             target = $(target);
1656             target.style.position = 'absolute';
1657             var offsets = this.cumulativeOffset(source);
1658             target.style.top    = offsets[1] + 'px';
1659             target.style.left   = offsets[0] + 'px';
1660             target.style.width  = source.offsetWidth + 'px';
1661             target.style.height = source.offsetHeight + 'px';
1662         },
1663  
1664  page: function(forElement) {
1665            var valueT = 0, valueL = 0;
1666  
1667            var element = forElement;
1668            do {
1669                valueT += element.offsetTop  || 0;
1670                valueL += element.offsetLeft || 0;
1671  
1672                // Safari fix
1673                if (element.offsetParent==document.body)
1674                    if (Element.getStyle(element,'position')=='absolute') break;
1675  
1676            } while (element = element.offsetParent);
1677  
1678            element = forElement;
1679            do {
1680                valueT -= element.scrollTop  || 0;
1681                valueL -= element.scrollLeft || 0;
1682            } while (element = element.parentNode);
1683  
1684            return [valueL, valueT];
1685        },
1686  
1687  clone: function(source, target) {
1688             var options = Object.extend({
1689  setLeft:    true,
1690  setTop:     true,
1691  setWidth:   true,
1692  setHeight:  true,
1693  offsetTop:  0,
1694  offsetLeft: 0
1695  }, arguments[2] || {})
1696  
1697  // find page position of source
1698  source = $(source);
1699  var p = Position.page(source);
1700  
1701  // find coordinate system to use
1702  target = $(target);
1703  var delta = [0, 0];
1704  var parent = null;
1705  // delta [0,0] will do fine with position: fixed elements,
1706  // position:absolute needs offsetParent deltas
1707  if (Element.getStyle(target,'position') == 'absolute') {
1708      parent = Position.offsetParent(target);
1709      delta = Position.page(parent);
1710  }
1711  
1712  // correct by body offsets (fixes Safari)
1713  if (parent == document.body) {
1714      delta[0] -= document.body.offsetLeft;
1715      delta[1] -= document.body.offsetTop;
1716  }
1717  
1718  // set position
1719  if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
1720  if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
1721  if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
1722  if(options.setHeight) target.style.height = source.offsetHeight + 'px';
1723  },
1724  
1725  absolutize: function(element) {
1726                  element = $(element);
1727                  if (element.style.position == 'absolute') return;
1728                  Position.prepare();
1729  
1730                  var offsets = Position.positionedOffset(element);
1731                  var top     = offsets[1];
1732                  var left    = offsets[0];
1733                  var width   = element.clientWidth;
1734                  var height  = element.clientHeight;
1735  
1736                  element._originalLeft   = left - parseFloat(element.style.left  || 0);
1737                  element._originalTop    = top  - parseFloat(element.style.top || 0);
1738                  element._originalWidth  = element.style.width;
1739                  element._originalHeight = element.style.height;
1740  
1741                  element.style.position = 'absolute';
1742                  element.style.top    = top + 'px';;
1743                  element.style.left   = left + 'px';;
1744                  element.style.width  = width + 'px';;
1745                  element.style.height = height + 'px';;
1746              },
1747  
1748  relativize: function(element) {
1749                  element = $(element);
1750                  if (element.style.position == 'relative') return;
1751                  Position.prepare();
1752  
1753                  element.style.position = 'relative';
1754                  var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
1755                  var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
1756  
1757                  element.style.top    = top + 'px';
1758                  element.style.left   = left + 'px';
1759                  element.style.height = element._originalHeight;
1760                  element.style.width  = element._originalWidth;
1761              }
1762  }
1763  
1764  // Safari returns margins on body which is incorrect if the child is absolutely
1765  // positioned.  For performance reasons, redefine Position.cumulativeOffset for
1766  // KHTML/WebKit only.
1767  if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
1768      Position.cumulativeOffset = function(element) {
1769          var valueT = 0, valueL = 0;
1770          do {
1771              valueT += element.offsetTop  || 0;
1772              valueL += element.offsetLeft || 0;
1773              if (element.offsetParent == document.body)
1774                  if (Element.getStyle(element, 'position') == 'absolute') break;
1775  
1776              element = element.offsetParent;
1777          } while (element);
1778  
1779          return [valueL, valueT];
1780      }
1781  }


Généré le : Sun Feb 25 10:22:19 2007 par Balluche grâce à PHPXref 0.7