Update trunk to latests script.aculo.us

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3033 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Thomas Fuchs 2005-11-14 20:49:10 +00:00
parent 037f61c8e9
commit 415d27490f
8 changed files with 144 additions and 218 deletions

@ -1,5 +1,7 @@
*SVN*
* Update to latest script.aculo.us version (as of [3031])
* Updated docs for in_place_editor, fixes a couple bugs and offers extended support for external controls [Justin Palmer]
* Update documentation for render :file. #2858 [Tom Werner]

@ -80,7 +80,10 @@ Autocompleter.Base.prototype = {
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (Element.getStyle(this.update, 'position')=='absolute')) {
if(!this.iefix &&
(navigator.appVersion.indexOf('MSIE')>0) &&
(navigator.userAgent.indexOf('Opera')<0) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
@ -718,4 +721,30 @@ Ajax.InPlaceEditor.prototype = {
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));
}
};

@ -1,7 +1,5 @@
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// Element.Class part Copyright (c) 2005 by Rick Olson
//
// See scriptaculous.js for full license.
/*--------------------------------------------------------------------------*/
@ -31,6 +29,8 @@ var Droppables = {
options._containers.push($(containment));
}
}
if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
options.element = element;
@ -49,20 +49,21 @@ var Droppables = {
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
(Element.Class.has_any(element, drop.accept))) &&
(Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, pX, pY) );
},
deactivate: function(drop) {
if(drop.hoverclass)
Element.Class.remove(drop.element, drop.hoverclass);
Element.removeClassName(drop.element, drop.hoverclass);
this.last_active = null;
},
activate: function(drop) {
if(this.last_active) this.deactivate(this.last_active);
if(drop.hoverclass)
Element.Class.add(drop.element, drop.hoverclass);
Element.addClassName(drop.element, drop.hoverclass);
this.last_active = drop;
},
@ -105,13 +106,25 @@ var Droppables = {
var Draggables = {
observers: [],
addObserver: function(observer) {
this.observers.push(observer);
this.observers.push(observer);
this._cacheObserverCallbacks();
},
removeObserver: function(element) { // element instead of obsever fixes mem leaks
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) { // 'onStart', 'onEnd'
this.observers.invoke(eventName, draggable);
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;
});
}
}
@ -138,7 +151,7 @@ Draggable.prototype = {
this.element = $(element);
if(options.handle && (typeof options.handle == 'string'))
this.handle = Element.Class.childrenWith(this.element, options.handle)[0];
this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
@ -219,7 +232,7 @@ Draggable.prototype = {
}
if(success) Droppables.fire(event, this.element);
Draggables.notify('onEnd', this);
Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
if(revert && typeof revert == 'function') revert = revert(this.element);
@ -290,11 +303,12 @@ Draggable.prototype = {
this.element.parentNode.insertBefore(this._clone, this.element);
}
Draggables.notify('onStart', this);
Draggables.notify('onStart', this, event);
if(this.options.starteffect) this.options.starteffect(this.element);
}
Droppables.show(event, this.element);
Draggables.notify('onDrag', this, event);
this.draw(event);
if(this.options.change) this.options.change(this);
@ -413,7 +427,7 @@ var Sortable = {
(this.findElements(element, options) || []).each( function(e) {
// handles are per-draggable
var handle = options.handle ?
Element.Class.childrenWith(e, options.handle)[0] : e;
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);
@ -434,7 +448,7 @@ var Sortable = {
var elements = [];
$A(element.childNodes).each( function(e) {
if(e.tagName && e.tagName==options.tag.toUpperCase() &&
(!options.only || (Element.Class.has(e, options.only))))
(!options.only || (Element.hasClassName(e, options.only))))
elements.push(e);
if(options.tree) {
var grandchildren = this.findElements(e, options);
@ -491,14 +505,20 @@ var Sortable = {
if(!Sortable._marker) {
Sortable._marker = $('dropmarker') || document.createElement('DIV');
Element.hide(Sortable._marker);
Element.Class.add(Sortable._marker, 'dropmarker');
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.top = offsets[1] + 'px';
if(position=='after') Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
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);
},

@ -86,97 +86,9 @@ Element.setInlineOpacity = function(element, value){
els.opacity = value;
}
/*--------------------------------------------------------------------------*/
Element.Class = {
// Element.toggleClass(element, className) toggles the class being on/off
// Element.toggleClass(element, className1, className2) toggles between both classes,
// defaulting to className1 if neither exist
toggle: function(element, className) {
if(Element.Class.has(element, className)) {
Element.Class.remove(element, className);
if(arguments.length == 3) Element.Class.add(element, arguments[2]);
} else {
Element.Class.add(element, className);
if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
}
},
// gets space-delimited classnames of an element as an array
get: function(element) {
return $(element).className.split(' ');
},
// functions adapted from original functions by Gavin Kistner
remove: function(element) {
element = $(element);
var removeClasses = arguments;
$R(1,arguments.length-1).each( function(index) {
element.className =
element.className.split(' ').reject(
function(klass) { return (klass == removeClasses[index]) } ).join(' ');
});
},
add: function(element) {
element = $(element);
for(var i = 1; i < arguments.length; i++) {
Element.Class.remove(element, arguments[i]);
element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
}
},
// returns true if all given classes exist in said element
has: function(element) {
element = $(element);
if(!element || !element.className) return false;
var regEx;
for(var i = 1; i < arguments.length; i++) {
if((typeof arguments[i] == 'object') &&
(arguments[i].constructor == Array)) {
for(var j = 0; j < arguments[i].length; j++) {
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
if(!regEx.test(element.className)) return false;
}
} else {
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
if(!regEx.test(element.className)) return false;
}
}
return true;
},
// expects arrays of strings and/or strings as optional paramters
// Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
has_any: function(element) {
element = $(element);
if(!element || !element.className) return false;
var regEx;
for(var i = 1; i < arguments.length; i++) {
if((typeof arguments[i] == 'object') &&
(arguments[i].constructor == Array)) {
for(var j = 0; j < arguments[i].length; j++) {
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
if(regEx.test(element.className)) return true;
}
} else {
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
if(regEx.test(element.className)) return true;
}
}
return false;
},
childrenWith: function(element, className) {
var children = $(element).getElementsByTagName('*');
var elements = new Array();
for (var i = 0; i < children.length; i++)
if (Element.Class.has(children[i], className))
elements.push(children[i]);
return elements;
}
Element.childrenWithClassName = function(element, className) {
return $A($(element).getElementsByTagName('*')).select(
function(c) { return Element.hasClassName(c, className) });
}
/*--------------------------------------------------------------------------*/

@ -1,5 +1,7 @@
*SVN*
* Update to latest script.aculo.us version (as of [3031])
* Eliminate Subversion dependencies in scripts/plugin. Correct install options. Introduce --force option to reinstall a plugin. Remove useless --long option for list. Use --quiet to quiet the download output and --revision to update to a specific svn revision. #2842 [Chad Fowler, Rick Olson]
* SQLite: the clone_structure_to_test and purge_test_database Rake tasks should always use the test environment. #2846 [Rick Olson]

@ -80,7 +80,10 @@ Autocompleter.Base.prototype = {
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (Element.getStyle(this.update, 'position')=='absolute')) {
if(!this.iefix &&
(navigator.appVersion.indexOf('MSIE')>0) &&
(navigator.userAgent.indexOf('Opera')<0) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
@ -718,4 +721,30 @@ Ajax.InPlaceEditor.prototype = {
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));
}
};

@ -1,7 +1,5 @@
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// Element.Class part Copyright (c) 2005 by Rick Olson
//
// See scriptaculous.js for full license.
/*--------------------------------------------------------------------------*/
@ -31,6 +29,8 @@ var Droppables = {
options._containers.push($(containment));
}
}
if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
options.element = element;
@ -49,20 +49,21 @@ var Droppables = {
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
(Element.Class.has_any(element, drop.accept))) &&
(Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, pX, pY) );
},
deactivate: function(drop) {
if(drop.hoverclass)
Element.Class.remove(drop.element, drop.hoverclass);
Element.removeClassName(drop.element, drop.hoverclass);
this.last_active = null;
},
activate: function(drop) {
if(this.last_active) this.deactivate(this.last_active);
if(drop.hoverclass)
Element.Class.add(drop.element, drop.hoverclass);
Element.addClassName(drop.element, drop.hoverclass);
this.last_active = drop;
},
@ -105,13 +106,25 @@ var Droppables = {
var Draggables = {
observers: [],
addObserver: function(observer) {
this.observers.push(observer);
this.observers.push(observer);
this._cacheObserverCallbacks();
},
removeObserver: function(element) { // element instead of obsever fixes mem leaks
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) { // 'onStart', 'onEnd'
this.observers.invoke(eventName, draggable);
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;
});
}
}
@ -138,7 +151,7 @@ Draggable.prototype = {
this.element = $(element);
if(options.handle && (typeof options.handle == 'string'))
this.handle = Element.Class.childrenWith(this.element, options.handle)[0];
this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
@ -219,7 +232,7 @@ Draggable.prototype = {
}
if(success) Droppables.fire(event, this.element);
Draggables.notify('onEnd', this);
Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
if(revert && typeof revert == 'function') revert = revert(this.element);
@ -290,11 +303,12 @@ Draggable.prototype = {
this.element.parentNode.insertBefore(this._clone, this.element);
}
Draggables.notify('onStart', this);
Draggables.notify('onStart', this, event);
if(this.options.starteffect) this.options.starteffect(this.element);
}
Droppables.show(event, this.element);
Draggables.notify('onDrag', this, event);
this.draw(event);
if(this.options.change) this.options.change(this);
@ -413,7 +427,7 @@ var Sortable = {
(this.findElements(element, options) || []).each( function(e) {
// handles are per-draggable
var handle = options.handle ?
Element.Class.childrenWith(e, options.handle)[0] : e;
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);
@ -434,7 +448,7 @@ var Sortable = {
var elements = [];
$A(element.childNodes).each( function(e) {
if(e.tagName && e.tagName==options.tag.toUpperCase() &&
(!options.only || (Element.Class.has(e, options.only))))
(!options.only || (Element.hasClassName(e, options.only))))
elements.push(e);
if(options.tree) {
var grandchildren = this.findElements(e, options);
@ -491,14 +505,20 @@ var Sortable = {
if(!Sortable._marker) {
Sortable._marker = $('dropmarker') || document.createElement('DIV');
Element.hide(Sortable._marker);
Element.Class.add(Sortable._marker, 'dropmarker');
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.top = offsets[1] + 'px';
if(position=='after') Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
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);
},

@ -86,97 +86,9 @@ Element.setInlineOpacity = function(element, value){
els.opacity = value;
}
/*--------------------------------------------------------------------------*/
Element.Class = {
// Element.toggleClass(element, className) toggles the class being on/off
// Element.toggleClass(element, className1, className2) toggles between both classes,
// defaulting to className1 if neither exist
toggle: function(element, className) {
if(Element.Class.has(element, className)) {
Element.Class.remove(element, className);
if(arguments.length == 3) Element.Class.add(element, arguments[2]);
} else {
Element.Class.add(element, className);
if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
}
},
// gets space-delimited classnames of an element as an array
get: function(element) {
return $(element).className.split(' ');
},
// functions adapted from original functions by Gavin Kistner
remove: function(element) {
element = $(element);
var removeClasses = arguments;
$R(1,arguments.length-1).each( function(index) {
element.className =
element.className.split(' ').reject(
function(klass) { return (klass == removeClasses[index]) } ).join(' ');
});
},
add: function(element) {
element = $(element);
for(var i = 1; i < arguments.length; i++) {
Element.Class.remove(element, arguments[i]);
element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
}
},
// returns true if all given classes exist in said element
has: function(element) {
element = $(element);
if(!element || !element.className) return false;
var regEx;
for(var i = 1; i < arguments.length; i++) {
if((typeof arguments[i] == 'object') &&
(arguments[i].constructor == Array)) {
for(var j = 0; j < arguments[i].length; j++) {
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
if(!regEx.test(element.className)) return false;
}
} else {
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
if(!regEx.test(element.className)) return false;
}
}
return true;
},
// expects arrays of strings and/or strings as optional paramters
// Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
has_any: function(element) {
element = $(element);
if(!element || !element.className) return false;
var regEx;
for(var i = 1; i < arguments.length; i++) {
if((typeof arguments[i] == 'object') &&
(arguments[i].constructor == Array)) {
for(var j = 0; j < arguments[i].length; j++) {
regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
if(regEx.test(element.className)) return true;
}
} else {
regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
if(regEx.test(element.className)) return true;
}
}
return false;
},
childrenWith: function(element, className) {
var children = $(element).getElementsByTagName('*');
var elements = new Array();
for (var i = 0; i < children.length; i++)
if (Element.Class.has(children[i], className))
elements.push(children[i]);
return elements;
}
Element.childrenWithClassName = function(element, className) {
return $A($(element).getElementsByTagName('*')).select(
function(c) { return Element.hasClassName(c, className) });
}
/*--------------------------------------------------------------------------*/