Project

General

Profile

« Previous | Next » 

Revision 2364

rake rails:update

View differences:

sandbox/rails-2.2/config/boot.rb
67 67

  
68 68
    class << self
69 69
      def rubygems_version
70
        Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
70
        Gem::RubyGemsVersion rescue nil
71 71
      end
72 72

  
73 73
      def gem_version
......
82 82

  
83 83
      def load_rubygems
84 84
        require 'rubygems'
85

  
86
        unless rubygems_version >= '0.9.4'
87
          $stderr.puts %(Rails requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.)
85
        min_version = '1.3.1'
86
        unless rubygems_version >= min_version
87
          $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
88 88
          exit 1
89 89
        end
90 90

  
91 91
      rescue LoadError
92
        $stderr.puts %(Rails requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org)
92
        $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
93 93
        exit 1
94 94
      end
95 95

  
sandbox/rails-2.2/config/environment.rb
5 5
# ENV['RAILS_ENV'] ||= 'production'
6 6

  
7 7
# Specifies gem version of Rails to use when vendor/rails is not present
8
RAILS_GEM_VERSION = '2.1.2' unless defined? RAILS_GEM_VERSION
8
RAILS_GEM_VERSION = '2.2.2' unless defined? RAILS_GEM_VERSION
9 9

  
10 10
# Bootstrap the Rails environment, frameworks, and default configuration
11 11
require File.join(File.dirname(__FILE__), 'boot')
sandbox/rails-2.2/public/javascripts/controls.js
1 1
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
//           (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
3
//           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
2
//           (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
3
//           (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
4 4
// Contributors:
5 5
//  Richard Livsey
6 6
//  Rahul Bhargava
7 7
//  Rob Wills
8
// 
8
//
9 9
// script.aculo.us is freely distributable under the terms of an MIT-style license.
10 10
// For details, see the script.aculo.us web site: http://script.aculo.us/
11 11

  
12
// Autocompleter.Base handles all the autocompletion functionality 
12
// Autocompleter.Base handles all the autocompletion functionality
13 13
// that's independent of the data source for autocompletion. This
14 14
// includes drawing the autocompletion menu, observing keyboard
15 15
// and mouse events, and similar.
16 16
//
17
// Specific autocompleters need to provide, at the very least, 
17
// Specific autocompleters need to provide, at the very least,
18 18
// a getUpdatedChoices function that will be invoked every time
19
// the text inside the monitored textbox changes. This method 
19
// the text inside the monitored textbox changes. This method
20 20
// should get the text for which to provide autocompletion by
21 21
// invoking this.getToken(), NOT by directly accessing
22 22
// this.element.value. This is to allow incremental tokenized
......
30 30
// will incrementally autocomplete with a comma as the token.
31 31
// Additionally, ',' in the above example can be replaced with
32 32
// a token array, e.g. { tokens: [',', '\n'] } which
33
// enables autocompletion on multiple tokens. This is most 
34
// useful when one of the tokens is \n (a newline), as it 
33
// enables autocompletion on multiple tokens. This is most
34
// useful when one of the tokens is \n (a newline), as it
35 35
// allows smart autocompletion after linebreaks.
36 36

  
37 37
if(typeof Effect == 'undefined')
38 38
  throw("controls.js requires including script.aculo.us' effects.js library");
39 39

  
40
var Autocompleter = { }
40
var Autocompleter = { };
41 41
Autocompleter.Base = Class.create({
42 42
  baseInitialize: function(element, update, options) {
43
    element          = $(element)
44
    this.element     = element; 
45
    this.update      = $(update);  
46
    this.hasFocus    = false; 
47
    this.changed     = false; 
48
    this.active      = false; 
49
    this.index       = 0;     
43
    element          = $(element);
44
    this.element     = element;
45
    this.update      = $(update);
46
    this.hasFocus    = false;
47
    this.changed     = false;
48
    this.active      = false;
49
    this.index       = 0;
50 50
    this.entryCount  = 0;
51 51
    this.oldElementValue = this.element.value;
52 52

  
......
59 59
    this.options.tokens       = this.options.tokens || [];
60 60
    this.options.frequency    = this.options.frequency || 0.4;
61 61
    this.options.minChars     = this.options.minChars || 1;
62
    this.options.onShow       = this.options.onShow || 
63
      function(element, update){ 
62
    this.options.onShow       = this.options.onShow ||
63
      function(element, update){
64 64
        if(!update.style.position || update.style.position=='absolute') {
65 65
          update.style.position = 'absolute';
66 66
          Position.clone(element, update, {
67
            setHeight: false, 
67
            setHeight: false,
68 68
            offsetTop: element.offsetHeight
69 69
          });
70 70
        }
71 71
        Effect.Appear(update,{duration:0.15});
72 72
      };
73
    this.options.onHide = this.options.onHide || 
73
    this.options.onHide = this.options.onHide ||
74 74
      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
75 75

  
76
    if(typeof(this.options.tokens) == 'string') 
76
    if(typeof(this.options.tokens) == 'string')
77 77
      this.options.tokens = new Array(this.options.tokens);
78 78
    // Force carriage returns as token delimiters anyway
79 79
    if (!this.options.tokens.include('\n'))
80 80
      this.options.tokens.push('\n');
81 81

  
82 82
    this.observer = null;
83
    
83

  
84 84
    this.element.setAttribute('autocomplete','off');
85 85

  
86 86
    Element.hide(this.update);
......
91 91

  
92 92
  show: function() {
93 93
    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
94
    if(!this.iefix && 
94
    if(!this.iefix &&
95 95
      (Prototype.Browser.IE) &&
96 96
      (Element.getStyle(this.update, 'position')=='absolute')) {
97
      new Insertion.After(this.update, 
97
      new Insertion.After(this.update,
98 98
       '<iframe id="' + this.update.id + '_iefix" '+
99 99
       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
100 100
       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
......
102 102
    }
103 103
    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
104 104
  },
105
  
105

  
106 106
  fixIEOverlapping: function() {
107 107
    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
108 108
    this.iefix.style.zIndex = 1;
......
150 150
         Event.stop(event);
151 151
         return;
152 152
      }
153
     else 
154
       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
153
     else
154
       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
155 155
         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
156 156

  
157 157
    this.changed = true;
158 158
    this.hasFocus = true;
159 159

  
160 160
    if(this.observer) clearTimeout(this.observer);
161
      this.observer = 
161
      this.observer =
162 162
        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
163 163
  },
164 164

  
......
170 170

  
171 171
  onHover: function(event) {
172 172
    var element = Event.findElement(event, 'LI');
173
    if(this.index != element.autocompleteIndex) 
173
    if(this.index != element.autocompleteIndex)
174 174
    {
175 175
        this.index = element.autocompleteIndex;
176 176
        this.render();
177 177
    }
178 178
    Event.stop(event);
179 179
  },
180
  
180

  
181 181
  onClick: function(event) {
182 182
    var element = Event.findElement(event, 'LI');
183 183
    this.index = element.autocompleteIndex;
184 184
    this.selectEntry();
185 185
    this.hide();
186 186
  },
187
  
187

  
188 188
  onBlur: function(event) {
189 189
    // needed to make click events working
190 190
    setTimeout(this.hide.bind(this), 250);
191 191
    this.hasFocus = false;
192
    this.active = false;     
193
  }, 
194
  
192
    this.active = false;
193
  },
194

  
195 195
  render: function() {
196 196
    if(this.entryCount > 0) {
197 197
      for (var i = 0; i < this.entryCount; i++)
198
        this.index==i ? 
199
          Element.addClassName(this.getEntry(i),"selected") : 
198
        this.index==i ?
199
          Element.addClassName(this.getEntry(i),"selected") :
200 200
          Element.removeClassName(this.getEntry(i),"selected");
201
      if(this.hasFocus) { 
201
      if(this.hasFocus) {
202 202
        this.show();
203 203
        this.active = true;
204 204
      }
......
207 207
      this.hide();
208 208
    }
209 209
  },
210
  
210

  
211 211
  markPrevious: function() {
212
    if(this.index > 0) this.index--
212
    if(this.index > 0) this.index--;
213 213
      else this.index = this.entryCount-1;
214 214
    this.getEntry(this.index).scrollIntoView(true);
215 215
  },
216
  
216

  
217 217
  markNext: function() {
218
    if(this.index < this.entryCount-1) this.index++
218
    if(this.index < this.entryCount-1) this.index++;
219 219
      else this.index = 0;
220 220
    this.getEntry(this.index).scrollIntoView(false);
221 221
  },
222
  
222

  
223 223
  getEntry: function(index) {
224 224
    return this.update.firstChild.childNodes[index];
225 225
  },
226
  
226

  
227 227
  getCurrentEntry: function() {
228 228
    return this.getEntry(this.index);
229 229
  },
230
  
230

  
231 231
  selectEntry: function() {
232 232
    this.active = false;
233 233
    this.updateElement(this.getCurrentEntry());
......
244 244
      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
245 245
    } else
246 246
      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
247
    
247

  
248 248
    var bounds = this.getTokenBounds();
249 249
    if (bounds[0] != -1) {
250 250
      var newValue = this.element.value.substr(0, bounds[0]);
......
257 257
    }
258 258
    this.oldElementValue = this.element.value;
259 259
    this.element.focus();
260
    
260

  
261 261
    if (this.options.afterUpdateElement)
262 262
      this.options.afterUpdateElement(this.element, selectedElement);
263 263
  },
......
269 269
      Element.cleanWhitespace(this.update.down());
270 270

  
271 271
      if(this.update.firstChild && this.update.down().childNodes) {
272
        this.entryCount = 
272
        this.entryCount =
273 273
          this.update.down().childNodes.length;
274 274
        for (var i = 0; i < this.entryCount; i++) {
275 275
          var entry = this.getEntry(i);
276 276
          entry.autocompleteIndex = i;
277 277
          this.addObservers(entry);
278 278
        }
279
      } else { 
279
      } else {
280 280
        this.entryCount = 0;
281 281
      }
282 282

  
283 283
      this.stopIndicator();
284 284
      this.index = 0;
285
      
285

  
286 286
      if(this.entryCount==1 && this.options.autoSelect) {
287 287
        this.selectEntry();
288 288
        this.hide();
......
298 298
  },
299 299

  
300 300
  onObserverEvent: function() {
301
    this.changed = false;   
301
    this.changed = false;
302 302
    this.tokenBounds = null;
303 303
    if(this.getToken().length>=this.options.minChars) {
304 304
      this.getUpdatedChoices();
......
351 351

  
352 352
  getUpdatedChoices: function() {
353 353
    this.startIndicator();
354
    
355
    var entry = encodeURIComponent(this.options.paramName) + '=' + 
354

  
355
    var entry = encodeURIComponent(this.options.paramName) + '=' +
356 356
      encodeURIComponent(this.getToken());
357 357

  
358 358
    this.options.parameters = this.options.callback ?
359 359
      this.options.callback(this.element, entry) : entry;
360 360

  
361
    if(this.options.defaultParams) 
361
    if(this.options.defaultParams)
362 362
      this.options.parameters += '&' + this.options.defaultParams;
363
    
363

  
364 364
    new Ajax.Request(this.url, this.options);
365 365
  },
366 366

  
......
382 382
// - choices - How many autocompletion choices to offer
383 383
//
384 384
// - partialSearch - If false, the autocompleter will match entered
385
//                    text only at the beginning of strings in the 
385
//                    text only at the beginning of strings in the
386 386
//                    autocomplete array. Defaults to true, which will
387 387
//                    match text at the beginning of any *word* in the
388 388
//                    strings in the autocomplete array. If you want to
......
399 399
// - ignoreCase - Whether to ignore case when autocompleting.
400 400
//                 Defaults to true.
401 401
//
402
// It's possible to pass in a custom function as the 'selector' 
402
// It's possible to pass in a custom function as the 'selector'
403 403
// option, if you prefer to write your own autocompletion logic.
404 404
// In that case, the other options above will not apply unless
405 405
// you support them.
......
427 427
        var entry     = instance.getToken();
428 428
        var count     = 0;
429 429

  
430
        for (var i = 0; i < instance.options.array.length &&  
431
          ret.length < instance.options.choices ; i++) { 
430
        for (var i = 0; i < instance.options.array.length &&
431
          ret.length < instance.options.choices ; i++) {
432 432

  
433 433
          var elem = instance.options.array[i];
434
          var foundPos = instance.options.ignoreCase ? 
435
            elem.toLowerCase().indexOf(entry.toLowerCase()) : 
434
          var foundPos = instance.options.ignoreCase ?
435
            elem.toLowerCase().indexOf(entry.toLowerCase()) :
436 436
            elem.indexOf(entry);
437 437

  
438 438
          while (foundPos != -1) {
439
            if (foundPos == 0 && elem.length != entry.length) { 
440
              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
439
            if (foundPos == 0 && elem.length != entry.length) {
440
              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
441 441
                elem.substr(entry.length) + "</li>");
442 442
              break;
443
            } else if (entry.length >= instance.options.partialChars && 
443
            } else if (entry.length >= instance.options.partialChars &&
444 444
              instance.options.partialSearch && foundPos != -1) {
445 445
              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
446 446
                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
......
450 450
              }
451 451
            }
452 452

  
453
            foundPos = instance.options.ignoreCase ? 
454
              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
453
            foundPos = instance.options.ignoreCase ?
454
              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
455 455
              elem.indexOf(entry, foundPos + 1);
456 456

  
457 457
          }
458 458
        }
459 459
        if (partial.length)
460
          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
460
          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
461 461
        return "<ul>" + ret.join('') + "</ul>";
462 462
      }
463 463
    }, options || { });
......
474 474
  setTimeout(function() {
475 475
    Field.activate(field);
476 476
  }, 1);
477
}
477
};
478 478

  
479 479
Ajax.InPlaceEditor = Class.create({
480 480
  initialize: function(element, url, options) {
......
604 604
    this.triggerCallback('onEnterHover');
605 605
  },
606 606
  getText: function() {
607
    return this.element.innerHTML;
607
    return this.element.innerHTML.unescapeHTML();
608 608
  },
609 609
  handleAJAXFailure: function(transport) {
610 610
    this.triggerCallback('onFailure', transport);
......
780 780
      onSuccess: function(transport) {
781 781
        var js = transport.responseText.strip();
782 782
        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
783
          throw 'Server returned an invalid collection representation.';
783
          throw('Server returned an invalid collection representation.');
784 784
        this._collection = eval(js);
785 785
        this.checkForExternalText();
786 786
      }.bind(this),
......
937 937
  loadingCollectionText: 'Loading options...'
938 938
};
939 939

  
940
// Delayed observer, like Form.Element.Observer, 
940
// Delayed observer, like Form.Element.Observer,
941 941
// but waits for delay after last key input
942 942
// Ideal for live-search fields
943 943

  
......
947 947
    this.element   = $(element);
948 948
    this.callback  = callback;
949 949
    this.timer     = null;
950
    this.lastValue = $F(this.element); 
950
    this.lastValue = $F(this.element);
951 951
    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
952 952
  },
953 953
  delayedListener: function(event) {
......
960 960
    this.timer = null;
961 961
    this.callback(this.element, $F(this.element));
962 962
  }
963
});
963
});
sandbox/rails-2.2/public/javascripts/dragdrop.js
1 1
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
//           (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, [email protected])
3
// 
2
//           (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, [email protected])
3
//
4 4
// script.aculo.us is freely distributable under the terms of an MIT-style license.
5 5
// For details, see the script.aculo.us web site: http://script.aculo.us/
6 6

  
......
32 32
        options._containers.push($(containment));
33 33
      }
34 34
    }
35
    
35

  
36 36
    if(options.accept) options.accept = [options.accept].flatten();
37 37

  
38 38
    Element.makePositioned(element); // fix IE
......
40 40

  
41 41
    this.drops.push(options);
42 42
  },
43
  
43

  
44 44
  findDeepestChild: function(drops) {
45 45
    deepest = drops[0];
46
      
46

  
47 47
    for (i = 1; i < drops.length; ++i)
48 48
      if (Element.isParent(drops[i].element, deepest.element))
49 49
        deepest = drops[i];
50
    
50

  
51 51
    return deepest;
52 52
  },
53 53

  
54 54
  isContained: function(element, drop) {
55 55
    var containmentNode;
56 56
    if(drop.tree) {
57
      containmentNode = element.treeNode; 
57
      containmentNode = element.treeNode;
58 58
    } else {
59 59
      containmentNode = element.parentNode;
60 60
    }
61 61
    return drop._containers.detect(function(c) { return containmentNode == c });
62 62
  },
63
  
63

  
64 64
  isAffected: function(point, element, drop) {
65 65
    return (
66 66
      (drop.element!=element) &&
67 67
      ((!drop._containers) ||
68 68
        this.isContained(element, drop)) &&
69 69
      ((!drop.accept) ||
70
        (Element.classNames(element).detect( 
70
        (Element.classNames(element).detect(
71 71
          function(v) { return drop.accept.include(v) } ) )) &&
72 72
      Position.within(drop.element, point[0], point[1]) );
73 73
  },
......
87 87
  show: function(point, element) {
88 88
    if(!this.drops.length) return;
89 89
    var drop, affected = [];
90
    
90

  
91 91
    this.drops.each( function(drop) {
92 92
      if(Droppables.isAffected(point, element, drop))
93 93
        affected.push(drop);
94 94
    });
95
        
95

  
96 96
    if(affected.length>0)
97 97
      drop = Droppables.findDeepestChild(affected);
98 98

  
......
101 101
      Position.within(drop.element, point[0], point[1]);
102 102
      if(drop.onHover)
103 103
        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
104
      
104

  
105 105
      if (drop != this.last_active) Droppables.activate(drop);
106 106
    }
107 107
  },
......
112 112

  
113 113
    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
114 114
      if (this.last_active.onDrop) {
115
        this.last_active.onDrop(element, this.last_active.element, event); 
116
        return true; 
115
        this.last_active.onDrop(element, this.last_active.element, event);
116
        return true;
117 117
      }
118 118
  },
119 119

  
......
121 121
    if(this.last_active)
122 122
      this.deactivate(this.last_active);
123 123
  }
124
}
124
};
125 125

  
126 126
var Draggables = {
127 127
  drags: [],
128 128
  observers: [],
129
  
129

  
130 130
  register: function(draggable) {
131 131
    if(this.drags.length == 0) {
132 132
      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
133 133
      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
134 134
      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
135
      
135

  
136 136
      Event.observe(document, "mouseup", this.eventMouseUp);
137 137
      Event.observe(document, "mousemove", this.eventMouseMove);
138 138
      Event.observe(document, "keypress", this.eventKeypress);
139 139
    }
140 140
    this.drags.push(draggable);
141 141
  },
142
  
142

  
143 143
  unregister: function(draggable) {
144 144
    this.drags = this.drags.reject(function(d) { return d==draggable });
145 145
    if(this.drags.length == 0) {
......
148 148
      Event.stopObserving(document, "keypress", this.eventKeypress);
149 149
    }
150 150
  },
151
  
151

  
152 152
  activate: function(draggable) {
153
    if(draggable.options.delay) { 
154
      this._timeout = setTimeout(function() { 
155
        Draggables._timeout = null; 
156
        window.focus(); 
157
        Draggables.activeDraggable = draggable; 
158
      }.bind(this), draggable.options.delay); 
153
    if(draggable.options.delay) {
154
      this._timeout = setTimeout(function() {
155
        Draggables._timeout = null;
156
        window.focus();
157
        Draggables.activeDraggable = draggable;
158
      }.bind(this), draggable.options.delay);
159 159
    } else {
160 160
      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
161 161
      this.activeDraggable = draggable;
162 162
    }
163 163
  },
164
  
164

  
165 165
  deactivate: function() {
166 166
    this.activeDraggable = null;
167 167
  },
168
  
168

  
169 169
  updateDrag: function(event) {
170 170
    if(!this.activeDraggable) return;
171 171
    var pointer = [Event.pointerX(event), Event.pointerY(event)];
......
173 173
    // the same coordinates, prevent needless redrawing (moz bug?)
174 174
    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
175 175
    this._lastPointer = pointer;
176
    
176

  
177 177
    this.activeDraggable.updateDrag(event, pointer);
178 178
  },
179
  
179

  
180 180
  endDrag: function(event) {
181
    if(this._timeout) { 
182
      clearTimeout(this._timeout); 
183
      this._timeout = null; 
181
    if(this._timeout) {
182
      clearTimeout(this._timeout);
183
      this._timeout = null;
184 184
    }
185 185
    if(!this.activeDraggable) return;
186 186
    this._lastPointer = null;
187 187
    this.activeDraggable.endDrag(event);
188 188
    this.activeDraggable = null;
189 189
  },
190
  
190

  
191 191
  keyPress: function(event) {
192 192
    if(this.activeDraggable)
193 193
      this.activeDraggable.keyPress(event);
194 194
  },
195
  
195

  
196 196
  addObserver: function(observer) {
197 197
    this.observers.push(observer);
198 198
    this._cacheObserverCallbacks();
199 199
  },
200
  
200

  
201 201
  removeObserver: function(element) {  // element instead of observer fixes mem leaks
202 202
    this.observers = this.observers.reject( function(o) { return o.element==element });
203 203
    this._cacheObserverCallbacks();
204 204
  },
205
  
205

  
206 206
  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
207 207
    if(this[eventName+'Count'] > 0)
208 208
      this.observers.each( function(o) {
......
210 210
      });
211 211
    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
212 212
  },
213
  
213

  
214 214
  _cacheObserverCallbacks: function() {
215 215
    ['onStart','onEnd','onDrag'].each( function(eventName) {
216 216
      Draggables[eventName+'Count'] = Draggables.observers.select(
......
218 218
      ).length;
219 219
    });
220 220
  }
221
}
221
};
222 222

  
223 223
/*--------------------------------------------------------------------------*/
224 224

  
......
234 234
      },
235 235
      endeffect: function(element) {
236 236
        var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
237
        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 
237
        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
238 238
          queue: {scope:'_draggable', position:'end'},
239
          afterFinish: function(){ 
240
            Draggable._dragging[element] = false 
239
          afterFinish: function(){
240
            Draggable._dragging[element] = false
241 241
          }
242
        }); 
242
        });
243 243
      },
244 244
      zindex: 1000,
245 245
      revert: false,
......
250 250
      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
251 251
      delay: 0
252 252
    };
253
    
253

  
254 254
    if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
255 255
      Object.extend(defaults, {
256 256
        starteffect: function(element) {
257 257
          element._opacity = Element.getOpacity(element);
258 258
          Draggable._dragging[element] = true;
259
          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); 
259
          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
260 260
        }
261 261
      });
262
    
262

  
263 263
    var options = Object.extend(defaults, arguments[1] || { });
264 264

  
265 265
    this.element = $(element);
266
    
266

  
267 267
    if(options.handle && Object.isString(options.handle))
268 268
      this.handle = this.element.down('.'+options.handle, 0);
269
    
269

  
270 270
    if(!this.handle) this.handle = $(options.handle);
271 271
    if(!this.handle) this.handle = this.element;
272
    
272

  
273 273
    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
274 274
      options.scroll = $(options.scroll);
275 275
      this._isScrollChild = Element.childOf(this.element, options.scroll);
276 276
    }
277 277

  
278
    Element.makePositioned(this.element); // fix IE    
278
    Element.makePositioned(this.element); // fix IE
279 279

  
280 280
    this.options  = options;
281
    this.dragging = false;   
281
    this.dragging = false;
282 282

  
283 283
    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
284 284
    Event.observe(this.handle, "mousedown", this.eventMouseDown);
285
    
285

  
286 286
    Draggables.register(this);
287 287
  },
288
  
288

  
289 289
  destroy: function() {
290 290
    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
291 291
    Draggables.unregister(this);
292 292
  },
293
  
293

  
294 294
  currentDelta: function() {
295 295
    return([
296 296
      parseInt(Element.getStyle(this.element,'left') || '0'),
297 297
      parseInt(Element.getStyle(this.element,'top') || '0')]);
298 298
  },
299
  
299

  
300 300
  initDrag: function(event) {
301 301
    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
302 302
      Draggable._dragging[this.element]) return;
303
    if(Event.isLeftClick(event)) {    
303
    if(Event.isLeftClick(event)) {
304 304
      // abort on form elements, fixes a Firefox issue
305 305
      var src = Event.element(event);
306 306
      if((tag_name = src.tagName.toUpperCase()) && (
......
309 309
        tag_name=='OPTION' ||
310 310
        tag_name=='BUTTON' ||
311 311
        tag_name=='TEXTAREA')) return;
312
        
312

  
313 313
      var pointer = [Event.pointerX(event), Event.pointerY(event)];
314 314
      var pos     = Position.cumulativeOffset(this.element);
315 315
      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
316
      
316

  
317 317
      Draggables.activate(this);
318 318
      Event.stop(event);
319 319
    }
320 320
  },
321
  
321

  
322 322
  startDrag: function(event) {
323 323
    this.dragging = true;
324 324
    if(!this.delta)
325 325
      this.delta = this.currentDelta();
326
    
326

  
327 327
    if(this.options.zindex) {
328 328
      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
329 329
      this.element.style.zIndex = this.options.zindex;
330 330
    }
331
    
331

  
332 332
    if(this.options.ghosting) {
333 333
      this._clone = this.element.cloneNode(true);
334
      this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
335
      if (!this.element._originallyAbsolute)
334
      this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
335
      if (!this._originallyAbsolute)
336 336
        Position.absolutize(this.element);
337 337
      this.element.parentNode.insertBefore(this._clone, this.element);
338 338
    }
339
    
339

  
340 340
    if(this.options.scroll) {
341 341
      if (this.options.scroll == window) {
342 342
        var where = this._getWindowScroll(this.options.scroll);
......
347 347
        this.originalScrollTop = this.options.scroll.scrollTop;
348 348
      }
349 349
    }
350
    
350

  
351 351
    Draggables.notify('onStart', this, event);
352
        
352

  
353 353
    if(this.options.starteffect) this.options.starteffect(this.element);
354 354
  },
355
  
355

  
356 356
  updateDrag: function(event, pointer) {
357 357
    if(!this.dragging) this.startDrag(event);
358
    
358

  
359 359
    if(!this.options.quiet){
360 360
      Position.prepare();
361 361
      Droppables.show(pointer, this.element);
362 362
    }
363
    
363

  
364 364
    Draggables.notify('onDrag', this, event);
365
    
365

  
366 366
    this.draw(pointer);
367 367
    if(this.options.change) this.options.change(this);
368
    
368

  
369 369
    if(this.options.scroll) {
370 370
      this.stopScrolling();
371
      
371

  
372 372
      var p;
373 373
      if (this.options.scroll == window) {
374 374
        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
......
386 386
      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
387 387
      this.startScrolling(speed);
388 388
    }
389
    
389

  
390 390
    // fix AppleWebKit rendering
391 391
    if(Prototype.Browser.WebKit) window.scrollBy(0,0);
392
    
392

  
393 393
    Event.stop(event);
394 394
  },
395
  
395

  
396 396
  finishDrag: function(event, success) {
397 397
    this.dragging = false;
398
    
398

  
399 399
    if(this.options.quiet){
400 400
      Position.prepare();
401 401
      var pointer = [Event.pointerX(event), Event.pointerY(event)];
......
403 403
    }
404 404

  
405 405
    if(this.options.ghosting) {
406
      if (!this.element._originallyAbsolute)
406
      if (!this._originallyAbsolute)
407 407
        Position.relativize(this.element);
408
      delete this.element._originallyAbsolute;
408
      delete this._originallyAbsolute;
409 409
      Element.remove(this._clone);
410 410
      this._clone = null;
411 411
    }
412 412

  
413
    var dropped = false; 
414
    if(success) { 
415
      dropped = Droppables.fire(event, this.element); 
416
      if (!dropped) dropped = false; 
413
    var dropped = false;
414
    if(success) {
415
      dropped = Droppables.fire(event, this.element);
416
      if (!dropped) dropped = false;
417 417
    }
418 418
    if(dropped && this.options.onDropped) this.options.onDropped(this.element);
419 419
    Draggables.notify('onEnd', this, event);
420 420

  
421 421
    var revert = this.options.revert;
422 422
    if(revert && Object.isFunction(revert)) revert = revert(this.element);
423
    
423

  
424 424
    var d = this.currentDelta();
425 425
    if(revert && this.options.reverteffect) {
426 426
      if (dropped == 0 || revert != 'failure')
......
433 433
    if(this.options.zindex)
434 434
      this.element.style.zIndex = this.originalZ;
435 435

  
436
    if(this.options.endeffect) 
436
    if(this.options.endeffect)
437 437
      this.options.endeffect(this.element);
438
      
438

  
439 439
    Draggables.deactivate(this);
440 440
    Droppables.reset();
441 441
  },
442
  
442

  
443 443
  keyPress: function(event) {
444 444
    if(event.keyCode!=Event.KEY_ESC) return;
445 445
    this.finishDrag(event, false);
446 446
    Event.stop(event);
447 447
  },
448
  
448

  
449 449
  endDrag: function(event) {
450 450
    if(!this.dragging) return;
451 451
    this.stopScrolling();
452 452
    this.finishDrag(event, true);
453 453
    Event.stop(event);
454 454
  },
455
  
455

  
456 456
  draw: function(point) {
457 457
    var pos = Position.cumulativeOffset(this.element);
458 458
    if(this.options.ghosting) {
459 459
      var r   = Position.realOffset(this.element);
460 460
      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
461 461
    }
462
    
462

  
463 463
    var d = this.currentDelta();
464 464
    pos[0] -= d[0]; pos[1] -= d[1];
465
    
465

  
466 466
    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
467 467
      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
468 468
      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
469 469
    }
470
    
471
    var p = [0,1].map(function(i){ 
472
      return (point[i]-pos[i]-this.offset[i]) 
470

  
471
    var p = [0,1].map(function(i){
472
      return (point[i]-pos[i]-this.offset[i])
473 473
    }.bind(this));
474
    
474

  
475 475
    if(this.options.snap) {
476 476
      if(Object.isFunction(this.options.snap)) {
477 477
        p = this.options.snap(p[0],p[1],this);
478 478
      } else {
479 479
      if(Object.isArray(this.options.snap)) {
480 480
        p = p.map( function(v, i) {
481
          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this))
481
          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
482 482
      } else {
483 483
        p = p.map( function(v) {
484
          return (v/this.options.snap).round()*this.options.snap }.bind(this))
484
          return (v/this.options.snap).round()*this.options.snap }.bind(this));
485 485
      }
486 486
    }}
487
    
487

  
488 488
    var style = this.element.style;
489 489
    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
490 490
      style.left = p[0] + "px";
491 491
    if((!this.options.constraint) || (this.options.constraint=='vertical'))
492 492
      style.top  = p[1] + "px";
493
    
493

  
494 494
    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
495 495
  },
496
  
496

  
497 497
  stopScrolling: function() {
498 498
    if(this.scrollInterval) {
499 499
      clearInterval(this.scrollInterval);
......
501 501
      Draggables._lastScrollPointer = null;
502 502
    }
503 503
  },
504
  
504

  
505 505
  startScrolling: function(speed) {
506 506
    if(!(speed[0] || speed[1])) return;
507 507
    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
508 508
    this.lastScrolled = new Date();
509 509
    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
510 510
  },
511
  
511

  
512 512
  scroll: function() {
513 513
    var current = new Date();
514 514
    var delta = current - this.lastScrolled;
......
524 524
      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
525 525
      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
526 526
    }
527
    
527

  
528 528
    Position.prepare();
529 529
    Droppables.show(Draggables._lastPointer, this.element);
530 530
    Draggables.notify('onDrag', this);
......
538 538
        Draggables._lastScrollPointer[1] = 0;
539 539
      this.draw(Draggables._lastScrollPointer);
540 540
    }
541
    
541

  
542 542
    if(this.options.change) this.options.change(this);
543 543
  },
544
  
544

  
545 545
  _getWindowScroll: function(w) {
546 546
    var T, L, W, H;
547 547
    with (w.document) {
......
560 560
        H = documentElement.clientHeight;
561 561
      } else {
562 562
        W = body.offsetWidth;
563
        H = body.offsetHeight
563
        H = body.offsetHeight;
564 564
      }
565 565
    }
566 566
    return { top: T, left: L, width: W, height: H };
......
577 577
    this.observer  = observer;
578 578
    this.lastValue = Sortable.serialize(this.element);
579 579
  },
580
  
580

  
581 581
  onStart: function() {
582 582
    this.lastValue = Sortable.serialize(this.element);
583 583
  },
584
  
584

  
585 585
  onEnd: function() {
586 586
    Sortable.unmark();
587 587
    if(this.lastValue != Sortable.serialize(this.element))
......
591 591

  
592 592
var Sortable = {
593 593
  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
594
  
594

  
595 595
  sortables: { },
596
  
596

  
597 597
  _findRootElement: function(element) {
598
    while (element.tagName.toUpperCase() != "BODY") {  
598
    while (element.tagName.toUpperCase() != "BODY") {
599 599
      if(element.id && Sortable.sortables[element.id]) return element;
600 600
      element = element.parentNode;
601 601
    }
......
606 606
    if(!element) return;
607 607
    return Sortable.sortables[element.id];
608 608
  },
609
  
609

  
610 610
  destroy: function(element){
611
    var s = Sortable.options(element);
612
    
611
    element = $(element);
612
    var s = Sortable.sortables[element.id];
613

  
613 614
    if(s) {
614 615
      Draggables.removeObserver(s.element);
615 616
      s.droppables.each(function(d){ Droppables.remove(d) });
616 617
      s.draggables.invoke('destroy');
617
      
618

  
618 619
      delete Sortable.sortables[s.element.id];
619 620
    }
620 621
  },
621 622

  
622 623
  create: function(element) {
623 624
    element = $(element);
624
    var options = Object.extend({ 
625
    var options = Object.extend({
625 626
      element:     element,
626 627
      tag:         'li',       // assumes li children, override with tag: 'tagname'
627 628
      dropOnEmpty: false,
......
635 636
      delay:       0,
636 637
      hoverclass:  null,
637 638
      ghosting:    false,
638
      quiet:       false, 
639
      quiet:       false,
639 640
      scroll:      false,
640 641
      scrollSensitivity: 20,
641 642
      scrollSpeed: 15,
642 643
      format:      this.SERIALIZE_RULE,
643
      
644
      // these take arrays of elements or ids and can be 
644

  
645
      // these take arrays of elements or ids and can be
645 646
      // used for better initialization performance
646 647
      elements:    false,
647 648
      handles:     false,
648
      
649

  
649 650
      onChange:    Prototype.emptyFunction,
650 651
      onUpdate:    Prototype.emptyFunction
651 652
    }, arguments[1] || { });
......
682 683
    if(options.zindex)
683 684
      options_for_draggable.zindex = options.zindex;
684 685

  
685
    // build options for the droppables  
686
    // build options for the droppables
686 687
    var options_for_droppable = {
687 688
      overlap:     options.overlap,
688 689
      containment: options.containment,
689 690
      tree:        options.tree,
690 691
      hoverclass:  options.hoverclass,
691 692
      onHover:     Sortable.onHover
692
    }
693
    
693
    };
694

  
694 695
    var options_for_tree = {
695 696
      onHover:      Sortable.onEmptyHover,
696 697
      overlap:      options.overlap,
697 698
      containment:  options.containment,
698 699
      hoverclass:   options.hoverclass
699
    }
700
    };
700 701

  
701 702
    // fix for gecko engine
702
    Element.cleanWhitespace(element); 
703
    Element.cleanWhitespace(element);
703 704

  
704 705
    options.draggables = [];
705 706
    options.droppables = [];
......
712 713

  
713 714
    (options.elements || this.findElements(element, options) || []).each( function(e,i) {
714 715
      var handle = options.handles ? $(options.handles[i]) :
715
        (options.handle ? $(e).select('.' + options.handle)[0] : e); 
716
        (options.handle ? $(e).select('.' + options.handle)[0] : e);
716 717
      options.draggables.push(
717 718
        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
718 719
      Droppables.add(e, options_for_droppable);
719 720
      if(options.tree) e.treeNode = element;
720
      options.droppables.push(e);      
721
      options.droppables.push(e);
721 722
    });
722
    
723

  
723 724
    if(options.tree) {
724 725
      (Sortable.findTreeElements(element, options) || []).each( function(e) {
725 726
        Droppables.add(e, options_for_tree);
......
741 742
    return Element.findChildren(
742 743
      element, options.only, options.tree ? true : false, options.tag);
743 744
  },
744
  
745

  
745 746
  findTreeElements: function(element, options) {
746 747
    return Element.findChildren(
747 748
      element, options.only, options.tree ? true : false, options.treeTag);
......
758 759
        var oldParentNode = element.parentNode;
759 760
        element.style.visibility = "hidden"; // fix gecko rendering
760 761
        dropon.parentNode.insertBefore(element, dropon);
761
        if(dropon.parentNode!=oldParentNode) 
762
        if(dropon.parentNode!=oldParentNode)
762 763
          Sortable.options(oldParentNode).onChange(element);
763 764
        Sortable.options(dropon.parentNode).onChange(element);
764 765
      }
......
769 770
        var oldParentNode = element.parentNode;
770 771
        element.style.visibility = "hidden"; // fix gecko rendering
771 772
        dropon.parentNode.insertBefore(element, nextElement);
772
        if(dropon.parentNode!=oldParentNode) 
773
        if(dropon.parentNode!=oldParentNode)
773 774
          Sortable.options(oldParentNode).onChange(element);
774 775
        Sortable.options(dropon.parentNode).onChange(element);
775 776
      }
776 777
    }
777 778
  },
778
  
779

  
779 780
  onEmptyHover: function(element, dropon, overlap) {
780 781
    var oldParentNode = element.parentNode;
781 782
    var droponOptions = Sortable.options(dropon);
782
        
783

  
783 784
    if(!Element.isParent(dropon, element)) {
784 785
      var index;
785
      
786

  
786 787
      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
787 788
      var child = null;
788
            
789

  
789 790
      if(children) {
790 791
        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
791
        
792

  
792 793
        for (index = 0; index < children.length; index += 1) {
793 794
          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
794 795
            offset -= Element.offsetSize (children[index], droponOptions.overlap);
......
801 802
          }
802 803
        }
803 804
      }
804
      
805

  
805 806
      dropon.insertBefore(element, child);
806
      
807

  
807 808
      Sortable.options(oldParentNode).onChange(element);
808 809
      droponOptions.onChange(element);
809 810
    }
......
816 817
  mark: function(dropon, position) {
817 818
    // mark on ghosting only
818 819
    var sortable = Sortable.options(dropon.parentNode);
819
    if(sortable && !sortable.ghosting) return; 
820
    if(sortable && !sortable.ghosting) return;
820 821

  
821 822
    if(!Sortable._marker) {
822
      Sortable._marker = 
823
      Sortable._marker =
823 824
        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
824 825
          hide().addClassName('dropmarker').setStyle({position:'absolute'});
825 826
      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
826
    }    
827
    }
827 828
    var offsets = Position.cumulativeOffset(dropon);
828 829
    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
829
    
830

  
830 831
    if(position=='after')
831
      if(sortable.overlap == 'horizontal') 
832
      if(sortable.overlap == 'horizontal')
832 833
        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
833 834
      else
834 835
        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
835
    
836

  
836 837
    Sortable._marker.show();
837 838
  },
838
  
839

  
839 840
  _tree: function(element, options, parent) {
840 841
    var children = Sortable.findElements(element, options) || [];
841
  
842

  
842 843
    for (var i = 0; i < children.length; ++i) {
843 844
      var match = children[i].id.match(options.format);
844 845

  
845 846
      if (!match) continue;
846
      
847

  
847 848
      var child = {
848 849
        id: encodeURIComponent(match ? match[1] : null),
849 850
        element: element,
......
851 852
        children: [],
852 853
        position: parent.children.length,
853 854
        container: $(children[i]).down(options.treeTag)
854
      }
855
      
855
      };
856

  
856 857
      /* Get the element containing the children and recurse over it */
857 858
      if (child.container)
858
        this._tree(child.container, options, child)
859
      
859
        this._tree(child.container, options, child);
860

  
860 861
      parent.children.push (child);
861 862
    }
862 863

  
863
    return parent; 
864
    return parent;
864 865
  },
865 866

  
866 867
  tree: function(element) {
......
873 874
      name: element.id,
874 875
      format: sortableOptions.format
875 876
    }, arguments[1] || { });
876
    
877

  
877 878
    var root = {
878 879
      id: null,
879 880
      parent: null,
880 881
      children: [],
881 882
      container: element,
882 883
      position: 0
883
    }
884
    
884
    };
885

  
885 886
    return Sortable._tree(element, options, root);
886 887
  },
887 888

  
......
897 898
  sequence: function(element) {
898 899
    element = $(element);
899 900
    var options = Object.extend(this.options(element), arguments[1] || { });
900
    
901

  
901 902
    return $(this.findElements(element, options) || []).map( function(item) {
902 903
      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
903 904
    });
......
906 907
  setSequence: function(element, new_sequence) {
907 908
    element = $(element);
908 909
    var options = Object.extend(this.options(element), arguments[2] || { });
909
    
910

  
910 911
    var nodeMap = { };
911 912
    this.findElements(element, options).each( function(n) {
912 913
        if (n.id.match(options.format))
913 914
            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
914 915
        n.parentNode.removeChild(n);
915 916
    });
916
   
917

  
917 918
    new_sequence.each(function(ident) {
918 919
      var n = nodeMap[ident];
919 920
      if (n) {
......
922 923
      }
923 924
    });
924 925
  },
925
  
926

  
926 927
  serialize: function(element) {
927 928
    element = $(element);
928 929
    var options = Object.extend(Sortable.options(element), arguments[1] || { });
929 930
    var name = encodeURIComponent(
930 931
      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
931
    
932

  
932 933
    if (options.tree) {
933 934
      return Sortable.tree(element, arguments[1]).children.map( function (item) {
934
        return [name + Sortable._constructIndex(item) + "[id]=" + 
935
        return [name + Sortable._constructIndex(item) + "[id]=" +
935 936
                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
936 937
      }).flatten().join('&');
937 938
    } else {
......
940 941
      }).join('&');
941 942
    }
942 943
  }
943
}
944
};
944 945

  
945 946
// Returns true if child is contained within element
946 947
Element.isParent = function(child, element) {
947 948
  if (!child.parentNode || child == element) return false;
948 949
  if (child.parentNode == element) return true;
949 950
  return Element.isParent(child.parentNode, element);
950
}
951
};
951 952

  
952
Element.findChildren = function(element, only, recursive, tagName) {   
953
Element.findChildren = function(element, only, recursive, tagName) {
953 954
  if(!element.hasChildNodes()) return null;
954 955
  tagName = tagName.toUpperCase();
955 956
  if(only) only = [only].flatten();
......
965 966
  });
966 967

  
967 968
  return (elements.length>0 ? elements.flatten() : []);
968
}
969
};
969 970

  
970 971
Element.offsetSize = function (element, type) {
971 972
  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
972
}
973
};
sandbox/rails-2.2/public/javascripts/effects.js
3 3
//  Justin Palmer (http://encytemedia.com/)
4 4
//  Mark Pilgrim (http://diveintomark.org/)
5 5
//  Martin Bialasinki
6
// 
6
//
7 7
// script.aculo.us is freely distributable under the terms of an MIT-style license.
8
// For details, see the script.aculo.us web site: http://script.aculo.us/ 
8
// For details, see the script.aculo.us web site: http://script.aculo.us/
9 9

  
10
// converts rgb() and #xxx to #xxxxxx format,  
11
// returns self (or first argument) if not convertable  
12
String.prototype.parseColor = function() {  
10
// converts rgb() and #xxx to #xxxxxx format,
11
// returns self (or first argument) if not convertable
12
String.prototype.parseColor = function() {
13 13
  var color = '#';
14
  if (this.slice(0,4) == 'rgb(') {  
15
    var cols = this.slice(4,this.length-1).split(',');  
16
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
17
  } else {  
18
    if (this.slice(0,1) == '#') {  
19
      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
20
      if (this.length==7) color = this.toLowerCase();  
21
    }  
22
  }  
23
  return (color.length==7 ? color : (arguments[0] || this));  
14
  if (this.slice(0,4) == 'rgb(') {
15
    var cols = this.slice(4,this.length-1).split(',');
16
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
17
  } else {
18
    if (this.slice(0,1) == '#') {
19
      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
20
      if (this.length==7) color = this.toLowerCase();
21
    }
22
  }
23
  return (color.length==7 ? color : (arguments[0] || this));
24 24
};
25 25

  
26 26
/*--------------------------------------------------------------------------*/
27 27

  
28
Element.collectTextNodes = function(element) {  
28
Element.collectTextNodes = function(element) {
29 29
  return $A($(element).childNodes).collect( function(node) {
30
    return (node.nodeType==3 ? node.nodeValue : 
30
    return (node.nodeType==3 ? node.nodeValue :
31 31
      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
32 32
  }).flatten().join('');
33 33
};
34 34

  
35
Element.collectTextNodesIgnoreClass = function(element, className) {  
35
Element.collectTextNodesIgnoreClass = function(element, className) {
36 36
  return $A($(element).childNodes).collect( function(node) {
37
    return (node.nodeType==3 ? node.nodeValue : 
38
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
37
    return (node.nodeType==3 ? node.nodeValue :
38
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
39 39
        Element.collectTextNodesIgnoreClass(node, className) : ''));
40 40
  }).flatten().join('');
41 41
};
42 42

  
43 43
Element.setContentZoom = function(element, percent) {
44
  element = $(element);  
45
  element.setStyle({fontSize: (percent/100) + 'em'});   
44
  element = $(element);
45
  element.setStyle({fontSize: (percent/100) + 'em'});
46 46
  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
47 47
  return element;
48 48
};
......
70 70
  Transitions: {
71 71
    linear: Prototype.K,
72 72
    sinoidal: function(pos) {
73
      return (-Math.cos(pos*Math.PI)/2) + 0.5;
73
      return (-Math.cos(pos*Math.PI)/2) + .5;
74 74
    },
75 75
    reverse: function(pos) {
76 76
      return 1-pos;
77 77
    },
78 78
    flicker: function(pos) {
79
      var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
79
      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
80 80
      return pos > 1 ? 1 : pos;
81 81
    },
82 82
    wobble: function(pos) {
83
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
83
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
84 84
    },
85
    pulse: function(pos, pulses) { 
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff