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