1var Prototype = { 2 Version: '1.4.0', 3 ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', 4 5 emptyFunction: function() {}, 6 K: function(x) {return x} 7} 8 9var Class = { 10 create: function() { 11 return function() { 12 this.initialize.apply(this, arguments); 13 } 14 } 15} 16 17var Abstract = new Object(); 18 19Object.extend = function(destination, source) { 20 for (property in source) { 21 destination[property] = source[property]; 22 } 23 return destination; 24} 25 26Object.inspect = function(object) { 27 try { 28 if (object == undefined) return 'undefined'; 29 if (object == null) return 'null'; 30 return object.inspect ? object.inspect() : object.toString(); 31 } catch (e) { 32 if (e instanceof RangeError) return '...'; 33 throw e; 34 } 35} 36 37Function.prototype.bind = function() { 38 var __method = this, args = $A(arguments), object = args.shift(); 39 return function() { 40 return __method.apply(object, args.concat($A(arguments))); 41 } 42} 43 44Function.prototype.bindAsEventListener = function(object) { 45 var __method = this; 46 return function(event) { 47 return __method.call(object, event || window.event); 48 } 49} 50 51Object.extend(Number.prototype, { 52 toColorPart: function() { 53 var digits = this.toString(16); 54 if (this < 16) return '0' + digits; 55 return digits; 56 }, 57 58 succ: function() { 59 return this + 1; 60 }, 61 62 times: function(iterator) { 63 $R(0, this, true).each(iterator); 64 return this; 65 } 66}); 67 68var Try = { 69 these: function() { 70 var returnValue; 71 72 for (var i = 0; i < arguments.length; i++) { 73 var lambda = arguments[i]; 74 try { 75 returnValue = lambda(); 76 break; 77 } catch (e) {} 78 } 79 80 return returnValue; 81 } 82} 83 84/*--------------------------------------------------------------------------*/ 85 86var PeriodicalExecuter = Class.create(); 87PeriodicalExecuter.prototype = { 88 initialize: function(callback, frequency) { 89 this.callback = callback; 90 this.frequency = frequency; 91 this.currentlyExecuting = false; 92 93 this.registerCallback(); 94 }, 95 96 registerCallback: function() { 97 setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 98 }, 99 100 onTimerEvent: function() { 101 if (!this.currentlyExecuting) { 102 try { 103 this.currentlyExecuting = true; 104 this.callback(); 105 } finally { 106 this.currentlyExecuting = false; 107 } 108 } 109 } 110} 111 112/*--------------------------------------------------------------------------*/ 113 114function $() { 115 var elements = new Array(); 116 117 for (var i = 0; i < arguments.length; i++) { 118 var element = arguments[i]; 119 if (typeof element == 'string') 120 element = document.getElementById(element); 121 122 if (arguments.length == 1) 123 return element; 124 125 elements.push(element); 126 } 127 128 return elements; 129} 130Object.extend(String.prototype, { 131 stripTags: function() { 132 return this.replace(/<\/?[^>]+>/gi, ''); 133 }, 134 135 stripScripts: function() { 136 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); 137 }, 138 139 extractScripts: function() { 140 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); 141 var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); 142 return (this.match(matchAll) || []).map(function(scriptTag) { 143 return (scriptTag.match(matchOne) || ['', ''])[1]; 144 }); 145 }, 146 147 evalScripts: function() { 148 return this.extractScripts().map(eval); 149 }, 150 151 escapeHTML: function() { 152 var div = document.createElement('div'); 153 var text = document.createTextNode(this); 154 div.appendChild(text); 155 return div.innerHTML; 156 }, 157 158 unescapeHTML: function() { 159 var div = document.createElement('div'); 160 div.innerHTML = this.stripTags(); 161 return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; 162 }, 163 164 toQueryParams: function() { 165 var pairs = this.match(/^\??(.*)$/)[1].split('&'); 166 return pairs.inject({}, function(params, pairString) { 167 var pair = pairString.split('='); 168 params[pair[0]] = pair[1]; 169 return params; 170 }); 171 }, 172 173 toArray: function() { 174 return this.split(''); 175 }, 176 177 camelize: function() { 178 var oStringList = this.split('-'); 179 if (oStringList.length == 1) return oStringList[0]; 180 181 var camelizedString = this.indexOf('-') == 0 182 ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) 183 : oStringList[0]; 184 185 for (var i = 1, len = oStringList.length; i < len; i++) { 186 var s = oStringList[i]; 187 camelizedString += s.charAt(0).toUpperCase() + s.substring(1); 188 } 189 190 return camelizedString; 191 }, 192 193 inspect: function() { 194 return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; 195 } 196}); 197 198String.prototype.parseQuery = String.prototype.toQueryParams; 199 200var $break = new Object(); 201var $continue = new Object(); 202 203var Enumerable = { 204 each: function(iterator) { 205 var index = 0; 206 try { 207 this._each(function(value) { 208 try { 209 iterator(value, index++); 210 } catch (e) { 211 if (e != $continue) throw e; 212 } 213 }); 214 } catch (e) { 215 if (e != $break) throw e; 216 } 217 }, 218 219 all: function(iterator) { 220 var result = true; 221 this.each(function(value, index) { 222 result = result && !!(iterator || Prototype.K)(value, index); 223 if (!result) throw $break; 224 }); 225 return result; 226 }, 227 228 any: function(iterator) { 229 var result = true; 230 this.each(function(value, index) { 231 if (result = !!(iterator || Prototype.K)(value, index)) 232 throw $break; 233 }); 234 return result; 235 }, 236 237 collect: function(iterator) { 238 var results = []; 239 this.each(function(value, index) { 240 results.push(iterator(value, index)); 241 }); 242 return results; 243 }, 244 245 detect: function (iterator) { 246 var result; 247 this.each(function(value, index) { 248 if (iterator(value, index)) { 249 result = value; 250 throw $break; 251 } 252 }); 253 return result; 254 }, 255 256 findAll: function(iterator) { 257 var results = []; 258 this.each(function(value, index) { 259 if (iterator(value, index)) 260 results.push(value); 261 }); 262 return results; 263 }, 264 265 grep: function(pattern, iterator) { 266 var results = []; 267 this.each(function(value, index) { 268 var stringValue = value.toString(); 269 if (stringValue.match(pattern)) 270 results.push((iterator || Prototype.K)(value, index)); 271 }) 272 return results; 273 }, 274 275 include: function(object) { 276 var found = false;
277 this.each(function(value) { 278 if (value == object) { 279 found = true; 280 throw $break; 281 } 282 }); 283 return found; 284 }, 285 286 inject: function(memo, iterator) { 287 this.each(function(value, index) { 288 memo = iterator(memo, value, index); 289 }); 290 return memo; 291 }, 292 293 invoke: function(method) { 294 var args = $A(arguments).slice(1); 295 return this.collect(function(value) { 296 return value[method].apply(value, args); 297 }); 298 }, 299 300 max: function(iterator) { 301 var result; 302 this.each(function(value, index) { 303 value = (iterator || Prototype.K)(value, index); 304 if (value >= (result || value)) 305 result = value; 306 }); 307 return result; 308 }, 309 310 min: function(iterator) { 311 var result; 312 this.each(function(value, index) { 313 value = (iterator || Prototype.K)(value, index); 314 if (value <= (result || value)) 315 result = value; 316 }); 317 return result; 318 }, 319 320 partition: function(iterator) { 321 var trues = [], falses = []; 322 this.each(function(value, index) { 323 ((iterator || Prototype.K)(value, index) ? 324 trues : falses).push(value); 325 }); 326 return [trues, falses]; 327 }, 328 329 pluck: function(property) { 330 var results = []; 331 this.each(function(value, index) { 332 results.push(value[property]); 333 }); 334 return results; 335 }, 336 337 reject: function(iterator) { 338 var results = []; 339 this.each(function(value, index) { 340 if (!iterator(value, index)) 341 results.push(value); 342 }); 343 return results; 344 }, 345 346 sortBy: function(iterator) { 347 return this.collect(function(value, index) { 348 return {value: value, criteria: iterator(value, index)}; 349 }).sort(function(left, right) { 350 var a = left.criteria, b = right.criteria; 351 return a < b ? -1 : a > b ? 1 : 0; 352 }).pluck('value'); 353 }, 354 355 toArray: function() { 356 return this.collect(Prototype.K); 357 }, 358 359 zip: function() { 360 var iterator = Prototype.K, args = $A(arguments); 361 if (typeof args.last() == 'function') 362 iterator = args.pop(); 363 364 var collections = [this].concat(args).map($A); 365 return this.map(function(value, index) { 366 iterator(value = collections.pluck(index)); 367 return value; 368 }); 369 }, 370 371 inspect: function() { 372 return '#<Enumerable:' + this.toArray().inspect() + '>'; 373 } 374} 375 376Object.extend(Enumerable, { 377 map: Enumerable.collect, 378 find: Enumerable.detect, 379 select: Enumerable.findAll, 380 member: Enumerable.include, 381 entries: Enumerable.toArray 382}); 383var $A = Array.from = function(iterable) { 384 if (!iterable) return []; 385 if (iterable.toArray) { 386 return iterable.toArray(); 387 } else { 388 var results = []; 389 for (var i = 0; i < iterable.length; i++) 390 results.push(iterable[i]); 391 return results; 392 } 393} 394 395Object.extend(Array.prototype, Enumerable); 396 397Array.prototype._reverse = Array.prototype.reverse; 398 399Object.extend(Array.prototype, { 400 _each: function(iterator) { 401 for (var i = 0; i < this.length; i++) 402 iterator(this[i]); 403 }, 404 405 clear: function() { 406 this.length = 0; 407 return this; 408 }, 409 410 first: function() { 411 return this[0]; 412 }, 413 414 last: function() { 415 return this[this.length - 1]; 416 }, 417 418 compact: function() { 419 return this.select(function(value) { 420 return value != undefined || value != null; 421 }); 422 }, 423 424 flatten: function() { 425 return this.inject([], function(array, value) { 426 return array.concat(value.constructor == Array ? 427 value.flatten() : [value]); 428 }); 429 }, 430 431 without: function() { 432 var values = $A(arguments); 433 return this.select(function(value) { 434 return !values.include(value); 435 }); 436 }, 437 438 indexOf: function(object) { 439 for (var i = 0; i < this.length; i++) 440 if (this[i] == object) return i; 441 return -1; 442 }, 443 444 reverse: function(inline) { 445 return (inline !== false ? this : this.toArray())._reverse(); 446 }, 447 448 shift: function() { 449 var result = this[0]; 450 for (var i = 0; i < this.length - 1; i++) 451 this[i] = this[i + 1]; 452 this.length--; 453 return result; 454 }, 455 456 inspect: function() { 457 return '[' + this.map(Object.inspect).join(', ') + ']'; 458 } 459}); 460var Hash = { 461 _each: function(iterator) { 462 for (key in this) { 463 var value = this[key]; 464 if (typeof value == 'function') continue; 465 466 var pair = [key, value]; 467 pair.key = key; 468 pair.value = value; 469 iterator(pair); 470 } 471 }, 472 473 keys: function() { 474 return this.pluck('key'); 475 }, 476 477 values: function() { 478 return this.pluck('value'); 479 }, 480 481 merge: function(hash) { 482 return $H(hash).inject($H(this), function(mergedHash, pair) { 483 mergedHash[pair.key] = pair.value; 484 return mergedHash; 485 }); 486 }, 487 488 toQueryString: function() { 489 return this.map(function(pair) { 490 return pair.map(encodeURIComponent).join('='); 491 }).join('&'); 492 }, 493 494 inspect: function() { 495 return '#<Hash:{' + this.map(function(pair) { 496 return pair.map(Object.inspect).join(': '); 497 }).join(', ') + '}>'; 498 } 499} 500 501function $H(object) { 502 var hash = Object.extend({}, object || {}); 503 Object.extend(hash, Enumerable); 504 Object.extend(hash, Hash); 505 return hash; 506} 507ObjectRange = Class.create(); 508Object.extend(ObjectRange.prototype, Enumerable); 509Object.extend(ObjectRange.prototype, { 510 initialize: function(start, end, exclusive) { 511 this.start = start; 512 this.end = end; 513 this.exclusive = exclusive; 514 }, 515 516 _each: function(iterator) { 517 var value = this.start; 518 do { 519 iterator(value); 520 value = value.succ(); 521 } while (this.include(value)); 522 }, 523 524 include: function(value) { 525 if (value < this.start) 526 return false;
527 if (this.exclusive) 528 return value < this.end; 529 return value <= this.end; 530 } 531}); 532 533var $R = function(start, end, exclusive) { 534 return new ObjectRange(start, end, exclusive); 535} 536 537var Ajax = { 538 getTransport: function() { 539 return Try.these( 540 function() {return new ActiveXObject('Msxml2.XMLHTTP')}, 541 function() {return new ActiveXObject('Microsoft.XMLHTTP')}, 542 function() {return new XMLHttpRequest()} 543 ) || false; 544 }, 545 546 activeRequestCount: 0 547} 548 549Ajax.Responders = { 550 responders: [], 551 552 _each: function(iterator) { 553 this.responders._each(iterator); 554 }, 555 556 register: function(responderToAdd) { 557 if (!this.include(responderToAdd)) 558 this.responders.push(responderToAdd); 559 }, 560 561 unregister: function(responderToRemove) { 562 this.responders = this.responders.without(responderToRemove); 563 }, 564 565 dispatch: function(callback, request, transport, json) { 566 this.each(function(responder) { 567 if (responder[callback] && typeof responder[callback] == 'function') { 568 try { 569 responder[callback].apply(responder, [request, transport, json]); 570 } catch (e) {} 571 } 572 }); 573 } 574}; 575 576Object.extend(Ajax.Responders, Enumerable); 577 578Ajax.Responders.register({ 579 onCreate: function() { 580 Ajax.activeRequestCount++; 581 }, 582 583 onComplete: function() { 584 Ajax.activeRequestCount--; 585 } 586}); 587 588Ajax.Base = function() {}; 589Ajax.Base.prototype = { 590 setOptions: function(options) { 591 this.options = { 592 method: 'post', 593 asynchronous: true, 594 parameters: '' 595 } 596 Object.extend(this.options, options || {}); 597 }, 598 599 responseIsSuccess: function() { 600 return this.transport.status == undefined 601 || this.transport.status == 0 602 || (this.transport.status >= 200 && this.transport.status < 300); 603 }, 604 605 responseIsFailure: function() { 606 return !this.responseIsSuccess(); 607 } 608} 609 610Ajax.Request = Class.create(); 611Ajax.Request.Events = 612 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 613 614Ajax.Request.prototype = Object.extend(new Ajax.Base(), { 615 initialize: function(url, options) { 616 this.transport = Ajax.getTransport(); 617 this.setOptions(options); 618 this.request(url); 619 }, 620 621 request: function(url) { 622 var parameters = this.options.parameters || ''; 623 if (parameters.length > 0) parameters += '&_='; 624 625 try { 626 this.url = url; 627 if (this.options.method == 'get' && parameters.length > 0) 628 this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; 629 630 Ajax.Responders.dispatch('onCreate', this, this.transport); 631 632 this.transport.open(this.options.method, this.url, 633 this.options.asynchronous); 634 635 if (this.options.asynchronous) { 636 this.transport.onreadystatechange = this.onStateChange.bind(this); 637 setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); 638 } 639 640 this.setRequestHeaders(); 641 642 var body = this.options.postBody ? this.options.postBody : parameters; 643 this.transport.send(this.options.method == 'post' ? body : null); 644 645 } catch (e) { 646 this.dispatchException(e); 647 } 648 }, 649 650 setRequestHeaders: function() { 651 var requestHeaders = 652 ['X-Requested-With', 'XMLHttpRequest', 653 'X-Prototype-Version', Prototype.Version]; 654 655 if (this.options.method == 'post') { 656 requestHeaders.push('Content-type', 657 'application/x-www-form-urlencoded'); 658 659 /* Force "Connection: close" for Mozilla browsers to work around 660 * a bug where XMLHttpReqeuest sends an incorrect Content-length 661 * header. See Mozilla Bugzilla #246651. 662 */ 663 if (this.transport.overrideMimeType) 664 requestHeaders.push('Connection', 'close'); 665 } 666 667 if (this.options.requestHeaders) 668 requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); 669 670 for (var i = 0; i < requestHeaders.length; i += 2) 671 this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); 672 }, 673 674 onStateChange: function() { 675 var readyState = this.transport.readyState; 676 if (readyState != 1) 677 this.respondToReadyState(this.transport.readyState); 678 }, 679 680 header: function(name) { 681 try { 682 return this.transport.getResponseHeader(name); 683 } catch (e) {} 684 }, 685 686 evalJSON: function() { 687 try { 688 return eval(this.header('X-JSON')); 689 } catch (e) {} 690 }, 691 692 evalResponse: function() { 693 try { 694 return eval(this.transport.responseText); 695 } catch (e) { 696 this.dispatchException(e); 697 } 698 }, 699 700 respondToReadyState: function(readyState) { 701 var event = Ajax.Request.Events[readyState]; 702 var transport = this.transport, json = this.evalJSON(); 703 704 if (event == 'Complete') {
705 try { 706 (this.options['on' + this.transport.status] 707 || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] 708 || Prototype.emptyFunction)(transport, json); 709 } catch (e) { 710 this.dispatchException(e); 711 } 712 713 if ((this.header('Content-type') || '').match(/^text\/javascript/i)) 714 this.evalResponse(); 715 } 716 717 try { 718 (this.options['on' + event] || Prototype.emptyFunction)(transport, json); 719 Ajax.Responders.dispatch('on' + event, this, transport, json); 720 } catch (e) { 721 this.dispatchException(e); 722 } 723 724 /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ 725 if (event == 'Complete') 726 this.transport.onreadystatechange = Prototype.emptyFunction; 727 }, 728 729 dispatchException: function(exception) { 730 (this.options.onException || Prototype.emptyFunction)(this, exception); 731 Ajax.Responders.dispatch('onException', this, exception); 732 } 733}); 734 735Ajax.Updater = Class.create(); 736 737Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { 738 initialize: function(container, url, options) { 739 this.containers = { 740 success: container.success ? $(container.success) : $(container), 741 failure: container.failure ? $(container.failure) : 742 (container.success ? null : $(container)) 743 } 744 745 this.transport = Ajax.getTransport(); 746 this.setOptions(options); 747 748 var onComplete = this.options.onComplete || Prototype.emptyFunction; 749 this.options.onComplete = (function(transport, object) { 750 this.updateContent(); 751 onComplete(transport, object); 752 }).bind(this); 753 754 this.request(url); 755 }, 756 757 updateContent: function() { 758 var receiver = this.responseIsSuccess() ? 759 this.containers.success : this.containers.failure; 760 var response = this.transport.responseText; 761 762 if (!this.options.evalScripts) 763 response = response.stripScripts(); 764 765 if (receiver) { 766 if (this.options.insertion) { 767 new this.options.insertion(receiver, response); 768 } else { 769 Element.update(receiver, response); 770 } 771 } 772 773 if (this.responseIsSuccess()) { 774 if (this.onComplete) 775 setTimeout(this.onComplete.bind(this), 10); 776 } 777 } 778}); 779
780Ajax.PeriodicalUpdater = Class.create(); 781Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { 782 initialize: function(container, url, options) { 783 this.setOptions(options); 784 this.onComplete = this.options.onComplete; 785 786 this.frequency = (this.options.frequency || 2); 787 this.decay = (this.options.decay || 1); 788 789 this.updater = {}; 790 this.container = container; 791 this.url = url; 792 793 this.start(); 794 }, 795 796 start: function() { 797 this.options.onComplete = this.updateComplete.bind(this); 798 this.onTimerEvent(); 799 }, 800 801 stop: function() { 802 this.updater.onComplete = undefined; 803 clearTimeout(this.timer); 804 (this.onComplete || Prototype.emptyFunction).apply(this, arguments); 805 }, 806 807 updateComplete: function(request) { 808 if (this.options.decay) { 809 this.decay = (request.responseText == this.lastText ? 810 this.decay * this.options.decay : 1); 811 812 this.lastText = request.responseText; 813 } 814 this.timer = setTimeout(this.onTimerEvent.bind(this), 815 this.decay * this.frequency * 1000); 816 }, 817 818 onTimerEvent: function() { 819 this.updater = new Ajax.Updater(this.container, this.url, this.options); 820 } 821}); 822document.getElementsByClassName = function(className, parentElement) { 823 var children = ($(parentElement) || document.body).getElementsByTagName('*'); 824 return $A(children).inject([], function(elements, child) { 825 if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) 826 elements.push(child); 827 return elements; 828 }); 829} 830 831/*--------------------------------------------------------------------------*/ 832 833if (!window.Element) { 834 var Element = new Object(); 835} 836 837Object.extend(Element, { 838 visible: function(element) { 839 return $(element).style.display != 'none'; 840 }, 841 842 toggle: function() { 843 for (var i = 0; i < arguments.length; i++) { 844 var element = $(arguments[i]); 845 Element[Element.visible(element) ? 'hide' : 'show'](element); 846 } 847 }, 848 849 hide: function() { 850 for (var i = 0; i < arguments.length; i++) { 851 var element = $(arguments[i]); 852 element.style.display = 'none'; 853 } 854 }, 855 856 show: function() { 857 for (var i = 0; i < arguments.length; i++) { 858 var element = $(arguments[i]); 859 element.style.display = ''; 860 } 861 }, 862 863 remove: function(element) { 864 element = $(element); 865 element.parentNode.removeChild(element); 866 }, 867 868 update: function(element, html) { 869 $(element).innerHTML = html.stripScripts(); 870 setTimeout(function() {html.evalScripts()}, 10); 871 }, 872 873 getHeight: function(element) { 874 element = $(element); 875 return element.offsetHeight; 876 }, 877 878 classNames: function(element) { 879 return new Element.ClassNames(element); 880 }, 881 882 hasClassName: function(element, className) { 883 if (!(element = $(element))) return; 884 return Element.classNames(element).include(className); 885 }, 886 887 addClassName: function(element, className) { 888 if (!(element = $(element))) return; 889 return Element.classNames(element).add(className); 890 }, 891 892 removeClassName: function(element, className) { 893 if (!(element = $(element))) return; 894 return Element.classNames(element).remove(className); 895 }, 896 897 // removes whitespace-only text node children 898 cleanWhitespace: function(element) { 899 element = $(element); 900 for (var i = 0; i < element.childNodes.length; i++) { 901 var node = element.childNodes[i]; 902 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) 903 Element.remove(node); 904 } 905 }, 906 907 empty: function(element) { 908 return $(element).innerHTML.match(/^\s*$/); 909 }, 910 911 scrollTo: function(element) { 912 element = $(element); 913 var x = element.x ? element.x : element.offsetLeft, 914 y = element.y ? element.y : element.offsetTop; 915 window.scrollTo(x, y); 916 }, 917 918 getStyle: function(element, style) { 919 element = $(element); 920 var value = element.style[style.camelize()]; 921 if (!value) { 922 if (document.defaultView && document.defaultView.getComputedStyle) { 923 var css = document.defaultView.getComputedStyle(element, null); 924 value = css ? css.getPropertyValue(style) : null; 925 } else if (element.currentStyle) { 926 value = element.currentStyle[style.camelize()]; 927 } 928 } 929 930 if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) 931 if (Element.getStyle(element, 'position') == 'static') value = 'auto'; 932 933 return value == 'auto' ? null : value; 934 }, 935 936 setStyle: function(element, style) { 937 element = $(element); 938 for (name in style) 939 element.style[name.camelize()] = style[name]; 940 }, 941 942 getDimensions: function(element) { 943 element = $(element); 944 if (Element.getStyle(element, 'display') != 'none') 945 return {width: element.offsetWidth, height: element.offsetHeight}; 946 947 // All *Width and *Height properties give 0 on elements with display none, 948 // so enable the element temporarily 949 var els = element.style; 950 var originalVisibility = els.visibility; 951 var originalPosition = els.position; 952 els.visibility = 'hidden'; 953 els.position = 'absolute'; 954 els.display = ''; 955 var originalWidth = element.clientWidth; 956 var originalHeight = element.clientHeight; 957 els.display = 'none'; 958 els.position = originalPosition; 959 els.visibility = originalVisibility; 960 return {width: originalWidth, height: originalHeight}; 961 }, 962 963 makePositioned: function(element) { 964 element = $(element); 965 var pos = Element.getStyle(element, 'position'); 966 if (pos == 'static' || !pos) { 967 element._madePositioned = true; 968 element.style.position = 'relative'; 969 // Opera returns the offset relative to the positioning context, when an 970 // element is position relative but top and left have not been defined 971 if (window.opera) { 972 element.style.top = 0; 973 element.style.left = 0; 974 } 975 } 976 }, 977 978 undoPositioned: function(element) { 979 element = $(element); 980 if (element._madePositioned) { 981 element._madePositioned = undefined; 982 element.style.position = 983 element.style.top = 984 element.style.left = 985 element.style.bottom = 986 element.style.right = ''; 987 } 988 }, 989 990 makeClipping: function(element) { 991 element = $(element); 992 if (element._overflow) return; 993 element._overflow = element.style.overflow; 994 if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') 995 element.style.overflow = 'hidden'; 996 }, 997 998 undoClipping: function(element) { 999 element = $(element); 1000 if (element._overflow) return; 1001 element.style.overflow = element._overflow; 1002 element._overflow = undefined; 1003 } 1004}); 1005 1006var Toggle = new Object(); 1007Toggle.display = Element.toggle; 1008 1009/*--------------------------------------------------------------------------*/ 1010 1011Abstract.Insertion = function(adjacency) { 1012 this.adjacency = adjacency; 1013} 1014 1015Abstract.Insertion.prototype = { 1016 initialize: function(element, content) { 1017 this.element = $(element); 1018 this.content = content.stripScripts(); 1019 1020 if (this.adjacency && this.element.insertAdjacentHTML) {
1021 try { 1022 this.element.insertAdjacentHTML(this.adjacency, this.content); 1023 } catch (e) { 1024 if (this.element.tagName.toLowerCase() == 'tbody') { 1025 this.insertContent(this.contentFromAnonymousTable()); 1026 } else { 1027 throw e; 1028 } 1029 } 1030 } else { 1031 this.range = this.element.ownerDocument.createRange(); 1032 if (this.initializeRange) this.initializeRange(); 1033 this.insertContent([this.range.createContextualFragment(this.content)]); 1034 } 1035 1036 setTimeout(function() {content.evalScripts()}, 10); 1037 }, 1038 1039 contentFromAnonymousTable: function() { 1040 var div = document.createElement('div'); 1041 div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>'; 1042 return $A(div.childNodes[0].childNodes[0].childNodes); 1043 } 1044} 1045 1046var Insertion = new Object(); 1047 1048Insertion.Before = Class.create(); 1049Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { 1050 initializeRange: function() { 1051 this.range.setStartBefore(this.element); 1052 }, 1053 1054 insertContent: function(fragments) { 1055 fragments.each((function(fragment) { 1056 this.element.parentNode.insertBefore(fragment, this.element); 1057 }).bind(this)); 1058 } 1059}); 1060 1061Insertion.Top = Class.create(); 1062Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { 1063 initializeRange: function() { 1064 this.range.selectNodeContents(this.element); 1065 this.range.collapse(true); 1066 }, 1067 1068 insertContent: function(fragments) { 1069 fragments.reverse(false).each((function(fragment) { 1070 this.element.insertBefore(fragment, this.element.firstChild); 1071 }).bind(this)); 1072 } 1073}); 1074 1075Insertion.Bottom = Class.create(); 1076Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { 1077 initializeRange: function() { 1078 this.range.selectNodeContents(this.element); 1079 this.range.collapse(this.element); 1080 }, 1081 1082 insertContent: function(fragments) { 1083 fragments.each((function(fragment) { 1084 this.element.appendChild(fragment); 1085 }).bind(this)); 1086 } 1087}); 1088 1089Insertion.After = Class.create(); 1090Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { 1091 initializeRange: function() { 1092 this.range.setStartAfter(this.element); 1093 }, 1094 1095 insertContent: function(fragments) { 1096 fragments.each((function(fragment) { 1097 this.element.parentNode.insertBefore(fragment, 1098 this.element.nextSibling); 1099 }).bind(this)); 1100 } 1101}); 1102 1103/*--------------------------------------------------------------------------*/ 1104 1105Element.ClassNames = Class.create(); 1106Element.ClassNames.prototype = { 1107 initialize: function(element) { 1108 this.element = $(element); 1109 }, 1110 1111 _each: function(iterator) { 1112 this.element.className.split(/\s+/).select(function(name) { 1113 return name.length > 0; 1114 })._each(iterator); 1115 }, 1116 1117 set: function(className) { 1118 this.element.className = className; 1119 }, 1120 1121 add: function(classNameToAdd) { 1122 if (this.include(classNameToAdd)) return; 1123 this.set(this.toArray().concat(classNameToAdd).join(' ')); 1124 }, 1125 1126 remove: function(classNameToRemove) { 1127 if (!this.include(classNameToRemove)) return; 1128 this.set(this.select(function(className) { 1129 return className != classNameToRemove; 1130 }).join(' ')); 1131 }, 1132 1133 toString: function() { 1134 return this.toArray().join(' '); 1135 } 1136} 1137 1138Object.extend(Element.ClassNames.prototype, Enumerable); 1139var Field = { 1140 clear: function() { 1141 for (var i = 0; i < arguments.length; i++) 1142 $(arguments[i]).value = ''; 1143 }, 1144 1145 focus: function(element) { 1146 $(element).focus(); 1147 }, 1148 1149 present: function() { 1150 for (var i = 0; i < arguments.length; i++) 1151 if ($(arguments[i]).value == '') return false; 1152 return true; 1153 }, 1154 1155 select: function(element) { 1156 $(element).select(); 1157 }, 1158 1159 activate: function(element) { 1160 element = $(element); 1161 element.focus(); 1162 if (element.select) 1163 element.select(); 1164 } 1165} 1166 1167/*--------------------------------------------------------------------------*/ 1168 1169var Form = { 1170 serialize: function(form) { 1171 var elements = Form.getElements($(form)); 1172 var queryComponents = new Array(); 1173 1174 for (var i = 0; i < elements.length; i++) { 1175 var queryComponent = Form.Element.serialize(elements[i]); 1176 if (queryComponent) 1177 queryComponents.push(queryComponent); 1178 } 1179 1180 return queryComponents.join('&'); 1181 }, 1182 1183 getElements: function(form) { 1184 form = $(form); 1185 var elements = new Array(); 1186 1187 for (tagName in Form.Element.Serializers) { 1188 var tagElements = form.getElementsByTagName(tagName); 1189 for (var j = 0; j < tagElements.length; j++) 1190 elements.push(tagElements[j]); 1191 } 1192 return elements; 1193 }, 1194 1195 getInputs: function(form, typeName, name) { 1196 form = $(form); 1197 var inputs = form.getElementsByTagName('input'); 1198 1199 if (!typeName && !name)
1200 return inputs; 1201 1202 var matchingInputs = new Array(); 1203 for (var i = 0; i < inputs.length; i++) { 1204 var input = inputs[i]; 1205 if ((typeName && input.type != typeName) || 1206 (name && input.name != name)) 1207 continue; 1208 matchingInputs.push(input); 1209 } 1210 1211 return matchingInputs; 1212 }, 1213 1214 disable: function(form) { 1215 var elements = Form.getElements(form); 1216 for (var i = 0; i < elements.length; i++) { 1217 var element = elements[i]; 1218 element.blur(); 1219 element.disabled = 'true'; 1220 } 1221 }, 1222 1223 enable: function(form) { 1224 var elements = Form.getElements(form); 1225 for (var i = 0; i < elements.length; i++) { 1226 var element = elements[i]; 1227 element.disabled = ''; 1228 } 1229 }, 1230 1231 findFirstElement: function(form) { 1232 return Form.getElements(form).find(function(element) { 1233 return element.type != 'hidden' && !element.disabled && 1234 ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); 1235 }); 1236 }, 1237 1238 focusFirstElement: function(form) { 1239 Field.activate(Form.findFirstElement(form)); 1240 }, 1241 1242 reset: function(form) { 1243 $(form).reset(); 1244 } 1245} 1246 1247Form.Element = { 1248 serialize: function(element) { 1249 element = $(element); 1250 var method = element.tagName.toLowerCase(); 1251 var parameter = Form.Element.Serializers[method](element); 1252 1253 if (parameter) { 1254 var key = encodeURIComponent(parameter[0]); 1255 if (key.length == 0) return; 1256 1257 if (parameter[1].constructor != Array) 1258 parameter[1] = [parameter[1]]; 1259 1260 return parameter[1].map(function(value) { 1261 return key + '=' + encodeURIComponent(value); 1262 }).join('&'); 1263 } 1264 }, 1265 1266 getValue: function(element) { 1267 element = $(element); 1268 var method = element.tagName.toLowerCase(); 1269 var parameter = Form.Element.Serializers[method](element); 1270 1271 if (parameter) 1272 return parameter[1]; 1273 } 1274} 1275 1276Form.Element.Serializers = { 1277 input: function(element) { 1278 switch (element.type.toLowerCase()) { 1279 case 'submit': 1280 case 'hidden': 1281 case 'password': 1282 case 'text': 1283 return Form.Element.Serializers.textarea(element); 1284 case 'checkbox': 1285 case 'radio': 1286 return Form.Element.Serializers.inputSelector(element); 1287 } 1288 return false; 1289 }, 1290 1291 inputSelector: function(element) { 1292 if (element.checked) 1293 return [element.name, element.value]; 1294 }, 1295 1296 textarea: function(element) { 1297 return [element.name, element.value]; 1298 }, 1299 1300 select: function(element) { 1301 return Form.Element.Serializers[element.type == 'select-one' ? 1302 'selectOne' : 'selectMany'](element); 1303 }, 1304 1305 selectOne: function(element) { 1306 var value = '', opt, index = element.selectedIndex; 1307 if (index >= 0) { 1308 opt = element.options[index]; 1309 value = opt.value; 1310 if (!value && !('value' in opt)) 1311 value = opt.text; 1312 } 1313 return [element.name, value]; 1314 }, 1315 1316 selectMany: function(element) { 1317 var value = new Array(); 1318 for (var i = 0; i < element.length; i++) { 1319 var opt = element.options[i]; 1320 if (opt.selected) { 1321 var optValue = opt.value; 1322 if (!optValue && !('value' in opt)) 1323 optValue = opt.text; 1324 value.push(optValue); 1325 } 1326 } 1327 return [element.name, value]; 1328 } 1329} 1330 1331/*--------------------------------------------------------------------------*/ 1332 1333var $F = Form.Element.getValue; 1334 1335/*--------------------------------------------------------------------------*/ 1336 1337Abstract.TimedObserver = function() {} 1338Abstract.TimedObserver.prototype = { 1339 initialize: function(element, frequency, callback) { 1340 this.frequency = frequency; 1341 this.element = $(element); 1342 this.callback = callback; 1343 1344 this.lastValue = this.getValue(); 1345 this.registerCallback(); 1346 }, 1347 1348 registerCallback: function() { 1349 setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 1350 }, 1351 1352 onTimerEvent: function() { 1353 var value = this.getValue(); 1354 if (this.lastValue != value) { 1355 this.callback(this.element, value); 1356 this.lastValue = value; 1357 } 1358 } 1359} 1360 1361Form.Element.Observer = Class.create(); 1362Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { 1363 getValue: function() { 1364 return Form.Element.getValue(this.element); 1365 } 1366}); 1367 1368Form.Observer = Class.create(); 1369Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { 1370 getValue: function() { 1371 return Form.serialize(this.element); 1372 } 1373}); 1374 1375/*--------------------------------------------------------------------------*/ 1376 1377Abstract.EventObserver = function() {} 1378Abstract.EventObserver.prototype = { 1379 initialize: function(element, callback) { 1380 this.element = $(element); 1381 this.callback = callback; 1382 1383 this.lastValue = this.getValue(); 1384 if (this.element.tagName.toLowerCase() == 'form') 1385 this.registerFormCallbacks(); 1386 else 1387 this.registerCallback(this.element); 1388 }, 1389 1390 onElementEvent: function() { 1391 var value = this.getValue(); 1392 if (this.lastValue != value) { 1393 this.callback(this.element, value); 1394 this.lastValue = value; 1395 } 1396 }, 1397 1398 registerFormCallbacks: function() { 1399 var elements = Form.getElements(this.element); 1400 for (var i = 0; i < elements.length; i++) 1401 this.registerCallback(elements[i]); 1402 }, 1403 1404 registerCallback: function(element) { 1405 if (element.type) { 1406 switch (element.type.toLowerCase()) { 1407 case 'checkbox': 1408 case 'radio': 1409 Event.observe(element, 'click', this.onElementEvent.bind(this)); 1410 break; 1411 case 'password': 1412 case 'text': 1413 case 'textarea': 1414 case 'select-one': 1415 case 'select-multiple': 1416 Event.observe(element, 'change', this.onElementEvent.bind(this)); 1417 break; 1418 } 1419 } 1420 } 1421} 1422 1423Form.Element.EventObserver = Class.create(); 1424Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { 1425 getValue: function() { 1426 return Form.Element.getValue(this.element); 1427 } 1428}); 1429 1430Form.EventObserver = Class.create(); 1431Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { 1432 getValue: function() { 1433 return Form.serialize(this.element); 1434 } 1435}); 1436if (!window.Event) { 1437 var Event = new Object(); 1438} 1439 1440Object.extend(Event, { 1441 KEY_BACKSPACE: 8, 1442 KEY_TAB: 9, 1443 KEY_RETURN: 13, 1444 KEY_ESC: 27, 1445 KEY_LEFT: 37, 1446 KEY_UP: 38, 1447 KEY_RIGHT: 39, 1448 KEY_DOWN: 40, 1449 KEY_DELETE: 46, 1450 1451 element: function(event) { 1452 return event.target || event.srcElement; 1453 }, 1454 1455 isLeftClick: function(event) { 1456 return (((event.which) && (event.which == 1)) || 1457 ((event.button) && (event.button == 1))); 1458 }, 1459 1460 pointerX: function(event) { 1461 return event.pageX || (event.clientX + 1462 (document.documentElement.scrollLeft || document.body.scrollLeft)); 1463 }, 1464 1465 pointerY: function(event) { 1466 return event.pageY || (event.clientY + 1467 (document.documentElement.scrollTop || document.body.scrollTop)); 1468 }, 1469 1470 stop: function(event) { 1471 if (event.preventDefault) { 1472 event.preventDefault(); 1473 event.stopPropagation(); 1474 } else { 1475 event.returnValue = false;
1476 event.cancelBubble = true; 1477 } 1478 }, 1479 1480 // find the first node with the given tagName, starting from the 1481 // node the event was triggered on; traverses the DOM upwards 1482 findElement: function(event, tagName) { 1483 var element = Event.element(event); 1484 while (element.parentNode && (!element.tagName || 1485 (element.tagName.toUpperCase() != tagName.toUpperCase()))) 1486 element = element.parentNode; 1487 return element; 1488 }, 1489 1490 observers: false, 1491 1492 _observeAndCache: function(element, name, observer, useCapture) { 1493 if (!this.observers) this.observers = []; 1494 if (element.addEventListener) { 1495 this.observers.push([element, name, observer, useCapture]); 1496 element.addEventListener(name, observer, useCapture); 1497 } else if (element.attachEvent) { 1498 this.observers.push([element, name, observer, useCapture]); 1499 element.attachEvent('on' + name, observer); 1500 } 1501 }, 1502 1503 unloadCache: function() { 1504 if (!Event.observers) return; 1505 for (var i = 0; i < Event.observers.length; i++) { 1506 Event.stopObserving.apply(this, Event.observers[i]); 1507 Event.observers[i][0] = null; 1508 } 1509 Event.observers = false; 1510 }, 1511 1512 observe: function(element, name, observer, useCapture) { 1513 var element = $(element); 1514 useCapture = useCapture || false; 1515 1516 if (name == 'keypress' && 1517 (navigator.appVersion.match(/Konqueror|Safari|KHTML/) 1518 || element.attachEvent)) 1519 name = 'keydown'; 1520 1521 this._observeAndCache(element, name, observer, useCapture); 1522 }, 1523 1524 stopObserving: function(element, name, observer, useCapture) { 1525 var element = $(element); 1526 useCapture = useCapture || false; 1527 1528 if (name == 'keypress' && 1529 (navigator.appVersion.match(/Konqueror|Safari|KHTML/) 1530 || element.detachEvent)) 1531 name = 'keydown'; 1532 1533 if (element.removeEventListener) { 1534 element.removeEventListener(name, observer, useCapture); 1535 } else if (element.detachEvent) { 1536 element.detachEvent('on' + name, observer); 1537 } 1538 } 1539}); 1540 1541/* prevent memory leaks in IE */ 1542Event.observe(window, 'unload', Event.unloadCache, false); 1543var Position = { 1544 // set to true if needed, warning: firefox performance problems 1545 // NOT neeeded for page scrolling, only if draggable contained in 1546 // scrollable elements 1547 includeScrollOffsets: false, 1548 1549 // must be called before calling withinIncludingScrolloffset, every time the 1550 // page is scrolled 1551 prepare: function() { 1552 this.deltaX = window.pageXOffset 1553 || document.documentElement.scrollLeft 1554 || document.body.scrollLeft 1555 || 0; 1556 this.deltaY = window.pageYOffset 1557 || document.documentElement.scrollTop 1558 || document.body.scrollTop 1559 || 0; 1560 }, 1561 1562 realOffset: function(element) { 1563 var valueT = 0, valueL = 0; 1564 do { 1565 valueT += element.scrollTop || 0; 1566 valueL += element.scrollLeft || 0; 1567 element = element.parentNode; 1568 } while (element); 1569 return [valueL, valueT]; 1570 }, 1571 1572 cumulativeOffset: function(element) { 1573 var valueT = 0, valueL = 0; 1574 do { 1575 valueT += element.offsetTop || 0; 1576 valueL += element.offsetLeft || 0; 1577 element = element.offsetParent; 1578 } while (element); 1579 return [valueL, valueT]; 1580 }, 1581 1582 positionedOffset: function(element) { 1583 var valueT = 0, valueL = 0; 1584 do { 1585 valueT += element.offsetTop || 0; 1586 valueL += element.offsetLeft || 0; 1587 element = element.offsetParent; 1588 if (element) { 1589 p = Element.getStyle(element, 'position'); 1590 if (p == 'relative' || p == 'absolute') break; 1591 } 1592 } while (element); 1593 return [valueL, valueT]; 1594 }, 1595 1596 offsetParent: function(element) { 1597 if (element.offsetParent) return element.offsetParent; 1598 if (element == document.body) return element; 1599 1600 while ((element = element.parentNode) && element != document.body) 1601 if (Element.getStyle(element, 'position') != 'static') 1602 return element; 1603 1604 return document.body; 1605 }, 1606 1607 // caches x/y coordinate pair to use with overlap 1608 within: function(element, x, y) { 1609 if (this.includeScrollOffsets) 1610 return this.withinIncludingScrolloffsets(element, x, y); 1611 this.xcomp = x; 1612 this.ycomp = y; 1613 this.offset = this.cumulativeOffset(element); 1614 1615 return (y >= this.offset[1] && 1616 y < this.offset[1] + element.offsetHeight && 1617 x >= this.offset[0] && 1618 x < this.offset[0] + element.offsetWidth); 1619 }, 1620 1621 withinIncludingScrolloffsets: function(element, x, y) { 1622 var offsetcache = this.realOffset(element); 1623 1624 this.xcomp = x + offsetcache[0] - this.deltaX; 1625 this.ycomp = y + offsetcache[1] - this.deltaY; 1626 this.offset = this.cumulativeOffset(element); 1627 1628 return (this.ycomp >= this.offset[1] && 1629 this.ycomp < this.offset[1] + element.offsetHeight && 1630 this.xcomp >= this.offset[0] && 1631 this.xcomp < this.offset[0] + element.offsetWidth); 1632 }, 1633 1634 // within must be called directly before 1635 overlap: function(mode, element) { 1636 if (!mode) return 0; 1637 if (mode == 'vertical') 1638 return ((this.offset[1] + element.offsetHeight) - this.ycomp) / 1639 element.offsetHeight; 1640 if (mode == 'horizontal') 1641 return ((this.offset[0] + element.offsetWidth) - this.xcomp) / 1642 element.offsetWidth; 1643 }, 1644 1645 clone: function(source, target) { 1646 source = $(source); 1647 target = $(target); 1648 target.style.position = 'absolute'; 1649 var offsets = this.cumulativeOffset(source); 1650 target.style.top = offsets[1] + 'px'; 1651 target.style.left = offsets[0] + 'px'; 1652 target.style.width = source.offsetWidth + 'px'; 1653 target.style.height = source.offsetHeight + 'px'; 1654 }, 1655 1656 page: function(forElement) { 1657 var valueT = 0, valueL = 0; 1658 1659 var element = forElement; 1660 do { 1661 valueT += element.offsetTop || 0; 1662 valueL += element.offsetLeft || 0; 1663 1664 // Safari fix 1665 if (element.offsetParent==document.body) 1666 if (Element.getStyle(element,'position')=='absolute') break; 1667 1668 } while (element = element.offsetParent); 1669 1670 element = forElement; 1671 do { 1672 valueT -= element.scrollTop || 0; 1673 valueL -= element.scrollLeft || 0; 1674 } while (element = element.parentNode); 1675 1676 return [valueL, valueT]; 1677 }, 1678 1679 clone: function(source, target) { 1680 var options = Object.extend({ 1681 setLeft: true, 1682 setTop: true, 1683 setWidth: true, 1684 setHeight: true, 1685 offsetTop: 0, 1686 offsetLeft: 0 1687 }, arguments[2] || {}) 1688 1689 // find page position of source 1690 source = $(source); 1691 var p = Position.page(source); 1692 1693 // find coordinate system to use 1694 target = $(target); 1695 var delta = [0, 0]; 1696 var parent = null; 1697 // delta [0,0] will do fine with position: fixed elements, 1698 // position:absolute needs offsetParent deltas 1699 if (Element.getStyle(target,'position') == 'absolute') { 1700 parent = Position.offsetParent(target); 1701 delta = Position.page(parent); 1702 } 1703 1704 // correct by body offsets (fixes Safari) 1705 if (parent == document.body) { 1706 delta[0] -= document.body.offsetLeft; 1707 delta[1] -= document.body.offsetTop; 1708 } 1709 1710 // set position 1711 if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; 1712 if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; 1713 if(options.setWidth) target.style.width = source.offsetWidth + 'px'; 1714 if(options.setHeight) target.style.height = source.offsetHeight + 'px'; 1715 }, 1716 1717 absolutize: function(element) { 1718 element = $(element); 1719 if (element.style.position == 'absolute') return; 1720 Position.prepare(); 1721 1722 var offsets = Position.positionedOffset(element); 1723 var top = offsets[1]; 1724 var left = offsets[0]; 1725 var width = element.clientWidth; 1726 var height = element.clientHeight; 1727 1728 element._originalLeft = left - parseFloat(element.style.left || 0); 1729 element._originalTop = top - parseFloat(element.style.top || 0); 1730 element._originalWidth = element.style.width; 1731 element._originalHeight = element.style.height; 1732 1733 element.style.position = 'absolute'; 1734 element.style.top = top + 'px';; 1735 element.style.left = left + 'px';; 1736 element.style.width = width + 'px';; 1737 element.style.height = height + 'px';; 1738 }, 1739 1740 relativize: function(element) { 1741 element = $(element); 1742 if (element.style.position == 'relative') return; 1743 Position.prepare(); 1744 1745 element.style.position = 'relative'; 1746 var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); 1747 var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); 1748 1749 element.style.top = top + 'px'; 1750 element.style.left = left + 'px'; 1751 element.style.height = element._originalHeight; 1752 element.style.width = element._originalWidth; 1753 } 1754} 1755 1756if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { 1757 Position.cumulativeOffset = function(element) { 1758 var valueT = 0, valueL = 0; 1759 do { 1760 valueT += element.offsetTop || 0; 1761 valueL += element.offsetLeft || 0; 1762 if (element.offsetParent == document.body) 1763 if (Element.getStyle(element, 'position') == 'absolute') break; 1764 1765 element = element.offsetParent; 1766 } while (element); 1767 1768 return [valueL, valueT]; 1769 } 1770}
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.