diff --git a/tracks/public/javascripts/controls.js b/tracks/public/javascripts/controls.js
index 9742b691..de0261ed 100644
--- a/tracks/public/javascripts/controls.js
+++ b/tracks/public/javascripts/controls.js
@@ -141,8 +141,8 @@ Autocompleter.Base.prototype = {
return;
}
else
- if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN)
- return;
+ if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
+ (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;
this.changed = true;
this.hasFocus = true;
@@ -152,6 +152,12 @@ Autocompleter.Base.prototype = {
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 @@ Autocompleter.Base.prototype = {
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 @@ Autocompleter.Base.prototype = {
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 @@ Ajax.InPlaceEditor.prototype = {
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 @@ Ajax.InPlaceEditor.prototype = {
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 @@ Ajax.InPlaceEditor.prototype = {
this.form.appendChild(br);
}
- okButton = document.createElement("input");
- okButton.type = "submit";
- okButton.value = this.options.okText;
- this.form.appendChild(okButton);
+ 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);
+ }
- 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.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 @@ Ajax.InPlaceEditor.prototype = {
} 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 @@ Ajax.InPlaceEditor.prototype = {
// 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]);
@@ -723,6 +761,33 @@ Ajax.InPlaceEditor.prototype = {
}
};
+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
// Ideal for live-search fields
@@ -747,4 +812,4 @@ Form.Element.DelayedObserver.prototype = {
this.timer = null;
this.callback(this.element, $F(this.element));
}
-};
\ No newline at end of file
+};
diff --git a/tracks/public/javascripts/dragdrop.js b/tracks/public/javascripts/dragdrop.js
index 92d1f731..f1dc7ea2 100644
--- a/tracks/public/javascripts/dragdrop.js
+++ b/tracks/public/javascripts/dragdrop.js
@@ -128,7 +128,7 @@ var Draggables = {
this.activeDraggable = draggable;
},
- deactivate: function(draggbale) {
+ deactivate: function() {
this.activeDraggable = null;
},
@@ -146,6 +146,7 @@ var Draggables = {
if(!this.activeDraggable) return;
this._lastPointer = null;
this.activeDraggable.endDrag(event);
+ this.activeDraggable = null;
},
keyPress: function(event) {
@@ -191,22 +192,28 @@ Draggable.prototype = {
},
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] || {});
this.element = $(element);
if(options.handle && (typeof options.handle == 'string'))
- this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
+ this.handle = Element.childrenWithClassName(this.element, options.handle, true)[0];
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
+
+ if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML)
+ options.scroll = $(options.scroll);
Element.makePositioned(this.element); // fix IE
@@ -227,8 +234,8 @@ Draggable.prototype = {
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 +245,7 @@ Draggable.prototype = {
if(src.tagName && (
src.tagName=='INPUT' ||
src.tagName=='SELECT' ||
+ src.tagName=='OPTION' ||
src.tagName=='BUTTON' ||
src.tagName=='TEXTAREA')) return;
@@ -269,6 +277,17 @@ Draggable.prototype = {
this.element.parentNode.insertBefore(this._clone, this.element);
}
+ if(this.options.scroll) {
+ if (this.options.scroll == window) {
+ var where = this._getWindowScroll(this.options.scroll);
+ this.originalScrollLeft = where.left;
+ this.originalScrollTop = where.top;
+ } else {
+ 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 +300,30 @@ Draggable.prototype = {
this.draw(pointer);
if(this.options.change) this.options.change(this);
+ if(this.options.scroll) {
+ this.stopScrolling();
+
+ var p;
+ if (this.options.scroll == window) {
+ with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
+ } else {
+ 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 +361,14 @@ Draggable.prototype = {
},
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 +378,14 @@ Draggable.prototype = {
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 && (this.options.scroll != window)) {
+ 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 +406,67 @@ Draggable.prototype = {
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;
+ if(this.options.scroll == window) {
+ with (this._getWindowScroll(this.options.scroll)) {
+ if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
+ var d = delta / 1000;
+ this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
+ }
+ }
+ } else {
+ 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);
+ },
+
+ _getWindowScroll: function(w) {
+ var T, L, W, H;
+ with (w.document) {
+ if (w.document.documentElement && documentElement.scrollTop) {
+ T = documentElement.scrollTop;
+ L = documentElement.scrollLeft;
+ } else if (w.document.body) {
+ T = body.scrollTop;
+ L = body.scrollLeft;
+ }
+ if (w.innerWidth) {
+ W = w.innerWidth;
+ H = w.innerHeight;
+ } else if (w.document.documentElement && documentElement.clientWidth) {
+ W = documentElement.clientWidth;
+ H = documentElement.clientHeight;
+ } else {
+ W = body.offsetWidth;
+ H = body.offsetHeight
+ }
+ }
+ return { top: T, left: L, width: W, height: H };
}
}
@@ -413,7 +523,10 @@ var Sortable = {
only: false,
hoverclass: null,
ghosting: false,
- format: null,
+ scroll: false,
+ scrollSensitivity: 20,
+ scrollSpeed: 15,
+ format: /^[^_]*_(.*)$/,
onChange: Prototype.emptyFunction,
onUpdate: Prototype.emptyFunction
}, arguments[1] || {});
@@ -424,6 +537,9 @@ var Sortable = {
// build options for the draggables
var options_for_draggable = {
revert: true,
+ scroll: options.scroll,
+ scrollSpeed: options.scrollSpeed,
+ scrollSensitivity: options.scrollSensitivity,
ghosting: options.ghosting,
constraint: options.constraint,
handle: options.handle };
@@ -491,9 +607,10 @@ var Sortable = {
findElements: function(element, options) {
if(!element.hasChildNodes()) return null;
var elements = [];
+ var only = options.only ? [options.only].flatten() : null;
$A(element.childNodes).each( function(e) {
if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() &&
- (!options.only || (Element.hasClassName(e, options.only))))
+ (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
elements.push(e);
if(options.tree) {
var grandchildren = this.findElements(e, options);
@@ -567,18 +684,41 @@ var Sortable = {
Element.show(Sortable._marker);
},
+ sequence: function(element) {
+ element = $(element);
+ var options = Object.extend(this.options(element), arguments[1] || {});
+
+ return $(this.findElements(element, options) || []).map( function(item) {
+ 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 sortableOptions = this.options(element);
- var options = Object.extend({
- tag: sortableOptions.tag,
- only: sortableOptions.only,
- name: element.id,
- format: sortableOptions.format || /^[^_]*_(.*)$/
- }, 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("&");
+ 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('&');
}
-}
\ No newline at end of file
+}
diff --git a/tracks/public/javascripts/effects.js b/tracks/public/javascripts/effects.js
index 414398ce..bcf836b8 100644
--- a/tracks/public/javascripts/effects.js
+++ b/tracks/public/javascripts/effects.js
@@ -6,8 +6,6 @@
//
// See scriptaculous.js for full license.
-/* ------------- element ext -------------- */
-
// converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable
String.prototype.parseColor = function() {
@@ -22,33 +20,29 @@ String.prototype.parseColor = function() {
}
}
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.setStyle = function(element, style) {
- element = $(element);
- for(k in style) element.style[k.camelize()] = style[k];
+/*--------------------------------------------------------------------------*/
+
+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.setContentZoom = function(element, percent) {
+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.setContentZoom = function(element, percent) {
+ element = $(element);
Element.setStyle(element, {fontSize: (percent/100) + 'em'});
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
}
Element.getOpacity = function(element){
@@ -75,18 +69,35 @@ Element.setOpacity = function(element, value){
Element.setStyle(element,
{ filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
'alpha(opacity='+value*100+')' });
- }
+ }
}
Element.getInlineOpacity = function(element){
return $(element).style.opacity || '';
}
-Element.childrenWithClassName = function(element, className) {
- return $A($(element).getElementsByTagName('*')).select(
- function(c) { return Element.hasClassName(c, className) });
+Element.childrenWithClassName = function(element, className, findFirst) {
+ return [$A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) {
+ return c.className ? Element.hasClassName(c, className) : false;
+ })].flatten();
}
+Element.forceRerendering = function(element) {
+ try {
+ element = $(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch(e) { }
+};
+
+['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
+ 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(
+ function(f) { Element.Methods[f] = Element[f]; }
+);
+
+/*--------------------------------------------------------------------------*/
+
Array.prototype.call = function() {
var args = arguments;
this.each(function(f){ f.apply(this, args) });
@@ -129,6 +140,20 @@ var Effect = {
$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() ?
+ Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
}
};
@@ -166,16 +191,22 @@ Effect.Transitions.full = function(pos) {
/* ------------- 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 +222,10 @@ Effect.Queue = {
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 +240,45 @@ Effect.Queue = {
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 +316,9 @@ Effect.Base.prototype = {
}
},
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) {
@@ -307,43 +356,57 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
this.element = $(element);
// make this work on IE on elements without 'layout'
if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
- Element.setStyle(this.element, {zoom: 1});
+ this.element.setStyle({zoom: 1});
var options = Object.extend({
- from: Element.getOpacity(this.element) || 0.0,
+ from: this.element.getOpacity() || 0.0,
to: 1.0
}, arguments[1] || {});
this.start(options);
},
update: function(position) {
- Element.setOpacity(this.element, position);
+ this.element.setOpacity(position);
}
});
-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
// relative element that does not have top/left explicitly set.
// ==> 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.element.makePositioned();
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+ this.originalTop = parseFloat(this.element.getStyle('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'
+ this.element.setStyle({
+ 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) {
@@ -361,7 +424,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
},
setup: function() {
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
- this.elementPositioning = Element.getStyle(this.element,'position');
+ this.elementPositioning = this.element.getStyle('position');
this.originalStyle = {};
['top','left','width','height','fontSize'].each( function(k) {
@@ -371,7 +434,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
- var fontSize = Element.getStyle(this.element,'font-size') || '100%';
+ var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%'].each( function(fontSizeType) {
if(fontSize.indexOf(fontSizeType)>0) {
this.fontSize = parseFloat(fontSize);
@@ -393,11 +456,11 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
update: function(position) {
var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
if(this.options.scaleContent && this.fontSize)
- Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType });
+ this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
},
finish: function(position) {
- if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle);
+ if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
},
setDimensions: function(height, width) {
var d = {};
@@ -414,7 +477,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
if(this.options.scaleX) d.left = -leftd + 'px';
}
}
- Element.setStyle(this.element, d);
+ this.element.setStyle(d);
}
});
@@ -427,25 +490,25 @@ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype),
},
setup: function() {
// Prevent executing on elements not in the layout flow
- if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; }
+ if(this.element.getStyle('display')=='none') { this.cancel(); return; }
// Disable background image during the effect
this.oldStyle = {
- backgroundImage: Element.getStyle(this.element, 'background-image') };
- Element.setStyle(this.element, {backgroundImage: 'none'});
+ backgroundImage: this.element.getStyle('background-image') };
+ this.element.setStyle({backgroundImage: 'none'});
if(!this.options.endcolor)
- this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
+ this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
if(!this.options.restorecolor)
- this.options.restorecolor = Element.getStyle(this.element, 'background-color');
+ this.options.restorecolor = this.element.getStyle('background-color');
// init color calculations
this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
},
update: function(position) {
- Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){
+ this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
},
finish: function() {
- Element.setStyle(this.element, Object.extend(this.oldStyle, {
+ this.element.setStyle(Object.extend(this.oldStyle, {
backgroundColor: this.options.restorecolor
}));
}
@@ -479,85 +542,91 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
/* ------------- combination effects ------------- */
Effect.Fade = function(element) {
- var oldOpacity = Element.getInlineOpacity(element);
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
var options = Object.extend({
- from: Element.getOpacity(element) || 1.0,
+ from: element.getOpacity() || 1.0,
to: 0.0,
- afterFinishInternal: function(effect) { with(Element) {
+ afterFinishInternal: function(effect) {
if(effect.options.to!=0) return;
- hide(effect.element);
- setStyle(effect.element, {opacity: oldOpacity}); }}
- }, arguments[1] || {});
+ effect.element.hide();
+ effect.element.setStyle({opacity: oldOpacity});
+ }}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Appear = function(element) {
+ element = $(element);
var options = Object.extend({
- from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0),
+ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
to: 1.0,
- beforeSetup: function(effect) { with(Element) {
- setOpacity(effect.element, effect.options.from);
- show(effect.element); }}
- }, arguments[1] || {});
+ // force Safari to render floated elements properly
+ afterFinishInternal: function(effect) {
+ effect.element.forceRerendering();
+ },
+ beforeSetup: function(effect) {
+ effect.element.setOpacity(effect.options.from);
+ effect.element.show();
+ }}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Puff = function(element) {
element = $(element);
- var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') };
+ var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') };
return new Effect.Parallel(
[ new Effect.Scale(element, 200,
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
Object.extend({ duration: 1.0,
- beforeSetupInternal: function(effect) { with(Element) {
- setStyle(effect.effects[0].element, {position: 'absolute'}); }},
- afterFinishInternal: function(effect) { with(Element) {
- hide(effect.effects[0].element);
- setStyle(effect.effects[0].element, oldStyle); }}
+ beforeSetupInternal: function(effect) {
+ effect.effects[0].element.setStyle({position: 'absolute'}); },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.setStyle(oldStyle); }
}, arguments[1] || {})
);
}
Effect.BlindUp = function(element) {
element = $(element);
- Element.makeClipping(element);
+ element.makeClipping();
return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleX: false,
restoreAfterFinish: true,
- afterFinishInternal: function(effect) { with(Element) {
- [hide, undoClipping].call(effect.element); }}
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ }
}, arguments[1] || {})
);
}
Effect.BlindDown = function(element) {
element = $(element);
- var oldHeight = Element.getStyle(element, 'height');
- var elementDimensions = Element.getDimensions(element);
+ var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100,
Object.extend({ scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
- afterSetup: function(effect) { with(Element) {
- makeClipping(effect.element);
- setStyle(effect.element, {height: '0px'});
- show(effect.element);
- }},
- afterFinishInternal: function(effect) { with(Element) {
- undoClipping(effect.element);
- setStyle(effect.element, {height: oldHeight});
- }}
+ afterSetup: function(effect) {
+ effect.element.makeClipping();
+ effect.element.setStyle({height: '0px'});
+ effect.element.show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ }
}, arguments[1] || {})
);
}
Effect.SwitchOff = function(element) {
element = $(element);
- var oldOpacity = Element.getInlineOpacity(element);
+ var oldOpacity = element.getInlineOpacity();
return new Effect.Appear(element, {
duration: 0.4,
from: 0,
@@ -566,13 +635,16 @@ Effect.SwitchOff = function(element) {
new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
- beforeSetup: function(effect) { with(Element) {
- [makePositioned,makeClipping].call(effect.element);
- }},
- afterFinishInternal: function(effect) { with(Element) {
- [hide,undoClipping,undoPositioned].call(effect.element);
- setStyle(effect.element, {opacity: oldOpacity});
- }}
+ beforeSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.undoPositioned();
+ effect.element.setStyle({opacity: oldOpacity});
+ }
})
}
});
@@ -581,99 +653,110 @@ Effect.SwitchOff = function(element) {
Effect.DropOut = function(element) {
element = $(element);
var oldStyle = {
- top: Element.getStyle(element, 'top'),
- left: Element.getStyle(element, 'left'),
- opacity: Element.getInlineOpacity(element) };
+ top: element.getStyle('top'),
+ left: element.getStyle('left'),
+ opacity: element.getInlineOpacity() };
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,
- beforeSetup: function(effect) { with(Element) {
- makePositioned(effect.effects[0].element); }},
- afterFinishInternal: function(effect) { with(Element) {
- [hide, undoPositioned].call(effect.effects[0].element);
- setStyle(effect.effects[0].element, oldStyle); }}
+ beforeSetup: function(effect) {
+ effect.effects[0].element.makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
}, arguments[1] || {}));
}
Effect.Shake = function(element) {
element = $(element);
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) {
- undoPositioned(effect.element);
- setStyle(effect.element, oldStyle);
- }}}) }}) }}) }}) }}) }});
+ top: element.getStyle('top'),
+ left: element.getStyle('left') };
+ 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) {
+ effect.element.undoPositioned();
+ effect.element.setStyle(oldStyle);
+ }}) }}) }}) }}) }}) }});
}
Effect.SlideDown = function(element) {
element = $(element);
- Element.cleanWhitespace(element);
+ element.cleanWhitespace();
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
- var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
- var elementDimensions = Element.getDimensions(element);
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+ var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
- afterSetup: function(effect) { with(Element) {
- makePositioned(effect.element);
- makePositioned(effect.element.firstChild);
- if(window.opera) setStyle(effect.element, {top: ''});
- makeClipping(effect.element);
- setStyle(effect.element, {height: '0px'});
- show(element); }},
- afterUpdateInternal: function(effect) { with(Element) {
- setStyle(effect.element.firstChild, {bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
- afterFinishInternal: function(effect) { with(Element) {
- undoClipping(effect.element);
- undoPositioned(effect.element.firstChild);
- undoPositioned(effect.element);
- setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
+ afterSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.firstChild.makePositioned();
+ if(window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping();
+ effect.element.setStyle({height: '0px'});
+ effect.element.show(); },
+ afterUpdateInternal: function(effect) {
+ effect.element.firstChild.setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ // IE will crash if child is undoPositioned first
+ if(/MSIE/.test(navigator.userAgent)){
+ effect.element.undoPositioned();
+ effect.element.firstChild.undoPositioned();
+ }else{
+ effect.element.firstChild.undoPositioned();
+ effect.element.undoPositioned();
+ }
+ effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
}, arguments[1] || {})
);
}
Effect.SlideUp = function(element) {
element = $(element);
- Element.cleanWhitespace(element);
- var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
+ element.cleanWhitespace();
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
restoreAfterFinish: true,
- beforeStartInternal: function(effect) { with(Element) {
- makePositioned(effect.element);
- makePositioned(effect.element.firstChild);
- if(window.opera) setStyle(effect.element, {top: ''});
- makeClipping(effect.element);
- show(element); }},
- afterUpdateInternal: function(effect) { with(Element) {
- setStyle(effect.element.firstChild, {bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
- afterFinishInternal: function(effect) { with(Element) {
- [hide, undoClipping].call(effect.element);
- undoPositioned(effect.element.firstChild);
- undoPositioned(effect.element);
- setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
+ beforeStartInternal: function(effect) {
+ effect.element.makePositioned();
+ effect.element.firstChild.makePositioned();
+ if(window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping();
+ effect.element.show(); },
+ afterUpdateInternal: function(effect) {
+ effect.element.firstChild.setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' }); },
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.firstChild.undoPositioned();
+ effect.element.undoPositioned();
+ effect.element.setStyle({bottom: oldInnerBottom}); }
}, arguments[1] || {})
);
}
@@ -682,11 +765,11 @@ Effect.SlideUp = function(element) {
Effect.Squish = function(element) {
return new Effect.Scale(element, window.opera ? 1 : 0,
{ restoreAfterFinish: true,
- beforeSetup: function(effect) { with(Element) {
- makeClipping(effect.element); }},
- afterFinishInternal: function(effect) { with(Element) {
- hide(effect.element);
- undoClipping(effect.element); }}
+ beforeSetup: function(effect) {
+ effect.element.makeClipping(effect.element); },
+ afterFinishInternal: function(effect) {
+ effect.element.hide(effect.element);
+ effect.element.undoClipping(effect.element); }
});
}
@@ -694,7 +777,7 @@ Effect.Grow = function(element) {
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] || {});
@@ -703,9 +786,9 @@ Effect.Grow = function(element) {
left: element.style.left,
height: element.style.height,
width: element.style.width,
- opacity: Element.getInlineOpacity(element) };
+ opacity: element.getInlineOpacity() };
- var dims = Element.getDimensions(element);
+ var dims = element.getDimensions();
var initialMoveX, initialMoveY;
var moveX, moveY;
@@ -737,27 +820,32 @@ Effect.Grow = function(element) {
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);
- makeClipping(effect.element);
- makePositioned(effect.element);
- }},
+ beforeSetup: function(effect) {
+ effect.element.hide();
+ effect.element.makeClipping();
+ effect.element.makePositioned();
+ },
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})
], Object.extend({
- beforeSetup: function(effect) { with(Element) {
- setStyle(effect.effects[0].element, {height: '0px'});
- show(effect.effects[0].element); }},
- afterFinishInternal: function(effect) { with(Element) {
- [undoClipping, undoPositioned].call(effect.effects[0].element);
- setStyle(effect.effects[0].element, oldStyle); }}
+ beforeSetup: function(effect) {
+ effect.effects[0].element.setStyle({height: '0px'});
+ effect.effects[0].element.show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.undoClipping();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
}, options)
)
}
@@ -768,7 +856,7 @@ Effect.Shrink = function(element) {
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] || {});
@@ -777,9 +865,9 @@ Effect.Shrink = function(element) {
left: element.style.left,
height: element.style.height,
width: element.style.width,
- opacity: Element.getInlineOpacity(element) };
+ opacity: element.getInlineOpacity() };
- var dims = Element.getDimensions(element);
+ var dims = element.getDimensions();
var moveX, moveY;
switch (options.direction) {
@@ -807,13 +895,16 @@ Effect.Shrink = function(element) {
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) }},
- afterFinishInternal: function(effect) { with(Element) {
- [hide, undoClipping, undoPositioned].call(effect.effects[0].element);
- setStyle(effect.effects[0].element, oldStyle); }}
+ beforeStartInternal: function(effect) {
+ effect.effects[0].element.makePositioned();
+ effect.effects[0].element.makeClipping(); },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.undoClipping();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle); }
}, options)
);
}
@@ -821,13 +912,13 @@ Effect.Shrink = function(element) {
Effect.Pulsate = function(element) {
element = $(element);
var options = arguments[1] || {};
- var oldOpacity = Element.getInlineOpacity(element);
+ var oldOpacity = element.getInlineOpacity();
var transition = options.transition || Effect.Transitions.sinoidal;
var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
reverser.bind(transition);
return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 3.0, from: 0,
- afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); }
+ afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
}
@@ -846,9 +937,17 @@ Effect.Fold = function(element) {
new Effect.Scale(element, 1, {
scaleContent: false,
scaleY: false,
- afterFinishInternal: function(effect) { with(Element) {
- [hide, undoClipping].call(effect.element);
- setStyle(effect.element, oldStyle);
- }} });
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.setStyle(oldStyle);
+ } });
}}, arguments[1] || {}));
}
+
+Element.Methods.visualEffect = function(element, effect, options) {
+ s = effect.gsub(/_/, '-').camelize();
+ effect_class = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[effect_class](element, options);
+ return $(element);
+};
\ No newline at end of file
diff --git a/tracks/public/javascripts/prototype.js b/tracks/public/javascripts/prototype.js
index e9ccd3c8..2d4ba34c 100644
--- a/tracks/public/javascripts/prototype.js
+++ b/tracks/public/javascripts/prototype.js
@@ -1,17 +1,13 @@
-/* Prototype JavaScript framework, version 1.4.0
+/* Prototype JavaScript framework, version 1.5.0_pre1
* (c) 2005 Sam Stephenson New product! Product 1 Product 2 New Product: #{@product.name} /gi, "");
- },
- createEditField: function() {
- var text;
- if(this.options.loadTextURL) {
- text = this.options.loadingText;
- } else {
- text = this.getText();
- }
-
- if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
- this.options.textarea = false;
- var textField = document.createElement("input");
- textField.type = "text";
- textField.name = "value";
- textField.value = text;
- textField.style.backgroundColor = this.options.highlightcolor;
- var size = this.options.size || this.options.cols || 0;
- if (size != 0) textField.size = size;
- this.editField = textField;
- } else {
- this.options.textarea = true;
- var textArea = document.createElement("textarea");
- textArea.name = "value";
- textArea.value = this.convertHTMLLineBreaks(text);
- textArea.rows = this.options.rows;
- textArea.cols = this.options.cols || 40;
- this.editField = textArea;
- }
-
- if(this.options.loadTextURL) {
- this.loadExternalText();
- }
- this.form.appendChild(this.editField);
- },
- getText: function() {
- return this.element.innerHTML;
- },
- loadExternalText: function() {
- Element.addClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = true;
- new Ajax.Request(
- this.options.loadTextURL,
- Object.extend({
- asynchronous: true,
- onComplete: this.onLoadedExternalText.bind(this)
- }, this.options.ajaxOptions)
- );
- },
- onLoadedExternalText: function(transport) {
- Element.removeClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = false;
- this.editField.value = transport.responseText.stripTags();
- },
- onclickCancel: function() {
- this.onComplete();
- this.leaveEditMode();
- return false;
- },
- onFailure: function(transport) {
- this.options.onFailure(transport);
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- this.oldInnerHTML = null;
- }
- return false;
- },
- onSubmit: function() {
- // onLoading resets these so we need to save them away for the Ajax call
- var form = this.form;
- var value = this.editField.value;
-
- // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
- // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
- // 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)
- );
- // stop the event to avoid a page refresh in Safari
- if (arguments.length > 1) {
- Event.stop(arguments[0]);
- }
- return false;
- },
- onLoading: function() {
- this.saving = true;
- this.removeForm();
- this.leaveHover();
- this.showSaving();
- },
- showSaving: function() {
- this.oldInnerHTML = this.element.innerHTML;
- this.element.innerHTML = this.options.savingText;
- Element.addClassName(this.element, this.options.savingClassName);
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
- },
- removeForm: function() {
- if(this.form) {
- if (this.form.parentNode) Element.remove(this.form);
- this.form = null;
- }
- },
- enterHover: function() {
- if (this.saving) return;
- this.element.style.backgroundColor = this.options.highlightcolor;
- if (this.effect) {
- this.effect.cancel();
- }
- Element.addClassName(this.element, this.options.hoverClassName)
- },
- leaveHover: function() {
- if (this.options.backgroundColor) {
- this.element.style.backgroundColor = this.oldBackground;
- }
- Element.removeClassName(this.element, this.options.hoverClassName)
- if (this.saving) return;
- this.effect = new Effect.Highlight(this.element, {
- startcolor: this.options.highlightcolor,
- endcolor: this.options.highlightendcolor,
- restorecolor: this.originalBackground
- });
- },
- leaveEditMode: function() {
- Element.removeClassName(this.element, this.options.savingClassName);
- this.removeForm();
- this.leaveHover();
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
- if (this.options.externalControl) {
- Element.show(this.options.externalControl);
- }
- this.editing = false;
- this.saving = false;
- this.oldInnerHTML = null;
- this.onLeaveEditMode();
- },
- onComplete: function(transport) {
- this.leaveEditMode();
- this.options.onComplete.bind(this)(transport, this.element);
- },
- onEnterEditMode: function() {},
- onLeaveEditMode: function() {},
- dispose: function() {
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- }
- this.leaveEditMode();
- Event.stopObserving(this.element, 'click', this.onclickListener);
- Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
- if (this.options.externalControl) {
- Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
- Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
- }
- }
-};
-
-// Delayed observer, like Form.Element.Observer,
-// but waits for delay after last key input
-// Ideal for live-search fields
-
-Form.Element.DelayedObserver = Class.create();
-Form.Element.DelayedObserver.prototype = {
- initialize: function(element, delay, callback) {
- this.delay = delay || 0.5;
- this.element = $(element);
- this.callback = callback;
- this.timer = null;
- this.lastValue = $F(this.element);
- Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
- },
- delayedListener: function(event) {
- if(this.lastValue == $F(this.element)) return;
- if(this.timer) clearTimeout(this.timer);
- this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
- this.lastValue = $F(this.element);
- },
- onTimerEvent: function() {
- this.timer = null;
- this.callback(this.element, $F(this.element));
- }
-};
\ No newline at end of file
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/dragdrop.js b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/dragdrop.js
deleted file mode 100644
index 92d1f731..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/dragdrop.js
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-//
-// See scriptaculous.js for full license.
-
-/*--------------------------------------------------------------------------*/
-
-var Droppables = {
- drops: [],
-
- remove: function(element) {
- this.drops = this.drops.reject(function(d) { return d.element==$(element) });
- },
-
- add: function(element) {
- element = $(element);
- var options = Object.extend({
- greedy: true,
- hoverclass: null
- }, arguments[1] || {});
-
- // cache containers
- if(options.containment) {
- options._containers = [];
- var containment = options.containment;
- if((typeof containment == 'object') &&
- (containment.constructor == Array)) {
- containment.each( function(c) { options._containers.push($(c)) });
- } else {
- options._containers.push($(containment));
- }
- }
-
- if(options.accept) options.accept = [options.accept].flatten();
-
- Element.makePositioned(element); // fix IE
- options.element = element;
-
- this.drops.push(options);
- },
-
- isContained: function(element, drop) {
- var parentNode = element.parentNode;
- return drop._containers.detect(function(c) { return parentNode == c });
- },
-
- isAffected: function(point, element, drop) {
- return (
- (drop.element!=element) &&
- ((!drop._containers) ||
- this.isContained(element, drop)) &&
- ((!drop.accept) ||
- (Element.classNames(element).detect(
- function(v) { return drop.accept.include(v) } ) )) &&
- Position.within(drop.element, point[0], point[1]) );
- },
-
- deactivate: function(drop) {
- if(drop.hoverclass)
- Element.removeClassName(drop.element, drop.hoverclass);
- this.last_active = null;
- },
-
- activate: function(drop) {
- if(drop.hoverclass)
- Element.addClassName(drop.element, drop.hoverclass);
- this.last_active = drop;
- },
-
- show: function(point, element) {
- if(!this.drops.length) return;
-
- if(this.last_active) this.deactivate(this.last_active);
- this.drops.each( function(drop) {
- if(Droppables.isAffected(point, element, drop)) {
- if(drop.onHover)
- drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
- if(drop.greedy) {
- Droppables.activate(drop);
- throw $break;
- }
- }
- });
- },
-
- fire: function(event, element) {
- if(!this.last_active) return;
- Position.prepare();
-
- if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
- if (this.last_active.onDrop)
- this.last_active.onDrop(element, this.last_active.element, event);
- },
-
- reset: function() {
- if(this.last_active)
- this.deactivate(this.last_active);
- }
-}
-
-var Draggables = {
- drags: [],
- observers: [],
-
- register: function(draggable) {
- if(this.drags.length == 0) {
- this.eventMouseUp = this.endDrag.bindAsEventListener(this);
- this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
- this.eventKeypress = this.keyPress.bindAsEventListener(this);
-
- Event.observe(document, "mouseup", this.eventMouseUp);
- Event.observe(document, "mousemove", this.eventMouseMove);
- Event.observe(document, "keypress", this.eventKeypress);
- }
- this.drags.push(draggable);
- },
-
- unregister: function(draggable) {
- this.drags = this.drags.reject(function(d) { return d==draggable });
- if(this.drags.length == 0) {
- Event.stopObserving(document, "mouseup", this.eventMouseUp);
- Event.stopObserving(document, "mousemove", this.eventMouseMove);
- Event.stopObserving(document, "keypress", this.eventKeypress);
- }
- },
-
- activate: function(draggable) {
- window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
- this.activeDraggable = draggable;
- },
-
- deactivate: function(draggbale) {
- this.activeDraggable = null;
- },
-
- updateDrag: function(event) {
- if(!this.activeDraggable) return;
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- // Mozilla-based browsers fire successive mousemove events with
- // the same coordinates, prevent needless redrawing (moz bug?)
- if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
- this._lastPointer = pointer;
- this.activeDraggable.updateDrag(event, pointer);
- },
-
- endDrag: function(event) {
- if(!this.activeDraggable) return;
- this._lastPointer = null;
- this.activeDraggable.endDrag(event);
- },
-
- keyPress: function(event) {
- if(this.activeDraggable)
- this.activeDraggable.keyPress(event);
- },
-
- addObserver: function(observer) {
- this.observers.push(observer);
- this._cacheObserverCallbacks();
- },
-
- removeObserver: function(element) { // element instead of observer fixes mem leaks
- this.observers = this.observers.reject( function(o) { return o.element==element });
- this._cacheObserverCallbacks();
- },
-
- notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
- if(this[eventName+'Count'] > 0)
- this.observers.each( function(o) {
- if(o[eventName]) o[eventName](eventName, draggable, event);
- });
- },
-
- _cacheObserverCallbacks: function() {
- ['onStart','onEnd','onDrag'].each( function(eventName) {
- Draggables[eventName+'Count'] = Draggables.observers.select(
- function(o) { return o[eventName]; }
- ).length;
- });
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Draggable = Class.create();
-Draggable.prototype = {
- initialize: function(element) {
- var options = Object.extend({
- handle: false,
- starteffect: function(element) {
- new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7});
- },
- 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});
- },
- endeffect: function(element) {
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
- },
- zindex: 1000,
- revert: false,
- snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] }
- }, arguments[1] || {});
-
- this.element = $(element);
-
- if(options.handle && (typeof options.handle == 'string'))
- this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
- if(!this.handle) this.handle = $(options.handle);
- if(!this.handle) this.handle = this.element;
-
- Element.makePositioned(this.element); // fix IE
-
- this.delta = this.currentDelta();
- this.options = options;
- this.dragging = false;
-
- this.eventMouseDown = this.initDrag.bindAsEventListener(this);
- Event.observe(this.handle, "mousedown", this.eventMouseDown);
-
- Draggables.register(this);
- },
-
- destroy: function() {
- Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
- Draggables.unregister(this);
- },
-
- currentDelta: function() {
- return([
- parseInt(this.element.style.left || '0'),
- parseInt(this.element.style.top || '0')]);
- },
-
- initDrag: function(event) {
- if(Event.isLeftClick(event)) {
- // abort on form elements, fixes a Firefox issue
- var src = Event.element(event);
- if(src.tagName && (
- src.tagName=='INPUT' ||
- src.tagName=='SELECT' ||
- src.tagName=='BUTTON' ||
- src.tagName=='TEXTAREA')) return;
-
- if(this.element._revert) {
- this.element._revert.cancel();
- this.element._revert = null;
- }
-
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var pos = Position.cumulativeOffset(this.element);
- this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
-
- Draggables.activate(this);
- Event.stop(event);
- }
- },
-
- startDrag: function(event) {
- this.dragging = true;
-
- if(this.options.zindex) {
- this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
- this.element.style.zIndex = this.options.zindex;
- }
-
- if(this.options.ghosting) {
- this._clone = this.element.cloneNode(true);
- Position.absolutize(this.element);
- this.element.parentNode.insertBefore(this._clone, this.element);
- }
-
- Draggables.notify('onStart', this, event);
- if(this.options.starteffect) this.options.starteffect(this.element);
- },
-
- updateDrag: function(event, pointer) {
- if(!this.dragging) this.startDrag(event);
- Position.prepare();
- Droppables.show(pointer, this.element);
- Draggables.notify('onDrag', this, event);
- this.draw(pointer);
- if(this.options.change) this.options.change(this);
-
- // fix AppleWebKit rendering
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
- Event.stop(event);
- },
-
- finishDrag: function(event, success) {
- this.dragging = false;
-
- if(this.options.ghosting) {
- Position.relativize(this.element);
- Element.remove(this._clone);
- this._clone = null;
- }
-
- if(success) Droppables.fire(event, this.element);
- Draggables.notify('onEnd', this, event);
-
- var revert = this.options.revert;
- if(revert && typeof revert == 'function') revert = revert(this.element);
-
- var d = this.currentDelta();
- if(revert && this.options.reverteffect) {
- this.options.reverteffect(this.element,
- d[1]-this.delta[1], d[0]-this.delta[0]);
- } else {
- this.delta = d;
- }
-
- if(this.options.zindex)
- this.element.style.zIndex = this.originalZ;
-
- if(this.options.endeffect)
- this.options.endeffect(this.element);
-
- Draggables.deactivate(this);
- Droppables.reset();
- },
-
- keyPress: function(event) {
- if(!event.keyCode==Event.KEY_ESC) return;
- this.finishDrag(event, false);
- Event.stop(event);
- },
-
- endDrag: function(event) {
- if(!this.dragging) return;
- this.finishDrag(event, true);
- Event.stop(event);
- },
-
- draw: function(point) {
- var pos = Position.cumulativeOffset(this.element);
- 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.snap) {
- if(typeof this.options.snap == 'function') {
- p = this.options.snap(p[0],p[1]);
- } else {
- if(this.options.snap instanceof Array) {
- p = p.map( function(v, i) {
- return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
- } else {
- p = p.map( function(v) {
- return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
- }
- }}
-
- var style = this.element.style;
- if((!this.options.constraint) || (this.options.constraint=='horizontal'))
- style.left = p[0] + "px";
- if((!this.options.constraint) || (this.options.constraint=='vertical'))
- style.top = p[1] + "px";
- if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var SortableObserver = Class.create();
-SortableObserver.prototype = {
- initialize: function(element, observer) {
- this.element = $(element);
- this.observer = observer;
- this.lastValue = Sortable.serialize(this.element);
- },
-
- onStart: function() {
- this.lastValue = Sortable.serialize(this.element);
- },
-
- onEnd: function() {
- Sortable.unmark();
- if(this.lastValue != Sortable.serialize(this.element))
- this.observer(this.element)
- }
-}
-
-var Sortable = {
- sortables: new Array(),
-
- options: function(element){
- element = $(element);
- return this.sortables.detect(function(s) { return s.element == element });
- },
-
- destroy: function(element){
- element = $(element);
- this.sortables.findAll(function(s) { return s.element == element }).each(function(s){
- Draggables.removeObserver(s.element);
- s.droppables.each(function(d){ Droppables.remove(d) });
- s.draggables.invoke('destroy');
- });
- this.sortables = this.sortables.reject(function(s) { return s.element == element });
- },
-
- create: function(element) {
- element = $(element);
- var options = Object.extend({
- element: element,
- tag: 'li', // assumes li children, override with tag: 'tagname'
- dropOnEmpty: false,
- tree: false, // fixme: unimplemented
- overlap: 'vertical', // one of 'vertical', 'horizontal'
- constraint: 'vertical', // one of 'vertical', 'horizontal', false
- containment: element, // also takes array of elements (or id's); or false
- handle: false, // or a CSS class
- only: false,
- hoverclass: null,
- ghosting: false,
- format: null,
- onChange: Prototype.emptyFunction,
- onUpdate: Prototype.emptyFunction
- }, arguments[1] || {});
-
- // clear any old sortable with same element
- this.destroy(element);
-
- // build options for the draggables
- var options_for_draggable = {
- revert: true,
- ghosting: options.ghosting,
- constraint: options.constraint,
- handle: options.handle };
-
- if(options.starteffect)
- options_for_draggable.starteffect = options.starteffect;
-
- if(options.reverteffect)
- options_for_draggable.reverteffect = options.reverteffect;
- else
- if(options.ghosting) options_for_draggable.reverteffect = function(element) {
- element.style.top = 0;
- element.style.left = 0;
- };
-
- if(options.endeffect)
- options_for_draggable.endeffect = options.endeffect;
-
- if(options.zindex)
- options_for_draggable.zindex = options.zindex;
-
- // build options for the droppables
- var options_for_droppable = {
- overlap: options.overlap,
- containment: options.containment,
- hoverclass: options.hoverclass,
- onHover: Sortable.onHover,
- greedy: !options.dropOnEmpty
- }
-
- // fix for gecko engine
- Element.cleanWhitespace(element);
-
- options.draggables = [];
- options.droppables = [];
-
- // make it so
-
- // drop on empty handling
- if(options.dropOnEmpty) {
- Droppables.add(element,
- {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false});
- options.droppables.push(element);
- }
-
- (this.findElements(element, options) || []).each( function(e) {
- // handles are per-draggable
- var handle = options.handle ?
- Element.childrenWithClassName(e, options.handle)[0] : e;
- options.draggables.push(
- new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
- Droppables.add(e, options_for_droppable);
- options.droppables.push(e);
- });
-
- // keep reference
- this.sortables.push(options);
-
- // for onupdate
- Draggables.addObserver(new SortableObserver(element, options.onUpdate));
-
- },
-
- // return all suitable-for-sortable elements in a guaranteed order
- findElements: function(element, options) {
- if(!element.hasChildNodes()) return null;
- var elements = [];
- $A(element.childNodes).each( function(e) {
- if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() &&
- (!options.only || (Element.hasClassName(e, options.only))))
- elements.push(e);
- if(options.tree) {
- var grandchildren = this.findElements(e, options);
- if(grandchildren) elements.push(grandchildren);
- }
- });
-
- return (elements.length>0 ? elements.flatten() : null);
- },
-
- onHover: function(element, dropon, overlap) {
- if(overlap>0.5) {
- Sortable.mark(dropon, 'before');
- if(dropon.previousSibling != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden"; // fix gecko rendering
- dropon.parentNode.insertBefore(element, dropon);
- if(dropon.parentNode!=oldParentNode)
- Sortable.options(oldParentNode).onChange(element);
- Sortable.options(dropon.parentNode).onChange(element);
- }
- } else {
- Sortable.mark(dropon, 'after');
- var nextElement = dropon.nextSibling || null;
- if(nextElement != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden"; // fix gecko rendering
- dropon.parentNode.insertBefore(element, nextElement);
- if(dropon.parentNode!=oldParentNode)
- Sortable.options(oldParentNode).onChange(element);
- Sortable.options(dropon.parentNode).onChange(element);
- }
- }
- },
-
- onEmptyHover: function(element, dropon) {
- if(element.parentNode!=dropon) {
- var oldParentNode = element.parentNode;
- dropon.appendChild(element);
- Sortable.options(oldParentNode).onChange(element);
- Sortable.options(dropon).onChange(element);
- }
- },
-
- unmark: function() {
- if(Sortable._marker) Element.hide(Sortable._marker);
- },
-
- mark: function(dropon, position) {
- // mark on ghosting only
- var sortable = Sortable.options(dropon.parentNode);
- if(sortable && !sortable.ghosting) return;
-
- if(!Sortable._marker) {
- Sortable._marker = $('dropmarker') || document.createElement('DIV');
- Element.hide(Sortable._marker);
- Element.addClassName(Sortable._marker, 'dropmarker');
- Sortable._marker.style.position = 'absolute';
- document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
- }
- var offsets = Position.cumulativeOffset(dropon);
- Sortable._marker.style.left = offsets[0] + 'px';
- Sortable._marker.style.top = offsets[1] + 'px';
-
- if(position=='after')
- if(sortable.overlap == 'horizontal')
- Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
- else
- Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
-
- Element.show(Sortable._marker);
- },
-
- serialize: 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] || {});
- 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("&");
- }
-}
\ No newline at end of file
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/effects.js b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/effects.js
deleted file mode 100644
index 414398ce..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/effects.js
+++ /dev/null
@@ -1,854 +0,0 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// Contributors:
-// Justin Palmer (http://encytemedia.com/)
-// Mark Pilgrim (http://diveintomark.org/)
-// Martin Bialasinki
-//
-// See scriptaculous.js for full license.
-
-/* ------------- element ext -------------- */
-
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function() {
- var color = '#';
- if(this.slice(0,4) == 'rgb(') {
- var cols = this.slice(4,this.length-1).split(',');
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
- } else {
- if(this.slice(0,1) == '#') {
- if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
- if(this.length==7) color = this.toLowerCase();
- }
- }
- 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.setStyle = function(element, style) {
- element = $(element);
- for(k in style) element.style[k.camelize()] = style[k];
-}
-
-Element.setContentZoom = function(element, percent) {
- Element.setStyle(element, {fontSize: (percent/100) + 'em'});
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
-}
-
-Element.getOpacity = function(element){
- var opacity;
- if (opacity = Element.getStyle(element, 'opacity'))
- return parseFloat(opacity);
- if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
- if(opacity[1]) return parseFloat(opacity[1]) / 100;
- return 1.0;
-}
-
-Element.setOpacity = function(element, value){
- element= $(element);
- if (value == 1){
- Element.setStyle(element, { opacity:
- (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
- 0.999999 : null });
- if(/MSIE/.test(navigator.userAgent))
- Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
- } else {
- if(value < 0.00001) value = 0;
- Element.setStyle(element, {opacity: value});
- if(/MSIE/.test(navigator.userAgent))
- Element.setStyle(element,
- { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
- 'alpha(opacity='+value*100+')' });
- }
-}
-
-Element.getInlineOpacity = function(element){
- return $(element).style.opacity || '';
-}
-
-Element.childrenWithClassName = function(element, className) {
- return $A($(element).getElementsByTagName('*')).select(
- function(c) { return Element.hasClassName(c, className) });
-}
-
-Array.prototype.call = function() {
- var args = arguments;
- this.each(function(f){ f.apply(this, args) });
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Effect = {
- tagifyText: function(element) {
- var tagifyStyle = 'position:relative';
- if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
- element = $(element);
- $A(element.childNodes).each( function(child) {
- if(child.nodeType==3) {
- child.nodeValue.toArray().each( function(character) {
- element.insertBefore(
- Builder.node('span',{style: tagifyStyle},
- character == ' ' ? String.fromCharCode(160) : character),
- child);
- });
- Element.remove(child);
- }
- });
- },
- multiple: function(element, effect) {
- var elements;
- if(((typeof element == 'object') ||
- (typeof element == 'function')) &&
- (element.length))
- elements = element;
- else
- elements = $(element).childNodes;
-
- var options = Object.extend({
- speed: 0.1,
- delay: 0.0
- }, arguments[2] || {});
- var masterDelay = options.delay;
-
- $A(elements).each( function(element, index) {
- new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
- });
- }
-};
-
-var Effect2 = Effect; // deprecated
-
-/* ------------- transitions ------------- */
-
-Effect.Transitions = {}
-
-Effect.Transitions.linear = function(pos) {
- return pos;
-}
-Effect.Transitions.sinoidal = function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
-}
-Effect.Transitions.reverse = function(pos) {
- return 1-pos;
-}
-Effect.Transitions.flicker = function(pos) {
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
-}
-Effect.Transitions.wobble = function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
-}
-Effect.Transitions.pulse = function(pos) {
- return (Math.floor(pos*10) % 2 == 0 ?
- (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
-}
-Effect.Transitions.none = function(pos) {
- return 0;
-}
-Effect.Transitions.full = function(pos) {
- return 1;
-}
-
-/* ------------- core effects ------------- */
-
-Effect.Queue = {
- effects: [],
- _each: function(iterator) {
- this.effects._each(iterator);
- },
- interval: null,
- add: function(effect) {
- var timestamp = new Date().getTime();
-
- switch(effect.options.queue) {
- case 'front':
- // move unstarted effects after this effect
- this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
- e.startOn += effect.finishOn;
- e.finishOn += effect.finishOn;
- });
- break;
- case 'end':
- // start effect after last queued effect has finished
- timestamp = this.effects.pluck('finishOn').max() || timestamp;
- break;
- }
-
- effect.startOn += timestamp;
- effect.finishOn += timestamp;
- this.effects.push(effect);
- if(!this.interval)
- this.interval = setInterval(this.loop.bind(this), 40);
- },
- remove: function(effect) {
- this.effects = this.effects.reject(function(e) { return e==effect });
- if(this.effects.length == 0) {
- clearInterval(this.interval);
- this.interval = null;
- }
- },
- loop: function() {
- var timePos = new Date().getTime();
- this.effects.invoke('loop', timePos);
- }
-}
-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.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);
- },
- loop: function(timePos) {
- if(timePos >= this.startOn) {
- if(timePos >= this.finishOn) {
- this.render(1.0);
- this.cancel();
- this.event('beforeFinish');
- if(this.finish) this.finish();
- this.event('afterFinish');
- return;
- }
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
- var frame = Math.round(pos * this.options.fps * this.options.duration);
- if(frame > this.currentFrame) {
- this.render(pos);
- this.currentFrame = frame;
- }
- }
- },
- render: function(pos) {
- if(this.state == 'idle') {
- this.state = 'running';
- this.event('beforeSetup');
- if(this.setup) this.setup();
- this.event('afterSetup');
- }
- if(this.state == 'running') {
- if(this.options.transition) pos = this.options.transition(pos);
- pos *= (this.options.to-this.options.from);
- pos += this.options.from;
- this.position = pos;
- this.event('beforeUpdate');
- if(this.update) this.update(pos);
- this.event('afterUpdate');
- }
- },
- cancel: function() {
- if(!this.options.sync) Effect.Queue.remove(this);
- this.state = 'finished';
- },
- event: function(eventName) {
- if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
- if(this.options[eventName]) this.options[eventName](this);
- },
- inspect: function() {
- return '# Hello world! Hello world! tag.
- # This method is only available if RedCloth can be required.
- def textilize_without_paragraph(text)
- textiled = textilize(text)
- if textiled[0..2] == " " then textiled = textiled[3..-1] end
- if textiled[-4..-1] == " ') # turn two newlines into paragraph
- text.gsub!(/([^\n])(\n)([^\n])/, '\1\2 ' + this.content + '
';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function() {
- this.range.setStartBefore(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
- },
-
- insertContent: function(fragments) {
- fragments.reverse(false).each((function(fragment) {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function() {
- this.range.setStartAfter(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment,
- this.element.nextSibling);
- }).bind(this));
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function(element) {
- this.element = $(element);
- },
-
- _each: function(iterator) {
- this.element.className.split(/\s+/).select(function(name) {
- return name.length > 0;
- })._each(iterator);
- },
-
- set: function(className) {
- this.element.className = className;
- },
-
- add: function(classNameToAdd) {
- if (this.include(classNameToAdd)) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
- },
-
- remove: function(classNameToRemove) {
- if (!this.include(classNameToRemove)) return;
- this.set(this.select(function(className) {
- return className != classNameToRemove;
- }).join(' '));
- },
-
- toString: function() {
- return this.toArray().join(' ');
- }
-}
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-var Field = {
- clear: function() {
- for (var i = 0; i < arguments.length; i++)
- $(arguments[i]).value = '';
- },
-
- focus: function(element) {
- $(element).focus();
- },
-
- present: function() {
- for (var i = 0; i < arguments.length; i++)
- if ($(arguments[i]).value == '') return false;
- return true;
- },
-
- select: function(element) {
- $(element).select();
- },
-
- activate: function(element) {
- element = $(element);
- element.focus();
- if (element.select)
- element.select();
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Form = {
- serialize: function(form) {
- var elements = Form.getElements($(form));
- var queryComponents = new Array();
-
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = Form.Element.serialize(elements[i]);
- if (queryComponent)
- queryComponents.push(queryComponent);
- }
-
- return queryComponents.join('&');
- },
-
- getElements: function(form) {
- form = $(form);
- var elements = new Array();
-
- for (tagName in Form.Element.Serializers) {
- var tagElements = form.getElementsByTagName(tagName);
- for (var j = 0; j < tagElements.length; j++)
- elements.push(tagElements[j]);
- }
- return elements;
- },
-
- getInputs: function(form, typeName, name) {
- form = $(form);
- var inputs = form.getElementsByTagName('input');
-
- if (!typeName && !name)
- return inputs;
-
- var matchingInputs = new Array();
- for (var i = 0; i < inputs.length; i++) {
- var input = inputs[i];
- if ((typeName && input.type != typeName) ||
- (name && input.name != name))
- continue;
- matchingInputs.push(input);
- }
-
- return matchingInputs;
- },
-
- disable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- element.blur();
- element.disabled = 'true';
- }
- },
-
- enable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- element.disabled = '';
- }
- },
-
- findFirstElement: function(form) {
- return Form.getElements(form).find(function(element) {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
- });
- },
-
- focusFirstElement: function(form) {
- Field.activate(Form.findFirstElement(form));
- },
-
- reset: function(form) {
- $(form).reset();
- }
-}
-
-Form.Element = {
- serialize: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if (parameter) {
- var key = encodeURIComponent(parameter[0]);
- if (key.length == 0) return;
-
- if (parameter[1].constructor != Array)
- parameter[1] = [parameter[1]];
-
- return parameter[1].map(function(value) {
- return key + '=' + encodeURIComponent(value);
- }).join('&');
- }
- },
-
- getValue: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if (parameter)
- return parameter[1];
- }
-}
-
-Form.Element.Serializers = {
- input: function(element) {
- switch (element.type.toLowerCase()) {
- case 'submit':
- case 'hidden':
- case 'password':
- case 'text':
- return Form.Element.Serializers.textarea(element);
- case 'checkbox':
- case 'radio':
- return Form.Element.Serializers.inputSelector(element);
- }
- return false;
- },
-
- inputSelector: function(element) {
- if (element.checked)
- return [element.name, element.value];
- },
-
- textarea: function(element) {
- return [element.name, element.value];
- },
-
- select: function(element) {
- return Form.Element.Serializers[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- },
-
- selectOne: function(element) {
- var value = '', opt, index = element.selectedIndex;
- if (index >= 0) {
- opt = element.options[index];
- value = opt.value;
- if (!value && !('value' in opt))
- value = opt.text;
- }
- return [element.name, value];
- },
-
- selectMany: function(element) {
- var value = new Array();
- for (var i = 0; i < element.length; i++) {
- var opt = element.options[i];
- if (opt.selected) {
- var optValue = opt.value;
- if (!optValue && !('value' in opt))
- optValue = opt.text;
- value.push(optValue);
- }
- }
- return [element.name, value];
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
- initialize: function(element, frequency, callback) {
- this.frequency = frequency;
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- this.registerCallback();
- },
-
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
- initialize: function(element, callback) {
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- if (this.element.tagName.toLowerCase() == 'form')
- this.registerFormCallbacks();
- else
- this.registerCallback(this.element);
- },
-
- onElementEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- },
-
- registerFormCallbacks: function() {
- var elements = Form.getElements(this.element);
- for (var i = 0; i < elements.length; i++)
- this.registerCallback(elements[i]);
- },
-
- registerCallback: function(element) {
- if (element.type) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- Event.observe(element, 'click', this.onElementEvent.bind(this));
- break;
- case 'password':
- case 'text':
- case 'textarea':
- case 'select-one':
- case 'select-multiple':
- Event.observe(element, 'change', this.onElementEvent.bind(this));
- break;
- }
- }
- }
-}
-
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-if (!window.Event) {
- var Event = new Object();
-}
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
-
- element: function(event) {
- return event.target || event.srcElement;
- },
-
- isLeftClick: function(event) {
- return (((event.which) && (event.which == 1)) ||
- ((event.button) && (event.button == 1)));
- },
-
- pointerX: function(event) {
- return event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
-
- pointerY: function(event) {
- return event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop));
- },
-
- stop: function(event) {
- if (event.preventDefault) {
- event.preventDefault();
- event.stopPropagation();
- } else {
- event.returnValue = false;
- event.cancelBubble = true;
- }
- },
-
- // find the first node with the given tagName, starting from the
- // node the event was triggered on; traverses the DOM upwards
- findElement: function(event, tagName) {
- var element = Event.element(event);
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase())))
- element = element.parentNode;
- return element;
- },
-
- observers: false,
-
- _observeAndCache: function(element, name, observer, useCapture) {
- if (!this.observers) this.observers = [];
- if (element.addEventListener) {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- } else if (element.attachEvent) {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
- }
- },
-
- unloadCache: function() {
- if (!Event.observers) return;
- for (var i = 0; i < Event.observers.length; i++) {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
- }
- Event.observers = false;
- },
-
- observe: function(element, name, observer, useCapture) {
- var element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.attachEvent))
- name = 'keydown';
-
- this._observeAndCache(element, name, observer, useCapture);
- },
-
- stopObserving: function(element, name, observer, useCapture) {
- var element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.detachEvent))
- name = 'keydown';
-
- if (element.removeEventListener) {
- element.removeEventListener(name, observer, useCapture);
- } else if (element.detachEvent) {
- element.detachEvent('on' + name, observer);
- }
- }
-});
-
-/* prevent memory leaks in IE */
-Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
- includeScrollOffsets: false,
-
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
- prepare: function() {
- this.deltaX = window.pageXOffset
- || document.documentElement.scrollLeft
- || document.body.scrollLeft
- || 0;
- this.deltaY = window.pageYOffset
- || document.documentElement.scrollTop
- || document.body.scrollTop
- || 0;
- },
-
- realOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return [valueL, valueT];
- },
-
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return [valueL, valueT];
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
- }
- } while (element);
- return [valueL, valueT];
- },
-
- offsetParent: function(element) {
- if (element.offsetParent) return element.offsetParent;
- if (element == document.body) return element;
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return element;
-
- return document.body;
- },
-
- // caches x/y coordinate pair to use with overlap
- within: function(element, x, y) {
- if (this.includeScrollOffsets)
- return this.withinIncludingScrolloffsets(element, x, y);
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
-
- return (y >= this.offset[1] &&
- y < this.offset[1] + element.offsetHeight &&
- x >= this.offset[0] &&
- x < this.offset[0] + element.offsetWidth);
- },
-
- withinIncludingScrolloffsets: function(element, x, y) {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache[0] - this.deltaX;
- this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset[1] &&
- this.ycomp < this.offset[1] + element.offsetHeight &&
- this.xcomp >= this.offset[0] &&
- this.xcomp < this.offset[0] + element.offsetWidth);
- },
-
- // within must be called directly before
- overlap: function(mode, element) {
- if (!mode) return 0;
- if (mode == 'vertical')
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
- element.offsetHeight;
- if (mode == 'horizontal')
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
- element.offsetWidth;
- },
-
- clone: function(source, target) {
- source = $(source);
- target = $(target);
- target.style.position = 'absolute';
- var offsets = this.cumulativeOffset(source);
- target.style.top = offsets[1] + 'px';
- target.style.left = offsets[0] + 'px';
- target.style.width = source.offsetWidth + 'px';
- target.style.height = source.offsetHeight + 'px';
- },
-
- page: function(forElement) {
- var valueT = 0, valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if (element.offsetParent==document.body)
- if (Element.getStyle(element,'position')=='absolute') break;
-
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- } while (element = element.parentNode);
-
- return [valueL, valueT];
- },
-
- clone: function(source, target) {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
-
- // find page position of source
- source = $(source);
- var p = Position.page(source);
-
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if (Element.getStyle(target,'position') == 'absolute') {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
-
- // correct by body offsets (fixes Safari)
- if (parent == document.body) {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
- }
-
- // set position
- if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if(options.setWidth) target.style.width = source.offsetWidth + 'px';
- if(options.setHeight) target.style.height = source.offsetHeight + 'px';
- },
-
- absolutize: function(element) {
- element = $(element);
- if (element.style.position == 'absolute') return;
- Position.prepare();
-
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';;
- element.style.left = left + 'px';;
- element.style.width = width + 'px';;
- element.style.height = height + 'px';;
- },
-
- relativize: function(element) {
- element = $(element);
- if (element.style.position == 'relative') return;
- Position.prepare();
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
- Position.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
-
- element = element.offsetParent;
- } while (element);
-
- return [valueL, valueT];
- }
-}
\ No newline at end of file
diff --git a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb b/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb
deleted file mode 100644
index 91d79c15..00000000
--- a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-#--
-# Copyright (c) 2004 David Heinemeier Hansson
-#
-# 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.
-#++
-module ActionController #:nodoc:
- class Base
- protected
- def render_action(action_name, status = nil, with_layout = true)
- template = default_template_name(action_name)
- if with_layout && !template_exempt_from_layout?(template)
- render_with_layout(template, status)
- else
- render_without_layout(template, status)
- end
- end
-
- private
- def template_exempt_from_layout?(template_name = default_template_name)
- @template.javascript_template_exists?(template_name)
- end
-
- def default_template_name(default_action_name = action_name)
- default_action_name = default_action_name.dup
- strip_out_controller!(default_action_name) if template_path_includes_controller?(default_action_name)
- "#{self.class.controller_path}/#{default_action_name}"
- end
-
- def strip_out_controller!(path)
- path.replace path.split('/', 2).last
- end
-
- def template_path_includes_controller?(path)
- path.to_s['/'] && self.class.controller_path.split('/')[-1] == path.split('/')[0]
- end
- end
-
- module Layout #:nodoc:
- private
- def apply_layout?(template_with_options, options)
- template_with_options ? candidate_for_layout?(options) : !template_exempt_from_layout?
- end
-
- def candidate_for_layout?(options)
- (options.has_key?(:layout) && options[:layout] != false) ||
- options.values_at(:text, :file, :inline, :partial, :nothing).compact.empty? &&
- !template_exempt_from_layout?(default_template_name(options[:action] || options[:template]))
- end
- end
-end
diff --git a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb b/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb
deleted file mode 100644
index 7b2c2de2..00000000
--- a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb
+++ /dev/null
@@ -1,142 +0,0 @@
-#--
-# Copyright (c) 2004 David Heinemeier Hansson
-#
-# 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.
-#++
-module ActionView
- class Base
- def pick_template_extension(template_path)#:nodoc:
- if match = delegate_template_exists?(template_path)
- match.first
- elsif erb_template_exists?(template_path): 'rhtml'
- elsif builder_template_exists?(template_path): 'rxml'
- elsif javascript_template_exists?(template_path): 'rjs'
- else
- raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path}"
- end
- end
-
- def javascript_template_exists?(template_path)#:nodoc:
- template_exists?(template_path, :rjs)
- end
-
- def file_exists?(template_path)#:nodoc:
- %w(erb builder javascript delegate).any? do |template_type|
- send("#{template_type}_template_exists?", template_path)
- end
- end
-
- private
- # Create source code for given template
- def create_template_source(extension, template, render_symbol, locals)
- if template_requires_setup?(extension)
- body = case extension.to_sym
- when :rxml
- "xml = Builder::XmlMarkup.new(:indent => 2)\n" +
- "@controller.headers['Content-Type'] ||= 'text/xml'\n" +
- template
- when :rjs
- "@controller.headers['Content-Type'] ||= 'text/javascript'\n" +
- "update_page do |page|\n#{template}\nend"
- end
- else
- body = ERB.new(template, nil, @@erb_trim_mode).src
- end
-
- @@template_args[render_symbol] ||= {}
- locals_keys = @@template_args[render_symbol].keys | locals
- @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h }
-
- locals_code = ""
- locals_keys.each do |key|
- locals_code << "#{key} = local_assigns[:#{key}] if local_assigns.has_key?(:#{key})\n"
- end
-
- "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
- end
-
- def template_requires_setup?(extension)
- templates_requiring_setup.include? extension.to_s
- end
-
- def templates_requiring_setup
- %w(rxml rjs)
- end
-
- def assign_method_name(extension, template, file_name)
- method_name = '_run_'
- method_name << "#{extension}_" if extension
-
- if file_name
- file_path = File.expand_path(file_name)
- base_path = File.expand_path(@base_path)
-
- i = file_path.index(base_path)
- l = base_path.length
-
- method_name_file_part = i ? file_path[i+l+1,file_path.length-l-1] : file_path.clone
- method_name_file_part.sub!(/\.r(html|xml|js)$/,'')
- method_name_file_part.tr!('/:-', '_')
- method_name_file_part.gsub!(/[^a-zA-Z0-9_]/){|s| s[0].to_s}
-
- method_name += method_name_file_part
- else
- @@inline_template_count += 1
- method_name << @@inline_template_count.to_s
- end
-
- @@method_names[file_name || template] = method_name.intern
- end
-
- def compile_template(extension, template, file_name, local_assigns)
- method_key = file_name || template
-
- render_symbol = @@method_names[method_key] || assign_method_name(extension, template, file_name)
- render_source = create_template_source(extension, template, render_symbol, local_assigns.keys)
-
- line_offset = @@template_args[render_symbol].size
- if extension
- case extension.to_sym
- when :rxml, :rjs
- line_offset += 2
- end
- end
-
- begin
- unless file_name.blank?
- CompiledTemplates.module_eval(render_source, file_name, -line_offset)
- else
- CompiledTemplates.module_eval(render_source, 'compiled-template', -line_offset)
- end
- rescue Object => e
- if logger
- logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
- logger.debug "Function body: #{render_source}"
- logger.debug "Backtrace: #{e.backtrace.join("\n")}"
- end
-
- raise TemplateError.new(@base_path, method_key, @assigns, template, e)
- end
-
- @@compile_time[render_symbol] = Time.now
- # logger.debug "Compiled template #{method_key}\n ==> #{render_symbol}" if logger
- end
- end
-end
diff --git a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb b/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb
deleted file mode 100644
index 04201e46..00000000
--- a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb
+++ /dev/null
@@ -1,204 +0,0 @@
-#--
-# Copyright (c) 2004 David Heinemeier Hansson
-#
-# 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.
-#++
-module ActionView
- module Helpers
- module JavaScriptHelper
- # JavaScriptGenerator generates blocks of JavaScript code that allow you
- # to change the content and presentation of multiple DOM elements. Use
- # this in your Ajax response bodies, either in a ),
- periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" })
- end
-
- def test_form_remote_tag
- assert_dom_equal %("
- def end_form_tag
- ""
- end
-
- # Creates a dropdown selection box, or if the :multiple option is set to true, a multiple
- # choice selection box.
- #
- # Helpers::FormOptions can be used to create common select boxes such as countries, time zones, or
- # associated records.
- #
- # option_tags is a string containing the option tags for the select box:
- # # Outputs
- # select_tag "people", ""
- #
- # Options:
- # * :multiple - If set to true the selection will allow multiple choices.
- def select_tag(name, option_tags = nil, options = {})
- content_tag("select", option_tags, { "name" => name, "id" => name }.update(options.stringify_keys))
- end
-
- # Creates a standard text field.
- #
- # Options:
- # * :disabled - If set to true, the user will not be able to use this input.
- # * :size - The number of visible characters that will fit in the input.
- # * :maxlength - The maximum number of characters that the browser will allow the user to enter.
- #
- # A hash of standard HTML options for the tag.
- def text_field_tag(name, value = nil, options = {})
- tag("input", { "type" => "text", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys))
- end
-
- # Creates a hidden field.
- #
- # Takes the same options as text_field_tag
- def hidden_field_tag(name, value = nil, options = {})
- text_field_tag(name, value, options.stringify_keys.update("type" => "hidden"))
- end
-
- # Creates a file upload field.
- #
- # If you are using file uploads then you will also need to set the multipart option for the form:
- # <%= form_tag { :action => "post" }, { :multipart => true } %>
- # <%= file_field_tag "file" %>
- # <%= submit_tag %>
- # <%= end_form_tag %>
- #
- # The specified URL will then be passed a File object containing the selected file, or if the field
- # was left blank, a StringIO object.
- def file_field_tag(name, options = {})
- text_field_tag(name, nil, options.update("type" => "file"))
- end
-
- # Creates a password field.
- #
- # Takes the same options as text_field_tag
- def password_field_tag(name = "password", value = nil, options = {})
- text_field_tag(name, value, options.update("type" => "password"))
- end
-
- # Creates a text input area.
- #
- # Options:
- # * :size - A string specifying the dimensions of the textarea.
- # # Outputs
- # <%= text_area_tag "body", nil, :size => "25x10" %>
- def text_area_tag(name, content = nil, options = {})
- options = options.stringify_keys
- if options["size"]
- options["cols"], options["rows"] = options["size"].split("x")
- options.delete("size")
- end
-
- content_tag("textarea", content, { "name" => name, "id" => name }.update(options.stringify_keys))
- end
-
- # Creates a check box.
- def check_box_tag(name, value = "1", checked = false, options = {})
- html_options = { "type" => "checkbox", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys)
- html_options["checked"] = "checked" if checked
- tag("input", html_options)
- end
-
- # Creates a radio button.
- def radio_button_tag(name, value, checked = false, options = {})
- html_options = { "type" => "radio", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys)
- html_options["checked"] = "checked" if checked
- tag("input", html_options)
- end
-
- # Creates a submit button with the text value as the caption.
- def submit_tag(value = "Save changes", options = {})
- tag("input", { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys))
- end
-
- # Displays an image which when clicked will submit the form.
- #
- # source is passed to AssetTagHelper#image_path
- def image_submit_tag(source, options = {})
- tag("input", { "type" => "image", "src" => image_path(source) }.update(options.stringify_keys))
- end
- end
- end
-end
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb
deleted file mode 100644
index f0fc0925..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb
+++ /dev/null
@@ -1,190 +0,0 @@
-require File.dirname(__FILE__) + '/tag_helper'
-
-module ActionView
- module Helpers
- # Provides a set of helpers for creating JavaScript macros that rely on and often bundle methods from JavaScriptHelper into
- # larger units. These macros also rely on counterparts in the controller that provide them with their backing. The in-place
- # editing relies on ActionController::Base.in_place_edit_for and the autocompletion relies on
- # ActionController::Base.auto_complete_for.
- module JavaScriptMacrosHelper
- # Makes an HTML element specified by the DOM ID +field_id+ become an in-place
- # editor of a property.
- #
- # A form is automatically created and displayed when the user clicks the element,
- # something like this:
- # list,
- # or nothing if no entries should be displayed for autocompletion.
- #
- # You'll probably want to turn the browser's built-in autocompletion off,
- # su be sure to include a autocomplete="off" attribute with your text
- # input field.
- #
- # Required +options+ are:
- # :url:: URL to call for autocompletion results
- # in url_for format.
- #
- # Addtional +options+ are:
- # :update:: Specifies the DOM ID of the element whose
- # innerHTML should be updated with the autocomplete
- # entries returned by the AJAX request.
- # Defaults to field_id + '_auto_complete'
- # :with:: A JavaScript expression specifying the
- # parameters for the XMLHttpRequest. This defaults
- # to 'fieldname=value'.
- # :indicator:: Specifies the DOM ID of an element which will be
- # displayed while autocomplete is running.
- # :tokens:: A string or an array of strings containing
- # separator tokens for tokenized incremental
- # autocompletion. Example: :tokens => ',' would
- # allow multiple autocompletion entries, separated
- # by commas.
- # :min_chars:: The minimum number of characters that should be
- # in the input field before an Ajax call is made
- # to the server.
- # :on_hide:: A Javascript expression that is called when the
- # autocompletion div is hidden. The expression
- # should take two variables: element and update.
- # Element is a DOM element for the field, update
- # is a DOM element for the div from which the
- # innerHTML is replaced.
- # :on_show:: Like on_hide, only now the expression is called
- # then the div is shown.
- def auto_complete_field(field_id, options = {})
- function = "new Ajax.Autocompleter("
- function << "'#{field_id}', "
- function << "'" + (options[:update] || "#{field_id}_auto_complete") + "', "
- function << "'#{url_for(options[:url])}'"
-
- js_options = {}
- js_options[:tokens] = array_or_string_for_javascript(options[:tokens]) if options[:tokens]
- js_options[:callback] = "function(element, value) { return #{options[:with]} }" if options[:with]
- js_options[:indicator] = "'#{options[:indicator]}'" if options[:indicator]
- {:on_show => :onShow, :on_hide => :onHide, :min_chars => :min_chars}.each do |k,v|
- js_options[v] = options[k] if options[k]
- end
- function << (', ' + options_for_javascript(js_options) + ')')
-
- javascript_tag(function)
- end
-
- # Use this method in your view to generate a return for the AJAX autocomplete requests.
- #
- # Example action:
- #
- # def auto_complete_for_item_title
- # @items = Item.find(:all,
- # :conditions => [ 'LOWER(description) LIKE ?',
- # '%' + request.raw_post.downcase + '%' ])
- # render :inline => '<%= auto_complete_result(@items, 'description') %>'
- # end
- #
- # The auto_complete_result can of course also be called from a view belonging to the
- # auto_complete action if you need to decorate it further.
- def auto_complete_result(entries, field, phrase = nil)
- return unless entries
- items = entries.map { |entry| content_tag("li", phrase ? highlight(entry[field], phrase) : h(entry[field])) }
- content_tag("ul", items.uniq)
- end
-
- # Wrapper for text_field with added AJAX autocompletion functionality.
- #
- # In your controller, you'll need to define an action called
- # auto_complete_for_object_method to respond the AJAX calls,
- #
- # See the RDoc on ActionController::AutoComplete to learn more about this.
- def text_field_with_auto_complete(object, method, tag_options = {}, completion_options = {})
- (completion_options[:skip_style] ? "" : auto_complete_stylesheet) +
- text_field(object, method, tag_options) +
- content_tag("div", "", :id => "#{object}_#{method}_auto_complete", :class => "auto_complete") +
- auto_complete_field("#{object}_#{method}", { :url => { :action => "auto_complete_for_#{object}_#{method}" } }.update(completion_options))
- end
-
- private
- def auto_complete_stylesheet
- content_tag("style", <<-EOT
- div.auto_complete {
- width: 350px;
- background: #fff;
- }
- div.auto_complete ul {
- border:1px solid #888;
- margin:0;
- padding:0;
- width:100%;
- list-style-type:none;
- }
- div.auto_complete ul li {
- margin:0;
- padding:3px;
- }
- div.auto_complete ul li.selected {
- background-color: #ffb;
- }
- div.auto_complete ul strong.highlight {
- color: #800;
- margin:0;
- padding:0;
- }
- EOT
- )
- end
-
- end
- end
-end
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb
deleted file mode 100644
index e7109e92..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ /dev/null
@@ -1,528 +0,0 @@
-require File.dirname(__FILE__) + '/tag_helper'
-
-module ActionView
- module Helpers
- # Provides a set of helpers for calling JavaScript functions and, most importantly, to call remote methods using what has
- # been labelled AJAX[http://www.adaptivepath.com/publications/essays/archives/000385.php]. This means that you can call
- # actions in your controllers without reloading the page, but still update certain parts of it using injections into the
- # DOM. The common use case is having a form that adds a new element to a list without reloading the page.
- #
- # To be able to use the JavaScript helpers, you must include the Prototype JavaScript Framework and for some functions
- # script.aculo.us (which both come with Rails) on your pages. Choose one of these options:
- #
- # * Use <%= javascript_include_tag :defaults %> in the HEAD section of your page (recommended):
- # The function will return references to the JavaScript files created by the +rails+ command in your
- # public/javascripts directory. Using it is recommended as the browser can then cache the libraries
- # instead of fetching all the functions anew on every request.
- # * Use <%= javascript_include_tag 'prototype' %>: As above, but will only include the Prototype core library,
- # which means you are able to use all basic AJAX functionality. For the script.aculo.us-based JavaScript helpers,
- # like visual effects, autocompletion, drag and drop and so on, you should use the method described above.
- # * Use <%= define_javascript_functions %>: this will copy all the JavaScript support functions within a single
- # script block.
- #
- # For documentation on +javascript_include_tag+ see ActionView::Helpers::AssetTagHelper.
- #
- # If you're the visual type, there's an AJAX movie[http://www.rubyonrails.com/media/video/rails-ajax.mov] demonstrating
- # the use of form_remote_tag.
- module JavaScriptHelper
- unless const_defined? :CALLBACKS
- CALLBACKS =
- [:uninitialized, :loading, :loaded, :interactive, :complete, :failure, :success].push((100..599).to_a).flatten
- AJAX_OPTIONS = [ :before, :after, :condition, :url, :asynchronous, :method,
- :insertion, :position, :form, :with, :update, :script ].concat(CALLBACKS)
- JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts')
- end
-
- # Returns a link that'll trigger a javascript +function+ using the
- # onclick handler and return false after the fact.
- #
- # Examples:
- # link_to_function "Greeting", "alert('Hello world!')"
- # link_to_function(image_tag("delete"), "if confirm('Really?'){ do_delete(); }")
- def link_to_function(name, function, html_options = {})
- content_tag(
- "a", name,
- {:href => "#", :onclick => "#{function}; return false;"}.merge(html_options.symbolize_keys)
- )
- end
-
- # Returns a link to a remote action defined by options[:url]
- # (using the url_for format) that's called in the background using
- # XMLHttpRequest. The result of that request can then be inserted into a
- # DOM object whose id can be specified with options[:update].
- # Usually, the result would be a partial prepared by the controller with
- # either render_partial or render_partial_collection.
- #
- # Examples:
- # link_to_remote "Delete this post", :update => "posts", :url => { :action => "destroy", :id => post.id }
- # link_to_remote(image_tag("refresh"), :update => "emails", :url => { :action => "list_emails" })
- #
- # You can also specify a hash for options[:update] to allow for
- # easy redirection of output to an other DOM element if a server-side error occurs:
- #
- # Example:
- # link_to_remote "Delete this post",
- # :url => { :action => "destroy", :id => post.id },
- # :update => { :success => "posts", :failure => "error" }
- #
- # Optionally, you can use the options[:position] parameter to influence
- # how the target DOM element is updated. It must be one of
- # :before, :top, :bottom, or :after.
- #
- # By default, these remote requests are processed asynchronous during
- # which various JavaScript callbacks can be triggered (for progress indicators and
- # the likes). All callbacks get access to the request object,
- # which holds the underlying XMLHttpRequest.
- #
- # To access the server response, use request.responseText, to
- # find out the HTTP status, use request.status.
- #
- # Example:
- # link_to_remote word,
- # :url => { :action => "undo", :n => word_counter },
- # :complete => "undoRequestCompleted(request)"
- #
- # The callbacks that may be specified are (in order):
- #
- # :loading:: Called when the remote document is being
- # loaded with data by the browser.
- # :loaded:: Called when the browser has finished loading
- # the remote document.
- # :interactive:: Called when the user can interact with the
- # remote document, even though it has not
- # finished loading.
- # :success:: Called when the XMLHttpRequest is completed,
- # and the HTTP status code is in the 2XX range.
- # :failure:: Called when the XMLHttpRequest is completed,
- # and the HTTP status code is not in the 2XX
- # range.
- # :complete:: Called when the XMLHttpRequest is complete
- # (fires after success/failure if they are present).,
- #
- # You can further refine :success and :failure by adding additional
- # callbacks for specific status codes:
- #
- # Example:
- # link_to_remote word,
- # :url => { :action => "action" },
- # 404 => "alert('Not found...? Wrong URL...?')",
- # :failure => "alert('HTTP Error ' + request.status + '!')"
- #
- # A status code callback overrides the success/failure handlers if present.
- #
- # If you for some reason or another need synchronous processing (that'll
- # block the browser while the request is happening), you can specify
- # options[:type] = :synchronous.
- #
- # You can customize further browser side call logic by passing
- # in JavaScript code snippets via some optional parameters. In
- # their order of use these are:
- #
- # :confirm:: Adds confirmation dialog.
- # :condition:: Perform remote request conditionally
- # by this expression. Use this to
- # describe browser-side conditions when
- # request should not be initiated.
- # :before:: Called before request is initiated.
- # :after:: Called immediately after request was
- # initiated and before :loading.
- # :submit:: Specifies the DOM element ID that's used
- # as the parent of the form elements. By
- # default this is the current form, but
- # it could just as well be the ID of a
- # table row or any other DOM element.
- def link_to_remote(name, options = {}, html_options = {})
- link_to_function(name, remote_function(options), html_options)
- end
-
- # Periodically calls the specified url (options[:url]) every options[:frequency] seconds (default is 10).
- # Usually used to update a specified div (options[:update]) with the results of the remote call.
- # The options for specifying the target with :url and defining callbacks is the same as link_to_remote.
- def periodically_call_remote(options = {})
- frequency = options[:frequency] || 10 # every ten seconds by default
- code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})"
- javascript_tag(code)
- end
-
- # Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular
- # reloading POST arrangement. Even though it's using JavaScript to serialize the form elements, the form submission
- # will work just like a regular submission as viewed by the receiving side (all elements available in @params).
- # The options for specifying the target with :url and defining callbacks is the same as link_to_remote.
- #
- # A "fall-through" target for browsers that doesn't do JavaScript can be specified with the :action/:method options on :html
- #
- # form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") }
- # The Hash passed to the :html key is equivalent to the options (2nd) argument in the FormTagHelper.form_tag method.
- #
- # By default the fall-through action is the same as the one specified in the :url (and the default method is :post).
- def form_remote_tag(options = {})
- options[:form] = true
-
- options[:html] ||= {}
- options[:html][:onsubmit] = "#{remote_function(options)}; return false;"
- options[:html][:action] = options[:html][:action] || url_for(options[:url])
- options[:html][:method] = options[:html][:method] || "post"
-
- tag("form", options[:html], true)
- end
-
- # Returns a button input tag that will submit form using XMLHttpRequest in the background instead of regular
- # reloading POST arrangement. options argument is the same as in form_remote_tag
- def submit_to_remote(name, value, options = {})
- options[:with] ||= 'Form.serialize(this.form)'
-
- options[:html] ||= {}
- options[:html][:type] = 'button'
- options[:html][:onclick] = "#{remote_function(options)}; return false;"
- options[:html][:name] = name
- options[:html][:value] = value
-
- tag("input", options[:html], false)
- end
-
- # Returns a Javascript function (or expression) that'll update a DOM element according to the options passed.
- #
- # * :content: The content to use for updating. Can be left out if using block, see example.
- # * :action: Valid options are :update (assumed by default), :empty, :remove
- # * :position If the :action is :update, you can optionally specify one of the following positions: :before, :top, :bottom, :after.
- #
- # Examples:
- # <%= javascript_tag(update_element_function(
- # "products", :position => :bottom, :content => "
" + ret.join('') + "
";
- }
- }, options || {});
- }
-});
-
-// AJAX in-place editor
-//
-// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
-
-// Use this if you notice weird scrolling problems on some browsers,
-// the DOM might be a bit confused when this gets called so do this
-// waits 1 ms (with setTimeout) until it does the activation
-Field.scrollFreeActivate = function(field) {
- setTimeout(function() {
- Field.activate(field);
- }, 1);
-}
-
-Ajax.InPlaceEditor = Class.create();
-Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
-Ajax.InPlaceEditor.prototype = {
- initialize: function(element, url, options) {
- this.url = url;
- this.element = $(element);
-
- this.options = Object.extend({
- okText: "ok",
- cancelText: "cancel",
- savingText: "Saving...",
- clickToEditText: "Click to edit",
- okText: "ok",
- rows: 1,
- onComplete: function(transport, element) {
- new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
- },
- onFailure: function(transport) {
- alert("Error communicating with the server: " + transport.responseText.stripTags());
- },
- callback: function(form) {
- return Form.serialize(form);
- },
- handleLineBreaks: true,
- loadingText: 'Loading...',
- savingClassName: 'inplaceeditor-saving',
- loadingClassName: 'inplaceeditor-loading',
- formClassName: 'inplaceeditor-form',
- highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
- highlightendcolor: "#FFFFFF",
- externalControl: null,
- ajaxOptions: {}
- }, options || {});
-
- if(!this.options.formId && this.element.id) {
- this.options.formId = this.element.id + "-inplaceeditor";
- if ($(this.options.formId)) {
- // there's already a form with that name, don't specify an id
- this.options.formId = null;
- }
- }
-
- if (this.options.externalControl) {
- this.options.externalControl = $(this.options.externalControl);
- }
-
- this.originalBackground = Element.getStyle(this.element, 'background-color');
- if (!this.originalBackground) {
- this.originalBackground = "transparent";
- }
-
- this.element.title = this.options.clickToEditText;
-
- this.onclickListener = this.enterEditMode.bindAsEventListener(this);
- this.mouseoverListener = this.enterHover.bindAsEventListener(this);
- this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
- Event.observe(this.element, 'click', this.onclickListener);
- Event.observe(this.element, 'mouseover', this.mouseoverListener);
- Event.observe(this.element, 'mouseout', this.mouseoutListener);
- if (this.options.externalControl) {
- Event.observe(this.options.externalControl, 'click', this.onclickListener);
- Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
- Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
- }
- },
- enterEditMode: function(evt) {
- if (this.saving) return;
- if (this.editing) return;
- this.editing = true;
- this.onEnterEditMode();
- if (this.options.externalControl) {
- Element.hide(this.options.externalControl);
- }
- Element.hide(this.element);
- this.createForm();
- this.element.parentNode.insertBefore(this.form, this.element);
- Field.scrollFreeActivate(this.editField);
- // stop the event to avoid a page refresh in Safari
- if (evt) {
- Event.stop(evt);
- }
- return false;
- },
- createForm: function() {
- this.form = document.createElement("form");
- this.form.id = this.options.formId;
- Element.addClassName(this.form, this.options.formClassName)
- this.form.onsubmit = this.onSubmit.bind(this);
-
- this.createEditField();
-
- if (this.options.textarea) {
- var br = document.createElement("br");
- 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);
- },
- hasHTMLLineBreaks: function(string) {
- if (!this.options.handleLineBreaks) return false;
- return string.match(/
/i);
- },
- convertHTMLLineBreaks: function(string) {
- return string.replace(/
/gi, "\n").replace(/
/gi, "\n").replace(/<\/p>/gi, "\n").replace(/' + this.content + '
';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function() {
- this.range.setStartBefore(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
- },
-
- insertContent: function(fragments) {
- fragments.reverse(false).each((function(fragment) {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function() {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function() {
- this.range.setStartAfter(this.element);
- },
-
- insertContent: function(fragments) {
- fragments.each((function(fragment) {
- this.element.parentNode.insertBefore(fragment,
- this.element.nextSibling);
- }).bind(this));
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function(element) {
- this.element = $(element);
- },
-
- _each: function(iterator) {
- this.element.className.split(/\s+/).select(function(name) {
- return name.length > 0;
- })._each(iterator);
- },
-
- set: function(className) {
- this.element.className = className;
- },
-
- add: function(classNameToAdd) {
- if (this.include(classNameToAdd)) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
- },
-
- remove: function(classNameToRemove) {
- if (!this.include(classNameToRemove)) return;
- this.set(this.select(function(className) {
- return className != classNameToRemove;
- }).join(' '));
- },
-
- toString: function() {
- return this.toArray().join(' ');
- }
-}
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-var Field = {
- clear: function() {
- for (var i = 0; i < arguments.length; i++)
- $(arguments[i]).value = '';
- },
-
- focus: function(element) {
- $(element).focus();
- },
-
- present: function() {
- for (var i = 0; i < arguments.length; i++)
- if ($(arguments[i]).value == '') return false;
- return true;
- },
-
- select: function(element) {
- $(element).select();
- },
-
- activate: function(element) {
- element = $(element);
- element.focus();
- if (element.select)
- element.select();
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Form = {
- serialize: function(form) {
- var elements = Form.getElements($(form));
- var queryComponents = new Array();
-
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = Form.Element.serialize(elements[i]);
- if (queryComponent)
- queryComponents.push(queryComponent);
- }
-
- return queryComponents.join('&');
- },
-
- getElements: function(form) {
- form = $(form);
- var elements = new Array();
-
- for (tagName in Form.Element.Serializers) {
- var tagElements = form.getElementsByTagName(tagName);
- for (var j = 0; j < tagElements.length; j++)
- elements.push(tagElements[j]);
- }
- return elements;
- },
-
- getInputs: function(form, typeName, name) {
- form = $(form);
- var inputs = form.getElementsByTagName('input');
-
- if (!typeName && !name)
- return inputs;
-
- var matchingInputs = new Array();
- for (var i = 0; i < inputs.length; i++) {
- var input = inputs[i];
- if ((typeName && input.type != typeName) ||
- (name && input.name != name))
- continue;
- matchingInputs.push(input);
- }
-
- return matchingInputs;
- },
-
- disable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- element.blur();
- element.disabled = 'true';
- }
- },
-
- enable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- element.disabled = '';
- }
- },
-
- findFirstElement: function(form) {
- return Form.getElements(form).find(function(element) {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
- });
- },
-
- focusFirstElement: function(form) {
- Field.activate(Form.findFirstElement(form));
- },
-
- reset: function(form) {
- $(form).reset();
- }
-}
-
-Form.Element = {
- serialize: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if (parameter) {
- var key = encodeURIComponent(parameter[0]);
- if (key.length == 0) return;
-
- if (parameter[1].constructor != Array)
- parameter[1] = [parameter[1]];
-
- return parameter[1].map(function(value) {
- return key + '=' + encodeURIComponent(value);
- }).join('&');
- }
- },
-
- getValue: function(element) {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if (parameter)
- return parameter[1];
- }
-}
-
-Form.Element.Serializers = {
- input: function(element) {
- switch (element.type.toLowerCase()) {
- case 'submit':
- case 'hidden':
- case 'password':
- case 'text':
- return Form.Element.Serializers.textarea(element);
- case 'checkbox':
- case 'radio':
- return Form.Element.Serializers.inputSelector(element);
- }
- return false;
- },
-
- inputSelector: function(element) {
- if (element.checked)
- return [element.name, element.value];
- },
-
- textarea: function(element) {
- return [element.name, element.value];
- },
-
- select: function(element) {
- return Form.Element.Serializers[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- },
-
- selectOne: function(element) {
- var value = '', opt, index = element.selectedIndex;
- if (index >= 0) {
- opt = element.options[index];
- value = opt.value;
- if (!value && !('value' in opt))
- value = opt.text;
- }
- return [element.name, value];
- },
-
- selectMany: function(element) {
- var value = new Array();
- for (var i = 0; i < element.length; i++) {
- var opt = element.options[i];
- if (opt.selected) {
- var optValue = opt.value;
- if (!optValue && !('value' in opt))
- optValue = opt.text;
- value.push(optValue);
- }
- }
- return [element.name, value];
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function() {}
-Abstract.TimedObserver.prototype = {
- initialize: function(element, frequency, callback) {
- this.frequency = frequency;
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- this.registerCallback();
- },
-
- registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function() {}
-Abstract.EventObserver.prototype = {
- initialize: function(element, callback) {
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- if (this.element.tagName.toLowerCase() == 'form')
- this.registerFormCallbacks();
- else
- this.registerCallback(this.element);
- },
-
- onElementEvent: function() {
- var value = this.getValue();
- if (this.lastValue != value) {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- },
-
- registerFormCallbacks: function() {
- var elements = Form.getElements(this.element);
- for (var i = 0; i < elements.length; i++)
- this.registerCallback(elements[i]);
- },
-
- registerCallback: function(element) {
- if (element.type) {
- switch (element.type.toLowerCase()) {
- case 'checkbox':
- case 'radio':
- Event.observe(element, 'click', this.onElementEvent.bind(this));
- break;
- case 'password':
- case 'text':
- case 'textarea':
- case 'select-one':
- case 'select-multiple':
- Event.observe(element, 'change', this.onElementEvent.bind(this));
- break;
- }
- }
- }
-}
-
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function() {
- return Form.serialize(this.element);
- }
-});
-if (!window.Event) {
- var Event = new Object();
-}
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
-
- element: function(event) {
- return event.target || event.srcElement;
- },
-
- isLeftClick: function(event) {
- return (((event.which) && (event.which == 1)) ||
- ((event.button) && (event.button == 1)));
- },
-
- pointerX: function(event) {
- return event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
-
- pointerY: function(event) {
- return event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop));
- },
-
- stop: function(event) {
- if (event.preventDefault) {
- event.preventDefault();
- event.stopPropagation();
- } else {
- event.returnValue = false;
- event.cancelBubble = true;
- }
- },
-
- // find the first node with the given tagName, starting from the
- // node the event was triggered on; traverses the DOM upwards
- findElement: function(event, tagName) {
- var element = Event.element(event);
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase())))
- element = element.parentNode;
- return element;
- },
-
- observers: false,
-
- _observeAndCache: function(element, name, observer, useCapture) {
- if (!this.observers) this.observers = [];
- if (element.addEventListener) {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- } else if (element.attachEvent) {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
- }
- },
-
- unloadCache: function() {
- if (!Event.observers) return;
- for (var i = 0; i < Event.observers.length; i++) {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
- }
- Event.observers = false;
- },
-
- observe: function(element, name, observer, useCapture) {
- var element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.attachEvent))
- name = 'keydown';
-
- this._observeAndCache(element, name, observer, useCapture);
- },
-
- stopObserving: function(element, name, observer, useCapture) {
- var element = $(element);
- useCapture = useCapture || false;
-
- if (name == 'keypress' &&
- (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
- || element.detachEvent))
- name = 'keydown';
-
- if (element.removeEventListener) {
- element.removeEventListener(name, observer, useCapture);
- } else if (element.detachEvent) {
- element.detachEvent('on' + name, observer);
- }
- }
-});
-
-/* prevent memory leaks in IE */
-Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
- includeScrollOffsets: false,
-
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
- prepare: function() {
- this.deltaX = window.pageXOffset
- || document.documentElement.scrollLeft
- || document.body.scrollLeft
- || 0;
- this.deltaY = window.pageYOffset
- || document.documentElement.scrollTop
- || document.body.scrollTop
- || 0;
- },
-
- realOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return [valueL, valueT];
- },
-
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return [valueL, valueT];
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
- }
- } while (element);
- return [valueL, valueT];
- },
-
- offsetParent: function(element) {
- if (element.offsetParent) return element.offsetParent;
- if (element == document.body) return element;
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return element;
-
- return document.body;
- },
-
- // caches x/y coordinate pair to use with overlap
- within: function(element, x, y) {
- if (this.includeScrollOffsets)
- return this.withinIncludingScrolloffsets(element, x, y);
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
-
- return (y >= this.offset[1] &&
- y < this.offset[1] + element.offsetHeight &&
- x >= this.offset[0] &&
- x < this.offset[0] + element.offsetWidth);
- },
-
- withinIncludingScrolloffsets: function(element, x, y) {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache[0] - this.deltaX;
- this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset[1] &&
- this.ycomp < this.offset[1] + element.offsetHeight &&
- this.xcomp >= this.offset[0] &&
- this.xcomp < this.offset[0] + element.offsetWidth);
- },
-
- // within must be called directly before
- overlap: function(mode, element) {
- if (!mode) return 0;
- if (mode == 'vertical')
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
- element.offsetHeight;
- if (mode == 'horizontal')
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
- element.offsetWidth;
- },
-
- clone: function(source, target) {
- source = $(source);
- target = $(target);
- target.style.position = 'absolute';
- var offsets = this.cumulativeOffset(source);
- target.style.top = offsets[1] + 'px';
- target.style.left = offsets[0] + 'px';
- target.style.width = source.offsetWidth + 'px';
- target.style.height = source.offsetHeight + 'px';
- },
-
- page: function(forElement) {
- var valueT = 0, valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if (element.offsetParent==document.body)
- if (Element.getStyle(element,'position')=='absolute') break;
-
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- } while (element = element.parentNode);
-
- return [valueL, valueT];
- },
-
- clone: function(source, target) {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
-
- // find page position of source
- source = $(source);
- var p = Position.page(source);
-
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if (Element.getStyle(target,'position') == 'absolute') {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
-
- // correct by body offsets (fixes Safari)
- if (parent == document.body) {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
- }
-
- // set position
- if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if(options.setWidth) target.style.width = source.offsetWidth + 'px';
- if(options.setHeight) target.style.height = source.offsetHeight + 'px';
- },
-
- absolutize: function(element) {
- element = $(element);
- if (element.style.position == 'absolute') return;
- Position.prepare();
-
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';;
- element.style.left = left + 'px';;
- element.style.width = width + 'px';;
- element.style.height = height + 'px';;
- },
-
- relativize: function(element) {
- element = $(element);
- if (element.style.position == 'relative') return;
- Position.prepare();
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
- Position.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
-
- element = element.offsetParent;
- } while (element);
-
- return [valueL, valueT];
- }
-}
\ No newline at end of file
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb
deleted file mode 100644
index e06eb14f..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-module ActionView
- module Helpers
- # Provides methods for converting a number into a formatted string that currently represents
- # one of the following forms: phone number, percentage, money, or precision level.
- module NumberHelper
-
- # Formats a +number+ into a US phone number string. The +options+ can be a hash used to customize the format of the output.
- # The area code can be surrounded by parentheses by setting +:area_code+ to true; default is false
- # The delimiter can be set using +:delimiter+; default is "-"
- # Examples:
- # number_to_phone(1235551234) => 123-555-1234
- # number_to_phone(1235551234, {:area_code => true}) => (123) 555-1234
- # number_to_phone(1235551234, {:delimiter => " "}) => 123 555 1234
- # number_to_phone(1235551234, {:area_code => true, :extension => 555}) => (123) 555-1234 x 555
- def number_to_phone(number, options = {})
- options = options.stringify_keys
- area_code = options.delete("area_code") { false }
- delimiter = options.delete("delimiter") { "-" }
- extension = options.delete("extension") { "" }
- begin
- str = area_code == true ? number.to_s.gsub(/([0-9]{3})([0-9]{3})([0-9]{4})/,"(\\1) \\2#{delimiter}\\3") : number.to_s.gsub(/([0-9]{3})([0-9]{3})([0-9]{4})/,"\\1#{delimiter}\\2#{delimiter}\\3")
- extension.to_s.strip.empty? ? str : "#{str} x #{extension.to_s.strip}"
- rescue
- number
- end
- end
-
- # Formats a +number+ into a currency string. The +options+ hash can be used to customize the format of the output.
- # The +number+ can contain a level of precision using the +precision+ key; default is 2
- # The currency type can be set using the +unit+ key; default is "$"
- # The unit separator can be set using the +separator+ key; default is "."
- # The delimiter can be set using the +delimiter+ key; default is ","
- # Examples:
- # number_to_currency(1234567890.50) => $1,234,567,890.50
- # number_to_currency(1234567890.506) => $1,234,567,890.51
- # number_to_currency(1234567890.50, {:unit => "£", :separator => ",", :delimiter => ""}) => £1234567890,50
- def number_to_currency(number, options = {})
- options = options.stringify_keys
- precision, unit, separator, delimiter = options.delete("precision") { 2 }, options.delete("unit") { "$" }, options.delete("separator") { "." }, options.delete("delimiter") { "," }
- separator = "" unless precision > 0
- begin
- parts = number_with_precision(number, precision).split('.')
- unit + number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s
- rescue
- number
- end
- end
-
- # Formats a +number+ as into a percentage string. The +options+ hash can be used to customize the format of the output.
- # The +number+ can contain a level of precision using the +precision+ key; default is 3
- # The unit separator can be set using the +separator+ key; default is "."
- # Examples:
- # number_to_percentage(100) => 100.000%
- # number_to_percentage(100, {:precision => 0}) => 100%
- # number_to_percentage(302.0574, {:precision => 2}) => 302.06%
- def number_to_percentage(number, options = {})
- options = options.stringify_keys
- precision, separator = options.delete("precision") { 3 }, options.delete("separator") { "." }
- begin
- number = number_with_precision(number, precision)
- parts = number.split('.')
- if parts.at(1).nil?
- parts[0] + "%"
- else
- parts[0] + separator + parts[1].to_s + "%"
- end
- rescue
- number
- end
- end
-
- # Formats a +number+ with a +delimiter+.
- # Example:
- # number_with_delimiter(12345678) => 12,345,678
- def number_with_delimiter(number, delimiter=",")
- number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
- end
-
- # Returns a formatted-for-humans file size.
- #
- # Examples:
- # human_size(123) => 123 Bytes
- # human_size(1234) => 1.2 KB
- # human_size(12345) => 12.1 KB
- # human_size(1234567) => 1.2 MB
- # human_size(1234567890) => 1.1 GB
- def number_to_human_size(size)
- begin
- return "%d Bytes" % size if size < 1.kilobytes
- return "%.1f KB" % (size/1.0.kilobytes) if size < 1.megabytes
- return "%.1f MB" % (size/1.0.megabytes) if size < 1.gigabytes
- return "%.1f GB" % (size/1.0.gigabytes) if size < 1.terabytes
- return "%.1f TB" % (size/1.0.terabytes)
- rescue
- # just return nothing
- end
- end
-
- alias_method :human_size, :number_to_human_size # deprecated alias
-
- # Formats a +number+ with a level of +precision+.
- # Example:
- # number_with_precision(111.2345) => 111.235
- def number_with_precision(number, precision=3)
- sprintf("%01.#{precision}f", number)
- end
- end
- end
-end
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/pagination_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/pagination_helper.rb
deleted file mode 100644
index 51510599..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/pagination_helper.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-module ActionView
- module Helpers
- # Provides methods for linking to ActionController::Pagination objects.
- #
- # You can also build your links manually, like in this example:
- #
- # <%= link_to "Previous page", { :page => paginator.current.previous } if paginator.current.previous %>
- #
- # <%= link_to "Next page", { :page => paginator.current.next } if paginator.current.next =%>
- module PaginationHelper
- unless const_defined?(:DEFAULT_OPTIONS)
- DEFAULT_OPTIONS = {
- :name => :page,
- :window_size => 2,
- :always_show_anchors => true,
- :link_to_current_page => false,
- :params => {}
- }
- end
-
- # Creates a basic HTML link bar for the given +paginator+.
- # +html_options+ are passed to +link_to+.
- #
- # +options+ are:
- # :name:: the routing name for this paginator
- # (defaults to +page+)
- # :window_size:: the number of pages to show around
- # the current page (defaults to +2+)
- # :always_show_anchors:: whether or not the first and last
- # pages should always be shown
- # (defaults to +true+)
- # :link_to_current_page:: whether or not the current page
- # should be linked to (defaults to
- # +false+)
- # :params:: any additional routing parameters
- # for page URLs
- def pagination_links(paginator, options={}, html_options={})
- name = options[:name] || DEFAULT_OPTIONS[:name]
- params = (options[:params] || DEFAULT_OPTIONS[:params]).clone
-
- pagination_links_each(paginator, options) do |n|
- params[name] = n
- link_to(n.to_s, params, html_options)
- end
- end
-
- # Iterate through the pages of a given +paginator+, invoking a
- # block for each page number that needs to be rendered as a link.
- def pagination_links_each(paginator, options)
- options = DEFAULT_OPTIONS.merge(options)
- link_to_current_page = options[:link_to_current_page]
- always_show_anchors = options[:always_show_anchors]
-
- current_page = paginator.current_page
- window_pages = current_page.window(options[:window_size]).pages
- return if window_pages.length <= 1 unless link_to_current_page
-
- first, last = paginator.first, paginator.last
-
- html = ''
- if always_show_anchors and not (wp_first = window_pages[0]).first?
- html << yield(first.number)
- html << ' ... ' if wp_first.number - first.number > 1
- html << ' '
- end
-
- window_pages.each do |page|
- if current_page == page && !link_to_current_page
- html << page.number.to_s
- else
- html << yield(page.number)
- end
- html << ' '
- end
-
- if always_show_anchors and not (wp_last = window_pages[-1]).last?
- html << ' ... ' if last.number - wp_last.number > 1
- html << yield(last.number)
- end
-
- html
- end
-
- end # PaginationHelper
- end # Helpers
-end # ActionView
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb
deleted file mode 100644
index 6c71b8b7..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-require 'cgi'
-require 'erb'
-
-module ActionView
- module Helpers
- # This is poor man's Builder for the rare cases where you need to programmatically make tags but can't use Builder.
- module TagHelper
- include ERB::Util
-
- # Examples:
- # * tag("br") =>
- # * tag("input", { "type" => "text"}) =>
- def tag(name, options = nil, open = false)
- "<#{name}#{tag_options(options.stringify_keys) if options}" + (open ? ">" : " />")
- end
-
- # Examples:
- # * content_tag("p", "Hello world!") =>
\3') # turn single newline into
-
- content_tag("p", text)
- end
-
- # Turns all urls and email addresses into clickable links. The +link+ parameter can limit what should be linked.
- # Options are :all (default), :email_addresses, and :urls.
- #
- # Example:
- # auto_link("Go to http://www.rubyonrails.com and say hello to david@loudthinking.com") =>
- # Go to http://www.rubyonrails.com and
- # say hello to david@loudthinking.com
- #
- # If a block is given, each url and email address is yielded and the
- # result is used as the link text. Example:
- # auto_link(post.body, :all, :target => '_blank') do |text|
- # truncate(text, 15)
- # end
- def auto_link(text, link = :all, href_options = {}, &block)
- case link
- when :all then auto_link_urls(auto_link_email_addresses(text, &block), href_options, &block)
- when :email_addresses then auto_link_email_addresses(text, &block)
- when :urls then auto_link_urls(text, href_options, &block)
- end
- end
-
- # Turns all links into words, like "else" to "else".
- def strip_links(text)
- text.gsub(/">
- # ... use item ...
- #
- # <%- end -%>
- #
- # You can use named cycles to prevent clashes in nested loops. You'll
- # have to reset the inner cycle, manually:
- #
- # <%- for item in @items do -%>
- # "row_class")
- #
- # <%- end -%>
- def cycle(first_value, *values)
- if (values.last.instance_of? Hash)
- params = values.pop
- name = params[:name]
- else
- name = "default"
- end
- values.unshift(first_value)
-
- cycle = get_cycle(name)
- if (cycle.nil? || cycle.values != values)
- cycle = set_cycle(name, Cycle.new(*values))
- end
- return cycle.to_s
- end
-
- # Resets a cycle so that it starts from the first element in the array
- # the next time it is used.
- def reset_cycle(name = "default")
- cycle = get_cycle(name)
- return if cycle.nil?
- cycle.reset
- end
-
- class Cycle #:nodoc:
- attr_reader :values
-
- def initialize(first_value, *values)
- @values = values.unshift(first_value)
- reset
- end
-
- def reset
- @index = 0
- end
-
- def to_s
- value = @values[@index].to_s
- @index = (@index + 1) % @values.size
- return value
- end
- end
-
- private
- # The cycle helpers need to store the cycles in a place that is
- # guaranteed to be reset every time a page is rendered, so it
- # uses an instance variable of ActionView::Base.
- def get_cycle(name)
- @_cycles = Hash.new if @_cycles.nil?
- return @_cycles[name]
- end
-
- def set_cycle(name, cycle_object)
- @_cycles = Hash.new if @_cycles.nil?
- @_cycles[name] = cycle_object
- end
-
- AUTO_LINK_RE = /
- ( # leading text
- <\w+.*?>| # leading HTML tag, or
- [^=!:'"\/]| # leading punctuation, or
- ^ # beginning of line
- )
- (
- (?:http[s]?:\/\/)| # protocol spec, or
- (?:www\.) # www.*
- )
- (
- ([\w]+[=?&\/.-]?)* # url segment
- \w+[\/]? # url tail
- (?:\#\w*)? # trailing anchor
- )
- ([[:punct:]]|\s|<|$) # trailing text
- /x unless const_defined?(:AUTO_LINK_RE)
-
- # Turns all urls into clickable links. If a block is given, each url
- # is yielded and the result is used as the link text. Example:
- # auto_link_urls(post.body, :all, :target => '_blank') do |text|
- # truncate(text, 15)
- # end
- def auto_link_urls(text, href_options = {})
- extra_options = tag_options(href_options.stringify_keys) || ""
- text.gsub(AUTO_LINK_RE) do
- all, a, b, c, d = $&, $1, $2, $3, $5
- if a =~ /#{text}#{d})
- end
- end
- end
-
- # Turns all email addresses into clickable links. If a block is given,
- # each email is yielded and the result is used as the link text.
- # Example:
- # auto_link_email_addresses(post.body) do |text|
- # truncate(text, 15)
- # end
- def auto_link_email_addresses(text)
- text.gsub(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
- text = $1
- text = yield(text) if block_given?
- %{#{text}}
- end
- end
- end
- end
-end
diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/upload_progress_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/upload_progress_helper.rb
deleted file mode 100644
index 00e5f25f..00000000
--- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/upload_progress_helper.rb
+++ /dev/null
@@ -1,433 +0,0 @@
-module ActionView
- module Helpers
- # == THIS IS AN EXPERIMENTAL FEATURE
- #
- # Which means that it doesn't yet work on all systems. We're still working on full
- # compatibility. It's thus not advised to use this unless you've verified it to work
- # fully on all the systems that is a part of your environment. Consider this an extended
- # preview.
- #
- # Provides a set of methods to be used in your views to help with the
- # rendering of Ajax enabled status updating during a multipart upload.
- #
- # The basic mechanism for upload progress is that the form will post to a
- # hidden
- # <%- for value in item.values do -%>
- # "colors") %>'">
- # item
- #
- # <%- end -%>
- # <%- reset_cycle("colors") -%>
- #
- #
\n\n\n
\n\n\n — \n : \n
There were problems with the following fields:
There were problems with the following fields:
),
- %(image_tag("rss", :alt => "rss syndication")) => %(
),
- %(image_tag("gold", :size => "45x70")) => %(
),
- %(image_tag("rss", :alt => "rss syndication")) => %(
),
- %(image_tag("gold", :size => "45x70")) => %(