Changeset 3300
- Timestamp:
- 12/13/05 18:41:10 (3 years ago)
- Files:
-
- branches/stable/actionpack/CHANGELOG (modified) (1 diff)
- branches/stable/actionpack/lib/action_view/helpers/javascripts/dragdrop.js (modified) (18 diffs)
- branches/stable/actionpack/lib/action_view/helpers/javascripts/effects.js (modified) (37 diffs)
- branches/stable/railties/CHANGELOG (modified) (1 diff)
- branches/stable/railties/html/javascripts/dragdrop.js (modified) (18 diffs)
- branches/stable/railties/html/javascripts/effects.js (modified) (37 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/stable/actionpack/CHANGELOG
r3297 r3300 1 1 *1.1.2* (December 13th, 2005) 2 3 * Update to script.aculo.us 1.5.0 final (equals 1.5.0_rc6) [Thomas Fuchs] 2 4 3 5 * Update to Prototype 1.4.0 final [Sam Stephenson] branches/stable/actionpack/lib/action_view/helpers/javascripts/dragdrop.js
r3034 r3300 9 9 10 10 remove: function(element) { 11 this.drops = this.drops.reject(function(d) { return d.element== element});11 this.drops = this.drops.reject(function(d) { return d.element==$(element) }); 12 12 }, 13 13 … … 44 44 }, 45 45 46 isAffected: function(p X, pY, element, drop) {46 isAffected: function(point, element, drop) { 47 47 return ( 48 48 (drop.element!=element) && … … 52 52 (Element.classNames(element).detect( 53 53 function(v) { return drop.accept.include(v) } ) )) && 54 Position.within(drop.element, p X, pY) );54 Position.within(drop.element, point[0], point[1]) ); 55 55 }, 56 56 … … 62 62 63 63 activate: function(drop) { 64 if(this.last_active) this.deactivate(this.last_active);65 64 if(drop.hoverclass) 66 65 Element.addClassName(drop.element, drop.hoverclass); … … 68 67 }, 69 68 70 show: function( event, element) {69 show: function(point, element) { 71 70 if(!this.drops.length) return; 72 var pX = Event.pointerX(event); 73 var pY = Event.pointerY(event); 74 Position.prepare(); 75 76 var i = this.drops.length-1; do { 77 var drop = this.drops[i]; 78 if(this.isAffected(pX, pY, element, drop)) { 71 72 if(this.last_active) this.deactivate(this.last_active); 73 this.drops.each( function(drop) { 74 if(Droppables.isAffected(point, element, drop)) { 79 75 if(drop.onHover) 80 76 drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); 81 77 if(drop.greedy) { 82 this.activate(drop);83 return;78 Droppables.activate(drop); 79 throw $break; 84 80 } 85 81 } 86 } while (i--); 87 88 if(this.last_active) this.deactivate(this.last_active); 82 }); 89 83 }, 90 84 … … 93 87 Position.prepare(); 94 88 95 if (this.isAffected( Event.pointerX(event), Event.pointerY(event), element, this.last_active))89 if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) 96 90 if (this.last_active.onDrop) 97 91 this.last_active.onDrop(element, this.last_active.element, event); … … 105 99 106 100 var Draggables = { 101 drags: [], 107 102 observers: [], 103 104 register: function(draggable) { 105 if(this.drags.length == 0) { 106 this.eventMouseUp = this.endDrag.bindAsEventListener(this); 107 this.eventMouseMove = this.updateDrag.bindAsEventListener(this); 108 this.eventKeypress = this.keyPress.bindAsEventListener(this); 109 110 Event.observe(document, "mouseup", this.eventMouseUp); 111 Event.observe(document, "mousemove", this.eventMouseMove); 112 Event.observe(document, "keypress", this.eventKeypress); 113 } 114 this.drags.push(draggable); 115 }, 116 117 unregister: function(draggable) { 118 this.drags = this.drags.reject(function(d) { return d==draggable }); 119 if(this.drags.length == 0) { 120 Event.stopObserving(document, "mouseup", this.eventMouseUp); 121 Event.stopObserving(document, "mousemove", this.eventMouseMove); 122 Event.stopObserving(document, "keypress", this.eventKeypress); 123 } 124 }, 125 126 activate: function(draggable) { 127 window.focus(); // allows keypress events if window isn't currently focused, fails for Safari 128 this.activeDraggable = draggable; 129 }, 130 131 deactivate: function(draggbale) { 132 this.activeDraggable = null; 133 }, 134 135 updateDrag: function(event) { 136 if(!this.activeDraggable) return; 137 var pointer = [Event.pointerX(event), Event.pointerY(event)]; 138 // Mozilla-based browsers fire successive mousemove events with 139 // the same coordinates, prevent needless redrawing (moz bug?) 140 if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; 141 this._lastPointer = pointer; 142 this.activeDraggable.updateDrag(event, pointer); 143 }, 144 145 endDrag: function(event) { 146 if(!this.activeDraggable) return; 147 this._lastPointer = null; 148 this.activeDraggable.endDrag(event); 149 }, 150 151 keyPress: function(event) { 152 if(this.activeDraggable) 153 this.activeDraggable.keyPress(event); 154 }, 155 108 156 addObserver: function(observer) { 109 157 this.observers.push(observer); 110 158 this._cacheObserverCallbacks(); 111 159 }, 160 112 161 removeObserver: function(element) { // element instead of observer fixes mem leaks 113 162 this.observers = this.observers.reject( function(o) { return o.element==element }); 114 163 this._cacheObserverCallbacks(); 115 164 }, 165 116 166 notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' 117 167 if(this[eventName+'Count'] > 0) … … 120 170 }); 121 171 }, 172 122 173 _cacheObserverCallbacks: function() { 123 174 ['onStart','onEnd','onDrag'].each( function(eventName) { … … 141 192 reverteffect: function(element, top_offset, left_offset) { 142 193 var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; 143 new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});194 element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur}); 144 195 }, 145 196 endeffect: function(element) { 146 new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});197 new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); 147 198 }, 148 199 zindex: 1000, 149 revert: false 200 revert: false, 201 snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } 150 202 }, arguments[1] || {}); 151 203 152 this.element = $(element); 204 this.element = $(element); 205 153 206 if(options.handle && (typeof options.handle == 'string')) 154 this.handle = Element.childrenWithClassName(this.element, options.handle)[0]; 155 207 this.handle = Element.childrenWithClassName(this.element, options.handle)[0]; 156 208 if(!this.handle) this.handle = $(options.handle); 157 209 if(!this.handle) this.handle = this.element; … … 159 211 Element.makePositioned(this.element); // fix IE 160 212 161 this.offsetX = 0; 162 this.offsetY = 0; 163 this.originalLeft = this.currentLeft(); 164 this.originalTop = this.currentTop(); 165 this.originalX = this.element.offsetLeft; 166 this.originalY = this.element.offsetTop; 167 168 this.options = options; 169 170 this.active = false; 171 this.dragging = false; 172 173 this.eventMouseDown = this.startDrag.bindAsEventListener(this); 174 this.eventMouseUp = this.endDrag.bindAsEventListener(this); 175 this.eventMouseMove = this.update.bindAsEventListener(this); 176 this.eventKeypress = this.keyPress.bindAsEventListener(this); 177 178 this.registerEvents(); 179 }, 213 this.delta = this.currentDelta(); 214 this.options = options; 215 this.dragging = false; 216 217 this.eventMouseDown = this.initDrag.bindAsEventListener(this); 218 Event.observe(this.handle, "mousedown", this.eventMouseDown); 219 220 Draggables.register(this); 221 }, 222 180 223 destroy: function() { 181 224 Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); 182 this.unregisterEvents(); 183 }, 184 registerEvents: function() { 185 Event.observe(document, "mouseup", this.eventMouseUp); 186 Event.observe(document, "mousemove", this.eventMouseMove); 187 Event.observe(document, "keypress", this.eventKeypress); 188 Event.observe(this.handle, "mousedown", this.eventMouseDown); 189 }, 190 unregisterEvents: function() { 191 //if(!this.active) return; 192 //Event.stopObserving(document, "mouseup", this.eventMouseUp); 193 //Event.stopObserving(document, "mousemove", this.eventMouseMove); 194 //Event.stopObserving(document, "keypress", this.eventKeypress); 195 }, 196 currentLeft: function() { 197 return parseInt(this.element.style.left || '0'); 198 }, 199 currentTop: function() { 200 return parseInt(this.element.style.top || '0') 201 }, 202 startDrag: function(event) { 203 if(Event.isLeftClick(event)) { 204 225 Draggables.unregister(this); 226 }, 227 228 currentDelta: function() { 229 return([ 230 parseInt(this.element.style.left || '0'), 231 parseInt(this.element.style.top || '0')]); 232 }, 233 234 initDrag: function(event) { 235 if(Event.isLeftClick(event)) { 205 236 // abort on form elements, fixes a Firefox issue 206 237 var src = Event.element(event); … … 210 241 src.tagName=='BUTTON' || 211 242 src.tagName=='TEXTAREA')) return; 243 244 if(this.element._revert) { 245 this.element._revert.cancel(); 246 this.element._revert = null; 247 } 212 248 213 // this.registerEvents();214 this.active = true;215 249 var pointer = [Event.pointerX(event), Event.pointerY(event)]; 216 var offsets = Position.cumulativeOffset(this.element); 217 this.offsetX = (pointer[0] - offsets[0]); 218 this.offsetY = (pointer[1] - offsets[1]); 250 var pos = Position.cumulativeOffset(this.element); 251 this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); 252 253 Draggables.activate(this); 219 254 Event.stop(event); 220 255 } 221 256 }, 257 258 startDrag: function(event) { 259 this.dragging = true; 260 261 if(this.options.zindex) { 262 this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); 263 this.element.style.zIndex = this.options.zindex; 264 } 265 266 if(this.options.ghosting) { 267 this._clone = this.element.cloneNode(true); 268 Position.absolutize(this.element); 269 this.element.parentNode.insertBefore(this._clone, this.element); 270 } 271 272 Draggables.notify('onStart', this, event); 273 if(this.options.starteffect) this.options.starteffect(this.element); 274 }, 275 276 updateDrag: function(event, pointer) { 277 if(!this.dragging) this.startDrag(event); 278 Position.prepare(); 279 Droppables.show(pointer, this.element); 280 Draggables.notify('onDrag', this, event); 281 this.draw(pointer); 282 if(this.options.change) this.options.change(this); 283 284 // fix AppleWebKit rendering 285 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); 286 Event.stop(event); 287 }, 288 222 289 finishDrag: function(event, success) { 223 // this.unregisterEvents();224 225 this.active = false;226 290 this.dragging = false; 227 291 … … 237 301 var revert = this.options.revert; 238 302 if(revert && typeof revert == 'function') revert = revert(this.element); 239 303 304 var d = this.currentDelta(); 240 305 if(revert && this.options.reverteffect) { 241 306 this.options.reverteffect(this.element, 242 this.currentTop()-this.originalTop, 243 this.currentLeft()-this.originalLeft); 307 d[1]-this.delta[1], d[0]-this.delta[0]); 244 308 } else { 245 this.originalLeft = this.currentLeft(); 246 this.originalTop = this.currentTop(); 309 this.delta = d; 247 310 } 248 311 … … 253 316 this.options.endeffect(this.element); 254 317 255 318 Draggables.deactivate(this); 256 319 Droppables.reset(); 257 320 }, 321 258 322 keyPress: function(event) { 259 if(this.active) { 260 if(event.keyCode==Event.KEY_ESC) { 261 this.finishDrag(event, false); 262 Event.stop(event); 263 } 264 } 265 }, 323 if(!event.keyCode==Event.KEY_ESC) return; 324 this.finishDrag(event, false); 325 Event.stop(event); 326 }, 327 266 328 endDrag: function(event) { 267 if(this.active && this.dragging) { 268 this.finishDrag(event, true); 269 Event.stop(event); 270 } 271 this.active = false; 272 this.dragging = false; 273 }, 274 draw: function(event) { 275 var pointer = [Event.pointerX(event), Event.pointerY(event)]; 276 var offsets = Position.cumulativeOffset(this.element); 277 offsets[0] -= this.currentLeft(); 278 offsets[1] -= this.currentTop(); 329 if(!this.dragging) return; 330 this.finishDrag(event, true); 331 Event.stop(event); 332 }, 333 334 draw: function(point) { 335 var pos = Position.cumulativeOffset(this.element); 336 var d = this.currentDelta(); 337 pos[0] -= d[0]; pos[1] -= d[1]; 338 339 var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this)); 340 341 if(this.options.snap) { 342 if(typeof this.options.snap == 'function') { 343 p = this.options.snap(p[0],p[1]); 344 } else { 345 if(this.options.snap instanceof Array) { 346 p = p.map( function(v, i) { 347 return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) 348 } else { 349 p = p.map( function(v) { 350 return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) 351 } 352 }} 353 279 354 var style = this.element.style; 280 355 if((!this.options.constraint) || (this.options.constraint=='horizontal')) 281 style.left = (pointer[0] - offsets[0] - this.offsetX)+ "px";356 style.left = p[0] + "px"; 282 357 if((!this.options.constraint) || (this.options.constraint=='vertical')) 283 style.top = (pointer[1] - offsets[1] - this.offsetY)+ "px";358 style.top = p[1] + "px"; 284 359 if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering 285 },286 update: function(event) {287 if(this.active) {288 if(!this.dragging) {289 var style = this.element.style;290 this.dragging = true;291 292 if(Element.getStyle(this.element,'position')=='')293 style.position = "relative";294 295 if(this.options.zindex) {296 this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);297 style.zIndex = this.options.zindex;298 }299 300 if(this.options.ghosting) {301 this._clone = this.element.cloneNode(true);302 Position.absolutize(this.element);303 this.element.parentNode.insertBefore(this._clone, this.element);304 }305 306 Draggables.notify('onStart', this, event);307 if(this.options.starteffect) this.options.starteffect(this.element);308 }309 310 Droppables.show(event, this.element);311 Draggables.notify('onDrag', this, event);312 this.draw(event);313 if(this.options.change) this.options.change(this);314 315 // fix AppleWebKit rendering316 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);317 318 Event.stop(event);319 }320 360 } 321 361 } … … 330 370 this.lastValue = Sortable.serialize(this.element); 331 371 }, 372 332 373 onStart: function() { 333 374 this.lastValue = Sortable.serialize(this.element); 334 375 }, 376 335 377 onEnd: function() { 336 378 Sortable.unmark(); … … 342 384 var Sortable = { 343 385 sortables: new Array(), 386 344 387 options: function(element){ 345 388 element = $(element); 346 389 return this.sortables.detect(function(s) { return s.element == element }); 347 390 }, 391 348 392 destroy: function(element){ 349 393 element = $(element); … … 355 399 this.sortables = this.sortables.reject(function(s) { return s.element == element }); 356 400 }, 401 357 402 create: function(element) { 358 403 element = $(element); … … 448 493 var elements = []; 449 494 $A(element.childNodes).each( function(e) { 450 if(e.tagName && e.tagName ==options.tag.toUpperCase() &&495 if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() && 451 496 (!options.only || (Element.hasClassName(e, options.only)))) 452 497 elements.push(e); … … 532 577 format: sortableOptions.format || /^[^_]*_(.*)$/ 533 578 }, arguments[1] || {}); 534 return $(this.findElements(element, options) || []). collect( function(item) {579 return $(this.findElements(element, options) || []).map( function(item) { 535 580 return (encodeURIComponent(options.name) + "[]=" + 536 581 encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : '')); branches/stable/actionpack/lib/action_view/helpers/javascripts/effects.js
r3034 r3300 12 12 // returns self (or first argument) if not convertable 13 13 String.prototype.parseColor = function() { 14 color = "#";15 if(this.slice(0,4) == "rgb(") {14 var color = '#'; 15 if(this.slice(0,4) == 'rgb(') { 16 16 var cols = this.slice(4,this.length-1).split(','); 17 17 var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); … … 27 27 Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { 28 28 var children = $(element).childNodes; 29 var text = "";30 var classtest = new RegExp( "^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i");29 var text = ''; 30 var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i'); 31 31 32 32 for (var i = 0; i < children.length; i++) { … … 42 42 } 43 43 44 Element.setStyle = function(element, style) { 45 element = $(element); 46 for(k in style) element.style[k.camelize()] = style[k]; 47 } 48 44 49 Element.setContentZoom = function(element, percent) { 45 element = $(element); 46 element.style.fontSize = (percent/100) + "em"; 50 Element.setStyle(element, {fontSize: (percent/100) + 'em'}); 47 51 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); 48 52 } 49 53 50 54 Element.getOpacity = function(element){ 51 var opacity; 52 if (opacity = Element.getStyle(element, "opacity"))55 var opacity; 56 if (opacity = Element.getStyle(element, 'opacity')) 53 57 return parseFloat(opacity); 54 if (opacity = (Element.getStyle(element, "filter") || '').match(/alpha\(opacity=(.*)\)/))58 if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) 55 59 if(opacity[1]) return parseFloat(opacity[1]) / 100; 56 60 return 1.0; … … 59 63 Element.setOpacity = function(element, value){ 60 64 element= $(element); 61 var els = element.style; 62 if (value == 1){ 63 els.opacity = '0.999999'; 65 if (value == 1){ 66 Element.setStyle(element, { opacity: 67 (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 68 0.999999 : null }); 64 69 if(/MSIE/.test(navigator.userAgent)) 65 els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'');70 Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); 66 71 } else { 67 72 if(value < 0.00001) value = 0; 68 els.opacity = value;73 Element.setStyle(element, {opacity: value}); 69 74 if(/MSIE/.test(navigator.userAgent)) 70 els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + 71 "alpha(opacity="+value*100+")"; 75 Element.setStyle(element, 76 { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + 77 'alpha(opacity='+value*100+')' }); 72 78 } 73 79 } 74 80 75 81 Element.getInlineOpacity = function(element){ 76 element= $(element); 77 var op; 78 op = element.style.opacity; 79 if (typeof op != "undefined" && op != "") return op; 80 return ""; 82 return $(element).style.opacity || ''; 81 83 } 82 83 Element.setInlineOpacity = function(element, value){ 84 element= $(element); 85 var els = element.style; 86 els.opacity = value; 87 } 88 84 89 85 Element.childrenWithClassName = function(element, className) { 90 86 return $A($(element).getElementsByTagName('*')).select( 91 87 function(c) { return Element.hasClassName(c, className) }); 92 } 93 88 } 89 90 Array.prototype.call = function() { 91 var args = arguments; 92 this.each(function(f){ f.apply(this, args) }); 93 } 94 94 95 /*--------------------------------------------------------------------------*/ 95 96 96 97 var Effect = { 97 98 tagifyText: function(element) { 98 var tagifyStyle = "position:relative";99 if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ";zoom:1";99 var tagifyStyle = 'position:relative'; 100 if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; 100 101 element = $(element); 101 102 $A(element.childNodes).each( function(child) { … … 104 105 element.insertBefore( 105 106 Builder.node('span',{style: tagifyStyle}, 106 character == " "? String.fromCharCode(160) : character),107 character == ' ' ? String.fromCharCode(160) : character), 107 108 child); 108 109 }); … … 124 125 delay: 0.0 125 126 }, arguments[2] || {}); 126 var speed = options.speed; 127 var delay = options.delay; 127 var masterDelay = options.delay; 128 128 129 129 $A(elements).each( function(element, index) { 130 new effect(element, Object.extend(options, { delay: delay + index * speed}));130 new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); 131 131 }); 132 132 } … … 259 259 this.event('afterSetup'); 260 260 } 261 if(this.options.transition) pos = this.options.transition(pos); 262 pos *= (this.options.to-this.options.from); 263 pos += this.options.from; 264 this.position = pos; 265 this.event('beforeUpdate'); 266 if(this.update) this.update(pos); 267 this.event('afterUpdate'); 261 if(this.state == 'running') { 262 if(this.options.transition) pos = this.options.transition(pos); 263 pos *= (this.options.to-this.options.from); 264 pos += this.options.from; 265 this.position = pos; 266 this.event('beforeUpdate'); 267 if(this.update) this.update(pos); 268 this.event('afterUpdate'); 269 } 268 270 }, 269 271 cancel: function() { … … 274 276 if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); 275 277 if(this.options[eventName]) this.options[eventName](this); 278 }, 279 inspect: function() { 280 return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>'; 276 281 } 277 282 } … … 303 308 // make this work on IE on elements without 'layout' 304 309 if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout)) 305 this.element.style.zoom = 1;310 Element.setStyle(this.element, {zoom: 1}); 306 311 var options = Object.extend({ 307 312 from: Element.getOpacity(this.element) || 0.0, … … 327 332 // relative element that does not have top/left explicitly set. 328 333 // ==> Always set top and left for position relative elements in your stylesheets 329 // (to 0 if you do not need them) 330 334 // (to 0 if you do not need them) 331 335 Element.makePositioned(this.element); 332 336 this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0'); … … 334 338 }, 335 339 update: function(position) { 336 var topd = this.toTop * position + this.originalTop; 337 var leftd = this.toLeft * position + this.originalLeft; 338 this.setPosition(topd, leftd); 339 }, 340 setPosition: function(topd, leftd) { 341 this.element.style.top = topd + "px"; 342 this.element.style.left = leftd + "px"; 340 Element.setStyle(this.element, { 341 top: this.toTop * position + this.originalTop + 'px', 342 left: this.toLeft * position + this.originalLeft + 'px' 343 }); 343 344 } 344 345 }); … … 360 361 }, 361 362 setup: function() { 362 var effect = this;363 364 363 this.restoreAfterFinish = this.options.restoreAfterFinish || false; 365 364 this.elementPositioning = Element.getStyle(this.element,'position'); 366 365 367 effect.originalStyle = {};366 this.originalStyle = {}; 368 367 ['top','left','width','height','fontSize'].each( function(k) { 369 effect.originalStyle[k] = effect.element.style[k];370 } );368 this.originalStyle[k] = this.element.style[k]; 369 }.bind(this)); 371 370 372 371 this.originalTop = this.element.offsetTop; 373 372 this.originalLeft = this.element.offsetLeft; 374 373 375 var fontSize = Element.getStyle(this.element,'font-size') || "100%";374 var fontSize = Element.getStyle(this.element,'font-size') || '100%'; 376 375 ['em','px','%'].each( function(fontSizeType) { 377 376 if(fontSize.indexOf(fontSizeType)>0) { 378 effect.fontSize = parseFloat(fontSize);379 effect.fontSizeType = fontSizeType;377 this.fontSize = parseFloat(fontSize); 378 this.fontSizeType = fontSizeType; 380 379 } 381 } );380 }.bind(this)); 382 381 383 382 this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; … … 385 384 this.dims = null; 386 385 if(this.options.scaleMode=='box') 387 this.dims = [this.element. clientHeight, this.element.clientWidth];388 if( this.options.scaleMode=='content')386 this.dims = [this.element.offsetHeight, this.element.offsetWidth]; 387 if(/^content/.test(this.options.scaleMode)) 389 388 this.dims = [this.element.scrollHeight, this.element.scrollWidth]; 390 389 if(!this.dims) … … 395 394 var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); 396 395 if(this.options.scaleContent && this.fontSize) 397 this.element.style.fontSize = this.fontSize*currentScale + this.fontSizeType;396 Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType }); 398 397 this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); 399 398 }, 400 399 finish: function(position) { 401 if (this.restoreAfterFinish) { 402 var effect = this; 403 ['top','left','width','height','fontSize'].each( function(k) { 404 effect.element.style[k] = effect.originalStyle[k]; 405 }); 406 } 400 if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle); 407 401 }, 408 402 setDimensions: function(height, width) { 409 var els = this.element.style;410 if(this.options.scaleX) els.width = width + 'px';411 if(this.options.scaleY) els.height = height + 'px';403 var d = {}; 404 if(this.options.scaleX) d.width = width + 'px'; 405 if(this.options.scaleY) d.height = height + 'px'; 412 406 if(this.options.scaleFromCenter) { 413 407 var topd = (height - this.dims[0])/2; 414 408 var leftd = (width - this.dims[1])/2; 415 409 if(this.elementPositioning == 'absolute') { 416 if(this.options.scaleY) els.top = this.originalTop-topd + "px";417 if(this.options.scaleX) els.left = this.originalLeft-leftd + "px";410 if(this.options.scaleY) d.top = this.originalTop-topd + 'px'; 411 if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; 418 412 } else { 419 if(this.options.scaleY) els.top = -topd + "px";420 if(this.options.scaleX) els.left = -leftd + "px";413 if(this.options.scaleY) d.top = -topd + 'px'; 414 if(this.options.scaleX) d.left = -leftd + 'px'; 421 415 } 422 416 } 417 Element.setStyle(this.element, d); 423 418 } 424 419 }); … … 428 423 initialize: function(element) { 429 424 this.element = $(element); 430 var options = Object.extend({ 431 startcolor: "#ffff99" 432 }, arguments[1] || {}); 425 var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {}); 433 426 this.start(options); 434 427 }, 435 428 setup: function() { 436 429 // Prevent executing on elements not in the layout flow 437 if( this.element.style.display=='none') { this.cancel(); return; }430 if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; } 438 431 // Disable background image during the effect 439 this.oldBgImage = this.element.style.backgroundImage; 440 this.element.style.backgroundImage = "none"; 432 this.oldStyle = { 433 backgroundImage: Element.getStyle(this.element, 'background-image') }; 434 Element.setStyle(this.element, {backgroundImage: 'none'}); 441 435 if(!this.options.endcolor) 442 436 this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff'); 443 if (typeof this.options.restorecolor == "undefined")444 this.options.restorecolor = this.element.style.backgroundColor;437 if(!this.options.restorecolor) 438 this.options.restorecolor = Element.getStyle(this.element, 'background-color'); 445 439 // init color calculations 446 this.colors_base = [ 447 parseInt(this.options.startcolor.slice(1,3),16), 448 parseInt(this.options.startcolor.slice(3,5),16), 449 parseInt(this.options.startcolor.slice(5),16) ]; 450 this.colors_delta = [ 451 parseInt(this.options.endcolor.slice(1,3),16)-this.colors_base[0], 452 parseInt(this.options.endcolor.slice(3,5),16)-this.colors_base[1], 453 parseInt(this.options.endcolor.slice(5),16)-this.colors_base[2]]; 440 this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); 441 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)); 454 442 }, 455 443 update: function(position) { 456 var effect = this; var colors = $R(0,2).map( function(i){ 457 return Math.round(effect.colors_base[i]+(effect.colors_delta[i]*position)) 458 }); 459 this.element.style.backgroundColor = "#" + 460 colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart(); 444 Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){ 445 return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); 461 446 }, 462 447 finish: function() { 463 this.element.style.backgroundColor = this.options.restorecolor; 464 this.element.style.backgroundImage = this.oldBgImage; 448 Element.setStyle(this.element, Object.extend(this.oldStyle, { 449 backgroundColor: this.options.restorecolor 450 })); 465 451 } 466 452 }); … … 475 461 Position.prepare(); 476 462 var offsets = Position.cumulativeOffset(this.element); 463 if(this.options.offset) offsets[1] += this.options.offset; 477 464 var max = window.innerHeight ? 478 465 window.height - window.innerHeight : … … 497 484 from: Element.getOpacity(element) || 1.0, 498 485 to: 0.0, 499 afterFinishInternal: function(effect) 500 { if (effect.options.to == 0) { 501 Element.hide(effect.element); 502 Element.setInlineOpacity(effect.element, oldOpacity); 503 } 504 } 486 afterFinishInternal: function(effect) { with(Element) { 487 if(effect.options.to!=0) return; 488 hide(effect.element); 489 setStyle(effect.element, {opacity: oldOpacity}); }} 505 490 }, arguments[1] || {}); 506 491 return new Effect.Opacity(element,options); … … 509 494 Effect.Appear = function(element) { 510 495 var options = Object.extend({ 511 from: (Element.getStyle(element, "display") == "none"? 0.0 : Element.getOpacity(element) || 0.0),496 from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0), 512 497 to: 1.0, 513 beforeSetup: function(effect) 514 { Element.setOpacity(effect.element, effect.options.from);515 Element.show(effect.element);}498 beforeSetup: function(effect) { with(Element) { 499 setOpacity(effect.element, effect.options.from); 500 show(effect.element); }} 516 501 }, arguments[1] || {}); 517 502 return new Effect.Opacity(element,options); … … 520 505 Effect.Puff = function(element) { 521 506 element = $(element); 522 var oldOpacity = Element.getInlineOpacity(element); 523 var oldPosition = element.style.position; 507 var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') }; 524 508 return new Effect.Parallel( 525 509 [ new Effect.Scale(element, 200, … … 527 511 new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 528 512 Object.extend({ duration: 1.0, 529 beforeSetupInternal: function(effect) 530 { effect.effects[0].element.style.position = 'absolute'; }, 531 afterFinishInternal: function(effect) 532 { Element.hide(effect.effects[0].element); 533 effect.effects[0].element.style.position = oldPosition; 534 Element.setInlineOpacity(effect.effects[0].element, oldOpacity); } 513 beforeSetupInternal: function(effect) { with(Element) { 514 setStyle(effect.effects[0].element, {position: 'absolute'}); }}, 515 afterFinishInternal: function(effect) { with(Element) { 516 hide(effect.effects[0].element); 517 setStyle(effect.effects[0].element, oldStyle); }} 535 518 }, arguments[1] || {}) 536 519 ); … … 544 527 scaleX: false, 545 528 restoreAfterFinish: true, 546 afterFinishInternal: function(effect) 547 { 548 Element.hide(effect.element); 549 Element.undoClipping(effect.element); 550 } 529 afterFinishInternal: function(effect) { with(Element) { 530 [hide, undoClipping].call(effect.element); }} 551 531 }, arguments[1] || {}) 552 532 ); … … 555 535 Effect.BlindDown = function(element) { 556 536 element = $(element); 557 var oldHeight = element.style.height;537 var oldHeight = Element.getStyle(element, 'height'); 558 538 var elementDimensions = Element.getDimensions(element); 559 539 return new Effect.Scale(element, 100, … … 563 543 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, 564 544 restoreAfterFinish: true, 565 afterSetup: function(effect) { 566 Element.makeClipping(effect.element);567 effect.element.style.height = "0px";568 Element.show(effect.element);569 } ,570 afterFinishInternal: function(effect) { 571 Element.undoClipping(effect.element);572 effect.element.style.height = oldHeight;573 } 545 afterSetup: function(effect) { with(Element) { 546 makeClipping(effect.element); 547 setStyle(effect.element, {height: '0px'}); 548 show(effect.element); 549 }}, 550 afterFinishInternal: function(effect) { with(Element) { 551 undoClipping(effect.element); 552 setStyle(effect.element, {height: oldHeight}); 553 }} 574 554 }, arguments[1] || {}) 575 555 ); … … 587 567 duration: 0.3, scaleFromCenter: true, 588 568 scaleX: false, scaleContent: false, restoreAfterFinish: true, 589 beforeSetup: function(effect) { 590 Element.makePositioned(effect.element); 591 Element.makeClipping(effect.element); 592 }, 593 afterFinishInternal: function(effect) { 594 Element.hide(effect.element); 595 Element.undoClipping(effect.element); 596 Element.undoPositioned(effect.element); 597 Element.setInlineOpacity(effect.element, oldOpacity); 598 } 569 beforeSetup: function(effect) { with(Element) { 570 [makePositioned,makeClipping].call(effect.element); 571 }}, 572 afterFinishInternal: function(effect) { with(Element) { 573 [hide,undoClipping,undoPositioned].call(effect.element); 574 setStyle(effect.element, {opacity: oldOpacity}); 575 }} 599 576 }) 600 577 } … … 604 581 Effect.DropOut = function(element) { 605 582 element = $(element); 606 var oldTop = element.style.top; 607 var oldLeft = element.style.left; 608 var oldOpacity = Element.getInlineOpacity(element); 583 var oldStyle = { 584 top: Element.getStyle(element, 'top'), 585 left: Element.getStyle(element, 'left'), 586 opacity: Element.getInlineOpacity(element) }; 609 587 return new Effect.Parallel( 610 588 [ new Effect.MoveBy(element, 100, 0, { sync: true }), … … 612 590 Object.extend( 613 591 { duration: 0.5, 614 beforeSetup: function(effect) { 615 Element.makePositioned(effect.effects[0].element); }, 616 afterFinishInternal: function(effect) { 617 Element.hide(effect.effects[0].element); 618 Element.undoPositioned(effect.effects[0].element); 619 effect.effects[0].element.style.left = oldLeft; 620 effect.effects[0].element.style.top = oldTop; 621 Element.setInlineOpacity(effect.effects[0].element, oldOpacity); } 592 beforeSetup: function(effect) { with(Element) { 593 makePositioned(effect.effects[0].element); }}, 594 afterFinishInternal: function(effect) { with(Element) { 595 [hide, undoPositioned].call(effect.effects[0].element); 596 setStyle(effect.effects[0].element, oldStyle); }} 622 597 }, arguments[1] || {})); 623 598 } … … 625 600 Effect.Shake = function(element) { 626 601 element = $(element); 627 var oldTop = element.style.top; 628 var oldLeft = element.style.left; 602 var oldStyle = { 603 top: Element.getStyle(element, 'top'), 604 left: Element.getStyle(element, 'left') }; 629 605 return new Effect.MoveBy(element, 0, 20, 630 606 { duration: 0.05, afterFinishInternal: function(effect) { … … 638 614 { duration: 0.1, afterFinishInternal: function(effect) { 639 615 new Effect.MoveBy(effect.element, 0, -20, 640 { duration: 0.05, afterFinishInternal: function(effect) { 641 Element.undoPositioned(effect.element); 642 effect.element.style.left = oldLeft; 643 effect.element.style.top = oldTop; 644 }}) }}) }}) }}) }}) }}); 616 { duration: 0.05, afterFinishInternal: function(effect) { with(Element) { 617 undoPositioned(effect.element); 618 setStyle(effect.element, oldStyle); 619 }}}) }}) }}) }}) }}) }}); 645 620 } 646 621 … … 649 624 Element.cleanWhitespace(element); 650 625 // SlideDown need to have the content of the element wrapped in a container element with fixed height! 651 var oldInnerBottom = element.firstChild.style.bottom;626 var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); 652 627 var elementDimensions = Element.getDimensions(element); 653 return new Effect.Scale(element, 100, 654 Object.extend({scaleContent: false,628 return new Effect.Scale(element, 100, Object.extend({ 629 scaleContent: false, 655 630 scaleX: false, 656 631 scaleFrom: 0, 657 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, 632 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, 658 633 restoreAfterFinish: true, 659 afterSetup: function(effect) { 660 Element.makePositioned(effect.element.firstChild); 661 if (window.opera) effect.element.firstChild.style.top = ""; 662 Element.makeClipping(effect.element); 663 element.style.height = '0'; 664 Element.show(element); 665