Changeset 6236
- Timestamp:
- 02/25/07 23:40:43 (3 years ago)
- Files:
-
- spinoffs/scriptaculous/CHANGELOG (modified) (1 diff)
- spinoffs/scriptaculous/lib/prototype.js (modified) (2 diffs)
- spinoffs/scriptaculous/src/effects.js (modified) (11 diffs)
- spinoffs/scriptaculous/test/unit/effects_test.html (modified) (5 diffs)
- spinoffs/scriptaculous/test/unit/element_test.html (modified) (1 diff)
- spinoffs/scriptaculous/test/unit/transform_test.html (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
spinoffs/scriptaculous/CHANGELOG
r6191 r6236 1 1 *SVN* 2 3 * Various effects engine optimizations [Tobie Langel, Thomas Fuchs] 2 4 3 5 * Update to new Prototype Browser detection spinoffs/scriptaculous/lib/prototype.js
r6191 r6236 1433 1433 setStyle: function(element, style) { 1434 1434 element = $(element); 1435 var elementStyle = element.style; 1435 1436 for (var name in style) { 1436 1437 var value = style[name]; 1437 if(name == 'opacity') { 1438 if (value == 1) { 1439 value = (/Gecko/.test(navigator.userAgent) && 1440 !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0; 1441 if(/MSIE/.test(navigator.userAgent) && !window.opera) 1442 element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,''); 1443 } else if(value === '') { 1444 if(/MSIE/.test(navigator.userAgent) && !window.opera) 1445 element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,''); 1446 } else { 1447 if(value < 0.00001) value = 0; 1448 if(/MSIE/.test(navigator.userAgent) && !window.opera) 1449 element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') + 1450 'alpha(opacity='+value*100+')'; 1451 } 1452 } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat'; 1453 element.style[name.camelize()] = value; 1454 } 1438 if (name == 'opacity') element.setOpacity(value); 1439 if (name == 'float' || name == 'cssFloat') { 1440 name = (typeof elementStyle.styleFloat != 'undefined') ? 1441 'styleFloat' : 'cssFloat'; 1442 } 1443 elementStyle[name.camelize()] = value; 1444 } 1445 return element; 1446 }, 1447 1448 setOpacity: function(element, value) { 1449 element = $(element); 1450 element.style.opacity = (value < 0.00001) ? 0 : value; 1455 1451 return element; 1456 1452 }, … … 1527 1523 1528 1524 Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf}); 1525 1526 if (Prototype.Browser.IE) { 1527 Element.Methods.setOpacity = function(element, value) { 1528 element = $(element); 1529 var filter = element.getStyle('filter'), style = element.style; 1530 if (value == 1 || value === '') { 1531 style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); 1532 return element; 1533 } else if (value < 0.00001) value = 0; 1534 style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + 1535 'alpha(opacity=' + (value * 100) + ')'; 1536 return element; 1537 }; 1538 } 1539 1540 if (Prototype.Browser.Gecko) { 1541 Element.Methods.setOpacity = function(element, value) { 1542 element = $(element); 1543 var style = element.style; 1544 if (value == 1) value = 0.999999; 1545 else if (value < 0.00001) value = 0; 1546 style.opacity = value; 1547 return element; 1548 }; 1549 } 1529 1550 1530 1551 Element._attributeTranslations = {}; spinoffs/scriptaculous/src/effects.js
r6191 r6236 49 49 50 50 Element.getOpacity = function(element){ 51 return $(element).getStyle('opacity'); 52 } 53 54 Element.setOpacity = function(element, value){ 55 return $(element).setStyle({opacity:value}); 51 return Element.getStyle(element,'opacity'); 56 52 } 57 53 … … 151 147 }, 152 148 flicker: function(pos) { 153 return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; 149 var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; 150 return (pos > 1 ? 1 : pos); 154 151 }, 155 152 wobble: function(pos) { … … 257 254 position: null, 258 255 start: function(options) { 256 function codeForEvent(options,eventName){ 257 return ( 258 (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') + 259 (options[eventName] ? 'this.options.'+eventName+'(this);' : '') 260 ); 261 } 262 if(options.transition === false) options.transition = Effect.Transitions.linear; 259 263 this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); 260 264 this.currentFrame = 0; 261 265 this.state = 'idle'; 262 266 this.startOn = this.options.delay*1000; 263 this.finishOn = this.startOn + (this.options.duration*1000); 267 this.finishOn = this.startOn+(this.options.duration*1000); 268 this.fromToDelta = this.options.to-this.options.from; 269 this.totalTime = this.finishOn-this.startOn; 270 this.totalFrames = this.options.fps*this.options.duration; 271 272 eval('this.render = function(pos){ '+ 273 'if(this.state=="idle"){this.state="running";'+ 274 codeForEvent(options,'beforeSetup')+ 275 (this.setup ? 'this.setup();':'')+ 276 codeForEvent(options,'afterSetup')+ 277 '};if(this.state=="running"){'+ 278 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+ 279 'this.position=pos;'+ 280 codeForEvent(options,'beforeUpdate')+ 281 (this.update ? 'this.update(pos);':'')+ 282 codeForEvent(options,'afterUpdate')+ 283 '}}'); 284 264 285 this.event('beforeStart'); 265 286 if(!this.options.sync) … … 277 298 return; 278 299 } 279 var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);280 var frame = Math.round(pos * this.options.fps * this.options.duration);300 var pos = (timePos - this.startOn) / this.totalTime, 301 frame = Math.round(pos * this.totalFrames); 281 302 if(frame > this.currentFrame) { 282 303 this.render(pos); 283 304 this.currentFrame = frame; 284 305 } 285 }286 },287 render: function(pos) {288 if(this.state == 'idle') {289 this.state = 'running';290 this.event('beforeSetup');291 if(this.setup) this.setup();292 this.event('afterSetup');293 }294 if(this.state == 'running') {295 if(this.options.transition) pos = this.options.transition(pos);296 pos *= (this.options.to-this.options.from);297 pos += this.options.from;298 this.position = pos;299 this.event('beforeUpdate');300 if(this.update) this.update(pos);301 this.event('afterUpdate');302 306 } 303 307 }, … … 952 956 effect.transforms.each(function(transform) { 953 957 if(transform.style != 'opacity') 954 effect.element.style[transform.style .camelize()] = '';958 effect.element.style[transform.style] = ''; 955 959 }); 956 960 } … … 968 972 } 969 973 this.transforms = this.style.map(function(pair){ 970 var property = pair[0] .underscore().dasherize(), value = pair[1], unit = null;974 var property = pair[0], value = pair[1], unit = null; 971 975 972 976 if(value.parseColor('#zzzzzz') != '#zzzzzz') { … … 984 988 985 989 var originalValue = this.element.getStyle(property); 986 return $H({990 return { 987 991 style: property, 988 992 originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 989 993 targetValue: unit=='color' ? parseColor(value) : value, 990 994 unit: unit 991 } );995 }; 992 996 }.bind(this)).reject(function(transform){ 993 997 return ( … … 1001 1005 }, 1002 1006 update: function(position) { 1003 var style = $H(), value = null;1007 var style = {}, value = null; 1004 1008 this.transforms.each(function(transform){ 1005 1009 value = transform.unit=='color' ? … … 1058 1062 1059 1063 String.prototype.parseStyle = function(){ 1060 var element = Element.extend(document.createElement('div'));1064 var element = document.createElement('div'); 1061 1065 element.innerHTML = '<div style="' + this + '"></div>'; 1062 var style = element. down().style, styleRules = $H();1066 var style = element.childNodes[0].style, styleRules = $H(); 1063 1067 1064 1068 Element.CSS_PROPERTIES.each(function(property){ … … 1076 1080 }; 1077 1081 1078 [' setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',1082 ['getOpacity', 'getInlineOpacity','forceRerendering','setContentZoom', 1079 1083 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( 1080 1084 function(f) { Element.Methods[f] = Element[f]; } … … 1082 1086 1083 1087 Element.Methods.visualEffect = function(element, effect, options) { 1084 s = effect. gsub(/_/, '-').camelize();1088 s = effect.dasherize().camelize(); 1085 1089 effect_class = s.charAt(0).toUpperCase() + s.substring(1); 1086 1090 new Effect[effect_class](element, options); spinoffs/scriptaculous/test/unit/effects_test.html
r5742 r6236 32 32 ['Fade','Appear','BlindUp','BlindDown','Puff','SwitchOff','DropOut','Shake', 33 33 'SlideUp','SlideDown','Pulsate','Squish','Fold','Grow','Shrink']; 34 35 var COMBINED_RJS_EFFECTS = $w(''+ 36 'fade appear blind_up blind_down puff switch_off drop_out shake '+ 37 'slide_up slide_down pulsate squish fold grow shrink' 38 ); 34 39 35 40 var tmp, tmp2; … … 91 96 }}, 92 97 98 testTransition: function() { with(this) { 99 // false implies linear 100 var e = new Effect.Opacity('sandbox',{transition:false,from:0.0,to:0.25,duration:0.5}); 101 assert(e.options.transition == Effect.Transitions.linear); 102 103 wait(1000, function() { 104 assertEqual(0.25, $('sandbox').getStyle('opacity')); 105 // default to sinoidal 106 var e = new Effect.Opacity('sandbox',{from:0.0,to:0.25,duration:0.5}); 107 assert(e.options.transition == Effect.Transitions.sinoidal); 108 wait(1000, function() { 109 assertEqual(0.25, $('sandbox').getStyle('opacity')); 110 111 var transitions = [ 112 { transition: Effect.Transitions.linear, expected: 1 }, 113 { transition: Effect.Transitions.sinoidal, expected: 1 }, 114 { transition: Effect.Transitions.reverse, expected: 0 }, 115 { transition: Effect.Transitions.flicker, expected: 1 }, 116 { transition: Effect.Transitions.wobble, expected: 1 }, 117 { transition: Effect.Transitions.pulse, expected: 1 }, 118 { transition: Effect.Transitions.none, expected: 0 } 119 ]; 120 121 transitions.each(function(t){ 122 var e = new Effect.Opacity('sandbox',{sync:true, from:0, to: 1, transition:t.transition}); 123 assert(e.options.transition == t.transition); 124 e.render(1.0); 125 assertEqual(t.expected, e.position, t.transition); 126 }); 127 128 }); 129 }); 130 }}, 131 93 132 testInspect: function() { with(this) { 94 133 var e1 = new Effect.Opacity('sandbox',{from:1.0,to:0.5,duration:0.5}); … … 231 270 // test if all combined effects correctly initialize themselves 232 271 testCombinedEffectsInitialize: function() { with(this) { 233 COMBINED_EFFECTS.each(function(fx ){272 COMBINED_EFFECTS.each(function(fx,idx){ 234 273 info('Effect.'+fx); 235 274 $('sandbox').innerHTML = ""; … … 246 285 assertEqual(0, effect.currentFrame); 247 286 287 // and, for visualEffect 288 assert($('test_element') == $('test_element').visualEffect(COMBINED_RJS_EFFECTS[idx])); 289 248 290 // options parsing (shake, squish and grow are special here) 249 291 if(!['Shake','Squish','Grow'].include(fx)) { … … 284 326 assertEqual('finished', testeffect.state); 285 327 }); 328 }}, 329 330 testRenderPerformance: function() { with(this) { 331 info('The render() method is generated on a per-effect basis') 332 var e = new Effect.Opacity('sandbox',{sync:true}); 333 benchmark(function(){ 334 e.render(0.5); 335 },1000, 'Without events'); 336 var e = new Effect.Opacity('sandbox',{sync:true,afterUpdate:function(){return}}); 337 benchmark(function(){ 338 e.render(0.5); 339 },1000, 'With afterUpdate event'); 286 340 }} 287 341 spinoffs/scriptaculous/test/unit/element_test.html
r6192 r6236 104 104 assertEqual(0.3, Element.getOpacity('op4-ie')); 105 105 } 106 }}, 107 108 testVisualEffect: function() { with(this) { 109 assert($('style_test_3') == $('style_test_3').visualEffect('fade')); 110 wait(1500,function(){ 111 assert(!$('style_test_3').visible()) 112 }); 113 }}, 114 115 testParseStylePerformance: function() { with(this) { 116 benchmark(function(){ 117 "font:12px/15pt Verdana;opacity:0.4;border:4px dotted red".parseStyle(); 118 },100); 106 119 }} 107 120 spinoffs/scriptaculous/test/unit/transform_test.html
r5733 r6236 70 70 }); 71 71 $('error_message_3').morph('final', {duration:0.5}); 72 wait( 600,function(){72 wait(1000,function(){ 73 73 assertEqual('17px', $('error_test_ul').getStyle('margin-right')); 74 74 assertEqual('40px', $('error_test_ul').getStyle('font-size')); … … 79 79 assertEqual(.5, $('error_message_3').getStyle('opacity')); 80 80 assertEqual('', $('error_message_3').style.fontSize); 81 // chaining morphs 82 $('error_message').morph('font-size:17px').morph('opacity:0',{delay:3}); 83 wait(4100,function(){ // 3000ms delay + 1000ms default duration 84 assertEqual(0, $('error_message').getOpacity()); 85 }); 81 }); 82 }}, 83 84 testElementMorphChaining: function() { with(this) { 85 $('error_message').morph('font-size:17px').morph('opacity:0',{delay:3}); 86 wait(4100,function(){ // 3000ms delay + 1000ms default duration 87 assertEqual(0, $('error_message').getOpacity()); 86 88 }); 87 89 }}, … … 137 139 assertEnumEqual([255,255,255], 138 140 generatedEffect.effects[2].transforms.detect( function(transform){ 139 return (transform.style == 'background -color')141 return (transform.style == 'backgroundColor') 140 142 }).originalValue); 141 143 assertEnumEqual([153,85,68], 142 144 generatedEffect.effects[2].transforms.detect( function(transform){ 143 return (transform.style == 'background -color')145 return (transform.style == 'backgroundColor') 144 146 }).targetValue); 145 147