insults 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4401 +0,0 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
- <html lang='en'>
3
- <head>
4
- <title>Methods [Insults will insult you when it feels you deserve it.]</title>
5
- <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
6
- <link href='rdoc-style.css' media='screen' rel='stylesheet' type='text/css'>
7
- <base target='docwin'>
8
- </head>
9
- <body class='list'>
10
- <div id='index'>
11
- <h1>Methods</h1>
12
- <script type='text/javascript'>
13
- /* Prototype JavaScript framework, version 1.6.0.3
14
- * (c) 2005-2008 Sam Stephenson
15
- *
16
- * Prototype is freely distributable under the terms of an MIT-style license.
17
- * For details, see the Prototype web site: http://www.prototypejs.org/
18
- *
19
- *--------------------------------------------------------------------------*/
20
-
21
- var Prototype = {
22
- Version: '1.6.0.3',
23
-
24
- Browser: {
25
- IE: !!(window.attachEvent &&
26
- navigator.userAgent.indexOf('Opera') === -1),
27
- Opera: navigator.userAgent.indexOf('Opera') > -1,
28
- WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
29
- Gecko: navigator.userAgent.indexOf('Gecko') > -1 &&
30
- navigator.userAgent.indexOf('KHTML') === -1,
31
- MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
32
- },
33
-
34
- BrowserFeatures: {
35
- XPath: !!document.evaluate,
36
- SelectorsAPI: !!document.querySelector,
37
- ElementExtensions: !!window.HTMLElement,
38
- SpecificElementExtensions:
39
- document.createElement('div')['__proto__'] &&
40
- document.createElement('div')['__proto__'] !==
41
- document.createElement('form')['__proto__']
42
- },
43
-
44
- ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
45
- JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
46
-
47
- emptyFunction: function() { },
48
- K: function(x) { return x }
49
- };
50
-
51
- if (Prototype.Browser.MobileSafari)
52
- Prototype.BrowserFeatures.SpecificElementExtensions = false;
53
-
54
-
55
- /* Based on Alex Arnell's inheritance implementation. */
56
- var Class = {
57
- create: function() {
58
- var parent = null, properties = $A(arguments);
59
- if (Object.isFunction(properties[0]))
60
- parent = properties.shift();
61
-
62
- function klass() {
63
- this.initialize.apply(this, arguments);
64
- }
65
-
66
- Object.extend(klass, Class.Methods);
67
- klass.superclass = parent;
68
- klass.subclasses = [];
69
-
70
- if (parent) {
71
- var subclass = function() { };
72
- subclass.prototype = parent.prototype;
73
- klass.prototype = new subclass;
74
- parent.subclasses.push(klass);
75
- }
76
-
77
- for (var i = 0; i < properties.length; i++)
78
- klass.addMethods(properties[i]);
79
-
80
- if (!klass.prototype.initialize)
81
- klass.prototype.initialize = Prototype.emptyFunction;
82
-
83
- klass.prototype.constructor = klass;
84
-
85
- return klass;
86
- }
87
- };
88
-
89
- Class.Methods = {
90
- addMethods: function(source) {
91
- var ancestor = this.superclass && this.superclass.prototype;
92
- var properties = Object.keys(source);
93
-
94
- if (!Object.keys({ toString: true }).length)
95
- properties.push("toString", "valueOf");
96
-
97
- for (var i = 0, length = properties.length; i < length; i++) {
98
- var property = properties[i], value = source[property];
99
- if (ancestor && Object.isFunction(value) &&
100
- value.argumentNames().first() == "$super") {
101
- var method = value;
102
- value = (function(m) {
103
- return function() { return ancestor[m].apply(this, arguments) };
104
- })(property).wrap(method);
105
-
106
- value.valueOf = method.valueOf.bind(method);
107
- value.toString = method.toString.bind(method);
108
- }
109
- this.prototype[property] = value;
110
- }
111
-
112
- return this;
113
- }
114
- };
115
-
116
- var Abstract = { };
117
-
118
- Object.extend = function(destination, source) {
119
- for (var property in source)
120
- destination[property] = source[property];
121
- return destination;
122
- };
123
-
124
- Object.extend(Object, {
125
- inspect: function(object) {
126
- try {
127
- if (Object.isUndefined(object)) return 'undefined';
128
- if (object === null) return 'null';
129
- return object.inspect ? object.inspect() : String(object);
130
- } catch (e) {
131
- if (e instanceof RangeError) return '...';
132
- throw e;
133
- }
134
- },
135
-
136
- toJSON: function(object) {
137
- var type = typeof object;
138
- switch (type) {
139
- case 'undefined':
140
- case 'function':
141
- case 'unknown': return;
142
- case 'boolean': return object.toString();
143
- }
144
-
145
- if (object === null) return 'null';
146
- if (object.toJSON) return object.toJSON();
147
- if (Object.isElement(object)) return;
148
-
149
- var results = [];
150
- for (var property in object) {
151
- var value = Object.toJSON(object[property]);
152
- if (!Object.isUndefined(value))
153
- results.push(property.toJSON() + ': ' + value);
154
- }
155
-
156
- return '{' + results.join(', ') + '}';
157
- },
158
-
159
- toQueryString: function(object) {
160
- return $H(object).toQueryString();
161
- },
162
-
163
- toHTML: function(object) {
164
- return object && object.toHTML ? object.toHTML() : String.interpret(object);
165
- },
166
-
167
- keys: function(object) {
168
- var keys = [];
169
- for (var property in object)
170
- keys.push(property);
171
- return keys;
172
- },
173
-
174
- values: function(object) {
175
- var values = [];
176
- for (var property in object)
177
- values.push(object[property]);
178
- return values;
179
- },
180
-
181
- clone: function(object) {
182
- return Object.extend({ }, object);
183
- },
184
-
185
- isElement: function(object) {
186
- return !!(object && object.nodeType == 1);
187
- },
188
-
189
- isArray: function(object) {
190
- return object != null && typeof object == "object" &&
191
- 'splice' in object && 'join' in object;
192
- },
193
-
194
- isHash: function(object) {
195
- return object instanceof Hash;
196
- },
197
-
198
- isFunction: function(object) {
199
- return typeof object == "function";
200
- },
201
-
202
- isString: function(object) {
203
- return typeof object == "string";
204
- },
205
-
206
- isNumber: function(object) {
207
- return typeof object == "number";
208
- },
209
-
210
- isUndefined: function(object) {
211
- return typeof object == "undefined";
212
- }
213
- });
214
-
215
- Object.extend(Function.prototype, {
216
- argumentNames: function() {
217
- var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
218
- .replace(/\s+/g, '').split(',');
219
- return names.length == 1 && !names[0] ? [] : names;
220
- },
221
-
222
- bind: function() {
223
- if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
224
- var __method = this, args = $A(arguments), object = args.shift();
225
- return function() {
226
- return __method.apply(object, args.concat($A(arguments)));
227
- }
228
- },
229
-
230
- bindAsEventListener: function() {
231
- var __method = this, args = $A(arguments), object = args.shift();
232
- return function(event) {
233
- return __method.apply(object, [event || window.event].concat(args));
234
- }
235
- },
236
-
237
- curry: function() {
238
- if (!arguments.length) return this;
239
- var __method = this, args = $A(arguments);
240
- return function() {
241
- return __method.apply(this, args.concat($A(arguments)));
242
- }
243
- },
244
-
245
- delay: function() {
246
- var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
247
- return window.setTimeout(function() {
248
- return __method.apply(__method, args);
249
- }, timeout);
250
- },
251
-
252
- defer: function() {
253
- var args = [0.01].concat($A(arguments));
254
- return this.delay.apply(this, args);
255
- },
256
-
257
- wrap: function(wrapper) {
258
- var __method = this;
259
- return function() {
260
- return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
261
- }
262
- },
263
-
264
- methodize: function() {
265
- if (this._methodized) return this._methodized;
266
- var __method = this;
267
- return this._methodized = function() {
268
- return __method.apply(null, [this].concat($A(arguments)));
269
- };
270
- }
271
- });
272
-
273
- Date.prototype.toJSON = function() {
274
- return '"' + this.getUTCFullYear() + '-' +
275
- (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
276
- this.getUTCDate().toPaddedString(2) + 'T' +
277
- this.getUTCHours().toPaddedString(2) + ':' +
278
- this.getUTCMinutes().toPaddedString(2) + ':' +
279
- this.getUTCSeconds().toPaddedString(2) + 'Z"';
280
- };
281
-
282
- var Try = {
283
- these: function() {
284
- var returnValue;
285
-
286
- for (var i = 0, length = arguments.length; i < length; i++) {
287
- var lambda = arguments[i];
288
- try {
289
- returnValue = lambda();
290
- break;
291
- } catch (e) { }
292
- }
293
-
294
- return returnValue;
295
- }
296
- };
297
-
298
- RegExp.prototype.match = RegExp.prototype.test;
299
-
300
- RegExp.escape = function(str) {
301
- return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
302
- };
303
-
304
- /*--------------------------------------------------------------------------*/
305
-
306
- var PeriodicalExecuter = Class.create({
307
- initialize: function(callback, frequency) {
308
- this.callback = callback;
309
- this.frequency = frequency;
310
- this.currentlyExecuting = false;
311
-
312
- this.registerCallback();
313
- },
314
-
315
- registerCallback: function() {
316
- this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
317
- },
318
-
319
- execute: function() {
320
- this.callback(this);
321
- },
322
-
323
- stop: function() {
324
- if (!this.timer) return;
325
- clearInterval(this.timer);
326
- this.timer = null;
327
- },
328
-
329
- onTimerEvent: function() {
330
- if (!this.currentlyExecuting) {
331
- try {
332
- this.currentlyExecuting = true;
333
- this.execute();
334
- } finally {
335
- this.currentlyExecuting = false;
336
- }
337
- }
338
- }
339
- });
340
- Object.extend(String, {
341
- interpret: function(value) {
342
- return value == null ? '' : String(value);
343
- },
344
- specialChar: {
345
- '\b': '\\b',
346
- '\t': '\\t',
347
- '\n': '\\n',
348
- '\f': '\\f',
349
- '\r': '\\r',
350
- '\\': '\\\\'
351
- }
352
- });
353
-
354
- Object.extend(String.prototype, {
355
- gsub: function(pattern, replacement) {
356
- var result = '', source = this, match;
357
- replacement = arguments.callee.prepareReplacement(replacement);
358
-
359
- while (source.length > 0) {
360
- if (match = source.match(pattern)) {
361
- result += source.slice(0, match.index);
362
- result += String.interpret(replacement(match));
363
- source = source.slice(match.index + match[0].length);
364
- } else {
365
- result += source, source = '';
366
- }
367
- }
368
- return result;
369
- },
370
-
371
- sub: function(pattern, replacement, count) {
372
- replacement = this.gsub.prepareReplacement(replacement);
373
- count = Object.isUndefined(count) ? 1 : count;
374
-
375
- return this.gsub(pattern, function(match) {
376
- if (--count < 0) return match[0];
377
- return replacement(match);
378
- });
379
- },
380
-
381
- scan: function(pattern, iterator) {
382
- this.gsub(pattern, iterator);
383
- return String(this);
384
- },
385
-
386
- truncate: function(length, truncation) {
387
- length = length || 30;
388
- truncation = Object.isUndefined(truncation) ? '...' : truncation;
389
- return this.length > length ?
390
- this.slice(0, length - truncation.length) + truncation : String(this);
391
- },
392
-
393
- strip: function() {
394
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
395
- },
396
-
397
- stripTags: function() {
398
- return this.replace(/<\/?[^>]+>/gi, '');
399
- },
400
-
401
- stripScripts: function() {
402
- return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
403
- },
404
-
405
- extractScripts: function() {
406
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
407
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
408
- return (this.match(matchAll) || []).map(function(scriptTag) {
409
- return (scriptTag.match(matchOne) || ['', ''])[1];
410
- });
411
- },
412
-
413
- evalScripts: function() {
414
- return this.extractScripts().map(function(script) { return eval(script) });
415
- },
416
-
417
- escapeHTML: function() {
418
- var self = arguments.callee;
419
- self.text.data = this;
420
- return self.div.innerHTML;
421
- },
422
-
423
- unescapeHTML: function() {
424
- var div = new Element('div');
425
- div.innerHTML = this.stripTags();
426
- return div.childNodes[0] ? (div.childNodes.length > 1 ?
427
- $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
428
- div.childNodes[0].nodeValue) : '';
429
- },
430
-
431
- toQueryParams: function(separator) {
432
- var match = this.strip().match(/([^?#]*)(#.*)?$/);
433
- if (!match) return { };
434
-
435
- return match[1].split(separator || '&').inject({ }, function(hash, pair) {
436
- if ((pair = pair.split('='))[0]) {
437
- var key = decodeURIComponent(pair.shift());
438
- var value = pair.length > 1 ? pair.join('=') : pair[0];
439
- if (value != undefined) value = decodeURIComponent(value);
440
-
441
- if (key in hash) {
442
- if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
443
- hash[key].push(value);
444
- }
445
- else hash[key] = value;
446
- }
447
- return hash;
448
- });
449
- },
450
-
451
- toArray: function() {
452
- return this.split('');
453
- },
454
-
455
- succ: function() {
456
- return this.slice(0, this.length - 1) +
457
- String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
458
- },
459
-
460
- times: function(count) {
461
- return count < 1 ? '' : new Array(count + 1).join(this);
462
- },
463
-
464
- camelize: function() {
465
- var parts = this.split('-'), len = parts.length;
466
- if (len == 1) return parts[0];
467
-
468
- var camelized = this.charAt(0) == '-'
469
- ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
470
- : parts[0];
471
-
472
- for (var i = 1; i < len; i++)
473
- camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
474
-
475
- return camelized;
476
- },
477
-
478
- capitalize: function() {
479
- return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
480
- },
481
-
482
- underscore: function() {
483
- return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
484
- },
485
-
486
- dasherize: function() {
487
- return this.gsub(/_/,'-');
488
- },
489
-
490
- inspect: function(useDoubleQuotes) {
491
- var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
492
- var character = String.specialChar[match[0]];
493
- return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
494
- });
495
- if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
496
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
497
- },
498
-
499
- toJSON: function() {
500
- return this.inspect(true);
501
- },
502
-
503
- unfilterJSON: function(filter) {
504
- return this.sub(filter || Prototype.JSONFilter, '#{1}');
505
- },
506
-
507
- isJSON: function() {
508
- var str = this;
509
- if (str.blank()) return false;
510
- str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
511
- return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
512
- },
513
-
514
- evalJSON: function(sanitize) {
515
- var json = this.unfilterJSON();
516
- try {
517
- if (!sanitize || json.isJSON()) return eval('(' + json + ')');
518
- } catch (e) { }
519
- throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
520
- },
521
-
522
- include: function(pattern) {
523
- return this.indexOf(pattern) > -1;
524
- },
525
-
526
- startsWith: function(pattern) {
527
- return this.indexOf(pattern) === 0;
528
- },
529
-
530
- endsWith: function(pattern) {
531
- var d = this.length - pattern.length;
532
- return d >= 0 && this.lastIndexOf(pattern) === d;
533
- },
534
-
535
- empty: function() {
536
- return this == '';
537
- },
538
-
539
- blank: function() {
540
- return /^\s*$/.test(this);
541
- },
542
-
543
- interpolate: function(object, pattern) {
544
- return new Template(this, pattern).evaluate(object);
545
- }
546
- });
547
-
548
- if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
549
- escapeHTML: function() {
550
- return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
551
- },
552
- unescapeHTML: function() {
553
- return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
554
- }
555
- });
556
-
557
- String.prototype.gsub.prepareReplacement = function(replacement) {
558
- if (Object.isFunction(replacement)) return replacement;
559
- var template = new Template(replacement);
560
- return function(match) { return template.evaluate(match) };
561
- };
562
-
563
- String.prototype.parseQuery = String.prototype.toQueryParams;
564
-
565
- Object.extend(String.prototype.escapeHTML, {
566
- div: document.createElement('div'),
567
- text: document.createTextNode('')
568
- });
569
-
570
- String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
571
-
572
- var Template = Class.create({
573
- initialize: function(template, pattern) {
574
- this.template = template.toString();
575
- this.pattern = pattern || Template.Pattern;
576
- },
577
-
578
- evaluate: function(object) {
579
- if (Object.isFunction(object.toTemplateReplacements))
580
- object = object.toTemplateReplacements();
581
-
582
- return this.template.gsub(this.pattern, function(match) {
583
- if (object == null) return '';
584
-
585
- var before = match[1] || '';
586
- if (before == '\\') return match[2];
587
-
588
- var ctx = object, expr = match[3];
589
- var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
590
- match = pattern.exec(expr);
591
- if (match == null) return before;
592
-
593
- while (match != null) {
594
- var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
595
- ctx = ctx[comp];
596
- if (null == ctx || '' == match[3]) break;
597
- expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
598
- match = pattern.exec(expr);
599
- }
600
-
601
- return before + String.interpret(ctx);
602
- });
603
- }
604
- });
605
- Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
606
-
607
- var $break = { };
608
-
609
- var Enumerable = {
610
- each: function(iterator, context) {
611
- var index = 0;
612
- try {
613
- this._each(function(value) {
614
- iterator.call(context, value, index++);
615
- });
616
- } catch (e) {
617
- if (e != $break) throw e;
618
- }
619
- return this;
620
- },
621
-
622
- eachSlice: function(number, iterator, context) {
623
- var index = -number, slices = [], array = this.toArray();
624
- if (number < 1) return array;
625
- while ((index += number) < array.length)
626
- slices.push(array.slice(index, index+number));
627
- return slices.collect(iterator, context);
628
- },
629
-
630
- all: function(iterator, context) {
631
- iterator = iterator || Prototype.K;
632
- var result = true;
633
- this.each(function(value, index) {
634
- result = result && !!iterator.call(context, value, index);
635
- if (!result) throw $break;
636
- });
637
- return result;
638
- },
639
-
640
- any: function(iterator, context) {
641
- iterator = iterator || Prototype.K;
642
- var result = false;
643
- this.each(function(value, index) {
644
- if (result = !!iterator.call(context, value, index))
645
- throw $break;
646
- });
647
- return result;
648
- },
649
-
650
- collect: function(iterator, context) {
651
- iterator = iterator || Prototype.K;
652
- var results = [];
653
- this.each(function(value, index) {
654
- results.push(iterator.call(context, value, index));
655
- });
656
- return results;
657
- },
658
-
659
- detect: function(iterator, context) {
660
- var result;
661
- this.each(function(value, index) {
662
- if (iterator.call(context, value, index)) {
663
- result = value;
664
- throw $break;
665
- }
666
- });
667
- return result;
668
- },
669
-
670
- findAll: function(iterator, context) {
671
- var results = [];
672
- this.each(function(value, index) {
673
- if (iterator.call(context, value, index))
674
- results.push(value);
675
- });
676
- return results;
677
- },
678
-
679
- grep: function(filter, iterator, context) {
680
- iterator = iterator || Prototype.K;
681
- var results = [];
682
-
683
- if (Object.isString(filter))
684
- filter = new RegExp(filter);
685
-
686
- this.each(function(value, index) {
687
- if (filter.match(value))
688
- results.push(iterator.call(context, value, index));
689
- });
690
- return results;
691
- },
692
-
693
- include: function(object) {
694
- if (Object.isFunction(this.indexOf))
695
- if (this.indexOf(object) != -1) return true;
696
-
697
- var found = false;
698
- this.each(function(value) {
699
- if (value == object) {
700
- found = true;
701
- throw $break;
702
- }
703
- });
704
- return found;
705
- },
706
-
707
- inGroupsOf: function(number, fillWith) {
708
- fillWith = Object.isUndefined(fillWith) ? null : fillWith;
709
- return this.eachSlice(number, function(slice) {
710
- while(slice.length < number) slice.push(fillWith);
711
- return slice;
712
- });
713
- },
714
-
715
- inject: function(memo, iterator, context) {
716
- this.each(function(value, index) {
717
- memo = iterator.call(context, memo, value, index);
718
- });
719
- return memo;
720
- },
721
-
722
- invoke: function(method) {
723
- var args = $A(arguments).slice(1);
724
- return this.map(function(value) {
725
- return value[method].apply(value, args);
726
- });
727
- },
728
-
729
- max: function(iterator, context) {
730
- iterator = iterator || Prototype.K;
731
- var result;
732
- this.each(function(value, index) {
733
- value = iterator.call(context, value, index);
734
- if (result == null || value >= result)
735
- result = value;
736
- });
737
- return result;
738
- },
739
-
740
- min: function(iterator, context) {
741
- iterator = iterator || Prototype.K;
742
- var result;
743
- this.each(function(value, index) {
744
- value = iterator.call(context, value, index);
745
- if (result == null || value < result)
746
- result = value;
747
- });
748
- return result;
749
- },
750
-
751
- partition: function(iterator, context) {
752
- iterator = iterator || Prototype.K;
753
- var trues = [], falses = [];
754
- this.each(function(value, index) {
755
- (iterator.call(context, value, index) ?
756
- trues : falses).push(value);
757
- });
758
- return [trues, falses];
759
- },
760
-
761
- pluck: function(property) {
762
- var results = [];
763
- this.each(function(value) {
764
- results.push(value[property]);
765
- });
766
- return results;
767
- },
768
-
769
- reject: function(iterator, context) {
770
- var results = [];
771
- this.each(function(value, index) {
772
- if (!iterator.call(context, value, index))
773
- results.push(value);
774
- });
775
- return results;
776
- },
777
-
778
- sortBy: function(iterator, context) {
779
- return this.map(function(value, index) {
780
- return {
781
- value: value,
782
- criteria: iterator.call(context, value, index)
783
- };
784
- }).sort(function(left, right) {
785
- var a = left.criteria, b = right.criteria;
786
- return a < b ? -1 : a > b ? 1 : 0;
787
- }).pluck('value');
788
- },
789
-
790
- toArray: function() {
791
- return this.map();
792
- },
793
-
794
- zip: function() {
795
- var iterator = Prototype.K, args = $A(arguments);
796
- if (Object.isFunction(args.last()))
797
- iterator = args.pop();
798
-
799
- var collections = [this].concat(args).map($A);
800
- return this.map(function(value, index) {
801
- return iterator(collections.pluck(index));
802
- });
803
- },
804
-
805
- size: function() {
806
- return this.toArray().length;
807
- },
808
-
809
- inspect: function() {
810
- return '#<Enumerable:' + this.toArray().inspect() + '>';
811
- }
812
- };
813
-
814
- Object.extend(Enumerable, {
815
- map: Enumerable.collect,
816
- find: Enumerable.detect,
817
- select: Enumerable.findAll,
818
- filter: Enumerable.findAll,
819
- member: Enumerable.include,
820
- entries: Enumerable.toArray,
821
- every: Enumerable.all,
822
- some: Enumerable.any
823
- });
824
- function $A(iterable) {
825
- if (!iterable) return [];
826
- if (iterable.toArray) return iterable.toArray();
827
- var length = iterable.length || 0, results = new Array(length);
828
- while (length--) results[length] = iterable[length];
829
- return results;
830
- }
831
-
832
- if (Prototype.Browser.WebKit) {
833
- $A = function(iterable) {
834
- if (!iterable) return [];
835
- // In Safari, only use the `toArray` method if it's not a NodeList.
836
- // A NodeList is a function, has an function `item` property, and a numeric
837
- // `length` property. Adapted from Google Doctype.
838
- if (!(typeof iterable === 'function' && typeof iterable.length ===
839
- 'number' && typeof iterable.item === 'function') && iterable.toArray)
840
- return iterable.toArray();
841
- var length = iterable.length || 0, results = new Array(length);
842
- while (length--) results[length] = iterable[length];
843
- return results;
844
- };
845
- }
846
-
847
- Array.from = $A;
848
-
849
- Object.extend(Array.prototype, Enumerable);
850
-
851
- if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
852
-
853
- Object.extend(Array.prototype, {
854
- _each: function(iterator) {
855
- for (var i = 0, length = this.length; i < length; i++)
856
- iterator(this[i]);
857
- },
858
-
859
- clear: function() {
860
- this.length = 0;
861
- return this;
862
- },
863
-
864
- first: function() {
865
- return this[0];
866
- },
867
-
868
- last: function() {
869
- return this[this.length - 1];
870
- },
871
-
872
- compact: function() {
873
- return this.select(function(value) {
874
- return value != null;
875
- });
876
- },
877
-
878
- flatten: function() {
879
- return this.inject([], function(array, value) {
880
- return array.concat(Object.isArray(value) ?
881
- value.flatten() : [value]);
882
- });
883
- },
884
-
885
- without: function() {
886
- var values = $A(arguments);
887
- return this.select(function(value) {
888
- return !values.include(value);
889
- });
890
- },
891
-
892
- reverse: function(inline) {
893
- return (inline !== false ? this : this.toArray())._reverse();
894
- },
895
-
896
- reduce: function() {
897
- return this.length > 1 ? this : this[0];
898
- },
899
-
900
- uniq: function(sorted) {
901
- return this.inject([], function(array, value, index) {
902
- if (0 == index || (sorted ? array.last() != value : !array.include(value)))
903
- array.push(value);
904
- return array;
905
- });
906
- },
907
-
908
- intersect: function(array) {
909
- return this.uniq().findAll(function(item) {
910
- return array.detect(function(value) { return item === value });
911
- });
912
- },
913
-
914
- clone: function() {
915
- return [].concat(this);
916
- },
917
-
918
- size: function() {
919
- return this.length;
920
- },
921
-
922
- inspect: function() {
923
- return '[' + this.map(Object.inspect).join(', ') + ']';
924
- },
925
-
926
- toJSON: function() {
927
- var results = [];
928
- this.each(function(object) {
929
- var value = Object.toJSON(object);
930
- if (!Object.isUndefined(value)) results.push(value);
931
- });
932
- return '[' + results.join(', ') + ']';
933
- }
934
- });
935
-
936
- // use native browser JS 1.6 implementation if available
937
- if (Object.isFunction(Array.prototype.forEach))
938
- Array.prototype._each = Array.prototype.forEach;
939
-
940
- if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
941
- i || (i = 0);
942
- var length = this.length;
943
- if (i < 0) i = length + i;
944
- for (; i < length; i++)
945
- if (this[i] === item) return i;
946
- return -1;
947
- };
948
-
949
- if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
950
- i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
951
- var n = this.slice(0, i).reverse().indexOf(item);
952
- return (n < 0) ? n : i - n - 1;
953
- };
954
-
955
- Array.prototype.toArray = Array.prototype.clone;
956
-
957
- function $w(string) {
958
- if (!Object.isString(string)) return [];
959
- string = string.strip();
960
- return string ? string.split(/\s+/) : [];
961
- }
962
-
963
- if (Prototype.Browser.Opera){
964
- Array.prototype.concat = function() {
965
- var array = [];
966
- for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
967
- for (var i = 0, length = arguments.length; i < length; i++) {
968
- if (Object.isArray(arguments[i])) {
969
- for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
970
- array.push(arguments[i][j]);
971
- } else {
972
- array.push(arguments[i]);
973
- }
974
- }
975
- return array;
976
- };
977
- }
978
- Object.extend(Number.prototype, {
979
- toColorPart: function() {
980
- return this.toPaddedString(2, 16);
981
- },
982
-
983
- succ: function() {
984
- return this + 1;
985
- },
986
-
987
- times: function(iterator, context) {
988
- $R(0, this, true).each(iterator, context);
989
- return this;
990
- },
991
-
992
- toPaddedString: function(length, radix) {
993
- var string = this.toString(radix || 10);
994
- return '0'.times(length - string.length) + string;
995
- },
996
-
997
- toJSON: function() {
998
- return isFinite(this) ? this.toString() : 'null';
999
- }
1000
- });
1001
-
1002
- $w('abs round ceil floor').each(function(method){
1003
- Number.prototype[method] = Math[method].methodize();
1004
- });
1005
- function $H(object) {
1006
- return new Hash(object);
1007
- };
1008
-
1009
- var Hash = Class.create(Enumerable, (function() {
1010
-
1011
- function toQueryPair(key, value) {
1012
- if (Object.isUndefined(value)) return key;
1013
- return key + '=' + encodeURIComponent(String.interpret(value));
1014
- }
1015
-
1016
- return {
1017
- initialize: function(object) {
1018
- this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1019
- },
1020
-
1021
- _each: function(iterator) {
1022
- for (var key in this._object) {
1023
- var value = this._object[key], pair = [key, value];
1024
- pair.key = key;
1025
- pair.value = value;
1026
- iterator(pair);
1027
- }
1028
- },
1029
-
1030
- set: function(key, value) {
1031
- return this._object[key] = value;
1032
- },
1033
-
1034
- get: function(key) {
1035
- // simulating poorly supported hasOwnProperty
1036
- if (this._object[key] !== Object.prototype[key])
1037
- return this._object[key];
1038
- },
1039
-
1040
- unset: function(key) {
1041
- var value = this._object[key];
1042
- delete this._object[key];
1043
- return value;
1044
- },
1045
-
1046
- toObject: function() {
1047
- return Object.clone(this._object);
1048
- },
1049
-
1050
- keys: function() {
1051
- return this.pluck('key');
1052
- },
1053
-
1054
- values: function() {
1055
- return this.pluck('value');
1056
- },
1057
-
1058
- index: function(value) {
1059
- var match = this.detect(function(pair) {
1060
- return pair.value === value;
1061
- });
1062
- return match && match.key;
1063
- },
1064
-
1065
- merge: function(object) {
1066
- return this.clone().update(object);
1067
- },
1068
-
1069
- update: function(object) {
1070
- return new Hash(object).inject(this, function(result, pair) {
1071
- result.set(pair.key, pair.value);
1072
- return result;
1073
- });
1074
- },
1075
-
1076
- toQueryString: function() {
1077
- return this.inject([], function(results, pair) {
1078
- var key = encodeURIComponent(pair.key), values = pair.value;
1079
-
1080
- if (values && typeof values == 'object') {
1081
- if (Object.isArray(values))
1082
- return results.concat(values.map(toQueryPair.curry(key)));
1083
- } else results.push(toQueryPair(key, values));
1084
- return results;
1085
- }).join('&');
1086
- },
1087
-
1088
- inspect: function() {
1089
- return '#<Hash:{' + this.map(function(pair) {
1090
- return pair.map(Object.inspect).join(': ');
1091
- }).join(', ') + '}>';
1092
- },
1093
-
1094
- toJSON: function() {
1095
- return Object.toJSON(this.toObject());
1096
- },
1097
-
1098
- clone: function() {
1099
- return new Hash(this);
1100
- }
1101
- }
1102
- })());
1103
-
1104
- Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
1105
- Hash.from = $H;
1106
- var ObjectRange = Class.create(Enumerable, {
1107
- initialize: function(start, end, exclusive) {
1108
- this.start = start;
1109
- this.end = end;
1110
- this.exclusive = exclusive;
1111
- },
1112
-
1113
- _each: function(iterator) {
1114
- var value = this.start;
1115
- while (this.include(value)) {
1116
- iterator(value);
1117
- value = value.succ();
1118
- }
1119
- },
1120
-
1121
- include: function(value) {
1122
- if (value < this.start)
1123
- return false;
1124
- if (this.exclusive)
1125
- return value < this.end;
1126
- return value <= this.end;
1127
- }
1128
- });
1129
-
1130
- var $R = function(start, end, exclusive) {
1131
- return new ObjectRange(start, end, exclusive);
1132
- };
1133
-
1134
- var Ajax = {
1135
- getTransport: function() {
1136
- return Try.these(
1137
- function() {return new XMLHttpRequest()},
1138
- function() {return new ActiveXObject('Msxml2.XMLHTTP')},
1139
- function() {return new ActiveXObject('Microsoft.XMLHTTP')}
1140
- ) || false;
1141
- },
1142
-
1143
- activeRequestCount: 0
1144
- };
1145
-
1146
- Ajax.Responders = {
1147
- responders: [],
1148
-
1149
- _each: function(iterator) {
1150
- this.responders._each(iterator);
1151
- },
1152
-
1153
- register: function(responder) {
1154
- if (!this.include(responder))
1155
- this.responders.push(responder);
1156
- },
1157
-
1158
- unregister: function(responder) {
1159
- this.responders = this.responders.without(responder);
1160
- },
1161
-
1162
- dispatch: function(callback, request, transport, json) {
1163
- this.each(function(responder) {
1164
- if (Object.isFunction(responder[callback])) {
1165
- try {
1166
- responder[callback].apply(responder, [request, transport, json]);
1167
- } catch (e) { }
1168
- }
1169
- });
1170
- }
1171
- };
1172
-
1173
- Object.extend(Ajax.Responders, Enumerable);
1174
-
1175
- Ajax.Responders.register({
1176
- onCreate: function() { Ajax.activeRequestCount++ },
1177
- onComplete: function() { Ajax.activeRequestCount-- }
1178
- });
1179
-
1180
- Ajax.Base = Class.create({
1181
- initialize: function(options) {
1182
- this.options = {
1183
- method: 'post',
1184
- asynchronous: true,
1185
- contentType: 'application/x-www-form-urlencoded',
1186
- encoding: 'UTF-8',
1187
- parameters: '',
1188
- evalJSON: true,
1189
- evalJS: true
1190
- };
1191
- Object.extend(this.options, options || { });
1192
-
1193
- this.options.method = this.options.method.toLowerCase();
1194
-
1195
- if (Object.isString(this.options.parameters))
1196
- this.options.parameters = this.options.parameters.toQueryParams();
1197
- else if (Object.isHash(this.options.parameters))
1198
- this.options.parameters = this.options.parameters.toObject();
1199
- }
1200
- });
1201
-
1202
- Ajax.Request = Class.create(Ajax.Base, {
1203
- _complete: false,
1204
-
1205
- initialize: function($super, url, options) {
1206
- $super(options);
1207
- this.transport = Ajax.getTransport();
1208
- this.request(url);
1209
- },
1210
-
1211
- request: function(url) {
1212
- this.url = url;
1213
- this.method = this.options.method;
1214
- var params = Object.clone(this.options.parameters);
1215
-
1216
- if (!['get', 'post'].include(this.method)) {
1217
- // simulate other verbs over post
1218
- params['_method'] = this.method;
1219
- this.method = 'post';
1220
- }
1221
-
1222
- this.parameters = params;
1223
-
1224
- if (params = Object.toQueryString(params)) {
1225
- // when GET, append parameters to URL
1226
- if (this.method == 'get')
1227
- this.url += (this.url.include('?') ? '&' : '?') + params;
1228
- else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
1229
- params += '&_=';
1230
- }
1231
-
1232
- try {
1233
- var response = new Ajax.Response(this);
1234
- if (this.options.onCreate) this.options.onCreate(response);
1235
- Ajax.Responders.dispatch('onCreate', this, response);
1236
-
1237
- this.transport.open(this.method.toUpperCase(), this.url,
1238
- this.options.asynchronous);
1239
-
1240
- if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
1241
-
1242
- this.transport.onreadystatechange = this.onStateChange.bind(this);
1243
- this.setRequestHeaders();
1244
-
1245
- this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1246
- this.transport.send(this.body);
1247
-
1248
- /* Force Firefox to handle ready state 4 for synchronous requests */
1249
- if (!this.options.asynchronous && this.transport.overrideMimeType)
1250
- this.onStateChange();
1251
-
1252
- }
1253
- catch (e) {
1254
- this.dispatchException(e);
1255
- }
1256
- },
1257
-
1258
- onStateChange: function() {
1259
- var readyState = this.transport.readyState;
1260
- if (readyState > 1 && !((readyState == 4) && this._complete))
1261
- this.respondToReadyState(this.transport.readyState);
1262
- },
1263
-
1264
- setRequestHeaders: function() {
1265
- var headers = {
1266
- 'X-Requested-With': 'XMLHttpRequest',
1267
- 'X-Prototype-Version': Prototype.Version,
1268
- 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1269
- };
1270
-
1271
- if (this.method == 'post') {
1272
- headers['Content-type'] = this.options.contentType +
1273
- (this.options.encoding ? '; charset=' + this.options.encoding : '');
1274
-
1275
- /* Force "Connection: close" for older Mozilla browsers to work
1276
- * around a bug where XMLHttpRequest sends an incorrect
1277
- * Content-length header. See Mozilla Bugzilla #246651.
1278
- */
1279
- if (this.transport.overrideMimeType &&
1280
- (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1281
- headers['Connection'] = 'close';
1282
- }
1283
-
1284
- // user-defined headers
1285
- if (typeof this.options.requestHeaders == 'object') {
1286
- var extras = this.options.requestHeaders;
1287
-
1288
- if (Object.isFunction(extras.push))
1289
- for (var i = 0, length = extras.length; i < length; i += 2)
1290
- headers[extras[i]] = extras[i+1];
1291
- else
1292
- $H(extras).each(function(pair) { headers[pair.key] = pair.value });
1293
- }
1294
-
1295
- for (var name in headers)
1296
- this.transport.setRequestHeader(name, headers[name]);
1297
- },
1298
-
1299
- success: function() {
1300
- var status = this.getStatus();
1301
- return !status || (status >= 200 && status < 300);
1302
- },
1303
-
1304
- getStatus: function() {
1305
- try {
1306
- return this.transport.status || 0;
1307
- } catch (e) { return 0 }
1308
- },
1309
-
1310
- respondToReadyState: function(readyState) {
1311
- var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
1312
-
1313
- if (state == 'Complete') {
1314
- try {
1315
- this._complete = true;
1316
- (this.options['on' + response.status]
1317
- || this.options['on' + (this.success() ? 'Success' : 'Failure')]
1318
- || Prototype.emptyFunction)(response, response.headerJSON);
1319
- } catch (e) {
1320
- this.dispatchException(e);
1321
- }
1322
-
1323
- var contentType = response.getHeader('Content-type');
1324
- if (this.options.evalJS == 'force'
1325
- || (this.options.evalJS && this.isSameOrigin() && contentType
1326
- && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1327
- this.evalResponse();
1328
- }
1329
-
1330
- try {
1331
- (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
1332
- Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
1333
- } catch (e) {
1334
- this.dispatchException(e);
1335
- }
1336
-
1337
- if (state == 'Complete') {
1338
- // avoid memory leak in MSIE: clean up
1339
- this.transport.onreadystatechange = Prototype.emptyFunction;
1340
- }
1341
- },
1342
-
1343
- isSameOrigin: function() {
1344
- var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1345
- return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
1346
- protocol: location.protocol,
1347
- domain: document.domain,
1348
- port: location.port ? ':' + location.port : ''
1349
- }));
1350
- },
1351
-
1352
- getHeader: function(name) {
1353
- try {
1354
- return this.transport.getResponseHeader(name) || null;
1355
- } catch (e) { return null }
1356
- },
1357
-
1358
- evalResponse: function() {
1359
- try {
1360
- return eval((this.transport.responseText || '').unfilterJSON());
1361
- } catch (e) {
1362
- this.dispatchException(e);
1363
- }
1364
- },
1365
-
1366
- dispatchException: function(exception) {
1367
- (this.options.onException || Prototype.emptyFunction)(this, exception);
1368
- Ajax.Responders.dispatch('onException', this, exception);
1369
- }
1370
- });
1371
-
1372
- Ajax.Request.Events =
1373
- ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1374
-
1375
- Ajax.Response = Class.create({
1376
- initialize: function(request){
1377
- this.request = request;
1378
- var transport = this.transport = request.transport,
1379
- readyState = this.readyState = transport.readyState;
1380
-
1381
- if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1382
- this.status = this.getStatus();
1383
- this.statusText = this.getStatusText();
1384
- this.responseText = String.interpret(transport.responseText);
1385
- this.headerJSON = this._getHeaderJSON();
1386
- }
1387
-
1388
- if(readyState == 4) {
1389
- var xml = transport.responseXML;
1390
- this.responseXML = Object.isUndefined(xml) ? null : xml;
1391
- this.responseJSON = this._getResponseJSON();
1392
- }
1393
- },
1394
-
1395
- status: 0,
1396
- statusText: '',
1397
-
1398
- getStatus: Ajax.Request.prototype.getStatus,
1399
-
1400
- getStatusText: function() {
1401
- try {
1402
- return this.transport.statusText || '';
1403
- } catch (e) { return '' }
1404
- },
1405
-
1406
- getHeader: Ajax.Request.prototype.getHeader,
1407
-
1408
- getAllHeaders: function() {
1409
- try {
1410
- return this.getAllResponseHeaders();
1411
- } catch (e) { return null }
1412
- },
1413
-
1414
- getResponseHeader: function(name) {
1415
- return this.transport.getResponseHeader(name);
1416
- },
1417
-
1418
- getAllResponseHeaders: function() {
1419
- return this.transport.getAllResponseHeaders();
1420
- },
1421
-
1422
- _getHeaderJSON: function() {
1423
- var json = this.getHeader('X-JSON');
1424
- if (!json) return null;
1425
- json = decodeURIComponent(escape(json));
1426
- try {
1427
- return json.evalJSON(this.request.options.sanitizeJSON ||
1428
- !this.request.isSameOrigin());
1429
- } catch (e) {
1430
- this.request.dispatchException(e);
1431
- }
1432
- },
1433
-
1434
- _getResponseJSON: function() {
1435
- var options = this.request.options;
1436
- if (!options.evalJSON || (options.evalJSON != 'force' &&
1437
- !(this.getHeader('Content-type') || '').include('application/json')) ||
1438
- this.responseText.blank())
1439
- return null;
1440
- try {
1441
- return this.responseText.evalJSON(options.sanitizeJSON ||
1442
- !this.request.isSameOrigin());
1443
- } catch (e) {
1444
- this.request.dispatchException(e);
1445
- }
1446
- }
1447
- });
1448
-
1449
- Ajax.Updater = Class.create(Ajax.Request, {
1450
- initialize: function($super, container, url, options) {
1451
- this.container = {
1452
- success: (container.success || container),
1453
- failure: (container.failure || (container.success ? null : container))
1454
- };
1455
-
1456
- options = Object.clone(options);
1457
- var onComplete = options.onComplete;
1458
- options.onComplete = (function(response, json) {
1459
- this.updateContent(response.responseText);
1460
- if (Object.isFunction(onComplete)) onComplete(response, json);
1461
- }).bind(this);
1462
-
1463
- $super(url, options);
1464
- },
1465
-
1466
- updateContent: function(responseText) {
1467
- var receiver = this.container[this.success() ? 'success' : 'failure'],
1468
- options = this.options;
1469
-
1470
- if (!options.evalScripts) responseText = responseText.stripScripts();
1471
-
1472
- if (receiver = $(receiver)) {
1473
- if (options.insertion) {
1474
- if (Object.isString(options.insertion)) {
1475
- var insertion = { }; insertion[options.insertion] = responseText;
1476
- receiver.insert(insertion);
1477
- }
1478
- else options.insertion(receiver, responseText);
1479
- }
1480
- else receiver.update(responseText);
1481
- }
1482
- }
1483
- });
1484
-
1485
- Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
1486
- initialize: function($super, container, url, options) {
1487
- $super(options);
1488
- this.onComplete = this.options.onComplete;
1489
-
1490
- this.frequency = (this.options.frequency || 2);
1491
- this.decay = (this.options.decay || 1);
1492
-
1493
- this.updater = { };
1494
- this.container = container;
1495
- this.url = url;
1496
-
1497
- this.start();
1498
- },
1499
-
1500
- start: function() {
1501
- this.options.onComplete = this.updateComplete.bind(this);
1502
- this.onTimerEvent();
1503
- },
1504
-
1505
- stop: function() {
1506
- this.updater.options.onComplete = undefined;
1507
- clearTimeout(this.timer);
1508
- (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
1509
- },
1510
-
1511
- updateComplete: function(response) {
1512
- if (this.options.decay) {
1513
- this.decay = (response.responseText == this.lastText ?
1514
- this.decay * this.options.decay : 1);
1515
-
1516
- this.lastText = response.responseText;
1517
- }
1518
- this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
1519
- },
1520
-
1521
- onTimerEvent: function() {
1522
- this.updater = new Ajax.Updater(this.container, this.url, this.options);
1523
- }
1524
- });
1525
- function $(element) {
1526
- if (arguments.length > 1) {
1527
- for (var i = 0, elements = [], length = arguments.length; i < length; i++)
1528
- elements.push($(arguments[i]));
1529
- return elements;
1530
- }
1531
- if (Object.isString(element))
1532
- element = document.getElementById(element);
1533
- return Element.extend(element);
1534
- }
1535
-
1536
- if (Prototype.BrowserFeatures.XPath) {
1537
- document._getElementsByXPath = function(expression, parentElement) {
1538
- var results = [];
1539
- var query = document.evaluate(expression, $(parentElement) || document,
1540
- null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1541
- for (var i = 0, length = query.snapshotLength; i < length; i++)
1542
- results.push(Element.extend(query.snapshotItem(i)));
1543
- return results;
1544
- };
1545
- }
1546
-
1547
- /*--------------------------------------------------------------------------*/
1548
-
1549
- if (!window.Node) var Node = { };
1550
-
1551
- if (!Node.ELEMENT_NODE) {
1552
- // DOM level 2 ECMAScript Language Binding
1553
- Object.extend(Node, {
1554
- ELEMENT_NODE: 1,
1555
- ATTRIBUTE_NODE: 2,
1556
- TEXT_NODE: 3,
1557
- CDATA_SECTION_NODE: 4,
1558
- ENTITY_REFERENCE_NODE: 5,
1559
- ENTITY_NODE: 6,
1560
- PROCESSING_INSTRUCTION_NODE: 7,
1561
- COMMENT_NODE: 8,
1562
- DOCUMENT_NODE: 9,
1563
- DOCUMENT_TYPE_NODE: 10,
1564
- DOCUMENT_FRAGMENT_NODE: 11,
1565
- NOTATION_NODE: 12
1566
- });
1567
- }
1568
-
1569
- (function() {
1570
- var element = this.Element;
1571
- this.Element = function(tagName, attributes) {
1572
- attributes = attributes || { };
1573
- tagName = tagName.toLowerCase();
1574
- var cache = Element.cache;
1575
- if (Prototype.Browser.IE && attributes.name) {
1576
- tagName = '<' + tagName + ' name="' + attributes.name + '">';
1577
- delete attributes.name;
1578
- return Element.writeAttribute(document.createElement(tagName), attributes);
1579
- }
1580
- if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
1581
- return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
1582
- };
1583
- Object.extend(this.Element, element || { });
1584
- if (element) this.Element.prototype = element.prototype;
1585
- }).call(window);
1586
-
1587
- Element.cache = { };
1588
-
1589
- Element.Methods = {
1590
- visible: function(element) {
1591
- return $(element).style.display != 'none';
1592
- },
1593
-
1594
- toggle: function(element) {
1595
- element = $(element);
1596
- Element[Element.visible(element) ? 'hide' : 'show'](element);
1597
- return element;
1598
- },
1599
-
1600
- hide: function(element) {
1601
- element = $(element);
1602
- element.style.display = 'none';
1603
- return element;
1604
- },
1605
-
1606
- show: function(element) {
1607
- element = $(element);
1608
- element.style.display = '';
1609
- return element;
1610
- },
1611
-
1612
- remove: function(element) {
1613
- element = $(element);
1614
- element.parentNode.removeChild(element);
1615
- return element;
1616
- },
1617
-
1618
- update: function(element, content) {
1619
- element = $(element);
1620
- if (content && content.toElement) content = content.toElement();
1621
- if (Object.isElement(content)) return element.update().insert(content);
1622
- content = Object.toHTML(content);
1623
- element.innerHTML = content.stripScripts();
1624
- content.evalScripts.bind(content).defer();
1625
- return element;
1626
- },
1627
-
1628
- replace: function(element, content) {
1629
- element = $(element);
1630
- if (content && content.toElement) content = content.toElement();
1631
- else if (!Object.isElement(content)) {
1632
- content = Object.toHTML(content);
1633
- var range = element.ownerDocument.createRange();
1634
- range.selectNode(element);
1635
- content.evalScripts.bind(content).defer();
1636
- content = range.createContextualFragment(content.stripScripts());
1637
- }
1638
- element.parentNode.replaceChild(content, element);
1639
- return element;
1640
- },
1641
-
1642
- insert: function(element, insertions) {
1643
- element = $(element);
1644
-
1645
- if (Object.isString(insertions) || Object.isNumber(insertions) ||
1646
- Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
1647
- insertions = {bottom:insertions};
1648
-
1649
- var content, insert, tagName, childNodes;
1650
-
1651
- for (var position in insertions) {
1652
- content = insertions[position];
1653
- position = position.toLowerCase();
1654
- insert = Element._insertionTranslations[position];
1655
-
1656
- if (content && content.toElement) content = content.toElement();
1657
- if (Object.isElement(content)) {
1658
- insert(element, content);
1659
- continue;
1660
- }
1661
-
1662
- content = Object.toHTML(content);
1663
-
1664
- tagName = ((position == 'before' || position == 'after')
1665
- ? element.parentNode : element).tagName.toUpperCase();
1666
-
1667
- childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
1668
-
1669
- if (position == 'top' || position == 'after') childNodes.reverse();
1670
- childNodes.each(insert.curry(element));
1671
-
1672
- content.evalScripts.bind(content).defer();
1673
- }
1674
-
1675
- return element;
1676
- },
1677
-
1678
- wrap: function(element, wrapper, attributes) {
1679
- element = $(element);
1680
- if (Object.isElement(wrapper))
1681
- $(wrapper).writeAttribute(attributes || { });
1682
- else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
1683
- else wrapper = new Element('div', wrapper);
1684
- if (element.parentNode)
1685
- element.parentNode.replaceChild(wrapper, element);
1686
- wrapper.appendChild(element);
1687
- return wrapper;
1688
- },
1689
-
1690
- inspect: function(element) {
1691
- element = $(element);
1692
- var result = '<' + element.tagName.toLowerCase();
1693
- $H({'id': 'id', 'className': 'class'}).each(function(pair) {
1694
- var property = pair.first(), attribute = pair.last();
1695
- var value = (element[property] || '').toString();
1696
- if (value) result += ' ' + attribute + '=' + value.inspect(true);
1697
- });
1698
- return result + '>';
1699
- },
1700
-
1701
- recursivelyCollect: function(element, property) {
1702
- element = $(element);
1703
- var elements = [];
1704
- while (element = element[property])
1705
- if (element.nodeType == 1)
1706
- elements.push(Element.extend(element));
1707
- return elements;
1708
- },
1709
-
1710
- ancestors: function(element) {
1711
- return $(element).recursivelyCollect('parentNode');
1712
- },
1713
-
1714
- descendants: function(element) {
1715
- return $(element).select("*");
1716
- },
1717
-
1718
- firstDescendant: function(element) {
1719
- element = $(element).firstChild;
1720
- while (element && element.nodeType != 1) element = element.nextSibling;
1721
- return $(element);
1722
- },
1723
-
1724
- immediateDescendants: function(element) {
1725
- if (!(element = $(element).firstChild)) return [];
1726
- while (element && element.nodeType != 1) element = element.nextSibling;
1727
- if (element) return [element].concat($(element).nextSiblings());
1728
- return [];
1729
- },
1730
-
1731
- previousSiblings: function(element) {
1732
- return $(element).recursivelyCollect('previousSibling');
1733
- },
1734
-
1735
- nextSiblings: function(element) {
1736
- return $(element).recursivelyCollect('nextSibling');
1737
- },
1738
-
1739
- siblings: function(element) {
1740
- element = $(element);
1741
- return element.previousSiblings().reverse().concat(element.nextSiblings());
1742
- },
1743
-
1744
- match: function(element, selector) {
1745
- if (Object.isString(selector))
1746
- selector = new Selector(selector);
1747
- return selector.match($(element));
1748
- },
1749
-
1750
- up: function(element, expression, index) {
1751
- element = $(element);
1752
- if (arguments.length == 1) return $(element.parentNode);
1753
- var ancestors = element.ancestors();
1754
- return Object.isNumber(expression) ? ancestors[expression] :
1755
- Selector.findElement(ancestors, expression, index);
1756
- },
1757
-
1758
- down: function(element, expression, index) {
1759
- element = $(element);
1760
- if (arguments.length == 1) return element.firstDescendant();
1761
- return Object.isNumber(expression) ? element.descendants()[expression] :
1762
- Element.select(element, expression)[index || 0];
1763
- },
1764
-
1765
- previous: function(element, expression, index) {
1766
- element = $(element);
1767
- if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
1768
- var previousSiblings = element.previousSiblings();
1769
- return Object.isNumber(expression) ? previousSiblings[expression] :
1770
- Selector.findElement(previousSiblings, expression, index);
1771
- },
1772
-
1773
- next: function(element, expression, index) {
1774
- element = $(element);
1775
- if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
1776
- var nextSiblings = element.nextSiblings();
1777
- return Object.isNumber(expression) ? nextSiblings[expression] :
1778
- Selector.findElement(nextSiblings, expression, index);
1779
- },
1780
-
1781
- select: function() {
1782
- var args = $A(arguments), element = $(args.shift());
1783
- return Selector.findChildElements(element, args);
1784
- },
1785
-
1786
- adjacent: function() {
1787
- var args = $A(arguments), element = $(args.shift());
1788
- return Selector.findChildElements(element.parentNode, args).without(element);
1789
- },
1790
-
1791
- identify: function(element) {
1792
- element = $(element);
1793
- var id = element.readAttribute('id'), self = arguments.callee;
1794
- if (id) return id;
1795
- do { id = 'anonymous_element_' + self.counter++ } while ($(id));
1796
- element.writeAttribute('id', id);
1797
- return id;
1798
- },
1799
-
1800
- readAttribute: function(element, name) {
1801
- element = $(element);
1802
- if (Prototype.Browser.IE) {
1803
- var t = Element._attributeTranslations.read;
1804
- if (t.values[name]) return t.values[name](element, name);
1805
- if (t.names[name]) name = t.names[name];
1806
- if (name.include(':')) {
1807
- return (!element.attributes || !element.attributes[name]) ? null :
1808
- element.attributes[name].value;
1809
- }
1810
- }
1811
- return element.getAttribute(name);
1812
- },
1813
-
1814
- writeAttribute: function(element, name, value) {
1815
- element = $(element);
1816
- var attributes = { }, t = Element._attributeTranslations.write;
1817
-
1818
- if (typeof name == 'object') attributes = name;
1819
- else attributes[name] = Object.isUndefined(value) ? true : value;
1820
-
1821
- for (var attr in attributes) {
1822
- name = t.names[attr] || attr;
1823
- value = attributes[attr];
1824
- if (t.values[attr]) name = t.values[attr](element, value);
1825
- if (value === false || value === null)
1826
- element.removeAttribute(name);
1827
- else if (value === true)
1828
- element.setAttribute(name, name);
1829
- else element.setAttribute(name, value);
1830
- }
1831
- return element;
1832
- },
1833
-
1834
- getHeight: function(element) {
1835
- return $(element).getDimensions().height;
1836
- },
1837
-
1838
- getWidth: function(element) {
1839
- return $(element).getDimensions().width;
1840
- },
1841
-
1842
- classNames: function(element) {
1843
- return new Element.ClassNames(element);
1844
- },
1845
-
1846
- hasClassName: function(element, className) {
1847
- if (!(element = $(element))) return;
1848
- var elementClassName = element.className;
1849
- return (elementClassName.length > 0 && (elementClassName == className ||
1850
- new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
1851
- },
1852
-
1853
- addClassName: function(element, className) {
1854
- if (!(element = $(element))) return;
1855
- if (!element.hasClassName(className))
1856
- element.className += (element.className ? ' ' : '') + className;
1857
- return element;
1858
- },
1859
-
1860
- removeClassName: function(element, className) {
1861
- if (!(element = $(element))) return;
1862
- element.className = element.className.replace(
1863
- new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
1864
- return element;
1865
- },
1866
-
1867
- toggleClassName: function(element, className) {
1868
- if (!(element = $(element))) return;
1869
- return element[element.hasClassName(className) ?
1870
- 'removeClassName' : 'addClassName'](className);
1871
- },
1872
-
1873
- // removes whitespace-only text node children
1874
- cleanWhitespace: function(element) {
1875
- element = $(element);
1876
- var node = element.firstChild;
1877
- while (node) {
1878
- var nextNode = node.nextSibling;
1879
- if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
1880
- element.removeChild(node);
1881
- node = nextNode;
1882
- }
1883
- return element;
1884
- },
1885
-
1886
- empty: function(element) {
1887
- return $(element).innerHTML.blank();
1888
- },
1889
-
1890
- descendantOf: function(element, ancestor) {
1891
- element = $(element), ancestor = $(ancestor);
1892
-
1893
- if (element.compareDocumentPosition)
1894
- return (element.compareDocumentPosition(ancestor) & 8) === 8;
1895
-
1896
- if (ancestor.contains)
1897
- return ancestor.contains(element) && ancestor !== element;
1898
-
1899
- while (element = element.parentNode)
1900
- if (element == ancestor) return true;
1901
-
1902
- return false;
1903
- },
1904
-
1905
- scrollTo: function(element) {
1906
- element = $(element);
1907
- var pos = element.cumulativeOffset();
1908
- window.scrollTo(pos[0], pos[1]);
1909
- return element;
1910
- },
1911
-
1912
- getStyle: function(element, style) {
1913
- element = $(element);
1914
- style = style == 'float' ? 'cssFloat' : style.camelize();
1915
- var value = element.style[style];
1916
- if (!value || value == 'auto') {
1917
- var css = document.defaultView.getComputedStyle(element, null);
1918
- value = css ? css[style] : null;
1919
- }
1920
- if (style == 'opacity') return value ? parseFloat(value) : 1.0;
1921
- return value == 'auto' ? null : value;
1922
- },
1923
-
1924
- getOpacity: function(element) {
1925
- return $(element).getStyle('opacity');
1926
- },
1927
-
1928
- setStyle: function(element, styles) {
1929
- element = $(element);
1930
- var elementStyle = element.style, match;
1931
- if (Object.isString(styles)) {
1932
- element.style.cssText += ';' + styles;
1933
- return styles.include('opacity') ?
1934
- element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
1935
- }
1936
- for (var property in styles)
1937
- if (property == 'opacity') element.setOpacity(styles[property]);
1938
- else
1939
- elementStyle[(property == 'float' || property == 'cssFloat') ?
1940
- (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
1941
- property] = styles[property];
1942
-
1943
- return element;
1944
- },
1945
-
1946
- setOpacity: function(element, value) {
1947
- element = $(element);
1948
- element.style.opacity = (value == 1 || value === '') ? '' :
1949
- (value < 0.00001) ? 0 : value;
1950
- return element;
1951
- },
1952
-
1953
- getDimensions: function(element) {
1954
- element = $(element);
1955
- var display = element.getStyle('display');
1956
- if (display != 'none' && display != null) // Safari bug
1957
- return {width: element.offsetWidth, height: element.offsetHeight};
1958
-
1959
- // All *Width and *Height properties give 0 on elements with display none,
1960
- // so enable the element temporarily
1961
- var els = element.style;
1962
- var originalVisibility = els.visibility;
1963
- var originalPosition = els.position;
1964
- var originalDisplay = els.display;
1965
- els.visibility = 'hidden';
1966
- els.position = 'absolute';
1967
- els.display = 'block';
1968
- var originalWidth = element.clientWidth;
1969
- var originalHeight = element.clientHeight;
1970
- els.display = originalDisplay;
1971
- els.position = originalPosition;
1972
- els.visibility = originalVisibility;
1973
- return {width: originalWidth, height: originalHeight};
1974
- },
1975
-
1976
- makePositioned: function(element) {
1977
- element = $(element);
1978
- var pos = Element.getStyle(element, 'position');
1979
- if (pos == 'static' || !pos) {
1980
- element._madePositioned = true;
1981
- element.style.position = 'relative';
1982
- // Opera returns the offset relative to the positioning context, when an
1983
- // element is position relative but top and left have not been defined
1984
- if (Prototype.Browser.Opera) {
1985
- element.style.top = 0;
1986
- element.style.left = 0;
1987
- }
1988
- }
1989
- return element;
1990
- },
1991
-
1992
- undoPositioned: function(element) {
1993
- element = $(element);
1994
- if (element._madePositioned) {
1995
- element._madePositioned = undefined;
1996
- element.style.position =
1997
- element.style.top =
1998
- element.style.left =
1999
- element.style.bottom =
2000
- element.style.right = '';
2001
- }
2002
- return element;
2003
- },
2004
-
2005
- makeClipping: function(element) {
2006
- element = $(element);
2007
- if (element._overflow) return element;
2008
- element._overflow = Element.getStyle(element, 'overflow') || 'auto';
2009
- if (element._overflow !== 'hidden')
2010
- element.style.overflow = 'hidden';
2011
- return element;
2012
- },
2013
-
2014
- undoClipping: function(element) {
2015
- element = $(element);
2016
- if (!element._overflow) return element;
2017
- element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
2018
- element._overflow = null;
2019
- return element;
2020
- },
2021
-
2022
- cumulativeOffset: function(element) {
2023
- var valueT = 0, valueL = 0;
2024
- do {
2025
- valueT += element.offsetTop || 0;
2026
- valueL += element.offsetLeft || 0;
2027
- element = element.offsetParent;
2028
- } while (element);
2029
- return Element._returnOffset(valueL, valueT);
2030
- },
2031
-
2032
- positionedOffset: function(element) {
2033
- var valueT = 0, valueL = 0;
2034
- do {
2035
- valueT += element.offsetTop || 0;
2036
- valueL += element.offsetLeft || 0;
2037
- element = element.offsetParent;
2038
- if (element) {
2039
- if (element.tagName.toUpperCase() == 'BODY') break;
2040
- var p = Element.getStyle(element, 'position');
2041
- if (p !== 'static') break;
2042
- }
2043
- } while (element);
2044
- return Element._returnOffset(valueL, valueT);
2045
- },
2046
-
2047
- absolutize: function(element) {
2048
- element = $(element);
2049
- if (element.getStyle('position') == 'absolute') return element;
2050
- // Position.prepare(); // To be done manually by Scripty when it needs it.
2051
-
2052
- var offsets = element.positionedOffset();
2053
- var top = offsets[1];
2054
- var left = offsets[0];
2055
- var width = element.clientWidth;
2056
- var height = element.clientHeight;
2057
-
2058
- element._originalLeft = left - parseFloat(element.style.left || 0);
2059
- element._originalTop = top - parseFloat(element.style.top || 0);
2060
- element._originalWidth = element.style.width;
2061
- element._originalHeight = element.style.height;
2062
-
2063
- element.style.position = 'absolute';
2064
- element.style.top = top + 'px';
2065
- element.style.left = left + 'px';
2066
- element.style.width = width + 'px';
2067
- element.style.height = height + 'px';
2068
- return element;
2069
- },
2070
-
2071
- relativize: function(element) {
2072
- element = $(element);
2073
- if (element.getStyle('position') == 'relative') return element;
2074
- // Position.prepare(); // To be done manually by Scripty when it needs it.
2075
-
2076
- element.style.position = 'relative';
2077
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
2078
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
2079
-
2080
- element.style.top = top + 'px';
2081
- element.style.left = left + 'px';
2082
- element.style.height = element._originalHeight;
2083
- element.style.width = element._originalWidth;
2084
- return element;
2085
- },
2086
-
2087
- cumulativeScrollOffset: function(element) {
2088
- var valueT = 0, valueL = 0;
2089
- do {
2090
- valueT += element.scrollTop || 0;
2091
- valueL += element.scrollLeft || 0;
2092
- element = element.parentNode;
2093
- } while (element);
2094
- return Element._returnOffset(valueL, valueT);
2095
- },
2096
-
2097
- getOffsetParent: function(element) {
2098
- if (element.offsetParent) return $(element.offsetParent);
2099
- if (element == document.body) return $(element);
2100
-
2101
- while ((element = element.parentNode) && element != document.body)
2102
- if (Element.getStyle(element, 'position') != 'static')
2103
- return $(element);
2104
-
2105
- return $(document.body);
2106
- },
2107
-
2108
- viewportOffset: function(forElement) {
2109
- var valueT = 0, valueL = 0;
2110
-
2111
- var element = forElement;
2112
- do {
2113
- valueT += element.offsetTop || 0;
2114
- valueL += element.offsetLeft || 0;
2115
-
2116
- // Safari fix
2117
- if (element.offsetParent == document.body &&
2118
- Element.getStyle(element, 'position') == 'absolute') break;
2119
-
2120
- } while (element = element.offsetParent);
2121
-
2122
- element = forElement;
2123
- do {
2124
- if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
2125
- valueT -= element.scrollTop || 0;
2126
- valueL -= element.scrollLeft || 0;
2127
- }
2128
- } while (element = element.parentNode);
2129
-
2130
- return Element._returnOffset(valueL, valueT);
2131
- },
2132
-
2133
- clonePosition: function(element, source) {
2134
- var options = Object.extend({
2135
- setLeft: true,
2136
- setTop: true,
2137
- setWidth: true,
2138
- setHeight: true,
2139
- offsetTop: 0,
2140
- offsetLeft: 0
2141
- }, arguments[2] || { });
2142
-
2143
- // find page position of source
2144
- source = $(source);
2145
- var p = source.viewportOffset();
2146
-
2147
- // find coordinate system to use
2148
- element = $(element);
2149
- var delta = [0, 0];
2150
- var parent = null;
2151
- // delta [0,0] will do fine with position: fixed elements,
2152
- // position:absolute needs offsetParent deltas
2153
- if (Element.getStyle(element, 'position') == 'absolute') {
2154
- parent = element.getOffsetParent();
2155
- delta = parent.viewportOffset();
2156
- }
2157
-
2158
- // correct by body offsets (fixes Safari)
2159
- if (parent == document.body) {
2160
- delta[0] -= document.body.offsetLeft;
2161
- delta[1] -= document.body.offsetTop;
2162
- }
2163
-
2164
- // set position
2165
- if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
2166
- if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
2167
- if (options.setWidth) element.style.width = source.offsetWidth + 'px';
2168
- if (options.setHeight) element.style.height = source.offsetHeight + 'px';
2169
- return element;
2170
- }
2171
- };
2172
-
2173
- Element.Methods.identify.counter = 1;
2174
-
2175
- Object.extend(Element.Methods, {
2176
- getElementsBySelector: Element.Methods.select,
2177
- childElements: Element.Methods.immediateDescendants
2178
- });
2179
-
2180
- Element._attributeTranslations = {
2181
- write: {
2182
- names: {
2183
- className: 'class',
2184
- htmlFor: 'for'
2185
- },
2186
- values: { }
2187
- }
2188
- };
2189
-
2190
- if (Prototype.Browser.Opera) {
2191
- Element.Methods.getStyle = Element.Methods.getStyle.wrap(
2192
- function(proceed, element, style) {
2193
- switch (style) {
2194
- case 'left': case 'top': case 'right': case 'bottom':
2195
- if (proceed(element, 'position') === 'static') return null;
2196
- case 'height': case 'width':
2197
- // returns '0px' for hidden elements; we want it to return null
2198
- if (!Element.visible(element)) return null;
2199
-
2200
- // returns the border-box dimensions rather than the content-box
2201
- // dimensions, so we subtract padding and borders from the value
2202
- var dim = parseInt(proceed(element, style), 10);
2203
-
2204
- if (dim !== element['offset' + style.capitalize()])
2205
- return dim + 'px';
2206
-
2207
- var properties;
2208
- if (style === 'height') {
2209
- properties = ['border-top-width', 'padding-top',
2210
- 'padding-bottom', 'border-bottom-width'];
2211
- }
2212
- else {
2213
- properties = ['border-left-width', 'padding-left',
2214
- 'padding-right', 'border-right-width'];
2215
- }
2216
- return properties.inject(dim, function(memo, property) {
2217
- var val = proceed(element, property);
2218
- return val === null ? memo : memo - parseInt(val, 10);
2219
- }) + 'px';
2220
- default: return proceed(element, style);
2221
- }
2222
- }
2223
- );
2224
-
2225
- Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
2226
- function(proceed, element, attribute) {
2227
- if (attribute === 'title') return element.title;
2228
- return proceed(element, attribute);
2229
- }
2230
- );
2231
- }
2232
-
2233
- else if (Prototype.Browser.IE) {
2234
- // IE doesn't report offsets correctly for static elements, so we change them
2235
- // to "relative" to get the values, then change them back.
2236
- Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
2237
- function(proceed, element) {
2238
- element = $(element);
2239
- // IE throws an error if element is not in document
2240
- try { element.offsetParent }
2241
- catch(e) { return $(document.body) }
2242
- var position = element.getStyle('position');
2243
- if (position !== 'static') return proceed(element);
2244
- element.setStyle({ position: 'relative' });
2245
- var value = proceed(element);
2246
- element.setStyle({ position: position });
2247
- return value;
2248
- }
2249
- );
2250
-
2251
- $w('positionedOffset viewportOffset').each(function(method) {
2252
- Element.Methods[method] = Element.Methods[method].wrap(
2253
- function(proceed, element) {
2254
- element = $(element);
2255
- try { element.offsetParent }
2256
- catch(e) { return Element._returnOffset(0,0) }
2257
- var position = element.getStyle('position');
2258
- if (position !== 'static') return proceed(element);
2259
- // Trigger hasLayout on the offset parent so that IE6 reports
2260
- // accurate offsetTop and offsetLeft values for position: fixed.
2261
- var offsetParent = element.getOffsetParent();
2262
- if (offsetParent && offsetParent.getStyle('position') === 'fixed')
2263
- offsetParent.setStyle({ zoom: 1 });
2264
- element.setStyle({ position: 'relative' });
2265
- var value = proceed(element);
2266
- element.setStyle({ position: position });
2267
- return value;
2268
- }
2269
- );
2270
- });
2271
-
2272
- Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
2273
- function(proceed, element) {
2274
- try { element.offsetParent }
2275
- catch(e) { return Element._returnOffset(0,0) }
2276
- return proceed(element);
2277
- }
2278
- );
2279
-
2280
- Element.Methods.getStyle = function(element, style) {
2281
- element = $(element);
2282
- style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
2283
- var value = element.style[style];
2284
- if (!value && element.currentStyle) value = element.currentStyle[style];
2285
-
2286
- if (style == 'opacity') {
2287
- if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
2288
- if (value[1]) return parseFloat(value[1]) / 100;
2289
- return 1.0;
2290
- }
2291
-
2292
- if (value == 'auto') {
2293
- if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
2294
- return element['offset' + style.capitalize()] + 'px';
2295
- return null;
2296
- }
2297
- return value;
2298
- };
2299
-
2300
- Element.Methods.setOpacity = function(element, value) {
2301
- function stripAlpha(filter){
2302
- return filter.replace(/alpha\([^\)]*\)/gi,'');
2303
- }
2304
- element = $(element);
2305
- var currentStyle = element.currentStyle;
2306
- if ((currentStyle && !currentStyle.hasLayout) ||
2307
- (!currentStyle && element.style.zoom == 'normal'))
2308
- element.style.zoom = 1;
2309
-
2310
- var filter = element.getStyle('filter'), style = element.style;
2311
- if (value == 1 || value === '') {
2312
- (filter = stripAlpha(filter)) ?
2313
- style.filter = filter : style.removeAttribute('filter');
2314
- return element;
2315
- } else if (value < 0.00001) value = 0;
2316
- style.filter = stripAlpha(filter) +
2317
- 'alpha(opacity=' + (value * 100) + ')';
2318
- return element;
2319
- };
2320
-
2321
- Element._attributeTranslations = {
2322
- read: {
2323
- names: {
2324
- 'class': 'className',
2325
- 'for': 'htmlFor'
2326
- },
2327
- values: {
2328
- _getAttr: function(element, attribute) {
2329
- return element.getAttribute(attribute, 2);
2330
- },
2331
- _getAttrNode: function(element, attribute) {
2332
- var node = element.getAttributeNode(attribute);
2333
- return node ? node.value : "";
2334
- },
2335
- _getEv: function(element, attribute) {
2336
- attribute = element.getAttribute(attribute);
2337
- return attribute ? attribute.toString().slice(23, -2) : null;
2338
- },
2339
- _flag: function(element, attribute) {
2340
- return $(element).hasAttribute(attribute) ? attribute : null;
2341
- },
2342
- style: function(element) {
2343
- return element.style.cssText.toLowerCase();
2344
- },
2345
- title: function(element) {
2346
- return element.title;
2347
- }
2348
- }
2349
- }
2350
- };
2351
-
2352
- Element._attributeTranslations.write = {
2353
- names: Object.extend({
2354
- cellpadding: 'cellPadding',
2355
- cellspacing: 'cellSpacing'
2356
- }, Element._attributeTranslations.read.names),
2357
- values: {
2358
- checked: function(element, value) {
2359
- element.checked = !!value;
2360
- },
2361
-
2362
- style: function(element, value) {
2363
- element.style.cssText = value ? value : '';
2364
- }
2365
- }
2366
- };
2367
-
2368
- Element._attributeTranslations.has = {};
2369
-
2370
- $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
2371
- 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
2372
- Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
2373
- Element._attributeTranslations.has[attr.toLowerCase()] = attr;
2374
- });
2375
-
2376
- (function(v) {
2377
- Object.extend(v, {
2378
- href: v._getAttr,
2379
- src: v._getAttr,
2380
- type: v._getAttr,
2381
- action: v._getAttrNode,
2382
- disabled: v._flag,
2383
- checked: v._flag,
2384
- readonly: v._flag,
2385
- multiple: v._flag,
2386
- onload: v._getEv,
2387
- onunload: v._getEv,
2388
- onclick: v._getEv,
2389
- ondblclick: v._getEv,
2390
- onmousedown: v._getEv,
2391
- onmouseup: v._getEv,
2392
- onmouseover: v._getEv,
2393
- onmousemove: v._getEv,
2394
- onmouseout: v._getEv,
2395
- onfocus: v._getEv,
2396
- onblur: v._getEv,
2397
- onkeypress: v._getEv,
2398
- onkeydown: v._getEv,
2399
- onkeyup: v._getEv,
2400
- onsubmit: v._getEv,
2401
- onreset: v._getEv,
2402
- onselect: v._getEv,
2403
- onchange: v._getEv
2404
- });
2405
- })(Element._attributeTranslations.read.values);
2406
- }
2407
-
2408
- else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
2409
- Element.Methods.setOpacity = function(element, value) {
2410
- element = $(element);
2411
- element.style.opacity = (value == 1) ? 0.999999 :
2412
- (value === '') ? '' : (value < 0.00001) ? 0 : value;
2413
- return element;
2414
- };
2415
- }
2416
-
2417
- else if (Prototype.Browser.WebKit) {
2418
- Element.Methods.setOpacity = function(element, value) {
2419
- element = $(element);
2420
- element.style.opacity = (value == 1 || value === '') ? '' :
2421
- (value < 0.00001) ? 0 : value;
2422
-
2423
- if (value == 1)
2424
- if(element.tagName.toUpperCase() == 'IMG' && element.width) {
2425
- element.width++; element.width--;
2426
- } else try {
2427
- var n = document.createTextNode(' ');
2428
- element.appendChild(n);
2429
- element.removeChild(n);
2430
- } catch (e) { }
2431
-
2432
- return element;
2433
- };
2434
-
2435
- // Safari returns margins on body which is incorrect if the child is absolutely
2436
- // positioned. For performance reasons, redefine Element#cumulativeOffset for
2437
- // KHTML/WebKit only.
2438
- Element.Methods.cumulativeOffset = function(element) {
2439
- var valueT = 0, valueL = 0;
2440
- do {
2441
- valueT += element.offsetTop || 0;
2442
- valueL += element.offsetLeft || 0;
2443
- if (element.offsetParent == document.body)
2444
- if (Element.getStyle(element, 'position') == 'absolute') break;
2445
-
2446
- element = element.offsetParent;
2447
- } while (element);
2448
-
2449
- return Element._returnOffset(valueL, valueT);
2450
- };
2451
- }
2452
-
2453
- if (Prototype.Browser.IE || Prototype.Browser.Opera) {
2454
- // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
2455
- Element.Methods.update = function(element, content) {
2456
- element = $(element);
2457
-
2458
- if (content && content.toElement) content = content.toElement();
2459
- if (Object.isElement(content)) return element.update().insert(content);
2460
-
2461
- content = Object.toHTML(content);
2462
- var tagName = element.tagName.toUpperCase();
2463
-
2464
- if (tagName in Element._insertionTranslations.tags) {
2465
- $A(element.childNodes).each(function(node) { element.removeChild(node) });
2466
- Element._getContentFromAnonymousElement(tagName, content.stripScripts())
2467
- .each(function(node) { element.appendChild(node) });
2468
- }
2469
- else element.innerHTML = content.stripScripts();
2470
-
2471
- content.evalScripts.bind(content).defer();
2472
- return element;
2473
- };
2474
- }
2475
-
2476
- if ('outerHTML' in document.createElement('div')) {
2477
- Element.Methods.replace = function(element, content) {
2478
- element = $(element);
2479
-
2480
- if (content && content.toElement) content = content.toElement();
2481
- if (Object.isElement(content)) {
2482
- element.parentNode.replaceChild(content, element);
2483
- return element;
2484
- }
2485
-
2486
- content = Object.toHTML(content);
2487
- var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2488
-
2489
- if (Element._insertionTranslations.tags[tagName]) {
2490
- var nextSibling = element.next();
2491
- var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2492
- parent.removeChild(element);
2493
- if (nextSibling)
2494
- fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
2495
- else
2496
- fragments.each(function(node) { parent.appendChild(node) });
2497
- }
2498
- else element.outerHTML = content.stripScripts();
2499
-
2500
- content.evalScripts.bind(content).defer();
2501
- return element;
2502
- };
2503
- }
2504
-
2505
- Element._returnOffset = function(l, t) {
2506
- var result = [l, t];
2507
- result.left = l;
2508
- result.top = t;
2509
- return result;
2510
- };
2511
-
2512
- Element._getContentFromAnonymousElement = function(tagName, html) {
2513
- var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
2514
- if (t) {
2515
- div.innerHTML = t[0] + html + t[1];
2516
- t[2].times(function() { div = div.firstChild });
2517
- } else div.innerHTML = html;
2518
- return $A(div.childNodes);
2519
- };
2520
-
2521
- Element._insertionTranslations = {
2522
- before: function(element, node) {
2523
- element.parentNode.insertBefore(node, element);
2524
- },
2525
- top: function(element, node) {
2526
- element.insertBefore(node, element.firstChild);
2527
- },
2528
- bottom: function(element, node) {
2529
- element.appendChild(node);
2530
- },
2531
- after: function(element, node) {
2532
- element.parentNode.insertBefore(node, element.nextSibling);
2533
- },
2534
- tags: {
2535
- TABLE: ['<table>', '</table>', 1],
2536
- TBODY: ['<table><tbody>', '</tbody></table>', 2],
2537
- TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
2538
- TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
2539
- SELECT: ['<select>', '</select>', 1]
2540
- }
2541
- };
2542
-
2543
- (function() {
2544
- Object.extend(this.tags, {
2545
- THEAD: this.tags.TBODY,
2546
- TFOOT: this.tags.TBODY,
2547
- TH: this.tags.TD
2548
- });
2549
- }).call(Element._insertionTranslations);
2550
-
2551
- Element.Methods.Simulated = {
2552
- hasAttribute: function(element, attribute) {
2553
- attribute = Element._attributeTranslations.has[attribute] || attribute;
2554
- var node = $(element).getAttributeNode(attribute);
2555
- return !!(node && node.specified);
2556
- }
2557
- };
2558
-
2559
- Element.Methods.ByTag = { };
2560
-
2561
- Object.extend(Element, Element.Methods);
2562
-
2563
- if (!Prototype.BrowserFeatures.ElementExtensions &&
2564
- document.createElement('div')['__proto__']) {
2565
- window.HTMLElement = { };
2566
- window.HTMLElement.prototype = document.createElement('div')['__proto__'];
2567
- Prototype.BrowserFeatures.ElementExtensions = true;
2568
- }
2569
-
2570
- Element.extend = (function() {
2571
- if (Prototype.BrowserFeatures.SpecificElementExtensions)
2572
- return Prototype.K;
2573
-
2574
- var Methods = { }, ByTag = Element.Methods.ByTag;
2575
-
2576
- var extend = Object.extend(function(element) {
2577
- if (!element || element._extendedByPrototype ||
2578
- element.nodeType != 1 || element == window) return element;
2579
-
2580
- var methods = Object.clone(Methods),
2581
- tagName = element.tagName.toUpperCase(), property, value;
2582
-
2583
- // extend methods for specific tags
2584
- if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
2585
-
2586
- for (property in methods) {
2587
- value = methods[property];
2588
- if (Object.isFunction(value) && !(property in element))
2589
- element[property] = value.methodize();
2590
- }
2591
-
2592
- element._extendedByPrototype = Prototype.emptyFunction;
2593
- return element;
2594
-
2595
- }, {
2596
- refresh: function() {
2597
- // extend methods for all tags (Safari doesn't need this)
2598
- if (!Prototype.BrowserFeatures.ElementExtensions) {
2599
- Object.extend(Methods, Element.Methods);
2600
- Object.extend(Methods, Element.Methods.Simulated);
2601
- }
2602
- }
2603
- });
2604
-
2605
- extend.refresh();
2606
- return extend;
2607
- })();
2608
-
2609
- Element.hasAttribute = function(element, attribute) {
2610
- if (element.hasAttribute) return element.hasAttribute(attribute);
2611
- return Element.Methods.Simulated.hasAttribute(element, attribute);
2612
- };
2613
-
2614
- Element.addMethods = function(methods) {
2615
- var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
2616
-
2617
- if (!methods) {
2618
- Object.extend(Form, Form.Methods);
2619
- Object.extend(Form.Element, Form.Element.Methods);
2620
- Object.extend(Element.Methods.ByTag, {
2621
- "FORM": Object.clone(Form.Methods),
2622
- "INPUT": Object.clone(Form.Element.Methods),
2623
- "SELECT": Object.clone(Form.Element.Methods),
2624
- "TEXTAREA": Object.clone(Form.Element.Methods)
2625
- });
2626
- }
2627
-
2628
- if (arguments.length == 2) {
2629
- var tagName = methods;
2630
- methods = arguments[1];
2631
- }
2632
-
2633
- if (!tagName) Object.extend(Element.Methods, methods || { });
2634
- else {
2635
- if (Object.isArray(tagName)) tagName.each(extend);
2636
- else extend(tagName);
2637
- }
2638
-
2639
- function extend(tagName) {
2640
- tagName = tagName.toUpperCase();
2641
- if (!Element.Methods.ByTag[tagName])
2642
- Element.Methods.ByTag[tagName] = { };
2643
- Object.extend(Element.Methods.ByTag[tagName], methods);
2644
- }
2645
-
2646
- function copy(methods, destination, onlyIfAbsent) {
2647
- onlyIfAbsent = onlyIfAbsent || false;
2648
- for (var property in methods) {
2649
- var value = methods[property];
2650
- if (!Object.isFunction(value)) continue;
2651
- if (!onlyIfAbsent || !(property in destination))
2652
- destination[property] = value.methodize();
2653
- }
2654
- }
2655
-
2656
- function findDOMClass(tagName) {
2657
- var klass;
2658
- var trans = {
2659
- "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
2660
- "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
2661
- "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
2662
- "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
2663
- "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
2664
- "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
2665
- "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
2666
- "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
2667
- "FrameSet", "IFRAME": "IFrame"
2668
- };
2669
- if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
2670
- if (window[klass]) return window[klass];
2671
- klass = 'HTML' + tagName + 'Element';
2672
- if (window[klass]) return window[klass];
2673
- klass = 'HTML' + tagName.capitalize() + 'Element';
2674
- if (window[klass]) return window[klass];
2675
-
2676
- window[klass] = { };
2677
- window[klass].prototype = document.createElement(tagName)['__proto__'];
2678
- return window[klass];
2679
- }
2680
-
2681
- if (F.ElementExtensions) {
2682
- copy(Element.Methods, HTMLElement.prototype);
2683
- copy(Element.Methods.Simulated, HTMLElement.prototype, true);
2684
- }
2685
-
2686
- if (F.SpecificElementExtensions) {
2687
- for (var tag in Element.Methods.ByTag) {
2688
- var klass = findDOMClass(tag);
2689
- if (Object.isUndefined(klass)) continue;
2690
- copy(T[tag], klass.prototype);
2691
- }
2692
- }
2693
-
2694
- Object.extend(Element, Element.Methods);
2695
- delete Element.ByTag;
2696
-
2697
- if (Element.extend.refresh) Element.extend.refresh();
2698
- Element.cache = { };
2699
- };
2700
-
2701
- document.viewport = {
2702
- getDimensions: function() {
2703
- var dimensions = { }, B = Prototype.Browser;
2704
- $w('width height').each(function(d) {
2705
- var D = d.capitalize();
2706
- if (B.WebKit && !document.evaluate) {
2707
- // Safari <3.0 needs self.innerWidth/Height
2708
- dimensions[d] = self['inner' + D];
2709
- } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
2710
- // Opera <9.5 needs document.body.clientWidth/Height
2711
- dimensions[d] = document.body['client' + D]
2712
- } else {
2713
- dimensions[d] = document.documentElement['client' + D];
2714
- }
2715
- });
2716
- return dimensions;
2717
- },
2718
-
2719
- getWidth: function() {
2720
- return this.getDimensions().width;
2721
- },
2722
-
2723
- getHeight: function() {
2724
- return this.getDimensions().height;
2725
- },
2726
-
2727
- getScrollOffsets: function() {
2728
- return Element._returnOffset(
2729
- window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
2730
- window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
2731
- }
2732
- };
2733
- /* Portions of the Selector class are derived from Jack Slocum's DomQuery,
2734
- * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
2735
- * license. Please see http://www.yui-ext.com/ for more information. */
2736
-
2737
- var Selector = Class.create({
2738
- initialize: function(expression) {
2739
- this.expression = expression.strip();
2740
-
2741
- if (this.shouldUseSelectorsAPI()) {
2742
- this.mode = 'selectorsAPI';
2743
- } else if (this.shouldUseXPath()) {
2744
- this.mode = 'xpath';
2745
- this.compileXPathMatcher();
2746
- } else {
2747
- this.mode = "normal";
2748
- this.compileMatcher();
2749
- }
2750
-
2751
- },
2752
-
2753
- shouldUseXPath: function() {
2754
- if (!Prototype.BrowserFeatures.XPath) return false;
2755
-
2756
- var e = this.expression;
2757
-
2758
- // Safari 3 chokes on :*-of-type and :empty
2759
- if (Prototype.Browser.WebKit &&
2760
- (e.include("-of-type") || e.include(":empty")))
2761
- return false;
2762
-
2763
- // XPath can't do namespaced attributes, nor can it read
2764
- // the "checked" property from DOM nodes
2765
- if ((/(\[[\w-]*?:|:checked)/).test(e))
2766
- return false;
2767
-
2768
- return true;
2769
- },
2770
-
2771
- shouldUseSelectorsAPI: function() {
2772
- if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
2773
-
2774
- if (!Selector._div) Selector._div = new Element('div');
2775
-
2776
- // Make sure the browser treats the selector as valid. Test on an
2777
- // isolated element to minimize cost of this check.
2778
- try {
2779
- Selector._div.querySelector(this.expression);
2780
- } catch(e) {
2781
- return false;
2782
- }
2783
-
2784
- return true;
2785
- },
2786
-
2787
- compileMatcher: function() {
2788
- var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
2789
- c = Selector.criteria, le, p, m;
2790
-
2791
- if (Selector._cache[e]) {
2792
- this.matcher = Selector._cache[e];
2793
- return;
2794
- }
2795
-
2796
- this.matcher = ["this.matcher = function(root) {",
2797
- "var r = root, h = Selector.handlers, c = false, n;"];
2798
-
2799
- while (e && le != e && (/\S/).test(e)) {
2800
- le = e;
2801
- for (var i in ps) {
2802
- p = ps[i];
2803
- if (m = e.match(p)) {
2804
- this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
2805
- new Template(c[i]).evaluate(m));
2806
- e = e.replace(m[0], '');
2807
- break;
2808
- }
2809
- }
2810
- }
2811
-
2812
- this.matcher.push("return h.unique(n);\n}");
2813
- eval(this.matcher.join('\n'));
2814
- Selector._cache[this.expression] = this.matcher;
2815
- },
2816
-
2817
- compileXPathMatcher: function() {
2818
- var e = this.expression, ps = Selector.patterns,
2819
- x = Selector.xpath, le, m;
2820
-
2821
- if (Selector._cache[e]) {
2822
- this.xpath = Selector._cache[e]; return;
2823
- }
2824
-
2825
- this.matcher = ['.//*'];
2826
- while (e && le != e && (/\S/).test(e)) {
2827
- le = e;
2828
- for (var i in ps) {
2829
- if (m = e.match(ps[i])) {
2830
- this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
2831
- new Template(x[i]).evaluate(m));
2832
- e = e.replace(m[0], '');
2833
- break;
2834
- }
2835
- }
2836
- }
2837
-
2838
- this.xpath = this.matcher.join('');
2839
- Selector._cache[this.expression] = this.xpath;
2840
- },
2841
-
2842
- findElements: function(root) {
2843
- root = root || document;
2844
- var e = this.expression, results;
2845
-
2846
- switch (this.mode) {
2847
- case 'selectorsAPI':
2848
- // querySelectorAll queries document-wide, then filters to descendants
2849
- // of the context element. That's not what we want.
2850
- // Add an explicit context to the selector if necessary.
2851
- if (root !== document) {
2852
- var oldId = root.id, id = $(root).identify();
2853
- e = "#" + id + " " + e;
2854
- }
2855
-
2856
- results = $A(root.querySelectorAll(e)).map(Element.extend);
2857
- root.id = oldId;
2858
-
2859
- return results;
2860
- case 'xpath':
2861
- return document._getElementsByXPath(this.xpath, root);
2862
- default:
2863
- return this.matcher(root);
2864
- }
2865
- },
2866
-
2867
- match: function(element) {
2868
- this.tokens = [];
2869
-
2870
- var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
2871
- var le, p, m;
2872
-
2873
- while (e && le !== e && (/\S/).test(e)) {
2874
- le = e;
2875
- for (var i in ps) {
2876
- p = ps[i];
2877
- if (m = e.match(p)) {
2878
- // use the Selector.assertions methods unless the selector
2879
- // is too complex.
2880
- if (as[i]) {
2881
- this.tokens.push([i, Object.clone(m)]);
2882
- e = e.replace(m[0], '');
2883
- } else {
2884
- // reluctantly do a document-wide search
2885
- // and look for a match in the array
2886
- return this.findElements(document).include(element);
2887
- }
2888
- }
2889
- }
2890
- }
2891
-
2892
- var match = true, name, matches;
2893
- for (var i = 0, token; token = this.tokens[i]; i++) {
2894
- name = token[0], matches = token[1];
2895
- if (!Selector.assertions[name](element, matches)) {
2896
- match = false; break;
2897
- }
2898
- }
2899
-
2900
- return match;
2901
- },
2902
-
2903
- toString: function() {
2904
- return this.expression;
2905
- },
2906
-
2907
- inspect: function() {
2908
- return "#<Selector:" + this.expression.inspect() + ">";
2909
- }
2910
- });
2911
-
2912
- Object.extend(Selector, {
2913
- _cache: { },
2914
-
2915
- xpath: {
2916
- descendant: "//*",
2917
- child: "/*",
2918
- adjacent: "/following-sibling::*[1]",
2919
- laterSibling: '/following-sibling::*',
2920
- tagName: function(m) {
2921
- if (m[1] == '*') return '';
2922
- return "[local-name()='" + m[1].toLowerCase() +
2923
- "' or local-name()='" + m[1].toUpperCase() + "']";
2924
- },
2925
- className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
2926
- id: "[@id='#{1}']",
2927
- attrPresence: function(m) {
2928
- m[1] = m[1].toLowerCase();
2929
- return new Template("[@#{1}]").evaluate(m);
2930
- },
2931
- attr: function(m) {
2932
- m[1] = m[1].toLowerCase();
2933
- m[3] = m[5] || m[6];
2934
- return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
2935
- },
2936
- pseudo: function(m) {
2937
- var h = Selector.xpath.pseudos[m[1]];
2938
- if (!h) return '';
2939
- if (Object.isFunction(h)) return h(m);
2940
- return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
2941
- },
2942
- operators: {
2943
- '=': "[@#{1}='#{3}']",
2944
- '!=': "[@#{1}!='#{3}']",
2945
- '^=': "[starts-with(@#{1}, '#{3}')]",
2946
- '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
2947
- '*=': "[contains(@#{1}, '#{3}')]",
2948
- '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
2949
- '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
2950
- },
2951
- pseudos: {
2952
- 'first-child': '[not(preceding-sibling::*)]',
2953
- 'last-child': '[not(following-sibling::*)]',
2954
- 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
2955
- 'empty': "[count(*) = 0 and (count(text()) = 0)]",
2956
- 'checked': "[@checked]",
2957
- 'disabled': "[(@disabled) and (@type!='hidden')]",
2958
- 'enabled': "[not(@disabled) and (@type!='hidden')]",
2959
- 'not': function(m) {
2960
- var e = m[6], p = Selector.patterns,
2961
- x = Selector.xpath, le, v;
2962
-
2963
- var exclusion = [];
2964
- while (e && le != e && (/\S/).test(e)) {
2965
- le = e;
2966
- for (var i in p) {
2967
- if (m = e.match(p[i])) {
2968
- v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
2969
- exclusion.push("(" + v.substring(1, v.length - 1) + ")");
2970
- e = e.replace(m[0], '');
2971
- break;
2972
- }
2973
- }
2974
- }
2975
- return "[not(" + exclusion.join(" and ") + ")]";
2976
- },
2977
- 'nth-child': function(m) {
2978
- return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
2979
- },
2980
- 'nth-last-child': function(m) {
2981
- return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
2982
- },
2983
- 'nth-of-type': function(m) {
2984
- return Selector.xpath.pseudos.nth("position() ", m);
2985
- },
2986
- 'nth-last-of-type': function(m) {
2987
- return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
2988
- },
2989
- 'first-of-type': function(m) {
2990
- m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
2991
- },
2992
- 'last-of-type': function(m) {
2993
- m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
2994
- },
2995
- 'only-of-type': function(m) {
2996
- var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
2997
- },
2998
- nth: function(fragment, m) {
2999
- var mm, formula = m[6], predicate;
3000
- if (formula == 'even') formula = '2n+0';
3001
- if (formula == 'odd') formula = '2n+1';
3002
- if (mm = formula.match(/^(\d+)$/)) // digit only
3003
- return '[' + fragment + "= " + mm[1] + ']';
3004
- if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
3005
- if (mm[1] == "-") mm[1] = -1;
3006
- var a = mm[1] ? Number(mm[1]) : 1;
3007
- var b = mm[2] ? Number(mm[2]) : 0;
3008
- predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
3009
- "((#{fragment} - #{b}) div #{a} >= 0)]";
3010
- return new Template(predicate).evaluate({
3011
- fragment: fragment, a: a, b: b });
3012
- }
3013
- }
3014
- }
3015
- },
3016
-
3017
- criteria: {
3018
- tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
3019
- className: 'n = h.className(n, r, "#{1}", c); c = false;',
3020
- id: 'n = h.id(n, r, "#{1}", c); c = false;',
3021
- attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
3022
- attr: function(m) {
3023
- m[3] = (m[5] || m[6]);
3024
- return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
3025
- },
3026
- pseudo: function(m) {
3027
- if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
3028
- return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
3029
- },
3030
- descendant: 'c = "descendant";',
3031
- child: 'c = "child";',
3032
- adjacent: 'c = "adjacent";',
3033
- laterSibling: 'c = "laterSibling";'
3034
- },
3035
-
3036
- patterns: {
3037
- // combinators must be listed first
3038
- // (and descendant needs to be last combinator)
3039
- laterSibling: /^\s*~\s*/,
3040
- child: /^\s*>\s*/,
3041
- adjacent: /^\s*\+\s*/,
3042
- descendant: /^\s/,
3043
-
3044
- // selectors follow
3045
- tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
3046
- id: /^#([\w\-\*]+)(\b|$)/,
3047
- className: /^\.([\w\-\*]+)(\b|$)/,
3048
- pseudo:
3049
- /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
3050
- attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
3051
- attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
3052
- },
3053
-
3054
- // for Selector.match and Element#match
3055
- assertions: {
3056
- tagName: function(element, matches) {
3057
- return matches[1].toUpperCase() == element.tagName.toUpperCase();
3058
- },
3059
-
3060
- className: function(element, matches) {
3061
- return Element.hasClassName(element, matches[1]);
3062
- },
3063
-
3064
- id: function(element, matches) {
3065
- return element.id === matches[1];
3066
- },
3067
-
3068
- attrPresence: function(element, matches) {
3069
- return Element.hasAttribute(element, matches[1]);
3070
- },
3071
-
3072
- attr: function(element, matches) {
3073
- var nodeValue = Element.readAttribute(element, matches[1]);
3074
- return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
3075
- }
3076
- },
3077
-
3078
- handlers: {
3079
- // UTILITY FUNCTIONS
3080
- // joins two collections
3081
- concat: function(a, b) {
3082
- for (var i = 0, node; node = b[i]; i++)
3083
- a.push(node);
3084
- return a;
3085
- },
3086
-
3087
- // marks an array of nodes for counting
3088
- mark: function(nodes) {
3089
- var _true = Prototype.emptyFunction;
3090
- for (var i = 0, node; node = nodes[i]; i++)
3091
- node._countedByPrototype = _true;
3092
- return nodes;
3093
- },
3094
-
3095
- unmark: function(nodes) {
3096
- for (var i = 0, node; node = nodes[i]; i++)
3097
- node._countedByPrototype = undefined;
3098
- return nodes;
3099
- },
3100
-
3101
- // mark each child node with its position (for nth calls)
3102
- // "ofType" flag indicates whether we're indexing for nth-of-type
3103
- // rather than nth-child
3104
- index: function(parentNode, reverse, ofType) {
3105
- parentNode._countedByPrototype = Prototype.emptyFunction;
3106
- if (reverse) {
3107
- for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
3108
- var node = nodes[i];
3109
- if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
3110
- }
3111
- } else {
3112
- for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
3113
- if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
3114
- }
3115
- },
3116
-
3117
- // filters out duplicates and extends all nodes
3118
- unique: function(nodes) {
3119
- if (nodes.length == 0) return nodes;
3120
- var results = [], n;
3121
- for (var i = 0, l = nodes.length; i < l; i++)
3122
- if (!(n = nodes[i])._countedByPrototype) {
3123
- n._countedByPrototype = Prototype.emptyFunction;
3124
- results.push(Element.extend(n));
3125
- }
3126
- return Selector.handlers.unmark(results);
3127
- },
3128
-
3129
- // COMBINATOR FUNCTIONS
3130
- descendant: function(nodes) {
3131
- var h = Selector.handlers;
3132
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3133
- h.concat(results, node.getElementsByTagName('*'));
3134
- return results;
3135
- },
3136
-
3137
- child: function(nodes) {
3138
- var h = Selector.handlers;
3139
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3140
- for (var j = 0, child; child = node.childNodes[j]; j++)
3141
- if (child.nodeType == 1 && child.tagName != '!') results.push(child);
3142
- }
3143
- return results;
3144
- },
3145
-
3146
- adjacent: function(nodes) {
3147
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3148
- var next = this.nextElementSibling(node);
3149
- if (next) results.push(next);
3150
- }
3151
- return results;
3152
- },
3153
-
3154
- laterSibling: function(nodes) {
3155
- var h = Selector.handlers;
3156
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3157
- h.concat(results, Element.nextSiblings(node));
3158
- return results;
3159
- },
3160
-
3161
- nextElementSibling: function(node) {
3162
- while (node = node.nextSibling)
3163
- if (node.nodeType == 1) return node;
3164
- return null;
3165
- },
3166
-
3167
- previousElementSibling: function(node) {
3168
- while (node = node.previousSibling)
3169
- if (node.nodeType == 1) return node;
3170
- return null;
3171
- },
3172
-
3173
- // TOKEN FUNCTIONS
3174
- tagName: function(nodes, root, tagName, combinator) {
3175
- var uTagName = tagName.toUpperCase();
3176
- var results = [], h = Selector.handlers;
3177
- if (nodes) {
3178
- if (combinator) {
3179
- // fastlane for ordinary descendant combinators
3180
- if (combinator == "descendant") {
3181
- for (var i = 0, node; node = nodes[i]; i++)
3182
- h.concat(results, node.getElementsByTagName(tagName));
3183
- return results;
3184
- } else nodes = this[combinator](nodes);
3185
- if (tagName == "*") return nodes;
3186
- }
3187
- for (var i = 0, node; node = nodes[i]; i++)
3188
- if (node.tagName.toUpperCase() === uTagName) results.push(node);
3189
- return results;
3190
- } else return root.getElementsByTagName(tagName);
3191
- },
3192
-
3193
- id: function(nodes, root, id, combinator) {
3194
- var targetNode = $(id), h = Selector.handlers;
3195
- if (!targetNode) return [];
3196
- if (!nodes && root == document) return [targetNode];
3197
- if (nodes) {
3198
- if (combinator) {
3199
- if (combinator == 'child') {
3200
- for (var i = 0, node; node = nodes[i]; i++)
3201
- if (targetNode.parentNode == node) return [targetNode];
3202
- } else if (combinator == 'descendant') {
3203
- for (var i = 0, node; node = nodes[i]; i++)
3204
- if (Element.descendantOf(targetNode, node)) return [targetNode];
3205
- } else if (combinator == 'adjacent') {
3206
- for (var i = 0, node; node = nodes[i]; i++)
3207
- if (Selector.handlers.previousElementSibling(targetNode) == node)
3208
- return [targetNode];
3209
- } else nodes = h[combinator](nodes);
3210
- }
3211
- for (var i = 0, node; node = nodes[i]; i++)
3212
- if (node == targetNode) return [targetNode];
3213
- return [];
3214
- }
3215
- return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
3216
- },
3217
-
3218
- className: function(nodes, root, className, combinator) {
3219
- if (nodes && combinator) nodes = this[combinator](nodes);
3220
- return Selector.handlers.byClassName(nodes, root, className);
3221
- },
3222
-
3223
- byClassName: function(nodes, root, className) {
3224
- if (!nodes) nodes = Selector.handlers.descendant([root]);
3225
- var needle = ' ' + className + ' ';
3226
- for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
3227
- nodeClassName = node.className;
3228
- if (nodeClassName.length == 0) continue;
3229
- if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
3230
- results.push(node);
3231
- }
3232
- return results;
3233
- },
3234
-
3235
- attrPresence: function(nodes, root, attr, combinator) {
3236
- if (!nodes) nodes = root.getElementsByTagName("*");
3237
- if (nodes && combinator) nodes = this[combinator](nodes);
3238
- var results = [];
3239
- for (var i = 0, node; node = nodes[i]; i++)
3240
- if (Element.hasAttribute(node, attr)) results.push(node);
3241
- return results;
3242
- },
3243
-
3244
- attr: function(nodes, root, attr, value, operator, combinator) {
3245
- if (!nodes) nodes = root.getElementsByTagName("*");
3246
- if (nodes && combinator) nodes = this[combinator](nodes);
3247
- var handler = Selector.operators[operator], results = [];
3248
- for (var i = 0, node; node = nodes[i]; i++) {
3249
- var nodeValue = Element.readAttribute(node, attr);
3250
- if (nodeValue === null) continue;
3251
- if (handler(nodeValue, value)) results.push(node);
3252
- }
3253
- return results;
3254
- },
3255
-
3256
- pseudo: function(nodes, name, value, root, combinator) {
3257
- if (nodes && combinator) nodes = this[combinator](nodes);
3258
- if (!nodes) nodes = root.getElementsByTagName("*");
3259
- return Selector.pseudos[name](nodes, value, root);
3260
- }
3261
- },
3262
-
3263
- pseudos: {
3264
- 'first-child': function(nodes, value, root) {
3265
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3266
- if (Selector.handlers.previousElementSibling(node)) continue;
3267
- results.push(node);
3268
- }
3269
- return results;
3270
- },
3271
- 'last-child': function(nodes, value, root) {
3272
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3273
- if (Selector.handlers.nextElementSibling(node)) continue;
3274
- results.push(node);
3275
- }
3276
- return results;
3277
- },
3278
- 'only-child': function(nodes, value, root) {
3279
- var h = Selector.handlers;
3280
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3281
- if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
3282
- results.push(node);
3283
- return results;
3284
- },
3285
- 'nth-child': function(nodes, formula, root) {
3286
- return Selector.pseudos.nth(nodes, formula, root);
3287
- },
3288
- 'nth-last-child': function(nodes, formula, root) {
3289
- return Selector.pseudos.nth(nodes, formula, root, true);
3290
- },
3291
- 'nth-of-type': function(nodes, formula, root) {
3292
- return Selector.pseudos.nth(nodes, formula, root, false, true);
3293
- },
3294
- 'nth-last-of-type': function(nodes, formula, root) {
3295
- return Selector.pseudos.nth(nodes, formula, root, true, true);
3296
- },
3297
- 'first-of-type': function(nodes, formula, root) {
3298
- return Selector.pseudos.nth(nodes, "1", root, false, true);
3299
- },
3300
- 'last-of-type': function(nodes, formula, root) {
3301
- return Selector.pseudos.nth(nodes, "1", root, true, true);
3302
- },
3303
- 'only-of-type': function(nodes, formula, root) {
3304
- var p = Selector.pseudos;
3305
- return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
3306
- },
3307
-
3308
- // handles the an+b logic
3309
- getIndices: function(a, b, total) {
3310
- if (a == 0) return b > 0 ? [b] : [];
3311
- return $R(1, total).inject([], function(memo, i) {
3312
- if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
3313
- return memo;
3314
- });
3315
- },
3316
-
3317
- // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
3318
- nth: function(nodes, formula, root, reverse, ofType) {
3319
- if (nodes.length == 0) return [];
3320
- if (formula == 'even') formula = '2n+0';
3321
- if (formula == 'odd') formula = '2n+1';
3322
- var h = Selector.handlers, results = [], indexed = [], m;
3323
- h.mark(nodes);
3324
- for (var i = 0, node; node = nodes[i]; i++) {
3325
- if (!node.parentNode._countedByPrototype) {
3326
- h.index(node.parentNode, reverse, ofType);
3327
- indexed.push(node.parentNode);
3328
- }
3329
- }
3330
- if (formula.match(/^\d+$/)) { // just a number
3331
- formula = Number(formula);
3332
- for (var i = 0, node; node = nodes[i]; i++)
3333
- if (node.nodeIndex == formula) results.push(node);
3334
- } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
3335
- if (m[1] == "-") m[1] = -1;
3336
- var a = m[1] ? Number(m[1]) : 1;
3337
- var b = m[2] ? Number(m[2]) : 0;
3338
- var indices = Selector.pseudos.getIndices(a, b, nodes.length);
3339
- for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
3340
- for (var j = 0; j < l; j++)
3341
- if (node.nodeIndex == indices[j]) results.push(node);
3342
- }
3343
- }
3344
- h.unmark(nodes);
3345
- h.unmark(indexed);
3346
- return results;
3347
- },
3348
-
3349
- 'empty': function(nodes, value, root) {
3350
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3351
- // IE treats comments as element nodes
3352
- if (node.tagName == '!' || node.firstChild) continue;
3353
- results.push(node);
3354
- }
3355
- return results;
3356
- },
3357
-
3358
- 'not': function(nodes, selector, root) {
3359
- var h = Selector.handlers, selectorType, m;
3360
- var exclusions = new Selector(selector).findElements(root);
3361
- h.mark(exclusions);
3362
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3363
- if (!node._countedByPrototype) results.push(node);
3364
- h.unmark(exclusions);
3365
- return results;
3366
- },
3367
-
3368
- 'enabled': function(nodes, value, root) {
3369
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3370
- if (!node.disabled && (!node.type || node.type !== 'hidden'))
3371
- results.push(node);
3372
- return results;
3373
- },
3374
-
3375
- 'disabled': function(nodes, value, root) {
3376
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3377
- if (node.disabled) results.push(node);
3378
- return results;
3379
- },
3380
-
3381
- 'checked': function(nodes, value, root) {
3382
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3383
- if (node.checked) results.push(node);
3384
- return results;
3385
- }
3386
- },
3387
-
3388
- operators: {
3389
- '=': function(nv, v) { return nv == v; },
3390
- '!=': function(nv, v) { return nv != v; },
3391
- '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
3392
- '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
3393
- '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
3394
- '$=': function(nv, v) { return nv.endsWith(v); },
3395
- '*=': function(nv, v) { return nv.include(v); },
3396
- '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
3397
- '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
3398
- '-').include('-' + (v || "").toUpperCase() + '-'); }
3399
- },
3400
-
3401
- split: function(expression) {
3402
- var expressions = [];
3403
- expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
3404
- expressions.push(m[1].strip());
3405
- });
3406
- return expressions;
3407
- },
3408
-
3409
- matchElements: function(elements, expression) {
3410
- var matches = $$(expression), h = Selector.handlers;
3411
- h.mark(matches);
3412
- for (var i = 0, results = [], element; element = elements[i]; i++)
3413
- if (element._countedByPrototype) results.push(element);
3414
- h.unmark(matches);
3415
- return results;
3416
- },
3417
-
3418
- findElement: function(elements, expression, index) {
3419
- if (Object.isNumber(expression)) {
3420
- index = expression; expression = false;
3421
- }
3422
- return Selector.matchElements(elements, expression || '*')[index || 0];
3423
- },
3424
-
3425
- findChildElements: function(element, expressions) {
3426
- expressions = Selector.split(expressions.join(','));
3427
- var results = [], h = Selector.handlers;
3428
- for (var i = 0, l = expressions.length, selector; i < l; i++) {
3429
- selector = new Selector(expressions[i].strip());
3430
- h.concat(results, selector.findElements(element));
3431
- }
3432
- return (l > 1) ? h.unique(results) : results;
3433
- }
3434
- });
3435
-
3436
- if (Prototype.Browser.IE) {
3437
- Object.extend(Selector.handlers, {
3438
- // IE returns comment nodes on getElementsByTagName("*").
3439
- // Filter them out.
3440
- concat: function(a, b) {
3441
- for (var i = 0, node; node = b[i]; i++)
3442
- if (node.tagName !== "!") a.push(node);
3443
- return a;
3444
- },
3445
-
3446
- // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
3447
- unmark: function(nodes) {
3448
- for (var i = 0, node; node = nodes[i]; i++)
3449
- node.removeAttribute('_countedByPrototype');
3450
- return nodes;
3451
- }
3452
- });
3453
- }
3454
-
3455
- function $$() {
3456
- return Selector.findChildElements(document, $A(arguments));
3457
- }
3458
- var Form = {
3459
- reset: function(form) {
3460
- $(form).reset();
3461
- return form;
3462
- },
3463
-
3464
- serializeElements: function(elements, options) {
3465
- if (typeof options != 'object') options = { hash: !!options };
3466
- else if (Object.isUndefined(options.hash)) options.hash = true;
3467
- var key, value, submitted = false, submit = options.submit;
3468
-
3469
- var data = elements.inject({ }, function(result, element) {
3470
- if (!element.disabled && element.name) {
3471
- key = element.name; value = $(element).getValue();
3472
- if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
3473
- submit !== false && (!submit || key == submit) && (submitted = true)))) {
3474
- if (key in result) {
3475
- // a key is already present; construct an array of values
3476
- if (!Object.isArray(result[key])) result[key] = [result[key]];
3477
- result[key].push(value);
3478
- }
3479
- else result[key] = value;
3480
- }
3481
- }
3482
- return result;
3483
- });
3484
-
3485
- return options.hash ? data : Object.toQueryString(data);
3486
- }
3487
- };
3488
-
3489
- Form.Methods = {
3490
- serialize: function(form, options) {
3491
- return Form.serializeElements(Form.getElements(form), options);
3492
- },
3493
-
3494
- getElements: function(form) {
3495
- return $A($(form).getElementsByTagName('*')).inject([],
3496
- function(elements, child) {
3497
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
3498
- elements.push(Element.extend(child));
3499
- return elements;
3500
- }
3501
- );
3502
- },
3503
-
3504
- getInputs: function(form, typeName, name) {
3505
- form = $(form);
3506
- var inputs = form.getElementsByTagName('input');
3507
-
3508
- if (!typeName && !name) return $A(inputs).map(Element.extend);
3509
-
3510
- for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
3511
- var input = inputs[i];
3512
- if ((typeName && input.type != typeName) || (name && input.name != name))
3513
- continue;
3514
- matchingInputs.push(Element.extend(input));
3515
- }
3516
-
3517
- return matchingInputs;
3518
- },
3519
-
3520
- disable: function(form) {
3521
- form = $(form);
3522
- Form.getElements(form).invoke('disable');
3523
- return form;
3524
- },
3525
-
3526
- enable: function(form) {
3527
- form = $(form);
3528
- Form.getElements(form).invoke('enable');
3529
- return form;
3530
- },
3531
-
3532
- findFirstElement: function(form) {
3533
- var elements = $(form).getElements().findAll(function(element) {
3534
- return 'hidden' != element.type && !element.disabled;
3535
- });
3536
- var firstByIndex = elements.findAll(function(element) {
3537
- return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
3538
- }).sortBy(function(element) { return element.tabIndex }).first();
3539
-
3540
- return firstByIndex ? firstByIndex : elements.find(function(element) {
3541
- return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
3542
- });
3543
- },
3544
-
3545
- focusFirstElement: function(form) {
3546
- form = $(form);
3547
- form.findFirstElement().activate();
3548
- return form;
3549
- },
3550
-
3551
- request: function(form, options) {
3552
- form = $(form), options = Object.clone(options || { });
3553
-
3554
- var params = options.parameters, action = form.readAttribute('action') || '';
3555
- if (action.blank()) action = window.location.href;
3556
- options.parameters = form.serialize(true);
3557
-
3558
- if (params) {
3559
- if (Object.isString(params)) params = params.toQueryParams();
3560
- Object.extend(options.parameters, params);
3561
- }
3562
-
3563
- if (form.hasAttribute('method') && !options.method)
3564
- options.method = form.method;
3565
-
3566
- return new Ajax.Request(action, options);
3567
- }
3568
- };
3569
-
3570
- /*--------------------------------------------------------------------------*/
3571
-
3572
- Form.Element = {
3573
- focus: function(element) {
3574
- $(element).focus();
3575
- return element;
3576
- },
3577
-
3578
- select: function(element) {
3579
- $(element).select();
3580
- return element;
3581
- }
3582
- };
3583
-
3584
- Form.Element.Methods = {
3585
- serialize: function(element) {
3586
- element = $(element);
3587
- if (!element.disabled && element.name) {
3588
- var value = element.getValue();
3589
- if (value != undefined) {
3590
- var pair = { };
3591
- pair[element.name] = value;
3592
- return Object.toQueryString(pair);
3593
- }
3594
- }
3595
- return '';
3596
- },
3597
-
3598
- getValue: function(element) {
3599
- element = $(element);
3600
- var method = element.tagName.toLowerCase();
3601
- return Form.Element.Serializers[method](element);
3602
- },
3603
-
3604
- setValue: function(element, value) {
3605
- element = $(element);
3606
- var method = element.tagName.toLowerCase();
3607
- Form.Element.Serializers[method](element, value);
3608
- return element;
3609
- },
3610
-
3611
- clear: function(element) {
3612
- $(element).value = '';
3613
- return element;
3614
- },
3615
-
3616
- present: function(element) {
3617
- return $(element).value != '';
3618
- },
3619
-
3620
- activate: function(element) {
3621
- element = $(element);
3622
- try {
3623
- element.focus();
3624
- if (element.select && (element.tagName.toLowerCase() != 'input' ||
3625
- !['button', 'reset', 'submit'].include(element.type)))
3626
- element.select();
3627
- } catch (e) { }
3628
- return element;
3629
- },
3630
-
3631
- disable: function(element) {
3632
- element = $(element);
3633
- element.disabled = true;
3634
- return element;
3635
- },
3636
-
3637
- enable: function(element) {
3638
- element = $(element);
3639
- element.disabled = false;
3640
- return element;
3641
- }
3642
- };
3643
-
3644
- /*--------------------------------------------------------------------------*/
3645
-
3646
- var Field = Form.Element;
3647
- var $F = Form.Element.Methods.getValue;
3648
-
3649
- /*--------------------------------------------------------------------------*/
3650
-
3651
- Form.Element.Serializers = {
3652
- input: function(element, value) {
3653
- switch (element.type.toLowerCase()) {
3654
- case 'checkbox':
3655
- case 'radio':
3656
- return Form.Element.Serializers.inputSelector(element, value);
3657
- default:
3658
- return Form.Element.Serializers.textarea(element, value);
3659
- }
3660
- },
3661
-
3662
- inputSelector: function(element, value) {
3663
- if (Object.isUndefined(value)) return element.checked ? element.value : null;
3664
- else element.checked = !!value;
3665
- },
3666
-
3667
- textarea: function(element, value) {
3668
- if (Object.isUndefined(value)) return element.value;
3669
- else element.value = value;
3670
- },
3671
-
3672
- select: function(element, value) {
3673
- if (Object.isUndefined(value))
3674
- return this[element.type == 'select-one' ?
3675
- 'selectOne' : 'selectMany'](element);
3676
- else {
3677
- var opt, currentValue, single = !Object.isArray(value);
3678
- for (var i = 0, length = element.length; i < length; i++) {
3679
- opt = element.options[i];
3680
- currentValue = this.optionValue(opt);
3681
- if (single) {
3682
- if (currentValue == value) {
3683
- opt.selected = true;
3684
- return;
3685
- }
3686
- }
3687
- else opt.selected = value.include(currentValue);
3688
- }
3689
- }
3690
- },
3691
-
3692
- selectOne: function(element) {
3693
- var index = element.selectedIndex;
3694
- return index >= 0 ? this.optionValue(element.options[index]) : null;
3695
- },
3696
-
3697
- selectMany: function(element) {
3698
- var values, length = element.length;
3699
- if (!length) return null;
3700
-
3701
- for (var i = 0, values = []; i < length; i++) {
3702
- var opt = element.options[i];
3703
- if (opt.selected) values.push(this.optionValue(opt));
3704
- }
3705
- return values;
3706
- },
3707
-
3708
- optionValue: function(opt) {
3709
- // extend element because hasAttribute may not be native
3710
- return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
3711
- }
3712
- };
3713
-
3714
- /*--------------------------------------------------------------------------*/
3715
-
3716
- Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
3717
- initialize: function($super, element, frequency, callback) {
3718
- $super(callback, frequency);
3719
- this.element = $(element);
3720
- this.lastValue = this.getValue();
3721
- },
3722
-
3723
- execute: function() {
3724
- var value = this.getValue();
3725
- if (Object.isString(this.lastValue) && Object.isString(value) ?
3726
- this.lastValue != value : String(this.lastValue) != String(value)) {
3727
- this.callback(this.element, value);
3728
- this.lastValue = value;
3729
- }
3730
- }
3731
- });
3732
-
3733
- Form.Element.Observer = Class.create(Abstract.TimedObserver, {
3734
- getValue: function() {
3735
- return Form.Element.getValue(this.element);
3736
- }
3737
- });
3738
-
3739
- Form.Observer = Class.create(Abstract.TimedObserver, {
3740
- getValue: function() {
3741
- return Form.serialize(this.element);
3742
- }
3743
- });
3744
-
3745
- /*--------------------------------------------------------------------------*/
3746
-
3747
- Abstract.EventObserver = Class.create({
3748
- initialize: function(element, callback) {
3749
- this.element = $(element);
3750
- this.callback = callback;
3751
-
3752
- this.lastValue = this.getValue();
3753
- if (this.element.tagName.toLowerCase() == 'form')
3754
- this.registerFormCallbacks();
3755
- else
3756
- this.registerCallback(this.element);
3757
- },
3758
-
3759
- onElementEvent: function() {
3760
- var value = this.getValue();
3761
- if (this.lastValue != value) {
3762
- this.callback(this.element, value);
3763
- this.lastValue = value;
3764
- }
3765
- },
3766
-
3767
- registerFormCallbacks: function() {
3768
- Form.getElements(this.element).each(this.registerCallback, this);
3769
- },
3770
-
3771
- registerCallback: function(element) {
3772
- if (element.type) {
3773
- switch (element.type.toLowerCase()) {
3774
- case 'checkbox':
3775
- case 'radio':
3776
- Event.observe(element, 'click', this.onElementEvent.bind(this));
3777
- break;
3778
- default:
3779
- Event.observe(element, 'change', this.onElementEvent.bind(this));
3780
- break;
3781
- }
3782
- }
3783
- }
3784
- });
3785
-
3786
- Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
3787
- getValue: function() {
3788
- return Form.Element.getValue(this.element);
3789
- }
3790
- });
3791
-
3792
- Form.EventObserver = Class.create(Abstract.EventObserver, {
3793
- getValue: function() {
3794
- return Form.serialize(this.element);
3795
- }
3796
- });
3797
- if (!window.Event) var Event = { };
3798
-
3799
- Object.extend(Event, {
3800
- KEY_BACKSPACE: 8,
3801
- KEY_TAB: 9,
3802
- KEY_RETURN: 13,
3803
- KEY_ESC: 27,
3804
- KEY_LEFT: 37,
3805
- KEY_UP: 38,
3806
- KEY_RIGHT: 39,
3807
- KEY_DOWN: 40,
3808
- KEY_DELETE: 46,
3809
- KEY_HOME: 36,
3810
- KEY_END: 35,
3811
- KEY_PAGEUP: 33,
3812
- KEY_PAGEDOWN: 34,
3813
- KEY_INSERT: 45,
3814
-
3815
- cache: { },
3816
-
3817
- relatedTarget: function(event) {
3818
- var element;
3819
- switch(event.type) {
3820
- case 'mouseover': element = event.fromElement; break;
3821
- case 'mouseout': element = event.toElement; break;
3822
- default: return null;
3823
- }
3824
- return Element.extend(element);
3825
- }
3826
- });
3827
-
3828
- Event.Methods = (function() {
3829
- var isButton;
3830
-
3831
- if (Prototype.Browser.IE) {
3832
- var buttonMap = { 0: 1, 1: 4, 2: 2 };
3833
- isButton = function(event, code) {
3834
- return event.button == buttonMap[code];
3835
- };
3836
-
3837
- } else if (Prototype.Browser.WebKit) {
3838
- isButton = function(event, code) {
3839
- switch (code) {
3840
- case 0: return event.which == 1 && !event.metaKey;
3841
- case 1: return event.which == 1 && event.metaKey;
3842
- default: return false;
3843
- }
3844
- };
3845
-
3846
- } else {
3847
- isButton = function(event, code) {
3848
- return event.which ? (event.which === code + 1) : (event.button === code);
3849
- };
3850
- }
3851
-
3852
- return {
3853
- isLeftClick: function(event) { return isButton(event, 0) },
3854
- isMiddleClick: function(event) { return isButton(event, 1) },
3855
- isRightClick: function(event) { return isButton(event, 2) },
3856
-
3857
- element: function(event) {
3858
- event = Event.extend(event);
3859
-
3860
- var node = event.target,
3861
- type = event.type,
3862
- currentTarget = event.currentTarget;
3863
-
3864
- if (currentTarget && currentTarget.tagName) {
3865
- // Firefox screws up the "click" event when moving between radio buttons
3866
- // via arrow keys. It also screws up the "load" and "error" events on images,
3867
- // reporting the document as the target instead of the original image.
3868
- if (type === 'load' || type === 'error' ||
3869
- (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
3870
- && currentTarget.type === 'radio'))
3871
- node = currentTarget;
3872
- }
3873
- if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
3874
- return Element.extend(node);
3875
- },
3876
-
3877
- findElement: function(event, expression) {
3878
- var element = Event.element(event);
3879
- if (!expression) return element;
3880
- var elements = [element].concat(element.ancestors());
3881
- return Selector.findElement(elements, expression, 0);
3882
- },
3883
-
3884
- pointer: function(event) {
3885
- var docElement = document.documentElement,
3886
- body = document.body || { scrollLeft: 0, scrollTop: 0 };
3887
- return {
3888
- x: event.pageX || (event.clientX +
3889
- (docElement.scrollLeft || body.scrollLeft) -
3890
- (docElement.clientLeft || 0)),
3891
- y: event.pageY || (event.clientY +
3892
- (docElement.scrollTop || body.scrollTop) -
3893
- (docElement.clientTop || 0))
3894
- };
3895
- },
3896
-
3897
- pointerX: function(event) { return Event.pointer(event).x },
3898
- pointerY: function(event) { return Event.pointer(event).y },
3899
-
3900
- stop: function(event) {
3901
- Event.extend(event);
3902
- event.preventDefault();
3903
- event.stopPropagation();
3904
- event.stopped = true;
3905
- }
3906
- };
3907
- })();
3908
-
3909
- Event.extend = (function() {
3910
- var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
3911
- m[name] = Event.Methods[name].methodize();
3912
- return m;
3913
- });
3914
-
3915
- if (Prototype.Browser.IE) {
3916
- Object.extend(methods, {
3917
- stopPropagation: function() { this.cancelBubble = true },
3918
- preventDefault: function() { this.returnValue = false },
3919
- inspect: function() { return "[object Event]" }
3920
- });
3921
-
3922
- return function(event) {
3923
- if (!event) return false;
3924
- if (event._extendedByPrototype) return event;
3925
-
3926
- event._extendedByPrototype = Prototype.emptyFunction;
3927
- var pointer = Event.pointer(event);
3928
- Object.extend(event, {
3929
- target: event.srcElement,
3930
- relatedTarget: Event.relatedTarget(event),
3931
- pageX: pointer.x,
3932
- pageY: pointer.y
3933
- });
3934
- return Object.extend(event, methods);
3935
- };
3936
-
3937
- } else {
3938
- Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
3939
- Object.extend(Event.prototype, methods);
3940
- return Prototype.K;
3941
- }
3942
- })();
3943
-
3944
- Object.extend(Event, (function() {
3945
- var cache = Event.cache;
3946
-
3947
- function getEventID(element) {
3948
- if (element._prototypeEventID) return element._prototypeEventID[0];
3949
- arguments.callee.id = arguments.callee.id || 1;
3950
- return element._prototypeEventID = [++arguments.callee.id];
3951
- }
3952
-
3953
- function getDOMEventName(eventName) {
3954
- if (eventName && eventName.include(':')) return "dataavailable";
3955
- return eventName;
3956
- }
3957
-
3958
- function getCacheForID(id) {
3959
- return cache[id] = cache[id] || { };
3960
- }
3961
-
3962
- function getWrappersForEventName(id, eventName) {
3963
- var c = getCacheForID(id);
3964
- return c[eventName] = c[eventName] || [];
3965
- }
3966
-
3967
- function createWrapper(element, eventName, handler) {
3968
- var id = getEventID(element);
3969
- var c = getWrappersForEventName(id, eventName);
3970
- if (c.pluck("handler").include(handler)) return false;
3971
-
3972
- var wrapper = function(event) {
3973
- if (!Event || !Event.extend ||
3974
- (event.eventName && event.eventName != eventName))
3975
- return false;
3976
-
3977
- Event.extend(event);
3978
- handler.call(element, event);
3979
- };
3980
-
3981
- wrapper.handler = handler;
3982
- c.push(wrapper);
3983
- return wrapper;
3984
- }
3985
-
3986
- function findWrapper(id, eventName, handler) {
3987
- var c = getWrappersForEventName(id, eventName);
3988
- return c.find(function(wrapper) { return wrapper.handler == handler });
3989
- }
3990
-
3991
- function destroyWrapper(id, eventName, handler) {
3992
- var c = getCacheForID(id);
3993
- if (!c[eventName]) return false;
3994
- c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
3995
- }
3996
-
3997
- function destroyCache() {
3998
- for (var id in cache)
3999
- for (var eventName in cache[id])
4000
- cache[id][eventName] = null;
4001
- }
4002
-
4003
-
4004
- // Internet Explorer needs to remove event handlers on page unload
4005
- // in order to avoid memory leaks.
4006
- if (window.attachEvent) {
4007
- window.attachEvent("onunload", destroyCache);
4008
- }
4009
-
4010
- // Safari has a dummy event handler on page unload so that it won't
4011
- // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
4012
- // object when page is returned to via the back button using its bfcache.
4013
- if (Prototype.Browser.WebKit) {
4014
- window.addEventListener('unload', Prototype.emptyFunction, false);
4015
- }
4016
-
4017
- return {
4018
- observe: function(element, eventName, handler) {
4019
- element = $(element);
4020
- var name = getDOMEventName(eventName);
4021
-
4022
- var wrapper = createWrapper(element, eventName, handler);
4023
- if (!wrapper) return element;
4024
-
4025
- if (element.addEventListener) {
4026
- element.addEventListener(name, wrapper, false);
4027
- } else {
4028
- element.attachEvent("on" + name, wrapper);
4029
- }
4030
-
4031
- return element;
4032
- },
4033
-
4034
- stopObserving: function(element, eventName, handler) {
4035
- element = $(element);
4036
- var id = getEventID(element), name = getDOMEventName(eventName);
4037
-
4038
- if (!handler && eventName) {
4039
- getWrappersForEventName(id, eventName).each(function(wrapper) {
4040
- element.stopObserving(eventName, wrapper.handler);
4041
- });
4042
- return element;
4043
-
4044
- } else if (!eventName) {
4045
- Object.keys(getCacheForID(id)).each(function(eventName) {
4046
- element.stopObserving(eventName);
4047
- });
4048
- return element;
4049
- }
4050
-
4051
- var wrapper = findWrapper(id, eventName, handler);
4052
- if (!wrapper) return element;
4053
-
4054
- if (element.removeEventListener) {
4055
- element.removeEventListener(name, wrapper, false);
4056
- } else {
4057
- element.detachEvent("on" + name, wrapper);
4058
- }
4059
-
4060
- destroyWrapper(id, eventName, handler);
4061
-
4062
- return element;
4063
- },
4064
-
4065
- fire: function(element, eventName, memo) {
4066
- element = $(element);
4067
- if (element == document && document.createEvent && !element.dispatchEvent)
4068
- element = document.documentElement;
4069
-
4070
- var event;
4071
- if (document.createEvent) {
4072
- event = document.createEvent("HTMLEvents");
4073
- event.initEvent("dataavailable", true, true);
4074
- } else {
4075
- event = document.createEventObject();
4076
- event.eventType = "ondataavailable";
4077
- }
4078
-
4079
- event.eventName = eventName;
4080
- event.memo = memo || { };
4081
-
4082
- if (document.createEvent) {
4083
- element.dispatchEvent(event);
4084
- } else {
4085
- element.fireEvent(event.eventType, event);
4086
- }
4087
-
4088
- return Event.extend(event);
4089
- }
4090
- };
4091
- })());
4092
-
4093
- Object.extend(Event, Event.Methods);
4094
-
4095
- Element.addMethods({
4096
- fire: Event.fire,
4097
- observe: Event.observe,
4098
- stopObserving: Event.stopObserving
4099
- });
4100
-
4101
- Object.extend(document, {
4102
- fire: Element.Methods.fire.methodize(),
4103
- observe: Element.Methods.observe.methodize(),
4104
- stopObserving: Element.Methods.stopObserving.methodize(),
4105
- loaded: false
4106
- });
4107
-
4108
- (function() {
4109
- /* Support for the DOMContentLoaded event is based on work by Dan Webb,
4110
- Matthias Miller, Dean Edwards and John Resig. */
4111
-
4112
- var timer;
4113
-
4114
- function fireContentLoadedEvent() {
4115
- if (document.loaded) return;
4116
- if (timer) window.clearInterval(timer);
4117
- document.fire("dom:loaded");
4118
- document.loaded = true;
4119
- }
4120
-
4121
- if (document.addEventListener) {
4122
- if (Prototype.Browser.WebKit) {
4123
- timer = window.setInterval(function() {
4124
- if (/loaded|complete/.test(document.readyState))
4125
- fireContentLoadedEvent();
4126
- }, 0);
4127
-
4128
- Event.observe(window, "load", fireContentLoadedEvent);
4129
-
4130
- } else {
4131
- document.addEventListener("DOMContentLoaded",
4132
- fireContentLoadedEvent, false);
4133
- }
4134
-
4135
- } else {
4136
- document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
4137
- $("__onDOMContentLoaded").onreadystatechange = function() {
4138
- if (this.readyState == "complete") {
4139
- this.onreadystatechange = null;
4140
- fireContentLoadedEvent();
4141
- }
4142
- };
4143
- }
4144
- })();
4145
- /*------------------------------- DEPRECATED -------------------------------*/
4146
-
4147
- Hash.toQueryString = Object.toQueryString;
4148
-
4149
- var Toggle = { display: Element.toggle };
4150
-
4151
- Element.Methods.childOf = Element.Methods.descendantOf;
4152
-
4153
- var Insertion = {
4154
- Before: function(element, content) {
4155
- return Element.insert(element, {before:content});
4156
- },
4157
-
4158
- Top: function(element, content) {
4159
- return Element.insert(element, {top:content});
4160
- },
4161
-
4162
- Bottom: function(element, content) {
4163
- return Element.insert(element, {bottom:content});
4164
- },
4165
-
4166
- After: function(element, content) {
4167
- return Element.insert(element, {after:content});
4168
- }
4169
- };
4170
-
4171
- var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
4172
-
4173
- // This should be moved to script.aculo.us; notice the deprecated methods
4174
- // further below, that map to the newer Element methods.
4175
- var Position = {
4176
- // set to true if needed, warning: firefox performance problems
4177
- // NOT neeeded for page scrolling, only if draggable contained in
4178
- // scrollable elements
4179
- includeScrollOffsets: false,
4180
-
4181
- // must be called before calling withinIncludingScrolloffset, every time the
4182
- // page is scrolled
4183
- prepare: function() {
4184
- this.deltaX = window.pageXOffset
4185
- || document.documentElement.scrollLeft
4186
- || document.body.scrollLeft
4187
- || 0;
4188
- this.deltaY = window.pageYOffset
4189
- || document.documentElement.scrollTop
4190
- || document.body.scrollTop
4191
- || 0;
4192
- },
4193
-
4194
- // caches x/y coordinate pair to use with overlap
4195
- within: function(element, x, y) {
4196
- if (this.includeScrollOffsets)
4197
- return this.withinIncludingScrolloffsets(element, x, y);
4198
- this.xcomp = x;
4199
- this.ycomp = y;
4200
- this.offset = Element.cumulativeOffset(element);
4201
-
4202
- return (y >= this.offset[1] &&
4203
- y < this.offset[1] + element.offsetHeight &&
4204
- x >= this.offset[0] &&
4205
- x < this.offset[0] + element.offsetWidth);
4206
- },
4207
-
4208
- withinIncludingScrolloffsets: function(element, x, y) {
4209
- var offsetcache = Element.cumulativeScrollOffset(element);
4210
-
4211
- this.xcomp = x + offsetcache[0] - this.deltaX;
4212
- this.ycomp = y + offsetcache[1] - this.deltaY;
4213
- this.offset = Element.cumulativeOffset(element);
4214
-
4215
- return (this.ycomp >= this.offset[1] &&
4216
- this.ycomp < this.offset[1] + element.offsetHeight &&
4217
- this.xcomp >= this.offset[0] &&
4218
- this.xcomp < this.offset[0] + element.offsetWidth);
4219
- },
4220
-
4221
- // within must be called directly before
4222
- overlap: function(mode, element) {
4223
- if (!mode) return 0;
4224
- if (mode == 'vertical')
4225
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
4226
- element.offsetHeight;
4227
- if (mode == 'horizontal')
4228
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
4229
- element.offsetWidth;
4230
- },
4231
-
4232
- // Deprecation layer -- use newer Element methods now (1.5.2).
4233
-
4234
- cumulativeOffset: Element.Methods.cumulativeOffset,
4235
-
4236
- positionedOffset: Element.Methods.positionedOffset,
4237
-
4238
- absolutize: function(element) {
4239
- Position.prepare();
4240
- return Element.absolutize(element);
4241
- },
4242
-
4243
- relativize: function(element) {
4244
- Position.prepare();
4245
- return Element.relativize(element);
4246
- },
4247
-
4248
- realOffset: Element.Methods.cumulativeScrollOffset,
4249
-
4250
- offsetParent: Element.Methods.getOffsetParent,
4251
-
4252
- page: Element.Methods.viewportOffset,
4253
-
4254
- clone: function(source, target, options) {
4255
- options = options || { };
4256
- return Element.clonePosition(target, source, options);
4257
- }
4258
- };
4259
-
4260
- /*--------------------------------------------------------------------------*/
4261
-
4262
- if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
4263
- function iter(name) {
4264
- return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
4265
- }
4266
-
4267
- instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
4268
- function(element, className) {
4269
- className = className.toString().strip();
4270
- var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
4271
- return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
4272
- } : function(element, className) {
4273
- className = className.toString().strip();
4274
- var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
4275
- if (!classNames && !className) return elements;
4276
-
4277
- var nodes = $(element).getElementsByTagName('*');
4278
- className = ' ' + className + ' ';
4279
-
4280
- for (var i = 0, child, cn; child = nodes[i]; i++) {
4281
- if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
4282
- (classNames && classNames.all(function(name) {
4283
- return !name.toString().blank() && cn.include(' ' + name + ' ');
4284
- }))))
4285
- elements.push(Element.extend(child));
4286
- }
4287
- return elements;
4288
- };
4289
-
4290
- return function(className, parentElement) {
4291
- return $(parentElement || document.body).getElementsByClassName(className);
4292
- };
4293
- }(Element.Methods);
4294
-
4295
- /*--------------------------------------------------------------------------*/
4296
-
4297
- Element.ClassNames = Class.create();
4298
- Element.ClassNames.prototype = {
4299
- initialize: function(element) {
4300
- this.element = $(element);
4301
- },
4302
-
4303
- _each: function(iterator) {
4304
- this.element.className.split(/\s+/).select(function(name) {
4305
- return name.length > 0;
4306
- })._each(iterator);
4307
- },
4308
-
4309
- set: function(className) {
4310
- this.element.className = className;
4311
- },
4312
-
4313
- add: function(classNameToAdd) {
4314
- if (this.include(classNameToAdd)) return;
4315
- this.set($A(this).concat(classNameToAdd).join(' '));
4316
- },
4317
-
4318
- remove: function(classNameToRemove) {
4319
- if (!this.include(classNameToRemove)) return;
4320
- this.set($A(this).without(classNameToRemove).join(' '));
4321
- },
4322
-
4323
- toString: function() {
4324
- return $A(this).join(' ');
4325
- }
4326
- };
4327
-
4328
- Object.extend(Element.ClassNames.prototype, Enumerable);
4329
-
4330
- /*--------------------------------------------------------------------------*/
4331
-
4332
- Element.addMethods();
4333
- var search_index = [
4334
- { method: 'broken', module: 'try', html: '<a href="classes/Try.html#M000001"><span class="method_name">broken</span> <span class="module_name">(Try)</span></a>' },
4335
- ]
4336
- $(document).observe('dom:loaded', function() {
4337
- // Setup search-during-typing.
4338
- new Form.Element.Observer('search', 0.3, function(element, value) {
4339
- performSearch();
4340
- });
4341
-
4342
- // Remove the default search box value when the user puts the focus on
4343
- // the search box for the first time.
4344
- var search_box = $('search');
4345
- if ($F('search') == 'Enter search terms...') {
4346
- search_box.observe('focus', function() {
4347
- if (search_box.hasClassName('untouched')) {
4348
- search_box.removeClassName('untouched');
4349
- search_box.value = '';
4350
- }
4351
- });
4352
- } else {
4353
- search_box.removeClassName('untouched');
4354
- }
4355
- });
4356
-
4357
- function searchInIndex(query) {
4358
- var i;
4359
- var results = [];
4360
- query = query.toLowerCase();
4361
- for (i = 0; i < search_index.length; i++) {
4362
- if (search_index[i].method.indexOf(query) != -1) {
4363
- results.push(search_index[i]);
4364
- }
4365
- }
4366
- return results;
4367
- }
4368
-
4369
- function buildHtmlForResults(results) {
4370
- var html = "";
4371
- var i;
4372
- for (i = 0; i < results.length; i++) {
4373
- html += '<li>' + results[i].html + '</li>';
4374
- }
4375
- return html;
4376
- }
4377
-
4378
- function performSearch() {
4379
- var query = $F('search');
4380
- if (query == '') {
4381
- $('index-entries').show();
4382
- $('search-results').hide();
4383
- } else {
4384
- var results = searchInIndex(query);
4385
- $('search-results').update(buildHtmlForResults(results));
4386
- $('index-entries').hide();
4387
- $('search-results').show();
4388
- }
4389
- return false;
4390
- }
4391
- </script>
4392
- <form onsubmit='return performSearch()'>
4393
- <input class='untouched' id='search' type='text' value='Enter search terms...'>
4394
- </form>
4395
- <ol class='methods' id='search-results' style='display: none'></ol>
4396
- <ol class='methods' id='index-entries'>
4397
- <li><a href="classes/Try.html#M000001"><span class="method_name">broken</span> <span class="module_name">(Try)</span></a></li>
4398
- </ol>
4399
- </div>
4400
- </body>
4401
- </html>