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