Changeset 169 for ruby/branches/0.5/public
- Timestamp:
- Aug 6, 2009, 11:21:29 PM (15 years ago)
- Location:
- ruby/branches/0.5
- Files:
-
- 3 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
ruby/branches/0.5/public/javascripts/controls.js
r164 r169 1 1 // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) 2 // (c) 2005-200 7Ivan Krstic (http://blogs.law.harvard.edu/ivan)3 // (c) 2005-200 7Jon Tirsen (http://www.tirsen.com)2 // (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan) 3 // (c) 2005-2008 Jon Tirsen (http://www.tirsen.com) 4 4 // Contributors: 5 5 // Richard Livsey 6 6 // Rahul Bhargava 7 7 // Rob Wills 8 // 8 // 9 9 // script.aculo.us is freely distributable under the terms of an MIT-style license. 10 10 // For details, see the script.aculo.us web site: http://script.aculo.us/ 11 11 12 // Autocompleter.Base handles all the autocompletion functionality 12 // Autocompleter.Base handles all the autocompletion functionality 13 13 // that's independent of the data source for autocompletion. This 14 14 // includes drawing the autocompletion menu, observing keyboard 15 15 // and mouse events, and similar. 16 16 // 17 // Specific autocompleters need to provide, at the very least, 17 // Specific autocompleters need to provide, at the very least, 18 18 // a getUpdatedChoices function that will be invoked every time 19 // the text inside the monitored textbox changes. This method 19 // the text inside the monitored textbox changes. This method 20 20 // should get the text for which to provide autocompletion by 21 21 // invoking this.getToken(), NOT by directly accessing … … 31 31 // Additionally, ',' in the above example can be replaced with 32 32 // a token array, e.g. { tokens: [',', '\n'] } which 33 // enables autocompletion on multiple tokens. This is most 34 // useful when one of the tokens is \n (a newline), as it 33 // enables autocompletion on multiple tokens. This is most 34 // useful when one of the tokens is \n (a newline), as it 35 35 // allows smart autocompletion after linebreaks. 36 36 … … 38 38 throw("controls.js requires including script.aculo.us' effects.js library"); 39 39 40 var Autocompleter = { } 40 var Autocompleter = { }; 41 41 Autocompleter.Base = Class.create({ 42 42 baseInitialize: function(element, update, options) { 43 element = $(element) 44 this.element = element; 45 this.update = $(update); 46 this.hasFocus = false; 47 this.changed = false; 48 this.active = false; 49 this.index = 0; 43 element = $(element); 44 this.element = element; 45 this.update = $(update); 46 this.hasFocus = false; 47 this.changed = false; 48 this.active = false; 49 this.index = 0; 50 50 this.entryCount = 0; 51 51 this.oldElementValue = this.element.value; … … 60 60 this.options.frequency = this.options.frequency || 0.4; 61 61 this.options.minChars = this.options.minChars || 1; 62 this.options.onShow = this.options.onShow || 63 function(element, update){ 62 this.options.onShow = this.options.onShow || 63 function(element, update){ 64 64 if(!update.style.position || update.style.position=='absolute') { 65 65 update.style.position = 'absolute'; 66 66 Position.clone(element, update, { 67 setHeight: false, 67 setHeight: false, 68 68 offsetTop: element.offsetHeight 69 69 }); … … 71 71 Effect.Appear(update,{duration:0.15}); 72 72 }; 73 this.options.onHide = this.options.onHide || 73 this.options.onHide = this.options.onHide || 74 74 function(element, update){ new Effect.Fade(update,{duration:0.15}) }; 75 75 76 if(typeof(this.options.tokens) == 'string') 76 if(typeof(this.options.tokens) == 'string') 77 77 this.options.tokens = new Array(this.options.tokens); 78 78 // Force carriage returns as token delimiters anyway … … 81 81 82 82 this.observer = null; 83 83 84 84 this.element.setAttribute('autocomplete','off'); 85 85 … … 92 92 show: function() { 93 93 if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); 94 if(!this.iefix && 94 if(!this.iefix && 95 95 (Prototype.Browser.IE) && 96 96 (Element.getStyle(this.update, 'position')=='absolute')) { 97 new Insertion.After(this.update, 97 new Insertion.After(this.update, 98 98 '<iframe id="' + this.update.id + '_iefix" '+ 99 99 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + … … 103 103 if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); 104 104 }, 105 105 106 106 fixIEOverlapping: function() { 107 107 Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); … … 151 151 return; 152 152 } 153 else 154 if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 153 else 154 if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 155 155 (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; 156 156 … … 159 159 160 160 if(this.observer) clearTimeout(this.observer); 161 this.observer = 161 this.observer = 162 162 setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); 163 163 }, … … 171 171 onHover: function(event) { 172 172 var element = Event.findElement(event, 'LI'); 173 if(this.index != element.autocompleteIndex) 173 if(this.index != element.autocompleteIndex) 174 174 { 175 175 this.index = element.autocompleteIndex; … … 178 178 Event.stop(event); 179 179 }, 180 180 181 181 onClick: function(event) { 182 182 var element = Event.findElement(event, 'LI'); … … 185 185 this.hide(); 186 186 }, 187 187 188 188 onBlur: function(event) { 189 189 // needed to make click events working 190 190 setTimeout(this.hide.bind(this), 250); 191 191 this.hasFocus = false; 192 this.active = false; 193 }, 194 192 this.active = false; 193 }, 194 195 195 render: function() { 196 196 if(this.entryCount > 0) { 197 197 for (var i = 0; i < this.entryCount; i++) 198 this.index==i ? 199 Element.addClassName(this.getEntry(i),"selected") : 198 this.index==i ? 199 Element.addClassName(this.getEntry(i),"selected") : 200 200 Element.removeClassName(this.getEntry(i),"selected"); 201 if(this.hasFocus) { 201 if(this.hasFocus) { 202 202 this.show(); 203 203 this.active = true; … … 208 208 } 209 209 }, 210 210 211 211 markPrevious: function() { 212 if(this.index > 0) this.index-- 212 if(this.index > 0) this.index--; 213 213 else this.index = this.entryCount-1; 214 214 this.getEntry(this.index).scrollIntoView(true); 215 215 }, 216 216 217 217 markNext: function() { 218 if(this.index < this.entryCount-1) this.index++ 218 if(this.index < this.entryCount-1) this.index++; 219 219 else this.index = 0; 220 220 this.getEntry(this.index).scrollIntoView(false); 221 221 }, 222 222 223 223 getEntry: function(index) { 224 224 return this.update.firstChild.childNodes[index]; 225 225 }, 226 226 227 227 getCurrentEntry: function() { 228 228 return this.getEntry(this.index); 229 229 }, 230 230 231 231 selectEntry: function() { 232 232 this.active = false; … … 245 245 } else 246 246 value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); 247 247 248 248 var bounds = this.getTokenBounds(); 249 249 if (bounds[0] != -1) { … … 258 258 this.oldElementValue = this.element.value; 259 259 this.element.focus(); 260 260 261 261 if (this.options.afterUpdateElement) 262 262 this.options.afterUpdateElement(this.element, selectedElement); … … 270 270 271 271 if(this.update.firstChild && this.update.down().childNodes) { 272 this.entryCount = 272 this.entryCount = 273 273 this.update.down().childNodes.length; 274 274 for (var i = 0; i < this.entryCount; i++) { … … 277 277 this.addObservers(entry); 278 278 } 279 } else { 279 } else { 280 280 this.entryCount = 0; 281 281 } … … 283 283 this.stopIndicator(); 284 284 this.index = 0; 285 285 286 286 if(this.entryCount==1 && this.options.autoSelect) { 287 287 this.selectEntry(); … … 299 299 300 300 onObserverEvent: function() { 301 this.changed = false; 301 this.changed = false; 302 302 this.tokenBounds = null; 303 303 if(this.getToken().length>=this.options.minChars) { … … 352 352 getUpdatedChoices: function() { 353 353 this.startIndicator(); 354 355 var entry = encodeURIComponent(this.options.paramName) + '=' + 354 355 var entry = encodeURIComponent(this.options.paramName) + '=' + 356 356 encodeURIComponent(this.getToken()); 357 357 … … 359 359 this.options.callback(this.element, entry) : entry; 360 360 361 if(this.options.defaultParams) 361 if(this.options.defaultParams) 362 362 this.options.parameters += '&' + this.options.defaultParams; 363 363 364 364 new Ajax.Request(this.url, this.options); 365 365 }, … … 383 383 // 384 384 // - partialSearch - If false, the autocompleter will match entered 385 // text only at the beginning of strings in the 385 // text only at the beginning of strings in the 386 386 // autocomplete array. Defaults to true, which will 387 387 // match text at the beginning of any *word* in the … … 400 400 // Defaults to true. 401 401 // 402 // It's possible to pass in a custom function as the 'selector' 402 // It's possible to pass in a custom function as the 'selector' 403 403 // option, if you prefer to write your own autocompletion logic. 404 404 // In that case, the other options above will not apply unless … … 428 428 var count = 0; 429 429 430 for (var i = 0; i < instance.options.array.length && 431 ret.length < instance.options.choices ; i++) { 430 for (var i = 0; i < instance.options.array.length && 431 ret.length < instance.options.choices ; i++) { 432 432 433 433 var elem = instance.options.array[i]; 434 var foundPos = instance.options.ignoreCase ? 435 elem.toLowerCase().indexOf(entry.toLowerCase()) : 434 var foundPos = instance.options.ignoreCase ? 435 elem.toLowerCase().indexOf(entry.toLowerCase()) : 436 436 elem.indexOf(entry); 437 437 438 438 while (foundPos != -1) { 439 if (foundPos == 0 && elem.length != entry.length) { 440 ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 439 if (foundPos == 0 && elem.length != entry.length) { 440 ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 441 441 elem.substr(entry.length) + "</li>"); 442 442 break; 443 } else if (entry.length >= instance.options.partialChars && 443 } else if (entry.length >= instance.options.partialChars && 444 444 instance.options.partialSearch && foundPos != -1) { 445 445 if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { … … 451 451 } 452 452 453 foundPos = instance.options.ignoreCase ? 454 elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 453 foundPos = instance.options.ignoreCase ? 454 elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 455 455 elem.indexOf(entry, foundPos + 1); 456 456 … … 458 458 } 459 459 if (partial.length) 460 ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) 460 ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)); 461 461 return "<ul>" + ret.join('') + "</ul>"; 462 462 } … … 475 475 Field.activate(field); 476 476 }, 1); 477 } 477 }; 478 478 479 479 Ajax.InPlaceEditor = Class.create({ … … 605 605 }, 606 606 getText: function() { 607 return this.element.innerHTML ;607 return this.element.innerHTML.unescapeHTML(); 608 608 }, 609 609 handleAJAXFailure: function(transport) { … … 781 781 var js = transport.responseText.strip(); 782 782 if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check 783 throw 'Server returned an invalid collection representation.';783 throw('Server returned an invalid collection representation.'); 784 784 this._collection = eval(js); 785 785 this.checkForExternalText(); … … 938 938 }; 939 939 940 // Delayed observer, like Form.Element.Observer, 940 // Delayed observer, like Form.Element.Observer, 941 941 // but waits for delay after last key input 942 942 // Ideal for live-search fields … … 948 948 this.callback = callback; 949 949 this.timer = null; 950 this.lastValue = $F(this.element); 950 this.lastValue = $F(this.element); 951 951 Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); 952 952 }, -
ruby/branches/0.5/public/javascripts/dragdrop.js
r164 r169 1 1 // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) 2 // (c) 2005-200 7Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)3 // 2 // (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) 3 // 4 4 // script.aculo.us is freely distributable under the terms of an MIT-style license. 5 5 // For details, see the script.aculo.us web site: http://script.aculo.us/ … … 33 33 } 34 34 } 35 35 36 36 if(options.accept) options.accept = [options.accept].flatten(); 37 37 … … 41 41 this.drops.push(options); 42 42 }, 43 43 44 44 findDeepestChild: function(drops) { 45 45 deepest = drops[0]; 46 46 47 47 for (i = 1; i < drops.length; ++i) 48 48 if (Element.isParent(drops[i].element, deepest.element)) 49 49 deepest = drops[i]; 50 50 51 51 return deepest; 52 52 }, … … 55 55 var containmentNode; 56 56 if(drop.tree) { 57 containmentNode = element.treeNode; 57 containmentNode = element.treeNode; 58 58 } else { 59 59 containmentNode = element.parentNode; … … 61 61 return drop._containers.detect(function(c) { return containmentNode == c }); 62 62 }, 63 63 64 64 isAffected: function(point, element, drop) { 65 65 return ( … … 68 68 this.isContained(element, drop)) && 69 69 ((!drop.accept) || 70 (Element.classNames(element).detect( 70 (Element.classNames(element).detect( 71 71 function(v) { return drop.accept.include(v) } ) )) && 72 72 Position.within(drop.element, point[0], point[1]) ); … … 88 88 if(!this.drops.length) return; 89 89 var drop, affected = []; 90 90 91 91 this.drops.each( function(drop) { 92 92 if(Droppables.isAffected(point, element, drop)) 93 93 affected.push(drop); 94 94 }); 95 95 96 96 if(affected.length>0) 97 97 drop = Droppables.findDeepestChild(affected); … … 102 102 if(drop.onHover) 103 103 drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); 104 104 105 105 if (drop != this.last_active) Droppables.activate(drop); 106 106 } … … 113 113 if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) 114 114 if (this.last_active.onDrop) { 115 this.last_active.onDrop(element, this.last_active.element, event); 116 return true; 115 this.last_active.onDrop(element, this.last_active.element, event); 116 return true; 117 117 } 118 118 }, … … 122 122 this.deactivate(this.last_active); 123 123 } 124 } 124 }; 125 125 126 126 var Draggables = { 127 127 drags: [], 128 128 observers: [], 129 129 130 130 register: function(draggable) { 131 131 if(this.drags.length == 0) { … … 133 133 this.eventMouseMove = this.updateDrag.bindAsEventListener(this); 134 134 this.eventKeypress = this.keyPress.bindAsEventListener(this); 135 135 136 136 Event.observe(document, "mouseup", this.eventMouseUp); 137 137 Event.observe(document, "mousemove", this.eventMouseMove); … … 140 140 this.drags.push(draggable); 141 141 }, 142 142 143 143 unregister: function(draggable) { 144 144 this.drags = this.drags.reject(function(d) { return d==draggable }); … … 149 149 } 150 150 }, 151 151 152 152 activate: function(draggable) { 153 if(draggable.options.delay) { 154 this._timeout = setTimeout(function() { 155 Draggables._timeout = null; 156 window.focus(); 157 Draggables.activeDraggable = draggable; 158 }.bind(this), draggable.options.delay); 153 if(draggable.options.delay) { 154 this._timeout = setTimeout(function() { 155 Draggables._timeout = null; 156 window.focus(); 157 Draggables.activeDraggable = draggable; 158 }.bind(this), draggable.options.delay); 159 159 } else { 160 160 window.focus(); // allows keypress events if window isn't currently focused, fails for Safari … … 162 162 } 163 163 }, 164 164 165 165 deactivate: function() { 166 166 this.activeDraggable = null; 167 167 }, 168 168 169 169 updateDrag: function(event) { 170 170 if(!this.activeDraggable) return; … … 174 174 if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; 175 175 this._lastPointer = pointer; 176 176 177 177 this.activeDraggable.updateDrag(event, pointer); 178 178 }, 179 179 180 180 endDrag: function(event) { 181 if(this._timeout) { 182 clearTimeout(this._timeout); 183 this._timeout = null; 181 if(this._timeout) { 182 clearTimeout(this._timeout); 183 this._timeout = null; 184 184 } 185 185 if(!this.activeDraggable) return; … … 188 188 this.activeDraggable = null; 189 189 }, 190 190 191 191 keyPress: function(event) { 192 192 if(this.activeDraggable) 193 193 this.activeDraggable.keyPress(event); 194 194 }, 195 195 196 196 addObserver: function(observer) { 197 197 this.observers.push(observer); 198 198 this._cacheObserverCallbacks(); 199 199 }, 200 200 201 201 removeObserver: function(element) { // element instead of observer fixes mem leaks 202 202 this.observers = this.observers.reject( function(o) { return o.element==element }); 203 203 this._cacheObserverCallbacks(); 204 204 }, 205 205 206 206 notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' 207 207 if(this[eventName+'Count'] > 0) … … 211 211 if(draggable.options[eventName]) draggable.options[eventName](draggable, event); 212 212 }, 213 213 214 214 _cacheObserverCallbacks: function() { 215 215 ['onStart','onEnd','onDrag'].each( function(eventName) { … … 219 219 }); 220 220 } 221 } 221 }; 222 222 223 223 /*--------------------------------------------------------------------------*/ … … 235 235 endeffect: function(element) { 236 236 var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; 237 new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 237 new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 238 238 queue: {scope:'_draggable', position:'end'}, 239 afterFinish: function(){ 240 Draggable._dragging[element] = false 239 afterFinish: function(){ 240 Draggable._dragging[element] = false 241 241 } 242 }); 242 }); 243 243 }, 244 244 zindex: 1000, … … 251 251 delay: 0 252 252 }; 253 253 254 254 if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) 255 255 Object.extend(defaults, { … … 257 257 element._opacity = Element.getOpacity(element); 258 258 Draggable._dragging[element] = true; 259 new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); 259 new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); 260 260 } 261 261 }); 262 262 263 263 var options = Object.extend(defaults, arguments[1] || { }); 264 264 265 265 this.element = $(element); 266 266 267 267 if(options.handle && Object.isString(options.handle)) 268 268 this.handle = this.element.down('.'+options.handle, 0); 269 269 270 270 if(!this.handle) this.handle = $(options.handle); 271 271 if(!this.handle) this.handle = this.element; 272 272 273 273 if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { 274 274 options.scroll = $(options.scroll); … … 276 276 } 277 277 278 Element.makePositioned(this.element); // fix IE 278 Element.makePositioned(this.element); // fix IE 279 279 280 280 this.options = options; 281 this.dragging = false; 281 this.dragging = false; 282 282 283 283 this.eventMouseDown = this.initDrag.bindAsEventListener(this); 284 284 Event.observe(this.handle, "mousedown", this.eventMouseDown); 285 285 286 286 Draggables.register(this); 287 287 }, 288 288 289 289 destroy: function() { 290 290 Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); 291 291 Draggables.unregister(this); 292 292 }, 293 293 294 294 currentDelta: function() { 295 295 return([ … … 297 297 parseInt(Element.getStyle(this.element,'top') || '0')]); 298 298 }, 299 299 300 300 initDrag: function(event) { 301 301 if(!Object.isUndefined(Draggable._dragging[this.element]) && 302 302 Draggable._dragging[this.element]) return; 303 if(Event.isLeftClick(event)) { 303 if(Event.isLeftClick(event)) { 304 304 // abort on form elements, fixes a Firefox issue 305 305 var src = Event.element(event); … … 310 310 tag_name=='BUTTON' || 311 311 tag_name=='TEXTAREA')) return; 312 312 313 313 var pointer = [Event.pointerX(event), Event.pointerY(event)]; 314 314 var pos = Position.cumulativeOffset(this.element); 315 315 this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); 316 316 317 317 Draggables.activate(this); 318 318 Event.stop(event); 319 319 } 320 320 }, 321 321 322 322 startDrag: function(event) { 323 323 this.dragging = true; 324 324 if(!this.delta) 325 325 this.delta = this.currentDelta(); 326 326 327 327 if(this.options.zindex) { 328 328 this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); 329 329 this.element.style.zIndex = this.options.zindex; 330 330 } 331 331 332 332 if(this.options.ghosting) { 333 333 this._clone = this.element.cloneNode(true); 334 this. element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');335 if (!this. element._originallyAbsolute)334 this._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); 335 if (!this._originallyAbsolute) 336 336 Position.absolutize(this.element); 337 337 this.element.parentNode.insertBefore(this._clone, this.element); 338 338 } 339 339 340 340 if(this.options.scroll) { 341 341 if (this.options.scroll == window) { … … 348 348 } 349 349 } 350 350 351 351 Draggables.notify('onStart', this, event); 352 352 353 353 if(this.options.starteffect) this.options.starteffect(this.element); 354 354 }, 355 355 356 356 updateDrag: function(event, pointer) { 357 357 if(!this.dragging) this.startDrag(event); 358 358 359 359 if(!this.options.quiet){ 360 360 Position.prepare(); 361 361 Droppables.show(pointer, this.element); 362 362 } 363 363 364 364 Draggables.notify('onDrag', this, event); 365 365 366 366 this.draw(pointer); 367 367 if(this.options.change) this.options.change(this); 368 368 369 369 if(this.options.scroll) { 370 370 this.stopScrolling(); 371 371 372 372 var p; 373 373 if (this.options.scroll == window) { … … 387 387 this.startScrolling(speed); 388 388 } 389 389 390 390 // fix AppleWebKit rendering 391 391 if(Prototype.Browser.WebKit) window.scrollBy(0,0); 392 392 393 393 Event.stop(event); 394 394 }, 395 395 396 396 finishDrag: function(event, success) { 397 397 this.dragging = false; 398 398 399 399 if(this.options.quiet){ 400 400 Position.prepare(); … … 404 404 405 405 if(this.options.ghosting) { 406 if (!this. element._originallyAbsolute)406 if (!this._originallyAbsolute) 407 407 Position.relativize(this.element); 408 delete this. element._originallyAbsolute;408 delete this._originallyAbsolute; 409 409 Element.remove(this._clone); 410 410 this._clone = null; 411 411 } 412 412 413 var dropped = false; 414 if(success) { 415 dropped = Droppables.fire(event, this.element); 416 if (!dropped) dropped = false; 413 var dropped = false; 414 if(success) { 415 dropped = Droppables.fire(event, this.element); 416 if (!dropped) dropped = false; 417 417 } 418 418 if(dropped && this.options.onDropped) this.options.onDropped(this.element); … … 421 421 var revert = this.options.revert; 422 422 if(revert && Object.isFunction(revert)) revert = revert(this.element); 423 423 424 424 var d = this.currentDelta(); 425 425 if(revert && this.options.reverteffect) { … … 434 434 this.element.style.zIndex = this.originalZ; 435 435 436 if(this.options.endeffect) 436 if(this.options.endeffect) 437 437 this.options.endeffect(this.element); 438 438 439 439 Draggables.deactivate(this); 440 440 Droppables.reset(); 441 441 }, 442 442 443 443 keyPress: function(event) { 444 444 if(event.keyCode!=Event.KEY_ESC) return; … … 446 446 Event.stop(event); 447 447 }, 448 448 449 449 endDrag: function(event) { 450 450 if(!this.dragging) return; … … 453 453 Event.stop(event); 454 454 }, 455 455 456 456 draw: function(point) { 457 457 var pos = Position.cumulativeOffset(this.element); … … 460 460 pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; 461 461 } 462 462 463 463 var d = this.currentDelta(); 464 464 pos[0] -= d[0]; pos[1] -= d[1]; 465 465 466 466 if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { 467 467 pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; 468 468 pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; 469 469 } 470 471 var p = [0,1].map(function(i){ 472 return (point[i]-pos[i]-this.offset[i]) 470 471 var p = [0,1].map(function(i){ 472 return (point[i]-pos[i]-this.offset[i]) 473 473 }.bind(this)); 474 474 475 475 if(this.options.snap) { 476 476 if(Object.isFunction(this.options.snap)) { … … 479 479 if(Object.isArray(this.options.snap)) { 480 480 p = p.map( function(v, i) { 481 return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) 481 return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)); 482 482 } else { 483 483 p = p.map( function(v) { 484 return (v/this.options.snap).round()*this.options.snap }.bind(this)) 484 return (v/this.options.snap).round()*this.options.snap }.bind(this)); 485 485 } 486 486 }} 487 487 488 488 var style = this.element.style; 489 489 if((!this.options.constraint) || (this.options.constraint=='horizontal')) … … 491 491 if((!this.options.constraint) || (this.options.constraint=='vertical')) 492 492 style.top = p[1] + "px"; 493 493 494 494 if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering 495 495 }, 496 496 497 497 stopScrolling: function() { 498 498 if(this.scrollInterval) { … … 502 502 } 503 503 }, 504 504 505 505 startScrolling: function(speed) { 506 506 if(!(speed[0] || speed[1])) return; … … 509 509 this.scrollInterval = setInterval(this.scroll.bind(this), 10); 510 510 }, 511 511 512 512 scroll: function() { 513 513 var current = new Date(); … … 525 525 this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; 526 526 } 527 527 528 528 Position.prepare(); 529 529 Droppables.show(Draggables._lastPointer, this.element); … … 539 539 this.draw(Draggables._lastScrollPointer); 540 540 } 541 541 542 542 if(this.options.change) this.options.change(this); 543 543 }, 544 544 545 545 _getWindowScroll: function(w) { 546 546 var T, L, W, H; … … 561 561 } else { 562 562 W = body.offsetWidth; 563 H = body.offsetHeight 563 H = body.offsetHeight; 564 564 } 565 565 } … … 578 578 this.lastValue = Sortable.serialize(this.element); 579 579 }, 580 580 581 581 onStart: function() { 582 582 this.lastValue = Sortable.serialize(this.element); 583 583 }, 584 584 585 585 onEnd: function() { 586 586 Sortable.unmark(); … … 592 592 var Sortable = { 593 593 SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, 594 594 595 595 sortables: { }, 596 596 597 597 _findRootElement: function(element) { 598 while (element.tagName.toUpperCase() != "BODY") { 598 while (element.tagName.toUpperCase() != "BODY") { 599 599 if(element.id && Sortable.sortables[element.id]) return element; 600 600 element = element.parentNode; … … 607 607 return Sortable.sortables[element.id]; 608 608 }, 609 609 610 610 destroy: function(element){ 611 var s = Sortable.options(element); 612 611 element = $(element); 612 var s = Sortable.sortables[element.id]; 613 613 614 if(s) { 614 615 Draggables.removeObserver(s.element); 615 616 s.droppables.each(function(d){ Droppables.remove(d) }); 616 617 s.draggables.invoke('destroy'); 617 618 618 619 delete Sortable.sortables[s.element.id]; 619 620 } … … 622 623 create: function(element) { 623 624 element = $(element); 624 var options = Object.extend({ 625 var options = Object.extend({ 625 626 element: element, 626 627 tag: 'li', // assumes li children, override with tag: 'tagname' … … 636 637 hoverclass: null, 637 638 ghosting: false, 638 quiet: false, 639 quiet: false, 639 640 scroll: false, 640 641 scrollSensitivity: 20, 641 642 scrollSpeed: 15, 642 643 format: this.SERIALIZE_RULE, 643 644 // these take arrays of elements or ids and can be 644 645 // these take arrays of elements or ids and can be 645 646 // used for better initialization performance 646 647 elements: false, 647 648 handles: false, 648 649 649 650 onChange: Prototype.emptyFunction, 650 651 onUpdate: Prototype.emptyFunction … … 683 684 options_for_draggable.zindex = options.zindex; 684 685 685 // build options for the droppables 686 // build options for the droppables 686 687 var options_for_droppable = { 687 688 overlap: options.overlap, … … 690 691 hoverclass: options.hoverclass, 691 692 onHover: Sortable.onHover 692 } 693 693 }; 694 694 695 var options_for_tree = { 695 696 onHover: Sortable.onEmptyHover, … … 697 698 containment: options.containment, 698 699 hoverclass: options.hoverclass 699 } 700 }; 700 701 701 702 // fix for gecko engine 702 Element.cleanWhitespace(element); 703 Element.cleanWhitespace(element); 703 704 704 705 options.draggables = []; … … 713 714 (options.elements || this.findElements(element, options) || []).each( function(e,i) { 714 715 var handle = options.handles ? $(options.handles[i]) : 715 (options.handle ? $(e).select('.' + options.handle)[0] : e); 716 (options.handle ? $(e).select('.' + options.handle)[0] : e); 716 717 options.draggables.push( 717 718 new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); 718 719 Droppables.add(e, options_for_droppable); 719 720 if(options.tree) e.treeNode = element; 720 options.droppables.push(e); 721 options.droppables.push(e); 721 722 }); 722 723 723 724 if(options.tree) { 724 725 (Sortable.findTreeElements(element, options) || []).each( function(e) { … … 742 743 element, options.only, options.tree ? true : false, options.tag); 743 744 }, 744 745 745 746 findTreeElements: function(element, options) { 746 747 return Element.findChildren( … … 759 760 element.style.visibility = "hidden"; // fix gecko rendering 760 761 dropon.parentNode.insertBefore(element, dropon); 761 if(dropon.parentNode!=oldParentNode) 762 if(dropon.parentNode!=oldParentNode) 762 763 Sortable.options(oldParentNode).onChange(element); 763 764 Sortable.options(dropon.parentNode).onChange(element); … … 770 771 element.style.visibility = "hidden"; // fix gecko rendering 771 772 dropon.parentNode.insertBefore(element, nextElement); 772 if(dropon.parentNode!=oldParentNode) 773 if(dropon.parentNode!=oldParentNode) 773 774 Sortable.options(oldParentNode).onChange(element); 774 775 Sortable.options(dropon.parentNode).onChange(element); … … 776 777 } 777 778 }, 778 779 779 780 onEmptyHover: function(element, dropon, overlap) { 780 781 var oldParentNode = element.parentNode; 781 782 var droponOptions = Sortable.options(dropon); 782 783 783 784 if(!Element.isParent(dropon, element)) { 784 785 var index; 785 786 786 787 var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); 787 788 var child = null; 788 789 789 790 if(children) { 790 791 var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); 791 792 792 793 for (index = 0; index < children.length; index += 1) { 793 794 if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { … … 802 803 } 803 804 } 804 805 805 806 dropon.insertBefore(element, child); 806 807 807 808 Sortable.options(oldParentNode).onChange(element); 808 809 droponOptions.onChange(element); … … 817 818 // mark on ghosting only 818 819 var sortable = Sortable.options(dropon.parentNode); 819 if(sortable && !sortable.ghosting) return; 820 if(sortable && !sortable.ghosting) return; 820 821 821 822 if(!Sortable._marker) { 822 Sortable._marker = 823 Sortable._marker = 823 824 ($('dropmarker') || Element.extend(document.createElement('DIV'))). 824 825 hide().addClassName('dropmarker').setStyle({position:'absolute'}); 825 826 document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); 826 } 827 } 827 828 var offsets = Position.cumulativeOffset(dropon); 828 829 Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); 829 830 830 831 if(position=='after') 831 if(sortable.overlap == 'horizontal') 832 if(sortable.overlap == 'horizontal') 832 833 Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); 833 834 else 834 835 Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); 835 836 836 837 Sortable._marker.show(); 837 838 }, 838 839 839 840 _tree: function(element, options, parent) { 840 841 var children = Sortable.findElements(element, options) || []; 841 842 842 843 for (var i = 0; i < children.length; ++i) { 843 844 var match = children[i].id.match(options.format); 844 845 845 846 if (!match) continue; 846 847 847 848 var child = { 848 849 id: encodeURIComponent(match ? match[1] : null), … … 852 853 position: parent.children.length, 853 854 container: $(children[i]).down(options.treeTag) 854 } 855 855 }; 856 856 857 /* Get the element containing the children and recurse over it */ 857 858 if (child.container) 858 this._tree(child.container, options, child) 859 859 this._tree(child.container, options, child); 860 860 861 parent.children.push (child); 861 862 } 862 863 863 return parent; 864 return parent; 864 865 }, 865 866 … … 874 875 format: sortableOptions.format 875 876 }, arguments[1] || { }); 876 877 877 878 var root = { 878 879 id: null, … … 881 882 container: element, 882 883 position: 0 883 } 884 884 }; 885 885 886 return Sortable._tree(element, options, root); 886 887 }, … … 898 899 element = $(element); 899 900 var options = Object.extend(this.options(element), arguments[1] || { }); 900 901 901 902 return $(this.findElements(element, options) || []).map( function(item) { 902 903 return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; … … 907 908 element = $(element); 908 909 var options = Object.extend(this.options(element), arguments[2] || { }); 909 910 910 911 var nodeMap = { }; 911 912 this.findElements(element, options).each( function(n) { … … 914 915 n.parentNode.removeChild(n); 915 916 }); 916 917 917 918 new_sequence.each(function(ident) { 918 919 var n = nodeMap[ident]; … … 923 924 }); 924 925 }, 925 926 926 927 serialize: function(element) { 927 928 element = $(element); … … 929 930 var name = encodeURIComponent( 930 931 (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); 931 932 932 933 if (options.tree) { 933 934 return Sortable.tree(element, arguments[1]).children.map( function (item) { 934 return [name + Sortable._constructIndex(item) + "[id]=" + 935 return [name + Sortable._constructIndex(item) + "[id]=" + 935 936 encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); 936 937 }).flatten().join('&'); … … 941 942 } 942 943 } 943 } 944 }; 944 945 945 946 // Returns true if child is contained within element … … 948 949 if (child.parentNode == element) return true; 949 950 return Element.isParent(child.parentNode, element); 950 } 951 952 Element.findChildren = function(element, only, recursive, tagName) { 951 }; 952 953 Element.findChildren = function(element, only, recursive, tagName) { 953 954 if(!element.hasChildNodes()) return null; 954 955 tagName = tagName.toUpperCase(); … … 966 967 967 968 return (elements.length>0 ? elements.flatten() : []); 968 } 969 }; 969 970 970 971 Element.offsetSize = function (element, type) { 971 972 return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; 972 } 973 }; -
ruby/branches/0.5/public/javascripts/effects.js
r164 r169 4 4 // Mark Pilgrim (http://diveintomark.org/) 5 5 // Martin Bialasinki 6 // 6 // 7 7 // script.aculo.us is freely distributable under the terms of an MIT-style license. 8 // For details, see the script.aculo.us web site: http://script.aculo.us/ 9 10 // converts rgb() and #xxx to #xxxxxx format, 11 // returns self (or first argument) if not convertable 12 String.prototype.parseColor = function() { 8 // For details, see the script.aculo.us web site: http://script.aculo.us/ 9 10 // converts rgb() and #xxx to #xxxxxx format, 11 // returns self (or first argument) if not convertable 12 String.prototype.parseColor = function() { 13 13 var color = '#'; 14 if (this.slice(0,4) == 'rgb(') { 15 var cols = this.slice(4,this.length-1).split(','); 16 var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); 17 } else { 18 if (this.slice(0,1) == '#') { 19 if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); 20 if (this.length==7) color = this.toLowerCase(); 21 } 22 } 23 return (color.length==7 ? color : (arguments[0] || this)); 14 if (this.slice(0,4) == 'rgb(') { 15 var cols = this.slice(4,this.length-1).split(','); 16 var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); 17 } else { 18 if (this.slice(0,1) == '#') { 19 if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); 20 if (this.length==7) color = this.toLowerCase(); 21 } 22 } 23 return (color.length==7 ? color : (arguments[0] || this)); 24 24 }; 25 25 26 26 /*--------------------------------------------------------------------------*/ 27 27 28 Element.collectTextNodes = function(element) { 28 Element.collectTextNodes = function(element) { 29 29 return $A($(element).childNodes).collect( function(node) { 30 return (node.nodeType==3 ? node.nodeValue : 30 return (node.nodeType==3 ? node.nodeValue : 31 31 (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); 32 32 }).flatten().join(''); 33 33 }; 34 34 35 Element.collectTextNodesIgnoreClass = function(element, className) { 35 Element.collectTextNodesIgnoreClass = function(element, className) { 36 36 return $A($(element).childNodes).collect( function(node) { 37 return (node.nodeType==3 ? node.nodeValue : 38 ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 37 return (node.nodeType==3 ? node.nodeValue : 38 ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 39 39 Element.collectTextNodesIgnoreClass(node, className) : '')); 40 40 }).flatten().join(''); … … 42 42 43 43 Element.setContentZoom = function(element, percent) { 44 element = $(element); 45 element.setStyle({fontSize: (percent/100) + 'em'}); 44 element = $(element); 45 element.setStyle({fontSize: (percent/100) + 'em'}); 46 46 if (Prototype.Browser.WebKit) window.scrollBy(0,0); 47 47 return element; … … 71 71 linear: Prototype.K, 72 72 sinoidal: function(pos) { 73 return (-Math.cos(pos*Math.PI)/2) + 0.5;73 return (-Math.cos(pos*Math.PI)/2) + .5; 74 74 }, 75 75 reverse: function(pos) { … … 77 77 }, 78 78 flicker: function(pos) { 79 var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;79 var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4; 80 80 return pos > 1 ? 1 : pos; 81 81 }, 82 82 wobble: function(pos) { 83 return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; 84 }, 85 pulse: function(pos, pulses) { 86 pulses = pulses || 5; 87 return ( 88 ((pos % (1/pulses)) * pulses).round() == 0 ? 89 ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 90 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor()) 91 ); 92 }, 93 spring: function(pos) { 94 return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 83 return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5; 84 }, 85 pulse: function(pos, pulses) { 86 return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5; 87 }, 88 spring: function(pos) { 89 return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 95 90 }, 96 91 none: function(pos) { … … 113 108 var tagifyStyle = 'position:relative'; 114 109 if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; 115 110 116 111 element = $(element); 117 112 $A(element.childNodes).each( function(child) { … … 120 115 element.insertBefore( 121 116 new Element('span', {style: tagifyStyle}).update( 122 character == ' ' ? String.fromCharCode(160) : character), 117 character == ' ' ? String.fromCharCode(160) : character), 123 118 child); 124 119 }); … … 129 124 multiple: function(element, effect) { 130 125 var elements; 131 if (((typeof element == 'object') || 132 Object.isFunction(element)) && 126 if (((typeof element == 'object') || 127 Object.isFunction(element)) && 133 128 (element.length)) 134 129 elements = element; 135 130 else 136 131 elements = $(element).childNodes; 137 132 138 133 var options = Object.extend({ 139 134 speed: 0.1, … … 157 152 queue: { position:'end', scope:(element.id || 'global'), limit: 1 } 158 153 }, arguments[2] || { }); 159 Effect[element.visible() ? 154 Effect[element.visible() ? 160 155 Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); 161 156 } … … 169 164 initialize: function() { 170 165 this.effects = []; 171 this.interval = null; 166 this.interval = null; 172 167 }, 173 168 _each: function(iterator) { … … 176 171 add: function(effect) { 177 172 var timestamp = new Date().getTime(); 178 179 var position = Object.isString(effect.options.queue) ? 173 174 var position = Object.isString(effect.options.queue) ? 180 175 effect.options.queue : effect.options.queue.position; 181 176 182 177 switch(position) { 183 178 case 'front': 184 // move unstarted effects after this effect 179 // move unstarted effects after this effect 185 180 this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { 186 181 e.startOn += effect.finishOn; … … 196 191 break; 197 192 } 198 193 199 194 effect.startOn += timestamp; 200 195 effect.finishOn += timestamp; … … 202 197 if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) 203 198 this.effects.push(effect); 204 199 205 200 if (!this.interval) 206 201 this.interval = setInterval(this.loop.bind(this), 15); … … 215 210 loop: function() { 216 211 var timePos = new Date().getTime(); 217 for(var i=0, len=this.effects.length;i<len;i++) 212 for(var i=0, len=this.effects.length;i<len;i++) 218 213 this.effects[i] && this.effects[i].loop(timePos); 219 214 } … … 224 219 get: function(queueName) { 225 220 if (!Object.isString(queueName)) return queueName; 226 221 227 222 return this.instances.get(queueName) || 228 223 this.instances.set(queueName, new Effect.ScopedQueue()); … … 249 244 this.totalTime = this.finishOn-this.startOn; 250 245 this.totalFrames = this.options.fps*this.options.duration; 251 252 eval('this.render = function(pos){ '+ 253 'if (this.state=="idle"){this.state="running";'+ 254 codeForEvent(this.options,'beforeSetup')+ 255 (this.setup ? 'this.setup();':'')+ 256 codeForEvent(this.options,'afterSetup')+ 257 '};if (this.state=="running"){'+ 258 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+ 259 'this.position=pos;'+ 260 codeForEvent(this.options,'beforeUpdate')+ 261 (this.update ? 'this.update(pos);':'')+ 262 codeForEvent(this.options,'afterUpdate')+ 263 '}}'); 264 246 247 this.render = (function() { 248 function dispatch(effect, eventName) { 249 if (effect.options[eventName + 'Internal']) 250 effect.options[eventName + 'Internal'](effect); 251 if (effect.options[eventName]) 252 effect.options[eventName](effect); 253 } 254 255 return function(pos) { 256 if (this.state === "idle") { 257 this.state = "running"; 258 dispatch(this, 'beforeSetup'); 259 if (this.setup) this.setup(); 260 dispatch(this, 'afterSetup'); 261 } 262 if (this.state === "running") { 263 pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from; 264 this.position = pos; 265 dispatch(this, 'beforeUpdate'); 266 if (this.update) this.update(pos); 267 dispatch(this, 'afterUpdate'); 268 } 269 }; 270 })(); 271 265 272 this.event('beforeStart'); 266 273 if (!this.options.sync) 267 Effect.Queues.get(Object.isString(this.options.queue) ? 274 Effect.Queues.get(Object.isString(this.options.queue) ? 268 275 'global' : this.options.queue.scope).add(this); 269 276 }, … … 274 281 this.cancel(); 275 282 this.event('beforeFinish'); 276 if (this.finish) this.finish(); 283 if (this.finish) this.finish(); 277 284 this.event('afterFinish'); 278 return; 285 return; 279 286 } 280 287 var pos = (timePos - this.startOn) / this.totalTime, … … 288 295 cancel: function() { 289 296 if (!this.options.sync) 290 Effect.Queues.get(Object.isString(this.options.queue) ? 297 Effect.Queues.get(Object.isString(this.options.queue) ? 291 298 'global' : this.options.queue.scope).remove(this); 292 299 this.state = 'finished'; … … 326 333 initialize: function(object, from, to) { 327 334 object = Object.isString(object) ? $(object) : object; 328 var args = $A(arguments), method = args.last(), 335 var args = $A(arguments), method = args.last(), 329 336 options = args.length == 5 ? args[3] : null; 330 337 this.method = Object.isFunction(method) ? method.bind(object) : 331 Object.isFunction(object[method]) ? object[method].bind(object) : 338 Object.isFunction(object[method]) ? object[method].bind(object) : 332 339 function(value) { object[method] = value }; 333 340 this.start(Object.extend({ from: from, to: to }, options || { })); … … 393 400 // for backwards compatibility 394 401 Effect.MoveBy = function(element, toTop, toLeft) { 395 return new Effect.Move(element, 402 return new Effect.Move(element, 396 403 Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); 397 404 }; … … 415 422 this.restoreAfterFinish = this.options.restoreAfterFinish || false; 416 423 this.elementPositioning = this.element.getStyle('position'); 417 424 418 425 this.originalStyle = { }; 419 426 ['top','left','width','height','fontSize'].each( function(k) { 420 427 this.originalStyle[k] = this.element.style[k]; 421 428 }.bind(this)); 422 429 423 430 this.originalTop = this.element.offsetTop; 424 431 this.originalLeft = this.element.offsetLeft; 425 432 426 433 var fontSize = this.element.getStyle('font-size') || '100%'; 427 434 ['em','px','%','pt'].each( function(fontSizeType) { … … 431 438 } 432 439 }.bind(this)); 433 440 434 441 this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; 435 442 436 443 this.dims = null; 437 444 if (this.options.scaleMode=='box') … … 508 515 Effect.ScrollTo = function(element) { 509 516 var options = arguments[1] || { }, 510 scrollOffsets = document.viewport.getScrollOffsets(), 511 elementOffsets = $(element).cumulativeOffset(), 512 max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); 517 scrollOffsets = document.viewport.getScrollOffsets(), 518 elementOffsets = $(element).cumulativeOffset(); 513 519 514 520 if (options.offset) elementOffsets[1] += options.offset; … … 516 522 return new Effect.Tween(null, 517 523 scrollOffsets.top, 518 elementOffsets[1] > max ? max : elementOffsets[1],524 elementOffsets[1], 519 525 options, 520 function(p){ scrollTo(scrollOffsets.left, p.round()) }526 function(p){ scrollTo(scrollOffsets.left, p.round()); } 521 527 ); 522 528 }; … … 530 536 from: element.getOpacity() || 1.0, 531 537 to: 0.0, 532 afterFinishInternal: function(effect) { 538 afterFinishInternal: function(effect) { 533 539 if (effect.options.to!=0) return; 534 effect.element.hide().setStyle({opacity: oldOpacity}); 540 effect.element.hide().setStyle({opacity: oldOpacity}); 535 541 } 536 542 }, arguments[1] || { }); … … 548 554 }, 549 555 beforeSetup: function(effect) { 550 effect.element.setOpacity(effect.options.from).show(); 556 effect.element.setOpacity(effect.options.from).show(); 551 557 }}, arguments[1] || { }); 552 558 return new Effect.Opacity(element,options); … … 555 561 Effect.Puff = function(element) { 556 562 element = $(element); 557 var oldStyle = { 558 opacity: element.getInlineOpacity(), 563 var oldStyle = { 564 opacity: element.getInlineOpacity(), 559 565 position: element.getStyle('position'), 560 566 top: element.style.top, … … 564 570 }; 565 571 return new Effect.Parallel( 566 [ new Effect.Scale(element, 200, 567 { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 568 new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 569 Object.extend({ duration: 1.0, 572 [ new Effect.Scale(element, 200, 573 { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 574 new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 575 Object.extend({ duration: 1.0, 570 576 beforeSetupInternal: function(effect) { 571 Position.absolutize(effect.effects[0].element) 577 Position.absolutize(effect.effects[0].element); 572 578 }, 573 579 afterFinishInternal: function(effect) { … … 581 587 element.makeClipping(); 582 588 return new Effect.Scale(element, 0, 583 Object.extend({ scaleContent: false, 584 scaleX: false, 589 Object.extend({ scaleContent: false, 590 scaleX: false, 585 591 restoreAfterFinish: true, 586 592 afterFinishInternal: function(effect) { 587 593 effect.element.hide().undoClipping(); 588 } 594 } 589 595 }, arguments[1] || { }) 590 596 ); … … 594 600 element = $(element); 595 601 var elementDimensions = element.getDimensions(); 596 return new Effect.Scale(element, 100, Object.extend({ 597 scaleContent: false, 602 return new Effect.Scale(element, 100, Object.extend({ 603 scaleContent: false, 598 604 scaleX: false, 599 605 scaleFrom: 0, … … 601 607 restoreAfterFinish: true, 602 608 afterSetup: function(effect) { 603 effect.element.makeClipping().setStyle({height: '0px'}).show(); 604 }, 609 effect.element.makeClipping().setStyle({height: '0px'}).show(); 610 }, 605 611 afterFinishInternal: function(effect) { 606 612 effect.element.undoClipping(); … … 617 623 transition: Effect.Transitions.flicker, 618 624 afterFinishInternal: function(effect) { 619 new Effect.Scale(effect.element, 1, { 625 new Effect.Scale(effect.element, 1, { 620 626 duration: 0.3, scaleFromCenter: true, 621 627 scaleX: false, scaleContent: false, restoreAfterFinish: true, 622 beforeSetup: function(effect) { 628 beforeSetup: function(effect) { 623 629 effect.element.makePositioned().makeClipping(); 624 630 }, … … 626 632 effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); 627 633 } 628 }) 634 }); 629 635 } 630 636 }, arguments[1] || { })); … … 638 644 opacity: element.getInlineOpacity() }; 639 645 return new Effect.Parallel( 640 [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 646 [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 641 647 new Effect.Opacity(element, { sync: true, to: 0.0 }) ], 642 648 Object.extend( 643 649 { duration: 0.5, 644 650 beforeSetup: function(effect) { 645 effect.effects[0].element.makePositioned(); 651 effect.effects[0].element.makePositioned(); 646 652 }, 647 653 afterFinishInternal: function(effect) { 648 654 effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); 649 } 655 } 650 656 }, arguments[1] || { })); 651 657 }; … … 675 681 { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { 676 682 effect.element.undoPositioned().setStyle(oldStyle); 677 }}) }}) }}) }}) }})}});683 }}); }}); }}); }}); }}); }}); 678 684 }; 679 685 … … 683 689 var oldInnerBottom = element.down().getStyle('bottom'); 684 690 var elementDimensions = element.getDimensions(); 685 return new Effect.Scale(element, 100, Object.extend({ 686 scaleContent: false, 687 scaleX: false, 691 return new Effect.Scale(element, 100, Object.extend({ 692 scaleContent: false, 693 scaleX: false, 688 694 scaleFrom: window.opera ? 0 : 1, 689 695 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, … … 693 699 effect.element.down().makePositioned(); 694 700 if (window.opera) effect.element.setStyle({top: ''}); 695 effect.element.makeClipping().setStyle({height: '0px'}).show(); 701 effect.element.makeClipping().setStyle({height: '0px'}).show(); 696 702 }, 697 703 afterUpdateInternal: function(effect) { 698 704 effect.element.down().setStyle({bottom: 699 (effect.dims[0] - effect.element.clientHeight) + 'px' }); 705 (effect.dims[0] - effect.element.clientHeight) + 'px' }); 700 706 }, 701 707 afterFinishInternal: function(effect) { … … 711 717 var elementDimensions = element.getDimensions(); 712 718 return new Effect.Scale(element, window.opera ? 0 : 1, 713 Object.extend({ scaleContent: false, 714 scaleX: false, 719 Object.extend({ scaleContent: false, 720 scaleX: false, 715 721 scaleMode: 'box', 716 722 scaleFrom: 100, … … 722 728 if (window.opera) effect.element.setStyle({top: ''}); 723 729 effect.element.makeClipping().show(); 724 }, 730 }, 725 731 afterUpdateInternal: function(effect) { 726 732 effect.element.down().setStyle({bottom: … … 735 741 }; 736 742 737 // Bug in opera makes the TD containing this element expand for a instance after finish 743 // Bug in opera makes the TD containing this element expand for a instance after finish 738 744 Effect.Squish = function(element) { 739 return new Effect.Scale(element, window.opera ? 1 : 0, { 745 return new Effect.Scale(element, window.opera ? 1 : 0, { 740 746 restoreAfterFinish: true, 741 747 beforeSetup: function(effect) { 742 effect.element.makeClipping(); 743 }, 748 effect.element.makeClipping(); 749 }, 744 750 afterFinishInternal: function(effect) { 745 effect.element.hide().undoClipping(); 751 effect.element.hide().undoClipping(); 746 752 } 747 753 }); … … 763 769 opacity: element.getInlineOpacity() }; 764 770 765 var dims = element.getDimensions(); 771 var dims = element.getDimensions(); 766 772 var initialMoveX, initialMoveY; 767 773 var moveX, moveY; 768 774 769 775 switch (options.direction) { 770 776 case 'top-left': 771 initialMoveX = initialMoveY = moveX = moveY = 0; 777 initialMoveX = initialMoveY = moveX = moveY = 0; 772 778 break; 773 779 case 'top-right': … … 794 800 break; 795 801 } 796 802 797 803 return new Effect.Move(element, { 798 804 x: initialMoveX, 799 805 y: initialMoveY, 800 duration: 0.01, 806 duration: 0.01, 801 807 beforeSetup: function(effect) { 802 808 effect.element.hide().makeClipping().makePositioned(); … … 807 813 new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), 808 814 new Effect.Scale(effect.element, 100, { 809 scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 815 scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 810 816 sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) 811 817 ], Object.extend({ 812 818 beforeSetup: function(effect) { 813 effect.effects[0].element.setStyle({height: '0px'}).show(); 819 effect.effects[0].element.setStyle({height: '0px'}).show(); 814 820 }, 815 821 afterFinishInternal: function(effect) { 816 effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 822 effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 817 823 } 818 824 }, options) 819 ) 825 ); 820 826 } 821 827 }); … … 839 845 var dims = element.getDimensions(); 840 846 var moveX, moveY; 841 847 842 848 switch (options.direction) { 843 849 case 'top-left': … … 856 862 moveY = dims.height; 857 863 break; 858 case 'center': 864 case 'center': 859 865 moveX = dims.width / 2; 860 866 moveY = dims.height / 2; 861 867 break; 862 868 } 863 869 864 870 return new Effect.Parallel( 865 871 [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), 866 872 new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), 867 873 new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) 868 ], Object.extend({ 874 ], Object.extend({ 869 875 beforeStartInternal: function(effect) { 870 effect.effects[0].element.makePositioned().makeClipping(); 876 effect.effects[0].element.makePositioned().makeClipping(); 871 877 }, 872 878 afterFinishInternal: function(effect) { … … 878 884 Effect.Pulsate = function(element) { 879 885 element = $(element); 880 var options = arguments[1] || { }; 881 var oldOpacity = element.getInlineOpacity(); 882 var transition = options.transition || Effect.Transitions.sinoidal; 883 var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; 884 reverser.bind(transition); 885 return new Effect.Opacity(element, 886 var options = arguments[1] || { }, 887 oldOpacity = element.getInlineOpacity(), 888 transition = options.transition || Effect.Transitions.linear, 889 reverser = function(pos){ 890 return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5); 891 }; 892 893 return new Effect.Opacity(element, 886 894 Object.extend(Object.extend({ duration: 2.0, from: 0, 887 895 afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } … … 897 905 height: element.style.height }; 898 906 element.makeClipping(); 899 return new Effect.Scale(element, 5, Object.extend({ 907 return new Effect.Scale(element, 5, Object.extend({ 900 908 scaleContent: false, 901 909 scaleX: false, 902 910 afterFinishInternal: function(effect) { 903 new Effect.Scale(element, 1, { 904 scaleContent: false, 911 new Effect.Scale(element, 1, { 912 scaleContent: false, 905 913 scaleY: false, 906 914 afterFinishInternal: function(effect) { … … 917 925 style: { } 918 926 }, arguments[1] || { }); 919 927 920 928 if (!Object.isString(options.style)) this.style = $H(options.style); 921 929 else { … … 935 943 effect.element.style[transform.style] = ''; 936 944 }); 937 } 945 }; 938 946 } 939 947 } 940 948 this.start(options); 941 949 }, 942 950 943 951 setup: function(){ 944 952 function parseColor(color){ … … 946 954 color = color.parseColor(); 947 955 return $R(0,2).map(function(i){ 948 return parseInt( color.slice(i*2+1,i*2+3), 16 ) 956 return parseInt( color.slice(i*2+1,i*2+3), 16 ); 949 957 }); 950 958 } … … 966 974 967 975 var originalValue = this.element.getStyle(property); 968 return { 969 style: property.camelize(), 970 originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 976 return { 977 style: property.camelize(), 978 originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 971 979 targetValue: unit=='color' ? parseColor(value) : value, 972 980 unit: unit … … 979 987 (isNaN(transform.originalValue) || isNaN(transform.targetValue)) 980 988 ) 981 ) 989 ); 982 990 }); 983 991 }, … … 985 993 var style = { }, transform, i = this.transforms.length; 986 994 while(i--) 987 style[(transform = this.transforms[i]).style] = 995 style[(transform = this.transforms[i]).style] = 988 996 transform.unit=='color' ? '#'+ 989 997 (Math.round(transform.originalValue[0]+ … … 994 1002 (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : 995 1003 (transform.originalValue + 996 (transform.targetValue - transform.originalValue) * position).toFixed(3) + 1004 (transform.targetValue - transform.originalValue) * position).toFixed(3) + 997 1005 (transform.unit === null ? '' : transform.unit); 998 1006 this.element.setStyle(style, true); … … 1031 1039 1032 1040 Element.CSS_PROPERTIES = $w( 1033 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 1041 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 1034 1042 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + 1035 1043 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + … … 1040 1048 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + 1041 1049 'right textIndent top width wordSpacing zIndex'); 1042 1050 1043 1051 Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; 1044 1052 … … 1052 1060 style = String.__parseStyleElement.childNodes[0].style; 1053 1061 } 1054 1062 1055 1063 Element.CSS_PROPERTIES.each(function(property){ 1056 if (style[property]) styleRules.set(property, style[property]); 1064 if (style[property]) styleRules.set(property, style[property]); 1057 1065 }); 1058 1066 1059 1067 if (Prototype.Browser.IE && this.include('opacity')) 1060 1068 styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); … … 1075 1083 element = $(element); 1076 1084 var css = element.currentStyle, styles; 1077 styles = Element.CSS_PROPERTIES.inject({ }, function( hash, property) {1078 hash.set(property, css[property]);1079 return hash;1085 styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) { 1086 results[property] = css[property]; 1087 return results; 1080 1088 }); 1081 if (!styles.opacity) styles. set('opacity', element.getOpacity());1089 if (!styles.opacity) styles.opacity = element.getOpacity(); 1082 1090 return styles; 1083 1091 }; 1084 } ;1092 } 1085 1093 1086 1094 Effect.Methods = { … … 1091 1099 }, 1092 1100 visualEffect: function(element, effect, options) { 1093 element = $(element) 1101 element = $(element); 1094 1102 var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); 1095 1103 new Effect[klass](element, options); … … 1105 1113 $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ 1106 1114 'pulsate shake puff squish switchOff dropOut').each( 1107 function(effect) { 1115 function(effect) { 1108 1116 Effect.Methods[effect] = function(element, options){ 1109 1117 element = $(element); 1110 1118 Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); 1111 1119 return element; 1112 } 1120 }; 1113 1121 } 1114 1122 ); 1115 1123 1116 $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 1124 $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 1117 1125 function(f) { Effect.Methods[f] = Element[f]; } 1118 1126 );
Note:
See TracChangeset
for help on using the changeset viewer.