Changeset 5012
- Timestamp:
- 09/05/06 04:17:06 (2 years ago)
- Files:
-
- trunk/actionpack/CHANGELOG (modified) (1 diff)
- trunk/actionpack/lib/action_view/helpers/javascripts/prototype.js (modified) (43 diffs)
- trunk/railties/CHANGELOG (modified) (1 diff)
- trunk/railties/html/javascripts/prototype.js (modified) (43 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r5004 r5012 1 1 *SVN* 2 3 * Update to Prototype 1.5.0_rc1 [sam] 2 4 3 5 * Added access to nested attributes in RJS #4548 [richcollins@gmail.com]. Examples: trunk/actionpack/lib/action_view/helpers/javascripts/prototype.js
r4375 r5012 1 /* Prototype JavaScript framework, version 1.5.0_rc 01 /* Prototype JavaScript framework, version 1.5.0_rc1 2 2 * (c) 2005 Sam Stephenson <sam@conio.net> 3 3 * … … 8 8 9 9 var Prototype = { 10 Version: '1.5.0_rc 0',10 Version: '1.5.0_rc1', 11 11 ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', 12 12 … … 32 32 } 33 33 34 Object.inspect = function(object) { 35 try { 36 if (object == undefined) return 'undefined'; 37 if (object == null) return 'null'; 38 return object.inspect ? object.inspect() : object.toString(); 39 } catch (e) { 40 if (e instanceof RangeError) return '...'; 41 throw e; 42 } 43 } 34 Object.extend(Object, { 35 inspect: function(object) { 36 try { 37 if (object == undefined) return 'undefined'; 38 if (object == null) return 'null'; 39 return object.inspect ? object.inspect() : object.toString(); 40 } catch (e) { 41 if (e instanceof RangeError) return '...'; 42 throw e; 43 } 44 }, 45 46 keys: function(object) { 47 var keys = []; 48 for (var property in object) 49 keys.push(property); 50 return keys; 51 }, 52 53 values: function(object) { 54 var values = []; 55 for (var property in object) 56 values.push(object[property]); 57 return values; 58 }, 59 60 clone: function(object) { 61 return Object.extend({}, object); 62 } 63 }); 44 64 45 65 Function.prototype.bind = function() { … … 51 71 52 72 Function.prototype.bindAsEventListener = function(object) { 53 var __method = this ;73 var __method = this, args = $A(arguments), object = args.shift(); 54 74 return function(event) { 55 return __method. call(object, event || window.event);75 return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments))); 56 76 } 57 77 } … … 103 123 104 124 registerCallback: function() { 105 setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 125 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 126 }, 127 128 stop: function() { 129 if (!this.timer) return; 130 clearInterval(this.timer); 131 this.timer = null; 106 132 }, 107 133 … … 110 136 try { 111 137 this.currentlyExecuting = true; 112 this.callback( );138 this.callback(this); 113 139 } finally { 114 140 this.currentlyExecuting = false; … … 196 222 var pairs = this.match(/^\??(.*)$/)[1].split('&'); 197 223 return pairs.inject({}, function(params, pairString) { 198 var pair = pairString.split('='); 199 params[pair[0]] = pair[1]; 224 var pair = pairString.split('='); 225 var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; 226 params[decodeURIComponent(pair[0])] = value; 200 227 return params; 201 228 }); … … 222 249 }, 223 250 224 inspect: function() { 225 return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; 251 inspect: function(useDoubleQuotes) { 252 var escapedString = this.replace(/\\/g, '\\\\'); 253 if (useDoubleQuotes) 254 return '"' + escapedString.replace(/"/g, '\\"') + '"'; 255 else 256 return "'" + escapedString.replace(/'/g, '\\\'') + "'"; 226 257 } 227 258 }); … … 281 312 282 313 any: function(iterator) { 283 var result = true;314 var result = false; 284 315 this.each(function(value, index) { 285 316 if (result = !!(iterator || Prototype.K)(value, index)) … … 500 531 }, 501 532 533 reduce: function() { 534 return this.length > 1 ? this : this[0]; 535 }, 536 537 uniq: function() { 538 return this.inject([], function(array, value) { 539 return array.include(value) ? array : array.concat([value]); 540 }); 541 }, 542 502 543 inspect: function() { 503 544 return '[' + this.map(Object.inspect).join(', ') + ']'; … … 562 603 _each: function(iterator) { 563 604 var value = this.start; 564 do{605 while (this.include(value)) { 565 606 iterator(value); 566 607 value = value.succ(); 567 } while (this.include(value));608 } 568 609 }, 569 610 … … 672 713 /* Simulate other verbs over post */ 673 714 if (this.options.method != 'get' && this.options.method != 'post') { 674 parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method 675 this.options.method = 'post' 715 parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method; 716 this.options.method = 'post'; 676 717 } 677 718 … … 686 727 this.options.asynchronous); 687 728 688 if (this.options.asynchronous) { 689 this.transport.onreadystatechange = this.onStateChange.bind(this); 690 setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); 691 } 692 729 if (this.options.asynchronous) 730 setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); 731 732 this.transport.onreadystatechange = this.onStateChange.bind(this); 693 733 this.setRequestHeaders(); 694 734 695 735 var body = this.options.postBody ? this.options.postBody : parameters; 696 736 this.transport.send(this.options.method == 'post' ? body : null); 737 738 /* Force Firefox to handle ready state 4 for synchronous requests */ 739 if (!this.options.asynchronous && this.transport.overrideMimeType) 740 this.onStateChange(); 697 741 698 742 } catch (e) { … … 853 897 854 898 stop: function() { 855 this.updater.o nComplete = undefined;899 this.updater.options.onComplete = undefined; 856 900 clearTimeout(this.timer); 857 901 (this.onComplete || Prototype.emptyFunction).apply(this, arguments); … … 881 925 results.push(Element.extend(element)); 882 926 } 883 return results. length < 2 ? results[0] : results;927 return results.reduce(); 884 928 } 885 929 … … 903 947 904 948 if (!element._extended && element.tagName && element != window) { 905 var methods = Element.Methods, cache = Element.extend.cache; 906 for (property in methods) { 949 var methods = Object.clone(Element.Methods), cache = Element.extend.cache; 950 951 if (element.tagName == 'FORM') 952 Object.extend(methods, Form.Methods); 953 if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName)) 954 Object.extend(methods, Form.Element.Methods); 955 956 for (var property in methods) { 907 957 var value = methods[property]; 908 958 if (typeof value == 'function') … … 928 978 }, 929 979 930 toggle: function() { 931 for (var i = 0; i < arguments.length; i++) { 932 var element = $(arguments[i]); 933 Element[Element.visible(element) ? 'hide' : 'show'](element); 934 } 935 }, 936 937 hide: function() { 938 for (var i = 0; i < arguments.length; i++) { 939 var element = $(arguments[i]); 940 element.style.display = 'none'; 941 } 942 }, 943 944 show: function() { 945 for (var i = 0; i < arguments.length; i++) { 946 var element = $(arguments[i]); 947 element.style.display = ''; 948 } 980 toggle: function(element) { 981 element = $(element); 982 Element[Element.visible(element) ? 'hide' : 'show'](element); 983 return element; 984 }, 985 986 hide: function(element) { 987 $(element).style.display = 'none'; 988 return element; 989 }, 990 991 show: function(element) { 992 $(element).style.display = ''; 993 return element; 949 994 }, 950 995 … … 952 997 element = $(element); 953 998 element.parentNode.removeChild(element); 999 return element; 954 1000 }, 955 1001 … … 957 1003 $(element).innerHTML = html.stripScripts(); 958 1004 setTimeout(function() {html.evalScripts()}, 10); 1005 return element; 959 1006 }, 960 1007 … … 970 1017 } 971 1018 setTimeout(function() {html.evalScripts()}, 10); 1019 return element; 1020 }, 1021 1022 inspect: function(element) { 1023 element = $(element); 1024 var result = '<' + element.tagName.toLowerCase(); 1025 $H({'id': 'id', 'className': 'class'}).each(function(pair) { 1026 var property = pair.first(), attribute = pair.last(); 1027 var value = (element[property] || '').toString(); 1028 if (value) result += ' ' + attribute + '=' + value.inspect(true); 1029 }); 1030 return result + '>'; 1031 }, 1032 1033 recursivelyCollect: function(element, property) { 1034 element = $(element); 1035 var elements = []; 1036 while (element = element[property]) 1037 if (element.nodeType == 1) 1038 elements.push(Element.extend(element)); 1039 return elements; 1040 }, 1041 1042 ancestors: function(element) { 1043 return $(element).recursivelyCollect('parentNode'); 1044 }, 1045 1046 descendants: function(element) { 1047 element = $(element); 1048 return $A(element.getElementsByTagName('*')); 1049 }, 1050 1051 previousSiblings: function(element) { 1052 return $(element).recursivelyCollect('previousSibling'); 1053 }, 1054 1055 nextSiblings: function(element) { 1056 return $(element).recursivelyCollect('nextSibling'); 1057 }, 1058 1059 siblings: function(element) { 1060 element = $(element); 1061 return element.previousSiblings().reverse().concat(element.nextSiblings()); 1062 }, 1063 1064 match: function(element, selector) { 1065 element = $(element); 1066 if (typeof selector == 'string') 1067 selector = new Selector(selector); 1068 return selector.match(element); 1069 }, 1070 1071 up: function(element, expression, index) { 1072 return Selector.findElement($(element).ancestors(), expression, index); 1073 }, 1074 1075 down: function(element, expression, index) { 1076 return Selector.findElement($(element).descendants(), expression, index); 1077 }, 1078 1079 previous: function(element, expression, index) { 1080 return Selector.findElement($(element).previousSiblings(), expression, index); 1081 }, 1082 1083 next: function(element, expression, index) { 1084 return Selector.findElement($(element).nextSiblings(), expression, index); 1085 }, 1086 1087 getElementsBySelector: function() { 1088 var args = $A(arguments), element = $(args.shift()); 1089 return Selector.findChildElements(element, args); 1090 }, 1091 1092 getElementsByClassName: function(element, className) { 1093 element = $(element); 1094 return document.getElementsByClassName(className, element); 972 1095 }, 973 1096 … … 988 1111 addClassName: function(element, className) { 989 1112 if (!(element = $(element))) return; 990 return Element.classNames(element).add(className); 1113 Element.classNames(element).add(className); 1114 return element; 991 1115 }, 992 1116 993 1117 removeClassName: function(element, className) { 994 1118 if (!(element = $(element))) return; 995 return Element.classNames(element).remove(className); 1119 Element.classNames(element).remove(className); 1120 return element; 1121 }, 1122 1123 observe: function() { 1124 Event.observe.apply(Event, arguments); 1125 return $A(arguments).first(); 1126 }, 1127 1128 stopObserving: function() { 1129 Event.stopObserving.apply(Event, arguments); 1130 return $A(arguments).first(); 996 1131 }, 997 1132 … … 1004 1139 Element.remove(node); 1005 1140 } 1141 return element; 1006 1142 }, 1007 1143 … … 1022 1158 y = element.y ? element.y : element.offsetTop; 1023 1159 window.scrollTo(x, y); 1160 return element; 1024 1161 }, 1025 1162 … … 1046 1183 for (var name in style) 1047 1184 element.style[name.camelize()] = style[name]; 1185 return element; 1048 1186 }, 1049 1187 … … 1082 1220 } 1083 1221 } 1222 return element; 1084 1223 }, 1085 1224 … … 1094 1233 element.style.right = ''; 1095 1234 } 1235 return element; 1096 1236 }, 1097 1237 … … 1099 1239 element = $(element); 1100 1240 if (element._overflow) return; 1101 element._overflow = element.style.overflow ;1241 element._overflow = element.style.overflow || 'auto'; 1102 1242 if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') 1103 1243 element.style.overflow = 'hidden'; 1244 return element; 1104 1245 }, 1105 1246 1106 1247 undoClipping: function(element) { 1107 1248 element = $(element); 1108 if (element._overflow) return; 1109 element.style.overflow = element._overflow; 1110 element._overflow = undefined; 1249 if (!element._overflow) return; 1250 element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; 1251 delete element._overflow; 1252 return element; 1253 } 1254 } 1255 1256 // IE is missing .innerHTML support for TABLE-related elements 1257 if(document.all){ 1258 Element.Methods.update = function(element, html) { 1259 element = $(element); 1260 var tagName = element.tagName.toUpperCase(); 1261 if (['THEAD','TBODY','TR','TD'].indexOf(tagName) > -1) { 1262 var div = document.createElement('div'); 1263 switch (tagName) { 1264 case 'THEAD': 1265 case 'TBODY': 1266 div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>'; 1267 depth = 2; 1268 break; 1269 case 'TR': 1270 div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>'; 1271 depth = 3; 1272 break; 1273 case 'TD': 1274 div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>'; 1275 depth = 4; 1276 } 1277 $A(element.childNodes).each(function(node){ 1278 element.removeChild(node) 1279 }); 1280 depth.times(function(){ div = div.firstChild }); 1281 1282 $A(div.childNodes).each( 1283 function(node){ element.appendChild(node) }); 1284 } else { 1285 element.innerHTML = html.stripScripts(); 1286 } 1287 setTimeout(function() {html.evalScripts()}, 10); 1288 return element; 1111 1289 } 1112 1290 } … … 1116 1294 var _nativeExtensions = false; 1117 1295 1118 if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { 1119 var HTMLElement = {} 1120 HTMLElement.prototype = document.createElement('div').__proto__; 1296 if (!window.HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { 1297 /* Emulate HTMLElement, HTMLFormElement, HTMLInputElement, HTMLTextAreaElement, 1298 and HTMLSelectElement in Safari */ 1299 ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) { 1300 var klass = window['HTML' + tag + 'Element'] = {}; 1301 klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__; 1302 }); 1121 1303 } 1122 1304 … … 1124 1306 Object.extend(Element.Methods, methods || {}); 1125 1307 1126 if(typeof HTMLElement != 'undefined') {1127 var methods = Element.Methods,cache = Element.extend.cache;1128 for ( property in methods) {1308 function copy(methods, destination) { 1309 var cache = Element.extend.cache; 1310 for (var property in methods) { 1129 1311 var value = methods[property]; 1130 if (typeof value == 'function') 1131 HTMLElement.prototype[property] = cache.findOrStore(value); 1132 } 1312 destination[property] = cache.findOrStore(value); 1313 } 1314 } 1315 1316 if (typeof HTMLElement != 'undefined') { 1317 copy(Element.Methods, HTMLElement.prototype); 1318 copy(Form.Methods, HTMLFormElement.prototype); 1319 [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) { 1320 copy(Form.Element.Methods, klass.prototype); 1321 }); 1133 1322 _nativeExtensions = true; 1134 1323 } 1135 1324 } 1136 1137 Element.addMethods();1138 1325 1139 1326 var Toggle = new Object(); … … 1373 1560 } 1374 1561 1562 Object.extend(Selector, { 1563 matchElements: function(elements, expression) { 1564 var selector = new Selector(expression); 1565 return elements.select(selector.match.bind(selector)); 1566 }, 1567 1568 findElement: function(elements, expression, index) { 1569 if (typeof expression == 'number') index = expression, expression = false; 1570 return Selector.matchElements(elements, expression || '*')[index || 0]; 1571 }, 1572 1573 findChildElements: function(element, expressions) { 1574 return expressions.map(function(expression) { 1575 return expression.strip().split(/\s+/).inject([null], function(results, expr) { 1576 var selector = new Selector(expr); 1577 return results.inject([], function(elements, result) { 1578 return elements.concat(selector.findElements(result || element)); 1579 }); 1580 }); 1581 }).flatten(); 1582 } 1583 }); 1584 1375 1585 function $$() { 1376 return $A(arguments).map(function(expression) { 1377 return expression.strip().split(/\s+/).inject([null], function(results, expr) { 1378 var selector = new Selector(expr); 1379 return results.map(selector.findElements.bind(selector)).flatten(); 1380 }); 1381 }).flatten(); 1382 } 1383 var Field = { 1384 clear: function() { 1385 for (var i = 0; i < arguments.length; i++) 1386 $(arguments[i]).value = ''; 1387 }, 1388 1389 focus: function(element) { 1390 $(element).focus(); 1391 }, 1392 1393 present: function() { 1394 for (var i = 0; i < arguments.length; i++) 1395 if ($(arguments[i]).value == '') return false; 1396 return true; 1397 }, 1398 1399 select: function(element) { 1400 $(element).select(); 1401 }, 1402 1403 activate: function(element) { 1404 element = $(element); 1405 element.focus(); 1406 if (element.select) 1407 element.select(); 1408 } 1409 } 1410 1411 /*--------------------------------------------------------------------------*/ 1412 1586 return Selector.findChildElements(document, $A(arguments)); 1587 } 1413 1588 var Form = { 1589 reset: function(form) { 1590 $(form).reset(); 1591 return form; 1592 } 1593 }; 1594 1595 Form.Methods = { 1414 1596 serialize: function(form) { 1415 1597 var elements = Form.getElements($(form)); … … 1457 1639 1458 1640 disable: function(form) { 1641 form = $(form); 1459 1642 var elements = Form.getElements(form); 1460 1643 for (var i = 0; i < elements.length; i++) { … … 1463 1646 element.disabled = 'true'; 1464 1647 } 1648 return form; 1465 1649 }, 1466 1650 1467 1651 enable: function(form) { 1652 form = $(form); 1468 1653 var elements = Form.getElements(form); 1469 1654 for (var i = 0; i < elements.length; i++) { … … 1471 1656 element.disabled = ''; 1472 1657 } 1658 return form; 1473 1659 }, 1474 1660 … … 1481 1667 1482 1668 focusFirstElement: function(form) { 1669 form = $(form); 1483 1670 Field.activate(Form.findFirstElement(form)); 1484 }, 1485 1486 reset: function(form) { 1487 $(form).reset(); 1488 } 1489 } 1671 return form; 1672 } 1673 } 1674 1675 Object.extend(Form, Form.Methods); 1676 1677 /*--------------------------------------------------------------------------*/ 1490 1678 1491 1679 Form.Element = { 1680 focus: function(element) { 1681 $(element).focus(); 1682 return element; 1683 }, 1684 1685 select: function(element) { 1686 $(element).select(); 1687 return element; 1688 } 1689 } 1690 1691 Form.Element.Methods = { 1492 1692 serialize: function(element) { 1493 1693 element = $(element); … … 1515 1715 if (parameter) 1516 1716 return parameter[1]; 1517 } 1518 } 1717 }, 1718 1719 clear: function(element) { 1720 $(element).value = ''; 1721 return element; 1722 }, 1723 1724 present: function(element) { 1725 return $(element).value != ''; 1726 }, 1727 1728 activate: function(element) { 1729 element = $(element); 1730 element.focus(); 1731 if (element.select) 1732 element.select(); 1733 return element; 1734 }, 1735 1736 disable: function(element) { 1737 element = $(element); 1738 element.disabled = ''; 1739 return element; 1740 }, 1741 1742 enable: function(element) { 1743 element = $(element); 1744 element.blur(); 1745 element.disabled = 'true'; 1746 return element; 1747 } 1748 } 1749 1750 Object.extend(Form.Element, Form.Element.Methods); 1751 var Field = Form.Element; 1752 1753 /*--------------------------------------------------------------------------*/ 1519 1754 1520 1755 Form.Element.Serializers = { 1521 1756 input: function(element) { 1522 1757 switch (element.type.toLowerCase()) { 1523 case 'submit':1524 case 'hidden':1525 case 'password':1526 case 'text':1527 return Form.Element.Serializers.textarea(element);1528 1758 case 'checkbox': 1529 1759 case 'radio': 1530 1760 return Form.Element.Serializers.inputSelector(element); 1761 default: 1762 return Form.Element.Serializers.textarea(element); 1531 1763 } 1532 1764 return false; … … 1647 1879 Event.observe(element, 'click', this.onElementEvent.bind(this)); 1648 1880 break; 1649 case 'password': 1650 case 'text': 1651 case 'textarea': 1652 case 'select-one': 1653 case 'select-multiple': 1881 default: 1654 1882 Event.observe(element, 'change', this.onElementEvent.bind(this)); 1655 1883 break; … … 1686 1914 KEY_DOWN: 40, 1687 1915 KEY_DELETE: 46, 1916 KEY_HOME: 36, 1917 KEY_END: 35, 1918 KEY_PAGEUP: 33, 1919 KEY_PAGEDOWN: 34, 1688 1920 1689 1921 element: function(event) { … … 1749 1981 1750 1982 observe: function(element, name, observer, useCapture) { 1751 varelement = $(element);1983 element = $(element); 1752 1984 useCapture = useCapture || false; 1753 1985 … … 1757 1989 name = 'keydown'; 1758 1990 1759 this._observeAndCache(element, name, observer, useCapture);1991 Event._observeAndCache(element, name, observer, useCapture); 1760 1992 }, 1761 1993 1762 1994 stopObserving: function(element, name, observer, useCapture) { 1763 varelement = $(element);1995 element = $(element); 1764 1996 useCapture = useCapture || false; 1765 1997 … … 1772 2004 element.removeEventListener(name, observer, useCapture); 1773 2005 } else if (element.detachEvent) { 1774 element.detachEvent('on' + name, observer); 2006 try { 2007 element.detachEvent('on' + name, observer); 2008 } catch (e) {} 1775 2009 } 1776 2010 } … … 1882 2116 }, 1883 2117 1884 clone: function(source, target) {1885 source = $(source);1886 target = $(target);1887 target.style.position = 'absolute';1888 var offsets = this.cumulativeOffset(source);1889 target.style.top = offsets[1] + 'px';1890 target.style.left = offsets[0] + 'px';1891 target.style.width = source.offsetWidth + 'px';1892 target.style.height = source.offsetHeight + 'px';1893 },1894 1895 2118 page: function(forElement) { 1896 2119 var valueT = 0, valueL = 0; … … 1909 2132 element = forElement; 1910 2133 do { 1911 valueT -= element.scrollTop || 0; 1912 valueL -= element.scrollLeft || 0; 2134 if (!window.opera || element.tagName=='BODY') { 2135 valueT -= element.scrollTop || 0; 2136 valueL -= element.scrollLeft || 0; 2137 } 1913 2138 } while (element = element.parentNode); 1914 2139 … … 2011 2236 } 2012 2237 } 2238 2239 Element.addMethods(); trunk/railties/CHANGELOG
r4960 r5012 1 1 *SVN* 2 3 * Update to Prototype 1.5.0_rc1 [sam] 2 4 3 5 * Formally Deprecate the old rake tasks. [Koz] trunk/railties/html/javascripts/prototype.js
r4376 r5012 1 /* Prototype JavaScript framework, version 1.5.0_rc 01 /* Prototype JavaScript framework, version 1.5.0_rc1 2 2 * (c) 2005 Sam Stephenson <sam@conio.net> 3 3 * … … 8 8 9 9 var Prototype = { 10 Version: '1.5.0_rc 0',10 Version: '1.5.0_rc1', 11 11 ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', 12 12 … … 32 32 } 33 33 34 Object.inspect = function(object) { 35 try { 36 if (object == undefined) return 'undefined'; 37 if (object == null) return 'null'; 38 return object.inspect ? object.inspect() : object.toString(); 39 } catch (e) { 40 if (e instanceof RangeError) return '...'; 41 throw e; 42 } 43 } 34 Object.extend(Object, { 35 inspect: function(object) { 36 try { 37 if (object == undefined) return 'undefined'; 38 if (object == null) return 'null'; 39 return object.inspect ? object.inspect() : object.toString(); 40 } catch (e) { 41 if (e instanceof RangeError) return '...'; 42 throw e; 43 } 44 }, 45 46 keys: function(object) { 47 var keys = []; 48 for (var property in object) 49 keys.push(property); 50 return keys; 51 }, 52 53 values: function(object) { 54 var values = []; 55 for (var property in object) 56 values.push(object[property]); 57 return values; 58 }, 59 60 clone: function(object) { 61 return Object.extend({}, object); 62 } 63 }); 44 64 45 65 Function.prototype.bind = function() { … … 51 71 52 72 Function.prototype.bindAsEventListener = function(object) { 53 var __method = this ;73 var __method = this, args = $A(arguments), object = args.shift(); 54 74 return function(event) { 55 return __method. call(object, event || window.event);75 return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments))); 56 76 } 57 77 } … … 103 123 104 124 registerCallback: function() { 105 setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 125 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 126 }, 127 128 stop: function() { 129 if (!this.timer) return; 130 clearInterval(this.timer); 131 this.timer = null; 106 132 }, 107 133 … … 110 136 try { 111 137 this.currentlyExecuting = true; 112 this.callback( );138 this.callback(this); 113 139 } finally { 114 140 this.currentlyExecuting = false; … … 196 222 var pairs = this.match(/^\??(.*)$/)[1].split('&'); 197 223 return pairs.inject({}, function(params, pairString) { 198 var pair = pairString.split('='); 199 params[pair[0]] = pair[1]; 224 var pair = pairString.split('='); 225 var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; 226 params[decodeURIComponent(pair[0])] = value; 200 227 return params; 201 228 }); … … 222 249 }, 223 250 224 inspect: function() { 225 return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; 251 inspect: function(useDoubleQuotes) { 252 var escapedString = this.replace(/\\/g, '\\\\'); 253 if (useDoubleQuotes) 254 return '"' + escapedString.replace(/"/g, '\\"') + '"'; 255 else 256 return "'" + escapedString.replace(/'/g, '\\\'') + "'"; 226 257 } 227 258 }); … … 281 312 282 313 any: function(iterator) { 283 var result = true;314 var result = false; 284 315 this.each(function(value, index) { 285 316 if (result = !!(iterator || Prototype.K)(value, index)) … … 500 531 }, 501 532 533 reduce: function() { 534 return this.length > 1 ? this : this[0]; 535 }, 536 537 uniq: function() { 538 return this.inject([], function(array, value) { 539 return array.include(value) ? array : array.concat([value]); 540 }); 541 }, 542 502 543 inspect: function() { 503 544 return '[' + this.map(Object.inspect).join(', ') + ']'; … … 562 603 _each: function(iterator) { 563 604 var value = this.start; 564 do{605 while (this.include(value)) { 565 606 iterator(value); 566 607 value = value.succ(); 567 } while (this.include(value));608 } 568 609 }, 569 610 … … 672 713 /* Simulate other verbs over post */ 673 714 if (this.options.method != 'get' && this.options.method != 'post') { 674 parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method 675 this.options.method = 'post' 715 parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method; 716 this.options.method = 'post'; 676 717 } 677 718 … … 686 727 this.options.asynchronous); 687 728 688 if (this.options.asynchronous) { 689 this.transport.onreadystatechange = this.onStateChange.bind(this); 690 setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); 691 } 692 729 if (this.options.asynchronous) 730 setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); 731 732 this.transport.onreadystatechange = this.onStateChange.bind(this); 693 733 this.setRequestHeaders(); 694 734 695 735 var body = this.options.postBody ? this.options.postBody : parameters; 696 736 this.transport.send(this.options.method == 'post' ? body : null); 737 738 /* Force Firefox to handle ready state 4 for synchronous requests */ 739 if (!this.options.asynchronous && this.transport.overrideMimeType) 740 this.onStateChange(); 697 741 698 742 } catch (e) { … … 853 897 854 898 stop: function() { 855 this.updater.o nComplete = undefined;899 this.updater.options.onComplete = undefined; 856 900 clearTimeout(this.timer); 857 901 (this.onComplete || Prototype.emptyFunction).apply(this, arguments); … … 881 925 results.push(Element.extend(element)); 882 926 } 883 return results. length < 2 ? results[0] : results;927 return results.reduce(); 884 928 } 885 929 … … 903 947 904 948 if (!element._extended && element.tagName && element != window) { 905 var methods = Element.Methods, cache = Element.extend.cache; 906 for (property in methods) { 949 var methods = Object.clone(Element.Methods), cache = Element.extend.cache; 950 951 if (element.tagName == 'FORM') 952 Object.extend(methods, Form.Methods); 953 if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName)) 954 Object.extend(methods, Form.Element.Methods); 955 956 for (var property in methods) { 907 957 var value = methods[property]; 908 958 if (typeof value == 'function') … … 928 978 }, 929 979 930 toggle: function() { 931 for (var i = 0; i < arguments.length; i++) { 932 var element = $(arguments[i]); 933 Element[Element.visible(element) ? 'hide' : 'show'](element); 934 } 935 }, 936 937 hide: function() { 938 for (var i = 0; i < arguments.length; i++) { 939 var element = $(arguments[i]); 940 element.style.display = 'none'; 941 } 942 }, 943 944 show: function() { 945 for (var i = 0; i < arguments.length; i++) { 946 var element = $(arguments[i]); 947 element.style.display = ''; 948 } 980 toggle: function(element) { 981 element = $(element); 982 Element[Element.visible(element) ? 'hide' : 'show'](element); 983 return element; 984 }, 985 986 hide: function(element) { 987 $(element).style.display = 'none'; 988 return element; 989 }, 990 991 show: function(element) { 992 $(element).style.display = ''; 993 return element; 949 994 }, 950 995 … … 952 997 element = $(element); 953 998 element.parentNode.removeChild(element); 999 return element; 954 1000 }, 955 1001 … … 957 1003 $(element).innerHTML = html.stripScripts(); 958 1004 setTimeout(function() {html.evalScripts()}, 10); 1005 return element; 959 1006 }, 960 1007 … … 970 1017 } 971 1018 setTimeout(function() {html.evalScripts()}, 10); 1019 return element; 1020 }, 1021 1022 inspect: function(element) { 1023 element = $(element); 1024 var result = '<' + element.tagName.toLowerCase(); 1025 $H({'id': 'id', 'className': 'class'}).each(function(pair) { 1026 var property = pair.first(), attribute = pair.last(); 1027 var value = (element[property] || '').toString(); 1028 if (value) result += ' ' + attribute + '=' + value.inspect(true); 1029 }); 1030 return result + '>'; 1031 }, 1032 1033 recursivelyCollect: function(element, property) { 1034 element = $(element); 1035 var elements = []; 1036 while (element = element[property]) 1037 if (element.nodeType == 1) 1038 elements.push(Element.extend(element)); 1039 return elements; 1040 }, 1041 1042 ancestors: function(element) { 1043 return $(element).recursivelyCollect('parentNode'); 1044 }, 1045 1046 descendants: function(element) { 1047 element = $(element); 1048 return $A(element.getElementsByTagName('*')); 1049 }, 1050 1051 previousSiblings: function(element) { 1052 return $(element).recursivelyCollect('previousSibling'); 1053 }, 1054 1055 nextSiblings: function(element) { 1056 return $(element).recursivelyCollect('nextSibling'); 1057 }, 1058 1059 siblings: function(element) { 1060 element = $(element); 1061 return element.previousSiblings().reverse().concat(element.nextSiblings()); 1062 }, 1063 1064 match: function(element, selector) { 1065 element = $(element); 1066 if (typeof selector == 'string') 1067 selector = new Selector(selector); 1068 return selector.match(element); 1069 }, 1070 1071 up: function(element, expression, index) { 1072 return Selector.findElement($(element).ancestors(), expression, index); 1073 }, 1074 1075 down: function(element, expression, index) { 1076 return Selector.findElement($(element).descendants(), expression, index); 1077 }, 1078 1079 previous: function(element, expression, index) { 1080 return Selector.findElement($(element).previousSiblings(), expression, index); 1081 }, 1082 1083 next: function(element, expression, index) { 1084 return Selector.findElement($(element).nextSiblings(), expression, index); 1085 }, 1086 1087 getElementsBySelector: function() { 1088 var args = $A(arguments), element = $(args.shift()); 1089 return Selector.findChildElements(element, args); 1090 }, 1091 1092 getElementsByClassName: function(element, className) { 1093 element = $(element); 1094 return document.getElementsByClassName(className, element); 972 1095 }, 973 1096 … … 988 1111 addClassName: function(element, className) { 989 1112 if (!(element = $(element))) return; 990 return Element.classNames(element).add(className); 1113 Element.classNames(element).add(className); 1114 return element; 991 1115 }, 992 1116 993 1117 removeClassName: function(element, className) { 994 1118 if (!(element = $(element))) return; 995 return Element.classNames(element).remove(className); <