YurtCMS 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1781 @@
1
+ /* Prototype JavaScript framework, version 1.4.0
2
+ * (c) 2005 Sam Stephenson <sam@conio.net>
3
+ *
4
+ * Prototype is freely distributable under the terms of an MIT-style license.
5
+ * For details, see the Prototype web site: http://prototype.conio.net/
6
+ *
7
+ /*--------------------------------------------------------------------------*/
8
+
9
+ var Prototype = {
10
+ Version: '1.4.0',
11
+ ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
12
+
13
+ emptyFunction: function() {},
14
+ K: function(x) {return x}
15
+ }
16
+
17
+ var Class = {
18
+ create: function() {
19
+ return function() {
20
+ this.initialize.apply(this, arguments);
21
+ }
22
+ }
23
+ }
24
+
25
+ var Abstract = new Object();
26
+
27
+ Object.extend = function(destination, source) {
28
+ for (property in source) {
29
+ destination[property] = source[property];
30
+ }
31
+ return destination;
32
+ }
33
+
34
+ Object.inspect = function(object) {
35
+ try {
36
+ if (object == undefined) return 'undefined';
37
+ if (object == null) return 'null';
38
+ return object.inspect ? object.inspect() : object.toString();
39
+ } catch (e) {
40
+ if (e instanceof RangeError) return '...';
41
+ throw e;
42
+ }
43
+ }
44
+
45
+ Function.prototype.bind = function() {
46
+ var __method = this, args = $A(arguments), object = args.shift();
47
+ return function() {
48
+ return __method.apply(object, args.concat($A(arguments)));
49
+ }
50
+ }
51
+
52
+ Function.prototype.bindAsEventListener = function(object) {
53
+ var __method = this;
54
+ return function(event) {
55
+ return __method.call(object, event || window.event);
56
+ }
57
+ }
58
+
59
+ Object.extend(Number.prototype, {
60
+ toColorPart: function() {
61
+ var digits = this.toString(16);
62
+ if (this < 16) return '0' + digits;
63
+ return digits;
64
+ },
65
+
66
+ succ: function() {
67
+ return this + 1;
68
+ },
69
+
70
+ times: function(iterator) {
71
+ $R(0, this, true).each(iterator);
72
+ return this;
73
+ }
74
+ });
75
+
76
+ var Try = {
77
+ these: function() {
78
+ var returnValue;
79
+
80
+ for (var i = 0; i < arguments.length; i++) {
81
+ var lambda = arguments[i];
82
+ try {
83
+ returnValue = lambda();
84
+ break;
85
+ } catch (e) {}
86
+ }
87
+
88
+ return returnValue;
89
+ }
90
+ }
91
+
92
+ /*--------------------------------------------------------------------------*/
93
+
94
+ var PeriodicalExecuter = Class.create();
95
+ PeriodicalExecuter.prototype = {
96
+ initialize: function(callback, frequency) {
97
+ this.callback = callback;
98
+ this.frequency = frequency;
99
+ this.currentlyExecuting = false;
100
+
101
+ this.registerCallback();
102
+ },
103
+
104
+ registerCallback: function() {
105
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
106
+ },
107
+
108
+ onTimerEvent: function() {
109
+ if (!this.currentlyExecuting) {
110
+ try {
111
+ this.currentlyExecuting = true;
112
+ this.callback();
113
+ } finally {
114
+ this.currentlyExecuting = false;
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ /*--------------------------------------------------------------------------*/
121
+
122
+ function $() {
123
+ var elements = new Array();
124
+
125
+ for (var i = 0; i < arguments.length; i++) {
126
+ var element = arguments[i];
127
+ if (typeof element == 'string')
128
+ element = document.getElementById(element);
129
+
130
+ if (arguments.length == 1)
131
+ return element;
132
+
133
+ elements.push(element);
134
+ }
135
+
136
+ return elements;
137
+ }
138
+ Object.extend(String.prototype, {
139
+ stripTags: function() {
140
+ return this.replace(/<\/?[^>]+>/gi, '');
141
+ },
142
+
143
+ stripScripts: function() {
144
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
145
+ },
146
+
147
+ extractScripts: function() {
148
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
149
+ var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
150
+ return (this.match(matchAll) || []).map(function(scriptTag) {
151
+ return (scriptTag.match(matchOne) || ['', ''])[1];
152
+ });
153
+ },
154
+
155
+ evalScripts: function() {
156
+ return this.extractScripts().map(eval);
157
+ },
158
+
159
+ escapeHTML: function() {
160
+ var div = document.createElement('div');
161
+ var text = document.createTextNode(this);
162
+ div.appendChild(text);
163
+ return div.innerHTML;
164
+ },
165
+
166
+ unescapeHTML: function() {
167
+ var div = document.createElement('div');
168
+ div.innerHTML = this.stripTags();
169
+ return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
170
+ },
171
+
172
+ toQueryParams: function() {
173
+ var pairs = this.match(/^\??(.*)$/)[1].split('&');
174
+ return pairs.inject({}, function(params, pairString) {
175
+ var pair = pairString.split('=');
176
+ params[pair[0]] = pair[1];
177
+ return params;
178
+ });
179
+ },
180
+
181
+ toArray: function() {
182
+ return this.split('');
183
+ },
184
+
185
+ camelize: function() {
186
+ var oStringList = this.split('-');
187
+ if (oStringList.length == 1) return oStringList[0];
188
+
189
+ var camelizedString = this.indexOf('-') == 0
190
+ ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
191
+ : oStringList[0];
192
+
193
+ for (var i = 1, len = oStringList.length; i < len; i++) {
194
+ var s = oStringList[i];
195
+ camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
196
+ }
197
+
198
+ return camelizedString;
199
+ },
200
+
201
+ inspect: function() {
202
+ return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
203
+ }
204
+ });
205
+
206
+ String.prototype.parseQuery = String.prototype.toQueryParams;
207
+
208
+ var $break = new Object();
209
+ var $continue = new Object();
210
+
211
+ var Enumerable = {
212
+ each: function(iterator) {
213
+ var index = 0;
214
+ try {
215
+ this._each(function(value) {
216
+ try {
217
+ iterator(value, index++);
218
+ } catch (e) {
219
+ if (e != $continue) throw e;
220
+ }
221
+ });
222
+ } catch (e) {
223
+ if (e != $break) throw e;
224
+ }
225
+ },
226
+
227
+ all: function(iterator) {
228
+ var result = true;
229
+ this.each(function(value, index) {
230
+ result = result && !!(iterator || Prototype.K)(value, index);
231
+ if (!result) throw $break;
232
+ });
233
+ return result;
234
+ },
235
+
236
+ any: function(iterator) {
237
+ var result = true;
238
+ this.each(function(value, index) {
239
+ if (result = !!(iterator || Prototype.K)(value, index))
240
+ throw $break;
241
+ });
242
+ return result;
243
+ },
244
+
245
+ collect: function(iterator) {
246
+ var results = [];
247
+ this.each(function(value, index) {
248
+ results.push(iterator(value, index));
249
+ });
250
+ return results;
251
+ },
252
+
253
+ detect: function (iterator) {
254
+ var result;
255
+ this.each(function(value, index) {
256
+ if (iterator(value, index)) {
257
+ result = value;
258
+ throw $break;
259
+ }
260
+ });
261
+ return result;
262
+ },
263
+
264
+ findAll: function(iterator) {
265
+ var results = [];
266
+ this.each(function(value, index) {
267
+ if (iterator(value, index))
268
+ results.push(value);
269
+ });
270
+ return results;
271
+ },
272
+
273
+ grep: function(pattern, iterator) {
274
+ var results = [];
275
+ this.each(function(value, index) {
276
+ var stringValue = value.toString();
277
+ if (stringValue.match(pattern))
278
+ results.push((iterator || Prototype.K)(value, index));
279
+ })
280
+ return results;
281
+ },
282
+
283
+ include: function(object) {
284
+ var found = false;
285
+ this.each(function(value) {
286
+ if (value == object) {
287
+ found = true;
288
+ throw $break;
289
+ }
290
+ });
291
+ return found;
292
+ },
293
+
294
+ inject: function(memo, iterator) {
295
+ this.each(function(value, index) {
296
+ memo = iterator(memo, value, index);
297
+ });
298
+ return memo;
299
+ },
300
+
301
+ invoke: function(method) {
302
+ var args = $A(arguments).slice(1);
303
+ return this.collect(function(value) {
304
+ return value[method].apply(value, args);
305
+ });
306
+ },
307
+
308
+ max: function(iterator) {
309
+ var result;
310
+ this.each(function(value, index) {
311
+ value = (iterator || Prototype.K)(value, index);
312
+ if (value >= (result || value))
313
+ result = value;
314
+ });
315
+ return result;
316
+ },
317
+
318
+ min: function(iterator) {
319
+ var result;
320
+ this.each(function(value, index) {
321
+ value = (iterator || Prototype.K)(value, index);
322
+ if (value <= (result || value))
323
+ result = value;
324
+ });
325
+ return result;
326
+ },
327
+
328
+ partition: function(iterator) {
329
+ var trues = [], falses = [];
330
+ this.each(function(value, index) {
331
+ ((iterator || Prototype.K)(value, index) ?
332
+ trues : falses).push(value);
333
+ });
334
+ return [trues, falses];
335
+ },
336
+
337
+ pluck: function(property) {
338
+ var results = [];
339
+ this.each(function(value, index) {
340
+ results.push(value[property]);
341
+ });
342
+ return results;
343
+ },
344
+
345
+ reject: function(iterator) {
346
+ var results = [];
347
+ this.each(function(value, index) {
348
+ if (!iterator(value, index))
349
+ results.push(value);
350
+ });
351
+ return results;
352
+ },
353
+
354
+ sortBy: function(iterator) {
355
+ return this.collect(function(value, index) {
356
+ return {value: value, criteria: iterator(value, index)};
357
+ }).sort(function(left, right) {
358
+ var a = left.criteria, b = right.criteria;
359
+ return a < b ? -1 : a > b ? 1 : 0;
360
+ }).pluck('value');
361
+ },
362
+
363
+ toArray: function() {
364
+ return this.collect(Prototype.K);
365
+ },
366
+
367
+ zip: function() {
368
+ var iterator = Prototype.K, args = $A(arguments);
369
+ if (typeof args.last() == 'function')
370
+ iterator = args.pop();
371
+
372
+ var collections = [this].concat(args).map($A);
373
+ return this.map(function(value, index) {
374
+ iterator(value = collections.pluck(index));
375
+ return value;
376
+ });
377
+ },
378
+
379
+ inspect: function() {
380
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
381
+ }
382
+ }
383
+
384
+ Object.extend(Enumerable, {
385
+ map: Enumerable.collect,
386
+ find: Enumerable.detect,
387
+ select: Enumerable.findAll,
388
+ member: Enumerable.include,
389
+ entries: Enumerable.toArray
390
+ });
391
+ var $A = Array.from = function(iterable) {
392
+ if (!iterable) return [];
393
+ if (iterable.toArray) {
394
+ return iterable.toArray();
395
+ } else {
396
+ var results = [];
397
+ for (var i = 0; i < iterable.length; i++)
398
+ results.push(iterable[i]);
399
+ return results;
400
+ }
401
+ }
402
+
403
+ Object.extend(Array.prototype, Enumerable);
404
+
405
+ Array.prototype._reverse = Array.prototype.reverse;
406
+
407
+ Object.extend(Array.prototype, {
408
+ _each: function(iterator) {
409
+ for (var i = 0; i < this.length; i++)
410
+ iterator(this[i]);
411
+ },
412
+
413
+ clear: function() {
414
+ this.length = 0;
415
+ return this;
416
+ },
417
+
418
+ first: function() {
419
+ return this[0];
420
+ },
421
+
422
+ last: function() {
423
+ return this[this.length - 1];
424
+ },
425
+
426
+ compact: function() {
427
+ return this.select(function(value) {
428
+ return value != undefined || value != null;
429
+ });
430
+ },
431
+
432
+ flatten: function() {
433
+ return this.inject([], function(array, value) {
434
+ return array.concat(value.constructor == Array ?
435
+ value.flatten() : [value]);
436
+ });
437
+ },
438
+
439
+ without: function() {
440
+ var values = $A(arguments);
441
+ return this.select(function(value) {
442
+ return !values.include(value);
443
+ });
444
+ },
445
+
446
+ indexOf: function(object) {
447
+ for (var i = 0; i < this.length; i++)
448
+ if (this[i] == object) return i;
449
+ return -1;
450
+ },
451
+
452
+ reverse: function(inline) {
453
+ return (inline !== false ? this : this.toArray())._reverse();
454
+ },
455
+
456
+ shift: function() {
457
+ var result = this[0];
458
+ for (var i = 0; i < this.length - 1; i++)
459
+ this[i] = this[i + 1];
460
+ this.length--;
461
+ return result;
462
+ },
463
+
464
+ inspect: function() {
465
+ return '[' + this.map(Object.inspect).join(', ') + ']';
466
+ }
467
+ });
468
+ var Hash = {
469
+ _each: function(iterator) {
470
+ for (key in this) {
471
+ var value = this[key];
472
+ if (typeof value == 'function') continue;
473
+
474
+ var pair = [key, value];
475
+ pair.key = key;
476
+ pair.value = value;
477
+ iterator(pair);
478
+ }
479
+ },
480
+
481
+ keys: function() {
482
+ return this.pluck('key');
483
+ },
484
+
485
+ values: function() {
486
+ return this.pluck('value');
487
+ },
488
+
489
+ merge: function(hash) {
490
+ return $H(hash).inject($H(this), function(mergedHash, pair) {
491
+ mergedHash[pair.key] = pair.value;
492
+ return mergedHash;
493
+ });
494
+ },
495
+
496
+ toQueryString: function() {
497
+ return this.map(function(pair) {
498
+ return pair.map(encodeURIComponent).join('=');
499
+ }).join('&');
500
+ },
501
+
502
+ inspect: function() {
503
+ return '#<Hash:{' + this.map(function(pair) {
504
+ return pair.map(Object.inspect).join(': ');
505
+ }).join(', ') + '}>';
506
+ }
507
+ }
508
+
509
+ function $H(object) {
510
+ var hash = Object.extend({}, object || {});
511
+ Object.extend(hash, Enumerable);
512
+ Object.extend(hash, Hash);
513
+ return hash;
514
+ }
515
+ ObjectRange = Class.create();
516
+ Object.extend(ObjectRange.prototype, Enumerable);
517
+ Object.extend(ObjectRange.prototype, {
518
+ initialize: function(start, end, exclusive) {
519
+ this.start = start;
520
+ this.end = end;
521
+ this.exclusive = exclusive;
522
+ },
523
+
524
+ _each: function(iterator) {
525
+ var value = this.start;
526
+ do {
527
+ iterator(value);
528
+ value = value.succ();
529
+ } while (this.include(value));
530
+ },
531
+
532
+ include: function(value) {
533
+ if (value < this.start)
534
+ return false;
535
+ if (this.exclusive)
536
+ return value < this.end;
537
+ return value <= this.end;
538
+ }
539
+ });
540
+
541
+ var $R = function(start, end, exclusive) {
542
+ return new ObjectRange(start, end, exclusive);
543
+ }
544
+
545
+ var Ajax = {
546
+ getTransport: function() {
547
+ return Try.these(
548
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
549
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')},
550
+ function() {return new XMLHttpRequest()}
551
+ ) || false;
552
+ },
553
+
554
+ activeRequestCount: 0
555
+ }
556
+
557
+ Ajax.Responders = {
558
+ responders: [],
559
+
560
+ _each: function(iterator) {
561
+ this.responders._each(iterator);
562
+ },
563
+
564
+ register: function(responderToAdd) {
565
+ if (!this.include(responderToAdd))
566
+ this.responders.push(responderToAdd);
567
+ },
568
+
569
+ unregister: function(responderToRemove) {
570
+ this.responders = this.responders.without(responderToRemove);
571
+ },
572
+
573
+ dispatch: function(callback, request, transport, json) {
574
+ this.each(function(responder) {
575
+ if (responder[callback] && typeof responder[callback] == 'function') {
576
+ try {
577
+ responder[callback].apply(responder, [request, transport, json]);
578
+ } catch (e) {}
579
+ }
580
+ });
581
+ }
582
+ };
583
+
584
+ Object.extend(Ajax.Responders, Enumerable);
585
+
586
+ Ajax.Responders.register({
587
+ onCreate: function() {
588
+ Ajax.activeRequestCount++;
589
+ },
590
+
591
+ onComplete: function() {
592
+ Ajax.activeRequestCount--;
593
+ }
594
+ });
595
+
596
+ Ajax.Base = function() {};
597
+ Ajax.Base.prototype = {
598
+ setOptions: function(options) {
599
+ this.options = {
600
+ method: 'post',
601
+ asynchronous: true,
602
+ parameters: ''
603
+ }
604
+ Object.extend(this.options, options || {});
605
+ },
606
+
607
+ responseIsSuccess: function() {
608
+ return this.transport.status == undefined
609
+ || this.transport.status == 0
610
+ || (this.transport.status >= 200 && this.transport.status < 300);
611
+ },
612
+
613
+ responseIsFailure: function() {
614
+ return !this.responseIsSuccess();
615
+ }
616
+ }
617
+
618
+ Ajax.Request = Class.create();
619
+ Ajax.Request.Events =
620
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
621
+
622
+ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
623
+ initialize: function(url, options) {
624
+ this.transport = Ajax.getTransport();
625
+ this.setOptions(options);
626
+ this.request(url);
627
+ },
628
+
629
+ request: function(url) {
630
+ var parameters = this.options.parameters || '';
631
+ if (parameters.length > 0) parameters += '&_=';
632
+
633
+ try {
634
+ this.url = url;
635
+ if (this.options.method == 'get' && parameters.length > 0)
636
+ this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
637
+
638
+ Ajax.Responders.dispatch('onCreate', this, this.transport);
639
+
640
+ this.transport.open(this.options.method, this.url,
641
+ this.options.asynchronous);
642
+
643
+ if (this.options.asynchronous) {
644
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
645
+ setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
646
+ }
647
+
648
+ this.setRequestHeaders();
649
+
650
+ var body = this.options.postBody ? this.options.postBody : parameters;
651
+ this.transport.send(this.options.method == 'post' ? body : null);
652
+
653
+ } catch (e) {
654
+ this.dispatchException(e);
655
+ }
656
+ },
657
+
658
+ setRequestHeaders: function() {
659
+ var requestHeaders =
660
+ ['X-Requested-With', 'XMLHttpRequest',
661
+ 'X-Prototype-Version', Prototype.Version];
662
+
663
+ if (this.options.method == 'post') {
664
+ requestHeaders.push('Content-type',
665
+ 'application/x-www-form-urlencoded');
666
+
667
+ /* Force "Connection: close" for Mozilla browsers to work around
668
+ * a bug where XMLHttpReqeuest sends an incorrect Content-length
669
+ * header. See Mozilla Bugzilla #246651.
670
+ */
671
+ if (this.transport.overrideMimeType)
672
+ requestHeaders.push('Connection', 'close');
673
+ }
674
+
675
+ if (this.options.requestHeaders)
676
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
677
+
678
+ for (var i = 0; i < requestHeaders.length; i += 2)
679
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
680
+ },
681
+
682
+ onStateChange: function() {
683
+ var readyState = this.transport.readyState;
684
+ if (readyState != 1)
685
+ this.respondToReadyState(this.transport.readyState);
686
+ },
687
+
688
+ header: function(name) {
689
+ try {
690
+ return this.transport.getResponseHeader(name);
691
+ } catch (e) {}
692
+ },
693
+
694
+ evalJSON: function() {
695
+ try {
696
+ return eval(this.header('X-JSON'));
697
+ } catch (e) {}
698
+ },
699
+
700
+ evalResponse: function() {
701
+ try {
702
+ return eval(this.transport.responseText);
703
+ } catch (e) {
704
+ this.dispatchException(e);
705
+ }
706
+ },
707
+
708
+ respondToReadyState: function(readyState) {
709
+ var event = Ajax.Request.Events[readyState];
710
+ var transport = this.transport, json = this.evalJSON();
711
+
712
+ if (event == 'Complete') {
713
+ try {
714
+ (this.options['on' + this.transport.status]
715
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
716
+ || Prototype.emptyFunction)(transport, json);
717
+ } catch (e) {
718
+ this.dispatchException(e);
719
+ }
720
+
721
+ if ((this.header('Content-type') || '').match(/^text\/javascript/i))
722
+ this.evalResponse();
723
+ }
724
+
725
+ try {
726
+ (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
727
+ Ajax.Responders.dispatch('on' + event, this, transport, json);
728
+ } catch (e) {
729
+ this.dispatchException(e);
730
+ }
731
+
732
+ /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
733
+ if (event == 'Complete')
734
+ this.transport.onreadystatechange = Prototype.emptyFunction;
735
+ },
736
+
737
+ dispatchException: function(exception) {
738
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
739
+ Ajax.Responders.dispatch('onException', this, exception);
740
+ }
741
+ });
742
+
743
+ Ajax.Updater = Class.create();
744
+
745
+ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
746
+ initialize: function(container, url, options) {
747
+ this.containers = {
748
+ success: container.success ? $(container.success) : $(container),
749
+ failure: container.failure ? $(container.failure) :
750
+ (container.success ? null : $(container))
751
+ }
752
+
753
+ this.transport = Ajax.getTransport();
754
+ this.setOptions(options);
755
+
756
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
757
+ this.options.onComplete = (function(transport, object) {
758
+ this.updateContent();
759
+ onComplete(transport, object);
760
+ }).bind(this);
761
+
762
+ this.request(url);
763
+ },
764
+
765
+ updateContent: function() {
766
+ var receiver = this.responseIsSuccess() ?
767
+ this.containers.success : this.containers.failure;
768
+ var response = this.transport.responseText;
769
+
770
+ if (!this.options.evalScripts)
771
+ response = response.stripScripts();
772
+
773
+ if (receiver) {
774
+ if (this.options.insertion) {
775
+ new this.options.insertion(receiver, response);
776
+ } else {
777
+ Element.update(receiver, response);
778
+ }
779
+ }
780
+
781
+ if (this.responseIsSuccess()) {
782
+ if (this.onComplete)
783
+ setTimeout(this.onComplete.bind(this), 10);
784
+ }
785
+ }
786
+ });
787
+
788
+ Ajax.PeriodicalUpdater = Class.create();
789
+ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
790
+ initialize: function(container, url, options) {
791
+ this.setOptions(options);
792
+ this.onComplete = this.options.onComplete;
793
+
794
+ this.frequency = (this.options.frequency || 2);
795
+ this.decay = (this.options.decay || 1);
796
+
797
+ this.updater = {};
798
+ this.container = container;
799
+ this.url = url;
800
+
801
+ this.start();
802
+ },
803
+
804
+ start: function() {
805
+ this.options.onComplete = this.updateComplete.bind(this);
806
+ this.onTimerEvent();
807
+ },
808
+
809
+ stop: function() {
810
+ this.updater.onComplete = undefined;
811
+ clearTimeout(this.timer);
812
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
813
+ },
814
+
815
+ updateComplete: function(request) {
816
+ if (this.options.decay) {
817
+ this.decay = (request.responseText == this.lastText ?
818
+ this.decay * this.options.decay : 1);
819
+
820
+ this.lastText = request.responseText;
821
+ }
822
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
823
+ this.decay * this.frequency * 1000);
824
+ },
825
+
826
+ onTimerEvent: function() {
827
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
828
+ }
829
+ });
830
+ document.getElementsByClassName = function(className, parentElement) {
831
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
832
+ return $A(children).inject([], function(elements, child) {
833
+ if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
834
+ elements.push(child);
835
+ return elements;
836
+ });
837
+ }
838
+
839
+ /*--------------------------------------------------------------------------*/
840
+
841
+ if (!window.Element) {
842
+ var Element = new Object();
843
+ }
844
+
845
+ Object.extend(Element, {
846
+ visible: function(element) {
847
+ return $(element).style.display != 'none';
848
+ },
849
+
850
+ toggle: function() {
851
+ for (var i = 0; i < arguments.length; i++) {
852
+ var element = $(arguments[i]);
853
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
854
+ }
855
+ },
856
+
857
+ hide: function() {
858
+ for (var i = 0; i < arguments.length; i++) {
859
+ var element = $(arguments[i]);
860
+ element.style.display = 'none';
861
+ }
862
+ },
863
+
864
+ show: function() {
865
+ for (var i = 0; i < arguments.length; i++) {
866
+ var element = $(arguments[i]);
867
+ element.style.display = '';
868
+ }
869
+ },
870
+
871
+ remove: function(element) {
872
+ element = $(element);
873
+ element.parentNode.removeChild(element);
874
+ },
875
+
876
+ update: function(element, html) {
877
+ $(element).innerHTML = html.stripScripts();
878
+ setTimeout(function() {html.evalScripts()}, 10);
879
+ },
880
+
881
+ getHeight: function(element) {
882
+ element = $(element);
883
+ return element.offsetHeight;
884
+ },
885
+
886
+ classNames: function(element) {
887
+ return new Element.ClassNames(element);
888
+ },
889
+
890
+ hasClassName: function(element, className) {
891
+ if (!(element = $(element))) return;
892
+ return Element.classNames(element).include(className);
893
+ },
894
+
895
+ addClassName: function(element, className) {
896
+ if (!(element = $(element))) return;
897
+ return Element.classNames(element).add(className);
898
+ },
899
+
900
+ removeClassName: function(element, className) {
901
+ if (!(element = $(element))) return;
902
+ return Element.classNames(element).remove(className);
903
+ },
904
+
905
+ // removes whitespace-only text node children
906
+ cleanWhitespace: function(element) {
907
+ element = $(element);
908
+ for (var i = 0; i < element.childNodes.length; i++) {
909
+ var node = element.childNodes[i];
910
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
911
+ Element.remove(node);
912
+ }
913
+ },
914
+
915
+ empty: function(element) {
916
+ return $(element).innerHTML.match(/^\s*$/);
917
+ },
918
+
919
+ scrollTo: function(element) {
920
+ element = $(element);
921
+ var x = element.x ? element.x : element.offsetLeft,
922
+ y = element.y ? element.y : element.offsetTop;
923
+ window.scrollTo(x, y);
924
+ },
925
+
926
+ getStyle: function(element, style) {
927
+ element = $(element);
928
+ var value = element.style[style.camelize()];
929
+ if (!value) {
930
+ if (document.defaultView && document.defaultView.getComputedStyle) {
931
+ var css = document.defaultView.getComputedStyle(element, null);
932
+ value = css ? css.getPropertyValue(style) : null;
933
+ } else if (element.currentStyle) {
934
+ value = element.currentStyle[style.camelize()];
935
+ }
936
+ }
937
+
938
+ if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
939
+ if (Element.getStyle(element, 'position') == 'static') value = 'auto';
940
+
941
+ return value == 'auto' ? null : value;
942
+ },
943
+
944
+ setStyle: function(element, style) {
945
+ element = $(element);
946
+ for (name in style)
947
+ element.style[name.camelize()] = style[name];
948
+ },
949
+
950
+ getDimensions: function(element) {
951
+ element = $(element);
952
+ if (Element.getStyle(element, 'display') != 'none')
953
+ return {width: element.offsetWidth, height: element.offsetHeight};
954
+
955
+ // All *Width and *Height properties give 0 on elements with display none,
956
+ // so enable the element temporarily
957
+ var els = element.style;
958
+ var originalVisibility = els.visibility;
959
+ var originalPosition = els.position;
960
+ els.visibility = 'hidden';
961
+ els.position = 'absolute';
962
+ els.display = '';
963
+ var originalWidth = element.clientWidth;
964
+ var originalHeight = element.clientHeight;
965
+ els.display = 'none';
966
+ els.position = originalPosition;
967
+ els.visibility = originalVisibility;
968
+ return {width: originalWidth, height: originalHeight};
969
+ },
970
+
971
+ makePositioned: function(element) {
972
+ element = $(element);
973
+ var pos = Element.getStyle(element, 'position');
974
+ if (pos == 'static' || !pos) {
975
+ element._madePositioned = true;
976
+ element.style.position = 'relative';
977
+ // Opera returns the offset relative to the positioning context, when an
978
+ // element is position relative but top and left have not been defined
979
+ if (window.opera) {
980
+ element.style.top = 0;
981
+ element.style.left = 0;
982
+ }
983
+ }
984
+ },
985
+
986
+ undoPositioned: function(element) {
987
+ element = $(element);
988
+ if (element._madePositioned) {
989
+ element._madePositioned = undefined;
990
+ element.style.position =
991
+ element.style.top =
992
+ element.style.left =
993
+ element.style.bottom =
994
+ element.style.right = '';
995
+ }
996
+ },
997
+
998
+ makeClipping: function(element) {
999
+ element = $(element);
1000
+ if (element._overflow) return;
1001
+ element._overflow = element.style.overflow;
1002
+ if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
1003
+ element.style.overflow = 'hidden';
1004
+ },
1005
+
1006
+ undoClipping: function(element) {
1007
+ element = $(element);
1008
+ if (element._overflow) return;
1009
+ element.style.overflow = element._overflow;
1010
+ element._overflow = undefined;
1011
+ }
1012
+ });
1013
+
1014
+ var Toggle = new Object();
1015
+ Toggle.display = Element.toggle;
1016
+
1017
+ /*--------------------------------------------------------------------------*/
1018
+
1019
+ Abstract.Insertion = function(adjacency) {
1020
+ this.adjacency = adjacency;
1021
+ }
1022
+
1023
+ Abstract.Insertion.prototype = {
1024
+ initialize: function(element, content) {
1025
+ this.element = $(element);
1026
+ this.content = content.stripScripts();
1027
+
1028
+ if (this.adjacency && this.element.insertAdjacentHTML) {
1029
+ try {
1030
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
1031
+ } catch (e) {
1032
+ if (this.element.tagName.toLowerCase() == 'tbody') {
1033
+ this.insertContent(this.contentFromAnonymousTable());
1034
+ } else {
1035
+ throw e;
1036
+ }
1037
+ }
1038
+ } else {
1039
+ this.range = this.element.ownerDocument.createRange();
1040
+ if (this.initializeRange) this.initializeRange();
1041
+ this.insertContent([this.range.createContextualFragment(this.content)]);
1042
+ }
1043
+
1044
+ setTimeout(function() {content.evalScripts()}, 10);
1045
+ },
1046
+
1047
+ contentFromAnonymousTable: function() {
1048
+ var div = document.createElement('div');
1049
+ div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
1050
+ return $A(div.childNodes[0].childNodes[0].childNodes);
1051
+ }
1052
+ }
1053
+
1054
+ var Insertion = new Object();
1055
+
1056
+ Insertion.Before = Class.create();
1057
+ Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
1058
+ initializeRange: function() {
1059
+ this.range.setStartBefore(this.element);
1060
+ },
1061
+
1062
+ insertContent: function(fragments) {
1063
+ fragments.each((function(fragment) {
1064
+ this.element.parentNode.insertBefore(fragment, this.element);
1065
+ }).bind(this));
1066
+ }
1067
+ });
1068
+
1069
+ Insertion.Top = Class.create();
1070
+ Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
1071
+ initializeRange: function() {
1072
+ this.range.selectNodeContents(this.element);
1073
+ this.range.collapse(true);
1074
+ },
1075
+
1076
+ insertContent: function(fragments) {
1077
+ fragments.reverse(false).each((function(fragment) {
1078
+ this.element.insertBefore(fragment, this.element.firstChild);
1079
+ }).bind(this));
1080
+ }
1081
+ });
1082
+
1083
+ Insertion.Bottom = Class.create();
1084
+ Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
1085
+ initializeRange: function() {
1086
+ this.range.selectNodeContents(this.element);
1087
+ this.range.collapse(this.element);
1088
+ },
1089
+
1090
+ insertContent: function(fragments) {
1091
+ fragments.each((function(fragment) {
1092
+ this.element.appendChild(fragment);
1093
+ }).bind(this));
1094
+ }
1095
+ });
1096
+
1097
+ Insertion.After = Class.create();
1098
+ Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
1099
+ initializeRange: function() {
1100
+ this.range.setStartAfter(this.element);
1101
+ },
1102
+
1103
+ insertContent: function(fragments) {
1104
+ fragments.each((function(fragment) {
1105
+ this.element.parentNode.insertBefore(fragment,
1106
+ this.element.nextSibling);
1107
+ }).bind(this));
1108
+ }
1109
+ });
1110
+
1111
+ /*--------------------------------------------------------------------------*/
1112
+
1113
+ Element.ClassNames = Class.create();
1114
+ Element.ClassNames.prototype = {
1115
+ initialize: function(element) {
1116
+ this.element = $(element);
1117
+ },
1118
+
1119
+ _each: function(iterator) {
1120
+ this.element.className.split(/\s+/).select(function(name) {
1121
+ return name.length > 0;
1122
+ })._each(iterator);
1123
+ },
1124
+
1125
+ set: function(className) {
1126
+ this.element.className = className;
1127
+ },
1128
+
1129
+ add: function(classNameToAdd) {
1130
+ if (this.include(classNameToAdd)) return;
1131
+ this.set(this.toArray().concat(classNameToAdd).join(' '));
1132
+ },
1133
+
1134
+ remove: function(classNameToRemove) {
1135
+ if (!this.include(classNameToRemove)) return;
1136
+ this.set(this.select(function(className) {
1137
+ return className != classNameToRemove;
1138
+ }).join(' '));
1139
+ },
1140
+
1141
+ toString: function() {
1142
+ return this.toArray().join(' ');
1143
+ }
1144
+ }
1145
+
1146
+ Object.extend(Element.ClassNames.prototype, Enumerable);
1147
+ var Field = {
1148
+ clear: function() {
1149
+ for (var i = 0; i < arguments.length; i++)
1150
+ $(arguments[i]).value = '';
1151
+ },
1152
+
1153
+ focus: function(element) {
1154
+ $(element).focus();
1155
+ },
1156
+
1157
+ present: function() {
1158
+ for (var i = 0; i < arguments.length; i++)
1159
+ if ($(arguments[i]).value == '') return false;
1160
+ return true;
1161
+ },
1162
+
1163
+ select: function(element) {
1164
+ $(element).select();
1165
+ },
1166
+
1167
+ activate: function(element) {
1168
+ element = $(element);
1169
+ element.focus();
1170
+ if (element.select)
1171
+ element.select();
1172
+ }
1173
+ }
1174
+
1175
+ /*--------------------------------------------------------------------------*/
1176
+
1177
+ var Form = {
1178
+ serialize: function(form) {
1179
+ var elements = Form.getElements($(form));
1180
+ var queryComponents = new Array();
1181
+
1182
+ for (var i = 0; i < elements.length; i++) {
1183
+ var queryComponent = Form.Element.serialize(elements[i]);
1184
+ if (queryComponent)
1185
+ queryComponents.push(queryComponent);
1186
+ }
1187
+
1188
+ return queryComponents.join('&');
1189
+ },
1190
+
1191
+ getElements: function(form) {
1192
+ form = $(form);
1193
+ var elements = new Array();
1194
+
1195
+ for (tagName in Form.Element.Serializers) {
1196
+ var tagElements = form.getElementsByTagName(tagName);
1197
+ for (var j = 0; j < tagElements.length; j++)
1198
+ elements.push(tagElements[j]);
1199
+ }
1200
+ return elements;
1201
+ },
1202
+
1203
+ getInputs: function(form, typeName, name) {
1204
+ form = $(form);
1205
+ var inputs = form.getElementsByTagName('input');
1206
+
1207
+ if (!typeName && !name)
1208
+ return inputs;
1209
+
1210
+ var matchingInputs = new Array();
1211
+ for (var i = 0; i < inputs.length; i++) {
1212
+ var input = inputs[i];
1213
+ if ((typeName && input.type != typeName) ||
1214
+ (name && input.name != name))
1215
+ continue;
1216
+ matchingInputs.push(input);
1217
+ }
1218
+
1219
+ return matchingInputs;
1220
+ },
1221
+
1222
+ disable: function(form) {
1223
+ var elements = Form.getElements(form);
1224
+ for (var i = 0; i < elements.length; i++) {
1225
+ var element = elements[i];
1226
+ element.blur();
1227
+ element.disabled = 'true';
1228
+ }
1229
+ },
1230
+
1231
+ enable: function(form) {
1232
+ var elements = Form.getElements(form);
1233
+ for (var i = 0; i < elements.length; i++) {
1234
+ var element = elements[i];
1235
+ element.disabled = '';
1236
+ }
1237
+ },
1238
+
1239
+ findFirstElement: function(form) {
1240
+ return Form.getElements(form).find(function(element) {
1241
+ return element.type != 'hidden' && !element.disabled &&
1242
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
1243
+ });
1244
+ },
1245
+
1246
+ focusFirstElement: function(form) {
1247
+ Field.activate(Form.findFirstElement(form));
1248
+ },
1249
+
1250
+ reset: function(form) {
1251
+ $(form).reset();
1252
+ }
1253
+ }
1254
+
1255
+ Form.Element = {
1256
+ serialize: function(element) {
1257
+ element = $(element);
1258
+ var method = element.tagName.toLowerCase();
1259
+ var parameter = Form.Element.Serializers[method](element);
1260
+
1261
+ if (parameter) {
1262
+ var key = encodeURIComponent(parameter[0]);
1263
+ if (key.length == 0) return;
1264
+
1265
+ if (parameter[1].constructor != Array)
1266
+ parameter[1] = [parameter[1]];
1267
+
1268
+ return parameter[1].map(function(value) {
1269
+ return key + '=' + encodeURIComponent(value);
1270
+ }).join('&');
1271
+ }
1272
+ },
1273
+
1274
+ getValue: function(element) {
1275
+ element = $(element);
1276
+ var method = element.tagName.toLowerCase();
1277
+ var parameter = Form.Element.Serializers[method](element);
1278
+
1279
+ if (parameter)
1280
+ return parameter[1];
1281
+ }
1282
+ }
1283
+
1284
+ Form.Element.Serializers = {
1285
+ input: function(element) {
1286
+ switch (element.type.toLowerCase()) {
1287
+ case 'submit':
1288
+ case 'hidden':
1289
+ case 'password':
1290
+ case 'text':
1291
+ return Form.Element.Serializers.textarea(element);
1292
+ case 'checkbox':
1293
+ case 'radio':
1294
+ return Form.Element.Serializers.inputSelector(element);
1295
+ }
1296
+ return false;
1297
+ },
1298
+
1299
+ inputSelector: function(element) {
1300
+ if (element.checked)
1301
+ return [element.name, element.value];
1302
+ },
1303
+
1304
+ textarea: function(element) {
1305
+ return [element.name, element.value];
1306
+ },
1307
+
1308
+ select: function(element) {
1309
+ return Form.Element.Serializers[element.type == 'select-one' ?
1310
+ 'selectOne' : 'selectMany'](element);
1311
+ },
1312
+
1313
+ selectOne: function(element) {
1314
+ var value = '', opt, index = element.selectedIndex;
1315
+ if (index >= 0) {
1316
+ opt = element.options[index];
1317
+ value = opt.value;
1318
+ if (!value && !('value' in opt))
1319
+ value = opt.text;
1320
+ }
1321
+ return [element.name, value];
1322
+ },
1323
+
1324
+ selectMany: function(element) {
1325
+ var value = new Array();
1326
+ for (var i = 0; i < element.length; i++) {
1327
+ var opt = element.options[i];
1328
+ if (opt.selected) {
1329
+ var optValue = opt.value;
1330
+ if (!optValue && !('value' in opt))
1331
+ optValue = opt.text;
1332
+ value.push(optValue);
1333
+ }
1334
+ }
1335
+ return [element.name, value];
1336
+ }
1337
+ }
1338
+
1339
+ /*--------------------------------------------------------------------------*/
1340
+
1341
+ var $F = Form.Element.getValue;
1342
+
1343
+ /*--------------------------------------------------------------------------*/
1344
+
1345
+ Abstract.TimedObserver = function() {}
1346
+ Abstract.TimedObserver.prototype = {
1347
+ initialize: function(element, frequency, callback) {
1348
+ this.frequency = frequency;
1349
+ this.element = $(element);
1350
+ this.callback = callback;
1351
+
1352
+ this.lastValue = this.getValue();
1353
+ this.registerCallback();
1354
+ },
1355
+
1356
+ registerCallback: function() {
1357
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
1358
+ },
1359
+
1360
+ onTimerEvent: function() {
1361
+ var value = this.getValue();
1362
+ if (this.lastValue != value) {
1363
+ this.callback(this.element, value);
1364
+ this.lastValue = value;
1365
+ }
1366
+ }
1367
+ }
1368
+
1369
+ Form.Element.Observer = Class.create();
1370
+ Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
1371
+ getValue: function() {
1372
+ return Form.Element.getValue(this.element);
1373
+ }
1374
+ });
1375
+
1376
+ Form.Observer = Class.create();
1377
+ Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
1378
+ getValue: function() {
1379
+ return Form.serialize(this.element);
1380
+ }
1381
+ });
1382
+
1383
+ /*--------------------------------------------------------------------------*/
1384
+
1385
+ Abstract.EventObserver = function() {}
1386
+ Abstract.EventObserver.prototype = {
1387
+ initialize: function(element, callback) {
1388
+ this.element = $(element);
1389
+ this.callback = callback;
1390
+
1391
+ this.lastValue = this.getValue();
1392
+ if (this.element.tagName.toLowerCase() == 'form')
1393
+ this.registerFormCallbacks();
1394
+ else
1395
+ this.registerCallback(this.element);
1396
+ },
1397
+
1398
+ onElementEvent: function() {
1399
+ var value = this.getValue();
1400
+ if (this.lastValue != value) {
1401
+ this.callback(this.element, value);
1402
+ this.lastValue = value;
1403
+ }
1404
+ },
1405
+
1406
+ registerFormCallbacks: function() {
1407
+ var elements = Form.getElements(this.element);
1408
+ for (var i = 0; i < elements.length; i++)
1409
+ this.registerCallback(elements[i]);
1410
+ },
1411
+
1412
+ registerCallback: function(element) {
1413
+ if (element.type) {
1414
+ switch (element.type.toLowerCase()) {
1415
+ case 'checkbox':
1416
+ case 'radio':
1417
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
1418
+ break;
1419
+ case 'password':
1420
+ case 'text':
1421
+ case 'textarea':
1422
+ case 'select-one':
1423
+ case 'select-multiple':
1424
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
1425
+ break;
1426
+ }
1427
+ }
1428
+ }
1429
+ }
1430
+
1431
+ Form.Element.EventObserver = Class.create();
1432
+ Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1433
+ getValue: function() {
1434
+ return Form.Element.getValue(this.element);
1435
+ }
1436
+ });
1437
+
1438
+ Form.EventObserver = Class.create();
1439
+ Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1440
+ getValue: function() {
1441
+ return Form.serialize(this.element);
1442
+ }
1443
+ });
1444
+ if (!window.Event) {
1445
+ var Event = new Object();
1446
+ }
1447
+
1448
+ Object.extend(Event, {
1449
+ KEY_BACKSPACE: 8,
1450
+ KEY_TAB: 9,
1451
+ KEY_RETURN: 13,
1452
+ KEY_ESC: 27,
1453
+ KEY_LEFT: 37,
1454
+ KEY_UP: 38,
1455
+ KEY_RIGHT: 39,
1456
+ KEY_DOWN: 40,
1457
+ KEY_DELETE: 46,
1458
+
1459
+ element: function(event) {
1460
+ return event.target || event.srcElement;
1461
+ },
1462
+
1463
+ isLeftClick: function(event) {
1464
+ return (((event.which) && (event.which == 1)) ||
1465
+ ((event.button) && (event.button == 1)));
1466
+ },
1467
+
1468
+ pointerX: function(event) {
1469
+ return event.pageX || (event.clientX +
1470
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
1471
+ },
1472
+
1473
+ pointerY: function(event) {
1474
+ return event.pageY || (event.clientY +
1475
+ (document.documentElement.scrollTop || document.body.scrollTop));
1476
+ },
1477
+
1478
+ stop: function(event) {
1479
+ if (event.preventDefault) {
1480
+ event.preventDefault();
1481
+ event.stopPropagation();
1482
+ } else {
1483
+ event.returnValue = false;
1484
+ event.cancelBubble = true;
1485
+ }
1486
+ },
1487
+
1488
+ // find the first node with the given tagName, starting from the
1489
+ // node the event was triggered on; traverses the DOM upwards
1490
+ findElement: function(event, tagName) {
1491
+ var element = Event.element(event);
1492
+ while (element.parentNode && (!element.tagName ||
1493
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
1494
+ element = element.parentNode;
1495
+ return element;
1496
+ },
1497
+
1498
+ observers: false,
1499
+
1500
+ _observeAndCache: function(element, name, observer, useCapture) {
1501
+ if (!this.observers) this.observers = [];
1502
+ if (element.addEventListener) {
1503
+ this.observers.push([element, name, observer, useCapture]);
1504
+ element.addEventListener(name, observer, useCapture);
1505
+ } else if (element.attachEvent) {
1506
+ this.observers.push([element, name, observer, useCapture]);
1507
+ element.attachEvent('on' + name, observer);
1508
+ }
1509
+ },
1510
+
1511
+ unloadCache: function() {
1512
+ if (!Event.observers) return;
1513
+ for (var i = 0; i < Event.observers.length; i++) {
1514
+ Event.stopObserving.apply(this, Event.observers[i]);
1515
+ Event.observers[i][0] = null;
1516
+ }
1517
+ Event.observers = false;
1518
+ },
1519
+
1520
+ observe: function(element, name, observer, useCapture) {
1521
+ var element = $(element);
1522
+ useCapture = useCapture || false;
1523
+
1524
+ if (name == 'keypress' &&
1525
+ (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
1526
+ || element.attachEvent))
1527
+ name = 'keydown';
1528
+
1529
+ this._observeAndCache(element, name, observer, useCapture);
1530
+ },
1531
+
1532
+ stopObserving: function(element, name, observer, useCapture) {
1533
+ var element = $(element);
1534
+ useCapture = useCapture || false;
1535
+
1536
+ if (name == 'keypress' &&
1537
+ (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
1538
+ || element.detachEvent))
1539
+ name = 'keydown';
1540
+
1541
+ if (element.removeEventListener) {
1542
+ element.removeEventListener(name, observer, useCapture);
1543
+ } else if (element.detachEvent) {
1544
+ element.detachEvent('on' + name, observer);
1545
+ }
1546
+ }
1547
+ });
1548
+
1549
+ /* prevent memory leaks in IE */
1550
+ Event.observe(window, 'unload', Event.unloadCache, false);
1551
+ var Position = {
1552
+ // set to true if needed, warning: firefox performance problems
1553
+ // NOT neeeded for page scrolling, only if draggable contained in
1554
+ // scrollable elements
1555
+ includeScrollOffsets: false,
1556
+
1557
+ // must be called before calling withinIncludingScrolloffset, every time the
1558
+ // page is scrolled
1559
+ prepare: function() {
1560
+ this.deltaX = window.pageXOffset
1561
+ || document.documentElement.scrollLeft
1562
+ || document.body.scrollLeft
1563
+ || 0;
1564
+ this.deltaY = window.pageYOffset
1565
+ || document.documentElement.scrollTop
1566
+ || document.body.scrollTop
1567
+ || 0;
1568
+ },
1569
+
1570
+ realOffset: function(element) {
1571
+ var valueT = 0, valueL = 0;
1572
+ do {
1573
+ valueT += element.scrollTop || 0;
1574
+ valueL += element.scrollLeft || 0;
1575
+ element = element.parentNode;
1576
+ } while (element);
1577
+ return [valueL, valueT];
1578
+ },
1579
+
1580
+ cumulativeOffset: function(element) {
1581
+ var valueT = 0, valueL = 0;
1582
+ do {
1583
+ valueT += element.offsetTop || 0;
1584
+ valueL += element.offsetLeft || 0;
1585
+ element = element.offsetParent;
1586
+ } while (element);
1587
+ return [valueL, valueT];
1588
+ },
1589
+
1590
+ positionedOffset: function(element) {
1591
+ var valueT = 0, valueL = 0;
1592
+ do {
1593
+ valueT += element.offsetTop || 0;
1594
+ valueL += element.offsetLeft || 0;
1595
+ element = element.offsetParent;
1596
+ if (element) {
1597
+ p = Element.getStyle(element, 'position');
1598
+ if (p == 'relative' || p == 'absolute') break;
1599
+ }
1600
+ } while (element);
1601
+ return [valueL, valueT];
1602
+ },
1603
+
1604
+ offsetParent: function(element) {
1605
+ if (element.offsetParent) return element.offsetParent;
1606
+ if (element == document.body) return element;
1607
+
1608
+ while ((element = element.parentNode) && element != document.body)
1609
+ if (Element.getStyle(element, 'position') != 'static')
1610
+ return element;
1611
+
1612
+ return document.body;
1613
+ },
1614
+
1615
+ // caches x/y coordinate pair to use with overlap
1616
+ within: function(element, x, y) {
1617
+ if (this.includeScrollOffsets)
1618
+ return this.withinIncludingScrolloffsets(element, x, y);
1619
+ this.xcomp = x;
1620
+ this.ycomp = y;
1621
+ this.offset = this.cumulativeOffset(element);
1622
+
1623
+ return (y >= this.offset[1] &&
1624
+ y < this.offset[1] + element.offsetHeight &&
1625
+ x >= this.offset[0] &&
1626
+ x < this.offset[0] + element.offsetWidth);
1627
+ },
1628
+
1629
+ withinIncludingScrolloffsets: function(element, x, y) {
1630
+ var offsetcache = this.realOffset(element);
1631
+
1632
+ this.xcomp = x + offsetcache[0] - this.deltaX;
1633
+ this.ycomp = y + offsetcache[1] - this.deltaY;
1634
+ this.offset = this.cumulativeOffset(element);
1635
+
1636
+ return (this.ycomp >= this.offset[1] &&
1637
+ this.ycomp < this.offset[1] + element.offsetHeight &&
1638
+ this.xcomp >= this.offset[0] &&
1639
+ this.xcomp < this.offset[0] + element.offsetWidth);
1640
+ },
1641
+
1642
+ // within must be called directly before
1643
+ overlap: function(mode, element) {
1644
+ if (!mode) return 0;
1645
+ if (mode == 'vertical')
1646
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
1647
+ element.offsetHeight;
1648
+ if (mode == 'horizontal')
1649
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
1650
+ element.offsetWidth;
1651
+ },
1652
+
1653
+ clone: function(source, target) {
1654
+ source = $(source);
1655
+ target = $(target);
1656
+ target.style.position = 'absolute';
1657
+ var offsets = this.cumulativeOffset(source);
1658
+ target.style.top = offsets[1] + 'px';
1659
+ target.style.left = offsets[0] + 'px';
1660
+ target.style.width = source.offsetWidth + 'px';
1661
+ target.style.height = source.offsetHeight + 'px';
1662
+ },
1663
+
1664
+ page: function(forElement) {
1665
+ var valueT = 0, valueL = 0;
1666
+
1667
+ var element = forElement;
1668
+ do {
1669
+ valueT += element.offsetTop || 0;
1670
+ valueL += element.offsetLeft || 0;
1671
+
1672
+ // Safari fix
1673
+ if (element.offsetParent==document.body)
1674
+ if (Element.getStyle(element,'position')=='absolute') break;
1675
+
1676
+ } while (element = element.offsetParent);
1677
+
1678
+ element = forElement;
1679
+ do {
1680
+ valueT -= element.scrollTop || 0;
1681
+ valueL -= element.scrollLeft || 0;
1682
+ } while (element = element.parentNode);
1683
+
1684
+ return [valueL, valueT];
1685
+ },
1686
+
1687
+ clone: function(source, target) {
1688
+ var options = Object.extend({
1689
+ setLeft: true,
1690
+ setTop: true,
1691
+ setWidth: true,
1692
+ setHeight: true,
1693
+ offsetTop: 0,
1694
+ offsetLeft: 0
1695
+ }, arguments[2] || {})
1696
+
1697
+ // find page position of source
1698
+ source = $(source);
1699
+ var p = Position.page(source);
1700
+
1701
+ // find coordinate system to use
1702
+ target = $(target);
1703
+ var delta = [0, 0];
1704
+ var parent = null;
1705
+ // delta [0,0] will do fine with position: fixed elements,
1706
+ // position:absolute needs offsetParent deltas
1707
+ if (Element.getStyle(target,'position') == 'absolute') {
1708
+ parent = Position.offsetParent(target);
1709
+ delta = Position.page(parent);
1710
+ }
1711
+
1712
+ // correct by body offsets (fixes Safari)
1713
+ if (parent == document.body) {
1714
+ delta[0] -= document.body.offsetLeft;
1715
+ delta[1] -= document.body.offsetTop;
1716
+ }
1717
+
1718
+ // set position
1719
+ if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
1720
+ if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
1721
+ if(options.setWidth) target.style.width = source.offsetWidth + 'px';
1722
+ if(options.setHeight) target.style.height = source.offsetHeight + 'px';
1723
+ },
1724
+
1725
+ absolutize: function(element) {
1726
+ element = $(element);
1727
+ if (element.style.position == 'absolute') return;
1728
+ Position.prepare();
1729
+
1730
+ var offsets = Position.positionedOffset(element);
1731
+ var top = offsets[1];
1732
+ var left = offsets[0];
1733
+ var width = element.clientWidth;
1734
+ var height = element.clientHeight;
1735
+
1736
+ element._originalLeft = left - parseFloat(element.style.left || 0);
1737
+ element._originalTop = top - parseFloat(element.style.top || 0);
1738
+ element._originalWidth = element.style.width;
1739
+ element._originalHeight = element.style.height;
1740
+
1741
+ element.style.position = 'absolute';
1742
+ element.style.top = top + 'px';;
1743
+ element.style.left = left + 'px';;
1744
+ element.style.width = width + 'px';;
1745
+ element.style.height = height + 'px';;
1746
+ },
1747
+
1748
+ relativize: function(element) {
1749
+ element = $(element);
1750
+ if (element.style.position == 'relative') return;
1751
+ Position.prepare();
1752
+
1753
+ element.style.position = 'relative';
1754
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
1755
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
1756
+
1757
+ element.style.top = top + 'px';
1758
+ element.style.left = left + 'px';
1759
+ element.style.height = element._originalHeight;
1760
+ element.style.width = element._originalWidth;
1761
+ }
1762
+ }
1763
+
1764
+ // Safari returns margins on body which is incorrect if the child is absolutely
1765
+ // positioned. For performance reasons, redefine Position.cumulativeOffset for
1766
+ // KHTML/WebKit only.
1767
+ if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
1768
+ Position.cumulativeOffset = function(element) {
1769
+ var valueT = 0, valueL = 0;
1770
+ do {
1771
+ valueT += element.offsetTop || 0;
1772
+ valueL += element.offsetLeft || 0;
1773
+ if (element.offsetParent == document.body)
1774
+ if (Element.getStyle(element, 'position') == 'absolute') break;
1775
+
1776
+ element = element.offsetParent;
1777
+ } while (element);
1778
+
1779
+ return [valueL, valueT];
1780
+ }
1781
+ }