Changeset 6512
- Timestamp:
- 12/28/2007 07:17:21 PM (17 years ago)
- Location:
- trunk/wp-includes
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-includes/js/prototype.js
r5743 r6512 1 /* Prototype JavaScript framework, version 1. 5.1.11 /* Prototype JavaScript framework, version 1.6.0 2 2 * (c) 2005-2007 Sam Stephenson 3 3 * … … 5 5 * For details, see the Prototype web site: http://www.prototypejs.org/ 6 6 * 7 /*--------------------------------------------------------------------------*/7 *--------------------------------------------------------------------------*/ 8 8 9 9 var Prototype = { 10 Version: '1. 5.1.1',10 Version: '1.6.0', 11 11 12 12 Browser: { … … 14 14 Opera: !!window.opera, 15 15 WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, 16 Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1 16 Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, 17 MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) 17 18 }, 18 19 … … 21 22 ElementExtensions: !!window.HTMLElement, 22 23 SpecificElementExtensions: 23 (document.createElement('div').__proto__ !== 24 document.createElement('form').__proto__) 24 document.createElement('div').__proto__ && 25 document.createElement('div').__proto__ !== 26 document.createElement('form').__proto__ 25 27 }, 26 28 … … 30 32 emptyFunction: function() { }, 31 33 K: function(x) { return x } 32 } 33 34 }; 35 36 if (Prototype.Browser.MobileSafari) 37 Prototype.BrowserFeatures.SpecificElementExtensions = false; 38 39 if (Prototype.Browser.WebKit) 40 Prototype.BrowserFeatures.XPath = false; 41 42 /* Based on Alex Arnell's inheritance implementation. */ 34 43 var Class = { 35 44 create: function() { 36 return function() { 45 var parent = null, properties = $A(arguments); 46 if (Object.isFunction(properties[0])) 47 parent = properties.shift(); 48 49 function klass() { 37 50 this.initialize.apply(this, arguments); 38 51 } 39 } 40 } 41 42 var Abstract = new Object(); 52 53 Object.extend(klass, Class.Methods); 54 klass.superclass = parent; 55 klass.subclasses = []; 56 57 if (parent) { 58 var subclass = function() { }; 59 subclass.prototype = parent.prototype; 60 klass.prototype = new subclass; 61 parent.subclasses.push(klass); 62 } 63 64 for (var i = 0; i < properties.length; i++) 65 klass.addMethods(properties[i]); 66 67 if (!klass.prototype.initialize) 68 klass.prototype.initialize = Prototype.emptyFunction; 69 70 klass.prototype.constructor = klass; 71 72 return klass; 73 } 74 }; 75 76 Class.Methods = { 77 addMethods: function(source) { 78 var ancestor = this.superclass && this.superclass.prototype; 79 var properties = Object.keys(source); 80 81 if (!Object.keys({ toString: true }).length) 82 properties.push("toString", "valueOf"); 83 84 for (var i = 0, length = properties.length; i < length; i++) { 85 var property = properties[i], value = source[property]; 86 if (ancestor && Object.isFunction(value) && 87 value.argumentNames().first() == "$super") { 88 var method = value, value = Object.extend((function(m) { 89 return function() { return ancestor[m].apply(this, arguments) }; 90 })(property).wrap(method), { 91 valueOf: function() { return method }, 92 toString: function() { return method.toString() } 93 }); 94 } 95 this.prototype[property] = value; 96 } 97 98 return this; 99 } 100 }; 101 102 var Abstract = { }; 43 103 44 104 Object.extend = function(destination, source) { 45 for (var property in source) {105 for (var property in source) 46 106 destination[property] = source[property]; 47 }48 107 return destination; 49 } 108 }; 50 109 51 110 Object.extend(Object, { … … 63 122 toJSON: function(object) { 64 123 var type = typeof object; 65 switch (type) {124 switch (type) { 66 125 case 'undefined': 67 126 case 'function': … … 69 128 case 'boolean': return object.toString(); 70 129 } 130 71 131 if (object === null) return 'null'; 72 132 if (object.toJSON) return object.toJSON(); 73 if (object.ownerDocument === document) return; 133 if (Object.isElement(object)) return; 134 74 135 var results = []; 75 136 for (var property in object) { … … 78 139 results.push(property.toJSON() + ': ' + value); 79 140 } 141 80 142 return '{' + results.join(', ') + '}'; 143 }, 144 145 toQueryString: function(object) { 146 return $H(object).toQueryString(); 147 }, 148 149 toHTML: function(object) { 150 return object && object.toHTML ? object.toHTML() : String.interpret(object); 81 151 }, 82 152 … … 96 166 97 167 clone: function(object) { 98 return Object.extend({}, object); 168 return Object.extend({ }, object); 169 }, 170 171 isElement: function(object) { 172 return object && object.nodeType == 1; 173 }, 174 175 isArray: function(object) { 176 return object && object.constructor === Array; 177 }, 178 179 isHash: function(object) { 180 return object instanceof Hash; 181 }, 182 183 isFunction: function(object) { 184 return typeof object == "function"; 185 }, 186 187 isString: function(object) { 188 return typeof object == "string"; 189 }, 190 191 isNumber: function(object) { 192 return typeof object == "number"; 193 }, 194 195 isUndefined: function(object) { 196 return typeof object == "undefined"; 99 197 } 100 198 }); 101 199 102 Function.prototype.bind = function() { 103 var __method = this, args = $A(arguments), object = args.shift(); 104 return function() { 105 return __method.apply(object, args.concat($A(arguments))); 106 } 107 } 108 109 Function.prototype.bindAsEventListener = function(object) { 110 var __method = this, args = $A(arguments), object = args.shift(); 111 return function(event) { 112 return __method.apply(object, [event || window.event].concat(args)); 113 } 114 } 115 116 Object.extend(Number.prototype, { 117 toColorPart: function() { 118 return this.toPaddedString(2, 16); 119 }, 120 121 succ: function() { 122 return this + 1; 123 }, 124 125 times: function(iterator) { 126 $R(0, this, true).each(iterator); 127 return this; 128 }, 129 130 toPaddedString: function(length, radix) { 131 var string = this.toString(radix || 10); 132 return '0'.times(length - string.length) + string; 133 }, 134 135 toJSON: function() { 136 return isFinite(this) ? this.toString() : 'null'; 200 Object.extend(Function.prototype, { 201 argumentNames: function() { 202 var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); 203 return names.length == 1 && !names[0] ? [] : names; 204 }, 205 206 bind: function() { 207 if (arguments.length < 2 && arguments[0] === undefined) return this; 208 var __method = this, args = $A(arguments), object = args.shift(); 209 return function() { 210 return __method.apply(object, args.concat($A(arguments))); 211 } 212 }, 213 214 bindAsEventListener: function() { 215 var __method = this, args = $A(arguments), object = args.shift(); 216 return function(event) { 217 return __method.apply(object, [event || window.event].concat(args)); 218 } 219 }, 220 221 curry: function() { 222 if (!arguments.length) return this; 223 var __method = this, args = $A(arguments); 224 return function() { 225 return __method.apply(this, args.concat($A(arguments))); 226 } 227 }, 228 229 delay: function() { 230 var __method = this, args = $A(arguments), timeout = args.shift() * 1000; 231 return window.setTimeout(function() { 232 return __method.apply(__method, args); 233 }, timeout); 234 }, 235 236 wrap: function(wrapper) { 237 var __method = this; 238 return function() { 239 return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); 240 } 241 }, 242 243 methodize: function() { 244 if (this._methodized) return this._methodized; 245 var __method = this; 246 return this._methodized = function() { 247 return __method.apply(null, [this].concat($A(arguments))); 248 }; 137 249 } 138 250 }); 139 251 252 Function.prototype.defer = Function.prototype.delay.curry(0.01); 253 140 254 Date.prototype.toJSON = function() { 141 return '"' + this.get FullYear() + '-' +142 (this.get Month() + 1).toPaddedString(2) + '-' +143 this.get Date().toPaddedString(2) + 'T' +144 this.get Hours().toPaddedString(2) + ':' +145 this.get Minutes().toPaddedString(2) + ':' +146 this.get Seconds().toPaddedString(2) + '"';255 return '"' + this.getUTCFullYear() + '-' + 256 (this.getUTCMonth() + 1).toPaddedString(2) + '-' + 257 this.getUTCDate().toPaddedString(2) + 'T' + 258 this.getUTCHours().toPaddedString(2) + ':' + 259 this.getUTCMinutes().toPaddedString(2) + ':' + 260 this.getUTCSeconds().toPaddedString(2) + 'Z"'; 147 261 }; 148 262 … … 156 270 returnValue = lambda(); 157 271 break; 158 } catch (e) { }272 } catch (e) { } 159 273 } 160 274 161 275 return returnValue; 162 276 } 163 } 277 }; 278 279 RegExp.prototype.match = RegExp.prototype.test; 280 281 RegExp.escape = function(str) { 282 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 283 }; 164 284 165 285 /*--------------------------------------------------------------------------*/ 166 286 167 var PeriodicalExecuter = Class.create(); 168 PeriodicalExecuter.prototype = { 287 var PeriodicalExecuter = Class.create({ 169 288 initialize: function(callback, frequency) { 170 289 this.callback = callback; … … 179 298 }, 180 299 300 execute: function() { 301 this.callback(this); 302 }, 303 181 304 stop: function() { 182 305 if (!this.timer) return; … … 189 312 try { 190 313 this.currentlyExecuting = true; 191 this. callback(this);314 this.execute(); 192 315 } finally { 193 316 this.currentlyExecuting = false; … … 195 318 } 196 319 } 197 } 320 }); 198 321 Object.extend(String, { 199 322 interpret: function(value) { … … 239 362 scan: function(pattern, iterator) { 240 363 this.gsub(pattern, iterator); 241 return this;364 return String(this); 242 365 }, 243 366 … … 246 369 truncation = truncation === undefined ? '...' : truncation; 247 370 return this.length > length ? 248 this.slice(0, length - truncation.length) + truncation : this;371 this.slice(0, length - truncation.length) + truncation : String(this); 249 372 }, 250 373 … … 280 403 281 404 unescapeHTML: function() { 282 var div = document.createElement('div');405 var div = new Element('div'); 283 406 div.innerHTML = this.stripTags(); 284 407 return div.childNodes[0] ? (div.childNodes.length > 1 ? … … 289 412 toQueryParams: function(separator) { 290 413 var match = this.strip().match(/([^?#]*)(#.*)?$/); 291 if (!match) return { };292 293 return match[1].split(separator || '&').inject({ }, function(hash, pair) {414 if (!match) return { }; 415 416 return match[1].split(separator || '&').inject({ }, function(hash, pair) { 294 417 if ((pair = pair.split('='))[0]) { 295 418 var key = decodeURIComponent(pair.shift()); … … 298 421 299 422 if (key in hash) { 300 if ( hash[key].constructor != Array) hash[key] = [hash[key]];423 if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; 301 424 hash[key].push(value); 302 425 } … … 317 440 318 441 times: function(count) { 319 var result = ''; 320 for (var i = 0; i < count; i++) result += this; 321 return result; 442 return count < 1 ? '' : new Array(count + 1).join(this); 322 443 }, 323 444 … … 397 518 blank: function() { 398 519 return /^\s*$/.test(this); 520 }, 521 522 interpolate: function(object, pattern) { 523 return new Template(this, pattern).evaluate(object); 399 524 } 400 525 }); … … 410 535 411 536 String.prototype.gsub.prepareReplacement = function(replacement) { 412 if ( typeof replacement == 'function') return replacement;537 if (Object.isFunction(replacement)) return replacement; 413 538 var template = new Template(replacement); 414 539 return function(match) { return template.evaluate(match) }; 415 } 540 }; 416 541 417 542 String.prototype.parseQuery = String.prototype.toQueryParams; … … 424 549 with (String.prototype.escapeHTML) div.appendChild(text); 425 550 426 var Template = Class.create(); 427 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 428 Template.prototype = { 551 var Template = Class.create({ 429 552 initialize: function(template, pattern) { 430 553 this.template = template.toString(); 431 this.pattern 554 this.pattern = pattern || Template.Pattern; 432 555 }, 433 556 434 557 evaluate: function(object) { 558 if (Object.isFunction(object.toTemplateReplacements)) 559 object = object.toTemplateReplacements(); 560 435 561 return this.template.gsub(this.pattern, function(match) { 436 var before = match[1]; 562 if (object == null) return ''; 563 564 var before = match[1] || ''; 437 565 if (before == '\\') return match[2]; 438 return before + String.interpret(object[match[3]]); 439 }); 440 } 441 } 442 443 var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead'); 566 567 var ctx = object, expr = match[3]; 568 var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr); 569 if (match == null) return before; 570 571 while (match != null) { 572 var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; 573 ctx = ctx[comp]; 574 if (null == ctx || '' == match[3]) break; 575 expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); 576 match = pattern.exec(expr); 577 } 578 579 return before + String.interpret(ctx); 580 }.bind(this)); 581 } 582 }); 583 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; 584 585 var $break = { }; 444 586 445 587 var Enumerable = { 446 each: function(iterator ) {588 each: function(iterator, context) { 447 589 var index = 0; 590 iterator = iterator.bind(context); 448 591 try { 449 592 this._each(function(value) { … … 456 599 }, 457 600 458 eachSlice: function(number, iterator) { 601 eachSlice: function(number, iterator, context) { 602 iterator = iterator ? iterator.bind(context) : Prototype.K; 459 603 var index = -number, slices = [], array = this.toArray(); 460 604 while ((index += number) < array.length) 461 605 slices.push(array.slice(index, index+number)); 462 return slices.map(iterator); 463 }, 464 465 all: function(iterator) { 606 return slices.collect(iterator, context); 607 }, 608 609 all: function(iterator, context) { 610 iterator = iterator ? iterator.bind(context) : Prototype.K; 466 611 var result = true; 467 612 this.each(function(value, index) { 468 result = result && !! (iterator || Prototype.K)(value, index);613 result = result && !!iterator(value, index); 469 614 if (!result) throw $break; 470 615 }); … … 472 617 }, 473 618 474 any: function(iterator) { 619 any: function(iterator, context) { 620 iterator = iterator ? iterator.bind(context) : Prototype.K; 475 621 var result = false; 476 622 this.each(function(value, index) { 477 if (result = !! (iterator || Prototype.K)(value, index))623 if (result = !!iterator(value, index)) 478 624 throw $break; 479 625 }); … … 481 627 }, 482 628 483 collect: function(iterator) { 629 collect: function(iterator, context) { 630 iterator = iterator ? iterator.bind(context) : Prototype.K; 484 631 var results = []; 485 632 this.each(function(value, index) { 486 results.push( (iterator || Prototype.K)(value, index));633 results.push(iterator(value, index)); 487 634 }); 488 635 return results; 489 636 }, 490 637 491 detect: function(iterator) { 638 detect: function(iterator, context) { 639 iterator = iterator.bind(context); 492 640 var result; 493 641 this.each(function(value, index) { … … 500 648 }, 501 649 502 findAll: function(iterator) { 650 findAll: function(iterator, context) { 651 iterator = iterator.bind(context); 503 652 var results = []; 504 653 this.each(function(value, index) { … … 509 658 }, 510 659 511 grep: function(pattern, iterator) { 660 grep: function(filter, iterator, context) { 661 iterator = iterator ? iterator.bind(context) : Prototype.K; 512 662 var results = []; 663 664 if (Object.isString(filter)) 665 filter = new RegExp(filter); 666 513 667 this.each(function(value, index) { 514 var stringValue = value.toString(); 515 if (stringValue.match(pattern)) 516 results.push((iterator || Prototype.K)(value, index)); 517 }) 668 if (filter.match(value)) 669 results.push(iterator(value, index)); 670 }); 518 671 return results; 519 672 }, 520 673 521 674 include: function(object) { 675 if (Object.isFunction(this.indexOf)) 676 if (this.indexOf(object) != -1) return true; 677 522 678 var found = false; 523 679 this.each(function(value) { … … 538 694 }, 539 695 540 inject: function(memo, iterator) { 696 inject: function(memo, iterator, context) { 697 iterator = iterator.bind(context); 541 698 this.each(function(value, index) { 542 699 memo = iterator(memo, value, index); … … 552 709 }, 553 710 554 max: function(iterator) { 711 max: function(iterator, context) { 712 iterator = iterator ? iterator.bind(context) : Prototype.K; 555 713 var result; 556 714 this.each(function(value, index) { 557 value = (iterator || Prototype.K)(value, index);715 value = iterator(value, index); 558 716 if (result == undefined || value >= result) 559 717 result = value; … … 562 720 }, 563 721 564 min: function(iterator) { 722 min: function(iterator, context) { 723 iterator = iterator ? iterator.bind(context) : Prototype.K; 565 724 var result; 566 725 this.each(function(value, index) { 567 value = (iterator || Prototype.K)(value, index);726 value = iterator(value, index); 568 727 if (result == undefined || value < result) 569 728 result = value; … … 572 731 }, 573 732 574 partition: function(iterator) { 733 partition: function(iterator, context) { 734 iterator = iterator ? iterator.bind(context) : Prototype.K; 575 735 var trues = [], falses = []; 576 736 this.each(function(value, index) { 577 ( (iterator || Prototype.K)(value, index) ?737 (iterator(value, index) ? 578 738 trues : falses).push(value); 579 739 }); … … 583 743 pluck: function(property) { 584 744 var results = []; 585 this.each(function(value , index) {745 this.each(function(value) { 586 746 results.push(value[property]); 587 747 }); … … 589 749 }, 590 750 591 reject: function(iterator) { 751 reject: function(iterator, context) { 752 iterator = iterator.bind(context); 592 753 var results = []; 593 754 this.each(function(value, index) { … … 598 759 }, 599 760 600 sortBy: function(iterator) { 761 sortBy: function(iterator, context) { 762 iterator = iterator.bind(context); 601 763 return this.map(function(value, index) { 602 764 return {value: value, criteria: iterator(value, index)}; … … 613 775 zip: function() { 614 776 var iterator = Prototype.K, args = $A(arguments); 615 if ( typeof args.last() == 'function')777 if (Object.isFunction(args.last())) 616 778 iterator = args.pop(); 617 779 … … 629 791 return '#<Enumerable:' + this.toArray().inspect() + '>'; 630 792 } 631 } 793 }; 632 794 633 795 Object.extend(Enumerable, { … … 635 797 find: Enumerable.detect, 636 798 select: Enumerable.findAll, 799 filter: Enumerable.findAll, 637 800 member: Enumerable.include, 638 entries: Enumerable.toArray 801 entries: Enumerable.toArray, 802 every: Enumerable.all, 803 some: Enumerable.any 639 804 }); 640 var $A = Array.from = function(iterable) {805 function $A(iterable) { 641 806 if (!iterable) return []; 642 if (iterable.toArray) { 643 return iterable.toArray(); 644 } else { 645 var results = []; 646 for (var i = 0, length = iterable.length; i < length; i++) 647 results.push(iterable[i]); 807 if (iterable.toArray) return iterable.toArray(); 808 var length = iterable.length, results = new Array(length); 809 while (length--) results[length] = iterable[length]; 810 return results; 811 } 812 813 if (Prototype.Browser.WebKit) { 814 function $A(iterable) { 815 if (!iterable) return []; 816 if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && 817 iterable.toArray) return iterable.toArray(); 818 var length = iterable.length, results = new Array(length); 819 while (length--) results[length] = iterable[length]; 648 820 return results; 649 821 } 650 822 } 651 823 652 if (Prototype.Browser.WebKit) { 653 $A = Array.from = function(iterable) { 654 if (!iterable) return []; 655 if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && 656 iterable.toArray) { 657 return iterable.toArray(); 658 } else { 659 var results = []; 660 for (var i = 0, length = iterable.length; i < length; i++) 661 results.push(iterable[i]); 662 return results; 663 } 664 } 665 } 824 Array.from = $A; 666 825 667 826 Object.extend(Array.prototype, Enumerable); 668 827 669 if (!Array.prototype._reverse) 670 Array.prototype._reverse = Array.prototype.reverse; 828 if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; 671 829 672 830 Object.extend(Array.prototype, { … … 697 855 flatten: function() { 698 856 return this.inject([], function(array, value) { 699 return array.concat( value && value.constructor == Array?857 return array.concat(Object.isArray(value) ? 700 858 value.flatten() : [value]); 701 859 }); … … 709 867 }, 710 868 711 indexOf: function(object) {712 for (var i = 0, length = this.length; i < length; i++)713 if (this[i] == object) return i;714 return -1;715 },716 717 869 reverse: function(inline) { 718 870 return (inline !== false ? this : this.toArray())._reverse(); … … 728 880 array.push(value); 729 881 return array; 882 }); 883 }, 884 885 intersect: function(array) { 886 return this.uniq().findAll(function(item) { 887 return array.detect(function(value) { return item === value }); 730 888 }); 731 889 }, … … 753 911 }); 754 912 913 // use native browser JS 1.6 implementation if available 914 if (Object.isFunction(Array.prototype.forEach)) 915 Array.prototype._each = Array.prototype.forEach; 916 917 if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { 918 i || (i = 0); 919 var length = this.length; 920 if (i < 0) i = length + i; 921 for (; i < length; i++) 922 if (this[i] === item) return i; 923 return -1; 924 }; 925 926 if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { 927 i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; 928 var n = this.slice(0, i).reverse().indexOf(item); 929 return (n < 0) ? n : i - n - 1; 930 }; 931 755 932 Array.prototype.toArray = Array.prototype.clone; 756 933 757 934 function $w(string) { 935 if (!Object.isString(string)) return []; 758 936 string = string.strip(); 759 937 return string ? string.split(/\s+/) : []; … … 765 943 for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); 766 944 for (var i = 0, length = arguments.length; i < length; i++) { 767 if ( arguments[i].constructor == Array) {945 if (Object.isArray(arguments[i])) { 768 946 for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) 769 947 array.push(arguments[i][j]); … … 773 951 } 774 952 return array; 775 } 953 }; 776 954 } 777 var Hash = function(object) { 778 if (object instanceof Hash) this.merge(object); 779 else Object.extend(this, object || {}); 780 }; 781 782 Object.extend(Hash, { 783 toQueryString: function(obj) { 784 var parts = []; 785 parts.add = arguments.callee.addPair; 786 787 this.prototype._each.call(obj, function(pair) { 788 if (!pair.key) return; 789 var value = pair.value; 790 791 if (value && typeof value == 'object') { 792 if (value.constructor == Array) value.each(function(value) { 793 parts.add(pair.key, value); 794 }); 795 return; 796 } 797 parts.add(pair.key, value); 798 }); 799 800 return parts.join('&'); 801 }, 802 803 toJSON: function(object) { 804 var results = []; 805 this.prototype._each.call(object, function(pair) { 806 var value = Object.toJSON(pair.value); 807 if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value); 808 }); 809 return '{' + results.join(', ') + '}'; 955 Object.extend(Number.prototype, { 956 toColorPart: function() { 957 return this.toPaddedString(2, 16); 958 }, 959 960 succ: function() { 961 return this + 1; 962 }, 963 964 times: function(iterator) { 965 $R(0, this, true).each(iterator); 966 return this; 967 }, 968 969 toPaddedString: function(length, radix) { 970 var string = this.toString(radix || 10); 971 return '0'.times(length - string.length) + string; 972 }, 973 974 toJSON: function() { 975 return isFinite(this) ? this.toString() : 'null'; 810 976 } 811 977 }); 812 978 813 Hash.toQueryString.addPair = function(key, value, prefix) { 814 key = encodeURIComponent(key); 815 if (value === undefined) this.push(key); 816 else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); 817 } 818 819 Object.extend(Hash.prototype, Enumerable); 820 Object.extend(Hash.prototype, { 821 _each: function(iterator) { 822 for (var key in this) { 823 var value = this[key]; 824 if (value && value == Hash.prototype[key]) continue; 825 826 var pair = [key, value]; 827 pair.key = key; 828 pair.value = value; 829 iterator(pair); 830 } 831 }, 832 833 keys: function() { 834 return this.pluck('key'); 835 }, 836 837 values: function() { 838 return this.pluck('value'); 839 }, 840 841 merge: function(hash) { 842 return $H(hash).inject(this, function(mergedHash, pair) { 843 mergedHash[pair.key] = pair.value; 844 return mergedHash; 845 }); 846 }, 847 848 remove: function() { 849 var result; 850 for(var i = 0, length = arguments.length; i < length; i++) { 851 var value = this[arguments[i]]; 852 if (value !== undefined){ 853 if (result === undefined) result = value; 854 else { 855 if (result.constructor != Array) result = [result]; 856 result.push(value) 857 } 858 } 859 delete this[arguments[i]]; 860 } 861 return result; 862 }, 863 864 toQueryString: function() { 865 return Hash.toQueryString(this); 866 }, 867 868 inspect: function() { 869 return '#<Hash:{' + this.map(function(pair) { 870 return pair.map(Object.inspect).join(': '); 871 }).join(', ') + '}>'; 872 }, 873 874 toJSON: function() { 875 return Hash.toJSON(this); 876 } 979 $w('abs round ceil floor').each(function(method){ 980 Number.prototype[method] = Math[method].methodize(); 877 981 }); 878 879 982 function $H(object) { 880 if (object instanceof Hash) return object;881 983 return new Hash(object); 882 984 }; 883 985 884 // Safari iterates over shadowed properties 885 if (function() { 886 var i = 0, Test = function(value) { this.key = value }; 887 Test.prototype.key = 'foo'; 888 for (var property in new Test('bar')) i++; 889 return i > 1; 890 }()) Hash.prototype._each = function(iterator) { 891 var cache = []; 892 for (var key in this) { 893 var value = this[key]; 894 if ((value && value == Hash.prototype[key]) || cache.include(key)) continue; 895 cache.push(key); 896 var pair = [key, value]; 897 pair.key = key; 898 pair.value = value; 899 iterator(pair); 900 } 901 }; 902 ObjectRange = Class.create(); 903 Object.extend(ObjectRange.prototype, Enumerable); 904 Object.extend(ObjectRange.prototype, { 986 var Hash = Class.create(Enumerable, (function() { 987 if (function() { 988 var i = 0, Test = function(value) { this.key = value }; 989 Test.prototype.key = 'foo'; 990 for (var property in new Test('bar')) i++; 991 return i > 1; 992 }()) { 993 function each(iterator) { 994 var cache = []; 995 for (var key in this._object) { 996 var value = this._object[key]; 997 if (cache.include(key)) continue; 998 cache.push(key); 999 var pair = [key, value]; 1000 pair.key = key; 1001 pair.value = value; 1002 iterator(pair); 1003 } 1004 } 1005 } else { 1006 function each(iterator) { 1007 for (var key in this._object) { 1008 var value = this._object[key], pair = [key, value]; 1009 pair.key = key; 1010 pair.value = value; 1011 iterator(pair); 1012 } 1013 } 1014 } 1015 1016 function toQueryPair(key, value) { 1017 if (Object.isUndefined(value)) return key; 1018 return key + '=' + encodeURIComponent(String.interpret(value)); 1019 } 1020 1021 return { 1022 initialize: function(object) { 1023 this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); 1024 }, 1025 1026 _each: each, 1027 1028 set: function(key, value) { 1029 return this._object[key] = value; 1030 }, 1031 1032 get: function(key) { 1033 return this._object[key]; 1034 }, 1035 1036 unset: function(key) { 1037 var value = this._object[key]; 1038 delete this._object[key]; 1039 return value; 1040 }, 1041 1042 toObject: function() { 1043 return Object.clone(this._object); 1044 }, 1045 1046 keys: function() { 1047 return this.pluck('key'); 1048 }, 1049 1050 values: function() { 1051 return this.pluck('value'); 1052 }, 1053 1054 index: function(value) { 1055 var match = this.detect(function(pair) { 1056 return pair.value === value; 1057 }); 1058 return match && match.key; 1059 }, 1060 1061 merge: function(object) { 1062 return this.clone().update(object); 1063 }, 1064 1065 update: function(object) { 1066 return new Hash(object).inject(this, function(result, pair) { 1067 result.set(pair.key, pair.value); 1068 return result; 1069 }); 1070 }, 1071 1072 toQueryString: function() { 1073 return this.map(function(pair) { 1074 var key = encodeURIComponent(pair.key), values = pair.value; 1075 1076 if (values && typeof values == 'object') { 1077 if (Object.isArray(values)) 1078 return values.map(toQueryPair.curry(key)).join('&'); 1079 } 1080 return toQueryPair(key, values); 1081 }).join('&'); 1082 }, 1083 1084 inspect: function() { 1085 return '#<Hash:{' + this.map(function(pair) { 1086 return pair.map(Object.inspect).join(': '); 1087 }).join(', ') + '}>'; 1088 }, 1089 1090 toJSON: function() { 1091 return Object.toJSON(this.toObject()); 1092 }, 1093 1094 clone: function() { 1095 return new Hash(this); 1096 } 1097 } 1098 })()); 1099 1100 Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; 1101 Hash.from = $H; 1102 var ObjectRange = Class.create(Enumerable, { 905 1103 initialize: function(start, end, exclusive) { 906 1104 this.start = start; … … 928 1126 var $R = function(start, end, exclusive) { 929 1127 return new ObjectRange(start, end, exclusive); 930 } 1128 }; 931 1129 932 1130 var Ajax = { … … 940 1138 941 1139 activeRequestCount: 0 942 } 1140 }; 943 1141 944 1142 Ajax.Responders = { … … 960 1158 dispatch: function(callback, request, transport, json) { 961 1159 this.each(function(responder) { 962 if ( typeof responder[callback] == 'function') {1160 if (Object.isFunction(responder[callback])) { 963 1161 try { 964 1162 responder[callback].apply(responder, [request, transport, json]); 965 } catch (e) { }1163 } catch (e) { } 966 1164 } 967 1165 }); … … 972 1170 973 1171 Ajax.Responders.register({ 974 onCreate: function() { 975 Ajax.activeRequestCount++; 976 }, 977 onComplete: function() { 978 Ajax.activeRequestCount--; 979 } 1172 onCreate: function() { Ajax.activeRequestCount++ }, 1173 onComplete: function() { Ajax.activeRequestCount-- } 980 1174 }); 981 1175 982 Ajax.Base = function() {}; 983 Ajax.Base.prototype = { 984 setOptions: function(options) { 1176 Ajax.Base = Class.create({ 1177 initialize: function(options) { 985 1178 this.options = { 986 1179 method: 'post', … … 988 1181 contentType: 'application/x-www-form-urlencoded', 989 1182 encoding: 'UTF-8', 990 parameters: '' 991 } 992 Object.extend(this.options, options || {}); 1183 parameters: '', 1184 evalJSON: true, 1185 evalJS: true 1186 }; 1187 Object.extend(this.options, options || { }); 993 1188 994 1189 this.options.method = this.options.method.toLowerCase(); 995 if ( typeof this.options.parameters == 'string')1190 if (Object.isString(this.options.parameters)) 996 1191 this.options.parameters = this.options.parameters.toQueryParams(); 997 1192 } 998 } 999 1000 Ajax.Request = Class.create(); 1001 Ajax.Request.Events = 1002 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 1003 1004 Ajax.Request.prototype = Object.extend(new Ajax.Base(), { 1193 }); 1194 1195 Ajax.Request = Class.create(Ajax.Base, { 1005 1196 _complete: false, 1006 1197 1007 initialize: function(url, options) { 1198 initialize: function($super, url, options) { 1199 $super(options); 1008 1200 this.transport = Ajax.getTransport(); 1009 this.setOptions(options);1010 1201 this.request(url); 1011 1202 }, … … 1024 1215 this.parameters = params; 1025 1216 1026 if (params = Hash.toQueryString(params)) {1217 if (params = Object.toQueryString(params)) { 1027 1218 // when GET, append parameters to URL 1028 1219 if (this.method == 'get') … … 1033 1224 1034 1225 try { 1035 if (this.options.onCreate) this.options.onCreate(this.transport); 1036 Ajax.Responders.dispatch('onCreate', this, this.transport); 1226 var response = new Ajax.Response(this); 1227 if (this.options.onCreate) this.options.onCreate(response); 1228 Ajax.Responders.dispatch('onCreate', this, response); 1037 1229 1038 1230 this.transport.open(this.method.toUpperCase(), this.url, 1039 1231 this.options.asynchronous); 1040 1232 1041 if (this.options.asynchronous) 1042 setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); 1233 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); 1043 1234 1044 1235 this.transport.onreadystatechange = this.onStateChange.bind(this); … … 1088 1279 var extras = this.options.requestHeaders; 1089 1280 1090 if ( typeof extras.push == 'function')1281 if (Object.isFunction(extras.push)) 1091 1282 for (var i = 0, length = extras.length; i < length; i += 2) 1092 1283 headers[extras[i]] = extras[i+1]; … … 1100 1291 1101 1292 success: function() { 1102 return !this.transport.status 1103 || (this.transport.status >= 200 && this.transport.status < 300); 1293 var status = this.getStatus(); 1294 return !status || (status >= 200 && status < 300); 1295 }, 1296 1297 getStatus: function() { 1298 try { 1299 return this.transport.status || 0; 1300 } catch (e) { return 0 } 1104 1301 }, 1105 1302 1106 1303 respondToReadyState: function(readyState) { 1107 var state = Ajax.Request.Events[readyState]; 1108 var transport = this.transport, json = this.evalJSON(); 1304 var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); 1109 1305 1110 1306 if (state == 'Complete') { 1111 1307 try { 1112 1308 this._complete = true; 1113 (this.options['on' + this.transport.status]1309 (this.options['on' + response.status] 1114 1310 || this.options['on' + (this.success() ? 'Success' : 'Failure')] 1115 || Prototype.emptyFunction)( transport, json);1311 || Prototype.emptyFunction)(response, response.headerJSON); 1116 1312 } catch (e) { 1117 1313 this.dispatchException(e); 1118 1314 } 1119 1315 1120 var contentType = this.getHeader('Content-type'); 1121 if (contentType && contentType.strip(). 1122 match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) 1123 this.evalResponse(); 1316 var contentType = response.getHeader('Content-type'); 1317 if (this.options.evalJS == 'force' 1318 || (this.options.evalJS && contentType 1319 && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) 1320 this.evalResponse(); 1124 1321 } 1125 1322 1126 1323 try { 1127 (this.options['on' + state] || Prototype.emptyFunction)( transport, json);1128 Ajax.Responders.dispatch('on' + state, this, transport, json);1324 (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); 1325 Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); 1129 1326 } catch (e) { 1130 1327 this.dispatchException(e); … … 1140 1337 try { 1141 1338 return this.transport.getResponseHeader(name); 1142 } catch (e) { return null }1143 },1144 1145 evalJSON: function() {1146 try {1147 var json = this.getHeader('X-JSON');1148 return json ? json.evalJSON() : null;1149 1339 } catch (e) { return null } 1150 1340 }, … … 1164 1354 }); 1165 1355 1166 Ajax.Updater = Class.create(); 1167 1168 Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { 1169 initialize: function(container, url, options) { 1356 Ajax.Request.Events = 1357 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 1358 1359 Ajax.Response = Class.create({ 1360 initialize: function(request){ 1361 this.request = request; 1362 var transport = this.transport = request.transport, 1363 readyState = this.readyState = transport.readyState; 1364 1365 if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { 1366 this.status = this.getStatus(); 1367 this.statusText = this.getStatusText(); 1368 this.responseText = String.interpret(transport.responseText); 1369 this.headerJSON = this._getHeaderJSON(); 1370 } 1371 1372 if(readyState == 4) { 1373 var xml = transport.responseXML; 1374 this.responseXML = xml === undefined ? null : xml; 1375 this.responseJSON = this._getResponseJSON(); 1376 } 1377 }, 1378 1379 status: 0, 1380 statusText: '', 1381 1382 getStatus: Ajax.Request.prototype.getStatus, 1383 1384 getStatusText: function() { 1385 try { 1386 return this.transport.statusText || ''; 1387 } catch (e) { return '' } 1388 }, 1389 1390 getHeader: Ajax.Request.prototype.getHeader, 1391 1392 getAllHeaders: function() { 1393 try { 1394 return this.getAllResponseHeaders(); 1395 } catch (e) { return null } 1396 }, 1397 1398 getResponseHeader: function(name) { 1399 return this.transport.getResponseHeader(name); 1400 }, 1401 1402 getAllResponseHeaders: function() { 1403 return this.transport.getAllResponseHeaders(); 1404 }, 1405 1406 _getHeaderJSON: function() { 1407 var json = this.getHeader('X-JSON'); 1408 if (!json) return null; 1409 json = decodeURIComponent(escape(json)); 1410 try { 1411 return json.evalJSON(this.request.options.sanitizeJSON); 1412 } catch (e) { 1413 this.request.dispatchException(e); 1414 } 1415 }, 1416 1417 _getResponseJSON: function() { 1418 var options = this.request.options; 1419 if (!options.evalJSON || (options.evalJSON != 'force' && 1420 !(this.getHeader('Content-type') || '').include('application/json'))) 1421 return null; 1422 try { 1423 return this.transport.responseText.evalJSON(options.sanitizeJSON); 1424 } catch (e) { 1425 this.request.dispatchException(e); 1426 } 1427 } 1428 }); 1429 1430 Ajax.Updater = Class.create(Ajax.Request, { 1431 initialize: function($super, container, url, options) { 1170 1432 this.container = { 1171 1433 success: (container.success || container), 1172 1434 failure: (container.failure || (container.success ? null : container)) 1173 } 1174 1175 this.transport = Ajax.getTransport(); 1176 this.setOptions(options); 1177 1178 var onComplete = this.options.onComplete || Prototype.emptyFunction; 1179 this.options.onComplete = (function(transport, param) { 1180 this.updateContent(); 1181 onComplete(transport, param); 1435 }; 1436 1437 options = options || { }; 1438 var onComplete = options.onComplete; 1439 options.onComplete = (function(response, param) { 1440 this.updateContent(response.responseText); 1441 if (Object.isFunction(onComplete)) onComplete(response, param); 1182 1442 }).bind(this); 1183 1443 1184 this.request(url);1185 }, 1186 1187 updateContent: function( ) {1188 var receiver = this.container[this.success() ? 'success' : 'failure'] ;1189 var response = this.transport.responseText;1190 1191 if (! this.options.evalScripts) response = response.stripScripts();1444 $super(url, options); 1445 }, 1446 1447 updateContent: function(responseText) { 1448 var receiver = this.container[this.success() ? 'success' : 'failure'], 1449 options = this.options; 1450 1451 if (!options.evalScripts) responseText = responseText.stripScripts(); 1192 1452 1193 1453 if (receiver = $(receiver)) { 1194 if (this.options.insertion) 1195 new this.options.insertion(receiver, response); 1196 else 1197 receiver.update(response); 1454 if (options.insertion) { 1455 if (Object.isString(options.insertion)) { 1456 var insertion = { }; insertion[options.insertion] = responseText; 1457 receiver.insert(insertion); 1458 } 1459 else options.insertion(receiver, responseText); 1460 } 1461 else receiver.update(responseText); 1198 1462 } 1199 1463 1200 1464 if (this.success()) { 1201 if (this.onComplete) 1202 setTimeout(this.onComplete.bind(this), 10); 1465 if (this.onComplete) this.onComplete.bind(this).defer(); 1203 1466 } 1204 1467 } 1205 1468 }); 1206 1469 1207 Ajax.PeriodicalUpdater = Class.create(); 1208 Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { 1209 initialize: function(container, url, options) { 1210 this.setOptions(options); 1470 Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { 1471 initialize: function($super, container, url, options) { 1472 $super(options); 1211 1473 this.onComplete = this.options.onComplete; 1212 1474 … … 1214 1476 this.decay = (this.options.decay || 1); 1215 1477 1216 this.updater = { };1478 this.updater = { }; 1217 1479 this.container = container; 1218 1480 this.url = url; … … 1232 1494 }, 1233 1495 1234 updateComplete: function(re quest) {1496 updateComplete: function(response) { 1235 1497 if (this.options.decay) { 1236 this.decay = (re quest.responseText == this.lastText ?1498 this.decay = (response.responseText == this.lastText ? 1237 1499 this.decay * this.options.decay : 1); 1238 1500 1239 this.lastText = request.responseText; 1240 } 1241 this.timer = setTimeout(this.onTimerEvent.bind(this), 1242 this.decay * this.frequency * 1000); 1501 this.lastText = response.responseText; 1502 } 1503 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); 1243 1504 }, 1244 1505 … … 1253 1514 return elements; 1254 1515 } 1255 if ( typeof element == 'string')1516 if (Object.isString(element)) 1256 1517 element = document.getElementById(element); 1257 1518 return Element.extend(element); … … 1264 1525 null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 1265 1526 for (var i = 0, length = query.snapshotLength; i < length; i++) 1266 results.push( query.snapshotItem(i));1527 results.push(Element.extend(query.snapshotItem(i))); 1267 1528 return results; 1268 1529 }; 1269 1270 document.getElementsByClassName = function(className, parentElement) { 1271 var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; 1272 return document._getElementsByXPath(q, parentElement); 1273 } 1274 1275 } else document.getElementsByClassName = function(className, parentElement) { 1276 var children = ($(parentElement) || document.body).getElementsByTagName('*'); 1277 var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)"); 1278 for (var i = 0, length = children.length; i < length; i++) { 1279 child = children[i]; 1280 var elementClassName = child.className; 1281 if (elementClassName.length == 0) continue; 1282 if (elementClassName == className || elementClassName.match(pattern)) 1283 elements.push(Element.extend(child)); 1284 } 1285 return elements; 1286 }; 1530 } 1287 1531 1288 1532 /*--------------------------------------------------------------------------*/ 1289 1533 1290 if (!window.Element) var Element = {}; 1291 1292 Element.extend = function(element) { 1293 var F = Prototype.BrowserFeatures; 1294 if (!element || !element.tagName || element.nodeType == 3 || 1295 element._extended || F.SpecificElementExtensions || element == window) 1296 return element; 1297 1298 var methods = {}, tagName = element.tagName, cache = Element.extend.cache, 1299 T = Element.Methods.ByTag; 1300 1301 // extend methods for all tags (Safari doesn't need this) 1302 if (!F.ElementExtensions) { 1303 Object.extend(methods, Element.Methods), 1304 Object.extend(methods, Element.Methods.Simulated); 1305 } 1306 1307 // extend methods for specific tags 1308 if (T[tagName]) Object.extend(methods, T[tagName]); 1309 1310 for (var property in methods) { 1311 var value = methods[property]; 1312 if (typeof value == 'function' && !(property in element)) 1313 element[property] = cache.findOrStore(value); 1314 } 1315 1316 element._extended = Prototype.emptyFunction; 1317 return element; 1318 }; 1319 1320 Element.extend.cache = { 1321 findOrStore: function(value) { 1322 return this[value] = this[value] || function() { 1323 return value.apply(null, [this].concat($A(arguments))); 1324 } 1325 } 1326 }; 1534 if (!window.Node) var Node = { }; 1535 1536 if (!Node.ELEMENT_NODE) { 1537 // DOM level 2 ECMAScript Language Binding 1538 Object.extend(Node, { 1539 ELEMENT_NODE: 1, 1540 ATTRIBUTE_NODE: 2, 1541 TEXT_NODE: 3, 1542 CDATA_SECTION_NODE: 4, 1543 ENTITY_REFERENCE_NODE: 5, 1544 ENTITY_NODE: 6, 1545 PROCESSING_INSTRUCTION_NODE: 7, 1546 COMMENT_NODE: 8, 1547 DOCUMENT_NODE: 9, 1548 DOCUMENT_TYPE_NODE: 10, 1549 DOCUMENT_FRAGMENT_NODE: 11, 1550 NOTATION_NODE: 12 1551 }); 1552 } 1553 1554 (function() { 1555 var element = this.Element; 1556 this.Element = function(tagName, attributes) { 1557 attributes = attributes || { }; 1558 tagName = tagName.toLowerCase(); 1559 var cache = Element.cache; 1560 if (Prototype.Browser.IE && attributes.name) { 1561 tagName = '<' + tagName + ' name="' + attributes.name + '">'; 1562 delete attributes.name; 1563 return Element.writeAttribute(document.createElement(tagName), attributes); 1564 } 1565 if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); 1566 return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); 1567 }; 1568 Object.extend(this.Element, element || { }); 1569 }).call(window); 1570 1571 Element.cache = { }; 1327 1572 1328 1573 Element.Methods = { … … 1353 1598 }, 1354 1599 1355 update: function(element, html) { 1356 html = typeof html == 'undefined' ? '' : html.toString(); 1357 $(element).innerHTML = html.stripScripts(); 1358 setTimeout(function() {html.evalScripts()}, 10); 1600 update: function(element, content) { 1601 element = $(element); 1602 if (content && content.toElement) content = content.toElement(); 1603 if (Object.isElement(content)) return element.update().insert(content); 1604 content = Object.toHTML(content); 1605 element.innerHTML = content.stripScripts(); 1606 content.evalScripts.bind(content).defer(); 1359 1607 return element; 1360 1608 }, 1361 1609 1362 replace: function(element, html) {1610 replace: function(element, content) { 1363 1611 element = $(element); 1364 html = typeof html == 'undefined' ? '' : html.toString(); 1365 if (element.outerHTML) { 1366 element.outerHTML = html.stripScripts(); 1367 } else { 1612 if (content && content.toElement) content = content.toElement(); 1613 else if (!Object.isElement(content)) { 1614 content = Object.toHTML(content); 1368 1615 var range = element.ownerDocument.createRange(); 1369 range.selectNode Contents(element);1370 element.parentNode.replaceChild(1371 range.createContextualFragment(html.stripScripts()), element);1372 } 1373 setTimeout(function() {html.evalScripts()}, 10);1616 range.selectNode(element); 1617 content.evalScripts.bind(content).defer(); 1618 content = range.createContextualFragment(content.stripScripts()); 1619 } 1620 element.parentNode.replaceChild(content, element); 1374 1621 return element; 1622 }, 1623 1624 insert: function(element, insertions) { 1625 element = $(element); 1626 1627 if (Object.isString(insertions) || Object.isNumber(insertions) || 1628 Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) 1629 insertions = {bottom:insertions}; 1630 1631 var content, t, range; 1632 1633 for (position in insertions) { 1634 content = insertions[position]; 1635 position = position.toLowerCase(); 1636 t = Element._insertionTranslations[position]; 1637 1638 if (content && content.toElement) content = content.toElement(); 1639 if (Object.isElement(content)) { 1640 t.insert(element, content); 1641 continue; 1642 } 1643 1644 content = Object.toHTML(content); 1645 1646 range = element.ownerDocument.createRange(); 1647 t.initializeRange(element, range); 1648 t.insert(element, range.createContextualFragment(content.stripScripts())); 1649 1650 content.evalScripts.bind(content).defer(); 1651 } 1652 1653 return element; 1654 }, 1655 1656 wrap: function(element, wrapper, attributes) { 1657 element = $(element); 1658 if (Object.isElement(wrapper)) 1659 $(wrapper).writeAttribute(attributes || { }); 1660 else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); 1661 else wrapper = new Element('div', wrapper); 1662 if (element.parentNode) 1663 element.parentNode.replaceChild(wrapper, element); 1664 wrapper.appendChild(element); 1665 return wrapper; 1375 1666 }, 1376 1667 … … 1430 1721 1431 1722 match: function(element, selector) { 1432 if ( typeof selector == 'string')1723 if (Object.isString(selector)) 1433 1724 selector = new Selector(selector); 1434 1725 return selector.match($(element)); … … 1467 1758 }, 1468 1759 1469 getElementsBySelector: function() {1760 select: function() { 1470 1761 var args = $A(arguments), element = $(args.shift()); 1471 1762 return Selector.findChildElements(element, args); 1472 1763 }, 1473 1764 1474 getElementsByClassName: function(element, className) { 1475 return document.getElementsByClassName(className, element); 1765 adjacent: function() { 1766 var args = $A(arguments), element = $(args.shift()); 1767 return Selector.findChildElements(element.parentNode, args).without(element); 1768 }, 1769 1770 identify: function(element) { 1771 element = $(element); 1772 var id = element.readAttribute('id'), self = arguments.callee; 1773 if (id) return id; 1774 do { id = 'anonymous_element_' + self.counter++ } while ($(id)); 1775 element.writeAttribute('id', id); 1776 return id; 1476 1777 }, 1477 1778 … … 1479 1780 element = $(element); 1480 1781 if (Prototype.Browser.IE) { 1481 if (!element.attributes) return null; 1482 var t = Element._attributeTranslations; 1782 var t = Element._attributeTranslations.read; 1483 1783 if (t.values[name]) return t.values[name](element, name); 1484 if (t.names[name]) name = t.names[name]; 1485 var attribute = element.attributes[name]; 1486 return attribute ? attribute.nodeValue : null; 1784 if (t.names[name]) name = t.names[name]; 1785 if (name.include(':')) { 1786 return (!element.attributes || !element.attributes[name]) ? null : 1787 element.attributes[name].value; 1788 } 1487 1789 } 1488 1790 return element.getAttribute(name); 1791 }, 1792 1793 writeAttribute: function(element, name, value) { 1794 element = $(element); 1795 var attributes = { }, t = Element._attributeTranslations.write; 1796 1797 if (typeof name == 'object') attributes = name; 1798 else attributes[name] = value === undefined ? true : value; 1799 1800 for (var attr in attributes) { 1801 var name = t.names[attr] || attr, value = attributes[attr]; 1802 if (t.values[attr]) name = t.values[attr](element, value); 1803 if (value === false || value === null) 1804 element.removeAttribute(name); 1805 else if (value === true) 1806 element.setAttribute(name, name); 1807 else element.setAttribute(name, value); 1808 } 1809 return element; 1489 1810 }, 1490 1811 … … 1504 1825 if (!(element = $(element))) return; 1505 1826 var elementClassName = element.className; 1506 if (elementClassName.length == 0) return false; 1507 if (elementClassName == className || 1508 elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) 1509 return true; 1510 return false; 1827 return (elementClassName.length > 0 && (elementClassName == className || 1828 new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); 1511 1829 }, 1512 1830 1513 1831 addClassName: function(element, className) { 1514 1832 if (!(element = $(element))) return; 1515 Element.classNames(element).add(className); 1833 if (!element.hasClassName(className)) 1834 element.className += (element.className ? ' ' : '') + className; 1516 1835 return element; 1517 1836 }, … … 1519 1838 removeClassName: function(element, className) { 1520 1839 if (!(element = $(element))) return; 1521 Element.classNames(element).remove(className); 1840 element.className = element.className.replace( 1841 new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); 1522 1842 return element; 1523 1843 }, … … 1525 1845 toggleClassName: function(element, className) { 1526 1846 if (!(element = $(element))) return; 1527 Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); 1528 return element; 1529 }, 1530 1531 observe: function() { 1532 Event.observe.apply(Event, arguments); 1533 return $A(arguments).first(); 1534 }, 1535 1536 stopObserving: function() { 1537 Event.stopObserving.apply(Event, arguments); 1538 return $A(arguments).first(); 1847 return element[element.hasClassName(className) ? 1848 'removeClassName' : 'addClassName'](className); 1539 1849 }, 1540 1850 … … 1558 1868 descendantOf: function(element, ancestor) { 1559 1869 element = $(element), ancestor = $(ancestor); 1870 1871 if (element.compareDocumentPosition) 1872 return (element.compareDocumentPosition(ancestor) & 8) === 8; 1873 1874 if (element.sourceIndex && !Prototype.Browser.Opera) { 1875 var e = element.sourceIndex, a = ancestor.sourceIndex, 1876 nextAncestor = ancestor.nextSibling; 1877 if (!nextAncestor) { 1878 do { ancestor = ancestor.parentNode; } 1879 while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode); 1880 } 1881 if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex); 1882 } 1883 1560 1884 while (element = element.parentNode) 1561 1885 if (element == ancestor) return true; … … 1565 1889 scrollTo: function(element) { 1566 1890 element = $(element); 1567 var pos = Position.cumulativeOffset(element);1891 var pos = element.cumulativeOffset(); 1568 1892 window.scrollTo(pos[0], pos[1]); 1569 1893 return element; … … 1586 1910 }, 1587 1911 1588 setStyle: function(element, styles , camelized) {1912 setStyle: function(element, styles) { 1589 1913 element = $(element); 1590 var elementStyle = element.style; 1591 1914 var elementStyle = element.style, match; 1915 if (Object.isString(styles)) { 1916 element.style.cssText += ';' + styles; 1917 return styles.include('opacity') ? 1918 element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; 1919 } 1592 1920 for (var property in styles) 1593 if (property == 'opacity') element.setOpacity(styles[property]) 1921 if (property == 'opacity') element.setOpacity(styles[property]); 1594 1922 else 1595 1923 elementStyle[(property == 'float' || property == 'cssFloat') ? 1596 1924 (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : 1597 (camelized ? property : property.camelize())] = styles[property];1925 property] = styles[property]; 1598 1926 1599 1927 return element; … … 1662 1990 element = $(element); 1663 1991 if (element._overflow) return element; 1664 element._overflow = element.style.overflow|| 'auto';1665 if ( (Element.getStyle(element, 'overflow') || 'visible') != 'hidden')1992 element._overflow = Element.getStyle(element, 'overflow') || 'auto'; 1993 if (element._overflow !== 'hidden') 1666 1994 element.style.overflow = 'hidden'; 1667 1995 return element; … … 1674 2002 element._overflow = null; 1675 2003 return element; 2004 }, 2005 2006 cumulativeOffset: function(element) { 2007 var valueT = 0, valueL = 0; 2008 do { 2009 valueT += element.offsetTop || 0; 2010 valueL += element.offsetLeft || 0; 2011 element = element.offsetParent; 2012 } while (element); 2013 return Element._returnOffset(valueL, valueT); 2014 }, 2015 2016 positionedOffset: function(element) { 2017 var valueT = 0, valueL = 0; 2018 do { 2019 valueT += element.offsetTop || 0; 2020 valueL += element.offsetLeft || 0; 2021 element = element.offsetParent; 2022 if (element) { 2023 if (element.tagName == 'BODY') break; 2024 var p = Element.getStyle(element, 'position'); 2025 if (p == 'relative' || p == 'absolute') break; 2026 } 2027 } while (element); 2028 return Element._returnOffset(valueL, valueT); 2029 }, 2030 2031 absolutize: function(element) { 2032 element = $(element); 2033 if (element.getStyle('position') == 'absolute') return; 2034 // Position.prepare(); // To be done manually by Scripty when it needs it. 2035 2036 var offsets = element.positionedOffset(); 2037 var top = offsets[1]; 2038 var left = offsets[0]; 2039 var width = element.clientWidth; 2040 var height = element.clientHeight; 2041 2042 element._originalLeft = left - parseFloat(element.style.left || 0); 2043 element._originalTop = top - parseFloat(element.style.top || 0); 2044 element._originalWidth = element.style.width; 2045 element._originalHeight = element.style.height; 2046 2047 element.style.position = 'absolute'; 2048 element.style.top = top + 'px'; 2049 element.style.left = left + 'px'; 2050 element.style.width = width + 'px'; 2051 element.style.height = height + 'px'; 2052 return element; 2053 }, 2054 2055 relativize: function(element) { 2056 element = $(element); 2057 if (element.getStyle('position') == 'relative') return; 2058 // Position.prepare(); // To be done manually by Scripty when it needs it. 2059 2060 element.style.position = 'relative'; 2061 var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); 2062 var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); 2063 2064 element.style.top = top + 'px'; 2065 element.style.left = left + 'px'; 2066 element.style.height = element._originalHeight; 2067 element.style.width = element._originalWidth; 2068 return element; 2069 }, 2070 2071 cumulativeScrollOffset: function(element) { 2072 var valueT = 0, valueL = 0; 2073 do { 2074 valueT += element.scrollTop || 0; 2075 valueL += element.scrollLeft || 0; 2076 element = element.parentNode; 2077 } while (element); 2078 return Element._returnOffset(valueL, valueT); 2079 }, 2080 2081 getOffsetParent: function(element) { 2082 if (element.offsetParent) return $(element.offsetParent); 2083 if (element == document.body) return $(element); 2084 2085 while ((element = element.parentNode) && element != document.body) 2086 if (Element.getStyle(element, 'position') != 'static') 2087 return $(element); 2088 2089 return $(document.body); 2090 }, 2091 2092 viewportOffset: function(forElement) { 2093 var valueT = 0, valueL = 0; 2094 2095 var element = forElement; 2096 do { 2097 valueT += element.offsetTop || 0; 2098 valueL += element.offsetLeft || 0; 2099 2100 // Safari fix 2101 if (element.offsetParent == document.body && 2102 Element.getStyle(element, 'position') == 'absolute') break; 2103 2104 } while (element = element.offsetParent); 2105 2106 element = forElement; 2107 do { 2108 if (!Prototype.Browser.Opera || element.tagName == 'BODY') { 2109 valueT -= element.scrollTop || 0; 2110 valueL -= element.scrollLeft || 0; 2111 } 2112 } while (element = element.parentNode); 2113 2114 return Element._returnOffset(valueL, valueT); 2115 }, 2116 2117 clonePosition: function(element, source) { 2118 var options = Object.extend({ 2119 setLeft: true, 2120 setTop: true, 2121 setWidth: true, 2122 setHeight: true, 2123 offsetTop: 0, 2124 offsetLeft: 0 2125 }, arguments[2] || { }); 2126 2127 // find page position of source 2128 source = $(source); 2129 var p = source.viewportOffset(); 2130 2131 // find coordinate system to use 2132 element = $(element); 2133 var delta = [0, 0]; 2134 var parent = null; 2135 // delta [0,0] will do fine with position: fixed elements, 2136 // position:absolute needs offsetParent deltas 2137 if (Element.getStyle(element, 'position') == 'absolute') { 2138 parent = element.getOffsetParent(); 2139 delta = parent.viewportOffset(); 2140 } 2141 2142 // correct by body offsets (fixes Safari) 2143 if (parent == document.body) { 2144 delta[0] -= document.body.offsetLeft; 2145 delta[1] -= document.body.offsetTop; 2146 } 2147 2148 // set position 2149 if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; 2150 if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; 2151 if (options.setWidth) element.style.width = source.offsetWidth + 'px'; 2152 if (options.setHeight) element.style.height = source.offsetHeight + 'px'; 2153 return element; 1676 2154 } 1677 2155 }; 1678 2156 2157 Element.Methods.identify.counter = 1; 2158 1679 2159 Object.extend(Element.Methods, { 1680 childOf: Element.Methods.descendantOf,2160 getElementsBySelector: Element.Methods.select, 1681 2161 childElements: Element.Methods.immediateDescendants 1682 2162 }); 2163 2164 Element._attributeTranslations = { 2165 write: { 2166 names: { 2167 className: 'class', 2168 htmlFor: 'for' 2169 }, 2170 values: { } 2171 } 2172 }; 2173 2174 2175 if (!document.createRange || Prototype.Browser.Opera) { 2176 Element.Methods.insert = function(element, insertions) { 2177 element = $(element); 2178 2179 if (Object.isString(insertions) || Object.isNumber(insertions) || 2180 Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) 2181 insertions = { bottom: insertions }; 2182 2183 var t = Element._insertionTranslations, content, position, pos, tagName; 2184 2185 for (position in insertions) { 2186 content = insertions[position]; 2187 position = position.toLowerCase(); 2188 pos = t[position]; 2189 2190 if (content && content.toElement) content = content.toElement(); 2191 if (Object.isElement(content)) { 2192 pos.insert(element, content); 2193 continue; 2194 } 2195 2196 content = Object.toHTML(content); 2197 tagName = ((position == 'before' || position == 'after') 2198 ? element.parentNode : element).tagName.toUpperCase(); 2199 2200 if (t.tags[tagName]) { 2201 var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); 2202 if (position == 'top' || position == 'after') fragments.reverse(); 2203 fragments.each(pos.insert.curry(element)); 2204 } 2205 else element.insertAdjacentHTML(pos.adjacency, content.stripScripts()); 2206 2207 content.evalScripts.bind(content).defer(); 2208 } 2209 2210 return element; 2211 }; 2212 } 1683 2213 1684 2214 if (Prototype.Browser.Opera) { … … 1694 2224 } 1695 2225 }; 2226 Element.Methods._readAttribute = Element.Methods.readAttribute; 2227 Element.Methods.readAttribute = function(element, attribute) { 2228 if (attribute == 'title') return element.title; 2229 return Element._readAttribute(element, attribute); 2230 }; 1696 2231 } 2232 1697 2233 else if (Prototype.Browser.IE) { 2234 $w('positionedOffset getOffsetParent viewportOffset').each(function(method) { 2235 Element.Methods[method] = Element.Methods[method].wrap( 2236 function(proceed, element) { 2237 element = $(element); 2238 var position = element.getStyle('position'); 2239 if (position != 'static') return proceed(element); 2240 element.setStyle({ position: 'relative' }); 2241 var value = proceed(element); 2242 element.setStyle({ position: position }); 2243 return value; 2244 } 2245 ); 2246 }); 2247 1698 2248 Element.Methods.getStyle = function(element, style) { 1699 2249 element = $(element); … … 1710 2260 if (value == 'auto') { 1711 2261 if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) 1712 return element['offset' +style.capitalize()] + 'px';2262 return element['offset' + style.capitalize()] + 'px'; 1713 2263 return null; 1714 2264 } … … 1717 2267 1718 2268 Element.Methods.setOpacity = function(element, value) { 2269 function stripAlpha(filter){ 2270 return filter.replace(/alpha\([^\)]*\)/gi,''); 2271 } 1719 2272 element = $(element); 2273 var currentStyle = element.currentStyle; 2274 if ((currentStyle && !currentStyle.hasLayout) || 2275 (!currentStyle && element.style.zoom == 'normal')) 2276 element.style.zoom = 1; 2277 1720 2278 var filter = element.getStyle('filter'), style = element.style; 1721 2279 if (value == 1 || value === '') { 1722 style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); 2280 (filter = stripAlpha(filter)) ? 2281 style.filter = filter : style.removeAttribute('filter'); 1723 2282 return element; 1724 2283 } else if (value < 0.00001) value = 0; 1725 style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +2284 style.filter = stripAlpha(filter) + 1726 2285 'alpha(opacity=' + (value * 100) + ')'; 1727 2286 return element; 1728 2287 }; 1729 2288 1730 // IE is missing .innerHTML support for TABLE-related elements 1731 Element.Methods.update = function(element, html) { 1732 element = $(element); 1733 html = typeof html == 'undefined' ? '' : html.toString(); 1734 var tagName = element.tagName.toUpperCase(); 1735 if (['THEAD','TBODY','TR','TD'].include(tagName)) { 1736 var div = document.createElement('div'); 1737 switch (tagName) { 1738 case 'THEAD': 1739 case 'TBODY': 1740 div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>'; 1741 depth = 2; 1742 break; 1743 case 'TR': 1744 div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>'; 1745 depth = 3; 1746 break; 1747 case 'TD': 1748 div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>'; 1749 depth = 4; 1750 } 1751 $A(element.childNodes).each(function(node) { element.removeChild(node) }); 1752 depth.times(function() { div = div.firstChild }); 1753 $A(div.childNodes).each(function(node) { element.appendChild(node) }); 1754 } else { 1755 element.innerHTML = html.stripScripts(); 1756 } 1757 setTimeout(function() { html.evalScripts() }, 10); 1758 return element; 1759 } 2289 Element._attributeTranslations = { 2290 read: { 2291 names: { 2292 'class': 'className', 2293 'for': 'htmlFor' 2294 }, 2295 values: { 2296 _getAttr: function(element, attribute) { 2297 return element.getAttribute(attribute, 2); 2298 }, 2299 _getAttrNode: function(element, attribute) { 2300 var node = element.getAttributeNode(attribute); 2301 return node ? node.value : ""; 2302 }, 2303 _getEv: function(element, attribute) { 2304 var attribute = element.getAttribute(attribute); 2305 return attribute ? attribute.toString().slice(23, -2) : null; 2306 }, 2307 _flag: function(element, attribute) { 2308 return $(element).hasAttribute(attribute) ? attribute : null; 2309 }, 2310 style: function(element) { 2311 return element.style.cssText.toLowerCase(); 2312 }, 2313 title: function(element) { 2314 return element.title; 2315 } 2316 } 2317 } 2318 }; 2319 2320 Element._attributeTranslations.write = { 2321 names: Object.clone(Element._attributeTranslations.read.names), 2322 values: { 2323 checked: function(element, value) { 2324 element.checked = !!value; 2325 }, 2326 2327 style: function(element, value) { 2328 element.style.cssText = value ? value : ''; 2329 } 2330 } 2331 }; 2332 2333 Element._attributeTranslations.has = {}; 2334 2335 $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + 2336 'encType maxLength readOnly longDesc').each(function(attr) { 2337 Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; 2338 Element._attributeTranslations.has[attr.toLowerCase()] = attr; 2339 }); 2340 2341 (function(v) { 2342 Object.extend(v, { 2343 href: v._getAttr, 2344 src: v._getAttr, 2345 type: v._getAttr, 2346 action: v._getAttrNode, 2347 disabled: v._flag, 2348 checked: v._flag, 2349 readonly: v._flag, 2350 multiple: v._flag, 2351 onload: v._getEv, 2352 onunload: v._getEv, 2353 onclick: v._getEv, 2354 ondblclick: v._getEv, 2355 onmousedown: v._getEv, 2356 onmouseup: v._getEv, 2357 onmouseover: v._getEv, 2358 onmousemove: v._getEv, 2359 onmouseout: v._getEv, 2360 onfocus: v._getEv, 2361 onblur: v._getEv, 2362 onkeypress: v._getEv, 2363 onkeydown: v._getEv, 2364 onkeyup: v._getEv, 2365 onsubmit: v._getEv, 2366 onreset: v._getEv, 2367 onselect: v._getEv, 2368 onchange: v._getEv 2369 }); 2370 })(Element._attributeTranslations.read.values); 1760 2371 } 1761 else if (Prototype.Browser.Gecko) { 2372 2373 else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { 1762 2374 Element.Methods.setOpacity = function(element, value) { 1763 2375 element = $(element); … … 1768 2380 } 1769 2381 1770 Element._attributeTranslations = { 1771 names: { 1772 colspan: "colSpan", 1773 rowspan: "rowSpan", 1774 valign: "vAlign", 1775 datetime: "dateTime", 1776 accesskey: "accessKey", 1777 tabindex: "tabIndex", 1778 enctype: "encType", 1779 maxlength: "maxLength", 1780 readonly: "readOnly", 1781 longdesc: "longDesc" 1782 }, 1783 values: { 1784 _getAttr: function(element, attribute) { 1785 return element.getAttribute(attribute, 2); 1786 }, 1787 _flag: function(element, attribute) { 1788 return $(element).hasAttribute(attribute) ? attribute : null; 1789 }, 1790 style: function(element) { 1791 return element.style.cssText.toLowerCase(); 1792 }, 1793 title: function(element) { 1794 var node = element.getAttributeNode('title'); 1795 return node.specified ? node.nodeValue : null; 1796 } 1797 } 2382 else if (Prototype.Browser.WebKit) { 2383 Element.Methods.setOpacity = function(element, value) { 2384 element = $(element); 2385 element.style.opacity = (value == 1 || value === '') ? '' : 2386 (value < 0.00001) ? 0 : value; 2387 2388 if (value == 1) 2389 if(element.tagName == 'IMG' && element.width) { 2390 element.width++; element.width--; 2391 } else try { 2392 var n = document.createTextNode(' '); 2393 element.appendChild(n); 2394 element.removeChild(n); 2395 } catch (e) { } 2396 2397 return element; 2398 }; 2399 2400 // Safari returns margins on body which is incorrect if the child is absolutely 2401 // positioned. For performance reasons, redefine Position.cumulativeOffset for 2402 // KHTML/WebKit only. 2403 Element.Methods.cumulativeOffset = function(element) { 2404 var valueT = 0, valueL = 0; 2405 do { 2406 valueT += element.offsetTop || 0; 2407 valueL += element.offsetLeft || 0; 2408 if (element.offsetParent == document.body) 2409 if (Element.getStyle(element, 'position') == 'absolute') break; 2410 2411 element = element.offsetParent; 2412 } while (element); 2413 2414 return Element._returnOffset(valueL, valueT); 2415 }; 2416 } 2417 2418 if (Prototype.Browser.IE || Prototype.Browser.Opera) { 2419 // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements 2420 Element.Methods.update = function(element, content) { 2421 element = $(element); 2422 2423 if (content && content.toElement) content = content.toElement(); 2424 if (Object.isElement(content)) return element.update().insert(content); 2425 2426 content = Object.toHTML(content); 2427 var tagName = element.tagName.toUpperCase(); 2428 2429 if (tagName in Element._insertionTranslations.tags) { 2430 $A(element.childNodes).each(function(node) { element.removeChild(node) }); 2431 Element._getContentFromAnonymousElement(tagName, content.stripScripts()) 2432 .each(function(node) { element.appendChild(node) }); 2433 } 2434 else element.innerHTML = content.stripScripts(); 2435 2436 content.evalScripts.bind(content).defer(); 2437 return element; 2438 }; 2439 } 2440 2441 if (document.createElement('div').outerHTML) { 2442 Element.Methods.replace = function(element, content) { 2443 element = $(element); 2444 2445 if (content && content.toElement) content = content.toElement(); 2446 if (Object.isElement(content)) { 2447 element.parentNode.replaceChild(content, element); 2448 return element; 2449 } 2450 2451 content = Object.toHTML(content); 2452 var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); 2453 2454 if (Element._insertionTranslations.tags[tagName]) { 2455 var nextSibling = element.next(); 2456 var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); 2457 parent.removeChild(element); 2458 if (nextSibling) 2459 fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); 2460 else 2461 fragments.each(function(node) { parent.appendChild(node) }); 2462 } 2463 else element.outerHTML = content.stripScripts(); 2464 2465 content.evalScripts.bind(content).defer(); 2466 return element; 2467 }; 2468 } 2469 2470 Element._returnOffset = function(l, t) { 2471 var result = [l, t]; 2472 result.left = l; 2473 result.top = t; 2474 return result; 1798 2475 }; 1799 2476 2477 Element._getContentFromAnonymousElement = function(tagName, html) { 2478 var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; 2479 div.innerHTML = t[0] + html + t[1]; 2480 t[2].times(function() { div = div.firstChild }); 2481 return $A(div.childNodes); 2482 }; 2483 2484 Element._insertionTranslations = { 2485 before: { 2486 adjacency: 'beforeBegin', 2487 insert: function(element, node) { 2488 element.parentNode.insertBefore(node, element); 2489 }, 2490 initializeRange: function(element, range) { 2491 range.setStartBefore(element); 2492 } 2493 }, 2494 top: { 2495 adjacency: 'afterBegin', 2496 insert: function(element, node) { 2497 element.insertBefore(node, element.firstChild); 2498 }, 2499 initializeRange: function(element, range) { 2500 range.selectNodeContents(element); 2501 range.collapse(true); 2502 } 2503 }, 2504 bottom: { 2505 adjacency: 'beforeEnd', 2506 insert: function(element, node) { 2507 element.appendChild(node); 2508 } 2509 }, 2510 after: { 2511 adjacency: 'afterEnd', 2512 insert: function(element, node) { 2513 element.parentNode.insertBefore(node, element.nextSibling); 2514 }, 2515 initializeRange: function(element, range) { 2516 range.setStartAfter(element); 2517 } 2518 }, 2519 tags: { 2520 TABLE: ['<table>', '</table>', 1], 2521 TBODY: ['<table><tbody>', '</tbody></table>', 2], 2522 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], 2523 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], 2524 SELECT: ['<select>', '</select>', 1] 2525 } 2526 }; 2527 1800 2528 (function() { 1801 Object.extend(this, { 1802 href: this._getAttr, 1803 src: this._getAttr, 1804 type: this._getAttr, 1805 disabled: this._flag, 1806 checked: this._flag, 1807 readonly: this._flag, 1808 multiple: this._flag 2529 this.bottom.initializeRange = this.top.initializeRange; 2530 Object.extend(this.tags, { 2531 THEAD: this.tags.TBODY, 2532 TFOOT: this.tags.TBODY, 2533 TH: this.tags.TD 1809 2534 }); 1810 }).call(Element._ attributeTranslations.values);2535 }).call(Element._insertionTranslations); 1811 2536 1812 2537 Element.Methods.Simulated = { 1813 2538 hasAttribute: function(element, attribute) { 1814 var t = Element._attributeTranslations, node; 1815 attribute = t.names[attribute] || attribute; 1816 node = $(element).getAttributeNode(attribute); 2539 attribute = Element._attributeTranslations.has[attribute] || attribute; 2540 var node = $(element).getAttributeNode(attribute); 1817 2541 return node && node.specified; 1818 2542 } 1819 2543 }; 1820 2544 1821 Element.Methods.ByTag = { };2545 Element.Methods.ByTag = { }; 1822 2546 1823 2547 Object.extend(Element, Element.Methods); 1824 2548 1825 2549 if (!Prototype.BrowserFeatures.ElementExtensions && 1826 document.createElement('div').__proto__) {1827 window.HTMLElement = { };2550 document.createElement('div').__proto__) { 2551 window.HTMLElement = { }; 1828 2552 window.HTMLElement.prototype = document.createElement('div').__proto__; 1829 2553 Prototype.BrowserFeatures.ElementExtensions = true; 1830 2554 } 2555 2556 Element.extend = (function() { 2557 if (Prototype.BrowserFeatures.SpecificElementExtensions) 2558 return Prototype.K; 2559 2560 var Methods = { }, ByTag = Element.Methods.ByTag; 2561 2562 var extend = Object.extend(function(element) { 2563 if (!element || element._extendedByPrototype || 2564 element.nodeType != 1 || element == window) return element; 2565 2566 var methods = Object.clone(Methods), 2567 tagName = element.tagName, property, value; 2568 2569 // extend methods for specific tags 2570 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); 2571 2572 for (property in methods) { 2573 value = methods[property]; 2574 if (Object.isFunction(value) && !(property in element)) 2575 element[property] = value.methodize(); 2576 } 2577 2578 element._extendedByPrototype = Prototype.emptyFunction; 2579 return element; 2580 2581 }, { 2582 refresh: function() { 2583 // extend methods for all tags (Safari doesn't need this) 2584 if (!Prototype.BrowserFeatures.ElementExtensions) { 2585 Object.extend(Methods, Element.Methods); 2586 Object.extend(Methods, Element.Methods.Simulated); 2587 } 2588 } 2589 }); 2590 2591 extend.refresh(); 2592 return extend; 2593 })(); 1831 2594 1832 2595 Element.hasAttribute = function(element, attribute) { … … 1854 2617 } 1855 2618 1856 if (!tagName) Object.extend(Element.Methods, methods || { });2619 if (!tagName) Object.extend(Element.Methods, methods || { }); 1857 2620 else { 1858 if ( tagName.constructor == Array) tagName.each(extend);2621 if (Object.isArray(tagName)) tagName.each(extend); 1859 2622 else extend(tagName); 1860 2623 } … … 1863 2626 tagName = tagName.toUpperCase(); 1864 2627 if (!Element.Methods.ByTag[tagName]) 1865 Element.Methods.ByTag[tagName] = { };2628 Element.Methods.ByTag[tagName] = { }; 1866 2629 Object.extend(Element.Methods.ByTag[tagName], methods); 1867 2630 } … … 1869 2632 function copy(methods, destination, onlyIfAbsent) { 1870 2633 onlyIfAbsent = onlyIfAbsent || false; 1871 var cache = Element.extend.cache;1872 2634 for (var property in methods) { 1873 2635 var value = methods[property]; 2636 if (!Object.isFunction(value)) continue; 1874 2637 if (!onlyIfAbsent || !(property in destination)) 1875 destination[property] = cache.findOrStore(value);2638 destination[property] = value.methodize(); 1876 2639 } 1877 2640 } … … 1897 2660 if (window[klass]) return window[klass]; 1898 2661 1899 window[klass] = { };2662 window[klass] = { }; 1900 2663 window[klass].prototype = document.createElement(tagName).__proto__; 1901 2664 return window[klass]; … … 1910 2673 for (var tag in Element.Methods.ByTag) { 1911 2674 var klass = findDOMClass(tag); 1912 if ( typeof klass == "undefined") continue;2675 if (Object.isUndefined(klass)) continue; 1913 2676 copy(T[tag], klass.prototype); 1914 2677 } … … 1917 2680 Object.extend(Element, Element.Methods); 1918 2681 delete Element.ByTag; 2682 2683 if (Element.extend.refresh) Element.extend.refresh(); 2684 Element.cache = { }; 1919 2685 }; 1920 2686 1921 var Toggle = { display: Element.toggle }; 1922 1923 /*--------------------------------------------------------------------------*/ 1924 1925 Abstract.Insertion = function(adjacency) { 1926 this.adjacency = adjacency; 1927 } 1928 1929 Abstract.Insertion.prototype = { 1930 initialize: function(element, content) { 1931 this.element = $(element); 1932 this.content = content.stripScripts(); 1933 1934 if (this.adjacency && this.element.insertAdjacentHTML) { 1935 try { 1936 this.element.insertAdjacentHTML(this.adjacency, this.content); 1937 } catch (e) { 1938 var tagName = this.element.tagName.toUpperCase(); 1939 if (['TBODY', 'TR'].include(tagName)) { 1940 this.insertContent(this.contentFromAnonymousTable()); 1941 } else { 1942 throw e; 1943 } 1944 } 1945 } else { 1946 this.range = this.element.ownerDocument.createRange(); 1947 if (this.initializeRange) this.initializeRange(); 1948 this.insertContent([this.range.createContextualFragment(this.content)]); 1949 } 1950 1951 setTimeout(function() {content.evalScripts()}, 10); 1952 }, 1953 1954 contentFromAnonymousTable: function() { 1955 var div = document.createElement('div'); 1956 div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>'; 1957 return $A(div.childNodes[0].childNodes[0].childNodes); 1958 } 1959 } 1960 1961 var Insertion = new Object(); 1962 1963 Insertion.Before = Class.create(); 1964 Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { 1965 initializeRange: function() { 1966 this.range.setStartBefore(this.element); 1967 }, 1968 1969 insertContent: function(fragments) { 1970 fragments.each((function(fragment) { 1971 this.element.parentNode.insertBefore(fragment, this.element); 1972 }).bind(this)); 1973 } 1974 }); 1975 1976 Insertion.Top = Class.create(); 1977 Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { 1978 initializeRange: function() { 1979 this.range.selectNodeContents(this.element); 1980 this.range.collapse(true); 1981 }, 1982 1983 insertContent: function(fragments) { 1984 fragments.reverse(false).each((function(fragment) { 1985 this.element.insertBefore(fragment, this.element.firstChild); 1986 }).bind(this)); 1987 } 1988 }); 1989 1990 Insertion.Bottom = Class.create(); 1991 Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { 1992 initializeRange: function() { 1993 this.range.selectNodeContents(this.element); 1994 this.range.collapse(this.element); 1995 }, 1996 1997 insertContent: function(fragments) { 1998 fragments.each((function(fragment) { 1999 this.element.appendChild(fragment); 2000 }).bind(this)); 2001 } 2002 }); 2003 2004 Insertion.After = Class.create(); 2005 Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { 2006 initializeRange: function() { 2007 this.range.setStartAfter(this.element); 2008 }, 2009 2010 insertContent: function(fragments) { 2011 fragments.each((function(fragment) { 2012 this.element.parentNode.insertBefore(fragment, 2013 this.element.nextSibling); 2014 }).bind(this)); 2015 } 2016 }); 2017 2018 /*--------------------------------------------------------------------------*/ 2019 2020 Element.ClassNames = Class.create(); 2021 Element.ClassNames.prototype = { 2022 initialize: function(element) { 2023 this.element = $(element); 2024 }, 2025 2026 _each: function(iterator) { 2027 this.element.className.split(/\s+/).select(function(name) { 2028 return name.length > 0; 2029 })._each(iterator); 2030 }, 2031 2032 set: function(className) { 2033 this.element.className = className; 2034 }, 2035 2036 add: function(classNameToAdd) { 2037 if (this.include(classNameToAdd)) return; 2038 this.set($A(this).concat(classNameToAdd).join(' ')); 2039 }, 2040 2041 remove: function(classNameToRemove) { 2042 if (!this.include(classNameToRemove)) return; 2043 this.set($A(this).without(classNameToRemove).join(' ')); 2044 }, 2045 2046 toString: function() { 2047 return $A(this).join(' '); 2687 document.viewport = { 2688 getDimensions: function() { 2689 var dimensions = { }; 2690 $w('width height').each(function(d) { 2691 var D = d.capitalize(); 2692 dimensions[d] = self['inner' + D] || 2693 (document.documentElement['client' + D] || document.body['client' + D]); 2694 }); 2695 return dimensions; 2696 }, 2697 2698 getWidth: function() { 2699 return this.getDimensions().width; 2700 }, 2701 2702 getHeight: function() { 2703 return this.getDimensions().height; 2704 }, 2705 2706 getScrollOffsets: function() { 2707 return Element._returnOffset( 2708 window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, 2709 window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 2048 2710 } 2049 2711 }; 2050 2051 Object.extend(Element.ClassNames.prototype, Enumerable);2052 2712 /* Portions of the Selector class are derived from Jack Slocum’s DomQuery, 2053 2713 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style 2054 2714 * license. Please see http://www.yui-ext.com/ for more information. */ 2055 2715 2056 var Selector = Class.create(); 2057 2058 Selector.prototype = { 2716 var Selector = Class.create({ 2059 2717 initialize: function(expression) { 2060 2718 this.expression = expression.strip(); … … 2064 2722 compileMatcher: function() { 2065 2723 // Selectors with namespaced attributes can't use the XPath version 2066 if (Prototype.BrowserFeatures.XPath && !(/ \[[\w-]*?:/).test(this.expression))2724 if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression)) 2067 2725 return this.compileXPathMatcher(); 2068 2726 … … 2071 2729 2072 2730 if (Selector._cache[e]) { 2073 this.matcher = Selector._cache[e]; return; 2074 } 2731 this.matcher = Selector._cache[e]; 2732 return; 2733 } 2734 2075 2735 this.matcher = ["this.matcher = function(root) {", 2076 2736 "var r = root, h = Selector.handlers, c = false, n;"]; … … 2081 2741 p = ps[i]; 2082 2742 if (m = e.match(p)) { 2083 this.matcher.push( typeof c[i] == 'function'? c[i](m) :2743 this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : 2084 2744 new Template(c[i]).evaluate(m)); 2085 2745 e = e.replace(m[0], ''); … … 2096 2756 compileXPathMatcher: function() { 2097 2757 var e = this.expression, ps = Selector.patterns, 2098 x = Selector.xpath, le, 2758 x = Selector.xpath, le, m; 2099 2759 2100 2760 if (Selector._cache[e]) { … … 2107 2767 for (var i in ps) { 2108 2768 if (m = e.match(ps[i])) { 2109 this.matcher.push( typeof x[i] == 'function'? x[i](m) :2769 this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : 2110 2770 new Template(x[i]).evaluate(m)); 2111 2771 e = e.replace(m[0], ''); … … 2126 2786 2127 2787 match: function(element) { 2128 return this.findElements(document).include(element); 2788 this.tokens = []; 2789 2790 var e = this.expression, ps = Selector.patterns, as = Selector.assertions; 2791 var le, p, m; 2792 2793 while (e && le !== e && (/\S/).test(e)) { 2794 le = e; 2795 for (var i in ps) { 2796 p = ps[i]; 2797 if (m = e.match(p)) { 2798 // use the Selector.assertions methods unless the selector 2799 // is too complex. 2800 if (as[i]) { 2801 this.tokens.push([i, Object.clone(m)]); 2802 e = e.replace(m[0], ''); 2803 } else { 2804 // reluctantly do a document-wide search 2805 // and look for a match in the array 2806 return this.findElements(document).include(element); 2807 } 2808 } 2809 } 2810 } 2811 2812 var match = true, name, matches; 2813 for (var i = 0, token; token = this.tokens[i]; i++) { 2814 name = token[0], matches = token[1]; 2815 if (!Selector.assertions[name](element, matches)) { 2816 match = false; break; 2817 } 2818 } 2819 2820 return match; 2129 2821 }, 2130 2822 … … 2136 2828 return "#<Selector:" + this.expression.inspect() + ">"; 2137 2829 } 2138 } ;2830 }); 2139 2831 2140 2832 Object.extend(Selector, { 2141 _cache: { },2833 _cache: { }, 2142 2834 2143 2835 xpath: { … … 2161 2853 var h = Selector.xpath.pseudos[m[1]]; 2162 2854 if (!h) return ''; 2163 if ( typeof h === 'function') return h(m);2855 if (Object.isFunction(h)) return h(m); 2164 2856 return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); 2165 2857 }, … … 2190 2882 for (var i in p) { 2191 2883 if (m = e.match(p[i])) { 2192 v = typeof x[i] == 'function'? x[i](m) : new Template(x[i]).evaluate(m);2884 v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); 2193 2885 exclusion.push("(" + v.substring(1, v.length - 1) + ")"); 2194 2886 e = e.replace(m[0], ''); … … 2248 2940 return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); 2249 2941 }, 2250 pseudo: 2942 pseudo: function(m) { 2251 2943 if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); 2252 2944 return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); … … 2270 2962 id: /^#([\w\-\*]+)(\b|$)/, 2271 2963 className: /^\.([\w\-\*]+)(\b|$)/, 2272 pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$| \s|(?=:))/,2964 pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/, 2273 2965 attrPresence: /^\[([\w]+)\]/, 2274 attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/ 2966 attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ 2967 }, 2968 2969 // for Selector.match and Element#match 2970 assertions: { 2971 tagName: function(element, matches) { 2972 return matches[1].toUpperCase() == element.tagName.toUpperCase(); 2973 }, 2974 2975 className: function(element, matches) { 2976 return Element.hasClassName(element, matches[1]); 2977 }, 2978 2979 id: function(element, matches) { 2980 return element.id === matches[1]; 2981 }, 2982 2983 attrPresence: function(element, matches) { 2984 return Element.hasAttribute(element, matches[1]); 2985 }, 2986 2987 attr: function(element, matches) { 2988 var nodeValue = Element.readAttribute(element, matches[1]); 2989 return Selector.operators[matches[2]](nodeValue, matches[3]); 2990 } 2275 2991 }, 2276 2992 … … 2304 3020 if (reverse) { 2305 3021 for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { 2306 node = nodes[i];3022 var node = nodes[i]; 2307 3023 if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; 2308 3024 } … … 2391 3107 id: function(nodes, root, id, combinator) { 2392 3108 var targetNode = $(id), h = Selector.handlers; 2393 if (!nodes && root == document) return targetNode ? [targetNode] : []; 3109 if (!targetNode) return []; 3110 if (!nodes && root == document) return [targetNode]; 2394 3111 if (nodes) { 2395 3112 if (combinator) { … … 2431 3148 2432 3149 attrPresence: function(nodes, root, attr) { 3150 if (!nodes) nodes = root.getElementsByTagName("*"); 2433 3151 var results = []; 2434 3152 for (var i = 0, node; node = nodes[i]; i++) … … 2599 3317 2600 3318 findElement: function(elements, expression, index) { 2601 if ( typeof expression == 'number') {3319 if (Object.isNumber(expression)) { 2602 3320 index = expression; expression = false; 2603 3321 } … … 2628 3346 }, 2629 3347 2630 serializeElements: function(elements, getHash) { 2631 var data = elements.inject({}, function(result, element) { 3348 serializeElements: function(elements, options) { 3349 if (typeof options != 'object') options = { hash: !!options }; 3350 else if (options.hash === undefined) options.hash = true; 3351 var key, value, submitted = false, submit = options.submit; 3352 3353 var data = elements.inject({ }, function(result, element) { 2632 3354 if (!element.disabled && element.name) { 2633 var key = element.name, value = $(element).getValue(); 2634 if (value != null) { 2635 if (key in result) { 2636 if (result[key].constructor != Array) result[key] = [result[key]]; 3355 key = element.name; value = $(element).getValue(); 3356 if (value != null && (element.type != 'submit' || (!submitted && 3357 submit !== false && (!submit || key == submit) && (submitted = true)))) { 3358 if (key in result) { 3359 // a key is already present; construct an array of values 3360 if (!Object.isArray(result[key])) result[key] = [result[key]]; 2637 3361 result[key].push(value); 2638 3362 } … … 2643 3367 }); 2644 3368 2645 return getHash ? data : Hash.toQueryString(data);3369 return options.hash ? data : Object.toQueryString(data); 2646 3370 } 2647 3371 }; 2648 3372 2649 3373 Form.Methods = { 2650 serialize: function(form, getHash) {2651 return Form.serializeElements(Form.getElements(form), getHash);3374 serialize: function(form, options) { 3375 return Form.serializeElements(Form.getElements(form), options); 2652 3376 }, 2653 3377 … … 2691 3415 2692 3416 findFirstElement: function(form) { 2693 return $(form).getElements().find(function(element) { 2694 return element.type != 'hidden' && !element.disabled && 2695 ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); 3417 var elements = $(form).getElements().findAll(function(element) { 3418 return 'hidden' != element.type && !element.disabled; 3419 }); 3420 var firstByIndex = elements.findAll(function(element) { 3421 return element.hasAttribute('tabIndex') && element.tabIndex >= 0; 3422 }).sortBy(function(element) { return element.tabIndex }).first(); 3423 3424 return firstByIndex ? firstByIndex : elements.find(function(element) { 3425 return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); 2696 3426 }); 2697 3427 }, … … 2704 3434 2705 3435 request: function(form, options) { 2706 form = $(form), options = Object.clone(options || {}); 2707 2708 var params = options.parameters; 3436 form = $(form), options = Object.clone(options || { }); 3437 3438 var params = options.parameters, action = form.readAttribute('action') || ''; 3439 if (action.blank()) action = window.location.href; 2709 3440 options.parameters = form.serialize(true); 2710 3441 2711 3442 if (params) { 2712 if ( typeof params == 'string') params = params.toQueryParams();3443 if (Object.isString(params)) params = params.toQueryParams(); 2713 3444 Object.extend(options.parameters, params); 2714 3445 } … … 2717 3448 options.method = form.method; 2718 3449 2719 return new Ajax.Request( form.readAttribute('action'), options);2720 } 2721 } 3450 return new Ajax.Request(action, options); 3451 } 3452 }; 2722 3453 2723 3454 /*--------------------------------------------------------------------------*/ … … 2733 3464 return element; 2734 3465 } 2735 } 3466 }; 2736 3467 2737 3468 Form.Element.Methods = { … … 2741 3472 var value = element.getValue(); 2742 3473 if (value != undefined) { 2743 var pair = { };3474 var pair = { }; 2744 3475 pair[element.name] = value; 2745 return Hash.toQueryString(pair);3476 return Object.toQueryString(pair); 2746 3477 } 2747 3478 } … … 2753 3484 var method = element.tagName.toLowerCase(); 2754 3485 return Form.Element.Serializers[method](element); 3486 }, 3487 3488 setValue: function(element, value) { 3489 element = $(element); 3490 var method = element.tagName.toLowerCase(); 3491 Form.Element.Serializers[method](element, value); 3492 return element; 2755 3493 }, 2756 3494 … … 2769 3507 element.focus(); 2770 3508 if (element.select && (element.tagName.toLowerCase() != 'input' || 2771 !['button', 'reset', 'submit'].include(element.type)))3509 !['button', 'reset', 'submit'].include(element.type))) 2772 3510 element.select(); 2773 } catch (e) { }3511 } catch (e) { } 2774 3512 return element; 2775 3513 }, … … 2787 3525 return element; 2788 3526 } 2789 } 3527 }; 2790 3528 2791 3529 /*--------------------------------------------------------------------------*/ … … 2797 3535 2798 3536 Form.Element.Serializers = { 2799 input: function(element ) {3537 input: function(element, value) { 2800 3538 switch (element.type.toLowerCase()) { 2801 3539 case 'checkbox': 2802 3540 case 'radio': 2803 return Form.Element.Serializers.inputSelector(element );3541 return Form.Element.Serializers.inputSelector(element, value); 2804 3542 default: 2805 return Form.Element.Serializers.textarea(element); 2806 } 2807 }, 2808 2809 inputSelector: function(element) { 2810 return element.checked ? element.value : null; 2811 }, 2812 2813 textarea: function(element) { 2814 return element.value; 2815 }, 2816 2817 select: function(element) { 2818 return this[element.type == 'select-one' ? 2819 'selectOne' : 'selectMany'](element); 3543 return Form.Element.Serializers.textarea(element, value); 3544 } 3545 }, 3546 3547 inputSelector: function(element, value) { 3548 if (value === undefined) return element.checked ? element.value : null; 3549 else element.checked = !!value; 3550 }, 3551 3552 textarea: function(element, value) { 3553 if (value === undefined) return element.value; 3554 else element.value = value; 3555 }, 3556 3557 select: function(element, index) { 3558 if (index === undefined) 3559 return this[element.type == 'select-one' ? 3560 'selectOne' : 'selectMany'](element); 3561 else { 3562 var opt, value, single = !Object.isArray(index); 3563 for (var i = 0, length = element.length; i < length; i++) { 3564 opt = element.options[i]; 3565 value = this.optionValue(opt); 3566 if (single) { 3567 if (value == index) { 3568 opt.selected = true; 3569 return; 3570 } 3571 } 3572 else opt.selected = index.include(value); 3573 } 3574 } 2820 3575 }, 2821 3576 … … 2840 3595 return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; 2841 3596 } 2842 } 3597 }; 2843 3598 2844 3599 /*--------------------------------------------------------------------------*/ 2845 3600 2846 Abstract.TimedObserver = function() {} 2847 Abstract.TimedObserver.prototype = { 2848 initialize: function(element, frequency, callback) { 2849 this.frequency = frequency; 3601 Abstract.TimedObserver = Class.create(PeriodicalExecuter, { 3602 initialize: function($super, element, frequency, callback) { 3603 $super(callback, frequency); 2850 3604 this.element = $(element); 2851 this.callback = callback;2852 2853 3605 this.lastValue = this.getValue(); 2854 this.registerCallback(); 2855 }, 2856 2857 registerCallback: function() { 2858 setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 2859 }, 2860 2861 onTimerEvent: function() { 3606 }, 3607 3608 execute: function() { 2862 3609 var value = this.getValue(); 2863 var changed = ('string' == typeof this.lastValue && 'string' == typeof value 2864 ? this.lastValue != value : String(this.lastValue) != String(value)); 2865 if (changed) { 3610 if (Object.isString(this.lastValue) && Object.isString(value) ? 3611 this.lastValue != value : String(this.lastValue) != String(value)) { 2866 3612 this.callback(this.element, value); 2867 3613 this.lastValue = value; 2868 3614 } 2869 3615 } 2870 } 2871 2872 Form.Element.Observer = Class.create(); 2873 Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { 3616 }); 3617 3618 Form.Element.Observer = Class.create(Abstract.TimedObserver, { 2874 3619 getValue: function() { 2875 3620 return Form.Element.getValue(this.element); … … 2877 3622 }); 2878 3623 2879 Form.Observer = Class.create(); 2880 Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { 3624 Form.Observer = Class.create(Abstract.TimedObserver, { 2881 3625 getValue: function() { 2882 3626 return Form.serialize(this.element); … … 2886 3630 /*--------------------------------------------------------------------------*/ 2887 3631 2888 Abstract.EventObserver = function() {} 2889 Abstract.EventObserver.prototype = { 3632 Abstract.EventObserver = Class.create({ 2890 3633 initialize: function(element, callback) { 2891 3634 this.element = $(element); … … 2908 3651 2909 3652 registerFormCallbacks: function() { 2910 Form.getElements(this.element).each(this.registerCallback .bind(this));3653 Form.getElements(this.element).each(this.registerCallback, this); 2911 3654 }, 2912 3655 … … 2924 3667 } 2925 3668 } 2926 } 2927 2928 Form.Element.EventObserver = Class.create(); 2929 Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { 3669 }); 3670 3671 Form.Element.EventObserver = Class.create(Abstract.EventObserver, { 2930 3672 getValue: function() { 2931 3673 return Form.Element.getValue(this.element); … … 2933 3675 }); 2934 3676 2935 Form.EventObserver = Class.create(); 2936 Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { 3677 Form.EventObserver = Class.create(Abstract.EventObserver, { 2937 3678 getValue: function() { 2938 3679 return Form.serialize(this.element); 2939 3680 } 2940 3681 }); 2941 if (!window.Event) { 2942 var Event = new Object(); 2943 } 3682 if (!window.Event) var Event = { }; 2944 3683 2945 3684 Object.extend(Event, { … … 2957 3696 KEY_PAGEUP: 33, 2958 3697 KEY_PAGEDOWN: 34, 2959 2960 element: function(event) { 2961 return $(event.target || event.srcElement); 2962 }, 2963 2964 isLeftClick: function(event) { 2965 return (((event.which) && (event.which == 1)) || 2966 ((event.button) && (event.button == 1))); 2967 }, 2968 2969 pointerX: function(event) { 2970 return event.pageX || (event.clientX + 2971 (document.documentElement.scrollLeft || document.body.scrollLeft)); 2972 }, 2973 2974 pointerY: function(event) { 2975 return event.pageY || (event.clientY + 2976 (document.documentElement.scrollTop || document.body.scrollTop)); 2977 }, 2978 2979 stop: function(event) { 2980 if (event.preventDefault) { 3698 KEY_INSERT: 45, 3699 3700 cache: { }, 3701 3702 relatedTarget: function(event) { 3703 var element; 3704 switch(event.type) { 3705 case 'mouseover': element = event.fromElement; break; 3706 case 'mouseout': element = event.toElement; break; 3707 default: return null; 3708 } 3709 return Element.extend(element); 3710 } 3711 }); 3712 3713 Event.Methods = (function() { 3714 var isButton; 3715 3716 if (Prototype.Browser.IE) { 3717 var buttonMap = { 0: 1, 1: 4, 2: 2 }; 3718 isButton = function(event, code) { 3719 return event.button == buttonMap[code]; 3720 }; 3721 3722 } else if (Prototype.Browser.WebKit) { 3723 isButton = function(event, code) { 3724 switch (code) { 3725 case 0: return event.which == 1 && !event.metaKey; 3726 case 1: return event.which == 1 && event.metaKey; 3727 default: return false; 3728 } 3729 }; 3730 3731 } else { 3732 isButton = function(event, code) { 3733 return event.which ? (event.which === code + 1) : (event.button === code); 3734 }; 3735 } 3736 3737 return { 3738 isLeftClick: function(event) { return isButton(event, 0) }, 3739 isMiddleClick: function(event) { return isButton(event, 1) }, 3740 isRightClick: function(event) { return isButton(event, 2) }, 3741 3742 element: function(event) { 3743 var node = Event.extend(event).target; 3744 return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node); 3745 }, 3746 3747 findElement: function(event, expression) { 3748 var element = Event.element(event); 3749 return element.match(expression) ? element : element.up(expression); 3750 }, 3751 3752 pointer: function(event) { 3753 return { 3754 x: event.pageX || (event.clientX + 3755 (document.documentElement.scrollLeft || document.body.scrollLeft)), 3756 y: event.pageY || (event.clientY + 3757 (document.documentElement.scrollTop || document.body.scrollTop)) 3758 }; 3759 }, 3760 3761 pointerX: function(event) { return Event.pointer(event).x }, 3762 pointerY: function(event) { return Event.pointer(event).y }, 3763 3764 stop: function(event) { 3765 Event.extend(event); 2981 3766 event.preventDefault(); 2982 3767 event.stopPropagation(); 3768 event.stopped = true; 3769 } 3770 }; 3771 })(); 3772 3773 Event.extend = (function() { 3774 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { 3775 m[name] = Event.Methods[name].methodize(); 3776 return m; 3777 }); 3778 3779 if (Prototype.Browser.IE) { 3780 Object.extend(methods, { 3781 stopPropagation: function() { this.cancelBubble = true }, 3782 preventDefault: function() { this.returnValue = false }, 3783 inspect: function() { return "[object Event]" } 3784 }); 3785 3786 return function(event) { 3787 if (!event) return false; 3788 if (event._extendedByPrototype) return event; 3789 3790 event._extendedByPrototype = Prototype.emptyFunction; 3791 var pointer = Event.pointer(event); 3792 Object.extend(event, { 3793 target: event.srcElement, 3794 relatedTarget: Event.relatedTarget(event), 3795 pageX: pointer.x, 3796 pageY: pointer.y 3797 }); 3798 return Object.extend(event, methods); 3799 }; 3800 3801 } else { 3802 Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__; 3803 Object.extend(Event.prototype, methods); 3804 return Prototype.K; 3805 } 3806 })(); 3807 3808 Object.extend(Event, (function() { 3809 var cache = Event.cache; 3810 3811 function getEventID(element) { 3812 if (element._eventID) return element._eventID; 3813 arguments.callee.id = arguments.callee.id || 1; 3814 return element._eventID = ++arguments.callee.id; 3815 } 3816 3817 function getDOMEventName(eventName) { 3818 if (eventName && eventName.include(':')) return "dataavailable"; 3819 return eventName; 3820 } 3821 3822 function getCacheForID(id) { 3823 return cache[id] = cache[id] || { }; 3824 } 3825 3826 function getWrappersForEventName(id, eventName) { 3827 var c = getCacheForID(id); 3828 return c[eventName] = c[eventName] || []; 3829 } 3830 3831 function createWrapper(element, eventName, handler) { 3832 var id = getEventID(element); 3833 var c = getWrappersForEventName(id, eventName); 3834 if (c.pluck("handler").include(handler)) return false; 3835 3836 var wrapper = function(event) { 3837 if (!Event || !Event.extend || 3838 (event.eventName && event.eventName != eventName)) 3839 return false; 3840 3841 Event.extend(event); 3842 handler.call(element, event) 3843 }; 3844 3845 wrapper.handler = handler; 3846 c.push(wrapper); 3847 return wrapper; 3848 } 3849 3850 function findWrapper(id, eventName, handler) { 3851 var c = getWrappersForEventName(id, eventName); 3852 return c.find(function(wrapper) { return wrapper.handler == handler }); 3853 } 3854 3855 function destroyWrapper(id, eventName, handler) { 3856 var c = getCacheForID(id); 3857 if (!c[eventName]) return false; 3858 c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); 3859 } 3860 3861 function destroyCache() { 3862 for (var id in cache) 3863 for (var eventName in cache[id]) 3864 cache[id][eventName] = null; 3865 } 3866 3867 if (window.attachEvent) { 3868 window.attachEvent("onunload", destroyCache); 3869 } 3870 3871 return { 3872 observe: function(element, eventName, handler) { 3873 element = $(element); 3874 var name = getDOMEventName(eventName); 3875 3876 var wrapper = createWrapper(element, eventName, handler); 3877 if (!wrapper) return element; 3878 3879 if (element.addEventListener) { 3880 element.addEventListener(name, wrapper, false); 3881 } else { 3882 element.attachEvent("on" + name, wrapper); 3883 } 3884 3885 return element; 3886 }, 3887 3888 stopObserving: function(element, eventName, handler) { 3889 element = $(element); 3890 var id = getEventID(element), name = getDOMEventName(eventName); 3891 3892 if (!handler && eventName) { 3893 getWrappersForEventName(id, eventName).each(function(wrapper) { 3894 element.stopObserving(eventName, wrapper.handler); 3895 }); 3896 return element; 3897 3898 } else if (!eventName) { 3899 Object.keys(getCacheForID(id)).each(function(eventName) { 3900 element.stopObserving(eventName); 3901 }); 3902 return element; 3903 } 3904 3905 var wrapper = findWrapper(id, eventName, handler); 3906 if (!wrapper) return element; 3907 3908 if (element.removeEventListener) { 3909 element.removeEventListener(name, wrapper, false); 3910 } else { 3911 element.detachEvent("on" + name, wrapper); 3912 } 3913 3914 destroyWrapper(id, eventName, handler); 3915 3916 return element; 3917 }, 3918 3919 fire: function(element, eventName, memo) { 3920 element = $(element); 3921 if (element == document && document.createEvent && !element.dispatchEvent) 3922 element = document.documentElement; 3923 3924 if (document.createEvent) { 3925 var event = document.createEvent("HTMLEvents"); 3926 event.initEvent("dataavailable", true, true); 3927 } else { 3928 var event = document.createEventObject(); 3929 event.eventType = "ondataavailable"; 3930 } 3931 3932 event.eventName = eventName; 3933 event.memo = memo || { }; 3934 3935 if (document.createEvent) { 3936 element.dispatchEvent(event); 3937 } else { 3938 element.fireEvent(event.eventType, event); 3939 } 3940 3941 return event; 3942 } 3943 }; 3944 })()); 3945 3946 Object.extend(Event, Event.Methods); 3947 3948 Element.addMethods({ 3949 fire: Event.fire, 3950 observe: Event.observe, 3951 stopObserving: Event.stopObserving 3952 }); 3953 3954 Object.extend(document, { 3955 fire: Element.Methods.fire.methodize(), 3956 observe: Element.Methods.observe.methodize(), 3957 stopObserving: Element.Methods.stopObserving.methodize() 3958 }); 3959 3960 (function() { 3961 /* Support for the DOMContentLoaded event is based on work by Dan Webb, 3962 Matthias Miller, Dean Edwards and John Resig. */ 3963 3964 var timer, fired = false; 3965 3966 function fireContentLoadedEvent() { 3967 if (fired) return; 3968 if (timer) window.clearInterval(timer); 3969 document.fire("dom:loaded"); 3970 fired = true; 3971 } 3972 3973 if (document.addEventListener) { 3974 if (Prototype.Browser.WebKit) { 3975 timer = window.setInterval(function() { 3976 if (/loaded|complete/.test(document.readyState)) 3977 fireContentLoadedEvent(); 3978 }, 0); 3979 3980 Event.observe(window, "load", fireContentLoadedEvent); 3981 2983 3982 } else { 2984 event.returnValue = false; 2985 event.cancelBubble = true; 2986 } 2987 }, 2988 2989 // find the first node with the given tagName, starting from the 2990 // node the event was triggered on; traverses the DOM upwards 2991 findElement: function(event, tagName) { 2992 var element = Event.element(event); 2993 while (element.parentNode && (!element.tagName || 2994 (element.tagName.toUpperCase() != tagName.toUpperCase()))) 2995 element = element.parentNode; 2996 return element; 2997 }, 2998 2999 observers: false, 3000 3001 _observeAndCache: function(element, name, observer, useCapture) { 3002 if (!this.observers) this.observers = []; 3003 if (element.addEventListener) { 3004 this.observers.push([element, name, observer, useCapture]); 3005 element.addEventListener(name, observer, useCapture); 3006 } else if (element.attachEvent) { 3007 this.observers.push([element, name, observer, useCapture]); 3008 element.attachEvent('on' + name, observer); 3009 } 3010 }, 3011 3012 unloadCache: function() { 3013 if (!Event.observers) return; 3014 for (var i = 0, length = Event.observers.length; i < length; i++) { 3015 Event.stopObserving.apply(this, Event.observers[i]); 3016 Event.observers[i][0] = null; 3017 } 3018 Event.observers = false; 3019 }, 3020 3021 observe: function(element, name, observer, useCapture) { 3022 element = $(element); 3023 useCapture = useCapture || false; 3024 3025 if (name == 'keypress' && 3026 (Prototype.Browser.WebKit || element.attachEvent)) 3027 name = 'keydown'; 3028 3029 Event._observeAndCache(element, name, observer, useCapture); 3030 }, 3031 3032 stopObserving: function(element, name, observer, useCapture) { 3033 element = $(element); 3034 useCapture = useCapture || false; 3035 3036 if (name == 'keypress' && 3037 (Prototype.Browser.WebKit || element.attachEvent)) 3038 name = 'keydown'; 3039 3040 if (element.removeEventListener) { 3041 element.removeEventListener(name, observer, useCapture); 3042 } else if (element.detachEvent) { 3043 try { 3044 element.detachEvent('on' + name, observer); 3045 } catch (e) {} 3046 } 3047 } 3048 }); 3049 3050 /* prevent memory leaks in IE */ 3051 if (Prototype.Browser.IE) 3052 Event.observe(window, 'unload', Event.unloadCache, false); 3983 document.addEventListener("DOMContentLoaded", 3984 fireContentLoadedEvent, false); 3985 } 3986 3987 } else { 3988 document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>"); 3989 $("__onDOMContentLoaded").onreadystatechange = function() { 3990 if (this.readyState == "complete") { 3991 this.onreadystatechange = null; 3992 fireContentLoadedEvent(); 3993 } 3994 }; 3995 } 3996 })(); 3997 /*------------------------------- DEPRECATED -------------------------------*/ 3998 3999 Hash.toQueryString = Object.toQueryString; 4000 4001 var Toggle = { display: Element.toggle }; 4002 4003 Element.Methods.childOf = Element.Methods.descendantOf; 4004 4005 var Insertion = { 4006 Before: function(element, content) { 4007 return Element.insert(element, {before:content}); 4008 }, 4009 4010 Top: function(element, content) { 4011 return Element.insert(element, {top:content}); 4012 }, 4013 4014 Bottom: function(element, content) { 4015 return Element.insert(element, {bottom:content}); 4016 }, 4017 4018 After: function(element, content) { 4019 return Element.insert(element, {after:content}); 4020 } 4021 }; 4022 4023 var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); 4024 4025 // This should be moved to script.aculo.us; notice the deprecated methods 4026 // further below, that map to the newer Element methods. 3053 4027 var Position = { 3054 4028 // set to true if needed, warning: firefox performance problems … … 3070 4044 }, 3071 4045 3072 realOffset: function(element) {3073 var valueT = 0, valueL = 0;3074 do {3075 valueT += element.scrollTop || 0;3076 valueL += element.scrollLeft || 0;3077 element = element.parentNode;3078 } while (element);3079 return [valueL, valueT];3080 },3081 3082 cumulativeOffset: function(element) {3083 var valueT = 0, valueL = 0;3084 do {3085 valueT += element.offsetTop || 0;3086 valueL += element.offsetLeft || 0;3087 element = element.offsetParent;3088 } while (element);3089 return [valueL, valueT];3090 },3091 3092 positionedOffset: function(element) {3093 var valueT = 0, valueL = 0;3094 do {3095 valueT += element.offsetTop || 0;3096 valueL += element.offsetLeft || 0;3097 element = element.offsetParent;3098 if (element) {3099 if(element.tagName=='BODY') break;3100 var p = Element.getStyle(element, 'position');3101 if (p == 'relative' || p == 'absolute') break;3102 }3103 } while (element);3104 return [valueL, valueT];3105 },3106 3107 offsetParent: function(element) {3108 if (element.offsetParent) return element.offsetParent;3109 if (element == document.body) return element;3110 3111 while ((element = element.parentNode) && element != document.body)3112 if (Element.getStyle(element, 'position') != 'static')3113 return element;3114 3115 return document.body;3116 },3117 3118 4046 // caches x/y coordinate pair to use with overlap 3119 4047 within: function(element, x, y) { … … 3122 4050 this.xcomp = x; 3123 4051 this.ycomp = y; 3124 this.offset = this.cumulativeOffset(element);4052 this.offset = Element.cumulativeOffset(element); 3125 4053 3126 4054 return (y >= this.offset[1] && … … 3131 4059 3132 4060 withinIncludingScrolloffsets: function(element, x, y) { 3133 var offsetcache = this.realOffset(element);4061 var offsetcache = Element.cumulativeScrollOffset(element); 3134 4062 3135 4063 this.xcomp = x + offsetcache[0] - this.deltaX; 3136 4064 this.ycomp = y + offsetcache[1] - this.deltaY; 3137 this.offset = this.cumulativeOffset(element);4065 this.offset = Element.cumulativeOffset(element); 3138 4066 3139 4067 return (this.ycomp >= this.offset[1] && … … 3154 4082 }, 3155 4083 3156 page: function(forElement) { 3157 var valueT = 0, valueL = 0; 3158 3159 var element = forElement; 3160 do { 3161 valueT += element.offsetTop || 0; 3162 valueL += element.offsetLeft || 0; 3163 3164 // Safari fix 3165 if (element.offsetParent == document.body) 3166 if (Element.getStyle(element,'position')=='absolute') break; 3167 3168 } while (element = element.offsetParent); 3169 3170 element = forElement; 3171 do { 3172 if (!window.opera || element.tagName=='BODY') { 3173 valueT -= element.scrollTop || 0; 3174 valueL -= element.scrollLeft || 0; 3175 } 3176 } while (element = element.parentNode); 3177 3178 return [valueL, valueT]; 3179 }, 3180 3181 clone: function(source, target) { 3182 var options = Object.extend({ 3183 setLeft: true, 3184 setTop: true, 3185 setWidth: true, 3186 setHeight: true, 3187 offsetTop: 0, 3188 offsetLeft: 0 3189 }, arguments[2] || {}) 3190 3191 // find page position of source 3192 source = $(source); 3193 var p = Position.page(source); 3194 3195 // find coordinate system to use 3196 target = $(target); 3197 var delta = [0, 0]; 3198 var parent = null; 3199 // delta [0,0] will do fine with position: fixed elements, 3200 // position:absolute needs offsetParent deltas 3201 if (Element.getStyle(target,'position') == 'absolute') { 3202 parent = Position.offsetParent(target); 3203 delta = Position.page(parent); 3204 } 3205 3206 // correct by body offsets (fixes Safari) 3207 if (parent == document.body) { 3208 delta[0] -= document.body.offsetLeft; 3209 delta[1] -= document.body.offsetTop; 3210 } 3211 3212 // set position 3213 if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; 3214 if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; 3215 if(options.setWidth) target.style.width = source.offsetWidth + 'px'; 3216 if(options.setHeight) target.style.height = source.offsetHeight + 'px'; 3217 }, 4084 // Deprecation layer -- use newer Element methods now (1.5.2). 4085 4086 cumulativeOffset: Element.Methods.cumulativeOffset, 4087 4088 positionedOffset: Element.Methods.positionedOffset, 3218 4089 3219 4090 absolutize: function(element) { 3220 element = $(element);3221 if (element.style.position == 'absolute') return;3222 4091 Position.prepare(); 3223 3224 var offsets = Position.positionedOffset(element); 3225 var top = offsets[1]; 3226 var left = offsets[0]; 3227 var width = element.clientWidth; 3228 var height = element.clientHeight; 3229 3230 element._originalLeft = left - parseFloat(element.style.left || 0); 3231 element._originalTop = top - parseFloat(element.style.top || 0); 3232 element._originalWidth = element.style.width; 3233 element._originalHeight = element.style.height; 3234 3235 element.style.position = 'absolute'; 3236 element.style.top = top + 'px'; 3237 element.style.left = left + 'px'; 3238 element.style.width = width + 'px'; 3239 element.style.height = height + 'px'; 4092 return Element.absolutize(element); 3240 4093 }, 3241 4094 3242 4095 relativize: function(element) { 3243 element = $(element);3244 if (element.style.position == 'relative') return;3245 4096 Position.prepare(); 3246 3247 element.style.position = 'relative'; 3248 var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); 3249 var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); 3250 3251 element.style.top = top + 'px'; 3252 element.style.left = left + 'px'; 3253 element.style.height = element._originalHeight; 3254 element.style.width = element._originalWidth; 3255 } 3256 } 3257 3258 // Safari returns margins on body which is incorrect if the child is absolutely 3259 // positioned. For performance reasons, redefine Position.cumulativeOffset for 3260 // KHTML/WebKit only. 3261 if (Prototype.Browser.WebKit) { 3262 Position.cumulativeOffset = function(element) { 3263 var valueT = 0, valueL = 0; 3264 do { 3265 valueT += element.offsetTop || 0; 3266 valueL += element.offsetLeft || 0; 3267 if (element.offsetParent == document.body) 3268 if (Element.getStyle(element, 'position') == 'absolute') break; 3269 3270 element = element.offsetParent; 3271 } while (element); 3272 3273 return [valueL, valueT]; 3274 } 3275 } 4097 return Element.relativize(element); 4098 }, 4099 4100 realOffset: Element.Methods.cumulativeScrollOffset, 4101 4102 offsetParent: Element.Methods.getOffsetParent, 4103 4104 page: Element.Methods.viewportOffset, 4105 4106 clone: function(source, target, options) { 4107 options = options || { }; 4108 return Element.clonePosition(target, source, options); 4109 } 4110 }; 4111 4112 /*--------------------------------------------------------------------------*/ 4113 4114 if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ 4115 function iter(name) { 4116 return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; 4117 } 4118 4119 instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? 4120 function(element, className) { 4121 className = className.toString().strip(); 4122 var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); 4123 return cond ? document._getElementsByXPath('.//*' + cond, element) : []; 4124 } : function(element, className) { 4125 className = className.toString().strip(); 4126 var elements = [], classNames = (/\s/.test(className) ? $w(className) : null); 4127 if (!classNames && !className) return elements; 4128 4129 var nodes = $(element).getElementsByTagName('*'); 4130 className = ' ' + className + ' '; 4131 4132 for (var i = 0, child, cn; child = nodes[i]; i++) { 4133 if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || 4134 (classNames && classNames.all(function(name) { 4135 return !name.toString().blank() && cn.include(' ' + name + ' '); 4136 })))) 4137 elements.push(Element.extend(child)); 4138 } 4139 return elements; 4140 }; 4141 4142 return function(className, parentElement) { 4143 return $(parentElement || document.body).getElementsByClassName(className); 4144 }; 4145 }(Element.Methods); 4146 4147 /*--------------------------------------------------------------------------*/ 4148 4149 Element.ClassNames = Class.create(); 4150 Element.ClassNames.prototype = { 4151 initialize: function(element) { 4152 this.element = $(element); 4153 }, 4154 4155 _each: function(iterator) { 4156 this.element.className.split(/\s+/).select(function(name) { 4157 return name.length > 0; 4158 })._each(iterator); 4159 }, 4160 4161 set: function(className) { 4162 this.element.className = className; 4163 }, 4164 4165 add: function(classNameToAdd) { 4166 if (this.include(classNameToAdd)) return; 4167 this.set($A(this).concat(classNameToAdd).join(' ')); 4168 }, 4169 4170 remove: function(classNameToRemove) { 4171 if (!this.include(classNameToRemove)) return; 4172 this.set($A(this).without(classNameToRemove).join(' ')); 4173 }, 4174 4175 toString: function() { 4176 return $A(this).join(' '); 4177 } 4178 }; 4179 4180 Object.extend(Element.ClassNames.prototype, Enumerable); 4181 4182 /*--------------------------------------------------------------------------*/ 3276 4183 3277 4184 Element.addMethods(); -
trunk/wp-includes/js/scriptaculous/builder.js
r5792 r6512 1 // script.aculo.us builder.js v1. 7.1_beta3, Fri May 25 17:19:41 +0200 20071 // script.aculo.us builder.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 2 2 3 3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -
trunk/wp-includes/js/scriptaculous/controls.js
r5792 r6512 1 // script.aculo.us controls.js v1. 7.1_beta3, Fri May 25 17:19:41 +0200 20071 // script.aculo.us controls.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 2 2 3 3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) … … 40 40 throw("controls.js requires including script.aculo.us' effects.js library"); 41 41 42 var Autocompleter = {} 43 Autocompleter.Base = function() {}; 44 Autocompleter.Base.prototype = { 42 var Autocompleter = { } 43 Autocompleter.Base = Class.create({ 45 44 baseInitialize: function(element, update, options) { 46 45 element = $(element) … … 52 51 this.index = 0; 53 52 this.entryCount = 0; 53 this.oldElementValue = this.element.value; 54 54 55 55 if(this.setOptions) 56 56 this.setOptions(options); 57 57 else 58 this.options = options || { };58 this.options = options || { }; 59 59 60 60 this.options.paramName = this.options.paramName || this.element.name; … … 78 78 if(typeof(this.options.tokens) == 'string') 79 79 this.options.tokens = new Array(this.options.tokens); 80 // Force carriage returns as token delimiters anyway 81 if (!this.options.tokens.include('\n')) 82 this.options.tokens.push('\n'); 80 83 81 84 this.observer = null; … … 87 90 Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this)); 88 91 Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this)); 89 90 // Turn autocomplete back on when the user leaves the page, so that the91 // field's value will be remembered on Mozilla-based browsers.92 Event.observe(window, 'beforeunload', function(){93 element.setAttribute('autocomplete', 'on');94 });95 92 }, 96 93 … … 246 243 var value = ''; 247 244 if (this.options.select) { 248 var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];245 var nodes = $(selectedElement).select('.' + this.options.select) || []; 249 246 if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); 250 247 } else 251 248 value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); 252 249 253 var lastTokenPos = this.findLastToken();254 if ( lastTokenPos!= -1) {255 var newValue = this.element.value.substr(0, lastTokenPos + 1);256 var whitespace = this.element.value.substr( lastTokenPos + 1).match(/^\s+/);250 var bounds = this.getTokenBounds(); 251 if (bounds[0] != -1) { 252 var newValue = this.element.value.substr(0, bounds[0]); 253 var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); 257 254 if (whitespace) 258 255 newValue += whitespace[0]; 259 this.element.value = newValue + value ;256 this.element.value = newValue + value + this.element.value.substr(bounds[1]); 260 257 } else { 261 258 this.element.value = value; 262 259 } 260 this.oldElementValue = this.element.value; 263 261 this.element.focus(); 264 262 … … 304 302 onObserverEvent: function() { 305 303 this.changed = false; 304 this.tokenBounds = null; 306 305 if(this.getToken().length>=this.options.minChars) { 307 306 this.getUpdatedChoices(); … … 310 309 this.hide(); 311 310 } 311 this.oldElementValue = this.element.value; 312 312 }, 313 313 314 314 getToken: function() { 315 var tokenPos = this.findLastToken(); 316 if (tokenPos != -1) 317 var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); 318 else 319 var ret = this.element.value; 320 321 return /\n/.test(ret) ? '' : ret; 322 }, 323 324 findLastToken: function() { 325 var lastTokenPos = -1; 326 327 for (var i=0; i<this.options.tokens.length; i++) { 328 var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]); 329 if (thisTokenPos > lastTokenPos) 330 lastTokenPos = thisTokenPos; 331 } 332 return lastTokenPos; 315 var bounds = this.getTokenBounds(); 316 return this.element.value.substring(bounds[0], bounds[1]).strip(); 317 }, 318 319 getTokenBounds: function() { 320 if (null != this.tokenBounds) return this.tokenBounds; 321 var value = this.element.value; 322 if (value.strip().empty()) return [-1, 0]; 323 var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue); 324 var offset = (diff == this.oldElementValue.length ? 1 : 0); 325 var prevTokenPos = -1, nextTokenPos = value.length; 326 var tp; 327 for (var index = 0, l = this.options.tokens.length; index < l; ++index) { 328 tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); 329 if (tp > prevTokenPos) prevTokenPos = tp; 330 tp = value.indexOf(this.options.tokens[index], diff + offset); 331 if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; 332 } 333 return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); 333 334 } 334 } 335 336 Ajax.Autocompleter = Class.create(); 337 Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { 335 }); 336 337 Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) { 338 var boundary = Math.min(newS.length, oldS.length); 339 for (var index = 0; index < boundary; ++index) 340 if (newS[index] != oldS[index]) 341 return index; 342 return boundary; 343 }; 344 345 Ajax.Autocompleter = Class.create(Autocompleter.Base, { 338 346 initialize: function(element, update, url, options) { 339 347 this.baseInitialize(element, update, options); … … 362 370 this.updateChoices(request.responseText); 363 371 } 364 365 372 }); 366 373 … … 400 407 // you support them. 401 408 402 Autocompleter.Local = Class.create(); 403 Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { 409 Autocompleter.Local = Class.create(Autocompleter.Base, { 404 410 initialize: function(element, update, array, options) { 405 411 this.baseInitialize(element, update, options); … … 457 463 return "<ul>" + ret.join('') + "</ul>"; 458 464 } 459 }, options || { });465 }, options || { }); 460 466 } 461 467 }); 462 468 463 // AJAX in-place editor 464 // 465 // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor 469 // AJAX in-place editor and collection editor 470 // Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007). 466 471 467 472 // Use this if you notice weird scrolling problems on some browsers, … … 474 479 } 475 480 476 Ajax.InPlaceEditor = Class.create(); 477 Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; 478 Ajax.InPlaceEditor.prototype = { 481 Ajax.InPlaceEditor = Class.create({ 479 482 initialize: function(element, url, options) { 480 483 this.url = url; 481 this.element = $(element); 482 483 this.options = Object.extend({ 484 paramName: "value", 485 okButton: true, 486 okLink: false, 487 okText: "ok", 488 cancelButton: false, 489 cancelLink: true, 490 cancelText: "cancel", 491 textBeforeControls: '', 492 textBetweenControls: '', 493 textAfterControls: '', 494 savingText: "Saving...", 495 clickToEditText: "Click to edit", 496 okText: "ok", 497 rows: 1, 498 onComplete: function(transport, element) { 499 new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); 500 }, 501 onFailure: function(transport) { 502 alert("Error communicating with the server: " + transport.responseText.stripTags()); 503 }, 504 callback: function(form) { 505 return Form.serialize(form); 506 }, 507 handleLineBreaks: true, 508 loadingText: 'Loading...', 509 savingClassName: 'inplaceeditor-saving', 510 loadingClassName: 'inplaceeditor-loading', 511 formClassName: 'inplaceeditor-form', 512 highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, 513 highlightendcolor: "#FFFFFF", 514 externalControl: null, 515 submitOnBlur: false, 516 ajaxOptions: {}, 517 evalScripts: false 518 }, options || {}); 519 520 if(!this.options.formId && this.element.id) { 521 this.options.formId = this.element.id + "-inplaceeditor"; 522 if ($(this.options.formId)) { 523 // there's already a form with that name, don't specify an id 524 this.options.formId = null; 525 } 526 } 527 528 if (this.options.externalControl) { 484 this.element = element = $(element); 485 this.prepareOptions(); 486 this._controls = { }; 487 arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! 488 Object.extend(this.options, options || { }); 489 if (!this.options.formId && this.element.id) { 490 this.options.formId = this.element.id + '-inplaceeditor'; 491 if ($(this.options.formId)) 492 this.options.formId = ''; 493 } 494 if (this.options.externalControl) 529 495 this.options.externalControl = $(this.options.externalControl); 530 } 531 532 this.originalBackground = Element.getStyle(this.element, 'background-color'); 533 if (!this.originalBackground) { 534 this.originalBackground = "transparent"; 535 } 536 496 if (!this.options.externalControl) 497 this.options.externalControlOnly = false; 498 this._originalBackground = this.element.getStyle('background-color') || 'transparent'; 537 499 this.element.title = this.options.clickToEditText; 538 539 this.onclickListener = this.enterEditMode.bindAsEventListener(this); 540 this.mouseoverListener = this.enterHover.bindAsEventListener(this); 541 this.mouseoutListener = this.leaveHover.bindAsEventListener(this); 542 Event.observe(this.element, 'click', this.onclickListener); 543 Event.observe(this.element, 'mouseover', this.mouseoverListener); 544 Event.observe(this.element, 'mouseout', this.mouseoutListener); 545 if (this.options.externalControl) { 546 Event.observe(this.options.externalControl, 'click', this.onclickListener); 547 Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); 548 Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); 549 } 550 }, 551 enterEditMode: function(evt) { 552 if (this.saving) return; 553 if (this.editing) return; 554 this.editing = true; 555 this.onEnterEditMode(); 556 if (this.options.externalControl) { 557 Element.hide(this.options.externalControl); 558 } 559 Element.hide(this.element); 500 this._boundCancelHandler = this.handleFormCancellation.bind(this); 501 this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); 502 this._boundFailureHandler = this.handleAJAXFailure.bind(this); 503 this._boundSubmitHandler = this.handleFormSubmission.bind(this); 504 this._boundWrapperHandler = this.wrapUp.bind(this); 505 this.registerListeners(); 506 }, 507 checkForEscapeOrReturn: function(e) { 508 if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; 509 if (Event.KEY_ESC == e.keyCode) 510 this.handleFormCancellation(e); 511 else if (Event.KEY_RETURN == e.keyCode) 512 this.handleFormSubmission(e); 513 }, 514 createControl: function(mode, handler, extraClasses) { 515 var control = this.options[mode + 'Control']; 516 var text = this.options[mode + 'Text']; 517 if ('button' == control) { 518 var btn = document.createElement('input'); 519 btn.type = 'submit'; 520 btn.value = text; 521 btn.className = 'editor_' + mode + '_button'; 522 if ('cancel' == mode) 523 btn.onclick = this._boundCancelHandler; 524 this._form.appendChild(btn); 525 this._controls[mode] = btn; 526 } else if ('link' == control) { 527 var link = document.createElement('a'); 528 link.href = '#'; 529 link.appendChild(document.createTextNode(text)); 530 link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; 531 link.className = 'editor_' + mode + '_link'; 532 if (extraClasses) 533 link.className += ' ' + extraClasses; 534 this._form.appendChild(link); 535 this._controls[mode] = link; 536 } 537 }, 538 createEditField: function() { 539 var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); 540 var fld; 541 if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { 542 fld = document.createElement('input'); 543 fld.type = 'text'; 544 var size = this.options.size || this.options.cols || 0; 545 if (0 < size) fld.size = size; 546 } else { 547 fld = document.createElement('textarea'); 548 fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); 549 fld.cols = this.options.cols || 40; 550 } 551 fld.name = this.options.paramName; 552 fld.value = text; // No HTML breaks conversion anymore 553 fld.className = 'editor_field'; 554 if (this.options.submitOnBlur) 555 fld.onblur = this._boundSubmitHandler; 556 this._controls.editor = fld; 557 if (this.options.loadTextURL) 558 this.loadExternalText(); 559 this._form.appendChild(this._controls.editor); 560 }, 561 createForm: function() { 562 var ipe = this; 563 function addText(mode, condition) { 564 var text = ipe.options['text' + mode + 'Controls']; 565 if (!text || condition === false) return; 566 ipe._form.appendChild(document.createTextNode(text)); 567 }; 568 this._form = $(document.createElement('form')); 569 this._form.id = this.options.formId; 570 this._form.addClassName(this.options.formClassName); 571 this._form.onsubmit = this._boundSubmitHandler; 572 this.createEditField(); 573 if ('textarea' == this._controls.editor.tagName.toLowerCase()) 574 this._form.appendChild(document.createElement('br')); 575 if (this.options.onFormCustomization) 576 this.options.onFormCustomization(this, this._form); 577 addText('Before', this.options.okControl || this.options.cancelControl); 578 this.createControl('ok', this._boundSubmitHandler); 579 addText('Between', this.options.okControl && this.options.cancelControl); 580 this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); 581 addText('After', this.options.okControl || this.options.cancelControl); 582 }, 583 destroy: function() { 584 if (this._oldInnerHTML) 585 this.element.innerHTML = this._oldInnerHTML; 586 this.leaveEditMode(); 587 this.unregisterListeners(); 588 }, 589 enterEditMode: function(e) { 590 if (this._saving || this._editing) return; 591 this._editing = true; 592 this.triggerCallback('onEnterEditMode'); 593 if (this.options.externalControl) 594 this.options.externalControl.hide(); 595 this.element.hide(); 560 596 this.createForm(); 561 this.element.parentNode.insertBefore(this.form, this.element); 562 if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField); 563 // stop the event to avoid a page refresh in Safari 564 if (evt) { 565 Event.stop(evt); 566 } 567 return false; 568 }, 569 createForm: function() { 570 this.form = document.createElement("form"); 571 this.form.id = this.options.formId; 572 Element.addClassName(this.form, this.options.formClassName) 573 this.form.onsubmit = this.onSubmit.bind(this); 574 575 this.createEditField(); 576 577 if (this.options.textarea) { 578 var br = document.createElement("br"); 579 this.form.appendChild(br); 580 } 581 582 if (this.options.textBeforeControls) 583 this.form.appendChild(document.createTextNode(this.options.textBeforeControls)); 584 585 if (this.options.okButton) { 586 var okButton = document.createElement("input"); 587 okButton.type = "submit"; 588 okButton.value = this.options.okText; 589 okButton.className = 'editor_ok_button'; 590 this.form.appendChild(okButton); 591 } 592 593 if (this.options.okLink) { 594 var okLink = document.createElement("a"); 595 okLink.href = "#"; 596 okLink.appendChild(document.createTextNode(this.options.okText)); 597 okLink.onclick = this.onSubmit.bind(this); 598 okLink.className = 'editor_ok_link'; 599 this.form.appendChild(okLink); 600 } 601 602 if (this.options.textBetweenControls && 603 (this.options.okLink || this.options.okButton) && 604 (this.options.cancelLink || this.options.cancelButton)) 605 this.form.appendChild(document.createTextNode(this.options.textBetweenControls)); 606 607 if (this.options.cancelButton) { 608 var cancelButton = document.createElement("input"); 609 cancelButton.type = "submit"; 610 cancelButton.value = this.options.cancelText; 611 cancelButton.onclick = this.onclickCancel.bind(this); 612 cancelButton.className = 'editor_cancel_button'; 613 this.form.appendChild(cancelButton); 614 } 615 616 if (this.options.cancelLink) { 617 var cancelLink = document.createElement("a"); 618 cancelLink.href = "#"; 619 cancelLink.appendChild(document.createTextNode(this.options.cancelText)); 620 cancelLink.onclick = this.onclickCancel.bind(this); 621 cancelLink.className = 'editor_cancel editor_cancel_link'; 622 this.form.appendChild(cancelLink); 623 } 624 625 if (this.options.textAfterControls) 626 this.form.appendChild(document.createTextNode(this.options.textAfterControls)); 627 }, 628 hasHTMLLineBreaks: function(string) { 629 if (!this.options.handleLineBreaks) return false; 630 return string.match(/<br/i) || string.match(/<p>/i); 631 }, 632 convertHTMLLineBreaks: function(string) { 633 return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, ""); 634 }, 635 createEditField: function() { 636 var text; 637 if(this.options.loadTextURL) { 638 text = this.options.loadingText; 639 } else { 640 text = this.getText(); 641 } 642 643 var obj = this; 644 645 if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { 646 this.options.textarea = false; 647 var textField = document.createElement("input"); 648 textField.obj = this; 649 textField.type = "text"; 650 textField.name = this.options.paramName; 651 textField.value = text; 652 textField.style.backgroundColor = this.options.highlightcolor; 653 textField.className = 'editor_field'; 654 var size = this.options.size || this.options.cols || 0; 655 if (size != 0) textField.size = size; 656 if (this.options.submitOnBlur) 657 textField.onblur = this.onSubmit.bind(this); 658 this.editField = textField; 659 } else { 660 this.options.textarea = true; 661 var textArea = document.createElement("textarea"); 662 textArea.obj = this; 663 textArea.name = this.options.paramName; 664 textArea.value = this.convertHTMLLineBreaks(text); 665 textArea.rows = this.options.rows; 666 textArea.cols = this.options.cols || 40; 667 textArea.className = 'editor_field'; 668 if (this.options.submitOnBlur) 669 textArea.onblur = this.onSubmit.bind(this); 670 this.editField = textArea; 671 } 672 673 if(this.options.loadTextURL) { 674 this.loadExternalText(); 675 } 676 this.form.appendChild(this.editField); 597 this.element.parentNode.insertBefore(this._form, this.element); 598 if (!this.options.loadTextURL) 599 this.postProcessEditField(); 600 if (e) Event.stop(e); 601 }, 602 enterHover: function(e) { 603 if (this.options.hoverClassName) 604 this.element.addClassName(this.options.hoverClassName); 605 if (this._saving) return; 606 this.triggerCallback('onEnterHover'); 677 607 }, 678 608 getText: function() { 679 609 return this.element.innerHTML; 680 610 }, 611 handleAJAXFailure: function(transport) { 612 this.triggerCallback('onFailure', transport); 613 if (this._oldInnerHTML) { 614 this.element.innerHTML = this._oldInnerHTML; 615 this._oldInnerHTML = null; 616 } 617 }, 618 handleFormCancellation: function(e) { 619 this.wrapUp(); 620 if (e) Event.stop(e); 621 }, 622 handleFormSubmission: function(e) { 623 var form = this._form; 624 var value = $F(this._controls.editor); 625 this.prepareSubmission(); 626 var params = this.options.callback(form, value) || ''; 627 if (Object.isString(params)) 628 params = params.toQueryParams(); 629 params.editorId = this.element.id; 630 if (this.options.htmlResponse) { 631 var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); 632 Object.extend(options, { 633 parameters: params, 634 onComplete: this._boundWrapperHandler, 635 onFailure: this._boundFailureHandler 636 }); 637 new Ajax.Updater({ success: this.element }, this.url, options); 638 } else { 639 var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); 640 Object.extend(options, { 641 parameters: params, 642 onComplete: this._boundWrapperHandler, 643 onFailure: this._boundFailureHandler 644 }); 645 new Ajax.Request(this.url, options); 646 } 647 if (e) Event.stop(e); 648 }, 649 leaveEditMode: function() { 650 this.element.removeClassName(this.options.savingClassName); 651 this.removeForm(); 652 this.leaveHover(); 653 this.element.style.backgroundColor = this._originalBackground; 654 this.element.show(); 655 if (this.options.externalControl) 656 this.options.externalControl.show(); 657 this._saving = false; 658 this._editing = false; 659 this._oldInnerHTML = null; 660 this.triggerCallback('onLeaveEditMode'); 661 }, 662 leaveHover: function(e) { 663 if (this.options.hoverClassName) 664 this.element.removeClassName(this.options.hoverClassName); 665 if (this._saving) return; 666 this.triggerCallback('onLeaveHover'); 667 }, 681 668 loadExternalText: function() { 682 Element.addClassName(this.form, this.options.loadingClassName); 683 this.editField.disabled = true; 684 new Ajax.Request( 685 this.options.loadTextURL, 686 Object.extend({ 687 asynchronous: true, 688 onComplete: this.onLoadedExternalText.bind(this) 689 }, this.options.ajaxOptions) 690 ); 691 }, 692 onLoadedExternalText: function(transport) { 693 Element.removeClassName(this.form, this.options.loadingClassName); 694 this.editField.disabled = false; 695 this.editField.value = transport.responseText.stripTags(); 696 Field.scrollFreeActivate(this.editField); 697 }, 698 onclickCancel: function() { 699 this.onComplete(); 700 this.leaveEditMode(); 701 return false; 702 }, 703 onFailure: function(transport) { 704 this.options.onFailure(transport); 705 if (this.oldInnerHTML) { 706 this.element.innerHTML = this.oldInnerHTML; 707 this.oldInnerHTML = null; 708 } 709 return false; 710 }, 711 onSubmit: function() { 712 // onLoading resets these so we need to save them away for the Ajax call 713 var form = this.form; 714 var value = this.editField.value; 715 716 // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... 717 // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... 718 // to be displayed indefinitely 719 this.onLoading(); 720 721 if (this.options.evalScripts) { 722 new Ajax.Request( 723 this.url, Object.extend({ 724 parameters: this.options.callback(form, value), 725 onComplete: this.onComplete.bind(this), 726 onFailure: this.onFailure.bind(this), 727 asynchronous:true, 728 evalScripts:true 729 }, this.options.ajaxOptions)); 730 } else { 731 new Ajax.Updater( 732 { success: this.element, 733 // don't update on failure (this could be an option) 734 failure: null }, 735 this.url, Object.extend({ 736 parameters: this.options.callback(form, value), 737 onComplete: this.onComplete.bind(this), 738 onFailure: this.onFailure.bind(this) 739 }, this.options.ajaxOptions)); 740 } 741 // stop the event to avoid a page refresh in Safari 742 if (arguments.length > 1) { 743 Event.stop(arguments[0]); 744 } 745 return false; 746 }, 747 onLoading: function() { 748 this.saving = true; 669 this._form.addClassName(this.options.loadingClassName); 670 this._controls.editor.disabled = true; 671 var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); 672 Object.extend(options, { 673 parameters: 'editorId=' + encodeURIComponent(this.element.id), 674 onComplete: Prototype.emptyFunction, 675 onSuccess: function(transport) { 676 this._form.removeClassName(this.options.loadingClassName); 677 var text = transport.responseText; 678 if (this.options.stripLoadedTextTags) 679 text = text.stripTags(); 680 this._controls.editor.value = text; 681 this._controls.editor.disabled = false; 682 this.postProcessEditField(); 683 }.bind(this), 684 onFailure: this._boundFailureHandler 685 }); 686 new Ajax.Request(this.options.loadTextURL, options); 687 }, 688 postProcessEditField: function() { 689 var fpc = this.options.fieldPostCreation; 690 if (fpc) 691 $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); 692 }, 693 prepareOptions: function() { 694 this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); 695 Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); 696 [this._extraDefaultOptions].flatten().compact().each(function(defs) { 697 Object.extend(this.options, defs); 698 }.bind(this)); 699 }, 700 prepareSubmission: function() { 701 this._saving = true; 749 702 this.removeForm(); 750 703 this.leaveHover(); 751 704 this.showSaving(); 752 705 }, 706 registerListeners: function() { 707 this._listeners = { }; 708 var listener; 709 $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { 710 listener = this[pair.value].bind(this); 711 this._listeners[pair.key] = listener; 712 if (!this.options.externalControlOnly) 713 this.element.observe(pair.key, listener); 714 if (this.options.externalControl) 715 this.options.externalControl.observe(pair.key, listener); 716 }.bind(this)); 717 }, 718 removeForm: function() { 719 if (!this._form) return; 720 this._form.remove(); 721 this._form = null; 722 this._controls = { }; 723 }, 753 724 showSaving: function() { 754 this. oldInnerHTML = this.element.innerHTML;725 this._oldInnerHTML = this.element.innerHTML; 755 726 this.element.innerHTML = this.options.savingText; 756 Element.addClassName(this.element, this.options.savingClassName); 757 this.element.style.backgroundColor = this.originalBackground; 758 Element.show(this.element); 759 }, 760 removeForm: function() { 761 if(this.form) { 762 if (this.form.parentNode) Element.remove(this.form); 763 this.form = null; 764 } 765 }, 766 enterHover: function() { 767 if (this.saving) return; 768 this.element.style.backgroundColor = this.options.highlightcolor; 769 if (this.effect) { 770 this.effect.cancel(); 771 } 772 Element.addClassName(this.element, this.options.hoverClassName) 773 }, 774 leaveHover: function() { 775 if (this.options.backgroundColor) { 776 this.element.style.backgroundColor = this.oldBackground; 777 } 778 Element.removeClassName(this.element, this.options.hoverClassName) 779 if (this.saving) return; 780 this.effect = new Effect.Highlight(this.element, { 781 startcolor: this.options.highlightcolor, 782 endcolor: this.options.highlightendcolor, 783 restorecolor: this.originalBackground 784 }); 785 }, 786 leaveEditMode: function() { 787 Element.removeClassName(this.element, this.options.savingClassName); 788 this.removeForm(); 789 this.leaveHover(); 790 this.element.style.backgroundColor = this.originalBackground; 791 Element.show(this.element); 792 if (this.options.externalControl) { 793 Element.show(this.options.externalControl); 794 } 795 this.editing = false; 796 this.saving = false; 797 this.oldInnerHTML = null; 798 this.onLeaveEditMode(); 799 }, 800 onComplete: function(transport) { 727 this.element.addClassName(this.options.savingClassName); 728 this.element.style.backgroundColor = this._originalBackground; 729 this.element.show(); 730 }, 731 triggerCallback: function(cbName, arg) { 732 if ('function' == typeof this.options[cbName]) { 733 this.options[cbName](this, arg); 734 } 735 }, 736 unregisterListeners: function() { 737 $H(this._listeners).each(function(pair) { 738 if (!this.options.externalControlOnly) 739 this.element.stopObserving(pair.key, pair.value); 740 if (this.options.externalControl) 741 this.options.externalControl.stopObserving(pair.key, pair.value); 742 }.bind(this)); 743 }, 744 wrapUp: function(transport) { 801 745 this.leaveEditMode(); 802 this.options.onComplete.bind(this)(transport, this.element); 803 }, 804 onEnterEditMode: function() {}, 805 onLeaveEditMode: function() {}, 806 dispose: function() { 807 if (this.oldInnerHTML) { 808 this.element.innerHTML = this.oldInnerHTML; 809 } 810 this.leaveEditMode(); 811 Event.stopObserving(this.element, 'click', this.onclickListener); 812 Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); 813 Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); 814 if (this.options.externalControl) { 815 Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); 816 Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); 817 Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); 818 } 819 } 820 }; 821 822 Ajax.InPlaceCollectionEditor = Class.create(); 823 Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); 824 Object.extend(Ajax.InPlaceCollectionEditor.prototype, { 825 createEditField: function() { 826 if (!this.cached_selectTag) { 827 var selectTag = document.createElement("select"); 828 var collection = this.options.collection || []; 829 var optionTag; 830 collection.each(function(e,i) { 831 optionTag = document.createElement("option"); 832 optionTag.value = (e instanceof Array) ? e[0] : e; 833 if((typeof this.options.value == 'undefined') && 834 ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true; 835 if(this.options.value==optionTag.value) optionTag.selected = true; 836 optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e)); 837 selectTag.appendChild(optionTag); 838 }.bind(this)); 839 this.cached_selectTag = selectTag; 840 } 841 842 this.editField = this.cached_selectTag; 843 if(this.options.loadTextURL) this.loadExternalText(); 844 this.form.appendChild(this.editField); 845 this.options.callback = function(form, value) { 846 return "value=" + encodeURIComponent(value); 847 } 746 // Can't use triggerCallback due to backward compatibility: requires 747 // binding + direct element 748 this._boundComplete(transport, this.element); 848 749 } 849 750 }); 751 752 Object.extend(Ajax.InPlaceEditor.prototype, { 753 dispose: Ajax.InPlaceEditor.prototype.destroy 754 }); 755 756 Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, { 757 initialize: function($super, element, url, options) { 758 this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; 759 $super(element, url, options); 760 }, 761 762 createEditField: function() { 763 var list = document.createElement('select'); 764 list.name = this.options.paramName; 765 list.size = 1; 766 this._controls.editor = list; 767 this._collection = this.options.collection || []; 768 if (this.options.loadCollectionURL) 769 this.loadCollection(); 770 else 771 this.checkForExternalText(); 772 this._form.appendChild(this._controls.editor); 773 }, 774 775 loadCollection: function() { 776 this._form.addClassName(this.options.loadingClassName); 777 this.showLoadingText(this.options.loadingCollectionText); 778 var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); 779 Object.extend(options, { 780 parameters: 'editorId=' + encodeURIComponent(this.element.id), 781 onComplete: Prototype.emptyFunction, 782 onSuccess: function(transport) { 783 var js = transport.responseText.strip(); 784 if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check 785 throw 'Server returned an invalid collection representation.'; 786 this._collection = eval(js); 787 this.checkForExternalText(); 788 }.bind(this), 789 onFailure: this.onFailure 790 }); 791 new Ajax.Request(this.options.loadCollectionURL, options); 792 }, 793 794 showLoadingText: function(text) { 795 this._controls.editor.disabled = true; 796 var tempOption = this._controls.editor.firstChild; 797 if (!tempOption) { 798 tempOption = document.createElement('option'); 799 tempOption.value = ''; 800 this._controls.editor.appendChild(tempOption); 801 tempOption.selected = true; 802 } 803 tempOption.update((text || '').stripScripts().stripTags()); 804 }, 805 806 checkForExternalText: function() { 807 this._text = this.getText(); 808 if (this.options.loadTextURL) 809 this.loadExternalText(); 810 else 811 this.buildOptionList(); 812 }, 813 814 loadExternalText: function() { 815 this.showLoadingText(this.options.loadingText); 816 var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); 817 Object.extend(options, { 818 parameters: 'editorId=' + encodeURIComponent(this.element.id), 819 onComplete: Prototype.emptyFunction, 820 onSuccess: function(transport) { 821 this._text = transport.responseText.strip(); 822 this.buildOptionList(); 823 }.bind(this), 824 onFailure: this.onFailure 825 }); 826 new Ajax.Request(this.options.loadTextURL, options); 827 }, 828 829 buildOptionList: function() { 830 this._form.removeClassName(this.options.loadingClassName); 831 this._collection = this._collection.map(function(entry) { 832 return 2 === entry.length ? entry : [entry, entry].flatten(); 833 }); 834 var marker = ('value' in this.options) ? this.options.value : this._text; 835 var textFound = this._collection.any(function(entry) { 836 return entry[0] == marker; 837 }.bind(this)); 838 this._controls.editor.update(''); 839 var option; 840 this._collection.each(function(entry, index) { 841 option = document.createElement('option'); 842 option.value = entry[0]; 843 option.selected = textFound ? entry[0] == marker : 0 == index; 844 option.appendChild(document.createTextNode(entry[1])); 845 this._controls.editor.appendChild(option); 846 }.bind(this)); 847 this._controls.editor.disabled = false; 848 Field.scrollFreeActivate(this._controls.editor); 849 } 850 }); 851 852 //**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** 853 //**** This only exists for a while, in order to let **** 854 //**** users adapt to the new API. Read up on the new **** 855 //**** API and convert your code to it ASAP! **** 856 857 Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { 858 if (!options) return; 859 function fallback(name, expr) { 860 if (name in options || expr === undefined) return; 861 options[name] = expr; 862 }; 863 fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : 864 options.cancelLink == options.cancelButton == false ? false : undefined))); 865 fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : 866 options.okLink == options.okButton == false ? false : undefined))); 867 fallback('highlightColor', options.highlightcolor); 868 fallback('highlightEndColor', options.highlightendcolor); 869 }; 870 871 Object.extend(Ajax.InPlaceEditor, { 872 DefaultOptions: { 873 ajaxOptions: { }, 874 autoRows: 3, // Use when multi-line w/ rows == 1 875 cancelControl: 'link', // 'link'|'button'|false 876 cancelText: 'cancel', 877 clickToEditText: 'Click to edit', 878 externalControl: null, // id|elt 879 externalControlOnly: false, 880 fieldPostCreation: 'activate', // 'activate'|'focus'|false 881 formClassName: 'inplaceeditor-form', 882 formId: null, // id|elt 883 highlightColor: '#ffff99', 884 highlightEndColor: '#ffffff', 885 hoverClassName: '', 886 htmlResponse: true, 887 loadingClassName: 'inplaceeditor-loading', 888 loadingText: 'Loading...', 889 okControl: 'button', // 'link'|'button'|false 890 okText: 'ok', 891 paramName: 'value', 892 rows: 1, // If 1 and multi-line, uses autoRows 893 savingClassName: 'inplaceeditor-saving', 894 savingText: 'Saving...', 895 size: 0, 896 stripLoadedTextTags: false, 897 submitOnBlur: false, 898 textAfterControls: '', 899 textBeforeControls: '', 900 textBetweenControls: '' 901 }, 902 DefaultCallbacks: { 903 callback: function(form) { 904 return Form.serialize(form); 905 }, 906 onComplete: function(transport, element) { 907 // For backward compatibility, this one is bound to the IPE, and passes 908 // the element directly. It was too often customized, so we don't break it. 909 new Effect.Highlight(element, { 910 startcolor: this.options.highlightColor, keepBackgroundImage: true }); 911 }, 912 onEnterEditMode: null, 913 onEnterHover: function(ipe) { 914 ipe.element.style.backgroundColor = ipe.options.highlightColor; 915 if (ipe._effect) 916 ipe._effect.cancel(); 917 }, 918 onFailure: function(transport, ipe) { 919 alert('Error communication with the server: ' + transport.responseText.stripTags()); 920 }, 921 onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. 922 onLeaveEditMode: null, 923 onLeaveHover: function(ipe) { 924 ipe._effect = new Effect.Highlight(ipe.element, { 925 startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, 926 restorecolor: ipe._originalBackground, keepBackgroundImage: true 927 }); 928 } 929 }, 930 Listeners: { 931 click: 'enterEditMode', 932 keydown: 'checkForEscapeOrReturn', 933 mouseover: 'enterHover', 934 mouseout: 'leaveHover' 935 } 936 }); 937 938 Ajax.InPlaceCollectionEditor.DefaultOptions = { 939 loadingCollectionText: 'Loading options...' 940 }; 850 941 851 942 // Delayed observer, like Form.Element.Observer, … … 853 944 // Ideal for live-search fields 854 945 855 Form.Element.DelayedObserver = Class.create(); 856 Form.Element.DelayedObserver.prototype = { 946 Form.Element.DelayedObserver = Class.create({ 857 947 initialize: function(element, delay, callback) { 858 948 this.delay = delay || 0.5; … … 873 963 this.callback(this.element, $F(this.element)); 874 964 } 875 } ;965 }); -
trunk/wp-includes/js/scriptaculous/dragdrop.js
r5792 r6512 1 // script.aculo.us dragdrop.js v1. 7.1_beta3, Fri May 25 17:19:41 +0200 20071 // script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 2 2 3 3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) … … 7 7 // For details, see the script.aculo.us web site: http://script.aculo.us/ 8 8 9 if( typeof Effect == 'undefined')9 if(Object.isUndefined(Effect)) 10 10 throw("dragdrop.js requires including script.aculo.us' effects.js library"); 11 11 … … 23 23 hoverclass: null, 24 24 tree: false 25 }, arguments[1] || { });25 }, arguments[1] || { }); 26 26 27 27 // cache containers … … 29 29 options._containers = []; 30 30 var containment = options.containment; 31 if((typeof containment == 'object') && 32 (containment.constructor == Array)) { 31 if(Object.isArray(containment)) { 33 32 containment.each( function(c) { options._containers.push($(c)) }); 34 33 } else { … … 90 89 show: function(point, element) { 91 90 if(!this.drops.length) return; 92 var affected = []; 93 94 if(this.last_active) this.deactivate(this.last_active); 91 var drop, affected = []; 92 95 93 this.drops.each( function(drop) { 96 94 if(Droppables.isAffected(point, element, drop)) … … 98 96 }); 99 97 100 if(affected.length>0) {98 if(affected.length>0) 101 99 drop = Droppables.findDeepestChild(affected); 100 101 if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); 102 if (drop) { 102 103 Position.within(drop.element, point[0], point[1]); 103 104 if(drop.onHover) 104 105 drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); 105 106 106 Droppables.activate(drop);107 if (drop != this.last_active) Droppables.activate(drop); 107 108 } 108 109 }, … … 224 225 /*--------------------------------------------------------------------------*/ 225 226 226 var Draggable = Class.create(); 227 Draggable._dragging = {}; 228 229 Draggable.prototype = { 227 var Draggable = Class.create({ 230 228 initialize: function(element) { 231 229 var defaults = { … … 238 236 }, 239 237 endeffect: function(element) { 240 var toOpacity = typeof element._opacity == 'number'? element._opacity : 1.0;238 var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; 241 239 new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 242 240 queue: {scope:'_draggable', position:'end'}, … … 256 254 }; 257 255 258 if(!arguments[1] || typeof arguments[1].endeffect == 'undefined')256 if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) 259 257 Object.extend(defaults, { 260 258 starteffect: function(element) { … … 265 263 }); 266 264 267 var options = Object.extend(defaults, arguments[1] || { });265 var options = Object.extend(defaults, arguments[1] || { }); 268 266 269 267 this.element = $(element); 270 268 271 if(options.handle && (typeof options.handle == 'string'))269 if(options.handle && Object.isString(options.handle)) 272 270 this.handle = this.element.down('.'+options.handle, 0); 273 271 … … 282 280 Element.makePositioned(this.element); // fix IE 283 281 284 this.delta = this.currentDelta();285 282 this.options = options; 286 283 this.dragging = false; … … 304 301 305 302 initDrag: function(event) { 306 if( typeof Draggable._dragging[this.element] != 'undefined'&&303 if(!Object.isUndefined(Draggable._dragging[this.element]) && 307 304 Draggable._dragging[this.element]) return; 308 305 if(Event.isLeftClick(event)) { … … 327 324 startDrag: function(event) { 328 325 this.dragging = true; 326 if(!this.delta) 327 this.delta = this.currentDelta(); 329 328 330 329 if(this.options.zindex) { … … 335 334 if(this.options.ghosting) { 336 335 this._clone = this.element.cloneNode(true); 337 Position.absolutize(this.element); 336 this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); 337 if (!this.element._originallyAbsolute) 338 Position.absolutize(this.element); 338 339 this.element.parentNode.insertBefore(this._clone, this.element); 339 340 } … … 405 406 406 407 if(this.options.ghosting) { 407 Position.relativize(this.element); 408 if (!this.element._originallyAbsolute) 409 Position.relativize(this.element); 410 delete this.element._originallyAbsolute; 408 411 Element.remove(this._clone); 409 412 this._clone = null; … … 419 422 420 423 var revert = this.options.revert; 421 if(revert && typeof revert == 'function') revert = revert(this.element);424 if(revert && Object.isFunction(revert)) revert = revert(this.element); 422 425 423 426 var d = this.currentDelta(); … … 473 476 474 477 if(this.options.snap) { 475 if( typeof this.options.snap == 'function') {478 if(Object.isFunction(this.options.snap)) { 476 479 p = this.options.snap(p[0],p[1],this); 477 480 } else { 478 if( this.options.snap instanceof Array) {481 if(Object.isArray(this.options.snap)) { 479 482 p = p.map( function(v, i) { 480 return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))483 return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) 481 484 } else { 482 485 p = p.map( function(v) { 483 return Math.round(v/this.options.snap)*this.options.snap }.bind(this))486 return (v/this.options.snap).round()*this.options.snap }.bind(this)) 484 487 } 485 488 }} … … 565 568 return { top: T, left: L, width: W, height: H }; 566 569 } 567 } 570 }); 571 572 Draggable._dragging = { }; 568 573 569 574 /*--------------------------------------------------------------------------*/ 570 575 571 var SortableObserver = Class.create(); 572 SortableObserver.prototype = { 576 var SortableObserver = Class.create({ 573 577 initialize: function(element, observer) { 574 578 this.element = $(element); … … 586 590 this.observer(this.element) 587 591 } 588 } 592 }); 589 593 590 594 var Sortable = { 591 595 SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, 592 596 593 sortables: { },597 sortables: { }, 594 598 595 599 _findRootElement: function(element) { … … 644 648 elements: false, 645 649 handles: false, 646 650 647 651 onChange: Prototype.emptyFunction, 648 652 onUpdate: Prototype.emptyFunction 649 }, arguments[1] || { });653 }, arguments[1] || { }); 650 654 651 655 // clear any old sortable with same element … … 711 715 (options.elements || this.findElements(element, options) || []).each( function(e,i) { 712 716 var handle = options.handles ? $(options.handles[i]) : 713 (options.handle ? $(e). getElementsByClassName(options.handle)[0] : e);717 (options.handle ? $(e).select('.' + options.handle)[0] : e); 714 718 options.draggables.push( 715 719 new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); … … 871 875 name: element.id, 872 876 format: sortableOptions.format 873 }, arguments[1] || { });877 }, arguments[1] || { }); 874 878 875 879 var root = { … … 895 899 sequence: function(element) { 896 900 element = $(element); 897 var options = Object.extend(this.options(element), arguments[1] || { });901 var options = Object.extend(this.options(element), arguments[1] || { }); 898 902 899 903 return $(this.findElements(element, options) || []).map( function(item) { … … 904 908 setSequence: function(element, new_sequence) { 905 909 element = $(element); 906 var options = Object.extend(this.options(element), arguments[2] || { });907 908 var nodeMap = { };910 var options = Object.extend(this.options(element), arguments[2] || { }); 911 912 var nodeMap = { }; 909 913 this.findElements(element, options).each( function(n) { 910 914 if (n.id.match(options.format)) … … 924 928 serialize: function(element) { 925 929 element = $(element); 926 var options = Object.extend(Sortable.options(element), arguments[1] || { });930 var options = Object.extend(Sortable.options(element), arguments[1] || { }); 927 931 var name = encodeURIComponent( 928 932 (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); … … 948 952 } 949 953 950 Element.findChildren = function(element, only, recursive, tagName) { 954 Element.findChildren = function(element, only, recursive, tagName) { 951 955 if(!element.hasChildNodes()) return null; 952 956 tagName = tagName.toUpperCase(); -
trunk/wp-includes/js/scriptaculous/effects.js
r5792 r6512 1 // script.aculo.us effects.js v1. 7.1_beta3, Fri May 25 17:19:41 +0200 20071 // script.aculo.us effects.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 2 2 3 3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) … … 14 14 String.prototype.parseColor = function() { 15 15 var color = '#'; 16 if (this.slice(0,4) == 'rgb(') {16 if (this.slice(0,4) == 'rgb(') { 17 17 var cols = this.slice(4,this.length-1).split(','); 18 18 var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); 19 19 } else { 20 if (this.slice(0,1) == '#') {21 if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();22 if (this.length==7) color = this.toLowerCase();20 if (this.slice(0,1) == '#') { 21 if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); 22 if (this.length==7) color = this.toLowerCase(); 23 23 } 24 24 } 25 return (color.length==7 ? color : (arguments[0] || this));26 } 25 return (color.length==7 ? color : (arguments[0] || this)); 26 }; 27 27 28 28 /*--------------------------------------------------------------------------*/ … … 33 33 (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); 34 34 }).flatten().join(''); 35 } 35 }; 36 36 37 37 Element.collectTextNodesIgnoreClass = function(element, className) { … … 41 41 Element.collectTextNodesIgnoreClass(node, className) : '')); 42 42 }).flatten().join(''); 43 } 43 }; 44 44 45 45 Element.setContentZoom = function(element, percent) { 46 46 element = $(element); 47 47 element.setStyle({fontSize: (percent/100) + 'em'}); 48 if (Prototype.Browser.WebKit) window.scrollBy(0,0);48 if (Prototype.Browser.WebKit) window.scrollBy(0,0); 49 49 return element; 50 } 50 }; 51 51 52 52 Element.getInlineOpacity = function(element){ 53 53 return $(element).style.opacity || ''; 54 } 54 }; 55 55 56 56 Element.forceRerendering = function(element) { … … 65 65 /*--------------------------------------------------------------------------*/ 66 66 67 Array.prototype.call = function() {68 var args = arguments;69 this.each(function(f){ f.apply(this, args) });70 }71 72 /*--------------------------------------------------------------------------*/73 74 67 var Effect = { 75 68 _elementDoesNotExistError: { … … 77 70 message: 'The specified DOM element does not exist, but is required for this effect to operate' 78 71 }, 72 Transitions: { 73 linear: Prototype.K, 74 sinoidal: function(pos) { 75 return (-Math.cos(pos*Math.PI)/2) + 0.5; 76 }, 77 reverse: function(pos) { 78 return 1-pos; 79 }, 80 flicker: function(pos) { 81 var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; 82 return pos > 1 ? 1 : pos; 83 }, 84 wobble: function(pos) { 85 return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; 86 }, 87 pulse: function(pos, pulses) { 88 pulses = pulses || 5; 89 return ( 90 ((pos % (1/pulses)) * pulses).round() == 0 ? 91 ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 92 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor()) 93 ); 94 }, 95 spring: function(pos) { 96 return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 97 }, 98 none: function(pos) { 99 return 0; 100 }, 101 full: function(pos) { 102 return 1; 103 } 104 }, 105 DefaultOptions: { 106 duration: 1.0, // seconds 107 fps: 100, // 100= assume 66fps max. 108 sync: false, // true for combining 109 from: 0.0, 110 to: 1.0, 111 delay: 0.0, 112 queue: 'parallel' 113 }, 79 114 tagifyText: function(element) { 80 if(typeof Builder == 'undefined')81 throw("Effect.tagifyText requires including script.aculo.us' builder.js library");82 83 115 var tagifyStyle = 'position:relative'; 84 if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';116 if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; 85 117 86 118 element = $(element); 87 119 $A(element.childNodes).each( function(child) { 88 if (child.nodeType==3) {120 if (child.nodeType==3) { 89 121 child.nodeValue.toArray().each( function(character) { 90 122 element.insertBefore( 91 Builder.node('span',{style: tagifyStyle},123 new Element('span', {style: tagifyStyle}).update( 92 124 character == ' ' ? String.fromCharCode(160) : character), 93 125 child); … … 99 131 multiple: function(element, effect) { 100 132 var elements; 101 if (((typeof element == 'object') ||102 (typeof element == 'function')) &&133 if (((typeof element == 'object') || 134 Object.isFunction(element)) && 103 135 (element.length)) 104 136 elements = element; … … 109 141 speed: 0.1, 110 142 delay: 0.0 111 }, arguments[2] || { });143 }, arguments[2] || { }); 112 144 var masterDelay = options.delay; 113 145 … … 126 158 var options = Object.extend({ 127 159 queue: { position:'end', scope:(element.id || 'global'), limit: 1 } 128 }, arguments[2] || { });160 }, arguments[2] || { }); 129 161 Effect[element.visible() ? 130 162 Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); … … 132 164 }; 133 165 134 var Effect2 = Effect; // deprecated 135 136 /* ------------- transitions ------------- */ 137 138 Effect.Transitions = { 139 linear: Prototype.K, 140 sinoidal: function(pos) { 141 return (-Math.cos(pos*Math.PI)/2) + 0.5; 142 }, 143 reverse: function(pos) { 144 return 1-pos; 145 }, 146 flicker: function(pos) { 147 var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; 148 return (pos > 1 ? 1 : pos); 149 }, 150 wobble: function(pos) { 151 return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; 152 }, 153 pulse: function(pos, pulses) { 154 pulses = pulses || 5; 155 return ( 156 Math.round((pos % (1/pulses)) * pulses) == 0 ? 157 ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : 158 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) 159 ); 160 }, 161 none: function(pos) { 162 return 0; 163 }, 164 full: function(pos) { 165 return 1; 166 } 167 }; 166 Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; 168 167 169 168 /* ------------- core effects ------------- */ 170 169 171 Effect.ScopedQueue = Class.create(); 172 Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { 170 Effect.ScopedQueue = Class.create(Enumerable, { 173 171 initialize: function() { 174 172 this.effects = []; … … 181 179 var timestamp = new Date().getTime(); 182 180 183 var position = (typeof effect.options.queue == 'string') ?181 var position = Object.isString(effect.options.queue) ? 184 182 effect.options.queue : effect.options.queue.position; 185 183 … … 204 202 effect.finishOn += timestamp; 205 203 206 if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))204 if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) 207 205 this.effects.push(effect); 208 206 209 if (!this.interval)207 if (!this.interval) 210 208 this.interval = setInterval(this.loop.bind(this), 15); 211 209 }, 212 210 remove: function(effect) { 213 211 this.effects = this.effects.reject(function(e) { return e==effect }); 214 if (this.effects.length == 0) {212 if (this.effects.length == 0) { 215 213 clearInterval(this.interval); 216 214 this.interval = null; … … 227 225 instances: $H(), 228 226 get: function(queueName) { 229 if(typeof queueName != 'string') return queueName; 230 231 if(!this.instances[queueName]) 232 this.instances[queueName] = new Effect.ScopedQueue(); 233 234 return this.instances[queueName]; 235 } 236 } 227 if (!Object.isString(queueName)) return queueName; 228 229 return this.instances.get(queueName) || 230 this.instances.set(queueName, new Effect.ScopedQueue()); 231 } 232 }; 237 233 Effect.Queue = Effect.Queues.get('global'); 238 234 239 Effect.DefaultOptions = { 240 transition: Effect.Transitions.sinoidal, 241 duration: 1.0, // seconds 242 fps: 100, // 100= assume 66fps max. 243 sync: false, // true for combining 244 from: 0.0, 245 to: 1.0, 246 delay: 0.0, 247 queue: 'parallel' 248 } 249 250 Effect.Base = function() {}; 251 Effect.Base.prototype = { 235 Effect.Base = Class.create({ 252 236 position: null, 253 237 start: function(options) { … … 258 242 ); 259 243 } 260 if (options.transition === false) options.transition = Effect.Transitions.linear;261 this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || {});244 if (options && options.transition === false) options.transition = Effect.Transitions.linear; 245 this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { }); 262 246 this.currentFrame = 0; 263 247 this.state = 'idle'; … … 269 253 270 254 eval('this.render = function(pos){ '+ 271 'if (this.state=="idle"){this.state="running";'+272 codeForEvent( options,'beforeSetup')+255 'if (this.state=="idle"){this.state="running";'+ 256 codeForEvent(this.options,'beforeSetup')+ 273 257 (this.setup ? 'this.setup();':'')+ 274 codeForEvent( options,'afterSetup')+275 '};if (this.state=="running"){'+258 codeForEvent(this.options,'afterSetup')+ 259 '};if (this.state=="running"){'+ 276 260 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+ 277 261 'this.position=pos;'+ 278 codeForEvent( options,'beforeUpdate')+262 codeForEvent(this.options,'beforeUpdate')+ 279 263 (this.update ? 'this.update(pos);':'')+ 280 codeForEvent( options,'afterUpdate')+264 codeForEvent(this.options,'afterUpdate')+ 281 265 '}}'); 282 266 283 267 this.event('beforeStart'); 284 if (!this.options.sync)285 Effect.Queues.get( typeof this.options.queue == 'string'?268 if (!this.options.sync) 269 Effect.Queues.get(Object.isString(this.options.queue) ? 286 270 'global' : this.options.queue.scope).add(this); 287 271 }, 288 272 loop: function(timePos) { 289 if (timePos >= this.startOn) {290 if (timePos >= this.finishOn) {273 if (timePos >= this.startOn) { 274 if (timePos >= this.finishOn) { 291 275 this.render(1.0); 292 276 this.cancel(); 293 277 this.event('beforeFinish'); 294 if (this.finish) this.finish();278 if (this.finish) this.finish(); 295 279 this.event('afterFinish'); 296 280 return; 297 281 } 298 282 var pos = (timePos - this.startOn) / this.totalTime, 299 frame = Math.round(pos * this.totalFrames);300 if (frame > this.currentFrame) {283 frame = (pos * this.totalFrames).round(); 284 if (frame > this.currentFrame) { 301 285 this.render(pos); 302 286 this.currentFrame = frame; … … 305 289 }, 306 290 cancel: function() { 307 if (!this.options.sync)308 Effect.Queues.get( typeof this.options.queue == 'string'?291 if (!this.options.sync) 292 Effect.Queues.get(Object.isString(this.options.queue) ? 309 293 'global' : this.options.queue.scope).remove(this); 310 294 this.state = 'finished'; 311 295 }, 312 296 event: function(eventName) { 313 if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);314 if (this.options[eventName]) this.options[eventName](this);297 if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); 298 if (this.options[eventName]) this.options[eventName](this); 315 299 }, 316 300 inspect: function() { 317 301 var data = $H(); 318 302 for(property in this) 319 if (typeof this[property] != 'function') data[property] = this[property];303 if (!Object.isFunction(this[property])) data.set(property, this[property]); 320 304 return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>'; 321 305 } 322 } 323 324 Effect.Parallel = Class.create(); 325 Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { 306 }); 307 308 Effect.Parallel = Class.create(Effect.Base, { 326 309 initialize: function(effects) { 327 310 this.effects = effects || []; … … 336 319 effect.cancel(); 337 320 effect.event('beforeFinish'); 338 if (effect.finish) effect.finish(position);321 if (effect.finish) effect.finish(position); 339 322 effect.event('afterFinish'); 340 323 }); … … 342 325 }); 343 326 344 Effect.Event = Class.create(); 345 Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), { 327 Effect.Tween = Class.create(Effect.Base, { 328 initialize: function(object, from, to) { 329 object = Object.isString(object) ? $(object) : object; 330 var args = $A(arguments), method = args.last(), 331 options = args.length == 5 ? args[3] : null; 332 this.method = Object.isFunction(method) ? method.bind(object) : 333 Object.isFunction(object[method]) ? object[method].bind(object) : 334 function(value) { object[method] = value }; 335 this.start(Object.extend({ from: from, to: to }, options || { })); 336 }, 337 update: function(position) { 338 this.method(position); 339 } 340 }); 341 342 Effect.Event = Class.create(Effect.Base, { 346 343 initialize: function() { 347 var options = Object.extend({ 348 duration: 0 349 }, arguments[0] || {}); 350 this.start(options); 344 this.start(Object.extend({ duration: 0 }, arguments[0] || { })); 351 345 }, 352 346 update: Prototype.emptyFunction 353 347 }); 354 348 355 Effect.Opacity = Class.create(); 356 Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { 349 Effect.Opacity = Class.create(Effect.Base, { 357 350 initialize: function(element) { 358 351 this.element = $(element); 359 if (!this.element) throw(Effect._elementDoesNotExistError);352 if (!this.element) throw(Effect._elementDoesNotExistError); 360 353 // make this work on IE on elements without 'layout' 361 if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))354 if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) 362 355 this.element.setStyle({zoom: 1}); 363 356 var options = Object.extend({ 364 357 from: this.element.getOpacity() || 0.0,