Make WordPress Core

Ticket #3017: prototype.diff

File prototype.diff, 49.1 KB (added by masquerade, 18 years ago)
  • wp-includes/js/prototype.js

     
     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
     9var Prototype = {
     10  Version: '1.4.0',
     11  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
     12
     13  emptyFunction: function() {},
     14  K: function(x) {return x}
     15}
     16
     17var Class = {
     18  create: function() {
     19    return function() {
     20      this.initialize.apply(this, arguments);
     21    }
     22  }
     23}
     24
     25var Abstract = new Object();
     26
     27Object.extend = function(destination, source) {
     28  for (property in source) {
     29    destination[property] = source[property];
     30  }
     31  return destination;
     32}
     33
     34Object.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
     45Function.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
     52Function.prototype.bindAsEventListener = function(object) {
     53  var __method = this;
     54  return function(event) {
     55    return __method.call(object, event || window.event);
     56  }
     57}
     58
     59Object.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
     76var 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
     94var PeriodicalExecuter = Class.create();
     95PeriodicalExecuter.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
     122function $() {
     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}
     138Object.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
     206String.prototype.parseQuery = String.prototype.toQueryParams;
     207
     208var $break    = new Object();
     209var $continue = new Object();
     210
     211var 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
     384Object.extend(Enumerable, {
     385  map:     Enumerable.collect,
     386  find:    Enumerable.detect,
     387  select:  Enumerable.findAll,
     388  member:  Enumerable.include,
     389  entries: Enumerable.toArray
     390});
     391var $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
     403Object.extend(Array.prototype, Enumerable);
     404
     405Array.prototype._reverse = Array.prototype.reverse;
     406
     407Object.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});
     468var 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
     509function $H(object) {
     510  var hash = Object.extend({}, object || {});
     511  Object.extend(hash, Enumerable);
     512  Object.extend(hash, Hash);
     513  return hash;
     514}
     515ObjectRange = Class.create();
     516Object.extend(ObjectRange.prototype, Enumerable);
     517Object.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
     541var $R = function(start, end, exclusive) {
     542  return new ObjectRange(start, end, exclusive);
     543}
     544
     545var 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
     557Ajax.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
     584Object.extend(Ajax.Responders, Enumerable);
     585
     586Ajax.Responders.register({
     587  onCreate: function() {
     588    Ajax.activeRequestCount++;
     589  },
     590
     591  onComplete: function() {
     592    Ajax.activeRequestCount--;
     593  }
     594});
     595
     596Ajax.Base = function() {};
     597Ajax.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
     618Ajax.Request = Class.create();
     619Ajax.Request.Events =
     620  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
     621
     622Ajax.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
     743Ajax.Updater = Class.create();
     744
     745Object.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
     788Ajax.PeriodicalUpdater = Class.create();
     789Ajax.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});
     830document.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
     841if (!window.Element) {
     842  var Element = new Object();
     843}
     844
     845Object.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
     1014var Toggle = new Object();
     1015Toggle.display = Element.toggle;
     1016
     1017/*--------------------------------------------------------------------------*/
     1018
     1019Abstract.Insertion = function(adjacency) {
     1020  this.adjacency = adjacency;
     1021}
     1022
     1023Abstract.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
     1054var Insertion = new Object();
     1055
     1056Insertion.Before = Class.create();
     1057Insertion.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
     1069Insertion.Top = Class.create();
     1070Insertion.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
     1083Insertion.Bottom = Class.create();
     1084Insertion.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
     1097Insertion.After = Class.create();
     1098Insertion.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
     1113Element.ClassNames = Class.create();
     1114Element.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
     1146Object.extend(Element.ClassNames.prototype, Enumerable);
     1147var 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
     1177var 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
     1255Form.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
     1284Form.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
     1341var $F = Form.Element.getValue;
     1342
     1343/*--------------------------------------------------------------------------*/
     1344
     1345Abstract.TimedObserver = function() {}
     1346Abstract.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
     1369Form.Element.Observer = Class.create();
     1370Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
     1371  getValue: function() {
     1372    return Form.Element.getValue(this.element);
     1373  }
     1374});
     1375
     1376Form.Observer = Class.create();
     1377Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
     1378  getValue: function() {
     1379    return Form.serialize(this.element);
     1380  }
     1381});
     1382
     1383/*--------------------------------------------------------------------------*/
     1384
     1385Abstract.EventObserver = function() {}
     1386Abstract.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
     1431Form.Element.EventObserver = Class.create();
     1432Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
     1433  getValue: function() {
     1434    return Form.Element.getValue(this.element);
     1435  }
     1436});
     1437
     1438Form.EventObserver = Class.create();
     1439Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
     1440  getValue: function() {
     1441    return Form.serialize(this.element);
     1442  }
     1443});
     1444if (!window.Event) {
     1445  var Event = new Object();
     1446}
     1447
     1448Object.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 */
     1550Event.observe(window, 'unload', Event.unloadCache, false);
     1551var 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.
     1767if (/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}
     1782 No newline at end of file
  • wp-includes/script-loader.php

     
    1717                $this->add( 'colorpicker', '/wp-includes/js/colorpicker.js', false, '3517' );
    1818                $this->add( 'tiny_mce', '/wp-includes/js/tinymce/tiny_mce_gzip.php', false, '04162006' );
    1919                $this->add( 'wp_tiny_mce', '/wp-includes/js/tinymce/tiny_mce_config.php', array('tiny_mce'), '04162006' );
     20                $this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.4.0');
    2021                if ( is_admin() ) {
    2122                        $this->add( 'dbx-admin-key', '/wp-admin/dbx-admin-key-js.php', array('dbx'), '3651' );
    2223                        $this->add( 'listman', '/wp-admin/list-manipulation-js.php', array('sack', 'fat'), '4042' ); // Make changeset # the correct one