You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/06/08 23:55:43 UTC

svn commit: r664564 [1/5] - in /tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1: builder.js controls.js dragdrop.js effects.js prototype.js scriptaculous.js slider.js sound.js unittest.js

Author: hlship
Date: Sun Jun  8 14:55:43 2008
New Revision: 664564

URL: http://svn.apache.org/viewvc?rev=664564&view=rev
Log:
TAPESTRY-2441: Upgrade to Scriptaculous 1.8.1 (w/o code reformatting, this time!)

Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/builder.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/controls.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/dragdrop.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/effects.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/prototype.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/scriptaculous.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/slider.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/sound.js
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/unittest.js

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/builder.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/builder.js?rev=664564&r1=664563&r2=664564&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/builder.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/builder.js Sun Jun  8 14:55:43 2008
@@ -6,157 +6,131 @@
 // For details, see the script.aculo.us web site: http://script.aculo.us/
 
 var Builder = {
-    NODEMAP: {
-        AREA: 'map',
-        CAPTION: 'table',
-        COL: 'table',
-        COLGROUP: 'table',
-        LEGEND: 'fieldset',
-        OPTGROUP: 'select',
-        OPTION: 'select',
-        PARAM: 'object',
-        TBODY: 'table',
-        TD: 'table',
-        TFOOT: 'table',
-        TH: 'table',
-        THEAD: 'table',
-        TR: 'table'
-    },
-    // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
-    //       due to a Firefox bug
-    node: function(elementName)
-    {
-        elementName = elementName.toUpperCase();
+  NODEMAP: {
+    AREA: 'map',
+    CAPTION: 'table',
+    COL: 'table',
+    COLGROUP: 'table',
+    LEGEND: 'fieldset',
+    OPTGROUP: 'select',
+    OPTION: 'select',
+    PARAM: 'object',
+    TBODY: 'table',
+    TD: 'table',
+    TFOOT: 'table',
+    TH: 'table',
+    THEAD: 'table',
+    TR: 'table'
+  },
+  // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+  //       due to a Firefox bug
+  node: function(elementName) {
+    elementName = elementName.toUpperCase();
     
     // try innerHTML approach
-        var parentTag = this.NODEMAP[elementName] || 'div';
-        var parentElement = document.createElement(parentTag);
-        try
-        { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
-            parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
-        }
-        catch(e)
-        {
-        }
-        var element = parentElement.firstChild || null;
+    var parentTag = this.NODEMAP[elementName] || 'div';
+    var parentElement = document.createElement(parentTag);
+    try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+      parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
+    } catch(e) {}
+    var element = parentElement.firstChild || null;
       
     // see if browser added wrapping tags
-        if (element && (element.tagName.toUpperCase() != elementName))
-            element = element.getElementsByTagName(elementName)[0];
+    if(element && (element.tagName.toUpperCase() != elementName))
+      element = element.getElementsByTagName(elementName)[0];
     
     // fallback to createElement approach
-        if (!element) element = document.createElement(elementName);
+    if(!element) element = document.createElement(elementName);
     
     // abort if nothing could be created
-        if (!element) return;
+    if(!element) return;
 
     // attributes (or text)
-        if (arguments[1])
-            if (this._isStringOrNumber(arguments[1]) ||
-                (arguments[1] instanceof Array) ||
-                arguments[1].tagName)
-            {
-                this._children(element, arguments[1]);
-            }
-            else
-            {
-                var attrs = this._attributes(arguments[1]);
-                if (attrs.length)
-                {
-                    try
-                    { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
-                        parentElement.innerHTML = "<" + elementName + " " +
-                                                  attrs + "></" + elementName + ">";
-                    }
-                    catch(e)
-                    {
-                    }
-                    element = parentElement.firstChild || null;
+    if(arguments[1])
+      if(this._isStringOrNumber(arguments[1]) ||
+        (arguments[1] instanceof Array) ||
+        arguments[1].tagName) {
+          this._children(element, arguments[1]);
+        } else {
+          var attrs = this._attributes(arguments[1]);
+          if(attrs.length) {
+            try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+              parentElement.innerHTML = "<" +elementName + " " +
+                attrs + "></" + elementName + ">";
+            } catch(e) {}
+            element = parentElement.firstChild || null;
             // workaround firefox 1.0.X bug
-                    if (!element)
-                    {
-                        element = document.createElement(elementName);
-                        for (attr in arguments[1])
-                            element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
-                    }
-                    if (element.tagName.toUpperCase() != elementName)
-                        element = parentElement.getElementsByTagName(elementName)[0];
-                }
+            if(!element) {
+              element = document.createElement(elementName);
+              for(attr in arguments[1]) 
+                element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
             }
+            if(element.tagName.toUpperCase() != elementName)
+              element = parentElement.getElementsByTagName(elementName)[0];
+          }
+        } 
 
     // text, or array of children
-        if (arguments[2])
-            this._children(element, arguments[2]);
+    if(arguments[2])
+      this._children(element, arguments[2]);
 
-        return element;
-    },
-    _text: function(text)
-    {
-        return document.createTextNode(text);
-    },
-
-    ATTR_MAP: {
-        'className': 'class',
-        'htmlFor': 'for'
-    },
-
-    _attributes: function(attributes)
-    {
-        var attrs = [];
-        for (attribute in attributes)
-            attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
-                       '="' + attributes[attribute].toString().escapeHTML().gsub(/"/, '&quot;') + '"');
-        return attrs.join(" ");
-    },
-    _children: function(element, children)
-    {
-        if (children.tagName)
-        {
-            element.appendChild(children);
-            return;
-        }
-        if (typeof children == 'object')
-        { // array can hold nodes and text
-            children.flatten().each(function(e)
-            {
-                if (typeof e == 'object')
-                    element.appendChild(e)
-                else
-                    if (Builder._isStringOrNumber(e))
-                        element.appendChild(Builder._text(e));
-            });
-        }
-        else
-            if (Builder._isStringOrNumber(children))
-                element.appendChild(Builder._text(children));
-    },
-    _isStringOrNumber: function(param)
-    {
-        return(typeof param == 'string' || typeof param == 'number');
-    },
-    build: function(html)
-    {
-        var element = this.node('div');
-        $(element).update(html.strip());
-        return element.down();
-    },
-    dump: function(scope)
-    {
-        if (typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
-
-        var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
-                    "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
-                    "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX " +
-                    "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P " +
-                    "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD " +
-                    "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
-
-        tags.each(function(tag)
-        {
-            scope[tag] = function()
-            {
-                return Builder.node.apply(Builder, [tag].concat($A(arguments)));
-            }
-        });
+     return element;
+  },
+  _text: function(text) {
+     return document.createTextNode(text);
+  },
+
+  ATTR_MAP: {
+    'className': 'class',
+    'htmlFor': 'for'
+  },
+
+  _attributes: function(attributes) {
+    var attrs = [];
+    for(attribute in attributes)
+      attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
+          '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'&quot;') + '"');
+    return attrs.join(" ");
+  },
+  _children: function(element, children) {
+    if(children.tagName) {
+      element.appendChild(children);
+      return;
     }
+    if(typeof children=='object') { // array can hold nodes and text
+      children.flatten().each( function(e) {
+        if(typeof e=='object')
+          element.appendChild(e)
+        else
+          if(Builder._isStringOrNumber(e))
+            element.appendChild(Builder._text(e));
+      });
+    } else
+      if(Builder._isStringOrNumber(children))
+        element.appendChild(Builder._text(children));
+  },
+  _isStringOrNumber: function(param) {
+    return(typeof param=='string' || typeof param=='number');
+  },
+  build: function(html) {
+    var element = this.node('div');
+    $(element).update(html.strip());
+    return element.down();
+  },
+  dump: function(scope) { 
+    if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope 
+  
+    var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
+      "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
+      "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
+      "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
+      "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
+      "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
+  
+    tags.each( function(tag){ 
+      scope[tag] = function() { 
+        return Builder.node.apply(Builder, [tag].concat($A(arguments)));  
+      } 
+    });
+  }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/controls.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/controls.js?rev=664564&r1=664563&r2=664564&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/controls.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/controls.js Sun Jun  8 14:55:43 2008
@@ -36,395 +36,339 @@
 // useful when one of the tokens is \n (a newline), as it 
 // allows smart autocompletion after linebreaks.
 
-if (typeof Effect == 'undefined')
-    throw("controls.js requires including script.aculo.us' effects.js library");
+if(typeof Effect == 'undefined')
+  throw("controls.js requires including script.aculo.us' effects.js library");
 
 var Autocompleter = { }
 Autocompleter.Base = Class.create({
-    baseInitialize: function(element, update, options)
-    {
-        element = $(element)
-        this.element = element;
-        this.update = $(update);
-        this.hasFocus = false;
-        this.changed = false;
-        this.active = false;
-        this.index = 0;
-        this.entryCount = 0;
-        this.oldElementValue = this.element.value;
+  baseInitialize: function(element, update, options) {
+    element          = $(element)
+    this.element     = element; 
+    this.update      = $(update);  
+    this.hasFocus    = false; 
+    this.changed     = false; 
+    this.active      = false; 
+    this.index       = 0;     
+    this.entryCount  = 0;
+    this.oldElementValue = this.element.value;
+
+    if(this.setOptions)
+      this.setOptions(options);
+    else
+      this.options = options || { };
+
+    this.options.paramName    = this.options.paramName || this.element.name;
+    this.options.tokens       = this.options.tokens || [];
+    this.options.frequency    = this.options.frequency || 0.4;
+    this.options.minChars     = this.options.minChars || 1;
+    this.options.onShow       = this.options.onShow || 
+      function(element, update){ 
+        if(!update.style.position || update.style.position=='absolute') {
+          update.style.position = 'absolute';
+          Position.clone(element, update, {
+            setHeight: false, 
+            offsetTop: element.offsetHeight
+          });
+        }
+        Effect.Appear(update,{duration:0.15});
+      };
+    this.options.onHide = this.options.onHide || 
+      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
 
-        if (this.setOptions)
-            this.setOptions(options);
-        else
-            this.options = options || { };
-
-        this.options.paramName = this.options.paramName || this.element.name;
-        this.options.tokens = this.options.tokens || [];
-        this.options.frequency = this.options.frequency || 0.4;
-        this.options.minChars = this.options.minChars || 1;
-        this.options.onShow = this.options.onShow ||
-                              function(element, update)
-                              {
-                                  if (!update.style.position || update.style.position == 'absolute')
-                                  {
-                                      update.style.position = 'absolute';
-                                      Position.clone(element, update, {
-                                          setHeight: false,
-                                          offsetTop: element.offsetHeight
-                                      });
-                                  }
-                                  Effect.Appear(update, {duration:0.15});
-                              };
-        this.options.onHide = this.options.onHide ||
-                              function(element, update)
-                              {
-                                  new Effect.Fade(update, {duration:0.15})
-                              };
-
-        if (typeof(this.options.tokens) == 'string')
-            this.options.tokens = new Array(this.options.tokens);
+    if(typeof(this.options.tokens) == 'string') 
+      this.options.tokens = new Array(this.options.tokens);
     // Force carriage returns as token delimiters anyway
-        if (!this.options.tokens.include('\n'))
-            this.options.tokens.push('\n');
-
-        this.observer = null;
-
-        this.element.setAttribute('autocomplete', 'off');
-
-        Element.hide(this.update);
-
-        Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
-        Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
-    },
-
-    show: function()
-    {
-        if (Element.getStyle(this.update, 'display') == 'none') this.options.onShow(this.element, this.update);
-        if (!this.iefix &&
-            (Prototype.Browser.IE) &&
-            (Element.getStyle(this.update, 'position') == 'absolute'))
-        {
-            new Insertion.After(this.update,
-                    '<iframe id="' + this.update.id + '_iefix" ' +
-                    'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
-                    'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
-            this.iefix = $(this.update.id + '_iefix');
-        }
-        if (this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
-    },
-
-    fixIEOverlapping: function()
-    {
-        Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
-        this.iefix.style.zIndex = 1;
-        this.update.style.zIndex = 2;
-        Element.show(this.iefix);
-    },
-
-    hide: function()
-    {
-        this.stopIndicator();
-        if (Element.getStyle(this.update, 'display') != 'none') this.options.onHide(this.element, this.update);
-        if (this.iefix) Element.hide(this.iefix);
-    },
-
-    startIndicator: function()
-    {
-        if (this.options.indicator) Element.show(this.options.indicator);
-    },
-
-    stopIndicator: function()
-    {
-        if (this.options.indicator) Element.hide(this.options.indicator);
-    },
-
-    onKeyPress: function(event)
-    {
-        if (this.active)
-            switch (event.keyCode)
-                    {
-                case Event.KEY_TAB:
-                case Event.KEY_RETURN:
-                    this.selectEntry();
-                    Event.stop(event);
-                case Event.KEY_ESC:
-                    this.hide();
-                    this.active = false;
-                    Event.stop(event);
-                    return;
-                case Event.KEY_LEFT:
-                case Event.KEY_RIGHT:
-                    return;
-                case Event.KEY_UP:
-                    this.markPrevious();
-                    this.render();
-                    Event.stop(event);
-                    return;
-                case Event.KEY_DOWN:
-                    this.markNext();
-                    this.render();
-                    Event.stop(event);
-                    return;
-            }
-        else
-            if (event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN ||
-                (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
-
-        this.changed = true;
-        this.hasFocus = true;
-
-        if (this.observer) clearTimeout(this.observer);
-        this.observer =
-        setTimeout(this.onObserverEvent.bind(this), this.options.frequency * 1000);
-    },
+    if (!this.options.tokens.include('\n'))
+      this.options.tokens.push('\n');
 
-    activate: function()
-    {
-        this.changed = false;
-        this.hasFocus = true;
-        this.getUpdatedChoices();
-    },
-
-    onHover: function(event)
+    this.observer = null;
+    
+    this.element.setAttribute('autocomplete','off');
+
+    Element.hide(this.update);
+
+    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
+    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
+  },
+
+  show: function() {
+    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
+    if(!this.iefix && 
+      (Prototype.Browser.IE) &&
+      (Element.getStyle(this.update, 'position')=='absolute')) {
+      new Insertion.After(this.update, 
+       '<iframe id="' + this.update.id + '_iefix" '+
+       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
+       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+      this.iefix = $(this.update.id+'_iefix');
+    }
+    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
+  },
+  
+  fixIEOverlapping: function() {
+    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
+    this.iefix.style.zIndex = 1;
+    this.update.style.zIndex = 2;
+    Element.show(this.iefix);
+  },
+
+  hide: function() {
+    this.stopIndicator();
+    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
+    if(this.iefix) Element.hide(this.iefix);
+  },
+
+  startIndicator: function() {
+    if(this.options.indicator) Element.show(this.options.indicator);
+  },
+
+  stopIndicator: function() {
+    if(this.options.indicator) Element.hide(this.options.indicator);
+  },
+
+  onKeyPress: function(event) {
+    if(this.active)
+      switch(event.keyCode) {
+       case Event.KEY_TAB:
+       case Event.KEY_RETURN:
+         this.selectEntry();
+         Event.stop(event);
+       case Event.KEY_ESC:
+         this.hide();
+         this.active = false;
+         Event.stop(event);
+         return;
+       case Event.KEY_LEFT:
+       case Event.KEY_RIGHT:
+         return;
+       case Event.KEY_UP:
+         this.markPrevious();
+         this.render();
+         Event.stop(event);
+         return;
+       case Event.KEY_DOWN:
+         this.markNext();
+         this.render();
+         Event.stop(event);
+         return;
+      }
+     else 
+       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
+         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
+
+    this.changed = true;
+    this.hasFocus = true;
+
+    if(this.observer) clearTimeout(this.observer);
+      this.observer = 
+        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
+  },
+
+  activate: function() {
+    this.changed = false;
+    this.hasFocus = true;
+    this.getUpdatedChoices();
+  },
+
+  onHover: function(event) {
+    var element = Event.findElement(event, 'LI');
+    if(this.index != element.autocompleteIndex) 
     {
-        var element = Event.findElement(event, 'LI');
-        if (this.index != element.autocompleteIndex)
-        {
-            this.index = element.autocompleteIndex;
-            this.render();
+        this.index = element.autocompleteIndex;
+        this.render();
+    }
+    Event.stop(event);
+  },
+  
+  onClick: function(event) {
+    var element = Event.findElement(event, 'LI');
+    this.index = element.autocompleteIndex;
+    this.selectEntry();
+    this.hide();
+  },
+  
+  onBlur: function(event) {
+    // needed to make click events working
+    setTimeout(this.hide.bind(this), 250);
+    this.hasFocus = false;
+    this.active = false;     
+  }, 
+  
+  render: function() {
+    if(this.entryCount > 0) {
+      for (var i = 0; i < this.entryCount; i++)
+        this.index==i ? 
+          Element.addClassName(this.getEntry(i),"selected") : 
+          Element.removeClassName(this.getEntry(i),"selected");
+      if(this.hasFocus) { 
+        this.show();
+        this.active = true;
+      }
+    } else {
+      this.active = false;
+      this.hide();
+    }
+  },
+  
+  markPrevious: function() {
+    if(this.index > 0) this.index--
+      else this.index = this.entryCount-1;
+    this.getEntry(this.index).scrollIntoView(true);
+  },
+  
+  markNext: function() {
+    if(this.index < this.entryCount-1) this.index++
+      else this.index = 0;
+    this.getEntry(this.index).scrollIntoView(false);
+  },
+  
+  getEntry: function(index) {
+    return this.update.firstChild.childNodes[index];
+  },
+  
+  getCurrentEntry: function() {
+    return this.getEntry(this.index);
+  },
+  
+  selectEntry: function() {
+    this.active = false;
+    this.updateElement(this.getCurrentEntry());
+  },
+
+  updateElement: function(selectedElement) {
+    if (this.options.updateElement) {
+      this.options.updateElement(selectedElement);
+      return;
+    }
+    var value = '';
+    if (this.options.select) {
+      var nodes = $(selectedElement).select('.' + this.options.select) || [];
+      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
+    } else
+      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
+    
+    var bounds = this.getTokenBounds();
+    if (bounds[0] != -1) {
+      var newValue = this.element.value.substr(0, bounds[0]);
+      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
+      if (whitespace)
+        newValue += whitespace[0];
+      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
+    } else {
+      this.element.value = value;
+    }
+    this.oldElementValue = this.element.value;
+    this.element.focus();
+    
+    if (this.options.afterUpdateElement)
+      this.options.afterUpdateElement(this.element, selectedElement);
+  },
+
+  updateChoices: function(choices) {
+    if(!this.changed && this.hasFocus) {
+      this.update.innerHTML = choices;
+      Element.cleanWhitespace(this.update);
+      Element.cleanWhitespace(this.update.down());
+
+      if(this.update.firstChild && this.update.down().childNodes) {
+        this.entryCount = 
+          this.update.down().childNodes.length;
+        for (var i = 0; i < this.entryCount; i++) {
+          var entry = this.getEntry(i);
+          entry.autocompleteIndex = i;
+          this.addObservers(entry);
         }
-        Event.stop(event);
-    },
+      } else { 
+        this.entryCount = 0;
+      }
 
-    onClick: function(event)
-    {
-        var element = Event.findElement(event, 'LI');
-        this.index = element.autocompleteIndex;
+      this.stopIndicator();
+      this.index = 0;
+      
+      if(this.entryCount==1 && this.options.autoSelect) {
         this.selectEntry();
         this.hide();
-    },
-
-    onBlur: function(event)
-    {
-        // needed to make click events working
-        setTimeout(this.hide.bind(this), 250);
-        this.hasFocus = false;
-        this.active = false;
-    },
-
-    render: function()
-    {
-        if (this.entryCount > 0)
-        {
-            for (var i = 0; i < this.entryCount; i++)
-                this.index == i ?
-                Element.addClassName(this.getEntry(i), "selected") :
-                Element.removeClassName(this.getEntry(i), "selected");
-            if (this.hasFocus)
-            {
-                this.show();
-                this.active = true;
-            }
-        }
-        else
-        {
-            this.active = false;
-            this.hide();
-        }
-    },
-
-    markPrevious: function()
-    {
-        if (this.index > 0) this.index--
-        else this.index = this.entryCount - 1;
-        this.getEntry(this.index).scrollIntoView(true);
-    },
-
-    markNext: function()
-    {
-        if (this.index < this.entryCount - 1) this.index++
-        else this.index = 0;
-        this.getEntry(this.index).scrollIntoView(false);
-    },
-
-    getEntry: function(index)
-    {
-        return this.update.firstChild.childNodes[index];
-    },
-
-    getCurrentEntry: function()
-    {
-        return this.getEntry(this.index);
-    },
-
-    selectEntry: function()
-    {
-        this.active = false;
-        this.updateElement(this.getCurrentEntry());
-    },
-
-    updateElement: function(selectedElement)
-    {
-        if (this.options.updateElement)
-        {
-            this.options.updateElement(selectedElement);
-            return;
-        }
-        var value = '';
-        if (this.options.select)
-        {
-            var nodes = $(selectedElement).select('.' + this.options.select) || [];
-            if (nodes.length > 0) value = Element.collectTextNodes(nodes[0], this.options.select);
-        }
-        else
-            value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
-
-        var bounds = this.getTokenBounds();
-        if (bounds[0] != -1)
-        {
-            var newValue = this.element.value.substr(0, bounds[0]);
-            var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
-            if (whitespace)
-                newValue += whitespace[0];
-            this.element.value = newValue + value + this.element.value.substr(bounds[1]);
-        }
-        else
-        {
-            this.element.value = value;
-        }
-        this.oldElementValue = this.element.value;
-        this.element.focus();
-
-        if (this.options.afterUpdateElement)
-            this.options.afterUpdateElement(this.element, selectedElement);
-    },
-
-    updateChoices: function(choices)
-    {
-        if (!this.changed && this.hasFocus)
-        {
-            this.update.innerHTML = choices;
-            Element.cleanWhitespace(this.update);
-            Element.cleanWhitespace(this.update.down());
-
-            if (this.update.firstChild && this.update.down().childNodes)
-            {
-                this.entryCount =
-                this.update.down().childNodes.length;
-                for (var i = 0; i < this.entryCount; i++)
-                {
-                    var entry = this.getEntry(i);
-                    entry.autocompleteIndex = i;
-                    this.addObservers(entry);
-                }
-            }
-            else
-            {
-                this.entryCount = 0;
-            }
-
-            this.stopIndicator();
-            this.index = 0;
-
-            if (this.entryCount == 1 && this.options.autoSelect)
-            {
-                this.selectEntry();
-                this.hide();
-            }
-            else
-            {
-                this.render();
-            }
-        }
-    },
-
-    addObservers: function(element)
-    {
-        Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
-        Event.observe(element, "click", this.onClick.bindAsEventListener(this));
-    },
-
-    onObserverEvent: function()
-    {
-        this.changed = false;
-        this.tokenBounds = null;
-        if (this.getToken().length >= this.options.minChars)
-        {
-            this.getUpdatedChoices();
-        }
-        else
-        {
-            this.active = false;
-            this.hide();
-        }
-        this.oldElementValue = this.element.value;
-    },
+      } else {
+        this.render();
+      }
+    }
+  },
 
-    getToken: function()
-    {
-        var bounds = this.getTokenBounds();
-        return this.element.value.substring(bounds[0], bounds[1]).strip();
-    },
+  addObservers: function(element) {
+    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
+    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
+  },
+
+  onObserverEvent: function() {
+    this.changed = false;   
+    this.tokenBounds = null;
+    if(this.getToken().length>=this.options.minChars) {
+      this.getUpdatedChoices();
+    } else {
+      this.active = false;
+      this.hide();
+    }
+    this.oldElementValue = this.element.value;
+  },
 
-    getTokenBounds: function()
-    {
-        if (null != this.tokenBounds) return this.tokenBounds;
-        var value = this.element.value;
-        if (value.strip().empty()) return [-1, 0];
-        var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
-        var offset = (diff == this.oldElementValue.length ? 1 : 0);
-        var prevTokenPos = -1, nextTokenPos = value.length;
-        var tp;
-        for (var index = 0, l = this.options.tokens.length; index < l; ++index)
-        {
-            tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
-            if (tp > prevTokenPos) prevTokenPos = tp;
-            tp = value.indexOf(this.options.tokens[index], diff + offset);
-            if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
-        }
-        return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
+  getToken: function() {
+    var bounds = this.getTokenBounds();
+    return this.element.value.substring(bounds[0], bounds[1]).strip();
+  },
+
+  getTokenBounds: function() {
+    if (null != this.tokenBounds) return this.tokenBounds;
+    var value = this.element.value;
+    if (value.strip().empty()) return [-1, 0];
+    var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
+    var offset = (diff == this.oldElementValue.length ? 1 : 0);
+    var prevTokenPos = -1, nextTokenPos = value.length;
+    var tp;
+    for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
+      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
+      if (tp > prevTokenPos) prevTokenPos = tp;
+      tp = value.indexOf(this.options.tokens[index], diff + offset);
+      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
     }
+    return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
+  }
 });
 
-Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS)
-{
-    var boundary = Math.min(newS.length, oldS.length);
-    for (var index = 0; index < boundary; ++index)
-        if (newS[index] != oldS[index])
-            return index;
-    return boundary;
+Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
+  var boundary = Math.min(newS.length, oldS.length);
+  for (var index = 0; index < boundary; ++index)
+    if (newS[index] != oldS[index])
+      return index;
+  return boundary;
 };
 
 Ajax.Autocompleter = Class.create(Autocompleter.Base, {
-    initialize: function(element, update, url, options)
-    {
-        this.baseInitialize(element, update, options);
-        this.options.asynchronous = true;
-        this.options.onComplete = this.onComplete.bind(this);
-        this.options.defaultParams = this.options.parameters || null;
-        this.url = url;
-    },
-
-    getUpdatedChoices: function()
-    {
-        this.startIndicator();
-
-        var entry = encodeURIComponent(this.options.paramName) + '=' +
-                    encodeURIComponent(this.getToken());
-
-        this.options.parameters = this.options.callback ?
-                                  this.options.callback(this.element, entry) : entry;
-
-        if (this.options.defaultParams)
-            this.options.parameters += '&' + this.options.defaultParams;
-
-        new Ajax.Request(this.url, this.options);
-    },
-
-    onComplete: function(request)
-    {
-        this.updateChoices(request.responseText);
-    }
+  initialize: function(element, update, url, options) {
+    this.baseInitialize(element, update, options);
+    this.options.asynchronous  = true;
+    this.options.onComplete    = this.onComplete.bind(this);
+    this.options.defaultParams = this.options.parameters || null;
+    this.url                   = url;
+  },
+
+  getUpdatedChoices: function() {
+    this.startIndicator();
+    
+    var entry = encodeURIComponent(this.options.paramName) + '=' + 
+      encodeURIComponent(this.getToken());
+
+    this.options.parameters = this.options.callback ?
+      this.options.callback(this.element, entry) : entry;
+
+    if(this.options.defaultParams) 
+      this.options.parameters += '&' + this.options.defaultParams;
+    
+    new Ajax.Request(this.url, this.options);
+  },
+
+  onComplete: function(request) {
+    this.updateChoices(request.responseText);
+  }
 });
 
 // The local array autocompleter. Used when you'd prefer to
@@ -463,73 +407,63 @@
 // you support them.
 
 Autocompleter.Local = Class.create(Autocompleter.Base, {
-    initialize: function(element, update, array, options)
-    {
-        this.baseInitialize(element, update, options);
-        this.options.array = array;
-    },
-
-    getUpdatedChoices: function()
-    {
-        this.updateChoices(this.options.selector(this));
-    },
-
-    setOptions: function(options)
-    {
-        this.options = Object.extend({
-            choices: 10,
-            partialSearch: true,
-            partialChars: 2,
-            ignoreCase: true,
-            fullSearch: false,
-            selector: function(instance)
-            {
-                var ret = []; // Beginning matches
-                var partial = []; // Inside matches
-                var entry = instance.getToken();
-                var count = 0;
-
-                for (var i = 0; i < instance.options.array.length &&
-                                ret.length < instance.options.choices; i++)
-                {
-
-                    var elem = instance.options.array[i];
-                    var foundPos = instance.options.ignoreCase ?
-                                   elem.toLowerCase().indexOf(entry.toLowerCase()) :
-                                   elem.indexOf(entry);
-
-                    while (foundPos != -1)
-                    {
-                        if (foundPos == 0 && elem.length != entry.length)
-                        {
-                            ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
-                                     elem.substr(entry.length) + "</li>");
-                            break;
-                        }
-                        else if (entry.length >= instance.options.partialChars &&
-                                 instance.options.partialSearch && foundPos != -1)
-                        {
-                            if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos - 1, 1)))
-                            {
-                                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
-                                             elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
-                                        foundPos + entry.length) + "</li>");
-                                break;
-                            }
-                        }
-
-                        foundPos = instance.options.ignoreCase ?
-                                   elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
-                                   elem.indexOf(entry, foundPos + 1);
-
-                    }
-                }
-                if (partial.length)
-                    ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
-                return "<ul>" + ret.join('') + "</ul>";
+  initialize: function(element, update, array, options) {
+    this.baseInitialize(element, update, options);
+    this.options.array = array;
+  },
+
+  getUpdatedChoices: function() {
+    this.updateChoices(this.options.selector(this));
+  },
+
+  setOptions: function(options) {
+    this.options = Object.extend({
+      choices: 10,
+      partialSearch: true,
+      partialChars: 2,
+      ignoreCase: true,
+      fullSearch: false,
+      selector: function(instance) {
+        var ret       = []; // Beginning matches
+        var partial   = []; // Inside matches
+        var entry     = instance.getToken();
+        var count     = 0;
+
+        for (var i = 0; i < instance.options.array.length &&  
+          ret.length < instance.options.choices ; i++) { 
+
+          var elem = instance.options.array[i];
+          var foundPos = instance.options.ignoreCase ? 
+            elem.toLowerCase().indexOf(entry.toLowerCase()) : 
+            elem.indexOf(entry);
+
+          while (foundPos != -1) {
+            if (foundPos == 0 && elem.length != entry.length) { 
+              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
+                elem.substr(entry.length) + "</li>");
+              break;
+            } else if (entry.length >= instance.options.partialChars && 
+              instance.options.partialSearch && foundPos != -1) {
+              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
+                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
+                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
+                  foundPos + entry.length) + "</li>");
+                break;
+              }
             }
-        }, options || { });
-    }
+
+            foundPos = instance.options.ignoreCase ? 
+              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
+              elem.indexOf(entry, foundPos + 1);
+
+          }
+        }
+        if (partial.length)
+          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+        return "<ul>" + ret.join('') + "</ul>";
+      }
+    }, options || { });
+  }
 });
 
 // AJAX in-place editor and collection editor
@@ -538,438 +472,381 @@
 // Use this if you notice weird scrolling problems on some browsers,
 // the DOM might be a bit confused when this gets called so do this
 // waits 1 ms (with setTimeout) until it does the activation
-Field.scrollFreeActivate = function(field)
-{
-    setTimeout(function()
-    {
-        Field.activate(field);
-    }, 1);
+Field.scrollFreeActivate = function(field) {
+  setTimeout(function() {
+    Field.activate(field);
+  }, 1);
 }
 
 Ajax.InPlaceEditor = Class.create({
-    initialize: function(element, url, options)
-    {
-        this.url = url;
-        this.element = element = $(element);
-        this.prepareOptions();
-        this._controls = { };
-        arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
-        Object.extend(this.options, options || { });
-        if (!this.options.formId && this.element.id)
-        {
-            this.options.formId = this.element.id + '-inplaceeditor';
-            if ($(this.options.formId))
-                this.options.formId = '';
-        }
-        if (this.options.externalControl)
-            this.options.externalControl = $(this.options.externalControl);
-        if (!this.options.externalControl)
-            this.options.externalControlOnly = false;
-        this._originalBackground = this.element.getStyle('background-color') || 'transparent';
-        this.element.title = this.options.clickToEditText;
-        this._boundCancelHandler = this.handleFormCancellation.bind(this);
-        this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
-        this._boundFailureHandler = this.handleAJAXFailure.bind(this);
-        this._boundSubmitHandler = this.handleFormSubmission.bind(this);
-        this._boundWrapperHandler = this.wrapUp.bind(this);
-        this.registerListeners();
-    },
-    checkForEscapeOrReturn: function(e)
-    {
-        if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
-        if (Event.KEY_ESC == e.keyCode)
-            this.handleFormCancellation(e);
-        else if (Event.KEY_RETURN == e.keyCode)
-            this.handleFormSubmission(e);
-    },
-    createControl: function(mode, handler, extraClasses)
-    {
-        var control = this.options[mode + 'Control'];
-        var text = this.options[mode + 'Text'];
-        if ('button' == control)
-        {
-            var btn = document.createElement('input');
-            btn.type = 'submit';
-            btn.value = text;
-            btn.className = 'editor_' + mode + '_button';
-            if ('cancel' == mode)
-                btn.onclick = this._boundCancelHandler;
-            this._form.appendChild(btn);
-            this._controls[mode] = btn;
-        }
-        else if ('link' == control)
-        {
-            var link = document.createElement('a');
-            link.href = '#';
-            link.appendChild(document.createTextNode(text));
-            link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
-            link.className = 'editor_' + mode + '_link';
-            if (extraClasses)
-                link.className += ' ' + extraClasses;
-            this._form.appendChild(link);
-            this._controls[mode] = link;
-        }
-    },
-    createEditField: function()
-    {
-        var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
-        var fld;
-        if (1 >= this.options.rows && !/\r|\n/.test(this.getText()))
-        {
-            fld = document.createElement('input');
-            fld.type = 'text';
-            var size = this.options.size || this.options.cols || 0;
-            if (0 < size) fld.size = size;
-        }
-        else
-        {
-            fld = document.createElement('textarea');
-            fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
-            fld.cols = this.options.cols || 40;
-        }
-        fld.name = this.options.paramName;
-        fld.value = text; // No HTML breaks conversion anymore
-        fld.className = 'editor_field';
-        if (this.options.submitOnBlur)
-            fld.onblur = this._boundSubmitHandler;
-        this._controls.editor = fld;
-        if (this.options.loadTextURL)
-            this.loadExternalText();
-        this._form.appendChild(this._controls.editor);
-    },
-    createForm: function()
-    {
-        var ipe = this;
-        function addText(mode, condition)
-        {
-            var text = ipe.options['text' + mode + 'Controls'];
-            if (!text || condition === false) return;
-            ipe._form.appendChild(document.createTextNode(text));
-        }
-        ;
-        this._form = $(document.createElement('form'));
-        this._form.id = this.options.formId;
-        this._form.addClassName(this.options.formClassName);
-        this._form.onsubmit = this._boundSubmitHandler;
-        this.createEditField();
-        if ('textarea' == this._controls.editor.tagName.toLowerCase())
-            this._form.appendChild(document.createElement('br'));
-        if (this.options.onFormCustomization)
-            this.options.onFormCustomization(this, this._form);
-        addText('Before', this.options.okControl || this.options.cancelControl);
-        this.createControl('ok', this._boundSubmitHandler);
-        addText('Between', this.options.okControl && this.options.cancelControl);
-        this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
-        addText('After', this.options.okControl || this.options.cancelControl);
-    },
-    destroy: function()
-    {
-        if (this._oldInnerHTML)
-            this.element.innerHTML = this._oldInnerHTML;
-        this.leaveEditMode();
-        this.unregisterListeners();
-    },
-    enterEditMode: function(e)
-    {
-        if (this._saving || this._editing) return;
-        this._editing = true;
-        this.triggerCallback('onEnterEditMode');
-        if (this.options.externalControl)
-            this.options.externalControl.hide();
-        this.element.hide();
-        this.createForm();
-        this.element.parentNode.insertBefore(this._form, this.element);
-        if (!this.options.loadTextURL)
-            this.postProcessEditField();
-        if (e) Event.stop(e);
-    },
-    enterHover: function(e)
-    {
-        if (this.options.hoverClassName)
-            this.element.addClassName(this.options.hoverClassName);
-        if (this._saving) return;
-        this.triggerCallback('onEnterHover');
-    },
-    getText: function()
-    {
-        return this.element.innerHTML;
-    },
-    handleAJAXFailure: function(transport)
-    {
-        this.triggerCallback('onFailure', transport);
-        if (this._oldInnerHTML)
-        {
-            this.element.innerHTML = this._oldInnerHTML;
-            this._oldInnerHTML = null;
-        }
-    },
-    handleFormCancellation: function(e)
-    {
-        this.wrapUp();
-        if (e) Event.stop(e);
-    },
-    handleFormSubmission: function(e)
-    {
-        var form = this._form;
-        var value = $F(this._controls.editor);
-        this.prepareSubmission();
-        var params = this.options.callback(form, value) || '';
-        if (Object.isString(params))
-            params = params.toQueryParams();
-        params.editorId = this.element.id;
-        if (this.options.htmlResponse)
-        {
-            var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
-            Object.extend(options, {
-                parameters: params,
-                onComplete: this._boundWrapperHandler,
-                onFailure: this._boundFailureHandler
-            });
-            new Ajax.Updater({ success: this.element }, this.url, options);
-        }
-        else
-        {
-            var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-            Object.extend(options, {
-                parameters: params,
-                onComplete: this._boundWrapperHandler,
-                onFailure: this._boundFailureHandler
-            });
-            new Ajax.Request(this.url, options);
-        }
-        if (e) Event.stop(e);
-    },
-    leaveEditMode: function()
-    {
-        this.element.removeClassName(this.options.savingClassName);
-        this.removeForm();
-        this.leaveHover();
-        this.element.style.backgroundColor = this._originalBackground;
-        this.element.show();
-        if (this.options.externalControl)
-            this.options.externalControl.show();
-        this._saving = false;
-        this._editing = false;
-        this._oldInnerHTML = null;
-        this.triggerCallback('onLeaveEditMode');
-    },
-    leaveHover: function(e)
-    {
-        if (this.options.hoverClassName)
-            this.element.removeClassName(this.options.hoverClassName);
-        if (this._saving) return;
-        this.triggerCallback('onLeaveHover');
-    },
-    loadExternalText: function()
-    {
-        this._form.addClassName(this.options.loadingClassName);
-        this._controls.editor.disabled = true;
-        var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-        Object.extend(options, {
-            parameters: 'editorId=' + encodeURIComponent(this.element.id),
-            onComplete: Prototype.emptyFunction,
-            onSuccess: function(transport)
-            {
-                this._form.removeClassName(this.options.loadingClassName);
-                var text = transport.responseText;
-                if (this.options.stripLoadedTextTags)
-                    text = text.stripTags();
-                this._controls.editor.value = text;
-                this._controls.editor.disabled = false;
-                this.postProcessEditField();
-            }.bind(this),
-            onFailure: this._boundFailureHandler
-        });
-        new Ajax.Request(this.options.loadTextURL, options);
-    },
-    postProcessEditField: function()
-    {
-        var fpc = this.options.fieldPostCreation;
-        if (fpc)
-            $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
-    },
-    prepareOptions: function()
-    {
-        this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
-        Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
-        [this._extraDefaultOptions].flatten().compact().each(function(defs)
-        {
-            Object.extend(this.options, defs);
-        }.bind(this));
-    },
-    prepareSubmission: function()
-    {
-        this._saving = true;
-        this.removeForm();
-        this.leaveHover();
-        this.showSaving();
-    },
-    registerListeners: function()
-    {
-        this._listeners = { };
-        var listener;
-        $H(Ajax.InPlaceEditor.Listeners).each(function(pair)
-        {
-            listener = this[pair.value].bind(this);
-            this._listeners[pair.key] = listener;
-            if (!this.options.externalControlOnly)
-                this.element.observe(pair.key, listener);
-            if (this.options.externalControl)
-                this.options.externalControl.observe(pair.key, listener);
-        }.bind(this));
-    },
-    removeForm: function()
-    {
-        if (!this._form) return;
-        this._form.remove();
-        this._form = null;
-        this._controls = { };
-    },
-    showSaving: function()
-    {
-        this._oldInnerHTML = this.element.innerHTML;
-        this.element.innerHTML = this.options.savingText;
-        this.element.addClassName(this.options.savingClassName);
-        this.element.style.backgroundColor = this._originalBackground;
-        this.element.show();
-    },
-    triggerCallback: function(cbName, arg)
-    {
-        if ('function' == typeof this.options[cbName])
-        {
-            this.options[cbName](this, arg);
-        }
-    },
-    unregisterListeners: function()
-    {
-        $H(this._listeners).each(function(pair)
-        {
-            if (!this.options.externalControlOnly)
-                this.element.stopObserving(pair.key, pair.value);
-            if (this.options.externalControl)
-                this.options.externalControl.stopObserving(pair.key, pair.value);
-        }.bind(this));
-    },
-    wrapUp: function(transport)
-    {
-        this.leaveEditMode();
-    // Can't use triggerCallback due to backward compatibility: requires
-        // binding + direct element
-        this._boundComplete(transport, this.element);
+  initialize: function(element, url, options) {
+    this.url = url;
+    this.element = element = $(element);
+    this.prepareOptions();
+    this._controls = { };
+    arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
+    Object.extend(this.options, options || { });
+    if (!this.options.formId && this.element.id) {
+      this.options.formId = this.element.id + '-inplaceeditor';
+      if ($(this.options.formId))
+        this.options.formId = '';
+    }
+    if (this.options.externalControl)
+      this.options.externalControl = $(this.options.externalControl);
+    if (!this.options.externalControl)
+      this.options.externalControlOnly = false;
+    this._originalBackground = this.element.getStyle('background-color') || 'transparent';
+    this.element.title = this.options.clickToEditText;
+    this._boundCancelHandler = this.handleFormCancellation.bind(this);
+    this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
+    this._boundFailureHandler = this.handleAJAXFailure.bind(this);
+    this._boundSubmitHandler = this.handleFormSubmission.bind(this);
+    this._boundWrapperHandler = this.wrapUp.bind(this);
+    this.registerListeners();
+  },
+  checkForEscapeOrReturn: function(e) {
+    if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
+    if (Event.KEY_ESC == e.keyCode)
+      this.handleFormCancellation(e);
+    else if (Event.KEY_RETURN == e.keyCode)
+      this.handleFormSubmission(e);
+  },
+  createControl: function(mode, handler, extraClasses) {
+    var control = this.options[mode + 'Control'];
+    var text = this.options[mode + 'Text'];
+    if ('button' == control) {
+      var btn = document.createElement('input');
+      btn.type = 'submit';
+      btn.value = text;
+      btn.className = 'editor_' + mode + '_button';
+      if ('cancel' == mode)
+        btn.onclick = this._boundCancelHandler;
+      this._form.appendChild(btn);
+      this._controls[mode] = btn;
+    } else if ('link' == control) {
+      var link = document.createElement('a');
+      link.href = '#';
+      link.appendChild(document.createTextNode(text));
+      link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
+      link.className = 'editor_' + mode + '_link';
+      if (extraClasses)
+        link.className += ' ' + extraClasses;
+      this._form.appendChild(link);
+      this._controls[mode] = link;
     }
+  },
+  createEditField: function() {
+    var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
+    var fld;
+    if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
+      fld = document.createElement('input');
+      fld.type = 'text';
+      var size = this.options.size || this.options.cols || 0;
+      if (0 < size) fld.size = size;
+    } else {
+      fld = document.createElement('textarea');
+      fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
+      fld.cols = this.options.cols || 40;
+    }
+    fld.name = this.options.paramName;
+    fld.value = text; // No HTML breaks conversion anymore
+    fld.className = 'editor_field';
+    if (this.options.submitOnBlur)
+      fld.onblur = this._boundSubmitHandler;
+    this._controls.editor = fld;
+    if (this.options.loadTextURL)
+      this.loadExternalText();
+    this._form.appendChild(this._controls.editor);
+  },
+  createForm: function() {
+    var ipe = this;
+    function addText(mode, condition) {
+      var text = ipe.options['text' + mode + 'Controls'];
+      if (!text || condition === false) return;
+      ipe._form.appendChild(document.createTextNode(text));
+    };
+    this._form = $(document.createElement('form'));
+    this._form.id = this.options.formId;
+    this._form.addClassName(this.options.formClassName);
+    this._form.onsubmit = this._boundSubmitHandler;
+    this.createEditField();
+    if ('textarea' == this._controls.editor.tagName.toLowerCase())
+      this._form.appendChild(document.createElement('br'));
+    if (this.options.onFormCustomization)
+      this.options.onFormCustomization(this, this._form);
+    addText('Before', this.options.okControl || this.options.cancelControl);
+    this.createControl('ok', this._boundSubmitHandler);
+    addText('Between', this.options.okControl && this.options.cancelControl);
+    this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
+    addText('After', this.options.okControl || this.options.cancelControl);
+  },
+  destroy: function() {
+    if (this._oldInnerHTML)
+      this.element.innerHTML = this._oldInnerHTML;
+    this.leaveEditMode();
+    this.unregisterListeners();
+  },
+  enterEditMode: function(e) {
+    if (this._saving || this._editing) return;
+    this._editing = true;
+    this.triggerCallback('onEnterEditMode');
+    if (this.options.externalControl)
+      this.options.externalControl.hide();
+    this.element.hide();
+    this.createForm();
+    this.element.parentNode.insertBefore(this._form, this.element);
+    if (!this.options.loadTextURL)
+      this.postProcessEditField();
+    if (e) Event.stop(e);
+  },
+  enterHover: function(e) {
+    if (this.options.hoverClassName)
+      this.element.addClassName(this.options.hoverClassName);
+    if (this._saving) return;
+    this.triggerCallback('onEnterHover');
+  },
+  getText: function() {
+    return this.element.innerHTML;
+  },
+  handleAJAXFailure: function(transport) {
+    this.triggerCallback('onFailure', transport);
+    if (this._oldInnerHTML) {
+      this.element.innerHTML = this._oldInnerHTML;
+      this._oldInnerHTML = null;
+    }
+  },
+  handleFormCancellation: function(e) {
+    this.wrapUp();
+    if (e) Event.stop(e);
+  },
+  handleFormSubmission: function(e) {
+    var form = this._form;
+    var value = $F(this._controls.editor);
+    this.prepareSubmission();
+    var params = this.options.callback(form, value) || '';
+    if (Object.isString(params))
+      params = params.toQueryParams();
+    params.editorId = this.element.id;
+    if (this.options.htmlResponse) {
+      var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
+      Object.extend(options, {
+        parameters: params,
+        onComplete: this._boundWrapperHandler,
+        onFailure: this._boundFailureHandler
+      });
+      new Ajax.Updater({ success: this.element }, this.url, options);
+    } else {
+      var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+      Object.extend(options, {
+        parameters: params,
+        onComplete: this._boundWrapperHandler,
+        onFailure: this._boundFailureHandler
+      });
+      new Ajax.Request(this.url, options);
+    }
+    if (e) Event.stop(e);
+  },
+  leaveEditMode: function() {
+    this.element.removeClassName(this.options.savingClassName);
+    this.removeForm();
+    this.leaveHover();
+    this.element.style.backgroundColor = this._originalBackground;
+    this.element.show();
+    if (this.options.externalControl)
+      this.options.externalControl.show();
+    this._saving = false;
+    this._editing = false;
+    this._oldInnerHTML = null;
+    this.triggerCallback('onLeaveEditMode');
+  },
+  leaveHover: function(e) {
+    if (this.options.hoverClassName)
+      this.element.removeClassName(this.options.hoverClassName);
+    if (this._saving) return;
+    this.triggerCallback('onLeaveHover');
+  },
+  loadExternalText: function() {
+    this._form.addClassName(this.options.loadingClassName);
+    this._controls.editor.disabled = true;
+    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+    Object.extend(options, {
+      parameters: 'editorId=' + encodeURIComponent(this.element.id),
+      onComplete: Prototype.emptyFunction,
+      onSuccess: function(transport) {
+        this._form.removeClassName(this.options.loadingClassName);
+        var text = transport.responseText;
+        if (this.options.stripLoadedTextTags)
+          text = text.stripTags();
+        this._controls.editor.value = text;
+        this._controls.editor.disabled = false;
+        this.postProcessEditField();
+      }.bind(this),
+      onFailure: this._boundFailureHandler
+    });
+    new Ajax.Request(this.options.loadTextURL, options);
+  },
+  postProcessEditField: function() {
+    var fpc = this.options.fieldPostCreation;
+    if (fpc)
+      $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
+  },
+  prepareOptions: function() {
+    this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
+    Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
+    [this._extraDefaultOptions].flatten().compact().each(function(defs) {
+      Object.extend(this.options, defs);
+    }.bind(this));
+  },
+  prepareSubmission: function() {
+    this._saving = true;
+    this.removeForm();
+    this.leaveHover();
+    this.showSaving();
+  },
+  registerListeners: function() {
+    this._listeners = { };
+    var listener;
+    $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
+      listener = this[pair.value].bind(this);
+      this._listeners[pair.key] = listener;
+      if (!this.options.externalControlOnly)
+        this.element.observe(pair.key, listener);
+      if (this.options.externalControl)
+        this.options.externalControl.observe(pair.key, listener);
+    }.bind(this));
+  },
+  removeForm: function() {
+    if (!this._form) return;
+    this._form.remove();
+    this._form = null;
+    this._controls = { };
+  },
+  showSaving: function() {
+    this._oldInnerHTML = this.element.innerHTML;
+    this.element.innerHTML = this.options.savingText;
+    this.element.addClassName(this.options.savingClassName);
+    this.element.style.backgroundColor = this._originalBackground;
+    this.element.show();
+  },
+  triggerCallback: function(cbName, arg) {
+    if ('function' == typeof this.options[cbName]) {
+      this.options[cbName](this, arg);
+    }
+  },
+  unregisterListeners: function() {
+    $H(this._listeners).each(function(pair) {
+      if (!this.options.externalControlOnly)
+        this.element.stopObserving(pair.key, pair.value);
+      if (this.options.externalControl)
+        this.options.externalControl.stopObserving(pair.key, pair.value);
+    }.bind(this));
+  },
+  wrapUp: function(transport) {
+    this.leaveEditMode();
+    // Can't use triggerCallback due to backward compatibility: requires
+    // binding + direct element
+    this._boundComplete(transport, this.element);
+  }
 });
 
 Object.extend(Ajax.InPlaceEditor.prototype, {
-    dispose: Ajax.InPlaceEditor.prototype.destroy
+  dispose: Ajax.InPlaceEditor.prototype.destroy
 });
 
 Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
-    initialize: function($super, element, url, options)
-    {
-        this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
-        $super(element, url, options);
-    },
-
-    createEditField: function()
-    {
-        var list = document.createElement('select');
-        list.name = this.options.paramName;
-        list.size = 1;
-        this._controls.editor = list;
-        this._collection = this.options.collection || [];
-        if (this.options.loadCollectionURL)
-            this.loadCollection();
-        else
-            this.checkForExternalText();
-        this._form.appendChild(this._controls.editor);
-    },
-
-    loadCollection: function()
-    {
-        this._form.addClassName(this.options.loadingClassName);
-        this.showLoadingText(this.options.loadingCollectionText);
-        var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-        Object.extend(options, {
-            parameters: 'editorId=' + encodeURIComponent(this.element.id),
-            onComplete: Prototype.emptyFunction,
-            onSuccess: function(transport)
-            {
-                var js = transport.responseText.strip();
-                if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
-                    throw 'Server returned an invalid collection representation.';
-                this._collection = eval(js);
-                this.checkForExternalText();
-            }.bind(this),
-            onFailure: this.onFailure
-        });
-        new Ajax.Request(this.options.loadCollectionURL, options);
-    },
-
-    showLoadingText: function(text)
-    {
-        this._controls.editor.disabled = true;
-        var tempOption = this._controls.editor.firstChild;
-        if (!tempOption)
-        {
-            tempOption = document.createElement('option');
-            tempOption.value = '';
-            this._controls.editor.appendChild(tempOption);
-            tempOption.selected = true;
-        }
-        tempOption.update((text || '').stripScripts().stripTags());
-    },
-
-    checkForExternalText: function()
-    {
-        this._text = this.getText();
-        if (this.options.loadTextURL)
-            this.loadExternalText();
-        else
-            this.buildOptionList();
-    },
-
-    loadExternalText: function()
-    {
-        this.showLoadingText(this.options.loadingText);
-        var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-        Object.extend(options, {
-            parameters: 'editorId=' + encodeURIComponent(this.element.id),
-            onComplete: Prototype.emptyFunction,
-            onSuccess: function(transport)
-            {
-                this._text = transport.responseText.strip();
-                this.buildOptionList();
-            }.bind(this),
-            onFailure: this.onFailure
-        });
-        new Ajax.Request(this.options.loadTextURL, options);
-    },
-
-    buildOptionList: function()
-    {
-        this._form.removeClassName(this.options.loadingClassName);
-        this._collection = this._collection.map(function(entry)
-        {
-            return 2 === entry.length ? entry : [entry, entry].flatten();
-        });
-        var marker = ('value' in this.options) ? this.options.value : this._text;
-        var textFound = this._collection.any(function(entry)
-        {
-            return entry[0] == marker;
-        }.bind(this));
-        this._controls.editor.update('');
-        var option;
-        this._collection.each(function(entry, index)
-        {
-            option = document.createElement('option');
-            option.value = entry[0];
-            option.selected = textFound ? entry[0] == marker : 0 == index;
-            option.appendChild(document.createTextNode(entry[1]));
-            this._controls.editor.appendChild(option);
-        }.bind(this));
-        this._controls.editor.disabled = false;
-        Field.scrollFreeActivate(this._controls.editor);
+  initialize: function($super, element, url, options) {
+    this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
+    $super(element, url, options);
+  },
+
+  createEditField: function() {
+    var list = document.createElement('select');
+    list.name = this.options.paramName;
+    list.size = 1;
+    this._controls.editor = list;
+    this._collection = this.options.collection || [];
+    if (this.options.loadCollectionURL)
+      this.loadCollection();
+    else
+      this.checkForExternalText();
+    this._form.appendChild(this._controls.editor);
+  },
+
+  loadCollection: function() {
+    this._form.addClassName(this.options.loadingClassName);
+    this.showLoadingText(this.options.loadingCollectionText);
+    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+    Object.extend(options, {
+      parameters: 'editorId=' + encodeURIComponent(this.element.id),
+      onComplete: Prototype.emptyFunction,
+      onSuccess: function(transport) {
+        var js = transport.responseText.strip();
+        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
+          throw 'Server returned an invalid collection representation.';
+        this._collection = eval(js);
+        this.checkForExternalText();
+      }.bind(this),
+      onFailure: this.onFailure
+    });
+    new Ajax.Request(this.options.loadCollectionURL, options);
+  },
+
+  showLoadingText: function(text) {
+    this._controls.editor.disabled = true;
+    var tempOption = this._controls.editor.firstChild;
+    if (!tempOption) {
+      tempOption = document.createElement('option');
+      tempOption.value = '';
+      this._controls.editor.appendChild(tempOption);
+      tempOption.selected = true;
     }
+    tempOption.update((text || '').stripScripts().stripTags());
+  },
+
+  checkForExternalText: function() {
+    this._text = this.getText();
+    if (this.options.loadTextURL)
+      this.loadExternalText();
+    else
+      this.buildOptionList();
+  },
+
+  loadExternalText: function() {
+    this.showLoadingText(this.options.loadingText);
+    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+    Object.extend(options, {
+      parameters: 'editorId=' + encodeURIComponent(this.element.id),
+      onComplete: Prototype.emptyFunction,
+      onSuccess: function(transport) {
+        this._text = transport.responseText.strip();
+        this.buildOptionList();
+      }.bind(this),
+      onFailure: this.onFailure
+    });
+    new Ajax.Request(this.options.loadTextURL, options);
+  },
+
+  buildOptionList: function() {
+    this._form.removeClassName(this.options.loadingClassName);
+    this._collection = this._collection.map(function(entry) {
+      return 2 === entry.length ? entry : [entry, entry].flatten();
+    });
+    var marker = ('value' in this.options) ? this.options.value : this._text;
+    var textFound = this._collection.any(function(entry) {
+      return entry[0] == marker;
+    }.bind(this));
+    this._controls.editor.update('');
+    var option;
+    this._collection.each(function(entry, index) {
+      option = document.createElement('option');
+      option.value = entry[0];
+      option.selected = textFound ? entry[0] == marker : 0 == index;
+      option.appendChild(document.createTextNode(entry[1]));
+      this._controls.editor.appendChild(option);
+    }.bind(this));
+    this._controls.editor.disabled = false;
+    Field.scrollFreeActivate(this._controls.editor);
+  }
 });
 
 //**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
@@ -977,97 +854,89 @@
 //**** users adapt to  the new API.  Read up on the new ****
 //**** API and convert your code to it ASAP!            ****
 
-Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options)
-{
-    if (!options) return;
-    function fallback(name, expr)
-    {
-        if (name in options || expr === undefined) return;
-        options[name] = expr;
-    }
-    ;
-    fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
-                                                              options.cancelLink == options.cancelButton == false ? false : undefined)));
-    fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
-                                                      options.okLink == options.okButton == false ? false : undefined)));
-    fallback('highlightColor', options.highlightcolor);
-    fallback('highlightEndColor', options.highlightendcolor);
+Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
+  if (!options) return;
+  function fallback(name, expr) {
+    if (name in options || expr === undefined) return;
+    options[name] = expr;
+  };
+  fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
+    options.cancelLink == options.cancelButton == false ? false : undefined)));
+  fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
+    options.okLink == options.okButton == false ? false : undefined)));
+  fallback('highlightColor', options.highlightcolor);
+  fallback('highlightEndColor', options.highlightendcolor);
 };
 
 Object.extend(Ajax.InPlaceEditor, {
-    DefaultOptions: {
-        ajaxOptions: { },
-        autoRows: 3,                                // Use when multi-line w/ rows == 1
-        cancelControl: 'link',                      // 'link'|'button'|false
-        cancelText: 'cancel',
-        clickToEditText: 'Click to edit',
-        externalControl: null,                      // id|elt
-        externalControlOnly: false,
-        fieldPostCreation: 'activate',              // 'activate'|'focus'|false
-        formClassName: 'inplaceeditor-form',
-        formId: null,                               // id|elt
-        highlightColor: '#ffff99',
-        highlightEndColor: '#ffffff',
-        hoverClassName: '',
-        htmlResponse: true,
-        loadingClassName: 'inplaceeditor-loading',
-        loadingText: 'Loading...',
-        okControl: 'button',                        // 'link'|'button'|false
-        okText: 'ok',
-        paramName: 'value',
-        rows: 1,                                    // If 1 and multi-line, uses autoRows
-        savingClassName: 'inplaceeditor-saving',
-        savingText: 'Saving...',
-        size: 0,
-        stripLoadedTextTags: false,
-        submitOnBlur: false,
-        textAfterControls: '',
-        textBeforeControls: '',
-        textBetweenControls: ''
-    },
-    DefaultCallbacks: {
-        callback: function(form)
-        {
-            return Form.serialize(form);
-        },
-        onComplete: function(transport, element)
-        {
-            // For backward compatibility, this one is bound to the IPE, and passes
-            // the element directly.  It was too often customized, so we don't break it.
-            new Effect.Highlight(element, {
-                startcolor: this.options.highlightColor, keepBackgroundImage: true });
-        },
-        onEnterEditMode: null,
-        onEnterHover: function(ipe)
-        {
-            ipe.element.style.backgroundColor = ipe.options.highlightColor;
-            if (ipe._effect)
-                ipe._effect.cancel();
-        },
-        onFailure: function(transport, ipe)
-        {
-            alert('Error communication with the server: ' + transport.responseText.stripTags());
-        },
-        onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
-        onLeaveEditMode: null,
-        onLeaveHover: function(ipe)
-        {
-            ipe._effect = new Effect.Highlight(ipe.element, {
-                startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
-                restorecolor: ipe._originalBackground, keepBackgroundImage: true
-            });
-        }
-    },
-    Listeners: {
-        click: 'enterEditMode',
-        keydown: 'checkForEscapeOrReturn',
-        mouseover: 'enterHover',
-        mouseout: 'leaveHover'
+  DefaultOptions: {
+    ajaxOptions: { },
+    autoRows: 3,                                // Use when multi-line w/ rows == 1
+    cancelControl: 'link',                      // 'link'|'button'|false
+    cancelText: 'cancel',
+    clickToEditText: 'Click to edit',
+    externalControl: null,                      // id|elt
+    externalControlOnly: false,
+    fieldPostCreation: 'activate',              // 'activate'|'focus'|false
+    formClassName: 'inplaceeditor-form',
+    formId: null,                               // id|elt
+    highlightColor: '#ffff99',
+    highlightEndColor: '#ffffff',
+    hoverClassName: '',
+    htmlResponse: true,
+    loadingClassName: 'inplaceeditor-loading',
+    loadingText: 'Loading...',
+    okControl: 'button',                        // 'link'|'button'|false
+    okText: 'ok',
+    paramName: 'value',
+    rows: 1,                                    // If 1 and multi-line, uses autoRows
+    savingClassName: 'inplaceeditor-saving',
+    savingText: 'Saving...',
+    size: 0,
+    stripLoadedTextTags: false,
+    submitOnBlur: false,
+    textAfterControls: '',
+    textBeforeControls: '',
+    textBetweenControls: ''
+  },
+  DefaultCallbacks: {
+    callback: function(form) {
+      return Form.serialize(form);
+    },
+    onComplete: function(transport, element) {
+      // For backward compatibility, this one is bound to the IPE, and passes
+      // the element directly.  It was too often customized, so we don't break it.
+      new Effect.Highlight(element, {
+        startcolor: this.options.highlightColor, keepBackgroundImage: true });
+    },
+    onEnterEditMode: null,
+    onEnterHover: function(ipe) {
+      ipe.element.style.backgroundColor = ipe.options.highlightColor;
+      if (ipe._effect)
+        ipe._effect.cancel();
+    },
+    onFailure: function(transport, ipe) {
+      alert('Error communication with the server: ' + transport.responseText.stripTags());
+    },
+    onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
+    onLeaveEditMode: null,
+    onLeaveHover: function(ipe) {
+      ipe._effect = new Effect.Highlight(ipe.element, {
+        startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
+        restorecolor: ipe._originalBackground, keepBackgroundImage: true
+      });
     }
+  },
+  Listeners: {
+    click: 'enterEditMode',
+    keydown: 'checkForEscapeOrReturn',
+    mouseover: 'enterHover',
+    mouseout: 'leaveHover'
+  }
 });
 
 Ajax.InPlaceCollectionEditor.DefaultOptions = {
-    loadingCollectionText: 'Loading options...'
+  loadingCollectionText: 'Loading options...'
 };
 
 // Delayed observer, like Form.Element.Observer, 
@@ -1075,25 +944,22 @@
 // Ideal for live-search fields
 
 Form.Element.DelayedObserver = Class.create({
-    initialize: function(element, delay, callback)
-    {
-        this.delay = delay || 0.5;
-        this.element = $(element);
-        this.callback = callback;
-        this.timer = null;
-        this.lastValue = $F(this.element);
-        Event.observe(this.element, 'keyup', this.delayedListener.bindAsEventListener(this));
-    },
-    delayedListener: function(event)
-    {
-        if (this.lastValue == $F(this.element)) return;
-        if (this.timer) clearTimeout(this.timer);
-        this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
-        this.lastValue = $F(this.element);
-    },
-    onTimerEvent: function()
-    {
-        this.timer = null;
-        this.callback(this.element, $F(this.element));
-    }
+  initialize: function(element, delay, callback) {
+    this.delay     = delay || 0.5;
+    this.element   = $(element);
+    this.callback  = callback;
+    this.timer     = null;
+    this.lastValue = $F(this.element); 
+    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
+  },
+  delayedListener: function(event) {
+    if(this.lastValue == $F(this.element)) return;
+    if(this.timer) clearTimeout(this.timer);
+    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+    this.lastValue = $F(this.element);
+  },
+  onTimerEvent: function() {
+    this.timer = null;
+    this.callback(this.element, $F(this.element));
+  }
 });