Skip to content
This repository
Browse code

upgraded prototype version to 1.6.0.2

git-svn-id: svn://livevalidation.com/livevalidation/trunk@43 c130c166-013a-0410-90be-eade3a03707a
  • Loading branch information...
commit 0f27536a69641ac3fd682c3f609a143c134cd208 1 parent 5ea2220
Alec Hill authored February 04, 2008

Showing 1 changed file with 267 additions and 230 deletions. Show diff stats Hide diff stats

  1. 497  lib/prototype.js
497  lib/prototype.js
... ...
@@ -1,5 +1,5 @@
1  
-/*  Prototype JavaScript framework, version 1.6.0
2  
- *  (c) 2005-2007 Sam Stephenson
  1
+/*  Prototype JavaScript framework, version 1.6.0.2
  2
+ *  (c) 2005-2008 Sam Stephenson
3 3
  *
4 4
  *  Prototype is freely distributable under the terms of an MIT-style license.
5 5
  *  For details, see the Prototype web site: http://www.prototypejs.org/
@@ -7,7 +7,7 @@
7 7
  *--------------------------------------------------------------------------*/
8 8
 
9 9
 var Prototype = {
10  
-  Version: '1.6.0',
  10
+  Version: '1.6.0.2',
11 11
 
12 12
   Browser: {
13 13
     IE:     !!(window.attachEvent && !window.opera),
@@ -36,8 +36,6 @@ var Prototype = {
36 36
 if (Prototype.Browser.MobileSafari)
37 37
   Prototype.BrowserFeatures.SpecificElementExtensions = false;
38 38
 
39  
-if (Prototype.Browser.WebKit)
40  
-  Prototype.BrowserFeatures.XPath = false;
41 39
 
42 40
 /* Based on Alex Arnell's inheritance implementation. */
43 41
 var Class = {
@@ -110,9 +108,9 @@ Object.extend = function(destination, source) {
110 108
 Object.extend(Object, {
111 109
   inspect: function(object) {
112 110
     try {
113  
-      if (object === undefined) return 'undefined';
  111
+      if (Object.isUndefined(object)) return 'undefined';
114 112
       if (object === null) return 'null';
115  
-      return object.inspect ? object.inspect() : object.toString();
  113
+      return object.inspect ? object.inspect() : String(object);
116 114
     } catch (e) {
117 115
       if (e instanceof RangeError) return '...';
118 116
       throw e;
@@ -135,7 +133,7 @@ Object.extend(Object, {
135 133
     var results = [];
136 134
     for (var property in object) {
137 135
       var value = Object.toJSON(object[property]);
138  
-      if (value !== undefined)
  136
+      if (!Object.isUndefined(value))
139 137
         results.push(property.toJSON() + ': ' + value);
140 138
     }
141 139
 
@@ -173,7 +171,8 @@ Object.extend(Object, {
173 171
   },
174 172
 
175 173
   isArray: function(object) {
176  
-    return object && object.constructor === Array;
  174
+    return object != null && typeof object == "object" &&
  175
+      'splice' in object && 'join' in object;
177 176
   },
178 177
 
179 178
   isHash: function(object) {
@@ -204,7 +203,7 @@ Object.extend(Function.prototype, {
204 203
   },
205 204
 
206 205
   bind: function() {
207  
-    if (arguments.length < 2 && arguments[0] === undefined) return this;
  206
+    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
208 207
     var __method = this, args = $A(arguments), object = args.shift();
209 208
     return function() {
210 209
       return __method.apply(object, args.concat($A(arguments)));
@@ -351,7 +350,7 @@ Object.extend(String.prototype, {
351 350
 
352 351
   sub: function(pattern, replacement, count) {
353 352
     replacement = this.gsub.prepareReplacement(replacement);
354  
-    count = count === undefined ? 1 : count;
  353
+    count = Object.isUndefined(count) ? 1 : count;
355 354
 
356 355
     return this.gsub(pattern, function(match) {
357 356
       if (--count < 0) return match[0];
@@ -366,7 +365,7 @@ Object.extend(String.prototype, {
366 365
 
367 366
   truncate: function(length, truncation) {
368 367
     length = length || 30;
369  
-    truncation = truncation === undefined ? '...' : truncation;
  368
+    truncation = Object.isUndefined(truncation) ? '...' : truncation;
370 369
     return this.length > length ?
371 370
       this.slice(0, length - truncation.length) + truncation : String(this);
372 371
   },
@@ -486,7 +485,9 @@ Object.extend(String.prototype, {
486 485
   },
487 486
 
488 487
   isJSON: function() {
489  
-    var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
  488
+    var str = this;
  489
+    if (str.blank()) return false;
  490
+    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
490 491
     return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
491 492
   },
492 493
 
@@ -565,7 +566,8 @@ var Template = Class.create({
565 566
       if (before == '\\') return match[2];
566 567
 
567 568
       var ctx = object, expr = match[3];
568  
-      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
  569
+      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
  570
+      match = pattern.exec(expr);
569 571
       if (match == null) return before;
570 572
 
571 573
       while (match != null) {
@@ -577,7 +579,7 @@ var Template = Class.create({
577 579
       }
578 580
 
579 581
       return before + String.interpret(ctx);
580  
-    }.bind(this));
  582
+    });
581 583
   }
582 584
 });
583 585
 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
@@ -686,7 +688,7 @@ var Enumerable = {
686 688
   },
687 689
 
688 690
   inGroupsOf: function(number, fillWith) {
689  
-    fillWith = fillWith === undefined ? null : fillWith;
  691
+    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
690 692
     return this.eachSlice(number, function(slice) {
691 693
       while(slice.length < number) slice.push(fillWith);
692 694
       return slice;
@@ -713,7 +715,7 @@ var Enumerable = {
713 715
     var result;
714 716
     this.each(function(value, index) {
715 717
       value = iterator(value, index);
716  
-      if (result == undefined || value >= result)
  718
+      if (result == null || value >= result)
717 719
         result = value;
718 720
     });
719 721
     return result;
@@ -724,7 +726,7 @@ var Enumerable = {
724 726
     var result;
725 727
     this.each(function(value, index) {
726 728
       value = iterator(value, index);
727  
-      if (result == undefined || value < result)
  729
+      if (result == null || value < result)
728 730
         result = value;
729 731
     });
730 732
     return result;
@@ -805,20 +807,20 @@ Object.extend(Enumerable, {
805 807
 function $A(iterable) {
806 808
   if (!iterable) return [];
807 809
   if (iterable.toArray) return iterable.toArray();
808  
-  var length = iterable.length, results = new Array(length);
  810
+  var length = iterable.length || 0, results = new Array(length);
809 811
   while (length--) results[length] = iterable[length];
810 812
   return results;
811 813
 }
812 814
 
813 815
 if (Prototype.Browser.WebKit) {
814  
-  function $A(iterable) {
  816
+  $A = function(iterable) {
815 817
     if (!iterable) return [];
816 818
     if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
817 819
         iterable.toArray) return iterable.toArray();
818  
-    var length = iterable.length, results = new Array(length);
  820
+    var length = iterable.length || 0, results = new Array(length);
819 821
     while (length--) results[length] = iterable[length];
820 822
     return results;
821  
-  }
  823
+  };
822 824
 }
823 825
 
824 826
 Array.from = $A;
@@ -904,7 +906,7 @@ Object.extend(Array.prototype, {
904 906
     var results = [];
905 907
     this.each(function(object) {
906 908
       var value = Object.toJSON(object);
907  
-      if (value !== undefined) results.push(value);
  909
+      if (!Object.isUndefined(value)) results.push(value);
908 910
     });
909 911
     return '[' + results.join(', ') + ']';
910 912
   }
@@ -984,34 +986,6 @@ function $H(object) {
984 986
 };
985 987
 
986 988
 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 989
 
1016 990
   function toQueryPair(key, value) {
1017 991
     if (Object.isUndefined(value)) return key;
@@ -1023,7 +997,14 @@ var Hash = Class.create(Enumerable, (function() {
1023 997
       this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1024 998
     },
1025 999
 
1026  
-    _each: each,
  1000
+    _each: function(iterator) {
  1001
+      for (var key in this._object) {
  1002
+        var value = this._object[key], pair = [key, value];
  1003
+        pair.key = key;
  1004
+        pair.value = value;
  1005
+        iterator(pair);
  1006
+      }
  1007
+    },
1027 1008
 
1028 1009
     set: function(key, value) {
1029 1010
       return this._object[key] = value;
@@ -1187,8 +1168,11 @@ Ajax.Base = Class.create({
1187 1168
     Object.extend(this.options, options || { });
1188 1169
 
1189 1170
     this.options.method = this.options.method.toLowerCase();
  1171
+
1190 1172
     if (Object.isString(this.options.parameters))
1191 1173
       this.options.parameters = this.options.parameters.toQueryParams();
  1174
+    else if (Object.isHash(this.options.parameters))
  1175
+      this.options.parameters = this.options.parameters.toObject();
1192 1176
   }
1193 1177
 });
1194 1178
 
@@ -1315,7 +1299,7 @@ Ajax.Request = Class.create(Ajax.Base, {
1315 1299
 
1316 1300
       var contentType = response.getHeader('Content-type');
1317 1301
       if (this.options.evalJS == 'force'
1318  
-          || (this.options.evalJS && contentType
  1302
+          || (this.options.evalJS && this.isSameOrigin() && contentType
1319 1303
           && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1320 1304
         this.evalResponse();
1321 1305
     }
@@ -1333,9 +1317,18 @@ Ajax.Request = Class.create(Ajax.Base, {
1333 1317
     }
1334 1318
   },
1335 1319
 
  1320
+  isSameOrigin: function() {
  1321
+    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
  1322
+    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
  1323
+      protocol: location.protocol,
  1324
+      domain: document.domain,
  1325
+      port: location.port ? ':' + location.port : ''
  1326
+    }));
  1327
+  },
  1328
+
1336 1329
   getHeader: function(name) {
1337 1330
     try {
1338  
-      return this.transport.getResponseHeader(name);
  1331
+      return this.transport.getResponseHeader(name) || null;
1339 1332
     } catch (e) { return null }
1340 1333
   },
1341 1334
 
@@ -1371,7 +1364,7 @@ Ajax.Response = Class.create({
1371 1364
 
1372 1365
     if(readyState == 4) {
1373 1366
       var xml = transport.responseXML;
1374  
-      this.responseXML  = xml === undefined ? null : xml;
  1367
+      this.responseXML  = Object.isUndefined(xml) ? null : xml;
1375 1368
       this.responseJSON = this._getResponseJSON();
1376 1369
     }
1377 1370
   },
@@ -1408,7 +1401,8 @@ Ajax.Response = Class.create({
1408 1401
     if (!json) return null;
1409 1402
     json = decodeURIComponent(escape(json));
1410 1403
     try {
1411  
-      return json.evalJSON(this.request.options.sanitizeJSON);
  1404
+      return json.evalJSON(this.request.options.sanitizeJSON ||
  1405
+        !this.request.isSameOrigin());
1412 1406
     } catch (e) {
1413 1407
       this.request.dispatchException(e);
1414 1408
     }
@@ -1417,10 +1411,12 @@ Ajax.Response = Class.create({
1417 1411
   _getResponseJSON: function() {
1418 1412
     var options = this.request.options;
1419 1413
     if (!options.evalJSON || (options.evalJSON != 'force' &&
1420  
-      !(this.getHeader('Content-type') || '').include('application/json')))
1421  
-        return null;
  1414
+      !(this.getHeader('Content-type') || '').include('application/json')) ||
  1415
+        this.responseText.blank())
  1416
+          return null;
1422 1417
     try {
1423  
-      return this.transport.responseText.evalJSON(options.sanitizeJSON);
  1418
+      return this.responseText.evalJSON(options.sanitizeJSON ||
  1419
+        !this.request.isSameOrigin());
1424 1420
     } catch (e) {
1425 1421
       this.request.dispatchException(e);
1426 1422
     }
@@ -1434,11 +1430,11 @@ Ajax.Updater = Class.create(Ajax.Request, {
1434 1430
       failure: (container.failure || (container.success ? null : container))
1435 1431
     };
1436 1432
 
1437  
-    options = options || { };
  1433
+    options = Object.clone(options);
1438 1434
     var onComplete = options.onComplete;
1439  
-    options.onComplete = (function(response, param) {
  1435
+    options.onComplete = (function(response, json) {
1440 1436
       this.updateContent(response.responseText);
1441  
-      if (Object.isFunction(onComplete)) onComplete(response, param);
  1437
+      if (Object.isFunction(onComplete)) onComplete(response, json);
1442 1438
     }).bind(this);
1443 1439
 
1444 1440
     $super(url, options);
@@ -1460,10 +1456,6 @@ Ajax.Updater = Class.create(Ajax.Request, {
1460 1456
       }
1461 1457
       else receiver.update(responseText);
1462 1458
     }
1463  
-
1464  
-    if (this.success()) {
1465  
-      if (this.onComplete) this.onComplete.bind(this).defer();
1466  
-    }
1467 1459
   }
1468 1460
 });
1469 1461
 
@@ -1628,24 +1620,28 @@ Element.Methods = {
1628 1620
         Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
1629 1621
           insertions = {bottom:insertions};
1630 1622
 
1631  
-    var content, t, range;
  1623
+    var content, insert, tagName, childNodes;
1632 1624
 
1633  
-    for (position in insertions) {
  1625
+    for (var position in insertions) {
1634 1626
       content  = insertions[position];
1635 1627
       position = position.toLowerCase();
1636  
-      t = Element._insertionTranslations[position];
  1628
+      insert = Element._insertionTranslations[position];
1637 1629
 
1638 1630
       if (content && content.toElement) content = content.toElement();
1639 1631
       if (Object.isElement(content)) {
1640  
-        t.insert(element, content);
  1632
+        insert(element, content);
1641 1633
         continue;
1642 1634
       }
1643 1635
 
1644 1636
       content = Object.toHTML(content);
1645 1637
 
1646  
-      range = element.ownerDocument.createRange();
1647  
-      t.initializeRange(element, range);
1648  
-      t.insert(element, range.createContextualFragment(content.stripScripts()));
  1638
+      tagName = ((position == 'before' || position == 'after')
  1639
+        ? element.parentNode : element).tagName.toUpperCase();
  1640
+
  1641
+      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
  1642
+
  1643
+      if (position == 'top' || position == 'after') childNodes.reverse();
  1644
+      childNodes.each(insert.curry(element));
1649 1645
 
1650 1646
       content.evalScripts.bind(content).defer();
1651 1647
     }
@@ -1690,7 +1686,7 @@ Element.Methods = {
1690 1686
   },
1691 1687
 
1692 1688
   descendants: function(element) {
1693  
-    return $A($(element).getElementsByTagName('*')).each(Element.extend);
  1689
+    return $(element).select("*");
1694 1690
   },
1695 1691
 
1696 1692
   firstDescendant: function(element) {
@@ -1729,32 +1725,31 @@ Element.Methods = {
1729 1725
     element = $(element);
1730 1726
     if (arguments.length == 1) return $(element.parentNode);
1731 1727
     var ancestors = element.ancestors();
1732  
-    return expression ? Selector.findElement(ancestors, expression, index) :
1733  
-      ancestors[index || 0];
  1728
+    return Object.isNumber(expression) ? ancestors[expression] :
  1729
+      Selector.findElement(ancestors, expression, index);
1734 1730
   },
1735 1731
 
1736 1732
   down: function(element, expression, index) {
1737 1733
     element = $(element);
1738 1734
     if (arguments.length == 1) return element.firstDescendant();
1739  
-    var descendants = element.descendants();
1740  
-    return expression ? Selector.findElement(descendants, expression, index) :
1741  
-      descendants[index || 0];
  1735
+    return Object.isNumber(expression) ? element.descendants()[expression] :
  1736
+      element.select(expression)[index || 0];
1742 1737
   },
1743 1738
 
1744 1739
   previous: function(element, expression, index) {
1745 1740
     element = $(element);
1746 1741
     if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
1747 1742
     var previousSiblings = element.previousSiblings();
1748  
-    return expression ? Selector.findElement(previousSiblings, expression, index) :
1749  
-      previousSiblings[index || 0];
  1743
+    return Object.isNumber(expression) ? previousSiblings[expression] :
  1744
+      Selector.findElement(previousSiblings, expression, index);
1750 1745
   },
1751 1746
 
1752 1747
   next: function(element, expression, index) {
1753 1748
     element = $(element);
1754 1749
     if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
1755 1750
     var nextSiblings = element.nextSiblings();
1756  
-    return expression ? Selector.findElement(nextSiblings, expression, index) :
1757  
-      nextSiblings[index || 0];
  1751
+    return Object.isNumber(expression) ? nextSiblings[expression] :
  1752
+      Selector.findElement(nextSiblings, expression, index);
1758 1753
   },
1759 1754
 
1760 1755
   select: function() {
@@ -1795,10 +1790,11 @@ Element.Methods = {
1795 1790
     var attributes = { }, t = Element._attributeTranslations.write;
1796 1791
 
1797 1792
     if (typeof name == 'object') attributes = name;
1798  
-    else attributes[name] = value === undefined ? true : value;
  1793
+    else attributes[name] = Object.isUndefined(value) ? true : value;
1799 1794
 
1800 1795
     for (var attr in attributes) {
1801  
-      var name = t.names[attr] || attr, value = attributes[attr];
  1796
+      name = t.names[attr] || attr;
  1797
+      value = attributes[attr];
1802 1798
       if (t.values[attr]) name = t.values[attr](element, value);
1803 1799
       if (value === false || value === null)
1804 1800
         element.removeAttribute(name);
@@ -1867,6 +1863,7 @@ Element.Methods = {
1867 1863
 
1868 1864
   descendantOf: function(element, ancestor) {
1869 1865
     element = $(element), ancestor = $(ancestor);
  1866
+    var originalAncestor = ancestor;
1870 1867
 
1871 1868
     if (element.compareDocumentPosition)
1872 1869
       return (element.compareDocumentPosition(ancestor) & 8) === 8;
@@ -1878,11 +1875,12 @@ Element.Methods = {
1878 1875
         do { ancestor = ancestor.parentNode; }
1879 1876
         while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
1880 1877
       }
1881  
-      if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
  1878
+      if (nextAncestor && nextAncestor.sourceIndex)
  1879
+       return (e > a && e < nextAncestor.sourceIndex);
1882 1880
     }
1883 1881
 
1884 1882
     while (element = element.parentNode)
1885  
-      if (element == ancestor) return true;
  1883
+      if (element == originalAncestor) return true;
1886 1884
     return false;
1887 1885
   },
1888 1886
 
@@ -1921,7 +1919,7 @@ Element.Methods = {
1921 1919
       if (property == 'opacity') element.setOpacity(styles[property]);
1922 1920
       else
1923 1921
         elementStyle[(property == 'float' || property == 'cssFloat') ?
1924  
-          (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
  1922
+          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
1925 1923
             property] = styles[property];
1926 1924
 
1927 1925
     return element;
@@ -2022,7 +2020,7 @@ Element.Methods = {
2022 2020
       if (element) {
2023 2021
         if (element.tagName == 'BODY') break;
2024 2022
         var p = Element.getStyle(element, 'position');
2025  
-        if (p == 'relative' || p == 'absolute') break;
  2023
+        if (p !== 'static') break;
2026 2024
       }
2027 2025
     } while (element);
2028 2026
     return Element._returnOffset(valueL, valueT);
@@ -2171,72 +2169,75 @@ Element._attributeTranslations = {
2171 2169
   }
2172 2170
 };
2173 2171
 
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));
  2172
+if (Prototype.Browser.Opera) {
  2173
+  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
  2174
+    function(proceed, element, style) {
  2175
+      switch (style) {
  2176
+        case 'left': case 'top': case 'right': case 'bottom':
  2177
+          if (proceed(element, 'position') === 'static') return null;
  2178
+        case 'height': case 'width':
  2179
+          // returns '0px' for hidden elements; we want it to return null
  2180
+          if (!Element.visible(element)) return null;
  2181
+
  2182
+          // returns the border-box dimensions rather than the content-box
  2183
+          // dimensions, so we subtract padding and borders from the value
  2184
+          var dim = parseInt(proceed(element, style), 10);
  2185
+
  2186
+          if (dim !== element['offset' + style.capitalize()])
  2187
+            return dim + 'px';
  2188
+
  2189
+          var properties;
  2190
+          if (style === 'height') {
  2191
+            properties = ['border-top-width', 'padding-top',
  2192
+             'padding-bottom', 'border-bottom-width'];
  2193
+          }
  2194
+          else {
  2195
+            properties = ['border-left-width', 'padding-left',
  2196
+             'padding-right', 'border-right-width'];
  2197
+          }
  2198
+          return properties.inject(dim, function(memo, property) {
  2199
+            var val = proceed(element, property);
  2200
+            return val === null ? memo : memo - parseInt(val, 10);
  2201
+          }) + 'px';
  2202
+        default: return proceed(element, style);
2204 2203
       }
2205  
-      else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
2206  
-
2207  
-      content.evalScripts.bind(content).defer();
2208 2204
     }
  2205
+  );
2209 2206
 
2210  
-    return element;
2211  
-  };
2212  
-}
2213  
-
2214  
-if (Prototype.Browser.Opera) {
2215  
-  Element.Methods._getStyle = Element.Methods.getStyle;
2216  
-  Element.Methods.getStyle = function(element, style) {
2217  
-    switch(style) {
2218  
-      case 'left':
2219  
-      case 'top':
2220  
-      case 'right':
2221  
-      case 'bottom':
2222  
-        if (Element._getStyle(element, 'position') == 'static') return null;
2223  
-      default: return Element._getStyle(element, style);
  2207
+  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
  2208
+    function(proceed, element, attribute) {
  2209
+      if (attribute === 'title') return element.title;
  2210
+      return proceed(element, attribute);
2224 2211
     }
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  
-  };
  2212
+  );
2231 2213
 }
2232 2214
 
2233 2215
 else if (Prototype.Browser.IE) {
2234  
-  $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
  2216
+  // IE doesn't report offsets correctly for static elements, so we change them
  2217
+  // to "relative" to get the values, then change them back.
  2218
+  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
  2219
+    function(proceed, element) {
  2220
+      element = $(element);
  2221
+      var position = element.getStyle('position');
  2222
+      if (position !== 'static') return proceed(element);
  2223
+      element.setStyle({ position: 'relative' });
  2224
+      var value = proceed(element);
  2225
+      element.setStyle({ position: position });
  2226
+      return value;
  2227
+    }
  2228
+  );
  2229
+
  2230
+  $w('positionedOffset viewportOffset').each(function(method) {
2235 2231
     Element.Methods[method] = Element.Methods[method].wrap(
2236 2232
       function(proceed, element) {
2237 2233
         element = $(element);
2238 2234
         var position = element.getStyle('position');
2239  
-        if (position != 'static') return proceed(element);
  2235
+        if (position !== 'static') return proceed(element);
  2236
+        // Trigger hasLayout on the offset parent so that IE6 reports
  2237
+        // accurate offsetTop and offsetLeft values for position: fixed.
  2238
+        var offsetParent = element.getOffsetParent();
  2239
+        if (offsetParent && offsetParent.getStyle('position') === 'fixed')
  2240
+          offsetParent.setStyle({ zoom: 1 });
2240 2241
         element.setStyle({ position: 'relative' });
2241 2242
         var value = proceed(element);
2242 2243
         element.setStyle({ position: position });
@@ -2301,7 +2302,7 @@ else if (Prototype.Browser.IE) {
2301 2302
           return node ? node.value : "";
2302 2303
         },
2303 2304
         _getEv: function(element, attribute) {
2304  
-          var attribute = element.getAttribute(attribute);
  2305
+          attribute = element.getAttribute(attribute);
2305 2306
           return attribute ? attribute.toString().slice(23, -2) : null;
2306 2307
         },
2307 2308
         _flag: function(element, attribute) {
@@ -2318,7 +2319,10 @@ else if (Prototype.Browser.IE) {
2318 2319
   };
2319 2320
 
2320 2321
   Element._attributeTranslations.write = {
2321  
-    names: Object.clone(Element._attributeTranslations.read.names),
  2322
+    names: Object.extend({
  2323
+      cellpadding: 'cellPadding',
  2324
+      cellspacing: 'cellSpacing'
  2325
+    }, Element._attributeTranslations.read.names),
2322 2326
     values: {
2323 2327
       checked: function(element, value) {
2324 2328
         element.checked = !!value;
@@ -2398,7 +2402,7 @@ else if (Prototype.Browser.WebKit) {
2398 2402
   };
2399 2403
 
2400 2404
   // Safari returns margins on body which is incorrect if the child is absolutely
2401  
-  // positioned.  For performance reasons, redefine Position.cumulativeOffset for
  2405
+  // positioned.  For performance reasons, redefine Element#cumulativeOffset for
2402 2406
   // KHTML/WebKit only.
2403 2407
   Element.Methods.cumulativeOffset = function(element) {
2404 2408
     var valueT = 0, valueL = 0;
@@ -2438,7 +2442,7 @@ if (Prototype.Browser.IE || Prototype.Browser.Opera) {
2438 2442
   };
2439 2443
 }
2440 2444
 
2441  
-if (document.createElement('div').outerHTML) {
  2445
+if ('outerHTML' in document.createElement('div')) {
2442 2446
   Element.Methods.replace = function(element, content) {
2443 2447
     element = $(element);
2444 2448
 
@@ -2476,45 +2480,25 @@ Element._returnOffset = function(l, t) {
2476 2480
 
2477 2481
 Element._getContentFromAnonymousElement = function(tagName, html) {
2478 2482
   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 });
  2483
+  if (t) {
  2484
+    div.innerHTML = t[0] + html + t[1];
  2485
+    t[2].times(function() { div = div.firstChild });
  2486
+  } else div.innerHTML = html;
2481 2487
   return $A(div.childNodes);
2482 2488
 };
2483 2489
 
2484 2490
 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  
-    }
  2491
+  before: function(element, node) {
  2492
+    element.parentNode.insertBefore(node, element);
2493 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  
-    }
  2494
+  top: function(element, node) {
  2495
+    element.insertBefore(node, element.firstChild);
2503 2496
   },
2504  
-  bottom: {
2505  
-    adjacency: 'beforeEnd',
2506  
-    insert: function(element, node) {
2507  
-      element.appendChild(node);
2508  
-    }
  2497
+  bottom: function(element, node) {
  2498
+    element.appendChild(node);
2509 2499
   },
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  
-    }
  2500
+  after: function(element, node) {
  2501
+    element.parentNode.insertBefore(node, element.nextSibling);
2518 2502
   },
2519 2503
   tags: {
2520 2504
     TABLE:  ['<table>',                '</table>',                   1],
@@ -2526,7 +2510,6 @@ Element._insertionTranslations = {
2526 2510
 };
2527 2511
 
2528 2512
 (function() {
2529  
-  this.bottom.initializeRange = this.top.initializeRange;
2530 2513
   Object.extend(this.tags, {
2531 2514
     THEAD: this.tags.TBODY,
2532 2515
     TFOOT: this.tags.TBODY,
@@ -2687,10 +2670,11 @@ Element.addMethods = function(methods) {
2687 2670
 document.viewport = {
2688 2671
   getDimensions: function() {
2689 2672
     var dimensions = { };
  2673
+    var B = Prototype.Browser;
2690 2674
     $w('width height').each(function(d) {
2691 2675
       var D = d.capitalize();
2692  
-      dimensions[d] = self['inner' + D] ||
2693  
-       (document.documentElement['client' + D] || document.body['client' + D]);
  2676
+      dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
  2677
+        (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
2694 2678
     });
2695 2679
     return dimensions;
2696 2680
   },
@@ -2709,7 +2693,7 @@ document.viewport = {
2709 2693
       window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
2710 2694
   }
2711 2695
 };
2712  
-/* Portions of the Selector class are derived from Jack Slocums DomQuery,
  2696
+/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
2713 2697
  * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
2714 2698
  * license.  Please see http://www.yui-ext.com/ for more information. */
2715 2699
 
@@ -2719,9 +2703,26 @@ var Selector = Class.create({
2719 2703
     this.compileMatcher();
2720 2704
   },
2721 2705
 
  2706
+  shouldUseXPath: function() {
  2707
+    if (!Prototype.BrowserFeatures.XPath) return false;
  2708
+
  2709
+    var e = this.expression;
  2710
+
  2711
+    // Safari 3 chokes on :*-of-type and :empty
  2712
+    if (Prototype.Browser.WebKit &&
  2713
+     (e.include("-of-type") || e.include(":empty")))
  2714
+      return false;
  2715
+
  2716
+    // XPath can't do namespaced attributes, nor can it read
  2717
+    // the "checked" property from DOM nodes
  2718
+    if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
  2719
+      return false;
  2720
+
  2721
+    return true;
  2722
+  },
  2723
+
2722 2724
   compileMatcher: function() {
2723  
-    // Selectors with namespaced attributes can't use the XPath version
2724  
-    if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression))
  2725
+    if (this.shouldUseXPath())
2725 2726
       return this.compileXPathMatcher();
2726 2727
 
2727 2728
     var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
@@ -2844,8 +2845,12 @@ Object.extend(Selector, {
2844 2845
     },
2845 2846
     className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
2846 2847
     id:           "[@id='#{1}']",
2847  
-    attrPresence: "[@#{1}]",
  2848
+    attrPresence: function(m) {
  2849
+      m[1] = m[1].toLowerCase();
  2850
+      return new Template("[@#{1}]").evaluate(m);
  2851
+    },
2848 2852
     attr: function(m) {
  2853
+      m[1] = m[1].toLowerCase();
2849 2854
       m[3] = m[5] || m[6];
2850 2855
       return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
2851 2856
     },
@@ -2874,7 +2879,7 @@ Object.extend(Selector, {
2874 2879
       'enabled':     "[not(@disabled)]",
2875 2880
       'not': function(m) {
2876 2881
         var e = m[6], p = Selector.patterns,
2877  
-            x = Selector.xpath, le, m, v;
  2882
+            x = Selector.xpath, le, v;
2878 2883
 
2879 2884
         var exclusion = [];
2880 2885
         while (e && le != e && (/\S/).test(e)) {
@@ -2931,13 +2936,13 @@ Object.extend(Selector, {
2931 2936
   },
2932 2937
 
2933 2938
   criteria: {
2934  
-    tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
2935  
-    className:    'n = h.className(n, r, "#{1}", c); c = false;',
2936  
-    id:           'n = h.id(n, r, "#{1}", c);        c = false;',
2937  
-    attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
  2939
+    tagName:      'n = h.tagName(n, r, "#{1}", c);      c = false;',
  2940
+    className:    'n = h.className(n, r, "#{1}", c);    c = false;',
  2941
+    id:           'n = h.id(n, r, "#{1}", c);           c = false;',
  2942
+    attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
2938 2943
     attr: function(m) {
2939 2944
       m[3] = (m[5] || m[6]);
2940  
-      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
  2945
+      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
2941 2946
     },
2942 2947
     pseudo: function(m) {
2943 2948
       if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
@@ -2961,7 +2966,8 @@ Object.extend(Selector, {
2961 2966
     tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
2962 2967
     id:           /^#([\w\-\*]+)(\b|$)/,
2963 2968
     className:    /^\.([\w\-\*]+)(\b|$)/,
2964  
-    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
  2969
+    pseudo:
  2970
+/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
2965 2971
     attrPresence: /^\[([\w]+)\]/,
2966 2972
     attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
2967 2973
   },
@@ -2986,7 +2992,7 @@ Object.extend(Selector, {
2986 2992
 
2987 2993
     attr: function(element, matches) {
2988 2994
       var nodeValue = Element.readAttribute(element, matches[1]);
2989  
-      return Selector.operators[matches[2]](nodeValue, matches[3]);
  2995
+      return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
2990 2996
     }
2991 2997
   },
2992 2998
 
@@ -3001,14 +3007,15 @@ Object.extend(Selector, {
3001 3007
 
3002 3008
     // marks an array of nodes for counting
3003 3009
     mark: function(nodes) {
  3010
+      var _true = Prototype.emptyFunction;
3004 3011
       for (var i = 0, node; node = nodes[i]; i++)
3005  
-        node._counted = true;
  3012
+        node._countedByPrototype = _true;
3006 3013
       return nodes;
3007 3014
     },
3008 3015
 
3009 3016
     unmark: function(nodes) {
3010 3017
       for (var i = 0, node; node = nodes[i]; i++)
3011  
-        node._counted = undefined;
  3018
+        node._countedByPrototype = undefined;
3012 3019
       return nodes;
3013 3020
     },
3014 3021
 
@@ -3016,15 +3023,15 @@ Object.extend(Selector, {
3016 3023
     // "ofType" flag indicates whether we're indexing for nth-of-type
3017 3024
     // rather than nth-child
3018 3025
     index: function(parentNode, reverse, ofType) {
3019  
-      parentNode._counted = true;
  3026
+      parentNode._countedByPrototype = Prototype.emptyFunction;
3020 3027
       if (reverse) {
3021 3028
         for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
3022 3029
           var node = nodes[i];
3023  
-          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
  3030
+          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
3024 3031
         }
3025 3032
       } else {
3026 3033
         for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
3027  
-          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
  3034
+          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
3028 3035
       }
3029 3036
     },
3030 3037
 
@@ -3033,8 +3040,8 @@ Object.extend(Selector, {
3033 3040
       if (nodes.length == 0) return nodes;
3034 3041
       var results = [], n;
3035 3042
       for (var i = 0, l = nodes.length; i < l; i++)
3036  
-        if (!(n = nodes[i])._counted) {
3037  
-          n._counted = true;
  3043
+        if (!(n = nodes[i])._countedByPrototype) {
  3044
+          n._countedByPrototype = Prototype.emptyFunction;
3038 3045
           results.push(Element.extend(n));
3039 3046
         }
3040 3047
       return Selector.handlers.unmark(results);
@@ -3051,7 +3058,7 @@ Object.extend(Selector, {
3051 3058
     child: function(nodes) {
3052 3059
       var h = Selector.handlers;
3053 3060
       for (var i = 0, results = [], node; node = nodes[i]; i++) {
3054  
-        for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
  3061
+        for (var j = 0, child; child = node.childNodes[j]; j++)
3055 3062
           if (child.nodeType == 1 && child.tagName != '!') results.push(child);
3056 3063
       }
3057 3064
       return results;
@@ -3086,7 +3093,7 @@ Object.extend(Selector, {
3086 3093
 
3087 3094
     // TOKEN FUNCTIONS
3088 3095
     tagName: function(nodes, root, tagName, combinator) {
3089  
-      tagName = tagName.toUpperCase();
  3096
+      var uTagName = tagName.toUpperCase();
3090 3097
       var results = [], h = Selector.handlers;
3091 3098
       if (nodes) {
3092 3099
         if (combinator) {
@@ -3099,7 +3106,7 @@ Object.extend(Selector, {
3099 3106
           if (tagName == "*") return nodes;
3100 3107
         }
3101 3108
         for (var i = 0, node; node = nodes[i]; i++)
3102  
-          if (node.tagName.toUpperCase() == tagName) results.push(node);
  3109
+          if (node.tagName.toUpperCase() === uTagName) results.push(node);
3103 3110
         return results;
3104 3111
       } else return root.getElementsByTagName(tagName);
3105 3112
     },
@@ -3146,16 +3153,18 @@ Object.extend(Selector, {
3146 3153
       return results;
3147 3154
     },
3148 3155
 
3149  
-    attrPresence: function(nodes, root, attr) {
  3156
+    attrPresence: function(nodes, root, attr, combinator) {
3150 3157
       if (!nodes) nodes = root.getElementsByTagName("*");
  3158
+      if (nodes && combinator) nodes = this[combinator](nodes);
3151 3159
       var results = [];
3152 3160
       for (var i = 0, node; node = nodes[i]; i++)
3153 3161
         if (Element.hasAttribute(node, attr)) results.push(node);
3154 3162
       return results;
3155 3163
     },
3156 3164
 
3157  
-    attr: function(nodes, root, attr, value, operator) {
  3165
+    attr: function(nodes, root, attr, value, operator, combinator) {
3158 3166
       if (!nodes) nodes = root.getElementsByTagName("*");
  3167
+      if (nodes && combinator) nodes = this[combinator](nodes);
3159 3168
       var handler = Selector.operators[operator], results = [];
3160 3169
       for (var i = 0, node; node = nodes[i]; i++) {
3161 3170
         var nodeValue = Element.readAttribute(node, attr);
@@ -3234,7 +3243,7 @@ Object.extend(Selector, {
3234 3243
       var h = Selector.handlers, results = [], indexed = [], m;
3235 3244
       h.mark(nodes);
3236 3245
       for (var i = 0, node; node = nodes[i]; i++) {
3237  
-        if (!node.parentNode._counted) {
  3246
+        if (!node.parentNode._countedByPrototype) {
3238 3247
           h.index(node.parentNode, reverse, ofType);
3239 3248
           indexed.push(node.parentNode);
3240 3249
         }
@@ -3272,7 +3281,7 @@ Object.extend(Selector, {
3272 3281
       var exclusions = new Selector(selector).findElements(root);
3273 3282
       h.mark(exclusions);
3274 3283
       for (var i = 0, results = [], node; node = nodes[i]; i++)
3275  
-        if (!node._counted) results.push(node);
  3284
+        if (!node._countedByPrototype) results.push(node);
3276 3285
       h.unmark(exclusions);
3277 3286
       return results;
3278 3287
     },
@@ -3306,11 +3315,19 @@ Object.extend(Selector, {
3306 3315
     '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
3307 3316
   },
3308 3317
 
  3318
+  split: function(expression) {
  3319
+    var expressions = [];
  3320
+    expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
  3321
+      expressions.push(m[1].strip());
  3322
+    });
  3323
+    return expressions;
  3324
+  },
  3325
+
3309 3326
   matchElements: function(elements, expression) {
3310  
-    var matches = new Selector(expression).findElements(), h = Selector.handlers;
  3327
+    var matches = $$(expression), h = Selector.handlers;
3311 3328
     h.mark(matches);
3312 3329
     for (var i = 0, results = [], element; element = elements[i]; i++)
3313  
-      if (element._counted) results.push(element);
  3330
+      if (element._countedByPrototype) results.push(element);
3314 3331
     h.unmark(matches);
3315 3332
     return results;
3316 3333
   },
@@ -3323,10 +3340,7 @@ Object.extend(Selector, {
3323 3340
   },
3324 3341
 
3325 3342
   findChildElements: function(element, expressions) {
3326  
-    var exprs = expressions.join(','), expressions = [];
3327  
-    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
3328  
-      expressions.push(m[1].strip());
3329  
-    });
  3343
+    expressions = Selector.split(expressions.join(','));
3330 3344
     var results = [], h = Selector.handlers;
3331 3345
     for (var i = 0, l = expressions.length, selector; i < l; i++) {
3332 3346
       selector = new Selector(expressions[i].strip());
@@ -3336,6 +3350,25 @@ Object.extend(Selector, {
3336 3350
   }
3337 3351
 });
3338 3352
 
  3353
+if (Prototype.Browser.IE) {
  3354
+  Object.extend(Selector.handlers, {
  3355
+    // IE returns comment nodes on getElementsByTagName("*").
  3356
+    // Filter them out.
  3357
+    concat: function(a, b) {
  3358
+      for (var i = 0, node; node = b[i]; i++)
  3359
+        if (node.tagName !== "!") a.push(node);
  3360
+      return a;
  3361
+    },
  3362
+
  3363
+    // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
  3364
+    unmark: function(nodes) {
  3365
+      for (var i = 0, node; node = nodes[i]; i++)
  3366
+        node.removeAttribute('_countedByPrototype');
  3367
+      return nodes;
  3368
+    }
  3369
+  });
  3370
+}
  3371
+
3339 3372
 function $$() {
3340 3373
   return Selector.findChildElements(document, $A(arguments));
3341 3374
 }
@@ -3347,7 +3380,7 @@ var Form = {
3347 3380
 
3348 3381
   serializeElements: function(elements, options) {
3349 3382
     if (typeof options != 'object') options = { hash: !!options };
3350  
-    else if (options.hash === undefined) options.hash = true;
  3383
+    else if (Object.isUndefined(options.hash)) options.hash = true;
3351 3384
     var key, value, submitted = false, submit = options.submit;
3352 3385
 
3353 3386
     var data = elements.inject({ }, function(result, element) {
@@ -3545,17 +3578,17 @@ Form.Element.Serializers = {
3545 3578
   },
3546 3579
 
3547 3580
   inputSelector: function(element, value) {
3548  
-    if (value === undefined) return element.checked ? element.value : null;
  3581
+    if (Object.isUndefined(value)) return element.checked ? element.value : null;
3549 3582
     else element.checked = !!value;
3550 3583
   },
3551 3584
 
3552 3585
   textarea: function(element, value) {
3553  
-    if (value === undefined) return element.value;
  3586
+    if (Object.isUndefined(value)) return element.value;
3554 3587
     else element.value = value;
3555 3588
   },
3556 3589
 
3557 3590
   select: function(element, index) {
3558  
-    if (index === undefined)
  3591
+    if (Object.isUndefined(index))
3559 3592
       return this[element.type == 'select-one' ?
3560 3593
         'selectOne' : 'selectMany'](element);
3561 3594
     else {
@@ -3746,7 +3779,9 @@ Event.Methods = (function() {
3746 3779
 
3747 3780
     findElement: function(event, expression) {
3748 3781
       var element = Event.element(event);
3749  
-      return element.match(expression) ? element : element.up(expression);
  3782
+      if (!expression) return element;
  3783
+      var elements = [element].concat(element.ancestors());
  3784
+      return Selector.findElement(elements, expression, 0);
3750 3785
     },
3751 3786
 
3752 3787
     pointer: function(event) {
@@ -3809,9 +3844,9 @@ Object.extend(Event, (function() {
3809 3844
   var cache = Event.cache;
3810 3845
 
3811 3846
   function getEventID(element) {
3812  
-    if (element._eventID) return element._eventID;
  3847
+    if (element._prototypeEventID) return element._prototypeEventID[0];
3813 3848
     arguments.callee.id = arguments.callee.id || 1;
3814  
-    return element._eventID = ++arguments.callee.id;
  3849
+    return element._prototypeEventID = [++arguments.callee.id];
3815 3850
   }
3816 3851
 
3817 3852
   function getDOMEventName(eventName) {
@@ -3839,7 +3874,7 @@ Object.extend(Event, (function() {
3839 3874
           return false;
3840 3875
 
3841 3876
       Event.extend(event);
3842  
-      handler.call(element, event)
  3877
+      handler.call(element, event);
3843 3878
     };
3844 3879
 
3845 3880
     wrapper.handler = handler;
@@ -3921,11 +3956,12 @@ Object.extend(Event, (function() {
3921 3956
       if (element == document && document.createEvent && !element.dispatchEvent)
3922 3957
         element = document.documentElement;
3923 3958
 
  3959
+      var event;
3924 3960
       if (document.createEvent) {
3925  
-        var event = document.createEvent("HTMLEvents");
  3961
+        event = document.createEvent("HTMLEvents");
3926 3962
         event.initEvent("dataavailable", true, true);
3927 3963
       } else {
3928  
-        var event = document.createEventObject();
  3964
+        event = document.createEventObject();
3929 3965
         event.eventType = "ondataavailable";
3930 3966
       }
3931 3967
 
@@ -3938,7 +3974,7 @@ Object.extend(Event, (function() {
3938 3974
         element.fireEvent(event.eventType, event);
3939 3975
       }
3940 3976
 
3941  
-      return event;
  3977
+      return Event.extend(event);
3942 3978
     }
3943 3979
   };
3944 3980
 })());
@@ -3954,20 +3990,21 @@ Element.addMethods({
3954 3990
 Object.extend(document, {
3955 3991
   fire:          Element.Methods.fire.methodize(),
3956 3992
   observe:       Element.Methods.observe.methodize(),
3957  
-  stopObserving: Element.Methods.stopObserving.methodize()
  3993
+  stopObserving: Element.Methods.stopObserving.methodize(),
  3994
+  loaded:        false
3958 3995
 });
3959 3996
 
3960 3997
 (function() {
3961 3998
   /* Support for the DOMContentLoaded event is based on work by Dan Webb,
3962 3999
      Matthias Miller, Dean Edwards and John Resig. */
3963 4000
 
3964  
-  var timer, fired = false;
  4001
+  var timer;
3965 4002
 
3966 4003
   function fireContentLoadedEvent() {
3967  
-    if (fired) return;
  4004
+    if (document.loaded) return;
3968 4005
     if (timer) window.clearInterval(timer);
3969 4006
     document.fire("dom:loaded");
3970  
-    fired = true;
  4007
+    document.loaded = true;
3971 4008
   }
3972 4009
 
3973 4010
   if (document.addEventListener) {

0 notes on commit 0f27536

Please sign in to comment.
Something went wrong with that request. Please try again.