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