public
Fork of rails/rails
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/JackDanger/rails.git
Apply [5970] to 1.2 branch

git-svn-id: 
http://svn-commit.rubyonrails.org/rails/branches/1-2-pre-release@5971 
5ecf4fe2-1ee6-0310-87b1-e25e094e27de
sstephenson (author)
Tue Jan 16 21:05:17 -0800 2007
commit  81b94c2f106f615eaca40b14e1c6ef150a56319c
tree    5c9c96596f2b3c938d8f05489195c303fd742e9f
parent  a3dafb07ec64d3ae7f4fe1becf3b51105901418e
...
1
2
 
 
3
4
5
...
1
2
3
4
5
6
7
0
@@ -1,5 +1,7 @@
0
 *1.13.0* (January 16th, 2007)
0
 
0
+* Update to Prototype 1.5.0. [Sam Stephenson]
0
+
0
 * Allow exempt_from_layout :rhtml. #6742, #7026 [dcmanges, Squeegy]
0
 
0
 * Fix parsing of array[] CGI parameters so extra empty values aren't included. #6252 [Nicholas Seckar, aiwilliams, brentrowland]
...
1
 
2
3
4
...
7
8
9
10
 
11
12
13
...
629
630
631
632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
633
634
635
636
 
637
638
639
...
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
 
 
 
 
 
 
 
 
 
674
675
 
 
 
 
676
677
678
679
 
 
680
681
682
...
684
685
686
687
 
688
689
690
691
692
693
694
 
 
 
695
696
697
...
785
786
787
788
789
 
 
790
791
792
...
804
805
806
807
808
 
 
809
810
 
811
812
813
 
 
814
815
816
 
 
817
818
819
820
821
 
 
822
823
824
825
826
 
827
828
829
...
832
833
834
835
836
 
837
838
839
...
1054
1055
1056
1057
 
1058
1059
1060
...
1071
1072
1073
1074
 
1075
1076
1077
...
1100
1101
1102
1103
 
1104
1105
1106
...
1108
1109
1110
1111
 
1112
1113
1114
...
1146
1147
1148
 
1149
1150
1151
...
1238
1239
1240
1241
 
 
 
 
 
 
 
 
 
1242
1243
1244
1245
 
 
 
 
 
1246
1247
1248
...
1304
1305
1306
1307
 
1308
1309
1310
...
1320
1321
1322
1323
1324
1325
 
 
 
 
1326
1327
1328
1329
 
1330
1331
 
1332
1333
1334
...
1356
1357
1358
 
 
 
1359
1360
1361
1362
1363
1364
1365
 
1366
1367
1368
...
1370
1371
1372
1373
 
 
1374
1375
1376
...
1378
1379
1380
 
1381
1382
1383
 
1384
1385
1386
 
1387
1388
1389
...
1434
1435
1436
1437
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1438
1439
1440
 
 
1441
1442
1443
 
1444
1445
1446
 
1447
1448
1449
...
1477
1478
1479
1480
 
1481
1482
1483
...
1644
1645
1646
1647
 
1648
1649
1650
...
1691
1692
1693
1694
 
1695
1696
1697
1698
1699
 
1700
1701
1702
 
1703
1704
1705
...
1712
1713
1714
1715
 
1716
1717
1718
...
1723
1724
1725
 
1726
1727
1728
...
1762
1763
1764
1765
 
1766
1767
1768
...
1781
1782
1783
1784
1785
1786
1787
1788
1789
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1790
1791
1792
1793
1794
1795
 
 
1796
1797
1798
...
1807
1808
1809
1810
 
1811
1812
1813
 
1814
1815
 
1816
1817
1818
 
1819
1820
1821
...
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
 
 
 
 
 
 
 
1890
 
1891
1892
1893
1894
1895
1896
1897
1898
1899
 
1900
1901
1902
...
1933
1934
1935
 
1936
1937
1938
...
1945
1946
1947
1948
1949
1950
1951
1952
1953
 
1954
1955
1956
1957
 
1958
1959
1960
1961
 
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
 
 
1973
1974
1975
1976
1977
1978
1979
1980
1981
 
 
 
 
 
 
1982
1983
 
 
 
 
 
 
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
...
2382
2383
2384
2385
2386
2387
2388
 
 
 
 
2389
2390
2391
...
 
1
2
3
4
...
7
8
9
 
10
11
12
13
...
629
630
631
 
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
 
668
669
670
671
...
689
690
691
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
 
 
 
708
709
710
711
712
...
714
715
716
 
717
718
719
 
 
 
 
 
720
721
722
723
724
725
...
813
814
815
 
 
816
817
818
819
820
...
832
833
834
 
 
835
836
837
 
838
839
 
 
840
841
842
843
 
844
845
846
847
 
 
 
848
849
850
851
852
853
 
854
855
856
857
...
860
861
862
 
 
863
864
865
866
...
1081
1082
1083
 
1084
1085
1086
1087
...
1098
1099
1100
 
1101
1102
1103
1104
...
1127
1128
1129
 
1130
1131
1132
1133
...
1135
1136
1137
 
1138
1139
1140
1141
...
1173
1174
1175
1176
1177
1178
1179
...
1266
1267
1268
 
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
 
1281
1282
1283
1284
1285
1286
1287
1288
...
1344
1345
1346
 
1347
1348
1349
1350
...
1360
1361
1362
 
 
 
1363
1364
1365
1366
1367
1368
1369
 
1370
1371
 
1372
1373
1374
1375
...
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
 
1409
1410
1411
1412
...
1414
1415
1416
 
1417
1418
1419
1420
1421
...
1423
1424
1425
1426
1427
1428
 
1429
1430
1431
 
1432
1433
1434
1435
...
1480
1481
1482
 
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
 
1536
1537
1538
 
1539
1540
1541
1542
...
1570
1571
1572
 
1573
1574
1575
1576
...
1737
1738
1739
 
1740
1741
1742
1743
...
1784
1785
1786
 
1787
1788
1789
1790
1791
 
1792
1793
1794
 
1795
1796
1797
1798
...
1805
1806
1807
 
1808
1809
1810
1811
...
1816
1817
1818
1819
1820
1821
1822
...
1856
1857
1858
 
1859
1860
1861
1862
...
1875
1876
1877
 
 
 
 
 
 
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
 
 
1898
1899
1900
1901
1902
...
1911
1912
1913
 
1914
1915
 
 
1916
1917
 
1918
1919
 
 
1920
1921
1922
1923
...
1975
1976
1977
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
 
 
 
 
1992
1993
1994
1995
...
2026
2027
2028
2029
2030
2031
2032
...
2039
2040
2041
 
2042
2043
2044
 
 
2045
2046
2047
2048
 
2049
2050
2051
2052
 
2053
2054
2055
2056
2057
 
 
 
 
 
 
 
2058
2059
2060
2061
2062
 
 
 
 
 
 
2063
2064
2065
2066
2067
2068
2069
 
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
 
 
 
 
2081
2082
2083
...
2470
2471
2472
 
 
 
 
2473
2474
2475
2476
2477
2478
2479
0
@@ -1,4 +1,4 @@
0
-/* Prototype JavaScript framework, version 1.5.0_rc2
0
+/* Prototype JavaScript framework, version 1.5.0
0
  * (c) 2005-2007 Sam Stephenson
0
  *
0
  * Prototype is freely distributable under the terms of an MIT-style license.
0
@@ -7,7 +7,7 @@
0
 /*--------------------------------------------------------------------------*/
0
 
0
 var Prototype = {
0
- Version: '1.5.0_rc2',
0
+ Version: '1.5.0',
0
   BrowserFeatures: {
0
     XPath: !!document.evaluate
0
   },
0
@@ -629,11 +629,43 @@ if(window.opera){
0
     return array;
0
   }
0
 }
0
-var Hash = {
0
+var Hash = function(obj) {
0
+ Object.extend(this, obj || {});
0
+};
0
+
0
+Object.extend(Hash, {
0
+ toQueryString: function(obj) {
0
+ var parts = [];
0
+
0
+ this.prototype._each.call(obj, function(pair) {
0
+ if (!pair.key) return;
0
+
0
+ if (pair.value && pair.value.constructor == Array) {
0
+ var values = pair.value.compact();
0
+ if (values.length < 2) pair.value = values.reduce();
0
+ else {
0
+ key = encodeURIComponent(pair.key);
0
+ values.each(function(value) {
0
+ value = value != undefined ? encodeURIComponent(value) : '';
0
+ parts.push(key + '=' + encodeURIComponent(value));
0
+ });
0
+ return;
0
+ }
0
+ }
0
+ if (pair.value == undefined) pair[1] = '';
0
+ parts.push(pair.map(encodeURIComponent).join('='));
0
+ });
0
+
0
+ return parts.join('&');
0
+ }
0
+});
0
+
0
+Object.extend(Hash.prototype, Enumerable);
0
+Object.extend(Hash.prototype, {
0
   _each: function(iterator) {
0
     for (var key in this) {
0
       var value = this[key];
0
- if (typeof value == 'function') continue;
0
+ if (value && value == Hash.prototype[key]) continue;
0
 
0
       var pair = [key, value];
0
       pair.key = key;
0
@@ -657,26 +689,24 @@ var Hash = {
0
     });
0
   },
0
 
0
- toQueryString: function() {
0
- return this.map(function(pair) {
0
- if (!pair.key) return null;
0
-
0
- if (pair.value && pair.value.constructor == Array) {
0
- pair.value = pair.value.compact();
0
-
0
- if (pair.value.length < 2) {
0
- pair.value = pair.value.reduce();
0
- } else {
0
- var key = encodeURIComponent(pair.key);
0
- return pair.value.map(function(value) {
0
- return key + '=' + encodeURIComponent(value);
0
- }).join('&');
0
+ remove: function() {
0
+ var result;
0
+ for(var i = 0, length = arguments.length; i < length; i++) {
0
+ var value = this[arguments[i]];
0
+ if (value !== undefined){
0
+ if (result === undefined) result = value;
0
+ else {
0
+ if (result.constructor != Array) result = [result];
0
+ result.push(value)
0
         }
0
       }
0
+ delete this[arguments[i]];
0
+ }
0
+ return result;
0
+ },
0
 
0
- if (pair.value == undefined) pair[1] = '';
0
- return pair.map(encodeURIComponent).join('=');
0
- }).join('&');
0
+ toQueryString: function() {
0
+ return Hash.toQueryString(this);
0
   },
0
 
0
   inspect: function() {
0
@@ -684,14 +714,12 @@ var Hash = {
0
       return pair.map(Object.inspect).join(': ');
0
     }).join(', ') + '}>';
0
   }
0
-}
0
+});
0
 
0
 function $H(object) {
0
- var hash = Object.extend({}, object || {});
0
- Object.extend(hash, Enumerable);
0
- Object.extend(hash, Hash);
0
- return hash;
0
-}
0
+ if (object && object.constructor == Hash) return object;
0
+ return new Hash(object);
0
+};
0
 ObjectRange = Class.create();
0
 Object.extend(ObjectRange.prototype, Enumerable);
0
 Object.extend(ObjectRange.prototype, {
0
@@ -785,8 +813,8 @@ Ajax.Base.prototype = {
0
     Object.extend(this.options, options || {});
0
 
0
     this.options.method = this.options.method.toLowerCase();
0
- this.options.parameters = $H(typeof this.options.parameters == 'string' ?
0
- this.options.parameters.toQueryParams() : this.options.parameters);
0
+ if (typeof this.options.parameters == 'string')
0
+ this.options.parameters = this.options.parameters.toQueryParams();
0
   }
0
 }
0
 
0
@@ -804,26 +832,26 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
0
   },
0
 
0
   request: function(url) {
0
- var params = this.options.parameters;
0
- if (params.any()) params['_'] = '';
0
+ this.url = url;
0
+ var params = this.options.parameters, method = this.options.method;
0
 
0
- if (!['get', 'post'].include(this.options.method)) {
0
+ if (!['get', 'post'].include(method)) {
0
       // simulate other verbs over post
0
- params['_method'] = this.options.method;
0
- this.options.method = 'post';
0
+ params['_method'] = method;
0
+ method = 'post';
0
     }
0
 
0
- this.url = url;
0
+ params = Hash.toQueryString(params);
0
+ if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
0
 
0
     // when GET, append parameters to URL
0
- if (this.options.method == 'get' && params.any())
0
- this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') +
0
- params.toQueryString();
0
+ if (method == 'get' && params)
0
+ this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
0
 
0
     try {
0
       Ajax.Responders.dispatch('onCreate', this, this.transport);
0
 
0
- this.transport.open(this.options.method.toUpperCase(), this.url,
0
+ this.transport.open(method.toUpperCase(), this.url,
0
         this.options.asynchronous);
0
 
0
       if (this.options.asynchronous)
0
@@ -832,8 +860,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
0
       this.transport.onreadystatechange = this.onStateChange.bind(this);
0
       this.setRequestHeaders();
0
 
0
- var body = this.options.method == 'post' ?
0
- (this.options.postBody || params.toQueryString()) : null;
0
+ var body = method == 'post' ? (this.options.postBody || params) : null;
0
 
0
       this.transport.send(body);
0
 
0
@@ -1054,7 +1081,7 @@ if (Prototype.BrowserFeatures.XPath) {
0
     for (var i = 0, length = query.snapshotLength; i < length; i++)
0
       results.push(query.snapshotItem(i));
0
     return results;
0
- }
0
+ };
0
 }
0
 
0
 document.getElementsByClassName = function(className, parentElement) {
0
@@ -1071,7 +1098,7 @@ document.getElementsByClassName = function(className, parentElement) {
0
     }
0
     return elements;
0
   }
0
-}
0
+};
0
 
0
 /*--------------------------------------------------------------------------*/
0
 
0
@@ -1100,7 +1127,7 @@ Element.extend = function(element) {
0
 
0
   element._extended = true;
0
   return element;
0
-}
0
+};
0
 
0
 Element.extend.cache = {
0
   findOrStore: function(value) {
0
@@ -1108,7 +1135,7 @@ Element.extend.cache = {
0
       return value.apply(null, [this].concat($A(arguments)));
0
     }
0
   }
0
-}
0
+};
0
 
0
 Element.Methods = {
0
   visible: function(element) {
0
@@ -1146,6 +1173,7 @@ Element.Methods = {
0
 
0
   replace: function(element, html) {
0
     element = $(element);
0
+ html = typeof html == 'undefined' ? '' : html.toString();
0
     if (element.outerHTML) {
0
       element.outerHTML = html.stripScripts();
0
     } else {
0
@@ -1238,11 +1266,23 @@ Element.Methods = {
0
   },
0
 
0
   readAttribute: function(element, name) {
0
- return $(element).getAttribute(name);
0
+ element = $(element);
0
+ if (document.all && !window.opera) {
0
+ var t = Element._attributeTranslations;
0
+ if (t.values[name]) return t.values[name](element, name);
0
+ if (t.names[name]) name = t.names[name];
0
+ var attribute = element.attributes[name];
0
+ if(attribute) return attribute.nodeValue;
0
+ }
0
+ return element.getAttribute(name);
0
   },
0
 
0
   getHeight: function(element) {
0
- return $(element).offsetHeight;
0
+ return $(element).getDimensions().height;
0
+ },
0
+
0
+ getWidth: function(element) {
0
+ return $(element).getDimensions().width;
0
   },
0
 
0
   classNames: function(element) {
0
@@ -1304,7 +1344,7 @@ Element.Methods = {
0
     return $(element).innerHTML.match(/^\s*$/);
0
   },
0
 
0
- childOf: function(element, ancestor) {
0
+ descendantOf: function(element, ancestor) {
0
     element = $(element), ancestor = $(ancestor);
0
     while (element = element.parentNode)
0
       if (element == ancestor) return true;
0
@@ -1320,15 +1360,16 @@ Element.Methods = {
0
 
0
   getStyle: function(element, style) {
0
     element = $(element);
0
- var camelizedStyle = (style == 'float' ?
0
- (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat') : style).camelize();
0
- var value = element.style[camelizedStyle];
0
+ if (['float','cssFloat'].include(style))
0
+ style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
0
+ style = style.camelize();
0
+ var value = element.style[style];
0
     if (!value) {
0
       if (document.defaultView && document.defaultView.getComputedStyle) {
0
         var css = document.defaultView.getComputedStyle(element, null);
0
- value = css ? css[camelizedStyle] : null;
0
+ value = css ? css[style] : null;
0
       } else if (element.currentStyle) {
0
- value = element.currentStyle[camelizedStyle];
0
+ value = element.currentStyle[style];
0
       }
0
     }
0
 
0
@@ -1356,13 +1397,16 @@ Element.Methods = {
0
             !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
0
           if(/MSIE/.test(navigator.userAgent) && !window.opera)
0
             element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
0
+ } else if(value == '') {
0
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
0
+ element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
0
         } else {
0
           if(value < 0.00001) value = 0;
0
           if(/MSIE/.test(navigator.userAgent) && !window.opera)
0
             element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
0
               'alpha(opacity='+value*100+')';
0
         }
0
- } else if(name == 'float') name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
0
+ } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
0
       element.style[name.camelize()] = value;
0
     }
0
     return element;
0
@@ -1370,7 +1414,8 @@ Element.Methods = {
0
 
0
   getDimensions: function(element) {
0
     element = $(element);
0
- if (Element.getStyle(element, 'display') != 'none')
0
+ var display = $(element).getStyle('display');
0
+ if (display != 'none' && display != null) // Safari bug
0
       return {width: element.offsetWidth, height: element.offsetHeight};
0
 
0
     // All *Width and *Height properties give 0 on elements with display none,
0
@@ -1378,12 +1423,13 @@ Element.Methods = {
0
     var els = element.style;
0
     var originalVisibility = els.visibility;
0
     var originalPosition = els.position;
0
+ var originalDisplay = els.display;
0
     els.visibility = 'hidden';
0
     els.position = 'absolute';
0
- els.display = '';
0
+ els.display = 'block';
0
     var originalWidth = element.clientWidth;
0
     var originalHeight = element.clientHeight;
0
- els.display = 'none';
0
+ els.display = originalDisplay;
0
     els.position = originalPosition;
0
     els.visibility = originalVisibility;
0
     return {width: originalWidth, height: originalHeight};
0
@@ -1434,16 +1480,63 @@ Element.Methods = {
0
     element._overflow = null;
0
     return element;
0
   }
0
-}
0
+};
0
+
0
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
0
+
0
+Element._attributeTranslations = {};
0
+
0
+Element._attributeTranslations.names = {
0
+ colspan: "colSpan",
0
+ rowspan: "rowSpan",
0
+ valign: "vAlign",
0
+ datetime: "dateTime",
0
+ accesskey: "accessKey",
0
+ tabindex: "tabIndex",
0
+ enctype: "encType",
0
+ maxlength: "maxLength",
0
+ readonly: "readOnly",
0
+ longdesc: "longDesc"
0
+};
0
+
0
+Element._attributeTranslations.values = {
0
+ _getAttr: function(element, attribute) {
0
+ return element.getAttribute(attribute, 2);
0
+ },
0
+
0
+ _flag: function(element, attribute) {
0
+ return $(element).hasAttribute(attribute) ? attribute : null;
0
+ },
0
+
0
+ style: function(element) {
0
+ return element.style.cssText.toLowerCase();
0
+ },
0
+
0
+ title: function(element) {
0
+ var node = element.getAttributeNode('title');
0
+ return node.specified ? node.nodeValue : null;
0
+ }
0
+};
0
+
0
+Object.extend(Element._attributeTranslations.values, {
0
+ href: Element._attributeTranslations.values._getAttr,
0
+ src: Element._attributeTranslations.values._getAttr,
0
+ disabled: Element._attributeTranslations.values._flag,
0
+ checked: Element._attributeTranslations.values._flag,
0
+ readonly: Element._attributeTranslations.values._flag,
0
+ multiple: Element._attributeTranslations.values._flag
0
+});
0
 
0
 Element.Methods.Simulated = {
0
   hasAttribute: function(element, attribute) {
0
+ var t = Element._attributeTranslations;
0
+ attribute = t.names[attribute] || attribute;
0
     return $(element).getAttributeNode(attribute).specified;
0
   }
0
-}
0
+};
0
 
0
 // IE is missing .innerHTML support for TABLE-related elements
0
-if(document.all){
0
+if (document.all && !window.opera){
0
   Element.Methods.update = function(element, html) {
0
     element = $(element);
0
     html = typeof html == 'undefined' ? '' : html.toString();
0
@@ -1477,7 +1570,7 @@ if(document.all){
0
     setTimeout(function() {html.evalScripts()}, 10);
0
     return element;
0
   }
0
-}
0
+};
0
 
0
 Object.extend(Element, Element.Methods);
0
 
0
@@ -1644,7 +1737,7 @@ Element.ClassNames.prototype = {
0
   toString: function() {
0
     return $A(this).join(' ');
0
   }
0
-}
0
+};
0
 
0
 Object.extend(Element.ClassNames.prototype, Enumerable);
0
 var Selector = Class.create();
0
@@ -1691,15 +1784,15 @@ Selector.prototype = {
0
     if (params.wildcard)
0
       conditions.push('true');
0
     if (clause = params.id)
0
- conditions.push('element.getAttribute("id") == ' + clause.inspect());
0
+ conditions.push('element.readAttribute("id") == ' + clause.inspect());
0
     if (clause = params.tagName)
0
       conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
0
     if ((clause = params.classNames).length > 0)
0
       for (var i = 0, length = clause.length; i < length; i++)
0
- conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
0
+ conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
0
     if (clause = params.attributes) {
0
       clause.each(function(attribute) {
0
- var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
0
+ var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
0
         var splitValueBy = function(delimiter) {
0
           return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
0
         }
0
@@ -1712,7 +1805,7 @@ Selector.prototype = {
0
                           ); break;
0
           case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
0
           case '':
0
- case undefined: conditions.push(value + ' != null'); break;
0
+ case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
0
           default: throw 'Unknown operator ' + attribute.operator + ' in selector';
0
         }
0
       });
0
@@ -1723,6 +1816,7 @@ Selector.prototype = {
0
 
0
   compileMatcher: function() {
0
     this.match = new Function('element', 'if (!element.tagName) return false; \
0
+ element = $(element); \
0
       return ' + this.buildMatchExpression());
0
   },
0
 
0
@@ -1762,7 +1856,7 @@ Object.extend(Selector, {
0
 
0
   findChildElements: function(element, expressions) {
0
     return expressions.map(function(expression) {
0
- return expression.strip().split(/\s+/).inject([null], function(results, expr) {
0
+ return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
0
         var selector = new Selector(expr);
0
         return results.inject([], function(elements, result) {
0
           return elements.concat(selector.findElements(result || element));
0
@@ -1781,18 +1875,28 @@ var Form = {
0
     return form;
0
   },
0
 
0
- serializeElements: function(elements) {
0
- return elements.inject([], function(queryComponents, element) {
0
- var queryComponent = Form.Element.serialize(element);
0
- if (queryComponent) queryComponents.push(queryComponent);
0
- return queryComponents;
0
- }).join('&');
0
+ serializeElements: function(elements, getHash) {
0
+ var data = elements.inject({}, function(result, element) {
0
+ if (!element.disabled && element.name) {
0
+ var key = element.name, value = $(element).getValue();
0
+ if (value != undefined) {
0
+ if (result[key]) {
0
+ if (result[key].constructor != Array) result[key] = [result[key]];
0
+ result[key].push(value);
0
+ }
0
+ else result[key] = value;
0
+ }
0
+ }
0
+ return result;
0
+ });
0
+
0
+ return getHash ? data : Hash.toQueryString(data);
0
   }
0
 };
0
 
0
 Form.Methods = {
0
- serialize: function(form) {
0
- return Form.serializeElements(Form.getElements(form));
0
+ serialize: function(form, getHash) {
0
+ return Form.serializeElements(Form.getElements(form), getHash);
0
   },
0
 
0
   getElements: function(form) {
0
@@ -1807,15 +1911,13 @@ Form.Methods = {
0
 
0
   getInputs: function(form, typeName, name) {
0
     form = $(form);
0
- var inputs = form.getElementsByTagName('input'), matchingInputs = [];
0
+ var inputs = form.getElementsByTagName('input');
0
 
0
- if (!typeName && !name)
0
- return $A(inputs).map(Element.extend);
0
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
0
 
0
- for (var i = 0, length = inputs.length; i < length; i++) {
0
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
0
       var input = inputs[i];
0
- if ((typeName && input.type != typeName) ||
0
- (name && input.name != name))
0
+ if ((typeName && input.type != typeName) || (name && input.name != name))
0
         continue;
0
       matchingInputs.push(Element.extend(input));
0
     }
0
@@ -1873,30 +1975,21 @@ Form.Element = {
0
 Form.Element.Methods = {
0
   serialize: function(element) {
0
     element = $(element);
0
- if (element.disabled) return '';
0
- var method = element.tagName.toLowerCase();
0
- var parameter = Form.Element.Serializers[method](element);
0
-
0
- if (parameter) {
0
- var key = encodeURIComponent(parameter[0]);
0
- if (key.length == 0) return;
0
-
0
- if (parameter[1].constructor != Array)
0
- parameter[1] = [parameter[1]];
0
-
0
- return parameter[1].map(function(value) {
0
- return key + '=' + encodeURIComponent(value);
0
- }).join('&');
0
+ if (!element.disabled && element.name) {
0
+ var value = element.getValue();
0
+ if (value != undefined) {
0
+ var pair = {};
0
+ pair[element.name] = value;
0
+ return Hash.toQueryString(pair);
0
+ }
0
     }
0
+ return '';
0
   },
0
 
0
   getValue: function(element) {
0
     element = $(element);
0
     var method = element.tagName.toLowerCase();
0
- var parameter = Form.Element.Serializers[method](element);
0
-
0
- if (parameter)
0
- return parameter[1];
0
+ return Form.Element.Serializers[method](element);
0
   },
0
 
0
   clear: function(element) {
0
@@ -1933,6 +2026,7 @@ Form.Element.Methods = {
0
 
0
 Object.extend(Form.Element, Form.Element.Methods);
0
 var Field = Form.Element;
0
+var $F = Form.Element.getValue;
0
 
0
 /*--------------------------------------------------------------------------*/
0
 
0
@@ -1945,51 +2039,45 @@ Form.Element.Serializers = {
0
       default:
0
         return Form.Element.Serializers.textarea(element);
0
     }
0
- return false;
0
   },
0
 
0
   inputSelector: function(element) {
0
- if (element.checked)
0
- return [element.name, element.value];
0
+ return element.checked ? element.value : null;
0
   },
0
 
0
   textarea: function(element) {
0
- return [element.name, element.value];
0
+ return element.value;
0
   },
0
 
0
   select: function(element) {
0
- return Form.Element.Serializers[element.type == 'select-one' ?
0
+ return this[element.type == 'select-one' ?
0
       'selectOne' : 'selectMany'](element);
0
   },
0
 
0
   selectOne: function(element) {
0
- var value = '', opt, index = element.selectedIndex;
0
- if (index >= 0) {
0
- opt = Element.extend(element.options[index]);
0
- // Uses the new potential extension if hasAttribute isn't native.