1var Prototype = { 2 Version: '1.6.0.3', 3 Browser: { 4 IE: !! (window.attachEvent && navigator.userAgent.indexOf('Opera') === -1), 5 Opera: navigator.userAgent.indexOf('Opera') > -1, 6 WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, 7 Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') === -1, 8 MobileSafari: !! navigator.userAgent.match(/Apple.*Mobile.*Safari/) 9 }, 10 BrowserFeatures: { 11 XPath: !! document.evaluate, 12 SelectorsAPI: !! document.querySelector, 13 ElementExtensions: !! window.HTMLElement, 14 SpecificElementExtensions: document.createElement('div')['__proto__'] && document.createElement('div')['__proto__'] !== document.createElement('form')['__proto__'] 15 }, 16 ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', 17 JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, 18 emptyFunction: function() {}, 19 K: function(x) { 20 return x 21 } 22}; 23if (Prototype.Browser.MobileSafari) Prototype.BrowserFeatures.SpecificElementExtensions = false; 24var Class = { 25 create: function() { 26 var parent = null, 27 properties = $A(arguments); 28 if (Object.isFunction(properties[0])) parent = properties.shift(); 29 30 function klass() { 31 this.initialize.apply(this, arguments); 32 } 33 Object.extend(klass, Class.Methods); 34 klass.superclass = parent; 35 klass.subclasses = []; 36 if (parent) { 37 var subclass = function() {}; 38 subclass.prototype = parent.prototype; 39 klass.prototype = new subclass; 40 parent.subclasses.push(klass); 41 } 42 for (var i = 0; i < properties.length; i++) 43 klass.addMethods(properties[i]); 44 if (!klass.prototype.initialize) klass.prototype.initialize = Prototype.emptyFunction; 45 klass.prototype.constructor = klass; 46 return klass; 47 } 48}; 49Class.Methods = { 50 addMethods: function(source) { 51 var ancestor = this.superclass && this.superclass.prototype; 52 var properties = Object.keys(source); 53 if (!Object.keys({ 54 toString: true 55 }).length) properties.push("toString", "valueOf"); 56 for (var i = 0, length = properties.length; i < length; i++) { 57 var property = properties[i], 58 value = source[property]; 59 if (ancestor && Object.isFunction(value) && value.argumentNames().first() == "$super") { 60 var method = value; 61 value = (function(m) { 62 return function() { 63 return ancestor[m].apply(this, arguments) 64 }; 65 })(property).wrap(method); 66 value.valueOf = method.valueOf.bind(method); 67 value.toString = method.toString.bind(method); 68 } 69 this.prototype[property] = value; 70 } 71 return this; 72 } 73}; 74var Abstract = {}; 75Object.extend = function(destination, source) { 76 for (var property in source) 77 destination[property] = source[property]; 78 return destination; 79}; 80Object.extend(Object, { 81 inspect: function(object) { 82 try { 83 if (Object.isUndefined(object)) return 'undefined'; 84 if (object === null) return 'null'; 85 return object.inspect ? object.inspect() : String(object); 86 } catch (e) { 87 if (e instanceof RangeError) return '...'; 88 throw e; 89 } 90 }, 91 toJSON: function(object) { 92 var type = typeof object; 93 switch (type) { 94 case 'undefined': 95 case 'function': 96 case 'unknown': 97 return; 98 case 'boolean': 99 return object.toString(); 100 } 101 if (object === null) return 'null'; 102 if (object.toJSON) return object.toJSON(); 103 if (Object.isElement(object)) return; 104 var results = []; 105 for (var property in object) { 106 var value = Object.toJSON(object[property]); 107 if (!Object.isUndefined(value)) results.push(property.toJSON() + ': ' + value); 108 } 109 return '{' + results.join(', ') + '}'; 110 }, 111 toQueryString: function(object) { 112 return $H(object).toQueryString(); 113 }, 114 toHTML: function(object) { 115 return object && object.toHTML ? object.toHTML() : String.interpret(object); 116 }, 117 keys: function(object) { 118 var keys = []; 119 for (var property in object) 120 keys.push(property); 121 return keys; 122 }, 123 values: function(object) { 124 var values = []; 125 for (var property in object) 126 values.push(object[property]); 127 return values; 128 }, 129 clone: function(object) { 130 return Object.extend({}, object); 131 }, 132 isElement: function(object) { 133 return !!(object && object.nodeType == 1); 134 }, 135 isArray: function(object) { 136 return object != null && typeof object == "object" && 'splice' in object && 'join' in object; 137 }, 138 isHash: function(object) { 139 return object instanceof Hash; 140 }, 141 isFunction: function(object) { 142 return typeof object == "function"; 143 }, 144 isString: function(object) { 145 return typeof object == "string"; 146 }, 147 isNumber: function(object) { 148 return typeof object == "number"; 149 }, 150 isUndefined: function(object) { 151 return typeof object == "undefined"; 152 } 153}); 154Object.extend(Function.prototype, { 155 argumentNames: function() {
156 var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1].replace(/\s+/g, '').split(','); 157 return names.length == 1 && !names[0] ? [] : names; 158 }, 159 bind: function() { 160 if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; 161 var __method = this, 162 args = $A(arguments), 163 object = args.shift(); 164 return function() { 165 return __method.apply(object, args.concat($A(arguments))); 166 } 167 }, 168 bindAsEventListener: function() { 169 var __method = this, 170 args = $A(arguments), 171 object = args.shift(); 172 return function(event) { 173 return __method.apply(object, [event || window.event].concat(args)); 174 } 175 }, 176 curry: function() { 177 if (!arguments.length) return this; 178 var __method = this, 179 args = $A(arguments); 180 return function() { 181 return __method.apply(this, args.concat($A(arguments))); 182 } 183 }, 184 delay: function() { 185 var __method = this, 186 args = $A(arguments), 187 timeout = args.shift() * 1000; 188 return window.setTimeout(function() { 189 return __method.apply(__method, args); 190 }, timeout); 191 }, 192 defer: function() { 193 var args = [0.01].concat($A(arguments)); 194 return this.delay.apply(this, args); 195 }, 196 wrap: function(wrapper) { 197 var __method = this; 198 return function() { 199 return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); 200 } 201 }, 202 methodize: function() { 203 if (this._methodized) return this._methodized; 204 var __method = this; 205 return this._methodized = function() { 206 return __method.apply(null, [this].concat($A(arguments))); 207 }; 208 } 209}); 210Date.prototype.toJSON = function() { 211 return '"' + this.getUTCFullYear() + '-' + (this.getUTCMonth() + 1).toPaddedString(2) + '-' + this.getUTCDate().toPaddedString(2) + 'T' + this.getUTCHours().toPaddedString(2) + ':' + this.getUTCMinutes().toPaddedString(2) + ':' + this.getUTCSeconds().toPaddedString(2) + 'Z"'; 212}; 213var Try = { 214 these: function() { 215 var returnValue; 216 for (var i = 0, length = arguments.length; i < length; i++) { 217 var lambda = arguments[i]; 218 try { 219 returnValue = lambda(); 220 break; 221 } catch (e) {} 222 } 223 return returnValue; 224 } 225}; 226RegExp.prototype.match = RegExp.prototype.test; 227RegExp.escape = function(str) { 228 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 229}; 230var PeriodicalExecuter = Class.create({ 231 initialize: function(callback, frequency) { 232 this.callback = callback; 233 this.frequency = frequency; 234 this.currentlyExecuting = false; 235 this.registerCallback(); 236 }, 237 registerCallback: function() { 238 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 239 }, 240 execute: function() { 241 this.callback(this); 242 }, 243 stop: function() { 244 if (!this.timer) return; 245 clearInterval(this.timer); 246 this.timer = null; 247 }, 248 onTimerEvent: function() { 249 if (!this.currentlyExecuting) { 250 try { 251 this.currentlyExecuting = true; 252 this.execute(); 253 } finally { 254 this.currentlyExecuting = false; 255 } 256 } 257 } 258}); 259Object.extend(String, { 260 interpret: function(value) { 261 return value == null ? '' : String(value); 262 }, 263 specialChar: { 264 '\b': '\\b', 265 '\t': '\\t', 266 '\n': '\\n', 267 '\f': '\\f', 268 '\r': '\\r', 269 '\\': '\\\\' 270 } 271}); 272Object.extend(String.prototype, { 273 gsub: function(pattern, replacement) { 274 var result = '', 275 source = this, 276 match; 277 replacement = arguments.callee.prepareReplacement(replacement); 278 while (source.length > 0) { 279 if (match = source.match(pattern)) { 280 result += source.slice(0, match.index); 281 result += String.interpret(replacement(match)); 282 source = source.slice(match.index + match[0].length); 283 } else { 284 result += source, source = ''; 285 } 286 } 287 return result; 288 }, 289 sub: function(pattern, replacement, count) { 290 replacement = this.gsub.prepareReplacement(replacement); 291 count = Object.isUndefined(count) ? 1 : count; 292 return this.gsub(pattern, function(match) { 293 if (--count < 0) return match[0]; 294 return replacement(match); 295 }); 296 }, 297 scan: function(pattern, iterator) { 298 this.gsub(pattern, iterator); 299 return String(this); 300 }, 301 truncate: function(length, truncation) { 302 length = length || 30; 303 truncation = Object.isUndefined(truncation) ? '...' : truncation; 304 return this.length > length ? this.slice(0, length - truncation.length) + truncation : String(this); 305 }, 306 strip: function() { 307 return this.replace(/^\s+/, '').replace(/\s+$/, ''); 308 }, 309 stripTags: function() { 310 return this.replace(/<\/?[^>]+>/gi, ''); 311 }, 312 stripScripts: function() { 313 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); 314 }, 315 extractScripts: function() { 316 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); 317 var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); 318 return (this.match(matchAll) || []).map(function(scriptTag) { 319 return (scriptTag.match(matchOne) || ['', ''])[1]; 320 }); 321 }, 322 evalScripts: function() { 323 return this.extractScripts().map(function(script) { 324 return eval(script) 325 }); 326 }, 327 escapeHTML: function() { 328 var self = arguments.callee; 329 self.text.data = this; 330 return self.div.innerHTML; 331 }, 332 unescapeHTML: function() { 333 var div = new Element('div'); 334 div.innerHTML = this.stripTags(); 335 return div.childNodes[0] ? (div.childNodes.length > 1 ? $A(div.childNodes).inject('', function(memo, node) { 336 return memo + node.nodeValue 337 }) : div.childNodes[0].nodeValue) : ''; 338 }, 339 toQueryParams: function(separator) { 340 var match = this.strip().match(/([^?#]*)(#.*)?$/); 341 if (!match) return {}; 342 return match[1].split(separator || '&').inject({}, function(hash, pair) { 343 if ((pair = pair.split('='))[0]) { 344 var key = decodeURIComponent(pair.shift()); 345 var value = pair.length > 1 ? pair.join('=') : pair[0]; 346 if (value != undefined) value = decodeURIComponent(value); 347 if (key in hash) { 348 if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; 349 hash[key].push(value); 350 } 351 else hash[key] = value; 352 } 353 return hash; 354 }); 355 }, 356 toArray: function() { 357 return this.split(''); 358 }, 359 succ: function() { 360 return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); 361 }, 362 times: function(count) { 363 return count < 1 ? '' : new Array(count + 1).join(this); 364 }, 365 camelize: function() { 366 var parts = this.split('-'), 367 len = parts.length; 368 if (len == 1) return parts[0]; 369 var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0]; 370 for (var i = 1; i < len; i++) 371 camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); 372 return camelized; 373 }, 374 capitalize: function() { 375 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); 376 }, 377 underscore: function() { 378 return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/, '#{1}_#{2}').gsub(/([a-z\d])([A-Z])/, '#{1}_#{2}').gsub(/-/, '_').toLowerCase(); 379 }, 380 dasherize: function() { 381 return this.gsub(/_/, '-'); 382 }, 383 inspect: function(useDoubleQuotes) { 384 var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { 385 var character = String.specialChar[match[0]]; 386 return character ? character : '\\u00' + match[0].charCo
386deAt().toPaddedString(2, 16); 387 }); 388 if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; 389 return "'" + escapedString.replace(/'/g, '\\\'') + "'"; 390 }, 391 toJSON: function() { 392 return this.inspect(true); 393 }, 394 unfilterJSON: function(filter) { 395 return this.sub(filter || Prototype.JSONFilter, '#{1}'); 396 }, 397 isJSON: function() { 398 var str = this; 399 if (str.blank()) return false; 400 str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); 401 return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); 402 }, 403 evalJSON: function(sanitize) { 404 var json = this.unfilterJSON(); 405 try { 406 if (!sanitize || json.isJSON()) return eval('(' + json + ')'); 407 } catch (e) {} 408 throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); 409 }, 410 include: function(pattern) { 411 return this.indexOf(pattern) > -1; 412 }, 413 startsWith: function(pattern) { 414 return this.indexOf(pattern) === 0; 415 }, 416 endsWith: function(pattern) { 417 var d = this.length - pattern.length; 418 return d >= 0 && this.lastIndexOf(pattern) === d; 419 }, 420 empty: function() { 421 return this == ''; 422 }, 423 blank: function() { 424 return /^\s*$/.test(this); 425 }, 426 interpolate: function(object, pattern) { 427 return new Template(this, pattern).evaluate(object); 428 } 429}); 430if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { 431 escapeHTML: function() { 432 return this.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); 433 }, 434 unescapeHTML: function() { 435 return this.stripTags().replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); 436 } 437}); 438String.prototype.gsub.prepareReplacement = function(replacement) { 439 if (Object.isFunction(replacement)) return replacement; 440 var template = new Template(replacement); 441 return function(match) { 442 return template.evaluate(match) 443 }; 444}; 445String.prototype.parseQuery = String.prototype.toQueryParams; 446Object.extend(String.prototype.escapeHTML, { 447 div: document.createElement('div'), 448 text: document.createTextNode('') 449}); 450String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text); 451var Template = Class.create({ 452 initialize: function(template, pattern) { 453 this.template = template.toString(); 454 this.pattern = pattern || Template.Pattern; 455 }, 456 evaluate: function(object) { 457 if (Object.isFunction(object.toTemplateReplacements)) object = object.toTemplateReplacements(); 458 return this.template.gsub(this.pattern, function(match) { 459 if (object == null) return ''; 460 var before = match[1] || ''; 461 if (before == '\\') return match[2]; 462 var ctx = object, 463 expr = match[3]; 464 var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; 465 match = pattern.exec(expr); 466 if (match == null) return before; 467 while (match != null) { 468 var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; 469 ctx = ctx[comp]; 470 if (null == ctx || '' == match[3]) break; 471 expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); 472 match = pattern.exec(expr); 473 } 474 return before + String.interpret(ctx); 475 }); 476 } 477}); 478Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 479var $break = {}; 480var Enumerable = { 481 each: function(iterator, context) { 482 var index = 0; 483 try { 484 this._each(function(value) { 485 iterator.call(context, value, index++); 486 }); 487 } catch (e) { 488 if (e != $break) throw e; 489 } 490 return this; 491 }, 492 eachSlice: function(number, iterator, context) { 493 var index = -number, 494 slices = [], 495 array = this.toArray(); 496 if (number < 1) return array; 497 while ((index += number) < array.length) 498 slices.push(array.slice(index, index + number)); 499 return slices.collect(iterator, context); 500 }, 501 all: function(iterator, context) { 502 iterator = iterator || Prototype.K; 503 var result = true; 504 this.each(function(value, index) { 505 result = result && !! iterator.call(context, value, index); 506 if (!result) throw $break; 507 }); 508 return result; 509 }, 510 any: function(iterator, context) { 511 iterator = iterator || Prototype.K; 512 var result = false;
513 this.each(function(value, index) { 514 if (result = !! iterator.call(context, value, index)) throw $break; 515 }); 516 return result; 517 }, 518 collect: function(iterator, context) { 519 iterator = iterator || Prototype.K; 520 var results = []; 521 this.each(function(value, index) { 522 results.push(iterator.call(context, value, index)); 523 }); 524 return results; 525 }, 526 detect: function(iterator, context) { 527 var result; 528 this.each(function(value, index) { 529 if (iterator.call(context, value, index)) { 530 result = value; 531 throw $break; 532 } 533 }); 534 return result; 535 }, 536 findAll: function(iterator, context) { 537 var results = []; 538 this.each(function(value, index) { 539 if (iterator.call(context, value, index)) results.push(value); 540 }); 541 return results; 542 }, 543 grep: function(filter, iterator, context) { 544 iterator = iterator || Prototype.K; 545 var results = []; 546 if (Object.isString(filter)) filter = new RegExp(filter); 547 this.each(function(value, index) { 548 if (filter.match(value)) results.push(iterator.call(context, value, index)); 549 }); 550 return results; 551 }, 552 include: function(object) { 553 if (Object.isFunction(this.indexOf)) if (this.indexOf(object) != -1) return true; 554 var found = false; 555 this.each(function(value) { 556 if (value == object) { 557 found = true; 558 throw $break; 559 } 560 }); 561 return found; 562 }, 563 inGroupsOf: function(number, fillWith) { 564 fillWith = Object.isUndefined(fillWith) ? null : fillWith; 565 return this.eachSlice(number, function(slice) { 566 while (slice.length < number) slice.push(fillWith); 567 return slice; 568 }); 569 }, 570 inject: function(memo, iterator, context) { 571 this.each(function(value, index) { 572 memo = iterator.call(context, memo, value, index); 573 }); 574 return memo; 575 }, 576 invoke: function(method) { 577 var args = $A(arguments).slice(1); 578 return this.map(function(value) { 579 return value[method].apply(value, args); 580 }); 581 }, 582 max: function(iterator, context) { 583 iterator = iterator || Prototype.K; 584 var result; 585 this.each(function(value, index) { 586 value = iterator.call(context, value, index); 587 if (result == null || value >= result) result = value; 588 }); 589 return result; 590 }, 591 min: function(iterator, context) { 592 iterator = iterator || Prototype.K; 593 var result; 594 this.each(function(value, index) { 595 value = iterator.call(context, value, index); 596 if (result == null || value < result) result = value; 597 }); 598 return result; 599 }, 600 partition: function(iterator, context) { 601 iterator = iterator || Prototype.K; 602 var trues = [], 603 falses = []; 604 this.each(function(value, index) { 605 (iterator.call(context, value, index) ? trues : falses).push(value); 606 }); 607 return [trues, falses]; 608 }, 609 pluck: function(property) { 610 var results = []; 611 this.each(function(value) { 612 results.push(value[property]); 613 }); 614 return results; 615 }, 616 reject: function(iterator, context) { 617 var results = []; 618 this.each(function(value, index) { 619 if (!iterator.call(context, value, index)) results.push(value); 620 }); 621 return results; 622 }, 623 sortBy: function(iterator, context) { 624 return this.map(function(value, index) { 625 return { 626 value: value, 627 criteria: iterator.call(context, value, index) 628 }; 629 }).sort(function(left, right) { 630 var a = left.criteria, 631 b = right.criteria; 632 return a < b ? -1 : a > b ? 1 : 0; 633 }).pluck('value'); 634 }, 635 toArray: function() { 636 return this.map(); 637 }, 638 zip: function() { 639 var iterator = Prototype.K, 640 args = $A(arguments); 641 if (Object.isFunction(args.last())) iterator = args.pop(); 642 var collections = [this].concat(args).map($A); 643 return this.map(function(value, index) { 644 return iterator(collections.pluck(index)); 645 }); 646 }, 647 size: function() { 648 return this.toArray().length; 649 }, 650 inspect: function() { 651 return '#<Enumerable:' + this.toArray().inspect() + '>'; 652 } 653}; 654Object.extend(Enumerable, { 655 map: Enumerable.collect, 656 find: Enumerable.detect, 657 select: Enumerable.findAll, 658 filter: Enumerable.findAll, 659 member: Enumerable.include, 660 entries: Enumerable.toArray, 661 every: Enumerable.all, 662 some: Enumerable.any 663}); 664 665function $A(iterable) { 666 if (!iterable) return []; 667 if (iterable.toArray) return iterable.toArray(); 668 var length = iterable.length || 0, 669 results = new Array(length); 670 while (length--) results[length] = iterable[length]; 671 return results; 672} 673if (Prototype.Browser.WebKit) { 674 $A = function(iterable) { 675 if (!iterable) return []; 676 if (!(typeof iterable === 'function' && typeof iterable.length === 'number' && typeof iterable.item === 'function') && iterable.toArray) return iterable.toArray(); 677 var length = iterable.length || 0, 678 results = new Array(length); 679 while (length--) results[length] = iterable[length]; 680 return results; 681 }; 682} 683Array.from = $A; 684Object.extend(Array.prototype, Enumerable); 685if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; 686Object.extend(Array.prototype, { 687 _each: function(iterator) { 688 for (var i = 0, length = this.length; i < length; i++) 689 iterator(this[i]); 690 }, 691 clear: function() { 692 this.length = 0; 693 return this; 694 }, 695 first: function() { 696 return this[0]; 697 }, 698 last: function() { 699 return this[this.length - 1]; 700 }, 701 compact: function() { 702 return this.select(function(value) { 703 return value != null; 704 }); 705 }, 706 flatten: function() { 707 return this.inject([], function(array, value) { 708 return array.concat(Object.isArray(value) ? value.flatten() : [value]); 709 }); 710 }, 711 without: function() { 712 var values = $A(arguments); 713 return this.select(function(value) { 714 return !values.include(value); 715 }); 716 }, 717 reverse: function(inline) { 718 return (inline !== false ? this : this.toArray())._reverse(); 719 }, 720 reduce: function() { 721 return this.length >
721 1 ? this : this[0]; 722 }, 723 uniq: function(sorted) { 724 return this.inject([], function(array, value, index) { 725 if (0 == index || (sorted ? array.last() != value : !array.include(value))) array.push(value); 726 return array; 727 }); 728 }, 729 intersect: function(array) { 730 return this.uniq().findAll(function(item) { 731 return array.detect(function(value) { 732 return item === value 733 }); 734 }); 735 }, 736 clone: function() { 737 return [].concat(this); 738 }, 739 size: function() { 740 return this.length; 741 }, 742 inspect: function() { 743 return '[' + this.map(Object.inspect).join(', ') + ']'; 744 }, 745 toJSON: function() { 746 var results = []; 747 this.each(function(object) { 748 var value = Object.toJSON(object); 749 if (!Object.isUndefined(value)) results.push(value); 750 }); 751 return '[' + results.join(', ') + ']'; 752 } 753}); 754if (Object.isFunction(Array.prototype.forEach)) Array.prototype._each = Array.prototype.forEach; 755if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { 756 i || (i = 0); 757 var length = this.length; 758 if (i < 0) i = length + i; 759 for (; i < length; i++) 760 if (this[i] === item) return i; 761 return -1; 762}; 763if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { 764 i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; 765 var n = this.slice(0, i).reverse().indexOf(item); 766 return (n < 0) ? n : i - n - 1; 767}; 768Array.prototype.toArray = Array.prototype.clone; 769 770function $w(string) { 771 if (!Object.isString(string)) return []; 772 string = string.strip(); 773 return string ? string.split(/\s+/) : []; 774} 775if (Prototype.Browser.Opera) { 776 Array.prototype.concat = function() { 777 var array = []; 778 for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); 779 for (var i = 0, length = arguments.length; i < length; i++) { 780 if (Object.isArray(arguments[i])) { 781 for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) 782 array.push(arguments[i][j]); 783 } else { 784 array.push(arguments[i]); 785 } 786 } 787 return array; 788 }; 789} 790Object.extend(Number.prototype, { 791 toColorPart: function() { 792 return this.toPaddedString(2, 16); 793 }, 794 succ: function() { 795 return this + 1; 796 }, 797 times: function(iterator, context) { 798 $R(0, this, true).each(iterator, context); 799 return this; 800 }, 801 toPaddedString: function(length, radix) { 802 var string = this.toString(radix || 10); 803 return '0'.times(length - string.length) + string; 804 }, 805 toJSON: function() { 806 return isFinite(this) ? this.toString() : 'null'; 807 } 808}); 809$w('abs round ceil floor').each(function(method) { 810 Number.prototype[method] = Math[method].methodize(); 811}); 812 813function $H(object) { 814 return new Hash(object); 815}; 816var Hash = Class.create(Enumerable, (function() { 817 function toQueryPair(key, value) { 818 if (Object.isUndefined(value)) return key; 819 return key + '=' + encodeURIComponent(String.interpret(value)); 820 } 821 return { 822 initialize: function(object) { 823 this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); 824 }, 825 _each: function(iterator) { 826 for (var key in this._object) { 827 var value = this._object[key], 828 pair = [key, value]; 829 pair.key = key; 830 pair.value = value; 831 iterator(pair); 832 } 833 }, 834 set: function(key, value) { 835 return this._object[key] = value; 836 }, 837 get: function(key) { 838 if (this._object[key] !== Object.prototype[key]) return this._object[key]; 839 }, 840 unset: function(key) { 841 var value = this._object[key]; 842 delete this._object[key]; 843 return value; 844 }, 845 toObject: function() { 846 return Object.clone(this._object); 847 }, 848 keys: function() { 849 return this.pluck('key'); 850 }, 851 values: function() { 852 return this.pluck('value'); 853 }, 854 index: function(value) { 855 var match = this.detect(function(pair) { 856 return pair.value === value; 857 }); 858 return match && match.key; 859 }, 860 merge: function(object) { 861 return this.clone().update(object); 862 }, 863 update: function(object) { 864 return new Hash(object).inject(this, function(result, pair) { 865 result.set(pair.key, pair.value); 866 return result; 867 }); 868 }, 869 toQueryString: function() { 870 return this.inject([], function(results, pair) { 871 var key = encodeURIComponent(pair.key), 872 values = pair.value; 873 if (values && typeof values == 'object') { 874 if (Object.isArray(values)) return results.concat(values.map(toQueryPair.curry(key))); 875 } else results.push(toQueryPair(key, values)); 876 return results; 877 }).join('&'); 878 }, 879 inspect: function() { 880 return '#<Hash:{' + this.map(function(pair) { 881 return pair.map(Object.inspect).join(': '); 882 }).join(', ') + '}>'; 883 }, 884 toJSON: function() { 885 return Object.toJSON(this.toObject()); 886 }, 887 clone: function() { 888 return new Hash(this); 889 } 890 } 891})()); 892Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; 893Hash.from = $H; 894var ObjectRange = Class.create(Enumerable, { 895 initialize: function(start, end, exclusive) { 896 this.start = start; 897 this.end = end; 898 this.exclusive = exclusive; 899 }, 900 _each: function(iterator) { 901 var value = this.start; 902 while (this.include(value)) { 903 iterator(value); 904 value = value.succ(); 905 } 906 }, 907 include: function(value) { 908 if (value < this.start) return false;
909 if (this.exclusive) return value < this.end; 910 return value <= this.end; 911 } 912}); 913var $R = function(start, end, exclusive) { 914 return new ObjectRange(start, end, exclusive); 915}; 916var Ajax = { 917 getTransport: function() { 918 return Try.these(function() { 919 return new XMLHttpRequest() 920 }, function() { 921 return new ActiveXObject('Msxml2.XMLHTTP') 922 }, function() { 923 return new ActiveXObject('Microsoft.XMLHTTP') 924 }) || false; 925 }, 926 activeRequestCount: 0 927}; 928Ajax.Responders = { 929 responders: [], 930 _each: function(iterator) { 931 this.responders._each(iterator); 932 }, 933 register: function(responder) { 934 if (!this.include(responder)) this.responders.push(responder); 935 }, 936 unregister: function(responder) { 937 this.responders = this.responders.without(responder); 938 }, 939 dispatch: function(callback, request, transport, json) { 940 this.each(function(responder) { 941 if (Object.isFunction(responder[callback])) { 942 try { 943 responder[callback].apply(responder, [request, transport, json]); 944 } catch (e) {} 945 } 946 }); 947 } 948}; 949Object.extend(Ajax.Responders, Enumerable); 950Ajax.Responders.register({ 951 onCreate: function() { 952 Ajax.activeRequestCount++ 953 }, 954 onComplete: function() { 955 Ajax.activeRequestCount-- 956 } 957}); 958Ajax.Base = Class.create({ 959 initialize: function(options) { 960 this.options = { 961 method: 'post', 962 asynchronous: true, 963 contentType: 'application/x-www-form-urlencoded', 964 encoding: 'UTF-8', 965 parameters: '', 966 evalJSON: true, 967 evalJS: true 968 }; 969 Object.extend(this.options, options || {}); 970 this.options.method = this.options.method.toLowerCase(); 971 if (Object.isString(this.options.parameters)) this.options.parameters = this.options.parameters.toQueryParams(); 972 else if (Object.isHash(this.options.parameters)) this.options.parameters = this.options.parameters.toObject(); 973 } 974}); 975Ajax.Request = Class.create(Ajax.Base, { 976 _complete: false, 977 initialize: function($super, url, options) { 978 $super(options); 979 this.transport = Ajax.getTransport(); 980 this.request(url); 981 }, 982 request: function(url) { 983 this.url = url; 984 this.method = this.options.method; 985 var params = Object.clone(this.options.parameters); 986 if (!['get', 'post'].include(this.method)) { 987 params['_method'] = this.method; 988 this.method = 'post'; 989 } 990 this.parameters = params; 991 if (params = Object.toQueryString(params)) { 992 if (this.method == 'get') this.url += (this.url.include('?') ? '&' : '?') + params; 993 else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='; 994 } 995 try { 996 var response = new Ajax.Response(this); 997 if (this.options.onCreate) this.options.onCreate(response); 998 Ajax.Responders.dispatch('onCreate', this, response); 999 this.transport.open(this.method.toUpperCase(), this.url, this.options.asynchronous); 1000 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); 1001 this.transport.onreadystatechange = this.onStateChange.bind(this); 1002 this.setRequestHeaders(); 1003 this.body = this.method == 'post' ? (this.options.postBody || params) : null; 1004 this.transport.send(this.body); 1005 if (!this.options.asynchronous && this.transport.overrideMimeType) this.onStateChange(); 1006 } 1007 catch (e) { 1008 this.dispatchException(e); 1009 } 1010 }, 1011 onStateChange: function() { 1012 var readyState = this.transport.readyState; 1013 if (readyState > 1 && !((readyState == 4) && this._complete)) this.respondToReadyState(this.transport.readyState); 1014 }, 1015 setRequestHeaders: function() { 1016 var headers = { 1017 'X-Requested-With': 'XMLHttpRequest', 1018 'X-Prototype-Version': Prototype.Version, 1019 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' 1020 }; 1021 if (this.method == 'post') { 1022 headers['Content-type'] = this.options.contentType + (this.options.encoding ? '; charset=' + this.options.encoding : ''); 1023 if (this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0, 2005])[1] < 2005) headers['Connection'] = 'close'; 1024 } 1025 if (typeof this.options.requestHeaders == 'object') { 1026 var extras = this.options.requestHeaders; 1027 if (Object.isFunction(extras.push)) for (var i = 0, length = extras.length; i < length; i += 2) headers[extras[i]] = extras[i + 1]; 1028 else $H(extras).each(function(pair) { 1029 headers[pair.key] = pair.value 1030 }); 1031 } 1032 for (var name in headers) 1033 this.transport.setRequestHeader(name, headers[name]); 1034 }, 1035 success: function() {
1036 var status = this.getStatus(); 1037 return !status || (status >= 200 && status < 300); 1038 }, 1039 getStatus: function() { 1040 try { 1041 return this.transport.status || 0; 1042 } catch (e) { 1043 return 0 1044 } 1045 }, 1046 respondToReadyState: function(readyState) { 1047 var state = Ajax.Request.Events[readyState], 1048 response = new Ajax.Response(this); 1049 if (state == 'Complete') { 1050 try { 1051 this._complete = true; 1052 (this.options['on' + response.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(response, response.headerJSON); 1053 } catch (e) { 1054 this.dispatchException(e); 1055 } 1056 var contentType = response.getHeader('Content-type'); 1057 if (this.options.evalJS == 'force' || (this.options.evalJS && this.isSameOrigin() && contentType && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) this.evalResponse(); 1058 } 1059 try { 1060 (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); 1061 Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); 1062 } catch (e) { 1063 this.dispatchException(e); 1064 } 1065 if (state == 'Complete') { 1066 this.transport.onreadystatechange = Prototype.emptyFunction; 1067 } 1068 }, 1069 isSameOrigin: function() { 1070 var m = this.url.match(/^\s*https?:\/\/[^\/]*/); 1071 return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ 1072 protocol: location.protocol, 1073 domain: document.domain, 1074 port: location.port ? ':' + location.port : '' 1075 })); 1076 }, 1077 getHeader: function(name) { 1078 try { 1079 return this.transport.getResponseHeader(name) || null; 1080 } catch (e) { 1081 return null 1082 } 1083 }, 1084 evalResponse: function() { 1085 try { 1086 return eval((this.transport.responseText || '').unfilterJSON()); 1087 } catch (e) { 1088 this.dispatchException(e); 1089 } 1090 }, 1091 dispatchException: function(exception) { 1092 (this.options.onException || Prototype.emptyFunction)(this, exception); 1093 Ajax.Responders.dispatch('onException', this, exception); 1094 } 1095}); 1096Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 1097Ajax.Response = Class.create({ 1098 initialize: function(request) { 1099 this.request = request; 1100 var transport = this.transport = request.transport, 1101 readyState = this.readyState = transport.readyState; 1102 if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { 1103 this.status = this.getStatus(); 1104 this.statusText = this.getStatusText(); 1105 this.responseText = String.interpret(transport.responseText); 1106 this.headerJSON = this._getHeaderJSON(); 1107 } 1108 if (readyState == 4) { 1109 var xml = transport.responseXML; 1110 this.responseXML = Object.isUndefined(xml) ? null : xml; 1111 this.responseJSON = this._getResponseJSON(); 1112 } 1113 }, 1114 status: 0, 1115 statusText: '', 1116 getStatus: Ajax.Request.prototype.getStatus, 1117 getStatusText: function() { 1118 try { 1119 return this.transport.statusText || ''; 1120 } catch (e) { 1121 return '' 1122 } 1123 }, 1124 getHeader: Ajax.Request.prototype.getHeader, 1125 getAllHeaders: function() { 1126 try { 1127 return this.getAllResponseHeaders(); 1128 } catch (e) { 1129 return null 1130 } 1131 }, 1132 getResponseHeader: function(name) { 1133 return this.transport.getResponseHeader(name); 1134 }, 1135 getAllResponseHeaders: function() { 1136 return this.transport.getAllResponseHeaders(); 1137 }, 1138 _getHeaderJSON: function() { 1139 var json = this.getHeader('X-JSON'); 1140 if (!json) return null; 1141 json = decodeURIComponent(escape(json)); 1142 try { 1143 return json.evalJSON(this.request.options.sanitizeJSON || !this.request.isSameOrigin()); 1144 } catch (e) { 1145 this.request.dispatchException(e); 1146 } 1147 }, 1148 _getResponseJSON: function() { 1149 var options = this.request.options; 1150 if (!options.evalJSON || (options.evalJSON != 'force' && !(this.getHeader('Content-type') || '').include('application/json')) || this.responseText.blank()) return null; 1151 try { 1152 return this.responseText.evalJSON(options.sanitizeJSON || !this.request.isSameOrigin()); 1153 } catch (e) { 1154 this.request.dispatchException(e); 1155 } 1156 } 1157}); 1158Ajax.Updater = Class.create(Ajax.Request, { 1159 initialize: function($super, container, url, options) { 1160 this.container = { 1161 success: (container.success || container), 1162 failure: (container.failure || (container.success ? null : container)) 1163 }; 1164 options = Object.clone(options); 1165 var onComplete = options.onComplete; 1166 options.onComplete = (function(response, json) { 1167 this.updateContent(response.responseText); 1168 if (Object.isFunction(onComplete)) onComplete(response, json); 1169 }).bind(this); 1170 $super(url, options); 1171 }, 1172 updateContent: function(responseText) { 1173 var receiver = this.container[this.success() ? 'success' : 'failure'], 1174 options = this.options; 1175 if (!options.evalScripts) responseText = responseText.stripScripts(); 1176 if (receiver = $(receiver)) { 1177 if (options.insertion) { 1178 if (Object.isString(options.insertion)) { 1179 var insertion = {}; 1180 insertion[options.insertion] = responseText; 1181 receiver.insert(insertion); 1182 } 1183 else options.insertion(receiver, responseText); 1184 } 1185 else receiver.update(responseText); 1186 } 1187 } 1188});
1189Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { 1190 initialize: function($super, container, url, options) { 1191 $super(options); 1192 this.onComplete = this.options.onComplete; 1193 this.frequency = (this.options.frequency || 2); 1194 this.decay = (this.options.decay || 1); 1195 this.updater = {}; 1196 this.container = container; 1197 this.url = url; 1198 this.start(); 1199 }, 1200 start: function() { 1201 this.options.onComplete = this.updateComplete.bind(this); 1202 this.onTimerEvent(); 1203 }, 1204 stop: function() { 1205 this.updater.options.onComplete = undefined; 1206 clearTimeout(this.timer); 1207 (this.onComplete || Prototype.emptyFunction).apply(this, arguments); 1208 }, 1209 updateComplete: function(response) { 1210 if (this.options.decay) { 1211 this.decay = (response.responseText == this.lastText ? this.decay * this.options.decay : 1); 1212 this.lastText = response.responseText; 1213 } 1214 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); 1215 }, 1216 onTimerEvent: function() { 1217 this.updater = new Ajax.Updater(this.container, this.url, this.options); 1218 } 1219}); 1220 1221function $(element) { 1222 if (arguments.length > 1) { 1223 for (var i = 0, elements = [], length = arguments.length; i < length; i++) 1224 elements.push($(arguments[i])); 1225 return elements; 1226 } 1227 if (Object.isString(element)) element = document.getElementById(element); 1228 return Element.extend(element); 1229} 1230if (Prototype.BrowserFeatures.XPath) { 1231 document._getElementsByXPath = function(expression, parentElement) { 1232 var results = []; 1233 var query = document.evaluate(expression, $(parentElement) || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 1234 for (var i = 0, length = query.snapshotLength; i < length; i++) 1235 results.push(Element.extend(query.snapshotItem(i))); 1236 return results; 1237 }; 1238} 1239if (!window.Node) var Node = {}; 1240if (!Node.ELEMENT_NODE) { 1241 Object.extend(Node, { 1242 ELEMENT_NODE: 1, 1243 ATTRIBUTE_NODE: 2, 1244 TEXT_NODE: 3, 1245 CDATA_SECTION_NODE: 4, 1246 ENTITY_REFERENCE_NODE: 5, 1247 ENTITY_NODE: 6, 1248 PROCESSING_INSTRUCTION_NODE: 7, 1249 COMMENT_NODE: 8, 1250 DOCUMENT_NODE: 9, 1251 DOCUMENT_TYPE_NODE: 10, 1252 DOCUMENT_FRAGMENT_NODE: 11, 1253 NOTATION_NODE: 12 1254 }); 1255}(function() { 1256 var element = this.Element; 1257 this.Element = function(tagName, attributes) { 1258 attributes = attributes || {}; 1259 tagName = tagName.toLowerCase(); 1260 var cache = Element.cache; 1261 if (Prototype.Browser.IE && attributes.name) { 1262 tagName = '<' + tagName + ' name="' + attributes.name + '">'; 1263 delete attributes.name; 1264 return Element.writeAttribute(document.createElement(tagName), attributes); 1265 } 1266 if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); 1267 return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); 1268 }; 1269 Object.extend(this.Element, element || {}); 1270 if (element) this.Element.prototype = element.prototype; 1271}).call(window); 1272Element.cache = {}; 1273Element.Methods = { 1274 visible: function(element) { 1275 return $(element).style.display != 'none'; 1276 }, 1277 toggle: function(element) { 1278 element = $(element); 1279 Element[Element.visible(element) ? 'hide' : 'show'](element); 1280 return element; 1281 }, 1282 hide: function(element) { 1283 element = $(element); 1284 element.style.display = 'none'; 1285 return element; 1286 }, 1287 show: function(element) { 1288 element = $(element); 1289 element.style.display = ''; 1290 return element; 1291 }, 1292 remove: function(element) { 1293 element = $(element); 1294 element.parentNode.removeChild(element); 1295 return element; 1296 }, 1297 update: function(element, content) { 1298 element = $(element); 1299 if (content && content.toElement) content = content.toElement(); 1300 if (Object.isElement(content)) return element.update().insert(content); 1301 content = Object.toHTML(content); 1302 element.innerHTML = content.stripScripts(); 1303 content.evalScripts.bind(content).defer(); 1304 return element; 1305 }, 1306 replace: function(element, content) { 1307 element = $(element); 1308 if (content && content.toElement) content = content.toElement(); 1309 else if (!Object.isElement(content)) { 1310 content = Object.toHTML(content); 1311 var range = element.ownerDocument.createRange(); 1312 range.selectNode(element); 1313 content.evalScripts.bind(content).defer(); 1314 content = range.createContextualFragment(content.stripScripts()); 1315 } 1316 element.parentNode.replaceChild(content, element); 1317 return element; 1318 }, 1319 insert: function(element, insertions) { 1320 element = $(element); 1321 if (Object.isString(insertions) || Object.isNumber(insertions) || Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) insertions = { 1322 bottom: insertions 1323 }; 1324 var content, insert, tagName, childNodes; 1325 for (var position in insertions) { 1326 content = insertions[position]; 1327 position = position.toLowerCase(); 1328 insert = Element._insertionTranslations[position]; 1329 if (content && content.toElement) content = content.toElement(); 1330 if (Object.isElement(content)) { 1331 insert(element, content); 1332 continue; 1333 } 1334 content = Object.toHTML(content); 1335 tagName = ((position == 'before' || position == 'after') ? element.parentNode : element).tagName.toUpperCase(); 1336 childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); 1337 if (position == 'top' || position == 'after') childNodes.reverse(); 1338 childNodes.each(insert.curry(element)); 1339 content.evalScripts.bind(content).defer(); 1340 } 1341 return element; 1342 }, 1343 wrap: function(element, wrapper, attributes) { 1344 element = $(element); 1345 if (Object.isElement(wrapper)) $(wrapper).writeAttribute(attributes || {}); 1346 else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); 1347 else wrapper = new Element('div', wrapper); 1348 if (element.parentNode) element.parentNode.replaceChild(wrapper, element); 1349 wrapper.appendChild(element); 1350 return wrapper; 1351 }, 1352 inspect: function(element) { 1353 element = $(element); 1354 var result = '<' + element.tagName.toLowerCase(); 1355 $H({ 1356 'id': 'id', 1357 'className': 'class' 1358 }).each(function(pair) { 1359 var property = pair.first(), 1360 attribute = pair.last(); 1361 var value = (element[property] || '').toString(); 1362 if (value) result += ' ' + attribute + '=' + value.inspect(true); 1363 }); 1364 return result + '>'; 1365 }, 1366 recursivelyCollect: function(element, property) { 1367 element = $(element); 1368 var elements = []; 1369 while (element = element[property]) 1370 if (element.nodeType == 1) elements.push(Element.extend(element)); 1371 return elements; 1372 }, 1373 ancestors: function(element) { 1374 return $(element).recursivelyCollect('parentNode'); 1375 }, 1376 descendants: function(element) { 1377 return $(element).select("*"); 1378 }, 1379 firstDescendant: function(element) { 1380 element = $(element).firstChild; 1381 while (element && element.nodeType != 1) element = element.nextSibling; 1382 return $(element); 1383 }, 1384 immediateDescendants: function(element) { 1385 if (!(element = $(element).firstChild)) return []; 1386 while (element && element.nodeType != 1) element = element.nextSibling; 1387 if (element) return [element].concat($(element).nextSiblings()); 1388 return []; 1389 }, 1390 previousSiblings: function(element) { 1391 return $(element).recursivelyCollect('previousSibling'); 1392 }, 1393 nextSiblings: function(element) { 1394 return $(element).recursivelyCollect('nextSibling'); 1395 }, 1396 siblings: function(element) { 1397 element = $(element); 1398 return element.previousSiblings().reverse().concat(element.nextSiblings()); 1399 }, 1400 match: function(element, selector) { 1401 if (Object.isString(selector)) selector = new Selector(selector); 1402 return selector.match($(element)); 1403 }, 1404 up: function(element, expression, index) { 1405 element = $(element); 1406 if (arguments.length == 1) return $(element.parentNode); 1407 var ancestors = element.ancestors(); 1408 return Object.isNumber(expression) ? ancestors[expression] : Selector.findElement(ancestors, expression, index); 1409 }, 1410 down: function(element, expression, index) { 1411 element = $(element); 1412 if (arguments.length == 1) return element.firstDescendant(); 1413 return Object.isNumber(expression) ? element.descendants()[expression] : Element.select(element, expression)[index || 0]; 1414 }, 1415 previous: function(element, expression, index) { 1416 element = $(element); 1417 if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); 1418 var previousSiblings = element.previousSiblings(); 1419 return Object.isNumber(expression) ? previousSiblings[expression] : Selector.findElement(previousSiblings, expression, index); 1420 }, 1421 next: function(element, expression, index) { 1422 element = $(element); 1423 if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); 1424 var nextSiblings = element.nextSiblings(); 1425 return Object.isNumber(expression) ? nextSiblings[expression] : Selector.findElement(nextSiblings, expression, index); 1426 }, 1427 select: function() { 1428 var args = $A(arguments), 1429 element = $(args.shift()); 1430 return Selector.findChildElements(element, args); 1431 }, 1432 adjacent: function() { 1433 var args = $A(arguments), 1434 element = $(args.shift()); 1435 return Selector.findChildElements(element.parentNode, args).without(element); 1436 }, 1437 identify: function(element) { 1438 element = $(element); 1439 var id = element.readAttribute('id'), 1440 self = arguments.callee; 1441 if (id) return id; 1442 do { 1443 id = 'anonymous_element_' + self.counter++ 1444 } while ($(id)); 1445 element.writeAttribute('id', id); 1446 return id; 1447 }, 1448 readAttribute: function(element, name) { 1449 element = $(element); 1450 if (Prototype.Browser.IE) { 1451 var t = Element._attributeTranslations.read; 1452 if (t.values[name]) return t.values[name](element, name); 1453 if (t.names[name]) name = t.names[name]; 1454 if (name.include(':')) { 1455 return (!element.attributes || !element.attributes[name]) ? null : element.attributes[name].value; 1456 } 1457 } 1458 return element.getAttribute(name); 1459 }, 1460 writeAttribute: function(element, name, value) { 1461 element = $(element); 1462 var attributes = {}, 1463 t = Element._attributeTranslations.write; 1464 if (typeof name == 'object') attributes = name; 1465 else attributes[name] = Object.isUndefined(value) ? true : value; 1466 for (var attr in attributes) { 1467 name = t.names[attr] || attr; 1468 value = attributes[attr]; 1469 if (t.values[attr]) name = t.values[attr](element, value); 1470 if (value === false || value === null) element.removeAttribute(name); 1471 else if (value === true) element.setAttribute(name, name); 1472 else element.setAttribute(name, value); 1473 } 1474 return element; 1475 }, 1476 getHeight: function(element) { 1477 return $(element).getDimensions().height; 1478 }, 1479 getWidth: function(element) { 1480 return $(element).getDimensions().width; 1481 }, 1482 classNames: function(element) { 1483 return new Element.ClassNames(element); 1484 }, 1485 hasClassName: function(element, className) { 1486 if (!(element = $(element))) return; 1487 var elementClassName = element.className; 1488 return (elementClassName.length > 0 && (elementClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); 1489 }, 1490 addClassName: function(element, className) { 1491 if (!(element = $(element))) return; 1492 if (!element.hasClassName(className)) element.className += (element.className ? ' ' : '') + className; 1493 return element; 1494 }, 1495 removeClassName: function(element, className) { 1496 if (!(element = $(element))) return; 1497 element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); 1498 return element; 1499 }, 1500 toggleClassName: function(element, className) { 1501 if (!(element = $(element))) return; 1502 return element[element.hasClassName(className) ? 'removeClassName' : 'addClassName'](className); 1503 }, 1504 cleanWhitespace: function(element) { 1505 element = $(element); 1506 var node = element.firstChild; 1507 while (node) { 1508 var nextNode = node.nextSibling; 1509 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) element.removeChild(node); 1510 node = nextNode; 1511 } 1512 return element; 1513 }, 1514 empty: function(element) { 1515 return $(element).innerHTML.blank(); 1516 }, 1517 descendantOf: function(element, ancestor) { 1518 element = $(element), ancestor = $(ancestor); 1519 if (element.compareDocumentPosition) return (element.compareDocumentPosition(ancestor) & 8) === 8; 1520 if (ancestor.contains) return ancestor.contains(element) && ancestor !== element; 1521 while (element = element.parentNode) 1522 if (element == ancestor) return true; 1523 return false;
1524 }, 1525 scrollTo: function(element) { 1526 element = $(element); 1527 var pos = element.cumulativeOffset(); 1528 window.scrollTo(pos[0], pos[1]); 1529 return element; 1530 }, 1531 getStyle: function(element, style) { 1532 element = $(element); 1533 style = style == 'float' ? 'cssFloat' : style.camelize(); 1534 var value = element.style[style]; 1535 if (!value || value == 'auto') { 1536 var css = document.defaultView.getComputedStyle(element, null); 1537 value = css ? css[style] : null; 1538 } 1539 if (style == 'opacity') return value ? parseFloat(value) : 1.0; 1540 return value == 'auto' ? null : value; 1541 }, 1542 getOpacity: function(element) { 1543 return $(element).getStyle('opacity'); 1544 }, 1545 setStyle: function(element, styles) { 1546 element = $(element); 1547 var elementStyle = element.style, 1548 match; 1549 if (Object.isString(styles)) { 1550 element.style.cssText += ';' + styles; 1551 return styles.include('opacity') ? element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; 1552 } 1553 for (var property in styles) 1554 if (property == 'opacity') element.setOpacity(styles[property]); 1555 else elementStyle[(property == 'float' || property == 'cssFloat') ? (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : property] = styles[property]; 1556 return element; 1557 }, 1558 setOpacity: function(element, value) { 1559 element = $(element); 1560 element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value; 1561 return element; 1562 }, 1563 getDimensions: function(element) { 1564 element = $(element); 1565 var display = element.getStyle('display'); 1566 if (display != 'none' && display != null) return { 1567 width: element.offsetWidth, 1568 height: element.offsetHeight 1569 }; 1570 var els = element.style; 1571 var originalVisibility = els.visibility; 1572 var originalPosition = els.position; 1573 var originalDisplay = els.display; 1574 els.visibility = 'hidden'; 1575 els.position = 'absolute'; 1576 els.display = 'block'; 1577 var originalWidth = element.clientWidth; 1578 var originalHeight = element.clientHeight; 1579 els.display = originalDisplay; 1580 els.position = originalPosition; 1581 els.visibility = originalVisibility; 1582 return { 1583 width: originalWidth, 1584 height: originalHeight 1585 }; 1586 }, 1587 makePositioned: function(element) { 1588 element = $(element); 1589 var pos = Element.getStyle(element, 'position'); 1590 if (pos == 'static' || !pos) { 1591 element._madePositioned = true; 1592 element.style.position = 'relative'; 1593 if (Prototype.Browser.Opera) { 1594 element.style.top = 0; 1595 element.style.left = 0; 1596 } 1597 } 1598 return element; 1599 }, 1600 undoPositioned: function(element) { 1601 element = $(element); 1602 if (element._madePositioned) { 1603 element._madePositioned = undefined; 1604 element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = ''; 1605 } 1606 return element; 1607 }, 1608 makeClipping: function(element) { 1609 element = $(element); 1610 if (element._overflow) return element; 1611 element._overflow = Element.getStyle(element, 'overflow') || 'auto'; 1612 if (element._overflow !== 'hidden') element.style.overflow = 'hidden'; 1613 return element; 1614 }, 1615 undoClipping: function(element) { 1616 element = $(element); 1617 if (!element._overflow) return element; 1618 element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; 1619 element._overflow = null; 1620 return element; 1621 }, 1622 cumulativeOffset: function(element) { 1623 var valueT = 0, 1624 valueL = 0; 1625 do { 1626 valueT += element.offsetTop || 0; 1627 valueL += element.offsetLeft || 0; 1628 element = element.offsetParent; 1629 } while (element); 1630 return Element._returnOffset(valueL, valueT); 1631 }, 1632 positionedOffset: function(element) { 1633 var valueT = 0, 1634 valueL = 0; 1635 do { 1636 valueT += element.offsetTop || 0; 1637 valueL += element.offsetLeft || 0; 1638 element = element.offsetParent; 1639 if (element) { 1640 if (element.tagName.toUpperCase() == 'BODY') break; 1641 var p = Element.getStyle(element, 'position'); 1642 if (p !== 'static') break; 1643 } 1644 } while (element); 1645 return Element._returnOffset(valueL, valueT); 1646 }, 1647 absolutize: function(element) { 1648 element = $(element); 1649 if (element.getStyle('position') == 'absolute') return element; 1650 var offsets = element.positionedOffset(); 1651 var top = offsets[1]; 1652 var left = offsets[0]; 1653 var width = element.clientWidth; 1654 var height = element.clientHeight; 1655 element._originalLeft = left - parseFloat(element.style.left || 0); 1656 element._originalTop = top - parseFloat(element.style.top || 0); 1657 element._originalWidth = element.style.width; 1658 element._originalHeight = element.style.height; 1659 element.style.position = 'absolute'; 1660 element.style.top = top + 'px'; 1661 element.style.left = left + 'px'; 1662 element.style.width = width + 'px'; 1663 element.style.height = height + 'px'; 1664 return element; 1665 }, 1666 relativize: function(element) { 1667 element = $(element); 1668 if (element.getStyle('position') == 'relative') return element; 1669 element.style.position = 'relative'; 1670 var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); 1671 var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); 1672 element.style.top = top + 'px'; 1673 element.style.left = left + 'px'; 1674 element.style.height = element._originalHeight; 1675 element.style.width = element._originalWidth; 1676 return element; 1677 }, 1678 cumulativeScrollOffset: function(element) { 1679 var valueT = 0, 1680 valueL = 0; 1681 do { 1682 valueT += element.scrollTop || 0; 1683 valueL += element.scrollLeft || 0; 1684 element = element.parentNode; 1685 } while (element); 1686 return Element._returnOffset(valueL, valueT); 1687 }, 1688 getOffsetParent: function(element) { 1689 if (element.offsetParent) return $(element.offsetParent); 1690 if (element == document.body) return $(element); 1691 while ((element = element.parentNode) && element != document.body) 1692 if (Element.getStyle(element, 'position') != 'static') return $(element); 1693 return $(document.body); 1694 }, 1695 viewportOffset: function(forElement) { 1696 var valueT = 0, 1697 valueL = 0; 1698 var element = forElement; 1699 do { 1700 valueT += element.offsetTop || 0; 1701 valueL += element.offsetLeft || 0; 1702 if (element.offsetParent == document.body && Element.getStyle(element, 'position') == 'absolute') break; 1703 } while (element = element.offsetParent); 1704 element = forElement; 1705 do { 1706 if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) { 1707 valueT -= element.scrollTop || 0; 1708 valueL -= element.scrollLeft || 0; 1709 } 1710 } while (element = element.parentNode); 1711 return Element._returnOffset(valueL, valueT); 1712 }, 1713 clonePosition: function(element, source) { 1714 var options = Object.extend({ 1715 setLeft: true, 1716 setTop: true, 1717 setWidth: true, 1718 setHeight: true, 1719 offsetTop: 0, 1720 offsetLeft: 0 1721 }, arguments[2] || {}); 1722 source = $(source); 1723 var p = source.viewportOffset(); 1724 element = $(element); 1725 var delta = [0, 0]; 1726 var parent = null; 1727 if (Element.getStyle(element, 'position') == 'absolute') { 1728 parent = element.getOffsetParent(); 1729 delta = parent.viewportOffset(); 1730 } 1731 if (parent == document.body) { 1732 delta[0] -= document.body.offsetLeft; 1733 delta[1] -= document.body.offsetTop; 1734 } 1735 if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; 1736 if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; 1737 if (options.setWidth) element.style.width = source.offsetWidth + 'px'; 1738 if (options.setHeight) element.style.height = source.offsetHeight + 'px'; 1739 return element; 1740 } 1741}; 1742Element.Methods.identify.counter = 1; 1743Object.extend(Element.Methods, { 1744 getElementsBySelector: Element.Methods.select, 1745 childElements: Element.Methods.immediateDescendants 1746}); 1747Element._attributeTranslations = { 1748 write: { 1749 names: { 1750 className: 'class', 1751 htmlFor: 'for' 1752 }, 1753 values: {} 1754 } 1755}; 1756if (Prototype.Browser.Opera) { 1757 Element.Methods.getStyle = Element.Methods.getStyle.wrap(function(proceed, element, style) { 1758 switch (style) { 1759 case 'left': 1760 case 'top': 1761 case 'right': 1762 case 'bottom': 1763 if (proceed(element, 'position') === 'static') return null; 1764 case 'height': 1765 case 'width': 1766 if (!Element.visible(element)) return null; 1767 var dim = parseInt(proceed(element, style), 10); 1768 if (dim !== element['offset' + style.capitalize()]) return dim + 'px'; 1769 var properties; 1770 if (style === 'height') { 1771 properties = ['border-top-width', 'padding-top', 'padding-bottom', 'border-bottom-width']; 1772 } 1773 else { 1774 properties = ['border-left-width', 'padding-left', 'padding-right', 'border-right-width']; 1775 } 1776 return properties.inject(dim, function(memo, property) { 1777 var val = proceed(element, property); 1778 return val === null ? memo : memo - parseInt(val, 10); 1779 }) + 'px'; 1780 default: 1781 return proceed(element, style); 1782 } 1783 }); 1784 Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(function(proceed, element, attribute) { 1785 if (attribute === 'title') return element.title; 1786 return proceed(element, attribute); 1787 }); 1788} 1789else if (Prototype.Browser.IE) { 1790 Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(function(proceed, element) { 1791 element = $(element); 1792 try { 1793 element.offsetParent 1794 } 1795 catch (e) { 1796 return $(document.body) 1797 } 1798 var position = element.getStyle('position'); 1799 if (position !== 'static') return proceed(element); 1800 element.setStyle({ 1801 position: 'relative' 1802 }); 1803 var value = proceed(element); 1804 element.setStyle({ 1805 position: position 1806 }); 1807 return value; 1808 }); 1809 $w('positionedOffset viewportOffset').each(function(method) { 1810 Element.Methods[method] = Element.Methods[method].wrap(function(proceed, element) { 1811 element = $(element); 1812 try { 1813 element.offsetParent 1814 } 1815 catch (e) { 1816 return Element._returnOffset(0, 0) 1817 } 1818 var position = element.getStyle('position'); 1819 if (position !== 'static') return proceed(element); 1820 var offsetParent = element.getOffsetParent(); 1821 if (offsetParent && offsetParent.getStyle('position') === 'fixed') offsetParent.setStyle({ 1822 zoom: 1 1823 }); 1824 element.setStyle({ 1825 position: 'relative' 1826 }); 1827 var value = proceed(element); 1828 element.setStyle({ 1829 position: position 1830 }); 1831 return value; 1832 }); 1833 }); 1834 Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(function(proceed, element) { 1835 try { 1836 element.offsetParent 1837 } 1838 catch (e) { 1839 return Element._returnOffset(0, 0) 1840 } 1841 return proceed(element); 1842 }); 1843 Element.Methods.getStyle = function(element, style) { 1844 element = $(element); 1845 style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); 1846 var value = element.style[style]; 1847 if (!value && element.currentStyle) value = element.currentStyle[style]; 1848 if (style == 'opacity') { 1849 if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) if (value[1]) return parseFloat(value[1]) / 100; 1850 return 1.0; 1851 } 1852 if (value == 'auto') { 1853 if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) return element['offset' + style.capitalize()] + 'px'; 1854 return null; 1855 } 1856 return value; 1857 }; 1858 Element.Methods.setOpacity = function(element, value) { 1859 function stripAlpha(filter) { 1860 return filter.replace(/alpha\([^\)]*\)/gi, ''); 1861 } 1862 element = $(element); 1863 var currentStyle = element.currentStyle; 1864 if ((currentStyle && !currentStyle.hasLayout) || (!currentStyle && element.style.zoom == 'normal')) element.style.zoom = 1; 1865 var filter = element.getStyle('filter'), 1866 style = element.style; 1867 if (value == 1 || value === '') {
1868 (filter = stripAlpha(filter)) ? style.filter = filter : style.removeAttribute('filter'); 1869 return element; 1870 } else if (value < 0.00001) value = 0; 1871 style.filter = stripAlpha(filter) + 'alpha(opacity=' + (value * 100) + ')'; 1872 return element; 1873 }; 1874 Element._attributeTranslations = { 1875 read: { 1876 names: { 1877 'class': 'className', 1878 'for': 'htmlFor' 1879 }, 1880 values: { 1881 _getAttr: function(element, attribute) { 1882 return element.getAttribute(attribute, 2); 1883 }, 1884 _getAttrNode: function(element, attribute) { 1885 var node = element.getAttributeNode(attribute); 1886 return node ? node.value : ""; 1887 }, 1888 _getEv: function(element, attribute) { 1889 attribute = element.getAttribute(attribute); 1890 return attribute ? attribute.toString().slice(23, -2) : null; 1891 }, 1892 _flag: function(element, attribute) { 1893 return $(element).hasAttribute(attribute) ? attribute : null; 1894 }, 1895 style: function(element) { 1896 return element.style.cssText.toLowerCase(); 1897 }, 1898 title: function(element) { 1899 return element.title; 1900 } 1901 } 1902 } 1903 }; 1904 Element._attributeTranslations.write = { 1905 names: Object.extend({ 1906 cellpadding: 'cellPadding', 1907 cellspacing: 'cellSpacing' 1908 }, Element._attributeTranslations.read.names), 1909 values: { 1910 checked: function(element, value) { 1911 element.checked = !! value; 1912 }, 1913 style: function(element, value) { 1914 element.style.cssText = value ? value : ''; 1915 } 1916 } 1917 }; 1918 Element._attributeTranslations.has = {}; 1919 $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { 1920 Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; 1921 Element._attributeTranslations.has[attr.toLowerCase()] = attr; 1922 }); 1923 (function(v) { 1924 Object.extend(v, { 1925 href: v._getAttr, 1926 src: v._getAttr, 1927 type: v._getAttr, 1928 action: v._getAttrNode, 1929 disabled: v._flag, 1930 checked: v._flag, 1931 readonly: v._flag, 1932 multiple: v._flag, 1933 onload: v._getEv, 1934 onunload: v._getEv, 1935 onclick: v._getEv, 1936 ondblclick: v._getEv, 1937 onmousedown: v._getEv, 1938 onmouseup: v._getEv, 1939 onmouseover: v._getEv, 1940 onmousemove: v._getEv, 1941 onmouseout: v._getEv, 1942 onfocus: v._getEv, 1943 onblur: v._getEv, 1944 onkeypress: v._getEv, 1945 onkeydown: v._getEv, 1946 onkeyup: v._getEv, 1947 onsubmit: v._getEv, 1948 onreset: v._getEv, 1949 onselect: v._getEv, 1950 onchange: v._getEv 1951 }); 1952 })(Element._attributeTranslations.read.values); 1953} 1954else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { 1955 Element.Methods.setOpacity = function(element, value) { 1956 element = $(element); 1957 element.style.opacity = (value == 1) ? 0.999999 : (value === '') ? '' : (value < 0.00001) ? 0 : value; 1958 return element; 1959 }; 1960} 1961else if (Prototype.Browser.WebKit) { 1962 Element.Methods.setOpacity = function(element, value) { 1963 element = $(element); 1964 element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value; 1965 if (value == 1) if (element.tagName.toUpperCase() == 'IMG' && element.width) { 1966 element.width++; 1967 element.width--; 1968 } else try { 1969 var n = document.createTextNode(' '); 1970 element.appendChild(n); 1971 element.removeChild(n); 1972 } catch (e) {} 1973 return element; 1974 }; 1975 Element.Methods.cumulativeOffset = function(element) { 1976 var valueT = 0, 1977 valueL = 0; 1978 do { 1979 valueT += element.offsetTop || 0; 1980 valueL += element.offsetLeft || 0; 1981 if (element.offsetParent == document.body) if (Element.getStyle(element, 'position') == 'absolute') break; 1982 element = element.offsetParent; 1983 } while (element); 1984 return Element._returnOffset(valueL, valueT); 1985 }; 1986} 1987if (Prototype.Browser.IE || Prototype.Browser.Opera) { 1988 Element.Methods.update = function(element, content) { 1989 element = $(element); 1990 if (content && content.toElement) content = content.toElement();
1991 if (Object.isElement(content)) return element.update().insert(content); 1992 content = Object.toHTML(content); 1993 var tagName = element.tagName.toUpperCase(); 1994 if (tagName in Element._insertionTranslations.tags) { 1995 $A(element.childNodes).each(function(node) { 1996 element.removeChild(node) 1997 }); 1998 Element._getContentFromAnonymousElement(tagName, content.stripScripts()).each(function(node) { 1999 element.appendChild(node) 2000 }); 2001 } 2002 else element.innerHTML = content.stripScripts(); 2003 content.evalScripts.bind(content).defer(); 2004 return element; 2005 }; 2006} 2007if ('outerHTML' in document.createElement('div')) { 2008 Element.Methods.replace = function(element, content) { 2009 element = $(element); 2010 if (content && content.toElement) content = content.toElement(); 2011 if (Object.isElement(content)) { 2012 element.parentNode.replaceChild(content, element); 2013 return element; 2014 } 2015 content = Object.toHTML(content); 2016 var parent = element.parentNode, 2017 tagName = parent.tagName.toUpperCase(); 2018 if (Element._insertionTranslations.tags[tagName]) { 2019 var nextSibling = element.next(); 2020 var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); 2021 parent.removeChild(element); 2022 if (nextSibling) fragments.each(function(node) { 2023 parent.insertBefore(node, nextSibling) 2024 }); 2025 else fragments.each(function(node) { 2026 parent.appendChild(node) 2027 }); 2028 } 2029 else element.outerHTML = content.stripScripts(); 2030 content.evalScripts.bind(content).defer(); 2031 return element; 2032 }; 2033} 2034Element._returnOffset = function(l, t) { 2035 var result = [l, t]; 2036 result.left = l; 2037 result.top = t; 2038 return result; 2039}; 2040Element._getContentFromAnonymousElement = function(tagName, html) { 2041 var div = new Element('div'), 2042 t = Element._insertionTranslations.tags[tagName]; 2043 if (t) { 2044 div.innerHTML = t[0] + html + t[1]; 2045 t[2].times(function() { 2046 div = div.firstChild 2047 }); 2048 } else div.innerHTML = html; 2049 return $A(div.childNodes); 2050}; 2051Element._insertionTranslations = { 2052 before: function(element, node) { 2053 element.parentNode.insertBefore(node, element); 2054 }, 2055 top: function(element, node) { 2056 element.insertBefore(node, element.firstChild); 2057 }, 2058 bottom: function(element, node) { 2059 element.appendChild(node); 2060 }, 2061 after: function(element, node) { 2062 element.parentNode.insertBefore(node, element.nextSibling); 2063 }, 2064 tags: { 2065 TABLE: ['<table>', '</table>', 1], 2066 TBODY: ['<table><tbody>', '</tbody></table>', 2], 2067 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], 2068 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], 2069 SELECT: ['<select>', '</select>', 1] 2070 } 2071}; 2072(function() { 2073 Object.extend(this.tags, { 2074 THEAD: this.tags.TBODY, 2075 TFOOT: this.tags.TBODY, 2076 TH: this.tags.TD 2077 }); 2078}).call(Element._insertionTranslations); 2079Element.Methods.Simulated = { 2080 hasAttribute: function(element, attribute) { 2081 attribute = Element._attributeTranslations.has[attribute] || attribute; 2082 var node = $(element).getAttributeNode(attribute); 2083 return !!(node && node.specified); 2084 } 2085}; 2086Element.Methods.ByTag = {}; 2087Object.extend(Element, Element.Methods); 2088if (!Prototype.BrowserFeatures.ElementExtensions && document.createElement('div')['__proto__']) { 2089 window.HTMLElement = {}; 2090 window.HTMLElement.prototype = document.createElement('div')['__proto__']; 2091 Prototype.BrowserFeatures.ElementExtensions = true; 2092} 2093Element.extend = (function() { 2094 if (Prototype.BrowserFeatures.SpecificElementExtensions) return Prototype.K; 2095 var Methods = {}, 2096 ByTag = Element.Methods.ByTag; 2097 var extend = Object.extend(function(element) { 2098 if (!element || element._extendedByPrototype || element.nodeType != 1 || element == window) return element; 2099 var methods = Object.clone(Methods), 2100 tagName = element.tagName.toUpperCase(), 2101 property, value; 2102 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); 2103 for (property in methods) { 2104 value = methods[property]; 2105 if (Object.isFunction(value) && !(property in element)) element[property] = value.methodize(); 2106 } 2107 element._extendedByPrototype = Prototype.emptyFunction; 2108 return element; 2109 }, {
2110 refresh: function() { 2111 if (!Prototype.BrowserFeatures.ElementExtensions) { 2112 Object.extend(Methods, Element.Methods); 2113 Object.extend(Methods, Element.Methods.Simulated); 2114 } 2115 } 2116 }); 2117 extend.refresh(); 2118 return extend; 2119})(); 2120Element.hasAttribute = function(element, attribute) { 2121 if (element.hasAttribute) return element.hasAttribute(attribute); 2122 return Element.Methods.Simulated.hasAttribute(element, attribute); 2123}; 2124Element.addMethods = function(methods) { 2125 var F = Prototype.BrowserFeatures, 2126 T = Element.Methods.ByTag; 2127 if (!methods) { 2128 Object.extend(Form, Form.Methods); 2129 Object.extend(Form.Element, Form.Element.Methods); 2130 Object.extend(Element.Methods.ByTag, { 2131 "FORM": Object.clone(Form.Methods), 2132 "INPUT": Object.clone(Form.Element.Methods), 2133 "SELECT": Object.clone(Form.Element.Methods), 2134 "TEXTAREA": Object.clone(Form.Element.Methods) 2135 }); 2136 } 2137 if (arguments.length == 2) { 2138 var tagName = methods; 2139 methods = arguments[1]; 2140 } 2141 if (!tagName) Object.extend(Element.Methods, methods || {}); 2142 else { 2143 if (Object.isArray(tagName)) tagName.each(extend); 2144 else extend(tagName); 2145 } 2146 2147 function extend(tagName) { 2148 tagName = tagName.toUpperCase(); 2149 if (!Element.Methods.ByTag[tagName]) Element.Methods.ByTag[tagName] = {}; 2150 Object.extend(Element.Methods.ByTag[tagName], methods); 2151 } 2152 2153 function copy(methods, destination, onlyIfAbsent) { 2154 onlyIfAbsent = onlyIfAbsent || false; 2155 for (var property in methods) { 2156 var value = methods[property]; 2157 if (!Object.isFunction(value)) continue; 2158 if (!onlyIfAbsent || !(property in destination)) destination[property] = value.methodize(); 2159 } 2160 } 2161 2162 function findDOMClass(tagName) { 2163 var klass; 2164 var trans = { 2165 "OPTGROUP": "OptGroup", 2166 "TEXTAREA": "TextArea", 2167 "P": "Paragraph", 2168 "FIELDSET": "FieldSet", 2169 "UL": "UList", 2170 "OL": "OList", 2171 "DL": "DList", 2172 "DIR": "Directory", 2173 "H1": "Heading", 2174 "H2": "Heading", 2175 "H3": "Heading", 2176 "H4": "Heading", 2177 "H5": "Heading", 2178 "H6": "Heading", 2179 "Q": "Quote", 2180 "INS": "Mod", 2181 "DEL": "Mod", 2182 "A": "Anchor", 2183 "IMG": "Image", 2184 "CAPTION": "TableCaption", 2185 "COL": "TableCol", 2186 "COLGROUP": "TableCol", 2187 "THEAD": "TableSection", 2188 "TFOOT": "TableSection", 2189 "TBODY": "TableSection", 2190 "TR": "TableRow", 2191 "TH": "TableCell", 2192 "TD": "TableCell", 2193 "FRAMESET": "FrameSet", 2194 "IFRAME": "IFrame" 2195 }; 2196 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; 2197 if (window[klass]) return window[klass]; 2198 klass = 'HTML' + tagName + 'Element'; 2199 if (window[klass]) return window[klass]; 2200 klass = 'HTML' + tagName.capitalize() + 'Element'; 2201 if (window[klass]) return window[klass]; 2202 window[klass] = {}; 2203 window[klass].prototype = document.createElement(tagName)['__proto__']; 2204 return window[klass]; 2205 } 2206 if (F.ElementExtensions) { 2207 copy(Element.Methods, HTMLElement.prototype); 2208 copy(Element.Methods.Simulated, HTMLElement.prototype, true); 2209 } 2210 if (F.SpecificElementExtensions) { 2211 for (var tag in Element.Methods.ByTag) { 2212 var klass = findDOMClass(tag); 2213 if (Object.isUndefined(klass)) continue; 2214 copy(T[tag], klass.prototype); 2215 } 2216 } 2217 Object.extend(Element, Element.Methods); 2218 delete Element.ByTag; 2219 if (Element.extend.refresh) Element.extend.refresh(); 2220 Element.cache = {}; 2221}; 2222document.viewport = { 2223 getDimensions: function() { 2224 var dimensions = {}, 2225 B = Prototype.Browser; 2226 $w('width height').each(function(d) { 2227 var D = d.capitalize(); 2228 if (B.WebKit && !document.evaluate) { 2229 dimensions[d] = self['inner' + D]; 2230 } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) { 2231 dimensions[d] = document.body['client' + D] 2232 } else { 2233 dimensions[d] = document.documentElement['client' + D]; 2234 } 2235 }); 2236 return dimensions; 2237 }, 2238 getWidth: function() { 2239 return this.getDimensions().width; 2240 }, 2241 getHeight: function() { 2242 return this.getDimensions().height; 2243 }, 2244 getScrollOffsets: function() { 2245 return Element._returnOffset(window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 2246 } 2247}; 2248var Selector = Class.create({ 2249 initialize: function(expression) { 2250 this.expression = expression.strip(); 2251 if (this.shouldUseSelectorsAPI()) { 2252 this.mode = 'selectorsAPI'; 2253 } else if (this.shouldUseXPath()) { 2254 this.mode = 'xpath'; 2255 this.compileXPathMatcher(); 2256 } else { 2257 this.mode = "normal"; 2258 this.compileMatcher(); 2259 } 2260 }, 2261 shouldUseXPath: function() { 2262 if (!Prototype.BrowserFeatures.XPath) return false;
2263 var e = this.expression; 2264 if (Prototype.Browser.WebKit && (e.include("-of-type") || e.include(":empty"))) return false; 2265 if ((/(\[[\w-]*?:|:checked)/).test(e)) return false; 2266 return true; 2267 }, 2268 shouldUseSelectorsAPI: function() { 2269 if (!Prototype.BrowserFeatures.SelectorsAPI) return false; 2270 if (!Selector._div) Selector._div = new Element('div'); 2271 try { 2272 Selector._div.querySelector(this.expression); 2273 } catch (e) { 2274 return false; 2275 } 2276 return true; 2277 }, 2278 compileMatcher: function() { 2279 var e = this.expression, 2280 ps = Selector.patterns, 2281 h = Selector.handlers, 2282 c = Selector.criteria, 2283 le, p, m; 2284 if (Selector._cache[e]) { 2285 this.matcher = Selector._cache[e]; 2286 return; 2287 } 2288 this.matcher = ["this.matcher = function(root) {", "var r = root, h = Selector.handlers, c = false, n;"]; 2289 while (e && le != e && (/\S/).test(e)) { 2290 le = e; 2291 for (var i in ps) { 2292 p = ps[i]; 2293 if (m = e.match(p)) { 2294 this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : new Template(c[i]).evaluate(m)); 2295 e = e.replace(m[0], ''); 2296 break; 2297 } 2298 } 2299 } 2300 this.matcher.push("return h.unique(n);\n}"); 2301 eval(this.matcher.join('\n')); 2302 Selector._cache[this.expression] = this.matcher; 2303 }, 2304 compileXPathMatcher: function() { 2305 var e = this.expression, 2306 ps = Selector.patterns, 2307 x = Selector.xpath, 2308 le, m; 2309 if (Selector._cache[e]) { 2310 this.xpath = Selector._cache[e]; 2311 return; 2312 } 2313 this.matcher = ['.//*']; 2314 while (e && le != e && (/\S/).test(e)) { 2315 le = e; 2316 for (var i in ps) { 2317 if (m = e.match(ps[i])) { 2318 this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m)); 2319 e = e.replace(m[0], ''); 2320 break; 2321 } 2322 } 2323 } 2324 this.xpath = this.matcher.join(''); 2325 Selector._cache[this.expression] = this.xpath; 2326 }, 2327 findElements: function(root) { 2328 root = root || document; 2329 var e = this.expression, 2330 results; 2331 switch (this.mode) { 2332 case 'selectorsAPI': 2333 if (root !== document) { 2334 var oldId = root.id, 2335 id = $(root).identify(); 2336 e = "#" + id + " " + e; 2337 } 2338 results = $A(root.querySelectorAll(e)).map(Element.extend); 2339 root.id = oldId; 2340 return results; 2341 case 'xpath': 2342 return document._getElementsByXPath(this.xpath, root); 2343 default: 2344 return this.matcher(root); 2345 } 2346 }, 2347 match: function(element) { 2348 this.tokens = []; 2349 var e = this.expression, 2350 ps = Selector.patterns, 2351 as = Selector.assertions; 2352 var le, p, m; 2353 while (e && le !== e && (/\S/).test(e)) { 2354 le = e; 2355 for (var i in ps) { 2356 p = ps[i]; 2357 if (m = e.match(p)) { 2358 if (as[i]) { 2359 this.tokens.push([i, Object.clone(m)]); 2360 e = e.replace(m[0], ''); 2361 } else { 2362 return this.findElements(document).include(element); 2363 } 2364 } 2365 } 2366 } 2367 var match = true, 2368 name, matches; 2369 for (var i = 0, token; token = this.tokens[i]; i++) { 2370 name = token[0], matches = token[1]; 2371 if (!Selector.assertions[name](element, matches)) { 2372 match = false; 2373 break; 2374 } 2375 } 2376 return match; 2377 }, 2378 toString: function() { 2379 return this.expression; 2380 }, 2381 inspect: function() { 2382 return "#<Selector:" + this.expression.inspect() + ">"; 2383 } 2384}); 2385Object.extend(Selector, { 2386 _cache: {}, 2387 xpath: { 2388 descendant: "//*", 2389 child: "/*", 2390 adjacent: "/following-sibling::*[1]", 2391 laterSibling: '/following-sibling::*', 2392 tagName: function(m) { 2393 if (m[1] == '*') return ''; 2394 return "[local-name()='" + m[1].toLowerCase() + "' or local-name()='" + m[1].toUpperCase() + "']"; 2395 }, 2396 className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", 2397 id: "[@id='#{1}']", 2398 attrPresence: function(m) { 2399 m[1] = m[1].toLowerCase(); 2400 return new Template("[@#{1}]").evaluate(m); 2401 }, 2402 attr: function(m) { 2403 m[1] = m[1].toLowerCase(); 2404 m[3] = m[5] || m[6]; 2405 return new Template(Selector.xpath.operators[m[2]]).evaluate(m); 2406 }, 2407 pseudo: function(m) { 2408 var h = Selector.xpath.pseudos[m[1]]; 2409 if (!h) return ''; 2410 if (Object.isFunction(h)) return h(m); 2411 return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); 2412 }, 2413 operators: { 2414 '=': "[@#{1}='#{3}']", 2415 '!=': "[@#{1}!='#{3}']", 2416 '^=': "[starts-with(@#{1}, '#{3}')]", 2417 '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", 2418 '*=': "[contains(@#{1}, '#{3}')]", 2419 '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", 2420 '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" 2421 }, 2422 pseudos: { 2423 'first-child': '[not(preceding-sibling::*)]', 2424 'last-child': '[not(following-sibling::*)]', 2425 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', 2426 'empty': "[count(*) = 0 and (count(text()) = 0)]", 2427 'checked': "[@checked]", 2428 'disabled': "[(@disabled) and (@type!='hidden')]", 2429 'enabled': "[not(@disabled) and (@type!='hidden')]", 2430 'not': function(m) { 2431 var e = m[6], 2432 p = Selector.patterns, 2433 x = Selector.xpath, 2434 le, v; 2435 var exclusion = []; 2436 while (e && le != e && (/\S/).test(e)) { 2437 le = e; 2438 for (var i in p) { 2439 if (m = e.match(p[i])) { 2440 v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); 2441 exclusion.push("(" + v.substring(1, v.length - 1) + ")"); 2442 e = e.replace(m[0], ''); 2443 break; 2444 } 2445 } 2446 } 2447 return "[not(" + exclusion.join(" and ") + ")]"; 2448 }, 2449 'nth-child': function(m) { 2450 return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); 2451 }, 2452 'nth-last-child': function(m) { 2453 return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); 2454 }, 2455 'nth-of-type': function(m) { 2456 return Selector.xpath.pseudos.nth("position() ", m); 2457 }, 2458 'nth-last-of-type': function(m) { 2459 return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); 2460 }, 2461 'first-of-type': function(m) { 2462 m[6] = "1"; 2463 return Selector.xpath.pseudos['nth-of-type'](m); 2464 }, 2465 'last-of-type': function(m) { 2466 m[6] = "1"; 2467 return Selector.xpath.pseudos['nth-last-of-type'](m); 2468 }, 2469 'only-of-type': function(m) { 2470 var p = Selector.xpath.pseudos; 2471 return p['first-of-type'](m) + p['last-of-type'](m); 2472 }, 2473 nth: function(fragment, m) { 2474 var mm, formula = m[6], 2475 predicate; 2476 if (formula == 'even') formula = '2n+0'; 2477 if (formula == 'odd') formula = '2n+1'; 2478 if (mm = formula.match(/^(\d+)$/)) return '[' + fragment + "= " + mm[1] + ']'; 2479 if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { 2480 if (mm[1] == "-") mm[1] = -1; 2481 var a = mm[1] ? Number(mm[1]) : 1; 2482 var b = mm[2] ? Number(mm[2]) : 0; 2483 predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + "((#{fragment} - #{b}) div #{a} >= 0)]"; 2484 return new Template(predicate).evaluate({ 2485 fragment: fragment, 2486 a: a, 2487 b: b 2488 }); 2489 } 2490 } 2491 } 2492 }, 2493 criteria: { 2494 tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', 2495 className: 'n = h.className(n, r, "#{1}", c); c = false;', 2496 id: 'n = h.id(n, r, "#{1}", c); c = false;', 2497 attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', 2498 attr: function(m) { 2499 m[3] = (m[5] || m[6]); 2500 return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m); 2501 }, 2502 pseudo: function(m) { 2503 if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); 2504 return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); 2505 }, 2506 descendant: 'c = "descendant";', 2507 child: 'c = "child";', 2508 adjacent: 'c = "adjacent";', 2509 laterSibling: 'c = "laterSibling";' 2510 }, 2511 patterns: { 2512 laterSibling: /^\s*~\s*/, 2513 child: /^\s*>\s*/, 2514 adjacent: /^\s*\+\s*/, 2515 descendant: /^\s/, 2516 tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, 2517 id: /^#([\w\-\*]+)(\b|$)/, 2518 className: /^\.([\w\-\*]+)(\b|$)/, 2519 pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, 2520 attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/, 2521 attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ 2522 }, 2523 assertions: { 2524 tagName: function(element, matches) { 2525 return matches[1].toUpperCase() == element.tagName.toUpperCase(); 2526 }, 2527 className: function(element, matches) { 2528 return Element.hasClassName(element, matches[1]); 2529 }, 2530 id: function(element, matches) {
2531 return element.id === matches[1]; 2532 }, 2533 attrPresence: function(element, matches) { 2534 return Element.hasAttribute(element, matches[1]); 2535 }, 2536 attr: function(element, matches) { 2537 var nodeValue = Element.readAttribute(element, matches[1]); 2538 return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]); 2539 } 2540 }, 2541 handlers: { 2542 concat: function(a, b) { 2543 for (var i = 0, node; node = b[i]; i++) 2544 a.push(node); 2545 return a; 2546 }, 2547 mark: function(nodes) { 2548 var _true = Prototype.emptyFunction; 2549 for (var i = 0, node; node = nodes[i]; i++) 2550 node._countedByPrototype = _true; 2551 return nodes; 2552 }, 2553 unmark: function(nodes) { 2554 for (var i = 0, node; node = nodes[i]; i++) 2555 node._countedByPrototype = undefined; 2556 return nodes; 2557 }, 2558 index: function(parentNode, reverse, ofType) { 2559 parentNode._countedByPrototype = Prototype.emptyFunction; 2560 if (reverse) { 2561 for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { 2562 var node = nodes[i]; 2563 if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; 2564 } 2565 } else { 2566 for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) 2567 if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; 2568 } 2569 }, 2570 unique: function(nodes) { 2571 if (nodes.length == 0) return nodes; 2572 var results = [], 2573 n; 2574 for (var i = 0, l = nodes.length; i < l; i++) 2575 if (!(n = nodes[i])._countedByPrototype) { 2576 n._countedByPrototype = Prototype.emptyFunction; 2577 results.push(Element.extend(n)); 2578 } 2579 return Selector.handlers.unmark(results); 2580 }, 2581 descendant: function(nodes) { 2582 var h = Selector.handlers; 2583 for (var i = 0, results = [], node; node = nodes[i]; i++) 2584 h.concat(results, node.getElementsByTagName('*')); 2585 return results; 2586 }, 2587 child: function(nodes) { 2588 var h = Selector.handlers; 2589 for (var i = 0, results = [], node; node = nodes[i]; i++) { 2590 for (var j = 0, child; child = node.childNodes[j]; j++) 2591 if (child.nodeType == 1 && child.tagName != '!') results.push(child); 2592 } 2593 return results; 2594 }, 2595 adjacent: function(nodes) { 2596 for (var i = 0, results = [], node; node = nodes[i]; i++) { 2597 var next = this.nextElementSibling(node); 2598 if (next) results.push(next); 2599 } 2600 return results; 2601 }, 2602 laterSibling: function(nodes) { 2603 var h = Selector.handlers; 2604 for (var i = 0, results = [], node; node = nodes[i]; i++) 2605 h.concat(results, Element.nextSiblings(node)); 2606 return results; 2607 }, 2608 nextElementSibling: function(node) { 2609 while (node = node.nextSibling) 2610 if (node.nodeType == 1) return node; 2611 return null; 2612 }, 2613 previousElementSibling: function(node) { 2614 while (node = node.previousSibling) 2615 if (node.nodeType == 1) return node; 2616 return null; 2617 }, 2618 tagName: function(nodes, root, tagName, combinator) { 2619 var uTagName = tagName.toUpperCase(); 2620 var results = [], 2621 h = Selector.handlers; 2622 if (nodes) { 2623 if (combinator) { 2624 if (combinator == "descendant") { 2625 for (var i = 0, node; node = nodes[i]; i++) 2626 h.concat(results, node.getElementsByTagName(tagName)); 2627 return results; 2628 } else nodes = this[combinator](nodes); 2629 if (tagName == "*") return nodes; 2630 } 2631 for (var i = 0, node; node = nodes[i]; i++) 2632 if (node.tagName.toUpperCase() === uTagName) results.push(node); 2633 return results; 2634 } else return root.getElementsByTagName(tagName); 2635 }, 2636 id: function(nodes, root, id, combinator) { 2637 var targetNode = $(id), 2638 h = Selector.handlers; 2639 if (!targetNode) return []; 2640 if (!nodes && root == document) return [targetNode]; 2641 if (nodes) { 2642 if (combinator) { 2643 if (combinator == 'child') { 2644 for (var i = 0, node; node = nodes[i]; i++) 2645 if (targetNode.parentNode == node) return [targetNode]; 2646 } else if (combinator == 'descendant') { 2647 for (var i = 0, node; node = nodes[i]; i++) 2648 if (Element.descendantOf(targetNode, node)) return [targetNode]; 2649 } else if (combinator == 'adjacent') { 2650 for (var i = 0, node; node = nodes[i]; i++) 2651 if (Selector.handlers.previousElementSibling(targetNode) == node) return [targetNode]; 2652 } else nodes = h[combinator](nodes); 2653 } 2654 for (var i = 0, node; node = nodes[i]; i++) 2655 if (node == targetNode) return [targetNode]; 2656 return []; 2657 } 2658 return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; 2659 }, 2660 className: function(nodes, root, className, combinator) { 2661 if (nodes && combinator) nodes = this[combinator](nodes); 2662 return Selector.handlers.byClassName(nodes, root, className); 2663 }, 2664 byClassName: function(nodes, root, className) {
2665 if (!nodes) nodes = Selector.handlers.descendant([root]); 2666 var needle = ' ' + className + ' '; 2667 for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { 2668 nodeClassName = node.className; 2669 if (nodeClassName.length == 0) continue; 2670 if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) results.push(node); 2671 } 2672 return results; 2673 }, 2674 attrPresence: function(nodes, root, attr, combinator) { 2675 if (!nodes) nodes = root.getElementsByTagName("*"); 2676 if (nodes && combinator) nodes = this[combinator](nodes); 2677 var results = []; 2678 for (var i = 0, node; node = nodes[i]; i++) 2679 if (Element.hasAttribute(node, attr)) results.push(node); 2680 return results; 2681 }, 2682 attr: function(nodes, root, attr, value, operator, combinator) { 2683 if (!nodes) nodes = root.getElementsByTagName("*"); 2684 if (nodes && combinator) nodes = this[combinator](nodes); 2685 var handler = Selector.operators[operator], 2686 results = []; 2687 for (var i = 0, node; node = nodes[i]; i++) { 2688 var nodeValue = Element.readAttribute(node, attr); 2689 if (nodeValue === null) continue; 2690 if (handler(nodeValue, value)) results.push(node); 2691 } 2692 return results; 2693 }, 2694 pseudo: function(nodes, name, value, root, combinator) { 2695 if (nodes && combinator) nodes = this[combinator](nodes); 2696 if (!nodes) nodes = root.getElementsByTagName("*"); 2697 return Selector.pseudos[name](nodes, value, root); 2698 } 2699 }, 2700 pseudos: { 2701 'first-child': function(nodes, value, root) { 2702 for (var i = 0, results = [], node; node = nodes[i]; i++) { 2703 if (Selector.handlers.previousElementSibling(node)) continue; 2704 results.push(node); 2705 } 2706 return results; 2707 }, 2708 'last-child': function(nodes, value, root) { 2709 for (var i = 0, results = [], node; node = nodes[i]; i++) { 2710 if (Selector.handlers.nextElementSibling(node)) continue; 2711 results.push(node); 2712 } 2713 return results; 2714 }, 2715 'only-child': function(nodes, value, root) { 2716 var h = Selector.handlers; 2717 for (var i = 0, results = [], node; node = nodes[i]; i++) 2718 if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) results.push(node); 2719 return results; 2720 }, 2721 'nth-child': function(nodes, formula, root) { 2722 return Selector.pseudos.nth(nodes, formula, root); 2723 }, 2724 'nth-last-child': function(nodes, formula, root) { 2725 return Selector.pseudos.nth(nodes, formula, root, true); 2726 }, 2727 'nth-of-type': function(nodes, formula, root) { 2728 return Selector.pseudos.nth(nodes, formula, root, false, true); 2729 }, 2730 'nth-last-of-type': function(nodes, formula, root) { 2731 return Selector.pseudos.nth(nodes, formula, root, true, true); 2732 }, 2733 'first-of-type': function(nodes, formula, root) { 2734 return Selector.pseudos.nth(nodes, "1", root, false, true); 2735 }, 2736 'last-of-type': function(nodes, formula, root) { 2737 return Selector.pseudos.nth(nodes, "1", root, true, true); 2738 }, 2739 'only-of-type': function(nodes, formula, root) { 2740 var p = Selector.pseudos; 2741 return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); 2742 }, 2743 getIndices: function(a, b, total) { 2744 if (a == 0) return b > 0 ? [b] : []; 2745 return $R(1, total).inject([], function(memo, i) { 2746 if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); 2747 return memo; 2748 }); 2749 }, 2750 nth: function(nodes, formula, root, reverse, ofType) { 2751 if (nodes.length == 0) return []; 2752 if (formula == 'even') formula = '2n+0'; 2753 if (formula == 'odd') formula = '2n+1'; 2754 var h = Selector.handlers, 2755 results = [], 2756 indexed = [], 2757 m;
2758 h.mark(nodes); 2759 for (var i = 0, node; node = nodes[i]; i++) { 2760 if (!node.parentNode._countedByPrototype) { 2761 h.index(node.parentNode, reverse, ofType); 2762 indexed.push(node.parentNode); 2763 } 2764 } 2765 if (formula.match(/^\d+$/)) { 2766 formula = Number(formula); 2767 for (var i = 0, node; node = nodes[i]; i++) 2768 if (node.nodeIndex == formula) results.push(node); 2769 } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { 2770 if (m[1] == "-") m[1] = -1; 2771 var a = m[1] ? Number(m[1]) : 1; 2772 var b = m[2] ? Number(m[2]) : 0; 2773 var indices = Selector.pseudos.getIndices(a, b, nodes.length); 2774 for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { 2775 for (var j = 0; j < l; j++) 2776 if (node.nodeIndex == indices[j]) results.push(node); 2777 } 2778 } 2779 h.unmark(nodes); 2780 h.unmark(indexed); 2781 return results; 2782 }, 2783 'empty': function(nodes, value, root) { 2784 for (var i = 0, results = [], node; node = nodes[i]; i++) { 2785 if (node.tagName == '!' || node.firstChild) continue; 2786 results.push(node); 2787 } 2788 return results; 2789 }, 2790 'not': function(nodes, selector, root) { 2791 var h = Selector.handlers, 2792 selectorType, m; 2793 var exclusions = new Selector(selector).findElements(root); 2794 h.mark(exclusions); 2795 for (var i = 0, results = [], node; node = nodes[i]; i++) 2796 if (!node._countedByPrototype) results.push(node); 2797 h.unmark(exclusions); 2798 return results; 2799 }, 2800 'enabled': function(nodes, value, root) { 2801 for (var i = 0, results = [], node; node = nodes[i]; i++) 2802 if (!node.disabled && (!node.type || node.type !== 'hidden')) results.push(node); 2803 return results; 2804 }, 2805 'disabled': function(nodes, value, root) { 2806 for (var i = 0, results = [], node; node = nodes[i]; i++) 2807 if (node.disabled) results.push(node); 2808 return results; 2809 }, 2810 'checked': function(nodes, value, root) { 2811 for (var i = 0, results = [], node; node = nodes[i]; i++) 2812 if (node.checked) results.push(node); 2813 return results; 2814 } 2815 }, 2816 operators: { 2817 '=': function(nv, v) { 2818 return nv == v; 2819 }, 2820 '!=': function(nv, v) { 2821 return nv != v; 2822 }, 2823 '^=': function(nv, v) { 2824 return nv == v || nv && nv.startsWith(v); 2825 }, 2826 '$=': function(nv, v) { 2827 return nv == v || nv && nv.endsWith(v); 2828 }, 2829 '*=': function(nv, v) { 2830 return nv == v || nv && nv.include(v); 2831 }, 2832 '$=': function(nv, v) { 2833 return nv.endsWith(v); 2834 }, 2835 '*=': function(nv, v) { 2836 return nv.include(v); 2837 }, 2838 '~=': function(nv, v) { 2839 return (' ' + nv + ' ').include(' ' + v + ' '); 2840 }, 2841 '|=': function(nv, v) { 2842 return ('-' + (nv || "").toUpperCase() + '-').include('-' + (v || "").toUpperCase() + '-'); 2843 } 2844 }, 2845 split: function(expression) { 2846 var expressions = []; 2847 expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { 2848 expressions.push(m[1].strip()); 2849 }); 2850 return expressions; 2851 }, 2852 matchElements: function(elements, expression) { 2853 var matches = $$(expression), 2854 h = Selector.handlers; 2855 h.mark(matches); 2856 for (var i = 0, results = [], element; element = elements[i]; i++) 2857 if (element._countedByPrototype) results.push(element); 2858 h.unmark(matches); 2859 return results; 2860 }, 2861 findElement: function(elements, expression, index) { 2862 if (Object.isNumber(expression)) { 2863 index = expression; 2864 expression = false;
2865 } 2866 return Selector.matchElements(elements, expression || '*')[index || 0]; 2867 }, 2868 findChildElements: function(element, expressions) { 2869 expressions = Selector.split(expressions.join(',')); 2870 var results = [], 2871 h = Selector.handlers; 2872 for (var i = 0, l = expressions.length, selector; i < l; i++) { 2873 selector = new Selector(expressions[i].strip()); 2874 h.concat(results, selector.findElements(element)); 2875 } 2876 return (l > 1) ? h.unique(results) : results; 2877 } 2878}); 2879if (Prototype.Browser.IE) { 2880 Object.extend(Selector.handlers, { 2881 concat: function(a, b) { 2882 for (var i = 0, node; node = b[i]; i++) 2883 if (node.tagName !== "!") a.push(node); 2884 return a; 2885 }, 2886 unmark: function(nodes) { 2887 for (var i = 0, node; node = nodes[i]; i++) 2888 node.removeAttribute('_countedByPrototype'); 2889 return nodes; 2890 } 2891 }); 2892} 2893 2894function $$() { 2895 return Selector.findChildElements(document, $A(arguments)); 2896} 2897var Form = { 2898 reset: function(form) { 2899 $(form).reset(); 2900 return form; 2901 }, 2902 serializeElements: function(elements, options) { 2903 if (typeof options != 'object') options = { 2904 hash: !! options 2905 }; 2906 else if (Object.isUndefined(options.hash)) options.hash = true; 2907 var key, value, submitted = false, 2908 submit = options.submit; 2909 var data = elements.inject({}, function(result, element) { 2910 if (!element.disabled && element.name) { 2911 key = element.name; 2912 value = $(element).getValue(); 2913 if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && submit !== false && (!submit || key == submit) && (submitted = true)))) { 2914 if (key in result) { 2915 if (!Object.isArray(result[key])) result[key] = [result[key]]; 2916 result[key].push(value); 2917 } 2918 else result[key] = value; 2919 } 2920 } 2921 return result; 2922 }); 2923 return options.hash ? data : Object.toQueryString(data); 2924 } 2925}; 2926Form.Methods = { 2927 serialize: function(form, options) { 2928 return Form.serializeElements(Form.getElements(form), options); 2929 }, 2930 getElements: function(form) { 2931 return $A($(form).getElementsByTagName('*')).inject([], function(elements, child) { 2932 if (Form.Element.Serializers[child.tagName.toLowerCase()]) elements.push(Element.extend(child)); 2933 return elements; 2934 }); 2935 }, 2936 getInputs: function(form, typeName, name) { 2937 form = $(form); 2938 var inputs = form.getElementsByTagName('input'); 2939 if (!typeName && !name) return $A(inputs).map(Element.extend); 2940 for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { 2941 var input = inputs[i]; 2942 if ((typeName && input.type != typeName) || (name && input.name != name)) continue; 2943 matchingInputs.push(Element.extend(input)); 2944 } 2945 return matchingInputs; 2946 }, 2947 disable: function(form) { 2948 form = $(form); 2949 Form.getElements(form).invoke('disable'); 2950 return form; 2951 }, 2952 enable: function(form) { 2953 form = $(form); 2954 Form.getElements(form).invoke('enable'); 2955 return form; 2956 }, 2957 findFirstElement: function(form) { 2958 var elements = $(form).getElements().findAll(function(element) { 2959 return 'hidden' != element.type && !element.disabled; 2960 }); 2961 var firstByIndex = elements.findAll(function(element) { 2962 return element.hasAttribute('tabIndex') && element.tabIndex >= 0; 2963 }).sortBy(function(element) { 2964 return element.tabIndex 2965 }).first(); 2966 return firstByIndex ? firstByIndex : elements.find(function(element) { 2967 return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); 2968 }); 2969 }, 2970 focusFirstElement: function(form) { 2971 form = $(form); 2972 form.findFirstElement().activate(); 2973 return form; 2974 }, 2975 request: function(form, options) { 2976 form = $(form), options = Object.clone(options || {}); 2977 var params = options.parameters, 2978 action = form.readAttribute('action') || ''; 2979 if (action.blank()) action = window.location.href; 2980 options.parameters = form.serialize(true); 2981 if (params) { 2982 if (Object.isString(params)) params = params.toQueryParams(); 2983 Object.extend(options.parameters, params); 2984 } 2985 if (form.hasAttribute('method') && !options.method) options.method = form.method; 2986 return new Ajax.Request(action, options); 2987 } 2988}; 2989Form.Element = { 2990 focus: function(element) { 2991 $(element).focus(); 2992 return element; 2993 }, 2994 select: function(element) { 2995 $(element).select(); 2996 return element; 2997 } 2998}; 2999Form.Element.Methods = { 3000 serialize: function(element) { 3001 element = $(element); 3002 if (!element.disabled && element.name) { 3003 var value = element.getValue(); 3004 if (value != undefined) { 3005 var pair = {}; 3006 pair[element.name] = value; 3007 return Object.toQueryString(pair); 3008 } 3009 } 3010 return ''; 3011 }, 3012 getValue: function(element) { 3013 element = $(element); 3014 var method = element.tagName.toLowerCase(); 3015 return Form.Element.Serializers[method](element); 3016 }, 3017 setValue: function(element, value) { 3018 element = $(element); 3019 var method = element.tagName.toLowerCase(); 3020 Form.Element.Serializers[method](element, value); 3021 return element; 3022 }, 3023 clear: function(element) { 3024 $(element).value = ''; 3025 return element; 3026 }, 3027 present: function(element) { 3028 return $(element).value != ''; 3029 }, 3030 activate: function(element) { 3031 element = $(element); 3032 try { 3033 element.focus(); 3034 if (element.select && (element.tagName.toLowerCase() != 'input' || !['button', 'reset', 'submit'].include(element.type))) element.select(); 3035 } catch (e) {} 3036 return element; 3037 }, 3038 disable: function(element) { 3039 element = $(element); 3040 element.disabled = true; 3041 return element; 3042 }, 3043 enable: function(element) { 3044 element = $(element); 3045 element.disabled = false;
3046 return element; 3047 } 3048}; 3049var Field = Form.Element; 3050var $F = Form.Element.Methods.getValue; 3051Form.Element.Serializers = { 3052 input: function(element, value) { 3053 switch (element.type.toLowerCase()) { 3054 case 'checkbox': 3055 case 'radio': 3056 return Form.Element.Serializers.inputSelector(element, value); 3057 default: 3058 return Form.Element.Serializers.textarea(element, value); 3059 } 3060 }, 3061 inputSelector: function(element, value) { 3062 if (Object.isUndefined(value)) return element.checked ? element.value : null; 3063 else element.checked = !! value; 3064 }, 3065 textarea: function(element, value) { 3066 if (Object.isUndefined(value)) return element.value; 3067 else element.value = value; 3068 }, 3069 select: function(element, value) { 3070 if (Object.isUndefined(value)) return this[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element); 3071 else { 3072 var opt, currentValue, single = !Object.isArray(value); 3073 for (var i = 0, length = element.length; i < length; i++) { 3074 opt = element.options[i]; 3075 currentValue = this.optionValue(opt); 3076 if (single) { 3077 if (currentValue == value) { 3078 opt.selected = true; 3079 return; 3080 } 3081 } 3082 else opt.selected = value.include(currentValue); 3083 } 3084 } 3085 }, 3086 selectOne: function(element) { 3087 var index = element.selectedIndex; 3088 return index >= 0 ? this.optionValue(element.options[index]) : null; 3089 }, 3090 selectMany: function(element) { 3091 var values, length = element.length; 3092 if (!length) return null; 3093 for (var i = 0, values = []; i < length; i++) { 3094 var opt = element.options[i]; 3095 if (opt.selected) values.push(this.optionValue(opt)); 3096 } 3097 return values; 3098 }, 3099 optionValue: function(opt) { 3100 return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; 3101 } 3102}; 3103Abstract.TimedObserver = Class.create(PeriodicalExecuter, { 3104 initialize: function($super, element, frequency, callback) { 3105 $super(callback, frequency); 3106 this.element = $(element); 3107 this.lastValue = this.getValue(); 3108 }, 3109 execute: function() { 3110 var value = this.getValue(); 3111 if (Object.isString(this.lastValue) && Object.isString(value) ? this.lastValue != value : String(this.lastValue) != String(value)) { 3112 this.callback(this.element, value); 3113 this.lastValue = value; 3114 } 3115 } 3116}); 3117Form.Element.Observer = Class.create(Abstract.TimedObserver, { 3118 getValue: function() { 3119 return Form.Element.getValue(this.element); 3120 } 3121}); 3122Form.Observer = Class.create(Abstract.TimedObserver, { 3123 getValue: function() { 3124 return Form.serialize(this.element); 3125 } 3126}); 3127Abstract.EventObserver = Class.create({ 3128 initialize: function(element, callback) { 3129 this.element = $(element); 3130 this.callback = callback; 3131 this.lastValue = this.getValue(); 3132 if (this.element.tagName.toLowerCase() == 'form') this.registerFormCallbacks(); 3133 else this.registerCallback(this.element); 3134 }, 3135 onElementEvent: function() { 3136 var value = this.getValue(); 3137 if (this.lastValue != value) { 3138 this.callback(this.element, value); 3139 this.lastValue = value; 3140 } 3141 }, 3142 registerFormCallbacks: function() { 3143 Form.getElements(this.element).each(this.registerCallback, this); 3144 }, 3145 registerCallback: function(element) { 3146 if (element.type) { 3147 switch (element.type.toLowerCase()) { 3148 case 'checkbox': 3149 case 'radio': 3150 Event.observe(element, 'click', this.onElementEvent.bind(this)); 3151 break; 3152 default: 3153 Event.observe(element, 'change', this.onElementEvent.bind(this)); 3154 break; 3155 } 3156 } 3157 } 3158}); 3159Form.Element.EventObserver = Class.create(Abstract.EventObserver, { 3160 getValue: function() { 3161 return Form.Element.getValue(this.element); 3162 } 3163}); 3164Form.EventObserver = Class.create(Abstract.EventObserver, { 3165 getValue: function() { 3166 return Form.serialize(this.element); 3167 } 3168}); 3169if (!window.Event) var Event = {}; 3170Object.extend(Event, { 3171 KEY_BACKSPACE: 8, 3172 KEY_TAB: 9, 3173 KEY_RETURN: 13, 3174 KEY_ESC: 27, 3175 KEY_LEFT: 37, 3176 KEY_UP: 38, 3177 KEY_RIGHT: 39, 3178 KEY_DOWN: 40, 3179 KEY_DELETE: 46, 3180 KEY_HOME: 36, 3181 KEY_END: 35, 3182 KEY_PAGEUP: 33, 3183 KEY_PAGEDOWN: 34, 3184 KEY_INSERT: 45, 3185 cache: {}, 3186 relatedTarget: function(event) { 3187 var element; 3188 switch (event.type) { 3189 case 'mouseover': 3190 element = event.fromElement; 3191 break; 3192 case 'mouseout': 3193 element = event.toElement; 3194 break; 3195 default: 3196 return null; 3197 } 3198 return Element.extend(element); 3199 } 3200}); 3201Event.Methods = (function() { 3202 var isButton; 3203 if (Prototype.Browser.IE) { 3204 var buttonMap = { 3205 0: 1, 3206 1: 4, 3207 2: 2 3208 }; 3209 isButton = function(event, code) { 3210 return event.button == buttonMap[code]; 3211 }; 3212 } else if (Prototype.Browser.WebKit) { 3213 isButton = function(event, code) { 3214 switch (code) { 3215 case 0: 3216 return event.which == 1 && !event.metaKey; 3217 case 1: 3218 return event.which == 1 && event.metaKey; 3219 default: 3220 return false;
3221 } 3222 }; 3223 } else { 3224 isButton = function(event, code) { 3225 return event.which ? (event.which === code + 1) : (event.button === code); 3226 }; 3227 } 3228 return { 3229 isLeftClick: function(event) { 3230 return isButton(event, 0) 3231 }, 3232 isMiddleClick: function(event) { 3233 return isButton(event, 1) 3234 }, 3235 isRightClick: function(event) { 3236 return isButton(event, 2) 3237 }, 3238 element: function(event) { 3239 event = Event.extend(event); 3240 var node = event.target, 3241 type = event.type, 3242 currentTarget = event.currentTarget; 3243 if (currentTarget && currentTarget.tagName) { 3244 if (type === 'load' || type === 'error' || (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' && currentTarget.type === 'radio')) node = currentTarget; 3245 } 3246 if (node.nodeType == Node.TEXT_NODE) node = node.parentNode; 3247 return Element.extend(node); 3248 }, 3249 findElement: function(event, expression) { 3250 var element = Event.element(event); 3251 if (!expression) return element; 3252 var elements = [element].concat(element.ancestors()); 3253 return Selector.findElement(elements, expression, 0); 3254 }, 3255 pointer: function(event) { 3256 var docElement = document.documentElement, 3257 body = document.body || { 3258 scrollLeft: 0, 3259 scrollTop: 0 3260 }; 3261 return { 3262 x: event.pageX || (event.clientX + (docElement.scrollLeft || body.scrollLeft) - (docElement.clientLeft || 0)), 3263 y: event.pageY || (event.clientY + (docElement.scrollTop || body.scrollTop) - (docElement.clientTop || 0)) 3264 }; 3265 }, 3266 pointerX: function(event) { 3267 return Event.pointer(event).x 3268 }, 3269 pointerY: function(event) { 3270 return Event.pointer(event).y 3271 }, 3272 stop: function(event) { 3273 Event.extend(event); 3274 event.preventDefault(); 3275 event.stopPropagation(); 3276 event.stopped = true; 3277 } 3278 }; 3279})(); 3280Event.extend = (function() { 3281 var methods = Object.keys(Event.Methods).inject({}, function(m, name) { 3282 m[name] = Event.Methods[name].methodize(); 3283 return m; 3284 }); 3285 if (Prototype.Browser.IE) { 3286 Object.extend(methods, { 3287 stopPropagation: function() { 3288 this.cancelBubble = true 3289 }, 3290 preventDefault: function() { 3291 this.returnValue = false 3292 }, 3293 inspect: function() { 3294 return "[object Event]" 3295 } 3296 }); 3297 return function(event) { 3298 if (!event) return false; 3299 if (event._extendedByPrototype) return event; 3300 event._extendedByPrototype = Prototype.emptyFunction; 3301 var pointer = Event.pointer(event); 3302 Object.extend(event, { 3303 target: event.srcElement, 3304 relatedTarget: Event.relatedTarget(event), 3305 pageX: pointer.x, 3306 pageY: pointer.y 3307 }); 3308 return Object.extend(event, methods); 3309 }; 3310 } else { 3311 Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__']; 3312 Object.extend(Event.prototype, methods); 3313 return Prototype.K; 3314 } 3315})(); 3316Object.extend(Event, (function() { 3317 var cache = Event.cache; 3318 3319 function getEventID(element) { 3320 if (element._prototypeEventID) return element._prototypeEventID[0]; 3321 arguments.callee.id = arguments.callee.id || 1; 3322 return element._prototypeEventID = [++arguments.callee.id]; 3323 } 3324 3325 function getDOMEventName(eventName) { 3326 if (eventName && eventName.include(':')) return "dataavailable"; 3327 return eventName; 3328 } 3329 3330 function getCacheForID(id) { 3331 return cache[id] = cache[id] || {}; 3332 } 3333 3334 function getWrappersForEventName(id, eventName) { 3335 var c = getCacheForID(id); 3336 return c[eventName] = c[eventName] || []; 3337 } 3338 3339 function createWrapper(element, eventName, handler) { 3340 var id = getEventID(element); 3341 var c = getWrappersForEventName(id, eventName); 3342 if (c.pluck("handler").include(handler)) return false;
3343 var wrapper = function(event) { 3344 if (!Event || !Event.extend || (event.eventName && event.eventName != eventName)) return false; 3345 Event.extend(event); 3346 handler.call(element, event); 3347 }; 3348 wrapper.handler = handler; 3349 c.push(wrapper); 3350 return wrapper; 3351 } 3352 3353 function findWrapper(id, eventName, handler) { 3354 var c = getWrappersForEventName(id, eventName); 3355 return c.find(function(wrapper) { 3356 return wrapper.handler == handler 3357 }); 3358 } 3359 3360 function destroyWrapper(id, eventName, handler) { 3361 var c = getCacheForID(id); 3362 if (!c[eventName]) return false; 3363 c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); 3364 } 3365 3366 function destroyCache() { 3367 for (var id in cache) 3368 for (var eventName in cache[id]) 3369 cache[id][eventName] = null; 3370 } 3371 if (window.attachEvent) { 3372 window.attachEvent("onunload", destroyCache); 3373 } 3374 if (Prototype.Browser.WebKit) { 3375 window.addEventListener('unload', Prototype.emptyFunction, false); 3376 } 3377 return { 3378 observe: function(element, eventName, handler) { 3379 element = $(element); 3380 var name = getDOMEventName(eventName); 3381 var wrapper = createWrapper(element, eventName, handler); 3382 if (!wrapper) return element; 3383 if (element.addEventListener) { 3384 element.addEventListener(name, wrapper, false); 3385 } else { 3386 element.attachEvent("on" + name, wrapper); 3387 } 3388 return element; 3389 }, 3390 stopObserving: function(element, eventName, handler) { 3391 element = $(element); 3392 var id = getEventID(element), 3393 name = getDOMEventName(eventName); 3394 if (!handler && eventName) { 3395 getWrappersForEventName(id, eventName).each(function(wrapper) { 3396 element.stopObserving(eventName, wrapper.handler); 3397 }); 3398 return element; 3399 } else if (!eventName) { 3400 Object.keys(getCacheForID(id)).each(function(eventName) { 3401 element.stopObserving(eventName); 3402 }); 3403 return element; 3404 } 3405 var wrapper = findWrapper(id, eventName, handler); 3406 if (!wrapper) return element; 3407 if (element.removeEventListener) { 3408 element.removeEventListener(name, wrapper, false); 3409 } else { 3410 element.detachEvent("on" + name, wrapper); 3411 } 3412 destroyWrapper(id, eventName, handler); 3413 return element; 3414 }, 3415 fire: function(element, eventName, memo) { 3416 element = $(element); 3417 if (element == document && document.createEvent && !element.dispatchEvent) element = document.documentElement; 3418 var event; 3419 if (document.createEvent) { 3420 event = document.createEvent("HTMLEvents"); 3421 event.initEvent("dataavailable", true, true); 3422 } else { 3423 event = document.createEventObject(); 3424 event.eventType = "ondataavailable"; 3425 } 3426 event.eventName = eventName; 3427 event.memo = memo || {}; 3428 if (document.createEvent) { 3429 element.dispatchEvent(event); 3430 } else { 3431 element.fireEvent(event.eventType, event); 3432 } 3433 return Event.extend(event); 3434 } 3435 }; 3436})()); 3437Object.extend(Event, Event.Methods); 3438Element.addMethods({ 3439 fire: Event.fire, 3440 observe: Event.observe, 3441 stopObserving: Event.stopObserving 3442}); 3443Object.extend(document, { 3444 fire: Element.Methods.fire.methodize(), 3445 observe: Element.Methods.observe.methodize(), 3446 stopObserving: Element.Methods.stopObserving.methodize(), 3447 loaded: false 3448}); 3449(function() { 3450 var timer; 3451 3452 function fireContentLoadedEvent() { 3453 if (document.loaded) return; 3454 if (timer) window.clearInterval(timer); 3455 document.fire("dom:loaded"); 3456 document.loaded = true; 3457 } 3458 if (document.addEventListener) { 3459 if (Prototype.Browser.WebKit) { 3460 timer = window.setInterval(function() { 3461 if (/loaded|complete/.test(document.readyState)) fireContentLoadedEvent(); 3462 }, 0); 3463 Event.observe(window, "load", fireContentLoadedEvent); 3464 } else { 3465 document.addEventListener("DOMContentLoaded", fireContentLoadedEvent, false); 3466 } 3467 } else { 3468 document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>"); 3469 $("__onDOMContentLoaded").onreadystatechange = function() { 3470 if (this.readyState == "complete") { 3471 this.onreadystatechange = null; 3472 fireContentLoadedEvent(); 3473 } 3474 }; 3475 } 3476})(); 3477Hash.toQueryString = Object.toQueryString; 3478var Toggle = { 3479 display: Element.toggle 3480}; 3481Element.Methods.childOf = Element.Methods.descendantOf; 3482var Insertion = { 3483 Before: function(element, content) { 3484 return Element.insert(element, { 3485 before: content 3486 }); 3487 }, 3488 Top: function(element, content) { 3489 return Element.insert(element, { 3490 top: content 3491 }); 3492 }, 3493 Bottom: function(element, content) { 3494 return Element.insert(element, { 3495 bottom: content 3496 }); 3497 }, 3498 After: function(element, content) { 3499 return Element.insert(element, { 3500 after: content 3501 }); 3502 } 3503}; 3504var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); 3505var Position = { 3506 includeScrollOffsets: false, 3507 prepare: function() { 3508 this.deltaX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0; 3509 this.deltaY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; 3510 }, 3511 within: function(element, x, y) { 3512 if (this.includeScrollOffsets) return this.withinIncludingScrolloffsets(element, x, y); 3513 this.xcomp = x; 3514 this.ycomp = y; 3515 this.offset = Element.cumulativeOffset(element); 3516 return (y >= this.offset[1] && y < this.offset[1] + element.offsetHeight && x >= this.offset[0] && x < this.offset[0] + element.offsetWidth); 3517 }, 3518 withinIncludingScrolloffsets: function(element, x, y) { 3519 var offsetcache = Element.cumulativeScrollOffset(element); 3520 this.xcomp = x + offsetcache[0] - this.deltaX; 3521 this.ycomp = y + offsetcache[1] - this.deltaY; 3522 this.offset = Element.cumulativeOffset(element); 3523 return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + element.offsetHeight && this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + element.offsetWidth); 3524 }, 3525 overlap: function(mode, element) { 3526 if (!mode) return 0; 3527 if (mode == 'vertical') return ((this.offset[1] + element.offsetHeight) - this.ycomp) / element.offsetHeight; 3528 if (mode == 'horizontal') return ((this.offset[0] + element.offsetWidth) - this.xcomp) / element.offsetWidth; 3529 }, 3530 cumulativeOffset: Element.Methods.cumulativeOffset, 3531 positionedOffset: Element.Methods.positionedOffset, 3532 absolutize: function(element) { 3533 Position.prepare(); 3534 return Element.absolutize(element); 3535 }, 3536 relativize: function(element) { 3537 Position.prepare(); 3538 return Element.relativize(element); 3539 }, 3540 realOffset: Element.Methods.cumulativeScrollOffset, 3541 offsetParent: Element.Methods.getOffsetParent, 3542 page: Element.Methods.viewportOffset, 3543 clone: function(source, target, options) { 3544 options = options || {}; 3545 return Element.clonePosition(target, source, options); 3546 } 3547}; 3548if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods) { 3549 function iter(name) { 3550 return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; 3551 } 3552 instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? 3553 function(element, className) {
3554 className = className.toString().strip(); 3555 var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); 3556 return cond ? document._getElementsByXPath('.//*' + cond, element) : []; 3557 } : function(element, className) { 3558 className = className.toString().strip(); 3559 var elements = [], 3560 classNames = (/\s/.test(className) ? $w(className) : null); 3561 if (!classNames && !className) return elements; 3562 var nodes = $(element).getElementsByTagName('*'); 3563 className = ' ' + className + ' '; 3564 for (var i = 0, child, cn; child = nodes[i]; i++) { 3565 if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || (classNames && classNames.all(function(name) { 3566 return !name.toString().blank() && cn.include(' ' + name + ' '); 3567 })))) elements.push(Element.extend(child)); 3568 } 3569 return elements; 3570 }; 3571 return function(className, parentElement) { 3572 return $(parentElement || document.body).getElementsByClassName(className); 3573 }; 3574}(Element.Methods); 3575Element.ClassNames = Class.create(); 3576Element.ClassNames.prototype = { 3577 initialize: function(element) { 3578 this.element = $(element); 3579 }, 3580 _each: function(iterator) { 3581 this.element.className.split(/\s+/).select(function(name) { 3582 return name.length > 0; 3583 })._each(iterator); 3584 }, 3585 set: function(className) { 3586 this.element.className = className; 3587 }, 3588 add: function(classNameToAdd) { 3589 if (this.include(classNameToAdd)) return; 3590 this.set($A(this).concat(classNameToAdd).join(' ')); 3591 }, 3592 remove: function(classNameToRemove) { 3593 if (!this.include(classNameToRemove)) return; 3594 this.set($A(this).without(classNameToRemove).join(' ')); 3595 }, 3596 toString: function() { 3597 return $A(this).join(' '); 3598 } 3599}; 3600Object.extend(Element.ClassNames.prototype, Enumerable); 3601Element.addMethods();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.