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