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