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 if(element == null) { return; } 1281 var method = element.tagName.toLowerCase(); 1282 try { 1283 var parameter = Form.Element.Serializers[method](element); 1284 } 1285 catch(err) { 1286// alert(err); 1287 } 1288 1289 if (parameter) 1290 return parameter[1]; 1291 } 1292} 1293 1294Form.Element.Serializers = { 1295 input: function(element) { 1296 switch (element.type.toLowerCase()) { 1297 case 'submit': 1298 case 'hidden': 1299 case 'password': 1300 case 'text': 1301 return Form.Element.Serializers.textarea(element); 1302 case 'checkbox': 1303 case 'radio': 1304 return Form.Element.Serializers.inputSelector(element); 1305 } 1306 return false; 1307 }, 1308 1309 inputSelector: function(element) { 1310 if (element.checked) 1311 return [element.name, element.value]; 1312 }, 1313 1314 textarea: function(element) { 1315 return [element.name, element.value]; 1316 }, 1317 1318 select: function(element) { 1319 return Form.Element.Serializers[element.type == 'select-one' ? 1320 'selectOne' : 'selectMany'](element); 1321 }, 1322 1323 selectOne: function(element) { 1324 var value = '', opt, index = element.selectedIndex; 1325 if (index >= 0) { 1326 opt = element.options[index]; 1327 value = opt.value; 1328 if (!value && !('value' in opt)) 1329 value = opt.text; 1330 } 1331 return [element.name, value]; 1332 }, 1333 1334 selectMany: function(element) { 1335 var value = new Array(); 1336 for (var i = 0; i < element.length; i++) { 1337 var opt = element.options[i]; 1338 if (opt.selected) { 1339 var optValue = opt.value; 1340 if (!optValue && !('value' in opt)) 1341 optValue = opt.text; 1342 value.push(optValue); 1343 } 1344 } 1345 return [element.name, value]; 1346 } 1347} 1348 1349/*--------------------------------------------------------------------------*/ 1350 1351var $F = Form.Element.getValue; 1352 1353/*--------------------------------------------------------------------------*/ 1354 1355Abstract.TimedObserver = function() {} 1356Abstract.TimedObserver.prototype = { 1357 initialize: function(element, frequency, callback) { 1358 this.frequency = frequency; 1359 this.element = $(element); 1360 this.callback = callback; 1361 1362 this.lastValue = this.getValue(); 1363 this.registerCallback(); 1364 }, 1365 1366 registerCallback: function() { 1367 setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 1368 }, 1369 1370 onTimerEvent: function() { 1371 var value = this.getValue(); 1372 if (this.lastValue != value) { 1373 this.callback(this.element, value); 1374 this.lastValue = value; 1375 } 1376 } 1377} 1378 1379Form.Element.Observer = Class.create(); 1380Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { 1381 getValue: function() { 1382 return Form.Element.getValue(this.element); 1383 } 1384}); 1385 1386Form.Observer = Class.create(); 1387Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { 1388 getValue: function() { 1389 return Form.serialize(this.element); 1390 } 1391}); 1392 1393/*--------------------------------------------------------------------------*/ 1394 1395Abstract.EventObserver = function() {} 1396Abstract.EventObserver.prototype = { 1397 initialize: function(element, callback) { 1398 this.element = $(element); 1399 this.callback = callback; 1400 1401 this.lastValue = this.getValue(); 1402 if (this.element.tagName.toLowerCase() == 'form') 1403 this.registerFormCallbacks(); 1404 else 1405 this.registerCallback(this.element); 1406 }, 1407 1408 onElementEvent: function() { 1409 var value = this.getValue(); 1410 if (this.lastValue != value) { 1411 this.callback(this.element, value); 1412 this.lastValue = value; 1413 } 1414 }, 1415 1416 registerFormCallbacks: function() { 1417 var elements = Form.getElements(this.element); 1418 for (var i = 0; i < elements.length; i++) 1419 this.registerCallback(elements[i]); 1420 }, 1421 1422 registerCallback: function(element) { 1423 if (element.type) { 1424 switch (element.type.toLowerCase()) { 1425 case 'checkbox': 1426 case 'radio': 1427 Event.observe(element, 'click', this.onElementEvent.bind(this)); 1428 break; 1429 case 'password': 1430 case 'text': 1431 case 'textarea': 1432 case 'select-one': 1433 case 'select-multiple': 1434 Event.observe(element, 'change', this.onElementEvent.bind(this)); 1435 break; 1436 } 1437 } 1438 } 1439} 1440 1441Form.Element.EventObserver = Class.create(); 1442Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { 1443 getValue: function() { 1444 return Form.Element.getValue(this.element); 1445 } 1446}); 1447 1448Form.EventObserver = Class.create(); 1449Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { 1450 getValue: function() { 1451 return Form.serialize(this.element); 1452 } 1453}); 1454if (!window.Event) { 1455 var Event = new Object(); 1456} 1457 1458Object.extend(Event, { 1459 KEY_BACKSPACE: 8, 1460 KEY_TAB: 9, 1461 KEY_RETURN: 13, 1462 KEY_ESC: 27, 1463 KEY_LEFT: 37, 1464 KEY_UP: 38, 1465 KEY_RIGHT: 39, 1466 KEY_DOWN: 40, 1467 KEY_DELETE: 46, 1468 1469 element: function(event) { 1470 return event.target || event.srcElement; 1471 }, 1472 1473 isLeftClick: function(event) { 1474 return (((event.which) && (event.which == 1)) || 1475 ((event.button) && (event.button == 1))); 1476 }, 1477 1478 pointerX: function(event) { 1479 return event.pageX || (event.clientX + 1480 (document.documentElement.scrollLeft || document.body.scrollLeft)); 1481 }, 1482 1483 pointerY: function(event) { 1484 return event.pageY || (event.clientY + 1485 (document.documentElement.scrollTop || document.body.scrollTop)); 1486 }, 1487 1488 stop: function(event) { 1489 if (event.preventDefault) { 1490 event.preventDefault(); 1491 event.stopPropagation(); 1492 } else { 1493 event.returnValue = false;
1494 event.cancelBubble = true; 1495 } 1496 }, 1497 1498 // find the first node with the given tagName, starting from the 1499 // node the event was triggered on; traverses the DOM upwards 1500 findElement: function(event, tagName) { 1501 var element = Event.element(event); 1502 while (element.parentNode && (!element.tagName || 1503 (element.tagName.toUpperCase() != tagName.toUpperCase()))) 1504 element = element.parentNode; 1505 return element; 1506 }, 1507 1508 observers: false, 1509 1510 _observeAndCache: function(element, name, observer, useCapture) { 1511 if (!this.observers) this.observers = []; 1512 if (element.addEventListener) { 1513 this.observers.push([element, name, observer, useCapture]); 1514 element.addEventListener(name, observer, useCapture); 1515 } else if (element.attachEvent) { 1516 this.observers.push([element, name, observer, useCapture]); 1517 element.attachEvent('on' + name, observer); 1518 } 1519 }, 1520 1521 unloadCache: function() { 1522 if (!Event.observers) return; 1523 for (var i = 0; i < Event.observers.length; i++) { 1524 Event.stopObserving.apply(this, Event.observers[i]); 1525 Event.observers[i][0] = null; 1526 } 1527 Event.observers = false; 1528 }, 1529 1530 observe: function(element, name, observer, useCapture) { 1531 var element = $(element); 1532 useCapture = useCapture || false; 1533 1534 if (name == 'keypress' && 1535 (navigator.appVersion.match(/Konqueror|Safari|KHTML/) 1536 || element.attachEvent)) 1537 name = 'keydown'; 1538 1539 this._observeAndCache(element, name, observer, useCapture); 1540 }, 1541 1542 stopObserving: function(element, name, observer, useCapture) { 1543 var element = $(element); 1544 useCapture = useCapture || false; 1545 1546 if (name == 'keypress' && 1547 (navigator.appVersion.match(/Konqueror|Safari|KHTML/) 1548 || element.detachEvent)) 1549 name = 'keydown'; 1550 1551 if (element.removeEventListener) { 1552 element.removeEventListener(name, observer, useCapture); 1553 } else if (element.detachEvent) { 1554 element.detachEvent('on' + name, observer); 1555 } 1556 } 1557}); 1558 1559/* prevent memory leaks in IE */ 1560Event.observe(window, 'unload', Event.unloadCache, false); 1561var Position = { 1562 // set to true if needed, warning: firefox performance problems 1563 // NOT neeeded for page scrolling, only if draggable contained in 1564 // scrollable elements 1565 includeScrollOffsets: false, 1566 1567 // must be called before calling withinIncludingScrolloffset, every time the 1568 // page is scrolled 1569 prepare: function() { 1570 this.deltaX = window.pageXOffset 1571 || document.documentElement.scrollLeft 1572 || document.body.scrollLeft 1573 || 0; 1574 this.deltaY = window.pageYOffset 1575 || document.documentElement.scrollTop 1576 || document.body.scrollTop 1577 || 0; 1578 }, 1579 1580 realOffset: function(element) { 1581 var valueT = 0, valueL = 0; 1582 do { 1583 valueT += element.scrollTop || 0; 1584 valueL += element.scrollLeft || 0; 1585 element = element.parentNode; 1586 } while (element); 1587 return [valueL, valueT]; 1588 }, 1589 1590 cumulativeOffset: function(element) { 1591 var valueT = 0, valueL = 0; 1592 do { 1593 valueT += element.offsetTop || 0; 1594 valueL += element.offsetLeft || 0; 1595 element = element.offsetParent; 1596 } while (element); 1597 return [valueL, valueT]; 1598 }, 1599 1600 positionedOffset: function(element) { 1601 var valueT = 0, valueL = 0; 1602 do { 1603 valueT += element.offsetTop || 0; 1604 valueL += element.offsetLeft || 0; 1605 element = element.offsetParent; 1606 if (element) { 1607 p = Element.getStyle(element, 'position'); 1608 if (p == 'relative' || p == 'absolute') break; 1609 } 1610 } while (element); 1611 return [valueL, valueT]; 1612 }, 1613 1614 offsetParent: function(element) { 1615 if (element.offsetParent) return element.offsetParent; 1616 if (element == document.body) return element; 1617 1618 while ((element = element.parentNode) && element != document.body) 1619 if (Element.getStyle(element, 'position') != 'static') 1620 return element; 1621 1622 return document.body; 1623 }, 1624 1625 // caches x/y coordinate pair to use with overlap 1626 within: function(element, x, y) { 1627 if (this.includeScrollOffsets) 1628 return this.withinIncludingScrolloffsets(element, x, y); 1629 this.xcomp = x; 1630 this.ycomp = y; 1631 this.offset = this.cumulativeOffset(element); 1632 1633 return (y >= this.offset[1] && 1634 y < this.offset[1] + element.offsetHeight && 1635 x >= this.offset[0] && 1636 x < this.offset[0] + element.offsetWidth); 1637 }, 1638 1639 withinIncludingScrolloffsets: function(element, x, y) { 1640 var offsetcache = this.realOffset(element); 1641 1642 this.xcomp = x + offsetcache[0] - this.deltaX; 1643 this.ycomp = y + offsetcache[1] - this.deltaY; 1644 this.offset = this.cumulativeOffset(element); 1645 1646 return (this.ycomp >= this.offset[1] && 1647 this.ycomp < this.offset[1] + element.offsetHeight && 1648 this.xcomp >= this.offset[0] && 1649 this.xcomp < this.offset[0] + element.offsetWidth); 1650 }, 1651 1652 // within must be called directly before 1653 overlap: function(mode, element) { 1654 if (!mode) return 0; 1655 if (mode == 'vertical') 1656 return ((this.offset[1] + element.offsetHeight) - this.ycomp) / 1657 element.offsetHeight; 1658 if (mode == 'horizontal') 1659 return ((this.offset[0] + element.offsetWidth) - this.xcomp) / 1660 element.offsetWidth; 1661 }, 1662 1663 clone: function(source, target) { 1664 source = $(source); 1665 target = $(target); 1666 target.style.position = 'absolute'; 1667 var offsets = this.cumulativeOffset(source); 1668 target.style.top = offsets[1] + 'px'; 1669 target.style.left = offsets[0] + 'px'; 1670 target.style.width = source.offsetWidth + 'px'; 1671 target.style.height = source.offsetHeight + 'px'; 1672 }, 1673 1674 page: function(forElement) { 1675 var valueT = 0, valueL = 0; 1676 1677 var element = forElement; 1678 do { 1679 valueT += element.offsetTop || 0; 1680 valueL += element.offsetLeft || 0; 1681 1682 // Safari fix 1683 if (element.offsetParent==document.body) 1684 if (Element.getStyle(element,'position')=='absolute') break; 1685 1686 } while (element = element.offsetParent); 1687 1688 element = forElement; 1689 do { 1690 valueT -= element.scrollTop || 0; 1691 valueL -= element.scrollLeft || 0; 1692 } while (element = element.parentNode); 1693 1694 return [valueL, valueT]; 1695 }, 1696 1697 clone: function(source, target) { 1698 var options = Object.extend({ 1699 setLeft: true, 1700 setTop: true, 1701 setWidth: true, 1702 setHeight: true, 1703 offsetTop: 0, 1704 offsetLeft: 0 1705 }, arguments[2] || {}) 1706 1707 // find page position of source 1708 source = $(source); 1709 var p = Position.page(source); 1710 1711 // find coordinate system to use 1712 target = $(target); 1713 var delta = [0, 0]; 1714 var parent = null; 1715 // delta [0,0] will do fine with position: fixed elements, 1716 // position:absolute needs offsetParent deltas 1717 if (Element.getStyle(target,'position') == 'absolute') { 1718 parent = Position.offsetParent(target); 1719 delta = Position.page(parent); 1720 } 1721 1722 // correct by body offsets (fixes Safari) 1723 if (parent == document.body) { 1724 delta[0] -= document.body.offsetLeft; 1725 delta[1] -= document.body.offsetTop; 1726 } 1727 1728 // set position 1729 if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; 1730 if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; 1731 if(options.setWidth) target.style.width = source.offsetWidth + 'px'; 1732 if(options.setHeight) target.style.height = source.offsetHeight + 'px'; 1733 }, 1734 1735 absolutize: function(element) { 1736 element = $(element); 1737 if (element.style.position == 'absolute') return; 1738 Position.prepare(); 1739 1740 var offsets = Position.positionedOffset(element); 1741 var top = offsets[1]; 1742 var left = offsets[0]; 1743 var width = element.clientWidth; 1744 var height = element.clientHeight; 1745 1746 element._originalLeft = left - parseFloat(element.style.left || 0); 1747 element._originalTop = top - parseFloat(element.style.top || 0); 1748 element._originalWidth = element.style.width; 1749 element._originalHeight = element.style.height; 1750 1751 element.style.position = 'absolute'; 1752 element.style.top = top + 'px';; 1753 element.style.left = left + 'px';; 1754 element.style.width = width + 'px';; 1755 element.style.height = height + 'px';; 1756 }, 1757 1758 relativize: function(element) { 1759 element = $(element); 1760 if (element.style.position == 'relative') return; 1761 Position.prepare(); 1762 1763 element.style.position = 'relative'; 1764 var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); 1765 var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); 1766 1767 element.style.top = top + 'px'; 1768 element.style.left = left + 'px'; 1769 element.style.height = element._originalHeight; 1770 element.style.width = element._originalWidth; 1771 } 1772} 1773 1774// Safari returns margins on body which is incorrect if the child is absolutely 1775// positioned. For performance reasons, redefine Position.cumulativeOffset for 1776// KHTML/WebKit only. 1777if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { 1778 Position.cumulativeOffset = function(element) { 1779 var valueT = 0, valueL = 0; 1780 do { 1781 valueT += element.offsetTop || 0; 1782 valueL += element.offsetLeft || 0; 1783 if (element.offsetParent == document.body) 1784 if (Element.getStyle(element, 'position') == 'absolute') break; 1785 1786 element = element.offsetParent; 1787 } while (element); 1788 1789 return [valueL, valueT]; 1790 } 1791}
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.