]> git.wh0rd.org - tt-rss.git/blame - lib/prototype.js
pngcrush.sh
[tt-rss.git] / lib / prototype.js
CommitLineData
3fe38208
AD
1// Modified document.on() to modified.p_on() to fix compatibility with Dojo -fox
2
e3cfa33b 3/* Prototype JavaScript framework, version 1.7.3
3fe38208 4 * (c) 2005-2010 Sam Stephenson
14f69488
AD
5 *
6 * Prototype is freely distributable under the terms of an MIT-style license.
4b9dfd5b 7 * For details, see the Prototype web site: http://www.prototypejs.org/
14f69488 8 *
4b9dfd5b 9 *--------------------------------------------------------------------------*/
14f69488
AD
10
11var Prototype = {
3fe38208 12
e3cfa33b 13 Version: '1.7.3',
85e836d8
AD
14
15 Browser: (function(){
16 var ua = navigator.userAgent;
17 var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
18 return {
19 IE: !!window.attachEvent && !isOpera,
20 Opera: isOpera,
21 WebKit: ua.indexOf('AppleWebKit/') > -1,
22 Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
3fe38208 23 MobileSafari: /Apple.*Mobile/.test(ua)
85e836d8
AD
24 }
25 })(),
4b9dfd5b 26
5c656a9d 27 BrowserFeatures: {
4b9dfd5b 28 XPath: !!document.evaluate,
3fe38208 29
85e836d8 30 SelectorsAPI: !!document.querySelector,
3fe38208 31
85e836d8
AD
32 ElementExtensions: (function() {
33 var constructor = window.Element || window.HTMLElement;
34 return !!(constructor && constructor.prototype);
35 })(),
36 SpecificElementExtensions: (function() {
37 if (typeof window.HTMLDivElement !== 'undefined')
38 return true;
39
3fe38208
AD
40 var div = document.createElement('div'),
41 form = document.createElement('form'),
42 isSupported = false;
85e836d8
AD
43
44 if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
45 isSupported = true;
46 }
47
48 div = form = null;
49
50 return isSupported;
51 })()
5c656a9d 52 },
14f69488 53
e3cfa33b 54 ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script\\s*>',
4b9dfd5b
AD
55 JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
56
57 emptyFunction: function() { },
3fe38208 58
5c656a9d 59 K: function(x) { return x }
4b9dfd5b
AD
60};
61
62if (Prototype.Browser.MobileSafari)
63 Prototype.BrowserFeatures.SpecificElementExtensions = false;
4b9dfd5b 64/* Based on Alex Arnell's inheritance implementation. */
85e836d8
AD
65
66var Class = (function() {
3fe38208
AD
67
68 var IS_DONTENUM_BUGGY = (function(){
69 for (var p in { toString: 1 }) {
70 if (p === 'toString') return false;
71 }
72 return true;
73 })();
74
85e836d8
AD
75 function subclass() {};
76 function create() {
4b9dfd5b
AD
77 var parent = null, properties = $A(arguments);
78 if (Object.isFunction(properties[0]))
79 parent = properties.shift();
80
81 function klass() {
14f69488
AD
82 this.initialize.apply(this, arguments);
83 }
4b9dfd5b
AD
84
85 Object.extend(klass, Class.Methods);
86 klass.superclass = parent;
87 klass.subclasses = [];
88
89 if (parent) {
4b9dfd5b
AD
90 subclass.prototype = parent.prototype;
91 klass.prototype = new subclass;
92 parent.subclasses.push(klass);
93 }
94
3fe38208 95 for (var i = 0, length = properties.length; i < length; i++)
4b9dfd5b
AD
96 klass.addMethods(properties[i]);
97
98 if (!klass.prototype.initialize)
99 klass.prototype.initialize = Prototype.emptyFunction;
100
101 klass.prototype.constructor = klass;
4b9dfd5b
AD
102 return klass;
103 }
4b9dfd5b 104
85e836d8 105 function addMethods(source) {
3fe38208
AD
106 var ancestor = this.superclass && this.superclass.prototype,
107 properties = Object.keys(source);
4b9dfd5b 108
3fe38208 109 if (IS_DONTENUM_BUGGY) {
85e836d8
AD
110 if (source.toString != Object.prototype.toString)
111 properties.push("toString");
112 if (source.valueOf != Object.prototype.valueOf)
113 properties.push("valueOf");
114 }
4b9dfd5b
AD
115
116 for (var i = 0, length = properties.length; i < length; i++) {
117 var property = properties[i], value = source[property];
118 if (ancestor && Object.isFunction(value) &&
3fe38208 119 value.argumentNames()[0] == "$super") {
85e836d8
AD
120 var method = value;
121 value = (function(m) {
122 return function() { return ancestor[m].apply(this, arguments); };
123 })(property).wrap(method);
124
e3cfa33b
AK
125 value.valueOf = (function(method) {
126 return function() { return method.valueOf.call(method); };
127 })(method);
128
129 value.toString = (function(method) {
130 return function() { return method.toString.call(method); };
131 })(method);
4b9dfd5b
AD
132 }
133 this.prototype[property] = value;
134 }
135
136 return this;
14f69488 137 }
14f69488 138
85e836d8
AD
139 return {
140 create: create,
141 Methods: {
142 addMethods: addMethods
143 }
144 };
145})();
146(function() {
14f69488 147
3fe38208 148 var _toString = Object.prototype.toString,
e3cfa33b 149 _hasOwnProperty = Object.prototype.hasOwnProperty,
3fe38208
AD
150 NULL_TYPE = 'Null',
151 UNDEFINED_TYPE = 'Undefined',
152 BOOLEAN_TYPE = 'Boolean',
153 NUMBER_TYPE = 'Number',
154 STRING_TYPE = 'String',
155 OBJECT_TYPE = 'Object',
156 FUNCTION_CLASS = '[object Function]',
157 BOOLEAN_CLASS = '[object Boolean]',
158 NUMBER_CLASS = '[object Number]',
159 STRING_CLASS = '[object String]',
160 ARRAY_CLASS = '[object Array]',
161 DATE_CLASS = '[object Date]',
162 NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
163 typeof JSON.stringify === 'function' &&
164 JSON.stringify(0) === '0' &&
165 typeof JSON.stringify(Prototype.K) === 'undefined';
166
e3cfa33b
AK
167
168
169 var DONT_ENUMS = ['toString', 'toLocaleString', 'valueOf',
170 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'];
171
172 var IS_DONTENUM_BUGGY = (function(){
173 for (var p in { toString: 1 }) {
174 if (p === 'toString') return false;
175 }
176 return true;
177 })();
178
3fe38208
AD
179 function Type(o) {
180 switch(o) {
181 case null: return NULL_TYPE;
182 case (void 0): return UNDEFINED_TYPE;
183 }
184 var type = typeof o;
185 switch(type) {
186 case 'boolean': return BOOLEAN_TYPE;
187 case 'number': return NUMBER_TYPE;
188 case 'string': return STRING_TYPE;
189 }
190 return OBJECT_TYPE;
191 }
85e836d8
AD
192
193 function extend(destination, source) {
194 for (var property in source)
195 destination[property] = source[property];
196 return destination;
197 }
14f69488 198
85e836d8 199 function inspect(object) {
5c656a9d 200 try {
85e836d8 201 if (isUndefined(object)) return 'undefined';
5c656a9d 202 if (object === null) return 'null';
85e836d8 203 return object.inspect ? object.inspect() : String(object);
5c656a9d
AD
204 } catch (e) {
205 if (e instanceof RangeError) return '...';
206 throw e;
207 }
85e836d8 208 }
5c656a9d 209
3fe38208
AD
210 function toJSON(value) {
211 return Str('', { '': value }, []);
212 }
213
214 function Str(key, holder, stack) {
e3cfa33b 215 var value = holder[key];
3fe38208
AD
216 if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
217 value = value.toJSON(key);
4b9dfd5b
AD
218 }
219
3fe38208 220 var _class = _toString.call(value);
4b9dfd5b 221
3fe38208
AD
222 switch (_class) {
223 case NUMBER_CLASS:
224 case BOOLEAN_CLASS:
225 case STRING_CLASS:
226 value = value.valueOf();
227 }
228
229 switch (value) {
230 case null: return 'null';
231 case true: return 'true';
232 case false: return 'false';
233 }
234
e3cfa33b 235 var type = typeof value;
3fe38208
AD
236 switch (type) {
237 case 'string':
238 return value.inspect(true);
239 case 'number':
240 return isFinite(value) ? String(value) : 'null';
241 case 'object':
242
243 for (var i = 0, length = stack.length; i < length; i++) {
e3cfa33b
AK
244 if (stack[i] === value) {
245 throw new TypeError("Cyclic reference to '" + value + "' in object");
246 }
3fe38208
AD
247 }
248 stack.push(value);
249
250 var partial = [];
251 if (_class === ARRAY_CLASS) {
252 for (var i = 0, length = value.length; i < length; i++) {
253 var str = Str(i, value, stack);
254 partial.push(typeof str === 'undefined' ? 'null' : str);
255 }
256 partial = '[' + partial.join(',') + ']';
257 } else {
258 var keys = Object.keys(value);
259 for (var i = 0, length = keys.length; i < length; i++) {
260 var key = keys[i], str = Str(key, value, stack);
261 if (typeof str !== "undefined") {
262 partial.push(key.inspect(true)+ ':' + str);
263 }
264 }
265 partial = '{' + partial.join(',') + '}';
266 }
267 stack.pop();
268 return partial;
4b9dfd5b 269 }
3fe38208 270 }
4b9dfd5b 271
3fe38208
AD
272 function stringify(object) {
273 return JSON.stringify(object);
85e836d8 274 }
4b9dfd5b 275
85e836d8 276 function toQueryString(object) {
4b9dfd5b 277 return $H(object).toQueryString();
85e836d8 278 }
4b9dfd5b 279
85e836d8 280 function toHTML(object) {
4b9dfd5b 281 return object && object.toHTML ? object.toHTML() : String.interpret(object);
85e836d8 282 }
4b9dfd5b 283
85e836d8 284 function keys(object) {
3fe38208 285 if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
85e836d8 286 var results = [];
3fe38208 287 for (var property in object) {
e3cfa33b 288 if (_hasOwnProperty.call(object, property))
3fe38208 289 results.push(property);
e3cfa33b
AK
290 }
291
292 if (IS_DONTENUM_BUGGY) {
293 for (var i = 0; property = DONT_ENUMS[i]; i++) {
294 if (_hasOwnProperty.call(object, property))
295 results.push(property);
3fe38208
AD
296 }
297 }
e3cfa33b 298
85e836d8
AD
299 return results;
300 }
5c656a9d 301
85e836d8
AD
302 function values(object) {
303 var results = [];
5c656a9d 304 for (var property in object)
85e836d8
AD
305 results.push(object[property]);
306 return results;
307 }
5c656a9d 308
85e836d8
AD
309 function clone(object) {
310 return extend({ }, object);
311 }
4b9dfd5b 312
85e836d8
AD
313 function isElement(object) {
314 return !!(object && object.nodeType == 1);
315 }
316
317 function isArray(object) {
3fe38208 318 return _toString.call(object) === ARRAY_CLASS;
85e836d8 319 }
4b9dfd5b 320
3fe38208
AD
321 var hasNativeIsArray = (typeof Array.isArray == 'function')
322 && Array.isArray([]) && !Array.isArray({});
323
324 if (hasNativeIsArray) {
325 isArray = Array.isArray;
326 }
4b9dfd5b 327
85e836d8 328 function isHash(object) {
4b9dfd5b 329 return object instanceof Hash;
85e836d8 330 }
4b9dfd5b 331
85e836d8 332 function isFunction(object) {
3fe38208 333 return _toString.call(object) === FUNCTION_CLASS;
85e836d8 334 }
4b9dfd5b 335
85e836d8 336 function isString(object) {
3fe38208 337 return _toString.call(object) === STRING_CLASS;
85e836d8 338 }
4b9dfd5b 339
85e836d8 340 function isNumber(object) {
3fe38208
AD
341 return _toString.call(object) === NUMBER_CLASS;
342 }
343
344 function isDate(object) {
345 return _toString.call(object) === DATE_CLASS;
85e836d8 346 }
4b9dfd5b 347
85e836d8
AD
348 function isUndefined(object) {
349 return typeof object === "undefined";
14f69488 350 }
14f69488 351
85e836d8
AD
352 extend(Object, {
353 extend: extend,
354 inspect: inspect,
3fe38208 355 toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
85e836d8
AD
356 toQueryString: toQueryString,
357 toHTML: toHTML,
3fe38208 358 keys: Object.keys || keys,
85e836d8
AD
359 values: values,
360 clone: clone,
361 isElement: isElement,
362 isArray: isArray,
363 isHash: isHash,
364 isFunction: isFunction,
365 isString: isString,
366 isNumber: isNumber,
3fe38208 367 isDate: isDate,
85e836d8
AD
368 isUndefined: isUndefined
369 });
370})();
371Object.extend(Function.prototype, (function() {
372 var slice = Array.prototype.slice;
373
374 function update(array, args) {
375 var arrayLength = array.length, length = args.length;
376 while (length--) array[arrayLength + length] = args[length];
377 return array;
378 }
379
380 function merge(array, args) {
381 array = slice.call(array, 0);
382 return update(array, args);
383 }
384
385 function argumentNames() {
386 var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
387 .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
388 .replace(/\s+/g, '').split(',');
4b9dfd5b 389 return names.length == 1 && !names[0] ? [] : names;
85e836d8 390 }
14f69488 391
e3cfa33b 392
85e836d8 393 function bind(context) {
e3cfa33b
AK
394 if (arguments.length < 2 && Object.isUndefined(arguments[0]))
395 return this;
396
397 if (!Object.isFunction(this))
398 throw new TypeError("The object is not callable.");
399
400 var nop = function() {};
85e836d8 401 var __method = this, args = slice.call(arguments, 1);
e3cfa33b
AK
402
403 var bound = function() {
85e836d8 404 var a = merge(args, arguments);
e3cfa33b
AK
405 var c = this instanceof bound ? this : context;
406 return __method.apply(c, a);
407 };
408
409 nop.prototype = this.prototype;
410 bound.prototype = new nop();
411
412 return bound;
85e836d8 413 }
14f69488 414
85e836d8
AD
415 function bindAsEventListener(context) {
416 var __method = this, args = slice.call(arguments, 1);
4b9dfd5b 417 return function(event) {
85e836d8
AD
418 var a = update([event || window.event], args);
419 return __method.apply(context, a);
4b9dfd5b 420 }
85e836d8 421 }
14f69488 422
85e836d8 423 function curry() {
4b9dfd5b 424 if (!arguments.length) return this;
85e836d8 425 var __method = this, args = slice.call(arguments, 0);
4b9dfd5b 426 return function() {
85e836d8
AD
427 var a = merge(args, arguments);
428 return __method.apply(this, a);
4b9dfd5b 429 }
85e836d8 430 }
14f69488 431
85e836d8
AD
432 function delay(timeout) {
433 var __method = this, args = slice.call(arguments, 1);
3fe38208 434 timeout = timeout * 1000;
4b9dfd5b
AD
435 return window.setTimeout(function() {
436 return __method.apply(__method, args);
437 }, timeout);
85e836d8 438 }
4b9dfd5b 439
85e836d8
AD
440 function defer() {
441 var args = update([0.01], arguments);
442 return this.delay.apply(this, args);
443 }
444
445 function wrap(wrapper) {
4b9dfd5b
AD
446 var __method = this;
447 return function() {
85e836d8
AD
448 var a = update([__method.bind(this)], arguments);
449 return wrapper.apply(this, a);
4b9dfd5b 450 }
85e836d8 451 }
4b9dfd5b 452
85e836d8 453 function methodize() {
4b9dfd5b
AD
454 if (this._methodized) return this._methodized;
455 var __method = this;
456 return this._methodized = function() {
85e836d8
AD
457 var a = update([this], arguments);
458 return __method.apply(null, a);
4b9dfd5b 459 };
14f69488 460 }
14f69488 461
e3cfa33b 462 var extensions = {
85e836d8 463 argumentNames: argumentNames,
85e836d8
AD
464 bindAsEventListener: bindAsEventListener,
465 curry: curry,
466 delay: delay,
467 defer: defer,
468 wrap: wrap,
469 methodize: methodize
e3cfa33b
AK
470 };
471
472 if (!Function.prototype.bind)
473 extensions.bind = bind;
474
475 return extensions;
85e836d8
AD
476})());
477
4b9dfd5b 478
3fe38208
AD
479
480(function(proto) {
481
482
483 function toISOString() {
484 return this.getUTCFullYear() + '-' +
485 (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
486 this.getUTCDate().toPaddedString(2) + 'T' +
487 this.getUTCHours().toPaddedString(2) + ':' +
488 this.getUTCMinutes().toPaddedString(2) + ':' +
489 this.getUTCSeconds().toPaddedString(2) + 'Z';
490 }
491
492
493 function toJSON() {
494 return this.toISOString();
495 }
496
497 if (!proto.toISOString) proto.toISOString = toISOString;
498 if (!proto.toJSON) proto.toJSON = toJSON;
499
500})(Date.prototype);
4b9dfd5b 501
4b9dfd5b
AD
502
503RegExp.prototype.match = RegExp.prototype.test;
504
505RegExp.escape = function(str) {
506 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
507};
4b9dfd5b 508var PeriodicalExecuter = Class.create({
14f69488
AD
509 initialize: function(callback, frequency) {
510 this.callback = callback;
511 this.frequency = frequency;
512 this.currentlyExecuting = false;
513
514 this.registerCallback();
515 },
516
517 registerCallback: function() {
5c656a9d
AD
518 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
519 },
520
4b9dfd5b
AD
521 execute: function() {
522 this.callback(this);
523 },
524
5c656a9d
AD
525 stop: function() {
526 if (!this.timer) return;
527 clearInterval(this.timer);
528 this.timer = null;
14f69488
AD
529 },
530
531 onTimerEvent: function() {
532 if (!this.currentlyExecuting) {
533 try {
534 this.currentlyExecuting = true;
4b9dfd5b 535 this.execute();
14f69488 536 this.currentlyExecuting = false;
85e836d8
AD
537 } catch(e) {
538 this.currentlyExecuting = false;
539 throw e;
14f69488
AD
540 }
541 }
542 }
4b9dfd5b
AD
543});
544Object.extend(String, {
545 interpret: function(value) {
546 return value == null ? '' : String(value);
547 },
548 specialChar: {
549 '\b': '\\b',
550 '\t': '\\t',
551 '\n': '\\n',
552 '\f': '\\f',
553 '\r': '\\r',
554 '\\': '\\\\'
555 }
556});
14f69488 557
85e836d8 558Object.extend(String.prototype, (function() {
3fe38208
AD
559 var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
560 typeof JSON.parse === 'function' &&
561 JSON.parse('{"test": true}').test;
85e836d8
AD
562
563 function prepareReplacement(replacement) {
564 if (Object.isFunction(replacement)) return replacement;
565 var template = new Template(replacement);
566 return function(match) { return template.evaluate(match) };
567 }
568
e3cfa33b
AK
569 function isNonEmptyRegExp(regexp) {
570 return regexp.source && regexp.source !== '(?:)';
571 }
572
573
85e836d8 574 function gsub(pattern, replacement) {
5c656a9d 575 var result = '', source = this, match;
85e836d8
AD
576 replacement = prepareReplacement(replacement);
577
578 if (Object.isString(pattern))
579 pattern = RegExp.escape(pattern);
580
e3cfa33b 581 if (!(pattern.length || isNonEmptyRegExp(pattern))) {
85e836d8
AD
582 replacement = replacement('');
583 return replacement + source.split('').join(replacement) + replacement;
584 }
5c656a9d
AD
585
586 while (source.length > 0) {
e3cfa33b
AK
587 match = source.match(pattern)
588 if (match && match[0].length > 0) {
5c656a9d
AD
589 result += source.slice(0, match.index);
590 result += String.interpret(replacement(match));
591 source = source.slice(match.index + match[0].length);
592 } else {
593 result += source, source = '';
594 }
595 }
596 return result;
85e836d8 597 }
14f69488 598
85e836d8
AD
599 function sub(pattern, replacement, count) {
600 replacement = prepareReplacement(replacement);
4b9dfd5b 601 count = Object.isUndefined(count) ? 1 : count;
14f69488 602
5c656a9d
AD
603 return this.gsub(pattern, function(match) {
604 if (--count < 0) return match[0];
605 return replacement(match);
606 });
85e836d8 607 }
14f69488 608
85e836d8 609 function scan(pattern, iterator) {
5c656a9d 610 this.gsub(pattern, iterator);
4b9dfd5b 611 return String(this);
85e836d8 612 }
14f69488 613
85e836d8 614 function truncate(length, truncation) {
5c656a9d 615 length = length || 30;
4b9dfd5b 616 truncation = Object.isUndefined(truncation) ? '...' : truncation;
5c656a9d 617 return this.length > length ?
4b9dfd5b 618 this.slice(0, length - truncation.length) + truncation : String(this);
85e836d8 619 }
5c656a9d 620
85e836d8 621 function strip() {
5c656a9d 622 return this.replace(/^\s+/, '').replace(/\s+$/, '');
85e836d8 623 }
14f69488 624
85e836d8 625 function stripTags() {
e3cfa33b 626 return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, '');
85e836d8 627 }
14f69488 628
85e836d8 629 function stripScripts() {
14f69488 630 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
85e836d8 631 }
14f69488 632
85e836d8 633 function extractScripts() {
3fe38208
AD
634 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
635 matchOne = new RegExp(Prototype.ScriptFragment, 'im');
14f69488
AD
636 return (this.match(matchAll) || []).map(function(scriptTag) {
637 return (scriptTag.match(matchOne) || ['', ''])[1];
638 });
85e836d8 639 }
14f69488 640
85e836d8 641 function evalScripts() {
e3cfa33b 642 return this.extractScripts().map(function(script) { return eval(script); });
85e836d8 643 }
14f69488 644
85e836d8
AD
645 function escapeHTML() {
646 return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
647 }
648
649 function unescapeHTML() {
650 return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
651 }
14f69488 652
14f69488 653
85e836d8 654 function toQueryParams(separator) {
5c656a9d 655 var match = this.strip().match(/([^?#]*)(#.*)?$/);
4b9dfd5b 656 if (!match) return { };
5c656a9d 657
4b9dfd5b 658 return match[1].split(separator || '&').inject({ }, function(hash, pair) {
5c656a9d 659 if ((pair = pair.split('='))[0]) {
3fe38208
AD
660 var key = decodeURIComponent(pair.shift()),
661 value = pair.length > 1 ? pair.join('=') : pair[0];
662
e3cfa33b
AK
663 if (value != undefined) {
664 value = value.gsub('+', ' ');
665 value = decodeURIComponent(value);
666 }
5c656a9d 667
4b9dfd5b
AD
668 if (key in hash) {
669 if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
670 hash[key].push(value);
5c656a9d 671 }
4b9dfd5b 672 else hash[key] = value;
5c656a9d
AD
673 }
674 return hash;
14f69488 675 });
85e836d8 676 }
14f69488 677
85e836d8 678 function toArray() {
14f69488 679 return this.split('');
85e836d8 680 }
14f69488 681
85e836d8 682 function succ() {
5c656a9d
AD
683 return this.slice(0, this.length - 1) +
684 String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
85e836d8 685 }
5c656a9d 686
85e836d8 687 function times(count) {
4b9dfd5b 688 return count < 1 ? '' : new Array(count + 1).join(this);
85e836d8 689 }
4b9dfd5b 690
85e836d8 691 function camelize() {
3fe38208
AD
692 return this.replace(/-+(.)?/g, function(match, chr) {
693 return chr ? chr.toUpperCase() : '';
694 });
85e836d8 695 }
14f69488 696
85e836d8 697 function capitalize() {
5c656a9d 698 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
85e836d8 699 }
5c656a9d 700
85e836d8
AD
701 function underscore() {
702 return this.replace(/::/g, '/')
703 .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
704 .replace(/([a-z\d])([A-Z])/g, '$1_$2')
705 .replace(/-/g, '_')
706 .toLowerCase();
707 }
5c656a9d 708
85e836d8
AD
709 function dasherize() {
710 return this.replace(/_/g, '-');
711 }
5c656a9d 712
85e836d8
AD
713 function inspect(useDoubleQuotes) {
714 var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
715 if (character in String.specialChar) {
716 return String.specialChar[character];
717 }
718 return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
4b9dfd5b
AD
719 });
720 if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
721 return "'" + escapedString.replace(/'/g, '\\\'') + "'";
85e836d8 722 }
4b9dfd5b 723
85e836d8
AD
724 function unfilterJSON(filter) {
725 return this.replace(filter || Prototype.JSONFilter, '$1');
726 }
4b9dfd5b 727
85e836d8 728 function isJSON() {
4b9dfd5b
AD
729 var str = this;
730 if (str.blank()) return false;
3fe38208
AD
731 str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
732 str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
733 str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
734 return (/^[\],:{}\s]*$/).test(str);
85e836d8 735 }
4b9dfd5b 736
85e836d8 737 function evalJSON(sanitize) {
3fe38208 738 var json = this.unfilterJSON(),
e3cfa33b 739 cx = /[\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff\u0000]/g;
3fe38208
AD
740 if (cx.test(json)) {
741 json = json.replace(cx, function (a) {
742 return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
743 });
744 }
4b9dfd5b
AD
745 try {
746 if (!sanitize || json.isJSON()) return eval('(' + json + ')');
747 } catch (e) { }
748 throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
85e836d8 749 }
4b9dfd5b 750
3fe38208
AD
751 function parseJSON() {
752 var json = this.unfilterJSON();
753 return JSON.parse(json);
754 }
755
85e836d8 756 function include(pattern) {
4b9dfd5b 757 return this.indexOf(pattern) > -1;
85e836d8 758 }
4b9dfd5b 759
e3cfa33b
AK
760 function startsWith(pattern, position) {
761 position = Object.isNumber(position) ? position : 0;
762 return this.lastIndexOf(pattern, position) === position;
85e836d8 763 }
4b9dfd5b 764
e3cfa33b
AK
765 function endsWith(pattern, position) {
766 pattern = String(pattern);
767 position = Object.isNumber(position) ? position : this.length;
768 if (position < 0) position = 0;
769 if (position > this.length) position = this.length;
770 var d = position - pattern.length;
3fe38208 771 return d >= 0 && this.indexOf(pattern, d) === d;
85e836d8 772 }
4b9dfd5b 773
85e836d8 774 function empty() {
4b9dfd5b 775 return this == '';
85e836d8 776 }
4b9dfd5b 777
85e836d8 778 function blank() {
4b9dfd5b 779 return /^\s*$/.test(this);
4b9dfd5b 780 }
4b9dfd5b 781
85e836d8
AD
782 function interpolate(object, pattern) {
783 return new Template(this, pattern).evaluate(object);
14f69488 784 }
14f69488 785
85e836d8
AD
786 return {
787 gsub: gsub,
788 sub: sub,
789 scan: scan,
790 truncate: truncate,
3fe38208 791 strip: String.prototype.trim || strip,
85e836d8
AD
792 stripTags: stripTags,
793 stripScripts: stripScripts,
794 extractScripts: extractScripts,
795 evalScripts: evalScripts,
796 escapeHTML: escapeHTML,
797 unescapeHTML: unescapeHTML,
798 toQueryParams: toQueryParams,
799 parseQuery: toQueryParams,
800 toArray: toArray,
801 succ: succ,
802 times: times,
803 camelize: camelize,
804 capitalize: capitalize,
805 underscore: underscore,
806 dasherize: dasherize,
807 inspect: inspect,
85e836d8
AD
808 unfilterJSON: unfilterJSON,
809 isJSON: isJSON,
3fe38208 810 evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
85e836d8 811 include: include,
e3cfa33b
AK
812 startsWith: String.prototype.startsWith || startsWith,
813 endsWith: String.prototype.endsWith || endsWith,
85e836d8
AD
814 empty: empty,
815 blank: blank,
816 interpolate: interpolate
817 };
818})());
4b9dfd5b
AD
819
820var Template = Class.create({
5c656a9d
AD
821 initialize: function(template, pattern) {
822 this.template = template.toString();
4b9dfd5b 823 this.pattern = pattern || Template.Pattern;
5c656a9d
AD
824 },
825
826 evaluate: function(object) {
85e836d8 827 if (object && Object.isFunction(object.toTemplateReplacements))
4b9dfd5b
AD
828 object = object.toTemplateReplacements();
829
5c656a9d 830 return this.template.gsub(this.pattern, function(match) {
85e836d8 831 if (object == null) return (match[1] + '');
4b9dfd5b
AD
832
833 var before = match[1] || '';
5c656a9d 834 if (before == '\\') return match[2];
4b9dfd5b 835
3fe38208
AD
836 var ctx = object, expr = match[3],
837 pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
838
4b9dfd5b
AD
839 match = pattern.exec(expr);
840 if (match == null) return before;
841
842 while (match != null) {
85e836d8 843 var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
4b9dfd5b
AD
844 ctx = ctx[comp];
845 if (null == ctx || '' == match[3]) break;
846 expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
847 match = pattern.exec(expr);
848 }
849
850 return before + String.interpret(ctx);
85e836d8 851 });
5c656a9d 852 }
4b9dfd5b
AD
853});
854Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
5c656a9d 855
4b9dfd5b 856var $break = { };
14f69488 857
85e836d8
AD
858var Enumerable = (function() {
859 function each(iterator, context) {
14f69488 860 try {
e3cfa33b 861 this._each(iterator, context);
14f69488
AD
862 } catch (e) {
863 if (e != $break) throw e;
864 }
5c656a9d 865 return this;
85e836d8 866 }
5c656a9d 867
85e836d8 868 function eachSlice(number, iterator, context) {
5c656a9d 869 var index = -number, slices = [], array = this.toArray();
85e836d8 870 if (number < 1) return array;
5c656a9d
AD
871 while ((index += number) < array.length)
872 slices.push(array.slice(index, index+number));
4b9dfd5b 873 return slices.collect(iterator, context);
85e836d8 874 }
14f69488 875
85e836d8
AD
876 function all(iterator, context) {
877 iterator = iterator || Prototype.K;
14f69488
AD
878 var result = true;
879 this.each(function(value, index) {
e3cfa33b 880 result = result && !!iterator.call(context, value, index, this);
14f69488 881 if (!result) throw $break;
e3cfa33b 882 }, this);
14f69488 883 return result;
85e836d8 884 }
14f69488 885
85e836d8
AD
886 function any(iterator, context) {
887 iterator = iterator || Prototype.K;
5c656a9d 888 var result = false;
14f69488 889 this.each(function(value, index) {
e3cfa33b 890 if (result = !!iterator.call(context, value, index, this))
14f69488 891 throw $break;
e3cfa33b 892 }, this);
14f69488 893 return result;
85e836d8 894 }
14f69488 895
85e836d8
AD
896 function collect(iterator, context) {
897 iterator = iterator || Prototype.K;
14f69488
AD
898 var results = [];
899 this.each(function(value, index) {
e3cfa33b
AK
900 results.push(iterator.call(context, value, index, this));
901 }, this);
14f69488 902 return results;
85e836d8 903 }
14f69488 904
85e836d8 905 function detect(iterator, context) {
14f69488
AD
906 var result;
907 this.each(function(value, index) {
e3cfa33b 908 if (iterator.call(context, value, index, this)) {
14f69488
AD
909 result = value;
910 throw $break;
911 }
e3cfa33b 912 }, this);
14f69488 913 return result;
85e836d8 914 }
14f69488 915
85e836d8 916 function findAll(iterator, context) {
14f69488
AD
917 var results = [];
918 this.each(function(value, index) {
e3cfa33b 919 if (iterator.call(context, value, index, this))
14f69488 920 results.push(value);
e3cfa33b 921 }, this);
14f69488 922 return results;
85e836d8 923 }
14f69488 924
85e836d8
AD
925 function grep(filter, iterator, context) {
926 iterator = iterator || Prototype.K;
14f69488 927 var results = [];
4b9dfd5b
AD
928
929 if (Object.isString(filter))
85e836d8 930 filter = new RegExp(RegExp.escape(filter));
4b9dfd5b 931
14f69488 932 this.each(function(value, index) {
4b9dfd5b 933 if (filter.match(value))
e3cfa33b
AK
934 results.push(iterator.call(context, value, index, this));
935 }, this);
14f69488 936 return results;
85e836d8 937 }
14f69488 938
85e836d8 939 function include(object) {
e3cfa33b
AK
940 if (Object.isFunction(this.indexOf) && this.indexOf(object) != -1)
941 return true;
4b9dfd5b 942
14f69488
AD
943 var found = false;
944 this.each(function(value) {
945 if (value == object) {
946 found = true;
947 throw $break;
948 }
949 });
950 return found;
85e836d8 951 }
14f69488 952
85e836d8 953 function inGroupsOf(number, fillWith) {
4b9dfd5b 954 fillWith = Object.isUndefined(fillWith) ? null : fillWith;
5c656a9d
AD
955 return this.eachSlice(number, function(slice) {
956 while(slice.length < number) slice.push(fillWith);
957 return slice;
958 });
85e836d8 959 }
5c656a9d 960
85e836d8 961 function inject(memo, iterator, context) {
14f69488 962 this.each(function(value, index) {
e3cfa33b
AK
963 memo = iterator.call(context, memo, value, index, this);
964 }, this);
14f69488 965 return memo;
85e836d8 966 }
14f69488 967
85e836d8 968 function invoke(method) {
14f69488 969 var args = $A(arguments).slice(1);
5c656a9d 970 return this.map(function(value) {
14f69488
AD
971 return value[method].apply(value, args);
972 });
85e836d8 973 }
14f69488 974
85e836d8
AD
975 function max(iterator, context) {
976 iterator = iterator || Prototype.K;
14f69488
AD
977 var result;
978 this.each(function(value, index) {
e3cfa33b 979 value = iterator.call(context, value, index, this);
4b9dfd5b 980 if (result == null || value >= result)
14f69488 981 result = value;
e3cfa33b 982 }, this);
14f69488 983 return result;
85e836d8 984 }
14f69488 985
85e836d8
AD
986 function min(iterator, context) {
987 iterator = iterator || Prototype.K;
14f69488
AD
988 var result;
989 this.each(function(value, index) {
e3cfa33b 990 value = iterator.call(context, value, index, this);
4b9dfd5b 991 if (result == null || value < result)
14f69488 992 result = value;
e3cfa33b 993 }, this);
14f69488 994 return result;
85e836d8 995 }
14f69488 996
85e836d8
AD
997 function partition(iterator, context) {
998 iterator = iterator || Prototype.K;
14f69488
AD
999 var trues = [], falses = [];
1000 this.each(function(value, index) {
e3cfa33b 1001 (iterator.call(context, value, index, this) ?
14f69488 1002 trues : falses).push(value);
e3cfa33b 1003 }, this);
14f69488 1004 return [trues, falses];
85e836d8 1005 }
14f69488 1006
85e836d8 1007 function pluck(property) {
14f69488 1008 var results = [];
4b9dfd5b 1009 this.each(function(value) {
14f69488
AD
1010 results.push(value[property]);
1011 });
1012 return results;
85e836d8 1013 }
14f69488 1014
85e836d8 1015 function reject(iterator, context) {
14f69488
AD
1016 var results = [];
1017 this.each(function(value, index) {
e3cfa33b 1018 if (!iterator.call(context, value, index, this))
14f69488 1019 results.push(value);
e3cfa33b 1020 }, this);
14f69488 1021 return results;
85e836d8 1022 }
14f69488 1023
85e836d8 1024 function sortBy(iterator, context) {
5c656a9d 1025 return this.map(function(value, index) {
85e836d8
AD
1026 return {
1027 value: value,
e3cfa33b 1028 criteria: iterator.call(context, value, index, this)
85e836d8 1029 };
e3cfa33b 1030 }, this).sort(function(left, right) {
14f69488
AD
1031 var a = left.criteria, b = right.criteria;
1032 return a < b ? -1 : a > b ? 1 : 0;
1033 }).pluck('value');
85e836d8 1034 }
14f69488 1035
85e836d8 1036 function toArray() {
5c656a9d 1037 return this.map();
85e836d8 1038 }
14f69488 1039
85e836d8 1040 function zip() {
14f69488 1041 var iterator = Prototype.K, args = $A(arguments);
4b9dfd5b 1042 if (Object.isFunction(args.last()))
14f69488
AD
1043 iterator = args.pop();
1044
1045 var collections = [this].concat(args).map($A);
1046 return this.map(function(value, index) {
5c656a9d 1047 return iterator(collections.pluck(index));
14f69488 1048 });
85e836d8 1049 }
14f69488 1050
85e836d8 1051 function size() {
5c656a9d 1052 return this.toArray().length;
85e836d8 1053 }
5c656a9d 1054
85e836d8 1055 function inspect() {
14f69488
AD
1056 return '#<Enumerable:' + this.toArray().inspect() + '>';
1057 }
14f69488 1058
85e836d8
AD
1059
1060
1061
1062
1063
1064
1065
1066
1067 return {
1068 each: each,
1069 eachSlice: eachSlice,
1070 all: all,
1071 every: all,
1072 any: any,
1073 some: any,
1074 collect: collect,
1075 map: collect,
1076 detect: detect,
1077 findAll: findAll,
1078 select: findAll,
1079 filter: findAll,
1080 grep: grep,
1081 include: include,
1082 member: include,
1083 inGroupsOf: inGroupsOf,
1084 inject: inject,
1085 invoke: invoke,
1086 max: max,
1087 min: min,
1088 partition: partition,
1089 pluck: pluck,
1090 reject: reject,
1091 sortBy: sortBy,
1092 toArray: toArray,
1093 entries: toArray,
1094 zip: zip,
1095 size: size,
1096 inspect: inspect,
1097 find: detect
1098 };
1099})();
3fe38208 1100
4b9dfd5b 1101function $A(iterable) {
14f69488 1102 if (!iterable) return [];
85e836d8 1103 if ('toArray' in Object(iterable)) return iterable.toArray();
4b9dfd5b
AD
1104 var length = iterable.length || 0, results = new Array(length);
1105 while (length--) results[length] = iterable[length];
1106 return results;
1107}
1108
3fe38208 1109
85e836d8
AD
1110function $w(string) {
1111 if (!Object.isString(string)) return [];
1112 string = string.strip();
1113 return string ? string.split(/\s+/) : [];
14f69488
AD
1114}
1115
4b9dfd5b
AD
1116Array.from = $A;
1117
14f69488 1118
85e836d8
AD
1119(function() {
1120 var arrayProto = Array.prototype,
1121 slice = arrayProto.slice,
1122 _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
14f69488 1123
3fe38208
AD
1124 function each(iterator, context) {
1125 for (var i = 0, length = this.length >>> 0; i < length; i++) {
1126 if (i in this) iterator.call(context, this[i], i, this);
1127 }
85e836d8
AD
1128 }
1129 if (!_each) _each = each;
14f69488 1130
85e836d8 1131 function clear() {
14f69488
AD
1132 this.length = 0;
1133 return this;
85e836d8 1134 }
14f69488 1135
85e836d8 1136 function first() {
14f69488 1137 return this[0];
85e836d8 1138 }
14f69488 1139
85e836d8 1140 function last() {
14f69488 1141 return this[this.length - 1];
85e836d8 1142 }
14f69488 1143
85e836d8 1144 function compact() {
14f69488 1145 return this.select(function(value) {
5c656a9d 1146 return value != null;
14f69488 1147 });
85e836d8 1148 }
14f69488 1149
85e836d8 1150 function flatten() {
14f69488 1151 return this.inject([], function(array, value) {
85e836d8
AD
1152 if (Object.isArray(value))
1153 return array.concat(value.flatten());
1154 array.push(value);
1155 return array;
14f69488 1156 });
85e836d8 1157 }
14f69488 1158
85e836d8
AD
1159 function without() {
1160 var values = slice.call(arguments, 0);
14f69488
AD
1161 return this.select(function(value) {
1162 return !values.include(value);
1163 });
85e836d8 1164 }
14f69488 1165
85e836d8 1166 function reverse(inline) {
3fe38208 1167 return (inline === false ? this.toArray() : this)._reverse();
85e836d8 1168 }
5c656a9d 1169
85e836d8 1170 function uniq(sorted) {
4b9dfd5b
AD
1171 return this.inject([], function(array, value, index) {
1172 if (0 == index || (sorted ? array.last() != value : !array.include(value)))
1173 array.push(value);
1174 return array;
1175 });
85e836d8 1176 }
4b9dfd5b 1177
85e836d8 1178 function intersect(array) {
4b9dfd5b 1179 return this.uniq().findAll(function(item) {
e3cfa33b 1180 return array.indexOf(item) !== -1;
5c656a9d 1181 });
85e836d8 1182 }
5c656a9d 1183
5c656a9d 1184
85e836d8
AD
1185 function clone() {
1186 return slice.call(this, 0);
1187 }
1188
1189 function size() {
5c656a9d 1190 return this.length;
85e836d8 1191 }
14f69488 1192
85e836d8 1193 function inspect() {
14f69488 1194 return '[' + this.map(Object.inspect).join(', ') + ']';
85e836d8 1195 }
4b9dfd5b 1196
85e836d8 1197 function indexOf(item, i) {
e3cfa33b
AK
1198 if (this == null) throw new TypeError();
1199
1200 var array = Object(this), length = array.length >>> 0;
1201 if (length === 0) return -1;
1202
1203 i = Number(i);
1204 if (isNaN(i)) {
1205 i = 0;
1206 } else if (i !== 0 && isFinite(i)) {
1207 i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i));
1208 }
1209
1210 if (i > length) return -1;
1211
1212 var k = i >= 0 ? i : Math.max(length - Math.abs(i), 0);
1213 for (; k < length; k++)
1214 if (k in array && array[k] === item) return k;
85e836d8
AD
1215 return -1;
1216 }
5c656a9d 1217
e3cfa33b 1218
85e836d8 1219 function lastIndexOf(item, i) {
e3cfa33b
AK
1220 if (this == null) throw new TypeError();
1221
1222 var array = Object(this), length = array.length >>> 0;
1223 if (length === 0) return -1;
1224
1225 if (!Object.isUndefined(i)) {
1226 i = Number(i);
1227 if (isNaN(i)) {
1228 i = 0;
1229 } else if (i !== 0 && isFinite(i)) {
1230 i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i));
1231 }
1232 } else {
1233 i = length;
1234 }
1235
1236 var k = i >= 0 ? Math.min(i, length - 1) :
1237 length - Math.abs(i);
1238
1239 for (; k >= 0; k--)
1240 if (k in array && array[k] === item) return k;
1241 return -1;
85e836d8 1242 }
5c656a9d 1243
e3cfa33b
AK
1244 function concat(_) {
1245 var array = [], items = slice.call(arguments, 0), item, n = 0;
1246 items.unshift(this);
1247 for (var i = 0, length = items.length; i < length; i++) {
1248 item = items[i];
85e836d8 1249 if (Object.isArray(item) && !('callee' in item)) {
e3cfa33b
AK
1250 for (var j = 0, arrayLength = item.length; j < arrayLength; j++) {
1251 if (j in item) array[n] = item[j];
1252 n++;
1253 }
5c656a9d 1254 } else {
e3cfa33b 1255 array[n++] = item;
5c656a9d
AD
1256 }
1257 }
e3cfa33b 1258 array.length = n;
5c656a9d 1259 return array;
85e836d8 1260 }
14f69488 1261
e3cfa33b
AK
1262
1263 function wrapNative(method) {
1264 return function() {
1265 if (arguments.length === 0) {
1266 return method.call(this, Prototype.K);
1267 } else if (arguments[0] === undefined) {
1268 var args = slice.call(arguments, 1);
1269 args.unshift(Prototype.K);
1270 return method.apply(this, args);
1271 } else {
1272 return method.apply(this, arguments);
1273 }
1274 };
1275 }
1276
1277
1278 function map(iterator) {
1279 if (this == null) throw new TypeError();
1280 iterator = iterator || Prototype.K;
1281
1282 var object = Object(this);
1283 var results = [], context = arguments[1], n = 0;
1284
1285 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1286 if (i in object) {
1287 results[n] = iterator.call(context, object[i], i, object);
1288 }
1289 n++;
1290 }
1291 results.length = n;
1292 return results;
1293 }
1294
1295 if (arrayProto.map) {
1296 map = wrapNative(Array.prototype.map);
1297 }
1298
1299 function filter(iterator) {
1300 if (this == null || !Object.isFunction(iterator))
1301 throw new TypeError();
1302
1303 var object = Object(this);
1304 var results = [], context = arguments[1], value;
1305
1306 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1307 if (i in object) {
1308 value = object[i];
1309 if (iterator.call(context, value, i, object)) {
1310 results.push(value);
1311 }
1312 }
1313 }
1314 return results;
1315 }
1316
1317 if (arrayProto.filter) {
1318 filter = Array.prototype.filter;
1319 }
1320
1321 function some(iterator) {
1322 if (this == null) throw new TypeError();
1323 iterator = iterator || Prototype.K;
1324 var context = arguments[1];
1325
1326 var object = Object(this);
1327 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1328 if (i in object && iterator.call(context, object[i], i, object)) {
1329 return true;
1330 }
1331 }
1332
1333 return false;
1334 }
1335
1336 if (arrayProto.some) {
1337 some = wrapNative(Array.prototype.some);
1338 }
1339
1340 function every(iterator) {
1341 if (this == null) throw new TypeError();
1342 iterator = iterator || Prototype.K;
1343 var context = arguments[1];
1344
1345 var object = Object(this);
1346 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1347 if (i in object && !iterator.call(context, object[i], i, object)) {
1348 return false;
1349 }
1350 }
1351
1352 return true;
1353 }
1354
1355 if (arrayProto.every) {
1356 every = wrapNative(Array.prototype.every);
1357 }
1358
1359
85e836d8
AD
1360 Object.extend(arrayProto, Enumerable);
1361
e3cfa33b
AK
1362 if (arrayProto.entries === Enumerable.entries) {
1363 delete arrayProto.entries;
1364 }
1365
85e836d8
AD
1366 if (!arrayProto._reverse)
1367 arrayProto._reverse = arrayProto.reverse;
1368
1369 Object.extend(arrayProto, {
1370 _each: _each,
e3cfa33b
AK
1371
1372 map: map,
1373 collect: map,
1374 select: filter,
1375 filter: filter,
1376 findAll: filter,
1377 some: some,
1378 any: some,
1379 every: every,
1380 all: every,
1381
85e836d8
AD
1382 clear: clear,
1383 first: first,
1384 last: last,
1385 compact: compact,
1386 flatten: flatten,
1387 without: without,
1388 reverse: reverse,
1389 uniq: uniq,
1390 intersect: intersect,
1391 clone: clone,
1392 toArray: clone,
1393 size: size,
3fe38208 1394 inspect: inspect
85e836d8
AD
1395 });
1396
1397 var CONCAT_ARGUMENTS_BUGGY = (function() {
1398 return [].concat(arguments)[0][0] !== 1;
e3cfa33b 1399 })(1,2);
85e836d8
AD
1400
1401 if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
1402
1403 if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
1404 if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
1405})();
1406function $H(object) {
1407 return new Hash(object);
1408};
1409
1410var Hash = Class.create(Enumerable, (function() {
1411 function initialize(object) {
1412 this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1413 }
1414
3fe38208 1415
e3cfa33b
AK
1416 function _each(iterator, context) {
1417 var i = 0;
85e836d8
AD
1418 for (var key in this._object) {
1419 var value = this._object[key], pair = [key, value];
1420 pair.key = key;
1421 pair.value = value;
e3cfa33b
AK
1422 iterator.call(context, pair, i);
1423 i++;
85e836d8
AD
1424 }
1425 }
1426
1427 function set(key, value) {
1428 return this._object[key] = value;
1429 }
1430
1431 function get(key) {
1432 if (this._object[key] !== Object.prototype[key])
1433 return this._object[key];
1434 }
1435
1436 function unset(key) {
1437 var value = this._object[key];
1438 delete this._object[key];
1439 return value;
1440 }
1441
1442 function toObject() {
1443 return Object.clone(this._object);
1444 }
14f69488 1445
3fe38208
AD
1446
1447
85e836d8
AD
1448 function keys() {
1449 return this.pluck('key');
1450 }
5c656a9d 1451
85e836d8
AD
1452 function values() {
1453 return this.pluck('value');
1454 }
14f69488 1455
85e836d8
AD
1456 function index(value) {
1457 var match = this.detect(function(pair) {
1458 return pair.value === value;
1459 });
1460 return match && match.key;
14f69488 1461 }
14f69488 1462
85e836d8
AD
1463 function merge(object) {
1464 return this.clone().update(object);
1465 }
4b9dfd5b 1466
85e836d8
AD
1467 function update(object) {
1468 return new Hash(object).inject(this, function(result, pair) {
1469 result.set(pair.key, pair.value);
1470 return result;
1471 });
1472 }
4b9dfd5b
AD
1473
1474 function toQueryPair(key, value) {
1475 if (Object.isUndefined(value)) return key;
e3cfa33b
AK
1476
1477 value = String.interpret(value);
1478
1479 value = value.gsub(/(\r)?\n/, '\r\n');
1480 value = encodeURIComponent(value);
1481 value = value.gsub(/%20/, '+');
1482 return key + '=' + value;
4b9dfd5b
AD
1483 }
1484
85e836d8
AD
1485 function toQueryString() {
1486 return this.inject([], function(results, pair) {
1487 var key = encodeURIComponent(pair.key), values = pair.value;
4b9dfd5b 1488
85e836d8 1489 if (values && typeof values == 'object') {
3fe38208
AD
1490 if (Object.isArray(values)) {
1491 var queryValues = [];
1492 for (var i = 0, len = values.length, value; i < len; i++) {
1493 value = values[i];
1494 queryValues.push(toQueryPair(key, value));
1495 }
1496 return results.concat(queryValues);
1497 }
85e836d8
AD
1498 } else results.push(toQueryPair(key, values));
1499 return results;
1500 }).join('&');
1501 }
4b9dfd5b 1502
85e836d8
AD
1503 function inspect() {
1504 return '#<Hash:{' + this.map(function(pair) {
1505 return pair.map(Object.inspect).join(': ');
1506 }).join(', ') + '}>';
1507 }
4b9dfd5b 1508
85e836d8
AD
1509 function clone() {
1510 return new Hash(this);
1511 }
4b9dfd5b 1512
85e836d8
AD
1513 return {
1514 initialize: initialize,
1515 _each: _each,
1516 set: set,
1517 get: get,
1518 unset: unset,
1519 toObject: toObject,
1520 toTemplateReplacements: toObject,
1521 keys: keys,
1522 values: values,
1523 index: index,
1524 merge: merge,
1525 update: update,
1526 toQueryString: toQueryString,
1527 inspect: inspect,
3fe38208 1528 toJSON: toObject,
85e836d8
AD
1529 clone: clone
1530 };
1531})());
4b9dfd5b 1532
85e836d8
AD
1533Hash.from = $H;
1534Object.extend(Number.prototype, (function() {
1535 function toColorPart() {
1536 return this.toPaddedString(2, 16);
1537 }
4b9dfd5b 1538
85e836d8
AD
1539 function succ() {
1540 return this + 1;
1541 }
4b9dfd5b 1542
85e836d8
AD
1543 function times(iterator, context) {
1544 $R(0, this, true).each(iterator, context);
1545 return this;
1546 }
4b9dfd5b 1547
85e836d8
AD
1548 function toPaddedString(length, radix) {
1549 var string = this.toString(radix || 10);
1550 return '0'.times(length - string.length) + string;
1551 }
4b9dfd5b 1552
85e836d8
AD
1553 function abs() {
1554 return Math.abs(this);
1555 }
4b9dfd5b 1556
85e836d8
AD
1557 function round() {
1558 return Math.round(this);
1559 }
4b9dfd5b 1560
85e836d8
AD
1561 function ceil() {
1562 return Math.ceil(this);
1563 }
4b9dfd5b 1564
85e836d8
AD
1565 function floor() {
1566 return Math.floor(this);
4b9dfd5b 1567 }
85e836d8
AD
1568
1569 return {
1570 toColorPart: toColorPart,
1571 succ: succ,
1572 times: times,
1573 toPaddedString: toPaddedString,
85e836d8
AD
1574 abs: abs,
1575 round: round,
1576 ceil: ceil,
1577 floor: floor
1578 };
4b9dfd5b
AD
1579})());
1580
85e836d8
AD
1581function $R(start, end, exclusive) {
1582 return new ObjectRange(start, end, exclusive);
1583}
1584
1585var ObjectRange = Class.create(Enumerable, (function() {
1586 function initialize(start, end, exclusive) {
14f69488
AD
1587 this.start = start;
1588 this.end = end;
1589 this.exclusive = exclusive;
85e836d8 1590 }
14f69488 1591
e3cfa33b
AK
1592 function _each(iterator, context) {
1593 var value = this.start, i;
1594 for (i = 0; this.include(value); i++) {
1595 iterator.call(context, value, i);
14f69488 1596 value = value.succ();
5c656a9d 1597 }
85e836d8 1598 }
14f69488 1599
85e836d8 1600 function include(value) {
14f69488
AD
1601 if (value < this.start)
1602 return false;
1603 if (this.exclusive)
1604 return value < this.end;
1605 return value <= this.end;
1606 }
14f69488 1607
85e836d8
AD
1608 return {
1609 initialize: initialize,
1610 _each: _each,
1611 include: include
1612 };
1613})());
1614
1615
14f69488 1616
e3cfa33b
AK
1617var Abstract = { };
1618
1619
1620var Try = {
1621 these: function() {
1622 var returnValue;
1623
1624 for (var i = 0, length = arguments.length; i < length; i++) {
1625 var lambda = arguments[i];
1626 try {
1627 returnValue = lambda();
1628 break;
1629 } catch (e) { }
1630 }
1631
1632 return returnValue;
1633 }
1634};
1635
14f69488
AD
1636var Ajax = {
1637 getTransport: function() {
1638 return Try.these(
5c656a9d 1639 function() {return new XMLHttpRequest()},
14f69488 1640 function() {return new ActiveXObject('Msxml2.XMLHTTP')},
5c656a9d 1641 function() {return new ActiveXObject('Microsoft.XMLHTTP')}
14f69488
AD
1642 ) || false;
1643 },
1644
1645 activeRequestCount: 0
4b9dfd5b 1646};
14f69488
AD
1647
1648Ajax.Responders = {
1649 responders: [],
1650
e3cfa33b
AK
1651 _each: function(iterator, context) {
1652 this.responders._each(iterator, context);
14f69488
AD
1653 },
1654
5c656a9d
AD
1655 register: function(responder) {
1656 if (!this.include(responder))
1657 this.responders.push(responder);
14f69488
AD
1658 },
1659
5c656a9d
AD
1660 unregister: function(responder) {
1661 this.responders = this.responders.without(responder);
14f69488
AD
1662 },
1663
1664 dispatch: function(callback, request, transport, json) {
1665 this.each(function(responder) {
4b9dfd5b 1666 if (Object.isFunction(responder[callback])) {
14f69488
AD
1667 try {
1668 responder[callback].apply(responder, [request, transport, json]);
4b9dfd5b 1669 } catch (e) { }
14f69488
AD
1670 }
1671 });
1672 }
1673};
1674
1675Object.extend(Ajax.Responders, Enumerable);
1676
1677Ajax.Responders.register({
4b9dfd5b
AD
1678 onCreate: function() { Ajax.activeRequestCount++ },
1679 onComplete: function() { Ajax.activeRequestCount-- }
14f69488 1680});
4b9dfd5b
AD
1681Ajax.Base = Class.create({
1682 initialize: function(options) {
14f69488
AD
1683 this.options = {
1684 method: 'post',
1685 asynchronous: true,
5c656a9d
AD
1686 contentType: 'application/x-www-form-urlencoded',
1687 encoding: 'UTF-8',
4b9dfd5b
AD
1688 parameters: '',
1689 evalJSON: true,
1690 evalJS: true
1691 };
1692 Object.extend(this.options, options || { });
14f69488 1693
5c656a9d 1694 this.options.method = this.options.method.toLowerCase();
4b9dfd5b 1695
3fe38208 1696 if (Object.isHash(this.options.parameters))
4b9dfd5b 1697 this.options.parameters = this.options.parameters.toObject();
14f69488 1698 }
4b9dfd5b 1699});
4b9dfd5b 1700Ajax.Request = Class.create(Ajax.Base, {
5c656a9d
AD
1701 _complete: false,
1702
4b9dfd5b
AD
1703 initialize: function($super, url, options) {
1704 $super(options);
14f69488 1705 this.transport = Ajax.getTransport();
14f69488
AD
1706 this.request(url);
1707 },
1708
1709 request: function(url) {
5c656a9d
AD
1710 this.url = url;
1711 this.method = this.options.method;
3fe38208
AD
1712 var params = Object.isString(this.options.parameters) ?
1713 this.options.parameters :
1714 Object.toQueryString(this.options.parameters);
14f69488 1715
5c656a9d 1716 if (!['get', 'post'].include(this.method)) {
3fe38208 1717 params += (params ? '&' : '') + "_method=" + this.method;
5c656a9d
AD
1718 this.method = 'post';
1719 }
1720
3fe38208
AD
1721 if (params && this.method === 'get') {
1722 this.url += (this.url.include('?') ? '&' : '?') + params;
4b9dfd5b 1723 }
5c656a9d 1724
3fe38208
AD
1725 this.parameters = params.toQueryParams();
1726
5c656a9d 1727 try {
4b9dfd5b
AD
1728 var response = new Ajax.Response(this);
1729 if (this.options.onCreate) this.options.onCreate(response);
1730 Ajax.Responders.dispatch('onCreate', this, response);
14f69488 1731
5c656a9d 1732 this.transport.open(this.method.toUpperCase(), this.url,
14f69488
AD
1733 this.options.asynchronous);
1734
4b9dfd5b 1735 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
14f69488 1736
5c656a9d 1737 this.transport.onreadystatechange = this.onStateChange.bind(this);
14f69488
AD
1738 this.setRequestHeaders();
1739
4b9dfd5b
AD
1740 this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1741 this.transport.send(this.body);
14f69488 1742
5c656a9d
AD
1743 /* Force Firefox to handle ready state 4 for synchronous requests */
1744 if (!this.options.asynchronous && this.transport.overrideMimeType)
1745 this.onStateChange();
14f69488 1746
14f69488 1747 }
5c656a9d
AD
1748 catch (e) {
1749 this.dispatchException(e);
1750 }
14f69488
AD
1751 },
1752
1753 onStateChange: function() {
1754 var readyState = this.transport.readyState;
5c656a9d 1755 if (readyState > 1 && !((readyState == 4) && this._complete))
14f69488
AD
1756 this.respondToReadyState(this.transport.readyState);
1757 },
1758
5c656a9d
AD
1759 setRequestHeaders: function() {
1760 var headers = {
1761 'X-Requested-With': 'XMLHttpRequest',
1762 'X-Prototype-Version': Prototype.Version,
1763 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1764 };
1765
1766 if (this.method == 'post') {
1767 headers['Content-type'] = this.options.contentType +
1768 (this.options.encoding ? '; charset=' + this.options.encoding : '');
1769
1770 /* Force "Connection: close" for older Mozilla browsers to work
1771 * around a bug where XMLHttpRequest sends an incorrect
1772 * Content-length header. See Mozilla Bugzilla #246651.
1773 */
1774 if (this.transport.overrideMimeType &&
1775 (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1776 headers['Connection'] = 'close';
1777 }
14f69488 1778
5c656a9d
AD
1779 if (typeof this.options.requestHeaders == 'object') {
1780 var extras = this.options.requestHeaders;
14f69488 1781
4b9dfd5b 1782 if (Object.isFunction(extras.push))
5c656a9d
AD
1783 for (var i = 0, length = extras.length; i < length; i += 2)
1784 headers[extras[i]] = extras[i+1];
1785 else
1786 $H(extras).each(function(pair) { headers[pair.key] = pair.value });
14f69488 1787 }
5c656a9d
AD
1788
1789 for (var name in headers)
e3cfa33b
AK
1790 if (headers[name] != null)
1791 this.transport.setRequestHeader(name, headers[name]);
5c656a9d
AD
1792 },
1793
1794 success: function() {
4b9dfd5b 1795 var status = this.getStatus();
3fe38208 1796 return !status || (status >= 200 && status < 300) || status == 304;
4b9dfd5b
AD
1797 },
1798
1799 getStatus: function() {
1800 try {
3fe38208 1801 if (this.transport.status === 1223) return 204;
4b9dfd5b
AD
1802 return this.transport.status || 0;
1803 } catch (e) { return 0 }
14f69488
AD
1804 },
1805
1806 respondToReadyState: function(readyState) {
4b9dfd5b 1807 var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
14f69488 1808
5c656a9d 1809 if (state == 'Complete') {
14f69488 1810 try {
5c656a9d 1811 this._complete = true;
4b9dfd5b 1812 (this.options['on' + response.status]
5c656a9d 1813 || this.options['on' + (this.success() ? 'Success' : 'Failure')]
4b9dfd5b 1814 || Prototype.emptyFunction)(response, response.headerJSON);
14f69488
AD
1815 } catch (e) {
1816 this.dispatchException(e);
1817 }
1818
4b9dfd5b
AD
1819 var contentType = response.getHeader('Content-type');
1820 if (this.options.evalJS == 'force'
85e836d8 1821 || (this.options.evalJS && this.isSameOrigin() && contentType
4b9dfd5b
AD
1822 && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1823 this.evalResponse();
14f69488
AD
1824 }
1825
1826 try {
4b9dfd5b
AD
1827 (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
1828 Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
14f69488
AD
1829 } catch (e) {
1830 this.dispatchException(e);
1831 }
1832
5c656a9d 1833 if (state == 'Complete') {
14f69488 1834 this.transport.onreadystatechange = Prototype.emptyFunction;
5c656a9d
AD
1835 }
1836 },
1837
85e836d8
AD
1838 isSameOrigin: function() {
1839 var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1840 return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
1841 protocol: location.protocol,
1842 domain: document.domain,
1843 port: location.port ? ':' + location.port : ''
1844 }));
1845 },
1846
5c656a9d
AD
1847 getHeader: function(name) {
1848 try {
4b9dfd5b 1849 return this.transport.getResponseHeader(name) || null;
85e836d8 1850 } catch (e) { return null; }
5c656a9d
AD
1851 },
1852
1853 evalResponse: function() {
1854 try {
4b9dfd5b 1855 return eval((this.transport.responseText || '').unfilterJSON());
5c656a9d
AD
1856 } catch (e) {
1857 this.dispatchException(e);
1858 }
14f69488
AD
1859 },
1860
1861 dispatchException: function(exception) {
1862 (this.options.onException || Prototype.emptyFunction)(this, exception);
1863 Ajax.Responders.dispatch('onException', this, exception);
1864 }
1865});
1866
4b9dfd5b
AD
1867Ajax.Request.Events =
1868 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
14f69488 1869
85e836d8
AD
1870
1871
1872
1873
1874
1875
1876
4b9dfd5b
AD
1877Ajax.Response = Class.create({
1878 initialize: function(request){
1879 this.request = request;
1880 var transport = this.transport = request.transport,
1881 readyState = this.readyState = transport.readyState;
1882
3fe38208 1883 if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
4b9dfd5b
AD
1884 this.status = this.getStatus();
1885 this.statusText = this.getStatusText();
1886 this.responseText = String.interpret(transport.responseText);
1887 this.headerJSON = this._getHeaderJSON();
14f69488
AD
1888 }
1889
3fe38208 1890 if (readyState == 4) {
4b9dfd5b
AD
1891 var xml = transport.responseXML;
1892 this.responseXML = Object.isUndefined(xml) ? null : xml;
1893 this.responseJSON = this._getResponseJSON();
1894 }
1895 },
14f69488 1896
4b9dfd5b 1897 status: 0,
85e836d8 1898
4b9dfd5b 1899 statusText: '',
14f69488 1900
4b9dfd5b
AD
1901 getStatus: Ajax.Request.prototype.getStatus,
1902
1903 getStatusText: function() {
1904 try {
1905 return this.transport.statusText || '';
1906 } catch (e) { return '' }
14f69488
AD
1907 },
1908
4b9dfd5b 1909 getHeader: Ajax.Request.prototype.getHeader,
14f69488 1910
4b9dfd5b
AD
1911 getAllHeaders: function() {
1912 try {
1913 return this.getAllResponseHeaders();
1914 } catch (e) { return null }
1915 },
14f69488 1916
4b9dfd5b
AD
1917 getResponseHeader: function(name) {
1918 return this.transport.getResponseHeader(name);
1919 },
1920
1921 getAllResponseHeaders: function() {
1922 return this.transport.getAllResponseHeaders();
1923 },
1924
1925 _getHeaderJSON: function() {
1926 var json = this.getHeader('X-JSON');
1927 if (!json) return null;
e3cfa33b
AK
1928
1929 try {
1930 json = decodeURIComponent(escape(json));
1931 } catch(e) {
1932 }
1933
4b9dfd5b 1934 try {
85e836d8
AD
1935 return json.evalJSON(this.request.options.sanitizeJSON ||
1936 !this.request.isSameOrigin());
4b9dfd5b
AD
1937 } catch (e) {
1938 this.request.dispatchException(e);
1939 }
1940 },
1941
1942 _getResponseJSON: function() {
1943 var options = this.request.options;
1944 if (!options.evalJSON || (options.evalJSON != 'force' &&
1945 !(this.getHeader('Content-type') || '').include('application/json')) ||
1946 this.responseText.blank())
1947 return null;
1948 try {
85e836d8
AD
1949 return this.responseText.evalJSON(options.sanitizeJSON ||
1950 !this.request.isSameOrigin());
4b9dfd5b
AD
1951 } catch (e) {
1952 this.request.dispatchException(e);
14f69488 1953 }
4b9dfd5b
AD
1954 }
1955});
1956
1957Ajax.Updater = Class.create(Ajax.Request, {
1958 initialize: function($super, container, url, options) {
1959 this.container = {
1960 success: (container.success || container),
1961 failure: (container.failure || (container.success ? null : container))
1962 };
1963
1964 options = Object.clone(options);
1965 var onComplete = options.onComplete;
1966 options.onComplete = (function(response, json) {
1967 this.updateContent(response.responseText);
1968 if (Object.isFunction(onComplete)) onComplete(response, json);
1969 }).bind(this);
1970
1971 $super(url, options);
1972 },
1973
1974 updateContent: function(responseText) {
1975 var receiver = this.container[this.success() ? 'success' : 'failure'],
1976 options = this.options;
14f69488 1977
4b9dfd5b
AD
1978 if (!options.evalScripts) responseText = responseText.stripScripts();
1979
1980 if (receiver = $(receiver)) {
1981 if (options.insertion) {
1982 if (Object.isString(options.insertion)) {
1983 var insertion = { }; insertion[options.insertion] = responseText;
1984 receiver.insert(insertion);
1985 }
1986 else options.insertion(receiver, responseText);
1987 }
1988 else receiver.update(responseText);
14f69488
AD
1989 }
1990 }
1991});
1992
4b9dfd5b
AD
1993Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
1994 initialize: function($super, container, url, options) {
1995 $super(options);
14f69488
AD
1996 this.onComplete = this.options.onComplete;
1997
1998 this.frequency = (this.options.frequency || 2);
1999 this.decay = (this.options.decay || 1);
2000
4b9dfd5b 2001 this.updater = { };
14f69488
AD
2002 this.container = container;
2003 this.url = url;
2004
2005 this.start();
2006 },
2007
2008 start: function() {
2009 this.options.onComplete = this.updateComplete.bind(this);
2010 this.onTimerEvent();
2011 },
2012
2013 stop: function() {
5c656a9d 2014 this.updater.options.onComplete = undefined;
14f69488
AD
2015 clearTimeout(this.timer);
2016 (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
2017 },
2018
4b9dfd5b 2019 updateComplete: function(response) {
14f69488 2020 if (this.options.decay) {
4b9dfd5b 2021 this.decay = (response.responseText == this.lastText ?
14f69488
AD
2022 this.decay * this.options.decay : 1);
2023
4b9dfd5b 2024 this.lastText = response.responseText;
14f69488 2025 }
4b9dfd5b 2026 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
14f69488
AD
2027 },
2028
2029 onTimerEvent: function() {
2030 this.updater = new Ajax.Updater(this.container, this.url, this.options);
2031 }
2032});
85e836d8 2033
e3cfa33b 2034(function(GLOBAL) {
85e836d8 2035
e3cfa33b
AK
2036 var UNDEFINED;
2037 var SLICE = Array.prototype.slice;
2038
2039 var DIV = document.createElement('div');
2040
2041
2042 function $(element) {
2043 if (arguments.length > 1) {
2044 for (var i = 0, elements = [], length = arguments.length; i < length; i++)
2045 elements.push($(arguments[i]));
2046 return elements;
2047 }
2048
2049 if (Object.isString(element))
2050 element = document.getElementById(element);
2051 return Element.extend(element);
5c656a9d 2052 }
5c656a9d 2053
e3cfa33b 2054 GLOBAL.$ = $;
14f69488 2055
14f69488 2056
e3cfa33b 2057 if (!GLOBAL.Node) GLOBAL.Node = {};
5c656a9d 2058
e3cfa33b
AK
2059 if (!GLOBAL.Node.ELEMENT_NODE) {
2060 Object.extend(GLOBAL.Node, {
2061 ELEMENT_NODE: 1,
2062 ATTRIBUTE_NODE: 2,
2063 TEXT_NODE: 3,
2064 CDATA_SECTION_NODE: 4,
2065 ENTITY_REFERENCE_NODE: 5,
2066 ENTITY_NODE: 6,
2067 PROCESSING_INSTRUCTION_NODE: 7,
2068 COMMENT_NODE: 8,
2069 DOCUMENT_NODE: 9,
2070 DOCUMENT_TYPE_NODE: 10,
2071 DOCUMENT_FRAGMENT_NODE: 11,
2072 NOTATION_NODE: 12
2073 });
2074 }
85e836d8 2075
e3cfa33b 2076 var ELEMENT_CACHE = {};
3fe38208 2077
e3cfa33b 2078 function shouldUseCreationCache(tagName, attributes) {
3fe38208
AD
2079 if (tagName === 'select') return false;
2080 if ('type' in attributes) return false;
2081 return true;
2082 }
85e836d8 2083
3fe38208
AD
2084 var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
2085 try {
2086 var el = document.createElement('<input name="x">');
2087 return el.tagName.toLowerCase() === 'input' && el.name === 'x';
2088 }
2089 catch(err) {
2090 return false;
2091 }
85e836d8
AD
2092 })();
2093
3fe38208 2094
e3cfa33b
AK
2095 var oldElement = GLOBAL.Element;
2096 function Element(tagName, attributes) {
2097 attributes = attributes || {};
4b9dfd5b 2098 tagName = tagName.toLowerCase();
3fe38208
AD
2099
2100 if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
4b9dfd5b
AD
2101 tagName = '<' + tagName + ' name="' + attributes.name + '">';
2102 delete attributes.name;
2103 return Element.writeAttribute(document.createElement(tagName), attributes);
5c656a9d 2104 }
3fe38208 2105
e3cfa33b
AK
2106 if (!ELEMENT_CACHE[tagName])
2107 ELEMENT_CACHE[tagName] = Element.extend(document.createElement(tagName));
3fe38208 2108
e3cfa33b
AK
2109 var node = shouldUseCreationCache(tagName, attributes) ?
2110 ELEMENT_CACHE[tagName].cloneNode(false) : document.createElement(tagName);
3fe38208
AD
2111
2112 return Element.writeAttribute(node, attributes);
e3cfa33b 2113 }
3fe38208 2114
e3cfa33b 2115 GLOBAL.Element = Element;
3fe38208 2116
e3cfa33b
AK
2117 Object.extend(GLOBAL.Element, oldElement || {});
2118 if (oldElement) GLOBAL.Element.prototype = oldElement.prototype;
2119
2120 Element.Methods = { ByTag: {}, Simulated: {} };
2121
2122 var methods = {};
5c656a9d 2123
e3cfa33b
AK
2124 var INSPECT_ATTRIBUTES = { id: 'id', className: 'class' };
2125 function inspect(element) {
2126 element = $(element);
2127 var result = '<' + element.tagName.toLowerCase();
2128
2129 var attribute, value;
2130 for (var property in INSPECT_ATTRIBUTES) {
2131 attribute = INSPECT_ATTRIBUTES[property];
2132 value = (element[property] || '').toString();
2133 if (value) result += ' ' + attribute + '=' + value.inspect(true);
2134 }
3fe38208 2135
e3cfa33b 2136 return result + '>';
3fe38208 2137 }
5c656a9d 2138
e3cfa33b 2139 methods.inspect = inspect;
14f69488 2140
e3cfa33b
AK
2141
2142 function visible(element) {
2143 return $(element).getStyle('display') !== 'none';
2144 }
2145
2146 function toggle(element, bool) {
5c656a9d 2147 element = $(element);
e3cfa33b
AK
2148 if (typeof bool !== 'boolean')
2149 bool = !Element.visible(element);
2150 Element[bool ? 'show' : 'hide'](element);
2151
5c656a9d 2152 return element;
e3cfa33b 2153 }
14f69488 2154
e3cfa33b 2155 function hide(element) {
85e836d8
AD
2156 element = $(element);
2157 element.style.display = 'none';
5c656a9d 2158 return element;
e3cfa33b 2159 }
14f69488 2160
e3cfa33b 2161 function show(element) {
85e836d8
AD
2162 element = $(element);
2163 element.style.display = '';
5c656a9d 2164 return element;
e3cfa33b
AK
2165 }
2166
2167
2168 Object.extend(methods, {
2169 visible: visible,
2170 toggle: toggle,
2171 hide: hide,
2172 show: show
2173 });
2174
14f69488 2175
e3cfa33b 2176 function remove(element) {
14f69488
AD
2177 element = $(element);
2178 element.parentNode.removeChild(element);
5c656a9d 2179 return element;
e3cfa33b 2180 }
14f69488 2181
e3cfa33b
AK
2182 var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
2183 var el = document.createElement("select"),
2184 isBuggy = true;
2185 el.innerHTML = "<option value=\"test\">test</option>";
2186 if (el.options && el.options[0]) {
2187 isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
2188 }
2189 el = null;
2190 return isBuggy;
2191 })();
85e836d8 2192
e3cfa33b
AK
2193 var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
2194 try {
2195 var el = document.createElement("table");
2196 if (el && el.tBodies) {
2197 el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
2198 var isBuggy = typeof el.tBodies[0] == "undefined";
2199 el = null;
2200 return isBuggy;
85e836d8 2201 }
e3cfa33b
AK
2202 } catch (e) {
2203 return true;
2204 }
2205 })();
2206
2207 var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
2208 try {
2209 var el = document.createElement('div');
2210 el.innerHTML = "<link />";
2211 var isBuggy = (el.childNodes.length === 0);
85e836d8
AD
2212 el = null;
2213 return isBuggy;
e3cfa33b
AK
2214 } catch(e) {
2215 return true;
2216 }
2217 })();
85e836d8 2218
e3cfa33b
AK
2219 var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
2220 TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
85e836d8 2221
e3cfa33b
AK
2222 var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
2223 var s = document.createElement("script"),
2224 isBuggy = false;
2225 try {
2226 s.appendChild(document.createTextNode(""));
2227 isBuggy = !s.firstChild ||
2228 s.firstChild && s.firstChild.nodeType !== 3;
2229 } catch (e) {
2230 isBuggy = true;
2231 }
2232 s = null;
2233 return isBuggy;
2234 })();
3fe38208 2235
e3cfa33b
AK
2236 function update(element, content) {
2237 element = $(element);
3fe38208 2238
e3cfa33b
AK
2239 var descendants = element.getElementsByTagName('*'),
2240 i = descendants.length;
2241 while (i--) purgeElement(descendants[i]);
85e836d8 2242
e3cfa33b
AK
2243 if (content && content.toElement)
2244 content = content.toElement();
3fe38208 2245
e3cfa33b
AK
2246 if (Object.isElement(content))
2247 return element.update().insert(content);
3fe38208 2248
85e836d8 2249
e3cfa33b
AK
2250 content = Object.toHTML(content);
2251 var tagName = element.tagName.toUpperCase();
85e836d8 2252
e3cfa33b
AK
2253 if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
2254 element.text = content;
2255 return element;
2256 }
85e836d8 2257
e3cfa33b
AK
2258 if (ANY_INNERHTML_BUGGY) {
2259 if (tagName in INSERTION_TRANSLATIONS.tags) {
2260 while (element.firstChild)
2261 element.removeChild(element.firstChild);
85e836d8 2262
e3cfa33b
AK
2263 var nodes = getContentFromAnonymousElement(tagName, content.stripScripts());
2264 for (var i = 0, node; node = nodes[i]; i++)
2265 element.appendChild(node);
85e836d8 2266
e3cfa33b
AK
2267 } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
2268 while (element.firstChild)
2269 element.removeChild(element.firstChild);
85e836d8 2270
e3cfa33b
AK
2271 var nodes = getContentFromAnonymousElement(tagName,
2272 content.stripScripts(), true);
2273
2274 for (var i = 0, node; node = nodes[i]; i++)
2275 element.appendChild(node);
2276 } else {
85e836d8
AD
2277 element.innerHTML = content.stripScripts();
2278 }
e3cfa33b
AK
2279 } else {
2280 element.innerHTML = content.stripScripts();
85e836d8
AD
2281 }
2282
e3cfa33b
AK
2283 content.evalScripts.bind(content).defer();
2284 return element;
2285 }
14f69488 2286
e3cfa33b 2287 function replace(element, content) {
5c656a9d 2288 element = $(element);
e3cfa33b
AK
2289
2290 if (content && content.toElement) {
2291 content = content.toElement();
2292 } else if (!Object.isElement(content)) {
4b9dfd5b 2293 content = Object.toHTML(content);
5c656a9d 2294 var range = element.ownerDocument.createRange();
4b9dfd5b
AD
2295 range.selectNode(element);
2296 content.evalScripts.bind(content).defer();
2297 content = range.createContextualFragment(content.stripScripts());
5c656a9d 2298 }
e3cfa33b 2299
4b9dfd5b 2300 element.parentNode.replaceChild(content, element);
5c656a9d 2301 return element;
e3cfa33b
AK
2302 }
2303
2304 var INSERTION_TRANSLATIONS = {
2305 before: function(element, node) {
2306 element.parentNode.insertBefore(node, element);
2307 },
2308 top: function(element, node) {
2309 element.insertBefore(node, element.firstChild);
2310 },
2311 bottom: function(element, node) {
2312 element.appendChild(node);
2313 },
2314 after: function(element, node) {
2315 element.parentNode.insertBefore(node, element.nextSibling);
2316 },
2317
2318 tags: {
2319 TABLE: ['<table>', '</table>', 1],
2320 TBODY: ['<table><tbody>', '</tbody></table>', 2],
2321 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
2322 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
2323 SELECT: ['<select>', '</select>', 1]
2324 }
2325 };
2326
2327 var tags = INSERTION_TRANSLATIONS.tags;
5c656a9d 2328
e3cfa33b
AK
2329 Object.extend(tags, {
2330 THEAD: tags.TBODY,
2331 TFOOT: tags.TBODY,
2332 TH: tags.TD
2333 });
2334
2335 function replace_IE(element, content) {
4b9dfd5b 2336 element = $(element);
e3cfa33b
AK
2337 if (content && content.toElement)
2338 content = content.toElement();
2339 if (Object.isElement(content)) {
2340 element.parentNode.replaceChild(content, element);
2341 return element;
2342 }
4b9dfd5b 2343
e3cfa33b
AK
2344 content = Object.toHTML(content);
2345 var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
4b9dfd5b 2346
e3cfa33b
AK
2347 if (tagName in INSERTION_TRANSLATIONS.tags) {
2348 var nextSibling = Element.next(element);
2349 var fragments = getContentFromAnonymousElement(
2350 tagName, content.stripScripts());
4b9dfd5b 2351
e3cfa33b 2352 parent.removeChild(element);
4b9dfd5b 2353
e3cfa33b
AK
2354 var iterator;
2355 if (nextSibling)
2356 iterator = function(node) { parent.insertBefore(node, nextSibling) };
2357 else
2358 iterator = function(node) { parent.appendChild(node); }
4b9dfd5b 2359
e3cfa33b
AK
2360 fragments.each(iterator);
2361 } else {
2362 element.outerHTML = content.stripScripts();
2363 }
4b9dfd5b 2364
e3cfa33b
AK
2365 content.evalScripts.bind(content).defer();
2366 return element;
2367 }
4b9dfd5b 2368
e3cfa33b
AK
2369 if ('outerHTML' in document.documentElement)
2370 replace = replace_IE;
4b9dfd5b 2371
e3cfa33b
AK
2372 function isContent(content) {
2373 if (Object.isUndefined(content) || content === null) return false;
4b9dfd5b 2374
e3cfa33b
AK
2375 if (Object.isString(content) || Object.isNumber(content)) return true;
2376 if (Object.isElement(content)) return true;
2377 if (content.toElement || content.toHTML) return true;
2378
2379 return false;
2380 }
2381
2382 function insertContentAt(element, content, position) {
2383 position = position.toLowerCase();
2384 var method = INSERTION_TRANSLATIONS[position];
2385
2386 if (content && content.toElement) content = content.toElement();
2387 if (Object.isElement(content)) {
2388 method(element, content);
2389 return element;
4b9dfd5b
AD
2390 }
2391
e3cfa33b
AK
2392 content = Object.toHTML(content);
2393 var tagName = ((position === 'before' || position === 'after') ?
2394 element.parentNode : element).tagName.toUpperCase();
2395
2396 var childNodes = getContentFromAnonymousElement(tagName, content.stripScripts());
2397
2398 if (position === 'top' || position === 'after') childNodes.reverse();
2399
2400 for (var i = 0, node; node = childNodes[i]; i++)
2401 method(element, node);
2402
2403 content.evalScripts.bind(content).defer();
2404 }
2405
2406 function insert(element, insertions) {
2407 element = $(element);
2408
2409 if (isContent(insertions))
2410 insertions = { bottom: insertions };
2411
2412 for (var position in insertions)
2413 insertContentAt(element, insertions[position], position);
2414
4b9dfd5b 2415 return element;
e3cfa33b 2416 }
4b9dfd5b 2417
e3cfa33b 2418 function wrap(element, wrapper, attributes) {
4b9dfd5b 2419 element = $(element);
e3cfa33b
AK
2420
2421 if (Object.isElement(wrapper)) {
2422 $(wrapper).writeAttribute(attributes || {});
2423 } else if (Object.isString(wrapper)) {
2424 wrapper = new Element(wrapper, attributes);
2425 } else {
2426 wrapper = new Element('div', wrapper);
2427 }
2428
4b9dfd5b
AD
2429 if (element.parentNode)
2430 element.parentNode.replaceChild(wrapper, element);
e3cfa33b 2431
4b9dfd5b 2432 wrapper.appendChild(element);
e3cfa33b 2433
4b9dfd5b 2434 return wrapper;
e3cfa33b 2435 }
4b9dfd5b 2436
e3cfa33b 2437 function cleanWhitespace(element) {
5c656a9d 2438 element = $(element);
e3cfa33b 2439 var node = element.firstChild;
5c656a9d 2440
e3cfa33b
AK
2441 while (node) {
2442 var nextNode = node.nextSibling;
2443 if (node.nodeType === Node.TEXT_NODE && !/\S/.test(node.nodeValue))
2444 element.removeChild(node);
2445 node = nextNode;
2446 }
2447 return element;
2448 }
2449
2450 function empty(element) {
2451 return $(element).innerHTML.blank();
2452 }
2453
2454 function getContentFromAnonymousElement(tagName, html, force) {
2455 var t = INSERTION_TRANSLATIONS.tags[tagName], div = DIV;
2456
2457 var workaround = !!t;
2458 if (!workaround && force) {
2459 workaround = true;
2460 t = ['', '', 0];
2461 }
2462
2463 if (workaround) {
2464 div.innerHTML = '&#160;' + t[0] + html + t[1];
2465 div.removeChild(div.firstChild);
2466 for (var i = t[2]; i--; )
2467 div = div.firstChild;
2468 } else {
2469 div.innerHTML = html;
2470 }
2471
2472 return $A(div.childNodes);
2473 }
2474
2475 function clone(element, deep) {
2476 if (!(element = $(element))) return;
2477 var clone = element.cloneNode(deep);
2478 if (!HAS_UNIQUE_ID_PROPERTY) {
2479 clone._prototypeUID = UNDEFINED;
2480 if (deep) {
2481 var descendants = Element.select(clone, '*'),
2482 i = descendants.length;
2483 while (i--)
2484 descendants[i]._prototypeUID = UNDEFINED;
2485 }
2486 }
2487 return Element.extend(clone);
2488 }
2489
2490 function purgeElement(element) {
2491 var uid = getUniqueElementID(element);
2492 if (uid) {
2493 Element.stopObserving(element);
2494 if (!HAS_UNIQUE_ID_PROPERTY)
2495 element._prototypeUID = UNDEFINED;
2496 delete Element.Storage[uid];
2497 }
2498 }
2499
2500 function purgeCollection(elements) {
2501 var i = elements.length;
2502 while (i--)
2503 purgeElement(elements[i]);
2504 }
2505
2506 function purgeCollection_IE(elements) {
2507 var i = elements.length, element, uid;
2508 while (i--) {
2509 element = elements[i];
2510 uid = getUniqueElementID(element);
2511 delete Element.Storage[uid];
2512 delete Event.cache[uid];
2513 }
2514 }
2515
2516 if (HAS_UNIQUE_ID_PROPERTY) {
2517 purgeCollection = purgeCollection_IE;
2518 }
2519
2520
2521 function purge(element) {
2522 if (!(element = $(element))) return;
2523 purgeElement(element);
2524
2525 var descendants = element.getElementsByTagName('*'),
2526 i = descendants.length;
2527
2528 while (i--) purgeElement(descendants[i]);
2529
2530 return null;
2531 }
2532
2533 Object.extend(methods, {
2534 remove: remove,
2535 update: update,
2536 replace: replace,
2537 insert: insert,
2538 wrap: wrap,
2539 cleanWhitespace: cleanWhitespace,
2540 empty: empty,
2541 clone: clone,
2542 purge: purge
2543 });
2544
2545
2546
2547 function recursivelyCollect(element, property, maximumLength) {
5c656a9d 2548 element = $(element);
3fe38208 2549 maximumLength = maximumLength || -1;
5c656a9d 2550 var elements = [];
3fe38208
AD
2551
2552 while (element = element[property]) {
e3cfa33b 2553 if (element.nodeType === Node.ELEMENT_NODE)
5c656a9d 2554 elements.push(Element.extend(element));
e3cfa33b
AK
2555
2556 if (elements.length === maximumLength) break;
3fe38208
AD
2557 }
2558
5c656a9d 2559 return elements;
e3cfa33b 2560 }
5c656a9d 2561
5c656a9d 2562
e3cfa33b
AK
2563 function ancestors(element) {
2564 return recursivelyCollect(element, 'parentNode');
2565 }
4b9dfd5b 2566
e3cfa33b
AK
2567 function descendants(element) {
2568 return Element.select(element, '*');
2569 }
2570
2571 function firstDescendant(element) {
4b9dfd5b 2572 element = $(element).firstChild;
e3cfa33b
AK
2573 while (element && element.nodeType !== Node.ELEMENT_NODE)
2574 element = element.nextSibling;
2575
4b9dfd5b 2576 return $(element);
e3cfa33b 2577 }
5c656a9d 2578
e3cfa33b 2579 function immediateDescendants(element) {
3fe38208 2580 var results = [], child = $(element).firstChild;
e3cfa33b 2581
3fe38208 2582 while (child) {
e3cfa33b 2583 if (child.nodeType === Node.ELEMENT_NODE)
3fe38208 2584 results.push(Element.extend(child));
e3cfa33b 2585
3fe38208
AD
2586 child = child.nextSibling;
2587 }
e3cfa33b 2588
3fe38208 2589 return results;
e3cfa33b 2590 }
5c656a9d 2591
e3cfa33b
AK
2592 function previousSiblings(element) {
2593 return recursivelyCollect(element, 'previousSibling');
2594 }
5c656a9d 2595
e3cfa33b
AK
2596 function nextSiblings(element) {
2597 return recursivelyCollect(element, 'nextSibling');
2598 }
5c656a9d 2599
e3cfa33b 2600 function siblings(element) {
14f69488 2601 element = $(element);
e3cfa33b
AK
2602 var previous = previousSiblings(element),
2603 next = nextSiblings(element);
2604 return previous.reverse().concat(next);
2605 }
5c656a9d 2606
e3cfa33b 2607 function match(element, selector) {
3fe38208 2608 element = $(element);
e3cfa33b 2609
4b9dfd5b 2610 if (Object.isString(selector))
3fe38208 2611 return Prototype.Selector.match(element, selector);
e3cfa33b 2612
3fe38208 2613 return selector.match(element);
e3cfa33b 2614 }
5c656a9d 2615
5c656a9d 2616
e3cfa33b
AK
2617 function _recursivelyFind(element, property, expression, index) {
2618 element = $(element), expression = expression || 0, index = index || 0;
2619 if (Object.isNumber(expression)) {
2620 index = expression, expression = null;
2621 }
5c656a9d 2622
e3cfa33b
AK
2623 while (element = element[property]) {
2624 if (element.nodeType !== 1) continue;
2625 if (expression && !Prototype.Selector.match(element, expression))
2626 continue;
2627 if (--index >= 0) continue;
3fe38208 2628
e3cfa33b 2629 return Element.extend(element);
3fe38208 2630 }
e3cfa33b 2631 }
5c656a9d 2632
e3cfa33b
AK
2633
2634 function up(element, expression, index) {
4b9dfd5b 2635 element = $(element);
3fe38208 2636
e3cfa33b
AK
2637 if (arguments.length === 1) return $(element.parentNode);
2638 return _recursivelyFind(element, 'parentNode', expression, index);
2639 }
5c656a9d 2640
e3cfa33b
AK
2641 function down(element, expression, index) {
2642 if (arguments.length === 1) return firstDescendant(element);
2643 element = $(element), expression = expression || 0, index = index || 0;
85e836d8 2644
e3cfa33b
AK
2645 if (Object.isNumber(expression))
2646 index = expression, expression = '*';
2647
2648 var node = Prototype.Selector.select(expression, element)[index];
2649 return Element.extend(node);
2650 }
2651
2652 function previous(element, expression, index) {
2653 return _recursivelyFind(element, 'previousSibling', expression, index);
2654 }
2655
2656 function next(element, expression, index) {
2657 return _recursivelyFind(element, 'nextSibling', expression, index);
2658 }
2659
2660 function select(element) {
3fe38208 2661 element = $(element);
e3cfa33b 2662 var expressions = SLICE.call(arguments, 1).join(', ');
3fe38208 2663 return Prototype.Selector.select(expressions, element);
e3cfa33b 2664 }
5c656a9d 2665
e3cfa33b 2666 function adjacent(element) {
3fe38208 2667 element = $(element);
e3cfa33b
AK
2668 var expressions = SLICE.call(arguments, 1).join(', ');
2669 var siblings = Element.siblings(element), results = [];
2670 for (var i = 0, sibling; sibling = siblings[i]; i++) {
2671 if (Prototype.Selector.match(sibling, expressions))
2672 results.push(sibling);
2673 }
2674
2675 return results;
2676 }
2677
2678 function descendantOf_DOM(element, ancestor) {
2679 element = $(element), ancestor = $(ancestor);
2680 if (!element || !ancestor) return false;
2681 while (element = element.parentNode)
2682 if (element === ancestor) return true;
2683 return false;
2684 }
4b9dfd5b 2685
e3cfa33b
AK
2686 function descendantOf_contains(element, ancestor) {
2687 element = $(element), ancestor = $(ancestor);
2688 if (!element || !ancestor) return false;
2689 if (!ancestor.contains) return descendantOf_DOM(element, ancestor);
2690 return ancestor.contains(element) && ancestor !== element;
2691 }
2692
2693 function descendantOf_compareDocumentPosition(element, ancestor) {
2694 element = $(element), ancestor = $(ancestor);
2695 if (!element || !ancestor) return false;
2696 return (element.compareDocumentPosition(ancestor) & 8) === 8;
2697 }
2698
2699 var descendantOf;
2700 if (DIV.compareDocumentPosition) {
2701 descendantOf = descendantOf_compareDocumentPosition;
2702 } else if (DIV.contains) {
2703 descendantOf = descendantOf_contains;
2704 } else {
2705 descendantOf = descendantOf_DOM;
2706 }
2707
2708
2709 Object.extend(methods, {
2710 recursivelyCollect: recursivelyCollect,
2711 ancestors: ancestors,
2712 descendants: descendants,
2713 firstDescendant: firstDescendant,
2714 immediateDescendants: immediateDescendants,
2715 previousSiblings: previousSiblings,
2716 nextSiblings: nextSiblings,
2717 siblings: siblings,
2718 match: match,
2719 up: up,
2720 down: down,
2721 previous: previous,
2722 next: next,
2723 select: select,
2724 adjacent: adjacent,
2725 descendantOf: descendantOf,
2726
2727 getElementsBySelector: select,
2728
2729 childElements: immediateDescendants
2730 });
2731
2732
2733 var idCounter = 1;
2734 function identify(element) {
4b9dfd5b 2735 element = $(element);
85e836d8 2736 var id = Element.readAttribute(element, 'id');
4b9dfd5b 2737 if (id) return id;
e3cfa33b
AK
2738
2739 do { id = 'anonymous_element_' + idCounter++ } while ($(id));
2740
85e836d8 2741 Element.writeAttribute(element, 'id', id);
4b9dfd5b 2742 return id;
e3cfa33b
AK
2743 }
2744
5c656a9d 2745
e3cfa33b
AK
2746 function readAttribute(element, name) {
2747 return $(element).getAttribute(name);
2748 }
2749
2750 function readAttribute_IE(element, name) {
5c656a9d 2751 element = $(element);
e3cfa33b
AK
2752
2753 var table = ATTRIBUTE_TRANSLATIONS.read;
2754 if (table.values[name])
2755 return table.values[name](element, name);
2756
2757 if (table.names[name]) name = table.names[name];
2758
2759 if (name.include(':')) {
2760 if (!element.attributes || !element.attributes[name]) return null;
2761 return element.attributes[name].value;
5c656a9d 2762 }
e3cfa33b 2763
5c656a9d 2764 return element.getAttribute(name);
e3cfa33b
AK
2765 }
2766
2767 function readAttribute_Opera(element, name) {
2768 if (name === 'title') return element.title;
2769 return element.getAttribute(name);
2770 }
5c656a9d 2771
e3cfa33b
AK
2772 var PROBLEMATIC_ATTRIBUTE_READING = (function() {
2773 DIV.setAttribute('onclick', []);
2774 var value = DIV.getAttribute('onclick');
2775 var isFunction = Object.isArray(value);
2776 DIV.removeAttribute('onclick');
2777 return isFunction;
2778 })();
2779
2780 if (PROBLEMATIC_ATTRIBUTE_READING) {
2781 readAttribute = readAttribute_IE;
2782 } else if (Prototype.Browser.Opera) {
2783 readAttribute = readAttribute_Opera;
2784 }
2785
2786
2787 function writeAttribute(element, name, value) {
4b9dfd5b 2788 element = $(element);
e3cfa33b 2789 var attributes = {}, table = ATTRIBUTE_TRANSLATIONS.write;
4b9dfd5b 2790
e3cfa33b
AK
2791 if (typeof name === 'object') {
2792 attributes = name;
2793 } else {
2794 attributes[name] = Object.isUndefined(value) ? true : value;
2795 }
4b9dfd5b
AD
2796
2797 for (var attr in attributes) {
e3cfa33b 2798 name = table.names[attr] || attr;
4b9dfd5b 2799 value = attributes[attr];
e3cfa33b
AK
2800 if (table.values[attr]) {
2801 value = table.values[attr](element, value);
2802 if (Object.isUndefined(value)) continue;
2803 }
4b9dfd5b
AD
2804 if (value === false || value === null)
2805 element.removeAttribute(name);
2806 else if (value === true)
2807 element.setAttribute(name, name);
2808 else element.setAttribute(name, value);
2809 }
e3cfa33b 2810
4b9dfd5b 2811 return element;
e3cfa33b 2812 }
4b9dfd5b 2813
e3cfa33b
AK
2814 var PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES = (function () {
2815 if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) {
2816 return false;
2817 }
2818 var checkbox = document.createElement('<input type="checkbox">');
2819 checkbox.checked = true;
2820 var node = checkbox.getAttributeNode('checked');
2821 return !node || !node.specified;
2822 })();
5c656a9d 2823
e3cfa33b
AK
2824 function hasAttribute(element, attribute) {
2825 attribute = ATTRIBUTE_TRANSLATIONS.has[attribute] || attribute;
2826 var node = $(element).getAttributeNode(attribute);
2827 return !!(node && node.specified);
2828 }
2829
2830 function hasAttribute_IE(element, attribute) {
2831 if (attribute === 'checked') {
2832 return element.checked;
2833 }
2834 return hasAttribute(element, attribute);
2835 }
14f69488 2836
e3cfa33b
AK
2837 GLOBAL.Element.Methods.Simulated.hasAttribute =
2838 PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES ?
2839 hasAttribute_IE : hasAttribute;
2840
2841 function classNames(element) {
14f69488 2842 return new Element.ClassNames(element);
e3cfa33b
AK
2843 }
2844
2845 var regExpCache = {};
2846 function getRegExpForClassName(className) {
2847 if (regExpCache[className]) return regExpCache[className];
2848
2849 var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
2850 regExpCache[className] = re;
2851 return re;
2852 }
14f69488 2853
e3cfa33b 2854 function hasClassName(element, className) {
14f69488 2855 if (!(element = $(element))) return;
e3cfa33b 2856
5c656a9d 2857 var elementClassName = element.className;
14f69488 2858
e3cfa33b
AK
2859 if (elementClassName.length === 0) return false;
2860 if (elementClassName === className) return true;
2861
2862 return getRegExpForClassName(className).test(elementClassName);
2863 }
2864
2865 function addClassName(element, className) {
14f69488 2866 if (!(element = $(element))) return;
e3cfa33b
AK
2867
2868 if (!hasClassName(element, className))
4b9dfd5b 2869 element.className += (element.className ? ' ' : '') + className;
e3cfa33b 2870
5c656a9d 2871 return element;
e3cfa33b 2872 }
14f69488 2873
e3cfa33b 2874 function removeClassName(element, className) {
14f69488 2875 if (!(element = $(element))) return;
e3cfa33b 2876
4b9dfd5b 2877 element.className = element.className.replace(
e3cfa33b
AK
2878 getRegExpForClassName(className), ' ').strip();
2879
5c656a9d 2880 return element;
e3cfa33b 2881 }
5c656a9d 2882
e3cfa33b 2883 function toggleClassName(element, className, bool) {
5c656a9d 2884 if (!(element = $(element))) return;
14f69488 2885
e3cfa33b
AK
2886 if (Object.isUndefined(bool))
2887 bool = !hasClassName(element, className);
14f69488 2888
e3cfa33b
AK
2889 var method = Element[bool ? 'addClassName' : 'removeClassName'];
2890 return method(element, className);
2891 }
14f69488 2892
e3cfa33b 2893 var ATTRIBUTE_TRANSLATIONS = {};
4b9dfd5b 2894
e3cfa33b 2895 var classProp = 'className', forProp = 'for';
4b9dfd5b 2896
e3cfa33b
AK
2897 DIV.setAttribute(classProp, 'x');
2898 if (DIV.className !== 'x') {
2899 DIV.setAttribute('class', 'x');
2900 if (DIV.className === 'x')
2901 classProp = 'class';
2902 }
4b9dfd5b 2903
e3cfa33b
AK
2904 var LABEL = document.createElement('label');
2905 LABEL.setAttribute(forProp, 'x');
2906 if (LABEL.htmlFor !== 'x') {
2907 LABEL.setAttribute('htmlFor', 'x');
2908 if (LABEL.htmlFor === 'x')
2909 forProp = 'htmlFor';
2910 }
2911 LABEL = null;
85e836d8 2912
e3cfa33b
AK
2913 function _getAttr(element, attribute) {
2914 return element.getAttribute(attribute);
2915 }
5c656a9d 2916
e3cfa33b
AK
2917 function _getAttr2(element, attribute) {
2918 return element.getAttribute(attribute, 2);
2919 }
14f69488 2920
e3cfa33b
AK
2921 function _getAttrNode(element, attribute) {
2922 var node = element.getAttributeNode(attribute);
2923 return node ? node.value : '';
2924 }
14f69488 2925
e3cfa33b
AK
2926 function _getFlag(element, attribute) {
2927 return $(element).hasAttribute(attribute) ? attribute : null;
2928 }
5c656a9d 2929
e3cfa33b
AK
2930 DIV.onclick = Prototype.emptyFunction;
2931 var onclickValue = DIV.getAttribute('onclick');
4b9dfd5b 2932
e3cfa33b 2933 var _getEv;
14f69488 2934
e3cfa33b
AK
2935 if (String(onclickValue).indexOf('{') > -1) {
2936 _getEv = function(element, attribute) {
2937 var value = element.getAttribute(attribute);
2938 if (!value) return null;
2939 value = value.toString();
2940 value = value.split('{')[1];
2941 value = value.split('}')[0];
2942 return value.strip();
2943 };
2944 }
2945 else if (onclickValue === '') {
2946 _getEv = function(element, attribute) {
2947 var value = element.getAttribute(attribute);
2948 if (!value) return null;
2949 return value.strip();
2950 };
2951 }
14f69488 2952
e3cfa33b
AK
2953 ATTRIBUTE_TRANSLATIONS.read = {
2954 names: {
2955 'class': classProp,
2956 'className': classProp,
2957 'for': forProp,
2958 'htmlFor': forProp
2959 },
2960
2961 values: {
2962 style: function(element) {
2963 return element.style.cssText.toLowerCase();
2964 },
2965 title: function(element) {
2966 return element.title;
14f69488
AD
2967 }
2968 }
e3cfa33b 2969 };
14f69488 2970
e3cfa33b
AK
2971 ATTRIBUTE_TRANSLATIONS.write = {
2972 names: {
2973 className: 'class',
2974 htmlFor: 'for',
2975 cellpadding: 'cellPadding',
2976 cellspacing: 'cellSpacing'
2977 },
2978
2979 values: {
2980 checked: function(element, value) {
2981 value = !!value;
2982 element.checked = value;
2983 return value ? 'checked' : null;
2984 },
2985
2986 style: function(element, value) {
2987 element.style.cssText = value ? value : '';
2988 }
14f69488 2989 }
e3cfa33b 2990 };
14f69488 2991
e3cfa33b
AK
2992 ATTRIBUTE_TRANSLATIONS.has = { names: {} };
2993
2994 Object.extend(ATTRIBUTE_TRANSLATIONS.write.names,
2995 ATTRIBUTE_TRANSLATIONS.read.names);
2996
2997 var CAMEL_CASED_ATTRIBUTE_NAMES = $w('colSpan rowSpan vAlign dateTime ' +
2998 'accessKey tabIndex encType maxLength readOnly longDesc frameBorder');
2999
3000 for (var i = 0, attr; attr = CAMEL_CASED_ATTRIBUTE_NAMES[i]; i++) {
3001 ATTRIBUTE_TRANSLATIONS.write.names[attr.toLowerCase()] = attr;
3002 ATTRIBUTE_TRANSLATIONS.has.names[attr.toLowerCase()] = attr;
3003 }
3004
3005 Object.extend(ATTRIBUTE_TRANSLATIONS.read.values, {
3006 href: _getAttr2,
3007 src: _getAttr2,
3008 type: _getAttr,
3009 action: _getAttrNode,
3010 disabled: _getFlag,
3011 checked: _getFlag,
3012 readonly: _getFlag,
3013 multiple: _getFlag,
3014 onload: _getEv,
3015 onunload: _getEv,
3016 onclick: _getEv,
3017 ondblclick: _getEv,
3018 onmousedown: _getEv,
3019 onmouseup: _getEv,
3020 onmouseover: _getEv,
3021 onmousemove: _getEv,
3022 onmouseout: _getEv,
3023 onfocus: _getEv,
3024 onblur: _getEv,
3025 onkeypress: _getEv,
3026 onkeydown: _getEv,
3027 onkeyup: _getEv,
3028 onsubmit: _getEv,
3029 onreset: _getEv,
3030 onselect: _getEv,
3031 onchange: _getEv
3032 });
14f69488 3033
5c656a9d 3034
e3cfa33b
AK
3035 Object.extend(methods, {
3036 identify: identify,
3037 readAttribute: readAttribute,
3038 writeAttribute: writeAttribute,
3039 classNames: classNames,
3040 hasClassName: hasClassName,
3041 addClassName: addClassName,
3042 removeClassName: removeClassName,
3043 toggleClassName: toggleClassName
3044 });
4b9dfd5b 3045
4b9dfd5b 3046
e3cfa33b
AK
3047 function normalizeStyleName(style) {
3048 if (style === 'float' || style === 'styleFloat')
3049 return 'cssFloat';
3050 return style.camelize();
3051 }
3052
3053 function normalizeStyleName_IE(style) {
3054 if (style === 'float' || style === 'cssFloat')
3055 return 'styleFloat';
3056 return style.camelize();
3057 }
3058
3059 function setStyle(element, styles) {
4b9dfd5b 3060 element = $(element);
e3cfa33b 3061 var elementStyle = element.style, match;
3fe38208 3062
e3cfa33b
AK
3063 if (Object.isString(styles)) {
3064 elementStyle.cssText += ';' + styles;
3065 if (styles.include('opacity')) {
3066 var opacity = styles.match(/opacity:\s*(\d?\.?\d*)/)[1];
3067 Element.setOpacity(element, opacity);
3068 }
3069 return element;
4b9dfd5b
AD
3070 }
3071
e3cfa33b
AK
3072 for (var property in styles) {
3073 if (property === 'opacity') {
3074 Element.setOpacity(element, styles[property]);
3075 } else {
3076 var value = styles[property];
3077 if (property === 'float' || property === 'cssFloat') {
3078 property = Object.isUndefined(elementStyle.styleFloat) ?
3079 'cssFloat' : 'styleFloat';
3080 }
3081 elementStyle[property] = value;
3082 }
4b9dfd5b
AD
3083 }
3084
4b9dfd5b
AD
3085 return element;
3086 }
4b9dfd5b 3087
85e836d8 3088
e3cfa33b
AK
3089 function getStyle(element, style) {
3090 element = $(element);
3091 style = normalizeStyleName(style);
14f69488 3092
e3cfa33b
AK
3093 var value = element.style[style];
3094 if (!value || value === 'auto') {
3095 var css = document.defaultView.getComputedStyle(element, null);
3096 value = css ? css[style] : null;
3097 }
3098
3099 if (style === 'opacity') return value ? parseFloat(value) : 1.0;
3100 return value === 'auto' ? null : value;
4b9dfd5b 3101 }
14f69488 3102
e3cfa33b
AK
3103 function getStyle_Opera(element, style) {
3104 switch (style) {
3105 case 'height': case 'width':
3106 if (!Element.visible(element)) return null;
4b9dfd5b 3107
e3cfa33b 3108 var dim = parseInt(getStyle(element, style), 10);
4b9dfd5b 3109
e3cfa33b
AK
3110 if (dim !== element['offset' + style.capitalize()])
3111 return dim + 'px';
4b9dfd5b 3112
e3cfa33b 3113 return Element.measure(element, style);
14f69488 3114
e3cfa33b 3115 default: return getStyle(element, style);
4b9dfd5b 3116 }
e3cfa33b 3117 }
4b9dfd5b 3118
e3cfa33b 3119 function getStyle_IE(element, style) {
4b9dfd5b 3120 element = $(element);
e3cfa33b
AK
3121 style = normalizeStyleName_IE(style);
3122
4b9dfd5b 3123 var value = element.style[style];
e3cfa33b
AK
3124 if (!value && element.currentStyle) {
3125 value = element.currentStyle[style];
3126 }
4b9dfd5b 3127
e3cfa33b
AK
3128 if (style === 'opacity') {
3129 if (!STANDARD_CSS_OPACITY_SUPPORTED)
3130 return getOpacity_IE(element);
3131 else return value ? parseFloat(value) : 1.0;
4b9dfd5b
AD
3132 }
3133
e3cfa33b
AK
3134 if (value === 'auto') {
3135 if ((style === 'width' || style === 'height') && Element.visible(element))
3136 return Element.measure(element, style) + 'px';
4b9dfd5b
AD
3137 return null;
3138 }
e3cfa33b 3139
4b9dfd5b 3140 return value;
e3cfa33b 3141 }
4b9dfd5b 3142
e3cfa33b
AK
3143 function stripAlphaFromFilter_IE(filter) {
3144 return (filter || '').replace(/alpha\([^\)]*\)/gi, '');
3145 }
4b9dfd5b 3146
e3cfa33b
AK
3147 function hasLayout_IE(element) {
3148 if (!element.currentStyle || !element.currentStyle.hasLayout)
3149 element.style.zoom = 1;
4b9dfd5b 3150 return element;
e3cfa33b 3151 }
85e836d8 3152
e3cfa33b
AK
3153 var STANDARD_CSS_OPACITY_SUPPORTED = (function() {
3154 DIV.style.cssText = "opacity:.55";
3155 return /^0.55/.test(DIV.style.opacity);
85e836d8 3156 })();
4b9dfd5b 3157
e3cfa33b
AK
3158 function setOpacity(element, value) {
3159 element = $(element);
3160 if (value == 1 || value === '') value = '';
3161 else if (value < 0.00001) value = 0;
3162 element.style.opacity = value;
3163 return element;
3164 }
4b9dfd5b 3165
e3cfa33b
AK
3166 function setOpacity_IE(element, value) {
3167 if (STANDARD_CSS_OPACITY_SUPPORTED)
3168 return setOpacity(element, value);
4b9dfd5b 3169
e3cfa33b
AK
3170 element = hasLayout_IE($(element));
3171 var filter = Element.getStyle(element, 'filter'),
3172 style = element.style;
4b9dfd5b 3173
e3cfa33b
AK
3174 if (value == 1 || value === '') {
3175 filter = stripAlphaFromFilter_IE(filter);
3176 if (filter) style.filter = filter;
3177 else style.removeAttribute('filter');
3178 return element;
3179 }
4b9dfd5b 3180
e3cfa33b 3181 if (value < 0.00001) value = 0;
85e836d8 3182
e3cfa33b
AK
3183 style.filter = stripAlphaFromFilter_IE(filter) +
3184 ' alpha(opacity=' + (value * 100) + ')';
85e836d8 3185
e3cfa33b 3186 return element;
85e836d8
AD
3187 }
3188
4b9dfd5b 3189
e3cfa33b
AK
3190 function getOpacity(element) {
3191 return Element.getStyle(element, 'opacity');
3192 }
4b9dfd5b 3193
e3cfa33b
AK
3194 function getOpacity_IE(element) {
3195 if (STANDARD_CSS_OPACITY_SUPPORTED)
3196 return getOpacity(element);
4b9dfd5b 3197
e3cfa33b
AK
3198 var filter = Element.getStyle(element, 'filter');
3199 if (filter.length === 0) return 1.0;
3200 var match = (filter || '').match(/alpha\(opacity=(.*)\)/i);
3201 if (match && match[1]) return parseFloat(match[1]) / 100;
3202 return 1.0;
3203 }
4b9dfd5b 3204
4b9dfd5b 3205
e3cfa33b
AK
3206 Object.extend(methods, {
3207 setStyle: setStyle,
3208 getStyle: getStyle,
3209 setOpacity: setOpacity,
3210 getOpacity: getOpacity
3211 });
4b9dfd5b 3212
e3cfa33b
AK
3213 if ('styleFloat' in DIV.style) {
3214 methods.getStyle = getStyle_IE;
3215 methods.setOpacity = setOpacity_IE;
3216 methods.getOpacity = getOpacity_IE;
3217 }
4b9dfd5b 3218
e3cfa33b 3219 var UID = 0;
4b9dfd5b 3220
e3cfa33b 3221 GLOBAL.Element.Storage = { UID: 1 };
4b9dfd5b 3222
e3cfa33b
AK
3223 function getUniqueElementID(element) {
3224 if (element === window) return 0;
3fe38208 3225
e3cfa33b
AK
3226 if (typeof element._prototypeUID === 'undefined')
3227 element._prototypeUID = Element.Storage.UID++;
3228 return element._prototypeUID;
3fe38208
AD
3229 }
3230
e3cfa33b
AK
3231 function getUniqueElementID_IE(element) {
3232 if (element === window) return 0;
3233 if (element == document) return 1;
3234 return element.uniqueID;
3fe38208 3235 }
4b9dfd5b 3236
e3cfa33b
AK
3237 var HAS_UNIQUE_ID_PROPERTY = ('uniqueID' in DIV);
3238 if (HAS_UNIQUE_ID_PROPERTY)
3239 getUniqueElementID = getUniqueElementID_IE;
14f69488 3240
e3cfa33b
AK
3241 function getStorage(element) {
3242 if (!(element = $(element))) return;
4b9dfd5b 3243
e3cfa33b
AK
3244 var uid = getUniqueElementID(element);
3245
3246 if (!Element.Storage[uid])
3247 Element.Storage[uid] = $H();
3248
3249 return Element.Storage[uid];
4b9dfd5b 3250 }
4b9dfd5b 3251
e3cfa33b
AK
3252 function store(element, key, value) {
3253 if (!(element = $(element))) return;
3254 var storage = getStorage(element);
3255 if (arguments.length === 2) {
3256 storage.update(key);
3257 } else {
3258 storage.set(key, value);
3259 }
3260 return element;
3261 }
4b9dfd5b 3262
e3cfa33b
AK
3263 function retrieve(element, key, defaultValue) {
3264 if (!(element = $(element))) return;
3265 var storage = getStorage(element), value = storage.get(key);
4b9dfd5b 3266
e3cfa33b
AK
3267 if (Object.isUndefined(value)) {
3268 storage.set(key, defaultValue);
3269 value = defaultValue;
3270 }
85e836d8 3271
e3cfa33b 3272 return value;
85e836d8
AD
3273 }
3274
85e836d8 3275
e3cfa33b
AK
3276 Object.extend(methods, {
3277 getStorage: getStorage,
3278 store: store,
3279 retrieve: retrieve
3280 });
4b9dfd5b 3281
85e836d8 3282
e3cfa33b
AK
3283 var Methods = {}, ByTag = Element.Methods.ByTag,
3284 F = Prototype.BrowserFeatures;
3285
3286 if (!F.ElementExtensions && ('__proto__' in DIV)) {
3287 GLOBAL.HTMLElement = {};
3288 GLOBAL.HTMLElement.prototype = DIV['__proto__'];
3289 F.ElementExtensions = true;
3290 }
3291
3292 function checkElementPrototypeDeficiency(tagName) {
3293 if (typeof window.Element === 'undefined') return false;
3294 if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) return false;
3295 var proto = window.Element.prototype;
3296 if (proto) {
3297 var id = '_' + (Math.random() + '').slice(2),
3298 el = document.createElement(tagName);
3299 proto[id] = 'x';
3300 var isBuggy = (el[id] !== 'x');
3301 delete proto[id];
3302 el = null;
3303 return isBuggy;
85e836d8 3304 }
e3cfa33b 3305
85e836d8
AD
3306 return false;
3307 }
3308
e3cfa33b
AK
3309 var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY =
3310 checkElementPrototypeDeficiency('object');
3311
85e836d8
AD
3312 function extendElementWith(element, methods) {
3313 for (var property in methods) {
3314 var value = methods[property];
3315 if (Object.isFunction(value) && !(property in element))
3316 element[property] = value.methodize();
3317 }
3318 }
3319
e3cfa33b
AK
3320 var EXTENDED = {};
3321 function elementIsExtended(element) {
3322 var uid = getUniqueElementID(element);
3323 return (uid in EXTENDED);
85e836d8 3324 }
4b9dfd5b 3325
e3cfa33b
AK
3326 function extend(element) {
3327 if (!element || elementIsExtended(element)) return element;
3328 if (element.nodeType !== Node.ELEMENT_NODE || element == window)
3329 return element;
4b9dfd5b
AD
3330
3331 var methods = Object.clone(Methods),
e3cfa33b 3332 tagName = element.tagName.toUpperCase();
4b9dfd5b 3333
4b9dfd5b
AD
3334 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
3335
85e836d8 3336 extendElementWith(element, methods);
e3cfa33b 3337 EXTENDED[getUniqueElementID(element)] = true;
4b9dfd5b 3338 return element;
e3cfa33b 3339 }
4b9dfd5b 3340
e3cfa33b
AK
3341 function extend_IE8(element) {
3342 if (!element || elementIsExtended(element)) return element;
4b9dfd5b 3343
e3cfa33b
AK
3344 var t = element.tagName;
3345 if (t && (/^(?:object|applet|embed)$/i.test(t))) {
3346 extendElementWith(element, Element.Methods);
3347 extendElementWith(element, Element.Methods.Simulated);
3348 extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
3349 }
4b9dfd5b 3350
e3cfa33b 3351 return element;
4b9dfd5b
AD
3352 }
3353
e3cfa33b
AK
3354 if (F.SpecificElementExtensions) {
3355 extend = HTMLOBJECTELEMENT_PROTOTYPE_BUGGY ? extend_IE8 : Prototype.K;
4b9dfd5b
AD
3356 }
3357
e3cfa33b 3358 function addMethodsToTagName(tagName, methods) {
4b9dfd5b 3359 tagName = tagName.toUpperCase();
e3cfa33b
AK
3360 if (!ByTag[tagName]) ByTag[tagName] = {};
3361 Object.extend(ByTag[tagName], methods);
4b9dfd5b
AD
3362 }
3363
e3cfa33b
AK
3364 function mergeMethods(destination, methods, onlyIfAbsent) {
3365 if (Object.isUndefined(onlyIfAbsent)) onlyIfAbsent = false;
4b9dfd5b
AD
3366 for (var property in methods) {
3367 var value = methods[property];
3368 if (!Object.isFunction(value)) continue;
3369 if (!onlyIfAbsent || !(property in destination))
3370 destination[property] = value.methodize();
3371 }
3372 }
3373
3374 function findDOMClass(tagName) {
3375 var klass;
3376 var trans = {
3377 "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
3378 "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
3379 "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
3380 "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
3381 "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
3382 "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
3383 "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
3384 "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
3385 "FrameSet", "IFRAME": "IFrame"
3386 };
3387 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
3388 if (window[klass]) return window[klass];
3389 klass = 'HTML' + tagName + 'Element';
3390 if (window[klass]) return window[klass];
3391 klass = 'HTML' + tagName.capitalize() + 'Element';
3392 if (window[klass]) return window[klass];
3393
3fe38208 3394 var element = document.createElement(tagName),
e3cfa33b 3395 proto = element['__proto__'] || element.constructor.prototype;
3fe38208 3396
85e836d8
AD
3397 element = null;
3398 return proto;
4b9dfd5b
AD
3399 }
3400
e3cfa33b
AK
3401 function addMethods(methods) {
3402 if (arguments.length === 0) addFormMethods();
85e836d8 3403
e3cfa33b
AK
3404 if (arguments.length === 2) {
3405 var tagName = methods;
3406 methods = arguments[1];
3407 }
4b9dfd5b 3408
e3cfa33b
AK
3409 if (!tagName) {
3410 Object.extend(Element.Methods, methods || {});
3411 } else {
3412 if (Object.isArray(tagName)) {
3413 for (var i = 0, tag; tag = tagName[i]; i++)
3414 addMethodsToTagName(tag, methods);
3415 } else {
3416 addMethodsToTagName(tagName, methods);
3417 }
4b9dfd5b 3418 }
4b9dfd5b 3419
e3cfa33b
AK
3420 var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype :
3421 Element.prototype;
85e836d8 3422
e3cfa33b
AK
3423 if (F.ElementExtensions) {
3424 mergeMethods(ELEMENT_PROTOTYPE, Element.Methods);
3425 mergeMethods(ELEMENT_PROTOTYPE, Element.Methods.Simulated, true);
3426 }
85e836d8 3427
e3cfa33b
AK
3428 if (F.SpecificElementExtensions) {
3429 for (var tag in Element.Methods.ByTag) {
3430 var klass = findDOMClass(tag);
3431 if (Object.isUndefined(klass)) continue;
3432 mergeMethods(klass.prototype, ByTag[tag]);
3433 }
3434 }
85e836d8 3435
e3cfa33b
AK
3436 Object.extend(Element, Element.Methods);
3437 Object.extend(Element, Element.Methods.Simulated);
3438 delete Element.ByTag;
3439 delete Element.Simulated;
85e836d8 3440
e3cfa33b 3441 Element.extend.refresh();
85e836d8 3442
e3cfa33b 3443 ELEMENT_CACHE = {};
85e836d8 3444 }
85e836d8 3445
e3cfa33b
AK
3446 Object.extend(GLOBAL.Element, {
3447 extend: extend,
3448 addMethods: addMethods
3449 });
85e836d8 3450
e3cfa33b
AK
3451 if (extend === Prototype.K) {
3452 GLOBAL.Element.extend.refresh = Prototype.emptyFunction;
3453 } else {
3454 GLOBAL.Element.extend.refresh = function() {
3455 if (Prototype.BrowserFeatures.ElementExtensions) return;
3456 Object.extend(Methods, Element.Methods);
3457 Object.extend(Methods, Element.Methods.Simulated);
85e836d8 3458
e3cfa33b
AK
3459 EXTENDED = {};
3460 };
85e836d8
AD
3461 }
3462
e3cfa33b
AK
3463 function addFormMethods() {
3464 Object.extend(Form, Form.Methods);
3465 Object.extend(Form.Element, Form.Element.Methods);
3466 Object.extend(Element.Methods.ByTag, {
3467 "FORM": Object.clone(Form.Methods),
3468 "INPUT": Object.clone(Form.Element.Methods),
3469 "SELECT": Object.clone(Form.Element.Methods),
3470 "TEXTAREA": Object.clone(Form.Element.Methods),
3471 "BUTTON": Object.clone(Form.Element.Methods)
3472 });
85e836d8
AD
3473 }
3474
e3cfa33b 3475 Element.addMethods(methods);
85e836d8 3476
e3cfa33b
AK
3477 function destroyCache_IE() {
3478 DIV = null;
3479 ELEMENT_CACHE = null;
3480 }
85e836d8 3481
e3cfa33b
AK
3482 if (window.attachEvent)
3483 window.attachEvent('onunload', destroyCache_IE);
85e836d8 3484
e3cfa33b
AK
3485})(this);
3486(function() {
85e836d8 3487
e3cfa33b
AK
3488 function toDecimal(pctString) {
3489 var match = pctString.match(/^(\d+)%?$/i);
3490 if (!match) return null;
3491 return (Number(match[1]) / 100);
3492 }
14f69488 3493
e3cfa33b
AK
3494 function getRawStyle(element, style) {
3495 element = $(element);
85e836d8 3496
e3cfa33b
AK
3497 var value = element.style[style];
3498 if (!value || value === 'auto') {
3499 var css = document.defaultView.getComputedStyle(element, null);
3500 value = css ? css[style] : null;
85e836d8
AD
3501 }
3502
e3cfa33b
AK
3503 if (style === 'opacity') return value ? parseFloat(value) : 1.0;
3504 return value === 'auto' ? null : value;
3505 }
85e836d8 3506
e3cfa33b
AK
3507 function getRawStyle_IE(element, style) {
3508 var value = element.style[style];
3509 if (!value && element.currentStyle) {
3510 value = element.currentStyle[style];
85e836d8 3511 }
85e836d8 3512 return value;
e3cfa33b 3513 }
85e836d8 3514
e3cfa33b
AK
3515 function getContentWidth(element, context) {
3516 var boxWidth = element.offsetWidth;
85e836d8 3517
e3cfa33b
AK
3518 var bl = getPixelValue(element, 'borderLeftWidth', context) || 0;
3519 var br = getPixelValue(element, 'borderRightWidth', context) || 0;
3520 var pl = getPixelValue(element, 'paddingLeft', context) || 0;
3521 var pr = getPixelValue(element, 'paddingRight', context) || 0;
85e836d8 3522
e3cfa33b 3523 return boxWidth - bl - br - pl - pr;
3fe38208 3524 }
85e836d8 3525
e3cfa33b
AK
3526 if (!Object.isUndefined(document.documentElement.currentStyle) && !Prototype.Browser.Opera) {
3527 getRawStyle = getRawStyle_IE;
3fe38208 3528 }
85e836d8 3529
e3cfa33b 3530
3fe38208
AD
3531 function getPixelValue(value, property, context) {
3532 var element = null;
3533 if (Object.isElement(value)) {
3534 element = value;
e3cfa33b 3535 value = getRawStyle(element, property);
85e836d8
AD
3536 }
3537
e3cfa33b 3538 if (value === null || Object.isUndefined(value)) {
3fe38208
AD
3539 return null;
3540 }
85e836d8 3541
3fe38208
AD
3542 if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3543 return window.parseFloat(value);
3544 }
85e836d8 3545
3fe38208 3546 var isPercentage = value.include('%'), isViewport = (context === document.viewport);
85e836d8 3547
3fe38208
AD
3548 if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
3549 var style = element.style.left, rStyle = element.runtimeStyle.left;
3550 element.runtimeStyle.left = element.currentStyle.left;
3551 element.style.left = value || 0;
3552 value = element.style.pixelLeft;
3553 element.style.left = style;
3554 element.runtimeStyle.left = rStyle;
85e836d8 3555
3fe38208 3556 return value;
85e836d8 3557 }
4b9dfd5b 3558
3fe38208
AD
3559 if (element && isPercentage) {
3560 context = context || element.parentNode;
e3cfa33b 3561 var decimal = toDecimal(value), whole = null;
4b9dfd5b 3562
3fe38208
AD
3563 var isHorizontal = property.include('left') || property.include('right') ||
3564 property.include('width');
5c656a9d 3565
e3cfa33b 3566 var isVertical = property.include('top') || property.include('bottom') ||
3fe38208 3567 property.include('height');
4b9dfd5b 3568
3fe38208
AD
3569 if (context === document.viewport) {
3570 if (isHorizontal) {
3571 whole = document.viewport.getWidth();
3572 } else if (isVertical) {
3573 whole = document.viewport.getHeight();
3574 }
3575 } else {
3576 if (isHorizontal) {
3577 whole = $(context).measure('width');
3578 } else if (isVertical) {
3579 whole = $(context).measure('height');
4b9dfd5b 3580 }
5c656a9d 3581 }
5c656a9d 3582
3fe38208
AD
3583 return (whole === null) ? 0 : whole * decimal;
3584 }
5c656a9d 3585
3fe38208
AD
3586 return 0;
3587 }
5c656a9d 3588
3fe38208 3589 function toCSSPixels(number) {
e3cfa33b 3590 if (Object.isString(number) && number.endsWith('px'))
3fe38208 3591 return number;
3fe38208
AD
3592 return number + 'px';
3593 }
5c656a9d 3594
3fe38208 3595 function isDisplayed(element) {
3fe38208
AD
3596 while (element && element.parentNode) {
3597 var display = element.getStyle('display');
3598 if (display === 'none') {
3599 return false;
4b9dfd5b 3600 }
3fe38208 3601 element = $(element.parentNode);
5c656a9d 3602 }
3fe38208
AD
3603 return true;
3604 }
5c656a9d 3605
3fe38208
AD
3606 var hasLayout = Prototype.K;
3607 if ('currentStyle' in document.documentElement) {
3608 hasLayout = function(element) {
3609 if (!element.currentStyle.hasLayout) {
3610 element.style.zoom = 1;
3611 }
3612 return element;
3613 };
3614 }
14f69488 3615
3fe38208
AD
3616 function cssNameFor(key) {
3617 if (key.include('border')) key = key + '-width';
3618 return key.camelize();
3619 }
85e836d8 3620
3fe38208
AD
3621 Element.Layout = Class.create(Hash, {
3622 initialize: function($super, element, preCompute) {
3623 $super();
3624 this.element = $(element);
85e836d8 3625
3fe38208
AD
3626 Element.Layout.PROPERTIES.each( function(property) {
3627 this._set(property, null);
3628 }, this);
85e836d8 3629
3fe38208
AD
3630 if (preCompute) {
3631 this._preComputing = true;
3632 this._begin();
3633 Element.Layout.PROPERTIES.each( this._compute, this );
3634 this._end();
3635 this._preComputing = false;
3636 }
3637 },
14f69488 3638
3fe38208
AD
3639 _set: function(property, value) {
3640 return Hash.prototype.set.call(this, property, value);
3641 },
3642
3643 set: function(property, value) {
3644 throw "Properties of Element.Layout are read-only.";
3645 },
3646
3647 get: function($super, property) {
3648 var value = $super(property);
3649 return value === null ? this._compute(property) : value;
3650 },
3651
3652 _begin: function() {
e3cfa33b 3653 if (this._isPrepared()) return;
3fe38208
AD
3654
3655 var element = this.element;
3656 if (isDisplayed(element)) {
e3cfa33b 3657 this._setPrepared(true);
3fe38208 3658 return;
4b9dfd5b 3659 }
5c656a9d 3660
e3cfa33b 3661
3fe38208
AD
3662 var originalStyles = {
3663 position: element.style.position || '',
3664 width: element.style.width || '',
3665 visibility: element.style.visibility || '',
3666 display: element.style.display || ''
3667 };
3668
3669 element.store('prototype_original_styles', originalStyles);
3670
e3cfa33b 3671 var position = getRawStyle(element, 'position'), width = element.offsetWidth;
3fe38208 3672
e3cfa33b 3673 if (width === 0 || width === null) {
3fe38208 3674 element.style.display = 'block';
e3cfa33b 3675 width = element.offsetWidth;
4b9dfd5b 3676 }
5c656a9d 3677
3fe38208
AD
3678 var context = (position === 'fixed') ? document.viewport :
3679 element.parentNode;
14f69488 3680
e3cfa33b 3681 var tempStyles = {
3fe38208
AD
3682 visibility: 'hidden',
3683 display: 'block'
e3cfa33b 3684 };
4b9dfd5b 3685
e3cfa33b 3686 if (position !== 'fixed') tempStyles.position = 'absolute';
14f69488 3687
e3cfa33b
AK
3688 element.setStyle(tempStyles);
3689
3690 var positionedWidth = element.offsetWidth, newWidth;
3fe38208 3691 if (width && (positionedWidth === width)) {
e3cfa33b 3692 newWidth = getContentWidth(element, context);
3fe38208 3693 } else if (position === 'absolute' || position === 'fixed') {
e3cfa33b 3694 newWidth = getContentWidth(element, context);
3fe38208
AD
3695 } else {
3696 var parent = element.parentNode, pLayout = $(parent).getLayout();
3697
3698 newWidth = pLayout.get('width') -
3699 this.get('margin-left') -
3700 this.get('border-left') -
3701 this.get('padding-left') -
3702 this.get('padding-right') -
3703 this.get('border-right') -
3704 this.get('margin-right');
3705 }
3706
3707 element.setStyle({ width: newWidth + 'px' });
85e836d8 3708
e3cfa33b 3709 this._setPrepared(true);
4b9dfd5b 3710 },
3fe38208
AD
3711
3712 _end: function() {
3713 var element = this.element;
3714 var originalStyles = element.retrieve('prototype_original_styles');
3715 element.store('prototype_original_styles', null);
3716 element.setStyle(originalStyles);
e3cfa33b 3717 this._setPrepared(false);
4b9dfd5b 3718 },
3fe38208
AD
3719
3720 _compute: function(property) {
3721 var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3722 if (!(property in COMPUTATIONS)) {
3723 throw "Property not found.";
3724 }
3725
3726 return this._set(property, COMPUTATIONS[property].call(this, this.element));
3727 },
3728
e3cfa33b
AK
3729 _isPrepared: function() {
3730 return this.element.retrieve('prototype_element_layout_prepared', false);
3731 },
3732
3733 _setPrepared: function(bool) {
3734 return this.element.store('prototype_element_layout_prepared', bool);
3735 },
3736
3fe38208
AD
3737 toObject: function() {
3738 var args = $A(arguments);
3739 var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3740 args.join(' ').split(' ');
3741 var obj = {};
3742 keys.each( function(key) {
3743 if (!Element.Layout.PROPERTIES.include(key)) return;
3744 var value = this.get(key);
3745 if (value != null) obj[key] = value;
3746 }, this);
3747 return obj;
4b9dfd5b 3748 },
3fe38208
AD
3749
3750 toHash: function() {
3751 var obj = this.toObject.apply(this, arguments);
3752 return new Hash(obj);
4b9dfd5b 3753 },
3fe38208
AD
3754
3755 toCSS: function() {
3756 var args = $A(arguments);
3757 var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3758 args.join(' ').split(' ');
3759 var css = {};
3760
3761 keys.each( function(key) {
3762 if (!Element.Layout.PROPERTIES.include(key)) return;
3763 if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3764
3765 var value = this.get(key);
3766 if (value != null) css[cssNameFor(key)] = value + 'px';
3767 }, this);
3768 return css;
4b9dfd5b 3769 },
3fe38208
AD
3770
3771 inspect: function() {
3772 return "#<Element.Layout>";
3773 }
3774 });
3775
3776 Object.extend(Element.Layout, {
3777 PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3778
3779 COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3780
3781 COMPUTATIONS: {
3782 'height': function(element) {
3783 if (!this._preComputing) this._begin();
3784
3785 var bHeight = this.get('border-box-height');
3786 if (bHeight <= 0) {
3787 if (!this._preComputing) this._end();
3788 return 0;
4b9dfd5b 3789 }
3fe38208
AD
3790
3791 var bTop = this.get('border-top'),
3792 bBottom = this.get('border-bottom');
3793
3794 var pTop = this.get('padding-top'),
3795 pBottom = this.get('padding-bottom');
3796
3797 if (!this._preComputing) this._end();
3798
3799 return bHeight - bTop - bBottom - pTop - pBottom;
4b9dfd5b 3800 },
3fe38208
AD
3801
3802 'width': function(element) {
3803 if (!this._preComputing) this._begin();
3804
3805 var bWidth = this.get('border-box-width');
3806 if (bWidth <= 0) {
3807 if (!this._preComputing) this._end();
3808 return 0;
3809 }
3810
3811 var bLeft = this.get('border-left'),
3812 bRight = this.get('border-right');
3813
3814 var pLeft = this.get('padding-left'),
3815 pRight = this.get('padding-right');
3816
3817 if (!this._preComputing) this._end();
3fe38208 3818 return bWidth - bLeft - bRight - pLeft - pRight;
4b9dfd5b 3819 },
3fe38208
AD
3820
3821 'padding-box-height': function(element) {
3822 var height = this.get('height'),
3823 pTop = this.get('padding-top'),
3824 pBottom = this.get('padding-bottom');
3825
3826 return height + pTop + pBottom;
4b9dfd5b 3827 },
3fe38208
AD
3828
3829 'padding-box-width': function(element) {
3830 var width = this.get('width'),
3831 pLeft = this.get('padding-left'),
3832 pRight = this.get('padding-right');
3833
3834 return width + pLeft + pRight;
4b9dfd5b 3835 },
3fe38208
AD
3836
3837 'border-box-height': function(element) {
3838 if (!this._preComputing) this._begin();
3839 var height = element.offsetHeight;
3840 if (!this._preComputing) this._end();
3841 return height;
4b9dfd5b 3842 },
3fe38208
AD
3843
3844 'border-box-width': function(element) {
3845 if (!this._preComputing) this._begin();
3846 var width = element.offsetWidth;
3847 if (!this._preComputing) this._end();
3848 return width;
4b9dfd5b 3849 },
3fe38208
AD
3850
3851 'margin-box-height': function(element) {
3852 var bHeight = this.get('border-box-height'),
3853 mTop = this.get('margin-top'),
3854 mBottom = this.get('margin-bottom');
3855
3856 if (bHeight <= 0) return 0;
3857
3858 return bHeight + mTop + mBottom;
4b9dfd5b 3859 },
3fe38208
AD
3860
3861 'margin-box-width': function(element) {
3862 var bWidth = this.get('border-box-width'),
3863 mLeft = this.get('margin-left'),
3864 mRight = this.get('margin-right');
3865
3866 if (bWidth <= 0) return 0;
3867
3868 return bWidth + mLeft + mRight;
4b9dfd5b 3869 },
3fe38208
AD
3870
3871 'top': function(element) {
3872 var offset = element.positionedOffset();
3873 return offset.top;
3874 },
3875
3876 'bottom': function(element) {
3877 var offset = element.positionedOffset(),
3878 parent = element.getOffsetParent(),
3879 pHeight = parent.measure('height');
3880
3881 var mHeight = this.get('border-box-height');
3882
3883 return pHeight - mHeight - offset.top;
3884 },
3885
3886 'left': function(element) {
3887 var offset = element.positionedOffset();
3888 return offset.left;
3889 },
3890
3891 'right': function(element) {
3892 var offset = element.positionedOffset(),
3893 parent = element.getOffsetParent(),
3894 pWidth = parent.measure('width');
3895
3896 var mWidth = this.get('border-box-width');
3897
3898 return pWidth - mWidth - offset.left;
3899 },
3900
3901 'padding-top': function(element) {
3902 return getPixelValue(element, 'paddingTop');
3903 },
3904
3905 'padding-bottom': function(element) {
3906 return getPixelValue(element, 'paddingBottom');
3907 },
3908
3909 'padding-left': function(element) {
3910 return getPixelValue(element, 'paddingLeft');
3911 },
3912
3913 'padding-right': function(element) {
3914 return getPixelValue(element, 'paddingRight');
3915 },
3916
3917 'border-top': function(element) {
3918 return getPixelValue(element, 'borderTopWidth');
3919 },
3920
3921 'border-bottom': function(element) {
3922 return getPixelValue(element, 'borderBottomWidth');
3923 },
3924
3925 'border-left': function(element) {
3926 return getPixelValue(element, 'borderLeftWidth');
3927 },
3928
3929 'border-right': function(element) {
3930 return getPixelValue(element, 'borderRightWidth');
3931 },
3932
3933 'margin-top': function(element) {
3934 return getPixelValue(element, 'marginTop');
3935 },
3936
3937 'margin-bottom': function(element) {
3938 return getPixelValue(element, 'marginBottom');
3939 },
3940
3941 'margin-left': function(element) {
3942 return getPixelValue(element, 'marginLeft');
3943 },
3944
3945 'margin-right': function(element) {
3946 return getPixelValue(element, 'marginRight');
4b9dfd5b
AD
3947 }
3948 }
3fe38208
AD
3949 });
3950
3951 if ('getBoundingClientRect' in document.documentElement) {
3952 Object.extend(Element.Layout.COMPUTATIONS, {
3953 'right': function(element) {
3954 var parent = hasLayout(element.getOffsetParent());
3955 var rect = element.getBoundingClientRect(),
3956 pRect = parent.getBoundingClientRect();
3957
3958 return (pRect.right - rect.right).round();
3959 },
3960
3961 'bottom': function(element) {
3962 var parent = hasLayout(element.getOffsetParent());
3963 var rect = element.getBoundingClientRect(),
3964 pRect = parent.getBoundingClientRect();
3965
3966 return (pRect.bottom - rect.bottom).round();
3967 }
3968 });
3969 }
3970
3971 Element.Offset = Class.create({
3972 initialize: function(left, top) {
3973 this.left = left.round();
3974 this.top = top.round();
3975
3976 this[0] = this.left;
3977 this[1] = this.top;
3978 },
3979
3980 relativeTo: function(offset) {
3981 return new Element.Offset(
3982 this.left - offset.left,
3983 this.top - offset.top
3984 );
3985 },
3986
3987 inspect: function() {
3988 return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
3989 },
3990
3991 toString: function() {
3992 return "[#{left}, #{top}]".interpolate(this);
3993 },
3994
3995 toArray: function() {
3996 return [this.left, this.top];
3997 }
3998 });
3999
4000 function getLayout(element, preCompute) {
4001 return new Element.Layout(element, preCompute);
4002 }
4003
4004 function measure(element, property) {
4005 return $(element).getLayout().get(property);
4006 }
4007
e3cfa33b
AK
4008 function getHeight(element) {
4009 return Element.getDimensions(element).height;
4010 }
4011
4012 function getWidth(element) {
4013 return Element.getDimensions(element).width;
4014 }
4015
3fe38208
AD
4016 function getDimensions(element) {
4017 element = $(element);
4018 var display = Element.getStyle(element, 'display');
4019
4020 if (display && display !== 'none') {
4021 return { width: element.offsetWidth, height: element.offsetHeight };
4022 }
4023
4024 var style = element.style;
4025 var originalStyles = {
4026 visibility: style.visibility,
4027 position: style.position,
4028 display: style.display
4029 };
4030
4031 var newStyles = {
4032 visibility: 'hidden',
4033 display: 'block'
4034 };
4035
4036 if (originalStyles.position !== 'fixed')
4037 newStyles.position = 'absolute';
4038
4039 Element.setStyle(element, newStyles);
4040
4041 var dimensions = {
4042 width: element.offsetWidth,
4043 height: element.offsetHeight
4044 };
4045
4046 Element.setStyle(element, originalStyles);
4047
4048 return dimensions;
4049 }
4050
4051 function getOffsetParent(element) {
4052 element = $(element);
4053
e3cfa33b
AK
4054 function selfOrBody(element) {
4055 return isHtml(element) ? $(document.body) : $(element);
4056 }
4057
3fe38208
AD
4058 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
4059 return $(document.body);
4060
4061 var isInline = (Element.getStyle(element, 'display') === 'inline');
e3cfa33b 4062 if (!isInline && element.offsetParent) return selfOrBody(element.offsetParent);
3fe38208
AD
4063
4064 while ((element = element.parentNode) && element !== document.body) {
4065 if (Element.getStyle(element, 'position') !== 'static') {
e3cfa33b 4066 return selfOrBody(element);
3fe38208
AD
4067 }
4068 }
4069
4070 return $(document.body);
4071 }
4072
4073
4074 function cumulativeOffset(element) {
4075 element = $(element);
4076 var valueT = 0, valueL = 0;
4077 if (element.parentNode) {
4078 do {
4079 valueT += element.offsetTop || 0;
4080 valueL += element.offsetLeft || 0;
4081 element = element.offsetParent;
4082 } while (element);
4083 }
4084 return new Element.Offset(valueL, valueT);
4085 }
4086
4087 function positionedOffset(element) {
4088 element = $(element);
4089
4090 var layout = element.getLayout();
4091
4092 var valueT = 0, valueL = 0;
4093 do {
4094 valueT += element.offsetTop || 0;
4095 valueL += element.offsetLeft || 0;
4096 element = element.offsetParent;
4097 if (element) {
4098 if (isBody(element)) break;
4099 var p = Element.getStyle(element, 'position');
4100 if (p !== 'static') break;
4101 }
4102 } while (element);
4103
e3cfa33b
AK
4104 valueL -= layout.get('margin-left');
4105 valueT -= layout.get('margin-top');
3fe38208
AD
4106
4107 return new Element.Offset(valueL, valueT);
4108 }
4109
4110 function cumulativeScrollOffset(element) {
4111 var valueT = 0, valueL = 0;
4112 do {
e3cfa33b
AK
4113 if (element === document.body) {
4114 var bodyScrollNode = document.documentElement || document.body.parentNode || document.body;
4115 valueT += !Object.isUndefined(window.pageYOffset) ? window.pageYOffset : bodyScrollNode.scrollTop || 0;
4116 valueL += !Object.isUndefined(window.pageXOffset) ? window.pageXOffset : bodyScrollNode.scrollLeft || 0;
4117 break;
4118 } else {
4119 valueT += element.scrollTop || 0;
4120 valueL += element.scrollLeft || 0;
4121 element = element.parentNode;
4122 }
3fe38208
AD
4123 } while (element);
4124 return new Element.Offset(valueL, valueT);
4125 }
4126
4127 function viewportOffset(forElement) {
3fe38208
AD
4128 var valueT = 0, valueL = 0, docBody = document.body;
4129
e3cfa33b 4130 forElement = $(forElement);
3fe38208
AD
4131 var element = forElement;
4132 do {
4133 valueT += element.offsetTop || 0;
4134 valueL += element.offsetLeft || 0;
4135 if (element.offsetParent == docBody &&
4136 Element.getStyle(element, 'position') == 'absolute') break;
4137 } while (element = element.offsetParent);
4138
4139 element = forElement;
4140 do {
4141 if (element != docBody) {
4142 valueT -= element.scrollTop || 0;
4143 valueL -= element.scrollLeft || 0;
4144 }
4145 } while (element = element.parentNode);
4146 return new Element.Offset(valueL, valueT);
4147 }
4148
4149 function absolutize(element) {
4150 element = $(element);
4151
4152 if (Element.getStyle(element, 'position') === 'absolute') {
4153 return element;
4154 }
4155
4156 var offsetParent = getOffsetParent(element);
4157 var eOffset = element.viewportOffset(),
4158 pOffset = offsetParent.viewportOffset();
4159
4160 var offset = eOffset.relativeTo(pOffset);
4161 var layout = element.getLayout();
4162
4163 element.store('prototype_absolutize_original_styles', {
e3cfa33b
AK
4164 position: element.getStyle('position'),
4165 left: element.getStyle('left'),
4166 top: element.getStyle('top'),
4167 width: element.getStyle('width'),
4168 height: element.getStyle('height')
3fe38208
AD
4169 });
4170
4171 element.setStyle({
4172 position: 'absolute',
4173 top: offset.top + 'px',
4174 left: offset.left + 'px',
4175 width: layout.get('width') + 'px',
4176 height: layout.get('height') + 'px'
4177 });
4178
4179 return element;
4180 }
4181
4182 function relativize(element) {
4183 element = $(element);
4184 if (Element.getStyle(element, 'position') === 'relative') {
4185 return element;
4186 }
4187
e3cfa33b
AK
4188 var originalStyles =
4189 element.retrieve('prototype_absolutize_original_styles');
4190
4191 if (originalStyles) element.setStyle(originalStyles);
4192 return element;
4193 }
4194
4195
4196 function scrollTo(element) {
4197 element = $(element);
4198 var pos = Element.cumulativeOffset(element);
4199 window.scrollTo(pos.left, pos.top);
4200 return element;
4201 }
4202
4203
4204 function makePositioned(element) {
4205 element = $(element);
4206 var position = Element.getStyle(element, 'position'), styles = {};
4207 if (position === 'static' || !position) {
4208 styles.position = 'relative';
4209 if (Prototype.Browser.Opera) {
4210 styles.top = 0;
4211 styles.left = 0;
4212 }
4213 Element.setStyle(element, styles);
4214 Element.store(element, 'prototype_made_positioned', true);
4215 }
4216 return element;
4217 }
4218
4219 function undoPositioned(element) {
4220 element = $(element);
4221 var storage = Element.getStorage(element),
4222 madePositioned = storage.get('prototype_made_positioned');
4223
4224 if (madePositioned) {
4225 storage.unset('prototype_made_positioned');
4226 Element.setStyle(element, {
4227 position: '',
4228 top: '',
4229 bottom: '',
4230 left: '',
4231 right: ''
4232 });
4233 }
4234 return element;
4235 }
4236
4237 function makeClipping(element) {
4238 element = $(element);
4239
4240 var storage = Element.getStorage(element),
4241 madeClipping = storage.get('prototype_made_clipping');
4242
4243 if (Object.isUndefined(madeClipping)) {
4244 var overflow = Element.getStyle(element, 'overflow');
4245 storage.set('prototype_made_clipping', overflow);
4246 if (overflow !== 'hidden')
4247 element.style.overflow = 'hidden';
4248 }
4249
4250 return element;
4251 }
4252
4253 function undoClipping(element) {
4254 element = $(element);
4255 var storage = Element.getStorage(element),
4256 overflow = storage.get('prototype_made_clipping');
4257
4258 if (!Object.isUndefined(overflow)) {
4259 storage.unset('prototype_made_clipping');
4260 element.style.overflow = overflow || '';
4261 }
4262
4263 return element;
4264 }
4265
4266 function clonePosition(element, source, options) {
4267 options = Object.extend({
4268 setLeft: true,
4269 setTop: true,
4270 setWidth: true,
4271 setHeight: true,
4272 offsetTop: 0,
4273 offsetLeft: 0
4274 }, options || {});
4275
4276 var docEl = document.documentElement;
4277
4278 source = $(source);
4279 element = $(element);
4280 var p, delta, layout, styles = {};
4281
4282 if (options.setLeft || options.setTop) {
4283 p = Element.viewportOffset(source);
4284 delta = [0, 0];
4285 if (Element.getStyle(element, 'position') === 'absolute') {
4286 var parent = Element.getOffsetParent(element);
4287 if (parent !== document.body) delta = Element.viewportOffset(parent);
4288 }
4289 }
4290
4291 function pageScrollXY() {
4292 var x = 0, y = 0;
4293 if (Object.isNumber(window.pageXOffset)) {
4294 x = window.pageXOffset;
4295 y = window.pageYOffset;
4296 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
4297 x = document.body.scrollLeft;
4298 y = document.body.scrollTop;
4299 } else if (docEl && (docEl.scrollLeft || docEl.scrollTop)) {
4300 x = docEl.scrollLeft;
4301 y = docEl.scrollTop;
4302 }
4303 return { x: x, y: y };
4304 }
4305
4306 var pageXY = pageScrollXY();
4307
4308
4309 if (options.setWidth || options.setHeight) {
4310 layout = Element.getLayout(source);
4311 }
4312
4313 if (options.setLeft)
4314 styles.left = (p[0] + pageXY.x - delta[0] + options.offsetLeft) + 'px';
4315 if (options.setTop)
4316 styles.top = (p[1] + pageXY.y - delta[1] + options.offsetTop) + 'px';
3fe38208 4317
e3cfa33b
AK
4318 var currentLayout = element.getLayout();
4319
4320 if (options.setWidth) {
4321 styles.width = layout.get('width') + 'px';
4322 }
4323 if (options.setHeight) {
4324 styles.height = layout.get('height') + 'px';
4325 }
4326
4327 return Element.setStyle(element, styles);
3fe38208
AD
4328 }
4329
e3cfa33b 4330
3fe38208
AD
4331 if (Prototype.Browser.IE) {
4332 getOffsetParent = getOffsetParent.wrap(
4333 function(proceed, element) {
4334 element = $(element);
4335
4336 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
4337 return $(document.body);
4338
4339 var position = element.getStyle('position');
4340 if (position !== 'static') return proceed(element);
4341
4342 element.setStyle({ position: 'relative' });
4343 var value = proceed(element);
4344 element.setStyle({ position: position });
4345 return value;
4346 }
4347 );
4348
4349 positionedOffset = positionedOffset.wrap(function(proceed, element) {
4350 element = $(element);
4351 if (!element.parentNode) return new Element.Offset(0, 0);
4352 var position = element.getStyle('position');
4353 if (position !== 'static') return proceed(element);
4354
4355 var offsetParent = element.getOffsetParent();
4356 if (offsetParent && offsetParent.getStyle('position') === 'fixed')
4357 hasLayout(offsetParent);
4358
4359 element.setStyle({ position: 'relative' });
4360 var value = proceed(element);
4361 element.setStyle({ position: position });
4362 return value;
4363 });
4364 } else if (Prototype.Browser.Webkit) {
4365 cumulativeOffset = function(element) {
4366 element = $(element);
4367 var valueT = 0, valueL = 0;
4368 do {
4369 valueT += element.offsetTop || 0;
4370 valueL += element.offsetLeft || 0;
e3cfa33b 4371 if (element.offsetParent == document.body) {
3fe38208 4372 if (Element.getStyle(element, 'position') == 'absolute') break;
e3cfa33b 4373 }
3fe38208
AD
4374
4375 element = element.offsetParent;
4376 } while (element);
4377
4378 return new Element.Offset(valueL, valueT);
4379 };
4380 }
4381
4382
4383 Element.addMethods({
4384 getLayout: getLayout,
4385 measure: measure,
e3cfa33b
AK
4386 getWidth: getWidth,
4387 getHeight: getHeight,
3fe38208
AD
4388 getDimensions: getDimensions,
4389 getOffsetParent: getOffsetParent,
4390 cumulativeOffset: cumulativeOffset,
4391 positionedOffset: positionedOffset,
4392 cumulativeScrollOffset: cumulativeScrollOffset,
4393 viewportOffset: viewportOffset,
4394 absolutize: absolutize,
e3cfa33b
AK
4395 relativize: relativize,
4396 scrollTo: scrollTo,
4397 makePositioned: makePositioned,
4398 undoPositioned: undoPositioned,
4399 makeClipping: makeClipping,
4400 undoClipping: undoClipping,
4401 clonePosition: clonePosition
3fe38208
AD
4402 });
4403
4404 function isBody(element) {
4405 return element.nodeName.toUpperCase() === 'BODY';
4406 }
4407
4408 function isHtml(element) {
4409 return element.nodeName.toUpperCase() === 'HTML';
4410 }
4411
4412 function isDocument(element) {
4413 return element.nodeType === Node.DOCUMENT_NODE;
4414 }
4415
4416 function isDetached(element) {
4417 return element !== document.body &&
4418 !Element.descendantOf(element, document.body);
4419 }
4420
4421 if ('getBoundingClientRect' in document.documentElement) {
4422 Element.addMethods({
4423 viewportOffset: function(element) {
4424 element = $(element);
4425 if (isDetached(element)) return new Element.Offset(0, 0);
4426
4427 var rect = element.getBoundingClientRect(),
4428 docEl = document.documentElement;
4429 return new Element.Offset(rect.left - docEl.clientLeft,
4430 rect.top - docEl.clientTop);
4431 }
4432 });
4433 }
e3cfa33b
AK
4434
4435
4436})();
4437
4438(function() {
4439
4440 var IS_OLD_OPERA = Prototype.Browser.Opera &&
4441 (window.parseFloat(window.opera.version()) < 9.5);
4442 var ROOT = null;
4443 function getRootElement() {
4444 if (ROOT) return ROOT;
4445 ROOT = IS_OLD_OPERA ? document.body : document.documentElement;
4446 return ROOT;
4447 }
4448
4449 function getDimensions() {
4450 return { width: this.getWidth(), height: this.getHeight() };
4451 }
4452
4453 function getWidth() {
4454 return getRootElement().clientWidth;
4455 }
4456
4457 function getHeight() {
4458 return getRootElement().clientHeight;
4459 }
4460
4461 function getScrollOffsets() {
4462 var x = window.pageXOffset || document.documentElement.scrollLeft ||
4463 document.body.scrollLeft;
4464 var y = window.pageYOffset || document.documentElement.scrollTop ||
4465 document.body.scrollTop;
4466
4467 return new Element.Offset(x, y);
4468 }
4469
4470 document.viewport = {
4471 getDimensions: getDimensions,
4472 getWidth: getWidth,
4473 getHeight: getHeight,
4474 getScrollOffsets: getScrollOffsets
4475 };
4476
3fe38208
AD
4477})();
4478window.$$ = function() {
4479 var expression = $A(arguments).join(', ');
4480 return Prototype.Selector.select(expression, document);
4481};
4482
4483Prototype.Selector = (function() {
4484
4485 function select() {
4486 throw new Error('Method "Prototype.Selector.select" must be defined.');
4487 }
4488
4489 function match() {
4490 throw new Error('Method "Prototype.Selector.match" must be defined.');
4491 }
4492
4493 function find(elements, expression, index) {
4494 index = index || 0;
4495 var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
4496
4497 for (i = 0; i < length; i++) {
4498 if (match(elements[i], expression) && index == matchIndex++) {
4499 return Element.extend(elements[i]);
4500 }
4501 }
4502 }
4503
4504 function extendElements(elements) {
4505 for (var i = 0, length = elements.length; i < length; i++) {
4506 Element.extend(elements[i]);
4507 }
4508 return elements;
4509 }
4510
4511
4512 var K = Prototype.K;
4513
4514 return {
4515 select: select,
4516 match: match,
4517 find: find,
4518 extendElements: (Element.extend === K) ? K : extendElements,
4519 extendElement: Element.extend
4520 };
4521})();
4522Prototype._original_property = window.Sizzle;
e3cfa33b
AK
4523
4524;(function () {
4525 function fakeDefine(fn) {
4526 Prototype._actual_sizzle = fn();
4527 }
4528 fakeDefine.amd = true;
4529
4530 if (typeof define !== 'undefined' && define.amd) {
4531 Prototype._original_define = define;
4532 Prototype._actual_sizzle = null;
4533 window.define = fakeDefine;
4534 }
4535})();
4536
3fe38208 4537/*!
e3cfa33b
AK
4538 * Sizzle CSS Selector Engine v1.10.18
4539 * http://sizzlejs.com/
4540 *
4541 * Copyright 2013 jQuery Foundation, Inc. and other contributors
4542 * Released under the MIT license
4543 * http://jquery.org/license
4544 *
4545 * Date: 2014-02-05
3fe38208 4546 */
e3cfa33b
AK
4547(function( window ) {
4548
4549var i,
4550 support,
4551 Expr,
4552 getText,
4553 isXML,
4554 compile,
4555 select,
4556 outermostContext,
4557 sortInput,
4558 hasDuplicate,
4559
4560 setDocument,
4561 document,
4562 docElem,
4563 documentIsHTML,
4564 rbuggyQSA,
4565 rbuggyMatches,
4566 matches,
4567 contains,
4568
4569 expando = "sizzle" + -(new Date()),
4570 preferredDoc = window.document,
4571 dirruns = 0,
3fe38208 4572 done = 0,
e3cfa33b
AK
4573 classCache = createCache(),
4574 tokenCache = createCache(),
4575 compilerCache = createCache(),
4576 sortOrder = function( a, b ) {
4577 if ( a === b ) {
4578 hasDuplicate = true;
4579 }
4580 return 0;
4581 },
3fe38208 4582
e3cfa33b
AK
4583 strundefined = typeof undefined,
4584 MAX_NEGATIVE = 1 << 31,
4585
4586 hasOwn = ({}).hasOwnProperty,
4587 arr = [],
4588 pop = arr.pop,
4589 push_native = arr.push,
4590 push = arr.push,
4591 slice = arr.slice,
4592 indexOf = arr.indexOf || function( elem ) {
4593 var i = 0,
4594 len = this.length;
4595 for ( ; i < len; i++ ) {
4596 if ( this[i] === elem ) {
4597 return i;
4598 }
4599 }
4600 return -1;
4601 },
3fe38208 4602
e3cfa33b 4603 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
3fe38208 4604
e3cfa33b
AK
4605
4606 whitespace = "[\\x20\\t\\r\\n\\f]",
4607 characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
4608
4609 identifier = characterEncoding.replace( "w", "w#" ),
4610
4611 attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
4612 "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
4613
4614 pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
4615
4616 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
4617
4618 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
4619 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
4620
4621 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
4622
4623 rpseudo = new RegExp( pseudos ),
4624 ridentifier = new RegExp( "^" + identifier + "$" ),
4625
4626 matchExpr = {
4627 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
4628 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
4629 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
4630 "ATTR": new RegExp( "^" + attributes ),
4631 "PSEUDO": new RegExp( "^" + pseudos ),
4632 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
4633 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
4634 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
4635 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
4636 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
4637 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
4638 },
4639
4640 rinputs = /^(?:input|select|textarea|button)$/i,
4641 rheader = /^h\d$/i,
4642
4643 rnative = /^[^{]+\{\s*\[native \w/,
4644
4645 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
4646
4647 rsibling = /[+~]/,
4648 rescape = /'|\\/g,
4649
4650 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
4651 funescape = function( _, escaped, escapedWhitespace ) {
4652 var high = "0x" + escaped - 0x10000;
4653 return high !== high || escapedWhitespace ?
4654 escaped :
4655 high < 0 ?
4656 String.fromCharCode( high + 0x10000 ) :
4657 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
4658 };
4659
4660try {
4661 push.apply(
4662 (arr = slice.call( preferredDoc.childNodes )),
4663 preferredDoc.childNodes
4664 );
4665 arr[ preferredDoc.childNodes.length ].nodeType;
4666} catch ( e ) {
4667 push = { apply: arr.length ?
4668
4669 function( target, els ) {
4670 push_native.apply( target, slice.call(els) );
4671 } :
4672
4673 function( target, els ) {
4674 var j = target.length,
4675 i = 0;
4676 while ( (target[j++] = els[i++]) ) {}
4677 target.length = j - 1;
4678 }
4679 };
4680}
4681
4682function Sizzle( selector, context, results, seed ) {
4683 var match, elem, m, nodeType,
4684 i, groups, old, nid, newContext, newSelector;
4685
4686 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
4687 setDocument( context );
3fe38208
AD
4688 }
4689
e3cfa33b
AK
4690 context = context || document;
4691 results = results || [];
4692
3fe38208
AD
4693 if ( !selector || typeof selector !== "string" ) {
4694 return results;
4695 }
4696
e3cfa33b
AK
4697 if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
4698 return [];
4699 }
4700
4701 if ( documentIsHTML && !seed ) {
3fe38208 4702
e3cfa33b
AK
4703 if ( (match = rquickExpr.exec( selector )) ) {
4704 if ( (m = match[1]) ) {
4705 if ( nodeType === 9 ) {
4706 elem = context.getElementById( m );
4707 if ( elem && elem.parentNode ) {
4708 if ( elem.id === m ) {
4709 results.push( elem );
4710 return results;
4711 }
4712 } else {
4713 return results;
4714 }
4715 } else {
4716 if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
4717 contains( context, elem ) && elem.id === m ) {
4718 results.push( elem );
4719 return results;
4720 }
4721 }
3fe38208 4722
e3cfa33b
AK
4723 } else if ( match[2] ) {
4724 push.apply( results, context.getElementsByTagName( selector ) );
4725 return results;
3fe38208 4726
e3cfa33b
AK
4727 } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
4728 push.apply( results, context.getElementsByClassName( m ) );
4729 return results;
4730 }
3fe38208 4731 }
3fe38208 4732
e3cfa33b
AK
4733 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
4734 nid = old = expando;
4735 newContext = context;
4736 newSelector = nodeType === 9 && selector;
3fe38208 4737
e3cfa33b
AK
4738 if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4739 groups = tokenize( selector );
3fe38208 4740
e3cfa33b
AK
4741 if ( (old = context.getAttribute("id")) ) {
4742 nid = old.replace( rescape, "\\$&" );
4743 } else {
4744 context.setAttribute( "id", nid );
4745 }
4746 nid = "[id='" + nid + "'] ";
4747
4748 i = groups.length;
4749 while ( i-- ) {
4750 groups[i] = nid + toSelector( groups[i] );
4751 }
4752 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
4753 newSelector = groups.join(",");
4754 }
3fe38208 4755
e3cfa33b
AK
4756 if ( newSelector ) {
4757 try {
4758 push.apply( results,
4759 newContext.querySelectorAll( newSelector )
4760 );
4761 return results;
4762 } catch(qsaError) {
4763 } finally {
4764 if ( !old ) {
4765 context.removeAttribute("id");
4766 }
4767 }
3fe38208
AD
4768 }
4769 }
e3cfa33b
AK
4770 }
4771
4772 return select( selector.replace( rtrim, "$1" ), context, results, seed );
4773}
4774
4775/**
4776 * Create key-value caches of limited size
4777 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
4778 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
4779 * deleting the oldest entry
4780 */
4781function createCache() {
4782 var keys = [];
4783
4784 function cache( key, value ) {
4785 if ( keys.push( key + " " ) > Expr.cacheLength ) {
4786 delete cache[ keys.shift() ];
3fe38208 4787 }
e3cfa33b
AK
4788 return (cache[ key + " " ] = value);
4789 }
4790 return cache;
4791}
3fe38208 4792
e3cfa33b
AK
4793/**
4794 * Mark a function for special use by Sizzle
4795 * @param {Function} fn The function to mark
4796 */
4797function markFunction( fn ) {
4798 fn[ expando ] = true;
4799 return fn;
4800}
3fe38208 4801
e3cfa33b
AK
4802/**
4803 * Support testing using an element
4804 * @param {Function} fn Passed the created div and expects a boolean result
4805 */
4806function assert( fn ) {
4807 var div = document.createElement("div");
4808
4809 try {
4810 return !!fn( div );
4811 } catch (e) {
4812 return false;
4813 } finally {
4814 if ( div.parentNode ) {
4815 div.parentNode.removeChild( div );
4816 }
4817 div = null;
4818 }
4819}
4820
4821/**
4822 * Adds the same handler for all of the specified attrs
4823 * @param {String} attrs Pipe-separated list of attributes
4824 * @param {Function} handler The method that will be applied
4825 */
4826function addHandle( attrs, handler ) {
4827 var arr = attrs.split("|"),
4828 i = attrs.length;
4829
4830 while ( i-- ) {
4831 Expr.attrHandle[ arr[i] ] = handler;
4832 }
4833}
4834
4835/**
4836 * Checks document order of two siblings
4837 * @param {Element} a
4838 * @param {Element} b
4839 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
4840 */
4841function siblingCheck( a, b ) {
4842 var cur = b && a,
4843 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
4844 ( ~b.sourceIndex || MAX_NEGATIVE ) -
4845 ( ~a.sourceIndex || MAX_NEGATIVE );
4846
4847 if ( diff ) {
4848 return diff;
4849 }
4850
4851 if ( cur ) {
4852 while ( (cur = cur.nextSibling) ) {
4853 if ( cur === b ) {
4854 return -1;
3fe38208 4855 }
e3cfa33b
AK
4856 }
4857 }
3fe38208 4858
e3cfa33b
AK
4859 return a ? 1 : -1;
4860}
3fe38208 4861
e3cfa33b
AK
4862/**
4863 * Returns a function to use in pseudos for input types
4864 * @param {String} type
4865 */
4866function createInputPseudo( type ) {
4867 return function( elem ) {
4868 var name = elem.nodeName.toLowerCase();
4869 return name === "input" && elem.type === type;
4870 };
4871}
4872
4873/**
4874 * Returns a function to use in pseudos for buttons
4875 * @param {String} type
4876 */
4877function createButtonPseudo( type ) {
4878 return function( elem ) {
4879 var name = elem.nodeName.toLowerCase();
4880 return (name === "input" || name === "button") && elem.type === type;
4881 };
4882}
4883
4884/**
4885 * Returns a function to use in pseudos for positionals
4886 * @param {Function} fn
4887 */
4888function createPositionalPseudo( fn ) {
4889 return markFunction(function( argument ) {
4890 argument = +argument;
4891 return markFunction(function( seed, matches ) {
4892 var j,
4893 matchIndexes = fn( [], seed.length, argument ),
4894 i = matchIndexes.length;
4895
4896 while ( i-- ) {
4897 if ( seed[ (j = matchIndexes[i]) ] ) {
4898 seed[j] = !(matches[j] = seed[j]);
3fe38208 4899 }
e3cfa33b
AK
4900 }
4901 });
4902 });
4903}
4904
4905/**
4906 * Checks a node for validity as a Sizzle context
4907 * @param {Element|Object=} context
4908 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
4909 */
4910function testContext( context ) {
4911 return context && typeof context.getElementsByTagName !== strundefined && context;
4912}
4913
4914support = Sizzle.support = {};
4915
4916/**
4917 * Detects XML nodes
4918 * @param {Element|Object} elem An element or a document
4919 * @returns {Boolean} True iff elem is a non-HTML XML node
4920 */
4921isXML = Sizzle.isXML = function( elem ) {
4922 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4923 return documentElement ? documentElement.nodeName !== "HTML" : false;
4924};
4925
4926/**
4927 * Sets document-related variables once based on the current document
4928 * @param {Element|Object} [doc] An element or document object to use to set the document
4929 * @returns {Object} Returns the current document
4930 */
4931setDocument = Sizzle.setDocument = function( node ) {
4932 var hasCompare,
4933 doc = node ? node.ownerDocument || node : preferredDoc,
4934 parent = doc.defaultView;
4935
4936 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
4937 return document;
4938 }
4939
4940 document = doc;
4941 docElem = doc.documentElement;
4942
4943 documentIsHTML = !isXML( doc );
4944
4945 if ( parent && parent !== parent.top ) {
4946 if ( parent.addEventListener ) {
4947 parent.addEventListener( "unload", function() {
4948 setDocument();
4949 }, false );
4950 } else if ( parent.attachEvent ) {
4951 parent.attachEvent( "onunload", function() {
4952 setDocument();
4953 });
4954 }
4955 }
4956
4957 /* Attributes
4958 ---------------------------------------------------------------------- */
4959
4960 support.attributes = assert(function( div ) {
4961 div.className = "i";
4962 return !div.getAttribute("className");
4963 });
4964
4965 /* getElement(s)By*
4966 ---------------------------------------------------------------------- */
4967
4968 support.getElementsByTagName = assert(function( div ) {
4969 div.appendChild( doc.createComment("") );
4970 return !div.getElementsByTagName("*").length;
4971 });
4972
4973 support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
4974 div.innerHTML = "<div class='a'></div><div class='a i'></div>";
4975
4976 div.firstChild.className = "i";
4977 return div.getElementsByClassName("i").length === 2;
4978 });
4979
4980 support.getById = assert(function( div ) {
4981 docElem.appendChild( div ).id = expando;
4982 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
4983 });
3fe38208 4984
e3cfa33b
AK
4985 if ( support.getById ) {
4986 Expr.find["ID"] = function( id, context ) {
4987 if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
4988 var m = context.getElementById( id );
4989 return m && m.parentNode ? [m] : [];
4990 }
4991 };
4992 Expr.filter["ID"] = function( id ) {
4993 var attrId = id.replace( runescape, funescape );
4994 return function( elem ) {
4995 return elem.getAttribute("id") === attrId;
4996 };
4997 };
4998 } else {
4999 delete Expr.find["ID"];
5000
5001 Expr.filter["ID"] = function( id ) {
5002 var attrId = id.replace( runescape, funescape );
5003 return function( elem ) {
5004 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
5005 return node && node.value === attrId;
5006 };
5007 };
5008 }
5009
5010 Expr.find["TAG"] = support.getElementsByTagName ?
5011 function( tag, context ) {
5012 if ( typeof context.getElementsByTagName !== strundefined ) {
5013 return context.getElementsByTagName( tag );
5014 }
5015 } :
5016 function( tag, context ) {
5017 var elem,
5018 tmp = [],
5019 i = 0,
5020 results = context.getElementsByTagName( tag );
5021
5022 if ( tag === "*" ) {
5023 while ( (elem = results[i++]) ) {
5024 if ( elem.nodeType === 1 ) {
5025 tmp.push( elem );
5026 }
3fe38208
AD
5027 }
5028
e3cfa33b 5029 return tmp;
3fe38208 5030 }
e3cfa33b
AK
5031 return results;
5032 };
5033
5034 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
5035 if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
5036 return context.getElementsByClassName( className );
3fe38208 5037 }
e3cfa33b
AK
5038 };
5039
5040 /* QSA/matchesSelector
5041 ---------------------------------------------------------------------- */
3fe38208 5042
e3cfa33b
AK
5043
5044 rbuggyMatches = [];
5045
5046 rbuggyQSA = [];
5047
5048 if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
5049 assert(function( div ) {
5050 div.innerHTML = "<select t=''><option selected=''></option></select>";
5051
5052 if ( div.querySelectorAll("[t^='']").length ) {
5053 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
5054 }
5055
5056 if ( !div.querySelectorAll("[selected]").length ) {
5057 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
5058 }
5059
5060 if ( !div.querySelectorAll(":checked").length ) {
5061 rbuggyQSA.push(":checked");
5062 }
5063 });
5064
5065 assert(function( div ) {
5066 var input = doc.createElement("input");
5067 input.setAttribute( "type", "hidden" );
5068 div.appendChild( input ).setAttribute( "name", "D" );
5069
5070 if ( div.querySelectorAll("[name=d]").length ) {
5071 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
5072 }
5073
5074 if ( !div.querySelectorAll(":enabled").length ) {
5075 rbuggyQSA.push( ":enabled", ":disabled" );
5076 }
5077
5078 div.querySelectorAll("*,:x");
5079 rbuggyQSA.push(",.*:");
5080 });
3fe38208
AD
5081 }
5082
e3cfa33b
AK
5083 if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
5084 docElem.mozMatchesSelector ||
5085 docElem.oMatchesSelector ||
5086 docElem.msMatchesSelector) )) ) {
5087
5088 assert(function( div ) {
5089 support.disconnectedMatch = matches.call( div, "div" );
5090
5091 matches.call( div, "[s!='']:x" );
5092 rbuggyMatches.push( "!=", pseudos );
5093 });
3fe38208
AD
5094 }
5095
e3cfa33b
AK
5096 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
5097 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
5098
5099 /* Contains
5100 ---------------------------------------------------------------------- */
5101 hasCompare = rnative.test( docElem.compareDocumentPosition );
5102
5103 contains = hasCompare || rnative.test( docElem.contains ) ?
5104 function( a, b ) {
5105 var adown = a.nodeType === 9 ? a.documentElement : a,
5106 bup = b && b.parentNode;
5107 return a === bup || !!( bup && bup.nodeType === 1 && (
5108 adown.contains ?
5109 adown.contains( bup ) :
5110 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
5111 ));
5112 } :
5113 function( a, b ) {
5114 if ( b ) {
5115 while ( (b = b.parentNode) ) {
5116 if ( b === a ) {
5117 return true;
5118 }
3fe38208
AD
5119 }
5120 }
e3cfa33b
AK
5121 return false;
5122 };
5123
5124 /* Sorting
5125 ---------------------------------------------------------------------- */
5126
5127 sortOrder = hasCompare ?
5128 function( a, b ) {
5129
5130 if ( a === b ) {
5131 hasDuplicate = true;
5132 return 0;
5133 }
5134
5135 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
5136 if ( compare ) {
5137 return compare;
5138 }
5139
5140 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
5141 a.compareDocumentPosition( b ) :
5142
5143 1;
5144
5145 if ( compare & 1 ||
5146 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
5147
5148 if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
5149 return -1;
5150 }
5151 if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
5152 return 1;
3fe38208 5153 }
e3cfa33b
AK
5154
5155 return sortInput ?
5156 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
5157 0;
3fe38208 5158 }
e3cfa33b
AK
5159
5160 return compare & 4 ? -1 : 1;
5161 } :
5162 function( a, b ) {
5163 if ( a === b ) {
5164 hasDuplicate = true;
5165 return 0;
5166 }
5167
5168 var cur,
5169 i = 0,
5170 aup = a.parentNode,
5171 bup = b.parentNode,
5172 ap = [ a ],
5173 bp = [ b ];
5174
5175 if ( !aup || !bup ) {
5176 return a === doc ? -1 :
5177 b === doc ? 1 :
5178 aup ? -1 :
5179 bup ? 1 :
5180 sortInput ?
5181 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
5182 0;
5183
5184 } else if ( aup === bup ) {
5185 return siblingCheck( a, b );
5186 }
5187
5188 cur = a;
5189 while ( (cur = cur.parentNode) ) {
5190 ap.unshift( cur );
5191 }
5192 cur = b;
5193 while ( (cur = cur.parentNode) ) {
5194 bp.unshift( cur );
5195 }
5196
5197 while ( ap[i] === bp[i] ) {
5198 i++;
5199 }
5200
5201 return i ?
5202 siblingCheck( ap[i], bp[i] ) :
5203
5204 ap[i] === preferredDoc ? -1 :
5205 bp[i] === preferredDoc ? 1 :
5206 0;
5207 };
5208
5209 return doc;
5210};
5211
5212Sizzle.matches = function( expr, elements ) {
5213 return Sizzle( expr, null, null, elements );
5214};
5215
5216Sizzle.matchesSelector = function( elem, expr ) {
5217 if ( ( elem.ownerDocument || elem ) !== document ) {
5218 setDocument( elem );
3fe38208
AD
5219 }
5220
e3cfa33b
AK
5221 expr = expr.replace( rattributeQuotes, "='$1']" );
5222
5223 if ( support.matchesSelector && documentIsHTML &&
5224 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
5225 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
5226
5227 try {
5228 var ret = matches.call( elem, expr );
5229
5230 if ( ret || support.disconnectedMatch ||
5231 elem.document && elem.document.nodeType !== 11 ) {
5232 return ret;
5233 }
5234 } catch(e) {}
3fe38208
AD
5235 }
5236
e3cfa33b
AK
5237 return Sizzle( expr, document, null, [elem] ).length > 0;
5238};
5239
5240Sizzle.contains = function( context, elem ) {
5241 if ( ( context.ownerDocument || context ) !== document ) {
5242 setDocument( context );
5243 }
5244 return contains( context, elem );
3fe38208
AD
5245};
5246
e3cfa33b
AK
5247Sizzle.attr = function( elem, name ) {
5248 if ( ( elem.ownerDocument || elem ) !== document ) {
5249 setDocument( elem );
5250 }
3fe38208 5251
e3cfa33b
AK
5252 var fn = Expr.attrHandle[ name.toLowerCase() ],
5253 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
5254 fn( elem, name, !documentIsHTML ) :
5255 undefined;
5256
5257 return val !== undefined ?
5258 val :
5259 support.attributes || !documentIsHTML ?
5260 elem.getAttribute( name ) :
5261 (val = elem.getAttributeNode(name)) && val.specified ?
5262 val.value :
5263 null;
5264};
5265
5266Sizzle.error = function( msg ) {
5267 throw new Error( "Syntax error, unrecognized expression: " + msg );
5268};
5269
5270/**
5271 * Document sorting and removing duplicates
5272 * @param {ArrayLike} results
5273 */
5274Sizzle.uniqueSort = function( results ) {
5275 var elem,
5276 duplicates = [],
5277 j = 0,
5278 i = 0;
5279
5280 hasDuplicate = !support.detectDuplicates;
5281 sortInput = !support.sortStable && results.slice( 0 );
5282 results.sort( sortOrder );
5283
5284 if ( hasDuplicate ) {
5285 while ( (elem = results[i++]) ) {
5286 if ( elem === results[ i ] ) {
5287 j = duplicates.push( i );
3fe38208
AD
5288 }
5289 }
e3cfa33b
AK
5290 while ( j-- ) {
5291 results.splice( duplicates[ j ], 1 );
5292 }
3fe38208
AD
5293 }
5294
e3cfa33b
AK
5295 sortInput = null;
5296
3fe38208
AD
5297 return results;
5298};
5299
e3cfa33b
AK
5300/**
5301 * Utility function for retrieving the text value of an array of DOM nodes
5302 * @param {Array|Element} elem
5303 */
5304getText = Sizzle.getText = function( elem ) {
5305 var node,
5306 ret = "",
5307 i = 0,
5308 nodeType = elem.nodeType;
5309
5310 if ( !nodeType ) {
5311 while ( (node = elem[i++]) ) {
5312 ret += getText( node );
5313 }
5314 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
5315 if ( typeof elem.textContent === "string" ) {
5316 return elem.textContent;
5317 } else {
5318 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
5319 ret += getText( elem );
5320 }
5321 }
5322 } else if ( nodeType === 3 || nodeType === 4 ) {
5323 return elem.nodeValue;
5324 }
5325
5326 return ret;
3fe38208
AD
5327};
5328
e3cfa33b 5329Expr = Sizzle.selectors = {
3fe38208 5330
e3cfa33b 5331 cacheLength: 50,
3fe38208 5332
e3cfa33b 5333 createPseudo: markFunction,
3fe38208 5334
e3cfa33b 5335 match: matchExpr,
3fe38208 5336
e3cfa33b 5337 attrHandle: {},
3fe38208 5338
e3cfa33b 5339 find: {},
3fe38208 5340
e3cfa33b
AK
5341 relative: {
5342 ">": { dir: "parentNode", first: true },
5343 " ": { dir: "parentNode" },
5344 "+": { dir: "previousSibling", first: true },
5345 "~": { dir: "previousSibling" }
5346 },
3fe38208 5347
e3cfa33b
AK
5348 preFilter: {
5349 "ATTR": function( match ) {
5350 match[1] = match[1].replace( runescape, funescape );
3fe38208 5351
e3cfa33b 5352 match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
3fe38208 5353
e3cfa33b
AK
5354 if ( match[2] === "~=" ) {
5355 match[3] = " " + match[3] + " ";
5356 }
3fe38208 5357
e3cfa33b
AK
5358 return match.slice( 0, 4 );
5359 },
3fe38208 5360
e3cfa33b
AK
5361 "CHILD": function( match ) {
5362 /* matches from matchExpr["CHILD"]
5363 1 type (only|nth|...)
5364 2 what (child|of-type)
5365 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
5366 4 xn-component of xn+y argument ([+-]?\d*n|)
5367 5 sign of xn-component
5368 6 x of xn-component
5369 7 sign of y-component
5370 8 y of y-component
5371 */
5372 match[1] = match[1].toLowerCase();
5373
5374 if ( match[1].slice( 0, 3 ) === "nth" ) {
5375 if ( !match[3] ) {
5376 Sizzle.error( match[0] );
3fe38208
AD
5377 }
5378
e3cfa33b
AK
5379 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
5380 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
3fe38208 5381
e3cfa33b
AK
5382 } else if ( match[3] ) {
5383 Sizzle.error( match[0] );
5384 }
3fe38208 5385
e3cfa33b
AK
5386 return match;
5387 },
3fe38208 5388
e3cfa33b
AK
5389 "PSEUDO": function( match ) {
5390 var excess,
5391 unquoted = !match[5] && match[2];
3fe38208 5392
e3cfa33b
AK
5393 if ( matchExpr["CHILD"].test( match[0] ) ) {
5394 return null;
3fe38208 5395 }
3fe38208 5396
e3cfa33b
AK
5397 if ( match[3] && match[4] !== undefined ) {
5398 match[2] = match[4];
3fe38208 5399
e3cfa33b
AK
5400 } else if ( unquoted && rpseudo.test( unquoted ) &&
5401 (excess = tokenize( unquoted, true )) &&
5402 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
3fe38208 5403
e3cfa33b
AK
5404 match[0] = match[0].slice( 0, excess );
5405 match[2] = unquoted.slice( 0, excess );
5406 }
4b9dfd5b 5407
e3cfa33b 5408 return match.slice( 0, 3 );
3fe38208
AD
5409 }
5410 },
3fe38208 5411
e3cfa33b 5412 filter: {
3fe38208 5413
e3cfa33b
AK
5414 "TAG": function( nodeNameSelector ) {
5415 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
5416 return nodeNameSelector === "*" ?
5417 function() { return true; } :
5418 function( elem ) {
5419 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
5420 };
5421 },
3fe38208 5422
e3cfa33b
AK
5423 "CLASS": function( className ) {
5424 var pattern = classCache[ className + " " ];
3fe38208 5425
e3cfa33b
AK
5426 return pattern ||
5427 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
5428 classCache( className, function( elem ) {
5429 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
5430 });
3fe38208 5431 },
3fe38208 5432
e3cfa33b
AK
5433 "ATTR": function( name, operator, check ) {
5434 return function( elem ) {
5435 var result = Sizzle.attr( elem, name );
3fe38208 5436
e3cfa33b
AK
5437 if ( result == null ) {
5438 return operator === "!=";
3fe38208 5439 }
e3cfa33b
AK
5440 if ( !operator ) {
5441 return true;
3fe38208
AD
5442 }
5443
e3cfa33b
AK
5444 result += "";
5445
5446 return operator === "=" ? result === check :
5447 operator === "!=" ? result !== check :
5448 operator === "^=" ? check && result.indexOf( check ) === 0 :
5449 operator === "*=" ? check && result.indexOf( check ) > -1 :
5450 operator === "$=" ? check && result.slice( -check.length ) === check :
5451 operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
5452 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
5453 false;
5454 };
3fe38208 5455 },
3fe38208 5456
e3cfa33b
AK
5457 "CHILD": function( type, what, argument, first, last ) {
5458 var simple = type.slice( 0, 3 ) !== "nth",
5459 forward = type.slice( -4 ) !== "last",
5460 ofType = what === "of-type";
5461
5462 return first === 1 && last === 0 ?
5463
5464 function( elem ) {
5465 return !!elem.parentNode;
5466 } :
5467
5468 function( elem, context, xml ) {
5469 var cache, outerCache, node, diff, nodeIndex, start,
5470 dir = simple !== forward ? "nextSibling" : "previousSibling",
5471 parent = elem.parentNode,
5472 name = ofType && elem.nodeName.toLowerCase(),
5473 useCache = !xml && !ofType;
5474
5475 if ( parent ) {
5476
5477 if ( simple ) {
5478 while ( dir ) {
5479 node = elem;
5480 while ( (node = node[ dir ]) ) {
5481 if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
5482 return false;
5483 }
5484 }
5485 start = dir = type === "only" && !start && "nextSibling";
5486 }
5487 return true;
5488 }
3fe38208 5489
e3cfa33b 5490 start = [ forward ? parent.firstChild : parent.lastChild ];
3fe38208 5491
e3cfa33b
AK
5492 if ( forward && useCache ) {
5493 outerCache = parent[ expando ] || (parent[ expando ] = {});
5494 cache = outerCache[ type ] || [];
5495 nodeIndex = cache[0] === dirruns && cache[1];
5496 diff = cache[0] === dirruns && cache[2];
5497 node = nodeIndex && parent.childNodes[ nodeIndex ];
3fe38208 5498
e3cfa33b 5499 while ( (node = ++nodeIndex && node && node[ dir ] ||
3fe38208 5500
e3cfa33b 5501 (diff = nodeIndex = 0) || start.pop()) ) {
3fe38208 5502
e3cfa33b
AK
5503 if ( node.nodeType === 1 && ++diff && node === elem ) {
5504 outerCache[ type ] = [ dirruns, nodeIndex, diff ];
5505 break;
5506 }
5507 }
3fe38208 5508
e3cfa33b
AK
5509 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
5510 diff = cache[1];
3fe38208 5511
e3cfa33b
AK
5512 } else {
5513 while ( (node = ++nodeIndex && node && node[ dir ] ||
5514 (diff = nodeIndex = 0) || start.pop()) ) {
3fe38208 5515
e3cfa33b
AK
5516 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
5517 if ( useCache ) {
5518 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
5519 }
3fe38208 5520
e3cfa33b
AK
5521 if ( node === elem ) {
5522 break;
5523 }
5524 }
5525 }
5526 }
3fe38208 5527
e3cfa33b
AK
5528 diff -= last;
5529 return diff === first || ( diff % first === 0 && diff / first >= 0 );
5530 }
5531 };
3fe38208 5532 },
3fe38208 5533
e3cfa33b
AK
5534 "PSEUDO": function( pseudo, argument ) {
5535 var args,
5536 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
5537 Sizzle.error( "unsupported pseudo: " + pseudo );
3fe38208 5538
e3cfa33b
AK
5539 if ( fn[ expando ] ) {
5540 return fn( argument );
3fe38208
AD
5541 }
5542
e3cfa33b
AK
5543 if ( fn.length > 1 ) {
5544 args = [ pseudo, pseudo, "", argument ];
5545 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
5546 markFunction(function( seed, matches ) {
5547 var idx,
5548 matched = fn( seed, argument ),
5549 i = matched.length;
5550 while ( i-- ) {
5551 idx = indexOf.call( seed, matched[i] );
5552 seed[ idx ] = !( matches[ idx ] = matched[i] );
5553 }
5554 }) :
5555 function( elem ) {
5556 return fn( elem, 0, args );
5557 };
3fe38208
AD
5558 }
5559
e3cfa33b 5560 return fn;
3fe38208
AD
5561 }
5562 },
e3cfa33b
AK
5563
5564 pseudos: {
5565 "not": markFunction(function( selector ) {
5566 var input = [],
5567 results = [],
5568 matcher = compile( selector.replace( rtrim, "$1" ) );
5569
5570 return matcher[ expando ] ?
5571 markFunction(function( seed, matches, context, xml ) {
5572 var elem,
5573 unmatched = matcher( seed, null, xml, [] ),
5574 i = seed.length;
5575
5576 while ( i-- ) {
5577 if ( (elem = unmatched[i]) ) {
5578 seed[i] = !(matches[i] = elem);
5579 }
5580 }
5581 }) :
5582 function( elem, context, xml ) {
5583 input[0] = elem;
5584 matcher( input, null, xml, results );
5585 return !results.pop();
5586 };
5587 }),
5588
5589 "has": markFunction(function( selector ) {
5590 return function( elem ) {
5591 return Sizzle( selector, elem ).length > 0;
5592 };
5593 }),
5594
5595 "contains": markFunction(function( text ) {
5596 return function( elem ) {
5597 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
5598 };
5599 }),
5600
5601 "lang": markFunction( function( lang ) {
5602 if ( !ridentifier.test(lang || "") ) {
5603 Sizzle.error( "unsupported lang: " + lang );
5604 }
5605 lang = lang.replace( runescape, funescape ).toLowerCase();
5606 return function( elem ) {
5607 var elemLang;
5608 do {
5609 if ( (elemLang = documentIsHTML ?
5610 elem.lang :
5611 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
5612
5613 elemLang = elemLang.toLowerCase();
5614 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
5615 }
5616 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
5617 return false;
5618 };
5619 }),
5620
5621 "target": function( elem ) {
5622 var hash = window.location && window.location.hash;
5623 return hash && hash.slice( 1 ) === elem.id;
3fe38208 5624 },
e3cfa33b
AK
5625
5626 "root": function( elem ) {
5627 return elem === docElem;
3fe38208 5628 },
e3cfa33b
AK
5629
5630 "focus": function( elem ) {
5631 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
3fe38208 5632 },
e3cfa33b
AK
5633
5634 "enabled": function( elem ) {
5635 return elem.disabled === false;
3fe38208 5636 },
e3cfa33b
AK
5637
5638 "disabled": function( elem ) {
5639 return elem.disabled === true;
3fe38208 5640 },
e3cfa33b
AK
5641
5642 "checked": function( elem ) {
5643 var nodeName = elem.nodeName.toLowerCase();
5644 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
3fe38208 5645 },
e3cfa33b
AK
5646
5647 "selected": function( elem ) {
5648 if ( elem.parentNode ) {
5649 elem.parentNode.selectedIndex;
5650 }
5651
5652 return elem.selected === true;
3fe38208 5653 },
e3cfa33b
AK
5654
5655 "empty": function( elem ) {
5656 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
5657 if ( elem.nodeType < 6 ) {
5658 return false;
5659 }
5660 }
5661 return true;
3fe38208 5662 },
e3cfa33b
AK
5663
5664 "parent": function( elem ) {
5665 return !Expr.pseudos["empty"]( elem );
3fe38208 5666 },
e3cfa33b
AK
5667
5668 "header": function( elem ) {
5669 return rheader.test( elem.nodeName );
3fe38208 5670 },
e3cfa33b
AK
5671
5672 "input": function( elem ) {
5673 return rinputs.test( elem.nodeName );
3fe38208 5674 },
e3cfa33b
AK
5675
5676 "button": function( elem ) {
5677 var name = elem.nodeName.toLowerCase();
5678 return name === "input" && elem.type === "button" || name === "button";
3fe38208 5679 },
3fe38208 5680
e3cfa33b
AK
5681 "text": function( elem ) {
5682 var attr;
5683 return elem.nodeName.toLowerCase() === "input" &&
5684 elem.type === "text" &&
5685
5686 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
3fe38208 5687 },
3fe38208 5688
e3cfa33b
AK
5689 "first": createPositionalPseudo(function() {
5690 return [ 0 ];
5691 }),
3fe38208 5692
e3cfa33b
AK
5693 "last": createPositionalPseudo(function( matchIndexes, length ) {
5694 return [ length - 1 ];
5695 }),
3fe38208 5696
e3cfa33b
AK
5697 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
5698 return [ argument < 0 ? argument + length : argument ];
5699 }),
3fe38208 5700
e3cfa33b
AK
5701 "even": createPositionalPseudo(function( matchIndexes, length ) {
5702 var i = 0;
5703 for ( ; i < length; i += 2 ) {
5704 matchIndexes.push( i );
3fe38208 5705 }
e3cfa33b
AK
5706 return matchIndexes;
5707 }),
3fe38208 5708
e3cfa33b
AK
5709 "odd": createPositionalPseudo(function( matchIndexes, length ) {
5710 var i = 1;
5711 for ( ; i < length; i += 2 ) {
5712 matchIndexes.push( i );
3fe38208 5713 }
e3cfa33b
AK
5714 return matchIndexes;
5715 }),
5716
5717 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
5718 var i = argument < 0 ? argument + length : argument;
5719 for ( ; --i >= 0; ) {
5720 matchIndexes.push( i );
5721 }
5722 return matchIndexes;
5723 }),
5724
5725 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
5726 var i = argument < 0 ? argument + length : argument;
5727 for ( ; ++i < length; ) {
5728 matchIndexes.push( i );
5729 }
5730 return matchIndexes;
5731 })
3fe38208
AD
5732 }
5733};
4b9dfd5b 5734
e3cfa33b 5735Expr.pseudos["nth"] = Expr.pseudos["eq"];
4b9dfd5b 5736
e3cfa33b
AK
5737for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
5738 Expr.pseudos[ i ] = createInputPseudo( i );
5739}
5740for ( i in { submit: true, reset: true } ) {
5741 Expr.pseudos[ i ] = createButtonPseudo( i );
3fe38208 5742}
4b9dfd5b 5743
e3cfa33b
AK
5744function setFilters() {}
5745setFilters.prototype = Expr.filters = Expr.pseudos;
5746Expr.setFilters = new setFilters();
4b9dfd5b 5747
e3cfa33b
AK
5748function tokenize( selector, parseOnly ) {
5749 var matched, match, tokens, type,
5750 soFar, groups, preFilters,
5751 cached = tokenCache[ selector + " " ];
5752
5753 if ( cached ) {
5754 return parseOnly ? 0 : cached.slice( 0 );
3fe38208 5755 }
4b9dfd5b 5756
e3cfa33b
AK
5757 soFar = selector;
5758 groups = [];
5759 preFilters = Expr.preFilter;
4b9dfd5b 5760
e3cfa33b 5761 while ( soFar ) {
3fe38208 5762
e3cfa33b
AK
5763 if ( !matched || (match = rcomma.exec( soFar )) ) {
5764 if ( match ) {
5765 soFar = soFar.slice( match[0].length ) || soFar;
5766 }
5767 groups.push( (tokens = []) );
5768 }
3fe38208 5769
e3cfa33b
AK
5770 matched = false;
5771
5772 if ( (match = rcombinators.exec( soFar )) ) {
5773 matched = match.shift();
5774 tokens.push({
5775 value: matched,
5776 type: match[0].replace( rtrim, " " )
5777 });
5778 soFar = soFar.slice( matched.length );
5779 }
5780
5781 for ( type in Expr.filter ) {
5782 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
5783 (match = preFilters[ type ]( match ))) ) {
5784 matched = match.shift();
5785 tokens.push({
5786 value: matched,
5787 type: type,
5788 matches: match
5789 });
5790 soFar = soFar.slice( matched.length );
5791 }
5792 }
5793
5794 if ( !matched ) {
5795 break;
5796 }
5797 }
5798
5799 return parseOnly ?
5800 soFar.length :
5801 soFar ?
5802 Sizzle.error( selector ) :
5803 tokenCache( selector, groups ).slice( 0 );
5804}
5805
5806function toSelector( tokens ) {
5807 var i = 0,
5808 len = tokens.length,
5809 selector = "";
5810 for ( ; i < len; i++ ) {
5811 selector += tokens[i].value;
5812 }
5813 return selector;
5814}
5815
5816function addCombinator( matcher, combinator, base ) {
5817 var dir = combinator.dir,
5818 checkNonElements = base && dir === "parentNode",
5819 doneName = done++;
5820
5821 return combinator.first ?
5822 function( elem, context, xml ) {
5823 while ( (elem = elem[ dir ]) ) {
5824 if ( elem.nodeType === 1 || checkNonElements ) {
5825 return matcher( elem, context, xml );
5826 }
5827 }
5828 } :
5829
5830 function( elem, context, xml ) {
5831 var oldCache, outerCache,
5832 newCache = [ dirruns, doneName ];
5833
5834 if ( xml ) {
5835 while ( (elem = elem[ dir ]) ) {
5836 if ( elem.nodeType === 1 || checkNonElements ) {
5837 if ( matcher( elem, context, xml ) ) {
5838 return true;
5839 }
5840 }
3fe38208
AD
5841 }
5842 } else {
e3cfa33b
AK
5843 while ( (elem = elem[ dir ]) ) {
5844 if ( elem.nodeType === 1 || checkNonElements ) {
5845 outerCache = elem[ expando ] || (elem[ expando ] = {});
5846 if ( (oldCache = outerCache[ dir ]) &&
5847 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
5848
5849 return (newCache[ 2 ] = oldCache[ 2 ]);
5850 } else {
5851 outerCache[ dir ] = newCache;
5852
5853 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
5854 return true;
5855 }
5856 }
5857 }
3fe38208
AD
5858 }
5859 }
e3cfa33b
AK
5860 };
5861}
3fe38208 5862
e3cfa33b
AK
5863function elementMatcher( matchers ) {
5864 return matchers.length > 1 ?
5865 function( elem, context, xml ) {
5866 var i = matchers.length;
5867 while ( i-- ) {
5868 if ( !matchers[i]( elem, context, xml ) ) {
5869 return false;
5870 }
5871 }
5872 return true;
5873 } :
5874 matchers[0];
3fe38208 5875}
4b9dfd5b 5876
e3cfa33b
AK
5877function multipleContexts( selector, contexts, results ) {
5878 var i = 0,
5879 len = contexts.length;
5880 for ( ; i < len; i++ ) {
5881 Sizzle( selector, contexts[i], results );
5882 }
5883 return results;
5884}
3fe38208 5885
e3cfa33b
AK
5886function condense( unmatched, map, filter, context, xml ) {
5887 var elem,
5888 newUnmatched = [],
5889 i = 0,
5890 len = unmatched.length,
5891 mapped = map != null;
5892
5893 for ( ; i < len; i++ ) {
5894 if ( (elem = unmatched[i]) ) {
5895 if ( !filter || filter( elem, context, xml ) ) {
5896 newUnmatched.push( elem );
5897 if ( mapped ) {
5898 map.push( i );
5899 }
3fe38208 5900 }
3fe38208 5901 }
e3cfa33b 5902 }
3fe38208 5903
e3cfa33b
AK
5904 return newUnmatched;
5905}
5906
5907function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
5908 if ( postFilter && !postFilter[ expando ] ) {
5909 postFilter = setMatcher( postFilter );
5910 }
5911 if ( postFinder && !postFinder[ expando ] ) {
5912 postFinder = setMatcher( postFinder, postSelector );
5913 }
5914 return markFunction(function( seed, results, context, xml ) {
5915 var temp, i, elem,
5916 preMap = [],
5917 postMap = [],
5918 preexisting = results.length,
5919
5920 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
5921
5922 matcherIn = preFilter && ( seed || !selector ) ?
5923 condense( elems, preMap, preFilter, context, xml ) :
5924 elems,
5925
5926 matcherOut = matcher ?
5927 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
5928
5929 [] :
5930
5931 results :
5932 matcherIn;
5933
5934 if ( matcher ) {
5935 matcher( matcherIn, matcherOut, context, xml );
3fe38208 5936 }
e3cfa33b
AK
5937
5938 if ( postFilter ) {
5939 temp = condense( matcherOut, postMap );
5940 postFilter( temp, [], context, xml );
5941
5942 i = temp.length;
5943 while ( i-- ) {
5944 if ( (elem = temp[i]) ) {
5945 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
5946 }
3fe38208 5947 }
3fe38208
AD
5948 }
5949
e3cfa33b
AK
5950 if ( seed ) {
5951 if ( postFinder || preFilter ) {
5952 if ( postFinder ) {
5953 temp = [];
5954 i = matcherOut.length;
5955 while ( i-- ) {
5956 if ( (elem = matcherOut[i]) ) {
5957 temp.push( (matcherIn[i] = elem) );
5958 }
5959 }
5960 postFinder( null, (matcherOut = []), temp, xml );
5961 }
5962
5963 i = matcherOut.length;
5964 while ( i-- ) {
5965 if ( (elem = matcherOut[i]) &&
5966 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
5967
5968 seed[temp] = !(results[temp] = elem);
5969 }
5970 }
5971 }
5972
5973 } else {
5974 matcherOut = condense(
5975 matcherOut === results ?
5976 matcherOut.splice( preexisting, matcherOut.length ) :
5977 matcherOut
5978 );
5979 if ( postFinder ) {
5980 postFinder( null, results, matcherOut, xml );
5981 } else {
5982 push.apply( results, matcherOut );
3fe38208 5983 }
3fe38208 5984 }
e3cfa33b
AK
5985 });
5986}
3fe38208 5987
e3cfa33b
AK
5988function matcherFromTokens( tokens ) {
5989 var checkContext, matcher, j,
5990 len = tokens.length,
5991 leadingRelative = Expr.relative[ tokens[0].type ],
5992 implicitRelative = leadingRelative || Expr.relative[" "],
5993 i = leadingRelative ? 1 : 0,
5994
5995 matchContext = addCombinator( function( elem ) {
5996 return elem === checkContext;
5997 }, implicitRelative, true ),
5998 matchAnyContext = addCombinator( function( elem ) {
5999 return indexOf.call( checkContext, elem ) > -1;
6000 }, implicitRelative, true ),
6001 matchers = [ function( elem, context, xml ) {
6002 return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
6003 (checkContext = context).nodeType ?
6004 matchContext( elem, context, xml ) :
6005 matchAnyContext( elem, context, xml ) );
6006 } ];
6007
6008 for ( ; i < len; i++ ) {
6009 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
6010 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
6011 } else {
6012 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
6013
6014 if ( matcher[ expando ] ) {
6015 j = ++i;
6016 for ( ; j < len; j++ ) {
6017 if ( Expr.relative[ tokens[j].type ] ) {
6018 break;
6019 }
6020 }
6021 return setMatcher(
6022 i > 1 && elementMatcher( matchers ),
6023 i > 1 && toSelector(
6024 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
6025 ).replace( rtrim, "$1" ),
6026 matcher,
6027 i < j && matcherFromTokens( tokens.slice( i, j ) ),
6028 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
6029 j < len && toSelector( tokens )
6030 );
6031 }
6032 matchers.push( matcher );
3fe38208 6033 }
e3cfa33b
AK
6034 }
6035
6036 return elementMatcher( matchers );
3fe38208 6037}
4b9dfd5b 6038
e3cfa33b
AK
6039function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
6040 var bySet = setMatchers.length > 0,
6041 byElement = elementMatchers.length > 0,
6042 superMatcher = function( seed, context, xml, results, outermost ) {
6043 var elem, j, matcher,
6044 matchedCount = 0,
6045 i = "0",
6046 unmatched = seed && [],
6047 setMatched = [],
6048 contextBackup = outermostContext,
6049 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
6050 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
6051 len = elems.length;
6052
6053 if ( outermost ) {
6054 outermostContext = context !== document && context;
6055 }
6056
6057 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
6058 if ( byElement && elem ) {
6059 j = 0;
6060 while ( (matcher = elementMatchers[j++]) ) {
6061 if ( matcher( elem, context, xml ) ) {
6062 results.push( elem );
6063 break;
6064 }
6065 }
6066 if ( outermost ) {
6067 dirruns = dirrunsUnique;
6068 }
6069 }
3fe38208 6070
e3cfa33b
AK
6071 if ( bySet ) {
6072 if ( (elem = !matcher && elem) ) {
6073 matchedCount--;
6074 }
3fe38208 6075
e3cfa33b
AK
6076 if ( seed ) {
6077 unmatched.push( elem );
6078 }
6079 }
3fe38208 6080 }
3fe38208 6081
e3cfa33b
AK
6082 matchedCount += i;
6083 if ( bySet && i !== matchedCount ) {
6084 j = 0;
6085 while ( (matcher = setMatchers[j++]) ) {
6086 matcher( unmatched, setMatched, context, xml );
6087 }
85e836d8 6088
e3cfa33b
AK
6089 if ( seed ) {
6090 if ( matchedCount > 0 ) {
6091 while ( i-- ) {
6092 if ( !(unmatched[i] || setMatched[i]) ) {
6093 setMatched[i] = pop.call( results );
6094 }
6095 }
6096 }
4b9dfd5b 6097
e3cfa33b
AK
6098 setMatched = condense( setMatched );
6099 }
4b9dfd5b 6100
e3cfa33b 6101 push.apply( results, setMatched );
4b9dfd5b 6102
e3cfa33b
AK
6103 if ( outermost && !seed && setMatched.length > 0 &&
6104 ( matchedCount + setMatchers.length ) > 1 ) {
4b9dfd5b 6105
e3cfa33b 6106 Sizzle.uniqueSort( results );
3fe38208 6107 }
3fe38208 6108 }
4b9dfd5b 6109
e3cfa33b
AK
6110 if ( outermost ) {
6111 dirruns = dirrunsUnique;
6112 outermostContext = contextBackup;
6113 }
4b9dfd5b 6114
e3cfa33b 6115 return unmatched;
3fe38208 6116 };
4b9dfd5b 6117
e3cfa33b
AK
6118 return bySet ?
6119 markFunction( superMatcher ) :
6120 superMatcher;
6121}
85e836d8 6122
e3cfa33b
AK
6123compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
6124 var i,
6125 setMatchers = [],
6126 elementMatchers = [],
6127 cached = compilerCache[ selector + " " ];
85e836d8 6128
e3cfa33b
AK
6129 if ( !cached ) {
6130 if ( !match ) {
6131 match = tokenize( selector );
6132 }
6133 i = match.length;
6134 while ( i-- ) {
6135 cached = matcherFromTokens( match[i] );
6136 if ( cached[ expando ] ) {
6137 setMatchers.push( cached );
6138 } else {
6139 elementMatchers.push( cached );
6140 }
3fe38208 6141 }
4b9dfd5b 6142
e3cfa33b 6143 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
4b9dfd5b 6144
e3cfa33b 6145 cached.selector = selector;
3fe38208 6146 }
e3cfa33b
AK
6147 return cached;
6148};
4b9dfd5b 6149
e3cfa33b
AK
6150/**
6151 * A low-level selection function that works with Sizzle's compiled
6152 * selector functions
6153 * @param {String|Function} selector A selector or a pre-compiled
6154 * selector function built with Sizzle.compile
6155 * @param {Element} context
6156 * @param {Array} [results]
6157 * @param {Array} [seed] A set of elements to match against
6158 */
6159select = Sizzle.select = function( selector, context, results, seed ) {
6160 var i, tokens, token, type, find,
6161 compiled = typeof selector === "function" && selector,
6162 match = !seed && tokenize( (selector = compiled.selector || selector) );
4b9dfd5b 6163
e3cfa33b 6164 results = results || [];
4b9dfd5b 6165
e3cfa33b 6166 if ( match.length === 1 ) {
4b9dfd5b 6167
e3cfa33b
AK
6168 tokens = match[0] = match[0].slice( 0 );
6169 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
6170 support.getById && context.nodeType === 9 && documentIsHTML &&
6171 Expr.relative[ tokens[1].type ] ) {
4b9dfd5b 6172
e3cfa33b
AK
6173 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
6174 if ( !context ) {
6175 return results;
6176
6177 } else if ( compiled ) {
6178 context = context.parentNode;
6179 }
4b9dfd5b 6180
e3cfa33b 6181 selector = selector.slice( tokens.shift().value.length );
3fe38208 6182 }
4b9dfd5b 6183
e3cfa33b
AK
6184 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
6185 while ( i-- ) {
6186 token = tokens[i];
4b9dfd5b 6187
e3cfa33b
AK
6188 if ( Expr.relative[ (type = token.type) ] ) {
6189 break;
3fe38208 6190 }
e3cfa33b
AK
6191 if ( (find = Expr.find[ type ]) ) {
6192 if ( (seed = find(
6193 token.matches[0].replace( runescape, funescape ),
6194 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
6195 )) ) {
6196
6197 tokens.splice( i, 1 );
6198 selector = seed.length && toSelector( tokens );
6199 if ( !selector ) {
6200 push.apply( results, seed );
6201 return results;
6202 }
3fe38208 6203
3fe38208
AD
6204 break;
6205 }
3fe38208 6206 }
3fe38208
AD
6207 }
6208 }
4b9dfd5b 6209
e3cfa33b
AK
6210 ( compiled || compile( selector, match ) )(
6211 seed,
6212 context,
6213 !documentIsHTML,
6214 results,
6215 rsibling.test( selector ) && testContext( context.parentNode ) || context
6216 );
6217 return results;
6218};
3fe38208 6219
3fe38208 6220
e3cfa33b 6221support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
3fe38208 6222
e3cfa33b 6223support.detectDuplicates = !!hasDuplicate;
3fe38208 6224
e3cfa33b 6225setDocument();
3fe38208 6226
e3cfa33b
AK
6227support.sortDetached = assert(function( div1 ) {
6228 return div1.compareDocumentPosition( document.createElement("div") ) & 1;
6229});
6230
6231if ( !assert(function( div ) {
6232 div.innerHTML = "<a href='#'></a>";
6233 return div.firstChild.getAttribute("href") === "#" ;
6234}) ) {
6235 addHandle( "type|href|height|width", function( elem, name, isXML ) {
6236 if ( !isXML ) {
6237 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
3fe38208 6238 }
e3cfa33b 6239 });
3fe38208 6240}
4b9dfd5b 6241
e3cfa33b
AK
6242if ( !support.attributes || !assert(function( div ) {
6243 div.innerHTML = "<input/>";
6244 div.firstChild.setAttribute( "value", "" );
6245 return div.firstChild.getAttribute( "value" ) === "";
6246}) ) {
6247 addHandle( "value", function( elem, name, isXML ) {
6248 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
6249 return elem.defaultValue;
6250 }
6251 });
6252}
5c656a9d 6253
e3cfa33b
AK
6254if ( !assert(function( div ) {
6255 return div.getAttribute("disabled") == null;
6256}) ) {
6257 addHandle( booleans, function( elem, name, isXML ) {
6258 var val;
6259 if ( !isXML ) {
6260 return elem[ name ] === true ? name.toLowerCase() :
6261 (val = elem.getAttributeNode( name )) && val.specified ?
6262 val.value :
6263 null;
6264 }
6265 });
6266}
5c656a9d 6267
e3cfa33b
AK
6268if ( typeof define === "function" && define.amd ) {
6269 define(function() { return Sizzle; });
6270} else if ( typeof module !== "undefined" && module.exports ) {
6271 module.exports = Sizzle;
6272} else {
6273 window.Sizzle = Sizzle;
6274}
3fe38208 6275
e3cfa33b 6276})( window );
3fe38208 6277
e3cfa33b
AK
6278;(function() {
6279 if (typeof Sizzle !== 'undefined') {
6280 return;
6281 }
3fe38208 6282
e3cfa33b
AK
6283 if (typeof define !== 'undefined' && define.amd) {
6284 window.Sizzle = Prototype._actual_sizzle;
6285 window.define = Prototype._original_define;
6286 delete Prototype._actual_sizzle;
6287 delete Prototype._original_define;
6288 } else if (typeof module !== 'undefined' && module.exports) {
6289 window.Sizzle = module.exports;
6290 module.exports = {};
6291 }
3fe38208
AD
6292})();
6293
6294;(function(engine) {
6295 var extendElements = Prototype.Selector.extendElements;
6296
6297 function select(selector, scope) {
6298 return extendElements(engine(selector, scope || document));
5c656a9d 6299 }
14f69488 6300
3fe38208
AD
6301 function match(element, selector) {
6302 return engine.matches(selector, [element]).length == 1;
6303 }
4b9dfd5b 6304
3fe38208
AD
6305 Prototype.Selector.engine = engine;
6306 Prototype.Selector.select = select;
6307 Prototype.Selector.match = match;
6308})(Sizzle);
6309
6310window.Sizzle = Prototype._original_property;
6311delete Prototype._original_property;
85e836d8 6312
14f69488 6313var Form = {
5c656a9d 6314 reset: function(form) {
85e836d8
AD
6315 form = $(form);
6316 form.reset();
5c656a9d
AD
6317 return form;
6318 },
6319
4b9dfd5b
AD
6320 serializeElements: function(elements, options) {
6321 if (typeof options != 'object') options = { hash: !!options };
6322 else if (Object.isUndefined(options.hash)) options.hash = true;
3fe38208
AD
6323 var key, value, submitted = false, submit = options.submit, accumulator, initial;
6324
6325 if (options.hash) {
6326 initial = {};
6327 accumulator = function(result, key, value) {
6328 if (key in result) {
6329 if (!Object.isArray(result[key])) result[key] = [result[key]];
e3cfa33b 6330 result[key] = result[key].concat(value);
3fe38208
AD
6331 } else result[key] = value;
6332 return result;
6333 };
6334 } else {
6335 initial = '';
e3cfa33b
AK
6336 accumulator = function(result, key, values) {
6337 if (!Object.isArray(values)) {values = [values];}
6338 if (!values.length) {return result;}
6339 var encodedKey = encodeURIComponent(key).gsub(/%20/, '+');
6340 return result + (result ? "&" : "") + values.map(function (value) {
6341 value = value.gsub(/(\r)?\n/, '\r\n');
6342 value = encodeURIComponent(value);
6343 value = value.gsub(/%20/, '+');
6344 return encodedKey + "=" + value;
6345 }).join("&");
6346 };
3fe38208 6347 }
4b9dfd5b 6348
3fe38208 6349 return elements.inject(initial, function(result, element) {
5c656a9d 6350 if (!element.disabled && element.name) {
4b9dfd5b 6351 key = element.name; value = $(element).getValue();
85e836d8 6352 if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
4b9dfd5b 6353 submit !== false && (!submit || key == submit) && (submitted = true)))) {
3fe38208 6354 result = accumulator(result, key, value);
5c656a9d
AD
6355 }
6356 }
6357 return result;
6358 });
5c656a9d
AD
6359 }
6360};
14f69488 6361
5c656a9d 6362Form.Methods = {
4b9dfd5b
AD
6363 serialize: function(form, options) {
6364 return Form.serializeElements(Form.getElements(form), options);
14f69488
AD
6365 },
6366
e3cfa33b 6367
14f69488 6368 getElements: function(form) {
e3cfa33b
AK
6369 var elements = $(form).getElementsByTagName('*');
6370 var element, results = [], serializers = Form.Element.Serializers;
6371
85e836d8 6372 for (var i = 0; element = elements[i]; i++) {
e3cfa33b
AK
6373 if (serializers[element.tagName.toLowerCase()])
6374 results.push(Element.extend(element));
85e836d8 6375 }
e3cfa33b 6376 return results;
14f69488
AD
6377 },
6378
6379 getInputs: function(form, typeName, name) {
6380 form = $(form);
6381 var inputs = form.getElementsByTagName('input');
6382
5c656a9d 6383 if (!typeName && !name) return $A(inputs).map(Element.extend);
14f69488 6384
5c656a9d 6385 for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
14f69488 6386 var input = inputs[i];
5c656a9d 6387 if ((typeName && input.type != typeName) || (name && input.name != name))
14f69488 6388 continue;
5c656a9d 6389 matchingInputs.push(Element.extend(input));
14f69488
AD
6390 }
6391
6392 return matchingInputs;
6393 },
6394
6395 disable: function(form) {
5c656a9d 6396 form = $(form);
4b9dfd5b 6397 Form.getElements(form).invoke('disable');
5c656a9d 6398 return form;
14f69488
AD
6399 },
6400
6401 enable: function(form) {
5c656a9d 6402 form = $(form);
4b9dfd5b 6403 Form.getElements(form).invoke('enable');
5c656a9d 6404 return form;
14f69488
AD
6405 },
6406
6407 findFirstElement: function(form) {
4b9dfd5b
AD
6408 var elements = $(form).getElements().findAll(function(element) {
6409 return 'hidden' != element.type && !element.disabled;
6410 });
6411 var firstByIndex = elements.findAll(function(element) {
6412 return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
6413 }).sortBy(function(element) { return element.tabIndex }).first();
6414
6415 return firstByIndex ? firstByIndex : elements.find(function(element) {
85e836d8 6416 return /^(?:input|select|textarea)$/i.test(element.tagName);
14f69488
AD
6417 });
6418 },
6419
6420 focusFirstElement: function(form) {
5c656a9d 6421 form = $(form);
3fe38208
AD
6422 var element = form.findFirstElement();
6423 if (element) element.activate();
5c656a9d 6424 return form;
4b9dfd5b
AD
6425 },
6426
6427 request: function(form, options) {
6428 form = $(form), options = Object.clone(options || { });
5c656a9d 6429
4b9dfd5b
AD
6430 var params = options.parameters, action = form.readAttribute('action') || '';
6431 if (action.blank()) action = window.location.href;
6432 options.parameters = form.serialize(true);
6433
6434 if (params) {
6435 if (Object.isString(params)) params = params.toQueryParams();
6436 Object.extend(options.parameters, params);
6437 }
6438
6439 if (form.hasAttribute('method') && !options.method)
6440 options.method = form.method;
6441
6442 return new Ajax.Request(action, options);
6443 }
6444};
5c656a9d
AD
6445
6446/*--------------------------------------------------------------------------*/
6447
85e836d8 6448
5c656a9d
AD
6449Form.Element = {
6450 focus: function(element) {
6451 $(element).focus();
6452 return element;
14f69488
AD
6453 },
6454
5c656a9d
AD
6455 select: function(element) {
6456 $(element).select();
6457 return element;
14f69488 6458 }
4b9dfd5b 6459};
14f69488 6460
5c656a9d 6461Form.Element.Methods = {
85e836d8 6462
14f69488 6463 serialize: function(element) {
5c656a9d
AD
6464 element = $(element);
6465 if (!element.disabled && element.name) {
6466 var value = element.getValue();
6467 if (value != undefined) {
4b9dfd5b 6468 var pair = { };
5c656a9d 6469 pair[element.name] = value;
4b9dfd5b 6470 return Object.toQueryString(pair);
5c656a9d
AD
6471 }
6472 }
6473 return '';
6474 },
6475
6476 getValue: function(element) {
14f69488
AD
6477 element = $(element);
6478 var method = element.tagName.toLowerCase();
5c656a9d
AD
6479 return Form.Element.Serializers[method](element);
6480 },
14f69488 6481
4b9dfd5b
AD
6482 setValue: function(element, value) {
6483 element = $(element);
6484 var method = element.tagName.toLowerCase();
6485 Form.Element.Serializers[method](element, value);
6486 return element;
6487 },
6488
5c656a9d
AD
6489 clear: function(element) {
6490 $(element).value = '';
6491 return element;
6492 },
14f69488 6493
5c656a9d
AD
6494 present: function(element) {
6495 return $(element).value != '';
6496 },
14f69488 6497
5c656a9d
AD
6498 activate: function(element) {
6499 element = $(element);
4b9dfd5b
AD
6500 try {
6501 element.focus();
6502 if (element.select && (element.tagName.toLowerCase() != 'input' ||
85e836d8 6503 !(/^(?:button|reset|submit)$/i.test(element.type))))
4b9dfd5b
AD
6504 element.select();
6505 } catch (e) { }
5c656a9d 6506 return element;
14f69488
AD
6507 },
6508
5c656a9d 6509 disable: function(element) {
14f69488 6510 element = $(element);
5c656a9d
AD
6511 element.disabled = true;
6512 return element;
6513 },
14f69488 6514
5c656a9d
AD
6515 enable: function(element) {
6516 element = $(element);
5c656a9d
AD
6517 element.disabled = false;
6518 return element;
14f69488 6519 }
4b9dfd5b
AD
6520};
6521
6522/*--------------------------------------------------------------------------*/
14f69488 6523
5c656a9d 6524var Field = Form.Element;
85e836d8 6525
4b9dfd5b 6526var $F = Form.Element.Methods.getValue;
5c656a9d
AD
6527
6528/*--------------------------------------------------------------------------*/
6529
3fe38208
AD
6530Form.Element.Serializers = (function() {
6531 function input(element, value) {
14f69488 6532 switch (element.type.toLowerCase()) {
14f69488
AD
6533 case 'checkbox':
6534 case 'radio':
3fe38208 6535 return inputSelector(element, value);
5c656a9d 6536 default:
3fe38208 6537 return valueSelector(element, value);
14f69488 6538 }
3fe38208 6539 }
14f69488 6540
3fe38208
AD
6541 function inputSelector(element, value) {
6542 if (Object.isUndefined(value))
6543 return element.checked ? element.value : null;
4b9dfd5b 6544 else element.checked = !!value;
3fe38208 6545 }
14f69488 6546
3fe38208 6547 function valueSelector(element, value) {
4b9dfd5b
AD
6548 if (Object.isUndefined(value)) return element.value;
6549 else element.value = value;
3fe38208 6550 }
14f69488 6551
3fe38208 6552 function select(element, value) {
85e836d8 6553 if (Object.isUndefined(value))
3fe38208
AD
6554 return (element.type === 'select-one' ? selectOne : selectMany)(element);
6555
6556 var opt, currentValue, single = !Object.isArray(value);
6557 for (var i = 0, length = element.length; i < length; i++) {
6558 opt = element.options[i];
6559 currentValue = this.optionValue(opt);
6560 if (single) {
6561 if (currentValue == value) {
6562 opt.selected = true;
6563 return;
4b9dfd5b 6564 }
4b9dfd5b 6565 }
3fe38208 6566 else opt.selected = value.include(currentValue);
4b9dfd5b 6567 }
3fe38208 6568 }
14f69488 6569
3fe38208 6570 function selectOne(element) {
5c656a9d 6571 var index = element.selectedIndex;
3fe38208
AD
6572 return index >= 0 ? optionValue(element.options[index]) : null;
6573 }
14f69488 6574
3fe38208 6575 function selectMany(element) {
5c656a9d
AD
6576 var values, length = element.length;
6577 if (!length) return null;
6578
6579 for (var i = 0, values = []; i < length; i++) {
14f69488 6580 var opt = element.options[i];
3fe38208 6581 if (opt.selected) values.push(optionValue(opt));
14f69488 6582 }
5c656a9d 6583 return values;
3fe38208 6584 }
5c656a9d 6585
3fe38208
AD
6586 function optionValue(opt) {
6587 return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
14f69488 6588 }
3fe38208
AD
6589
6590 return {
6591 input: input,
6592 inputSelector: inputSelector,
6593 textarea: valueSelector,
6594 select: select,
6595 selectOne: selectOne,
6596 selectMany: selectMany,
6597 optionValue: optionValue,
6598 button: valueSelector
6599 };
6600})();
14f69488
AD
6601
6602/*--------------------------------------------------------------------------*/
6603
85e836d8 6604
4b9dfd5b
AD
6605Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
6606 initialize: function($super, element, frequency, callback) {
6607 $super(callback, frequency);
14f69488 6608 this.element = $(element);
14f69488 6609 this.lastValue = this.getValue();
14f69488
AD
6610 },
6611
4b9dfd5b
AD
6612 execute: function() {
6613 var value = this.getValue();
6614 if (Object.isString(this.lastValue) && Object.isString(value) ?
6615 this.lastValue != value : String(this.lastValue) != String(value)) {
6616 this.callback(this.element, value);
6617 this.lastValue = value;
6618 }
6619 }
6620});
6621
6622Form.Element.Observer = Class.create(Abstract.TimedObserver, {
6623 getValue: function() {
6624 return Form.Element.getValue(this.element);
6625 }
6626});
6627
6628Form.Observer = Class.create(Abstract.TimedObserver, {
6629 getValue: function() {
6630 return Form.serialize(this.element);
6631 }
6632});
6633
6634/*--------------------------------------------------------------------------*/
6635
6636Abstract.EventObserver = Class.create({
6637 initialize: function(element, callback) {
6638 this.element = $(element);
6639 this.callback = callback;
6640
6641 this.lastValue = this.getValue();
6642 if (this.element.tagName.toLowerCase() == 'form')
6643 this.registerFormCallbacks();
6644 else
6645 this.registerCallback(this.element);
14f69488
AD
6646 },
6647
4b9dfd5b 6648 onElementEvent: function() {
14f69488 6649 var value = this.getValue();
4b9dfd5b 6650 if (this.lastValue != value) {
14f69488
AD
6651 this.callback(this.element, value);
6652 this.lastValue = value;
6653 }
4b9dfd5b
AD
6654 },
6655
6656 registerFormCallbacks: function() {
6657 Form.getElements(this.element).each(this.registerCallback, this);
6658 },
6659
6660 registerCallback: function(element) {
6661 if (element.type) {
6662 switch (element.type.toLowerCase()) {
6663 case 'checkbox':
6664 case 'radio':
6665 Event.observe(element, 'click', this.onElementEvent.bind(this));
6666 break;
6667 default:
6668 Event.observe(element, 'change', this.onElementEvent.bind(this));
6669 break;
6670 }
6671 }
14f69488 6672 }
4b9dfd5b
AD
6673});
6674
6675Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
6676 getValue: function() {
6677 return Form.Element.getValue(this.element);
6678 }
6679});
6680
6681Form.EventObserver = Class.create(Abstract.EventObserver, {
6682 getValue: function() {
6683 return Form.serialize(this.element);
6684 }
6685});
e3cfa33b
AK
6686(function(GLOBAL) {
6687 var DIV = document.createElement('div');
6688 var docEl = document.documentElement;
6689 var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
6690 && 'onmouseleave' in docEl;
85e836d8
AD
6691
6692 var Event = {
6693 KEY_BACKSPACE: 8,
6694 KEY_TAB: 9,
6695 KEY_RETURN: 13,
6696 KEY_ESC: 27,
6697 KEY_LEFT: 37,
6698 KEY_UP: 38,
6699 KEY_RIGHT: 39,
6700 KEY_DOWN: 40,
6701 KEY_DELETE: 46,
6702 KEY_HOME: 36,
6703 KEY_END: 35,
6704 KEY_PAGEUP: 33,
6705 KEY_PAGEDOWN: 34,
e3cfa33b 6706 KEY_INSERT: 45
85e836d8 6707 };
4b9dfd5b 6708
3fe38208
AD
6709
6710 var isIELegacyEvent = function(event) { return false; };
6711
6712 if (window.attachEvent) {
6713 if (window.addEventListener) {
6714 isIELegacyEvent = function(event) {
6715 return !(event instanceof window.Event);
6716 };
6717 } else {
6718 isIELegacyEvent = function(event) { return true; };
6719 }
6720 }
6721
85e836d8 6722 var _isButton;
3fe38208
AD
6723
6724 function _isButtonForDOMEvents(event, code) {
6725 return event.which ? (event.which === code + 1) : (event.button === code);
6726 }
6727
6728 var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
6729 function _isButtonForLegacyEvents(event, code) {
6730 return event.button === legacyButtonMap[code];
6731 }
6732
6733 function _isButtonForWebKit(event, code) {
6734 switch (code) {
6735 case 0: return event.which == 1 && !event.metaKey;
6736 case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
6737 case 2: return event.which == 3;
6738 default: return false;
6739 }
6740 }
6741
6742 if (window.attachEvent) {
6743 if (!window.addEventListener) {
6744 _isButton = _isButtonForLegacyEvents;
6745 } else {
6746 _isButton = function(event, code) {
6747 return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
6748 _isButtonForDOMEvents(event, code);
4b9dfd5b 6749 }
3fe38208
AD
6750 }
6751 } else if (Prototype.Browser.WebKit) {
6752 _isButton = _isButtonForWebKit;
4b9dfd5b 6753 } else {
3fe38208 6754 _isButton = _isButtonForDOMEvents;
4b9dfd5b
AD
6755 }
6756
85e836d8 6757 function isLeftClick(event) { return _isButton(event, 0) }
4b9dfd5b 6758
85e836d8 6759 function isMiddleClick(event) { return _isButton(event, 1) }
4b9dfd5b 6760
85e836d8 6761 function isRightClick(event) { return _isButton(event, 2) }
4b9dfd5b 6762
85e836d8 6763 function element(event) {
e3cfa33b
AK
6764 return Element.extend(_element(event));
6765 }
6766
6767 function _element(event) {
85e836d8 6768 event = Event.extend(event);
4b9dfd5b 6769
85e836d8
AD
6770 var node = event.target, type = event.type,
6771 currentTarget = event.currentTarget;
4b9dfd5b 6772
85e836d8
AD
6773 if (currentTarget && currentTarget.tagName) {
6774 if (type === 'load' || type === 'error' ||
6775 (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
6776 && currentTarget.type === 'radio'))
6777 node = currentTarget;
4b9dfd5b 6778 }
85e836d8 6779
e3cfa33b 6780 return node.nodeType == Node.TEXT_NODE ? node.parentNode : node;
85e836d8
AD
6781 }
6782
6783 function findElement(event, expression) {
e3cfa33b
AK
6784 var element = _element(event), selector = Prototype.Selector;
6785 if (!expression) return Element.extend(element);
3fe38208 6786 while (element) {
e3cfa33b 6787 if (Object.isElement(element) && selector.match(element, expression))
3fe38208 6788 return Element.extend(element);
3fe38208
AD
6789 element = element.parentNode;
6790 }
85e836d8
AD
6791 }
6792
6793 function pointer(event) {
6794 return { x: pointerX(event), y: pointerY(event) };
6795 }
6796
6797 function pointerX(event) {
6798 var docElement = document.documentElement,
6799 body = document.body || { scrollLeft: 0 };
6800
6801 return event.pageX || (event.clientX +
6802 (docElement.scrollLeft || body.scrollLeft) -
6803 (docElement.clientLeft || 0));
6804 }
6805
6806 function pointerY(event) {
6807 var docElement = document.documentElement,
6808 body = document.body || { scrollTop: 0 };
6809
6810 return event.pageY || (event.clientY +
6811 (docElement.scrollTop || body.scrollTop) -
6812 (docElement.clientTop || 0));
6813 }
6814
6815
6816 function stop(event) {
6817 Event.extend(event);
6818 event.preventDefault();
6819 event.stopPropagation();
6820
6821 event.stopped = true;
6822 }
6823
3fe38208 6824
85e836d8 6825 Event.Methods = {
3fe38208 6826 isLeftClick: isLeftClick,
85e836d8 6827 isMiddleClick: isMiddleClick,
3fe38208 6828 isRightClick: isRightClick,
85e836d8 6829
3fe38208 6830 element: element,
85e836d8
AD
6831 findElement: findElement,
6832
3fe38208 6833 pointer: pointer,
85e836d8
AD
6834 pointerX: pointerX,
6835 pointerY: pointerY,
6836
6837 stop: stop
4b9dfd5b 6838 };
4b9dfd5b 6839
4b9dfd5b
AD
6840 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
6841 m[name] = Event.Methods[name].methodize();
6842 return m;
6843 });
6844
3fe38208 6845 if (window.attachEvent) {
85e836d8
AD
6846 function _relatedTarget(event) {
6847 var element;
6848 switch (event.type) {
3fe38208
AD
6849 case 'mouseover':
6850 case 'mouseenter':
6851 element = event.fromElement;
6852 break;
6853 case 'mouseout':
6854 case 'mouseleave':
6855 element = event.toElement;
6856 break;
6857 default:
6858 return null;
85e836d8
AD
6859 }
6860 return Element.extend(element);
6861 }
6862
3fe38208 6863 var additionalMethods = {
4b9dfd5b
AD
6864 stopPropagation: function() { this.cancelBubble = true },
6865 preventDefault: function() { this.returnValue = false },
85e836d8 6866 inspect: function() { return '[object Event]' }
3fe38208 6867 };
4b9dfd5b 6868
85e836d8 6869 Event.extend = function(event, element) {
4b9dfd5b 6870 if (!event) return false;
4b9dfd5b 6871
3fe38208
AD
6872 if (!isIELegacyEvent(event)) return event;
6873
6874 if (event._extendedByPrototype) return event;
4b9dfd5b 6875 event._extendedByPrototype = Prototype.emptyFunction;
3fe38208 6876
4b9dfd5b 6877 var pointer = Event.pointer(event);
85e836d8 6878
4b9dfd5b 6879 Object.extend(event, {
85e836d8
AD
6880 target: event.srcElement || element,
6881 relatedTarget: _relatedTarget(event),
4b9dfd5b
AD
6882 pageX: pointer.x,
6883 pageY: pointer.y
6884 });
85e836d8 6885
3fe38208
AD
6886 Object.extend(event, methods);
6887 Object.extend(event, additionalMethods);
6888
6889 return event;
4b9dfd5b 6890 };
4b9dfd5b 6891 } else {
3fe38208
AD
6892 Event.extend = Prototype.K;
6893 }
6894
6895 if (window.addEventListener) {
85e836d8 6896 Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
4b9dfd5b 6897 Object.extend(Event.prototype, methods);
4b9dfd5b 6898 }
4b9dfd5b 6899
e3cfa33b
AK
6900 var EVENT_TRANSLATIONS = {
6901 mouseenter: 'mouseover',
6902 mouseleave: 'mouseout'
6903 };
4b9dfd5b 6904
e3cfa33b
AK
6905 function getDOMEventName(eventName) {
6906 return EVENT_TRANSLATIONS[eventName] || eventName;
6907 }
4b9dfd5b 6908
e3cfa33b
AK
6909 if (MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED)
6910 getDOMEventName = Prototype.K;
4b9dfd5b 6911
e3cfa33b
AK
6912 function getUniqueElementID(element) {
6913 if (element === window) return 0;
4b9dfd5b 6914
e3cfa33b
AK
6915 if (typeof element._prototypeUID === 'undefined')
6916 element._prototypeUID = Element.Storage.UID++;
6917 return element._prototypeUID;
6918 }
4b9dfd5b 6919
e3cfa33b
AK
6920 function getUniqueElementID_IE(element) {
6921 if (element === window) return 0;
6922 if (element == document) return 1;
6923 return element.uniqueID;
6924 }
4b9dfd5b 6925
e3cfa33b
AK
6926 if ('uniqueID' in DIV)
6927 getUniqueElementID = getUniqueElementID_IE;
4b9dfd5b 6928
e3cfa33b
AK
6929 function isCustomEvent(eventName) {
6930 return eventName.include(':');
4b9dfd5b
AD
6931 }
6932
e3cfa33b 6933 Event._isCustomEvent = isCustomEvent;
4b9dfd5b 6934
e3cfa33b
AK
6935 function getOrCreateRegistryFor(element, uid) {
6936 var CACHE = GLOBAL.Event.cache;
6937 if (Object.isUndefined(uid))
6938 uid = getUniqueElementID(element);
6939 if (!CACHE[uid]) CACHE[uid] = { element: element };
6940 return CACHE[uid];
6941 }
85e836d8 6942
e3cfa33b
AK
6943 function destroyRegistryForElement(element, uid) {
6944 if (Object.isUndefined(uid))
6945 uid = getUniqueElementID(element);
6946 delete GLOBAL.Event.cache[uid];
6947 }
85e836d8 6948
85e836d8 6949
e3cfa33b
AK
6950 function register(element, eventName, handler) {
6951 var registry = getOrCreateRegistryFor(element);
6952 if (!registry[eventName]) registry[eventName] = [];
6953 var entries = registry[eventName];
85e836d8 6954
e3cfa33b
AK
6955 var i = entries.length;
6956 while (i--)
6957 if (entries[i].handler === handler) return null;
85e836d8 6958
e3cfa33b
AK
6959 var uid = getUniqueElementID(element);
6960 var responder = GLOBAL.Event._createResponder(uid, eventName, handler);
6961 var entry = {
6962 responder: responder,
6963 handler: handler
85e836d8 6964 };
e3cfa33b
AK
6965
6966 entries.push(entry);
6967 return entry;
4b9dfd5b
AD
6968 }
6969
e3cfa33b
AK
6970 function unregister(element, eventName, handler) {
6971 var registry = getOrCreateRegistryFor(element);
6972 var entries = registry[eventName] || [];
6973
6974 var i = entries.length, entry;
6975 while (i--) {
6976 if (entries[i].handler === handler) {
6977 entry = entries[i];
6978 break;
6979 }
6980 }
6981
6982 if (entry) {
6983 var index = entries.indexOf(entry);
6984 entries.splice(index, 1);
6985 }
6986
6987 if (entries.length === 0) {
6988 delete registry[eventName];
6989 if (Object.keys(registry).length === 1 && ('element' in registry))
6990 destroyRegistryForElement(element);
6991 }
6992
6993 return entry;
6994 }
6995
6996
85e836d8
AD
6997 function observe(element, eventName, handler) {
6998 element = $(element);
e3cfa33b 6999 var entry = register(element, eventName, handler);
4b9dfd5b 7000
e3cfa33b 7001 if (entry === null) return element;
4b9dfd5b 7002
e3cfa33b
AK
7003 var responder = entry.responder;
7004 if (isCustomEvent(eventName))
7005 observeCustomEvent(element, eventName, responder);
7006 else
7007 observeStandardEvent(element, eventName, responder);
85e836d8 7008
e3cfa33b
AK
7009 return element;
7010 }
4b9dfd5b 7011
e3cfa33b
AK
7012 function observeStandardEvent(element, eventName, responder) {
7013 var actualEventName = getDOMEventName(eventName);
7014 if (element.addEventListener) {
7015 element.addEventListener(actualEventName, responder, false);
7016 } else {
7017 element.attachEvent('on' + actualEventName, responder);
85e836d8 7018 }
e3cfa33b 7019 }
4b9dfd5b 7020
e3cfa33b
AK
7021 function observeCustomEvent(element, eventName, responder) {
7022 if (element.addEventListener) {
7023 element.addEventListener('dataavailable', responder, false);
7024 } else {
7025 element.attachEvent('ondataavailable', responder);
7026 element.attachEvent('onlosecapture', responder);
7027 }
85e836d8 7028 }
4b9dfd5b 7029
85e836d8
AD
7030 function stopObserving(element, eventName, handler) {
7031 element = $(element);
e3cfa33b
AK
7032 var handlerGiven = !Object.isUndefined(handler),
7033 eventNameGiven = !Object.isUndefined(eventName);
14f69488 7034
e3cfa33b
AK
7035 if (!eventNameGiven && !handlerGiven) {
7036 stopObservingElement(element);
85e836d8
AD
7037 return element;
7038 }
14f69488 7039
e3cfa33b
AK
7040 if (!handlerGiven) {
7041 stopObservingEventName(element, eventName);
3fe38208
AD
7042 return element;
7043 }
4b9dfd5b 7044
e3cfa33b
AK
7045 var entry = unregister(element, eventName, handler);
7046
7047 if (!entry) return element;
7048 removeEvent(element, eventName, entry.responder);
7049 return element;
7050 }
7051
7052 function stopObservingStandardEvent(element, eventName, responder) {
7053 var actualEventName = getDOMEventName(eventName);
7054 if (element.removeEventListener) {
7055 element.removeEventListener(actualEventName, responder, false);
7056 } else {
7057 element.detachEvent('on' + actualEventName, responder);
3fe38208 7058 }
e3cfa33b 7059 }
85e836d8 7060
e3cfa33b
AK
7061 function stopObservingCustomEvent(element, eventName, responder) {
7062 if (element.removeEventListener) {
7063 element.removeEventListener('dataavailable', responder, false);
85e836d8 7064 } else {
e3cfa33b
AK
7065 element.detachEvent('ondataavailable', responder);
7066 element.detachEvent('onlosecapture', responder);
85e836d8 7067 }
e3cfa33b 7068 }
85e836d8 7069
85e836d8 7070
e3cfa33b
AK
7071
7072 function stopObservingElement(element) {
7073 var uid = getUniqueElementID(element), registry = GLOBAL.Event.cache[uid];
7074 if (!registry) return;
7075
7076 destroyRegistryForElement(element, uid);
7077
7078 var entries, i;
7079 for (var eventName in registry) {
7080 if (eventName === 'element') continue;
7081
7082 entries = registry[eventName];
7083 i = entries.length;
7084 while (i--)
7085 removeEvent(element, eventName, entries[i].responder);
7086 }
85e836d8
AD
7087 }
7088
e3cfa33b
AK
7089 function stopObservingEventName(element, eventName) {
7090 var registry = getOrCreateRegistryFor(element);
7091 var entries = registry[eventName];
7092 if (entries) {
7093 delete registry[eventName];
7094 }
85e836d8 7095
e3cfa33b 7096 entries = entries || [];
4b9dfd5b 7097
e3cfa33b
AK
7098 var i = entries.length;
7099 while (i--)
7100 removeEvent(element, eventName, entries[i].responder);
85e836d8 7101
e3cfa33b
AK
7102 for (var name in registry) {
7103 if (name === 'element') continue;
7104 return; // There is another registered event
14f69488 7105 }
14f69488 7106
e3cfa33b
AK
7107 destroyRegistryForElement(element);
7108 }
4b9dfd5b 7109
e3cfa33b
AK
7110
7111 function removeEvent(element, eventName, handler) {
7112 if (isCustomEvent(eventName))
7113 stopObservingCustomEvent(element, eventName, handler);
85e836d8 7114 else
e3cfa33b
AK
7115 stopObservingStandardEvent(element, eventName, handler);
7116 }
7117
7118
14f69488 7119
e3cfa33b
AK
7120 function getFireTarget(element) {
7121 if (element !== document) return element;
7122 if (document.createEvent && !element.dispatchEvent)
7123 return document.documentElement;
7124 return element;
7125 }
7126
7127 function fire(element, eventName, memo, bubble) {
7128 element = getFireTarget($(element));
7129 if (Object.isUndefined(bubble)) bubble = true;
7130 memo = memo || {};
7131
7132 var event = fireEvent(element, eventName, memo, bubble);
85e836d8
AD
7133 return Event.extend(event);
7134 }
7135
e3cfa33b
AK
7136 function fireEvent_DOM(element, eventName, memo, bubble) {
7137 var event = document.createEvent('HTMLEvents');
7138 event.initEvent('dataavailable', bubble, true);
7139
7140 event.eventName = eventName;
7141 event.memo = memo;
7142
7143 element.dispatchEvent(event);
7144 return event;
7145 }
7146
7147 function fireEvent_IE(element, eventName, memo, bubble) {
7148 var event = document.createEventObject();
7149 event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
7150
7151 event.eventName = eventName;
7152 event.memo = memo;
7153
7154 element.fireEvent(event.eventType, event);
7155 return event;
7156 }
7157
7158 var fireEvent = document.createEvent ? fireEvent_DOM : fireEvent_IE;
7159
7160
7161
3fe38208
AD
7162 Event.Handler = Class.create({
7163 initialize: function(element, eventName, selector, callback) {
7164 this.element = $(element);
7165 this.eventName = eventName;
7166 this.selector = selector;
7167 this.callback = callback;
7168 this.handler = this.handleEvent.bind(this);
7169 },
7170
e3cfa33b 7171
3fe38208
AD
7172 start: function() {
7173 Event.observe(this.element, this.eventName, this.handler);
7174 return this;
7175 },
7176
7177 stop: function() {
7178 Event.stopObserving(this.element, this.eventName, this.handler);
7179 return this;
7180 },
7181
7182 handleEvent: function(event) {
7183 var element = Event.findElement(event, this.selector);
7184 if (element) this.callback.call(this.element, event, element);
7185 }
7186 });
7187
7188 function on(element, eventName, selector, callback) {
7189 element = $(element);
7190 if (Object.isFunction(selector) && Object.isUndefined(callback)) {
7191 callback = selector, selector = null;
7192 }
7193
7194 return new Event.Handler(element, eventName, selector, callback).start();
7195 }
85e836d8
AD
7196
7197 Object.extend(Event, Event.Methods);
7198
7199 Object.extend(Event, {
7200 fire: fire,
7201 observe: observe,
3fe38208
AD
7202 stopObserving: stopObserving,
7203 p_on: on
85e836d8
AD
7204 });
7205
7206 Element.addMethods({
7207 fire: fire,
7208
7209 observe: observe,
7210
3fe38208
AD
7211 stopObserving: stopObserving,
7212
7213 p_on: on
85e836d8
AD
7214 });
7215
7216 Object.extend(document, {
7217 fire: fire.methodize(),
7218
7219 observe: observe.methodize(),
7220
7221 stopObserving: stopObserving.methodize(),
7222
3fe38208
AD
7223 p_on: on.methodize(),
7224
85e836d8
AD
7225 loaded: false
7226 });
7227
e3cfa33b
AK
7228 if (GLOBAL.Event) Object.extend(window.Event, Event);
7229 else GLOBAL.Event = Event;
14f69488 7230
e3cfa33b
AK
7231 GLOBAL.Event.cache = {};
7232
7233 function destroyCache_IE() {
7234 GLOBAL.Event.cache = null;
7235 }
7236
7237 if (window.attachEvent)
7238 window.attachEvent('onunload', destroyCache_IE);
7239
7240 DIV = null;
7241 docEl = null;
7242})(this);
7243
7244(function(GLOBAL) {
7245 /* Code for creating leak-free event responders is based on work by
7246 John-David Dalton. */
7247
7248 var docEl = document.documentElement;
7249 var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
7250 && 'onmouseleave' in docEl;
7251
7252 function isSimulatedMouseEnterLeaveEvent(eventName) {
7253 return !MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
7254 (eventName === 'mouseenter' || eventName === 'mouseleave');
7255 }
7256
7257 function createResponder(uid, eventName, handler) {
7258 if (Event._isCustomEvent(eventName))
7259 return createResponderForCustomEvent(uid, eventName, handler);
7260 if (isSimulatedMouseEnterLeaveEvent(eventName))
7261 return createMouseEnterLeaveResponder(uid, eventName, handler);
7262
7263 return function(event) {
7264 if (!Event.cache) return;
7265
7266 var element = Event.cache[uid].element;
7267 Event.extend(event, element);
7268 handler.call(element, event);
7269 };
7270 }
7271
7272 function createResponderForCustomEvent(uid, eventName, handler) {
7273 return function(event) {
7274 var cache = Event.cache[uid];
7275 var element = cache && cache.element;
7276
7277 if (Object.isUndefined(event.eventName))
7278 return false;
7279
7280 if (event.eventName !== eventName)
7281 return false;
7282
7283 Event.extend(event, element);
7284 handler.call(element, event);
7285 };
7286 }
7287
7288 function createMouseEnterLeaveResponder(uid, eventName, handler) {
7289 return function(event) {
7290 var element = Event.cache[uid].element;
7291
7292 Event.extend(event, element);
7293 var parent = event.relatedTarget;
7294
7295 while (parent && parent !== element) {
7296 try { parent = parent.parentNode; }
7297 catch(e) { parent = element; }
7298 }
7299
7300 if (parent === element) return;
7301 handler.call(element, event);
7302 }
7303 }
7304
7305 GLOBAL.Event._createResponder = createResponder;
7306 docEl = null;
7307})(this);
7308
7309(function(GLOBAL) {
4b9dfd5b 7310 /* Support for the DOMContentLoaded event is based on work by Dan Webb,
85e836d8 7311 Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
14f69488 7312
e3cfa33b 7313 var TIMER;
14f69488 7314
4b9dfd5b
AD
7315 function fireContentLoadedEvent() {
7316 if (document.loaded) return;
e3cfa33b 7317 if (TIMER) window.clearTimeout(TIMER);
4b9dfd5b 7318 document.loaded = true;
85e836d8 7319 document.fire('dom:loaded');
4b9dfd5b 7320 }
14f69488 7321
85e836d8
AD
7322 function checkReadyState() {
7323 if (document.readyState === 'complete') {
e3cfa33b 7324 document.detachEvent('onreadystatechange', checkReadyState);
85e836d8
AD
7325 fireContentLoadedEvent();
7326 }
7327 }
14f69488 7328
85e836d8 7329 function pollDoScroll() {
e3cfa33b
AK
7330 try {
7331 document.documentElement.doScroll('left');
7332 } catch (e) {
7333 TIMER = pollDoScroll.defer();
85e836d8 7334 return;
14f69488 7335 }
e3cfa33b
AK
7336
7337 fireContentLoadedEvent();
7338 }
7339
7340
7341 if (document.readyState === 'complete') {
85e836d8 7342 fireContentLoadedEvent();
e3cfa33b 7343 return;
85e836d8 7344 }
14f69488 7345
85e836d8
AD
7346 if (document.addEventListener) {
7347 document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
4b9dfd5b 7348 } else {
e3cfa33b
AK
7349 document.attachEvent('onreadystatechange', checkReadyState);
7350 if (window == top) TIMER = pollDoScroll.defer();
4b9dfd5b 7351 }
85e836d8
AD
7352
7353 Event.observe(window, 'load', fireContentLoadedEvent);
e3cfa33b 7354})(this);
85e836d8 7355
85e836d8 7356
e3cfa33b 7357Element.addMethods();
4b9dfd5b 7358/*------------------------------- DEPRECATED -------------------------------*/
14f69488 7359
4b9dfd5b 7360Hash.toQueryString = Object.toQueryString;
14f69488 7361
4b9dfd5b 7362var Toggle = { display: Element.toggle };
14f69488 7363
e3cfa33b
AK
7364Element.addMethods({
7365 childOf: Element.Methods.descendantOf
7366});
14f69488 7367
4b9dfd5b
AD
7368var Insertion = {
7369 Before: function(element, content) {
7370 return Element.insert(element, {before:content});
14f69488
AD
7371 },
7372
4b9dfd5b
AD
7373 Top: function(element, content) {
7374 return Element.insert(element, {top:content});
7375 },
14f69488 7376
4b9dfd5b
AD
7377 Bottom: function(element, content) {
7378 return Element.insert(element, {bottom:content});
7379 },
14f69488 7380
4b9dfd5b
AD
7381 After: function(element, content) {
7382 return Element.insert(element, {after:content});
14f69488 7383 }
4b9dfd5b
AD
7384};
7385
7386var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
14f69488 7387
14f69488 7388var Position = {
14f69488
AD
7389 includeScrollOffsets: false,
7390
14f69488
AD
7391 prepare: function() {
7392 this.deltaX = window.pageXOffset
7393 || document.documentElement.scrollLeft
7394 || document.body.scrollLeft
7395 || 0;
7396 this.deltaY = window.pageYOffset
7397 || document.documentElement.scrollTop
7398 || document.body.scrollTop
7399 || 0;
7400 },
7401
14f69488
AD
7402 within: function(element, x, y) {
7403 if (this.includeScrollOffsets)
7404 return this.withinIncludingScrolloffsets(element, x, y);
7405 this.xcomp = x;
7406 this.ycomp = y;
4b9dfd5b 7407 this.offset = Element.cumulativeOffset(element);
14f69488
AD
7408
7409 return (y >= this.offset[1] &&
7410 y < this.offset[1] + element.offsetHeight &&
7411 x >= this.offset[0] &&
7412 x < this.offset[0] + element.offsetWidth);
7413 },
7414
7415 withinIncludingScrolloffsets: function(element, x, y) {
4b9dfd5b 7416 var offsetcache = Element.cumulativeScrollOffset(element);
14f69488
AD
7417
7418 this.xcomp = x + offsetcache[0] - this.deltaX;
7419 this.ycomp = y + offsetcache[1] - this.deltaY;
4b9dfd5b 7420 this.offset = Element.cumulativeOffset(element);
14f69488
AD
7421
7422 return (this.ycomp >= this.offset[1] &&
7423 this.ycomp < this.offset[1] + element.offsetHeight &&
7424 this.xcomp >= this.offset[0] &&
7425 this.xcomp < this.offset[0] + element.offsetWidth);
7426 },
7427
14f69488
AD
7428 overlap: function(mode, element) {
7429 if (!mode) return 0;
7430 if (mode == 'vertical')
7431 return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
7432 element.offsetHeight;
7433 if (mode == 'horizontal')
7434 return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
7435 element.offsetWidth;
7436 },
7437
14f69488 7438
4b9dfd5b 7439 cumulativeOffset: Element.Methods.cumulativeOffset,
14f69488 7440
4b9dfd5b 7441 positionedOffset: Element.Methods.positionedOffset,
14f69488 7442
4b9dfd5b
AD
7443 absolutize: function(element) {
7444 Position.prepare();
7445 return Element.absolutize(element);
7446 },
14f69488 7447
4b9dfd5b
AD
7448 relativize: function(element) {
7449 Position.prepare();
7450 return Element.relativize(element);
14f69488
AD
7451 },
7452
4b9dfd5b 7453 realOffset: Element.Methods.cumulativeScrollOffset,
14f69488 7454
4b9dfd5b 7455 offsetParent: Element.Methods.getOffsetParent,
14f69488 7456
4b9dfd5b 7457 page: Element.Methods.viewportOffset,
14f69488 7458
4b9dfd5b
AD
7459 clone: function(source, target, options) {
7460 options = options || { };
7461 return Element.clonePosition(target, source, options);
7462 }
7463};
7464
7465/*--------------------------------------------------------------------------*/
7466
7467if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
7468 function iter(name) {
7469 return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
7470 }
7471
7472 instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
7473 function(element, className) {
7474 className = className.toString().strip();
7475 var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
7476 return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
7477 } : function(element, className) {
7478 className = className.toString().strip();
7479 var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
7480 if (!classNames && !className) return elements;
7481
7482 var nodes = $(element).getElementsByTagName('*');
7483 className = ' ' + className + ' ';
7484
7485 for (var i = 0, child, cn; child = nodes[i]; i++) {
7486 if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
7487 (classNames && classNames.all(function(name) {
7488 return !name.toString().blank() && cn.include(' ' + name + ' ');
7489 }))))
7490 elements.push(Element.extend(child));
14f69488 7491 }
4b9dfd5b
AD
7492 return elements;
7493 };
14f69488 7494
4b9dfd5b
AD
7495 return function(className, parentElement) {
7496 return $(parentElement || document.body).getElementsByClassName(className);
7497 };
7498}(Element.Methods);
14f69488 7499
4b9dfd5b 7500/*--------------------------------------------------------------------------*/
14f69488 7501
4b9dfd5b
AD
7502Element.ClassNames = Class.create();
7503Element.ClassNames.prototype = {
7504 initialize: function(element) {
7505 this.element = $(element);
7506 },
14f69488 7507
e3cfa33b 7508 _each: function(iterator, context) {
4b9dfd5b
AD
7509 this.element.className.split(/\s+/).select(function(name) {
7510 return name.length > 0;
e3cfa33b 7511 })._each(iterator, context);
4b9dfd5b 7512 },
14f69488 7513
4b9dfd5b
AD
7514 set: function(className) {
7515 this.element.className = className;
14f69488
AD
7516 },
7517
4b9dfd5b
AD
7518 add: function(classNameToAdd) {
7519 if (this.include(classNameToAdd)) return;
7520 this.set($A(this).concat(classNameToAdd).join(' '));
7521 },
14f69488 7522
4b9dfd5b
AD
7523 remove: function(classNameToRemove) {
7524 if (!this.include(classNameToRemove)) return;
7525 this.set($A(this).without(classNameToRemove).join(' '));
7526 },
14f69488 7527
4b9dfd5b
AD
7528 toString: function() {
7529 return $A(this).join(' ');
14f69488 7530 }
4b9dfd5b 7531};
14f69488 7532
4b9dfd5b 7533Object.extend(Element.ClassNames.prototype, Enumerable);
14f69488 7534
4b9dfd5b 7535/*--------------------------------------------------------------------------*/
3fe38208
AD
7536
7537(function() {
7538 window.Selector = Class.create({
7539 initialize: function(expression) {
7540 this.expression = expression.strip();
7541 },
7542
7543 findElements: function(rootElement) {
7544 return Prototype.Selector.select(this.expression, rootElement);
7545 },
7546
7547 match: function(element) {
7548 return Prototype.Selector.match(element, this.expression);
7549 },
7550
7551 toString: function() {
7552 return this.expression;
7553 },
7554
7555 inspect: function() {
7556 return "#<Selector: " + this.expression + ">";
7557 }
7558 });
7559
7560 Object.extend(Selector, {
7561 matchElements: function(elements, expression) {
7562 var match = Prototype.Selector.match,
7563 results = [];
7564
7565 for (var i = 0, length = elements.length; i < length; i++) {
7566 var element = elements[i];
7567 if (match(element, expression)) {
7568 results.push(Element.extend(element));
7569 }
7570 }
7571 return results;
7572 },
7573
7574 findElement: function(elements, expression, index) {
7575 index = index || 0;
7576 var matchIndex = 0, element;
7577 for (var i = 0, length = elements.length; i < length; i++) {
7578 element = elements[i];
7579 if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
7580 return Element.extend(element);
7581 }
7582 }
7583 },
7584
7585 findChildElements: function(element, expressions) {
7586 var selector = expressions.toArray().join(', ');
7587 return Prototype.Selector.select(selector, element || document);
7588 }
7589 });
7590})();