equipment 0.1.0 → 1.4.84

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