tagz 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/README +240 -0
  2. data/README.tmpl +240 -0
  3. data/install.rb +4 -0
  4. data/lib/tagz.rb +146 -351
  5. data/test/tagz.rb +226 -191
  6. metadata +3 -106
  7. data/lib/tagz/rails.rb +0 -198
  8. data/rails/README +0 -182
  9. data/rails/Rakefile +0 -10
  10. data/rails/app/controllers/application.rb +0 -7
  11. data/rails/app/controllers/tagz_controller.rb +0 -51
  12. data/rails/app/helpers/application_helper.rb +0 -3
  13. data/rails/app/helpers/tagz_helper.rb +0 -2
  14. data/rails/app/views/layouts/layout.rb +0 -16
  15. data/rails/app/views/tagz/b.rb +0 -19
  16. data/rails/app/views/tagz/c.rb +0 -9
  17. data/rails/app/views/tagz/d.rhtml +0 -17
  18. data/rails/app/views/tagz/e.rb +0 -3
  19. data/rails/config/boot.rb +0 -45
  20. data/rails/config/database.yml +0 -36
  21. data/rails/config/environment.rb +0 -65
  22. data/rails/config/environments/development.rb +0 -21
  23. data/rails/config/environments/production.rb +0 -18
  24. data/rails/config/environments/test.rb +0 -19
  25. data/rails/config/lighttpd.conf +0 -54
  26. data/rails/config/routes.rb +0 -23
  27. data/rails/doc/README_FOR_APP +0 -2
  28. data/rails/log/development.log +0 -6713
  29. data/rails/log/fastcgi.crash.log +0 -103
  30. data/rails/log/lighttpd.access.log +0 -171
  31. data/rails/log/lighttpd.error.log +0 -116
  32. data/rails/log/production.log +0 -0
  33. data/rails/log/server.log +0 -0
  34. data/rails/log/test.log +0 -0
  35. data/rails/public/404.html +0 -30
  36. data/rails/public/500.html +0 -30
  37. data/rails/public/dispatch.cgi +0 -10
  38. data/rails/public/dispatch.fcgi +0 -24
  39. data/rails/public/dispatch.rb +0 -10
  40. data/rails/public/favicon.ico +0 -0
  41. data/rails/public/images/rails.png +0 -0
  42. data/rails/public/index.html +0 -277
  43. data/rails/public/javascripts/application.js +0 -2
  44. data/rails/public/javascripts/controls.js +0 -833
  45. data/rails/public/javascripts/dragdrop.js +0 -942
  46. data/rails/public/javascripts/effects.js +0 -1088
  47. data/rails/public/javascripts/prototype.js +0 -2515
  48. data/rails/public/robots.txt +0 -1
  49. data/rails/script/about +0 -3
  50. data/rails/script/breakpointer +0 -3
  51. data/rails/script/console +0 -3
  52. data/rails/script/destroy +0 -3
  53. data/rails/script/generate +0 -3
  54. data/rails/script/performance/benchmarker +0 -3
  55. data/rails/script/performance/profiler +0 -3
  56. data/rails/script/plugin +0 -3
  57. data/rails/script/process/inspector +0 -3
  58. data/rails/script/process/reaper +0 -3
  59. data/rails/script/process/spawner +0 -3
  60. data/rails/script/runner +0 -3
  61. data/rails/script/server +0 -4
  62. data/rails/test/functional/tagz_controller_test.rb +0 -18
  63. data/rails/test/test_helper.rb +0 -28
  64. data/rails/tmp/cache/index.html-gzip-1958902-7552-1181801882 +0 -0
  65. data/rails/tmp/cache/javascripts/effects.js-gzip-1958907-38200-1181801882 +0 -0
  66. data/rails/tmp/cache/javascripts/prototype.js-gzip-1958906-71260-1181801882 +0 -0
  67. data/rails/tmp/sessions/ruby_sess.365e696810aa7418 +0 -0
  68. data/rails/tmp/sessions/ruby_sess.3ab0cb2f589d3855 +0 -0
  69. data/rails/tmp/sessions/ruby_sess.c812e68d96a6e99f +0 -0
  70. data/rails/tmp/sessions/ruby_sess.e0a954440a7e27d7 +0 -0
@@ -1,1088 +0,0 @@
1
- // Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
- // Contributors:
3
- // Justin Palmer (http://encytemedia.com/)
4
- // Mark Pilgrim (http://diveintomark.org/)
5
- // Martin Bialasinki
6
- //
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() {
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));
24
- }
25
-
26
- /*--------------------------------------------------------------------------*/
27
-
28
- Element.collectTextNodes = function(element) {
29
- return $A($(element).childNodes).collect( function(node) {
30
- return (node.nodeType==3 ? node.nodeValue :
31
- (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
32
- }).flatten().join('');
33
- }
34
-
35
- Element.collectTextNodesIgnoreClass = function(element, className) {
36
- return $A($(element).childNodes).collect( function(node) {
37
- return (node.nodeType==3 ? node.nodeValue :
38
- ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
39
- Element.collectTextNodesIgnoreClass(node, className) : ''));
40
- }).flatten().join('');
41
- }
42
-
43
- Element.setContentZoom = function(element, percent) {
44
- element = $(element);
45
- element.setStyle({fontSize: (percent/100) + 'em'});
46
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
47
- return element;
48
- }
49
-
50
- Element.getOpacity = function(element){
51
- element = $(element);
52
- var opacity;
53
- if (opacity = element.getStyle('opacity'))
54
- return parseFloat(opacity);
55
- if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
56
- if(opacity[1]) return parseFloat(opacity[1]) / 100;
57
- return 1.0;
58
- }
59
-
60
- Element.setOpacity = function(element, value){
61
- element= $(element);
62
- if (value == 1){
63
- element.setStyle({ opacity:
64
- (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
65
- 0.999999 : 1.0 });
66
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
67
- element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
68
- } else {
69
- if(value < 0.00001) value = 0;
70
- element.setStyle({opacity: value});
71
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
72
- element.setStyle(
73
- { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
74
- 'alpha(opacity='+value*100+')' });
75
- }
76
- return element;
77
- }
78
-
79
- Element.getInlineOpacity = function(element){
80
- return $(element).style.opacity || '';
81
- }
82
-
83
- Element.forceRerendering = function(element) {
84
- try {
85
- element = $(element);
86
- var n = document.createTextNode(' ');
87
- element.appendChild(n);
88
- element.removeChild(n);
89
- } catch(e) { }
90
- };
91
-
92
- /*--------------------------------------------------------------------------*/
93
-
94
- Array.prototype.call = function() {
95
- var args = arguments;
96
- this.each(function(f){ f.apply(this, args) });
97
- }
98
-
99
- /*--------------------------------------------------------------------------*/
100
-
101
- var Effect = {
102
- _elementDoesNotExistError: {
103
- name: 'ElementDoesNotExistError',
104
- message: 'The specified DOM element does not exist, but is required for this effect to operate'
105
- },
106
- tagifyText: function(element) {
107
- if(typeof Builder == 'undefined')
108
- throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
109
-
110
- var tagifyStyle = 'position:relative';
111
- if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
112
-
113
- element = $(element);
114
- $A(element.childNodes).each( function(child) {
115
- if(child.nodeType==3) {
116
- child.nodeValue.toArray().each( function(character) {
117
- element.insertBefore(
118
- Builder.node('span',{style: tagifyStyle},
119
- character == ' ' ? String.fromCharCode(160) : character),
120
- child);
121
- });
122
- Element.remove(child);
123
- }
124
- });
125
- },
126
- multiple: function(element, effect) {
127
- var elements;
128
- if(((typeof element == 'object') ||
129
- (typeof element == 'function')) &&
130
- (element.length))
131
- elements = element;
132
- else
133
- elements = $(element).childNodes;
134
-
135
- var options = Object.extend({
136
- speed: 0.1,
137
- delay: 0.0
138
- }, arguments[2] || {});
139
- var masterDelay = options.delay;
140
-
141
- $A(elements).each( function(element, index) {
142
- new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
143
- });
144
- },
145
- PAIRS: {
146
- 'slide': ['SlideDown','SlideUp'],
147
- 'blind': ['BlindDown','BlindUp'],
148
- 'appear': ['Appear','Fade']
149
- },
150
- toggle: function(element, effect) {
151
- element = $(element);
152
- effect = (effect || 'appear').toLowerCase();
153
- var options = Object.extend({
154
- queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
155
- }, arguments[2] || {});
156
- Effect[element.visible() ?
157
- Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
158
- }
159
- };
160
-
161
- var Effect2 = Effect; // deprecated
162
-
163
- /* ------------- transitions ------------- */
164
-
165
- Effect.Transitions = {
166
- linear: Prototype.K,
167
- sinoidal: function(pos) {
168
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
169
- },
170
- reverse: function(pos) {
171
- return 1-pos;
172
- },
173
- flicker: function(pos) {
174
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
175
- },
176
- wobble: function(pos) {
177
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
178
- },
179
- pulse: function(pos, pulses) {
180
- pulses = pulses || 5;
181
- return (
182
- Math.round((pos % (1/pulses)) * pulses) == 0 ?
183
- ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
184
- 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
185
- );
186
- },
187
- none: function(pos) {
188
- return 0;
189
- },
190
- full: function(pos) {
191
- return 1;
192
- }
193
- };
194
-
195
- /* ------------- core effects ------------- */
196
-
197
- Effect.ScopedQueue = Class.create();
198
- Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
199
- initialize: function() {
200
- this.effects = [];
201
- this.interval = null;
202
- },
203
- _each: function(iterator) {
204
- this.effects._each(iterator);
205
- },
206
- add: function(effect) {
207
- var timestamp = new Date().getTime();
208
-
209
- var position = (typeof effect.options.queue == 'string') ?
210
- effect.options.queue : effect.options.queue.position;
211
-
212
- switch(position) {
213
- case 'front':
214
- // move unstarted effects after this effect
215
- this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
216
- e.startOn += effect.finishOn;
217
- e.finishOn += effect.finishOn;
218
- });
219
- break;
220
- case 'with-last':
221
- timestamp = this.effects.pluck('startOn').max() || timestamp;
222
- break;
223
- case 'end':
224
- // start effect after last queued effect has finished
225
- timestamp = this.effects.pluck('finishOn').max() || timestamp;
226
- break;
227
- }
228
-
229
- effect.startOn += timestamp;
230
- effect.finishOn += timestamp;
231
-
232
- if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
233
- this.effects.push(effect);
234
-
235
- if(!this.interval)
236
- this.interval = setInterval(this.loop.bind(this), 40);
237
- },
238
- remove: function(effect) {
239
- this.effects = this.effects.reject(function(e) { return e==effect });
240
- if(this.effects.length == 0) {
241
- clearInterval(this.interval);
242
- this.interval = null;
243
- }
244
- },
245
- loop: function() {
246
- var timePos = new Date().getTime();
247
- this.effects.invoke('loop', timePos);
248
- }
249
- });
250
-
251
- Effect.Queues = {
252
- instances: $H(),
253
- get: function(queueName) {
254
- if(typeof queueName != 'string') return queueName;
255
-
256
- if(!this.instances[queueName])
257
- this.instances[queueName] = new Effect.ScopedQueue();
258
-
259
- return this.instances[queueName];
260
- }
261
- }
262
- Effect.Queue = Effect.Queues.get('global');
263
-
264
- Effect.DefaultOptions = {
265
- transition: Effect.Transitions.sinoidal,
266
- duration: 1.0, // seconds
267
- fps: 25.0, // max. 25fps due to Effect.Queue implementation
268
- sync: false, // true for combining
269
- from: 0.0,
270
- to: 1.0,
271
- delay: 0.0,
272
- queue: 'parallel'
273
- }
274
-
275
- Effect.Base = function() {};
276
- Effect.Base.prototype = {
277
- position: null,
278
- start: function(options) {
279
- this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
280
- this.currentFrame = 0;
281
- this.state = 'idle';
282
- this.startOn = this.options.delay*1000;
283
- this.finishOn = this.startOn + (this.options.duration*1000);
284
- this.event('beforeStart');
285
- if(!this.options.sync)
286
- Effect.Queues.get(typeof this.options.queue == 'string' ?
287
- 'global' : this.options.queue.scope).add(this);
288
- },
289
- loop: function(timePos) {
290
- if(timePos >= this.startOn) {
291
- if(timePos >= this.finishOn) {
292
- this.render(1.0);
293
- this.cancel();
294
- this.event('beforeFinish');
295
- if(this.finish) this.finish();
296
- this.event('afterFinish');
297
- return;
298
- }
299
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
300
- var frame = Math.round(pos * this.options.fps * this.options.duration);
301
- if(frame > this.currentFrame) {
302
- this.render(pos);
303
- this.currentFrame = frame;
304
- }
305
- }
306
- },
307
- render: function(pos) {
308
- if(this.state == 'idle') {
309
- this.state = 'running';
310
- this.event('beforeSetup');
311
- if(this.setup) this.setup();
312
- this.event('afterSetup');
313
- }
314
- if(this.state == 'running') {
315
- if(this.options.transition) pos = this.options.transition(pos);
316
- pos *= (this.options.to-this.options.from);
317
- pos += this.options.from;
318
- this.position = pos;
319
- this.event('beforeUpdate');
320
- if(this.update) this.update(pos);
321
- this.event('afterUpdate');
322
- }
323
- },
324
- cancel: function() {
325
- if(!this.options.sync)
326
- Effect.Queues.get(typeof this.options.queue == 'string' ?
327
- 'global' : this.options.queue.scope).remove(this);
328
- this.state = 'finished';
329
- },
330
- event: function(eventName) {
331
- if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
332
- if(this.options[eventName]) this.options[eventName](this);
333
- },
334
- inspect: function() {
335
- return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
336
- }
337
- }
338
-
339
- Effect.Parallel = Class.create();
340
- Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
341
- initialize: function(effects) {
342
- this.effects = effects || [];
343
- this.start(arguments[1]);
344
- },
345
- update: function(position) {
346
- this.effects.invoke('render', position);
347
- },
348
- finish: function(position) {
349
- this.effects.each( function(effect) {
350
- effect.render(1.0);
351
- effect.cancel();
352
- effect.event('beforeFinish');
353
- if(effect.finish) effect.finish(position);
354
- effect.event('afterFinish');
355
- });
356
- }
357
- });
358
-
359
- Effect.Event = Class.create();
360
- Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
361
- initialize: function() {
362
- var options = Object.extend({
363
- duration: 0
364
- }, arguments[0] || {});
365
- this.start(options);
366
- },
367
- update: Prototype.emptyFunction
368
- });
369
-
370
- Effect.Opacity = Class.create();
371
- Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
372
- initialize: function(element) {
373
- this.element = $(element);
374
- if(!this.element) throw(Effect._elementDoesNotExistError);
375
- // make this work on IE on elements without 'layout'
376
- if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
377
- this.element.setStyle({zoom: 1});
378
- var options = Object.extend({
379
- from: this.element.getOpacity() || 0.0,
380
- to: 1.0
381
- }, arguments[1] || {});
382
- this.start(options);
383
- },
384
- update: function(position) {
385
- this.element.setOpacity(position);
386
- }
387
- });
388
-
389
- Effect.Move = Class.create();
390
- Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
391
- initialize: function(element) {
392
- this.element = $(element);
393
- if(!this.element) throw(Effect._elementDoesNotExistError);
394
- var options = Object.extend({
395
- x: 0,
396
- y: 0,
397
- mode: 'relative'
398
- }, arguments[1] || {});
399
- this.start(options);
400
- },
401
- setup: function() {
402
- // Bug in Opera: Opera returns the "real" position of a static element or
403
- // relative element that does not have top/left explicitly set.
404
- // ==> Always set top and left for position relative elements in your stylesheets
405
- // (to 0 if you do not need them)
406
- this.element.makePositioned();
407
- this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
408
- this.originalTop = parseFloat(this.element.getStyle('top') || '0');
409
- if(this.options.mode == 'absolute') {
410
- // absolute movement, so we need to calc deltaX and deltaY
411
- this.options.x = this.options.x - this.originalLeft;
412
- this.options.y = this.options.y - this.originalTop;
413
- }
414
- },
415
- update: function(position) {
416
- this.element.setStyle({
417
- left: Math.round(this.options.x * position + this.originalLeft) + 'px',
418
- top: Math.round(this.options.y * position + this.originalTop) + 'px'
419
- });
420
- }
421
- });
422
-
423
- // for backwards compatibility
424
- Effect.MoveBy = function(element, toTop, toLeft) {
425
- return new Effect.Move(element,
426
- Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
427
- };
428
-
429
- Effect.Scale = Class.create();
430
- Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
431
- initialize: function(element, percent) {
432
- this.element = $(element);
433
- if(!this.element) throw(Effect._elementDoesNotExistError);
434
- var options = Object.extend({
435
- scaleX: true,
436
- scaleY: true,
437
- scaleContent: true,
438
- scaleFromCenter: false,
439
- scaleMode: 'box', // 'box' or 'contents' or {} with provided values
440
- scaleFrom: 100.0,
441
- scaleTo: percent
442
- }, arguments[2] || {});
443
- this.start(options);
444
- },
445
- setup: function() {
446
- this.restoreAfterFinish = this.options.restoreAfterFinish || false;
447
- this.elementPositioning = this.element.getStyle('position');
448
-
449
- this.originalStyle = {};
450
- ['top','left','width','height','fontSize'].each( function(k) {
451
- this.originalStyle[k] = this.element.style[k];
452
- }.bind(this));
453
-
454
- this.originalTop = this.element.offsetTop;
455
- this.originalLeft = this.element.offsetLeft;
456
-
457
- var fontSize = this.element.getStyle('font-size') || '100%';
458
- ['em','px','%','pt'].each( function(fontSizeType) {
459
- if(fontSize.indexOf(fontSizeType)>0) {
460
- this.fontSize = parseFloat(fontSize);
461
- this.fontSizeType = fontSizeType;
462
- }
463
- }.bind(this));
464
-
465
- this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
466
-
467
- this.dims = null;
468
- if(this.options.scaleMode=='box')
469
- this.dims = [this.element.offsetHeight, this.element.offsetWidth];
470
- if(/^content/.test(this.options.scaleMode))
471
- this.dims = [this.element.scrollHeight, this.element.scrollWidth];
472
- if(!this.dims)
473
- this.dims = [this.options.scaleMode.originalHeight,
474
- this.options.scaleMode.originalWidth];
475
- },
476
- update: function(position) {
477
- var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
478
- if(this.options.scaleContent && this.fontSize)
479
- this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
480
- this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
481
- },
482
- finish: function(position) {
483
- if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
484
- },
485
- setDimensions: function(height, width) {
486
- var d = {};
487
- if(this.options.scaleX) d.width = Math.round(width) + 'px';
488
- if(this.options.scaleY) d.height = Math.round(height) + 'px';
489
- if(this.options.scaleFromCenter) {
490
- var topd = (height - this.dims[0])/2;
491
- var leftd = (width - this.dims[1])/2;
492
- if(this.elementPositioning == 'absolute') {
493
- if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
494
- if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
495
- } else {
496
- if(this.options.scaleY) d.top = -topd + 'px';
497
- if(this.options.scaleX) d.left = -leftd + 'px';
498
- }
499
- }
500
- this.element.setStyle(d);
501
- }
502
- });
503
-
504
- Effect.Highlight = Class.create();
505
- Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
506
- initialize: function(element) {
507
- this.element = $(element);
508
- if(!this.element) throw(Effect._elementDoesNotExistError);
509
- var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
510
- this.start(options);
511
- },
512
- setup: function() {
513
- // Prevent executing on elements not in the layout flow
514
- if(this.element.getStyle('display')=='none') { this.cancel(); return; }
515
- // Disable background image during the effect
516
- this.oldStyle = {
517
- backgroundImage: this.element.getStyle('background-image') };
518
- this.element.setStyle({backgroundImage: 'none'});
519
- if(!this.options.endcolor)
520
- this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
521
- if(!this.options.restorecolor)
522
- this.options.restorecolor = this.element.getStyle('background-color');
523
- // init color calculations
524
- this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
525
- 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));
526
- },
527
- update: function(position) {
528
- this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
529
- return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
530
- },
531
- finish: function() {
532
- this.element.setStyle(Object.extend(this.oldStyle, {
533
- backgroundColor: this.options.restorecolor
534
- }));
535
- }
536
- });
537
-
538
- Effect.ScrollTo = Class.create();
539
- Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
540
- initialize: function(element) {
541
- this.element = $(element);
542
- this.start(arguments[1] || {});
543
- },
544
- setup: function() {
545
- Position.prepare();
546
- var offsets = Position.cumulativeOffset(this.element);
547
- if(this.options.offset) offsets[1] += this.options.offset;
548
- var max = window.innerHeight ?
549
- window.height - window.innerHeight :
550
- document.body.scrollHeight -
551
- (document.documentElement.clientHeight ?
552
- document.documentElement.clientHeight : document.body.clientHeight);
553
- this.scrollStart = Position.deltaY;
554
- this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
555
- },
556
- update: function(position) {
557
- Position.prepare();
558
- window.scrollTo(Position.deltaX,
559
- this.scrollStart + (position*this.delta));
560
- }
561
- });
562
-
563
- /* ------------- combination effects ------------- */
564
-
565
- Effect.Fade = function(element) {
566
- element = $(element);
567
- var oldOpacity = element.getInlineOpacity();
568
- var options = Object.extend({
569
- from: element.getOpacity() || 1.0,
570
- to: 0.0,
571
- afterFinishInternal: function(effect) {
572
- if(effect.options.to!=0) return;
573
- effect.element.hide().setStyle({opacity: oldOpacity});
574
- }}, arguments[1] || {});
575
- return new Effect.Opacity(element,options);
576
- }
577
-
578
- Effect.Appear = function(element) {
579
- element = $(element);
580
- var options = Object.extend({
581
- from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
582
- to: 1.0,
583
- // force Safari to render floated elements properly
584
- afterFinishInternal: function(effect) {
585
- effect.element.forceRerendering();
586
- },
587
- beforeSetup: function(effect) {
588
- effect.element.setOpacity(effect.options.from).show();
589
- }}, arguments[1] || {});
590
- return new Effect.Opacity(element,options);
591
- }
592
-
593
- Effect.Puff = function(element) {
594
- element = $(element);
595
- var oldStyle = {
596
- opacity: element.getInlineOpacity(),
597
- position: element.getStyle('position'),
598
- top: element.style.top,
599
- left: element.style.left,
600
- width: element.style.width,
601
- height: element.style.height
602
- };
603
- return new Effect.Parallel(
604
- [ new Effect.Scale(element, 200,
605
- { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
606
- new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
607
- Object.extend({ duration: 1.0,
608
- beforeSetupInternal: function(effect) {
609
- Position.absolutize(effect.effects[0].element)
610
- },
611
- afterFinishInternal: function(effect) {
612
- effect.effects[0].element.hide().setStyle(oldStyle); }
613
- }, arguments[1] || {})
614
- );
615
- }
616
-
617
- Effect.BlindUp = function(element) {
618
- element = $(element);
619
- element.makeClipping();
620
- return new Effect.Scale(element, 0,
621
- Object.extend({ scaleContent: false,
622
- scaleX: false,
623
- restoreAfterFinish: true,
624
- afterFinishInternal: function(effect) {
625
- effect.element.hide().undoClipping();
626
- }
627
- }, arguments[1] || {})
628
- );
629
- }
630
-
631
- Effect.BlindDown = function(element) {
632
- element = $(element);
633
- var elementDimensions = element.getDimensions();
634
- return new Effect.Scale(element, 100, Object.extend({
635
- scaleContent: false,
636
- scaleX: false,
637
- scaleFrom: 0,
638
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
639
- restoreAfterFinish: true,
640
- afterSetup: function(effect) {
641
- effect.element.makeClipping().setStyle({height: '0px'}).show();
642
- },
643
- afterFinishInternal: function(effect) {
644
- effect.element.undoClipping();
645
- }
646
- }, arguments[1] || {}));
647
- }
648
-
649
- Effect.SwitchOff = function(element) {
650
- element = $(element);
651
- var oldOpacity = element.getInlineOpacity();
652
- return new Effect.Appear(element, Object.extend({
653
- duration: 0.4,
654
- from: 0,
655
- transition: Effect.Transitions.flicker,
656
- afterFinishInternal: function(effect) {
657
- new Effect.Scale(effect.element, 1, {
658
- duration: 0.3, scaleFromCenter: true,
659
- scaleX: false, scaleContent: false, restoreAfterFinish: true,
660
- beforeSetup: function(effect) {
661
- effect.element.makePositioned().makeClipping();
662
- },
663
- afterFinishInternal: function(effect) {
664
- effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
665
- }
666
- })
667
- }
668
- }, arguments[1] || {}));
669
- }
670
-
671
- Effect.DropOut = function(element) {
672
- element = $(element);
673
- var oldStyle = {
674
- top: element.getStyle('top'),
675
- left: element.getStyle('left'),
676
- opacity: element.getInlineOpacity() };
677
- return new Effect.Parallel(
678
- [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
679
- new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
680
- Object.extend(
681
- { duration: 0.5,
682
- beforeSetup: function(effect) {
683
- effect.effects[0].element.makePositioned();
684
- },
685
- afterFinishInternal: function(effect) {
686
- effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
687
- }
688
- }, arguments[1] || {}));
689
- }
690
-
691
- Effect.Shake = function(element) {
692
- element = $(element);
693
- var oldStyle = {
694
- top: element.getStyle('top'),
695
- left: element.getStyle('left') };
696
- return new Effect.Move(element,
697
- { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
698
- new Effect.Move(effect.element,
699
- { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
700
- new Effect.Move(effect.element,
701
- { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
702
- new Effect.Move(effect.element,
703
- { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
704
- new Effect.Move(effect.element,
705
- { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
706
- new Effect.Move(effect.element,
707
- { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
708
- effect.element.undoPositioned().setStyle(oldStyle);
709
- }}) }}) }}) }}) }}) }});
710
- }
711
-
712
- Effect.SlideDown = function(element) {
713
- element = $(element).cleanWhitespace();
714
- // SlideDown need to have the content of the element wrapped in a container element with fixed height!
715
- var oldInnerBottom = element.down().getStyle('bottom');
716
- var elementDimensions = element.getDimensions();
717
- return new Effect.Scale(element, 100, Object.extend({
718
- scaleContent: false,
719
- scaleX: false,
720
- scaleFrom: window.opera ? 0 : 1,
721
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
722
- restoreAfterFinish: true,
723
- afterSetup: function(effect) {
724
- effect.element.makePositioned();
725
- effect.element.down().makePositioned();
726
- if(window.opera) effect.element.setStyle({top: ''});
727
- effect.element.makeClipping().setStyle({height: '0px'}).show();
728
- },
729
- afterUpdateInternal: function(effect) {
730
- effect.element.down().setStyle({bottom:
731
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
732
- },
733
- afterFinishInternal: function(effect) {
734
- effect.element.undoClipping().undoPositioned();
735
- effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
736
- }, arguments[1] || {})
737
- );
738
- }
739
-
740
- Effect.SlideUp = function(element) {
741
- element = $(element).cleanWhitespace();
742
- var oldInnerBottom = element.down().getStyle('bottom');
743
- return new Effect.Scale(element, window.opera ? 0 : 1,
744
- Object.extend({ scaleContent: false,
745
- scaleX: false,
746
- scaleMode: 'box',
747
- scaleFrom: 100,
748
- restoreAfterFinish: true,
749
- beforeStartInternal: function(effect) {
750
- effect.element.makePositioned();
751
- effect.element.down().makePositioned();
752
- if(window.opera) effect.element.setStyle({top: ''});
753
- effect.element.makeClipping().show();
754
- },
755
- afterUpdateInternal: function(effect) {
756
- effect.element.down().setStyle({bottom:
757
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
758
- },
759
- afterFinishInternal: function(effect) {
760
- effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
761
- effect.element.down().undoPositioned();
762
- }
763
- }, arguments[1] || {})
764
- );
765
- }
766
-
767
- // Bug in opera makes the TD containing this element expand for a instance after finish
768
- Effect.Squish = function(element) {
769
- return new Effect.Scale(element, window.opera ? 1 : 0, {
770
- restoreAfterFinish: true,
771
- beforeSetup: function(effect) {
772
- effect.element.makeClipping();
773
- },
774
- afterFinishInternal: function(effect) {
775
- effect.element.hide().undoClipping();
776
- }
777
- });
778
- }
779
-
780
- Effect.Grow = function(element) {
781
- element = $(element);
782
- var options = Object.extend({
783
- direction: 'center',
784
- moveTransition: Effect.Transitions.sinoidal,
785
- scaleTransition: Effect.Transitions.sinoidal,
786
- opacityTransition: Effect.Transitions.full
787
- }, arguments[1] || {});
788
- var oldStyle = {
789
- top: element.style.top,
790
- left: element.style.left,
791
- height: element.style.height,
792
- width: element.style.width,
793
- opacity: element.getInlineOpacity() };
794
-
795
- var dims = element.getDimensions();
796
- var initialMoveX, initialMoveY;
797
- var moveX, moveY;
798
-
799
- switch (options.direction) {
800
- case 'top-left':
801
- initialMoveX = initialMoveY = moveX = moveY = 0;
802
- break;
803
- case 'top-right':
804
- initialMoveX = dims.width;
805
- initialMoveY = moveY = 0;
806
- moveX = -dims.width;
807
- break;
808
- case 'bottom-left':
809
- initialMoveX = moveX = 0;
810
- initialMoveY = dims.height;
811
- moveY = -dims.height;
812
- break;
813
- case 'bottom-right':
814
- initialMoveX = dims.width;
815
- initialMoveY = dims.height;
816
- moveX = -dims.width;
817
- moveY = -dims.height;
818
- break;
819
- case 'center':
820
- initialMoveX = dims.width / 2;
821
- initialMoveY = dims.height / 2;
822
- moveX = -dims.width / 2;
823
- moveY = -dims.height / 2;
824
- break;
825
- }
826
-
827
- return new Effect.Move(element, {
828
- x: initialMoveX,
829
- y: initialMoveY,
830
- duration: 0.01,
831
- beforeSetup: function(effect) {
832
- effect.element.hide().makeClipping().makePositioned();
833
- },
834
- afterFinishInternal: function(effect) {
835
- new Effect.Parallel(
836
- [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
837
- new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
838
- new Effect.Scale(effect.element, 100, {
839
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
840
- sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
841
- ], Object.extend({
842
- beforeSetup: function(effect) {
843
- effect.effects[0].element.setStyle({height: '0px'}).show();
844
- },
845
- afterFinishInternal: function(effect) {
846
- effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
847
- }
848
- }, options)
849
- )
850
- }
851
- });
852
- }
853
-
854
- Effect.Shrink = function(element) {
855
- element = $(element);
856
- var options = Object.extend({
857
- direction: 'center',
858
- moveTransition: Effect.Transitions.sinoidal,
859
- scaleTransition: Effect.Transitions.sinoidal,
860
- opacityTransition: Effect.Transitions.none
861
- }, arguments[1] || {});
862
- var oldStyle = {
863
- top: element.style.top,
864
- left: element.style.left,
865
- height: element.style.height,
866
- width: element.style.width,
867
- opacity: element.getInlineOpacity() };
868
-
869
- var dims = element.getDimensions();
870
- var moveX, moveY;
871
-
872
- switch (options.direction) {
873
- case 'top-left':
874
- moveX = moveY = 0;
875
- break;
876
- case 'top-right':
877
- moveX = dims.width;
878
- moveY = 0;
879
- break;
880
- case 'bottom-left':
881
- moveX = 0;
882
- moveY = dims.height;
883
- break;
884
- case 'bottom-right':
885
- moveX = dims.width;
886
- moveY = dims.height;
887
- break;
888
- case 'center':
889
- moveX = dims.width / 2;
890
- moveY = dims.height / 2;
891
- break;
892
- }
893
-
894
- return new Effect.Parallel(
895
- [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
896
- new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
897
- new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
898
- ], Object.extend({
899
- beforeStartInternal: function(effect) {
900
- effect.effects[0].element.makePositioned().makeClipping();
901
- },
902
- afterFinishInternal: function(effect) {
903
- effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
904
- }, options)
905
- );
906
- }
907
-
908
- Effect.Pulsate = function(element) {
909
- element = $(element);
910
- var options = arguments[1] || {};
911
- var oldOpacity = element.getInlineOpacity();
912
- var transition = options.transition || Effect.Transitions.sinoidal;
913
- var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
914
- reverser.bind(transition);
915
- return new Effect.Opacity(element,
916
- Object.extend(Object.extend({ duration: 2.0, from: 0,
917
- afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
918
- }, options), {transition: reverser}));
919
- }
920
-
921
- Effect.Fold = function(element) {
922
- element = $(element);
923
- var oldStyle = {
924
- top: element.style.top,
925
- left: element.style.left,
926
- width: element.style.width,
927
- height: element.style.height };
928
- element.makeClipping();
929
- return new Effect.Scale(element, 5, Object.extend({
930
- scaleContent: false,
931
- scaleX: false,
932
- afterFinishInternal: function(effect) {
933
- new Effect.Scale(element, 1, {
934
- scaleContent: false,
935
- scaleY: false,
936
- afterFinishInternal: function(effect) {
937
- effect.element.hide().undoClipping().setStyle(oldStyle);
938
- } });
939
- }}, arguments[1] || {}));
940
- };
941
-
942
- Effect.Morph = Class.create();
943
- Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
944
- initialize: function(element) {
945
- this.element = $(element);
946
- if(!this.element) throw(Effect._elementDoesNotExistError);
947
- var options = Object.extend({
948
- style: ''
949
- }, arguments[1] || {});
950
- this.start(options);
951
- },
952
- setup: function(){
953
- function parseColor(color){
954
- if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
955
- color = color.parseColor();
956
- return $R(0,2).map(function(i){
957
- return parseInt( color.slice(i*2+1,i*2+3), 16 )
958
- });
959
- }
960
- this.transforms = this.options.style.parseStyle().map(function(property){
961
- var originalValue = this.element.getStyle(property[0]);
962
- return $H({
963
- style: property[0],
964
- originalValue: property[1].unit=='color' ?
965
- parseColor(originalValue) : parseFloat(originalValue || 0),
966
- targetValue: property[1].unit=='color' ?
967
- parseColor(property[1].value) : property[1].value,
968
- unit: property[1].unit
969
- });
970
- }.bind(this)).reject(function(transform){
971
- return (
972
- (transform.originalValue == transform.targetValue) ||
973
- (
974
- transform.unit != 'color' &&
975
- (isNaN(transform.originalValue) || isNaN(transform.targetValue))
976
- )
977
- )
978
- });
979
- },
980
- update: function(position) {
981
- var style = $H(), value = null;
982
- this.transforms.each(function(transform){
983
- value = transform.unit=='color' ?
984
- $R(0,2).inject('#',function(m,v,i){
985
- return m+(Math.round(transform.originalValue[i]+
986
- (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) :
987
- transform.originalValue + Math.round(
988
- ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
989
- style[transform.style] = value;
990
- });
991
- this.element.setStyle(style);
992
- }
993
- });
994
-
995
- Effect.Transform = Class.create();
996
- Object.extend(Effect.Transform.prototype, {
997
- initialize: function(tracks){
998
- this.tracks = [];
999
- this.options = arguments[1] || {};
1000
- this.addTracks(tracks);
1001
- },
1002
- addTracks: function(tracks){
1003
- tracks.each(function(track){
1004
- var data = $H(track).values().first();
1005
- this.tracks.push($H({
1006
- ids: $H(track).keys().first(),
1007
- effect: Effect.Morph,
1008
- options: { style: data }
1009
- }));
1010
- }.bind(this));
1011
- return this;
1012
- },
1013
- play: function(){
1014
- return new Effect.Parallel(
1015
- this.tracks.map(function(track){
1016
- var elements = [$(track.ids) || $$(track.ids)].flatten();
1017
- return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
1018
- }).flatten(),
1019
- this.options
1020
- );
1021
- }
1022
- });
1023
-
1024
- Element.CSS_PROPERTIES = ['azimuth', 'backgroundAttachment', 'backgroundColor', 'backgroundImage',
1025
- 'backgroundPosition', 'backgroundRepeat', 'borderBottomColor', 'borderBottomStyle',
1026
- 'borderBottomWidth', 'borderCollapse', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth',
1027
- 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderSpacing', 'borderTopColor',
1028
- 'borderTopStyle', 'borderTopWidth', 'bottom', 'captionSide', 'clear', 'clip', 'color', 'content',
1029
- 'counterIncrement', 'counterReset', 'cssFloat', 'cueAfter', 'cueBefore', 'cursor', 'direction',
1030
- 'display', 'elevation', 'emptyCells', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
1031
- 'fontStyle', 'fontVariant', 'fontWeight', 'height', 'left', 'letterSpacing', 'lineHeight',
1032
- 'listStyleImage', 'listStylePosition', 'listStyleType', 'marginBottom', 'marginLeft', 'marginRight',
1033
- 'marginTop', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'opacity',
1034
- 'orphans', 'outlineColor', 'outlineOffset', 'outlineStyle', 'outlineWidth', 'overflowX', 'overflowY',
1035
- 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'page', 'pageBreakAfter', 'pageBreakBefore',
1036
- 'pageBreakInside', 'pauseAfter', 'pauseBefore', 'pitch', 'pitchRange', 'position', 'quotes',
1037
- 'richness', 'right', 'size', 'speakHeader', 'speakNumeral', 'speakPunctuation', 'speechRate', 'stress',
1038
- 'tableLayout', 'textAlign', 'textDecoration', 'textIndent', 'textShadow', 'textTransform', 'top',
1039
- 'unicodeBidi', 'verticalAlign', 'visibility', 'voiceFamily', 'volume', 'whiteSpace', 'widows',
1040
- 'width', 'wordSpacing', 'zIndex'];
1041
-
1042
- Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
1043
-
1044
- String.prototype.parseStyle = function(){
1045
- var element = Element.extend(document.createElement('div'));
1046
- element.innerHTML = '<div style="' + this + '"></div>';
1047
- var style = element.down().style, styleRules = $H();
1048
-
1049
- Element.CSS_PROPERTIES.each(function(property){
1050
- if(style[property]) styleRules[property] = style[property];
1051
- });
1052
-
1053
- var result = $H();
1054
-
1055
- styleRules.each(function(pair){
1056
- var property = pair[0], value = pair[1], unit = null;
1057
-
1058
- if(value.parseColor('#zzzzzz') != '#zzzzzz') {
1059
- value = value.parseColor();
1060
- unit = 'color';
1061
- } else if(Element.CSS_LENGTH.test(value))
1062
- var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
1063
- value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null;
1064
-
1065
- result[property.underscore().dasherize()] = $H({ value:value, unit:unit });
1066
- }.bind(this));
1067
-
1068
- return result;
1069
- };
1070
-
1071
- Element.morph = function(element, style) {
1072
- new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
1073
- return element;
1074
- };
1075
-
1076
- ['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
1077
- 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
1078
- function(f) { Element.Methods[f] = Element[f]; }
1079
- );
1080
-
1081
- Element.Methods.visualEffect = function(element, effect, options) {
1082
- s = effect.gsub(/_/, '-').camelize();
1083
- effect_class = s.charAt(0).toUpperCase() + s.substring(1);
1084
- new Effect[effect_class](element, options);
1085
- return $(element);
1086
- };
1087
-
1088
- Element.addMethods();