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