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