tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

slider.js (10352B)


      1 // script.aculo.us slider.js v1.7.1_beta2, Tue May 15 15:15:45 EDT 2007
      2 
      3 // Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs 
      4 //
      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/
      7 
      8 if(!Control) var Control = {};
      9 Control.Slider = Class.create();
     10 
     11 // options:
     12 //  axis: 'vertical', or 'horizontal' (default)
     13 //
     14 // callbacks:
     15 //  onChange(value)
     16 //  onSlide(value)
     17 Control.Slider.prototype = {
     18  initialize: function(handle, track, options) {
     19    var slider = this;
     20    
     21    if(handle instanceof Array) {
     22      this.handles = handle.collect( function(e) { return $(e) });
     23    } else {
     24      this.handles = [$(handle)];
     25    }
     26    
     27    this.track   = $(track);
     28    this.options = options || {};
     29 
     30    this.axis      = this.options.axis || 'horizontal';
     31    this.increment = this.options.increment || 1;
     32    this.step      = parseInt(this.options.step || '1');
     33    this.range     = this.options.range || $R(0,1);
     34    
     35    this.value     = 0; // assure backwards compat
     36    this.values    = this.handles.map( function() { return 0 });
     37    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
     38    this.options.startSpan = $(this.options.startSpan || null);
     39    this.options.endSpan   = $(this.options.endSpan || null);
     40 
     41    this.restricted = this.options.restricted || false;
     42 
     43    this.maximum   = this.options.maximum || this.range.end;
     44    this.minimum   = this.options.minimum || this.range.start;
     45 
     46    // Will be used to align the handle onto the track, if necessary
     47    this.alignX = parseInt(this.options.alignX || '0');
     48    this.alignY = parseInt(this.options.alignY || '0');
     49    
     50    this.trackLength = this.maximumOffset() - this.minimumOffset();
     51 
     52    this.handleLength = this.isVertical() ? 
     53      (this.handles[0].offsetHeight != 0 ? 
     54        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
     55      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
     56        this.handles[0].style.width.replace(/px$/,""));
     57 
     58    this.active   = false;
     59    this.dragging = false;
     60    this.disabled = false;
     61 
     62    if(this.options.disabled) this.setDisabled();
     63 
     64    // Allowed values array
     65    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
     66    if(this.allowedValues) {
     67      this.minimum = this.allowedValues.min();
     68      this.maximum = this.allowedValues.max();
     69    }
     70 
     71    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
     72    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
     73    this.eventMouseMove = this.update.bindAsEventListener(this);
     74 
     75    // Initialize handles in reverse (make sure first handle is active)
     76    this.handles.each( function(h,i) {
     77      i = slider.handles.length-1-i;
     78      slider.setValue(parseFloat(
     79        (slider.options.sliderValue instanceof Array ? 
     80          slider.options.sliderValue[i] : slider.options.sliderValue) || 
     81         slider.range.start), i);
     82      Element.makePositioned(h); // fix IE
     83      Event.observe(h, "mousedown", slider.eventMouseDown);
     84    });
     85    
     86    Event.observe(this.track, "mousedown", this.eventMouseDown);
     87    Event.observe(document, "mouseup", this.eventMouseUp);
     88    Event.observe(document, "mousemove", this.eventMouseMove);
     89    
     90    this.initialized = true;
     91  },
     92  dispose: function() {
     93    var slider = this;    
     94    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
     95    Event.stopObserving(document, "mouseup", this.eventMouseUp);
     96    Event.stopObserving(document, "mousemove", this.eventMouseMove);
     97    this.handles.each( function(h) {
     98      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
     99    });
    100  },
    101  setDisabled: function(){
    102    this.disabled = true;
    103  },
    104  setEnabled: function(){
    105    this.disabled = false;
    106  },  
    107  getNearestValue: function(value){
    108    if(this.allowedValues){
    109      if(value >= this.allowedValues.max()) return(this.allowedValues.max());
    110      if(value <= this.allowedValues.min()) return(this.allowedValues.min());
    111      
    112      var offset = Math.abs(this.allowedValues[0] - value);
    113      var newValue = this.allowedValues[0];
    114      this.allowedValues.each( function(v) {
    115        var currentOffset = Math.abs(v - value);
    116        if(currentOffset <= offset){
    117          newValue = v;
    118          offset = currentOffset;
    119        } 
    120      });
    121      return newValue;
    122    }
    123    if(value > this.range.end) return this.range.end;
    124    if(value < this.range.start) return this.range.start;
    125    return value;
    126  },
    127  setValue: function(sliderValue, handleIdx){
    128    if(!this.active) {
    129      this.activeHandleIdx = handleIdx || 0;
    130      this.activeHandle    = this.handles[this.activeHandleIdx];
    131      this.updateStyles();
    132    }
    133    handleIdx = handleIdx || this.activeHandleIdx || 0;
    134    if(this.initialized && this.restricted) {
    135      if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
    136        sliderValue = this.values[handleIdx-1];
    137      if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
    138        sliderValue = this.values[handleIdx+1];
    139    }
    140    sliderValue = this.getNearestValue(sliderValue);
    141    this.values[handleIdx] = sliderValue;
    142    this.value = this.values[0]; // assure backwards compat
    143    
    144    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
    145      this.translateToPx(sliderValue);
    146    
    147    this.drawSpans();
    148    if(!this.dragging || !this.event) this.updateFinished();
    149  },
    150  setValueBy: function(delta, handleIdx) {
    151    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
    152      handleIdx || this.activeHandleIdx || 0);
    153  },
    154  translateToPx: function(value) {
    155    return Math.round(
    156      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
    157      (value - this.range.start)) + "px";
    158  },
    159  translateToValue: function(offset) {
    160    return ((offset/(this.trackLength-this.handleLength) * 
    161      (this.range.end-this.range.start)) + this.range.start);
    162  },
    163  getRange: function(range) {
    164    var v = this.values.sortBy(Prototype.K); 
    165    range = range || 0;
    166    return $R(v[range],v[range+1]);
    167  },
    168  minimumOffset: function(){
    169    return(this.isVertical() ? this.alignY : this.alignX);
    170  },
    171  maximumOffset: function(){
    172    return(this.isVertical() ? 
    173      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
    174        this.track.style.height.replace(/px$/,"")) - this.alignY : 
    175      (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
    176        this.track.style.width.replace(/px$/,"")) - this.alignY);
    177  },  
    178  isVertical:  function(){
    179    return (this.axis == 'vertical');
    180  },
    181  drawSpans: function() {
    182    var slider = this;
    183    if(this.spans)
    184      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
    185    if(this.options.startSpan)
    186      this.setSpan(this.options.startSpan,
    187        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
    188    if(this.options.endSpan)
    189      this.setSpan(this.options.endSpan, 
    190        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
    191  },
    192  setSpan: function(span, range) {
    193    if(this.isVertical()) {
    194      span.style.top = this.translateToPx(range.start);
    195      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
    196    } else {
    197      span.style.left = this.translateToPx(range.start);
    198      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
    199    }
    200  },
    201  updateStyles: function() {
    202    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
    203    Element.addClassName(this.activeHandle, 'selected');
    204  },
    205  startDrag: function(event) {
    206    if(Event.isLeftClick(event)) {
    207      if(!this.disabled){
    208        this.active = true;
    209        
    210        var handle = Event.element(event);
    211        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
    212        var track = handle;
    213        if(track==this.track) {
    214          var offsets  = Position.cumulativeOffset(this.track); 
    215          this.event = event;
    216          this.setValue(this.translateToValue( 
    217           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
    218          ));
    219          var offsets  = Position.cumulativeOffset(this.activeHandle);
    220          this.offsetX = (pointer[0] - offsets[0]);
    221          this.offsetY = (pointer[1] - offsets[1]);
    222        } else {
    223          // find the handle (prevents issues with Safari)
    224          while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
    225            handle = handle.parentNode;
    226            
    227          if(this.handles.indexOf(handle)!=-1) {
    228            this.activeHandle    = handle;
    229            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
    230            this.updateStyles();
    231            
    232            var offsets  = Position.cumulativeOffset(this.activeHandle);
    233            this.offsetX = (pointer[0] - offsets[0]);
    234            this.offsetY = (pointer[1] - offsets[1]);
    235          }
    236        }
    237      }
    238      Event.stop(event);
    239    }
    240  },
    241  update: function(event) {
    242   if(this.active) {
    243      if(!this.dragging) this.dragging = true;
    244      this.draw(event);
    245      if(Prototype.Browser.WebKit) window.scrollBy(0,0);
    246      Event.stop(event);
    247   }
    248  },
    249  draw: function(event) {
    250    var pointer = [Event.pointerX(event), Event.pointerY(event)];
    251    var offsets = Position.cumulativeOffset(this.track);
    252    pointer[0] -= this.offsetX + offsets[0];
    253    pointer[1] -= this.offsetY + offsets[1];
    254    this.event = event;
    255    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
    256    if(this.initialized && this.options.onSlide)
    257      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
    258  },
    259  endDrag: function(event) {
    260    if(this.active && this.dragging) {
    261      this.finishDrag(event, true);
    262      Event.stop(event);
    263    }
    264    this.active = false;
    265    this.dragging = false;
    266  },  
    267  finishDrag: function(event, success) {
    268    this.active = false;
    269    this.dragging = false;
    270    this.updateFinished();
    271  },
    272  updateFinished: function() {
    273    if(this.initialized && this.options.onChange) 
    274      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
    275    this.event = null;
    276  }
    277 }