web/wp-includes/js/scriptaculous/slider.js
changeset 194 32102edaa81b
parent 136 bde1974c263b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
     1 // script.aculo.us slider.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
     1 // script.aculo.us slider.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
     2 
     2 
     3 // Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs 
     3 // Copyright (c) 2005-2009 Marty Haught, Thomas Fuchs
     4 //
     4 //
     5 // script.aculo.us is freely distributable under the terms of an MIT-style license.
     5 // script.aculo.us is freely distributable under the terms of an MIT-style license.
     6 // For details, see the script.aculo.us web site: http://script.aculo.us/
     6 // For details, see the script.aculo.us web site: http://script.aculo.us/
     7 
     7 
     8 if (!Control) var Control = { };
     8 if (!Control) var Control = { };
    14 //  onChange(value)
    14 //  onChange(value)
    15 //  onSlide(value)
    15 //  onSlide(value)
    16 Control.Slider = Class.create({
    16 Control.Slider = Class.create({
    17   initialize: function(handle, track, options) {
    17   initialize: function(handle, track, options) {
    18     var slider = this;
    18     var slider = this;
    19     
    19 
    20     if (Object.isArray(handle)) {
    20     if (Object.isArray(handle)) {
    21       this.handles = handle.collect( function(e) { return $(e) });
    21       this.handles = handle.collect( function(e) { return $(e) });
    22     } else {
    22     } else {
    23       this.handles = [$(handle)];
    23       this.handles = [$(handle)];
    24     }
    24     }
    25     
    25 
    26     this.track   = $(track);
    26     this.track   = $(track);
    27     this.options = options || { };
    27     this.options = options || { };
    28 
    28 
    29     this.axis      = this.options.axis || 'horizontal';
    29     this.axis      = this.options.axis || 'horizontal';
    30     this.increment = this.options.increment || 1;
    30     this.increment = this.options.increment || 1;
    31     this.step      = parseInt(this.options.step || '1');
    31     this.step      = parseInt(this.options.step || '1');
    32     this.range     = this.options.range || $R(0,1);
    32     this.range     = this.options.range || $R(0,1);
    33     
    33 
    34     this.value     = 0; // assure backwards compat
    34     this.value     = 0; // assure backwards compat
    35     this.values    = this.handles.map( function() { return 0 });
    35     this.values    = this.handles.map( function() { return 0 });
    36     this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
    36     this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
    37     this.options.startSpan = $(this.options.startSpan || null);
    37     this.options.startSpan = $(this.options.startSpan || null);
    38     this.options.endSpan   = $(this.options.endSpan || null);
    38     this.options.endSpan   = $(this.options.endSpan || null);
    43     this.minimum   = this.options.minimum || this.range.start;
    43     this.minimum   = this.options.minimum || this.range.start;
    44 
    44 
    45     // Will be used to align the handle onto the track, if necessary
    45     // Will be used to align the handle onto the track, if necessary
    46     this.alignX = parseInt(this.options.alignX || '0');
    46     this.alignX = parseInt(this.options.alignX || '0');
    47     this.alignY = parseInt(this.options.alignY || '0');
    47     this.alignY = parseInt(this.options.alignY || '0');
    48     
    48 
    49     this.trackLength = this.maximumOffset() - this.minimumOffset();
    49     this.trackLength = this.maximumOffset() - this.minimumOffset();
    50 
    50 
    51     this.handleLength = this.isVertical() ? 
    51     this.handleLength = this.isVertical() ?
    52       (this.handles[0].offsetHeight != 0 ? 
    52       (this.handles[0].offsetHeight != 0 ?
    53         this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
    53         this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
    54       (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
    54       (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
    55         this.handles[0].style.width.replace(/px$/,""));
    55         this.handles[0].style.width.replace(/px$/,""));
    56 
    56 
    57     this.active   = false;
    57     this.active   = false;
    58     this.dragging = false;
    58     this.dragging = false;
    59     this.disabled = false;
    59     this.disabled = false;
    73 
    73 
    74     // Initialize handles in reverse (make sure first handle is active)
    74     // Initialize handles in reverse (make sure first handle is active)
    75     this.handles.each( function(h,i) {
    75     this.handles.each( function(h,i) {
    76       i = slider.handles.length-1-i;
    76       i = slider.handles.length-1-i;
    77       slider.setValue(parseFloat(
    77       slider.setValue(parseFloat(
    78         (Object.isArray(slider.options.sliderValue) ? 
    78         (Object.isArray(slider.options.sliderValue) ?
    79           slider.options.sliderValue[i] : slider.options.sliderValue) || 
    79           slider.options.sliderValue[i] : slider.options.sliderValue) ||
    80          slider.range.start), i);
    80          slider.range.start), i);
    81       h.makePositioned().observe("mousedown", slider.eventMouseDown);
    81       h.makePositioned().observe("mousedown", slider.eventMouseDown);
    82     });
    82     });
    83     
    83 
    84     this.track.observe("mousedown", this.eventMouseDown);
    84     this.track.observe("mousedown", this.eventMouseDown);
    85     document.observe("mouseup", this.eventMouseUp);
    85     document.observe("mouseup", this.eventMouseUp);
    86     document.observe("mousemove", this.eventMouseMove);
    86     document.observe("mousemove", this.eventMouseMove);
    87     
    87 
    88     this.initialized = true;
    88     this.initialized = true;
    89   },
    89   },
    90   dispose: function() {
    90   dispose: function() {
    91     var slider = this;    
    91     var slider = this;
    92     Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
    92     Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
    93     Event.stopObserving(document, "mouseup", this.eventMouseUp);
    93     Event.stopObserving(document, "mouseup", this.eventMouseUp);
    94     Event.stopObserving(document, "mousemove", this.eventMouseMove);
    94     Event.stopObserving(document, "mousemove", this.eventMouseMove);
    95     this.handles.each( function(h) {
    95     this.handles.each( function(h) {
    96       Event.stopObserving(h, "mousedown", slider.eventMouseDown);
    96       Event.stopObserving(h, "mousedown", slider.eventMouseDown);
    99   setDisabled: function(){
    99   setDisabled: function(){
   100     this.disabled = true;
   100     this.disabled = true;
   101   },
   101   },
   102   setEnabled: function(){
   102   setEnabled: function(){
   103     this.disabled = false;
   103     this.disabled = false;
   104   },  
   104   },
   105   getNearestValue: function(value){
   105   getNearestValue: function(value){
   106     if (this.allowedValues){
   106     if (this.allowedValues){
   107       if (value >= this.allowedValues.max()) return(this.allowedValues.max());
   107       if (value >= this.allowedValues.max()) return(this.allowedValues.max());
   108       if (value <= this.allowedValues.min()) return(this.allowedValues.min());
   108       if (value <= this.allowedValues.min()) return(this.allowedValues.min());
   109       
   109 
   110       var offset = Math.abs(this.allowedValues[0] - value);
   110       var offset = Math.abs(this.allowedValues[0] - value);
   111       var newValue = this.allowedValues[0];
   111       var newValue = this.allowedValues[0];
   112       this.allowedValues.each( function(v) {
   112       this.allowedValues.each( function(v) {
   113         var currentOffset = Math.abs(v - value);
   113         var currentOffset = Math.abs(v - value);
   114         if (currentOffset <= offset){
   114         if (currentOffset <= offset){
   115           newValue = v;
   115           newValue = v;
   116           offset = currentOffset;
   116           offset = currentOffset;
   117         } 
   117         }
   118       });
   118       });
   119       return newValue;
   119       return newValue;
   120     }
   120     }
   121     if (value > this.range.end) return this.range.end;
   121     if (value > this.range.end) return this.range.end;
   122     if (value < this.range.start) return this.range.start;
   122     if (value < this.range.start) return this.range.start;
   136         sliderValue = this.values[handleIdx+1];
   136         sliderValue = this.values[handleIdx+1];
   137     }
   137     }
   138     sliderValue = this.getNearestValue(sliderValue);
   138     sliderValue = this.getNearestValue(sliderValue);
   139     this.values[handleIdx] = sliderValue;
   139     this.values[handleIdx] = sliderValue;
   140     this.value = this.values[0]; // assure backwards compat
   140     this.value = this.values[0]; // assure backwards compat
   141     
   141 
   142     this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
   142     this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
   143       this.translateToPx(sliderValue);
   143       this.translateToPx(sliderValue);
   144     
   144 
   145     this.drawSpans();
   145     this.drawSpans();
   146     if (!this.dragging || !this.event) this.updateFinished();
   146     if (!this.dragging || !this.event) this.updateFinished();
   147   },
   147   },
   148   setValueBy: function(delta, handleIdx) {
   148   setValueBy: function(delta, handleIdx) {
   149     this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
   149     this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
   150       handleIdx || this.activeHandleIdx || 0);
   150       handleIdx || this.activeHandleIdx || 0);
   151   },
   151   },
   152   translateToPx: function(value) {
   152   translateToPx: function(value) {
   153     return Math.round(
   153     return Math.round(
   154       ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
   154       ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
   155       (value - this.range.start)) + "px";
   155       (value - this.range.start)) + "px";
   156   },
   156   },
   157   translateToValue: function(offset) {
   157   translateToValue: function(offset) {
   158     return ((offset/(this.trackLength-this.handleLength) * 
   158     return ((offset/(this.trackLength-this.handleLength) *
   159       (this.range.end-this.range.start)) + this.range.start);
   159       (this.range.end-this.range.start)) + this.range.start);
   160   },
   160   },
   161   getRange: function(range) {
   161   getRange: function(range) {
   162     var v = this.values.sortBy(Prototype.K); 
   162     var v = this.values.sortBy(Prototype.K);
   163     range = range || 0;
   163     range = range || 0;
   164     return $R(v[range],v[range+1]);
   164     return $R(v[range],v[range+1]);
   165   },
   165   },
   166   minimumOffset: function(){
   166   minimumOffset: function(){
   167     return(this.isVertical() ? this.alignY : this.alignX);
   167     return(this.isVertical() ? this.alignY : this.alignX);
   168   },
   168   },
   169   maximumOffset: function(){
   169   maximumOffset: function(){
   170     return(this.isVertical() ? 
   170     return(this.isVertical() ?
   171       (this.track.offsetHeight != 0 ? this.track.offsetHeight :
   171       (this.track.offsetHeight != 0 ? this.track.offsetHeight :
   172         this.track.style.height.replace(/px$/,"")) - this.alignY : 
   172         this.track.style.height.replace(/px$/,"")) - this.alignY :
   173       (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
   173       (this.track.offsetWidth != 0 ? this.track.offsetWidth :
   174         this.track.style.width.replace(/px$/,"")) - this.alignX);
   174         this.track.style.width.replace(/px$/,"")) - this.alignX);
   175   },  
   175   },
   176   isVertical:  function(){
   176   isVertical:  function(){
   177     return (this.axis == 'vertical');
   177     return (this.axis == 'vertical');
   178   },
   178   },
   179   drawSpans: function() {
   179   drawSpans: function() {
   180     var slider = this;
   180     var slider = this;
   182       $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
   182       $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
   183     if (this.options.startSpan)
   183     if (this.options.startSpan)
   184       this.setSpan(this.options.startSpan,
   184       this.setSpan(this.options.startSpan,
   185         $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
   185         $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
   186     if (this.options.endSpan)
   186     if (this.options.endSpan)
   187       this.setSpan(this.options.endSpan, 
   187       this.setSpan(this.options.endSpan,
   188         $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
   188         $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
   189   },
   189   },
   190   setSpan: function(span, range) {
   190   setSpan: function(span, range) {
   191     if (this.isVertical()) {
   191     if (this.isVertical()) {
   192       span.style.top = this.translateToPx(range.start);
   192       span.style.top = this.translateToPx(range.start);
   202   },
   202   },
   203   startDrag: function(event) {
   203   startDrag: function(event) {
   204     if (Event.isLeftClick(event)) {
   204     if (Event.isLeftClick(event)) {
   205       if (!this.disabled){
   205       if (!this.disabled){
   206         this.active = true;
   206         this.active = true;
   207         
   207 
   208         var handle = Event.element(event);
   208         var handle = Event.element(event);
   209         var pointer  = [Event.pointerX(event), Event.pointerY(event)];
   209         var pointer  = [Event.pointerX(event), Event.pointerY(event)];
   210         var track = handle;
   210         var track = handle;
   211         if (track==this.track) {
   211         if (track==this.track) {
   212           var offsets  = Position.cumulativeOffset(this.track); 
   212           var offsets  = this.track.cumulativeOffset();
   213           this.event = event;
   213           this.event = event;
   214           this.setValue(this.translateToValue( 
   214           this.setValue(this.translateToValue(
   215            (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
   215            (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
   216           ));
   216           ));
   217           var offsets  = Position.cumulativeOffset(this.activeHandle);
   217           var offsets  = this.activeHandle.cumulativeOffset();
   218           this.offsetX = (pointer[0] - offsets[0]);
   218           this.offsetX = (pointer[0] - offsets[0]);
   219           this.offsetY = (pointer[1] - offsets[1]);
   219           this.offsetY = (pointer[1] - offsets[1]);
   220         } else {
   220         } else {
   221           // find the handle (prevents issues with Safari)
   221           // find the handle (prevents issues with Safari)
   222           while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
   222           while((this.handles.indexOf(handle) == -1) && handle.parentNode)
   223             handle = handle.parentNode;
   223             handle = handle.parentNode;
   224             
   224 
   225           if (this.handles.indexOf(handle)!=-1) {
   225           if (this.handles.indexOf(handle)!=-1) {
   226             this.activeHandle    = handle;
   226             this.activeHandle    = handle;
   227             this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
   227             this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
   228             this.updateStyles();
   228             this.updateStyles();
   229             
   229 
   230             var offsets  = Position.cumulativeOffset(this.activeHandle);
   230             var offsets  = this.activeHandle.cumulativeOffset();
   231             this.offsetX = (pointer[0] - offsets[0]);
   231             this.offsetX = (pointer[0] - offsets[0]);
   232             this.offsetY = (pointer[1] - offsets[1]);
   232             this.offsetY = (pointer[1] - offsets[1]);
   233           }
   233           }
   234         }
   234         }
   235       }
   235       }
   244       Event.stop(event);
   244       Event.stop(event);
   245    }
   245    }
   246   },
   246   },
   247   draw: function(event) {
   247   draw: function(event) {
   248     var pointer = [Event.pointerX(event), Event.pointerY(event)];
   248     var pointer = [Event.pointerX(event), Event.pointerY(event)];
   249     var offsets = Position.cumulativeOffset(this.track);
   249     var offsets = this.track.cumulativeOffset();
   250     pointer[0] -= this.offsetX + offsets[0];
   250     pointer[0] -= this.offsetX + offsets[0];
   251     pointer[1] -= this.offsetY + offsets[1];
   251     pointer[1] -= this.offsetY + offsets[1];
   252     this.event = event;
   252     this.event = event;
   253     this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
   253     this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
   254     if (this.initialized && this.options.onSlide)
   254     if (this.initialized && this.options.onSlide)
   259       this.finishDrag(event, true);
   259       this.finishDrag(event, true);
   260       Event.stop(event);
   260       Event.stop(event);
   261     }
   261     }
   262     this.active = false;
   262     this.active = false;
   263     this.dragging = false;
   263     this.dragging = false;
   264   },  
   264   },
   265   finishDrag: function(event, success) {
   265   finishDrag: function(event, success) {
   266     this.active = false;
   266     this.active = false;
   267     this.dragging = false;
   267     this.dragging = false;
   268     this.updateFinished();
   268     this.updateFinished();
   269   },
   269   },
   270   updateFinished: function() {
   270   updateFinished: function() {
   271     if (this.initialized && this.options.onChange) 
   271     if (this.initialized && this.options.onChange)
   272       this.options.onChange(this.values.length>1 ? this.values : this.value, this);
   272       this.options.onChange(this.values.length>1 ? this.values : this.value, this);
   273     this.event = null;
   273     this.event = null;
   274   }
   274   }
   275 });
   275 });