1/* Prototype JavaScript framework, version 1.7 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', 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>', 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 63 64var Abstract = { }; 65 66 67var Try = { 68 these: function() { 69 var returnValue; 70 71 for (var i = 0, length = arguments.length; i < length; i++) { 72 var lambda = arguments[i]; 73 try { 74 returnValue = lambda(); 75 break; 76 } catch (e) { } 77 } 78 79 return returnValue; 80 } 81}; 82 83/* Based on Alex Arnell's inheritance implementation. */ 84 85var Class = (function() { 86 87 var IS_DONTENUM_BUGGY = (function(){ 88 for (var p in { toString: 1 }) { 89 if (p === 'toString') return false; 90 } 91 return true; 92 })(); 93 94 function subclass() {}; 95 function create() { 96 var parent = null, properties = $A(arguments); 97 if (Object.isFunction(properties[0])) 98 parent = properties.shift(); 99 100 function klass() { 101 this.initialize.apply(this, arguments); 102 } 103 104 Object.extend(klass, Class.Methods); 105 klass.superclass = parent; 106 klass.subclasses = []; 107 108 if (parent) { 109 subclass.prototype = parent.prototype; 110 klass.prototype = new subclass; 111 parent.subclasses.push(klass); 112 } 113 114 for (var i = 0, length = properties.length; i < length; i++) 115 klass.addMethods(properties[i]); 116 117 if (!klass.prototype.initialize) 118 klass.prototype.initialize = Prototype.emptyFunction; 119 120 klass.prototype.constructor = klass; 121 return klass; 122 } 123 124 function addMethods(source) { 125 var ancestor = this.superclass && this.superclass.prototype, 126 properties = Object.keys(source); 127 128 if (IS_DONTENUM_BUGGY) { 129 if (source.toString != Object.prototype.toString) 130 properties.push("toString"); 131 if (source.valueOf != Object.prototype.valueOf) 132 properties.push("valueOf"); 133 } 134 135 for (var i = 0, length = properties.length; i < length; i++) { 136 var property = properties[i], value = source[property]; 137 if (ancestor && Object.isFunction(value) && 138 value.argumentNames()[0] == "$super") { 139 var method = value; 140 value = (function(m) { 141 return function() { return ancestor[m].apply(this, arguments); }; 142 })(property).wrap(method); 143 144 value.valueOf = method.valueOf.bind(method); 145 value.toString = method.toString.bind(method); 146 } 147 this.prototype[property] = value; 148 } 149 150 return this; 151 } 152 153 return { 154 create: create, 155 Methods: { 156 addMethods: addMethods 157 } 158 }; 159})(); 160(function() { 161 162 var _toString = Object.prototype.toString, 163 NULL_TYPE = 'Null', 164 UNDEFINED_TYPE = 'Undefined', 165 BOOLEAN_TYPE = 'Boolean', 166 NUMBER_TYPE = 'Number', 167 STRING_TYPE = 'String', 168 OBJECT_TYPE = 'Object', 169 FUNCTION_CLASS = '[object Function]', 170 BOOLEAN_CLASS = '[object Boolean]', 171 NUMBER_CLASS = '[object Number]', 172 STRING_CLASS = '[object String]', 173 ARRAY_CLASS = '[object Array]', 174 DATE_CLASS = '[object Date]', 175 NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON && 176 typeof JSON.stringify === 'function' && 177 JSON.stringify(0) === '0' && 178 typeof JSON.stringify(Prototype.K) === 'undefined'; 179 180 function Type(o) { 181 switch(o) { 182 case null: return NULL_TYPE; 183 case (void 0): return UNDEFINED_TYPE; 184 } 185 var type = typeof o; 186 switch(type) { 187 case 'boolean': return BOOLEAN_TYPE; 188 case 'number': return NUMBER_TYPE; 189 case 'string': return STRING_TYPE; 190 } 191 return OBJECT_TYPE; 192 } 193 194 function extend(destination, source) { 195 for (var property in source) 196 destination[property] = source[property]; 197 return destination; 198 } 199 200 function inspect(object) { 201 try { 202 if (isUndefined(object)) return 'undefined'; 203 if (object === null) return 'null'; 204 return object.inspect ? object.inspect() : String(object); 205 } catch (e) { 206 if (e instanceof RangeError) return '...'; 207 throw e; 208 } 209 } 210 211 function toJSON(value) { 212 return Str('', { '': value }, []); 213 } 214 215 function Str(key, holder, stack) { 216 var value = holder[key], 217 type = typeof value; 218 219 if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { 220 value = value.toJSON(key); 221 } 222 223 var _class = _toString.call(value); 224 225 switch (_class) { 226 case NUMBER_CLASS: 227 case BOOLEAN_CLASS: 228 case STRING_CLASS: 229 value = value.valueOf(); 230 } 231 232 switch (value) { 233 case null: return 'null'; 234 case true: return 'true'; 235 case false: return 'false'; 236 } 237 238 type = typeof value; 239 switch (type) { 240 case 'string': 241 return value.inspect(true); 242 case 'number': 243 return isFinite(value) ? String(value) : 'null'; 244 case 'object': 245 246 for (var i = 0, length = stack.length; i < length; i++) { 247 if (stack[i] === value) { throw new TypeError(); } 248 } 249 stack.push(value); 250 251 var partial = []; 252 if (_class === ARRAY_CLASS) { 253 for (var i = 0, length = value.length; i < length; i++) { 254 var str = Str(i, value, stack); 255 partial.push(typeof str === 'undefined' ? 'null' : str); 256 } 257 partial = '[' + partial.join(',') + ']'; 258 } else { 259 var keys = Object.keys(value); 260 for (var i = 0, length = keys.length; i < length; i++) { 261 var key = keys[i], str = Str(key, value, stack); 262 if (typeof str !== "undefined") { 263 partial.push(key.inspect(true)+ ':' + str); 264 } 265 } 266 partial = '{' + partial.join(',') + '}'; 267 } 268 stack.pop(); 269 return partial; 270 } 271 } 272 273 function stringify(object) { 274 return JSON.stringify(object); 275 } 276 277 function toQueryString(object) { 278 return $H(object).toQueryString(); 279 } 280 281 function toHTML(object) { 282 return object && object.toHTML ? object.toHTML() : String.interpret(object); 283 } 284 285 function keys(object) { 286 if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } 287 var results = []; 288 for (var property in object) { 289 if (object.hasOwnProperty(property)) { 290 results.push(property); 291 } 292 } 293 return results; 294 } 295 296 function values(object) { 297 var results = []; 298 for (var property in object) 299 results.push(object[property]); 300 return results; 301 } 302 303 function clone(object) { 304 return extend({ }, object); 305 } 306 307 function isElement(object) { 308 return !!(object && object.nodeType == 1); 309 } 310 311 function isArray(object) { 312 return _toString.call(object) === ARRAY_CLASS; 313 } 314 315 var hasNativeIsArray = (typeof Array.isArray == 'function') 316 && Array.isArray([]) && !Array.isArray({}); 317 318 if (hasNativeIsArray) { 319 isArray = Array.isArray; 320 } 321 322 function isHash(object) { 323 return object instanceof Hash; 324 } 325 326 function isFunction(object) { 327 return _toString.call(object) === FUNCTION_CLASS; 328 } 329 330 function isString(object) { 331 return _toString.call(object) === STRING_CLASS; 332 } 333 334 function isNumber(object) { 335 return _toString.call(object) === NUMBER_CLASS; 336 } 337 338 function isDate(object) { 339 return _toString.call(object) === DATE_CLASS; 340 } 341 342 function isUndefined(object) { 343 return typeof object === "undefined"; 344 } 345 346 extend(Object, { 347 extend: extend, 348 inspect: inspect, 349 toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, 350 toQueryString: toQueryString, 351 toHTML: toHTML, 352 keys: Object.keys || keys, 353 values: values, 354 clone: clone, 355 isElement: isElement, 356 isArray: isArray, 357 isHash: isHash, 358 isFunction: isFunction, 359 isString: isString, 360 isNumber: isNumber, 361 isDate: isDate, 362 isUndefined: isUndefined 363 }); 364})(); 365Object.extend(Function.prototype, (function() { 366 var slice = Array.prototype.slice; 367 368 function update(array, args) { 369 var arrayLength = array.length, length = args.length; 370 while (length--) array[arrayLength + length] = args[length]; 371 return array; 372 } 373 374 function merge(array, args) { 375 array = slice.call(array, 0); 376 return update(array, args); 377 } 378 379 function argumentNames() { 380 var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] 381 .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') 382 .replace(/\s+/g, '').split(','); 383 return names.length == 1 && !names[0] ? [] : names; 384 } 385 386 function bind(context) { 387 if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; 388 var __method = this, args = slice.call(arguments, 1); 389 return function() { 390 var a = merge(args, arguments); 391 return __method.apply(context, a); 392 } 393 } 394 395 function bindAsEventListener(context) { 396 var __method = this, args = slice.call(arguments, 1); 397 return function(event) { 398 var a = update([event || window.event], args); 399 return __method.apply(context, a); 400 } 401 } 402 403 function curry() { 404 if (!arguments.length) return this; 405 var __method = this, args = slice.call(arguments, 0); 406 return function() { 407 var a = merge(args, arguments); 408 return __method.apply(this, a); 409 } 410 } 411 412 function delay(timeout) { 413 var __method = this, args = slice.call(arguments, 1); 414 timeout = timeout * 1000; 415 return window.setTimeout(function() { 416 return __method.apply(__method, args); 417 }, timeout); 418 } 419 420 function defer() { 421 var args = update([0.01], arguments); 422 return this.delay.apply(this, args); 423 } 424 425 function wrap(wrapper) { 426 var __method = this; 427 return function() { 428 var a = update([__method.bind(this)], arguments); 429 return wrapper.apply(this, a); 430 } 431 } 432 433 function methodize() { 434 if (this._methodized) return this._methodized; 435 var __method = this; 436 return this._methodized = function() { 437 var a = update([this], arguments); 438 return __method.apply(null, a); 439 }; 440 } 441 442 return { 443 argumentNames: argumentNames, 444 bind: bind, 445 bindAsEventListener: bindAsEventListener, 446 curry: curry, 447 delay: delay, 448 defer: defer, 449 wrap: wrap, 450 methodize: methodize 451 } 452})()); 453 454 455 456(function(proto) { 457 458 459 function toISOString() { 460 return this.getUTCFullYear() + '-' + 461 (this.getUTCMonth() + 1).toPaddedString(2) + '-' + 462 this.getUTCDate().toPaddedString(2) + 'T' + 463 this.getUTCHours().toPaddedString(2) + ':' + 464 this.getUTCMinutes().toPaddedString(2) + ':' + 465 this.getUTCSeconds().toPaddedString(2) + 'Z'; 466 } 467 468 469 function toJSON() { 470 return this.toISOString(); 471 } 472 473 if (!proto.toISOString) proto.toISOString = toISOString; 474 if (!proto.toJSON) proto.toJSON = toJSON; 475 476})(Date.prototype); 477 478 479RegExp.prototype.match = RegExp.prototype.test; 480 481RegExp.escape = function(str) { 482 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 483}; 484var PeriodicalExecuter = Class.create({ 485 initialize: function(callback, frequency) { 486 this.callback = callback; 487 this.frequency = frequency; 488 this.currentlyExecuting = false; 489 490 this.registerCallback(); 491 }, 492 493 registerCallback: function() { 494 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 495 }, 496 497 execute: function() { 498 this.callback(this); 499 }, 500 501 stop: function() { 502 if (!this.timer) return; 503 clearInterval(this.timer); 504 this.timer = null; 505 }, 506 507 onTimerEvent: function() { 508 if (!this.currentlyExecuting) { 509 try { 510 this.currentlyExecuting = true; 511 this.execute(); 512 this.currentlyExecuting = false; 513 } catch(e) { 514 this.currentlyExecuting = false; 515 throw e; 516 } 517 } 518 } 519}); 520Object.extend(String, { 521 interpret: function(value) { 522 return value == null ? '' : String(value); 523 }, 524 specialChar: { 525 '\b': '\\b', 526 '\t': '\\t', 527 '\n': '\\n', 528 '\f': '\\f', 529 '\r': '\\r', 530 '\\': '\\\\' 531 } 532}); 533 534Object.extend(String.prototype, (function() { 535 var NATIVE_JSON_PARSE_SUPPORT = window.JSON && 536 typeof JSON.parse === 'function' && 537 JSON.parse('{"test": true}').test; 538 539 function prepareReplacement(replacement) { 540 if (Object.isFunction(replacement)) return replacement; 541 var template = new Template(replacement); 542 return function(match) { return template.evaluate(match) }; 543 } 544 545 function gsub(pattern, replacement) { 546 var result = '', source = this, match; 547 replacement = prepareReplacement(replacement); 548 549 if (Object.isString(pattern)) 550 pattern = RegExp.escape(pattern); 551 552 if (!(pattern.length || pattern.source)) { 553 replacement = replacement(''); 554 return replacement + source.split('').join(replacement) + replacement; 555 } 556 557 while (source.length > 0) { 558 if (match = source.match(pattern)) { 559 result += source.slice(0, match.index); 560 result += String.interpret(replacement(match)); 561 source = source.slice(match.index + match[0].length); 562 } else { 563 result += source, source = ''; 564 } 565 } 566 return result; 567 } 568 569 function sub(pattern, replacement, count) { 570 replacement = prepareReplacement(replacement); 571 count = Object.isUndefined(count) ? 1 : count; 572 573 return this.gsub(pattern, function(match) { 574 if (--count < 0) return match[0]; 575 return replacement(match); 576 }); 577 } 578 579 function scan(pattern, iterator) { 580 this.gsub(pattern, iterator); 581 return String(this); 582 } 583 584 function truncate(length, truncation) { 585 length = length || 30; 586 truncation = Object.isUndefined(truncation) ? '...' : truncation; 587 return this.length > length ? 588 this.slice(0, length - truncation.length) + truncation : String(this); 589 } 590 591 function strip() { 592 return this.replace(/^\s+/, '').replace(/\s+$/, ''); 593 } 594 595 function stripTags() { 596 return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); 597 } 598 599 function stripScripts() { 600 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); 601 } 602 603 function extractScripts() { 604 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), 605 matchOne = new RegExp(Prototype.ScriptFragment, 'im'); 606 return (this.match(matchAll) || []).map(function(scriptTag) { 607 return (scriptTag.match(matchOne) || ['', ''])[1]; 608 }); 609 } 610 611 function evalScripts() { 612 return this.extractScripts().map(function(script) { return eval(script) }); 613 } 614 615 function escapeHTML() { 616 return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); 617 } 618 619 function unescapeHTML() { 620 return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); 621 } 622 623 624 function toQueryParams(separator) { 625 var match = this.strip().match(/([^?#]*)(#.*)?$/); 626 if (!match) return { }; 627 628 return match[1].split(separator || '&').inject({ }, function(hash, pair) { 629 if ((pair = pair.split('='))[0]) { 630 var key = decodeURIComponent(pair.shift()), 631 value = pair.length > 1 ? pair.join('=') : pair[0]; 632 633 if (value != undefined) value = decodeURIComponent(value); 634 635 if (key in hash) { 636 if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; 637 hash[key].push(value); 638 } 639 else hash[key] = value; 640 } 641 return hash; 642 }); 643 } 644 645 function toArray() { 646 return this.split(''); 647 } 648 649 function succ() { 650 return this.slice(0, this.length - 1) + 651 String.fromCharCode(this.charCodeAt(this.length - 1) + 1); 652 } 653 654 function times(count) { 655 return count < 1 ? '' : new Array(count + 1).join(this); 656 } 657 658 function camelize() { 659 return this.replace(/-+(.)?/g, function(match, chr) { 660 return chr ? chr.toUpperCase() : ''; 661 }); 662 } 663 664 function capitalize() { 665 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); 666 } 667 668 function underscore() { 669 return this.replace(/::/g, '/') 670 .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 671 .replace(/([a-z\d])([A-Z])/g, '$1_$2') 672 .replace(/-/g, '_') 673 .toLowerCase(); 674 } 675 676 function dasherize() { 677 return this.replace(/_/g, '-'); 678 } 679 680 function inspect(useDoubleQuotes) { 681 var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { 682 if (character in String.specialChar) { 683 return String.specialChar[character]; 684 } 685 return '\\u00' + character.charCodeAt().toPaddedString(2, 16); 686 }); 687 if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; 688 return "'" + escapedString.replace(/'/g, '\\\'') + "'"; 689 } 690 691 function unfilterJSON(filter) { 692 return this.replace(filter || Prototype.JSONFilter, '$1'); 693 } 694 695 function isJSON() { 696 var str = this; 697 if (str.blank()) return false; 698 str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); 699 str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); 700 str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); 701 return (/^[\],:{}\s]*$/).test(str); 702 } 703 704 function evalJSON(sanitize) { 705 var json = this.unfilterJSON(), 706 cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; 707 if (cx.test(json)) { 708 json = json.replace(cx, function (a) { 709 return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 710 }); 711 } 712 try { 713 if (!sanitize || json.isJSON()) return eval('(' + json + ')'); 714 } catch (e) { } 715 throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); 716 } 717 718 function parseJSON() { 719 var json = this.unfilterJSON(); 720 return JSON.parse(json); 721 } 722 723 function include(pattern) { 724 return this.indexOf(pattern) > -1; 725 } 726 727 function startsWith(pattern) { 728 return this.lastIndexOf(pattern, 0) === 0; 729 } 730 731 function endsWith(pattern) { 732 var d = this.length - pattern.length; 733 return d >= 0 && this.indexOf(pattern, d) === d; 734 } 735 736 function empty() { 737 return this == ''; 738 } 739 740 function blank() { 741 return /^\s*$/.test(this); 742 } 743 744 function interpolate(object, pattern) { 745 return new Template(this, pattern).evaluate(object); 746 } 747 748 return { 749 gsub: gsub, 750 sub: sub, 751 scan: scan, 752 truncate: truncate, 753 strip: String.prototype.trim || strip, 754 stripTags: stripTags, 755 stripScripts: stripScripts, 756 extractScripts: extractScripts, 757 evalScripts: evalScripts, 758 escapeHTML: escapeHTML, 759 unescapeHTML: unescapeHTML, 760 toQueryParams: toQueryParams, 761 parseQuery: toQueryParams, 762 toArray: toArray, 763 succ: succ, 764 times: times, 765 camelize: camelize, 766 capitalize: capitalize, 767 underscore: underscore, 768 dasherize: dasherize, 769 inspect: inspect, 770 unfilterJSON: unfilterJSON, 771 isJSON: isJSON, 772 evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, 773 include: include, 774 startsWith: startsWith, 775 endsWith: endsWith, 776 empty: empty, 777 blank: blank, 778 interpolate: interpolate 779 }; 780})()); 781 782var Template = Class.create({ 783 initialize: function(template, pattern) { 784 this.template = template.toString(); 785 this.pattern = pattern || Template.Pattern; 786 }, 787 788 evaluate: function(object) { 789 if (object && Object.isFunction(object.toTemplateReplacements)) 790 object = object.toTemplateReplacements(); 791 792 return this.template.gsub(this.pattern, function(match) { 793 if (object == null) return (match[1] + ''); 794 795 var before = match[1] || ''; 796 if (before == '\\') return match[2]; 797 798 var ctx = object, expr = match[3], 799 pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; 800 801 match = pattern.exec(expr); 802 if (match == null) return before; 803 804 while (match != null) { 805 var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; 806 ctx = ctx[comp]; 807 if (null == ctx || '' == match[3]) break; 808 expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); 809 match = pattern.exec(expr); 810 } 811 812 return before + String.interpret(ctx); 813 }); 814 } 815}); 816Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 817 818var $break = { }; 819 820var Enumerable = (function() { 821 function each(iterator, context) { 822 var index = 0; 823 try { 824 this._each(function(value) { 825 iterator.call(context, value, index++); 826 }); 827 } catch (e) { 828 if (e != $break) throw e; 829 } 830 return this; 831 } 832 833 function eachSlice(number, iterator, context) { 834 var index = -number, slices = [], array = this.toArray(); 835 if (number < 1) return array; 836 while ((index += number) < array.length) 837 slices.push(array.slice(index, index+number)); 838 return slices.collect(iterator, context); 839 } 840 841 function all(iterator, context) { 842 iterator = iterator || Prototype.K; 843 var result = true; 844 this.each(function(value, index) { 845 result = result && !!iterator.call(context, value, index); 846 if (!result) throw $break; 847 }); 848 return result; 849 } 850 851 function any(iterator, context) { 852 iterator = iterator || Prototype.K; 853 var result = false; 854 this.each(function(value, index) { 855 if (result = !!iterator.call(context, value, index)) 856 throw $break; 857 }); 858 return result; 859 } 860 861 function collect(iterator, context) { 862 iterator = iterator || Prototype.K; 863 var results = []; 864 this.each(function(value, index) { 865 results.push(iterator.call(context, value, index)); 866 }); 867 return results; 868 } 869 870 function detect(iterator, context) { 871 var result; 872 this.each(function(value, index) { 873 if (iterator.call(context, value, index)) { 874 result = value; 875 throw $break; 876 } 877 }); 878 return result; 879 } 880 881 function findAll(iterator, context) { 882 var results = []; 883 this.each(function(value, index) { 884 if (iterator.call(context, value, index)) 885 results.push(value); 886 }); 887 return results; 888 } 889 890 function grep(filter, iterator, context) { 891 iterator = iterator || Prototype.K; 892 var results = []; 893 894 if (Object.isString(filter)) 895 filter = new RegExp(RegExp.escape(filter)); 896 897 this.each(function(value, index) { 898 if (filter.match(value)) 899 results.push(iterator.call(context, value, index)); 900 }); 901 return results; 902 } 903 904 function include(object) { 905 if (Object.isFunction(this.indexOf)) 906 if (this.indexOf(object) != -1) return true; 907 908 var found = false; 909 this.each(function(value) { 910 if (value == object) { 911 found = true; 912 throw $break; 913 } 914 }); 915 return found; 916 } 917 918 function inGroupsOf(number, fillWith) { 919 fillWith = Object.isUndefined(fillWith) ? null : fillWith; 920 return this.eachSlice(number, function(slice) { 921 while(slice.length < number) slice.push(fillWith); 922 return slice; 923 }); 924 } 925 926 function inject(memo, iterator, context) { 927 this.each(function(value, index) { 928 memo = iterator.call(context, memo, value, index); 929 }); 930 return memo; 931 } 932 933 function invoke(method) { 934 var args = $A(arguments).slice(1); 935 return this.map(function(value) { 936 return value[method].apply(value, args); 937 }); 938 } 939 940 function max(iterator, context) { 941 iterator = iterator || Prototype.K; 942 var result; 943 this.each(function(value, index) { 944 value = iterator.call(context, value, index); 945 if (result == null || value >= result) 946 result = value; 947 }); 948 return result; 949 } 950 951 function min(iterator, context) { 952 iterator = iterator || Prototype.K; 953 var result; 954 this.each(function(value, index) { 955 value = iterator.call(context, value, index); 956 if (result == null || value < result) 957 result = value; 958 }); 959 return result; 960 } 961 962 function partition(iterator, context) { 963 iterator = iterator || Prototype.K; 964 var trues = [], falses = []; 965 this.each(function(value, index) { 966 (iterator.call(context, value, index) ? 967 trues : falses).push(value); 968 }); 969 return [trues, falses]; 970 } 971 972 function pluck(property) { 973 var results = []; 974 this.each(function(value) { 975 results.push(value[property]); 976 }); 977 return results; 978 } 979 980 function reject(iterator, context) { 981 var results = []; 982 this.each(function(value, index) { 983 if (!iterator.call(context, value, index)) 984 results.push(value); 985 }); 986 return results; 987 } 988 989 function sortBy(iterator, context) { 990 return this.map(function(value, index) { 991 return { 992 value: value, 993 criteria: iterator.call(context, value, index) 994 }; 995 }).sort(function(left, right) { 996 var a = left.criteria, b = right.criteria; 997 return a < b ? -1 : a > b ? 1 : 0; 998 }).pluck('value'); 999 } 1000 1001 function toArray() { 1002 return this.map(); 1003 } 1004 1005 function zip() { 1006 var iterator = Prototype.K, args = $A(arguments); 1007 if (Object.isFunction(args.last())) 1008 iterator = args.pop(); 1009 1010 var collections = [this].concat(args).map($A); 1011 return this.map(function(value, index) { 1012 return iterator(collections.pluck(index)); 1013 }); 1014 } 1015 1016 function size() { 1017 return this.toArray().length; 1018 } 1019 1020 function inspect() { 1021 return '#<Enumerable:' + this.toArray().inspect() + '>'; 1022 } 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 return { 1033 each: each, 1034 eachSlice: eachSlice, 1035 all: all, 1036 every: all, 1037 any: any, 1038 some: any, 1039 collect: collect, 1040 map: collect, 1041 detect: detect, 1042 findAll: findAll, 1043 select: findAll, 1044 filter: findAll, 1045 grep: grep, 1046 include: include, 1047 member: include, 1048 inGroupsOf: inGroupsOf, 1049 inject: inject, 1050 invoke: invoke, 1051 max: max, 1052 min: min, 1053 partition: partition, 1054 pluck: pluck, 1055 reject: reject, 1056 sortBy: sortBy, 1057 toArray: toArray, 1058 entries: toArray, 1059 zip: zip, 1060 size: size, 1061 inspect: inspect, 1062 find: detect 1063 }; 1064})(); 1065 1066function $A(iterable) { 1067 if (!iterable) return []; 1068 if ('toArray' in Object(iterable)) return iterable.toArray(); 1069 var length = iterable.length || 0, results = new Array(length); 1070 while (length--) results[length] = iterable[length]; 1071 return results; 1072} 1073 1074 1075function $w(string) { 1076 if (!Object.isString(string)) return []; 1077 string = string.strip(); 1078 return string ? string.split(/\s+/) : []; 1079} 1080 1081Array.from = $A; 1082 1083 1084(function() { 1085 var arrayProto = Array.prototype, 1086 slice = arrayProto.slice, 1087 _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available 1088 1089 function each(iterator, context) { 1090 for (var i = 0, length = this.length >>> 0; i < length; i++) { 1091 if (i in this) iterator.call(context, this[i], i, this); 1092 } 1093 } 1094 if (!_each) _each = each; 1095 1096 function clear() { 1097 this.length = 0; 1098 return this; 1099 } 1100 1101 function first() { 1102 return this[0]; 1103 } 1104 1105 function last() { 1106 return this[this.length - 1]; 1107 } 1108 1109 function compact() { 1110 return this.select(function(value) { 1111 return value != null; 1112 }); 1113 } 1114 1115 function flatten() { 1116 return this.inject([], function(array, value) { 1117 if (Object.isArray(value)) 1118 return array.concat(value.flatten()); 1119 array.push(value); 1120 return array; 1121 }); 1122 } 1123 1124 function without() { 1125 var values = slice.call(arguments, 0); 1126 return this.select(function(value) { 1127 return !values.include(value); 1128 }); 1129 } 1130 1131 function reverse(inline) { 1132 return (inline === false ? this.toArray() : this)._reverse(); 1133 } 1134 1135 function uniq(sorted) { 1136 return this.inject([], function(array, value, index) { 1137 if (0 == index || (sorted ? array.last() != value : !array.include(value))) 1138 array.push(value); 1139 return array; 1140 }); 1141 } 1142 1143 function intersect(array) { 1144 return this.uniq().findAll(function(item) { 1145 return array.detect(function(value) { return item === value }); 1146 }); 1147 } 1148 1149 1150 function clone() { 1151 return slice.call(this, 0); 1152 } 1153 1154 function size() { 1155 return this.length; 1156 } 1157 1158 function inspect() { 1159 return '[' + this.map(Object.inspect).join(', ') + ']'; 1160 } 1161 1162 function indexOf(item, i) { 1163 i || (i = 0); 1164 var length = this.length; 1165 if (i < 0) i = length + i; 1166 for (; i < length; i++) 1167 if (this[i] === item) return i; 1168 return -1; 1169 } 1170 1171 function lastIndexOf(item, i) { 1172 i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; 1173 var n = this.slice(0, i).reverse().indexOf(item); 1174 return (n < 0) ? n : i - n - 1; 1175 } 1176 1177 function concat() { 1178 var array = slice.call(this, 0), item; 1179 for (var i = 0, length = arguments.length; i < length; i++) { 1180 item = arguments[i]; 1181 if (Object.isArray(item) && !('callee' in item)) { 1182 for (var j = 0, arrayLength = item.length; j < arrayLength; j++) 1183 array.push(item[j]); 1184 } else { 1185 array.push(item); 1186 } 1187 } 1188 return array; 1189 } 1190 1191 Object.extend(arrayProto, Enumerable); 1192 1193 if (!arrayProto._reverse) 1194 arrayProto._reverse = arrayProto.reverse; 1195 1196 Object.extend(arrayProto, { 1197 _each: _each, 1198 clear: clear, 1199 first: first, 1200 last: last, 1201 compact: compact, 1202 flatten: flatten, 1203 without: without, 1204 reverse: reverse, 1205 uniq: uniq, 1206 intersect: intersect, 1207 clone: clone, 1208 toArray: clone, 1209 size: size, 1210 inspect: inspect 1211 }); 1212 1213 var CONCAT_ARGUMENTS_BUGGY = (function() { 1214 return [].concat(arguments)[0][0] !== 1; 1215 })(1,2) 1216 1217 if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; 1218 1219 if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; 1220 if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; 1221})(); 1222function $H(object) { 1223 return new Hash(object); 1224}; 1225 1226var Hash = Class.create(Enumerable, (function() { 1227 function initialize(object) { 1228 this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); 1229 } 1230 1231 1232 function _each(iterator) { 1233 for (var key in this._object) { 1234 var value = this._object[key], pair = [key, value]; 1235 pair.key = key; 1236 pair.value = value; 1237 iterator(pair); 1238 } 1239 } 1240 1241 function set(key, value) { 1242 return this._object[key] = value; 1243 } 1244 1245 function get(key) { 1246 if (this._object[key] !== Object.prototype[key]) 1247 return this._object[key]; 1248 } 1249 1250 function unset(key) { 1251 var value = this._object[key]; 1252 delete this._object[key]; 1253 return value; 1254 } 1255 1256 function toObject() { 1257 return Object.clone(this._object); 1258 } 1259 1260 1261 1262 function keys() { 1263 return this.pluck('key'); 1264 } 1265 1266 function values() { 1267 return this.pluck('value'); 1268 } 1269 1270 function index(value) { 1271 var match = this.detect(function(pair) { 1272 return pair.value === value; 1273 }); 1274 return match && match.key; 1275 } 1276 1277 function merge(object) { 1278 return this.clone().update(object); 1279 } 1280 1281 function update(object) { 1282 return new Hash(object).inject(this, function(result, pair) { 1283 result.set(pair.key, pair.value); 1284 return result; 1285 }); 1286 } 1287 1288 function toQueryPair(key, value) { 1289 if (Object.isUndefined(value)) return key; 1290 return key + '=' + encodeURIComponent(String.interpret(value)); 1291 } 1292 1293 function toQueryString() { 1294 return this.inject([], function(results, pair) { 1295 var key = encodeURIComponent(pair.key), values = pair.value; 1296 1297 if (values && typeof values == 'object') { 1298 if (Object.isArray(values)) { 1299 var queryValues = []; 1300 for (var i = 0, len = values.length, value; i < len; i++) { 1301 value = values[i]; 1302 queryValues.push(toQueryPair(key, value)); 1303 } 1304 return results.concat(queryValues); 1305 } 1306 } else results.push(toQueryPair(key, values)); 1307 return results; 1308 }).join('&'); 1309 } 1310 1311 function inspect() { 1312 return '#<Hash:{' + this.map(function(pair) { 1313 return pair.map(Object.inspect).join(': '); 1314 }).join(', ') + '}>'; 1315 } 1316 1317 function clone() { 1318 return new Hash(this); 1319 } 1320 1321 return { 1322 initialize: initialize, 1323 _each: _each, 1324 set: set, 1325 get: get, 1326 unset: unset, 1327 toObject: toObject, 1328 toTemplateReplacements: toObject, 1329 keys: keys, 1330 values: values, 1331 index: index, 1332 merge: merge, 1333 update: update, 1334 toQueryString: toQueryString, 1335 inspect: inspect, 1336 toJSON: toObject, 1337 clone: clone 1338 }; 1339})()); 1340 1341Hash.from = $H; 1342Object.extend(Number.prototype, (function() { 1343 function toColorPart() { 1344 return this.toPaddedString(2, 16); 1345 } 1346 1347 function succ() { 1348 return this + 1; 1349 } 1350 1351 function times(iterator, context) { 1352 $R(0, this, true).each(iterator, context); 1353 return this; 1354 } 1355 1356 function toPaddedString(length, radix) { 1357 var string = this.toString(radix || 10); 1358 return '0'.times(length - string.length) + string; 1359 } 1360 1361 function abs() { 1362 return Math.abs(this); 1363 } 1364 1365 function round() { 1366 return Math.round(this); 1367 } 1368 1369 function ceil() { 1370 return Math.ceil(this); 1371 } 1372 1373 function floor() { 1374 return Math.floor(this); 1375 } 1376 1377 return { 1378 toColorPart: toColorPart, 1379 succ: succ, 1380 times: times, 1381 toPaddedString: toPaddedString, 1382 abs: abs, 1383 round: round, 1384 ceil: ceil, 1385 floor: floor 1386 }; 1387})()); 1388 1389function $R(start, end, exclusive) { 1390 return new ObjectRange(start, end, exclusive); 1391} 1392 1393var ObjectRange = Class.create(Enumerable, (function() { 1394 function initialize(start, end, exclusive) { 1395 this.start = start; 1396 this.end = end; 1397 this.exclusive = exclusive; 1398 } 1399 1400 function _each(iterator) { 1401 var value = this.start; 1402 while (this.include(value)) { 1403 iterator(value); 1404 value = value.succ(); 1405 } 1406 } 1407 1408 function include(value) { 1409 if (value < this.start) 1410 return false; 1411 if (this.exclusive) 1412 return value < this.end; 1413 return value <= this.end; 1414 } 1415 1416 return { 1417 initialize: initialize, 1418 _each: _each, 1419 include: include 1420 }; 1421})()); 1422 1423 1424 1425var Ajax = { 1426 getTransport: function() { 1427 return Try.these( 1428 function() {return new XMLHttpRequest()}, 1429 function() {return new ActiveXObject('Msxml2.XMLHTTP')}, 1430 function() {return new ActiveXObject('Microsoft.XMLHTTP')} 1431 ) || false; 1432 }, 1433 1434 activeRequestCount: 0 1435}; 1436 1437Ajax.Responders = { 1438 responders: [], 1439 1440 _each: function(iterator) { 1441 this.responders._each(iterator); 1442 }, 1443 1444 register: function(responder) { 1445 if (!this.include(responder)) 1446 this.responders.push(responder); 1447 }, 1448 1449 unregister: function(responder) { 1450 this.responders = this.responders.without(responder); 1451 }, 1452 1453 dispatch: function(callback, request, transport, json) { 1454 this.each(function(responder) { 1455 if (Object.isFunction(responder[callback])) { 1456 try { 1457 responder[callback].apply(responder, [request, transport, json]); 1458 } catch (e) { } 1459 } 1460 }); 1461 } 1462}; 1463 1464Object.extend(Ajax.Responders, Enumerable); 1465 1466Ajax.Responders.register({ 1467 onCreate: function() { Ajax.activeRequestCount++ }, 1468 onComplete: function() { Ajax.activeRequestCount-- } 1469}); 1470Ajax.Base = Class.create({ 1471 initialize: function(options) { 1472 this.options = { 1473 method: 'post', 1474 asynchronous: true, 1475 contentType: 'application/x-www-form-urlencoded', 1476 encoding: 'UTF-8', 1477 parameters: '', 1478 evalJSON: true, 1479 evalJS: true 1480 }; 1481 Object.extend(this.options, options || { }); 1482 1483 this.options.method = this.options.method.toLowerCase(); 1484 1485 if (Object.isHash(this.options.parameters)) 1486 this.options.parameters = this.options.parameters.toObject(); 1487 } 1488}); 1489Ajax.Request = Class.create(Ajax.Base, { 1490 _complete: false, 1491 1492 initialize: function($super, url, options) { 1493 $super(options); 1494 this.transport = Ajax.getTransport(); 1495 this.request(url); 1496 }, 1497 1498 request: function(url) { 1499 this.url = url; 1500 this.method = this.options.method; 1501 var params = Object.isString(this.options.parameters) ? 1502 this.options.parameters : 1503 Object.toQueryString(this.options.parameters); 1504 1505 if (!['get', 'post'].include(this.method)) { 1506 params += (params ? '&' : '') + "_method=" + this.method; 1507 this.method = 'post'; 1508 } 1509 1510 if (params && this.method === 'get') { 1511 this.url += (this.url.include('?') ? '&' : '?') + params; 1512 } 1513 1514 this.parameters = params.toQueryParams(); 1515 1516 try { 1517 var response = new Ajax.Response(this); 1518 if (this.options.onCreate) this.options.onCreate(response); 1519 Ajax.Responders.dispatch('onCreate', this, response); 1520 1521 this.transport.open(this.method.toUpperCase(), this.url, 1522 this.options.asynchronous); 1523 1524 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); 1525 1526 this.transport.onreadystatechange = this.onStateChange.bind(this); 1527 this.setRequestHeaders(); 1528 1529 this.body = this.method == 'post' ? (this.options.postBody || params) : null; 1530 this.transport.send(this.body); 1531 1532 /* Force Firefox to handle ready state 4 for synchronous requests */ 1533 if (!this.options.asynchronous && this.transport.overrideMimeType) 1534 this.onStateChange(); 1535 1536 } 1537 catch (e) { 1538 this.dispatchException(e); 1539 } 1540 }, 1541 1542 onStateChange: function() { 1543 var readyState = this.transport.readyState; 1544 if (readyState > 1 && !((readyState == 4) && this._complete)) 1545 this.respondToReadyState(this.transport.readyState); 1546 }, 1547 1548 setRequestHeaders: function() { 1549 var headers = { 1550 'X-Requested-With': 'XMLHttpRequest', 1551 'X-Prototype-Version': Prototype.Version, 1552 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' 1553 }; 1554 1555 if (this.method == 'post') { 1556 headers['Content-type'] = this.options.contentType + 1557 (this.options.encoding ? '; charset=' + this.options.encoding : ''); 1558 1559 /* Force "Connection: close" for older Mozilla browsers to work 1560 * around a bug where XMLHttpRequest sends an incorrect 1561 * Content-length header. See Mozilla Bugzilla #246651. 1562 */ 1563 if (this.transport.overrideMimeType && 1564 (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) 1565 headers['Connection'] = 'close'; 1566 } 1567 1568 if (typeof this.options.requestHeaders == 'object') { 1569 var extras = this.options.requestHeaders; 1570 1571 if (Object.isFunction(extras.push)) 1572 for (var i = 0, length = extras.length; i < length; i += 2) 1573 headers[extras[i]] = extras[i+1]; 1574 else 1575 $H(extras).each(function(pair) { headers[pair.key] = pair.value }); 1576 } 1577 1578 for (var name in headers) 1579 this.transport.setRequestHeader(name, headers[name]); 1580 }, 1581 1582 success: function() { 1583 var status = this.getStatus(); 1584 return !status || (status >= 200 && status < 300) || status == 304; 1585 }, 1586 1587 getStatus: function() { 1588 try { 1589 if (this.transport.status === 1223) return 204; 1590 return this.transport.status || 0; 1591 } catch (e) { return 0 } 1592 }, 1593 1594 respondToReadyState: function(readyState) { 1595 var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); 1596 1597 if (state == 'Complete') { 1598 try { 1599 this._complete = true; 1600 (this.options['on' + response.status] 1601 || this.options['on' + (this.success() ? 'Success' : 'Failure')] 1602 || Prototype.emptyFunction)(response, response.headerJSON); 1603 } catch (e) { 1604 this.dispatchException(e); 1605 } 1606 1607 var contentType = response.getHeader('Content-type'); 1608 if (this.options.evalJS == 'force' 1609 || (this.options.evalJS && this.isSameOrigin() && contentType 1610 && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) 1611 this.evalResponse(); 1612 } 1613 1614 try { 1615 (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); 1616 Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); 1617 } catch (e) { 1618 this.dispatchException(e); 1619 } 1620 1621 if (state == 'Complete') { 1622 this.transport.onreadystatechange = Prototype.emptyFunction; 1623 } 1624 }, 1625 1626 isSameOrigin: function() { 1627 var m = this.url.match(/^\s*https?:\/\/[^\/]*/); 1628 return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ 1629 protocol: location.protocol, 1630 domain: document.domain, 1631 port: location.port ? ':' + location.port : '' 1632 })); 1633 }, 1634 1635 getHeader: function(name) { 1636 try { 1637 return this.transport.getResponseHeader(name) || null; 1638 } catch (e) { return null; } 1639 }, 1640 1641 evalResponse: function() { 1642 try { 1643 return eval((this.transport.responseText || '').unfilterJSON()); 1644 } catch (e) { 1645 this.dispatchException(e); 1646 } 1647 }, 1648 1649 dispatchException: function(exception) { 1650 (this.options.onException || Prototype.emptyFunction)(this, exception); 1651 Ajax.Responders.dispatch('onException', this, exception); 1652 } 1653}); 1654 1655Ajax.Request.Events = 1656 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 1657 1658 1659 1660 1661 1662 1663 1664 1665Ajax.Response = Class.create({ 1666 initialize: function(request){ 1667 this.request = request; 1668 var transport = this.transport = request.transport, 1669 readyState = this.readyState = transport.readyState; 1670 1671 if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { 1672 this.status = this.getStatus(); 1673 this.statusText = this.getStatusText(); 1674 this.responseText = String.interpret(transport.responseText); 1675 this.headerJSON = this._getHeaderJSON(); 1676 } 1677 1678 if (readyState == 4) { 1679 var xml = transport.responseXML; 1680 this.responseXML = Object.isUndefined(xml) ? null : xml; 1681 this.responseJSON = this._getResponseJSON(); 1682 } 1683 }, 1684 1685 status: 0, 1686 1687 statusText: '', 1688 1689 getStatus: Ajax.Request.prototype.getStatus, 1690 1691 getStatusText: function() { 1692 try { 1693 return this.transport.statusText || ''; 1694 } catch (e) { return '' } 1695 }, 1696 1697 getHeader: Ajax.Request.prototype.getHeader, 1698 1699 getAllHeaders: function() { 1700 try { 1701 return this.getAllResponseHeaders(); 1702 } catch (e) { return null } 1703 }, 1704 1705 getResponseHeader: function(name) { 1706 return this.transport.getResponseHeader(name); 1707 }, 1708 1709 getAllResponseHeaders: function() { 1710 return this.transport.getAllResponseHeaders(); 1711 }, 1712 1713 _getHeaderJSON: function() { 1714 var json = this.getHeader('X-JSON'); 1715 if (!json) return null; 1716 json = decodeURIComponent(escape(json)); 1717 try { 1718 return json.evalJSON(this.request.options.sanitizeJSON || 1719 !this.request.isSameOrigin()); 1720 } catch (e) { 1721 this.request.dispatchException(e); 1722 } 1723 }, 1724 1725 _getResponseJSON: function() { 1726 var options = this.request.options; 1727 if (!options.evalJSON || (options.evalJSON != 'force' && 1728 !(this.getHeader('Content-type') || '').include('application/json')) || 1729 this.responseText.blank()) 1730 return null; 1731 try { 1732 return this.responseText.evalJSON(options.sanitizeJSON || 1733 !this.request.isSameOrigin()); 1734 } catch (e) { 1735 this.request.dispatchException(e); 1736 } 1737 } 1738}); 1739 1740Ajax.Updater = Class.create(Ajax.Request, { 1741 initialize: function($super, container, url, options) { 1742 this.container = { 1743 success: (container.success || container), 1744 failure: (container.failure || (container.success ? null : container)) 1745 }; 1746 1747 options = Object.clone(options); 1748 var onComplete = options.onComplete; 1749 options.onComplete = (function(response, json) { 1750 this.updateContent(response.responseText); 1751 if (Object.isFunction(onComplete)) onComplete(response, json); 1752 }).bind(this); 1753 1754 $super(url, options); 1755 }, 1756 1757 updateContent: function(responseText) { 1758 var receiver = this.container[this.success() ? 'success' : 'failure'], 1759 options = this.options; 1760 1761 if (!options.evalScripts) responseText = responseText.stripScripts(); 1762 1763 if (receiver = $(receiver)) { 1764 if (options.insertion) { 1765 if (Object.isString(options.insertion)) { 1766 var insertion = { }; insertion[options.insertion] = responseText; 1767 receiver.insert(insertion); 1768 } 1769 else options.insertion(receiver, responseText); 1770 } 1771 else receiver.update(responseText); 1772 } 1773 } 1774}); 1775 1776Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { 1777 initialize: function($super, container, url, options) { 1778 $super(options); 1779 this.onComplete = this.options.onComplete; 1780 1781 this.frequency = (this.options.frequency || 2); 1782 this.decay = (this.options.decay || 1); 1783 1784 this.updater = { }; 1785 this.container = container; 1786 this.url = url; 1787 1788 this.start(); 1789 }, 1790 1791 start: function() { 1792 this.options.onComplete = this.updateComplete.bind(this); 1793 this.onTimerEvent(); 1794 }, 1795 1796 stop: function() { 1797 this.updater.options.onComplete = undefined; 1798 clearTimeout(this.timer); 1799 (this.onComplete || Prototype.emptyFunction).apply(this, arguments); 1800 }, 1801 1802 updateComplete: function(response) { 1803 if (this.options.decay) { 1804 this.decay = (response.responseText == this.lastText ? 1805 this.decay * this.options.decay : 1); 1806 1807 this.lastText = response.responseText; 1808 } 1809 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); 1810 }, 1811 1812 onTimerEvent: function() { 1813 this.updater = new Ajax.Updater(this.container, this.url, this.options); 1814 } 1815}); 1816 1817 1818function $(element) { 1819 if (arguments.length > 1) { 1820 for (var i = 0, elements = [], length = arguments.length; i < length; i++) 1821 elements.push($(arguments[i])); 1822 return elements; 1823 } 1824 if (Object.isString(element)) 1825 element = document.getElementById(element); 1826 return Element.extend(element); 1827} 1828 1829if (Prototype.BrowserFeatures.XPath) { 1830 document._getElementsByXPath = function(expression, parentElement) { 1831 var results = []; 1832 var query = document.evaluate(expression, $(parentElement) || document, 1833 null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 1834 for (var i = 0, length = query.snapshotLength; i < length; i++) 1835 results.push(Element.extend(query.snapshotItem(i))); 1836 return results; 1837 }; 1838} 1839 1840/*--------------------------------------------------------------------------*/ 1841 1842if (!Node) var Node = { }; 1843 1844if (!Node.ELEMENT_NODE) { 1845 Object.extend(Node, { 1846 ELEMENT_NODE: 1, 1847 ATTRIBUTE_NODE: 2, 1848 TEXT_NODE: 3, 1849 CDATA_SECTION_NODE: 4, 1850 ENTITY_REFERENCE_NODE: 5, 1851 ENTITY_NODE: 6, 1852 PROCESSING_INSTRUCTION_NODE: 7, 1853 COMMENT_NODE: 8, 1854 DOCUMENT_NODE: 9, 1855 DOCUMENT_TYPE_NODE: 10, 1856 DOCUMENT_FRAGMENT_NODE: 11, 1857 NOTATION_NODE: 12 1858 }); 1859} 1860 1861 1862 1863(function(global) { 1864 function shouldUseCache(tagName, attributes) { 1865 if (tagName === 'select') return false; 1866 if ('type' in attributes) return false; 1867 return true; 1868 } 1869 1870 var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ 1871 try { 1872 var el = document.createElement('<input name="x">'); 1873 return el.tagName.toLowerCase() === 'input' && el.name === 'x'; 1874 } 1875 catch(err) { 1876 return false; 1877 } 1878 })(); 1879 1880 var element = global.Element; 1881 1882 global.Element = function(tagName, attributes) { 1883 attributes = attributes || { }; 1884 tagName = tagName.toLowerCase(); 1885 var cache = Element.cache; 1886 1887 if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { 1888 tagName = '<' + tagName + ' name="' + attributes.name + '">'; 1889 delete attributes.name; 1890 return Element.writeAttribute(document.createElement(tagName), attributes); 1891 } 1892 1893 if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); 1894 1895 var node = shouldUseCache(tagName, attributes) ? 1896 cache[tagName].cloneNode(false) : document.createElement(tagName); 1897 1898 return Element.writeAttribute(node, attributes); 1899 }; 1900 1901 Object.extend(global.Element, element || { }); 1902 if (element) global.Element.prototype = element.prototype; 1903 1904})(this); 1905 1906Element.idCounter = 1; 1907Element.cache = { }; 1908 1909Element._purgeElement = function(element) { 1910 var uid = element._prototypeUID; 1911 if (uid) { 1912 Element.stopObserving(element); 1913 element._prototypeUID = void 0; 1914 delete Element.Storage[uid]; 1915 } 1916} 1917 1918Element.Methods = { 1919 visible: function(element) { 1920 return $(element).style.display != 'none'; 1921 }, 1922 1923 toggle: function(element) { 1924 element = $(element); 1925 Element[Element.visible(element) ? 'hide' : 'show'](element); 1926 return element; 1927 }, 1928 1929 hide: function(element) { 1930 element = $(element); 1931 element.style.display = 'none'; 1932 return element; 1933 }, 1934 1935 show: function(element) { 1936 element = $(element); 1937 element.style.display = ''; 1938 return element; 1939 }, 1940 1941 remove: function(element) { 1942 element = $(element); 1943 element.parentNode.removeChild(element); 1944 return element; 1945 }, 1946 1947 update: (function(){ 1948 1949 var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ 1950 var el = document.createElement("select"), 1951 isBuggy = true; 1952 el.innerHTML = "<option value=\"test\">test</option>"; 1953 if (el.options && el.options[0]) { 1954 isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; 1955 } 1956 el = null; 1957 return isBuggy; 1958 })(); 1959 1960 var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ 1961 try { 1962 var el = document.createElement("table"); 1963 if (el && el.tBodies) { 1964 el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; 1965 var isBuggy = typeof el.tBodies[0] == "undefined"; 1966 el = null; 1967 return isBuggy; 1968 } 1969 } catch (e) { 1970 return true; 1971 } 1972 })(); 1973 1974 var LINK_ELEMENT_INNERHTML_BUGGY = (function() { 1975 try { 1976 var el = document.createElement('div'); 1977 el.innerHTML = "<link>"; 1978 var isBuggy = (el.childNodes.length === 0); 1979 el = null; 1980 return isBuggy; 1981 } catch(e) { 1982 return true; 1983 } 1984 })(); 1985 1986 var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || 1987 TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; 1988 1989 var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { 1990 var s = document.createElement("script"), 1991 isBuggy = false; 1992 try { 1993 s.appendChild(document.createTextNode("")); 1994 isBuggy = !s.firstChild || 1995 s.firstChild && s.firstChild.nodeType !== 3; 1996 } catch (e) { 1997 isBuggy = true; 1998 } 1999 s = null; 2000 return isBuggy; 2001 })(); 2002 2003 2004 function update(element, content) { 2005 element = $(element); 2006 var purgeElement = Element._purgeElement; 2007 2008 var descendants = element.getElementsByTagName('*'), 2009 i = descendants.length; 2010 while (i--) purgeElement(descendants[i]); 2011 2012 if (content && content.toElement) 2013 content = content.toElement(); 2014 2015 if (Object.isElement(content)) 2016 return element.update().insert(content); 2017 2018 content = Object.toHTML(content); 2019 2020 var tagName = element.tagName.toUpperCase(); 2021 2022 if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { 2023 element.text = content; 2024 return element; 2025 } 2026 2027 if (ANY_INNERHTML_BUGGY) { 2028 if (tagName in Element._insertionTranslations.tags) { 2029 while (element.firstChild) { 2030 element.removeChild(element.firstChild); 2031 } 2032 Element._getContentFromAnonymousElement(tagName, content.stripScripts()) 2033 .each(function(node) { 2034 element.appendChild(node) 2035 }); 2036 } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) { 2037 while (element.firstChild) { 2038 element.removeChild(element.firstChild); 2039 } 2040 var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true); 2041 nodes.each(function(node) { element.appendChild(node) }); 2042 } 2043 else { 2044 element.innerHTML = content.stripScripts(); 2045 } 2046 } 2047 else { 2048 element.innerHTML = content.stripScripts(); 2049 } 2050 2051 content.evalScripts.bind(content).defer(); 2052 return element; 2053 } 2054 2055 return update; 2056 })(), 2057 2058 replace: function(element, content) { 2059 element = $(element); 2060 if (content && content.toElement) content = content.toElement(); 2061 else if (!Object.isElement(content)) { 2062 content = Object.toHTML(content); 2063 var range = element.ownerDocument.createRange(); 2064 range.selectNode(element); 2065 content.evalScripts.bind(content).defer(); 2066 content = range.createContextualFragment(content.stripScripts()); 2067 } 2068 element.parentNode.replaceChild(content, element); 2069 return element; 2070 }, 2071 2072 insert: function(element, insertions) { 2073 element = $(element); 2074 2075 if (Object.isString(insertions) || Object.isNumber(insertions) || 2076 Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) 2077 insertions = {bottom:insertions}; 2078 2079 var content, insert, tagName, childNodes; 2080 2081 for (var position in insertions) { 2082 content = insertions[position]; 2083 position = position.toLowerCase(); 2084 insert = Element._insertionTranslations[position]; 2085 2086 if (content && content.toElement) content = content.toElement(); 2087 if (Object.isElement(content)) { 2088 insert(element, content); 2089 continue; 2090 } 2091 2092 content = Object.toHTML(content); 2093 2094 tagName = ((position == 'before' || position == 'after') 2095 ? element.parentNode : element).tagName.toUpperCase(); 2096 2097 childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); 2098 2099 if (position == 'top' || position == 'after') childNodes.reverse(); 2100 childNodes.each(insert.curry(element)); 2101 2102 content.evalScripts.bind(content).defer(); 2103 } 2104 2105 return element; 2106 }, 2107 2108 wrap: function(element, wrapper, attributes) { 2109 element = $(element); 2110 if (Object.isElement(wrapper)) 2111 $(wrapper).writeAttribute(attributes || { }); 2112 else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); 2113 else wrapper = new Element('div', wrapper); 2114 if (element.parentNode) 2115 element.parentNode.replaceChild(wrapper, element); 2116 wrapper.appendChild(element); 2117 return wrapper; 2118 }, 2119 2120 inspect: function(element) { 2121 element = $(element); 2122 var result = '<' + element.tagName.toLowerCase(); 2123 $H({'id': 'id', 'className': 'class'}).each(function(pair) { 2124 var property = pair.first(), 2125 attribute = pair.last(), 2126 value = (element[property] || '').toString(); 2127 if (value) result += ' ' + attribute + '=' + value.inspect(true); 2128 }); 2129 return result + '>'; 2130 }, 2131 2132 recursivelyCollect: function(element, property, maximumLength) { 2133 element = $(element); 2134 maximumLength = maximumLength || -1; 2135 var elements = []; 2136 2137 while (element = element[property]) { 2138 if (element.nodeType == 1) 2139 elements.push(Element.extend(element)); 2140 if (elements.length == maximumLength) 2141 break; 2142 } 2143 2144 return elements; 2145 }, 2146 2147 ancestors: function(element) { 2148 return Element.recursivelyCollect(element, 'parentNode'); 2149 }, 2150 2151 descendants: function(element) { 2152 return Element.select(element, "*"); 2153 }, 2154 2155 firstDescendant: function(element) { 2156 element = $(element).firstChild; 2157 while (element && element.nodeType != 1) element = element.nextSibling; 2158 return $(element); 2159 }, 2160 2161 immediateDescendants: function(element) { 2162 var results = [], child = $(element).firstChild; 2163 while (child) { 2164 if (child.nodeType === 1) { 2165 results.push(Element.extend(child)); 2166 } 2167 child = child.nextSibling; 2168 } 2169 return results; 2170 }, 2171 2172 previousSiblings: function(element, maximumLength) { 2173 return Element.recursivelyCollect(element, 'previousSibling'); 2174 }, 2175 2176 nextSiblings: function(element) { 2177 return Element.recursivelyCollect(element, 'nextSibling'); 2178 }, 2179 2180 siblings: function(element) { 2181 element = $(element); 2182 return Element.previousSiblings(element).reverse() 2183 .concat(Element.nextSiblings(element)); 2184 }, 2185 2186 match: function(element, selector) { 2187 element = $(element); 2188 if (Object.isString(selector)) 2189 return Prototype.Selector.match(element, selector); 2190 return selector.match(element); 2191 }, 2192 2193 up: function(element, expression, index) { 2194 element = $(element); 2195 if (arguments.length == 1) return $(element.parentNode); 2196 var ancestors = Element.ancestors(element); 2197 return Object.isNumber(expression) ? ancestors[expression] : 2198 Prototype.Selector.find(ancestors, expression, index); 2199 }, 2200 2201 down: function(element, expression, index) { 2202 element = $(element); 2203 if (arguments.length == 1) return Element.firstDescendant(element); 2204 return Object.isNumber(expression) ? Element.descendants(element)[expression] : 2205 Element.select(element, expression)[index || 0]; 2206 }, 2207 2208 previous: function(element, expression, index) { 2209 element = $(element); 2210 if (Object.isNumber(expression)) index = expression, expression = false; 2211 if (!Object.isNumber(index)) index = 0; 2212 2213 if (expression) { 2214 return Prototype.Selector.find(element.previousSiblings(), expression, index); 2215 } else { 2216 return element.recursivelyCollect("previousSibling", index + 1)[index]; 2217 } 2218 }, 2219 2220 next: function(element, expression, index) { 2221 element = $(element); 2222 if (Object.isNumber(expression)) index = expression, expression = false; 2223 if (!Object.isNumber(index)) index = 0; 2224 2225 if (expression) { 2226 return Prototype.Selector.find(element.nextSiblings(), expression, index); 2227 } else { 2228 var maximumLength = Object.isNumber(index) ? index + 1 : 1; 2229 return element.recursivelyCollect("nextSibling", index + 1)[index]; 2230 } 2231 }, 2232 2233 2234 select: function(element) { 2235 element = $(element); 2236 var expressions = Array.prototype.slice.call(arguments, 1).join(', '); 2237 return Prototype.Selector.select(expressions, element); 2238 }, 2239 2240 adjacent: function(element) { 2241 element = $(element); 2242 var expressions = Array.prototype.slice.call(arguments, 1).join(', '); 2243 return Prototype.Selector.select(expressions, element.parentNode).without(element); 2244 }, 2245 2246 identify: function(element) { 2247 element = $(element); 2248 var id = Element.readAttribute(element, 'id'); 2249 if (id) return id; 2250 do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); 2251 Element.writeAttribute(element, 'id', id); 2252 return id; 2253 }, 2254 2255 readAttribute: function(element, name) { 2256 element = $(element); 2257 if (Prototype.Browser.IE) { 2258 var t = Element._attributeTranslations.read; 2259 if (t.values[name]) return t.values[name](element, name); 2260 if (t.names[name]) name = t.names[name]; 2261 if (name.include(':')) { 2262 return (!element.attributes || !element.attributes[name]) ? null : 2263 element.attributes[name].value; 2264 } 2265 } 2266 return element.getAttribute(name); 2267 }, 2268 2269 writeAttribute: function(element, name, value) { 2270 element = $(element); 2271 var attributes = { }, t = Element._attributeTranslations.write; 2272 2273 if (typeof name == 'object') attributes = name; 2274 else attributes[name] = Object.isUndefined(value) ? true : value; 2275 2276 for (var attr in attributes) { 2277 name = t.names[attr] || attr; 2278 value = attributes[attr]; 2279 if (t.values[attr]) name = t.values[attr](element, value); 2280 if (value === false || value === null) 2281 element.removeAttribute(name); 2282 else if (value === true) 2283 element.setAttribute(name, name); 2284 else element.setAttribute(name, value); 2285 } 2286 return element; 2287 }, 2288 2289 getHeight: function(element) { 2290 return Element.getDimensions(element).height; 2291 }, 2292 2293 getWidth: function(element) { 2294 return Element.getDimensions(element).width; 2295 }, 2296 2297 classNames: function(element) { 2298 return new Element.ClassNames(element); 2299 }, 2300 2301 hasClassName: function(element, className) { 2302 if (!(element = $(element))) return; 2303 var elementClassName = element.className; 2304 return (elementClassName.length > 0 && (elementClassName == className || 2305 new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); 2306 }, 2307 2308 addClassName: function(element, className) { 2309 if (!(element = $(element))) return; 2310 if (!Element.hasClassName(element, className)) 2311 element.className += (element.className ? ' ' : '') + className; 2312 return element; 2313 }, 2314 2315 removeClassName: function(element, className) { 2316 if (!(element = $(element))) return; 2317 element.className = element.className.replace( 2318 new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); 2319 return element; 2320 }, 2321 2322 toggleClassName: function(element, className) { 2323 if (!(element = $(element))) return; 2324 return Element[Element.hasClassName(element, className) ? 2325 'removeClassName' : 'addClassName'](element, className); 2326 }, 2327 2328 cleanWhitespace: function(element) { 2329 element = $(element); 2330 var node = element.firstChild; 2331 while (node) { 2332 var nextNode = node.nextSibling; 2333 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) 2334 element.removeChild(node); 2335 node = nextNode; 2336 } 2337 return element; 2338 }, 2339 2340 empty: function(element) { 2341 return $(element).innerHTML.blank(); 2342 }, 2343 2344 descendantOf: function(element, ancestor) { 2345 element = $(element), ancestor = $(ancestor); 2346 2347 if (element.compareDocumentPosition) 2348 return (element.compareDocumentPosition(ancestor) & 8) === 8; 2349 2350 if (ancestor.contains) 2351 return ancestor.contains(element) && ancestor !== element; 2352 2353 while (element = element.parentNode) 2354 if (element == ancestor) return true; 2355 2356 return false; 2357 }, 2358 2359 scrollTo: function(element) { 2360 element = $(element); 2361 var pos = Element.cumulativeOffset(element); 2362 window.scrollTo(pos[0], pos[1]); 2363 return element; 2364 }, 2365 2366 getStyle: function(element, style) { 2367 element = $(element); 2368 style = style == 'float' ? 'cssFloat' : style.camelize(); 2369 var value = element.style[style]; 2370 if (!value || value == 'auto') { 2371 var css = document.defaultView.getComputedStyle(element, null); 2372 value = css ? css[style] : null; 2373 } 2374 if (style == 'opacity') return value ? parseFloat(value) : 1.0; 2375 return value == 'auto' ? null : value; 2376 }, 2377 2378 getOpacity: function(element) { 2379 return $(element).getStyle('opacity'); 2380 }, 2381 2382 setStyle: function(element, styles) { 2383 element = $(element); 2384 var elementStyle = element.style, match; 2385 if (Object.isString(styles)) { 2386 element.style.cssText += ';' + styles; 2387 return styles.include('opacity') ? 2388 element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; 2389 } 2390 for (var property in styles) 2391 if (property == 'opacity') element.setOpacity(styles[property]); 2392 else 2393 elementStyle[(property == 'float' || property == 'cssFloat') ? 2394 (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : 2395 property] = styles[property]; 2396 2397 return element; 2398 }, 2399 2400 setOpacity: function(element, value) { 2401 element = $(element); 2402 element.style.opacity = (value == 1 || value === '') ? '' : 2403 (value < 0.00001) ? 0 : value; 2404 return element; 2405 }, 2406 2407 makePositioned: function(element) { 2408 element = $(element); 2409 var pos = Element.getStyle(element, 'position'); 2410 if (pos == 'static' || !pos) { 2411 element._madePositioned = true; 2412 element.style.position = 'relative'; 2413 if (Prototype.Browser.Opera) { 2414 element.style.top = 0; 2415 element.style.left = 0; 2416 } 2417 } 2418 return element; 2419 }, 2420 2421 undoPositioned: function(element) { 2422 element = $(element); 2423 if (element._madePositioned) { 2424 element._madePositioned = undefined; 2425 element.style.position = 2426 element.style.top = 2427 element.style.left = 2428 element.style.bottom = 2429 element.style.right = ''; 2430 } 2431 return element; 2432 }, 2433 2434 makeClipping: function(element) { 2435 element = $(element); 2436 if (element._overflow) return element; 2437 element._overflow = Element.getStyle(element, 'overflow') || 'auto'; 2438 if (element._overflow !== 'hidden') 2439 element.style.overflow = 'hidden'; 2440 return element; 2441 }, 2442 2443 undoClipping: function(element) { 2444 element = $(element); 2445 if (!element._overflow) return element; 2446 element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; 2447 element._overflow = null; 2448 return element; 2449 }, 2450 2451 clonePosition: function(element, source) { 2452 var options = Object.extend({ 2453 setLeft: true, 2454 setTop: true, 2455 setWidth: true, 2456 setHeight: true, 2457 offsetTop: 0, 2458 offsetLeft: 0 2459 }, arguments[2] || { }); 2460 2461 source = $(source); 2462 var p = Element.viewportOffset(source), delta = [0, 0], parent = null; 2463 2464 element = $(element); 2465 2466 if (Element.getStyle(element, 'position') == 'absolute') { 2467 parent = Element.getOffsetParent(element); 2468 delta = Element.viewportOffset(parent); 2469 } 2470 2471 if (parent == document.body) { 2472 delta[0] -= document.body.offsetLeft; 2473 delta[1] -= document.body.offsetTop; 2474 } 2475 2476 if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; 2477 if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; 2478 if (options.setWidth) element.style.width = source.offsetWidth + 'px'; 2479 if (options.setHeight) element.style.height = source.offsetHeight + 'px'; 2480 return element; 2481 } 2482}; 2483 2484Object.extend(Element.Methods, { 2485 getElementsBySelector: Element.Methods.select, 2486 2487 childElements: Element.Methods.immediateDescendants 2488}); 2489 2490Element._attributeTranslations = { 2491 write: { 2492 names: { 2493 className: 'class', 2494 htmlFor: 'for' 2495 }, 2496 values: { } 2497 } 2498}; 2499 2500if (Prototype.Browser.Opera) { 2501 Element.Methods.getStyle = Element.Methods.getStyle.wrap( 2502 function(proceed, element, style) { 2503 switch (style) { 2504 case 'height': case 'width': 2505 if (!Element.visible(element)) return null; 2506 2507 var dim = parseInt(proceed(element, style), 10); 2508 2509 if (dim !== element['offset' + style.capitalize()]) 2510 return dim + 'px'; 2511 2512 var properties; 2513 if (style === 'height') { 2514 properties = ['border-top-width', 'padding-top', 2515 'padding-bottom', 'border-bottom-width']; 2516 } 2517 else { 2518 properties = ['border-left-width', 'padding-left', 2519 'padding-right', 'border-right-width']; 2520 } 2521 return properties.inject(dim, function(memo, property) { 2522 var val = proceed(element, property); 2523 return val === null ? memo : memo - parseInt(val, 10); 2524 }) + 'px'; 2525 default: return proceed(element, style); 2526 } 2527 } 2528 ); 2529 2530 Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( 2531 function(proceed, element, attribute) { 2532 if (attribute === 'title') return element.title; 2533 return proceed(element, attribute); 2534 } 2535 ); 2536} 2537 2538else if (Prototype.Browser.IE) { 2539 Element.Methods.getStyle = function(element, style) { 2540 element = $(element); 2541 style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); 2542 var value = element.style[style]; 2543 if (!value && element.currentStyle) value = element.currentStyle[style]; 2544 2545 if (style == 'opacity') { 2546 if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) 2547 if (value[1]) return parseFloat(value[1]) / 100; 2548 return 1.0; 2549 } 2550 2551 if (value == 'auto') { 2552 if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) 2553 return element['offset' + style.capitalize()] + 'px'; 2554 return null; 2555 } 2556 return value; 2557 }; 2558 2559 Element.Methods.setOpacity = function(element, value) { 2560 function stripAlpha(filter){ 2561 return filter.replace(/alpha\([^\)]*\)/gi,''); 2562 } 2563 element = $(element); 2564 var currentStyle = element.currentStyle; 2565 if ((currentStyle && !currentStyle.hasLayout) || 2566 (!currentStyle && element.style.zoom == 'normal')) 2567 element.style.zoom = 1; 2568 2569 var filter = element.getStyle('filter'), style = element.style; 2570 if (value == 1 || value === '') { 2571 (filter = stripAlpha(filter)) ? 2572 style.filter = filter : style.removeAttribute('filter'); 2573 return element; 2574 } else if (value < 0.00001) value = 0; 2575 style.filter = stripAlpha(filter) + 2576 'alpha(opacity=' + (value * 100) + ')'; 2577 return element; 2578 }; 2579 2580 Element._attributeTranslations = (function(){ 2581 2582 var classProp = 'className', 2583 forProp = 'for', 2584 el = document.createElement('div'); 2585 2586 el.setAttribute(classProp, 'x'); 2587 2588 if (el.className !== 'x') { 2589 el.setAttribute('class', 'x'); 2590 if (el.className === 'x') { 2591 classProp = 'class'; 2592 } 2593 } 2594 el = null; 2595 2596 el = document.createElement('label'); 2597 el.setAttribute(forProp, 'x'); 2598 if (el.htmlFor !== 'x') { 2599 el.setAttribute('htmlFor', 'x'); 2600 if (el.htmlFor === 'x') { 2601 forProp = 'htmlFor'; 2602 } 2603 } 2604 el = null; 2605 2606 return { 2607 read: { 2608 names: { 2609 'class': classProp, 2610 'className': classProp, 2611 'for': forProp, 2612 'htmlFor': forProp 2613 }, 2614 values: { 2615 _getAttr: function(element, attribute) { 2616 return element.getAttribute(attribute); 2617 }, 2618 _getAttr2: function(element, attribute) { 2619 return element.getAttribute(attribute, 2); 2620 }, 2621 _getAttrNode: function(element, attribute) { 2622 var node = element.getAttributeNode(attribute); 2623 return node ? node.value : ""; 2624 }, 2625 _getEv: (function(){ 2626 2627 var el = document.createElement('div'), f; 2628 el.onclick = Prototype.emptyFunction; 2629 var value = el.getAttribute('onclick'); 2630 2631 if (String(value).indexOf('{') > -1) { 2632 f = function(element, attribute) { 2633 attribute = element.getAttribute(attribute); 2634 if (!attribute) return null; 2635 attribute = attribute.toString(); 2636 attribute = attribute.split('{')[1]; 2637 attribute = attribute.split('}')[0]; 2638 return attribute.strip(); 2639 }; 2640 } 2641 else if (value === '') { 2642 f = function(element, attribute) { 2643 attribute = element.getAttribute(attribute); 2644 if (!attribute) return null; 2645 return attribute.strip(); 2646 }; 2647 } 2648 el = null; 2649 return f; 2650 })(), 2651 _flag: function(element, attribute) { 2652 return $(element).hasAttribute(attribute) ? attribute : null; 2653 }, 2654 style: function(element) { 2655 return element.style.cssText.toLowerCase(); 2656 }, 2657 title: function(element) { 2658 return element.title; 2659 } 2660 } 2661 } 2662 } 2663 })(); 2664 2665 Element._attributeTranslations.write = { 2666 names: Object.extend({ 2667 cellpadding: 'cellPadding', 2668 cellspacing: 'cellSpacing' 2669 }, Element._attributeTranslations.read.names), 2670 values: { 2671 checked: function(element, value) { 2672 element.checked = !!value; 2673 }, 2674 2675 style: function(element, value) { 2676 element.style.cssText = value ? value : ''; 2677 } 2678 } 2679 }; 2680 2681 Element._attributeTranslations.has = {}; 2682 2683 $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + 2684 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { 2685 Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; 2686 Element._attributeTranslations.has[attr.toLowerCase()] = attr; 2687 }); 2688 2689 (function(v) { 2690 Object.extend(v, { 2691 href: v._getAttr2, 2692 src: v._getAttr2, 2693 type: v._getAttr, 2694 action: v._getAttrNode, 2695 disabled: v._flag, 2696 checked: v._flag, 2697 readonly: v._flag, 2698 multiple: v._flag, 2699 onload: v._getEv, 2700 onunload: v._getEv, 2701 onclick: v._getEv, 2702 ondblclick: v._getEv, 2703 onmousedown: v._getEv, 2704 onmouseup: v._getEv, 2705 onmouseover: v._getEv, 2706 onmousemove: v._getEv, 2707 onmouseout: v._getEv, 2708 onfocus: v._getEv, 2709 onblur: v._getEv, 2710 onkeypress: v._getEv, 2711 onkeydown: v._getEv, 2712 onkeyup: v._getEv, 2713 onsubmit: v._getEv, 2714 onreset: v._getEv, 2715 onselect: v._getEv, 2716 onchange: v._getEv 2717 }); 2718 })(Element._attributeTranslations.read.values); 2719 2720 if (Prototype.BrowserFeatures.ElementExtensions) { 2721 (function() { 2722 function _descendants(element) { 2723 var nodes = element.getElementsByTagName('*'), results = []; 2724 for (var i = 0, node; node = nodes[i]; i++) 2725 if (node.tagName !== "!") // Filter out comment nodes. 2726 results.push(node); 2727 return results; 2728 } 2729 2730 Element.Methods.down = function(element, expression, index) { 2731 element = $(element); 2732 if (arguments.length == 1) return element.firstDescendant(); 2733 return Object.isNumber(expression) ? _descendants(element)[expression] : 2734 Element.select(element, expression)[index || 0]; 2735 } 2736 })(); 2737 } 2738 2739} 2740 2741else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { 2742 Element.Methods.setOpacity = function(element, value) { 2743 element = $(element); 2744 element.style.opacity = (value == 1) ? 0.999999 : 2745 (value === '') ? '' : (value < 0.00001) ? 0 : value; 2746 return element; 2747 }; 2748} 2749 2750else if (Prototype.Browser.WebKit) { 2751 Element.Methods.setOpacity = function(element, value) { 2752 element = $(element); 2753 element.style.opacity = (value == 1 || value === '') ? '' : 2754 (value < 0.00001) ? 0 : value; 2755 2756 if (value == 1) 2757 if (element.tagName.toUpperCase() == 'IMG' && element.width) { 2758 element.width++; element.width--; 2759 } else try { 2760 var n = document.createTextNode(' '); 2761 element.appendChild(n); 2762 element.removeChild(n); 2763 } catch (e) { } 2764 2765 return element; 2766 }; 2767} 2768 2769if ('outerHTML' in document.documentElement) { 2770 Element.Methods.replace = function(element, content) { 2771 element = $(element); 2772 2773 if (content && content.toElement) content = content.toElement(); 2774 if (Object.isElement(content)) { 2775 element.parentNode.replaceChild(content, element); 2776 return element; 2777 } 2778 2779 content = Object.toHTML(content); 2780 var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); 2781 2782 if (Element._insertionTranslations.tags[tagName]) { 2783 var nextSibling = element.next(), 2784 fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); 2785 parent.removeChild(element); 2786 if (nextSibling) 2787 fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); 2788 else 2789 fragments.each(function(node) { parent.appendChild(node) }); 2790 } 2791 else element.outerHTML = content.stripScripts(); 2792 2793 content.evalScripts.bind(content).defer(); 2794 return element; 2795 }; 2796} 2797 2798Element._returnOffset = function(l, t) { 2799 var result = [l, t]; 2800 result.left = l; 2801 result.top = t; 2802 return result; 2803}; 2804 2805Element._getContentFromAnonymousElement = function(tagName, html, force) { 2806 var div = new Element('div'), 2807 t = Element._insertionTranslations.tags[tagName]; 2808 2809 var workaround = false; 2810 if (t) workaround = true; 2811 else if (force) { 2812 workaround = true; 2813 t = ['', '', 0]; 2814 } 2815 2816 if (workaround) { 2817 div.innerHTML = ' ' + t[0] + html + t[1]; 2818 div.removeChild(div.firstChild); 2819 for (var i = t[2]; i--; ) { 2820 div = div.firstChild; 2821 } 2822 } 2823 else { 2824 div.innerHTML = html; 2825 } 2826 return $A(div.childNodes); 2827}; 2828 2829Element._insertionTranslations = { 2830 before: function(element, node) { 2831 element.parentNode.insertBefore(node, element); 2832 }, 2833 top: function(element, node) { 2834 element.insertBefore(node, element.firstChild); 2835 }, 2836 bottom: function(element, node) { 2837 element.appendChild(node); 2838 }, 2839 after: function(element, node) { 2840 element.parentNode.insertBefore(node, element.nextSibling); 2841 }, 2842 tags: { 2843 TABLE: ['<table>', '</table>', 1], 2844 TBODY: ['<table><tbody>', '</tbody></table>', 2], 2845 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], 2846 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], 2847 SELECT: ['<select>', '</select>', 1] 2848 } 2849}; 2850 2851(function() { 2852 var tags = Element._insertionTranslations.tags; 2853 Object.extend(tags, { 2854 THEAD: tags.TBODY, 2855 TFOOT: tags.TBODY, 2856 TH: tags.TD 2857 }); 2858})(); 2859 2860Element.Methods.Simulated = { 2861 hasAttribute: function(element, attribute) { 2862 attribute = Element._attributeTranslations.has[attribute] || attribute; 2863 var node = $(element).getAttributeNode(attribute); 2864 return !!(node && node.specified); 2865 } 2866}; 2867 2868Element.Methods.ByTag = { }; 2869 2870Object.extend(Element, Element.Methods); 2871 2872(function(div) { 2873 2874 if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { 2875 window.HTMLElement = { }; 2876 window.HTMLElement.prototype = div['__proto__']; 2877 Prototype.BrowserFeatures.ElementExtensions = true; 2878 } 2879 2880 div = null; 2881 2882})(document.createElement('div')); 2883 2884Element.extend = (function() { 2885 2886 function checkDeficiency(tagName) { 2887 if (typeof window.Element != 'undefined') { 2888 var proto = window.Element.prototype; 2889 if (proto) { 2890 var id = '_' + (Math.random()+'').slice(2), 2891 el = document.createElement(tagName); 2892 proto[id] = 'x'; 2893 var isBuggy = (el[id] !== 'x'); 2894 delete proto[id]; 2895 el = null; 2896 return isBuggy; 2897 } 2898 } 2899 return false; 2900 } 2901 2902 function extendElementWith(element, methods) { 2903 for (var property in methods) { 2904 var value = methods[property]; 2905 if (Object.isFunction(value) && !(property in element)) 2906 element[property] = value.methodize(); 2907 } 2908 } 2909 2910 var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); 2911 2912 if (Prototype.BrowserFeatures.SpecificElementExtensions) { 2913 if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { 2914 return function(element) { 2915 if (element && typeof element._extendedByPrototype == 'undefined') { 2916 var t = element.tagName; 2917 if (t && (/^(?:object|applet|embed)$/i.test(t))) { 2918 extendElementWith(element, Element.Methods); 2919 extendElementWith(element, Element.Methods.Simulated); 2920 extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); 2921 } 2922 } 2923 return element; 2924 } 2925 } 2926 return Prototype.K; 2927 } 2928 2929 var Methods = { }, ByTag = Element.Methods.ByTag; 2930 2931 var extend = Object.extend(function(element) { 2932 if (!element || typeof element._extendedByPrototype != 'undefined' || 2933 element.nodeType != 1 || element == window) return element; 2934 2935 var methods = Object.clone(Methods), 2936 tagName = element.tagName.toUpperCase(); 2937 2938 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); 2939 2940 extendElementWith(element, methods); 2941 2942 element._extendedByPrototype = Prototype.emptyFunction; 2943 return element; 2944 2945 }, { 2946 refresh: function() { 2947 if (!Prototype.BrowserFeatures.ElementExtensions) { 2948 Object.extend(Methods, Element.Methods); 2949 Object.extend(Methods, Element.Methods.Simulated); 2950 } 2951 } 2952 }); 2953 2954 extend.refresh(); 2955 return extend; 2956})(); 2957 2958if (document.documentElement.hasAttribute) { 2959 Element.hasAttribute = function(element, attribute) { 2960 return element.hasAttribute(attribute); 2961 }; 2962} 2963else { 2964 Element.hasAttribute = Element.Methods.Simulated.hasAttribute; 2965} 2966 2967Element.addMethods = function(methods) { 2968 var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; 2969 2970 if (!methods) { 2971 Object.extend(Form, Form.Methods); 2972 Object.extend(Form.Element, Form.Element.Methods); 2973 Object.extend(Element.Methods.ByTag, { 2974 "FORM": Object.clone(Form.Methods), 2975 "INPUT": Object.clone(Form.Element.Methods), 2976 "SELECT": Object.clone(Form.Element.Methods), 2977 "TEXTAREA": Object.clone(Form.Element.Methods), 2978 "BUTTON": Object.clone(Form.Element.Methods) 2979 }); 2980 } 2981 2982 if (arguments.length == 2) { 2983 var tagName = methods; 2984 methods = arguments[1]; 2985 } 2986 2987 if (!tagName) Object.extend(Element.Methods, methods || { }); 2988 else { 2989 if (Object.isArray(tagName)) tagName.each(extend); 2990 else extend(tagName); 2991 } 2992 2993 function extend(tagName) { 2994 tagName = tagName.toUpperCase(); 2995 if (!Element.Methods.ByTag[tagName]) 2996 Element.Methods.ByTag[tagName] = { }; 2997 Object.extend(Element.Methods.ByTag[tagName], methods); 2998 } 2999 3000 function copy(methods, destination, onlyIfAbsent) { 3001 onlyIfAbsent = onlyIfAbsent || false; 3002 for (var property in methods) { 3003 var value = methods[property]; 3004 if (!Object.isFunction(value)) continue; 3005 if (!onlyIfAbsent || !(property in destination)) 3006 destination[property] = value.methodize(); 3007 } 3008 } 3009 3010 function findDOMClass(tagName) { 3011 var klass; 3012 var trans = { 3013 "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", 3014 "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", 3015 "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", 3016 "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", 3017 "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": 3018 "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": 3019 "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": 3020 "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": 3021 "FrameSet", "IFRAME": "IFrame" 3022 }; 3023 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; 3024 if (window[klass]) return window[klass]; 3025 klass = 'HTML' + tagName + 'Element'; 3026 if (window[klass]) return window[klass]; 3027 klass = 'HTML' + tagName.capitalize() + 'Element'; 3028 if (window[klass]) return window[klass]; 3029 3030 var element = document.createElement(tagName), 3031 proto = element['__proto__'] || element.constructor.prototype; 3032 3033 element = null; 3034 return proto; 3035 } 3036 3037 var elementPrototype = window.HTMLElement ? HTMLElement.prototype : 3038 Element.prototype; 3039 3040 if (F.ElementExtensions) { 3041 copy(Element.Methods, elementPrototype); 3042 copy(Element.Methods.Simulated, elementPrototype, true); 3043 } 3044 3045 if (F.SpecificElementExtensions) { 3046 for (var tag in Element.Methods.ByTag) { 3047 var klass = findDOMClass(tag); 3048 if (Object.isUndefined(klass)) continue; 3049 copy(T[tag], klass.prototype); 3050 } 3051 } 3052 3053 Object.extend(Element, Element.Methods); 3054 delete Element.ByTag; 3055 3056 if (Element.extend.refresh) Element.extend.refresh(); 3057 Element.cache = { }; 3058}; 3059 3060 3061document.viewport = { 3062 3063 getDimensions: function() { 3064 return { width: this.getWidth(), height: this.getHeight() }; 3065 }, 3066 3067 getScrollOffsets: function() { 3068 return Element._returnOffset( 3069 window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, 3070 window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 3071 } 3072}; 3073 3074(function(viewport) { 3075 var B = Prototype.Browser, doc = document, element, property = {}; 3076 3077 function getRootElement() { 3078 if (B.WebKit && !doc.evaluate) 3079 return document; 3080 3081 if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) 3082 return document.body; 3083 3084 return document.documentElement; 3085 } 3086 3087 function define(D) { 3088 if (!element) element = getRootElement(); 3089 3090 property[D] = 'client' + D; 3091 3092 viewport['get' + D] = function() { return element[property[D]] }; 3093 return viewport['get' + D](); 3094 } 3095 3096 viewport.getWidth = define.curry('Width'); 3097 3098 viewport.getHeight = define.curry('Height'); 3099})(document.viewport); 3100 3101 3102Element.Storage = { 3103 UID: 1 3104}; 3105 3106Element.addMethods({ 3107 getStorage: function(element) { 3108 if (!(element = $(element))) return; 3109 3110 var uid; 3111 if (element === window) { 3112 uid = 0; 3113 } else { 3114 if (typeof element._prototypeUID === "undefined") 3115 element._prototypeUID = Element.Storage.UID++; 3116 uid = element._prototypeUID; 3117 } 3118 3119 if (!Element.Storage[uid]) 3120 Element.Storage[uid] = $H(); 3121 3122 return Element.Storage[uid]; 3123 }, 3124 3125 store: function(element, key, value) { 3126 if (!(element = $(element))) return; 3127 3128 if (arguments.length === 2) { 3129 Element.getStorage(element).update(key); 3130 } else { 3131 Element.getStorage(element).set(key, value); 3132 } 3133 3134 return element; 3135 }, 3136 3137 retrieve: function(element, key, defaultValue) { 3138 if (!(element = $(element))) return; 3139 var hash = Element.getStorage(element), value = hash.get(key); 3140 3141 if (Object.isUndefined(value)) { 3142 hash.set(key, defaultValue); 3143 value = defaultValue; 3144 } 3145 3146 return value; 3147 }, 3148 3149 clone: function(element, deep) { 3150 if (!(element = $(element))) return; 3151 var clone = element.cloneNode(deep); 3152 clone._prototypeUID = void 0; 3153 if (deep) { 3154 var descendants = Element.select(clone, '*'), 3155 i = descendants.length; 3156 while (i--) { 3157 descendants[i]._prototypeUID = void 0; 3158 } 3159 } 3160 return Element.extend(clone); 3161 }, 3162 3163 purge: function(element) { 3164 if (!(element = $(element))) return; 3165 var purgeElement = Element._purgeElement; 3166 3167 purgeElement(element); 3168 3169 var descendants = element.getElementsByTagName('*'), 3170 i = descendants.length; 3171 3172 while (i--) purgeElement(descendants[i]); 3173 3174 return null; 3175 } 3176}); 3177 3178(function() { 3179 3180 function toDecimal(pctString) { 3181 var match = pctString.match(/^(\d+)%?$/i); 3182 if (!match) return null; 3183 return (Number(match[1]) / 100); 3184 } 3185 3186 function getPixelValue(value, property, context) { 3187 var element = null; 3188 if (Object.isElement(value)) { 3189 element = value; 3190 value = element.getStyle(property); 3191 } 3192 3193 if (value === null) { 3194 return null; 3195 } 3196 3197 if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) { 3198 return window.parseFloat(value); 3199 } 3200 3201 var isPercentage = value.include('%'), isViewport = (context === document.viewport); 3202 3203 if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) { 3204 var style = element.style.left, rStyle = element.runtimeStyle.left; 3205 element.runtimeStyle.left = element.currentStyle.left; 3206 element.style.left = value || 0; 3207 value = element.style.pixelLeft; 3208 element.style.left = style; 3209 element.runtimeStyle.left = rStyle; 3210 3211 return value; 3212 } 3213 3214 if (element && isPercentage) { 3215 context = context || element.parentNode; 3216 var decimal = toDecimal(value); 3217 var whole = null; 3218 var position = element.getStyle('position'); 3219 3220 var isHorizontal = property.include('left') || property.include('right') || 3221 property.include('width'); 3222 3223 var isVertical = property.include('top') || property.include('bottom') || 3224 property.include('height'); 3225 3226 if (context === document.viewport) { 3227 if (isHorizontal) { 3228 whole = document.viewport.getWidth(); 3229 } else if (isVertical) { 3230 whole = document.viewport.getHeight(); 3231 } 3232 } else { 3233 if (isHorizontal) { 3234 whole = $(context).measure('width'); 3235 } else if (isVertical) { 3236 whole = $(context).measure('height'); 3237 } 3238 } 3239 3240 return (whole === null) ? 0 : whole * decimal; 3241 } 3242 3243 return 0; 3244 } 3245 3246 function toCSSPixels(number) { 3247 if (Object.isString(number) && number.endsWith('px')) { 3248 return number; 3249 } 3250 return number + 'px'; 3251 } 3252 3253 function isDisplayed(element) { 3254 var originalElement = element; 3255 while (element && element.parentNode) { 3256 var display = element.getStyle('display'); 3257 if (display === 'none') { 3258 return false; 3259 } 3260 element = $(element.parentNode); 3261 } 3262 return true; 3263 } 3264 3265 var hasLayout = Prototype.K; 3266 if ('currentStyle' in document.documentElement) { 3267 hasLayout = function(element) { 3268 if (!element.currentStyle.hasLayout) { 3269 element.style.zoom = 1; 3270 } 3271 return element; 3272 }; 3273 } 3274 3275 function cssNameFor(key) { 3276 if (key.include('border')) key = key + '-width'; 3277 return key.camelize(); 3278 } 3279 3280 Element.Layout = Class.create(Hash, { 3281 initialize: function($super, element, preCompute) { 3282 $super(); 3283 this.element = $(element); 3284 3285 Element.Layout.PROPERTIES.each( function(property) { 3286 this._set(property, null); 3287 }, this); 3288 3289 if (preCompute) { 3290 this._preComputing = true; 3291 this._begin(); 3292 Element.Layout.PROPERTIES.each( this._compute, this ); 3293 this._end(); 3294 this._preComputing = false; 3295 } 3296 }, 3297 3298 _set: function(property, value) { 3299 return Hash.prototype.set.call(this, property, value); 3300 }, 3301 3302 set: function(property, value) { 3303 throw "Properties of Element.Layout are read-only."; 3304 }, 3305 3306 get: function($super, property) { 3307 var value = $super(property); 3308 return value === null ? this._compute(property) : value; 3309 }, 3310 3311 _begin: function() { 3312 if (this._prepared) return; 3313 3314 var element = this.element; 3315 if (isDisplayed(element)) { 3316 this._prepared = true; 3317 return; 3318 } 3319 3320 var originalStyles = { 3321 position: element.style.position || '', 3322 width: element.style.width || '', 3323 visibility: element.style.visibility || '', 3324 display: element.style.display || '' 3325 }; 3326 3327 element.store('prototype_original_styles', originalStyles); 3328 3329 var position = element.getStyle('position'), 3330 width = element.getStyle('width'); 3331 3332 if (width === "0px" || width === null) { 3333 element.style.display = 'block'; 3334 width = element.getStyle('width'); 3335 } 3336 3337 var context = (position === 'fixed') ? document.viewport : 3338 element.parentNode; 3339 3340 element.setStyle({ 3341 position: 'absolute', 3342 visibility: 'hidden', 3343 display: 'block' 3344 }); 3345 3346 var positionedWidth = element.getStyle('width'); 3347 3348 var newWidth; 3349 if (width && (positionedWidth === width)) { 3350 newWidth = getPixelValue(element, 'width', context); 3351 } else if (position === 'absolute' || position === 'fixed') { 3352 newWidth = getPixelValue(element, 'width', context); 3353 } else { 3354 var parent = element.parentNode, pLayout = $(parent).getLayout(); 3355 3356 newWidth = pLayout.get('width') - 3357 this.get('margin-left') - 3358 this.get('border-left') - 3359 this.get('padding-left') - 3360 this.get('padding-right') - 3361 this.get('border-right') - 3362 this.get('margin-right'); 3363 } 3364 3365 element.setStyle({ width: newWidth + 'px' }); 3366 3367 this._prepared = true; 3368 }, 3369 3370 _end: function() { 3371 var element = this.element; 3372 var originalStyles = element.retrieve('prototype_original_styles'); 3373 element.store('prototype_original_styles', null); 3374 element.setStyle(originalStyles); 3375 this._prepared = false; 3376 }, 3377 3378 _compute: function(property) { 3379 var COMPUTATIONS = Element.Layout.COMPUTATIONS; 3380 if (!(property in COMPUTATIONS)) { 3381 throw "Property not found."; 3382 } 3383 3384 return this._set(property, COMPUTATIONS[property].call(this, this.element)); 3385 }, 3386 3387 toObject: function() { 3388 var args = $A(arguments); 3389 var keys = (args.length === 0) ? Element.Layout.PROPERTIES : 3390 args.join(' ').split(' '); 3391 var obj = {}; 3392 keys.each( function(key) { 3393 if (!Element.Layout.PROPERTIES.include(key)) return; 3394 var value = this.get(key); 3395 if (value != null) obj[key] = value; 3396 }, this); 3397 return obj; 3398 }, 3399 3400 toHash: function() { 3401 var obj = this.toObject.apply(this, arguments); 3402 return new Hash(obj); 3403 }, 3404 3405 toCSS: function() { 3406 var args = $A(arguments); 3407 var keys = (args.length === 0) ? Element.Layout.PROPERTIES : 3408 args.join(' ').split(' '); 3409 var css = {}; 3410 3411 keys.each( function(key) { 3412 if (!Element.Layout.PROPERTIES.include(key)) return; 3413 if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return; 3414 3415 var value = this.get(key); 3416 if (value != null) css[cssNameFor(key)] = value + 'px'; 3417 }, this); 3418 return css; 3419 }, 3420 3421 inspect: function() { 3422 return "#<Element.Layout>"; 3423 } 3424 }); 3425 3426 Object.extend(Element.Layout, { 3427 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'), 3428 3429 COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'), 3430 3431 COMPUTATIONS: { 3432 'height': function(element) { 3433 if (!this._preComputing) this._begin(); 3434 3435 var bHeight = this.get('border-box-height'); 3436 if (bHeight <= 0) { 3437 if (!this._preComputing) this._end(); 3438 return 0; 3439 } 3440 3441 var bTop = this.get('border-top'), 3442 bBottom = this.get('border-bottom'); 3443 3444 var pTop = this.get('padding-top'), 3445 pBottom = this.get('padding-bottom'); 3446 3447 if (!this._preComputing) this._end(); 3448 3449 return bHeight - bTop - bBottom - pTop - pBottom; 3450 }, 3451 3452 'width': function(element) { 3453 if (!this._preComputing) this._begin(); 3454 3455 var bWidth = this.get('border-box-width'); 3456 if (bWidth <= 0) { 3457 if (!this._preComputing) this._end(); 3458 return 0; 3459 } 3460 3461 var bLeft = this.get('border-left'), 3462 bRight = this.get('border-right'); 3463 3464 var pLeft = this.get('padding-left'), 3465 pRight = this.get('padding-right'); 3466 3467 if (!this._preComputing) this._end(); 3468 3469 return bWidth - bLeft - bRight - pLeft - pRight; 3470 }, 3471 3472 'padding-box-height': function(element) { 3473 var height = this.get('height'), 3474 pTop = this.get('padding-top'), 3475 pBottom = this.get('padding-bottom'); 3476 3477 return height + pTop + pBottom; 3478 }, 3479 3480 'padding-box-width': function(element) { 3481 var width = this.get('width'), 3482 pLeft = this.get('padding-left'), 3483 pRight = this.get('padding-right'); 3484 3485 return width + pLeft + pRight; 3486 }, 3487 3488 'border-box-height': function(element) { 3489 if (!this._preComputing) this._begin(); 3490 var height = element.offsetHeight; 3491 if (!this._preComputing) this._end(); 3492 return height; 3493 }, 3494 3495 'border-box-width': function(element) { 3496 if (!this._preComputing) this._begin(); 3497 var width = element.offsetWidth; 3498 if (!this._preComputing) this._end(); 3499 return width; 3500 }, 3501 3502 'margin-box-height': function(element) { 3503 var bHeight = this.get('border-box-height'), 3504 mTop = this.get('margin-top'), 3505 mBottom = this.get('margin-bottom'); 3506 3507 if (bHeight <= 0) return 0; 3508 3509 return bHeight + mTop + mBottom; 3510 }, 3511 3512 'margin-box-width': function(element) { 3513 var bWidth = this.get('border-box-width'), 3514 mLeft = this.get('margin-left'), 3515 mRight = this.get('margin-right'); 3516 3517 if (bWidth <= 0) return 0; 3518 3519 return bWidth + mLeft + mRight; 3520 }, 3521 3522 'top': function(element) { 3523 var offset = element.positionedOffset(); 3524 return offset.top; 3525 }, 3526 3527 'bottom': function(element) { 3528 var offset = element.positionedOffset(), 3529 parent = element.getOffsetParent(), 3530 pHeight = parent.measure('height'); 3531 3532 var mHeight = this.get('border-box-height'); 3533 3534 return pHeight - mHeight - offset.top; 3535 }, 3536 3537 'left': function(element) { 3538 var offset = element.positionedOffset(); 3539 return offset.left; 3540 }, 3541 3542 'right': function(element) { 3543 var offset = element.positionedOffset(), 3544 parent = element.getOffsetParent(), 3545 pWidth = parent.measure('width'); 3546 3547 var mWidth = this.get('border-box-width'); 3548 3549 return pWidth - mWidth - offset.left; 3550 }, 3551 3552 'padding-top': function(element) { 3553 return getPixelValue(element, 'paddingTop'); 3554 }, 3555 3556 'padding-bottom': function(element) { 3557 return getPixelValue(element, 'paddingBottom'); 3558 }, 3559 3560 'padding-left': function(element) { 3561 return getPixelValue(element, 'paddingLeft'); 3562 }, 3563 3564 'padding-right': function(element) { 3565 return getPixelValue(element, 'paddingRight'); 3566 }, 3567 3568 'border-top': function(element) { 3569 return getPixelValue(element, 'borderTopWidth'); 3570 }, 3571 3572 'border-bottom': function(element) { 3573 return getPixelValue(element, 'borderBottomWidth'); 3574 }, 3575 3576 'border-left': function(element) { 3577 return getPixelValue(element, 'borderLeftWidth'); 3578 }, 3579 3580 'border-right': function(element) { 3581 return getPixelValue(element, 'borderRightWidth'); 3582 }, 3583 3584 'margin-top': function(element) { 3585 return getPixelValue(element, 'marginTop'); 3586 }, 3587 3588 'margin-bottom': function(element) { 3589 return getPixelValue(element, 'marginBottom'); 3590 }, 3591 3592 'margin-left': function(element) { 3593 return getPixelValue(element, 'marginLeft'); 3594 }, 3595 3596 'margin-right': function(element) { 3597 return getPixelValue(element, 'marginRight'); 3598 } 3599 } 3600 }); 3601 3602 if ('getBoundingClientRect' in document.documentElement) { 3603 Object.extend(Element.Layout.COMPUTATIONS, { 3604 'right': function(element) { 3605 var parent = hasLayout(element.getOffsetParent()); 3606 var rect = element.getBoundingClientRect(), 3607 pRect = parent.getBoundingClientRect(); 3608 3609 return (pRect.right - rect.right).round(); 3610 }, 3611 3612 'bottom': function(element) { 3613 var parent = hasLayout(element.getOffsetParent()); 3614 var rect = element.getBoundingClientRect(), 3615 pRect = parent.getBoundingClientRect(); 3616 3617 return (pRect.bottom - rect.bottom).round(); 3618 } 3619 }); 3620 } 3621 3622 Element.Offset = Class.create({ 3623 initialize: function(left, top) { 3624 this.left = left.round(); 3625 this.top = top.round(); 3626 3627 this[0] = this.left; 3628 this[1] = this.top; 3629 }, 3630 3631 relativeTo: function(offset) { 3632 return new Element.Offset( 3633 this.left - offset.left, 3634 this.top - offset.top 3635 ); 3636 }, 3637 3638 inspect: function() { 3639 return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this); 3640 }, 3641 3642 toString: function() { 3643 return "[#{left}, #{top}]".interpolate(this); 3644 }, 3645 3646 toArray: function() { 3647 return [this.left, this.top]; 3648 } 3649 }); 3650 3651 function getLayout(element, preCompute) { 3652 return new Element.Layout(element, preCompute); 3653 } 3654 3655 function measure(element, property) { 3656 return $(element).getLayout().get(property); 3657 } 3658 3659 function getDimensions(element) { 3660 element = $(element); 3661 var display = Element.getStyle(element, 'display'); 3662 3663 if (display && display !== 'none') { 3664 return { width: element.offsetWidth, height: element.offsetHeight }; 3665 } 3666 3667 var style = element.style; 3668 var originalStyles = { 3669 visibility: style.visibility, 3670 position: style.position, 3671 display: style.display 3672 }; 3673 3674 var newStyles = { 3675 visibility: 'hidden', 3676 display: 'block' 3677 }; 3678 3679 if (originalStyles.position !== 'fixed') 3680 newStyles.position = 'absolute'; 3681 3682 Element.setStyle(element, newStyles); 3683 3684 var dimensions = { 3685 width: element.offsetWidth, 3686 height: element.offsetHeight 3687 }; 3688 3689 Element.setStyle(element, originalStyles); 3690 3691 return dimensions; 3692 } 3693 3694 function getOffsetParent(element) { 3695 element = $(element); 3696 3697 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) 3698 return $(document.body); 3699 3700 var isInline = (Element.getStyle(element, 'display') === 'inline'); 3701 if (!isInline && element.offsetParent) return $(element.offsetParent); 3702 3703 while ((element = element.parentNode) && element !== document.body) { 3704 if (Element.getStyle(element, 'position') !== 'static') { 3705 return isHtml(element) ? $(document.body) : $(element); 3706 } 3707 } 3708 3709 return $(document.body); 3710 } 3711 3712 3713 function cumulativeOffset(element) { 3714 element = $(element); 3715 var valueT = 0, valueL = 0; 3716 if (element.parentNode) { 3717 do { 3718 valueT += element.offsetTop || 0; 3719 valueL += element.offsetLeft || 0; 3720 element = element.offsetParent; 3721 } while (element); 3722 } 3723 return new Element.Offset(valueL, valueT); 3724 } 3725 3726 function positionedOffset(element) { 3727 element = $(element); 3728 3729 var layout = element.getLayout(); 3730 3731 var valueT = 0, valueL = 0; 3732 do { 3733 valueT += element.offsetTop || 0; 3734 valueL += element.offsetLeft || 0; 3735 element = element.offsetParent; 3736 if (element) { 3737 if (isBody(element)) break; 3738 var p = Element.getStyle(element, 'position'); 3739 if (p !== 'static') break; 3740 } 3741 } while (element); 3742 3743 valueL -= layout.get('margin-top'); 3744 valueT -= layout.get('margin-left'); 3745 3746 return new Element.Offset(valueL, valueT); 3747 } 3748 3749 function cumulativeScrollOffset(element) { 3750 var valueT = 0, valueL = 0; 3751 do { 3752 valueT += element.scrollTop || 0; 3753 valueL += element.scrollLeft || 0; 3754 element = element.parentNode; 3755 } while (element); 3756 return new Element.Offset(valueL, valueT); 3757 } 3758 3759 function viewportOffset(forElement) { 3760 element = $(element); 3761 var valueT = 0, valueL = 0, docBody = document.body; 3762 3763 var element = forElement; 3764 do { 3765 valueT += element.offsetTop || 0; 3766 valueL += element.offsetLeft || 0; 3767 if (element.offsetParent == docBody && 3768 Element.getStyle(element, 'position') == 'absolute') break; 3769 } while (element = element.offsetParent); 3770 3771 element = forElement; 3772 do { 3773 if (element != docBody) { 3774 valueT -= element.scrollTop || 0; 3775 valueL -= element.scrollLeft || 0; 3776 } 3777 } while (element = element.parentNode); 3778 return new Element.Offset(valueL, valueT); 3779 } 3780 3781 function absolutize(element) { 3782 element = $(element); 3783 3784 if (Element.getStyle(element, 'position') === 'absolute') { 3785 return element; 3786 } 3787 3788 var offsetParent = getOffsetParent(element); 3789 var eOffset = element.viewportOffset(), 3790 pOffset = offsetParent.viewportOffset(); 3791 3792 var offset = eOffset.relativeTo(pOffset); 3793 var layout = element.getLayout(); 3794 3795 element.store('prototype_absolutize_original_styles', { 3796 left: element.getStyle('left'), 3797 top: element.getStyle('top'), 3798 width: element.getStyle('width'), 3799 height: element.getStyle('height') 3800 }); 3801 3802 element.setStyle({ 3803 position: 'absolute', 3804 top: offset.top + 'px', 3805 left: offset.left + 'px', 3806 width: layout.get('width') + 'px', 3807 height: layout.get('height') + 'px' 3808 }); 3809 3810 return element; 3811 } 3812 3813 function relativize(element) { 3814 element = $(element); 3815 if (Element.getStyle(element, 'position') === 'relative') { 3816 return element; 3817 } 3818 3819 var originalStyles = 3820 element.retrieve('prototype_absolutize_original_styles'); 3821 3822 if (originalStyles) element.setStyle(originalStyles); 3823 return element; 3824 } 3825 3826 if (Prototype.Browser.IE) { 3827 getOffsetParent = getOffsetParent.wrap( 3828 function(proceed, element) { 3829 element = $(element); 3830 3831 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) 3832 return $(document.body); 3833 3834 var position = element.getStyle('position'); 3835 if (position !== 'static') return proceed(element); 3836 3837 element.setStyle({ position: 'relative' }); 3838 var value = proceed(element); 3839 element.setStyle({ position: position }); 3840 return value; 3841 } 3842 ); 3843 3844 positionedOffset = positionedOffset.wrap(function(proceed, element) { 3845 element = $(element); 3846 if (!element.parentNode) return new Element.Offset(0, 0); 3847 var position = element.getStyle('position'); 3848 if (position !== 'static') return proceed(element); 3849 3850 var offsetParent = element.getOffsetParent(); 3851 if (offsetParent && offsetParent.getStyle('position') === 'fixed') 3852 hasLayout(offsetParent); 3853 3854 element.setStyle({ position: 'relative' }); 3855 var value = proceed(element); 3856 element.setStyle({ position: position }); 3857 return value; 3858 }); 3859 } else if (Prototype.Browser.Webkit) { 3860 cumulativeOffset = function(element) { 3861 element = $(element); 3862 var valueT = 0, valueL = 0; 3863 do { 3864 valueT += element.offsetTop || 0; 3865 valueL += element.offsetLeft || 0; 3866 if (element.offsetParent == document.body) 3867 if (Element.getStyle(element, 'position') == 'absolute') break; 3868 3869 element = element.offsetParent; 3870 } while (element); 3871 3872 return new Element.Offset(valueL, valueT); 3873 }; 3874 } 3875 3876 3877 Element.addMethods({ 3878 getLayout: getLayout, 3879 measure: measure, 3880 getDimensions: getDimensions, 3881 getOffsetParent: getOffsetParent, 3882 cumulativeOffset: cumulativeOffset, 3883 positionedOffset: positionedOffset, 3884 cumulativeScrollOffset: cumulativeScrollOffset, 3885 viewportOffset: viewportOffset, 3886 absolutize: absolutize, 3887 relativize: relativize 3888 }); 3889 3890 function isBody(element) { 3891 return element.nodeName.toUpperCase() === 'BODY'; 3892 } 3893 3894 function isHtml(element) { 3895 return element.nodeName.toUpperCase() === 'HTML'; 3896 } 3897 3898 function isDocument(element) { 3899 return element.nodeType === Node.DOCUMENT_NODE; 3900 } 3901 3902 function isDetached(element) { 3903 return element !== document.body && 3904 !Element.descendantOf(element, document.body); 3905 } 3906 3907 if ('getBoundingClientRect' in document.documentElement) { 3908 Element.addMethods({ 3909 viewportOffset: function(element) { 3910 element = $(element); 3911 if (isDetached(element)) return new Element.Offset(0, 0); 3912 3913 var rect = element.getBoundingClientRect(), 3914 docEl = document.documentElement; 3915 return new Element.Offset(rect.left - docEl.clientLeft, 3916 rect.top - docEl.clientTop); 3917 } 3918 }); 3919 } 3920})(); 3921window.$$ = function() { 3922 var expression = $A(arguments).join(', '); 3923 return Prototype.Selector.select(expression, document); 3924}; 3925 3926Prototype.Selector = (function() { 3927 3928 function select() { 3929 throw new Error('Method "Prototype.Selector.select" must be defined.'); 3930 } 3931 3932 function match() { 3933 throw new Error('Method "Prototype.Selector.match" must be defined.'); 3934 } 3935 3936 function find(elements, expression, index) { 3937 index = index || 0; 3938 var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i; 3939 3940 for (i = 0; i < length; i++) { 3941 if (match(elements[i], expression) && index == matchIndex++) { 3942 return Element.extend(elements[i]); 3943 } 3944 } 3945 } 3946 3947 function extendElements(elements) { 3948 for (var i = 0, length = elements.length; i < length; i++) { 3949 Element.extend(elements[i]); 3950 } 3951 return elements; 3952 } 3953 3954 3955 var K = Prototype.K; 3956 3957 return { 3958 select: select, 3959 match: match, 3960 find: find, 3961 extendElements: (Element.extend === K) ? K : extendElements, 3962 extendElement: Element.extend 3963 }; 3964})(); 3965Prototype._original_property = window.Sizzle; 3966/*! 3967 * Sizzle CSS Selector Engine - v1.0 3968 * Copyright 2009, The Dojo Foundation 3969 * Released under the MIT, BSD, and GPL Licenses. 3970 * More information: http://sizzlejs.com/ 3971 */ 3972(function(){ 3973 3974var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 3975 done = 0, 3976 toString = Object.prototype.toString, 3977 hasDuplicate = false, 3978 baseHasDuplicate = true; 3979 3980[0, 0].sort(function(){ 3981 baseHasDuplicate = false; 3982 return 0; 3983}); 3984 3985var Sizzle = function(selector, context, results, seed) { 3986 results = results || []; 3987 var origContext = context = context || document; 3988 3989 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 3990 return []; 3991 } 3992 3993 if ( !selector || typeof selector !== "string" ) { 3994 return results; 3995 } 3996 3997 var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context), 3998 soFar = selector; 3999 4000 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { 4001 soFar = m[3]; 4002 4003 parts.push( m[1] ); 4004 4005 if ( m[2] ) { 4006 extra = m[3]; 4007 break; 4008 } 4009 } 4010 4011 if ( parts.length > 1 && origPOS.exec( selector ) ) { 4012 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 4013 set = posProcess( parts[0] + parts[1], context ); 4014 } else { 4015 set = Expr.relative[ parts[0] ] ? 4016 [ context ] : 4017 Sizzle( parts.shift(), context ); 4018 4019 while ( parts.length ) { 4020 selector = parts.shift(); 4021 4022 if ( Expr.relative[ selector ] ) 4023 selector += parts.shift(); 4024 4025 set = posProcess( selector, set ); 4026 } 4027 } 4028 } else { 4029 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 4030 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 4031 var ret = Sizzle.find( parts.shift(), context, contextXML ); 4032 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; 4033 } 4034 4035 if ( context ) { 4036 var ret = seed ? 4037 { expr: parts.pop(), set: makeArray(seed) } : 4038 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 4039 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; 4040 4041 if ( parts.length > 0 ) { 4042 checkSet = makeArray(set); 4043 } else { 4044 prune = false; 4045 } 4046 4047 while ( parts.length ) { 4048 var cur = parts.pop(), pop = cur; 4049 4050 if ( !Expr.relative[ cur ] ) { 4051 cur = ""; 4052 } else { 4053 pop = parts.pop(); 4054 } 4055 4056 if ( pop == null ) { 4057 pop = context; 4058 } 4059 4060 Expr.relative[ cur ]( checkSet, pop, contextXML ); 4061 } 4062 } else { 4063 checkSet = parts = []; 4064 } 4065 } 4066 4067 if ( !checkSet ) { 4068 checkSet = set; 4069 } 4070 4071 if ( !checkSet ) { 4072 throw "Syntax error, unrecognized expression: " + (cur || selector); 4073 } 4074 4075 if ( toString.call(checkSet) === "[object Array]" ) { 4076 if ( !prune ) { 4077 results.push.apply( results, checkSet ); 4078 } else if ( context && context.nodeType === 1 ) { 4079 for ( var i = 0; checkSet[i] != null; i++ ) { 4080 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { 4081 results.push( set[i] ); 4082 } 4083 } 4084 } else { 4085 for ( var i = 0; checkSet[i] != null; i++ ) { 4086 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 4087 results.push( set[i] ); 4088 } 4089 } 4090 } 4091 } else { 4092 makeArray( checkSet, results ); 4093 } 4094 4095 if ( extra ) { 4096 Sizzle( extra, origContext, results, seed ); 4097 Sizzle.uniqueSort( results ); 4098 } 4099 4100 return results; 4101}; 4102 4103Sizzle.uniqueSort = function(results){ 4104 if ( sortOrder ) { 4105 hasDuplicate = baseHasDuplicate; 4106 results.sort(sortOrder); 4107 4108 if ( hasDuplicate ) { 4109 for ( var i = 1; i < results.length; i++ ) { 4110 if ( results[i] === results[i-1] ) { 4111 results.splice(i--, 1); 4112 } 4113 } 4114 } 4115 } 4116 4117 return results; 4118}; 4119 4120Sizzle.matches = function(expr, set){ 4121 return Sizzle(expr, null, null, set); 4122}; 4123 4124Sizzle.find = function(expr, context, isXML){ 4125 var set, match; 4126 4127 if ( !expr ) { 4128 return []; 4129 } 4130 4131 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 4132 var type = Expr.order[i], match; 4133 4134 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 4135 var left = match[1]; 4136 match.splice(1,1); 4137 4138 if ( left.substr( left.length - 1 ) !== "\\" ) { 4139 match[1] = (match[1] || "").replace(/\\/g, ""); 4140 set = Expr.find[ type ]( match, context, isXML ); 4141 if ( set != null ) { 4142 expr = expr.replace( Expr.match[ type ], "" ); 4143 break; 4144 } 4145 } 4146 } 4147 } 4148 4149 if ( !set ) { 4150 set = context.getElementsByTagName("*"); 4151 } 4152 4153 return {set: set, expr: expr}; 4154}; 4155 4156Sizzle.filter = function(expr, set, inplace, not){ 4157 var old = expr, result = [], curLoop = set, match, anyFound, 4158 isXMLFilter = set && set[0] && isXML(set[0]); 4159 4160 while ( expr && set.length ) { 4161 for ( var type in Expr.filter ) { 4162 if ( (match = Expr.match[ type ].exec( expr )) != null ) { 4163 var filter = Expr.filter[ type ], found, item; 4164 anyFound = false; 4165 4166 if ( curLoop == result ) { 4167 result = []; 4168 } 4169 4170 if ( Expr.preFilter[ type ] ) { 4171 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 4172 4173 if ( !match ) { 4174 anyFound = found = true; 4175 } else if ( match === true ) { 4176 continue; 4177 } 4178 } 4179 4180 if ( match ) { 4181 for ( var i = 0; (item = curLoop[i]) != null; i++ ) { 4182 if ( item ) { 4183 found = filter( item, match, i, curLoop ); 4184 var pass = not ^ !!found; 4185 4186 if ( inplace && found != null ) { 4187 if ( pass ) { 4188 anyFound = true; 4189 } else { 4190 curLoop[i] = false; 4191 } 4192 } else if ( pass ) { 4193 result.push( item ); 4194 anyFound = true; 4195 } 4196 } 4197 } 4198 } 4199 4200 if ( found !== undefined ) { 4201 if ( !inplace ) { 4202 curLoop = result; 4203 } 4204 4205 expr = expr.replace( Expr.match[ type ], "" ); 4206 4207 if ( !anyFound ) { 4208 return []; 4209 } 4210 4211 break; 4212 } 4213 } 4214 } 4215 4216 if ( expr == old ) { 4217 if ( anyFound == null ) { 4218 throw "Syntax error, unrecognized expression: " + expr; 4219 } else { 4220 break; 4221 } 4222 } 4223 4224 old = expr; 4225 } 4226 4227 return curLoop; 4228}; 4229 4230var Expr = Sizzle.selectors = { 4231 order: [ "ID", "NAME", "TAG" ], 4232 match: { 4233 ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, 4234 CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, 4235 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, 4236 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, 4237 TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, 4238 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, 4239 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, 4240 PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/ 4241 }, 4242 leftMatch: {}, 4243 attrMap: { 4244 "class": "className", 4245 "for": "htmlFor" 4246 }, 4247 attrHandle: { 4248 href: function(elem){ 4249 return elem.getAttribute("href"); 4250 } 4251 }, 4252 relative: { 4253 "+": function(checkSet, part, isXML){ 4254 var isPartStr = typeof part === "string", 4255 isTag = isPartStr && !/\W/.test(part), 4256 isPartStrNotTag = isPartStr && !isTag; 4257 4258 if ( isTag && !isXML ) { 4259 part = part.toUpperCase(); 4260 } 4261 4262 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 4263 if ( (elem = checkSet[i]) ) { 4264 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 4265 4266 checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ? 4267 elem || false : 4268 elem === part; 4269 } 4270 } 4271 4272 if ( isPartStrNotTag ) { 4273 Sizzle.filter( part, checkSet, true ); 4274 } 4275 }, 4276 ">": function(checkSet, part, isXML){ 4277 var isPartStr = typeof part === "string"; 4278 4279 if ( isPartStr && !/\W/.test(part) ) { 4280 part = isXML ? part : part.toUpperCase(); 4281 4282 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 4283 var elem = checkSet[i]; 4284 if ( elem ) { 4285 var parent = elem.parentNode; 4286 checkSet[i] = parent.nodeName === part ? parent : false; 4287 } 4288 } 4289 } else { 4290 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 4291 var elem = checkSet[i]; 4292 if ( elem ) { 4293 checkSet[i] = isPartStr ? 4294 elem.parentNode : 4295 elem.parentNode === part; 4296 } 4297 } 4298 4299 if ( isPartStr ) { 4300 Sizzle.filter( part, checkSet, true ); 4301 } 4302 } 4303 }, 4304 "": function(checkSet, part, isXML){ 4305 var doneName = done++, checkFn = dirCheck; 4306 4307 if ( !/\W/.test(part) ) { 4308 var nodeCheck = part = isXML ? part : part.toUpperCase(); 4309 checkFn = dirNodeCheck; 4310 } 4311 4312 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); 4313 }, 4314 "~": function(checkSet, part, isXML){ 4315 var doneName = done++, checkFn = dirCheck; 4316 4317 if ( typeof part === "string" && !/\W/.test(part) ) { 4318 var nodeCheck = part = isXML ? part : part.toUpperCase(); 4319 checkFn = dirNodeCheck; 4320 } 4321 4322 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); 4323 } 4324 }, 4325 find: { 4326 ID: function(match, context, isXML){ 4327 if ( typeof context.getElementById !== "undefined" && !isXML ) { 4328 var m = context.getElementById(match[1]); 4329 return m ? [m] : []; 4330 } 4331 }, 4332 NAME: function(match, context, isXML){ 4333 if ( typeof context.getElementsByName !== "undefined" ) { 4334 var ret = [], results = context.getElementsByName(match[1]); 4335 4336 for ( var i = 0, l = results.length; i < l; i++ ) { 4337 if ( results[i].getAttribute("name") === match[1] ) { 4338 ret.push( results[i] ); 4339 } 4340 } 4341 4342 return ret.length === 0 ? null : ret; 4343 } 4344 }, 4345 TAG: function(match, context){ 4346 return context.getElementsByTagName(match[1]); 4347 } 4348 }, 4349 preFilter: { 4350 CLASS: function(match, curLoop, inplace, result, not, isXML){ 4351 match = " " + match[1].replace(/\\/g, "") + " "; 4352 4353 if ( isXML ) { 4354 return match; 4355 } 4356 4357 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 4358 if ( elem ) { 4359 if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) { 4360 if ( !inplace ) 4361 result.push( elem ); 4362 } else if ( inplace ) { 4363 curLoop[i] = false; 4364 } 4365 } 4366 } 4367 4368 return false; 4369 }, 4370 ID: function(match){ 4371 return match[1].replace(/\\/g, ""); 4372 }, 4373 TAG: function(match, curLoop){ 4374 for ( var i = 0; curLoop[i] === false; i++ ){} 4375 return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase(); 4376 }, 4377 CHILD: function(match){ 4378 if ( match[1] == "nth" ) { 4379 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 4380 match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" || 4381 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 4382 4383 match[2] = (test[1] + (test[2] || 1)) - 0; 4384 match[3] = test[3] - 0; 4385 } 4386 4387 match[0] = done++; 4388 4389 return match; 4390 }, 4391 ATTR: function(match, curLoop, inplace, result, not, isXML){ 4392 var name = match[1].replace(/\\/g, ""); 4393 4394 if ( !isXML && Expr.attrMap[name] ) { 4395 match[1] = Expr.attrMap[name]; 4396 } 4397 4398 if ( match[2] === "~=" ) { 4399 match[4] = " " + match[4] + " "; 4400 } 4401 4402 return match; 4403 }, 4404 PSEUDO: function(match, curLoop, inplace, result, not){ 4405 if ( match[1] === "not" ) { 4406 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { 4407 match[3] = Sizzle(match[3], null, null, curLoop); 4408 } else { 4409 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 4410 if ( !inplace ) { 4411 result.push.apply( result, ret ); 4412 } 4413 return false; 4414 } 4415 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 4416 return true; 4417 } 4418 4419 return match; 4420 }, 4421 POS: function(match){ 4422 match.unshift( true ); 4423 return match; 4424 } 4425 }, 4426 filters: { 4427 enabled: function(elem){ 4428 return elem.disabled === false && elem.type !== "hidden"; 4429 }, 4430 disabled: function(elem){ 4431 return elem.disabled === true; 4432 }, 4433 checked: function(elem){ 4434 return elem.checked === true; 4435 }, 4436 selected: function(elem){ 4437 elem.parentNode.selectedIndex; 4438 return elem.selected === true; 4439 }, 4440 parent: function(elem){ 4441 return !!elem.firstChild; 4442 }, 4443 empty: function(elem){ 4444 return !elem.firstChild; 4445 }, 4446 has: function(elem, i, match){ 4447 return !!Sizzle( match[3], elem ).length; 4448 }, 4449 header: function(elem){ 4450 return /h\d/i.test( elem.nodeName ); 4451 }, 4452 text: function(elem){ 4453 return "text" === elem.type; 4454 }, 4455 radio: function(elem){ 4456 return "radio" === elem.type; 4457 }, 4458 checkbox: function(elem){ 4459 return "checkbox" === elem.type; 4460 }, 4461 file: function(elem){ 4462 return "file" === elem.type; 4463 }, 4464 password: function(elem){ 4465 return "password" === elem.type; 4466 }, 4467 submit: function(elem){ 4468 return "submit" === elem.type; 4469 }, 4470 image: function(elem){ 4471 return "image" === elem.type; 4472 }, 4473 reset: function(elem){ 4474 return "reset" === elem.type; 4475 }, 4476 button: function(elem){ 4477 return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON"; 4478 }, 4479 input: function(elem){ 4480 return /input|select|textarea|button/i.test(elem.nodeName); 4481 } 4482 }, 4483 setFilters: { 4484 first: function(elem, i){ 4485 return i === 0; 4486 }, 4487 last: function(elem, i, match, array){ 4488 return i === array.length - 1; 4489 }, 4490 even: function(elem, i){ 4491 return i % 2 === 0; 4492 }, 4493 odd: function(elem, i){ 4494 return i % 2 === 1; 4495 }, 4496 lt: function(elem, i, match){ 4497 return i < match[3] - 0; 4498 }, 4499 gt: function(elem, i, match){ 4500 return i > match[3] - 0; 4501 }, 4502 nth: function(elem, i, match){ 4503 return match[3] - 0 == i; 4504 }, 4505 eq: function(elem, i, match){ 4506 return match[3] - 0 == i; 4507 } 4508 }, 4509 filter: { 4510 PSEUDO: function(elem, match, i, array){ 4511 var name = match[1], filter = Expr.filters[ name ]; 4512 4513 if ( filter ) { 4514 return filter( elem, i, match, array ); 4515 } else if ( name === "contains" ) { 4516 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0; 4517 } else if ( name === "not" ) { 4518 var not = match[3]; 4519 4520 for ( var i = 0, l = not.length; i < l; i++ ) { 4521 if ( not[i] === elem ) { 4522 return false; 4523 } 4524 } 4525 4526 return true; 4527 } 4528 }, 4529 CHILD: function(elem, match){ 4530 var type = match[1], node = elem; 4531 switch (type) { 4532 case 'only': 4533 case 'first': 4534 while ( (node = node.previousSibling) ) { 4535 if ( node.nodeType === 1 ) return false; 4536 } 4537 if ( type == 'first') return true; 4538 node = elem; 4539 case 'last': 4540 while ( (node = node.nextSibling) ) { 4541 if ( node.nodeType === 1 ) return false; 4542 } 4543 return true; 4544 case 'nth': 4545 var first = match[2], last = match[3]; 4546 4547 if ( first == 1 && last == 0 ) { 4548 return true; 4549 } 4550 4551 var doneName = match[0], 4552 parent = elem.parentNode; 4553 4554 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { 4555 var count = 0; 4556 for ( node = parent.firstChild; node; node = node.nextSibling ) { 4557 if ( node.nodeType === 1 ) { 4558 node.nodeIndex = ++count; 4559 } 4560 } 4561 parent.sizcache = doneName; 4562 } 4563 4564 var diff = elem.nodeIndex - last; 4565 if ( first == 0 ) { 4566 return diff == 0; 4567 } else { 4568 return ( diff % first == 0 && diff / first >= 0 ); 4569 } 4570 } 4571 }, 4572 ID: function(elem, match){ 4573 return elem.nodeType === 1 && elem.getAttribute("id") === match; 4574 }, 4575 TAG: function(elem, match){ 4576 return (match === "*" && elem.nodeType === 1) || elem.nodeName === match; 4577 }, 4578 CLASS: function(elem, match){ 4579 return (" " + (elem.className || elem.getAttribute("class")) + " ") 4580 .indexOf( match ) > -1; 4581 }, 4582 ATTR: function(elem, match){ 4583 var name = match[1], 4584 result = Expr.attrHandle[ name ] ? 4585 Expr.attrHandle[ name ]( elem ) : 4586 elem[ name ] != null ? 4587 elem[ name ] : 4588 elem.getAttribute( name ), 4589 value = result + "", 4590 type = match[2], 4591 check = match[4]; 4592 4593 return result == null ? 4594 type === "!=" : 4595 type === "=" ? 4596 value === check : 4597 type === "*=" ? 4598 value.indexOf(check) >= 0 : 4599 type === "~=" ? 4600 (" " + value + " ").indexOf(check) >= 0 : 4601 !check ? 4602 value && result !== false : 4603 type === "!=" ? 4604 value != check : 4605 type === "^=" ? 4606 value.indexOf(check) === 0 : 4607 type === "$=" ? 4608 value.substr(value.length - check.length) === check : 4609 type === "|=" ? 4610 value === check || value.substr(0, check.length + 1) === check + "-" : 4611 false; 4612 }, 4613 POS: function(elem, match, i, array){ 4614 var name = match[2], filter = Expr.setFilters[ name ]; 4615 4616 if ( filter ) { 4617 return filter( elem, i, match, array ); 4618 } 4619 } 4620 } 4621}; 4622 4623var origPOS = Expr.match.POS; 4624 4625for ( var type in Expr.match ) { 4626 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); 4627 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source ); 4628} 4629 4630var makeArray = function(array, results) { 4631 array = Array.prototype.slice.call( array, 0 ); 4632 4633 if ( results ) { 4634 results.push.apply( results, array ); 4635 return results; 4636 } 4637 4638 return array; 4639}; 4640 4641try { 4642 Array.prototype.slice.call( document.documentElement.childNodes, 0 ); 4643 4644} catch(e){ 4645 makeArray = function(array, results) { 4646 var ret = results || []; 4647 4648 if ( toString.call(array) === "[object Array]" ) { 4649 Array.prototype.push.apply( ret, array ); 4650 } else { 4651 if ( typeof array.length === "number" ) { 4652 for ( var i = 0, l = array.length; i < l; i++ ) { 4653 ret.push( array[i] ); 4654 } 4655 } else { 4656 for ( var i = 0; array[i]; i++ ) { 4657 ret.push( array[i] ); 4658 } 4659 } 4660 } 4661 4662 return ret; 4663 }; 4664} 4665 4666var sortOrder; 4667 4668if ( document.documentElement.compareDocumentPosition ) { 4669 sortOrder = function( a, b ) { 4670 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { 4671 if ( a == b ) { 4672 hasDuplicate = true; 4673 } 4674 return 0; 4675 } 4676 4677 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; 4678 if ( ret === 0 ) { 4679 hasDuplicate = true; 4680 } 4681 return ret; 4682 }; 4683} else if ( "sourceIndex" in document.documentElement ) { 4684 sortOrder = function( a, b ) { 4685 if ( !a.sourceIndex || !b.sourceIndex ) { 4686 if ( a == b ) { 4687 hasDuplicate = true; 4688 } 4689 return 0; 4690 } 4691 4692 var ret = a.sourceIndex - b.sourceIndex; 4693 if ( ret === 0 ) { 4694 hasDuplicate = true; 4695 } 4696 return ret; 4697 }; 4698} else if ( document.createRange ) { 4699 sortOrder = function( a, b ) { 4700 if ( !a.ownerDocument || !b.ownerDocument ) { 4701 if ( a == b ) { 4702 hasDuplicate = true; 4703 } 4704 return 0; 4705 } 4706 4707 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); 4708 aRange.setStart(a, 0); 4709 aRange.setEnd(a, 0); 4710 bRange.setStart(b, 0); 4711 bRange.setEnd(b, 0); 4712 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); 4713 if ( ret === 0 ) { 4714 hasDuplicate = true; 4715 } 4716 return ret; 4717 }; 4718} 4719 4720(function(){ 4721 var form = document.createElement("div"), 4722 id = "script" + (new Date).getTime(); 4723 form.innerHTML = "<a name='" + id + "'/>"; 4724 4725 var root = document.documentElement; 4726 root.insertBefore( form, root.firstChild ); 4727 4728 if ( !!document.getElementById( id ) ) { 4729 Expr.find.ID = function(match, context, isXML){ 4730 if ( typeof context.getElementById !== "undefined" && !isXML ) { 4731 var m = context.getElementById(match[1]); 4732 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; 4733 } 4734 }; 4735 4736 Expr.filter.ID = function(elem, match){ 4737 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 4738 return elem.nodeType === 1 && node && node.nodeValue === match; 4739 }; 4740 } 4741 4742 root.removeChild( form ); 4743 root = form = null; // release memory in IE 4744})(); 4745 4746(function(){ 4747 4748 var div = document.createElement("div"); 4749 div.appendChild( document.createComment("") ); 4750 4751 if ( div.getElementsByTagName("*").length > 0 ) { 4752 Expr.find.TAG = function(match, context){ 4753 var results = context.getElementsByTagName(match[1]); 4754 4755 if ( match[1] === "*" ) { 4756 var tmp = []; 4757 4758 for ( var i = 0; results[i]; i++ ) { 4759 if ( results[i].nodeType === 1 ) { 4760 tmp.push( results[i] ); 4761 } 4762 } 4763 4764 results = tmp; 4765 } 4766 4767 return results; 4768 }; 4769 } 4770 4771 div.innerHTML = "<a href='#'></a>"; 4772 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 4773 div.firstChild.getAttribute("href") !== "#" ) { 4774 Expr.attrHandle.href = function(elem){ 4775 return elem.getAttribute("href", 2); 4776 }; 4777 } 4778 4779 div = null; // release memory in IE 4780})(); 4781 4782if ( document.querySelectorAll ) (function(){ 4783 var oldSizzle = Sizzle, div = document.createElement("div"); 4784 div.innerHTML = "<p class='TEST'></p>"; 4785 4786 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 4787 return; 4788 } 4789 4790 Sizzle = function(query, context, extra, seed){ 4791 context = context || document; 4792 4793 if ( !seed && context.nodeType === 9 && !isXML(context) ) { 4794 try { 4795 return makeArray( context.querySelectorAll(query), extra ); 4796 } catch(e){} 4797 } 4798 4799 return oldSizzle(query, context, extra, seed); 4800 }; 4801 4802 for ( var prop in oldSizzle ) { 4803 Sizzle[ prop ] = oldSizzle[ prop ]; 4804 } 4805 4806 div = null; // release memory in IE 4807})(); 4808 4809if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ 4810 var div = document.createElement("div"); 4811 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 4812 4813 if ( div.getElementsByClassName("e").length === 0 ) 4814 return; 4815 4816 div.lastChild.className = "e"; 4817 4818 if ( div.getElementsByClassName("e").length === 1 ) 4819 return; 4820 4821 Expr.order.splice(1, 0, "CLASS"); 4822 Expr.find.CLASS = function(match, context, isXML) { 4823 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 4824 return context.getElementsByClassName(match[1]); 4825 } 4826 }; 4827 4828 div = null; // release memory in IE 4829})(); 4830 4831function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 4832 var sibDir = dir == "previousSibling" && !isXML; 4833 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 4834 var elem = checkSet[i]; 4835 if ( elem ) { 4836 if ( sibDir && elem.nodeType === 1 ){ 4837 elem.sizcache = doneName; 4838 elem.sizset = i; 4839 } 4840 elem = elem[dir]; 4841 var match = false; 4842 4843 while ( elem ) { 4844 if ( elem.sizcache === doneName ) { 4845 match = checkSet[elem.sizset]; 4846 break; 4847 } 4848 4849 if ( elem.nodeType === 1 && !isXML ){ 4850 elem.sizcache = doneName; 4851 elem.sizset = i; 4852 } 4853 4854 if ( elem.nodeName === cur ) { 4855 match = elem; 4856 break; 4857 } 4858 4859 elem = elem[dir]; 4860 } 4861 4862 checkSet[i] = match; 4863 } 4864 } 4865} 4866 4867function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 4868 var sibDir = dir == "previousSibling" && !isXML; 4869 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 4870 var elem = checkSet[i]; 4871 if ( elem ) { 4872 if ( sibDir && elem.nodeType === 1 ) { 4873 elem.sizcache = doneName; 4874 elem.sizset = i; 4875 } 4876 elem = elem[dir]; 4877 var match = false; 4878 4879 while ( elem ) { 4880 if ( elem.sizcache === doneName ) { 4881 match = checkSet[elem.sizset]; 4882 break; 4883 } 4884 4885 if ( elem.nodeType === 1 ) { 4886 if ( !isXML ) { 4887 elem.sizcache = doneName; 4888 elem.sizset = i; 4889 } 4890 if ( typeof cur !== "string" ) { 4891 if ( elem === cur ) { 4892 match = true; 4893 break; 4894 } 4895 4896 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 4897 match = elem; 4898 break; 4899 } 4900 } 4901 4902 elem = elem[dir]; 4903 } 4904 4905 checkSet[i] = match; 4906 } 4907 } 4908} 4909 4910var contains = document.compareDocumentPosition ? function(a, b){ 4911 return a.compareDocumentPosition(b) & 16; 4912} : function(a, b){ 4913 return a !== b && (a.contains ? a.contains(b) : true); 4914}; 4915 4916var isXML = function(elem){ 4917 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || 4918 !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; 4919}; 4920 4921var posProcess = function(selector, context){ 4922 var tmpSet = [], later = "", match, 4923 root = context.nodeType ? [context] : context; 4924 4925 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 4926 later += match[0]; 4927 selector = selector.replace( Expr.match.PSEUDO, "" ); 4928 } 4929 4930 selector = Expr.relative[selector] ? selector + "*" : selector; 4931 4932 for ( var i = 0, l = root.length; i < l; i++ ) { 4933 Sizzle( selector, root[i], tmpSet ); 4934 } 4935 4936 return Sizzle.filter( later, tmpSet ); 4937}; 4938 4939 4940window.Sizzle = Sizzle; 4941 4942})(); 4943 4944;(function(engine) { 4945 var extendElements = Prototype.Selector.extendElements; 4946 4947 function select(selector, scope) { 4948 return extendElements(engine(selector, scope || document)); 4949 } 4950 4951 function match(element, selector) { 4952 return engine.matches(selector, [element]).length == 1; 4953 } 4954 4955 Prototype.Selector.engine = engine; 4956 Prototype.Selector.select = select; 4957 Prototype.Selector.match = match; 4958})(Sizzle); 4959 4960window.Sizzle = Prototype._original_property; 4961delete Prototype._original_property; 4962 4963var Form = { 4964 reset: function(form) { 4965 form = $(form); 4966 form.reset(); 4967 return form; 4968 }, 4969 4970 serializeElements: function(elements, options) { 4971 if (typeof options != 'object') options = { hash: !!options }; 4972 else if (Object.isUndefined(options.hash)) options.hash = true; 4973 var key, value, submitted = false, submit = options.submit, accumulator, initial; 4974 4975 if (options.hash) { 4976 initial = {}; 4977 accumulator = function(result, key, value) { 4978 if (key in result) { 4979 if (!Object.isArray(result[key])) result[key] = [result[key]]; 4980 result[key].push(value); 4981 } else result[key] = value; 4982 return result; 4983 }; 4984 } else { 4985 initial = ''; 4986 accumulator = function(result, key, value) { 4987 return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value); 4988 } 4989 } 4990 4991 return elements.inject(initial, function(result, element) { 4992 if (!element.disabled && element.name) { 4993 key = element.name; value = $(element).getValue(); 4994 if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && 4995 submit !== false && (!submit || key == submit) && (submitted = true)))) { 4996 result = accumulator(result, key, value); 4997 } 4998 } 4999 return result; 5000 }); 5001 } 5002}; 5003 5004Form.Methods = { 5005 serialize: function(form, options) { 5006 return Form.serializeElements(Form.getElements(form), options); 5007 }, 5008 5009 getElements: function(form) { 5010 var elements = $(form).getElementsByTagName('*'), 5011 element, 5012 arr = [ ], 5013 serializers = Form.Element.Serializers; 5014 for (var i = 0; element = elements[i]; i++) { 5015 arr.push(element); 5016 } 5017 return arr.inject([], function(elements, child) { 5018 if (serializers[child.tagName.toLowerCase()]) 5019 elements.push(Element.extend(child)); 5020 return elements; 5021 }) 5022 }, 5023 5024 getInputs: function(form, typeName, name) { 5025 form = $(form); 5026 var inputs = form.getElementsByTagName('input'); 5027 5028 if (!typeName && !name) return $A(inputs).map(Element.extend); 5029 5030 for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { 5031 var input = inputs[i]; 5032 if ((typeName && input.type != typeName) || (name && input.name != name)) 5033 continue; 5034 matchingInputs.push(Element.extend(input)); 5035 } 5036 5037 return matchingInputs; 5038 }, 5039 5040 disable: function(form) { 5041 form = $(form); 5042 Form.getElements(form).invoke('disable'); 5043 return form; 5044 }, 5045 5046 enable: function(form) { 5047 form = $(form); 5048 Form.getElements(form).invoke('enable'); 5049 return form; 5050 }, 5051 5052 findFirstElement: function(form) { 5053 var elements = $(form).getElements().findAll(function(element) { 5054 return 'hidden' != element.type && !element.disabled; 5055 }); 5056 var firstByIndex = elements.findAll(function(element) { 5057 return element.hasAttribute('tabIndex') && element.tabIndex >= 0; 5058 }).sortBy(function(element) { return element.tabIndex }).first(); 5059 5060 return firstByIndex ? firstByIndex : elements.find(function(element) { 5061 return /^(?:input|select|textarea)$/i.test(element.tagName); 5062 }); 5063 }, 5064 5065 focusFirstElement: function(form) { 5066 form = $(form); 5067 var element = form.findFirstElement(); 5068 if (element) element.activate(); 5069 return form; 5070 }, 5071 5072 request: function(form, options) { 5073 form = $(form), options = Object.clone(options || { }); 5074 5075 var params = options.parameters, action = form.readAttribute('action') || ''; 5076 if (action.blank()) action = window.location.href; 5077 options.parameters = form.serialize(true); 5078 5079 if (params) { 5080 if (Object.isString(params)) params = params.toQueryParams(); 5081 Object.extend(options.parameters, params); 5082 } 5083 5084 if (form.hasAttribute('method') && !options.method) 5085 options.method = form.method; 5086 5087 return new Ajax.Request(action, options); 5088 } 5089}; 5090 5091/*--------------------------------------------------------------------------*/ 5092 5093 5094Form.Element = { 5095 focus: function(element) { 5096 $(element).focus(); 5097 return element; 5098 }, 5099 5100 select: function(element) { 5101 $(element).select(); 5102 return element; 5103 } 5104}; 5105 5106Form.Element.Methods = { 5107 5108 serialize: function(element) { 5109 element = $(element); 5110 if (!element.disabled && element.name) { 5111 var value = element.getValue(); 5112 if (value != undefined) { 5113 var pair = { }; 5114 pair[element.name] = value; 5115 return Object.toQueryString(pair); 5116 } 5117 } 5118 return ''; 5119 }, 5120 5121 getValue: function(element) { 5122 element = $(element); 5123 var method = element.tagName.toLowerCase(); 5124 return Form.Element.Serializers[method](element); 5125 }, 5126 5127 setValue: function(element, value) { 5128 element = $(element); 5129 var method = element.tagName.toLowerCase(); 5130 Form.Element.Serializers[method](element, value); 5131 return element; 5132 }, 5133 5134 clear: function(element) { 5135 $(element).value = ''; 5136 return element; 5137 }, 5138 5139 present: function(element) { 5140 return $(element).value != ''; 5141 }, 5142 5143 activate: function(element) { 5144 element = $(element); 5145 try { 5146 element.focus(); 5147 if (element.select && (element.tagName.toLowerCase() != 'input' || 5148 !(/^(?:button|reset|submit)$/i.test(element.type)))) 5149 element.select(); 5150 } catch (e) { } 5151 return element; 5152 }, 5153 5154 disable: function(element) { 5155 element = $(element); 5156 element.disabled = true; 5157 return element; 5158 }, 5159 5160 enable: function(element) { 5161 element = $(element); 5162 element.disabled = false; 5163 return element; 5164 } 5165}; 5166 5167/*--------------------------------------------------------------------------*/ 5168 5169var Field = Form.Element; 5170 5171var $F = Form.Element.Methods.getValue; 5172 5173/*--------------------------------------------------------------------------*/ 5174 5175Form.Element.Serializers = (function() { 5176 function input(element, value) { 5177 switch (element.type.toLowerCase()) { 5178 case 'checkbox': 5179 case 'radio': 5180 return inputSelector(element, value); 5181 default: 5182 return valueSelector(element, value); 5183 } 5184 } 5185 5186 function inputSelector(element, value) { 5187 if (Object.isUndefined(value)) 5188 return element.checked ? element.value : null; 5189 else element.checked = !!value; 5190 } 5191 5192 function valueSelector(element, value) { 5193 if (Object.isUndefined(value)) return element.value; 5194 else element.value = value; 5195 } 5196 5197 function select(element, value) { 5198 if (Object.isUndefined(value)) 5199 return (element.type === 'select-one' ? selectOne : selectMany)(element); 5200 5201 var opt, currentValue, single = !Object.isArray(value); 5202 for (var i = 0, length = element.length; i < length; i++) { 5203 opt = element.options[i]; 5204 currentValue = this.optionValue(opt); 5205 if (single) { 5206 if (currentValue == value) { 5207 opt.selected = true; 5208 return; 5209 } 5210 } 5211 else opt.selected = value.include(currentValue); 5212 } 5213 } 5214 5215 function selectOne(element) { 5216 var index = element.selectedIndex; 5217 return index >= 0 ? optionValue(element.options[index]) : null; 5218 } 5219 5220 function selectMany(element) { 5221 var values, length = element.length; 5222 if (!length) return null; 5223 5224 for (var i = 0, values = []; i < length; i++) { 5225 var opt = element.options[i]; 5226 if (opt.selected) values.push(optionValue(opt)); 5227 } 5228 return values; 5229 } 5230 5231 function optionValue(opt) { 5232 return Element.hasAttribute(opt, 'value') ? opt.value : opt.text; 5233 } 5234 5235 return { 5236 input: input, 5237 inputSelector: inputSelector, 5238 textarea: valueSelector, 5239 select: select, 5240 selectOne: selectOne, 5241 selectMany: selectMany, 5242 optionValue: optionValue, 5243 button: valueSelector 5244 }; 5245})(); 5246 5247/*--------------------------------------------------------------------------*/ 5248 5249 5250Abstract.TimedObserver = Class.create(PeriodicalExecuter, { 5251 initialize: function($super, element, frequency, callback) { 5252 $super(callback, frequency); 5253 this.element = $(element); 5254 this.lastValue = this.getValue(); 5255 }, 5256 5257 execute: function() { 5258 var value = this.getValue(); 5259 if (Object.isString(this.lastValue) && Object.isString(value) ? 5260 this.lastValue != value : String(this.lastValue) != String(value)) { 5261 this.callback(this.element, value); 5262 this.lastValue = value; 5263 } 5264 } 5265}); 5266 5267Form.Element.Observer = Class.create(Abstract.TimedObserver, { 5268 getValue: function() { 5269 return Form.Element.getValue(this.element); 5270 } 5271}); 5272 5273Form.Observer = Class.create(Abstract.TimedObserver, { 5274 getValue: function() { 5275 return Form.serialize(this.element); 5276 } 5277}); 5278 5279/*--------------------------------------------------------------------------*/ 5280 5281Abstract.EventObserver = Class.create({ 5282 initialize: function(element, callback) { 5283 this.element = $(element); 5284 this.callback = callback; 5285 5286 this.lastValue = this.getValue(); 5287 if (this.element.tagName.toLowerCase() == 'form') 5288 this.registerFormCallbacks(); 5289 else 5290 this.registerCallback(this.element); 5291 }, 5292 5293 onElementEvent: function() { 5294 var value = this.getValue(); 5295 if (this.lastValue != value) { 5296 this.callback(this.element, value); 5297 this.lastValue = value; 5298 } 5299 }, 5300 5301 registerFormCallbacks: function() { 5302 Form.getElements(this.element).each(this.registerCallback, this); 5303 }, 5304 5305 registerCallback: function(element) { 5306 if (element.type) { 5307 switch (element.type.toLowerCase()) { 5308 case 'checkbox': 5309 case 'radio': 5310 Event.observe(element, 'click', this.onElementEvent.bind(this)); 5311 break; 5312 default: 5313 Event.observe(element, 'change', this.onElementEvent.bind(this)); 5314 break; 5315 } 5316 } 5317 } 5318}); 5319 5320Form.Element.EventObserver = Class.create(Abstract.EventObserver, { 5321 getValue: function() { 5322 return Form.Element.getValue(this.element); 5323 } 5324}); 5325 5326Form.EventObserver = Class.create(Abstract.EventObserver, { 5327 getValue: function() { 5328 return Form.serialize(this.element); 5329 } 5330}); 5331(function() { 5332 5333 var Event = { 5334 KEY_BACKSPACE: 8, 5335 KEY_TAB: 9, 5336 KEY_RETURN: 13, 5337 KEY_ESC: 27, 5338 KEY_LEFT: 37, 5339 KEY_UP: 38, 5340 KEY_RIGHT: 39, 5341 KEY_DOWN: 40, 5342 KEY_DELETE: 46, 5343 KEY_HOME: 36, 5344 KEY_END: 35, 5345 KEY_PAGEUP: 33, 5346 KEY_PAGEDOWN: 34, 5347 KEY_INSERT: 45, 5348 5349 cache: {} 5350 }; 5351 5352 var docEl = document.documentElement; 5353 var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl 5354 && 'onmouseleave' in docEl; 5355 5356 5357 5358 var isIELegacyEvent = function(event) { return false; }; 5359 5360 if (window.attachEvent) { 5361 if (window.addEventListener) { 5362 isIELegacyEvent = function(event) { 5363 return !(event instanceof window.Event); 5364 }; 5365 } else { 5366 isIELegacyEvent = function(event) { return true; }; 5367 } 5368 } 5369 5370 var _isButton; 5371 5372 function _isButtonForDOMEvents(event, code) { 5373 return event.which ? (event.which === code + 1) : (event.button === code); 5374 } 5375 5376 var legacyButtonMap = { 0: 1, 1: 4, 2: 2 }; 5377 function _isButtonForLegacyEvents(event, code) { 5378 return event.button === legacyButtonMap[code]; 5379 } 5380 5381 function _isButtonForWebKit(event, code) { 5382 switch (code) { 5383 case 0: return event.which == 1 && !event.metaKey; 5384 case 1: return event.which == 2 || (event.which == 1 && event.metaKey); 5385 case 2: return event.which == 3; 5386 default: return false; 5387 } 5388 } 5389 5390 if (window.attachEvent) { 5391 if (!window.addEventListener) { 5392 _isButton = _isButtonForLegacyEvents; 5393 } else { 5394 _isButton = function(event, code) { 5395 return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) : 5396 _isButtonForDOMEvents(event, code); 5397 } 5398 } 5399 } else if (Prototype.Browser.WebKit) { 5400 _isButton = _isButtonForWebKit; 5401 } else { 5402 _isButton = _isButtonForDOMEvents; 5403 } 5404 5405 function isLeftClick(event) { return _isButton(event, 0) } 5406 5407 function isMiddleClick(event) { return _isButton(event, 1) } 5408 5409 function isRightClick(event) { return _isButton(event, 2) } 5410 5411 function element(event) { 5412 event = Event.extend(event); 5413 5414 var node = event.target, type = event.type, 5415 currentTarget = event.currentTarget; 5416 5417 if (currentTarget && currentTarget.tagName) { 5418 if (type === 'load' || type === 'error' || 5419 (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' 5420 && currentTarget.type === 'radio')) 5421 node = currentTarget; 5422 } 5423 5424 if (node.nodeType == Node.TEXT_NODE) 5425 node = node.parentNode; 5426 5427 return Element.extend(node); 5428 } 5429 5430 function findElement(event, expression) { 5431 var element = Event.element(event); 5432 5433 if (!expression) return element; 5434 while (element) { 5435 if (Object.isElement(element) && Prototype.Selector.match(element, expression)) { 5436 return Element.extend(element); 5437 } 5438 element = element.parentNode; 5439 } 5440 } 5441 5442 function pointer(event) { 5443 return { x: pointerX(event), y: pointerY(event) }; 5444 } 5445 5446 function pointerX(event) { 5447 var docElement = document.documentElement, 5448 body = document.body || { scrollLeft: 0 }; 5449 5450 return event.pageX || (event.clientX + 5451 (docElement.scrollLeft || body.scrollLeft) - 5452 (docElement.clientLeft || 0)); 5453 } 5454 5455 function pointerY(event) { 5456 var docElement = document.documentElement, 5457 body = document.body || { scrollTop: 0 }; 5458 5459 return event.pageY || (event.clientY + 5460 (docElement.scrollTop || body.scrollTop) - 5461 (docElement.clientTop || 0)); 5462 } 5463 5464 5465 function stop(event) { 5466 Event.extend(event); 5467 event.preventDefault(); 5468 event.stopPropagation(); 5469 5470 event.stopped = true; 5471 } 5472 5473 5474 Event.Methods = { 5475 isLeftClick: isLeftClick, 5476 isMiddleClick: isMiddleClick, 5477 isRightClick: isRightClick, 5478 5479 element: element, 5480 findElement: findElement, 5481 5482 pointer: pointer, 5483 pointerX: pointerX, 5484 pointerY: pointerY, 5485 5486 stop: stop 5487 }; 5488 5489 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { 5490 m[name] = Event.Methods[name].methodize(); 5491 return m; 5492 }); 5493 5494 if (window.attachEvent) { 5495 function _relatedTarget(event) { 5496 var element; 5497 switch (event.type) { 5498 case 'mouseover': 5499 case 'mouseenter': 5500 element = event.fromElement; 5501 break; 5502 case 'mouseout': 5503 case 'mouseleave': 5504 element = event.toElement; 5505 break; 5506 default: 5507 return null; 5508 } 5509 return Element.extend(element); 5510 } 5511 5512 var additionalMethods = { 5513 stopPropagation: function() { this.cancelBubble = true }, 5514 preventDefault: function() { this.returnValue = false }, 5515 inspect: function() { return '[object Event]' } 5516 }; 5517 5518 Event.extend = function(event, element) { 5519 if (!event) return false; 5520 5521 if (!isIELegacyEvent(event)) return event; 5522 5523 if (event._extendedByPrototype) return event; 5524 event._extendedByPrototype = Prototype.emptyFunction; 5525 5526 var pointer = Event.pointer(event); 5527 5528 Object.extend(event, { 5529 target: event.srcElement || element, 5530 relatedTarget: _relatedTarget(event), 5531 pageX: pointer.x, 5532 pageY: pointer.y 5533 }); 5534 5535 Object.extend(event, methods); 5536 Object.extend(event, additionalMethods); 5537 5538 return event; 5539 }; 5540 } else { 5541 Event.extend = Prototype.K; 5542 } 5543 5544 if (window.addEventListener) { 5545 Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; 5546 Object.extend(Event.prototype, methods); 5547 } 5548 5549 function _createResponder(element, eventName, handler) { 5550 var registry = Element.retrieve(element, 'prototype_event_registry'); 5551 5552 if (Object.isUndefined(registry)) { 5553 CACHE.push(element); 5554 registry = Element.retrieve(element, 'prototype_event_registry', $H()); 5555 } 5556 5557 var respondersForEvent = registry.get(eventName); 5558 if (Object.isUndefined(respondersForEvent)) { 5559 respondersForEvent = []; 5560 registry.set(eventName, respondersForEvent); 5561 } 5562 5563 if (respondersForEvent.pluck('handler').include(handler)) return false; 5564 5565 var responder; 5566 if (eventName.include(":")) { 5567 responder = function(event) { 5568 if (Object.isUndefined(event.eventName)) 5569 return false; 5570 5571 if (event.eventName !== eventName) 5572 return false; 5573 5574 Event.extend(event, element); 5575 handler.call(element, event); 5576 }; 5577 } else { 5578 if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && 5579 (eventName === "mouseenter" || eventName === "mouseleave")) { 5580 if (eventName === "mouseenter" || eventName === "mouseleave") { 5581 responder = function(event) { 5582 Event.extend(event, element); 5583 5584 var parent = event.relatedTarget; 5585 while (parent && parent !== element) { 5586 try { parent = parent.parentNode; } 5587 catch(e) { parent = element; } 5588 } 5589 5590 if (parent === element) return; 5591 5592 handler.call(element, event); 5593 }; 5594 } 5595 } else { 5596 responder = function(event) { 5597 Event.extend(event, element); 5598 handler.call(element, event); 5599 }; 5600 } 5601 } 5602 5603 responder.handler = handler; 5604 respondersForEvent.push(responder); 5605 return responder; 5606 } 5607 5608 function _destroyCache() { 5609 for (var i = 0, length = CACHE.length; i < length; i++) { 5610 Event.stopObserving(CACHE[i]); 5611 CACHE[i] = null; 5612 } 5613 } 5614 5615 var CACHE = []; 5616 5617 if (Prototype.Browser.IE) 5618 window.attachEvent('onunload', _destroyCache); 5619 5620 if (Prototype.Browser.WebKit) 5621 window.addEventListener('unload', Prototype.emptyFunction, false); 5622 5623 5624 var _getDOMEventName = Prototype.K, 5625 translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; 5626 5627 if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { 5628 _getDOMEventName = function(eventName) { 5629 return (translations[eventName] || eventName); 5630 }; 5631 } 5632 5633 function observe(element, eventName, handler) { 5634 element = $(element); 5635 5636 var responder = _createResponder(element, eventName, handler); 5637 5638 if (!responder) return element; 5639 5640 if (eventName.include(':')) { 5641 if (element.addEventListener) 5642 element.addEventListener("dataavailable", responder, false); 5643 else { 5644 element.attachEvent("ondataavailable", responder); 5645 element.attachEvent("onlosecapture", responder); 5646 } 5647 } else { 5648 var actualEventName = _getDOMEventName(eventName); 5649 5650 if (element.addEventListener) 5651 element.addEventListener(actualEventName, responder, false); 5652 else 5653 element.attachEvent("on" + actualEventName, responder); 5654 } 5655 5656 return element; 5657 } 5658 5659 function stopObserving(element, eventName, handler) { 5660 element = $(element); 5661 5662 var registry = Element.retrieve(element, 'prototype_event_registry'); 5663 if (!registry) return element; 5664 5665 if (!eventName) { 5666 registry.each( function(pair) { 5667 var eventName = pair.key; 5668 stopObserving(element, eventName); 5669 }); 5670 return element; 5671 } 5672 5673 var responders = registry.get(eventName); 5674 if (!responders) return element; 5675 5676 if (!handler) { 5677 responders.each(function(r) { 5678 stopObserving(element, eventName, r.handler); 5679 }); 5680 return element; 5681 } 5682 5683 var i = responders.length, responder; 5684 while (i--) { 5685 if (responders[i].handler === handler) { 5686 responder = responders[i]; 5687 break; 5688 } 5689 } 5690 if (!responder) return element; 5691 5692 if (eventName.include(':')) { 5693 if (element.removeEventListener) 5694 element.removeEventListener("dataavailable", responder, false); 5695 else { 5696 element.detachEvent("ondataavailable", responder); 5697 element.detachEvent("onlosecapture", responder); 5698 } 5699 } else { 5700 var actualEventName = _getDOMEventName(eventName); 5701 if (element.removeEventListener) 5702 element.removeEventListener(actualEventName, responder, false); 5703 else 5704 element.detachEvent('on' + actualEventName, responder); 5705 } 5706 5707 registry.set(eventName, responders.without(responder)); 5708 5709 return element; 5710 } 5711 5712 function fire(element, eventName, memo, bubble) { 5713 element = $(element); 5714 5715 if (Object.isUndefined(bubble)) 5716 bubble = true; 5717 5718 if (element == document && document.createEvent && !element.dispatchEvent) 5719 element = document.documentElement; 5720 5721 var event; 5722 if (document.createEvent) { 5723 event = document.createEvent('HTMLEvents'); 5724 event.initEvent('dataavailable', bubble, true); 5725 } else { 5726 event = document.createEventObject(); 5727 event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; 5728 } 5729 5730 event.eventName = eventName; 5731 event.memo = memo || { }; 5732 5733 if (document.createEvent) 5734 element.dispatchEvent(event); 5735 else 5736 element.fireEvent(event.eventType, event); 5737 5738 return Event.extend(event); 5739 } 5740 5741 Event.Handler = Class.create({ 5742 initialize: function(element, eventName, selector, callback) { 5743 this.element = $(element); 5744 this.eventName = eventName; 5745 this.selector = selector; 5746 this.callback = callback; 5747 this.handler = this.handleEvent.bind(this); 5748 }, 5749 5750 start: function() { 5751 Event.observe(this.element, this.eventName, this.handler); 5752 return this; 5753 }, 5754 5755 stop: function() { 5756 Event.stopObserving(this.element, this.eventName, this.handler); 5757 return this; 5758 }, 5759 5760 handleEvent: function(event) { 5761 var element = Event.findElement(event, this.selector); 5762 if (element) this.callback.call(this.element, event, element); 5763 } 5764 }); 5765 5766 function on(element, eventName, selector, callback) { 5767 element = $(element); 5768 if (Object.isFunction(selector) && Object.isUndefined(callback)) { 5769 callback = selector, selector = null; 5770 } 5771 5772 return new Event.Handler(element, eventName, selector, callback).start(); 5773 } 5774 5775 Object.extend(Event, Event.Methods); 5776 5777 Object.extend(Event, { 5778 fire: fire, 5779 observe: observe, 5780 stopObserving: stopObserving, 5781 on: on 5782 }); 5783 5784 Element.addMethods({ 5785 fire: fire, 5786 5787 observe: observe, 5788 5789 stopObserving: stopObserving, 5790 5791 on: on 5792 }); 5793 5794 Object.extend(document, { 5795 fire: fire.methodize(), 5796 5797 observe: observe.methodize(), 5798 5799 stopObserving: stopObserving.methodize(), 5800 5801 on: on.methodize(), 5802 5803 loaded: false 5804 }); 5805 5806 if (window.Event) Object.extend(window.Event, Event); 5807 else window.Event = Event; 5808})(); 5809 5810(function() { 5811 /* Support for the DOMContentLoaded event is based on work by Dan Webb, 5812 Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ 5813 5814 var timer; 5815 5816 function fireContentLoadedEvent() { 5817 if (document.loaded) return; 5818 if (timer) window.clearTimeout(timer); 5819 document.loaded = true; 5820 document.fire('dom:loaded'); 5821 } 5822 5823 function checkReadyState() { 5824 if (document.readyState === 'complete') { 5825 document.stopObserving('readystatechange', checkReadyState); 5826 fireContentLoadedEvent(); 5827 } 5828 } 5829 5830 function pollDoScroll() { 5831 try { document.documentElement.doScroll('left'); } 5832 catch(e) { 5833 timer = pollDoScroll.defer(); 5834 return; 5835 } 5836 fireContentLoadedEvent(); 5837 } 5838 5839 if (document.addEventListener) { 5840 document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); 5841 } else { 5842 document.observe('readystatechange', checkReadyState); 5843 if (window == top) 5844 timer = pollDoScroll.defer(); 5845 } 5846 5847 Event.observe(window, 'load', fireContentLoadedEvent); 5848})(); 5849 5850Element.addMethods(); 5851 5852/*------------------------------- DEPRECATED -------------------------------*/ 5853 5854Hash.toQueryString = Object.toQueryString; 5855 5856var Toggle = { display: Element.toggle }; 5857 5858Element.Methods.childOf = Element.Methods.descendantOf; 5859 5860var Insertion = { 5861 Before: function(element, content) { 5862 return Element.insert(element, {before:content}); 5863 }, 5864 5865 Top: function(element, content) { 5866 return Element.insert(element, {top:content}); 5867 }, 5868 5869 Bottom: function(element, content) { 5870 return Element.insert(element, {bottom:content}); 5871 }, 5872 5873 After: function(element, content) { 5874 return Element.insert(element, {after:content}); 5875 } 5876}; 5877 5878var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); 5879 5880var Position = { 5881 includeScrollOffsets: false, 5882 5883 prepare: function() { 5884 this.deltaX = window.pageXOffset 5885 || document.documentElement.scrollLeft 5886 || document.body.scrollLeft 5887 || 0; 5888 this.deltaY = window.pageYOffset 5889 || document.documentElement.scrollTop 5890 || document.body.scrollTop 5891 || 0; 5892 }, 5893 5894 within: function(element, x, y) { 5895 if (this.includeScrollOffsets) 5896 return this.withinIncludingScrolloffsets(element, x, y); 5897 this.xcomp = x; 5898 this.ycomp = y; 5899 this.offset = Element.cumulativeOffset(element); 5900 5901 return (y >= this.offset[1] && 5902 y < this.offset[1] + element.offsetHeight && 5903 x >= this.offset[0] && 5904 x < this.offset[0] + element.offsetWidth); 5905 }, 5906 5907 withinIncludingScrolloffsets: function(element, x, y) { 5908 var offsetcache = Element.cumulativeScrollOffset(element); 5909 5910 this.xcomp = x + offsetcache[0] - this.deltaX; 5911 this.ycomp = y + offsetcache[1] - this.deltaY; 5912 this.offset = Element.cumulativeOffset(element); 5913 5914 return (this.ycomp >= this.offset[1] && 5915 this.ycomp < this.offset[1] + element.offsetHeight && 5916 this.xcomp >= this.offset[0] && 5917 this.xcomp < this.offset[0] + element.offsetWidth); 5918 }, 5919 5920 overlap: function(mode, element) { 5921 if (!mode) return 0; 5922 if (mode == 'vertical') 5923 return ((this.offset[1] + element.offsetHeight) - this.ycomp) / 5924 element.offsetHeight; 5925 if (mode == 'horizontal') 5926 return ((this.offset[0] + element.offsetWidth) - this.xcomp) / 5927 element.offsetWidth; 5928 }, 5929 5930 5931 cumulativeOffset: Element.Methods.cumulativeOffset, 5932 5933 positionedOffset: Element.Methods.positionedOffset, 5934 5935 absolutize: function(element) { 5936 Position.prepare(); 5937 return Element.absolutize(element); 5938 }, 5939 5940 relativize: function(element) { 5941 Position.prepare(); 5942 return Element.relativize(element); 5943 }, 5944 5945 realOffset: Element.Methods.cumulativeScrollOffset, 5946 5947 offsetParent: Element.Methods.getOffsetParent, 5948 5949 page: Element.Methods.viewportOffset, 5950 5951 clone: function(source, target, options) { 5952 options = options || { }; 5953 return Element.clonePosition(target, source, options); 5954 } 5955}; 5956 5957/*--------------------------------------------------------------------------*/ 5958 5959if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ 5960 function iter(name) { 5961 return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; 5962 } 5963 5964 instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? 5965 function(element, className) { 5966 className = className.toString().strip(); 5967 var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); 5968 return cond ? document._getElementsByXPath('.//*' + cond, element) : []; 5969 } : function(element, className) { 5970 className = className.toString().strip(); 5971 var elements = [], classNames = (/\s/.test(className) ? $w(className) : null); 5972 if (!classNames && !className) return elements; 5973 5974 var nodes = $(element).getElementsByTagName('*'); 5975 className = ' ' + className + ' '; 5976 5977 for (var i = 0, child, cn; child = nodes[i]; i++) { 5978 if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || 5979 (classNames && classNames.all(function(name) { 5980 return !name.toString().blank() && cn.include(' ' + name + ' '); 5981 })))) 5982 elements.push(Element.extend(child)); 5983 } 5984 return elements; 5985 }; 5986 5987 return function(className, parentElement) { 5988 return $(parentElement || document.body).getElementsByClassName(className); 5989 }; 5990}(Element.Methods); 5991 5992/*--------------------------------------------------------------------------*/ 5993 5994Element.ClassNames = Class.create(); 5995Element.ClassNames.prototype = { 5996 initialize: function(element) { 5997 this.element = $(element); 5998 }, 5999 6000 _each: function(iterator) { 6001 this.element.className.split(/\s+/).select(function(name) { 6002 return name.length > 0; 6003 })._each(iterator); 6004 }, 6005 6006 set: function(className) { 6007 this.element.className = className; 6008 }, 6009 6010 add: function(classNameToAdd) { 6011 if (this.include(classNameToAdd)) return; 6012 this.set($A(this).concat(classNameToAdd).join(' ')); 6013 }, 6014 6015 remove: function(classNameToRemove) { 6016 if (!this.include(classNameToRemove)) return; 6017 this.set($A(this).without(classNameToRemove).join(' ')); 6018 }, 6019 6020 toString: function() { 6021 return $A(this).join(' '); 6022 } 6023}; 6024 6025Object.extend(Element.ClassNames.prototype, Enumerable); 6026 6027/*--------------------------------------------------------------------------*/ 6028 6029(function() { 6030 window.Selector = Class.create({ 6031 initialize: function(expression) { 6032 this.expression = expression.strip(); 6033 }, 6034 6035 findElements: function(rootElement) { 6036 return Prototype.Selector.select(this.expression, rootElement); 6037 }, 6038 6039 match: function(element) { 6040 return Prototype.Selector.match(element, this.expression); 6041 }, 6042 6043 toString: function() { 6044 return this.expression; 6045 }, 6046 6047 inspect: function() { 6048 return "#<Selector: " + this.expression + ">"; 6049 } 6050 }); 6051 6052 Object.extend(Selector, { 6053 matchElements: function(elements, expression) { 6054 var match = Prototype.Selector.match, 6055 results = []; 6056 6057 for (var i = 0, length = elements.length; i < length; i++) { 6058 var element = elements[i]; 6059 if (match(element, expression)) { 6060 results.push(Element.extend(element)); 6061 } 6062 } 6063 return results; 6064 }, 6065 6066 findElement: function(elements, expression, index) { 6067 index = index || 0; 6068 var matchIndex = 0, element; 6069 for (var i = 0, length = elements.length; i < length; i++) { 6070 element = elements[i]; 6071 if (Prototype.Selector.match(element, expression) && index === matchIndex++) { 6072 return Element.extend(element); 6073 } 6074 } 6075 }, 6076 6077 findChildElements: function(element, expressions) { 6078 var selector = expressions.toArray().join(', '); 6079 return Prototype.Selector.select(selector, element || document); 6080 } 6081 }); 6082})(); 6083