[xwiki-commits] r997 - in xwiki/trunk/src/main/web/skins/default: . ajax rico scriptaculous

jeremi joslin jeremi23 at gmail.com
Tue Mar 28 12:42:37 CEST 2006


Hi,
Don't you think we can put scriptaculous and prototype.js as a
resource, and not as a skin because some applications can depend on
it.

This library can be useful when you create an application.


Jérémi

On 3/28/06, Ludovic Dubost <ludovic at users.forge.objectweb.org> wrote:
> Author: ludovic
> Date: 2006-03-28 12:10:39 +0200 (Tue, 28 Mar 2006)
> New Revision: 997
>
> Added:
>    xwiki/trunk/src/main/web/skins/default/Thumbs.db
>    xwiki/trunk/src/main/web/skins/default/ajax/
>    xwiki/trunk/src/main/web/skins/default/ajax/Drag.js
>    xwiki/trunk/src/main/web/skins/default/ajax/ieemu.js
>    xwiki/trunk/src/main/web/skins/default/ajax/toolTip.js
>    xwiki/trunk/src/main/web/skins/default/prototype.js
>    xwiki/trunk/src/main/web/skins/default/rico/
>    xwiki/trunk/src/main/web/skins/default/rico/prototype.js
>    xwiki/trunk/src/main/web/skins/default/rico/rico.js
>    xwiki/trunk/src/main/web/skins/default/scriptaculous/
>    xwiki/trunk/src/main/web/skins/default/scriptaculous/controls.js
>    xwiki/trunk/src/main/web/skins/default/scriptaculous/dragdrop.js
>    xwiki/trunk/src/main/web/skins/default/scriptaculous/effects.js
>    xwiki/trunk/src/main/web/skins/default/scriptaculous/prototype.js
>    xwiki/trunk/src/main/web/skins/default/scriptaculous/util.js
>    xwiki/trunk/src/main/web/skins/default/xwiki.js
> Log:
> Added prototype.js to skin as it should be there
>
> Added: xwiki/trunk/src/main/web/skins/default/Thumbs.db
> ===================================================================
> (Binary files differ)
>
>
> Property changes on: xwiki/trunk/src/main/web/skins/default/Thumbs.db
> ___________________________________________________________________
> Name: svn:mime-type
>    + application/octet-stream
>
> Added: xwiki/trunk/src/main/web/skins/default/ajax/Drag.js
> ===================================================================
> --- xwiki/trunk/src/main/web/skins/default/ajax/Drag.js 2006-03-28 10:10:11 UTC (rev 996)
> +++ xwiki/trunk/src/main/web/skins/default/ajax/Drag.js 2006-03-28 10:10:39 UTC (rev 997)
> @@ -0,0 +1,53 @@
> +var Drag={
> +        "obj":null,
> +       "init":function(a, aRoot){
> +                       a.onmousedown=Drag.start;
> +                       a.root = aRoot;
> +                       if(isNaN(parseInt(a.root.style.left)))a.root.style.left="0px";
> +                       if(isNaN(parseInt(a.root.style.top)))a.root.style.top="0px";
> +                       a.root.onDragStart=new Function();
> +                       a.root.onDragEnd=new Function();
> +                       a.root.onDrag=new Function();
> +               },
> +       "start":function(a){
> +                       var b=Drag.obj=this;
> +                       a=Drag.fixE(a);
> +                       var c=parseInt(b.root.style.top);
> +                       var d=parseInt(b.root.style.left);
> +                       b.root.onDragStart(d,c,a.clientX,a.clientY);
> +                       b.lastMouseX=a.clientX;
> +                       b.lastMouseY=a.clientY;
> +                       document.onmousemove=Drag.drag;
> +                       document.onmouseup=Drag.end;
> +                       return false;
> +               },
> +       "drag":function(a){
> +                       a=Drag.fixE(a);
> +                       var b=Drag.obj;
> +                       var c=a.clientY;
> +                       var d=a.clientX;
> +                       var e=parseInt(b.root.style.top);
> +                       var f=parseInt(b.root.style.left);
> +                       var h,g;
> +                       h=f+d-b.lastMouseX;
> +                       g=e+c-b.lastMouseY;
> +                       b.root.style.left=h+"px";
> +                       b.root.style.top=g+"px";
> +                       b.lastMouseX=d;
> +                       b.lastMouseY=c;
> +                       b.root.onDrag(h,g,a.clientX,a.clientY);
> +                       return false;
> +               },
> +       "end":function(){
> +                       document.onmousemove=null;
> +                       document.onmouseup=null;
> +                       Drag.obj.root.onDragEnd(parseInt(Drag.obj.root.style.left),parseInt(Drag.obj.root.style.top));
> +                       Drag.obj=null;
> +               },
> +       "fixE":function(a){
> +                       if(typeof a=="undefined")a=window.event;
> +                       if(typeof a.layerX=="undefined")a.layerX=a.offsetX;
> +                       if(typeof a.layerY=="undefined")a.layerY=a.offsetY;
> +                       return a;
> +               }
> +};
> \ No newline at end of file
>
> Added: xwiki/trunk/src/main/web/skins/default/ajax/ieemu.js
> ===================================================================
> --- xwiki/trunk/src/main/web/skins/default/ajax/ieemu.js        2006-03-28 10:10:11 UTC (rev 996)
> +++ xwiki/trunk/src/main/web/skins/default/ajax/ieemu.js        2006-03-28 10:10:39 UTC (rev 997)
> @@ -0,0 +1,304 @@
> +/*----------------------------------------------------------------------------\
> +|                                   IE Emu                                    |
> +|-----------------------------------------------------------------------------|
> +|                         Created by Erik Arvidsson                           |
> +|                  (http://webfx.eae.net/contact.html#erik)                   |
> +|                      For WebFX (http://webfx.eae.net/)                      |
> +|-----------------------------------------------------------------------------|
> +| A emulation of Internet Explorer DHTML Object Model for Mozilla  |
> +|-----------------------------------------------------------------------------|
> +|                  Copyright (c) 1999 - 2004 Erik Arvidsson                   |
> +|-----------------------------------------------------------------------------|
> +*/
> +
> +if (Browser.isMozilla) { // set up ie environment for Moz
> +
> +       extendEventObject();
> +       emulateAttachEvent();
> +       emulateEventHandlers(["click", "dblclick", "mouseover", "mouseout",
> +                                                       "mousedown", "mouseup", "mousemove",
> +                                                       "keydown", "keypress", "keyup"]);
> +       emulateCurrentStyle();
> +       emulateHTMLModel();
> +       /*emulateDocumentAll();
> +       emulateElement()
> +       */
> +
> +       // It is better to use a constant for event.button
> +       Event.LEFT = 0;
> +       Event.MIDDLE = 1;
> +       Event.RIGHT = 2;
> +}
> +else {
> +       Event = {};
> +       // IE is returning wrong button number
> +       Event.LEFT = 1;
> +       Event.MIDDLE = 4;
> +       Event.RIGHT = 2;
> +}
> +
> +
> +
> +/*
> + * Extends the event object with srcElement, cancelBubble, returnValue,
> + * fromElement and toElement
> + */
> +function extendEventObject() {
> +       Event.prototype.__defineSetter__("returnValue", function (b) {
> +               if (!b) this.preventDefault();
> +               return b;
> +       });
> +
> +       Event.prototype.__defineSetter__("cancelBubble", function (b) {
> +               if (b) this.stopPropagation();
> +               return b;
> +       });
> +
> +       Event.prototype.__defineGetter__("srcElement", function () {
> +               var node = this.target;
> +               while (node.nodeType != 1) node = node.parentNode;
> +               return node;
> +       });
> +
> +       Event.prototype.__defineGetter__("fromElement", function () {
> +               var node;
> +               if (this.type == "mouseover")
> +                       node = this.relatedTarget;
> +               else if (this.type == "mouseout")
> +                       node = this.target;
> +               if (!node) return;
> +               while (node.nodeType != 1) node = node.parentNode;
> +               return node;
> +       });
> +
> +       Event.prototype.__defineGetter__("toElement", function () {
> +               var node;
> +               if (this.type == "mouseout")
> +                       node = this.relatedTarget;
> +               else if (this.type == "mouseover")
> +                       node = this.target;
> +               if (!node) return;
> +               while (node.nodeType != 1) node = node.parentNode;
> +               return node;
> +       });
> +
> +       Event.prototype.__defineGetter__("offsetX", function () {
> +               return this.layerX;
> +       });
> +       Event.prototype.__defineGetter__("offsetY", function () {
> +               return this.layerY;
> +       });
> +}
> +
> +/*
> + * Emulates element.attachEvent as well as detachEvent
> + */
> +function emulateAttachEvent() {
> +       HTMLDocument.prototype.attachEvent =
> +       HTMLElement.prototype.attachEvent = function (sType, fHandler) {
> +               var shortTypeName = sType.replace(/on/, "");
> +               fHandler._ieEmuEventHandler = function (e) {
> +                       window.event = e;
> +                       return fHandler();
> +               };
> +               this.addEventListener(shortTypeName, fHandler._ieEmuEventHandler, false);
> +       };
> +
> +       HTMLDocument.prototype.detachEvent =
> +       HTMLElement.prototype.detachEvent = function (sType, fHandler) {
> +               var shortTypeName = sType.replace(/on/, "");
> +               if (typeof fHandler._ieEmuEventHandler == "function")
> +                       this.removeEventListener(shortTypeName, fHandler._ieEmuEventHandler, false);
> +               else
> +                       this.removeEventListener(shortTypeName, fHandler, true);
> +       };
> +}
> +
> +/*
> + * This function binds the event object passed along in an
> + * event to window.event
> + */
> +function emulateEventHandlers(eventNames) {
> +       for (var i = 0; i < eventNames.length; i++) {
> +               document.addEventListener(eventNames[i], function (e) {
> +                       window.event = e;
> +               }, true);       // using capture
> +       }
> +}
> +
> +/*
> + * Simple emulation of document.all
> + * this one is far from complete. Be cautious
> + */
> +
> +function emulateAllModel() {
> +       var allGetter = function () {
> +               var a = this.getElementsByTagName("*");
> +               var node = this;
> +               a.tags = function (sTagName) {
> +                       return node.getElementsByTagName(sTagName);
> +               };
> +               return a;
> +       };
> +       HTMLDocument.prototype.__defineGetter__("all", allGetter);
> +       HTMLElement.prototype.__defineGetter__("all", allGetter);
> +}
> +
> +function extendElementModel() {
> +       HTMLElement.prototype.__defineGetter__("parentElement", function () {
> +               if (this.parentNode == this.ownerDocument) return null;
> +               return this.parentNode;
> +       });
> +
> +       HTMLElement.prototype.__defineGetter__("children", function () {
> +               var tmp = [];
> +               var j = 0;
> +               var n;
> +               for (var i = 0; i < this.childNodes.length; i++) {
> +                       n = this.childNodes[i];
> +                       if (n.nodeType == 1) {
> +                               tmp[j++] = n;
> +                               if (n.name) {   // named children
> +                                       if (!tmp[n.name])
> +                                               tmp[n.name] = [];
> +                                       tmp[n.name][tmp[n.name].length] = n;
> +                               }
> +                               if (n.id)               // child with id
> +                                       tmp[n.id] = n
> +                       }
> +               }
> +               return tmp;
> +       });
> +
> +       HTMLElement.prototype.contains = function (oEl) {
> +               if (oEl == this) return true;
> +               if (oEl == null) return false;
> +               return this.contains(oEl.parentNode);
> +       };
> +}
> +
> +function emulateCurrentStyle() {
> +       HTMLElement.prototype.__defineGetter__("currentStyle", function () {
> +               return this.ownerDocument.defaultView.getComputedStyle(this, null);
> +               /*
> +               var cs = {};
> +               var el = this;
> +               for (var i = 0; i < properties.length; i++) {
> +                       cs.__defineGetter__(properties[i], encapsulateObjects(el, properties[i]));
> +               }
> +               return cs;
> +               */
> +       });
> +}
> +
> +function emulateHTMLModel() {
> +
> +       // This function is used to generate a html string for the text properties/methods
> +       // It replaces '\n' with "<BR"> as well as fixes consecutive white spaces
> +       // It also repalaces some special characters
> +       function convertTextToHTML(s) {
> +               s = s.replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "<BR>");
> +               while (/\s\s/.test(s))
> +                       s = s.replace(/\s\s/, "&nbsp; ");
> +               return s.replace(/\s/g, " ");
> +       }
> +
> +       HTMLElement.prototype.insertAdjacentHTML = function (sWhere, sHTML) {
> +               var df; // : DocumentFragment
> +               var r = this.ownerDocument.createRange();
> +
> +               switch (String(sWhere).toLowerCase()) {
> +                       case "beforebegin":
> +                               r.setStartBefore(this);
> +                               df = r.createContextualFragment(sHTML);
> +                               this.parentNode.insertBefore(df, this);
> +                               break;
> +
> +                       case "afterbegin":
> +                               r.selectNodeContents(this);
> +                               r.collapse(true);
> +                               df = r.createContextualFragment(sHTML);
> +                               this.insertBefore(df, this.firstChild);
> +                               break;
> +
> +                       case "beforeend":
> +                               r.selectNodeContents(this);
> +                               r.collapse(false);
> +                               df = r.createContextualFragment(sHTML);
> +                               this.appendChild(df);
> +                               break;
> +
> +                       case "afterend":
> +                               r.setStartAfter(this);
> +                               df = r.createContextualFragment(sHTML);
> +                               this.parentNode.insertBefore(df, this.nextSibling);
> +                               break;
> +               }
> +       };
> +
> +       HTMLElement.prototype.__defineSetter__("outerHTML", function (sHTML) {
> +          var r = this.ownerDocument.createRange();
> +          r.setStartBefore(this);
> +          var df = r.createContextualFragment(sHTML);
> +          this.parentNode.replaceChild(df, this);
> +
> +          return sHTML;
> +       });
> +
> +       HTMLElement.prototype.__defineGetter__("canHaveChildren", function () {
> +               switch (this.tagName) {
> +                       case "AREA":
> +                       case "BASE":
> +                       case "BASEFONT":
> +                       case "COL":
> +                       case "FRAME":
> +                       case "HR":
> +                       case "IMG":
> +                       case "BR":
> +                       case "INPUT":
> +                       case "ISINDEX":
> +                       case "LINK":
> +                       case "META":
> +                       case "PARAM":
> +                               return false;
> +               }
> +               return true;
> +       });
> +
> +       HTMLElement.prototype.__defineGetter__("outerHTML", function () {
> +               var attr, attrs = this.attributes;
> +               var str = "<" + this.tagName;
> +               for (var i = 0; i < attrs.length; i++) {
> +                       attr = attrs[i];
> +                       if (attr.specified)
> +                               str += " " + attr.name + '="' + attr.value + '"';
> +               }
> +               if (!this.canHaveChildren)
> +                       return str + ">";
> +
> +               return str + ">" + this.innerHTML + "</" + this.tagName + ">";
> +       });
> +
> +
> +       HTMLElement.prototype.__defineSetter__("innerText", function (sText) {
> +               this.innerHTML = convertTextToHTML(sText);
> +               return sText;
> +       });
> +
> +       var tmpGet;
> +       HTMLElement.prototype.__defineGetter__("innerText", tmpGet = function () {
> +               var r = this.ownerDocument.createRange();
> +               r.selectNodeContents(this);
> +               return r.toString();
> +       });
> +
> +       HTMLElement.prototype.__defineSetter__("outerText", function (sText) {
> +               this.outerHTML = convertTextToHTML(sText);
> +               return sText;
> +       });
> +       HTMLElement.prototype.__defineGetter__("outerText", tmpGet);
> +
> +       HTMLElement.prototype.insertAdjacentText = function (sWhere, sText) {
> +               this.insertAdjacentHTML(sWhere, convertTextToHTML(sText));
> +       };
> +}
>
> Added: xwiki/trunk/src/main/web/skins/default/ajax/toolTip.js
> ===================================================================
> --- xwiki/trunk/src/main/web/skins/default/ajax/toolTip.js      2006-03-28 10:10:11 UTC (rev 996)
> +++ xwiki/trunk/src/main/web/skins/default/ajax/toolTip.js      2006-03-28 10:10:39 UTC (rev 997)
> @@ -0,0 +1,70 @@
> +/***********************************************
> +* Cool DHTML tooltip script- � Dynamic Drive DHTML code library (www.dynamicdrive.com)
> +* This notice MUST stay intact for legal use
> +* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
> +***********************************************/
> +
> +var offsetxpoint=-60 //Customize x offset of tooltip
> +var offsetypoint=20 //Customize y offset of tooltip
> +var ie=document.all
> +var ns6=document.getElementById && !document.all
> +var enabletip=false
> +if (ie||ns6)
> +var tipobj=document.all? document.all["dhtmltooltip"] : document.getElementById? document.getElementById("dhtmltooltip") : ""
> +
> +function ietruebody(){
> +       return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
> +}
> +
> +function showtip(node, txt, w, align){
> +       document.onmousemove=positiontip;
> +       node.onmouseout = hideddrivetip;
> +       //node.onclick = hideddrivetip;
> +       if (ns6||ie){
> +               tipobj.style.textAlign=align;
> +               tipobj.innerHTML=txt;
> +               if (tipobj.offsetWidth>w) tipobj.style.width=w+"px";
> +               enabletip=true;
> +               return false
> +       }
> +}
> +
> +function positiontip(e){
> +       if (enabletip){
> +               var curX=(ns6)?e.pageX : event.x+ietruebody().scrollLeft;
> +               var curY=(ns6)?e.pageY : event.y+ietruebody().scrollTop;
> +               //Find out how close the mouse is to the corner of the window
> +               var rightedge=ie&&!window.opera? ietruebody().clientWidth-event.clientX-offsetxpoint : window.innerWidth-e.clientX-offsetxpoint-20
> +               var bottomedge=ie&&!window.opera? ietruebody().clientHeight-event.clientY-offsetypoint : window.innerHeight-e.clientY-offsetypoint-20
> +
> +               var leftedge=(offsetxpoint<0)? offsetxpoint*(-1) : -1000
> +
> +               //if the horizontal distance isn't enough to accomodate the width of the context menu
> +               if (rightedge<tipobj.offsetWidth)
> +               //move the horizontal position of the menu to the left by it's width
> +               tipobj.style.left=ie? ietruebody().scrollLeft+event.clientX-tipobj.offsetWidth+"px" : window.pageXOffset+e.clientX-tipobj.offsetWidth+"px"
> +               else if (curX<leftedge)
> +               tipobj.style.left="5px"
> +               else
> +               //position the horizontal position of the menu where the mouse is positioned
> +               tipobj.style.left=curX+offsetxpoint+"px"
> +
> +               //same concept with the vertical position
> +               if (bottomedge<tipobj.offsetHeight)
> +               tipobj.style.top=ie? ietruebody().scrollTop+event.clientY-tipobj.offsetHeight-offsetypoint+"px" : window.pageYOffset+e.clientY-tipobj.offsetHeight-offsetypoint+"px"
> +               else
> +               tipobj.style.top=curY+offsetypoint+"px"
> +               tipobj.style.visibility="visible"
> +       }
> +}
> +
> +function hideddrivetip(){
> +       document.onmousemove=null;
> +       if (ns6||ie){
> +               enabletip=false
> +               tipobj.style.visibility="hidden"
> +               tipobj.style.left="-1000px"
> +               tipobj.style.backgroundColor=''
> +               tipobj.style.width=''
> +       }
> +}
>
> Added: xwiki/trunk/src/main/web/skins/default/prototype.js
> ===================================================================
> --- xwiki/trunk/src/main/web/skins/default/prototype.js 2006-03-28 10:10:11 UTC (rev 996)
> +++ xwiki/trunk/src/main/web/skins/default/prototype.js 2006-03-28 10:10:39 UTC (rev 997)
> @@ -0,0 +1,1039 @@
> +/*  Prototype JavaScript framework, version 1.3.1
> + *  (c) 2005 Sam Stephenson <sam at conio.net>
> + *
> + *  THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
> + *  against the source tree, available from the Prototype darcs repository.
> + *
> + *  Prototype is freely distributable under the terms of an MIT-style license.
> + *
> + *  For details, see the Prototype web site: http://prototype.conio.net/
> + *
> +/*--------------------------------------------------------------------------*/
> +
> +
> +var Prototype = {
> +  Version: '1.3.1',
> +  emptyFunction: function() {}
> +}
> +
> +var Class = {
> +  create: function() {
> +    return function() {
> +      this.initialize.apply(this, arguments);
> +    }
> +  }
> +}
> +
> +var Abstract = new Object();
> +
> +Object.extend = function(destination, source) {
> +  for (property in source) {
> +    destination[property] = source[property];
> +  }
> +  return destination;
> +}
> +
> +Object.prototype.extend = function(object) {
> +  return Object.extend.apply(this, [this, object]);
> +}
> +
> +Function.prototype.bind = function(object) {
> +  var __method = this;
> +  return function() {
> +    __method.apply(object, arguments);
> +  }
> +}
> +
> +Function.prototype.bindAsEventListener = function(object) {
> +  var __method = this;
> +  return function(event) {
> +    __method.call(object, event || window.event);
> +  }
> +}
> +
> +Number.prototype.toColorPart = function() {
> +  var digits = this.toString(16);
> +  if (this < 16) return '0' + digits;
> +  return digits;
> +}
> +
> +var Try = {
> +  these: function() {
> +    var returnValue;
> +
> +    for (var i = 0; i < arguments.length; i++) {
> +      var lambda = arguments[i];
> +      try {
> +        returnValue = lambda();
> +        break;
> +      } catch (e) {}
> +    }
> +
> +    return returnValue;
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +var PeriodicalExecuter = Class.create();
> +PeriodicalExecuter.prototype = {
> +  initialize: function(callback, frequency) {
> +    this.callback = callback;
> +    this.frequency = frequency;
> +    this.currentlyExecuting = false;
> +
> +    this.registerCallback();
> +  },
> +
> +  registerCallback: function() {
> +    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
> +  },
> +
> +  onTimerEvent: function() {
> +    if (!this.currentlyExecuting) {
> +      try {
> +        this.currentlyExecuting = true;
> +        this.callback();
> +      } finally {
> +        this.currentlyExecuting = false;
> +      }
> +    }
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +function $() {
> +  var elements = new Array();
> +
> +  for (var i = 0; i < arguments.length; i++) {
> +    var element = arguments[i];
> +    if (typeof element == 'string')
> +      element = document.getElementById(element);
> +
> +    if (arguments.length == 1)
> +      return element;
> +
> +    elements.push(element);
> +  }
> +
> +  return elements;
> +}
> +
> +if (!Array.prototype.push) {
> +  Array.prototype.push = function() {
> +               var startLength = this.length;
> +               for (var i = 0; i < arguments.length; i++)
> +      this[startLength + i] = arguments[i];
> +         return this.length;
> +  }
> +}
> +
> +if (!Function.prototype.apply) {
> +  // Based on code from http://www.youngpup.net/
> +  Function.prototype.apply = function(object, parameters) {
> +    var parameterStrings = new Array();
> +    if (!object)     object = window;
> +    if (!parameters) parameters = new Array();
> +
> +    for (var i = 0; i < parameters.length; i++)
> +      parameterStrings[i] = 'parameters[' + i + ']';
> +
> +    object.__apply__ = this;
> +    var result = eval('object.__apply__(' +
> +      parameterStrings.join(', ') + ')');
> +    object.__apply__ = null;
> +
> +    return result;
> +  }
> +}
> +
> +String.prototype.extend({
> +  stripTags: function() {
> +    return this.replace(/<\/?[^>]+>/gi, '');
> +  },
> +
> +  escapeHTML: function() {
> +    var div = document.createElement('div');
> +    var text = document.createTextNode(this);
> +    div.appendChild(text);
> +    return div.innerHTML;
> +  },
> +
> +  unescapeHTML: function() {
> +    var div = document.createElement('div');
> +    div.innerHTML = this.stripTags();
> +    return div.childNodes[0].nodeValue;
> +  }
> +});
> +
> +var Ajax = {
> +  getTransport: function() {
> +    return Try.these(
> +      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
> +      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
> +      function() {return new XMLHttpRequest()}
> +    ) || false;
> +  }
> +}
> +
> +Ajax.Base = function() {};
> +Ajax.Base.prototype = {
> +  setOptions: function(options) {
> +    this.options = {
> +      method:       'post',
> +      asynchronous: true,
> +      parameters:   ''
> +    }.extend(options || {});
> +  },
> +
> +  responseIsSuccess: function() {
> +    return this.transport.status == undefined
> +        || this.transport.status == 0
> +        || (this.transport.status >= 200 && this.transport.status < 300);
> +  },
> +
> +  responseIsFailure: function() {
> +    return !this.responseIsSuccess();
> +  }
> +}
> +
> +Ajax.Request = Class.create();
> +Ajax.Request.Events =
> +  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
> +
> +Ajax.Request.prototype = (new Ajax.Base()).extend({
> +  initialize: function(url, options) {
> +    this.transport = Ajax.getTransport();
> +    this.setOptions(options);
> +    this.request(url);
> +  },
> +
> +  request: function(url) {
> +    var parameters = this.options.parameters || '';
> +    if (parameters.length > 0) parameters += '&_=';
> +
> +    try {
> +      if (this.options.method == 'get')
> +        url += '?' + parameters;
> +
> +      this.transport.open(this.options.method, url,
> +        this.options.asynchronous);
> +
> +      if (this.options.asynchronous) {
> +        this.transport.onreadystatechange = this.onStateChange.bind(this);
> +        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
> +      }
> +
> +      this.setRequestHeaders();
> +
> +      var body = this.options.postBody ? this.options.postBody : parameters;
> +      this.transport.send(this.options.method == 'post' ? body : null);
> +
> +    } catch (e) {
> +    }
> +  },
> +
> +  setRequestHeaders: function() {
> +    var requestHeaders =
> +      ['X-Requested-With', 'XMLHttpRequest',
> +       'X-Prototype-Version', Prototype.Version];
> +
> +    if (this.options.method == 'post') {
> +      requestHeaders.push('Content-type',
> +        'application/x-www-form-urlencoded');
> +
> +      /* Force "Connection: close" for Mozilla browsers to work around
> +       * a bug where XMLHttpReqeuest sends an incorrect Content-length
> +       * header. See Mozilla Bugzilla #246651.
> +       */
> +      if (this.transport.overrideMimeType)
> +        requestHeaders.push('Connection', 'close');
> +    }
> +
> +    if (this.options.requestHeaders)
> +      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
> +
> +    for (var i = 0; i < requestHeaders.length; i += 2)
> +      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
> +  },
> +
> +  onStateChange: function() {
> +    var readyState = this.transport.readyState;
> +    if (readyState != 1)
> +      this.respondToReadyState(this.transport.readyState);
> +  },
> +
> +  respondToReadyState: function(readyState) {
> +    var event = Ajax.Request.Events[readyState];
> +
> +    if (event == 'Complete')
> +      (this.options['on' + this.transport.status]
> +       || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
> +       || Prototype.emptyFunction)(this.transport);
> +
> +    (this.options['on' + event] || Prototype.emptyFunction)(this.transport);
> +
> +    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
> +    if (event == 'Complete')
> +      this.transport.onreadystatechange = Prototype.emptyFunction;
> +  }
> +});
> +
> +Ajax.Updater = Class.create();
> +Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
> +
> +Ajax.Updater.prototype.extend(Ajax.Request.prototype).extend({
> +  initialize: function(container, url, options) {
> +    this.containers = {
> +      success: container.success ? $(container.success) : $(container),
> +      failure: container.failure ? $(container.failure) :
> +        (container.success ? null : $(container))
> +    }
> +
> +    this.transport = Ajax.getTransport();
> +    this.setOptions(options);
> +
> +    var onComplete = this.options.onComplete || Prototype.emptyFunction;
> +    this.options.onComplete = (function() {
> +      this.updateContent();
> +      onComplete(this.transport);
> +    }).bind(this);
> +
> +    this.request(url);
> +  },
> +
> +  updateContent: function() {
> +    var receiver = this.responseIsSuccess() ?
> +      this.containers.success : this.containers.failure;
> +
> +    var match    = new RegExp(Ajax.Updater.ScriptFragment, 'img');
> +    var response = this.transport.responseText.replace(match, '');
> +    var scripts  = this.transport.responseText.match(match);
> +
> +    if (receiver) {
> +      if (this.options.insertion) {
> +        new this.options.insertion(receiver, response);
> +      } else {
> +        receiver.innerHTML = response;
> +      }
> +    }
> +
> +    if (this.responseIsSuccess()) {
> +      if (this.onComplete)
> +        setTimeout((function() {this.onComplete(
> +          this.transport)}).bind(this), 10);
> +    }
> +
> +    if (this.options.evalScripts && scripts) {
> +      match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
> +      setTimeout((function() {
> +        for (var i = 0; i < scripts.length; i++)
> +          eval(scripts[i].match(match)[1]);
> +      }).bind(this), 10);
> +    }
> +  }
> +});
> +
> +Ajax.PeriodicalUpdater = Class.create();
> +Ajax.PeriodicalUpdater.prototype = (new Ajax.Base()).extend({
> +  initialize: function(container, url, options) {
> +    this.setOptions(options);
> +    this.onComplete = this.options.onComplete;
> +
> +    this.frequency = (this.options.frequency || 2);
> +    this.decay = 1;
> +
> +    this.updater = {};
> +    this.container = container;
> +    this.url = url;
> +
> +    this.start();
> +  },
> +
> +  start: function() {
> +    this.options.onComplete = this.updateComplete.bind(this);
> +    this.onTimerEvent();
> +  },
> +
> +  stop: function() {
> +    this.updater.onComplete = undefined;
> +    clearTimeout(this.timer);
> +    (this.onComplete || Ajax.emptyFunction).apply(this, arguments);
> +  },
> +
> +  updateComplete: function(request) {
> +    if (this.options.decay) {
> +      this.decay = (request.responseText == this.lastText ?
> +        this.decay * this.options.decay : 1);
> +
> +      this.lastText = request.responseText;
> +    }
> +    this.timer = setTimeout(this.onTimerEvent.bind(this),
> +      this.decay * this.frequency * 1000);
> +  },
> +
> +  onTimerEvent: function() {
> +    this.updater = new Ajax.Updater(this.container, this.url, this.options);
> +  }
> +});
> +
> +document.getElementsByClassName = function(className) {
> +  var children = document.getElementsByTagName('*') || document.all;
> +  var elements = new Array();
> +
> +  for (var i = 0; i < children.length; i++) {
> +    var child = children[i];
> +    var classNames = child.className.split(' ');
> +    for (var j = 0; j < classNames.length; j++) {
> +      if (classNames[j] == className) {
> +        elements.push(child);
> +        break;
> +      }
> +    }
> +  }
> +
> +  return elements;
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +if (!window.Element) {
> +  var ss = new Object();
> +}
> +
> +Object.extend(Element, {
> +  toggle: function() {
> +    for (var i = 0; i < arguments.length; i++) {
> +      var element = $(arguments[i]);
> +      element.style.display =
> +        (element.style.display == 'none' ? '' : 'none');
> +    }
> +  },
> +
> +  hide: function() {
> +    for (var i = 0; i < arguments.length; i++) {
> +      var element = $(arguments[i]);
> +      element.style.display = 'none';
> +    }
> +  },
> +
> +  show: function() {
> +    for (var i = 0; i < arguments.length; i++) {
> +      var element = $(arguments[i]);
> +      element.style.display = '';
> +    }
> +  },
> +
> +  remove: function(element) {
> +    element = $(element);
> +    element.parentNode.removeChild(element);
> +  },
> +
> +  getHeight: function(element) {
> +    element = $(element);
> +    return element.offsetHeight;
> +  },
> +
> +  hasClassName: function(element, className) {
> +    element = $(element);
> +    if (!element)
> +      return;
> +    var a = element.className.split(' ');
> +    for (var i = 0; i < a.length; i++) {
> +      if (a[i] == className)
> +        return true;
> +    }
> +    return false;
> +  },
> +
> +  addClassName: function(element, className) {
> +    element = $(element);
> +    Element.removeClassName(element, className);
> +    element.className += ' ' + className;
> +  },
> +
> +  removeClassName: function(element, className) {
> +    element = $(element);
> +    if (!element)
> +      return;
> +    var newClassName = '';
> +    var a = element.className.split(' ');
> +    for (var i = 0; i < a.length; i++) {
> +      if (a[i] != className) {
> +        if (i > 0)
> +          newClassName += ' ';
> +        newClassName += a[i];
> +      }
> +    }
> +    element.className = newClassName;
> +  },
> +
> +  // removes whitespace-only text node children
> +  cleanWhitespace: function(element) {
> +    var element = $(element);
> +    for (var i = 0; i < element.childNodes.length; i++) {
> +      var node = element.childNodes[i];
> +      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
> +        Element.remove(node);
> +    }
> +  }
> +});
> +
> +var Toggle = new Object();
> +Toggle.display = Element.toggle;
> +
> +/*--------------------------------------------------------------------------*/
> +
> +Abstract.Insertion = function(adjacency) {
> +  this.adjacency = adjacency;
> +}
> +
> +Abstract.Insertion.prototype = {
> +  initialize: function(element, content) {
> +    this.element = $(element);
> +    this.content = content;
> +
> +    if (this.adjacency && this.element.insertAdjacentHTML) {
> +      this.element.insertAdjacentHTML(this.adjacency, this.content);
> +    } else {
> +      this.range = this.element.ownerDocument.createRange();
> +      if (this.initializeRange) this.initializeRange();
> +      this.fragment = this.range.createContextualFragment(this.content);
> +      this.insertContent();
> +    }
> +  }
> +}
> +
> +var Insertion = new Object();
> +
> +Insertion.Before = Class.create();
> +Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
> +  initializeRange: function() {
> +    this.range.setStartBefore(this.element);
> +  },
> +
> +  insertContent: function() {
> +    this.element.parentNode.insertBefore(this.fragment, this.element);
> +  }
> +});
> +
> +Insertion.Top = Class.create();
> +Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
> +  initializeRange: function() {
> +    this.range.selectNodeContents(this.element);
> +    this.range.collapse(true);
> +  },
> +
> +  insertContent: function() {
> +    this.element.insertBefore(this.fragment, this.element.firstChild);
> +  }
> +});
> +
> +Insertion.Bottom = Class.create();
> +Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
> +  initializeRange: function() {
> +    this.range.selectNodeContents(this.element);
> +    this.range.collapse(this.element);
> +  },
> +
> +  insertContent: function() {
> +    this.element.appendChild(this.fragment);
> +  }
> +});
> +
> +Insertion.After = Class.create();
> +Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
> +  initializeRange: function() {
> +    this.range.setStartAfter(this.element);
> +  },
> +
> +  insertContent: function() {
> +    this.element.parentNode.insertBefore(this.fragment,
> +      this.element.nextSibling);
> +  }
> +});
> +
> +var Field = {
> +  clear: function() {
> +    for (var i = 0; i < arguments.length; i++)
> +      $(arguments[i]).value = '';
> +  },
> +
> +  focus: function(element) {
> +    $(element).focus();
> +  },
> +
> +  present: function() {
> +    for (var i = 0; i < arguments.length; i++)
> +      if ($(arguments[i]).value == '') return false;
> +    return true;
> +  },
> +
> +  select: function(element) {
> +    $(element).select();
> +  },
> +
> +  activate: function(element) {
> +    $(element).focus();
> +    $(element).select();
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +var Form = {
> +  serialize: function(form) {
> +    var elements = Form.getElements($(form));
> +    var queryComponents = new Array();
> +
> +    for (var i = 0; i < elements.length; i++) {
> +      var queryComponent = Form.Element.serialize(elements[i]);
> +      if (queryComponent)
> +        queryComponents.push(queryComponent);
> +    }
> +
> +    return queryComponents.join('&');
> +  },
> +
> +  getElements: function(form) {
> +    var form = $(form);
> +    var elements = new Array();
> +
> +    for (tagName in Form.Element.Serializers) {
> +      var tagElements = form.getElementsByTagName(tagName);
> +      for (var j = 0; j < tagElements.length; j++)
> +        elements.push(tagElements[j]);
> +    }
> +    return elements;
> +  },
> +
> +  getInputs: function(form, typeName, name) {
> +    var form = $(form);
> +    var inputs = form.getElementsByTagName('input');
> +
> +    if (!typeName && !name)
> +      return inputs;
> +
> +    var matchingInputs = new Array();
> +    for (var i = 0; i < inputs.length; i++) {
> +      var input = inputs[i];
> +      if ((typeName && input.type != typeName) ||
> +          (name && input.name != name))
> +        continue;
> +      matchingInputs.push(input);
> +    }
> +
> +    return matchingInputs;
> +  },
> +
> +  disable: function(form) {
> +    var elements = Form.getElements(form);
> +    for (var i = 0; i < elements.length; i++) {
> +      var element = elements[i];
> +      element.blur();
> +      element.disabled = 'true';
> +    }
> +  },
> +
> +  enable: function(form) {
> +    var elements = Form.getElements(form);
> +    for (var i = 0; i < elements.length; i++) {
> +      var element = elements[i];
> +      element.disabled = '';
> +    }
> +  },
> +
> +  focusFirstElement: function(form) {
> +    var form = $(form);
> +    var elements = Form.getElements(form);
> +    for (var i = 0; i < elements.length; i++) {
> +      var element = elements[i];
> +      if (element.type != 'hidden' && !element.disabled) {
> +        Field.activate(element);
> +        break;
> +      }
> +    }
> +  },
> +
> +  reset: function(form) {
> +    $(form).reset();
> +  }
> +}
> +
> +Form.Element = {
> +  serialize: function(element) {
> +    var element = $(element);
> +    var method = element.tagName.toLowerCase();
> +    var parameter = Form.Element.Serializers[method](element);
> +
> +    if (parameter)
> +      return encodeURIComponent(parameter[0]) + '=' +
> +        encodeURIComponent(parameter[1]);
> +  },
> +
> +  getValue: function(element) {
> +    var element = $(element);
> +    var method = element.tagName.toLowerCase();
> +    var parameter = Form.Element.Serializers[method](element);
> +
> +    if (parameter)
> +      return parameter[1];
> +  }
> +}
> +
> +Form.Element.Serializers = {
> +  input: function(element) {
> +    switch (element.type.toLowerCase()) {
> +      case 'submit':
> +      case 'hidden':
> +      case 'password':
> +      case 'text':
> +        return Form.Element.Serializers.textarea(element);
> +      case 'checkbox':
> +      case 'radio':
> +        return Form.Element.Serializers.inputSelector(element);
> +    }
> +    return false;
> +  },
> +
> +  inputSelector: function(element) {
> +    if (element.checked)
> +      return [element.name, element.value];
> +  },
> +
> +  textarea: function(element) {
> +    return [element.name, element.value];
> +  },
> +
> +  select: function(element) {
> +    var value = '';
> +    if (element.type == 'select-one') {
> +      var index = element.selectedIndex;
> +      if (index >= 0)
> +        value = element.options[index].value || element.options[index].text;
> +    } else {
> +      value = new Array();
> +      for (var i = 0; i < element.length; i++) {
> +        var opt = element.options[i];
> +        if (opt.selected)
> +          value.push(opt.value || opt.text);
> +      }
> +    }
> +    return [element.name, value];
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +var $F = Form.Element.getValue;
> +
> +/*--------------------------------------------------------------------------*/
> +
> +Abstract.TimedObserver = function() {}
> +Abstract.TimedObserver.prototype = {
> +  initialize: function(element, frequency, callback) {
> +    this.frequency = frequency;
> +    this.element   = $(element);
> +    this.callback  = callback;
> +
> +    this.lastValue = this.getValue();
> +    this.registerCallback();
> +  },
> +
> +  registerCallback: function() {
> +    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
> +  },
> +
> +  onTimerEvent: function() {
> +    var value = this.getValue();
> +    if (this.lastValue != value) {
> +      this.callback(this.element, value);
> +      this.lastValue = value;
> +    }
> +  }
> +}
> +
> +Form.Element.Observer = Class.create();
> +Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
> +  getValue: function() {
> +    return Form.Element.getValue(this.element);
> +  }
> +});
> +
> +Form.Observer = Class.create();
> +Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
> +  getValue: function() {
> +    return Form.serialize(this.element);
> +  }
> +});
> +
> +/*--------------------------------------------------------------------------*/
> +
> +Abstract.EventObserver = function() {}
> +Abstract.EventObserver.prototype = {
> +  initialize: function(element, callback) {
> +    this.element  = $(element);
> +    this.callback = callback;
> +
> +    this.lastValue = this.getValue();
> +    if (this.element.tagName.toLowerCase() == 'form')
> +      this.registerFormCallbacks();
> +    else
> +      this.registerCallback(this.element);
> +  },
> +
> +  onElementEvent: function() {
> +    var value = this.getValue();
> +    if (this.lastValue != value) {
> +      this.callback(this.element, value);
> +      this.lastValue = value;
> +    }
> +  },
> +
> +  registerFormCallbacks: function() {
> +    var elements = Form.getElements(this.element);
> +    for (var i = 0; i < elements.length; i++)
> +      this.registerCallback(elements[i]);
> +  },
> +
> +  registerCallback: function(element) {
> +    if (element.type) {
> +      switch (element.type.toLowerCase()) {
> +        case 'checkbox':
> +        case 'radio':
> +          element.target = this;
> +          element.prev_onclick = element.onclick || Prototype.emptyFunction;
> +          element.onclick = function() {
> +            this.prev_onclick();
> +            this.target.onElementEvent();
> +          }
> +          break;
> +        case 'password':
> +        case 'text':
> +        case 'textarea':
> +        case 'select-one':
> +        case 'select-multiple':
> +          element.target = this;
> +          element.prev_onchange = element.onchange || Prototype.emptyFunction;
> +          element.onchange = function() {
> +            this.prev_onchange();
> +            this.target.onElementEvent();
> +          }
> +          break;
> +      }
> +    }
> +  }
> +}
> +
> +Form.Element.EventObserver = Class.create();
> +Form.Element.EventObserver.prototype = (new Abstract.EventObserver()).extend({
> +  getValue: function() {
> +    return Form.Element.getValue(this.element);
> +  }
> +});
> +
> +Form.EventObserver = Class.create();
> +Form.EventObserver.prototype = (new Abstract.EventObserver()).extend({
> +  getValue: function() {
> +    return Form.serialize(this.element);
> +  }
> +});
> +
> +
> +if (!window.Event) {
> +  var Event = new Object();
> +}
> +
> +Object.extend(Event, {
> +  KEY_BACKSPACE: 8,
> +  KEY_TAB:       9,
> +  KEY_RETURN:   13,
> +  KEY_ESC:      27,
> +  KEY_LEFT:     37,
> +  KEY_UP:       38,
> +  KEY_RIGHT:    39,
> +  KEY_DOWN:     40,
> +  KEY_DELETE:   46,
> +
> +  element: function(event) {
> +    return event.target || event.srcElement;
> +  },
> +
> +  isLeftClick: function(event) {
> +    return (((event.which) && (event.which == 1)) ||
> +            ((event.button) && (event.button == 1)));
> +  },
> +
> +  pointerX: function(event) {
> +    return event.pageX || (event.clientX +
> +      (document.documentElement.scrollLeft || document.body.scrollLeft));
> +  },
> +
> +  pointerY: function(event) {
> +    return event.pageY || (event.clientY +
> +      (document.documentElement.scrollTop || document.body.scrollTop));
> +  },
> +
> +  stop: function(event) {
> +    if (event.preventDefault) {
> +      event.preventDefault();
> +      event.stopPropagation();
> +    } else {
> +      event.returnValue = false;
> +    }
> +  },
> +
> +  // find the first node with the given tagName, starting from the
> +  // node the event was triggered on; traverses the DOM upwards
> +  findElement: function(event, tagName) {
> +    var element = Event.element(event);
> +    while (element.parentNode && (!element.tagName ||
> +        (element.tagName.toUpperCase() != tagName.toUpperCase())))
> +      element = element.parentNode;
> +    return element;
> +  },
> +
> +  observers: false,
> +
> +  _observeAndCache: function(element, name, observer, useCapture) {
> +    if (!this.observers) this.observers = [];
> +    if (element.addEventListener) {
> +      this.observers.push([element, name, observer, useCapture]);
> +      element.addEventListener(name, observer, useCapture);
> +    } else if (element.attachEvent) {
> +      this.observers.push([element, name, observer, useCapture]);
> +      element.attachEvent('on' + name, observer);
> +    }
> +  },
> +
> +  unloadCache: function() {
> +    if (!Event.observers) return;
> +    for (var i = 0; i < Event.observers.length; i++) {
> +      Event.stopObserving.apply(this, Event.observers[i]);
> +      Event.observers[i][0] = null;
> +    }
> +    Event.observers = false;
> +  },
> +
> +  observe: function(element, name, observer, useCapture) {
> +    var element = $(element);
> +    useCapture = useCapture || false;
> +
> +    if (name == 'keypress' &&
> +        ((navigator.appVersion.indexOf('AppleWebKit') > 0)
> +        || element.attachEvent))
> +      name = 'keydown';
> +
> +    this._observeAndCache(element, name, observer, useCapture);
> +  },
> +
> +  stopObserving: function(element, name, observer, useCapture) {
> +    var element = $(element);
> +    useCapture = useCapture || false;
> +
> +    if (name == 'keypress' &&
> +        ((navigator.appVersion.indexOf('AppleWebKit') > 0)
> +        || element.detachEvent))
> +      name = 'keydown';
> +
> +    if (element.removeEventListener) {
> +      element.removeEventListener(name, observer, useCapture);
> +    } else if (element.detachEvent) {
> +      element.detachEvent('on' + name, observer);
> +    }
> +  }
> +});
> +
> +/* prevent memory leaks in IE */
> +Event.observe(window, 'unload', Event.unloadCache, false);
> +
> +var Position = {
> +
> +  // set to true if needed, warning: firefox performance problems
> +  // NOT neeeded for page scrolling, only if draggable contained in
> +  // scrollable elements
> +  includeScrollOffsets: false,
> +
> +  // must be called before calling withinIncludingScrolloffset, every time the
> +  // page is scrolled
> +  prepare: function() {
> +    this.deltaX =  window.pageXOffset
> +                || document.documentElement.scrollLeft
> +                || document.body.scrollLeft
> +                || 0;
> +    this.deltaY =  window.pageYOffset
> +                || document.documentElement.scrollTop
> +                || document.body.scrollTop
> +                || 0;
> +  },
> +
> +  realOffset: function(element) {
> +    var valueT = 0, valueL = 0;
> +    do {
> +      valueT += element.scrollTop  || 0;
> +      valueL += element.scrollLeft || 0;
> +      element = element.parentNode;
> +    } while (element);
> +    return [valueL, valueT];
> +  },
> +
> +  cumulativeOffset: function(element) {
> +    var valueT = 0, valueL = 0;
> +    do {
> +      valueT += element.offsetTop  || 0;
> +      valueL += element.offsetLeft || 0;
> +      element = element.offsetParent;
> +    } while (element);
> +    return [valueL, valueT];
> +  },
> +
> +  // caches x/y coordinate pair to use with overlap
> +  within: function(element, x, y) {
> +    if (this.includeScrollOffsets)
> +      return this.withinIncludingScrolloffsets(element, x, y);
> +    this.xcomp = x;
> +    this.ycomp = y;
> +    this.offset = this.cumulativeOffset(element);
> +
> +    return (y >= this.offset[1] &&
> +            y <  this.offset[1] + element.offsetHeight &&
> +            x >= this.offset[0] &&
> +            x <  this.offset[0] + element.offsetWidth);
> +  },
> +
> +  withinIncludingScrolloffsets: function(element, x, y) {
> +    var offsetcache = this.realOffset(element);
> +
> +    this.xcomp = x + offsetcache[0] - this.deltaX;
> +    this.ycomp = y + offsetcache[1] - this.deltaY;
> +    this.offset = this.cumulativeOffset(element);
> +
> +    return (this.ycomp >= this.offset[1] &&
> +            this.ycomp <  this.offset[1] + element.offsetHeight &&
> +            this.xcomp >= this.offset[0] &&
> +            this.xcomp <  this.offset[0] + element.offsetWidth);
> +  },
> +
> +  // within must be called directly before
> +  overlap: function(mode, element) {
> +    if (!mode) return 0;
> +    if (mode == 'vertical')
> +      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
> +        element.offsetHeight;
> +    if (mode == 'horizontal')
> +      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
> +        element.offsetWidth;
> +  },
> +
> +  clone: function(source, target) {
> +    source = $(source);
> +    target = $(target);
> +    target.style.position = 'absolute';
> +    var offsets = this.cumulativeOffset(source);
> +    target.style.top    = offsets[1] + 'px';
> +    target.style.left   = offsets[0] + 'px';
> +    target.style.width  = source.offsetWidth + 'px';
> +    target.style.height = source.offsetHeight + 'px';
> +  }
> +}
>
> Added: xwiki/trunk/src/main/web/skins/default/rico/prototype.js
> ===================================================================
> --- xwiki/trunk/src/main/web/skins/default/rico/prototype.js    2006-03-28 10:10:11 UTC (rev 996)
> +++ xwiki/trunk/src/main/web/skins/default/rico/prototype.js    2006-03-28 10:10:39 UTC (rev 997)
> @@ -0,0 +1,1047 @@
> +<script type="text/javascript">
> +<!--
> +/*  Prototype JavaScript framework, version 1.3.1
> + *  (c) 2005 Sam Stephenson <sam at conio.net>
> + *
> + *  THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
> + *  against the source tree, available from the Prototype darcs repository.
> + *
> + *  Prototype is freely distributable under the terms of an MIT-style license.
> + *
> + *  For details, see the Prototype web site: http://prototype.conio.net/
> + *
> +/*--------------------------------------------------------------------------*/
> +
> +var Prototype = {
> +  Version: '1.3.1',
> +  emptyFunction: function() {}
> +}
> +
> +var Class = {
> +  create: function() {
> +    return function() {
> +      this.initialize.apply(this, arguments);
> +    }
> +  }
> +}
> +
> +var Abstract = new Object();
> +
> +Object.extend = function(destination, source) {
> +  for (property in source) {
> +    destination[property] = source[property];
> +  }
> +  return destination;
> +}
> +
> +Object.prototype.extend = function(object) {
> +  return Object.extend.apply(this, [this, object]);
> +}
> +
> +Function.prototype.bind = function(object) {
> +  var __method = this;
> +  return function() {
> +    __method.apply(object, arguments);
> +  }
> +}
> +
> +Function.prototype.bindAsEventListener = function(object) {
> +  var __method = this;
> +  return function(event) {
> +    __method.call(object, event || window.event);
> +  }
> +}
> +
> +Number.prototype.toColorPart = function() {
> +  var digits = this.toString(16);
> +  if (this < 16) return '0' + digits;
> +  return digits;
> +}
> +
> +var Try = {
> +  these: function() {
> +    var returnValue;
> +
> +    for (var i = 0; i < arguments.length; i++) {
> +      var lambda = arguments[i];
> +      try {
> +        returnValue = lambda();
> +        break;
> +      } catch (e) {}
> +    }
> +
> +    return returnValue;
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +var PeriodicalExecuter = Class.create();
> +PeriodicalExecuter.prototype = {
> +  initialize: function(callback, frequency) {
> +    this.callback = callback;
> +    this.frequency = frequency;
> +    this.currentlyExecuting = false;
> +
> +    this.registerCallback();
> +  },
> +
> +  registerCallback: function() {
> +    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
> +  },
> +
> +  onTimerEvent: function() {
> +    if (!this.currentlyExecuting) {
> +      try {
> +        this.currentlyExecuting = true;
> +        this.callback();
> +      } finally {
> +        this.currentlyExecuting = false;
> +      }
> +    }
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +function $() {
> +  var elements = new Array();
> +
> +  for (var i = 0; i < arguments.length; i++) {
> +    var element = arguments[i];
> +    if (typeof element == 'string')
> +      element = document.getElementById(element);
> +
> +    if (arguments.length == 1)
> +      return element;
> +
> +    elements.push(element);
> +  }
> +
> +  return elements;
> +}
> +
> +if (!Array.prototype.push) {
> +  Array.prototype.push = function() {
> +               var startLength = this.length;
> +               for (var i = 0; i < arguments.length; i++)
> +      this[startLength + i] = arguments[i];
> +         return this.length;
> +  }
> +}
> +
> +if (!Function.prototype.apply) {
> +  // Based on code from http://www.youngpup.net/
> +  Function.prototype.apply = function(object, parameters) {
> +    var parameterStrings = new Array();
> +    if (!object)     object = window;
> +    if (!parameters) parameters = new Array();
> +
> +    for (var i = 0; i < parameters.length; i++)
> +      parameterStrings[i] = 'parameters[' + i + ']';
> +
> +    object.__apply__ = this;
> +    var result = eval('object.__apply__(' +
> +      parameterStrings.join(', ') + ')');
> +    object.__apply__ = null;
> +
> +    return result;
> +  }
> +}
> +
> +String.prototype.extend({
> +  stripTags: function() {
> +    return this.replace(/<\/?[^>]+>/gi, '');
> +  },
> +
> +  escapeHTML: function() {
> +    var div = document.createElement('div');
> +    var text = document.createTextNode(this);
> +    div.appendChild(text);
> +    return div.innerHTML;
> +  },
> +
> +  unescapeHTML: function() {
> +    var div = document.createElement('div');
> +    div.innerHTML = this.stripTags();
> +    return div.childNodes[0].nodeValue;
> +  }
> +});
> +
> +var Ajax = {
> +  getTransport: function() {
> +    return Try.these(
> +      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
> +      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
> +      function() {return new XMLHttpRequest()}
> +    ) || false;
> +  }
> +}
> +
> +Ajax.Base = function() {};
> +Ajax.Base.prototype = {
> +  setOptions: function(options) {
> +    this.options = {
> +      method:       'post',
> +      asynchronous: true,
> +      parameters:   ''
> +    }.extend(options || {});
> +  },
> +
> +  responseIsSuccess: function() {
> +    return this.transport.status == undefined
> +        || this.transport.status == 0
> +        || (this.transport.status >= 200 && this.transport.status < 300);
> +  },
> +
> +  responseIsFailure: function() {
> +    return !this.responseIsSuccess();
> +  }
> +}
> +
> +Ajax.Request = Class.create();
> +Ajax.Request.Events =
> +  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
> +
> +Ajax.Request.prototype = (new Ajax.Base()).extend({
> +  initialize: function(url, options) {
> +    this.transport = Ajax.getTransport();
> +    this.setOptions(options);
> +    this.request(url);
> +  },
> +
> +  request: function(url) {
> +    var parameters = this.options.parameters || '';
> +    if (parameters.length > 0) parameters += '&_=';
> +
> +    try {
> +      // changes for handling ?xpage=rdf
> +      if (this.options.method == 'get')
> +      {
> +       var urlSeparator = url.indexOf('?') ? '&' : '?'
> +        url += urlSeparator + parameters;
> +      }
> +
> +      this.transport.open(this.options.method, url,
> +        this.options.asynchronous);
> +
> +      if (this.options.asynchronous) {
> +        this.transport.onreadystatechange = this.onStateChange.bind(this);
> +        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
> +      }
> +
> +      this.setRequestHeaders();
> +
> +      var body = this.options.postBody ? this.options.postBody : parameters;
> +      this.transport.send(this.options.method == 'post' ? body : null);
> +
> +    } catch (e) {
> +      alert (e);
> +    }
> +  },
> +
> +  setRequestHeaders: function() {
> +    var requestHeaders =
> +      ['X-Requested-With', 'XMLHttpRequest',
> +       'X-Prototype-Version', Prototype.Version];
> +
> +    if (this.options.method == 'post') {
> +      requestHeaders.push('Content-type',
> +        'application/x-www-form-urlencoded');
> +
> +      /* Force "Connection: close" for Mozilla browsers to work around
> +       * a bug where XMLHttpReqeuest sends an incorrect Content-length
> +       * header. See Mozilla Bugzilla #246651.
> +       */
> +      if (this.transport.overrideMimeType)
> +        requestHeaders.push('Connection', 'close');
> +    }
> +
> +    if (this.options.requestHeaders)
> +      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
> +
> +    for (var i = 0; i < requestHeaders.length; i += 2)
> +      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
> +  },
> +
> +  onStateChange: function() {
> +    var readyState = this.transport.readyState;
> +    if (readyState != 1)
> +      this.respondToReadyState(this.transport.readyState);
> +  },
> +
> +  respondToReadyState: function(readyState) {
> +    var event = Ajax.Request.Events[readyState];
> +
> +    if (event == 'Complete')
> +      (this.options['on' + this.transport.status]
> +       || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
> +       || Prototype.emptyFunction)(this.transport);
> +
> +    (this.options['on' + event] || Prototype.emptyFunction)(this.transport);
> +
> +    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
> +    if (event == 'Complete')
> +      this.transport.onreadystatechange = Prototype.emptyFunction;
> +  }
> +});
> +
> +Ajax.Updater = Class.create();
> +Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
> +
> +Ajax.Updater.prototype.extend(Ajax.Request.prototype).extend({
> +  initialize: function(container, url, options) {
> +    this.containers = {
> +      success: container.success ? $(container.success) : $(container),
> +      failure: container.failure ? $(container.failure) :
> +        (container.success ? null : $(container))
> +    }
> +
> +    this.transport = Ajax.getTransport();
> +    this.setOptions(options);
> +
> +    var onComplete = this.options.onComplete || Prototype.emptyFunction;
> +    this.options.onComplete = (function() {
> +      this.updateContent();
> +      onComplete(this.transport);
> +    }).bind(this);
> +
> +    this.request(url);
> +  },
> +
> +  updateContent: function() {
> +    var receiver = this.responseIsSuccess() ?
> +      this.containers.success : this.containers.failure;
> +
> +    var match    = new RegExp(Ajax.Updater.ScriptFragment, 'img');
> +    var response = this.transport.responseText.replace(match, '');
> +    var scripts  = this.transport.responseText.match(match);
> +
> +    if (receiver) {
> +      if (this.options.insertion) {
> +        new this.options.insertion(receiver, response);
> +      } else {
> +        receiver.innerHTML = response;
> +      }
> +    }
> +
> +    if (this.responseIsSuccess()) {
> +      if (this.onComplete)
> +        setTimeout((function() {this.onComplete(
> +          this.transport)}).bind(this), 10);
> +    }
> +
> +    if (this.options.evalScripts && scripts) {
> +      match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
> +      setTimeout((function() {
> +        for (var i = 0; i < scripts.length; i++)
> +          eval(scripts[i].match(match)[1]);
> +      }).bind(this), 10);
> +    }
> +  }
> +});
> +
> +Ajax.PeriodicalUpdater = Class.create();
> +Ajax.PeriodicalUpdater.prototype = (new Ajax.Base()).extend({
> +  initialize: function(container, url, options) {
> +    this.setOptions(options);
> +    this.onComplete = this.options.onComplete;
> +
> +    this.frequency = (this.options.frequency || 2);
> +    this.decay = 1;
> +
> +    this.updater = {};
> +    this.container = container;
> +    this.url = url;
> +
> +    this.start();
> +  },
> +
> +  start: function() {
> +    this.options.onComplete = this.updateComplete.bind(this);
> +    this.onTimerEvent();
> +  },
> +
> +  stop: function() {
> +    this.updater.onComplete = undefined;
> +    clearTimeout(this.timer);
> +    (this.onComplete || Ajax.emptyFunction).apply(this, arguments);
> +  },
> +
> +  updateComplete: function(request) {
> +    if (this.options.decay) {
> +      this.decay = (request.responseText == this.lastText ?
> +        this.decay * this.options.decay : 1);
> +
> +      this.lastText = request.responseText;
> +    }
> +    this.timer = setTimeout(this.onTimerEvent.bind(this),
> +      this.decay * this.frequency * 1000);
> +  },
> +
> +  onTimerEvent: function() {
> +    this.updater = new Ajax.Updater(this.container, this.url, this.options);
> +  }
> +});
> +
> +document.getElementsByClassName = function(className) {
> +  var children = document.getElementsByTagName('*') || document.all;
> +  var elements = new Array();
> +
> +  for (var i = 0; i < children.length; i++) {
> +    var child = children[i];
> +    var classNames = child.className.split(' ');
> +    for (var j = 0; j < classNames.length; j++) {
> +      if (classNames[j] == className) {
> +        elements.push(child);
> +        break;
> +      }
> +    }
> +  }
> +
> +  return elements;
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +if (!window.Element) {
> +  var Element = new Object();
> +}
> +
> +Object.extend(Element, {
> +  toggle: function() {
> +    for (var i = 0; i < arguments.length; i++) {
> +      var element = $(arguments[i]);
> +      element.style.display =
> +        (element.style.display == 'none' ? '' : 'none');
> +    }
> +  },
> +
> +  hide: function() {
> +    for (var i = 0; i < arguments.length; i++) {
> +      var element = $(arguments[i]);
> +      element.style.display = 'none';
> +    }
> +  },
> +
> +  show: function() {
> +    for (var i = 0; i < arguments.length; i++) {
> +      var element = $(arguments[i]);
> +      element.style.display = '';
> +    }
> +  },
> +
> +  remove: function(element) {
> +    element = $(element);
> +    element.parentNode.removeChild(element);
> +  },
> +
> +  getHeight: function(element) {
> +    element = $(element);
> +    return element.offsetHeight;
> +  },
> +
> +  hasClassName: function(element, className) {
> +    element = $(element);
> +    if (!element)
> +      return;
> +    var a = element.className.split(' ');
> +    for (var i = 0; i < a.length; i++) {
> +      if (a[i] == className)
> +        return true;
> +    }
> +    return false;
> +  },
> +
> +  addClassName: function(element, className) {
> +    element = $(element);
> +    Element.removeClassName(element, className);
> +    element.className += ' ' + className;
> +  },
> +
> +  removeClassName: function(element, className) {
> +    element = $(element);
> +    if (!element)
> +      return;
> +    var newClassName = '';
> +    var a = element.className.split(' ');
> +    for (var i = 0; i < a.length; i++) {
> +      if (a[i] != className) {
> +        if (i > 0)
> +          newClassName += ' ';
> +        newClassName += a[i];
> +      }
> +    }
> +    element.className = newClassName;
> +  },
> +
> +  // removes whitespace-only text node children
> +  cleanWhitespace: function(element) {
> +    var element = $(element);
> +    for (var i = 0; i < element.childNodes.length; i++) {
> +      var node = element.childNodes[i];
> +      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
> +        Element.remove(node);
> +    }
> +  }
> +});
> +
> +var Toggle = new Object();
> +Toggle.display = Element.toggle;
> +
> +/*--------------------------------------------------------------------------*/
> +
> +Abstract.Insertion = function(adjacency) {
> +  this.adjacency = adjacency;
> +}
> +
> +Abstract.Insertion.prototype = {
> +  initialize: function(element, content) {
> +    this.element = $(element);
> +    this.content = content;
> +
> +    if (this.adjacency && this.element.insertAdjacentHTML) {
> +      this.element.insertAdjacentHTML(this.adjacency, this.content);
> +    } else {
> +      this.range = this.element.ownerDocument.createRange();
> +      if (this.initializeRange) this.initializeRange();
> +      this.fragment = this.range.createContextualFragment(this.content);
> +      this.insertContent();
> +    }
> +  }
> +}
> +
> +var Insertion = new Object();
> +
> +Insertion.Before = Class.create();
> +Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
> +  initializeRange: function() {
> +    this.range.setStartBefore(this.element);
> +  },
> +
> +  insertContent: function() {
> +    this.element.parentNode.insertBefore(this.fragment, this.element);
> +  }
> +});
> +
> +Insertion.Top = Class.create();
> +Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
> +  initializeRange: function() {
> +    this.range.selectNodeContents(this.element);
> +    this.range.collapse(true);
> +  },
> +
> +  insertContent: function() {
> +    this.element.insertBefore(this.fragment, this.element.firstChild);
> +  }
> +});
> +
> +Insertion.Bottom = Class.create();
> +Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
> +  initializeRange: function() {
> +    this.range.selectNodeContents(this.element);
> +    this.range.collapse(this.element);
> +  },
> +
> +  insertContent: function() {
> +    this.element.appendChild(this.fragment);
> +  }
> +});
> +
> +Insertion.After = Class.create();
> +Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
> +  initializeRange: function() {
> +    this.range.setStartAfter(this.element);
> +  },
> +
> +  insertContent: function() {
> +    this.element.parentNode.insertBefore(this.fragment,
> +      this.element.nextSibling);
> +  }
> +});
> +
> +var Field = {
> +  clear: function() {
> +    for (var i = 0; i < arguments.length; i++)
> +      $(arguments[i]).value = '';
> +  },
> +
> +  focus: function(element) {
> +    $(element).focus();
> +  },
> +
> +  present: function() {
> +    for (var i = 0; i < arguments.length; i++)
> +      if ($(arguments[i]).value == '') return false;
> +    return true;
> +  },
> +
> +  select: function(element) {
> +    $(element).select();
> +  },
> +
> +  activate: function(element) {
> +    $(element).focus();
> +    $(element).select();
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +var Form = {
> +  serialize: function(form) {
> +    var elements = Form.getElements($(form));
> +    var queryComponents = new Array();
> +
> +    for (var i = 0; i < elements.length; i++) {
> +      var queryComponent = Form.Element.serialize(elements[i]);
> +      if (queryComponent)
> +        queryComponents.push(queryComponent);
> +    }
> +
> +    return queryComponents.join('&');
> +  },
> +
> +  getElements: function(form) {
> +    var form = $(form);
> +    var elements = new Array();
> +
> +    for (tagName in Form.Element.Serializers) {
> +      var tagElements = form.getElementsByTagName(tagName);
> +      for (var j = 0; j < tagElements.length; j++)
> +        elements.push(tagElements[j]);
> +    }
> +    return elements;
> +  },
> +
> +  getInputs: function(form, typeName, name) {
> +    var form = $(form);
> +    var inputs = form.getElementsByTagName('input');
> +
> +    if (!typeName && !name)
> +      return inputs;
> +
> +    var matchingInputs = new Array();
> +    for (var i = 0; i < inputs.length; i++) {
> +      var input = inputs[i];
> +      if ((typeName && input.type != typeName) ||
> +          (name && input.name != name))
> +        continue;
> +      matchingInputs.push(input);
> +    }
> +
> +    return matchingInputs;
> +  },
> +
> +  disable: function(form) {
> +    var elements = Form.getElements(form);
> +    for (var i = 0; i < elements.length; i++) {
> +      var element = elements[i];
> +      element.blur();
> +      element.disabled = 'true';
> +    }
> +  },
> +
> +  enable: function(form) {
> +    var elements = Form.getElements(form);
> +    for (var i = 0; i < elements.length; i++) {
> +      var element = elements[i];
> +      element.disabled = '';
> +    }
> +  },
> +
> +  focusFirstElement: function(form) {
> +    var form = $(form);
> +    var elements = Form.getElements(form);
> +    for (var i = 0; i < elements.length; i++) {
> +      var element = elements[i];
> +      if (element.type != 'hidden' && !element.disabled) {
> +        Field.activate(element);
> +        break;
> +      }
> +    }
> +  },
> +
> +  reset: function(form) {
> +    $(form).reset();
> +  }
> +}
> +
> +Form.Element = {
> +  serialize: function(element) {
> +    var element = $(element);
> +    var method = element.tagName.toLowerCase();
> +    var parameter = Form.Element.Serializers[method](element);
> +
> +    if (parameter)
> +      return encodeURIComponent(parameter[0]) + '=' +
> +        encodeURIComponent(parameter[1]);
> +  },
> +
> +  getValue: function(element) {
> +    var element = $(element);
> +    var method = element.tagName.toLowerCase();
> +    var parameter = Form.Element.Serializers[method](element);
> +
> +    if (parameter)
> +      return parameter[1];
> +  }
> +}
> +
> +Form.Element.Serializers = {
> +  input: function(element) {
> +    switch (element.type.toLowerCase()) {
> +      case 'submit':
> +      case 'hidden':
> +      case 'password':
> +      case 'text':
> +        return Form.Element.Serializers.textarea(element);
> +      case 'checkbox':
> +      case 'radio':
> +        return Form.Element.Serializers.inputSelector(element);
> +    }
> +    return false;
> +  },
> +
> +  inputSelector: function(element) {
> +    if (element.checked)
> +      return [element.name, element.value];
> +  },
> +
> +  textarea: function(element) {
> +    return [element.name, element.value];
> +  },
> +
> +  select: function(element) {
> +    var value = '';
> +    if (element.type == 'select-one') {
> +      var index = element.selectedIndex;
> +      if (index >= 0)
> +        value = element.options[index].value || element.options[index].text;
> +    } else {
> +      value = new Array();
> +      for (var i = 0; i < element.length; i++) {
> +        var opt = element.options[i];
> +        if (opt.selected)
> +          value.push(opt.value || opt.text);
> +      }
> +    }
> +    return [element.name, value];
> +  }
> +}
> +
> +/*--------------------------------------------------------------------------*/
> +
> +var $F = Form.Element.getValue;
> +
> +/*--------------------------------------------------------------------------*/
> +
> +Abstract.TimedObserver = function() {}
> +Abstract.TimedObserver.prototype = {
> +  initialize: function(element, frequency, callback) {
> +    this.frequency = frequency;
> +    this.element   = $(element);
> +    this.callback  = callback;
> +
> +    this.lastValue = this.getValue();
> +    this.registerCallback();
> +  },
> +
> +  registerCallback: function() {
> +    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
> +  },
> +
> +  onTimerEvent: function() {
> +    var value = this.getValue();
> +    if (this.lastValue != value) {
> +      this.callback(this.element, value);
> +      this.lastValue = value;
> +    }
> +  }
> +}
> +
> +Form.Element.Observer = Class.create();
> +Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
> +  getValue: function() {
> +    return Form.Element.getValue(this.element);
> +  }
> +});
> +
> +Form.Observer = Class.create();
> +Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
> +  getValue: function() {
> +    return Form.serialize(this.element);
> +  }
> +});
> +
> +/*--------------------------------------------------------------------------*/
> +
> +Abstract.EventObserver = function() {}
> +Abstract.EventObserver.prototype = {
> +  initialize: function(element, callback) {
> +    this.element  = $(element);
> +    this.callback = callback;
> +
> +    this.lastValue = this.getValue();
> +    if (this.element.tagName.toLowerCase() == 'form')
> +      this.registerFormCallbacks();
> +    else
> +      this.registerCallback(this.element);
> +  },
> +
> +  onElementEvent: function() {
> +    var value = this.getValue();
> +    if (this.lastValue != value) {
> +      this.callback(this.element, value);
> +      this.lastValue = value;
> +    }
> +  },
> +
> +  registerFormCallbacks: function() {
> +    var elements = Form.getElements(this.element);
> +    for (var i = 0; i < elements.length; i++)
> +      this.registerCallback(elements[i]);
> +  },
> +
> +  registerCallback: function(element) {
> +    if (element.type) {
> +      switch (element.type.toLowerCase()) {
> +        case 'checkbox':
> +        case 'radio':
> +          element.target = this;
> +          element.prev_onclick = element.onclick || Prototype.emptyFunction;
> +          element.onclick = function() {
> +            this.prev_onclick();
> +            this.target.onElementEvent();
> +          }
> +          break;
> +        case 'password':
> +        case 'text':
> +        case 'textarea':
> +        case 'select-one':
> +        case 'select-multiple':
> +          element.target = this;
> +          element.prev_onchange = element.onchange || Prototype.emptyFunction;
> +          element.onchange = function() {
> +            this.prev_onchange();
> +            this.target.onElementEvent();
> +          }
> +          break;
> +      }
> +    }
> +  }
> +}
> +
> +Form.Element.EventObserver = Class.create();
> +Form.Element.EventObserver.prototype = (new Abstract.EventObserver()).extend({
> +  getValue: function() {
> +    return Form.Element.getValue(this.element);
> +  }
> +});
> +
> +Form.EventObserver = Class.create();
> +Form.EventObserver.prototype = (new Abstract.EventObserver()).extend({
> +  getValue: function() {
> +    return Form.serialize(this.element);
> +  }
> +});
> +
> +
> +if (!window.Event) {
> +  var Event = new Object();
> +}
> +
> +Object.extend(Event, {
> +  KEY_BACKSPACE: 8,
> +  KEY_TAB:       9,
> +  KEY_RETURN:   13,
> +  KEY_ESC:      27,
> +  KEY_LEFT:     37,
> +  KEY_UP:       38,
> +  KEY_RIGHT:    39,
> +  KEY_DOWN:     40,
> +  KEY_DELETE:   46,
> +
> +  element: function(event) {
> +    return event.target || event.srcElement;
> +  },
> +
> +  isLeftClick: function(event) {
> +    return (((event.which) && (event.which == 1)) ||
> +            ((event.button) && (event.button == 1)));
> +  },
> +
> +  pointerX: function(event) {
> +    return event.pageX || (event.clientX +
> +      (document.documentElement.scrollLeft || document.body.scrollLeft));
> +  },
> +
> +  pointerY: function(event) {
> +    return event.pageY || (event.clientY +
> +      (document.documentElement.scrollTop || document.body.scrollTop));
> +  },
> +
> +  stop: function(event) {
> +    if (event.preventDefault) {
> +      event.preventDefault();
> +      event.stopPropagation();
> +    } else {
> +      event.returnValue = false;
> +    }
> +  },
> +
> +  // find the first node with the given tagName, starting from the
> +  // node the event was triggered on; traverses the DOM upwards
> +  findElement: function(event, tagName) {
> +    var element = Event.element(event);
> +    while (element.parentNode && (!element.tagName ||
> +        (element.tagName.toUpperCase() != tagName.toUpperCase())))
> +      element = element.parentNode;
> +    return element;
> +  },
> +
> +  observers: false,
> +
> +  _observeAndCache: function(element, name, observer, useCapture) {
> +    if (!this.observers) this.observers = [];
> +    if (element.addEventListener) {
> +      this.observers.push([element, name, observer, useCapture]);
> +      element.addEventListener(name, observer, useCapture);
> +    } else if (element.attachEvent) {
> +      this.observers.push([element, name, observer, useCapture]);
> +      element.attachEvent('on' + name, observer);
> +    }
> +  },
> +
> +  unloadCache: function() {
> +    if (!Event.observers) return;
> +    for (var i = 0; i < Event.observers.length; i++) {
> +      Event.stopObserving.apply(this, Event.observers[i]);
> +      Event.observers[i][0] = null;
> +    }
> +    Event.observers = false;
> +  },
> +
> +  observe: function(element, name, observer, useCapture) {
> +    var element = $(element);
> +    useCapture = useCapture || false;
> +
> +    if (name == 'keypress' &&
> +        ((navigator.appVersion.indexOf('AppleWebKit') > 0)
> +        || element.attachEvent))
> +      name = 'keydown';
> +
> +    this._observeAndCache(element, name, observer, useCapture);
> +  },
> +
> +  stopObserving: function(element, name, observer, useCapture) {
> +    var element = $(element);
> +    useCapture = useCapture || false;
> +
> +    if (name == 'keypress' &&
> +        ((navigator.appVersion.indexOf('AppleWebKit') > 0)
> +        || element.detachEvent))
> +      name = 'keydown';
> +
> +    if (element.removeEventListener) {
> +      element.removeEventListener(name, observer, useCapture);
> +    } else if (element.detachEvent) {
> +      element.detachEvent('on' + name, observer);
> +    }
> +  }
> +});
> +
> +/* prevent memory leaks in IE */
> +Event.observe(window, 'unload', Event.unloadCache, false);
> +
> +var Position = {
> +
> +  // set to true if needed, warning: firefox performance problems
> +  // NOT neeeded for page scrolling, only if draggable contained in
> +  // scrollable elements
> +  includeScrollOffsets: false,
> +
> +  // must be called before calling withinIncludingScrolloffset, every time the
> +  // page is scrolled
> +  prepare: function() {
> +    this.deltaX =  window.pageXOffset
> +                || document.documentElement.scrollLeft
> +                || document.body.scrollLeft
> +                || 0;
> +    this.deltaY =  window.pageYOffset
> +                || document.documentElement.scrollTop
> +                || document.body.scrollTop
> +                || 0;
> +  },
> +
> +  realOffset: function(element) {
> +    var valueT = 0, valueL = 0;
> +    do {
> +      valueT += element.scrollTop  || 0;
> +      valueL += element.scrollLeft || 0;
> +      element = element.parentNode;
> +    } while (element);
> +    return [valueL, valueT];
> +  },
> +
> +  cumulativeOffset: function(element) {
> +    var valueT = 0, valueL = 0;
> +    do {
> +      valueT += element.offsetTop  || 0;
> +      valueL += element.offsetLeft || 0;
> +      element = element.offsetParent;
> +    } while (element);
> +    return [valueL, valueT];
> +  },
> +
> +  // caches x/y coordinate pair to use with overlap
> +  within: function(element, x, y) {
> +    if (this.includeScrollOffsets)
> +      return this.withinIncludingScrolloffsets(element, x, y);
> +    this.xcomp = x;
> +    this.ycomp = y;
> +    this.offset = this.cumulativeOffset(element);
> +
> +    return (y >= this.offset[1] &&
> +            y <  this.offset[1] + element.offsetHeight &&
> +            x >= this.offset[0] &&
> +            x <  this.offset[0] + element.offsetWidth);
> +  },
> +
> +  withinIncludingScrolloffsets: function(element, x, y) {
> +    var offsetcache = this.realOffset(element);
> +
> +    this.xcomp = x + offsetcache[0] - this.deltaX;
> +    this.ycomp = y + offsetcache[1] - this.deltaY;
> +    this.offset = this.cumulativeOffset(element);
> +
> +    return (this.ycomp >= this.offset[1] &&
> +            this.ycomp <  this.offset[1] + element.offsetHeight &&
> +            this.xcomp >= this.offset[0] &&
> +            this.xcomp <  this.offset[0] + element.offsetWidth);
> +  },
> +
> +  // within must be called directly before
> +  overlap: function(mode, element) {
> +    if (!mode) return 0;
> +    if (mode == 'vertical')
> +      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
> +        element.offsetHeight;
> +    if (mode == 'horizontal')
> +      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
> +        element.offsetWidth;
> +  },
> +
> +  clone: function(source, target) {
> +    source = $(source);
> +    target = $(target);
> +    target.style.position = 'absolute';
> +    var offsets = this.cumulativeOffset(source);
> +    target.style.top    = offsets[1] + 'px';
> +    target.style.left   = offsets[0] + 'px';
> +    target.style.width  = source.offsetWidth + 'px';
> +    target.style.height = source.offsetHeight + 'px';
> +  }
> +}
> +// -->
> +</script>
>
> Added: xwiki/trunk/src/main/web/skins/default/rico/rico.js
> ===================================================================
> --- xwiki/trunk/src/main/web/skins/default/rico/rico.js 2006-03-28 10:10:11 UTC (rev 996)
> +++ xwiki/trunk/src/main/web/skins/default/rico/rico.js 2006-03-28 10:10:39 UTC (rev 997)
> @@ -0,0 +1,2666 @@
> +/**
> +  *
> +  *  Copyright 2005 Sabre Airline Solutions
> +  *
> +  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
> +  *  file except in compliance with the License. You may obtain a copy of the License at
> +  *
> +  *         http://www.apache.org/licenses/LICENSE-2.0
> +  *
> +  *  Unless required by applicable law or agreed to in writing, software distributed under the
> +  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
> +  *  either express or implied. See the License for the specific language governing permissions
> +  *  and limitations under the License.
> +  **/
> +
> +
> +//-------------------- rico.js
> +var Rico = {
> +  Version: '1.1-beta2'
> +}
> +
> +Rico.ArrayExtensions = new Array();
> +
> +if (Object.prototype.extend) {
> +   // in prototype.js...
> +   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
> +}
> +
> +if (Array.prototype.push) {
> +   // in prototype.js...
> +   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
> +}
> +
> +if (!Array.prototype.remove) {
> +   Array.prototype.remove = function(dx) {
> +      if( isNaN(dx) || dx > this.length )
> +         return false;
> +      for( var i=0,n=0; i<this.length; i++ )
> +         if( i != dx )
> +            this[n++]=this[i];
> +      this.length-=1;
> +   };
> +  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
> +}
> +
> +if (!Array.prototype.removeItem) {
> +   Array.prototype.removeItem = function(item) {
> +      for ( var i = 0 ; i < this.length ; i++ )
> +         if ( this[i] == item ) {
> +            this.remove(i);
> +            break;
> +         }
> +   };
> +  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
> +}
> +
> +if (!Array.prototype.indices) {
> +   Array.prototype.indices = function() {
> +      var indexArray = new Array();
> +      for ( index in this ) {
> +         var ignoreThis = false;
> +         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
> +            if ( this[index] == Rico.ArrayExtensions[i] ) {
> +               ignoreThis = true;
> +               break;
> +            }
> +         }
> +         if ( !ignoreThis )
> +            indexArray[ indexArray.length ] = index;
> +      }
> +      return indexArray;
> +   }
> +  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
> +}
> +
> +// Create the loadXML method and xml getter for Mozilla
> +if ( window.DOMParser &&
> +         window.XMLSerializer &&
> +         window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
> +
> +   if (!Document.prototype.loadXML) {
> +      Document.prototype.loadXML = function (s) {
> +         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
> +         while (this.hasChildNodes())
> +            this.removeChild(this.lastChild);
> +
> +         for (var i = 0; i < doc2.childNodes.length; i++) {
> +            this.appendChild(this.importNode(doc2.childNodes[i], true));
> +         }
> +      };
> +       }
> +
> +       Document.prototype.__defineGetter__( "xml",
> +          function () {
> +                  return (new XMLSerializer()).serializeToString(this);
> +          }
> +        );
> +}
> +
> +document.getElementsByTagAndClassName = function(tagName, className) {
> +  if ( tagName == null )
> +     tagName = '*';
> +
> +  var children = document.getElementsByTagName(tagName) || document.all;
> +  var elements = new Array();
> +
> +  if ( className == null )
> +    return children;
> +
> +  for (var i = 0; i < children.length; i++) {
> +    var child = children[i];
> +    var classNames = child.className.split(' ');
> +    for (var j = 0; j < classNames.length; j++) {
> +      if (classNames[j] == className) {
> +        elements.push(child);
> +        break;
> +      }
> +    }
> +  }
> +
> +  return elements;
> +}
> +
> +
> +//-------------------- ricoAccordion.js
> +
> +Rico.Accordion = Class.create();
> +
> +Rico.Accordion.prototype = {
> +
> +   initialize: function(container, options) {
> +      this.container            = $(container);
> +      this.lastExpandedTab      = null;
> +      this.accordionTabs        = new Array();
> +      this.setOptions(options);
> +      this._attachBehaviors();
> +
> +      this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
> +
> +      // set the initial visual state...
> +      for ( var i=1 ; i < this.accordionTabs.length ; i++ )
> +      {
> +         this.accordionTabs[i].collapse();
> +         this.accordionTabs[i].content.style.display = 'none';
> +      }
> +      this.lastExpandedTab = this.accordionTabs[0];
> +      this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
> +      this.lastExpandedTab.showExpanded();
> +      this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
> +   },
> +
> +   setOptions: function(options) {
> +      this.options = {
> +         expandedBg          : '#63699c',
> +         hoverBg             : '#63699c',
> +         collapsedBg         : '#6b79a5',
> +         expandedTextColor   : '#ffffff',
> +         expandedFontWeight  : 'bold',
> +         hoverTextColor      : '#ffffff',
> +         collapsedTextColor  : '#ced7ef',
> +         collapsedFontWeight : 'normal',
> +         hoverTextColor      : '#ffffff',
> +         borderColor         : '#1f669b',
> +         panelHeight         : 200,
> +         onHideTab           : null,
> +         onShowTab           : null
> +      }.extend(options || {});
> +   },
> +
> +   showTabByIndex: function( anIndex, animate ) {
> +      var doAnimate = arguments.length == 1 ? true : animate;
> +      this.showTab( this.accordionTabs[anIndex], doAnimate );
> +   },
> +
> +   showTab: function( accordionTab, animate ) {
> +
> +      var doAnimate = arguments.length == 1 ? true : animate;
> +
> +      if ( this.options.onHideTab )
> +         this.options.onHideTab(this.lastExpandedTab);
> +
> +      this.lastExpandedTab.showCollapsed();
> +      var accordion = this;
> +      var lastExpandedTab = this.lastExpandedTab;
> +
> +      this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px';
> +      accordionTab.content.style.display = '';
> +
> +      accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
> +
> +      if ( doAnimate ) {
> +         new Effect.AccordionSize( this.lastExpandedTab.content,
> +                                   accordionTab.content,
> +                                   1,
> +                                   this.options.panelHeight,
> +                                   100, 10,
> +                                   { complete: function() {accordion.showTabDone(lastExpandedTab)} } );
> +         this.lastExpandedTab = accordionTab;
> +      }
> +      else {
> +         this.lastExpandedTab.content.style.height = "1px";
> +         accordionTab.content.style.height = this.options.panelHeight + "px";
> +         this.lastExpandedTab = accordionTab;
> +         this.showTabDone(lastExpandedTab);
> +      }
> +   },
> +
> +   showTabDone: function(collapsedTab) {
> +      collapsedTab.content.style.display = 'none';
> +      this.lastExpandedTab.showExpanded();
> +      if ( this.options.onShowTab )
> +         this.options.onShowTab(this.lastExpandedTab);
> +   },
> +
> +   _attachBehaviors: function() {
> +      var panels = this._getDirectChildrenByTag(this.container, 'DIV');
> +      for ( var i = 0 ; i < panels.length ; i++ ) {
> +
> +         var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV');
> +         if ( tabChildren.length != 2 )
> +            continue; // unexpected
> +
> +         var tabTitleBar   = tabChildren[0];
> +         var tabContentBox = tabChildren[1];
> +         this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) );
> +      }
> +   },
> +
> +   _getDirectChildrenByTag: function(e, tagName) {
> +      var kids = new Array();
> +      var allKids = e.childNodes;
> +      for( var i = 0 ; i < allKids.length ; i++ )
> +         if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName )
> +            kids.push(allKids[i]);
> +      return kids;
> +   }
> +
> +};
> +
> +Rico.Accordion.Tab = Class.create();
> +
> +Rico.Accordion.Tab.prototype = {
> +
> +   initialize: function(accordion, titleBar, content) {
> +      this.accordion = accordion;
> +      this.titleBar  = titleBar;
> +      this.content   = content;
> +      this._attachBehaviors();
> +   },
> +
> +   collapse: function() {
> +      this.showCollapsed();
> +      this.content.style.height = "1px";
> +   },
> +
> +   showCollapsed: function() {
> +      this.expanded = false;
> +      this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
> +      this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
> +      this.titleBar.style.fontWeight      = this.accordion.options.collapsedFontWeight;
> +      this.content.style.overflow = "hidden";
> +   },
> +
> +   showExpanded: function() {
> +      this.expanded = true;
> +      this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
> +      this.titleBar.style.color           = this.accordion.options.expandedTextColor;
> +      this.content.style.overflow         = "visible";
> +   },
> +
> +   titleBarClicked: function(e) {
> +      if ( this.accordion.lastExpandedTab == this )
> +         return;
> +      this.accordion.showTab(this);
> +   },
> +
> +   hover: function(e) {
> +               this.titleBar.style.backgroundColor = this.accordion.options.hoverBg;
> +               this.titleBar.style.color           = this.accordion.options.hoverTextColor;
> +   },
> +
> +   unhover: function(e) {
> +      if ( this.expanded ) {
> +         this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
> +         this.titleBar.style.color           = this.accordion.options.expandedTextColor;
> +      }
> +      else {
> +         this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
> +         this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
> +      }
> +   },
> +
> +   _attachBehaviors: function() {
> +      this.content.style.border = "1px solid " + this.accordion.options.borderColor;
> +      this.content.style.borderTopWidth    = "0px";
> +      this.content.style.borderBottomWidth = "0px";
> +      this.content.style.margin            = "0px";
> +
> +      this.titleBar.onclick     = this.titleBarClicked.bindAsEventListener(this);
> +      this.titleBar.onmouseover = this.hover.bindAsEventListener(this);
> +      this.titleBar.onmouseout  = this.unhover.bindAsEventListener(this);
> +   }
> +
> +};
> +
> +
> +//-------------------- ricoAjaxEngine.js
> +
> +Rico.AjaxEngine = Class.create();
> +
> +Rico.AjaxEngine.prototype = {
> +
> +   initialize: function() {
> +      this.ajaxElements = new Array();
> +      this.ajaxObjects  = new Array();
> +      this.requestURLS  = new Array();
> +   },
> +
> +   registerAjaxElement: function( anId, anElement ) {
> +      if ( arguments.length == 1 )
> +         anElement = $(anId);
> +      this.ajaxElements[anId] = anElement;
> +   },
> +
> +   registerAjaxObject: function( anId, anObject ) {
> +      this.ajaxObjects[anId] = anObject;
> +   },
> +
> +   registerRequest: function (requestLogicalName, requestURL) {
> +      this.requestURLS[requestLogicalName] = requestURL;
> +   },
> +
> +   sendRequest: function(requestName) {
> +      var requestURL = this.requestURLS[requestName];
> +      if ( requestURL == null )
> +         return;
> +
> +      var queryString = "";
> +      if ( arguments.length > 1 )
> +         queryString = this._createQueryString(arguments, 1);
> +
> +      new Ajax.Request(requestURL, this._requestOptions(queryString));
> +   },
> +
> +   sendRequestWithData: function(requestName, xmlDocument) {
> +      var requestURL = this.requestURLS[requestName];
> +      if ( requestURL == null )
> +         return;
> +
> +      var queryString = "";
> +      if ( arguments.length > 2 )
> +         queryString = this._createQueryString(arguments, 2);
> +
> +      new Ajax.Request(requestURL + "?" + queryString, this._requestOptions(null,xmlDocument));
> +   },
> +
> +   sendRequestAndUpdate: function(requestName,container,options) {
> +      var requestURL = this.requestURLS[requestName];
> +      if ( requestURL == null )
> +         return;
> +
><