diff options
author | Thomas Fuchs <thomas@fesch.at> | 2005-11-14 20:49:10 +0000 |
---|---|---|
committer | Thomas Fuchs <thomas@fesch.at> | 2005-11-14 20:49:10 +0000 |
commit | 415d27490f14f7ba360a0edd3d9e1211f7482c89 (patch) | |
tree | 54754d39aae29b8ab1cfd380f98874222bbc584c | |
parent | 037f61c8e9ceda65538a8d847db235f9d7a5e3ad (diff) | |
download | rails-415d27490f14f7ba360a0edd3d9e1211f7482c89.tar.gz rails-415d27490f14f7ba360a0edd3d9e1211f7482c89.tar.bz2 rails-415d27490f14f7ba360a0edd3d9e1211f7482c89.zip |
Update trunk to latests script.aculo.us
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3033 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | actionpack/CHANGELOG | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/javascripts/controls.js | 31 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/javascripts/dragdrop.js | 54 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/javascripts/effects.js | 94 | ||||
-rw-r--r-- | railties/CHANGELOG | 2 | ||||
-rw-r--r-- | railties/html/javascripts/controls.js | 31 | ||||
-rw-r--r-- | railties/html/javascripts/dragdrop.js | 54 | ||||
-rw-r--r-- | railties/html/javascripts/effects.js | 94 |
8 files changed, 144 insertions, 218 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 4e5cea8fb9..163ac77ec2 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -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] diff --git a/actionpack/lib/action_view/helpers/javascripts/controls.js b/actionpack/lib/action_view/helpers/javascripts/controls.js index 6da588543b..9742b69188 100644 --- a/actionpack/lib/action_view/helpers/javascripts/controls.js +++ b/actionpack/lib/action_view/helpers/javascripts/controls.js @@ -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)); + } };
\ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/javascripts/dragdrop.js b/actionpack/lib/action_view/helpers/javascripts/dragdrop.js index 63a68243b6..326700782e 100644 --- a/actionpack/lib/action_view/helpers/javascripts/dragdrop.js +++ b/actionpack/lib/action_view/helpers/javascripts/dragdrop.js @@ -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, event) { // 'onStart', 'onEnd', 'onDrag' + if(this[eventName+'Count'] > 0) + this.observers.each( function(o) { + if(o[eventName]) o[eventName](eventName, draggable, event); + }); }, - notify: function(eventName, draggable) { // 'onStart', 'onEnd' - this.observers.invoke(eventName, draggable); + _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); }, diff --git a/actionpack/lib/action_view/helpers/javascripts/effects.js b/actionpack/lib/action_view/helpers/javascripts/effects.js index 3f92992065..6a14d24b97 100644 --- a/actionpack/lib/action_view/helpers/javascripts/effects.js +++ b/actionpack/lib/action_view/helpers/javascripts/effects.js @@ -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) }); } /*--------------------------------------------------------------------------*/ diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 297058acf4..b3e274505c 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -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] diff --git a/railties/html/javascripts/controls.js b/railties/html/javascripts/controls.js index 6da588543b..9742b69188 100644 --- a/railties/html/javascripts/controls.js +++ b/railties/html/javascripts/controls.js @@ -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)); + } };
\ No newline at end of file diff --git a/railties/html/javascripts/dragdrop.js b/railties/html/javascripts/dragdrop.js index 63a68243b6..326700782e 100644 --- a/railties/html/javascripts/dragdrop.js +++ b/railties/html/javascripts/dragdrop.js @@ -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, event) { // 'onStart', 'onEnd', 'onDrag' + if(this[eventName+'Count'] > 0) + this.observers.each( function(o) { + if(o[eventName]) o[eventName](eventName, draggable, event); + }); }, - notify: function(eventName, draggable) { // 'onStart', 'onEnd' - this.observers.invoke(eventName, draggable); + _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); }, diff --git a/railties/html/javascripts/effects.js b/railties/html/javascripts/effects.js index 3f92992065..6a14d24b97 100644 --- a/railties/html/javascripts/effects.js +++ b/railties/html/javascripts/effects.js @@ -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) }); } /*--------------------------------------------------------------------------*/ |