Merge branch 'explain-map-concat' of https://github.com/ajpiano/jquery into ajpiano...
authorjeresig <jeresig@gmail.com>
Thu, 9 Dec 2010 17:51:14 +0000 (12:51 -0500)
committerjeresig <jeresig@gmail.com>
Thu, 9 Dec 2010 17:51:14 +0000 (12:51 -0500)
41 files changed:
.gitattributes
Makefile
Rakefile
build.xml
build/google-compiler-20091218.jar [deleted file]
build/google-compiler-20100917.jar [new file with mode: 0644]
build/jslint-check.js
speed/benchmark.js
speed/closest.html [new file with mode: 0644]
speed/filter.html [new file with mode: 0644]
speed/find.html [new file with mode: 0644]
src/ajax.js
src/attributes.js
src/core.js
src/css.js
src/data.js
src/dimensions.js
src/effects.js
src/event.js
src/manipulation.js
src/offset.js
src/queue.js
src/support.js
src/traversing.js
test/data/testsuite.css
test/data/text.php
test/delegatetest.html
test/index.html
test/unit/ajax.js
test/unit/attributes.js
test/unit/core.js
test/unit/css.js
test/unit/data.js
test/unit/dimensions.js
test/unit/effects.js
test/unit/event.js
test/unit/manipulation.js
test/unit/offset.js
test/unit/selector.js
test/unit/traversing.js
version.txt

index bcb36db..d6dc470 100644 (file)
@@ -1 +1,2 @@
-* crlf=input
+*     eol=lf
+*.jar binary
index ce92f4f..0dae732 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ DIST_DIR = ${PREFIX}/dist
 
 RHINO ?= java -jar ${BUILD_DIR}/js.jar
 
-CLOSURE_COMPILER = ${BUILD_DIR}/google-compiler-20091218.jar
+CLOSURE_COMPILER = ${BUILD_DIR}/google-compiler-20100917.jar
 
 MINJAR ?= java -jar ${CLOSURE_COMPILER}
 
@@ -39,7 +39,7 @@ SIZZLE_DIR = ${SRC_DIR}/sizzle
 QUNIT_DIR = ${TEST_DIR}/qunit
 
 JQ_VER = $(shell cat version.txt)
-VER = sed s/@VERSION/${JQ_VER}/
+VER = sed "s/@VERSION/${JQ_VER}/"
 
 DATE=$(shell git log -1 --pretty=format:%ad)
 
@@ -97,8 +97,10 @@ min: ${JQ_MIN}
 ${JQ_MIN}: ${JQ}
        @@echo "Building" ${JQ_MIN}
 
-       @@head -$(shell grep -m 1 -n '*/' ${JQ} | cut -f1 -d:) ${JQ} > ${JQ_MIN}
-       @@${MINJAR} --js ${JQ} --warning_level QUIET --js_output_file ${JQ_MIN}
+       @@head -15 ${JQ} > ${JQ_MIN}
+       @@${MINJAR} --js ${JQ} --warning_level QUIET --js_output_file ${JQ_MIN}.tmp
+       @@cat ${JQ_MIN}.tmp >> ${JQ_MIN}
+       @@rm -f ${JQ_MIN}.tmp
 
 clean:
        @@echo "Removing Distribution directory:" ${DIST_DIR}
index 38406bd..d0d8f66 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -28,7 +28,7 @@ version    = File.read( File.join( prefix, 'version.txt' ) ).strip
 
 # Build tools
 rhino      = "java -jar #{build_dir}/js.jar"
-minfier    = "java -jar #{build_dir}/google-compiler-20091218.jar"
+minfier    = "java -jar #{build_dir}/google-compiler-20100917.jar"
 
 # Turn off output other than needed from `sh` and file commands
 verbose(false) 
@@ -135,4 +135,4 @@ def cat( files )
   files.map do |file|
     File.read(file)
   end.join('')
-end
\ No newline at end of file
+end
index e91cdd1..c6be9f9 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -89,7 +89,7 @@
                                <include name="jquery.js" />
                        </fileset>
                        <arg line="-jar" />
-                       <arg path="build/google-compiler-20091218.jar" />
+                       <arg path="build/google-compiler-20100917.jar" />
                        <arg value="--warning_level" />
                        <arg value="QUIET" />
                        <arg value="--js_output_file" />
diff --git a/build/google-compiler-20091218.jar b/build/google-compiler-20091218.jar
deleted file mode 100644 (file)
index da053a7..0000000
Binary files a/build/google-compiler-20091218.jar and /dev/null differ
diff --git a/build/google-compiler-20100917.jar b/build/google-compiler-20100917.jar
new file mode 100644 (file)
index 0000000..4dfa5ad
Binary files /dev/null and b/build/google-compiler-20100917.jar differ
index e76abc0..976975a 100644 (file)
@@ -12,8 +12,8 @@ var ok = {
        "Use '===' to compare with 'null'.": true,
        "Use '!==' to compare with 'null'.": true,
        "Expected an assignment or function call and instead saw an expression.": true,
-       "Expected a 'break' statement before 'case'.": true
-
+       "Expected a 'break' statement before 'case'.": true,
+       "'e' is already defined.": true
 };
 
 var e = JSLINT.errors, found = 0, w;
index 8f1aa98..50d5cad 100644 (file)
@@ -1,9 +1,15 @@
 // Runs a function many times without the function call overhead
-function benchmark(fn, times){
+function benchmark(fn, times, name){
        fn = fn.toString();
        var s = fn.indexOf('{')+1,
                e = fn.lastIndexOf('}');
        fn = fn.substring(s,e);
        
-       return new Function('i','var t=new Date;while(i--){'+fn+'};return new Date-t')(times);
+  return benchmarkString(fn, times, name);
+}
+
+function benchmarkString(fn, times, name) {
+  var fn = new Function("i", "var t=new Date; while(i--) {" + fn + "}; return new Date - t")(times)
+  fn.displayName = name || "benchmarked";
+  return fn;
 }
diff --git a/speed/closest.html b/speed/closest.html
new file mode 100644 (file)
index 0000000..bb31f5d
--- /dev/null
@@ -0,0 +1,39 @@
+<!doctype html>
+<html>
+<head>
+       <title>Test .closest() Performance</title>
+       <script src="benchmark.js"></script>
+       <script src="jquery-basis.js"></script>
+       <script>var old = jQuery.noConflict(true);</script>
+       <script src="../dist/jquery.js"></script>
+  <script>
+    jQuery(function ready() {
+      var node = $("#child"), name;
+
+      jQuery.each([".zoo", "#zoo", "[data-foo=zoo]", "#nonexistant"], function(i, item) {
+       setTimeout(function(){
+               name = "closest '" + item + "'";
+
+               jQuery("#results").append("<li>" + name + "<ul>" +
+                       "<li>new: " + benchmarkString("$('#child').closest('" + item + "')", 2500, name) + "</li>" +
+                       "<li>old: " + benchmarkString("old('#child').closest('" + item + "')", 2500, name) + "</li>"
+                       + "</ul></li>");
+       }, 100);
+      });
+    });
+  </script>
+</head>
+<body>
+  <div>
+    <p>Hello</p>
+    <div class="zoo" id="zoo" data-foo="bar">
+      <div>
+        <p id="child">lorem ipsum</p>
+        <p>dolor sit amet</p>
+      </div>
+    </div>
+  </div>
+  <ul id="results"></ul>
+</body>
+</html>
+
diff --git a/speed/filter.html b/speed/filter.html
new file mode 100644 (file)
index 0000000..43ee94e
--- /dev/null
@@ -0,0 +1,183 @@
+<!doctype html>
+<html>
+<head>
+       <title>Test .filter() Performance</title>
+       <script src="benchmark.js"></script>
+       <script src="jquery-basis.js"></script>
+       <script>var old = jQuery.noConflict(true);</script>
+       <script src="../dist/jquery.js"></script>
+  <script>
+    jQuery(function ready() {
+      var node = $("#child"), name;
+
+      jQuery.each([".zoo", "#zoo", "[data-foo=zoo]", "#nonexistant"], function(i, item) {
+       setTimeout(function(){
+               name = "filter '" + item + "'";
+               jQuery("#results").append("<li>" + name + "<ul>" +
+                       "<li>new: " + benchmarkString("$('div').filter('" + item + "')", 100, name) + "</li>" +
+                       "<li>old: " + benchmarkString("old('div').filter('" + item + "')", 100, name) + "</li>" +
+                       "</ul></li>");
+               jQuery("#results").append("<li>single " + name + "<ul>" +
+                       "<li>new: " + benchmarkString("$('#nonexistant').filter('" + item + "')", 1000, name) + "</li>" +
+                       "<li>old: " + benchmarkString("old('#nonexistant').filter('" + item + "')", 1000, name) + "</li>" +
+                       "</ul></li>");
+       }, 100);
+      });
+    });
+  </script>
+</head>
+<body>
+  <div>
+    <p>Hello</p>
+    <div class="zoo" id="nonexistant" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+  </div>
+  <ul id="results"></ul>
+</body>
+</html>
+
diff --git a/speed/find.html b/speed/find.html
new file mode 100644 (file)
index 0000000..d3a2dc1
--- /dev/null
@@ -0,0 +1,179 @@
+<!doctype html>
+<html>
+<head>
+       <title>Test .find() Performance</title>
+       <script src="benchmark.js"></script>
+       <script src="jquery-basis.js"></script>
+       <script>var old = jQuery.noConflict(true);</script>
+       <script src="../dist/jquery.js"></script>
+  <script>
+    jQuery(function ready() {
+      var node = $("#child"), name;
+
+      jQuery.each([".zoo", "#zoo", "[data-foo=zoo]", "#nonexistant"], function(i, item) {
+       setTimeout(function(){
+               name = "find '" + item + "'";
+               jQuery("#results").append("<li>rooted " + name + "<ul>" +
+                       "<li>new: " + benchmarkString("$('body').find('" + item + "')", 250, name) + "</li>" +
+                       "<li>old: " + benchmarkString("old('body').find('" + item + "')", 250, name) + "</li>" +
+                       "</ul></li>");
+       }, 100);
+      });
+    });
+  </script>
+</head>
+<body>
+  <div>
+    <p>Hello</p>
+    <div class="zoo" id="nonexistant" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+    <div class="zoo" id="zoo" data-foo="bar"><div></div></div>
+  </div>
+  <ul id="results"></ul>
+</body>
+</html>
+
index 31efc56..90dc350 100644 (file)
@@ -4,7 +4,7 @@ var jsc = jQuery.now(),
        rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
        rselectTextarea = /^(?:select|textarea)/i,
        rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
-       rnoContent = /^(?:GET|HEAD|DELETE)$/,
+       rnoContent = /^(?:GET|HEAD)$/,
        rbracket = /\[\]$/,
        jsre = /\=\?(&|$)/,
        rquery = /\?/,
@@ -180,19 +180,10 @@ jQuery.extend({
                password: null,
                traditional: false,
                */
-               // Create the request object; Microsoft failed to properly
-               // implement the XMLHttpRequest in IE7 (can't request local files),
-               // so we use the ActiveXObject when it is available
                // This function can be overriden by calling jQuery.ajaxSetup
-               xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
-                       function() {
-                               return new window.XMLHttpRequest();
-                       } :
-                       function() {
-                               try {
-                                       return new window.ActiveXObject("Microsoft.XMLHTTP");
-                               } catch(e) {}
-                       },
+               xhr: function() {
+                       return new window.XMLHttpRequest();
+               },
                accepts: {
                        xml: "application/xml, text/xml",
                        html: "text/html",
@@ -204,10 +195,24 @@ jQuery.extend({
        },
 
        ajax: function( origSettings ) {
+               // IE8 leaks a lot when we've set abort, and IE6-8 a little
+               // when we have set onreadystatechange. Bug #6242
+               // XXX IE7 still leaks when abort is called, no matter what
+               // we do
+               function cleanup() {
+                       // IE6 will throw an error setting xhr.abort
+                       try {
+                               xhr.abort = xhr.onreadystatechange = jQuery.noop;
+                       } catch(e) {}
+               }
+
                var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
                        jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
 
-               s.url = s.url.replace( rhash, "" );
+               // toString fixes people passing a window.location or
+               // document.location to $.ajax, which worked in 1.4.2 and
+               // earlier (bug #7531). It should be removed in 1.5.
+               s.url = ("" + s.url).replace( rhash, "" );
 
                // Use original (not extended) context object if it was provided
                s.context = origSettings && origSettings.context != null ? origSettings.context : s;
@@ -248,10 +253,6 @@ jQuery.extend({
                        var customJsonp = window[ jsonp ];
 
                        window[ jsonp ] = function( tmp ) {
-                               data = tmp;
-                               jQuery.ajax.handleSuccess( s, xhr, status, data );
-                               jQuery.ajax.handleComplete( s, xhr, status, data );
-                               
                                if ( jQuery.isFunction( customJsonp ) ) {
                                        customJsonp( tmp );
 
@@ -263,6 +264,10 @@ jQuery.extend({
                                                delete window[ jsonp ];
                                        } catch( jsonpError ) {}
                                }
+
+                               data = tmp;
+                               jQuery.handleSuccess( s, xhr, status, data );
+                               jQuery.handleComplete( s, xhr, status, data );
                                
                                if ( head ) {
                                        head.removeChild( script );
@@ -270,11 +275,11 @@ jQuery.extend({
                        };
                }
 
-               if ( s.dataType === "script" && s.cache === null ) {
+               if ( s.dataType === "script" && s.cache === undefined ) {
                        s.cache = false;
                }
 
-               if ( s.cache === false && type === "GET" ) {
+               if ( s.cache === false && noContent ) {
                        var ts = jQuery.now();
 
                        // try replacing _= if it is there
@@ -284,19 +289,19 @@ jQuery.extend({
                        s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
                }
 
-               // If data is available, append data to url for get requests
-               if ( s.data && type === "GET" ) {
+               // If data is available, append data to url for GET/HEAD requests
+               if ( s.data && noContent ) {
                        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
                }
 
                // Watch for a new set of requests
-               if ( s.global && jQuery.ajax.active++ === 0 ) {
+               if ( s.global && jQuery.active++ === 0 ) {
                        jQuery.event.trigger( "ajaxStart" );
                }
 
                // Matches an absolute URL, and saves the domain
                var parts = rurl.exec( s.url ),
-                       remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+                       remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
 
                // If we're requesting a remote document
                // and trying to load JSON or Script with a GET
@@ -317,8 +322,8 @@ jQuery.extend({
                                        if ( !done && (!this.readyState ||
                                                        this.readyState === "loaded" || this.readyState === "complete") ) {
                                                done = true;
-                                               jQuery.ajax.handleSuccess( s, xhr, status, data );
-                                               jQuery.ajax.handleComplete( s, xhr, status, data );
+                                               jQuery.handleSuccess( s, xhr, status, data );
+                                               jQuery.handleComplete( s, xhr, status, data );
 
                                                // Handle memory leak in IE
                                                script.onload = script.onreadystatechange = null;
@@ -367,8 +372,8 @@ jQuery.extend({
                                        xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
                                }
 
-                               if ( jQuery.ajax.etag[s.url] ) {
-                                       xhr.setRequestHeader("If-None-Match", jQuery.ajax.etag[s.url]);
+                               if ( jQuery.etag[s.url] ) {
+                                       xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
                                }
                        }
 
@@ -387,7 +392,7 @@ jQuery.extend({
                // Allow custom headers/mimetypes and early abort
                if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
                        // Handle the global AJAX counter
-                       if ( s.global && jQuery.ajax.active-- === 1 ) {
+                       if ( s.global && jQuery.active-- === 1 ) {
                                jQuery.event.trigger( "ajaxStop" );
                        }
 
@@ -397,7 +402,7 @@ jQuery.extend({
                }
 
                if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxSend", [xhr, s] );
+                       jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
                }
 
                // Wait for a response to come back
@@ -407,24 +412,23 @@ jQuery.extend({
                                // Opera doesn't call onreadystatechange before this point
                                // so we simulate the call
                                if ( !requestDone ) {
-                                       jQuery.ajax.handleComplete( s, xhr, status, data );
+                                       jQuery.handleComplete( s, xhr, status, data );
                                }
 
                                requestDone = true;
                                if ( xhr ) {
-                                       xhr.onreadystatechange = jQuery.noop;
+                                       cleanup();
                                }
 
                        // The transfer is complete and the data is available, or the request timed out
                        } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
                                requestDone = true;
-                               xhr.onreadystatechange = jQuery.noop;
 
                                status = isTimeout === "timeout" ?
                                        "timeout" :
-                                       !jQuery.ajax.httpSuccess( xhr ) ?
+                                       !jQuery.httpSuccess( xhr ) ?
                                                "error" :
-                                               s.ifModified && jQuery.ajax.httpNotModified( xhr, s.url ) ?
+                                               s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
                                                        "notmodified" :
                                                        "success";
 
@@ -434,7 +438,7 @@ jQuery.extend({
                                        // Watch for, and catch, XML document parse errors
                                        try {
                                                // process the data (runs the xml through httpData regardless of callback)
-                                               data = jQuery.ajax.httpData( xhr, s.dataType, s );
+                                               data = jQuery.httpData( xhr, s.dataType, s );
                                        } catch( parserError ) {
                                                status = "parsererror";
                                                errMsg = parserError;
@@ -445,35 +449,35 @@ jQuery.extend({
                                if ( status === "success" || status === "notmodified" ) {
                                        // JSONP handles its own success callback
                                        if ( !jsonp ) {
-                                               jQuery.ajax.handleSuccess( s, xhr, status, data );
+                                               jQuery.handleSuccess( s, xhr, status, data );
                                        }
                                } else {
-                                       jQuery.ajax.handleError( s, xhr, status, errMsg );
+                                       jQuery.handleError( s, xhr, status, errMsg );
                                }
 
                                // Fire the complete handlers
                                if ( !jsonp ) {
-                                       jQuery.ajax.handleComplete( s, xhr, status, data );
+                                       jQuery.handleComplete( s, xhr, status, data );
                                }
 
                                if ( isTimeout === "timeout" ) {
                                        xhr.abort();
                                }
 
-                               // Stop memory leaks
-                               if ( s.async ) {
-                                       xhr = null;
-                               }
+                               cleanup();
                        }
                };
 
-               // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
+               // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
                // Opera doesn't fire onreadystatechange at all on abort
                try {
                        var oldAbort = xhr.abort;
                        xhr.abort = function() {
                                if ( xhr ) {
-                                       oldAbort.call( xhr );
+                                       // oldAbort has no call property in IE7 so
+                                       // just do it this way, which works in all
+                                       // browsers
+                                       Function.prototype.call.call( oldAbort, xhr );
                                }
 
                                onreadystatechange( "abort" );
@@ -495,10 +499,10 @@ jQuery.extend({
                        xhr.send( noContent || s.data == null ? null : s.data );
 
                } catch( sendError ) {
-                       jQuery.ajax.handleError( s, xhr, null, sendError );
+                       jQuery.handleError( s, xhr, null, sendError );
 
                        // Fire the complete handlers
-                       jQuery.ajax.handleComplete( s, xhr, status, data );
+                       jQuery.handleComplete( s, xhr, status, data );
                }
 
                // firefox 1.5 doesn't fire statechange for sync requests
@@ -513,11 +517,12 @@ jQuery.extend({
        // Serialize an array of form elements or a set of
        // key/values into a query string
        param: function( a, traditional ) {
-               var s = [], add = function( key, value ) {
-                       // If value is a function, invoke it and return its value
-                       value = jQuery.isFunction(value) ? value() : value;
-                       s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
-               };
+               var s = [],
+                       add = function( key, value ) {
+                               // If value is a function, invoke it and return its value
+                               value = jQuery.isFunction(value) ? value() : value;
+                               s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+                       };
                
                // Set traditional to true for jQuery <= 1.3.2 behavior.
                if ( traditional === undefined ) {
@@ -581,7 +586,9 @@ function buildParams( prefix, obj, traditional, add ) {
        }
 }
 
-jQuery.extend( jQuery.ajax, {
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
 
        // Counter for holding the number of active queries
        active: 0,
@@ -598,7 +605,7 @@ jQuery.extend( jQuery.ajax, {
 
                // Fire the global callback
                if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxError", [xhr, s, e] );
+                       jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
                }
        },
 
@@ -610,7 +617,7 @@ jQuery.extend( jQuery.ajax, {
 
                // Fire the global callback
                if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
+                       jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
                }
        },
 
@@ -622,11 +629,11 @@ jQuery.extend( jQuery.ajax, {
 
                // The request was completed
                if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxComplete", [xhr, s] );
+                       jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
                }
 
                // Handle the global AJAX counter
-               if ( s.global && jQuery.ajax.active-- === 1 ) {
+               if ( s.global && jQuery.active-- === 1 ) {
                        jQuery.event.trigger( "ajaxStop" );
                }
        },
@@ -653,11 +660,11 @@ jQuery.extend( jQuery.ajax, {
                        etag = xhr.getResponseHeader("Etag");
 
                if ( lastModified ) {
-                       jQuery.ajax.lastModified[url] = lastModified;
+                       jQuery.lastModified[url] = lastModified;
                }
 
                if ( etag ) {
-                       jQuery.ajax.etag[url] = etag;
+                       jQuery.etag[url] = etag;
                }
 
                return xhr.status === 304;
@@ -695,10 +702,28 @@ jQuery.extend( jQuery.ajax, {
 
 });
 
+/*
+ * Create the request object; Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+if ( window.ActiveXObject ) {
+       jQuery.ajaxSettings.xhr = function() {
+               if ( window.location.protocol !== "file:" ) {
+                       try {
+                               return new window.XMLHttpRequest();
+                       } catch(xhrError) {}
+               }
+
+               try {
+                       return new window.ActiveXObject("Microsoft.XMLHTTP");
+               } catch(activeError) {}
+       };
+}
+
 // Does this browser support XHR requests?
 jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
 
-// For backwards compatibility
-jQuery.extend( jQuery.ajax );
-
 })( jQuery );
index cb9f2cf..78b1bfd 100644 (file)
@@ -1,6 +1,6 @@
 (function( jQuery ) {
 
-var rclass = /[\n\t]/g,
+var rclass = /[\n\t\r]/g,
        rspaces = /\s+/,
        rreturn = /\r/g,
        rspecialurl = /^(?:href|src|style)$/,
@@ -9,6 +9,19 @@ var rclass = /[\n\t]/g,
        rclickable = /^a(?:rea)?$/i,
        rradiocheck = /^(?:radio|checkbox)$/i;
 
+jQuery.props = {
+       "for": "htmlFor",
+       "class": "className",
+       readonly: "readOnly",
+       maxlength: "maxLength",
+       cellspacing: "cellSpacing",
+       rowspan: "rowSpan",
+       colspan: "colSpan",
+       tabindex: "tabIndex",
+       usemap: "useMap",
+       frameborder: "frameBorder"
+};
+
 jQuery.fn.extend({
        attr: function( name, value ) {
                return jQuery.access( this, name, value, true, jQuery.attr );
@@ -42,7 +55,9 @@ jQuery.fn.extend({
                                                elem.className = value;
 
                                        } else {
-                                               var className = " " + elem.className + " ", setClass = elem.className;
+                                               var className = " " + elem.className + " ",
+                                                       setClass = elem.className;
+
                                                for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
                                                        if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
                                                                setClass += " " + classNames[c];
@@ -90,7 +105,8 @@ jQuery.fn.extend({
        },
 
        toggleClass: function( value, stateVal ) {
-               var type = typeof value, isBool = typeof stateVal === "boolean";
+               var type = typeof value,
+                       isBool = typeof stateVal === "boolean";
 
                if ( jQuery.isFunction( value ) ) {
                        return this.each(function(i) {
@@ -102,7 +118,9 @@ jQuery.fn.extend({
                return this.each(function() {
                        if ( type === "string" ) {
                                // toggle individual class names
-                               var className, i = 0, self = jQuery(this),
+                               var className,
+                                       i = 0,
+                                       self = jQuery( this ),
                                        state = stateVal,
                                        classNames = value.split( rspaces );
 
@@ -187,7 +205,6 @@ jQuery.fn.extend({
                                if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
                                        return elem.getAttribute("value") === null ? "on" : elem.value;
                                }
-                               
 
                                // Everything else, we just grab the value
                                return (elem.value || "").replace(rreturn, "");
@@ -215,6 +232,10 @@ jQuery.fn.extend({
                                val = "";
                        } else if ( typeof val === "number" ) {
                                val += "";
+                       } else if ( jQuery.isArray(val) ) {
+                               val = jQuery.map(val, function (value) {
+                                       return value == null ? "" : value + "";
+                               });
                        }
 
                        if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
@@ -249,10 +270,10 @@ jQuery.extend({
                height: true,
                offset: true
        },
-               
+
        attr: function( elem, name, value, pass ) {
-               // don't set attributes on text and comment nodes
-               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+               // don't get/set attributes on text, comment and attribute nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
                        return undefined;
                }
 
@@ -278,7 +299,7 @@ jQuery.extend({
                                var parent = elem.parentNode;
                                if ( parent ) {
                                        parent.selectedIndex;
-       
+
                                        // Make sure that it also works with optgroups, see #5701
                                        if ( parent.parentNode ) {
                                                parent.parentNode.selectedIndex;
@@ -295,7 +316,14 @@ jQuery.extend({
                                                jQuery.error( "type property can't be changed" );
                                        }
 
-                                       elem[ name ] = value;
+                                       if ( value === null ) {
+                                               if ( elem.nodeType === 1 ) {
+                                                       elem.removeAttribute( name );
+                                               }
+
+                                       } else {
+                                               elem[ name ] = value;
+                                       }
                                }
 
                                // browsers index elements by id/name on forms, give priority to attributes.
@@ -345,6 +373,11 @@ jQuery.extend({
                        // Non-existent attributes return null, we normalize to undefined
                        return attr === null ? undefined : attr;
                }
+               // Handle everything which isn't a DOM element node
+               if ( set ) {
+                       elem[ name ] = value;
+               }
+               return elem[ name ];
        }
 });
 
index 3c7572f..008a88c 100644 (file)
@@ -215,7 +215,7 @@ jQuery.fn = jQuery.prototype = {
                        this.toArray() :
 
                        // Return just the object
-                       ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+                       ( num < 0 ? this[ this.length + num ] : this[ num ] );
        },
 
        // Take an array of elements and push it onto the stack
@@ -311,8 +311,11 @@ jQuery.fn = jQuery.prototype = {
 jQuery.fn.init.prototype = jQuery.fn;
 
 jQuery.extend = jQuery.fn.extend = function() {
-       // copy reference to target object
-       var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray;
+        var options, name, src, copy, copyIsArray, clone,
+               target = arguments[0] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
 
        // Handle a deep copy situation
        if ( typeof target === "boolean" ) {
@@ -414,18 +417,21 @@ jQuery.extend({
                        // If there are functions bound, to execute
                        if ( readyList ) {
                                // Execute all of them
-                               var fn, i = 0;
-                               while ( (fn = readyList[ i++ ]) ) {
-                                       fn.call( document, jQuery );
-                               }
+                               var fn,
+                                       i = 0,
+                                       ready = readyList;
 
                                // Reset the list of functions
                                readyList = null;
-                       }
 
-                       // Trigger any bound ready events
-                       if ( jQuery.fn.triggerHandler ) {
-                               jQuery( document ).triggerHandler( "ready" );
+                               while ( (fn = ready[ i++ ]) ) {
+                                       fn.call( document, jQuery );
+                               }
+
+                               // Trigger any bound ready events
+                               if ( jQuery.fn.trigger ) {
+                                       jQuery( document ).trigger( "ready" ).unbind( "ready" );
+                               }
                        }
                }
        },
@@ -526,6 +532,12 @@ jQuery.extend({
        },
 
        isEmptyObject: function( obj ) {
+
+    // Fixes #7413 Check to see if obj passes isPlainObject
+    if ( !jQuery.isPlainObject( obj ) ) {
+      return false;
+    }
+       
                for ( var name in obj ) {
                        return false;
                }
@@ -678,7 +690,8 @@ jQuery.extend({
        },
 
        merge: function( first, second ) {
-               var i = first.length, j = 0;
+               var i = first.length,
+                       j = 0;
 
                if ( typeof second.length === "number" ) {
                        for ( var l = second.length; j < l; j++ ) {
index 07ff686..8a83c60 100644 (file)
@@ -1,6 +1,6 @@
 (function( jQuery ) {
 
-var ralpha = /alpha\([^)]*\)/,
+var ralpha = /alpha\([^)]*\)/i,
        ropacity = /opacity=([^)]*)/,
        rdashAlpha = /-([a-z])/ig,
        rupper = /([A-Z])/g,
@@ -12,14 +12,19 @@ var ralpha = /alpha\([^)]*\)/,
        cssHeight = [ "Top", "Bottom" ],
        curCSS,
 
-       // cache check for defaultView.getComputedStyle
-       getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+       getComputedStyle,
+       currentStyle,
 
        fcamelCase = function( all, letter ) {
                return letter.toUpperCase();
        };
 
 jQuery.fn.css = function( name, value ) {
+       // Setting 'undefined' is a no-op
+       if ( arguments.length === 2 && value === undefined ) {
+               return this;
+       }
+
        return jQuery.access( this, name, value, true, function( elem, name, value ) {
                return value !== undefined ?
                        jQuery.style( elem, name, value ) :
@@ -65,7 +70,7 @@ jQuery.extend({
        style: function( elem, name, value, extra ) {
                // Don't set styles on text and comment nodes
                if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
-                       return undefined;
+                       return;
                }
 
                // Make sure that we're working with the right name
@@ -76,6 +81,11 @@ jQuery.extend({
 
                // Check if we're setting a value
                if ( value !== undefined ) {
+                       // Make sure that NaN and null values aren't set. See: #7116
+                       if ( typeof value === "number" && isNaN( value ) || value == null ) {
+                               return;
+                       }
+
                        // If a number was passed in, add 'px' to the (except for certain CSS properties)
                        if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
                                value += "px";
@@ -83,7 +93,11 @@ jQuery.extend({
 
                        // If a hook was provided, use that value, otherwise just set the specified value
                        if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
-                               style[ name ] = value;
+                               // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+                               // Fixes bug #5509
+                               try {
+                                       style[ name ] = value;
+                               } catch(e) {}
                        }
 
                } else {
@@ -155,7 +169,29 @@ jQuery.each(["height", "width"], function( i, name ) {
                                        });
                                }
 
-                               return val + "px";
+                               if ( val <= 0 ) {
+                                       val = curCSS( elem, name, name );
+
+                                       if ( val === "0px" && currentStyle ) {
+                                               val = currentStyle( elem, name, name );
+                                       }
+
+                                       if ( val != null ) {
+                                               // Should return "auto" instead of 0, use 0 for
+                                               // temporary backwards-compat
+                                               return val === "" || val === "auto" ? "0px" : val;
+                                       }
+                               }
+
+                               if ( val < 0 || val == null ) {
+                                       val = elem.style[ name ];
+
+                                       // Should return "auto" instead of 0, use 0 for
+                                       // temporary backwards-compat
+                                       return val === "" || val === "auto" ? "0px" : val;
+                               }
+
+                               return typeof val === "string" ? val : val + "px";
                        }
                },
 
@@ -199,13 +235,13 @@ if ( !jQuery.support.opacity ) {
 
                        style.filter = ralpha.test(filter) ?
                                filter.replace(ralpha, opacity) :
-                               opacity;
+                               style.filter + ' ' + opacity;
                }
        };
 }
 
-if ( getComputedStyle ) {
-       curCSS = function( elem, newName, name ) {
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+       getComputedStyle = function( elem, newName, name ) {
                var ret, defaultView, computedStyle;
 
                name = name.replace( rupper, "-$1" ).toLowerCase();
@@ -216,14 +252,20 @@ if ( getComputedStyle ) {
 
                if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
                        ret = computedStyle.getPropertyValue( name );
+                       if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+                               ret = jQuery.style( elem, name );
+                       }
                }
 
                return ret;
        };
+}
 
-} else if ( document.documentElement.currentStyle ) {
-       curCSS = function( elem, name ) {
-               var left, rsLeft, ret = elem.currentStyle && elem.currentStyle[ name ], style = elem.style;
+if ( document.documentElement.currentStyle ) {
+       currentStyle = function( elem, name ) {
+               var left, rsLeft,
+                       ret = elem.currentStyle && elem.currentStyle[ name ],
+                       style = elem.style;
 
                // From the awesome hack by Dean Edwards
                // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
@@ -245,10 +287,12 @@ if ( getComputedStyle ) {
                        elem.runtimeStyle.left = rsLeft;
                }
 
-               return ret;
+               return ret === "" ? "auto" : ret;
        };
 }
 
+curCSS = getComputedStyle || currentStyle;
+
 function getWH( elem, name, extra ) {
        var which = name === "width" ? cssWidth : cssHeight,
                val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
@@ -275,14 +319,10 @@ function getWH( elem, name, extra ) {
 
 if ( jQuery.expr && jQuery.expr.filters ) {
        jQuery.expr.filters.hidden = function( elem ) {
-               var width = elem.offsetWidth, height = elem.offsetHeight,
-                       skip = elem.nodeName.toLowerCase() === "tr";
-
-               return width === 0 && height === 0 && !skip ?
-                       true :
-                       width > 0 && height > 0 && !skip ?
-                               false :
-                               (elem.style.display || jQuery.css( elem, "display" )) === "none";
+               var width = elem.offsetWidth,
+                       height = elem.offsetHeight;
+
+               return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
        };
 
        jQuery.expr.filters.visible = function( elem ) {
index 43ab595..f1e031f 100644 (file)
@@ -30,18 +30,17 @@ jQuery.extend({
                        windowData :
                        elem;
 
-               var id = elem[ jQuery.expando ], cache = jQuery.cache, thisCache,
-                       isNode = elem.nodeType,
-                       store;
+               var isNode = elem.nodeType,
+                       id = isNode ? elem[ jQuery.expando ] : null,
+                       cache = jQuery.cache, thisCache;
 
-               if ( !id && typeof name === "string" && data === undefined ) {
+               if ( isNode && !id && typeof name === "string" && data === undefined ) {
                        return;
                }
 
                // Get the data from the object directly
                if ( !isNode ) {
                        cache = elem;
-                       id = jQuery.expando;
 
                // Compute a unique ID for the element
                } else if ( !id ) {
@@ -55,26 +54,14 @@ jQuery.extend({
                                cache[ id ] = jQuery.extend(cache[ id ], name);
 
                        } else {
-                               store = jQuery.extend(cache[ id ], name);
-                               cache[ id ] = function() {
-                                       return store;
-                               };
+                               jQuery.extend( cache, name );
                        }
 
-               } else if ( !cache[ id ] ) {
-                       if ( isNode ) {
-                               cache[ id ] = {};
-
-                       } else {
-                               store = {};
-                               cache[ id ] = function() {
-                                       return store;
-                               };
-                       }
-                       
+               } else if ( isNode && !cache[ id ] ) {
+                       cache[ id ] = {};
                }
 
-               thisCache = isNode ? cache[ id ] : cache[ id ]();
+               thisCache = isNode ? cache[ id ] : cache;
 
                // Prevent overriding the named cache with undefined values
                if ( data !== undefined ) {
@@ -94,11 +81,9 @@ jQuery.extend({
                        elem;
 
                var isNode = elem.nodeType,
-                       id = elem[ jQuery.expando ], cache = jQuery.cache;
-               if ( id && !isNode ) {
-                       id = id();
-               }
-               var thisCache = cache[ id ];
+                       id = isNode ? elem[ jQuery.expando ] : elem,
+                       cache = jQuery.cache,
+                       thisCache = isNode ? cache[ id ] : id;
 
                // If we want to remove a specific section of the element's data
                if ( name ) {
@@ -107,23 +92,28 @@ jQuery.extend({
                                delete thisCache[ name ];
 
                                // If we've removed all the data, remove the element's cache
-                               if ( jQuery.isEmptyObject(thisCache) ) {
+                               if ( isNode && jQuery.isEmptyObject(thisCache) ) {
                                        jQuery.removeData( elem );
                                }
                        }
 
                // Otherwise, we want to remove all of the element's data
                } else {
-                       if ( jQuery.support.deleteExpando || !isNode ) {
+                       if ( isNode && jQuery.support.deleteExpando ) {
                                delete elem[ jQuery.expando ];
 
                        } else if ( elem.removeAttribute ) {
                                elem.removeAttribute( jQuery.expando );
-                       }
 
                        // Completely remove the data cache
-                       if ( isNode ) {
+                       } else if ( isNode ) {
                                delete cache[ id ];
+
+                       // Remove all fields from the object
+                       } else {
+                               for ( var n in elem ) {
+                                       delete elem[ n ];
+                               }
                        }
                }
        },
@@ -131,7 +121,7 @@ jQuery.extend({
        // A method for determining if a DOM node can handle the data expando
        acceptData: function( elem ) {
                if ( elem.nodeName ) {
-                       match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+                       var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
 
                        if ( match ) {
                                return !(match === true || elem.getAttribute("classid") !== match);
@@ -144,8 +134,26 @@ jQuery.extend({
 
 jQuery.fn.extend({
        data: function( key, value ) {
+               var data = null;
+
                if ( typeof key === "undefined" ) {
-                       return this.length ? jQuery.data( this[0] ) : null;
+                       if ( this.length ) {
+                               data = jQuery.data( this[0] );
+
+                               if ( this[0].nodeType === 1 ) {
+                                       var attr = this[0].attributes, name;
+                                       for ( var i = 0, l = attr.length; i < l; i++ ) {
+                                               name = attr[i].name;
+       
+                                               if ( name.indexOf( "data-" ) === 0 ) {
+                                                       name = name.substr( 5 );
+                                                       dataAttr( this[0], name, data[ name ] );
+                                               }
+                                       }
+                               }
+                       }
+
+                       return data;
 
                } else if ( typeof key === "object" ) {
                        return this.each(function() {
@@ -157,31 +165,12 @@ jQuery.fn.extend({
                parts[1] = parts[1] ? "." + parts[1] : "";
 
                if ( value === undefined ) {
-                       var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+                       data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
 
                        // Try to fetch any internally stored data first
                        if ( data === undefined && this.length ) {
                                data = jQuery.data( this[0], key );
-
-                               // If nothing was found internally, try to fetch any
-                               // data from the HTML5 data-* attribute
-                               if ( data === undefined && this[0].nodeType === 1 ) {
-                                       data = this[0].getAttribute( "data-" + key );
-
-                                       if ( typeof data === "string" ) {
-                                               try {
-                                                       data = data === "true" ? true :
-                                                               data === "false" ? false :
-                                                               data === "null" ? null :
-                                                               !jQuery.isNaN( data ) ? parseFloat( data ) :
-                                                               rbrace.test( data ) ? jQuery.parseJSON( data ) :
-                                                               data;
-                                               } catch( e ) {}
-
-                                       } else {
-                                               data = undefined;
-                                       }
-                               }
+                               data = dataAttr( this[0], key, data );
                        }
 
                        return data === undefined && parts[1] ?
@@ -190,7 +179,8 @@ jQuery.fn.extend({
 
                } else {
                        return this.each(function() {
-                               var $this = jQuery( this ), args = [ parts[0], value ];
+                               var $this = jQuery( this ),
+                                       args = [ parts[0], value ];
 
                                $this.triggerHandler( "setData" + parts[1] + "!", args );
                                jQuery.data( this, key, value );
@@ -206,4 +196,31 @@ jQuery.fn.extend({
        }
 });
 
+function dataAttr( elem, key, data ) {
+       // If nothing was found internally, try to fetch any
+       // data from the HTML5 data-* attribute
+       if ( data === undefined && elem.nodeType === 1 ) {
+               data = elem.getAttribute( "data-" + key );
+
+               if ( typeof data === "string" ) {
+                       try {
+                               data = data === "true" ? true :
+                               data === "false" ? false :
+                               data === "null" ? null :
+                               !jQuery.isNaN( data ) ? parseFloat( data ) :
+                                       rbrace.test( data ) ? jQuery.parseJSON( data ) :
+                                       data;
+                       } catch( e ) {}
+
+                       // Make sure we set the data so it isn't changed later
+                       jQuery.data( elem, key, data );
+
+               } else {
+                       data = undefined;
+               }
+       }
+
+       return data;
+}
+
 })( jQuery );
index 5aafbf4..f35b0ac 100644 (file)
@@ -33,27 +33,31 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
                        });
                }
 
-               return jQuery.isWindow( elem ) ?
+               if ( jQuery.isWindow( elem ) ) {
                        // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
-                       elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
-                       elem.document.body[ "client" + name ] :
-
-                       // Get document width or height
-                       (elem.nodeType === 9) ? // is it a document
-                               // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
-                               Math.max(
-                                       elem.documentElement["client" + name],
-                                       elem.body["scroll" + name], elem.documentElement["scroll" + name],
-                                       elem.body["offset" + name], elem.documentElement["offset" + name]
-                               ) :
-
-                               // Get or set width or height on the element
-                               size === undefined ?
-                                       // Get width or height on the element
-                                       parseFloat( jQuery.css( elem, type ) ) :
-
-                                       // Set the width or height on the element (default to pixels if value is unitless)
-                                       this.css( type, typeof size === "string" ? size : size + "px" );
+                       return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+                               elem.document.body[ "client" + name ];
+
+               // Get document width or height
+               } else if ( elem.nodeType === 9 ) {
+                       // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+                       return Math.max(
+                               elem.documentElement["client" + name],
+                               elem.body["scroll" + name], elem.documentElement["scroll" + name],
+                               elem.body["offset" + name], elem.documentElement["offset" + name]
+                       );
+
+               // Get or set width or height on the element
+               } else if ( size === undefined ) {
+                       var orig = jQuery.css( elem, type ),
+                               ret = parseFloat( orig );
+
+                       return jQuery.isNaN( ret ) ? orig : ret;
+
+               // Set the width or height on the element (default to pixels if value is unitless)
+               } else {
+                       return this.css( type, typeof size === "string" ? size : size + "px" );
+               }
        };
 
 });
index 56141bb..067383b 100644 (file)
@@ -2,7 +2,7 @@
 
 var elemdisplay = {},
        rfxtypes = /^(?:toggle|show|hide)$/,
-       rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
+       rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
        timerId,
        fxAttrs = [
                // height animations
@@ -15,43 +15,39 @@ var elemdisplay = {},
 
 jQuery.fn.extend({
        show: function( speed, easing, callback ) {
-               if ( speed || speed === 0) {
+               var elem, display;
+
+               if ( speed || speed === 0 ) {
                        return this.animate( genFx("show", 3), speed, easing, callback);
 
                } else {
-                       for ( var i = 0, l = this.length; i < l; i++ ) {
-                               var old = jQuery.data(this[i], "olddisplay");
-
-                               this[i].style.display = old || "";
-
-                               if ( jQuery.css( this[i], "display" ) === "none" ) {
-                                       var nodeName = this[i].nodeName, display;
-
-                                       if ( elemdisplay[ nodeName ] ) {
-                                               display = elemdisplay[ nodeName ];
-
-                                       } else {
-                                               var elem = jQuery("<" + nodeName + ">").appendTo("body");
-
-                                               display = elem.css("display");
-
-                                               if ( display === "none" ) {
-                                                       display = "block";
-                                               }
-
-                                               elem.remove();
-
-                                               elemdisplay[ nodeName ] = display;
-                                       }
+                       for ( var i = 0, j = this.length; i < j; i++ ) {
+                               elem = this[i];
+                               display = elem.style.display;
+
+                               // Reset the inline display of this element to learn if it is
+                               // being hidden by cascaded rules or not
+                               if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
+                                       display = elem.style.display = "";
+                               }
 
-                                       jQuery.data(this[i], "olddisplay", display);
+                               // Set elements which have been overridden with display: none
+                               // in a stylesheet to whatever the default browser style is
+                               // for such an element
+                               if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+                                       jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
                                }
                        }
 
-                       // Set the display of the elements in a second loop
+                       // Set the display of most of the elements in a second loop
                        // to avoid the constant reflow
-                       for ( var j = 0, k = this.length; j < k; j++ ) {
-                               this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
+                       for ( i = 0; i < j; i++ ) {
+                               elem = this[i];
+                               display = elem.style.display;
+
+                               if ( display === "" || display === "none" ) {
+                                       elem.style.display = jQuery.data(elem, "olddisplay") || "";
+                               }
                        }
 
                        return this;
@@ -63,17 +59,18 @@ jQuery.fn.extend({
                        return this.animate( genFx("hide", 3), speed, easing, callback);
 
                } else {
-                       for ( var i = 0, l = this.length; i < l; i++ ) {
-                               var old = jQuery.data(this[i], "olddisplay");
-                               if ( !old && old !== "none" ) {
-                                       jQuery.data( this[i], "olddisplay", jQuery.css( this[i], "display" ) );
+                       for ( var i = 0, j = this.length; i < j; i++ ) {
+                               var display = jQuery.css( this[i], "display" );
+
+                               if ( display !== "none" ) {
+                                       jQuery.data( this[i], "olddisplay", display );
                                }
                        }
 
                        // Set the display of the elements in a second loop
                        // to avoid the constant reflow
-                       for ( var j = 0, k = this.length; j < k; j++ ) {
-                               this[j].style.display = "none";
+                       for ( i = 0; i < j; i++ ) {
+                               this[i].style.display = "none";
                        }
 
                        return this;
@@ -115,8 +112,12 @@ jQuery.fn.extend({
                }
 
                return this[ optall.queue === false ? "each" : "queue" ](function() {
+                       // XXX 'this' does not always have a nodeName when running the
+                       // test suite
+
                        var opt = jQuery.extend({}, optall), p,
-                               hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
+                               isElement = this.nodeType === 1,
+                               hidden = isElement && jQuery(this).is(":hidden"),
                                self = this;
 
                        for ( p in prop ) {
@@ -132,12 +133,35 @@ jQuery.fn.extend({
                                        return opt.complete.call(this);
                                }
 
-                               if ( ( p === "height" || p === "width" ) && this.style ) {
-                                       // Store display property
-                                       opt.display = this.style.display;
-
+                               if ( isElement && ( p === "height" || p === "width" ) ) {
                                        // Make sure that nothing sneaks out
-                                       opt.overflow = this.style.overflow;
+                                       // Record all 3 overflow attributes because IE does not
+                                       // change the overflow attribute when overflowX and
+                                       // overflowY are set to the same value
+                                       opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+                                       // Set display property to inline-block for height/width
+                                       // animations on inline elements that are having width/height
+                                       // animated
+                                       if ( jQuery.css( this, "display" ) === "inline" &&
+                                                       jQuery.css( this, "float" ) === "none" ) {
+                                               if ( !jQuery.support.inlineBlockNeedsLayout ) {
+                                                       this.style.display = "inline-block";
+
+                                               } else {
+                                                       var display = defaultDisplay(this.nodeName);
+
+                                                       // inline-level elements accept inline-block;
+                                                       // block-level elements need to be inline with layout
+                                                       if ( display === "inline" ) {
+                                                               this.style.display = "inline-block";
+
+                                                       } else {
+                                                               this.style.display = "inline";
+                                                               this.style.zoom = 1;
+                                                       }
+                                               }
+                                       }
                                }
 
                                if ( jQuery.isArray( prop[p] ) ) {
@@ -161,7 +185,7 @@ jQuery.fn.extend({
 
                                } else {
                                        var parts = rfxnum.exec(val),
-                                               start = e.cur(true) || 0;
+                                               start = e.cur() || 0;
 
                                        if ( parts ) {
                                                var end = parseFloat( parts[2] ),
@@ -169,9 +193,9 @@ jQuery.fn.extend({
 
                                                // We need to compute starting value
                                                if ( unit !== "px" ) {
-                                                       self.style[ name ] = (end || 1) + unit;
-                                                       start = ((end || 1) / e.cur(true)) * start;
-                                                       self.style[ name ] = start + unit;
+                                                       jQuery.style( self, name, (end || 1) + unit);
+                                                       start = ((end || 1) / e.cur()) * start;
+                                                       jQuery.style( self, name, start + unit);
                                                }
 
                                                // If a +=/-= token was provided, we're doing a relative animation
@@ -239,7 +263,8 @@ jQuery.each({
        slideUp: genFx("hide", 1),
        slideToggle: genFx("toggle", 1),
        fadeIn: { opacity: "show" },
-       fadeOut: { opacity: "hide" }
+       fadeOut: { opacity: "hide" },
+       fadeToggle: { opacity: "toggle" }
 }, function( name, props ) {
        jQuery.fn[ name ] = function( speed, easing, callback ) {
                return this.animate( props, speed, easing, callback );
@@ -303,11 +328,6 @@ jQuery.fx.prototype = {
                }
 
                (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
-
-               // Set display property to block for height/width animations
-               if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
-                       this.elem.style.display = "block";
-               }
        },
 
        // Get the current size
@@ -322,6 +342,9 @@ jQuery.fx.prototype = {
 
        // Start an animation from one number to another
        custom: function( from, to, unit ) {
+               var self = this,
+                       fx = jQuery.fx;
+
                this.startTime = jQuery.now();
                this.start = from;
                this.end = to;
@@ -329,7 +352,6 @@ jQuery.fx.prototype = {
                this.now = this.start;
                this.pos = this.state = 0;
 
-               var self = this, fx = jQuery.fx;
                function t( gotoEnd ) {
                        return self.step(gotoEnd);
                }
@@ -384,17 +406,14 @@ jQuery.fx.prototype = {
                        }
 
                        if ( done ) {
-                               if ( this.options.display != null ) {
-                                       // Reset the overflow
-                                       this.elem.style.overflow = this.options.overflow;
-
-                                       // Reset the display
-                                       var old = jQuery.data(this.elem, "olddisplay");
-                                       this.elem.style.display = old ? old : this.options.display;
-
-                                       if ( jQuery.css( this.elem, "display" ) === "none" ) {
-                                               this.elem.style.display = "block";
-                                       }
+                               // Reset the overflow
+                               if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+                                       var elem = this.elem,
+                                               options = this.options;
+
+                                       jQuery.each( [ "", "X", "Y" ], function (index, value) {
+                                               elem.style[ "overflow" + value ] = options.overflow[index];
+                                       } );
                                }
 
                                // Hide the element if the "hide" operation was done
@@ -447,14 +466,14 @@ jQuery.extend( jQuery.fx, {
                        jQuery.fx.stop();
                }
        },
-  
+
        interval: 13,
-               
+
        stop: function() {
                clearInterval( timerId );
                timerId = null;
        },
-       
+
        speeds: {
                slow: 600,
                fast: 200,
@@ -485,4 +504,21 @@ if ( jQuery.expr && jQuery.expr.filters ) {
        };
 }
 
+function defaultDisplay( nodeName ) {
+       if ( !elemdisplay[ nodeName ] ) {
+               var elem = jQuery("<" + nodeName + ">").appendTo("body"),
+                       display = elem.css("display");
+
+               elem.remove();
+
+               if ( display === "none" || display === "" ) {
+                       display = "block";
+               }
+
+               elemdisplay[ nodeName ] = display;
+       }
+
+       return elemdisplay[ nodeName ];
+}
+
 })( jQuery );
index 65b5952..fd470e7 100644 (file)
@@ -7,7 +7,8 @@ var rnamespaces = /\.(.*)$/,
        rescape = /[^\w\s.|`]/g,
        fcleanup = function( nm ) {
                return nm.replace(rescape, "\\$&");
-       };
+       },
+       focusCounts = { focusin: 0, focusout: 0 };
 
 /*
  * A number of helper functions used for managing events.
@@ -31,6 +32,9 @@ jQuery.event = {
 
                if ( handler === false ) {
                        handler = returnFalse;
+               } else if ( !handler ) {
+                       // Fixes bug #7229. Fix recommended by jdalton
+                 return;
                }
 
                var handleObjIn, handleObj;
@@ -54,8 +58,28 @@ jQuery.event = {
                        return;
                }
 
-               var events = elemData.events = elemData.events || {},
+               // Use a key less likely to result in collisions for plain JS objects.
+               // Fixes bug #7150.
+               var eventKey = elem.nodeType ? "events" : "__events__",
+                       events = elemData[ eventKey ],
                        eventHandle = elemData.handle;
+                       
+               if ( typeof events === "function" ) {
+                       // On plain objects events is a fn that holds the the data
+                       // which prevents this data from being JSON serialized
+                       // the function does not need to be called, it just contains the data
+                       eventHandle = events.handle;
+                       events = events.events;
+
+               } else if ( !events ) {
+                       if ( !elem.nodeType ) {
+                               // On plain objects, create a fn that acts as the holder
+                               // of the values to avoid JSON serialization of event data
+                               elemData[ eventKey ] = elemData = function(){};
+                       }
+
+                       elemData.events = events = {};
+               }
 
                if ( !eventHandle ) {
                        elemData.handle = eventHandle = function() {
@@ -153,12 +177,18 @@ jQuery.event = {
                }
 
                var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+                       eventKey = elem.nodeType ? "events" : "__events__",
                        elemData = jQuery.data( elem ),
-                       events = elemData && elemData.events;
+                       events = elemData && elemData[ eventKey ];
 
                if ( !elemData || !events ) {
                        return;
                }
+               
+               if ( typeof events === "function" ) {
+                       elemData = events;
+                       events = events.events;
+               }
 
                // types is actually an event object here
                if ( types && types.type ) {
@@ -259,7 +289,10 @@ jQuery.event = {
                        delete elemData.events;
                        delete elemData.handle;
 
-                       if ( jQuery.isEmptyObject( elemData ) ) {
+                       if ( typeof elemData === "function" ) {
+                               jQuery.removeData( elem, eventKey );
+
+                       } else if ( jQuery.isEmptyObject( elemData ) ) {
                                jQuery.removeData( elem );
                        }
                }
@@ -319,7 +352,10 @@ jQuery.event = {
                event.currentTarget = elem;
 
                // Trigger the event, it is assumed that "handle" is a function
-               var handle = jQuery.data( elem, "handle" );
+               var handle = elem.nodeType ?
+                       jQuery.data( elem, "handle" ) :
+                       (jQuery.data( elem, "__events__" ) || {}).handle;
+
                if ( handle ) {
                        handle.apply( elem, data );
                }
@@ -342,8 +378,10 @@ jQuery.event = {
                        jQuery.event.trigger( event, data, parent, true );
 
                } else if ( !event.isDefaultPrevented() ) {
-                       var target = event.target, old, targetType = type.replace(rnamespaces, ""),
-                               isClick = jQuery.nodeName(target, "a") && targetType === "click",
+                       var old,
+                               target = event.target,
+                               targetType = type.replace( rnamespaces, "" ),
+                               isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
                                special = jQuery.event.special[ targetType ] || {};
 
                        if ( (!special._default || special._default.call( elem, event ) === false) && 
@@ -375,7 +413,9 @@ jQuery.event = {
        },
 
        handle: function( event ) {
-               var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
+               var all, handlers, namespaces, namespace_re, events,
+                       namespace_sort = [],
+                       args = jQuery.makeArray( arguments );
 
                event = args[0] = jQuery.event.fix( event || window.event );
                event.currentTarget = this;
@@ -392,7 +432,12 @@ jQuery.event = {
 
                event.namespace = event.namespace || namespace_sort.join(".");
 
-               events = jQuery.data(this, "events");
+               events = jQuery.data(this, this.nodeType ? "events" : "__events__");
+
+               if ( typeof events === "function" ) {
+                       events = events.events;
+               }
+
                handlers = (events || {})[ event.type ];
 
                if ( events && handlers ) {
@@ -449,7 +494,8 @@ jQuery.event = {
 
                // Fix target property, if necessary
                if ( !event.target ) {
-                       event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+                       // Fixes #1925 where srcElement might not be defined either
+                       event.target = event.srcElement || document;
                }
 
                // check if target is a textnode (safari)
@@ -464,14 +510,16 @@ jQuery.event = {
 
                // Calculate pageX/Y if missing and clientX/Y available
                if ( event.pageX == null && event.clientX != null ) {
-                       var doc = document.documentElement, body = document.body;
+                       var doc = document.documentElement,
+                               body = document.body;
+
                        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
                        event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
                }
 
                // Add which for key events
-               if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
-                       event.which = event.charCode || event.keyCode;
+               if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+                       event.which = event.charCode != null ? event.charCode : event.keyCode;
                }
 
                // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
@@ -668,19 +716,23 @@ if ( !jQuery.support.submitBubbles ) {
 
        jQuery.event.special.submit = {
                setup: function( data, namespaces ) {
-                       if ( this.nodeName.toLowerCase() !== "form" ) {
+                       if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) {
                                jQuery.event.add(this, "click.specialSubmit", function( e ) {
-                                       var elem = e.target, type = elem.type;
+                                       var elem = e.target,
+                                               type = elem.type;
 
                                        if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+                                               e.liveFired = undefined;
                                                return trigger( "submit", this, arguments );
                                        }
                                });
         
                                jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
-                                       var elem = e.target, type = elem.type;
+                                       var elem = e.target,
+                                               type = elem.type;
 
                                        if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+                                               e.liveFired = undefined;
                                                return trigger( "submit", this, arguments );
                                        }
                                });
@@ -743,6 +795,7 @@ if ( !jQuery.support.changeBubbles ) {
 
                if ( data != null || val ) {
                        e.type = "change";
+                       e.liveFired = undefined;
                        return jQuery.event.trigger( e, arguments[1], elem );
                }
        };
@@ -751,6 +804,8 @@ if ( !jQuery.support.changeBubbles ) {
                filters: {
                        focusout: testChange, 
 
+                       beforedeactivate: testChange,
+
                        click: function( e ) {
                                var elem = e.target, type = elem.type;
 
@@ -773,7 +828,7 @@ if ( !jQuery.support.changeBubbles ) {
 
                        // Beforeactivate happens also before the previous element is blurred
                        // with this event you can't trigger a change event, but you can store
-                       // information/focus[in] is not needed anymore
+                       // information
                        beforeactivate: function( e ) {
                                var elem = e.target;
                                jQuery.data( elem, "_change_data", getVal(elem) );
@@ -800,6 +855,9 @@ if ( !jQuery.support.changeBubbles ) {
        };
 
        changeFilters = jQuery.event.special.change.filters;
+
+       // Handle when the input is .focus()'d
+       changeFilters.focus = changeFilters.beforeactivate;
 }
 
 function trigger( type, elem, args ) {
@@ -812,17 +870,21 @@ if ( document.addEventListener ) {
        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
                jQuery.event.special[ fix ] = {
                        setup: function() {
-                               this.addEventListener( orig, handler, true );
+                               if ( focusCounts[fix]++ === 0 ) {
+                                       document.addEventListener( orig, handler, true );
+                               }
                        }, 
                        teardown: function() { 
-                               this.removeEventListener( orig, handler, true );
+                               if ( --focusCounts[fix] === 0 ) {
+                                       document.removeEventListener( orig, handler, true );
+                               }
                        }
                };
 
                function handler( e ) { 
                        e = jQuery.event.fix( e );
                        e.type = fix;
-                       return jQuery.event.handle.call( this, e );
+                       return jQuery.event.trigger( e, null, e.target );
                }
        });
 }
@@ -908,7 +970,8 @@ jQuery.fn.extend({
 
        toggle: function( fn ) {
                // Save reference to arguments for access in closure
-               var args = arguments, i = 1;
+               var args = arguments,
+                       i = 1;
 
                // link all the functions, so any of them can unbind this click handler
                while ( i < args.length ) {
@@ -1003,15 +1066,20 @@ jQuery.each(["live", "die"], function( i, name ) {
 });
 
 function liveHandler( event ) {
-       var stop, maxLevel, elems = [], selectors = [],
-               related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
-               events = jQuery.data( this, "events" );
+       var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+               elems = [],
+               selectors = [],
+               events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
 
-       // Make sure we avoid non-left-click bubbling in Firefox (#3861)
-       if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
-               return;
+       if ( typeof events === "function" ) {
+               events = events.events;
        }
 
+       // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
+       if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
+               return;
+       }
+       
        if ( event.namespace ) {
                namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
        }
@@ -1075,6 +1143,9 @@ function liveHandler( event ) {
                        if ( ret === false ) {
                                stop = false;
                        }
+                       if ( event.isImmediatePropagationStopped() ) {
+                               break;
+                       }
                }
        }
 
@@ -1111,7 +1182,7 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
 // More info:
 //  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
 if ( window.attachEvent && !window.addEventListener ) {
-       window.attachEvent("onunload", function() {
+       jQuery(window).bind("unload", function() {
                for ( var id in jQuery.cache ) {
                        if ( jQuery.cache[ id ].handle ) {
                                // Try/Catch is to handle iframes being unloaded, see #4280
index 00e3120..8d951b6 100644 (file)
@@ -7,8 +7,11 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
        rtbody = /<tbody/i,
        rhtml = /<|&#?\w+;/,
        rnocache = /<(?:script|object|embed|option|style)/i,
-       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
+       // checked="checked" or checked (html5)
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
        raction = /\=([^="'>\s]+\/)>/g,
+       rbodystart = /^\s*<body/i,
+       rbodyend = /<\/body>\s*$/i,
        wrapMap = {
                option: [ 1, "<select multiple='multiple'>", "</select>" ],
                legend: [ 1, "<fieldset>", "</fieldset>" ],
@@ -33,7 +36,8 @@ jQuery.fn.extend({
        text: function( text ) {
                if ( jQuery.isFunction(text) ) {
                        return this.each(function(i) {
-                               var self = jQuery(this);
+                               var self = jQuery( this );
+
                                self.text( text.call(this, i, self.text()) );
                        });
                }
@@ -82,7 +86,8 @@ jQuery.fn.extend({
                }
 
                return this.each(function() {
-                       var self = jQuery( this ), contents = self.contents();
+                       var self = jQuery( this ),
+                               contents = self.contents();
 
                        if ( contents.length ) {
                                contents.wrapAll( html );
@@ -146,7 +151,7 @@ jQuery.fn.extend({
                        return set;
                }
        },
-       
+
        // keepData is for internal use only--do not document
        remove: function( selector, keepData ) {
                for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
@@ -161,7 +166,7 @@ jQuery.fn.extend({
                                }
                        }
                }
-               
+
                return this;
        },
 
@@ -177,7 +182,7 @@ jQuery.fn.extend({
                                elem.removeChild( elem.firstChild );
                        }
                }
-               
+
                return this;
        },
 
@@ -193,11 +198,14 @@ jQuery.fn.extend({
                                // attributes in IE that are actually only stored
                                // as properties will not be copied (such as the
                                // the name attribute on an input).
-                               var html = this.outerHTML, ownerDocument = this.ownerDocument;
+                               var html = this.outerHTML,
+                                       ownerDocument = this.ownerDocument;
                                if ( !html ) {
                                        var div = ownerDocument.createElement("div");
                                        div.appendChild( this.cloneNode(true) );
                                        html = div.innerHTML;
+                               } else if ( rbodystart.test(html) && rbodyend.test(html) ) {
+                                       html = html.replace( rbodystart, "<div>" ).replace( rbodyend, "</div>" );
                                }
 
                                return jQuery.clean([html.replace(rinlinejQuery, "")
@@ -248,10 +256,9 @@ jQuery.fn.extend({
 
                } else if ( jQuery.isFunction( value ) ) {
                        this.each(function(i){
-                               var self = jQuery(this), old = self.html();
-                               self.empty().append(function(){
-                                       return value.call( this, i, old );
-                               });
+                               var self = jQuery( this );
+
+                               self.html( value.call(this, i, self.html()) );
                        });
 
                } else {
@@ -273,13 +280,14 @@ jQuery.fn.extend({
                        }
 
                        if ( typeof value !== "string" ) {
-                               value = jQuery(value).detach();
+                               value = jQuery( value ).detach();
                        }
 
                        return this.each(function() {
-                               var next = this.nextSibling, parent = this.parentNode;
+                               var next = this.nextSibling,
+                                       parent = this.parentNode;
 
-                               jQuery(this).remove();
+                               jQuery( this ).remove();
 
                                if ( next ) {
                                        jQuery(next).before( value );
@@ -297,7 +305,9 @@ jQuery.fn.extend({
        },
 
        domManip: function( args, table, callback ) {
-               var results, first, value = args[0], scripts = [], fragment, parent;
+               var results, first, fragment, parent,
+                       value = args[0],
+                       scripts = [];
 
                // We can't cloneNode fragments that contain checked, in WebKit
                if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
@@ -324,9 +334,9 @@ jQuery.fn.extend({
                        } else {
                                results = jQuery.buildFragment( args, this, scripts );
                        }
-                       
+
                        fragment = results.fragment;
-                       
+
                        if ( fragment.childNodes.length === 1 ) {
                                first = fragment = fragment.firstChild;
                        } else {
@@ -342,7 +352,7 @@ jQuery.fn.extend({
                                                        root(this[i], first) :
                                                        this[i],
                                                i > 0 || results.cacheable || this.length > 1  ?
-                                                       fragment.cloneNode(true) :
+                                                       jQuery(fragment).clone(true)[0] :
                                                        fragment
                                        );
                                }
@@ -372,7 +382,9 @@ function cloneCopyEvent(orig, ret) {
                        return;
                }
 
-               var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+               var oldData = jQuery.data( orig[i++] ),
+                       curData = jQuery.data( this, oldData ),
+                       events = oldData && oldData.events;
 
                if ( events ) {
                        delete curData.handle;
@@ -429,20 +441,21 @@ jQuery.each({
        replaceAll: "replaceWith"
 }, function( name, original ) {
        jQuery.fn[ name ] = function( selector ) {
-               var ret = [], insert = jQuery( selector ),
+               var ret = [],
+                       insert = jQuery( selector ),
                        parent = this.length === 1 && this[0].parentNode;
-               
+
                if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
                        insert[ original ]( this[0] );
                        return this;
-                       
+
                } else {
                        for ( var i = 0, l = insert.length; i < l; i++ ) {
                                var elems = (i > 0 ? this.clone(true) : this).get();
                                jQuery( insert[i] )[ original ]( elems );
                                ret = ret.concat( elems );
                        }
-               
+
                        return this.pushStack( ret, name, insert.selector );
                }
        };
@@ -530,7 +543,7 @@ jQuery.extend({
                        for ( i = 0; ret[i]; i++ ) {
                                if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
                                        scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
-                               
+
                                } else {
                                        if ( ret[i].nodeType === 1 ) {
                                                ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
@@ -542,22 +555,22 @@ jQuery.extend({
 
                return ret;
        },
-       
+
        cleanData: function( elems ) {
                var data, id, cache = jQuery.cache,
                        special = jQuery.event.special,
                        deleteExpando = jQuery.support.deleteExpando;
-               
+
                for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
                        if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
                                continue;
                        }
 
                        id = elem[ jQuery.expando ];
-                       
+
                        if ( id ) {
                                data = cache[ id ];
-                               
+
                                if ( data && data.events ) {
                                        for ( var type in data.events ) {
                                                if ( special[ type ] ) {
@@ -568,14 +581,14 @@ jQuery.extend({
                                                }
                                        }
                                }
-                               
+
                                if ( deleteExpando ) {
                                        delete elem[ jQuery.expando ];
 
                                } else if ( elem.removeAttribute ) {
                                        elem.removeAttribute( jQuery.expando );
                                }
-                               
+
                                delete cache[ id ];
                        }
                }
index 650cc08..3fb2917 100644 (file)
@@ -5,7 +5,7 @@ var rtable = /^t(?:able|d|h)$/i,
 
 if ( "getBoundingClientRect" in document.documentElement ) {
        jQuery.fn.offset = function( options ) {
-               var elem = this[0];
+               var elem = this[0], box;
 
                if ( options ) { 
                        return this.each(function( i ) {
@@ -21,10 +21,19 @@ if ( "getBoundingClientRect" in document.documentElement ) {
                        return jQuery.offset.bodyOffset( elem );
                }
 
-               var box = elem.getBoundingClientRect(),
-                       doc = elem.ownerDocument,
-                       body = doc.body,
-                       docElem = doc.documentElement,
+               try {
+                       box = elem.getBoundingClientRect();
+               } catch(e) {}
+
+               var doc = elem.ownerDocument,
+                       docElem = doc.documentElement;
+
+               // Make sure we're not dealing with a disconnected DOM node
+               if ( !box || !jQuery.contains( docElem, elem ) ) {
+                       return box || { top: 0, left: 0 };
+               }
+
+               var body = doc.body,
                        win = getWindow(doc),
                        clientTop  = docElem.clientTop  || body.clientTop  || 0,
                        clientLeft = docElem.clientLeft || body.clientLeft || 0,
@@ -56,11 +65,16 @@ if ( "getBoundingClientRect" in document.documentElement ) {
 
                jQuery.offset.initialize();
 
-               var offsetParent = elem.offsetParent, prevOffsetParent = elem,
-                       doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
-                       body = doc.body, defaultView = doc.defaultView,
+               var computedStyle,
+                       offsetParent = elem.offsetParent,
+                       prevOffsetParent = elem,
+                       doc = elem.ownerDocument,
+                       docElem = doc.documentElement,
+                       body = doc.body,
+                       defaultView = doc.defaultView,
                        prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
-                       top = elem.offsetTop, left = elem.offsetLeft;
+                       top = elem.offsetTop,
+                       left = elem.offsetLeft;
 
                while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
                        if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
@@ -142,7 +156,8 @@ jQuery.offset = {
        },
 
        bodyOffset: function( body ) {
-               var top = body.offsetTop, left = body.offsetLeft;
+               var top = body.offsetTop,
+                       left = body.offsetLeft;
 
                jQuery.offset.initialize();
 
index 23d4360..735b0e1 100644 (file)
@@ -27,7 +27,8 @@ jQuery.extend({
        dequeue: function( elem, type ) {
                type = type || "fx";
 
-               var queue = jQuery.queue( elem, type ), fn = queue.shift();
+               var queue = jQuery.queue( elem, type ),
+                       fn = queue.shift();
 
                // If the fx queue is dequeued, always remove the progress sentinel
                if ( fn === "inprogress" ) {
index d35dbed..67b41c4 100644 (file)
                optSelected: opt.selected,
 
                // Will be defined later
+               deleteExpando: true,
                optDisabled: false,
                checkClone: false,
                scriptEval: false,
                noCloneEvent: true,
-               boxModel: null
+               boxModel: null,
+               inlineBlockNeedsLayout: false,
+               shrinkWrapBlocks: false,
+               reliableHiddenOffsets: true
        };
 
        // Make sure that the options inside disabled selects aren't marked as disabled
                delete window[ id ];
        }
 
+       // Test to see if it's possible to delete an expando from an element
+       // Fails in Internet Explorer
+       try {
+               delete script.test;
+
+       } catch(e) {
+               jQuery.support.deleteExpando = false;
+       }
+
        root.removeChild( script );
 
        if ( div.attachEvent && div.fireEvent ) {
 
                document.body.appendChild( div );
                jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
-               document.body.removeChild( div ).style.display = 'none';
-               div = null;
+
+               if ( "zoom" in div.style ) {
+                       // Check if natively block-level elements act like inline-block
+                       // elements when setting their display to 'inline' and giving
+                       // them layout
+                       // (IE < 8 does this)
+                       div.style.display = "inline";
+                       div.style.zoom = 1;
+                       jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
+
+                       // Check if elements with layout shrink-wrap their children
+                       // (IE 6 does this)
+                       div.style.display = "";
+                       div.innerHTML = "<div style='width:4px;'></div>";
+                       jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
+               }
+
+               div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
+               var tds = div.getElementsByTagName("td");
+
+               // Check if table cells still have offsetWidth/Height when they are set
+               // to display:none and there are still other visible table cells in a
+               // table row; if so, offsetWidth/Height are not reliable for use when
+               // determining if an element has been hidden directly using
+               // display:none (it is still safe to use offsets if a parent element is
+               // hidden; don safety goggles and see bug #4512 for more information).
+               // (only IE 8 fails this test)
+               jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
+
+               tds[0].style.display = "";
+               tds[1].style.display = "none";
+
+               // Check if empty table cells still have offsetWidth/Height
+               // (IE < 8 fail this test)
+               jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
+               div.innerHTML = "";
+
+               document.body.removeChild( div ).style.display = "none";
+               div = tds = null;
        });
 
        // Technique from Juriy Zaytsev
        // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
-       var eventSupported = function( eventName ) { 
-               var el = document.createElement("div"); 
-               eventName = "on" + eventName; 
-
-               var isSupported = (eventName in el); 
-               if ( !isSupported ) { 
-                       el.setAttribute(eventName, "return;"); 
-                       isSupported = typeof el[eventName] === "function"; 
-               } 
-               el = null; 
-
-               return isSupported; 
+       var eventSupported = function( eventName ) {
+               var el = document.createElement("div");
+               eventName = "on" + eventName;
+
+               var isSupported = (eventName in el);
+               if ( !isSupported ) {
+                       el.setAttribute(eventName, "return;");
+                       isSupported = typeof el[eventName] === "function";
+               }
+               el = null;
+
+               return isSupported;
        };
-       
+
        jQuery.support.submitBubbles = eventSupported("submit");
        jQuery.support.changeBubbles = eventSupported("change");
 
        // release memory in IE
        root = script = div = all = a = null;
 })();
-
-jQuery.props = {
-       "for": "htmlFor",
-       "class": "className",
-       readonly: "readOnly",
-       maxlength: "maxLength",
-       cellspacing: "cellSpacing",
-       rowspan: "rowSpan",
-       colspan: "colSpan",
-       tabindex: "tabIndex",
-       usemap: "useMap",
-       frameborder: "frameBorder"
-};
-
 })( jQuery );
index dff1087..15446bd 100644 (file)
@@ -5,11 +5,13 @@ var runtil = /Until$/,
        // Note: This RegExp should be improved, or likely pulled from Sizzle
        rmultiselector = /,/,
        isSimple = /^.[^:#\[\.,]*$/,
-       slice = Array.prototype.slice;
+       slice = Array.prototype.slice,
+       POS = jQuery.expr.match.POS;
 
 jQuery.fn.extend({
        find: function( selector ) {
-               var ret = this.pushStack( "", "find", selector ), length = 0;
+               var ret = this.pushStack( "", "find", selector ),
+                       length = 0;
 
                for ( var i = 0, l = this.length; i < l; i++ ) {
                        length = ret.length;
@@ -55,14 +57,15 @@ jQuery.fn.extend({
        },
 
        closest: function( selectors, context ) {
-               var ret;
+               var ret = [], i, l, cur = this[0];
 
                if ( jQuery.isArray( selectors ) ) {
-                       var cur = this[0], match, matches = {}, selector, level = 1;
-                       ret = [];
+                       var match, selector,
+                               matches = {},
+                               level = 1;
 
                        if ( cur && selectors.length ) {
-                               for ( var i = 0, l = selectors.length; i < l; i++ ) {
+                               for ( i = 0, l = selectors.length; i < l; i++ ) {
                                        selector = selectors[i];
 
                                        if ( !matches[selector] ) {
@@ -89,21 +92,26 @@ jQuery.fn.extend({
                        return ret;
                }
 
-               var pos = jQuery.expr.match.POS.test( selectors ) ? 
+               var pos = POS.test( selectors ) ? 
                        jQuery( selectors, context || this.context ) : null;
 
-               ret = jQuery.map(this.get(),function( cur,i ) {
-                       while ( cur && cur.ownerDocument && cur !== context ) {
-                               if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
-                                       return cur;
-                               }
+               for ( i = 0, l = this.length; i < l; i++ ) {
+                       cur = this[i];
+
+                       while ( cur ) {
+                               if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+                                       ret.push( cur );
+                                       break;
 
-                               cur = cur.parentNode;
+                               } else {
+                                       cur = cur.parentNode;
+                                       if ( !cur || !cur.ownerDocument || cur === context ) {
+                                               break;
+                                       }
+                               }
                        }
+               }
 
-                       return null;
-               });
-               
                ret = ret.length > 1 ? jQuery.unique(ret) : ret;
                
                return this.pushStack( ret, "closest", selectors );
@@ -214,11 +222,15 @@ jQuery.extend({
                        expr = ":not(" + expr + ")";
                }
 
-               return jQuery.find.matches(expr, elems);
+               return elems.length === 1 ?
+                       jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+                       jQuery.find.matches(expr, elems);
        },
        
        dir: function( elem, dir, until ) {
-               var matched = [], cur = elem[dir];
+               var matched = [],
+                       cur = elem[ dir ];
+
                while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
                        if ( cur.nodeType === 1 ) {
                                matched.push( cur );
index 1846892..cffaaa4 100644 (file)
@@ -102,6 +102,8 @@ div.chain.test div { background: green; }
 div.chain.out { background: green; }
 div.chain.out div { background: red; display: none; }
 
+/* tests to ensure jQuery can determine the native display mode of elements
+   that have been set as display: none in stylesheets */
 div#show-tests * { display: none; }
 
 #nothiddendiv { font-size: 16px; }
index c06ef4b..b9df4cf 100644 (file)
@@ -1,12 +1,12 @@
-Lorem ipsum dolor sit amet\r
-consectetuer adipiscing elit\r
-Sed lorem leo\r
-lorem leo consectetuer adipiscing elit\r
-Sed lorem leo\r
-rhoncus sit amet\r
-elementum at\r
-bibendum at, eros\r
-Cras at mi et tortor egestas vestibulum\r
-sed Cras at mi vestibulum\r
-Phasellus sed felis sit amet\r
-orci dapibus semper.\r
+Lorem ipsum dolor sit amet
+consectetuer adipiscing elit
+Sed lorem leo
+lorem leo consectetuer adipiscing elit
+Sed lorem leo
+rhoncus sit amet
+elementum at
+bibendum at, eros
+Cras at mi et tortor egestas vestibulum
+sed Cras at mi vestibulum
+Phasellus sed felis sit amet
+orci dapibus semper.
index b2840c1..327085c 100644 (file)
-<html>\r
-    <head>\r
-        <script src='../dist/jquery.js' type='text/javascript'></script>\r
-        <style>\r
-       .red {\r
-           background-color: red;\r
-           border: solid 3px red;\r
-       }\r
-        </style>\r
-    </head>\r
-    <body>\r
-        <h2>Change Tests</h2>\r
-        <table>\r
-           <tr>\r
-               <td>\r
-               Change each:\r
-               </td>\r
-               <td>\r
-               <select class='select_test'>\r
-                   <option value='one'>change me 1</option>\r
-                   <option value='two'>change me 2</option>\r
-                   <option value='three'>change me 3</option>\r
-               </select>\r
-               <select class='select_test'>\r
-                   <option value='one'>change me 1</option>\r
-                   <option value='two' selected="selected">change me 2</option>\r
-                   <option value='three'>change me 3</option>\r
-               </select>\r
-               </td>\r
-               <td>\r
-               <select class='mselect_test' multiple="multiple">\r
-                   <option value='one'>change me 1</option>\r
-                   <option value='two'>change me 2</option>\r
-                   <option value='three'>change me 3</option>\r
-               </select>\r
-               </td>\r
-               <td>\r
-               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox1"/>\r
-               <label for="checkbox1">Checkbox 1</label><br/>\r
-               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox2"/>\r
-               <label for="checkbox2">Checkbox 2</label>\r
-               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox3" disabled="disabled"/>\r
-               <label for="checkbox3">Checkbox 3</label>\r
-               </td>\r
-               </td>\r
-               </td>\r
-               <td>\r
-               <input type="radio" class="radio_test" name="myradio" id="radio1"/>\r
-               <label for="radio1">Radio1</label><br/>\r
-               <input type="radio" class="radio_test" name="myradio" id="radio2"/>\r
-               <label for="radio2">Radio2</label>\r
-               <input type="radio" class="radio_test" name="myradio" id="radio3" disabled="disabled"/>\r
-               <label for="radio3">Radio3</label>\r
-               </td>\r
-               <td>\r
-               <input class="file_test" id="file1" type="file"/>\r
-               <td>\r
-               <input class='test' value='' id='input' size='10' />\r
-               <input class='test' value='test' id='input2' size='10' readonly="readonly" />\r
-               </td>\r
-               <td>\r
-               <textarea rows='2'></textarea>\r
-               </td>\r
-               <td>$(document).bind('change')</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Live:</td>\r
-               <td id='select' class="red">SELECT</td>\r
-               <td id='mselect' class="red">MULTI</td>\r
-               <td id='checkbox' class="red">CHECKBOX</td>\r
-               <td id='radio' class="red">RADIO</td>\r
-               <td id='file' class="red">FILE</td>\r
-               <td id='text' class="red">TEXT</td>\r
-               <td id='textarea' class="red">TEXTAREA</td>\r
-               <td id='boundChange' class="red">DOCUMENT</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Bind:</td>\r
-               <td id='selectbind' class="red">SELECT</td>\r
-               <td id='mselectbind' class="red">MULTI</td>\r
-               <td id='checkboxbind' class="red">CHECKBOX</td>\r
-               <td id='radiobind' class="red">RADIO</td>\r
-               <td id='filebind' class="red">FILE</td>\r
-               <td id='textbind' class="red">TEXT</td>\r
-               <td id='textareabind' class="red">TEXTAREA</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Focusin:</td>\r
-               <td id='selectfocus' class="red">SELECT</td>\r
-               <td id='mselectfocus' class="red">MULTI</td>\r
-               <td id='checkboxfocus' class="red">CHECKBOX</td>\r
-               <td id='radiofocus' class="red">RADIO</td>\r
-               <td id='filefocus' class="red">FILE</td>\r
-               <td id='textfocus' class="red">TEXT</td>\r
-               <td id='textareafocus' class="red">TEXTAREA</td>\r
-               <td id='boundFocus' class="red">DOCUMENT</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Focusout:</td>\r
-               <td id='selectblur' class="red">SELECT</td>\r
-               <td id='mselectblur' class="red">MULTI</td>\r
-               <td id='checkboxblur' class="red">CHECKBOX</td>\r
-               <td id='radioblur' class="red">RADIO</td>\r
-               <td id='fileblur' class="red">FILE</td>\r
-               <td id='textblur' class="red">TEXT</td>\r
-               <td id='textareablur' class="red">TEXTAREA</td>\r
-               <td id='boundBlur' class="red">DOCUMENT</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Live Focus:</td>\r
-               <td id='selectlfocus' class="red">SELECT</td>\r
-               <td id='mselectlfocus' class="red">MULTI</td>\r
-               <td id='checkboxlfocus' class="red">CHECKBOX</td>\r
-               <td id='radiolfocus' class="red">RADIO</td>\r
-               <td id='filelfocus' class="red">FILE</td>\r
-               <td id='textlfocus' class="red">TEXT</td>\r
-               <td id='textarealfocus' class="red">TEXTAREA</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Live Blur:</td>\r
-               <td id='selectlblur' class="red">SELECT</td>\r
-               <td id='mselectlblur' class="red">MULTI</td>\r
-               <td id='checkboxlblur' class="red">CHECKBOX</td>\r
-               <td id='radiolblur' class="red">RADIO</td>\r
-               <td id='filelblur' class="red">FILE</td>\r
-               <td id='textlblur' class="red">TEXT</td>\r
-               <td id='textarealblur' class="red">TEXTAREA</td>\r
-           </tr>\r
-        </table>\r
-        <h2>Submit Tests</h2>\r
-        <table>\r
-       <tr>\r
-           <td>\r
-               Submit each:\r
-           </td>\r
-           <td>\r
-               <form action="" id="text_submit">\r
-               <input class='test' type='text' value='Key Return To Submit'/>\r
-               </form>\r
-           </td>\r
-           <td>\r
-               <form action="" id="password_submit">\r
-               <input class='test' type='password' value=''/>\r
-               </form>\r
-           </td>\r
-           <td>\r
-               <form action="" id="submit_submit">\r
-               <input type='submit' value="Click Me To Submit" />\r
-               </form>\r
-           </td>\r
-           <td>$(document).bind('submit')</td>\r
-       </tr>\r
-       <tr>\r
-               <td>Results:</td>\r
-               <td id='textSubmit' class="red">TEXT</td>\r
-               <td id='passwordSubmit' class="red">PASSWORD</td>\r
-               <td id='submitSubmit' class="red">BUTTON</td>\r
-               <td id='boundSubmit' class="red">DOCUMENT</td>\r
-       </tr>\r
-        </table>\r
-\r
-       <ul id="log"></ul>\r
-\r
-        <script type='text/javascript'>\r
-       jQuery.fn.addChangeTest = function( id, prevent ) {\r
-               this.bind("focusin", function(){\r
-                       jQuery(id + "focus").blink();\r
-               }).bind("focusout", function(){\r
-                       jQuery(id + "blur").blink();\r
-               });\r
-\r
-               this.bind("focus", function(){\r
-                       jQuery(id + "lfocus").blink();\r
-               }).bind("blur", function(){\r
-                       jQuery(id + "lblur").blink();\r
-               });\r
-\r
-               return this.bind("change", function(e){\r
-                       jQuery(id + "bind").blink();\r
-               }).live("change", function(e){\r
-                       if ( prevent ) {\r
-                               e.preventDefault();\r
-                       }\r
-\r
-                       jQuery(id).blink();\r
-               });\r
-       };\r
-\r
-       jQuery.fn.addSubmitTest = function( id, prevent ) {\r
-               return this.live("submit", function(e){\r
-                       if ( prevent ) {\r
-                               e.preventDefault();\r
-                       }\r
-\r
-                       jQuery(id).blink();\r
-               });\r
-       };\r
-\r
-       jQuery.fn.blink = function(){\r
-               return this.css("backgroundColor","green").css("border","solid 3px green").delay(700).queue(function(next){\r
-                       jQuery(this).css("backgroundColor","");\r
-                       next();\r
-               });\r
-       };\r
-\r
-       $(document).bind("focusin", function() {\r
-               jQuery("#boundFocus").blink();\r
-       });\r
-       \r
-       $(document).bind("focusout", function() {\r
-               jQuery("#boundBlur").blink();\r
-       });\r
-\r
-       $("td.red").live("hover", function(e) {\r
-               if ( e.type === "mouseenter" ) {\r
-                       $(this).css("backgroundColor","green");\r
-               } else {\r
-                       $(this).css("backgroundColor","");\r
-               }\r
-       });\r
-\r
-       $(".select_test").addChangeTest("#select");\r
-       $(".mselect_test").addChangeTest("#mselect");\r
-       $(".checkbox_test").addChangeTest("#checkbox");\r
-       $(".radio_test").addChangeTest("#radio");\r
-       $(".file_test").addChangeTest("#file");\r
-       $('textarea').addChangeTest("#textarea");\r
-       $('#input').addChangeTest("#text");\r
-       $(document).bind("change", function(){\r
-               jQuery("#boundChange").blink();\r
-       });\r
-       \r
-       $("#text_submit").addSubmitTest("#textSubmit", true);\r
-       $("#password_submit").addSubmitTest("#passwordSubmit", true);\r
-       $("#submit_submit").addSubmitTest("#submitSubmit", true);\r
-       $(document).bind("submit", function(){\r
-               jQuery("#boundSubmit").blink();\r
-       });\r
-       \r
-        </script>\r
-    </body>\r
-</html>\r
+<html>
+    <head>
+        <script src='../dist/jquery.js' type='text/javascript'></script>
+        <style>
+       .red {
+           background-color: red;
+           border: solid 3px red;
+       }
+        </style>
+    </head>
+    <body>
+        <h2>Change Tests</h2>
+        <table>
+           <tr>
+               <td>
+               Change each:
+               </td>
+               <td>
+               <select class='select_test'>
+                   <option value='one'>change me 1</option>
+                   <option value='two'>change me 2</option>
+                   <option value='three'>change me 3</option>
+               </select>
+               <select class='select_test'>
+                   <option value='one'>change me 1</option>
+                   <option value='two' selected="selected">change me 2</option>
+                   <option value='three'>change me 3</option>
+               </select>
+               </td>
+               <td>
+               <select class='mselect_test' multiple="multiple">
+                   <option value='one'>change me 1</option>
+                   <option value='two'>change me 2</option>
+                   <option value='three'>change me 3</option>
+               </select>
+               </td>
+               <td>
+               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox1"/>
+               <label for="checkbox1">Checkbox 1</label><br/>
+               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox2"/>
+               <label for="checkbox2">Checkbox 2</label>
+               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox3" disabled="disabled"/>
+               <label for="checkbox3">Checkbox 3</label>
+               </td>
+               </td>
+               </td>
+               <td>
+               <input type="radio" class="radio_test" name="myradio" id="radio1"/>
+               <label for="radio1">Radio1</label><br/>
+               <input type="radio" class="radio_test" name="myradio" id="radio2"/>
+               <label for="radio2">Radio2</label>
+               <input type="radio" class="radio_test" name="myradio" id="radio3" disabled="disabled"/>
+               <label for="radio3">Radio3</label>
+               </td>
+               <td>
+               <input class="file_test" id="file1" type="file"/>
+               <td>
+               <input class='test' value='' id='input' size='10' />
+               <input class='test' value='test' id='input2' size='10' readonly="readonly" />
+               </td>
+               <td>
+               <textarea rows='2'></textarea>
+               </td>
+               <td>$(document).bind('change')</td>
+           </tr>
+           <tr>
+               <td>Live:</td>
+               <td id='select' class="red">SELECT</td>
+               <td id='mselect' class="red">MULTI</td>
+               <td id='checkbox' class="red">CHECKBOX</td>
+               <td id='radio' class="red">RADIO</td>
+               <td id='file' class="red">FILE</td>
+               <td id='text' class="red">TEXT</td>
+               <td id='textarea' class="red">TEXTAREA</td>
+               <td id='boundChange' class="red">DOCUMENT</td>
+           </tr>
+           <tr>
+               <td>Bind:</td>
+               <td id='selectbind' class="red">SELECT</td>
+               <td id='mselectbind' class="red">MULTI</td>
+               <td id='checkboxbind' class="red">CHECKBOX</td>
+               <td id='radiobind' class="red">RADIO</td>
+               <td id='filebind' class="red">FILE</td>
+               <td id='textbind' class="red">TEXT</td>
+               <td id='textareabind' class="red">TEXTAREA</td>
+           </tr>
+           <tr>
+               <td>Focusin:</td>
+               <td id='selectfocus' class="red">SELECT</td>
+               <td id='mselectfocus' class="red">MULTI</td>
+               <td id='checkboxfocus' class="red">CHECKBOX</td>
+               <td id='radiofocus' class="red">RADIO</td>
+               <td id='filefocus' class="red">FILE</td>
+               <td id='textfocus' class="red">TEXT</td>
+               <td id='textareafocus' class="red">TEXTAREA</td>
+               <td id='boundFocus' class="red">DOCUMENT</td>
+           </tr>
+           <tr>
+               <td>Focusout:</td>
+               <td id='selectblur' class="red">SELECT</td>
+               <td id='mselectblur' class="red">MULTI</td>
+               <td id='checkboxblur' class="red">CHECKBOX</td>
+               <td id='radioblur' class="red">RADIO</td>
+               <td id='fileblur' class="red">FILE</td>
+               <td id='textblur' class="red">TEXT</td>
+               <td id='textareablur' class="red">TEXTAREA</td>
+               <td id='boundBlur' class="red">DOCUMENT</td>
+           </tr>
+           <tr>
+               <td>Live Focus:</td>
+               <td id='selectlfocus' class="red">SELECT</td>
+               <td id='mselectlfocus' class="red">MULTI</td>
+               <td id='checkboxlfocus' class="red">CHECKBOX</td>
+               <td id='radiolfocus' class="red">RADIO</td>
+               <td id='filelfocus' class="red">FILE</td>
+               <td id='textlfocus' class="red">TEXT</td>
+               <td id='textarealfocus' class="red">TEXTAREA</td>
+           </tr>
+           <tr>
+               <td>Live Blur:</td>
+               <td id='selectlblur' class="red">SELECT</td>
+               <td id='mselectlblur' class="red">MULTI</td>
+               <td id='checkboxlblur' class="red">CHECKBOX</td>
+               <td id='radiolblur' class="red">RADIO</td>
+               <td id='filelblur' class="red">FILE</td>
+               <td id='textlblur' class="red">TEXT</td>
+               <td id='textarealblur' class="red">TEXTAREA</td>
+           </tr>
+        </table>
+        <h2>Submit Tests</h2>
+        <table>
+       <tr>
+           <td>
+               Submit each:
+           </td>
+           <td>
+               <form action="" id="text_submit">
+               <input class='test' type='text' value='Key Return To Submit'/>
+               </form>
+           </td>
+           <td>
+               <form action="" id="password_submit">
+               <input class='test' type='password' value=''/>
+               </form>
+           </td>
+           <td>
+               <form action="" id="submit_submit">
+               <input type='submit' value="Click Me To Submit" />
+               </form>
+           </td>
+           <td>$(document).bind('submit')</td>
+       </tr>
+       <tr>
+               <td>Results:</td>
+               <td id='textSubmit' class="red">TEXT</td>
+               <td id='passwordSubmit' class="red">PASSWORD</td>
+               <td id='submitSubmit' class="red">BUTTON</td>
+               <td id='boundSubmit' class="red">DOCUMENT</td>
+       </tr>
+        </table>
+
+       <ul id="log"></ul>
+
+        <script type='text/javascript'>
+       jQuery.fn.addChangeTest = function( id, prevent ) {
+               this.bind("focusin", function(){
+                       jQuery(id + "focus").blink();
+               }).bind("focusout", function(){
+                       jQuery(id + "blur").blink();
+               });
+
+               this.bind("focus", function(){
+                       jQuery(id + "lfocus").blink();
+               }).bind("blur", function(){
+                       jQuery(id + "lblur").blink();
+               });
+
+               return this.bind("change", function(e){
+                       jQuery(id + "bind").blink();
+               }).live("change", function(e){
+                       if ( prevent ) {
+                               e.preventDefault();
+                       }
+
+                       jQuery(id).blink();
+               });
+       };
+
+       jQuery.fn.addSubmitTest = function( id, prevent ) {
+               return this.live("submit", function(e){
+                       if ( prevent ) {
+                               e.preventDefault();
+                       }
+
+                       jQuery(id).blink();
+               });
+       };
+
+       jQuery.fn.blink = function(){
+               return this.css("backgroundColor","green").css("border","solid 3px green").delay(700).queue(function(next){
+                       jQuery(this).css("backgroundColor","");
+                       next();
+               });
+       };
+
+       $(document).bind("focusin", function() {
+               jQuery("#boundFocus").blink();
+       });
+       
+       $(document).bind("focusout", function() {
+               jQuery("#boundBlur").blink();
+       });
+
+       $("td.red").live("hover", function(e) {
+               if ( e.type === "mouseenter" ) {
+                       $(this).css("backgroundColor","green");
+               } else {
+                       $(this).css("backgroundColor","");
+               }
+       });
+
+       $(".select_test").addChangeTest("#select");
+       $(".mselect_test").addChangeTest("#mselect");
+       $(".checkbox_test").addChangeTest("#checkbox");
+       $(".radio_test").addChangeTest("#radio");
+       $(".file_test").addChangeTest("#file");
+       $('textarea').addChangeTest("#textarea");
+       $('#input').addChangeTest("#text");
+       $(document).bind("change", function(){
+               jQuery("#boundChange").blink();
+       });
+       
+       $("#text_submit").addSubmitTest("#textSubmit", true);
+       $("#password_submit").addSubmitTest("#passwordSubmit", true);
+       $("#submit_submit").addSubmitTest("#submitSubmit", true);
+       $(document).bind("submit", function(){
+               jQuery("#boundSubmit").blink();
+       });
+       
+        </script>
+    </body>
+</html>
index 5650a1d..e668727 100644 (file)
        <div id="qunit-testrunner-toolbar"></div>
        <h2 id="qunit-userAgent"></h2>
        <ol id="qunit-tests"></ol>
-       
+
        <!-- Test HTML -->
        <div id="nothiddendiv" style="height:1px;background:white;" class="nothiddendiv">
                <div id="nothiddendivchild"></div>
        </div>
        <!-- this iframe is outside the #main so it won't reload constantly wasting time, but it means the tests must be "safe" and clean up after themselves -->
        <iframe id="loadediframe" name="loadediframe" style="display:none;" src="data/iframe.html"></iframe>
-       <dl id="dl" style="display:none;">
-       <div id="main" style="display: none;">
+       <dl id="dl" style="position:absolute;top:-32767px;left:-32767px;">
+       <div id="main">
                <p id="firstp">See <a id="simon1" href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a> for more information.</p>
                <p id="ap">
-                       Here are some links in a normal paragraph: <a id="google" href="http://www.google.com/" title="Google!">Google</a>, 
-                       <a id="groups" href="http://groups.google.com/" class="GROUPS">Google Groups (Link)</a>. 
-                       This link has <code><a href="http://smin" id="anchor1">class="blog"</a></code>: 
+                       Here are some links in a normal paragraph: <a id="google" href="http://www.google.com/" title="Google!">Google</a>,
+                       <a id="groups" href="http://groups.google.com/" class="GROUPS">Google Groups (Link)</a>.
+                       This link has <code><a href="http://smin" id="anchor1">class="blog"</a></code>:
                        <a href="http://diveintomark.org/" class="blog" hreflang="en" id="mark">diveintomark</a>
 
                </p>
 
                        <input type="hidden" name="hidden" id="hidden1"/>
                        <input type="text" style="display:none;" name="foo[bar]" id="hidden2"/>
-                       
+
                        <input type="text" id="name" name="name" value="name" />
                        <input type="search" id="search" name="search" value="search" />
-                       
+
                        <button id="button" name="button" type="button">Button</button>
-                       
+
                        <textarea id="area1" maxlength="30">foobar</textarea>
-                       
+
                        <select name="select1" id="select1">
                                <option id="option1a" class="emptyopt" value="">Nothing</option>
                                <option id="option1b" value="1">1</option>
                                <option selected="selected" disabled="disabled" id="option4d" value="3">3</option>
                                <option id="option4e">no value</option>
                        </select>
-                       
+                       <select name="select5" id="select5">
+                               <option id="option5a" value="3">1</option>
+                               <option id="option5b" value="2">2</option>
+                               <option id="option5c" value="1">3</option>
+                       </select>
+
                        <object id="object1" codebase="stupid">
                                <param name="p1" value="x1" />
                                <param name="p2" value="x2" />
                        </object>
-                       
+
                        <span id="台北Táiběi"></span>
                        <span id="台北" lang="中文"></span>
                        <span id="utf8class1" class="台北Táiběi 台北"></span>
                        <span id="utf8class2" class="台北"></span>
                        <span id="foo:bar" class="foo:bar"></span>
                        <span id="test.foo[5]bar" class="test.foo[5]bar"></span>
-                       
+
                        <foo_bar id="foobar">test element</foo_bar>
                </form>
                <b id="floatTest">Float test.</b>
                        <input name="types[]" id="types_anime" type="checkbox" value="anime" />
                        <input name="types[]" id="types_movie" type="checkbox" value="movie" />
                </form>
-               
+
                <form id="testForm" action="#" method="get">
                        <textarea name="T3" rows="2" cols="15">?
 Z</textarea>
@@ -208,7 +213,7 @@ Z</textarea>
                                <div><div class="hidden">hidden</div></div>
                        </div>
                </div>
-               
+
                <div id="tabindex-tests">
                        <ol id="listWithTabIndex" tabindex="5">
                                <li id="foodWithNegativeTabIndex" tabindex="-1">Rice</li>
@@ -216,7 +221,7 @@ Z</textarea>
                                <li>Blinis</li>
                                <li>Tofu</li>
                        </ol>
-               
+
                        <div id="divWithNoTabIndex">I'm hungry. I should...</div>
                        <span>...</span><a href="#" id="linkWithNoTabIndex">Eat lots of food</a><span>...</span> |
                        <span>...</span><a href="#" id="linkWithTabIndex" tabindex="2">Eat a little food</a><span>...</span> |
@@ -225,7 +230,7 @@ Z</textarea>
                        <span>...</span><a id="linkWithNoHrefWithTabIndex" tabindex="1">Eat some funyuns</a><span>...</span>
                        <span>...</span><a id="linkWithNoHrefWithNegativeTabIndex" tabindex="-1">Eat some funyuns</a><span>...</span>
                </div>
-               
+
                <div id="liveHandlerOrder">
                        <span id="liveSpan1"><a href="#" id="liveLink1"></a></span>
                        <span id="liveSpan2"><a href="#" id="liveLink2"></a></span>
@@ -241,23 +246,26 @@ Z</textarea>
                <div id="fx-queue" name="test">
                        <div id="fadein" class='chain test' name='div'>fadeIn<div>fadeIn</div></div>
                        <div id="fadeout" class='chain test out'>fadeOut<div>fadeOut</div></div>
-                       
+
                        <div id="show" class='chain test'>show<div>show</div></div>
                        <div id="hide" class='chain test out'>hide<div>hide</div></div>
-                       
+
                        <div id="togglein" class='chain test'>togglein<div>togglein</div></div>
                        <div id="toggleout" class='chain test out'>toggleout<div>toggleout</div></div>
-               
-                       
+
+
                        <div id="slideup" class='chain test'>slideUp<div>slideUp</div></div>
                        <div id="slidedown" class='chain test out'>slideDown<div>slideDown</div></div>
-                       
+
                        <div id="slidetogglein" class='chain test'>slideToggleIn<div>slideToggleIn</div></div>
                        <div id="slidetoggleout" class='chain test out'>slideToggleOut<div>slideToggleOut</div></div>
+                       
+                       <div id="fadetogglein" class='chain test'>fadeToggleIn<div>fadeToggleIn</div></div>
+      <div id="fadetoggleout" class='chain test out'>fadeToggleOut<div>fadeToggleOut</div></div>
 
                        <div id="fadeto" class='chain test'>fadeTo<div>fadeTo</div></div>
                </div>
-               
+
                <div id="fx-tests"></div>
        </div>
 </body>
index 6199270..a0f3d49 100644 (file)
@@ -104,7 +104,10 @@ test(".ajax() - 304", function() {
        jQuery.ajax({
                url: url("data/notmodified.php"),
                success: function(){ ok(true, "304 ok"); },
-               error: function(){ ok(false, "304 not ok "); },
+               // Do this because opera simply refuses to implement 304 handling :(
+               // A feature-driven way of detecting this would be appreciated
+               // See: http://gist.github.com/599419
+               error: function(){ ok(jQuery.browser.opera, "304 not ok "); },
                complete: function(xhr){ start(); }
        });
 });
@@ -134,7 +137,7 @@ test(".load()) - 404 error callbacks", function() {
 });
 
 test("jQuery.ajax() - abort", function() {
-       expect( 6 );
+       expect( 8 );
        stop();
 
        jQuery('#foo').ajaxStart(function(){
@@ -154,7 +157,10 @@ test("jQuery.ajax() - abort", function() {
                complete: function(){ ok(true, "complete"); }
        });
 
+       equals( xhr.readyState, 1, "XHR readyState indicates successful dispatch" );
+
        xhr.abort();
+       equals( xhr.readyState, 0, "XHR readyState indicates successful abortion" );
 });
 
 test("Ajax events with context", function() {
@@ -286,6 +292,32 @@ test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", fun
        });
 });
 
+test("jQuery.ajax - HEAD requests", function() {
+       expect(2);
+
+       stop();
+       jQuery.ajax({
+               url: url("data/name.html"),
+               type: "HEAD",
+               success: function(data, status, xhr){
+                       var h = xhr.getAllResponseHeaders();
+                       ok( /Date/i.test(h), 'No Date in HEAD response' );
+                       
+                       jQuery.ajax({
+                               url: url("data/name.html"),
+                               data: { whip_it: "good" },
+                               type: "HEAD",
+                               success: function(data, status, xhr){
+                                       var h = xhr.getAllResponseHeaders();
+                                       ok( /Date/i.test(h), 'No Date in HEAD response with data' );
+                                       start();
+                               }
+                       });
+               }
+       });
+       
+});
+
 test("jQuery.ajax - beforeSend", function() {
        expect(1);
        stop();
@@ -362,11 +394,11 @@ test("serialize()", function() {
        );
 
        equals( jQuery('#form').serialize(),
-               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2",
+               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
                'Check form serialization as query string');
 
        equals( jQuery('#form :input').serialize(),
-               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2",
+               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
                'Check input serialization as query string');
 
        equals( jQuery('#testForm').serialize(),
@@ -378,7 +410,7 @@ test("serialize()", function() {
                'Check input serialization as query string');
 
        equals( jQuery('#form, #testForm').serialize(),
-               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
+               "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
                'Multiple form serialization as query string');
 
   /* Temporarily disabled. Opera 10 has problems with form serialization.
@@ -678,10 +710,10 @@ test("jQuery.getScript(String, Function) - no callback", function() {
 });
 
 test("jQuery.ajax() - JSONP, Local", function() {
-       expect(8);
+       expect(9);
 
        var count = 0;
-       function plus(){ if ( ++count == 8 ) start(); }
+       function plus(){ if ( ++count == 9 ) start(); }
 
        stop();
 
@@ -796,6 +828,17 @@ test("jQuery.ajax() - JSONP, Local", function() {
                        plus();
                }
        });
+
+       //#7578
+       jQuery.ajax({
+               url: "data/jsonp.php",
+               dataType: "jsonp",
+               beforeSend: function(){
+                       strictEqual( this.cache, false, "cache must be false on JSON request" );
+                       plus();
+                       return false;
+               }
+       });
 });
 
 test("JSONP - Custom JSONP Callback", function() {
@@ -1249,13 +1292,20 @@ test("jQuery.ajax - If-Modified-Since support", function() {
                                        start();
                                },
                                error: function() {
-                                       equals(false, "error");
+                                       // Do this because opera simply refuses to implement 304 handling :(
+                                       // A feature-driven way of detecting this would be appreciated
+                                       // See: http://gist.github.com/599419
+                                       ok(jQuery.browser.opera, "error");
+                                       ok(jQuery.browser.opera, "error");
                                        start();
                                }
                        });
                },
                error: function() {
-                       equals(false, "error");
+                       // Do this because opera simply refuses to implement 304 handling :(
+                       // A feature-driven way of detecting this would be appreciated
+                       // See: http://gist.github.com/599419
+                       ok(jQuery.browser.opera, "error");
                        start();
                }
        });
@@ -1288,22 +1338,39 @@ test("jQuery.ajax - Etag support", function() {
                                        start();
                                },
                                error: function() {
-                                       equals(false, "error");
+                                       // Do this because opera simply refuses to implement 304 handling :(
+                                       // A feature-driven way of detecting this would be appreciated
+                                       // See: http://gist.github.com/599419
+                                       ok(jQuery.browser.opera, "error");
+                                       ok(jQuery.browser.opera, "error");
                                        start();
                                }
                        });
                },
                error: function() {
-                       equals(false, "error");
+                       // Do this because opera simply refuses to implement 304 handling :(
+                       // A feature-driven way of detecting this would be appreciated
+                       // See: http://gist.github.com/599419
+                       ok(jQuery.browser.opera, "error");
                        start();
                }
        });
 });
 
 test("jQuery.ajax - active counter", function() {
-    ok( jQuery.ajax.active == 0, "ajax active counter should be zero: " + jQuery.ajax.active );
+    ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
 });
 
+test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
+       var success = false;
+       try {
+               var xhr = jQuery.ajax({ url: document.location });
+               success = true;
+               xhr.abort();
+       } catch (e) {}
+
+       ok( success, "document.location did not generate exception" );
+});
 
 }
 
index 3326dfe..f9506b3 100644 (file)
@@ -3,8 +3,33 @@ module("attributes");
 var bareObj = function(value) { return value; };
 var functionReturningObj = function(value) { return (function() { return value; }); };
 
+test("jQuery.props: itegrity test", function() {
+  
+  expect(1);
+  
+  //  This must be maintained and equal jQuery.props
+  //  Ensure that accidental or erroneous property 
+  //  overwrites don't occur
+  //  This is simply for better code coverage and future proofing. 
+  var propsShouldBe = {
+    "for": "htmlFor",
+    "class": "className",
+    readonly: "readOnly",
+    maxlength: "maxLength",
+    cellspacing: "cellSpacing",
+    rowspan: "rowSpan",
+    colspan: "colSpan",
+    tabindex: "tabIndex",
+    usemap: "useMap",
+    frameborder: "frameBorder"
+  };
+  
+  same(propsShouldBe, jQuery.props, "jQuery.props passes integrity check");
+
+});
+
 test("attr(String)", function() {
-       expect(30);
+       expect(37);
 
        // This one sometimes fails randomly ?!
        equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' );
@@ -65,6 +90,16 @@ test("attr(String)", function() {
 
        ok( jQuery("<div/>").attr("doesntexist") === undefined, "Make sure undefined is returned when no attribute is found." );
        ok( jQuery().attr("doesntexist") === undefined, "Make sure undefined is returned when no element is there." );
+
+       equals( jQuery(document).attr("nodeName"), "#document", "attr works correctly on document nodes (bug #7451)." );
+
+       var attributeNode = document.createAttribute("irrelevant"),
+               commentNode = document.createComment("some comment"),
+               textNode = document.createTextNode("some text"),
+               obj = {};
+       jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) {
+               strictEqual( jQuery(ele).attr("nonexisting"), undefined, "attr works correctly for non existing attributes (bug #7500)." );
+       });
 });
 
 if ( !isLocal ) {
@@ -98,15 +133,18 @@ test("attr(Hash)", function() {
 });
 
 test("attr(String, Object)", function() {
-       expect(23);
+       expect(30);
+
        var div = jQuery("div").attr("foo", "bar"),
                fail = false;
+
        for ( var i = 0; i < div.size(); i++ ) {
                if ( div.get(i).getAttribute('foo') != "bar" ){
                        fail = i;
                        break;
                }
        }
+
        equals( fail, false, "Set Attribute, the #"+fail+" element didn't get the attribute 'foo'" );
 
        // Fails on IE since recent changes to .attr()
@@ -114,6 +152,8 @@ test("attr(String, Object)", function() {
 
        jQuery("#name").attr('name', 'something');
        equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' );
+       jQuery("#name").attr('name', null);
+       equals( jQuery("#name").attr('title'), '', 'Remove name attribute' );
        jQuery("#check2").attr('checked', true);
        equals( document.getElementById('check2').checked, true, 'Set checked attribute' );
        jQuery("#check2").attr('checked', false);
@@ -127,6 +167,25 @@ test("attr(String, Object)", function() {
        jQuery("#name").attr('maxLength', '10');
        equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' );
 
+       var attributeNode = document.createAttribute("irrelevant"),
+               commentNode = document.createComment("some comment"),
+               textNode = document.createTextNode("some text"),
+               obj = {};
+       jQuery.each( [document, obj, "#firstp"], function( i, ele ) {
+               var $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" );
+               equal( $ele.attr("nonexisting"), "foo", "attr(name, value) works correctly for non existing attributes (bug #7500)." );
+       });
+       jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
+               var $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" );
+               strictEqual( $ele.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." );
+       });
+       //cleanup
+       jQuery.each( [document, "#firstp"], function( i, ele ) {
+               jQuery( ele ).removeAttr("nonexisting");
+       });
+
        var table = jQuery('#table').append("<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>"),
                td = table.find('td:first');
        td.attr("rowspan", "2");
@@ -297,12 +356,30 @@ test("attr('tabindex', value)", function() {
 });
 
 test("removeAttr(String)", function() {
-       expect(1);
+       expect(7);
        equals( jQuery('#mark').removeAttr( "class" )[0].className, "", "remove class" );
+
+       var attributeNode = document.createAttribute("irrelevant"),
+               commentNode = document.createComment("some comment"),
+               textNode = document.createTextNode("some text"),
+               obj = {};
+       //removeAttr only really removes on DOM element nodes handle all other seperatyl
+       strictEqual( jQuery( "#firstp" ).attr( "nonexisting", "foo" ).removeAttr( "nonexisting" )[0].nonexisting, undefined, "removeAttr works correctly on DOM element nodes" );
+
+       jQuery.each( [document, obj], function( i, ele ) {
+               var $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
+               strictEqual( ele.nonexisting, "", "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+       });
+       jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
+               $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
+               strictEqual( ele.nonexisting, undefined, "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+       });
 });
 
 test("val()", function() {
-       expect(20);
+       expect(23);
 
        document.getElementById('text1').value = "bla";
        equals( jQuery("#text1").val(), "bla", "Check for modified value of input element" );
@@ -337,6 +414,14 @@ test("val()", function() {
        jQuery('#select4').attr('disabled', true);
        same( jQuery('#select4').val(), ['2', '3'], 'Call val() on disabled multiple="multiple" select' );
 
+       equals( jQuery('#select5').val(), "3", "Check value on ambiguous select." );
+
+       jQuery('#select5').val(1);
+       equals( jQuery('#select5').val(), "1", "Check value on ambiguous select." );
+
+       jQuery('#select5').val(3);
+       equals( jQuery('#select5').val(), "3", "Check value on ambiguous select." );
+
        var checks = jQuery("<input type='checkbox' name='test' value='1'/><input type='checkbox' name='test' value='2'/><input type='checkbox' name='test' value=''/><input type='checkbox' name='test'/>").appendTo("#form");
 
        same( checks.serialize(), "", "Get unchecked values." );
@@ -396,7 +481,19 @@ test("val(String/Number)", function() {
 
 test("val(Function)", function() {
        testVal(functionReturningObj);
-})
+});
+
+test( "val(Array of Numbers) (Bug #7123)", function() {
+       expect(4);
+       jQuery('#form').append('<input type="checkbox" name="arrayTest" value="1" /><input type="checkbox" name="arrayTest" value="2" /><input type="checkbox" name="arrayTest" value="3" checked="checked" /><input type="checkbox" name="arrayTest" value="4" />');
+       var elements = jQuery('input[name=arrayTest]').val([ 1, 2 ]);
+       ok( elements[0].checked, "First element was checked" );
+       ok( elements[1].checked, "Second element was checked" );
+       ok( !elements[2].checked, "Third element was unchecked" );
+       ok( !elements[3].checked, "Fourth element remained unchecked" );
+       
+       elements.remove();
+});
 
 test("val(Function) with incoming value", function() {
        expect(10);
@@ -487,7 +584,7 @@ test("addClass(Function)", function() {
 });
 
 test("addClass(Function) with incoming value", function() {
-       expect(41);
+       expect(45);
 
        var div = jQuery("div"), old = div.map(function(){
                return jQuery(this).attr("class");
@@ -560,7 +657,7 @@ test("removeClass(Function) - simple", function() {
 });
 
 test("removeClass(Function) with incoming value", function() {
-       expect(41);
+       expect(45);
 
        var $divs = jQuery('div').addClass("test"), old = $divs.map(function(){
                return jQuery(this).attr("class");
@@ -692,7 +789,7 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
 });
 
 test("addClass, removeClass, hasClass", function() {
-       expect(14);
+       expect(17);
  
        var jq = jQuery("<p>Hi</p>"), x = jq[0];
  
@@ -712,12 +809,14 @@ test("addClass, removeClass, hasClass", function() {
        ok( jq.hasClass("hi"), "Check has1" );
        ok( jq.hasClass("bar"), "Check has2" );
  
-       var jq = jQuery("<p class='class1\nclass2\tcla.ss3\n'></p>");
-       ok( jq.hasClass("class1"), "Check hasClass with carriage return" );
-       ok( jq.is(".class1"), "Check is with carriage return" );
+       var jq = jQuery("<p class='class1\nclass2\tcla.ss3\n\rclass4'></p>");
+       ok( jq.hasClass("class1"), "Check hasClass with line feed" );
+       ok( jq.is(".class1"), "Check is with line feed" );
        ok( jq.hasClass("class2"), "Check hasClass with tab" );
        ok( jq.is(".class2"), "Check is with tab" );
        ok( jq.hasClass("cla.ss3"), "Check hasClass with dot" );
+       ok( jq.hasClass("class4"), "Check hasClass with carriage return" );
+       ok( jq.is(".class4"), "Check is with carriage return" );
  
        jq.removeClass("class2");
        ok( jq.hasClass("class2")==false, "Check the class has been properly removed" );
@@ -725,4 +824,6 @@ test("addClass, removeClass, hasClass", function() {
        ok( jq.hasClass("cla.ss3"), "Check the dotted class has not been removed" );
        jq.removeClass("cla.ss3");
        ok( jq.hasClass("cla.ss3")==false, "Check the dotted class has been removed" );
+       jq.removeClass("class4");
+       ok( jq.hasClass("class4")==false, "Check the class has been properly removed" );
 });
index 7ef2ad7..3cbf3f6 100644 (file)
@@ -547,15 +547,15 @@ test("toArray()", function() {
 })
 
 test("get(Number)", function() {
-       expect(1);
+       expect(2);
        equals( jQuery("p").get(0), document.getElementById("firstp"), "Get A Single Element" );
+       strictEqual( jQuery("#firstp").get(1), undefined, "Try get with index larger elements count" );
 });
 
 test("get(-Number)",function() {
-       expect(1);
-       equals( jQuery("p").get(-1),
-               document.getElementById("first"),
-               "Get a single element with negative index" )
+       expect(2);
+       equals( jQuery("p").get(-1), document.getElementById("first"), "Get a single element with negative index" );
+       strictEqual( jQuery("#firstp").get(-2), undefined, "Try get with index negative index larger then elements count" );
 })
 
 test("each(Function)", function() {
@@ -848,13 +848,20 @@ test("jQuery.makeArray", function(){
 });
 
 test("jQuery.isEmptyObject", function(){
-       expect(2);
+       expect(11);
        
        equals(true, jQuery.isEmptyObject({}), "isEmptyObject on empty object literal" );
        equals(false, jQuery.isEmptyObject({a:1}), "isEmptyObject on non-empty object literal" );
-       
-       // What about this ?
-       // equals(true, jQuery.isEmptyObject(null), "isEmptyObject on null" );
+  equals(false, jQuery.isEmptyObject(1), "isEmptyObject on number (wrong argument type)");
+  equals(false, jQuery.isEmptyObject(0), "isEmptyObject on falsy number (wrong argument type)");  
+  equals(false, jQuery.isEmptyObject("test"), "isEmptyObject on string (wrong argument type)");
+  equals(false, jQuery.isEmptyObject(""), "isEmptyObject on falsy string (wrong argument type)");
+  equals(false, jQuery.isEmptyObject([1,2,3]), "isEmptyObject on array (wrong argument type)");
+  equals(false, jQuery.isEmptyObject([]), "isEmptyObject on an empty array (wrong argument type)");
+  equals(false, jQuery.isEmptyObject(undefined), "isEmptyObject on undefined (wrong argument type)");
+  equals(false, jQuery.isEmptyObject(false), "isEmptyObject on undefined (wrong argument type)");
+  equals(false, jQuery.isEmptyObject(null), "isEmptyObject on null (wrong argument type)" );   
+
 });
 
 test("jQuery.proxy", function(){
index 0e91ae1..cddd902 100644 (file)
@@ -1,9 +1,9 @@
 module("css");
 
 test("css(String|Hash)", function() {
-       expect(29);
+       expect(41);
 
-       equals( jQuery('#main').css("display"), 'none', 'Check for css property "display"');
+       equals( jQuery('#main').css("display"), 'block', 'Check for css property "display"');
 
        ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible');
        jQuery('#nothiddendiv').css({display: 'none'});
@@ -11,6 +11,26 @@ test("css(String|Hash)", function() {
        jQuery('#nothiddendiv').css({display: 'block'});
        ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible');
 
+       var div = jQuery( "<div>" );
+
+       // These should be "auto" (or some better value)
+       // temporarily provide "0px" for backwards compat
+       equals( div.css("width"), "0px", "Width on disconnected node." );
+       equals( div.css("height"), "0px", "Height on disconnected node." );
+
+       div.css({ width: 4, height: 4 });
+
+       equals( div.css("width"), "4px", "Width on disconnected node." );
+       equals( div.css("height"), "4px", "Height on disconnected node." );
+
+       var div2 = jQuery( "<div style='display:none;'><input type='text' style='height:20px;'/><textarea style='height:20px;'/><div style='height:20px;'></div></div>").appendTo("body");
+
+       equals( div2.find("input").css("height"), "20px", "Height on hidden input." );
+       equals( div2.find("textarea").css("height"), "20px", "Height on hidden textarea." );
+       equals( div2.find("div").css("height"), "20px", "Height on hidden textarea." );
+
+       div2.remove();
+
        // handle negative numbers by ignoring #1599, #4216
        jQuery('#nothiddendiv').css({ 'width': 1, 'height': 1 });
 
@@ -19,6 +39,8 @@ test("css(String|Hash)", function() {
        equals( parseFloat(jQuery('#nothiddendiv').css('width')), width, 'Test negative width ignored')
        equals( parseFloat(jQuery('#nothiddendiv').css('height')), height, 'Test negative height ignored')
 
+       equals( jQuery('<div style="display: none;">').css('display'), 'none', 'Styles on disconnected nodes');
+
        jQuery('#floatTest').css({'float': 'right'});
        equals( jQuery('#floatTest').css('float'), 'right', 'Modified CSS float using "float": Assert float is right');
        jQuery('#floatTest').css({'font-size': '30px'});
@@ -61,10 +83,31 @@ test("css(String|Hash)", function() {
        equals( prctval, checkval, "Verify fontSize % set." );
 
        equals( typeof child.css("width"), "string", "Make sure that a string width is returned from css('width')." );
+
+       var old = child[0].style.height;
+
+       // Test NaN
+       child.css("height", parseFloat("zoo"));
+       equals( child[0].style.height, old, "Make sure height isn't changed on NaN." );
+
+       // Test null
+       child.css("height", null);
+       equals( child[0].style.height, old, "Make sure height isn't changed on null." );
+
+       old = child[0].style.fontSize;
+
+       // Test NaN
+       child.css("font-size", parseFloat("zoo"));
+       equals( child[0].style.fontSize, old, "Make sure font-size isn't changed on NaN." );
+
+       // Test null
+       child.css("font-size", null);
+       equals( child[0].style.fontSize, old, "Make sure font-size isn't changed on null." );
 });
 
 test("css(String, Object)", function() {
-       expect(19);
+       expect(22);
+
        ok( jQuery('#nothiddendiv').is(':visible'), 'Modifying CSS display: Assert element is visible');
        jQuery('#nothiddendiv').css("display", 'none');
        ok( !jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is hidden');
@@ -90,33 +133,52 @@ test("css(String, Object)", function() {
 
        // using contents will get comments regular, text, and comment nodes
        var j = jQuery("#nonnodes").contents();
-       j.css("padding-left", "1px");
-       equals( j.css("padding-left"), "1px", "Check node,textnode,comment css works" );
-
+       j.css("overflow", "visible");
+       equals( j.css("overflow"), "visible", "Check node,textnode,comment css works" );
        // opera sometimes doesn't update 'display' correctly, see #2037
        jQuery("#t2037")[0].innerHTML = jQuery("#t2037")[0].innerHTML
        equals( jQuery("#t2037 .hidden").css("display"), "none", "Make sure browser thinks it is hidden" );
+
+       var div = jQuery("#nothiddendiv"),
+               display = div.css("display"),
+               ret = div.css("display", undefined);
+
+       equals( ret, div, "Make sure setting undefined returns the original set." );
+       equals( div.css("display"), display, "Make sure that the display wasn't changed." );
+
+       // Test for Bug #5509
+       var success = true;
+       try {
+               jQuery('#foo').css("backgroundColor", "rgba(0, 0, 0, 0.1)");
+       }
+       catch (e) {
+               success = false;
+       }
+       ok( success, "Setting RGBA values does not throw Error" );
 });
 
-if(jQuery.browser.msie) {
-  test("css(String, Object) for MSIE", function() {
-    // for #1438, IE throws JS error when filter exists but doesn't have opacity in it
+if ( !jQuery.support.opacity ) {
+       test("css(String, Object) for MSIE", function() {
+               // for #1438, IE throws JS error when filter exists but doesn't have opacity in it
                jQuery('#foo').css("filter", "progid:DXImageTransform.Microsoft.Chroma(color='red');");
-       equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when a different filter is set in IE, #1438" );
-
-    var filterVal = "progid:DXImageTransform.Microsoft.alpha(opacity=30) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
-    var filterVal2 = "progid:DXImageTransform.Microsoft.alpha(opacity=100) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
-    jQuery('#foo').css("filter", filterVal);
-    equals( jQuery('#foo').css("filter"), filterVal, "css('filter', val) works" );
-    jQuery('#foo').css("opacity", 1)
-    equals( jQuery('#foo').css("filter"), filterVal2, "Setting opacity in IE doesn't clobber other filters" );
-    equals( jQuery('#foo').css("opacity"), 1, "Setting opacity in IE with other filters works" )
-  });
+               equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when a different filter is set in IE, #1438" );
+
+               var filterVal = "progid:DXImageTransform.Microsoft.Alpha(opacity=30) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
+               var filterVal2 = "progid:DXImageTransform.Microsoft.alpha(opacity=100) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
+               var filterVal3 = "progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
+               jQuery('#foo').css("filter", filterVal);
+               equals( jQuery('#foo').css("filter"), filterVal, "css('filter', val) works" );
+               jQuery('#foo').css("opacity", 1);
+               equals( jQuery('#foo').css("filter"), filterVal2, "Setting opacity in IE doesn't duplicate opacity filter" );
+               equals( jQuery('#foo').css("opacity"), 1, "Setting opacity in IE with other filters works" );
+               jQuery('#foo').css("filter", filterVal3).css("opacity", 1);
+               ok( jQuery('#foo').css("filter").indexOf(filterVal3) !== -1, "Setting opacity in IE doesn't clobber other filters" );
+       });
 }
 
 test("css(String, Function)", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -131,7 +193,7 @@ test("css(String, Function)", function() {
                index++;
                return size;
        });
-               
+       
        index = 0;
        
        jQuery("#cssFunctionTest div").each(function() {
@@ -146,7 +208,7 @@ test("css(String, Function)", function() {
 
 test("css(String, Function) with incoming value", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -161,7 +223,7 @@ test("css(String, Function) with incoming value", function() {
                index++;
                return size;
        });
-               
+       
        index = 0;
        
        jQuery("#cssFunctionTest div").css("font-size", function(i, computedSize) {
@@ -176,7 +238,7 @@ test("css(String, Function) with incoming value", function() {
 
 test("css(Object) where values are Functions", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -191,22 +253,22 @@ test("css(Object) where values are Functions", function() {
                index++;
                return size;
        }});
-               
+       
        index = 0;
-               
+       
        jQuery("#cssFunctionTest div").each(function() {
                var computedSize = jQuery(this).css("font-size")
                var expectedSize = sizes[index]
                equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
                index++;
        });
-               
+       
        jQuery("#cssFunctionTest").remove();
 });
 
 test("css(Object) where values are Functions with incoming values", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -221,16 +283,16 @@ test("css(Object) where values are Functions with incoming values", function() {
                index++;
                return size;
        }});
-               
+       
        index = 0;
-               
+       
        jQuery("#cssFunctionTest div").css({"font-size": function(i, computedSize) {
                var expectedSize = sizes[index]
                equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
                index++;
                return computedSize;
        }});
-               
+       
        jQuery("#cssFunctionTest").remove();
 });
 
@@ -245,3 +307,16 @@ test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", funct
        ok( !! jQuery(":checkbox:first", $checkedtest).attr("checked"), "Check first checkbox still checked." );
        ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." );
 });
+
+test(":visible selector works properly on table elements (bug #4512)", function () {
+       expect(1);
+
+       jQuery('#table').html('<tr><td style="display:none">cell</td><td>cell</td></tr>');
+       equals(jQuery('#table td:visible').length, 1, "hidden cell is not perceived as visible");
+});
+
+test(":visible selector works properly on children with a hidden parent (bug #4512)", function () {
+       expect(1);
+       jQuery('#table').css('display', 'none').html('<tr><td>cell</td><td>cell</td></tr>');
+       equals(jQuery('#table td:visible').length, 0, "hidden cell children not perceived as visible");
+});
index 77ee099..1a0f84c 100644 (file)
@@ -1,27 +1,22 @@
 module("data");
 
 test("expando", function(){
-       expect(7);
+       expect(6);
 
        equals("expando" in jQuery, true, "jQuery is exposing the expando");
 
        var obj = {};
-       jQuery.data(obj);
-       equals( jQuery.expando in obj, true, "jQuery.data adds an expando to the object" );
-       equals( typeof obj[jQuery.expando], "function", "jQuery.data adds an expando to the object as a function" );
+       equals( jQuery.data(obj), obj, "jQuery.data(obj) returns the object");
+       equals( jQuery.expando in obj, false, "jQuery.data(obj) did not add an expando to the object" );
 
        obj = {};
        jQuery.data(obj, 'test');
-       equals( jQuery.expando in obj, false, "jQuery.data did not add an expando to the object" );
+       equals( jQuery.expando in obj, false, "jQuery.data(obj,key) did not add an expando to the object" );
 
        obj = {};
        jQuery.data(obj, "foo", "bar");
-       equals( jQuery.expando in obj, true, "jQuery.data added an expando to the object" );
-
-       var id = obj[jQuery.expando]();
-       equals( id in jQuery.cache, false, "jQuery.data did not add an entry to jQuery.cache" );
-
-       equals( id.foo, "bar", "jQuery.data worked correctly" );
+       equals( jQuery.expando in obj, false, "jQuery.data(obj,key,value) did not add an expando to the object" );
+       equals( obj.foo, "bar", "jQuery.data(obj,key,value) sets fields directly on the object." );
 });
 
 test("jQuery.acceptData", function() {
@@ -43,7 +38,7 @@ test("jQuery.acceptData", function() {
 });
 
 test("jQuery.data", function() {
-       expect(13);
+       expect(15);
        var div = document.createElement("div");
 
        ok( jQuery.data(div, "test") === undefined, "Check for no data exists" );
@@ -67,21 +62,24 @@ test("jQuery.data", function() {
 
        jQuery.data(div, "test3", "orig");
        jQuery.data(div, { "test": "in", "test2": "in2" });
-       equals( jQuery.data(div, "test"), "in", "Verify setting an object in data." );
-       equals( jQuery.data(div, "test2"), "in2", "Verify setting an object in data." );
-       equals( jQuery.data(div, "test3"), "orig", "Verify original not overwritten." );
+       equals( jQuery.data(div, "test"), "in", "Verify setting an object in data" );
+       equals( jQuery.data(div, "test2"), "in2", "Verify setting an object in data" );
+       equals( jQuery.data(div, "test3"), "orig", "Verify original not overwritten" );
 
        var obj = {};
        jQuery.data( obj, "prop", true );
 
-       ok( obj[ jQuery.expando ], "Data is being stored on the object." );
-       ok( obj[ jQuery.expando ]().prop, "Data is being stored on the object." );
+       ok( obj.prop, "Data is being stored on the object" );
+       equals( jQuery.data( obj, "prop" ), true, "Make sure the right value is retrieved" );
 
-       equals( jQuery.data( obj, "prop" ), true, "Make sure the right value is retrieved." );
+       jQuery.data( window, "BAD", true );
+       ok( !window[ jQuery.expando ], "Make sure there is no expando on the window object." );
+       ok( !window.BAD, "And make sure that the property wasn't set directly on the window." );
+       ok( jQuery.data( window, "BAD" ), "Make sure that the value was set." );
 });
 
 test(".data()", function() {
-       expect(4);
+       expect(5);
 
        var div = jQuery("#foo");
        strictEqual( div.data("foo"), undefined, "Make sure that missing result is undefined" );
@@ -92,10 +90,13 @@ test(".data()", function() {
 
        var nodiv = jQuery("#unfound");
        equals( nodiv.data(), null, "data() on empty set returns null" );
+
+       var obj = { foo: "bar" };
+       equals( jQuery(obj).data(), obj, "Retrieve data object from a wrapped JS object (#7524)" );
 })
 
 test(".data(String) and .data(String, Object)", function() {
-       expect(27);
+       expect(29);
        var parent = jQuery("<div><div></div></div>"),
                div = parent.children();
 
@@ -173,25 +174,31 @@ test(".data(String) and .data(String, Object)", function() {
        equals( div.data("test.bar"), "testroot", "Check for unmatched namespace" );
 
        // #3748
-       var $elem = jQuery({});
+       var $elem = jQuery({exists:true});
        equals( $elem.data('nothing'), undefined, "Non-existent data returns undefined");
        equals( $elem.data('null',null).data('null'), null, "null's are preserved");
        equals( $elem.data('emptyString','').data('emptyString'), '', "Empty strings are preserved");
        equals( $elem.data('false',false).data('false'), false, "false's are preserved");
-
+       equals( $elem.data('exists'), true, "Existing data is returned" );
+       
        // Clean up
        $elem.removeData();
+       ok( jQuery.isEmptyObject( $elem[0] ), "removeData clears the object" );
 });
 
 test("data-* attributes", function() {
-       expect(27);
+       expect(37);
        var div = jQuery("<div>"),
-               child = jQuery("<div data-myobj='old data' data-ignored=\"DOM\"></div>");
+               child = jQuery("<div data-myobj='old data' data-ignored=\"DOM\" data-other='test'></div>"),
+               dummy = jQuery("<div data-myobj='old data' data-ignored=\"DOM\" data-other='test'></div>");
                
        equals( div.data("attr"), undefined, "Check for non-existing data-attr attribute" );
 
        div.attr("data-attr", "exists");
        equals( div.data("attr"), "exists", "Check for existing data-attr attribute" );
+
+       div.attr("data-attr", "exists2");
+       equals( div.data("attr"), "exists", "Check that updates to data- don't update .data()" );
                
        div.data("attr", "internal").attr("data-attr", "external");
        equals( div.data("attr"), "internal", "Check for .data('attr') precedence (internal > external data-* attribute)" );
@@ -205,6 +212,29 @@ test("data-* attributes", function() {
        child.data("ignored", "cache");
        equals( child.data("ignored"), "cache", "Cached data used before DOM data-* fallback");
 
+       var obj = child.data(), obj2 = dummy.data(), check = [ "myobj", "ignored", "other" ], num = 0, num2 = 0;
+
+       for ( var i = 0, l = check.length; i < l; i++ ) {
+               ok( obj[ check[i] ], "Make sure data- property exists when calling data-." );
+               ok( obj2[ check[i] ], "Make sure data- property exists when calling data-." );
+       }
+
+       for ( var prop in obj ) {
+               num++;
+       }
+
+       equals( num, check.length, "Make sure that the right number of properties came through." );
+
+       for ( var prop in obj2 ) {
+               num2++;
+       }
+
+       equals( num2, check.length, "Make sure that the right number of properties came through." );
+
+       child.attr("data-other", "newvalue");
+
+       equals( child.data("other"), "test", "Make sure value was pulled in properly from a .data()." );
+
        child
                .attr("data-true", "true")
                .attr("data-false", "false")
@@ -268,21 +298,43 @@ test("data-* attributes", function() {
 });
 
 test(".data(Object)", function() {
-       expect(2);
+       expect(4);
 
        var div = jQuery("<div/>");
 
        div.data({ "test": "in", "test2": "in2" });
-       equals( div.data("test"), "in", "Verify setting an object in data." );
-       equals( div.data("test2"), "in2", "Verify setting an object in data." );
+       equals( div.data("test"), "in", "Verify setting an object in data" );
+       equals( div.data("test2"), "in2", "Verify setting an object in data" );
+       
+       var obj = {test:"unset"},
+               jqobj = jQuery(obj);
+       jqobj.data({ "test": "in", "test2": "in2" });
+       equals( obj.test, "in", "Verify setting an object on an object extends the object" );
+       equals( obj.test2, "in2", "Verify setting an object on an object extends the object" ); 
 });
 
 test("jQuery.removeData", function() {
-       expect(1);
+       expect(7);
        var div = jQuery("#foo")[0];
        jQuery.data(div, "test", "testing");
        jQuery.removeData(div, "test");
        equals( jQuery.data(div, "test"), undefined, "Check removal of data" );
+
+       jQuery.data(div, "test2", "testing");
+       jQuery.removeData( div );
+       ok( !jQuery.data(div, "test2"), "Make sure that the data property no longer exists." );
+       ok( !div[ jQuery.expando ], "Make sure the expando no longer exists, as well." );
+       
+       var obj = {};
+       jQuery.data(obj, "test", "testing");
+       equals( obj.test, "testing", "verify data on plain object");
+       jQuery.removeData(obj, "test");
+       equals( jQuery.data(obj, "test"), undefined, "Check removal of data on plain object" );
+       equals( obj.test, undefined, "Check removal of data directly from plain object" );      
+
+       jQuery.data( window, "BAD", true );
+       jQuery.removeData( window, "BAD" );
+       ok( !jQuery.data( window, "BAD" ), "Make sure that the value was not still set." );
 });
 
 test(".removeData()", function() {
index 92cf17b..8255bf3 100644 (file)
@@ -103,7 +103,7 @@ test("height() with function args", function() {
 });
 
 test("innerWidth()", function() {
-       expect(3);
+       expect(4);
 
        var $div = jQuery("#nothiddendiv");
        // set styles
@@ -121,10 +121,15 @@ test("innerWidth()", function() {
        
        // reset styles
        $div.css({ display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.innerWidth(), 0, "Make sure that disconnected nodes are handled." );
 });
 
 test("innerHeight()", function() {
-       expect(3);
+       expect(4);
        
        var $div = jQuery("#nothiddendiv");
        // set styles
@@ -142,10 +147,15 @@ test("innerHeight()", function() {
        
        // reset styles
        $div.css({ display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.innerHeight(), 0, "Make sure that disconnected nodes are handled." );
 });
 
 test("outerWidth()", function() {
-       expect(6);
+       expect(7);
        
        var $div = jQuery("#nothiddendiv");
        $div.css("width", 30);
@@ -164,10 +174,15 @@ test("outerWidth()", function() {
        
        // reset styles
        $div.css({ position: "", display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.outerWidth(), 0, "Make sure that disconnected nodes are handled." );
 });
 
 test("outerHeight()", function() {
-       expect(6);
+       expect(7);
        
        var $div = jQuery("#nothiddendiv");
        $div.css("height", 30);
@@ -185,4 +200,9 @@ test("outerHeight()", function() {
        
        // reset styles
        $div.css({ display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.outerHeight(), 0, "Make sure that disconnected nodes are handled." );
 });
index b9d5c88..74b336f 100644 (file)
@@ -1,7 +1,37 @@
 module("effects");
 
+test("sanity check", function() {
+       expect(1);
+       ok( jQuery("#dl:visible, #main:visible, #foo:visible").length === 3, "QUnit state is correct for testing effects" );
+});
+
 test("show()", function() {
-       expect(23);
+       expect(28);
+
+       var hiddendiv = jQuery("div.hidden");
+
+       hiddendiv.hide().show();
+
+       equals( hiddendiv.css("display"), "block", "Make sure a pre-hidden div is visible." );
+
+       var div = jQuery("<div>").hide().appendTo("body").show();
+
+       equal( div.css("display"), "block", "Make sure pre-hidden divs show" );
+
+       QUnit.reset();
+
+       hiddendiv = jQuery("div.hidden");
+
+       equal(jQuery.css( hiddendiv[0], "display"), "none", "hiddendiv is display: none");
+
+       hiddendiv.css("display", "block");
+       equal(jQuery.css( hiddendiv[0], "display"), "block", "hiddendiv is display: block");
+
+       hiddendiv.show();
+       equal(jQuery.css( hiddendiv[0], "display"), "block", "hiddendiv is display: block");
+
+       hiddendiv.css("display","");
+
        var pass = true, div = jQuery("#main div");
        div.show().each(function(){
                if ( this.style.display == "none" ) pass = false;
@@ -32,9 +62,11 @@ test("show()", function() {
                ok( pass, "Show with " + name + " does not call animate callback" );
        });
 
-       jQuery("#main").append('<div id="show-tests"><div><p><a href="#"></a></p><code></code><pre></pre><span></span></div><table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table><ul><li></li></ul></div>');
-
-       var old = jQuery("#show-tests table").show().css("display") !== "table";
+       // #show-tests * is set display: none in CSS
+       jQuery("#main").append('<div id="show-tests"><div><p><a href="#"></a></p><code></code><pre></pre><span></span></div><table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table><ul><li></li></ul></div><table id="test-table"></table>');
+       
+       var old = jQuery("#test-table").show().css("display") !== "table";
+       jQuery("#test-table").remove();
 
        var test = {
                "div"      : "block",
@@ -64,10 +96,12 @@ test("show(Number) - other displays", function() {
        QUnit.reset();
        stop();
 
-       jQuery("#main").append('<div id="show-tests"><div><p><a href="#"></a></p><code></code><pre></pre><span></span></div><table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table><ul><li></li></ul></div>');
+       // #show-tests * is set display: none in CSS
+       jQuery("#main").append('<div id="show-tests"><div><p><a href="#"></a></p><code></code><pre></pre><span></span></div><table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table><ul><li></li></ul></div><table id="test-table"></table>');
 
-       var old = jQuery("#show-tests table").show().css("display") !== "table",
+       var old = jQuery("#test-table").show().css("display") !== "table",
                num = 0;
+       jQuery("#test-table").remove();
 
        var test = {
                "div"      : "block",
@@ -116,6 +150,133 @@ test("animate negative height", function() {
        });
 });
 
+test("animate block as inline width/height", function() {
+       expect(3);
+
+       var span = jQuery("<span>").css("display", "inline-block").appendTo("body"),
+               expected = span.css("display");
+       
+       span.remove();
+
+       if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) {
+               stop();
+
+               jQuery("#foo").css({ display: "inline", width: '', height: '' }).animate({ width: 42, height: 42 }, 100, function() {
+                       equals( jQuery(this).css("display"), jQuery.support.inlineBlockNeedsLayout ? "inline" : "inline-block", "inline-block was set on non-floated inline element when animating width/height" );
+                       equals( this.offsetWidth, 42, "width was animated" );
+                       equals( this.offsetHeight, 42, "height was animated" );
+                       start();
+               });
+
+       // Browser doesn't support inline-block
+       } else {
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+       }
+});
+
+test("animate native inline width/height", function() {
+       expect(3);
+
+       var span = jQuery("<span>").css("display", "inline-block").appendTo("body"),
+               expected = span.css("display");
+       
+       span.remove();
+
+       if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) {
+               stop();
+               jQuery("#foo").css({ display: "", width: '', height: '' })
+                       .append('<span>text</span>')
+                       .children('span')
+                               .animate({ width: 42, height: 42 }, 100, function() {
+                                       equals( jQuery(this).css("display"), "inline-block", "inline-block was set on non-floated inline element when animating width/height" );
+                                       equals( this.offsetWidth, 42, "width was animated" );
+                                       equals( this.offsetHeight, 42, "height was animated" );
+                                       start();
+                               });
+
+       // Browser doesn't support inline-block
+       } else {
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+       }
+});
+
+test("animate block width/height", function() {
+       expect(3);
+       stop();
+       jQuery("#foo").css({ display: "block", width: 20, height: 20 }).animate({ width: 42, height: 42 }, 100, function() {
+               equals( jQuery(this).css("display"), "block", "inline-block was not set on block element when animating width/height" );
+               equals( this.offsetWidth, 42, "width was animated" );
+               equals( this.offsetHeight, 42, "height was animated" );
+               start();
+       });
+});
+
+test("animate table width/height", function() {
+       expect(1);
+       stop();
+
+       var displayMode = jQuery("#table").css("display") !== "table" ? "block" : "table";
+
+       jQuery("#table").animate({ width: 42, height: 42 }, 100, function() {
+               equals( jQuery(this).css("display"), displayMode, "display mode is correct" );
+               start();
+       });
+});
+
+test("animate table-row width/height", function() {
+       expect(3);
+       stop();
+       var tr = jQuery("#table")
+               .attr({ "cellspacing": 0, "cellpadding": 0, "border": 0 })
+               .html("<tr style='height:42px;'><td style='padding:0;'><div style='width:20px;height:20px;'></div></td></tr>")
+               .find("tr");
+
+       // IE<8 uses “block” instead of the correct display type
+       var displayMode = tr.css("display") !== "table-row" ? "block" : "table-row";
+
+       tr.animate({ width: 10, height: 10 }, 100, function() {
+               equals( jQuery(this).css("display"), displayMode, "display mode is correct" );
+               equals( this.offsetWidth, 20, "width animated to shrink wrap point" );
+               equals( this.offsetHeight, 20, "height animated to shrink wrap point" );
+               start();
+       });
+});
+
+test("animate table-cell width/height", function() {
+       expect(3);
+       stop();
+       var td = jQuery("#table")
+               .attr({ "cellspacing": 0, "cellpadding": 0, "border": 0 })
+               .html("<tr><td style='width:42px;height:42px;padding:0;'><div style='width:20px;height:20px;'></div></td></tr>")
+               .find("td");
+
+       // IE<8 uses “block” instead of the correct display type
+       var displayMode = td.css("display") !== "table-cell" ? "block" : "table-cell";
+
+       td.animate({ width: 10, height: 10 }, 100, function() {
+               equals( jQuery(this).css("display"), displayMode, "display mode is correct" );
+               equals( this.offsetWidth, 20, "width animated to shrink wrap point" );
+               equals( this.offsetHeight, 20, "height animated to shrink wrap point" );
+               start();
+       });
+});
+
+test("animate resets overflow-x and overflow-y when finished", function() {
+       expect(2);
+       stop();
+       jQuery("#foo")
+               .css({ display: "block", width: 20, height: 20, overflowX: "visible", overflowY: "auto" })
+               .animate({ width: 42, height: 42 }, 100, function() {
+                       equals( this.style.overflowX, "visible", "overflow-x is visible" );
+                       equals( this.style.overflowY, "auto", "overflow-y is auto" );
+                       start();
+               });
+});
+
 /* // This test ends up being flaky depending upon the CPU load
 test("animate option (queue === false)", function () {
        expect(1);
@@ -139,7 +300,7 @@ test("animate option (queue === false)", function () {
 
 test("animate with no properties", function() {
        expect(2);
-       
+
        var divs = jQuery("div"), count = 0;
 
        divs.animate({}, function(){
@@ -161,30 +322,30 @@ test("animate with no properties", function() {
 
 test("animate duration 0", function() {
        expect(11);
-       
+
        stop();
-       
+
        var $elems = jQuery([{ a:0 },{ a:0 }]), counter = 0;
-       
+
        equals( jQuery.timers.length, 0, "Make sure no animation was running from another test" );
-               
+
        $elems.eq(0).animate( {a:1}, 0, function(){
                ok( true, "Animate a simple property." );
                counter++;
        });
-       
+
        // Failed until [6115]
        equals( jQuery.timers.length, 0, "Make sure synchronic animations are not left on jQuery.timers" );
-       
+
        equals( counter, 1, "One synchronic animations" );
-       
+
        $elems.animate( { a:2 }, 0, function(){
                ok( true, "Animate a second simple property." );
                counter++;
        });
-       
+
        equals( counter, 3, "Multiple synchronic animations" );
-       
+
        $elems.eq(0).animate( {a:3}, 0, function(){
                ok( true, "Animate a third simple property." );
                counter++;
@@ -195,12 +356,12 @@ test("animate duration 0", function() {
                equals( counter, 5, "One synchronic and one asynchronic" );
                start();
        });
-       
+
        var $elem = jQuery("<div />");
-       $elem.show(0, function(){ 
+       $elem.show(0, function(){
                ok(true, "Show callback with no duration");
        });
-       $elem.hide(0, function(){ 
+       $elem.hide(0, function(){
                ok(true, "Hide callback with no duration");
        });
 });
@@ -342,7 +503,7 @@ test("toggle()", function() {
        ok( x.is(":hidden"), "is hidden" );
        x.toggle();
        ok( x.is(":visible"), "is visible again" );
-       
+
        x.toggle(true);
        ok( x.is(":visible"), "is visible" );
        x.toggle(false);
@@ -372,7 +533,7 @@ test("JS Overflow and Display", function() {
                .after("text after")
                .animate({ opacity: 0.5 }, "slow", jQuery.checkOverflowDisplay);
 });
-               
+
 test("CSS Overflow and Display", function() {
        expect(2);
        stop();
@@ -444,16 +605,16 @@ jQuery.each( {
        }, function(tn, t){
                test(fn + " to " + tn, function() {
                        var elem = jQuery.makeTest( fn + " to " + tn );
-       
+
                        var t_w = t( elem, "width" );
                        var f_w = f( elem, "width" );
                        var t_h = t( elem, "height" );
                        var f_h = f( elem, "height" );
                        var t_o = t( elem, "opacity" );
                        var f_o = f( elem, "opacity" );
-                       
+
                        var num = 0;
-                       
+
                        if ( t_h == "show" ) num++;
                        if ( t_w == "show" ) num++;
                        if ( t_w == "hide"||t_w == "show" ) num++;
@@ -463,52 +624,52 @@ jQuery.each( {
                        if ( t_o.constructor == Number ) num += 2;
                        if ( t_w.constructor == Number ) num += 2;
                        if ( t_h.constructor == Number ) num +=2;
-                       
+
                        expect(num);
                        stop();
-       
+
                        var anim = { width: t_w, height: t_h, opacity: t_o };
-       
+
                        elem.animate(anim, 50, function(){
                                if ( t_w == "show" )
                                        equals( this.style.display, "block", "Showing, display should block: " + this.style.display);
-                                       
+
                                if ( t_w == "hide"||t_w == "show" )
                                        ok(f_w === "" ? this.style.width === f_w : this.style.width.indexOf(f_w) === 0, "Width must be reset to " + f_w + ": " + this.style.width);
-                                       
+
                                if ( t_h == "hide"||t_h == "show" )
                                        ok(f_h === "" ? this.style.height === f_h : this.style.height.indexOf(f_h) === 0, "Height must be reset to " + f_h + ": " + this.style.height);
-                                       
+
                                var cur_o = jQuery.style(this, "opacity");
 
                                if ( t_o == "hide" || t_o == "show" )
                                        equals(cur_o, f_o, "Opacity must be reset to " + f_o + ": " + cur_o);
-                                       
+
                                if ( t_w == "hide" )
                                        equals(this.style.display, "none", "Hiding, display should be none: " + this.style.display);
-                                       
+
                                if ( t_o.constructor == Number ) {
                                        equals(cur_o, t_o, "Final opacity should be " + t_o + ": " + cur_o);
-                                       
+
                                        ok(jQuery.css(this, "opacity") != "" || cur_o == t_o, "Opacity should be explicitly set to " + t_o + ", is instead: " + cur_o);
                                }
-                                       
+
                                if ( t_w.constructor == Number ) {
                                        equals(this.style.width, t_w + "px", "Final width should be " + t_w + ": " + this.style.width);
-                                       
+
                                        var cur_w = jQuery.css(this,"width");
 
                                        ok(this.style.width != "" || cur_w == t_w, "Width should be explicitly set to " + t_w + ", is instead: " + cur_w);
                                }
-                                       
+
                                if ( t_h.constructor == Number ) {
                                        equals(this.style.height, t_h + "px", "Final height should be " + t_h + ": " + this.style.height);
-                                       
+
                                        var cur_h = jQuery.css(this,"height");
 
                                        ok(this.style.height != "" || cur_h == t_h, "Height should be explicitly set to " + t_h + ", is instead: " + cur_w);
                                }
-                               
+
                                if ( t_h == "show" ) {
                                        var old_h = jQuery.css(this, "height");
                                        jQuery(this).append("<br/>Some more text<br/>and some more...");
@@ -519,23 +680,23 @@ jQuery.each( {
                                                equals(jQuery.css(this, "height"), old_h, "Make sure height is not auto.");
                                        }
                                }
-       
+
                                start();
                        });
                });
        });
 });
 
-jQuery.fn.saveState = function(){
-       var check = ['opacity','height','width','display','overflow'];  
+jQuery.fn.saveState = function(hiddenOverflow){
+       var check = ['opacity','height','width','display','overflow'];
        expect(check.length);
-       
+
        stop();
        return this.each(function(){
                var self = this;
                self.save = {};
                jQuery.each(check, function(i,c){
-                       self.save[c] = self.style[ c ] || jQuery.css(self,c);
+                       self.save[c] = c === "overflow" && hiddenOverflow ? "hidden" : self.style[ c ] || jQuery.css(self,c);
                });
        });
 };
@@ -558,39 +719,46 @@ test("Chain fadeIn fadeOut", function() {
 });
 
 test("Chain hide show", function() {
-       jQuery('#show div').saveState().hide('fast').show('fast',jQuery.checkState);
+       jQuery('#show div').saveState(jQuery.support.shrinkWrapBlocks).hide('fast').show('fast',jQuery.checkState);
 });
 test("Chain show hide", function() {
-       jQuery('#hide div').saveState().show('fast').hide('fast',jQuery.checkState);
+       jQuery('#hide div').saveState(jQuery.support.shrinkWrapBlocks).show('fast').hide('fast',jQuery.checkState);
 });
 test("Chain show hide with easing and callback", function() {
        jQuery('#hide div').saveState().show('fast').hide('fast','linear',jQuery.checkState);
 });
 
 test("Chain toggle in", function() {
-       jQuery('#togglein div').saveState().toggle('fast').toggle('fast',jQuery.checkState);
+       jQuery('#togglein div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast',jQuery.checkState);
 });
 test("Chain toggle out", function() {
-       jQuery('#toggleout div').saveState().toggle('fast').toggle('fast',jQuery.checkState);
+       jQuery('#toggleout div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast',jQuery.checkState);
 });
 test("Chain toggle out with easing and callback", function() {
- jQuery('#toggleout div').saveState().toggle('fast').toggle('fast','linear',jQuery.checkState);
+ jQuery('#toggleout div').saveState(jQuery.support.shrinkWrapBlocks).toggle('fast').toggle('fast','linear',jQuery.checkState);
 });
 test("Chain slideDown slideUp", function() {
-       jQuery('#slidedown div').saveState().slideDown('fast').slideUp('fast',jQuery.checkState);
+       jQuery('#slidedown div').saveState(jQuery.support.shrinkWrapBlocks).slideDown('fast').slideUp('fast',jQuery.checkState);
 });
 test("Chain slideUp slideDown", function() {
-       jQuery('#slideup div').saveState().slideUp('fast').slideDown('fast',jQuery.checkState);
+       jQuery('#slideup div').saveState(jQuery.support.shrinkWrapBlocks).slideUp('fast').slideDown('fast',jQuery.checkState);
 });
 test("Chain slideUp slideDown with easing and callback", function() {
-       jQuery('#slideup div').saveState().slideUp('fast').slideDown('fast','linear',jQuery.checkState);
+       jQuery('#slideup div').saveState(jQuery.support.shrinkWrapBlocks).slideUp('fast').slideDown('fast','linear',jQuery.checkState);
 });
 
 test("Chain slideToggle in", function() {
-       jQuery('#slidetogglein div').saveState().slideToggle('fast').slideToggle('fast',jQuery.checkState);
+       jQuery('#slidetogglein div').saveState(jQuery.support.shrinkWrapBlocks).slideToggle('fast').slideToggle('fast',jQuery.checkState);
 });
 test("Chain slideToggle out", function() {
-       jQuery('#slidetoggleout div').saveState().slideToggle('fast').slideToggle('fast',jQuery.checkState);
+       jQuery('#slidetoggleout div').saveState(jQuery.support.shrinkWrapBlocks).slideToggle('fast').slideToggle('fast',jQuery.checkState);
+});
+
+test("Chain fadeToggle in", function() {
+       jQuery('#fadetogglein div').saveState().fadeToggle('fast').fadeToggle('fast',jQuery.checkState);
+});
+test("Chain fadeToggle out", function() {
+       jQuery('#fadetoggleout div').saveState().fadeToggle('fast').fadeToggle('fast',jQuery.checkState);
 });
 
 test("Chain fadeTo 0.5 1.0 with easing and callback)", function() {
@@ -631,26 +799,26 @@ test("jQuery.show('fast') doesn't clear radio buttons (bug #1095)", function ()
 });
 
 test("animate with per-property easing", function(){
-       
+
        expect(3);
        stop();
-       
+
        var _test1_called = false;
        var _test2_called = false;
        var _default_test_called = false;
-       
+
        jQuery.easing['_test1'] = function() {
                _test1_called = true;
        };
-       
+
        jQuery.easing['_test2'] = function() {
                _test2_called = true;
        };
-       
+
        jQuery.easing['_default_test'] = function() {
                _default_test_called = true;
        };
-       
+
        jQuery({a:0,b:0,c:0}).animate({
                a: [100, '_test1'],
                b: [100, '_test2'],
@@ -661,5 +829,35 @@ test("animate with per-property easing", function(){
                ok(_test2_called, "Easing function (2) called");
                ok(_default_test_called, "Easing function (_default) called");
        });
+
+});
+
+test("hide hidden elements (bug #7141)", function() {
+       expect(3);
+       QUnit.reset();
+
+       var div = jQuery("<div style='display:none'></div>").appendTo("#main");
+       equals( div.css("display"), "none", "Element is hidden by default" );
+       div.hide();
+       ok( !div.data("olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
+       div.show();
+       equals( div.css("display"), "block", "Show a double-hidden element" );
+
+       div.remove();
+});
+
+test("hide hidden elements, with animation (bug #7141)", function() {
+       expect(3);
+       QUnit.reset();
+       stop();
        
+       var div = jQuery("<div style='display:none'></div>").appendTo("#main");
+       equals( div.css("display"), "none", "Element is hidden by default" );
+       div.hide(1, function () {
+               ok( !div.data("olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
+               div.show(1, function () {
+                       equals( div.css("display"), "block", "Show a double-hidden element" );
+                       start();
+               });
+       });
 });
index 3c77e34..a647e5f 100644 (file)
@@ -1,5 +1,25 @@
 module("event");
 
+test("null or undefined handler", function() {
+       expect(2);
+  // Supports Fixes bug #7229
+  try {
+  
+    jQuery("#firstp").click(null);
+  
+    ok(true, "Passing a null handler will not throw an exception");
+
+  } catch (e) {}  
+
+  try {
+  
+    jQuery("#firstp").click(undefined);
+  
+    ok(true, "Passing an undefined handler will not throw an exception");
+
+  } catch (e) {}  
+});
+
 test("bind(), with data", function() {
        expect(3);
        var handler = function(event) {
@@ -245,6 +265,36 @@ test("live/die(Object), delegate/undelegate(String, Object)", function() {
        equals( mouseoverCounter, 4, "die" );
 });
 
+test("live/delegate immediate propagation", function() {
+       expect(2);
+       
+       var $p = jQuery("#firstp"), $a = $p.find("a:first"), lastClick;
+       
+       lastClick = "";
+       $a.live( "click", function(e) { 
+               lastClick = "click1"; 
+               e.stopImmediatePropagation();
+       });
+       $a.live( "click", function(e) {
+               lastClick = "click2";
+       });
+       $a.trigger( "click" );
+       equals( lastClick, "click1", "live stopImmediatePropagation" );
+       $a.die( "click" );
+       
+       lastClick = "";
+       $p.delegate( "a", "click", function(e) { 
+               lastClick = "click1"; 
+               e.stopImmediatePropagation();
+       });
+       $p.delegate( "a", "click", function(e) {
+               lastClick = "click2";
+       });
+       $a.trigger( "click" );
+       equals( lastClick, "click1", "delegate stopImmediatePropagation" );
+       $p.undelegate( "click" );
+});
+
 test("bind(), iframes", function() {
        // events don't work with iframes, see #939 - this test fails in IE because of contentDocument
        var doc = jQuery("#loadediframe").contents();
@@ -255,7 +305,7 @@ test("bind(), iframes", function() {
 });
 
 test("bind(), trigger change on select", function() {
-       expect(4);
+       expect(5);
        var counter = 0;
        function selectOnChange(event) {
                equals( event.data, counter++, "Event.data is not a global event object" );
@@ -443,7 +493,7 @@ test("bind(name, false), unbind(name, false)", function() {
 });
 
 test("bind()/trigger()/unbind() on plain object", function() {
-       expect( 2 );
+       expect( 8 );
 
        var obj = {};
 
@@ -453,22 +503,36 @@ test("bind()/trigger()/unbind() on plain object", function() {
        // Make sure it doesn't complain when no events are found
        jQuery(obj).unbind("test");
 
-       jQuery(obj).bind("test", function(){
-               ok( true, "Custom event run." );
+       jQuery(obj).bind({
+               test: function() {
+                       ok( true, "Custom event run." );
+               },
+               submit: function() {
+                       ok( true, "Custom submit event run." );
+               }
        });
 
-       ok( jQuery(obj).data("events"), "Object has events bound." );
+       var events = jQuery(obj).data("__events__");
+       ok( events, "Object has events bound." );
+       equals( obj.events, undefined, "Events object on plain objects is not events" );
+       equals( typeof events, "function", "'events' expando is a function on plain objects." );
+       equals( obj.test, undefined, "Make sure that test event is not on the plain object." );
+       equals( obj.handle, undefined, "Make sure that the event handler is not on the plain object." );
 
        // Should trigger 1
        jQuery(obj).trigger("test");
+       jQuery(obj).trigger("submit");
 
        jQuery(obj).unbind("test");
+       jQuery(obj).unbind("submit");
 
        // Should trigger 0
        jQuery(obj).trigger("test");
 
        // Make sure it doesn't complain when no events are found
        jQuery(obj).unbind("test");
+       
+       equals( obj.__events__, undefined, "Make sure events object is removed" );
 });
 
 test("unbind(type)", function() {
@@ -1231,6 +1295,8 @@ test("live with namespaces", function(){
 });
 
 test("live with change", function(){
+       expect(8);
+
        var selectChange = 0, checkboxChange = 0;
        
        var select = jQuery("select[name='S1']")
@@ -1262,28 +1328,13 @@ test("live with change", function(){
        checkbox.trigger("change");
        equals( checkboxChange, 1, "Change on checkbox." );
        
-       // test before activate on radio
-       
-       // test blur/focus on textarea
-       var textarea = jQuery("#area1"), textareaChange = 0, oldVal = textarea.val();
-       textarea.live("change", function() {
-               textareaChange++;
-       });
-
-       textarea.val(oldVal + "foo");
-       textarea.trigger("change");
-       equals( textareaChange, 1, "Change on textarea." );
-
-       textarea.val(oldVal);
-       textarea.die("change");
-       
        // test blur/focus on text
        var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
        text.live("change", function() {
                textChange++;
        });
 
-       text.val(oldVal+"foo");
+       text.val(oldTextVal+"foo");
        text.trigger("change");
        equals( textChange, 1, "Change on text input." );
 
@@ -1700,6 +1751,8 @@ test("delegate with multiple events", function(){
 });
 
 test("delegate with change", function(){
+       expect(8);
+
        var selectChange = 0, checkboxChange = 0;
        
        var select = jQuery("select[name='S1']");
@@ -1731,28 +1784,13 @@ test("delegate with change", function(){
        checkbox.trigger("change");
        equals( checkboxChange, 1, "Change on checkbox." );
        
-       // test before activate on radio
-       
-       // test blur/focus on textarea
-       var textarea = jQuery("#area1"), textareaChange = 0, oldVal = textarea.val();
-       jQuery("#body").delegate("#area1", "change", function() {
-               textareaChange++;
-       });
-
-       textarea.val(oldVal + "foo");
-       textarea.trigger("change");
-       equals( textareaChange, 1, "Change on textarea." );
-
-       textarea.val(oldVal);
-       jQuery("#body").undelegate("#area1", "change");
-       
        // test blur/focus on text
        var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
        jQuery("#body").delegate("#name", "change", function() {
                textChange++;
        });
 
-       text.val(oldVal+"foo");
+       text.val(oldTextVal+"foo");
        text.trigger("change");
        equals( textChange, 1, "Change on text input." );
 
@@ -1825,6 +1863,38 @@ test("Non DOM element events", function() {
        jQuery(o).trigger('nonelementobj');
 });
 
+test("window resize", function() {
+       expect(2);
+
+       jQuery(window).unbind();
+
+       jQuery(window).bind("resize", function(){
+               ok( true, "Resize event fired." );
+       }).resize().unbind("resize");
+
+       ok( !jQuery(window).data("__events__"), "Make sure all the events are gone." );
+});
+
+test("focusin bubbles", function() {
+       //create an input and focusin on it
+       var input = jQuery("<input/>"), order = 0;
+
+       input.prependTo("body");
+
+       jQuery("body").bind("focusin.focusinBubblesTest",function(){
+               equals(1,order++,"focusin on the body second")
+       });
+
+       input.bind("focusin.focusinBubblesTest",function(){
+               equals(0,order++,"focusin on the element first")
+       });
+
+       input[0].focus();
+       input.remove();
+
+       jQuery("body").unbind("focusin.focusinBubblesTest");
+});
+
 /*
 test("jQuery(function($) {})", function() {
        stop();
index 2fc6f18..23ed898 100644 (file)
@@ -37,16 +37,16 @@ test("text(Function)", function() {
 
 test("text(Function) with incoming value", function() {
        expect(2);
-       
+
        var old = "This link has class=\"blog\": Simon Willison's Weblog";
-       
+
        jQuery('#sap').text(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return "foobar";
        });
-       
+
        equals( jQuery("#sap").text(), "foobar", 'Check for merged text of more then one element.' );
-       
+
        QUnit.reset();
 });
 
@@ -240,7 +240,7 @@ var testAppend = function(valueObj) {
        ok( jQuery("#sap").append(valueObj( [] )), "Check for appending an empty array." );
        ok( jQuery("#sap").append(valueObj( "" )), "Check for appending an empty string." );
        ok( jQuery("#sap").append(valueObj( document.getElementsByTagName("foo") )), "Check for appending an empty nodelist." );
-       
+
        QUnit.reset();
        jQuery("form").append(valueObj('<input name="radiotest" type="radio" checked="checked" />'));
        jQuery("form input[name=radiotest]").each(function(){
@@ -322,18 +322,18 @@ test("append(Function)", function() {
 
 test("append(Function) with incoming value", function() {
        expect(12);
-       
+
        var defaultText = 'Try them out:', old = jQuery("#first").html();
-       
+
        var result = jQuery('#first').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return '<b>buga</b>';
        });
        equals( result.text(), defaultText + 'buga', 'Check if text appending works' );
-       
+
        var select = jQuery('#select3');
        old = select.html();
-       
+
        equals( select.append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return '<option value="appendTest">Append Test</option>';
@@ -342,7 +342,7 @@ test("append(Function) with incoming value", function() {
        QUnit.reset();
        var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:";
        old = jQuery("#sap").html();
-       
+
        jQuery('#sap').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return document.getElementById('first');
@@ -352,7 +352,7 @@ test("append(Function) with incoming value", function() {
        QUnit.reset();
        expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo";
        old = jQuery("#sap").html();
-       
+
        jQuery('#sap').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return [document.getElementById('first'), document.getElementById('yahoo')];
@@ -362,7 +362,7 @@ test("append(Function) with incoming value", function() {
        QUnit.reset();
        expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:";
        old = jQuery("#sap").html();
-       
+
        jQuery('#sap').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return jQuery("#yahoo, #first");
@@ -371,16 +371,36 @@ test("append(Function) with incoming value", function() {
 
        QUnit.reset();
        old = jQuery("#sap").html();
-       
+
        jQuery("#sap").append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return 5;
        });
-       ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" );        
-       
+       ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" );
+
        QUnit.reset();
 });
 
+test("append the same fragment with events (Bug #6997, 5566)", function () {
+       expect(2);
+       stop(1000);
+
+       var element = jQuery("<a class='test6997'></a>").click(function () {
+               ok(true, "Append second element events work");
+       });
+
+       jQuery("#listWithTabIndex li").append(element)
+               .find('a.test6997').eq(1).click();
+
+       element = jQuery("<li class='test6997'></li>").click(function () {
+               ok(true, "Before second element events work");
+               start();
+       });
+
+       jQuery("#listWithTabIndex li").before(element);
+       jQuery("#listWithTabIndex li.test6997").eq(1).click();
+});
+
 test("appendTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
        expect(16);
 
@@ -489,16 +509,16 @@ test("prepend(Function)", function() {
 
 test("prepend(Function) with incoming value", function() {
        expect(10);
-       
+
        var defaultText = 'Try them out:', old = jQuery('#first').html();
        var result = jQuery('#first').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return '<b>buga</b>';
        });
        equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' );
-       
+
        old = jQuery("#select3").html();
-       
+
        equals( jQuery('#select3').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return '<option value="prependTest">Prepend Test</option>';
@@ -507,35 +527,35 @@ test("prepend(Function) with incoming value", function() {
        QUnit.reset();
        var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog";
        old = jQuery('#sap').html();
-       
+
        jQuery('#sap').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return document.getElementById('first');
        });
-       
+
        equals( jQuery('#sap').text(), expected, "Check for prepending of element" );
 
        QUnit.reset();
        expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog";
        old = jQuery('#sap').html();
-       
+
        jQuery('#sap').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return [document.getElementById('first'), document.getElementById('yahoo')];
        });
-       
+
        equals( jQuery('#sap').text(), expected, "Check for prepending of array of elements" );
 
        QUnit.reset();
        expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog";
        old = jQuery('#sap').html();
-       
+
        jQuery('#sap').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return jQuery("#yahoo, #first");
        });
-       
-       equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" );     
+
+       equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" );
 });
 
 test("prependTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
@@ -680,7 +700,7 @@ test("insertAfter(String|Element|Array&lt;Element&gt;|jQuery)", function() {
 });
 
 var testReplaceWith = function(val) {
-       expect(17);
+       expect(20);
        jQuery('#yahoo').replaceWith(val( '<b id="replace">buga</b>' ));
        ok( jQuery("#replace")[0], 'Replace element with string' );
        ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' );
@@ -748,6 +768,17 @@ var testReplaceWith = function(val) {
                //"</script>");
        equals(jQuery('.replacewith').length, 1, 'Check number of elements in page.');
        jQuery('.replacewith').remove();
+
+       QUnit.reset();
+
+       jQuery("#main").append("<div id='replaceWith'></div>");
+       equals( jQuery("#main").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." );
+
+       jQuery("#replaceWith").replaceWith( val("<div id='replaceWith'></div>") );
+       equals( jQuery("#main").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." );
+
+       jQuery("#replaceWith").replaceWith( val("<div id='replaceWith'></div>") );
+       equals( jQuery("#main").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." );
 }
 
 test("replaceWith(String|Element|Array&lt;Element&gt;|jQuery)", function() {
@@ -757,7 +788,7 @@ test("replaceWith(String|Element|Array&lt;Element&gt;|jQuery)", function() {
 test("replaceWith(Function)", function() {
        testReplaceWith(functionReturningObj);
 
-       expect(18);
+       expect(21);
 
        var y = jQuery("#yahoo")[0];
 
@@ -803,7 +834,7 @@ test("replaceAll(String|Element|Array&lt;Element&gt;|jQuery)", function() {
 });
 
 test("clone()", function() {
-       expect(31);
+       expect(32);
        equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' );
        var clone = jQuery('#yahoo').clone();
        equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' );
@@ -861,6 +892,8 @@ test("clone()", function() {
        form.appendChild( div );
 
        equals( jQuery(form).clone().children().length, 1, "Make sure we just get the form back." );
+
+       equal( jQuery("body").clone().children()[0].id, "qunit-header", "Make sure cloning body works" );
 });
 
 if (!isLocal) {
@@ -955,18 +988,29 @@ test("html(String)", function() {
 
 test("html(Function)", function() {
        testHtml(functionReturningObj);
+
+       expect(33);
+
+       QUnit.reset();
+
+       jQuery("#main").html(function(){
+               return jQuery(this).text();
+       });
+
+       ok( !/</.test( jQuery("#main").html() ), "Replace html with text." );
+       ok( jQuery("#main").html().length > 0, "Make sure text exists." );
 });
 
 test("html(Function) with incoming value", function() {
        expect(20);
-       
+
        var div = jQuery("#main > div"), old = div.map(function(){ return jQuery(this).html() });
-       
+
        div.html(function(i, val) {
                equals( val, old[i], "Make sure the incoming value is correct." );
                return "<b>test</b>";
        });
-       
+
        var pass = true;
        div.each(function(){
                if ( this.childNodes.length !== 1 ) {
@@ -979,7 +1023,7 @@ test("html(Function) with incoming value", function() {
        // using contents will get comments regular, text, and comment nodes
        var j = jQuery("#nonnodes").contents();
        old = j.map(function(){ return jQuery(this).html(); });
-       
+
        j.html(function(i, val) {
                equals( val, old[i], "Make sure the incoming value is correct." );
                return "<b>bold</b>";
@@ -989,17 +1033,17 @@ test("html(Function) with incoming value", function() {
        if ( j.length === 2 ) {
                equals( null, null, "Make sure the incoming value is correct." );
        }
-       
+
        j.find('b').removeData();
        equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "<b>bold</b>", "Check node,textnode,comment with html()" );
-       
+
        var $div = jQuery('<div />');
-       
+
        equals( $div.html(function(i, val) {
                equals( val, "", "Make sure the incoming value is correct." );
                return 5;
        }).html(), '5', 'Setting a number as html' );
-       
+
        equals( $div.html(function(i, val) {
                equals( val, "5", "Make sure the incoming value is correct." );
                return 0;
@@ -1010,16 +1054,16 @@ test("html(Function) with incoming value", function() {
                equals( val, "", "Make sure the incoming value is correct." );
                return insert;
        }).html().replace(/>/g, "&gt;"), insert, "Verify escaped insertion." );
-       
+
        equals( $div2.html(function(i, val) {
                equals( val.replace(/>/g, "&gt;"), insert, "Make sure the incoming value is correct." );
                return "x" + insert;
        }).html().replace(/>/g, "&gt;"), "x" + insert, "Verify escaped insertion." );
-       
+
        equals( $div2.html(function(i, val) {
                equals( val.replace(/>/g, "&gt;"), "x" + insert, "Make sure the incoming value is correct." );
                return " " + insert;
-       }).html().replace(/>/g, "&gt;"), " " + insert, "Verify escaped insertion." );   
+       }).html().replace(/>/g, "&gt;"), " " + insert, "Verify escaped insertion." );
 });
 
 var testRemove = function(method) {
@@ -1053,9 +1097,9 @@ var testRemove = function(method) {
        var count = 0;
        var first = jQuery("#ap").children(":first");
        var cleanUp = first.click(function() { count++ })[method]().appendTo("body").click();
-       
+
        equals( method == "remove" ? 0 : 1, count );
-       
+
        cleanUp.detach();
 };
 
@@ -1080,58 +1124,58 @@ test("empty()", function() {
 
 test("jQuery.cleanData", function() {
        expect(14);
-       
+
        var type, pos, div, child;
-       
+
        type = "remove";
-       
+
        // Should trigger 4 remove event
        div = getDiv().remove();
-       
+
        // Should both do nothing
        pos = "Outer";
        div.trigger("click");
-       
+
        pos = "Inner";
        div.children().trigger("click");
-       
+
        type = "empty";
        div = getDiv();
        child = div.children();
-       
+
        // Should trigger 2 remove event
        div.empty();
-       
+
        // Should trigger 1
        pos = "Outer";
        div.trigger("click");
-       
+
        // Should do nothing
        pos = "Inner";
        child.trigger("click");
 
        // Should trigger 2
        div.remove();
-       
+
        type = "html";
-       
+
        div = getDiv();
        child = div.children();
-       
+
        // Should trigger 2 remove event
        div.html("<div></div>");
-       
+
        // Should trigger 1
        pos = "Outer";
        div.trigger("click");
-       
+
        // Should do nothing
        pos = "Inner";
        child.trigger("click");
 
        // Should trigger 2
        div.remove();
-       
+
        function getDiv() {
                var div = jQuery("<div class='outer'><div class='inner'></div></div>").click(function(){
                        ok( true, type + " " + pos + " Click event fired." );
@@ -1142,15 +1186,15 @@ test("jQuery.cleanData", function() {
                }).focus(function(){
                        ok( false, type + " " + pos + " Focus event fired." );
                }).end().appendTo("body");
-               
+
                div[0].detachEvent = div[0].removeEventListener = function(t){
                        ok( true, type + " Outer " + t + " event unbound" );
                };
-               
+
                div[0].firstChild.detachEvent = div[0].firstChild.removeEventListener = function(t){
                        ok( true, type + " Inner " + t + " event unbound" );
                };
-               
+
                return div;
        }
 });
index ed3d962..8797531 100644 (file)
@@ -1,5 +1,14 @@
 module("offset");
 
+test("disconnected node", function() {
+       expect(2);
+
+       var result = jQuery( document.createElement("div") ).offset();
+
+       equals( result.top, 0, "Check top" );
+       equals( result.left, 0, "Check left" );
+});
+
 var supportsScroll = false;
 
 testoffset("absolute"/* in iframe */, function($, iframe) {
index 97fc689..6ec20bc 100644 (file)
@@ -1,7 +1,7 @@
 module("selector");
 
 test("element", function() {
-       expect(19);
+       expect(21);
        QUnit.reset();
 
        ok( jQuery("*").size() >= 30, "Select all" );
@@ -21,23 +21,27 @@ test("element", function() {
        same( jQuery("p", jQuery("div")).get(), q("firstp","ap","sndp","en","sap","first"), "Finding elements with a context." );
        same( jQuery("div").find("p").get(), q("firstp","ap","sndp","en","sap","first"), "Finding elements with a context." );
 
-       same( jQuery("#form").find("select").get(), q("select1","select2","select3","select4"), "Finding selects with a context." );
+       same( jQuery("#form").find("select").get(), q("select1","select2","select3","select4","select5"), "Finding selects with a context." );
        
        ok( jQuery("#length").length, '&lt;input name="length"&gt; cannot be found under IE, see #945' );
        ok( jQuery("#lengthtest input").length, '&lt;input name="length"&gt; cannot be found under IE, see #945' );
 
        // Check for unique-ness and sort order
-       same( jQuery("*, *").get(), jQuery("*").get(), "Check for duplicates: *, *" );
        same( jQuery("p, div p").get(), jQuery("p").get(), "Check for duplicates: p, div p" );
 
        t( "Checking sort order", "h2, h1", ["qunit-header", "qunit-banner", "qunit-userAgent"] );
        t( "Checking sort order", "h2:first, h1:first", ["qunit-header", "qunit-banner"] );
        t( "Checking sort order", "p, p a", ["firstp", "simon1", "ap", "google", "groups", "anchor1", "mark", "sndp", "en", "yahoo", "sap", "anchor2", "simon", "first"] );
+
+       // Test Conflict ID
+       same( jQuery("#lengthtest").find("#idTest").get(), q("idTest"), "Finding element with id of ID." );
+       same( jQuery("#lengthtest").find("[name='id']").get(), q("idTest"), "Finding element with id of ID." );
+       same( jQuery("#lengthtest").find("input[id='idTest']").get(), q("idTest"), "Finding elements with a context." );
 });
 
 if ( location.protocol != "file:" ) {
        test("XML Document Selectors", function() {
-               expect(7);
+               expect(8);
                stop();
                jQuery.get("data/with_fries.xml", function(xml) {
                        equals( jQuery("foo_bar", xml).length, 1, "Element Selector with underscore" );
@@ -47,6 +51,7 @@ if ( location.protocol != "file:" ) {
                        equals( jQuery("[name=prop2]", xml).length, 1, "Attribute selector with name" );
                        equals( jQuery("#seite1", xml).length, 1, "Attribute selector with ID" );
                        equals( jQuery("component#seite1", xml).length, 1, "Attribute selector with ID" );
+                       equals( jQuery("component", xml).filter("#seite1").length, 1, "Attribute selector filter with ID" );
                        start();
                });
        });
@@ -154,7 +159,7 @@ test("class", function() {
 });
 
 test("name", function() {
-       expect(14);
+       expect(15);
 
        t( "Name selector", "input[name=action]", ["text1"] );
        t( "Name selector with single quotes", "input[name='action']", ["text1"] );
@@ -169,6 +174,12 @@ test("name", function() {
        same( jQuery("#form").find("input[name=action]").get(), q("text1"), "Name selector within the context of another element" );
        same( jQuery("#form").find("input[name='foo[bar]']").get(), q("hidden2"), "Name selector for grouped form element within the context of another element" );
 
+       var form = jQuery("<form><input name='id'/></form>").appendTo("body");
+
+       equals( form.find("input").length, 1, "Make sure that rooted queries on forms (with possible expandos) work." );
+
+       form.remove();
+
        var a = jQuery('<div><a id="tName1ID" name="tName1">tName1 A</a><a id="tName2ID" name="tName2">tName2 A</a><div id="tName1">tName1 Div</div></div>').appendTo('#main').children();
 
        equals( a.length, 3, "Make sure the right number of elements were inserted." );
@@ -199,15 +210,15 @@ test("child and adjacent", function() {
        t( "Child w/ Class", "p > a.blog", ["mark","simon"] );
        t( "All Children", "code > *", ["anchor1","anchor2"] );
        t( "All Grandchildren", "p > * > *", ["anchor1","anchor2"] );
-       t( "Adjacent", "a + a", ["groups"] );
-       t( "Adjacent", "a +a", ["groups"] );
-       t( "Adjacent", "a+ a", ["groups"] );
-       t( "Adjacent", "a+a", ["groups"] );
+       t( "Adjacent", "#main a + a", ["groups"] );
+       t( "Adjacent", "#main a +a", ["groups"] );
+       t( "Adjacent", "#main a+ a", ["groups"] );
+       t( "Adjacent", "#main a+a", ["groups"] );
        t( "Adjacent", "p + p", ["ap","en","sap"] );
        t( "Adjacent", "p#firstp + p", ["ap"] );
        t( "Adjacent", "p[lang=en] + p", ["sap"] );
        t( "Adjacent", "a.GROUPS + code + a", ["mark"] );
-       t( "Comma, Child, and Adjacent", "a + a, code > a", ["groups","anchor1","anchor2"] );
+       t( "Comma, Child, and Adjacent", "#main a + a, code > a", ["groups","anchor1","anchor2"] );
        t( "Element Preceded By", "p ~ div", ["foo", "moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] );
        t( "Element Preceded By", "#first ~ div", ["moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] );
        t( "Element Preceded By", "#groups ~ a", ["mark"] );
@@ -226,7 +237,7 @@ test("child and adjacent", function() {
 });
 
 test("attributes", function() {
-       expect(34);
+       expect(39);
        t( "Attribute Exists", "a[title]", ["google"] );
        t( "Attribute Exists", "*[title]", ["google"] );
        t( "Attribute Exists", "[title]", ["google"] );
@@ -264,6 +275,17 @@ test("attributes", function() {
        t( "Attribute Contains", "a[href *= 'google']", ["google","groups"] );
        t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", ["google","groups","anchor1"] );
 
+       var opt = document.getElementById("option1a"),
+               match = (window.Sizzle || window.jQuery.find).matchesSelector;
+
+       opt.setAttribute("test", "");
+
+       ok( match( opt, "[id*=option1][type!=checkbox]" ), "Attribute Is Not Equal Matches" );
+       ok( match( opt, "[id*=option1]" ), "Attribute With No Quotes Contains Matches" );
+       ok( match( opt, "[test=]" ), "Attribute With No Quotes No Content Matches" );
+       ok( match( opt, "[id=option1a]" ), "Attribute With No Quotes Equals Matches" );
+       ok( match( document.getElementById("simon1"), "a[href*=#]" ), "Attribute With No Quotes Href Contains Matches" );
+
        t("Empty values", "#select1 option[value='']", ["option1a"]);
        t("Empty values", "#select1 option[value!='']", ["option1b","option1c","option1d"]);
        
@@ -321,10 +343,13 @@ test("pseudo - child", function() {
 });
 
 test("pseudo - misc", function() {
-       expect(6);
+       expect(7);
 
        t( "Headers", ":header", ["qunit-header", "qunit-banner", "qunit-userAgent"] );
        t( "Has Children - :has()", "p:has(a)", ["firstp","ap","en","sap"] );
+       
+       var select = document.getElementById("select1");
+       ok( (window.Sizzle || window.jQuery.find).matchesSelector( select, ":has(option)" ), "Has Option Matches" );
 
        t( "Text Contains", "a:contains(Google)", ["google","groups"] );
        t( "Text Contains", "a:contains(Google Groups)", ["groups"] );
@@ -338,7 +363,7 @@ test("pseudo - :not", function() {
        expect(24);
        t( "Not", "a.blog:not(.link)", ["mark"] );
 
-       t( "Not - multiple", "#form option:not(:contains(Nothing),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d", "option3e", "option4e"] );
+       t( "Not - multiple", "#form option:not(:contains(Nothing),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d", "option3e", "option4e", "option5b", "option5c"] );
        t( "Not - recursive", "#form option:not(:not(:selected))[id^='option3']", [ "option3b", "option3c"] );
 
        t( ":not() failing interior", "p:not(.foo)", ["firstp","ap","sndp","en","sap","first"] );
@@ -359,9 +384,9 @@ test("pseudo - :not", function() {
 
        t( "No element not selector", ".container div:not(.excluded) div", [] );
 
-       t( ":not() Existing attribute", "#form select:not([multiple])", ["select1", "select2"]);
-       t( ":not() Equals attribute", "#form select:not([name=select1])", ["select2", "select3", "select4"]);
-       t( ":not() Equals quoted attribute", "#form select:not([name='select1'])", ["select2", "select3", "select4"]);
+       t( ":not() Existing attribute", "#form select:not([multiple])", ["select1", "select2", "select5"]);
+       t( ":not() Equals attribute", "#form select:not([name=select1])", ["select2", "select3", "select4","select5"]);
+       t( ":not() Equals quoted attribute", "#form select:not([name='select1'])", ["select2", "select3", "select4", "select5"]);
 
        t( ":not() Multiple Class", "#foo a:not(.blog)", ["yahoo","anchor2"] );
        t( ":not() Multiple Class", "#foo a:not(.link)", ["yahoo","anchor2"] );
@@ -427,7 +452,7 @@ test("pseudo - visibility", function() {
 test("pseudo - form", function() {
        expect(8);
 
-       t( "Form element :input", "#form :input", ["text1", "text2", "radio1", "radio2", "check1", "check2", "hidden1", "hidden2", "name", "search", "button", "area1", "select1", "select2", "select3", "select4"] );
+       t( "Form element :input", "#form :input", ["text1", "text2", "radio1", "radio2", "check1", "check2", "hidden1", "hidden2", "name", "search", "button", "area1", "select1", "select2", "select3", "select4", "select5"] );
        t( "Form element :radio", "#form :radio", ["radio1", "radio2"] );
        t( "Form element :checkbox", "#form :checkbox", ["check1", "check2"] );
        t( "Form element :text", "#form :text:not(#search)", ["text1", "text2", "hidden2", "name"] );
@@ -435,5 +460,5 @@ test("pseudo - form", function() {
        t( "Form element :checkbox:checked", "#form :checkbox:checked", ["check1"] );
        t( "Form element :radio:checked, :checkbox:checked", "#form :radio:checked, #form :checkbox:checked", ["radio2", "check1"] );
 
-       t( "Selected Option Element", "#form option:selected", ["option1a","option2d","option3b","option3c","option4b","option4c","option4d"] );
+       t( "Selected Option Element", "#form option:selected", ["option1a","option2d","option3b","option3c","option4b","option4c","option4d","option5a"] );
 });
index 3fd98f6..0d079f1 100644 (file)
@@ -1,12 +1,16 @@
 module("traversing");
 
 test("find(String)", function() {
-       expect(2);
+       expect(5);
        equals( 'Yahoo', jQuery('#foo').find('.blogTest').text(), 'Check for find' );
 
        // using contents will get comments regular, text, and comment nodes
        var j = jQuery("#nonnodes").contents();
        equals( j.find("div").length, 0, "Check node,textnode,comment to find zero divs" );
+
+       same( jQuery("#main").find("> div").get(), q("foo", "moretests", "tabindex-tests", "liveHandlerOrder", "siblingTest"), "find child elements" );
+       same( jQuery("#main").find("> #foo, > #moretests").get(), q("foo", "moretests"), "find child elements" );
+       same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" );
 });
 
 test("is(String)", function() {
@@ -120,7 +124,7 @@ test("filter(jQuery)", function() {
 })
 
 test("closest()", function() {
-       expect(10);
+       expect(11);
        same( jQuery("body").closest("body").get(), q("body"), "closest(body)" );
        same( jQuery("body").closest("html").get(), q("html"), "closest(html)" );
        same( jQuery("body").closest("div").get(), [], "closest(div)" );
@@ -137,7 +141,9 @@ test("closest()", function() {
        
        //Test that .closest() returns unique'd set
        equals( jQuery('#main p').closest('#main').length, 1, "Closest should return a unique set" );
-       
+
+       // Test on disconnected node
+       equals( jQuery("<div><p></p></div>").find("p").closest("table").length, 0, "Make sure disconnected closest work." );
 });
 
 test("closest(Array)", function() {
@@ -157,7 +163,7 @@ test("not(Selector)", function() {
        equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" );
        same( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" );
        same( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" );
-       same( jQuery("#form option").not("option.emptyopt:contains('Nothing'),[selected],[value='1']").get(), q("option1c", "option1d", "option2c", "option3d", "option3e", "option4e" ), "not('complex selector')");
+       same( jQuery("#form option").not("option.emptyopt:contains('Nothing'),[selected],[value='1']").get(), q("option1c", "option1d", "option2c", "option3d", "option3e", "option4e","option5b"), "not('complex selector')");
 
        same( jQuery('#ap *').not('code').get(), q("google", "groups", "anchor1", "mark"), "not('tag selector')" );
        same( jQuery('#ap *').not('code, #mark').get(), q("google", "groups", "anchor1"), "not('tag, ID selector')" );
@@ -168,7 +174,7 @@ test("not(Element)", function() {
        expect(1);
 
        var selects = jQuery("#form select");
-       same( selects.not( selects[1] ).get(), q("select1", "select3", "select4"), "filter out DOM element");
+       same( selects.not( selects[1] ).get(), q("select1", "select3", "select4", "select5"), "filter out DOM element");
 });
 
 test("not(Function)", function() {
index 8032ca3..7810cd6 100644 (file)
@@ -1 +1 @@
-1.4.3pre
\ No newline at end of file
+1.4.5pre
\ No newline at end of file