You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Volker Weber <v....@inexso.de> on 2007/05/02 09:18:51 UTC

Re: svn commit: r534123 - in /myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script: builder.js controls.js dragdrop.js effects.js scriptaculous.js slider.js

Hi Pleff,

please add the jira id to the commit messages.

And (in this case) see my comment there :-).


Regards,
    Volker

2007/5/1, pleff@apache.org <pl...@apache.org>:
> Author: pleff
> Date: Tue May  1 08:28:43 2007
> New Revision: 534123
>
> URL: http://svn.apache.org/viewvc?view=rev&rev=534123
> Log:
> Update scriptaculous to 1.5.3 and added missing files.
>
> Added:
>     myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/builder.js
>     myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/slider.js
> Modified:
>     myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/controls.js
>     myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/dragdrop.js
>     myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/effects.js
>     myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/scriptaculous.js
>
> Added: myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/builder.js
> URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/builder.js?view=auto&rev=534123
> ==============================================================================
> --- myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/builder.js (added)
> +++ myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/builder.js Tue May  1 08:28:43 2007
> @@ -0,0 +1,101 @@
> +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
> +//
> +// See scriptaculous.js for full license.
> +
> +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();
> +
> +    // 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;
> +
> +    // see if browser added wrapping tags
> +    if(element && (element.tagName != elementName))
> +      element = element.getElementsByTagName(elementName)[0];
> +
> +    // fallback to createElement approach
> +    if(!element) element = document.createElement(elementName);
> +
> +    // abort if nothing could be created
> +    if(!element) return;
> +
> +    // attributes (or text)
> +    if(arguments[1])
> +      if(this._isStringOrNumber(arguments[1]) ||
> +        (arguments[1] instanceof Array)) {
> +          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 != elementName)
> +              element = parentElement.getElementsByTagName(elementName)[0];
> +            }
> +        }
> +
> +    // text, or array of children
> +    if(arguments[2])
> +      this._children(element, arguments[2]);
> +
> +     return element;
> +  },
> +  _text: function(text) {
> +     return document.createTextNode(text);
> +  },
> +  _attributes: function(attributes) {
> +    var attrs = [];
> +    for(attribute in attributes)
> +      attrs.push((attribute=='className' ? 'class' : attribute) +
> +          '="' + attributes[attribute].toString().escapeHTML() + '"');
> +    return attrs.join(" ");
> +  },
> +  _children: function(element, children) {
> +    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');
> +  }
> +}
> \ No newline at end of file
>
> Modified: myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/controls.js
> URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/controls.js?view=diff&rev=534123&r1=534122&r2=534123
> ==============================================================================
> --- myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/controls.js (original)
> +++ myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/controls.js Tue May  1 08:28:43 2007
> @@ -152,6 +152,12 @@
>          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)
> @@ -221,8 +227,13 @@
>        this.options.updateElement(selectedElement);
>        return;
>      }
> -
> -    var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
> +    var value = '';
> +    if (this.options.select) {
> +      var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
> +      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
> +    } else
> +      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
> +
>      var lastTokenPos = this.findLastToken();
>      if (lastTokenPos != -1) {
>        var newValue = this.element.value.substr(0, lastTokenPos + 1);
> @@ -305,7 +316,7 @@
>  Ajax.Autocompleter = Class.create();
>  Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
>    initialize: function(element, update, url, options) {
> -         this.baseInitialize(element, update, options);
> +    this.baseInitialize(element, update, options);
>      this.options.asynchronous  = true;
>      this.options.onComplete    = this.onComplete.bind(this);
>      this.options.defaultParams = this.options.parameters || null;
> @@ -448,7 +459,9 @@
>      this.element = $(element);
>
>      this.options = Object.extend({
> +      okButton: true,
>        okText: "ok",
> +      cancelLink: true,
>        cancelText: "cancel",
>        savingText: "Saving...",
>        clickToEditText: "Click to edit",
> @@ -470,8 +483,10 @@
>        formClassName: 'inplaceeditor-form',
>        highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
>        highlightendcolor: "#FFFFFF",
> -      externalControl: null,
> -      ajaxOptions: {}
> +      externalControl: null,
> +      submitOnBlur: false,
> +      ajaxOptions: {},
> +      evalScripts: false
>      }, options || {});
>
>      if(!this.options.formId && this.element.id) {
> @@ -536,16 +551,22 @@
>        this.form.appendChild(br);
>      }
>
> -    okButton = document.createElement("input");
> -    okButton.type = "submit";
> -    okButton.value = this.options.okText;
> -    this.form.appendChild(okButton);
> -
> -    cancelLink = document.createElement("a");
> -    cancelLink.href = "#";
> -    cancelLink.appendChild(document.createTextNode(this.options.cancelText));
> -    cancelLink.onclick = this.onclickCancel.bind(this);
> -    this.form.appendChild(cancelLink);
> +    if (this.options.okButton) {
> +      okButton = document.createElement("input");
> +      okButton.type = "submit";
> +      okButton.value = this.options.okText;
> +      okButton.className = 'editor_ok_button';
> +      this.form.appendChild(okButton);
> +    }
> +
> +    if (this.options.cancelLink) {
> +      cancelLink = document.createElement("a");
> +      cancelLink.href = "#";
> +      cancelLink.appendChild(document.createTextNode(this.options.cancelText));
> +      cancelLink.onclick = this.onclickCancel.bind(this);
> +      cancelLink.className = 'editor_cancel';
> +      this.form.appendChild(cancelLink);
> +    }
>    },
>    hasHTMLLineBreaks: function(string) {
>      if (!this.options.handleLineBreaks) return false;
> @@ -561,24 +582,34 @@
>      } else {
>        text = this.getText();
>      }
> +
> +    var obj = this;
>
>      if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
>        this.options.textarea = false;
>        var textField = document.createElement("input");
> +      textField.obj = this;
>        textField.type = "text";
>        textField.name = "value";
>        textField.value = text;
>        textField.style.backgroundColor = this.options.highlightcolor;
> +      textField.className = 'editor_field';
>        var size = this.options.size || this.options.cols || 0;
>        if (size != 0) textField.size = size;
> +      if (this.options.submitOnBlur)
> +        textField.onblur = this.onSubmit.bind(this);
>        this.editField = textField;
>      } else {
>        this.options.textarea = true;
>        var textArea = document.createElement("textarea");
> +      textArea.obj = this;
>        textArea.name = "value";
>        textArea.value = this.convertHTMLLineBreaks(text);
>        textArea.rows = this.options.rows;
>        textArea.cols = this.options.cols || 40;
> +      textArea.className = 'editor_field';
> +      if (this.options.submitOnBlur)
> +        textArea.onblur = this.onSubmit.bind(this);
>        this.editField = textArea;
>      }
>
> @@ -629,19 +660,26 @@
>      // to be displayed indefinitely
>      this.onLoading();
>
> -    new Ajax.Updater(
> -      {
> -        success: this.element,
> -         // don't update on failure (this could be an option)
> -        failure: null
> -      },
> -      this.url,
> -      Object.extend({
> -        parameters: this.options.callback(form, value),
> -        onComplete: this.onComplete.bind(this),
> -        onFailure: this.onFailure.bind(this)
> -      }, this.options.ajaxOptions)
> -    );
> +    if (this.options.evalScripts) {
> +      new Ajax.Request(
> +        this.url, Object.extend({
> +          parameters: this.options.callback(form, value),
> +          onComplete: this.onComplete.bind(this),
> +          onFailure: this.onFailure.bind(this),
> +          asynchronous:true,
> +          evalScripts:true
> +        }, this.options.ajaxOptions));
> +    } else  {
> +      new Ajax.Updater(
> +        { success: this.element,
> +          // don't update on failure (this could be an option)
> +          failure: null },
> +        this.url, Object.extend({
> +          parameters: this.options.callback(form, value),
> +          onComplete: this.onComplete.bind(this),
> +          onFailure: this.onFailure.bind(this)
> +        }, this.options.ajaxOptions));
> +    }
>      // stop the event to avoid a page refresh in Safari
>      if (arguments.length > 1) {
>        Event.stop(arguments[0]);
> @@ -722,6 +760,33 @@
>      }
>    }
>  };
> +
> +Ajax.InPlaceCollectionEditor = Class.create();
> +Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
> +Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
> +  createEditField: function() {
> +    if (!this.cached_selectTag) {
> +      var selectTag = document.createElement("select");
> +      var collection = this.options.collection || [];
> +      var optionTag;
> +      collection.each(function(e,i) {
> +        optionTag = document.createElement("option");
> +        optionTag.value = (e instanceof Array) ? e[0] : e;
> +        if(this.options.value==optionTag.value) optionTag.selected = true;
> +        optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
> +        selectTag.appendChild(optionTag);
> +      }.bind(this));
> +      this.cached_selectTag = selectTag;
> +    }
> +
> +    this.editField = this.cached_selectTag;
> +    if(this.options.loadTextURL) this.loadExternalText();
> +    this.form.appendChild(this.editField);
> +    this.options.callback = function(form, value) {
> +      return "value=" + encodeURIComponent(value);
> +    }
> +  }
> +});
>
>  // Delayed observer, like Form.Element.Observer,
>  // but waits for delay after last key input
>
> Modified: myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/dragdrop.js
> URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/dragdrop.js?view=diff&rev=534123&r1=534122&r2=534123
> ==============================================================================
> --- myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/dragdrop.js (original)
> +++ myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/dragdrop.js Tue May  1 08:28:43 2007
> @@ -128,7 +128,7 @@
>      this.activeDraggable = draggable;
>    },
>
> -  deactivate: function(draggbale) {
> +  deactivate: function() {
>      this.activeDraggable = null;
>    },
>
> @@ -146,6 +146,7 @@
>      if(!this.activeDraggable) return;
>      this._lastPointer = null;
>      this.activeDraggable.endDrag(event);
> +    this.activeDraggable = null;
>    },
>
>    keyPress: function(event) {
> @@ -191,13 +192,16 @@
>        },
>        reverteffect: function(element, top_offset, left_offset) {
>          var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
> -        element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
> +        element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur});
>        },
>        endeffect: function(element) {
>          new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
>        },
>        zindex: 1000,
>        revert: false,
> +      scroll: false,
> +      scrollSensitivity: 20,
> +      scrollSpeed: 15,
>        snap: false   // false, or xy or [x,y] or function(x,y){ return [x,y] }
>      }, arguments[1] || {});
>
> @@ -207,6 +211,8 @@
>        this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
>      if(!this.handle) this.handle = $(options.handle);
>      if(!this.handle) this.handle = this.element;
> +
> +    if(options.scroll) options.scroll = $(options.scroll);
>
>      Element.makePositioned(this.element); // fix IE
>
> @@ -227,8 +233,8 @@
>
>    currentDelta: function() {
>      return([
> -      parseInt(this.element.style.left || '0'),
> -      parseInt(this.element.style.top || '0')]);
> +      parseInt(Element.getStyle(this.element,'left') || '0'),
> +      parseInt(Element.getStyle(this.element,'top') || '0')]);
>    },
>
>    initDrag: function(event) {
> @@ -238,6 +244,7 @@
>        if(src.tagName && (
>          src.tagName=='INPUT' ||
>          src.tagName=='SELECT' ||
> +        src.tagName=='OPTION' ||
>          src.tagName=='BUTTON' ||
>          src.tagName=='TEXTAREA')) return;
>
> @@ -269,6 +276,11 @@
>        this.element.parentNode.insertBefore(this._clone, this.element);
>      }
>
> +    if(this.options.scroll) {
> +      this.originalScrollLeft = this.options.scroll.scrollLeft;
> +      this.originalScrollTop = this.options.scroll.scrollTop;
> +    }
> +
>      Draggables.notify('onStart', this, event);
>      if(this.options.starteffect) this.options.starteffect(this.element);
>    },
> @@ -281,8 +293,25 @@
>      this.draw(pointer);
>      if(this.options.change) this.options.change(this);
>
> +    if(this.options.scroll) {
> +      //if(this.scrollInterval) this.scroll();
> +      this.stopScrolling();
> +      var p = Position.page(this.options.scroll);
> +      p[0] += this.options.scroll.scrollLeft;
> +      p[1] += this.options.scroll.scrollTop;
> +      p.push(p[0]+this.options.scroll.offsetWidth);
> +      p.push(p[1]+this.options.scroll.offsetHeight);
> +      var speed = [0,0];
> +      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
> +      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
> +      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
> +      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
> +      this.startScrolling(speed);
> +    }
> +
>      // fix AppleWebKit rendering
>      if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
> +
>      Event.stop(event);
>    },
>
> @@ -320,13 +349,14 @@
>    },
>
>    keyPress: function(event) {
> -    if(!event.keyCode==Event.KEY_ESC) return;
> +    if(event.keyCode!=Event.KEY_ESC) return;
>      this.finishDrag(event, false);
>      Event.stop(event);
>    },
>
>    endDrag: function(event) {
>      if(!this.dragging) return;
> +    this.stopScrolling();
>      this.finishDrag(event, true);
>      Event.stop(event);
>    },
> @@ -336,7 +366,14 @@
>      var d = this.currentDelta();
>      pos[0] -= d[0]; pos[1] -= d[1];
>
> -    var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this));
> +    if(this.options.scroll) {
> +      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
> +      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
> +    }
> +
> +    var p = [0,1].map(function(i){
> +      return (point[i]-pos[i]-this.offset[i])
> +    }.bind(this));
>
>      if(this.options.snap) {
>        if(typeof this.options.snap == 'function') {
> @@ -357,6 +394,34 @@
>      if((!this.options.constraint) || (this.options.constraint=='vertical'))
>        style.top  = p[1] + "px";
>      if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
> +  },
> +
> +  stopScrolling: function() {
> +    if(this.scrollInterval) {
> +      clearInterval(this.scrollInterval);
> +      this.scrollInterval = null;
> +    }
> +  },
> +
> +  startScrolling: function(speed) {
> +    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
> +    this.lastScrolled = new Date();
> +    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
> +  },
> +
> +  scroll: function() {
> +    var current = new Date();
> +    var delta = current - this.lastScrolled;
> +    this.lastScrolled = current;
> +    this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
> +    this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
> +
> +    Position.prepare();
> +    Droppables.show(Draggables._lastPointer, this.element);
> +    Draggables.notify('onDrag', this);
> +    this.draw(Draggables._lastPointer);
> +
> +    if(this.options.change) this.options.change(this);
>    }
>  }
>
> @@ -413,7 +478,8 @@
>        only:        false,
>        hoverclass:  null,
>        ghosting:    false,
> -      format:      null,
> +      scroll:      false,
> +      format:      /^[^_]*_(.*)$/,
>        onChange:    Prototype.emptyFunction,
>        onUpdate:    Prototype.emptyFunction
>      }, arguments[1] || {});
> @@ -424,6 +490,7 @@
>      // build options for the draggables
>      var options_for_draggable = {
>        revert:      true,
> +      scroll:      options.scroll,
>        ghosting:    options.ghosting,
>        constraint:  options.constraint,
>        handle:      options.handle };
> @@ -567,18 +634,41 @@
>      Element.show(Sortable._marker);
>    },
>
> -  serialize: function(element) {
> +  sequence: function(element) {
>      element = $(element);
> -    var sortableOptions = this.options(element);
> -    var options = Object.extend({
> -      tag:  sortableOptions.tag,
> -      only: sortableOptions.only,
> -      name: element.id,
> -      format: sortableOptions.format || /^[^_]*_(.*)$/
> -    }, arguments[1] || {});
> +    var options = Object.extend(this.options(element), arguments[1] || {});
> +
>      return $(this.findElements(element, options) || []).map( function(item) {
> -      return (encodeURIComponent(options.name) + "[]=" +
> -              encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : ''));
> -    }).join("&");
> +      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
> +    });
> +  },
> +
> +  setSequence: function(element, new_sequence) {
> +    element = $(element);
> +    var options = Object.extend(this.options(element), arguments[2] || {});
> +
> +    var nodeMap = {};
> +    this.findElements(element, options).each( function(n) {
> +        if (n.id.match(options.format))
> +            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
> +        n.parentNode.removeChild(n);
> +    });
> +
> +    new_sequence.each(function(ident) {
> +        var n = nodeMap[ident];
> +        if (n) {
> +            n[1].appendChild(n[0]);
> +            delete nodeMap[ident];
> +        }
> +    });
> +  },
> +
> +  serialize: function(element) {
> +    element = $(element);
> +    var name = encodeURIComponent(
> +      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
> +    return Sortable.sequence(element, arguments[1]).map( function(item) {
> +      return name + "[]=" + encodeURIComponent(item);
> +    }).join('&');
>    }
>  }
>
> Modified: myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/effects.js
> URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/effects.js?view=diff&rev=534123&r1=534122&r2=534123
> ==============================================================================
> --- myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/effects.js (original)
> +++ myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/effects.js Tue May  1 08:28:43 2007
> @@ -22,23 +22,21 @@
>      }
>    }
>    return(color.length==7 ? color : (arguments[0] || this));
> -}
> +}
>
> -Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
> -  var children = $(element).childNodes;
> -  var text     = '';
> -  var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i');
> -
> -  for (var i = 0; i < children.length; i++) {
> -    if(children[i].nodeType==3) {
> -      text+=children[i].nodeValue;
> -    } else {
> -      if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
> -        text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
> -    }
> -  }
> -
> -  return text;
> +Element.collectTextNodes = function(element) {
> +  return $A($(element).childNodes).collect( function(node) {
> +    return (node.nodeType==3 ? node.nodeValue :
> +      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
> +  }).flatten().join('');
> +}
> +
> +Element.collectTextNodesIgnoreClass = function(element, className) {
> +  return $A($(element).childNodes).collect( function(node) {
> +    return (node.nodeType==3 ? node.nodeValue :
> +      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
> +        Element.collectTextNodesIgnoreClass(node, className) : ''));
> +  }).flatten().join('');
>  }
>
>  Element.setStyle = function(element, style) {
> @@ -129,6 +127,20 @@
>      $A(elements).each( function(element, index) {
>        new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
>      });
> +  },
> +  PAIRS: {
> +    'slide':  ['SlideDown','SlideUp'],
> +    'blind':  ['BlindDown','BlindUp'],
> +    'appear': ['Appear','Fade']
> +  },
> +  toggle: function(element, effect) {
> +    element = $(element);
> +    effect = (effect || 'appear').toLowerCase();
> +    var options = Object.extend({
> +      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
> +    }, arguments[2] || {});
> +    Effect[Element.visible(element) ?
> +      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
>    }
>  };
>
> @@ -166,16 +178,22 @@
>
>  /* ------------- core effects ------------- */
>
> -Effect.Queue = {
> -  effects:  [],
> +Effect.ScopedQueue = Class.create();
> +Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
> +  initialize: function() {
> +    this.effects  = [];
> +    this.interval = null;
> +  },
>    _each: function(iterator) {
>      this.effects._each(iterator);
>    },
> -  interval: null,
>    add: function(effect) {
>      var timestamp = new Date().getTime();
>
> -    switch(effect.options.queue) {
> +    var position = (typeof effect.options.queue == 'string') ?
> +      effect.options.queue : effect.options.queue.position;
> +
> +    switch(position) {
>        case 'front':
>          // move unstarted effects after this effect
>          this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
> @@ -191,7 +209,10 @@
>
>      effect.startOn  += timestamp;
>      effect.finishOn += timestamp;
> -    this.effects.push(effect);
> +
> +    if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
> +      this.effects.push(effect);
> +
>      if(!this.interval)
>        this.interval = setInterval(this.loop.bind(this), 40);
>    },
> @@ -206,32 +227,45 @@
>      var timePos = new Date().getTime();
>      this.effects.invoke('loop', timePos);
>    }
> +});
> +
> +Effect.Queues = {
> +  instances: $H(),
> +  get: function(queueName) {
> +    if(typeof queueName != 'string') return queueName;
> +
> +    if(!this.instances[queueName])
> +      this.instances[queueName] = new Effect.ScopedQueue();
> +
> +    return this.instances[queueName];
> +  }
> +}
> +Effect.Queue = Effect.Queues.get('global');
> +
> +Effect.DefaultOptions = {
> +  transition: Effect.Transitions.sinoidal,
> +  duration:   1.0,   // seconds
> +  fps:        25.0,  // max. 25fps due to Effect.Queue implementation
> +  sync:       false, // true for combining
> +  from:       0.0,
> +  to:         1.0,
> +  delay:      0.0,
> +  queue:      'parallel'
>  }
> -Object.extend(Effect.Queue, Enumerable);
>
>  Effect.Base = function() {};
>  Effect.Base.prototype = {
>    position: null,
> -  setOptions: function(options) {
> -    this.options = Object.extend({
> -      transition: Effect.Transitions.sinoidal,
> -      duration:   1.0,   // seconds
> -      fps:        25.0,  // max. 25fps due to Effect.Queue implementation
> -      sync:       false, // true for combining
> -      from:       0.0,
> -      to:         1.0,
> -      delay:      0.0,
> -      queue:      'parallel'
> -    }, options || {});
> -  },
>    start: function(options) {
> -    this.setOptions(options || {});
> +    this.options      = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
>      this.currentFrame = 0;
>      this.state        = 'idle';
>      this.startOn      = this.options.delay*1000;
>      this.finishOn     = this.startOn + (this.options.duration*1000);
>      this.event('beforeStart');
> -    if(!this.options.sync) Effect.Queue.add(this);
> +    if(!this.options.sync)
> +      Effect.Queues.get(typeof this.options.queue == 'string' ?
> +        'global' : this.options.queue.scope).add(this);
>    },
>    loop: function(timePos) {
>      if(timePos >= this.startOn) {
> @@ -269,7 +303,9 @@
>      }
>    },
>    cancel: function() {
> -    if(!this.options.sync) Effect.Queue.remove(this);
> +    if(!this.options.sync)
> +      Effect.Queues.get(typeof this.options.queue == 'string' ?
> +        'global' : this.options.queue.scope).remove(this);
>      this.state = 'finished';
>    },
>    event: function(eventName) {
> @@ -319,13 +355,16 @@
>    }
>  });
>
> -Effect.MoveBy = Class.create();
> -Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
> -  initialize: function(element, toTop, toLeft) {
> -    this.element      = $(element);
> -    this.toTop        = toTop;
> -    this.toLeft       = toLeft;
> -    this.start(arguments[3]);
> +Effect.Move = Class.create();
> +Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
> +  initialize: function(element) {
> +    this.element = $(element);
> +    var options = Object.extend({
> +      x:    0,
> +      y:    0,
> +      mode: 'relative'
> +    }, arguments[1] || {});
> +    this.start(options);
>    },
>    setup: function() {
>      // Bug in Opera: Opera returns the "real" position of a static element or
> @@ -333,17 +372,28 @@
>      // ==> Always set top and left for position relative elements in your stylesheets
>      // (to 0 if you do not need them)
>      Element.makePositioned(this.element);
> -    this.originalTop  = parseFloat(Element.getStyle(this.element,'top')  || '0');
>      this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
> +    this.originalTop  = parseFloat(Element.getStyle(this.element,'top')  || '0');
> +    if(this.options.mode == 'absolute') {
> +      // absolute movement, so we need to calc deltaX and deltaY
> +      this.options.x = this.options.x - this.originalLeft;
> +      this.options.y = this.options.y - this.originalTop;
> +    }
>    },
>    update: function(position) {
>      Element.setStyle(this.element, {
> -      top:  this.toTop  * position + this.originalTop + 'px',
> -      left: this.toLeft * position + this.originalLeft + 'px'
> +      left: this.options.x  * position + this.originalLeft + 'px',
> +      top:  this.options.y  * position + this.originalTop  + 'px'
>      });
>    }
>  });
>
> +// for backwards compatibility
> +Effect.MoveBy = function(element, toTop, toLeft) {
> +  return new Effect.Move(element,
> +    Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
> +};
> +
>  Effect.Scale = Class.create();
>  Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
>    initialize: function(element, percent) {
> @@ -534,7 +584,6 @@
>
>  Effect.BlindDown = function(element) {
>    element = $(element);
> -  var oldHeight = Element.getStyle(element, 'height');
>    var elementDimensions = Element.getDimensions(element);
>    return new Effect.Scale(element, 100,
>      Object.extend({ scaleContent: false,
> @@ -547,10 +596,9 @@
>          setStyle(effect.element, {height: '0px'});
>          show(effect.element);
>        }},
> -      afterFinishInternal: function(effect) { with(Element) {
> -        undoClipping(effect.element);
> -        setStyle(effect.element, {height: oldHeight});
> -      }}
> +      afterFinishInternal: function(effect) {
> +        Element.undoClipping(effect.element);
> +      }
>      }, arguments[1] || {})
>    );
>  }
> @@ -585,7 +633,7 @@
>      left: Element.getStyle(element, 'left'),
>      opacity: Element.getInlineOpacity(element) };
>    return new Effect.Parallel(
> -    [ new Effect.MoveBy(element, 100, 0, { sync: true }),
> +    [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
>        new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
>      Object.extend(
>        { duration: 0.5,
> @@ -602,18 +650,18 @@
>    var oldStyle = {
>      top: Element.getStyle(element, 'top'),
>      left: Element.getStyle(element, 'left') };
> -  return new Effect.MoveBy(element, 0, 20,
> -    { duration: 0.05, afterFinishInternal: function(effect) {
> -  new Effect.MoveBy(effect.element, 0, -40,
> -    { duration: 0.1, afterFinishInternal: function(effect) {
> -  new Effect.MoveBy(effect.element, 0, 40,
> -    { duration: 0.1, afterFinishInternal: function(effect) {
> -  new Effect.MoveBy(effect.element, 0, -40,
> -    { duration: 0.1, afterFinishInternal: function(effect) {
> -  new Effect.MoveBy(effect.element, 0, 40,
> -    { duration: 0.1, afterFinishInternal: function(effect) {
> -  new Effect.MoveBy(effect.element, 0, -20,
> -    { duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
> +         return new Effect.Move(element,
> +           { x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
> +         new Effect.Move(effect.element,
> +           { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
> +         new Effect.Move(effect.element,
> +           { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
> +         new Effect.Move(effect.element,
> +           { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
> +         new Effect.Move(effect.element,
> +           { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
> +         new Effect.Move(effect.element,
> +           { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
>          undoPositioned(effect.element);
>          setStyle(effect.element, oldStyle);
>    }}}) }}) }}) }}) }}) }});
> @@ -643,8 +691,14 @@
>          (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
>      afterFinishInternal: function(effect) { with(Element) {
>        undoClipping(effect.element);
> -      undoPositioned(effect.element.firstChild);
> -      undoPositioned(effect.element);
> +      // IE will crash if child is undoPositioned first
> +      if(/MSIE/.test(navigator.userAgent)){
> +        undoPositioned(effect.element);
> +        undoPositioned(effect.element.firstChild);
> +      }else{
> +        undoPositioned(effect.element.firstChild);
> +        undoPositioned(effect.element);
> +      }
>        setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
>      }, arguments[1] || {})
>    );
> @@ -694,7 +748,7 @@
>    element = $(element);
>    var options = Object.extend({
>      direction: 'center',
> -    moveTransistion: Effect.Transitions.sinoidal,
> +    moveTransition: Effect.Transitions.sinoidal,
>      scaleTransition: Effect.Transitions.sinoidal,
>      opacityTransition: Effect.Transitions.full
>    }, arguments[1] || {});
> @@ -737,7 +791,9 @@
>        break;
>    }
>
> -  return new Effect.MoveBy(element, initialMoveY, initialMoveX, {
> +  return new Effect.Move(element, {
> +    x: initialMoveX,
> +    y: initialMoveY,
>      duration: 0.01,
>      beforeSetup: function(effect) { with(Element) {
>        hide(effect.element);
> @@ -747,7 +803,7 @@
>      afterFinishInternal: function(effect) {
>        new Effect.Parallel(
>          [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
> -          new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }),
> +          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
>            new Effect.Scale(effect.element, 100, {
>              scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
>              sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
> @@ -768,7 +824,7 @@
>    element = $(element);
>    var options = Object.extend({
>      direction: 'center',
> -    moveTransistion: Effect.Transitions.sinoidal,
> +    moveTransition: Effect.Transitions.sinoidal,
>      scaleTransition: Effect.Transitions.sinoidal,
>      opacityTransition: Effect.Transitions.none
>    }, arguments[1] || {});
> @@ -807,7 +863,7 @@
>    return new Effect.Parallel(
>      [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
>        new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
> -      new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition })
> +      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
>      ], Object.extend({
>           beforeStartInternal: function(effect) { with(Element) {
>             [makePositioned, makeClipping].call(effect.effects[0].element) }},
>
> Modified: myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/scriptaculous.js
> URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/scriptaculous.js?view=diff&rev=534123&r1=534122&r2=534123
> ==============================================================================
> --- myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/scriptaculous.js (original)
> +++ myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/scriptaculous.js Tue May  1 08:28:43 2007
> @@ -20,7 +20,7 @@
>  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>
>  var Scriptaculous = {
> -  Version: '1.5.0',
> +  Version: '1.5.3',
>    require: function(libraryName) {
>      // inserting via DOM fails in Safari 2.0, so brute force approach
>      document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
> @@ -30,18 +30,15 @@
>        parseFloat(Prototype.Version.split(".")[0] + "." +
>                   Prototype.Version.split(".")[1]) < 1.4)
>        throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0");
> -    var scriptTags = document.getElementsByTagName("script");
> -    for(var i=0;i<scriptTags.length;i++) {
> -      if(scriptTags[i].src && scriptTags[i].src.match(/scriptaculous\.js(\?.*)?$/)) {
> -        var path = scriptTags[i].src.replace(/scriptaculous\.js(\?.*)?$/,'');
> -        this.require(path + 'builder.js');
> -        this.require(path + 'effects.js');
> -        this.require(path + 'dragdrop.js');
> -        this.require(path + 'controls.js');
> -        this.require(path + 'slider.js');
> -        break;
> -      }
> -    }
> +
> +    $A(document.getElementsByTagName("script")).findAll( function(s) {
> +      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
> +    }).each( function(s) {
> +      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
> +      var includes = s.src.match(/\?.*load=([a-z,]*)/);
> +      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(
> +       function(include) { Scriptaculous.require(path+include+'.js') });
> +    });
>    }
>  }
>
>
> Added: myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/slider.js
> URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/slider.js?view=auto&rev=534123
> ==============================================================================
> --- myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/slider.js (added)
> +++ myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/slider.js Tue May  1 08:28:43 2007
> @@ -0,0 +1,283 @@
> +// Copyright (c) 2005 Marty Haught, Thomas Fuchs
> +//
> +// See http://script.aculo.us for more info
> +//
> +// Permission is hereby granted, free of charge, to any person obtaining
> +// a copy of this software and associated documentation files (the
> +// "Software"), to deal in the Software without restriction, including
> +// without limitation the rights to use, copy, modify, merge, publish,
> +// distribute, sublicense, and/or sell copies of the Software, and to
> +// permit persons to whom the Software is furnished to do so, subject to
> +// the following conditions:
> +//
> +// The above copyright notice and this permission notice shall be
> +// included in all copies or substantial portions of the Software.
> +//
> +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
> +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
> +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
> +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +
> +if(!Control) var Control = {};
> +Control.Slider = Class.create();
> +
> +// options:
> +//  axis: 'vertical', or 'horizontal' (default)
> +//
> +// callbacks:
> +//  onChange(value)
> +//  onSlide(value)
> +Control.Slider.prototype = {
> +  initialize: function(handle, track, options) {
> +    var slider = this;
> +
> +    if(handle instanceof Array) {
> +      this.handles = handle.collect( function(e) { return $(e) });
> +    } else {
> +      this.handles = [$(handle)];
> +    }
> +
> +    this.track   = $(track);
> +    this.options = options || {};
> +
> +    this.axis      = this.options.axis || 'horizontal';
> +    this.increment = this.options.increment || 1;
> +    this.step      = parseInt(this.options.step || '1');
> +    this.range     = this.options.range || $R(0,1);
> +
> +    this.value     = 0; // assure backwards compat
> +    this.values    = this.handles.map( function() { return 0 });
> +    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
> +    this.options.startSpan = $(this.options.startSpan || null);
> +    this.options.endSpan   = $(this.options.endSpan || null);
> +
> +    this.restricted = this.options.restricted || false;
> +
> +    this.maximum   = this.options.maximum || this.range.end;
> +    this.minimum   = this.options.minimum || this.range.start;
> +
> +    // Will be used to align the handle onto the track, if necessary
> +    this.alignX = parseInt(this.options.alignX || '0');
> +    this.alignY = parseInt(this.options.alignY || '0');
> +
> +    this.trackLength = this.maximumOffset() - this.minimumOffset();
> +    this.handleLength = this.isVertical() ? this.handles[0].offsetHeight : this.handles[0].offsetWidth;
> +
> +    this.active   = false;
> +    this.dragging = false;
> +    this.disabled = false;
> +
> +    if(this.options.disabled) this.setDisabled();
> +
> +    // Allowed values array
> +    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
> +    if(this.allowedValues) {
> +      this.minimum = this.allowedValues.min();
> +      this.maximum = this.allowedValues.max();
> +    }
> +
> +    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
> +    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
> +    this.eventMouseMove = this.update.bindAsEventListener(this);
> +
> +    // Initialize handles in reverse (make sure first handle is active)
> +    this.handles.each( function(h,i) {
> +      i = slider.handles.length-1-i;
> +      slider.setValue(parseFloat(
> +        (slider.options.sliderValue instanceof Array ?
> +          slider.options.sliderValue[i] : slider.options.sliderValue) ||
> +         slider.range.start), i);
> +      Element.makePositioned(h); // fix IE
> +      Event.observe(h, "mousedown", slider.eventMouseDown);
> +    });
> +
> +    Event.observe(this.track, "mousedown", this.eventMouseDown);
> +    Event.observe(document, "mouseup", this.eventMouseUp);
> +    Event.observe(document, "mousemove", this.eventMouseMove);
> +
> +    this.initialized = true;
> +  },
> +  dispose: function() {
> +    var slider = this;
> +    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
> +    Event.stopObserving(document, "mouseup", this.eventMouseUp);
> +    Event.stopObserving(document, "mousemove", this.eventMouseMove);
> +    this.handles.each( function(h) {
> +      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
> +    });
> +  },
> +  setDisabled: function(){
> +    this.disabled = true;
> +  },
> +  setEnabled: function(){
> +    this.disabled = false;
> +  },
> +  getNearestValue: function(value){
> +    if(this.allowedValues){
> +      if(value >= this.allowedValues.max()) return(this.allowedValues.max());
> +      if(value <= this.allowedValues.min()) return(this.allowedValues.min());
> +
> +      var offset = Math.abs(this.allowedValues[0] - value);
> +      var newValue = this.allowedValues[0];
> +      this.allowedValues.each( function(v) {
> +        var currentOffset = Math.abs(v - value);
> +        if(currentOffset <= offset){
> +          newValue = v;
> +          offset = currentOffset;
> +        }
> +      });
> +      return newValue;
> +    }
> +    if(value > this.range.end) return this.range.end;
> +    if(value < this.range.start) return this.range.start;
> +    return value;
> +  },
> +  setValue: function(sliderValue, handleIdx){
> +    if(!this.active) {
> +      this.activeHandle    = this.handles[handleIdx];
> +      this.activeHandleIdx = handleIdx;
> +      this.updateStyles();
> +    }
> +    handleIdx = handleIdx || this.activeHandleIdx || 0;
> +    if(this.initialized && this.restricted) {
> +      if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
> +        sliderValue = this.values[handleIdx-1];
> +      if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
> +        sliderValue = this.values[handleIdx+1];
> +    }
> +    sliderValue = this.getNearestValue(sliderValue);
> +    this.values[handleIdx] = sliderValue;
> +    this.value = this.values[0]; // assure backwards compat
> +
> +    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
> +      this.translateToPx(sliderValue);
> +
> +    this.drawSpans();
> +    if(!this.dragging || !this.event) this.updateFinished();
> +  },
> +  setValueBy: function(delta, handleIdx) {
> +    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
> +      handleIdx || this.activeHandleIdx || 0);
> +  },
> +  translateToPx: function(value) {
> +    return Math.round(
> +      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
> +      (value - this.range.start)) + "px";
> +  },
> +  translateToValue: function(offset) {
> +    return ((offset/(this.trackLength-this.handleLength) *
> +      (this.range.end-this.range.start)) + this.range.start);
> +  },
> +  getRange: function(range) {
> +    var v = this.values.sortBy(Prototype.K);
> +    range = range || 0;
> +    return $R(v[range],v[range+1]);
> +  },
> +  minimumOffset: function(){
> +    return(this.isVertical() ? this.alignY : this.alignX);
> +  },
> +  maximumOffset: function(){
> +    return(this.isVertical() ?
> +      this.track.offsetHeight - this.alignY : this.track.offsetWidth - this.alignX);
> +  },
> +  isVertical:  function(){
> +    return (this.axis == 'vertical');
> +  },
> +  drawSpans: function() {
> +    var slider = this;
> +    if(this.spans)
> +      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
> +    if(this.options.startSpan)
> +      this.setSpan(this.options.startSpan,
> +        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
> +    if(this.options.endSpan)
> +      this.setSpan(this.options.endSpan,
> +        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
> +  },
> +  setSpan: function(span, range) {
> +    if(this.isVertical()) {
> +      span.style.top = this.translateToPx(range.start);
> +      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
> +    } else {
> +      span.style.left = this.translateToPx(range.start);
> +      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
> +    }
> +  },
> +  updateStyles: function() {
> +    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
> +    Element.addClassName(this.activeHandle, 'selected');
> +  },
> +  startDrag: function(event) {
> +    if(Event.isLeftClick(event)) {
> +      if(!this.disabled){
> +        this.active = true;
> +
> +        var handle = Event.element(event);
> +        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
> +        if(handle==this.track) {
> +          var offsets  = Position.cumulativeOffset(this.track);
> +          this.event = event;
> +          this.setValue(this.translateToValue(
> +           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
> +          ));
> +          var offsets  = Position.cumulativeOffset(this.activeHandle);
> +          this.offsetX = (pointer[0] - offsets[0]);
> +          this.offsetY = (pointer[1] - offsets[1]);
> +        } else {
> +          // find the handle (prevents issues with Safari)
> +          while((this.handles.indexOf(handle) == -1) && handle.parentNode)
> +            handle = handle.parentNode;
> +
> +          this.activeHandle    = handle;
> +          this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
> +          this.updateStyles();
> +
> +          var offsets  = Position.cumulativeOffset(this.activeHandle);
> +          this.offsetX = (pointer[0] - offsets[0]);
> +          this.offsetY = (pointer[1] - offsets[1]);
> +        }
> +      }
> +      Event.stop(event);
> +    }
> +  },
> +  update: function(event) {
> +   if(this.active) {
> +      if(!this.dragging) this.dragging = true;
> +      this.draw(event);
> +      // fix AppleWebKit rendering
> +      if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
> +      Event.stop(event);
> +   }
> +  },
> +  draw: function(event) {
> +    var pointer = [Event.pointerX(event), Event.pointerY(event)];
> +    var offsets = Position.cumulativeOffset(this.track);
> +    pointer[0] -= this.offsetX + offsets[0];
> +    pointer[1] -= this.offsetY + offsets[1];
> +    this.event = event;
> +    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
> +    if(this.initialized && this.options.onSlide)
> +      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
> +  },
> +  endDrag: function(event) {
> +    if(this.active && this.dragging) {
> +      this.finishDrag(event, true);
> +      Event.stop(event);
> +    }
> +    this.active = false;
> +    this.dragging = false;
> +  },
> +  finishDrag: function(event, success) {
> +    this.active = false;
> +    this.dragging = false;
> +    this.updateFinished();
> +  },
> +  updateFinished: function() {
> +    if(this.initialized && this.options.onChange)
> +      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
> +    this.event = null;
> +  }
> +}
> \ No newline at end of file
>
>
>