Click the white box to move the marker to it. Clicking the box also changes the position to absolute (if not already) and sets the position according to the position method.
Click the white box to move the marker to it. Clicking the box also changes the position to absolute (if not already) and sets the position according to the position method.
Has absolute position but no values set for the location ('auto').
47 |
48 |
Click the white box to move the marker to it. Clicking the box also changes the position to absolute (if not already) and sets the position according to the position method.
59 | This is a test page for
60 |
61 | #8135
62 |
63 | which was reported in Firefox when accessing properties
64 | of an XMLHttpRequest object after a network error occured.
65 |
66 |
Take the following steps:
67 |
68 |
69 | make sure you accessed this page through a web server,
70 |
71 |
72 | stop the web server,
73 |
74 |
75 | open the console,
76 |
77 |
78 | click this
79 |
80 | ,
81 |
82 |
83 | wait for both requests to fail.
84 |
85 |
86 |
87 | Test passes if you get two log lines:
88 |
89 |
90 | the first starting with "abort",
91 |
92 |
93 | the second starting with "complete",
94 |
95 |
96 |
97 |
98 | Test fails if the browser notifies an exception.
99 |
57 | This is a test page for jQuery.readyWait, that was
58 | added due to this ticket
59 | #6781.
60 |
61 |
62 | Test for jQuery.readyWait, which can be used
63 | by plugins and other scripts to indicate something
64 | important to the page is still loading and needs
65 | to block the DOM ready callbacks that are registered
66 | with jQuery.
67 |
68 |
69 | Script loaders are the most likely kind of script
70 | to use jQuery.readyWait, but it could be used by
71 | other things like a script that loads a CSS file
72 | and wants to pause the DOM ready callbacks.
73 |
74 |
75 | Expected Result: The text
76 | It Worked!
77 | appears below after about 2 seconds.
78 |
79 |
80 | If there is an error in the console,
81 | or the text does not show up, then the test failed.
82 |
37 | Access this file using the "file:" protocol,
38 |
39 |
40 | two green "OK" strings must appear below,
41 |
42 |
43 | Empty local files will issue errors, it's a known limitation.
44 |
45 |
46 |
47 | Results
48 |
49 |
50 |
51 | Success:
52 |
53 |
54 |
55 |
56 | Error:
57 |
58 |
59 |
60 |
61 |
62 | Logs:
63 |
64 |
65 |
66 |
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [jQuery](http://jquery.com/) - New Wave Javascript
2 | ==================================================
3 |
4 | What you need to build your own jQuery
5 | --------------------------------------
6 |
7 | In order to build jQuery, you need to have GNU make 3.8 or later, Node.js 0.2 or later, and git 1.7 or later.
8 | (Earlier versions might work OK, but are not tested.)
9 |
10 | Windows users have two options:
11 |
12 | 1. Install [msysgit](https://code.google.com/p/msysgit/) (Full installer for official Git),
13 | [GNU make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm), and a
14 | [binary version of Node.js](http://node-js.prcn.co.cc/). Make sure all three packages are installed to the same
15 | location (by default, this is C:\Program Files\Git).
16 | 2. Install [Cygwin](http://cygwin.com/) (make sure you install the git, make, and which packages), then either follow
17 | the [Node.js build instructions](https://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29) or install
18 | the [binary version of Node.js](http://node-js.prcn.co.cc/).
19 |
20 | Mac OS users should install Xcode (comes on your Mac OS install DVD, or downloadable from
21 | [Apple's Xcode site](http://developer.apple.com/technologies/xcode.html)) and
22 | [http://mxcl.github.com/homebrew/](Homebrew). Once Homebrew is installed, run `brew install git` to install git,
23 | and `brew install node` to install Node.js.
24 |
25 | Linux/BSD users should use their appropriate package managers to install make, git, and node, or build from source
26 | if you swing that way. Easy-peasy.
27 |
28 |
29 | How to build your own jQuery
30 | ----------------------------
31 |
32 | First, clone a copy of the main jQuery git repo by running `git clone git://github.com/jquery/jquery.git`.
33 |
34 | Then, to get a complete, minified, jslinted version of jQuery, simply `cd` to the `jquery` directory and type
35 | `make`. If you don't have Node installed and/or want to make a basic, uncompressed, unlinted version of jQuery, use
36 | `make jquery` instead of `make`.
37 |
38 | The built version of jQuery will be put in the `dist/` subdirectory.
39 |
40 | To remove all built files, run `make clean`.
41 |
42 |
43 | Building to a different directory
44 | ---------------------------------
45 |
46 | If you want to build jQuery to a directory that is different from the default location, you can specify the PREFIX
47 | directory: `make PREFIX=/home/jquery/test/ [command]`
48 |
49 | With this example, the output files would end up in `/home/jquery/test/dist/`.
50 |
51 |
52 | Troubleshooting
53 | ---------------
54 |
55 | Sometimes, the various git repositories get into an inconsistent state where builds don't complete properly
56 | (usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then
57 | run `make` again.
58 |
59 |
60 | Questions?
61 | ----------
62 |
63 | If you have any questions, please feel free to ask on the
64 | [Developing jQuery Core forum](http://forum.jquery.com/developing-jquery-core) or in #jquery on irc.freenode.net.
65 |
--------------------------------------------------------------------------------
/test/data/testinit.js:
--------------------------------------------------------------------------------
1 | var jQuery = this.jQuery || "jQuery", // For testing .noConflict()
2 | $ = this.$ || "$",
3 | originaljQuery = jQuery,
4 | original$ = $;
5 |
6 | /**
7 | * Returns an array of elements with the given IDs, eg.
8 | * @example q("main", "foo", "bar")
9 | * @result [
, , ]
10 | */
11 | function q() {
12 | var r = [];
13 |
14 | for ( var i = 0; i < arguments.length; i++ ) {
15 | r.push( document.getElementById( arguments[i] ) );
16 | }
17 |
18 | return r;
19 | }
20 |
21 | /**
22 | * Asserts that a select matches the given IDs * @example t("Check for something", "//[a]", ["foo", "baar"]);
23 | * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baa
24 | r'
25 | */
26 | function t(a,b,c) {
27 | var f = jQuery(b).get(), s = "";
28 |
29 | for ( var i = 0; i < f.length; i++ ) {
30 | s += (s && ",") + '"' + f[i].id + '"';
31 | }
32 |
33 | same(f, q.apply(q,c), a + " (" + b + ")");
34 | }
35 |
36 | /**
37 | * Add random number to url to stop IE from caching
38 | *
39 | * @example url("data/test.html")
40 | * @result "data/test.html?10538358428943"
41 | *
42 | * @example url("data/test.php?foo=bar")
43 | * @result "data/test.php?foo=bar&10538358345554"
44 | */
45 | function url(value) {
46 | return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
47 | }
48 |
49 | (function () {
50 | // Store the old counts so that we only assert on tests that have actually leaked,
51 | // instead of asserting every time a test has leaked sometime in the past
52 | var oldCacheLength = 0,
53 | oldFragmentsLength = 0,
54 | oldTimersLength = 0,
55 | oldActive = 0;
56 |
57 | /**
58 | * Ensures that tests have cleaned up properly after themselves. Should be passed as the
59 | * teardown function on all modules' lifecycle object.
60 | */
61 | this.moduleTeardown = function () {
62 | var i, fragmentsLength = 0, cacheLength = 0;
63 |
64 | // Allow QUnit.reset to clean up any attached elements before checking for leaks
65 | QUnit.reset();
66 |
67 | for ( i in jQuery.cache ) {
68 | ++cacheLength;
69 | }
70 |
71 | jQuery.fragments = {};
72 |
73 | for ( i in jQuery.fragments ) {
74 | ++fragmentsLength;
75 | }
76 |
77 | // Because QUnit doesn't have a mechanism for retrieving the number of expected assertions for a test,
78 | // if we unconditionally assert any of these, the test will fail with too many assertions :|
79 | if ( cacheLength !== oldCacheLength ) {
80 | equals( cacheLength, oldCacheLength, "No unit tests leak memory in jQuery.cache" );
81 | oldCacheLength = cacheLength;
82 | }
83 | if ( fragmentsLength !== oldFragmentsLength ) {
84 | equals( fragmentsLength, oldFragmentsLength, "No unit tests leak memory in jQuery.fragments" );
85 | oldFragmentsLength = fragmentsLength;
86 | }
87 | if ( jQuery.timers.length !== oldTimersLength ) {
88 | equals( jQuery.timers.length, oldTimersLength, "No timers are still running" );
89 | oldTimersLength = jQuery.timers.length;
90 | }
91 | if ( jQuery.active !== oldActive ) {
92 | equals( jQuery.active, 0, "No AJAX requests are still active" );
93 | oldActive = jQuery.active;
94 | }
95 | }
96 | }());
--------------------------------------------------------------------------------
/test/polluted.php:
--------------------------------------------------------------------------------
1 | array(
5 | "versions" => array( "1.1.1", "1.2.0", "1.2.3", "1.3.0", "1.3.1", "1.3.2", "1.4.0", "1.4.1", "1.4.3", "1.5.0" ),
6 | "url" => "dojo/XYZ/dojo/dojo.xd.js"
7 | ),
8 | "ExtCore" => array(
9 | "versions" => array( "3.0.0", "3.1.0" ),
10 | "url" => "ext-core/XYZ/ext-core.js"
11 | ),
12 | "jQuery" => array(
13 | "versions" => array( "1.2.3", "1.2.6", "1.3.0", "1.3.1", "1.3.2", "1.4.0", "1.4.1", "1.4.2", "1.4.3", "1.4.4", "1.5.0" ),
14 | "url" => "jquery/XYZ/jquery.min.js"
15 | ),
16 | "jQueryUI" => array(
17 | "versions" => array( "1.5.2", "1.5.3", "1.6.0", "1.7.0", "1.7.1", "1.7.2", "1.7.3", "1.8.0", "1.8.1", "1.8.2", "1.8.4", "1.8.5", "1.8.6", "1.8.7", "1.8.8", "1.8.9" ),
18 | "url" => "jqueryui/XYZ/jquery-ui.min.js"
19 | ),
20 | "MooTools" => array(
21 | "versions" => array( "1.1.1", "1.1.2", "1.2.1", "1.2.2", "1.2.3", "1.2.4", "1.2.5", "1.3.0" ),
22 | "url" => "mootools/XYZ/mootools-yui-compressed.js"
23 | ),
24 | "Prototype" => array(
25 | "versions" => array( "1.6.0.2", "1.6.0.3", "1.6.1.0", "1.7.0.0" ),
26 | "url" => "prototype/XYZ/prototype.js"
27 | ),
28 | "scriptaculous" => array(
29 | "versions" => array( "1.8.1", "1.8.2", "1.8.3" ),
30 | "url" => "scriptaculous/XYZ/scriptaculous.js"
31 | ),
32 | "SWFObject" => array(
33 | "versions" => array( "2.1", "2.2" ),
34 | "url" => "swfobject/XYZ/swfobject.js"
35 | ),
36 | "YUI" => array(
37 | "versions" => array( "2.6.0", "2.7.0", "2.8.0r4", "2.8.1", "2.8.2", "3.3.0" ),
38 | "url" => "yui/XYZ/build/yui/yui-min.js"
39 | )
40 | );
41 |
42 | if( count($_POST) ) {
43 | $includes = array();
44 | foreach( $_POST as $name => $ver ){
45 | $url = $libraries[ $name ][ "url" ];
46 | if( $name == "YUI" && $ver[0] == "2" ) {
47 | $url = str_replace( "/yui", "/yuiloader", $url, $count = 2 );
48 | }
49 | $include = "\n";
50 | if( $lib == "prototype" ) { // prototype must be included first
51 | array_unshift( $includes, $include );
52 | } else {
53 | array_push( $includes, $include );
54 | }
55 | }
56 |
57 | $includes = implode( "\n", $includes );
58 | $suite = file_get_contents( "index.html" );
59 | echo str_replace( "", $includes, $suite );
60 | exit;
61 | }
62 | ?>
63 |
64 |
65 |
66 |
67 | Run jQuery Test Suite Polluted
68 |
76 |
77 |
78 |
79 |
jQuery Test Suite
80 |
81 |
Choose other libraries to include
82 |
83 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | V ?= 0
2 |
3 | SRC_DIR = src
4 | TEST_DIR = test
5 | BUILD_DIR = build
6 |
7 | PREFIX = .
8 | DIST_DIR = ${PREFIX}/dist
9 |
10 | JS_ENGINE ?= `which node nodejs`
11 | COMPILER = ${JS_ENGINE} ${BUILD_DIR}/uglify.js --unsafe
12 | POST_COMPILER = ${JS_ENGINE} ${BUILD_DIR}/post-compile.js
13 |
14 | BASE_FILES = ${SRC_DIR}/core.js\
15 | ${SRC_DIR}/support.js\
16 | ${SRC_DIR}/data.js\
17 | ${SRC_DIR}/queue.js\
18 | ${SRC_DIR}/attributes.js\
19 | ${SRC_DIR}/event.js\
20 | ${SRC_DIR}/selector.js\
21 | ${SRC_DIR}/traversing.js\
22 | ${SRC_DIR}/manipulation.js\
23 | ${SRC_DIR}/css.js\
24 | ${SRC_DIR}/ajax.js\
25 | ${SRC_DIR}/ajax/jsonp.js\
26 | ${SRC_DIR}/ajax/script.js\
27 | ${SRC_DIR}/ajax/xhr.js\
28 | ${SRC_DIR}/effects.js\
29 | ${SRC_DIR}/offset.js\
30 | ${SRC_DIR}/dimensions.js
31 |
32 | MODULES = ${SRC_DIR}/intro.js\
33 | ${BASE_FILES}\
34 | ${SRC_DIR}/outro.js
35 |
36 | JQ = ${DIST_DIR}/jquery.js
37 | JQ_MIN = ${DIST_DIR}/jquery.min.js
38 |
39 | SIZZLE_DIR = ${SRC_DIR}/sizzle
40 | QUNIT_DIR = ${TEST_DIR}/qunit
41 |
42 | JQ_VER = $(shell cat version.txt)
43 | VER = sed "s/@VERSION/${JQ_VER}/"
44 |
45 | DATE=$(shell git log -1 --pretty=format:%ad)
46 |
47 | all: jquery min lint
48 | @@echo "jQuery build complete."
49 |
50 | ${DIST_DIR}:
51 | @@mkdir -p ${DIST_DIR}
52 |
53 | ifeq ($(strip $(V)),0)
54 | verbose = --quiet
55 | else ifeq ($(strip $(V)),1)
56 | verbose =
57 | else
58 | verbose = --verbose
59 | endif
60 |
61 | define clone_or_pull
62 | -@@if test ! -d $(strip ${1})/.git; then \
63 | echo "Cloning $(strip ${1})..."; \
64 | git clone $(strip ${verbose}) --depth=1 $(strip ${2}) $(strip ${1}); \
65 | else \
66 | echo "Pulling $(strip ${1})..."; \
67 | git --git-dir=$(strip ${1})/.git pull $(strip ${verbose}) origin master; \
68 | fi
69 |
70 | endef
71 |
72 | ${QUNIT_DIR}:
73 | $(call clone_or_pull, ${QUNIT_DIR}, git://github.com/jquery/qunit.git)
74 |
75 | ${SIZZLE_DIR}:
76 | $(call clone_or_pull, ${SIZZLE_DIR}, git://github.com/jeresig/sizzle.git)
77 |
78 | init: ${QUNIT_DIR} ${SIZZLE_DIR}
79 |
80 | jquery: init ${JQ}
81 | jq: init ${JQ}
82 |
83 | ${JQ}: ${MODULES} | ${DIST_DIR}
84 | @@echo "Building" ${JQ}
85 |
86 | @@cat ${MODULES} | \
87 | sed 's/.function..jQuery...{//' | \
88 | sed 's/}...jQuery..;//' | \
89 | sed 's/@DATE/'"${DATE}"'/' | \
90 | ${VER} > ${JQ};
91 |
92 | ${SRC_DIR}/selector.js: ${SIZZLE_DIR}/sizzle.js
93 | @@echo "Building selector code from Sizzle"
94 | @@sed '/EXPOSE/r src/sizzle-jquery.js' ${SIZZLE_DIR}/sizzle.js | grep -v window.Sizzle > ${SRC_DIR}/selector.js
95 |
96 | lint: jquery
97 | @@if test ! -z ${JS_ENGINE}; then \
98 | echo "Checking jQuery against JSLint..."; \
99 | ${JS_ENGINE} build/jslint-check.js; \
100 | else \
101 | echo "You must have NodeJS installed in order to test jQuery against JSLint."; \
102 | fi
103 |
104 | min: ${JQ_MIN}
105 |
106 | ${JQ_MIN}: jquery
107 | @@if test ! -z ${JS_ENGINE}; then \
108 | echo "Minifying jQuery" ${JQ_MIN}; \
109 | ${COMPILER} ${JQ} > ${JQ_MIN}.tmp; \
110 | ${POST_COMPILER} ${JQ_MIN}.tmp > ${JQ_MIN}; \
111 | rm -f ${JQ_MIN}.tmp; \
112 | else \
113 | echo "You must have NodeJS installed in order to minify jQuery."; \
114 | fi
115 |
116 |
117 | clean:
118 | @@echo "Removing Distribution directory:" ${DIST_DIR}
119 | @@rm -rf ${DIST_DIR}
120 |
121 | @@echo "Removing built copy of Sizzle"
122 | @@rm -f src/selector.js
123 |
124 | @@echo "Removing cloned directories"
125 | @@rm -rf test/qunit src/sizzle
126 |
127 | .PHONY: all jquery lint min init jq clean
128 |
--------------------------------------------------------------------------------
/test/unit/queue.js:
--------------------------------------------------------------------------------
1 | module("queue", { teardown: moduleTeardown });
2 |
3 | test("queue() with other types",function() {
4 | expect(9);
5 | var counter = 0;
6 |
7 | var $div = jQuery({});
8 |
9 | $div
10 | .queue('foo',function(){
11 | equals( ++counter, 1, "Dequeuing" );
12 | jQuery.dequeue(this,'foo');
13 | })
14 | .queue('foo',function(){
15 | equals( ++counter, 2, "Dequeuing" );
16 | jQuery(this).dequeue('foo');
17 | })
18 | .queue('foo',function(){
19 | equals( ++counter, 3, "Dequeuing" );
20 | })
21 | .queue('foo',function(){
22 | equals( ++counter, 4, "Dequeuing" );
23 | });
24 |
25 | equals( $div.queue('foo').length, 4, "Testing queue length" );
26 |
27 | $div.dequeue('foo');
28 |
29 | equals( counter, 3, "Testing previous call to dequeue" );
30 | equals( $div.queue('foo').length, 1, "Testing queue length" );
31 |
32 | $div.dequeue('foo');
33 |
34 | equals( counter, 4, "Testing previous call to dequeue" );
35 | equals( $div.queue('foo').length, 0, "Testing queue length" );
36 | });
37 |
38 | test("queue(name) passes in the next item in the queue as a parameter", function() {
39 | expect(2);
40 |
41 | var div = jQuery({});
42 | var counter = 0;
43 |
44 | div.queue("foo", function(next) {
45 | equals(++counter, 1, "Dequeueing");
46 | next();
47 | }).queue("foo", function(next) {
48 | equals(++counter, 2, "Next was called");
49 | next();
50 | }).queue("bar", function() {
51 | equals(++counter, 3, "Other queues are not triggered by next()")
52 | });
53 |
54 | div.dequeue("foo");
55 | });
56 |
57 | test("queue(name) passes in the next item in the queue as a parameter", function() {
58 | expect(2);
59 |
60 | var div = jQuery({});
61 | var counter = 0;
62 |
63 | div.queue("foo", function(next) {
64 | equals(++counter, 1, "Dequeueing");
65 | next();
66 | }).queue("foo", function(next) {
67 | equals(++counter, 2, "Next was called");
68 | next();
69 | }).queue("bar", function() {
70 | equals(++counter, 3, "Other queues are not triggered by next()")
71 | });
72 |
73 | div.dequeue("foo");
74 | });
75 |
76 | test("queue() passes in the next item in the queue as a parameter to fx queues", function() {
77 | expect(2);
78 | stop();
79 |
80 | var div = jQuery({});
81 | var counter = 0;
82 |
83 | div.queue(function(next) {
84 | equals(++counter, 1, "Dequeueing");
85 | var self = this;
86 | setTimeout(function() { next() }, 500);
87 | }).queue(function(next) {
88 | equals(++counter, 2, "Next was called");
89 | next();
90 | start();
91 | }).queue("bar", function() {
92 | equals(++counter, 3, "Other queues are not triggered by next()")
93 | });
94 |
95 | });
96 |
97 | test("delay()", function() {
98 | expect(2);
99 | stop();
100 |
101 | var foo = jQuery({}), run = 0;
102 |
103 | foo.delay(100).queue(function(){
104 | run = 1;
105 | ok( true, "The function was dequeued." );
106 | start();
107 | });
108 |
109 | equals( run, 0, "The delay delayed the next function from running." );
110 | });
111 |
112 | test("clearQueue(name) clears the queue", function() {
113 | expect(1);
114 |
115 | var div = jQuery({});
116 | var counter = 0;
117 |
118 | div.queue("foo", function(next) {
119 | counter++;
120 | jQuery(this).clearQueue("foo");
121 | next();
122 | }).queue("foo", function(next) {
123 | counter++;
124 | });
125 |
126 | div.dequeue("foo");
127 |
128 | equals(counter, 1, "the queue was cleared");
129 | });
130 |
131 | test("clearQueue() clears the fx queue", function() {
132 | expect(1);
133 |
134 | var div = jQuery({});
135 | var counter = 0;
136 |
137 | div.queue(function(next) {
138 | counter++;
139 | var self = this;
140 | setTimeout(function() { jQuery(self).clearQueue(); next(); }, 50);
141 | }).queue(function(next) {
142 | counter++;
143 | });
144 |
145 | equals(counter, 1, "the queue was cleared");
146 |
147 | div.removeData();
148 | });
149 |
--------------------------------------------------------------------------------
/src/ajax/xhr.js:
--------------------------------------------------------------------------------
1 | (function( jQuery ) {
2 |
3 | var // #5280: next active xhr id and list of active xhrs' callbacks
4 | xhrId = jQuery.now(),
5 | xhrCallbacks,
6 |
7 | // XHR used to determine supports properties
8 | testXHR;
9 |
10 | // #5280: Internet Explorer will keep connections alive if we don't abort on unload
11 | function xhrOnUnloadAbort() {
12 | jQuery( window ).unload(function() {
13 | // Abort all pending requests
14 | for ( var key in xhrCallbacks ) {
15 | xhrCallbacks[ key ]( 0, 1 );
16 | }
17 | });
18 | }
19 |
20 | // Functions to create xhrs
21 | function createStandardXHR() {
22 | try {
23 | return new window.XMLHttpRequest();
24 | } catch( e ) {}
25 | }
26 |
27 | function createActiveXHR() {
28 | try {
29 | return new window.ActiveXObject( "Microsoft.XMLHTTP" );
30 | } catch( e ) {}
31 | }
32 |
33 | // Create the request object
34 | // (This is still attached to ajaxSettings for backward compatibility)
35 | jQuery.ajaxSettings.xhr = window.ActiveXObject ?
36 | /* Microsoft failed to properly
37 | * implement the XMLHttpRequest in IE7 (can't request local files),
38 | * so we use the ActiveXObject when it is available
39 | * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
40 | * we need a fallback.
41 | */
42 | function() {
43 | return !this.isLocal && createStandardXHR() || createActiveXHR();
44 | } :
45 | // For all other browsers, use the standard XMLHttpRequest object
46 | createStandardXHR;
47 |
48 | // Test if we can create an xhr object
49 | testXHR = jQuery.ajaxSettings.xhr();
50 | jQuery.support.ajax = !!testXHR;
51 |
52 | // Does this browser support crossDomain XHR requests
53 | jQuery.support.cors = testXHR && ( "withCredentials" in testXHR );
54 |
55 | // No need for the temporary xhr anymore
56 | testXHR = undefined;
57 |
58 | // Create transport if the browser can provide an xhr
59 | if ( jQuery.support.ajax ) {
60 |
61 | jQuery.ajaxTransport(function( s ) {
62 | // Cross domain only allowed if supported through XMLHttpRequest
63 | if ( !s.crossDomain || jQuery.support.cors ) {
64 |
65 | var callback;
66 |
67 | return {
68 | send: function( headers, complete ) {
69 |
70 | // Get a new xhr
71 | var xhr = s.xhr(),
72 | handle,
73 | i;
74 |
75 | // Open the socket
76 | // Passing null username, generates a login popup on Opera (#2865)
77 | if ( s.username ) {
78 | xhr.open( s.type, s.url, s.async, s.username, s.password );
79 | } else {
80 | xhr.open( s.type, s.url, s.async );
81 | }
82 |
83 | // Apply custom fields if provided
84 | if ( s.xhrFields ) {
85 | for ( i in s.xhrFields ) {
86 | xhr[ i ] = s.xhrFields[ i ];
87 | }
88 | }
89 |
90 | // Override mime type if needed
91 | if ( s.mimeType && xhr.overrideMimeType ) {
92 | xhr.overrideMimeType( s.mimeType );
93 | }
94 |
95 | // Requested-With header
96 | // Not set for crossDomain requests with no content
97 | // (see why at http://trac.dojotoolkit.org/ticket/9486)
98 | // Won't change header if already provided
99 | if ( !( s.crossDomain && !s.hasContent ) && !headers["X-Requested-With"] ) {
100 | headers[ "X-Requested-With" ] = "XMLHttpRequest";
101 | }
102 |
103 | // Need an extra try/catch for cross domain requests in Firefox 3
104 | try {
105 | for ( i in headers ) {
106 | xhr.setRequestHeader( i, headers[ i ] );
107 | }
108 | } catch( _ ) {}
109 |
110 | // Do send the request
111 | // This may raise an exception which is actually
112 | // handled in jQuery.ajax (so no try/catch here)
113 | xhr.send( ( s.hasContent && s.data ) || null );
114 |
115 | // Listener
116 | callback = function( _, isAbort ) {
117 |
118 | var status,
119 | statusText,
120 | responseHeaders,
121 | responses,
122 | xml;
123 |
124 | // Firefox throws exceptions when accessing properties
125 | // of an xhr when a network error occured
126 | // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
127 | try {
128 |
129 | // Was never called and is aborted or complete
130 | if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
131 |
132 | // Only called once
133 | callback = undefined;
134 |
135 | // Do not keep as active anymore
136 | if ( handle ) {
137 | xhr.onreadystatechange = jQuery.noop;
138 | delete xhrCallbacks[ handle ];
139 | }
140 |
141 | // If it's an abort
142 | if ( isAbort ) {
143 | // Abort it manually if needed
144 | if ( xhr.readyState !== 4 ) {
145 | xhr.abort();
146 | }
147 | } else {
148 | status = xhr.status;
149 | responseHeaders = xhr.getAllResponseHeaders();
150 | responses = {};
151 | xml = xhr.responseXML;
152 |
153 | // Construct response list
154 | if ( xml && xml.documentElement /* #4958 */ ) {
155 | responses.xml = xml;
156 | }
157 | responses.text = xhr.responseText;
158 |
159 | // Firefox throws an exception when accessing
160 | // statusText for faulty cross-domain requests
161 | try {
162 | statusText = xhr.statusText;
163 | } catch( e ) {
164 | // We normalize with Webkit giving an empty statusText
165 | statusText = "";
166 | }
167 |
168 | // Filter status for non standard behaviors
169 |
170 | // If the request is local and we have data: assume a success
171 | // (success with no data won't get notified, that's the best we
172 | // can do given current implementations)
173 | if ( !status && s.isLocal && !s.crossDomain ) {
174 | status = responses.text ? 200 : 404;
175 | // IE - #1450: sometimes returns 1223 when it should be 204
176 | } else if ( status === 1223 ) {
177 | status = 204;
178 | }
179 | }
180 | }
181 | } catch( firefoxAccessException ) {
182 | if ( !isAbort ) {
183 | complete( -1, firefoxAccessException );
184 | }
185 | }
186 |
187 | // Call complete if needed
188 | if ( responses ) {
189 | complete( status, statusText, responses, responseHeaders );
190 | }
191 | };
192 |
193 | // if we're in sync mode or it's in cache
194 | // and has been retrieved directly (IE6 & IE7)
195 | // we need to manually fire the callback
196 | if ( !s.async || xhr.readyState === 4 ) {
197 | callback();
198 | } else {
199 | // Create the active xhrs callbacks list if needed
200 | // and attach the unload handler
201 | if ( !xhrCallbacks ) {
202 | xhrCallbacks = {};
203 | xhrOnUnloadAbort();
204 | }
205 | // Add to list of active xhrs callbacks
206 | handle = xhrId++;
207 | xhr.onreadystatechange = xhrCallbacks[ handle ] = callback;
208 | }
209 | },
210 |
211 | abort: function() {
212 | if ( callback ) {
213 | callback(0,1);
214 | }
215 | }
216 | };
217 | }
218 | });
219 | }
220 |
221 | })( jQuery );
222 |
--------------------------------------------------------------------------------
/speed/benchmarker.js:
--------------------------------------------------------------------------------
1 | jQuery.benchmarker.tests = [
2 | // Selectors from:
3 | // http://ejohn.org/blog/selectors-that-people-actually-use/
4 | /*
5 | // For Amazon.com
6 | "#navAmazonLogo", "#navSwmSkedPop",
7 | ".navbar", ".navGreeting",
8 | "div", "table",
9 | "img.navCrossshopTabCap", "span.navGreeting",
10 | "#navbar table", "#navidWelcomeMsg span",
11 | "div#navbar", "ul#navAmazonLogo",
12 | "#navAmazonLogo .navAmazonLogoGatewayPanel", "#navidWelcomeMsg .navGreeting",
13 | ".navbar .navAmazonLogoGatewayPanel", ".navbar .navGreeting",
14 | "*",
15 | "#navAmazonLogo li.navAmazonLogoGatewayPanel", "#navidWelcomeMsg span.navGreeting",
16 | "a[name=top]", "form[name=site-search]",
17 | ".navbar li", ".navbar span",
18 | "[name=top]", "[name=site-search]",
19 | "ul li", "a img",
20 | "#navbar #navidWelcomeMsg", "#navbar #navSwmDWPop",
21 | "#navbar ul li", "#navbar a img"
22 | */
23 | // For Yahoo.com
24 | "#page", "#masthead", "#mastheadhd",
25 | ".mastheadbd", ".first", ".on",
26 | "div", "li", "a",
27 | "div.mastheadbd", "li.first", "li.on",
28 | "#page div", "#dtba span",
29 | "div#page", "div#masthead",
30 | "#page .mastheadbd", "#page .first",
31 | ".outer_search_container .search_container", ".searchbox_container .inputtext",
32 | "*",
33 | "#page div.mastheadbd", "#page li.first",
34 | "input[name=p]", "a[name=marketplace]",
35 | ".outer_search_container div", ".searchbox_container span",
36 | "[name=p]", "[name=marketplace]",
37 | "ul li", "form input",
38 | "#page #e2econtent", "#page #e2e"
39 | ];
40 |
41 | jQuery.fn.benchmark = function() {
42 | this.each(function() {
43 | try {
44 | jQuery(this).parent().children("*:gt(1)").remove();
45 | } catch(e) { }
46 | })
47 | // set # times to run the test in index.html
48 | var times = parseInt(jQuery("#times").val());
49 | jQuery.benchmarker.startingList = this.get();
50 | benchmark(this.get(), times, jQuery.benchmarker.libraries);
51 | }
52 |
53 | jQuery(function() {
54 | for(i = 0; i < jQuery.benchmarker.tests.length; i++) {
55 | jQuery("tbody").append("
a";
11 |
12 | var all = div.getElementsByTagName("*"),
13 | a = div.getElementsByTagName("a")[0],
14 | select = document.createElement("select"),
15 | opt = select.appendChild( document.createElement("option") );
16 |
17 | // Can't get basic test support
18 | if ( !all || !all.length || !a ) {
19 | return;
20 | }
21 |
22 | jQuery.support = {
23 | // IE strips leading whitespace when .innerHTML is used
24 | leadingWhitespace: div.firstChild.nodeType === 3,
25 |
26 | // Make sure that tbody elements aren't automatically inserted
27 | // IE will insert them into empty tables
28 | tbody: !div.getElementsByTagName("tbody").length,
29 |
30 | // Make sure that link elements get serialized correctly by innerHTML
31 | // This requires a wrapper element in IE
32 | htmlSerialize: !!div.getElementsByTagName("link").length,
33 |
34 | // Get the style information from getAttribute
35 | // (IE uses .cssText insted)
36 | style: /red/.test( a.getAttribute("style") ),
37 |
38 | // Make sure that URLs aren't manipulated
39 | // (IE normalizes it by default)
40 | hrefNormalized: a.getAttribute("href") === "/a",
41 |
42 | // Make sure that element opacity exists
43 | // (IE uses filter instead)
44 | // Use a regex to work around a WebKit issue. See #5145
45 | opacity: /^0.55$/.test( a.style.opacity ),
46 |
47 | // Verify style float existence
48 | // (IE uses styleFloat instead of cssFloat)
49 | cssFloat: !!a.style.cssFloat,
50 |
51 | // Make sure that if no value is specified for a checkbox
52 | // that it defaults to "on".
53 | // (WebKit defaults to "" instead)
54 | checkOn: div.getElementsByTagName("input")[0].value === "on",
55 |
56 | // Make sure that a selected-by-default option has a working selected property.
57 | // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
58 | optSelected: opt.selected,
59 |
60 | // Will be defined later
61 | deleteExpando: true,
62 | optDisabled: false,
63 | checkClone: false,
64 | noCloneEvent: true,
65 | boxModel: null,
66 | inlineBlockNeedsLayout: false,
67 | shrinkWrapBlocks: false,
68 | reliableHiddenOffsets: true
69 | };
70 |
71 | // Make sure that the options inside disabled selects aren't marked as disabled
72 | // (WebKit marks them as diabled)
73 | select.disabled = true;
74 | jQuery.support.optDisabled = !opt.disabled;
75 |
76 | var _scriptEval = null;
77 | jQuery.support.scriptEval = function() {
78 | if ( _scriptEval === null ) {
79 | var root = document.documentElement,
80 | script = document.createElement("script"),
81 | id = "script" + jQuery.now();
82 |
83 | try {
84 | script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
85 | } catch(e) {}
86 |
87 | root.insertBefore( script, root.firstChild );
88 |
89 | // Make sure that the execution of code works by injecting a script
90 | // tag with appendChild/createTextNode
91 | // (IE doesn't support this, fails, and uses .text instead)
92 | if ( window[ id ] ) {
93 | _scriptEval = true;
94 | delete window[ id ];
95 | } else {
96 | _scriptEval = false;
97 | }
98 |
99 | root.removeChild( script );
100 | // release memory in IE
101 | root = script = id = null;
102 | }
103 |
104 | return _scriptEval;
105 | };
106 |
107 | // Test to see if it's possible to delete an expando from an element
108 | // Fails in Internet Explorer
109 | try {
110 | delete div.test;
111 |
112 | } catch(e) {
113 | jQuery.support.deleteExpando = false;
114 | }
115 |
116 | if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
117 | div.attachEvent("onclick", function click() {
118 | // Cloning a node shouldn't copy over any
119 | // bound event handlers (IE does this)
120 | jQuery.support.noCloneEvent = false;
121 | div.detachEvent("onclick", click);
122 | });
123 | div.cloneNode(true).fireEvent("onclick");
124 | }
125 |
126 | div = document.createElement("div");
127 | div.innerHTML = "";
128 |
129 | var fragment = document.createDocumentFragment();
130 | fragment.appendChild( div.firstChild );
131 |
132 | // WebKit doesn't clone checked state correctly in fragments
133 | jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
134 |
135 | // Figure out if the W3C box model works as expected
136 | // document.body must exist before we can do this
137 | jQuery(function() {
138 | var div = document.createElement("div"),
139 | body = document.getElementsByTagName("body")[0];
140 |
141 | // Frameset documents with no body should not run this code
142 | if ( !body ) {
143 | return;
144 | }
145 |
146 | div.style.width = div.style.paddingLeft = "1px";
147 | body.appendChild( div );
148 | jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
149 |
150 | if ( "zoom" in div.style ) {
151 | // Check if natively block-level elements act like inline-block
152 | // elements when setting their display to 'inline' and giving
153 | // them layout
154 | // (IE < 8 does this)
155 | div.style.display = "inline";
156 | div.style.zoom = 1;
157 | jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
158 |
159 | // Check if elements with layout shrink-wrap their children
160 | // (IE 6 does this)
161 | div.style.display = "";
162 | div.innerHTML = "";
163 | jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
164 | }
165 |
166 | div.innerHTML = "
t
";
167 | var tds = div.getElementsByTagName("td");
168 |
169 | // Check if table cells still have offsetWidth/Height when they are set
170 | // to display:none and there are still other visible table cells in a
171 | // table row; if so, offsetWidth/Height are not reliable for use when
172 | // determining if an element has been hidden directly using
173 | // display:none (it is still safe to use offsets if a parent element is
174 | // hidden; don safety goggles and see bug #4512 for more information).
175 | // (only IE 8 fails this test)
176 | jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
177 |
178 | tds[0].style.display = "";
179 | tds[1].style.display = "none";
180 |
181 | // Check if empty table cells still have offsetWidth/Height
182 | // (IE < 8 fail this test)
183 | jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
184 | div.innerHTML = "";
185 |
186 | body.removeChild( div ).style.display = "none";
187 | div = tds = null;
188 | });
189 |
190 | // Technique from Juriy Zaytsev
191 | // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
192 | var eventSupported = function( eventName ) {
193 | var el = document.createElement("div");
194 | eventName = "on" + eventName;
195 |
196 | // We only care about the case where non-standard event systems
197 | // are used, namely in IE. Short-circuiting here helps us to
198 | // avoid an eval call (in setAttribute) which can cause CSP
199 | // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
200 | if ( !el.attachEvent ) {
201 | return true;
202 | }
203 |
204 | var isSupported = (eventName in el);
205 | if ( !isSupported ) {
206 | el.setAttribute(eventName, "return;");
207 | isSupported = typeof el[eventName] === "function";
208 | }
209 | el = null;
210 |
211 | return isSupported;
212 | };
213 |
214 | jQuery.support.submitBubbles = eventSupported("submit");
215 | jQuery.support.changeBubbles = eventSupported("change");
216 |
217 | // release memory in IE
218 | div = all = a = null;
219 | })();
220 | })( jQuery );
221 |
--------------------------------------------------------------------------------
/test/delegatetest.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
Change Tests
13 |
14 |
15 |
16 | Change each:
17 |
18 |
19 |
24 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
$(document).bind('change')
65 |
66 |
67 |
Live:
68 |
SELECT
69 |
MULTI
70 |
CHECKBOX
71 |
RADIO
72 |
FILE
73 |
TEXT
74 |
TEXTAREA
75 |
DOCUMENT
76 |
77 |
78 |
Bind:
79 |
SELECT
80 |
MULTI
81 |
CHECKBOX
82 |
RADIO
83 |
FILE
84 |
TEXT
85 |
TEXTAREA
86 |
87 |
88 |
Focusin:
89 |
SELECT
90 |
MULTI
91 |
CHECKBOX
92 |
RADIO
93 |
FILE
94 |
TEXT
95 |
TEXTAREA
96 |
DOCUMENT
97 |
98 |
99 |
Focusout:
100 |
SELECT
101 |
MULTI
102 |
CHECKBOX
103 |
RADIO
104 |
FILE
105 |
TEXT
106 |
TEXTAREA
107 |
DOCUMENT
108 |
109 |
110 |
Live Focus:
111 |
SELECT
112 |
MULTI
113 |
CHECKBOX
114 |
RADIO
115 |
FILE
116 |
TEXT
117 |
TEXTAREA
118 |
119 |
120 |
Live Blur:
121 |
SELECT
122 |
MULTI
123 |
CHECKBOX
124 |
RADIO
125 |
FILE
126 |
TEXT
127 |
TEXTAREA
128 |
129 |
130 |
Submit Tests
131 |
132 |
133 |
134 | Submit each:
135 |
136 |
137 |
140 |
141 |
142 |
145 |
146 |
147 |
150 |
151 |
$(document).bind('submit')
152 |
153 |
154 |
Results:
155 |
TEXT
156 |
PASSWORD
157 |
BUTTON
158 |
DOCUMENT
159 |
160 |
161 |
162 |
163 |
164 |
241 |
242 |
243 |
--------------------------------------------------------------------------------
/src/traversing.js:
--------------------------------------------------------------------------------
1 | (function( jQuery ) {
2 |
3 | var runtil = /Until$/,
4 | rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5 | // Note: This RegExp should be improved, or likely pulled from Sizzle
6 | rmultiselector = /,/,
7 | isSimple = /^.[^:#\[\.,]*$/,
8 | slice = Array.prototype.slice,
9 | POS = jQuery.expr.match.POS,
10 | // methods guaranteed to produce a unique set when starting from a unique set
11 | guaranteedUnique = {
12 | children: true,
13 | contents: true,
14 | next: true,
15 | prev: true
16 | };
17 |
18 | jQuery.fn.extend({
19 | find: function( selector ) {
20 | var ret = this.pushStack( "", "find", selector ),
21 | length = 0;
22 |
23 | for ( var i = 0, l = this.length; i < l; i++ ) {
24 | length = ret.length;
25 | jQuery.find( selector, this[i], ret );
26 |
27 | if ( i > 0 ) {
28 | // Make sure that the results are unique
29 | for ( var n = length; n < ret.length; n++ ) {
30 | for ( var r = 0; r < length; r++ ) {
31 | if ( ret[r] === ret[n] ) {
32 | ret.splice(n--, 1);
33 | break;
34 | }
35 | }
36 | }
37 | }
38 | }
39 |
40 | return ret;
41 | },
42 |
43 | has: function( target ) {
44 | var targets = jQuery( target );
45 | return this.filter(function() {
46 | for ( var i = 0, l = targets.length; i < l; i++ ) {
47 | if ( jQuery.contains( this, targets[i] ) ) {
48 | return true;
49 | }
50 | }
51 | });
52 | },
53 |
54 | not: function( selector ) {
55 | return this.pushStack( winnow(this, selector, false), "not", selector);
56 | },
57 |
58 | filter: function( selector ) {
59 | return this.pushStack( winnow(this, selector, true), "filter", selector );
60 | },
61 |
62 | is: function( selector ) {
63 | return !!selector && jQuery.filter( selector, this ).length > 0;
64 | },
65 |
66 | closest: function( selectors, context ) {
67 | var ret = [], i, l, cur = this[0];
68 |
69 | if ( jQuery.isArray( selectors ) ) {
70 | var match, selector,
71 | matches = {},
72 | level = 1;
73 |
74 | if ( cur && selectors.length ) {
75 | for ( i = 0, l = selectors.length; i < l; i++ ) {
76 | selector = selectors[i];
77 |
78 | if ( !matches[selector] ) {
79 | matches[selector] = jQuery.expr.match.POS.test( selector ) ?
80 | jQuery( selector, context || this.context ) :
81 | selector;
82 | }
83 | }
84 |
85 | while ( cur && cur.ownerDocument && cur !== context ) {
86 | for ( selector in matches ) {
87 | match = matches[selector];
88 |
89 | if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
90 | ret.push({ selector: selector, elem: cur, level: level });
91 | }
92 | }
93 |
94 | cur = cur.parentNode;
95 | level++;
96 | }
97 | }
98 |
99 | return ret;
100 | }
101 |
102 | var pos = POS.test( selectors ) ?
103 | jQuery( selectors, context || this.context ) : null;
104 |
105 | for ( i = 0, l = this.length; i < l; i++ ) {
106 | cur = this[i];
107 |
108 | while ( cur ) {
109 | if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
110 | ret.push( cur );
111 | break;
112 |
113 | } else {
114 | cur = cur.parentNode;
115 | if ( !cur || !cur.ownerDocument || cur === context ) {
116 | break;
117 | }
118 | }
119 | }
120 | }
121 |
122 | ret = ret.length > 1 ? jQuery.unique(ret) : ret;
123 |
124 | return this.pushStack( ret, "closest", selectors );
125 | },
126 |
127 | // Determine the position of an element within
128 | // the matched set of elements
129 | index: function( elem ) {
130 | if ( !elem || typeof elem === "string" ) {
131 | return jQuery.inArray( this[0],
132 | // If it receives a string, the selector is used
133 | // If it receives nothing, the siblings are used
134 | elem ? jQuery( elem ) : this.parent().children() );
135 | }
136 | // Locate the position of the desired element
137 | return jQuery.inArray(
138 | // If it receives a jQuery object, the first element is used
139 | elem.jquery ? elem[0] : elem, this );
140 | },
141 |
142 | add: function( selector, context ) {
143 | var set = typeof selector === "string" ?
144 | jQuery( selector, context ) :
145 | jQuery.makeArray( selector ),
146 | all = jQuery.merge( this.get(), set );
147 |
148 | return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
149 | all :
150 | jQuery.unique( all ) );
151 | },
152 |
153 | andSelf: function() {
154 | return this.add( this.prevObject );
155 | }
156 | });
157 |
158 | // A painfully simple check to see if an element is disconnected
159 | // from a document (should be improved, where feasible).
160 | function isDisconnected( node ) {
161 | return !node || !node.parentNode || node.parentNode.nodeType === 11;
162 | }
163 |
164 | jQuery.each({
165 | parent: function( elem ) {
166 | var parent = elem.parentNode;
167 | return parent && parent.nodeType !== 11 ? parent : null;
168 | },
169 | parents: function( elem ) {
170 | return jQuery.dir( elem, "parentNode" );
171 | },
172 | parentsUntil: function( elem, i, until ) {
173 | return jQuery.dir( elem, "parentNode", until );
174 | },
175 | next: function( elem ) {
176 | return jQuery.nth( elem, 2, "nextSibling" );
177 | },
178 | prev: function( elem ) {
179 | return jQuery.nth( elem, 2, "previousSibling" );
180 | },
181 | nextAll: function( elem ) {
182 | return jQuery.dir( elem, "nextSibling" );
183 | },
184 | prevAll: function( elem ) {
185 | return jQuery.dir( elem, "previousSibling" );
186 | },
187 | nextUntil: function( elem, i, until ) {
188 | return jQuery.dir( elem, "nextSibling", until );
189 | },
190 | prevUntil: function( elem, i, until ) {
191 | return jQuery.dir( elem, "previousSibling", until );
192 | },
193 | siblings: function( elem ) {
194 | return jQuery.sibling( elem.parentNode.firstChild, elem );
195 | },
196 | children: function( elem ) {
197 | return jQuery.sibling( elem.firstChild );
198 | },
199 | contents: function( elem ) {
200 | return jQuery.nodeName( elem, "iframe" ) ?
201 | elem.contentDocument || elem.contentWindow.document :
202 | jQuery.makeArray( elem.childNodes );
203 | }
204 | }, function( name, fn ) {
205 | jQuery.fn[ name ] = function( until, selector ) {
206 | var ret = jQuery.map( this, fn, until ),
207 | // The variable 'args' was introduced in
208 | // https://github.com/jquery/jquery/commit/52a0238
209 | // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
210 | // http://code.google.com/p/v8/issues/detail?id=1050
211 | args = slice.call(arguments);
212 |
213 | if ( !runtil.test( name ) ) {
214 | selector = until;
215 | }
216 |
217 | if ( selector && typeof selector === "string" ) {
218 | ret = jQuery.filter( selector, ret );
219 | }
220 |
221 | ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
222 |
223 | if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
224 | ret = ret.reverse();
225 | }
226 |
227 | return this.pushStack( ret, name, args.join(",") );
228 | };
229 | });
230 |
231 | jQuery.extend({
232 | filter: function( expr, elems, not ) {
233 | if ( not ) {
234 | expr = ":not(" + expr + ")";
235 | }
236 |
237 | return elems.length === 1 ?
238 | jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
239 | jQuery.find.matches(expr, elems);
240 | },
241 |
242 | dir: function( elem, dir, until ) {
243 | var matched = [],
244 | cur = elem[ dir ];
245 |
246 | while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
247 | if ( cur.nodeType === 1 ) {
248 | matched.push( cur );
249 | }
250 | cur = cur[dir];
251 | }
252 | return matched;
253 | },
254 |
255 | nth: function( cur, result, dir, elem ) {
256 | result = result || 1;
257 | var num = 0;
258 |
259 | for ( ; cur; cur = cur[dir] ) {
260 | if ( cur.nodeType === 1 && ++num === result ) {
261 | break;
262 | }
263 | }
264 |
265 | return cur;
266 | },
267 |
268 | sibling: function( n, elem ) {
269 | var r = [];
270 |
271 | for ( ; n; n = n.nextSibling ) {
272 | if ( n.nodeType === 1 && n !== elem ) {
273 | r.push( n );
274 | }
275 | }
276 |
277 | return r;
278 | }
279 | });
280 |
281 | // Implement the identical functionality for filter and not
282 | function winnow( elements, qualifier, keep ) {
283 | if ( jQuery.isFunction( qualifier ) ) {
284 | return jQuery.grep(elements, function( elem, i ) {
285 | var retVal = !!qualifier.call( elem, i, elem );
286 | return retVal === keep;
287 | });
288 |
289 | } else if ( qualifier.nodeType ) {
290 | return jQuery.grep(elements, function( elem, i ) {
291 | return (elem === qualifier) === keep;
292 | });
293 |
294 | } else if ( typeof qualifier === "string" ) {
295 | var filtered = jQuery.grep(elements, function( elem ) {
296 | return elem.nodeType === 1;
297 | });
298 |
299 | if ( isSimple.test( qualifier ) ) {
300 | return jQuery.filter(qualifier, filtered, !keep);
301 | } else {
302 | qualifier = jQuery.filter( qualifier, filtered );
303 | }
304 | }
305 |
306 | return jQuery.grep(elements, function( elem, i ) {
307 | return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
308 | });
309 | }
310 |
311 | })( jQuery );
312 |
--------------------------------------------------------------------------------
/src/data.js:
--------------------------------------------------------------------------------
1 | (function( jQuery ) {
2 |
3 | var rbrace = /^(?:\{.*\}|\[.*\])$/;
4 |
5 | jQuery.extend({
6 | cache: {},
7 |
8 | // Please use with caution
9 | uuid: 0,
10 |
11 | // Unique for each copy of jQuery on the page
12 | // Non-digits removed to match rinlinejQuery
13 | expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
14 |
15 | // The following elements throw uncatchable exceptions if you
16 | // attempt to add expando properties to them.
17 | noData: {
18 | "embed": true,
19 | // Ban all objects except for Flash (which handle expandos)
20 | "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
21 | "applet": true
22 | },
23 |
24 | hasData: function( elem ) {
25 | elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
26 |
27 | return !!elem && !isEmptyDataObject( elem );
28 | },
29 |
30 | data: function( elem, name, data, pvt /* Internal Use Only */ ) {
31 | if ( !jQuery.acceptData( elem ) ) {
32 | return;
33 | }
34 |
35 | var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
36 |
37 | // We have to handle DOM nodes and JS objects differently because IE6-7
38 | // can't GC object references properly across the DOM-JS boundary
39 | isNode = elem.nodeType,
40 |
41 | // Only DOM nodes need the global jQuery cache; JS object data is
42 | // attached directly to the object so GC can occur automatically
43 | cache = isNode ? jQuery.cache : elem,
44 |
45 | // Only defining an ID for JS objects if its cache already exists allows
46 | // the code to shortcut on the same path as a DOM node with no cache
47 | id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
48 |
49 | // Avoid doing any more work than we need to when trying to get data on an
50 | // object that has no data at all
51 | if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
52 | return;
53 | }
54 |
55 | if ( !id ) {
56 | // Only DOM nodes need a new unique ID for each element since their data
57 | // ends up in the global cache
58 | if ( isNode ) {
59 | elem[ jQuery.expando ] = id = ++jQuery.uuid;
60 | } else {
61 | id = jQuery.expando;
62 | }
63 | }
64 |
65 | if ( !cache[ id ] ) {
66 | cache[ id ] = {};
67 |
68 | // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
69 | // metadata on plain JS objects when the object is serialized using
70 | // JSON.stringify
71 | if ( !isNode ) {
72 | cache[ id ].toJSON = jQuery.noop;
73 | }
74 | }
75 |
76 | // An object can be passed to jQuery.data instead of a key/value pair; this gets
77 | // shallow copied over onto the existing cache
78 | if ( typeof name === "object" || typeof name === "function" ) {
79 | if ( pvt ) {
80 | cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
81 | } else {
82 | cache[ id ] = jQuery.extend(cache[ id ], name);
83 | }
84 | }
85 |
86 | thisCache = cache[ id ];
87 |
88 | // Internal jQuery data is stored in a separate object inside the object's data
89 | // cache in order to avoid key collisions between internal data and user-defined
90 | // data
91 | if ( pvt ) {
92 | if ( !thisCache[ internalKey ] ) {
93 | thisCache[ internalKey ] = {};
94 | }
95 |
96 | thisCache = thisCache[ internalKey ];
97 | }
98 |
99 | if ( data !== undefined ) {
100 | thisCache[ name ] = data;
101 | }
102 |
103 | // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
104 | // not attempt to inspect the internal events object using jQuery.data, as this
105 | // internal data object is undocumented and subject to change.
106 | if ( name === "events" && !thisCache[name] ) {
107 | return thisCache[ internalKey ] && thisCache[ internalKey ].events;
108 | }
109 |
110 | return getByName ? thisCache[ name ] : thisCache;
111 | },
112 |
113 | removeData: function( elem, name, pvt /* Internal Use Only */ ) {
114 | if ( !jQuery.acceptData( elem ) ) {
115 | return;
116 | }
117 |
118 | var internalKey = jQuery.expando, isNode = elem.nodeType,
119 |
120 | // See jQuery.data for more information
121 | cache = isNode ? jQuery.cache : elem,
122 |
123 | // See jQuery.data for more information
124 | id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
125 |
126 | // If there is already no cache entry for this object, there is no
127 | // purpose in continuing
128 | if ( !cache[ id ] ) {
129 | return;
130 | }
131 |
132 | if ( name ) {
133 | var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
134 |
135 | if ( thisCache ) {
136 | delete thisCache[ name ];
137 |
138 | // If there is no data left in the cache, we want to continue
139 | // and let the cache object itself get destroyed
140 | if ( !isEmptyDataObject(thisCache) ) {
141 | return;
142 | }
143 | }
144 | }
145 |
146 | // See jQuery.data for more information
147 | if ( pvt ) {
148 | delete cache[ id ][ internalKey ];
149 |
150 | // Don't destroy the parent cache unless the internal data object
151 | // had been the only thing left in it
152 | if ( !isEmptyDataObject(cache[ id ]) ) {
153 | return;
154 | }
155 | }
156 |
157 | var internalCache = cache[ id ][ internalKey ];
158 |
159 | // Browsers that fail expando deletion also refuse to delete expandos on
160 | // the window, but it will allow it on all other JS objects; other browsers
161 | // don't care
162 | if ( jQuery.support.deleteExpando || cache != window ) {
163 | delete cache[ id ];
164 | } else {
165 | cache[ id ] = null;
166 | }
167 |
168 | // We destroyed the entire user cache at once because it's faster than
169 | // iterating through each key, but we need to continue to persist internal
170 | // data if it existed
171 | if ( internalCache ) {
172 | cache[ id ] = {};
173 | // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
174 | // metadata on plain JS objects when the object is serialized using
175 | // JSON.stringify
176 | if ( !isNode ) {
177 | cache[ id ].toJSON = jQuery.noop;
178 | }
179 |
180 | cache[ id ][ internalKey ] = internalCache;
181 |
182 | // Otherwise, we need to eliminate the expando on the node to avoid
183 | // false lookups in the cache for entries that no longer exist
184 | } else if ( isNode ) {
185 | // IE does not allow us to delete expando properties from nodes,
186 | // nor does it have a removeAttribute function on Document nodes;
187 | // we must handle all of these cases
188 | if ( jQuery.support.deleteExpando ) {
189 | delete elem[ jQuery.expando ];
190 | } else if ( elem.removeAttribute ) {
191 | elem.removeAttribute( jQuery.expando );
192 | } else {
193 | elem[ jQuery.expando ] = null;
194 | }
195 | }
196 | },
197 |
198 | // For internal use only.
199 | _data: function( elem, name, data ) {
200 | return jQuery.data( elem, name, data, true );
201 | },
202 |
203 | // A method for determining if a DOM node can handle the data expando
204 | acceptData: function( elem ) {
205 | if ( elem.nodeName ) {
206 | var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
207 |
208 | if ( match ) {
209 | return !(match === true || elem.getAttribute("classid") !== match);
210 | }
211 | }
212 |
213 | return true;
214 | }
215 | });
216 |
217 | jQuery.fn.extend({
218 | data: function( key, value ) {
219 | var data = null;
220 |
221 | if ( typeof key === "undefined" ) {
222 | if ( this.length ) {
223 | data = jQuery.data( this[0] );
224 |
225 | if ( this[0].nodeType === 1 ) {
226 | var attr = this[0].attributes, name;
227 | for ( var i = 0, l = attr.length; i < l; i++ ) {
228 | name = attr[i].name;
229 |
230 | if ( name.indexOf( "data-" ) === 0 ) {
231 | name = name.substr( 5 );
232 | dataAttr( this[0], name, data[ name ] );
233 | }
234 | }
235 | }
236 | }
237 |
238 | return data;
239 |
240 | } else if ( typeof key === "object" ) {
241 | return this.each(function() {
242 | jQuery.data( this, key );
243 | });
244 | }
245 |
246 | var parts = key.split(".");
247 | parts[1] = parts[1] ? "." + parts[1] : "";
248 |
249 | if ( value === undefined ) {
250 | data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
251 |
252 | // Try to fetch any internally stored data first
253 | if ( data === undefined && this.length ) {
254 | data = jQuery.data( this[0], key );
255 | data = dataAttr( this[0], key, data );
256 | }
257 |
258 | return data === undefined && parts[1] ?
259 | this.data( parts[0] ) :
260 | data;
261 |
262 | } else {
263 | return this.each(function() {
264 | var $this = jQuery( this ),
265 | args = [ parts[0], value ];
266 |
267 | $this.triggerHandler( "setData" + parts[1] + "!", args );
268 | jQuery.data( this, key, value );
269 | $this.triggerHandler( "changeData" + parts[1] + "!", args );
270 | });
271 | }
272 | },
273 |
274 | removeData: function( key ) {
275 | return this.each(function() {
276 | jQuery.removeData( this, key );
277 | });
278 | }
279 | });
280 |
281 | function dataAttr( elem, key, data ) {
282 | // If nothing was found internally, try to fetch any
283 | // data from the HTML5 data-* attribute
284 | if ( data === undefined && elem.nodeType === 1 ) {
285 | data = elem.getAttribute( "data-" + key );
286 |
287 | if ( typeof data === "string" ) {
288 | try {
289 | data = data === "true" ? true :
290 | data === "false" ? false :
291 | data === "null" ? null :
292 | !jQuery.isNaN( data ) ? parseFloat( data ) :
293 | rbrace.test( data ) ? jQuery.parseJSON( data ) :
294 | data;
295 | } catch( e ) {}
296 |
297 | // Make sure we set the data so it isn't changed later
298 | jQuery.data( elem, key, data );
299 |
300 | } else {
301 | data = undefined;
302 | }
303 | }
304 |
305 | return data;
306 | }
307 |
308 | // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
309 | // property to be considered empty objects; this property always exists in
310 | // order to make sure JSON.stringify does not expose internal metadata
311 | function isEmptyDataObject( obj ) {
312 | for ( var name in obj ) {
313 | if ( name !== "toJSON" ) {
314 | return false;
315 | }
316 | }
317 |
318 | return true;
319 | }
320 |
321 | })( jQuery );
322 |
--------------------------------------------------------------------------------
/src/css.js:
--------------------------------------------------------------------------------
1 | (function( jQuery ) {
2 |
3 | var ralpha = /alpha\([^)]*\)/i,
4 | ropacity = /opacity=([^)]*)/,
5 | rdashAlpha = /-([a-z])/ig,
6 | rupper = /([A-Z])/g,
7 | rnumpx = /^-?\d+(?:px)?$/i,
8 | rnum = /^-?\d/,
9 |
10 | cssShow = { position: "absolute", visibility: "hidden", display: "block" },
11 | cssWidth = [ "Left", "Right" ],
12 | cssHeight = [ "Top", "Bottom" ],
13 | curCSS,
14 |
15 | getComputedStyle,
16 | currentStyle,
17 |
18 | fcamelCase = function( all, letter ) {
19 | return letter.toUpperCase();
20 | };
21 |
22 | jQuery.fn.css = function( name, value ) {
23 | // Setting 'undefined' is a no-op
24 | if ( arguments.length === 2 && value === undefined ) {
25 | return this;
26 | }
27 |
28 | return jQuery.access( this, name, value, true, function( elem, name, value ) {
29 | return value !== undefined ?
30 | jQuery.style( elem, name, value ) :
31 | jQuery.css( elem, name );
32 | });
33 | };
34 |
35 | jQuery.extend({
36 | // Add in style property hooks for overriding the default
37 | // behavior of getting and setting a style property
38 | cssHooks: {
39 | opacity: {
40 | get: function( elem, computed ) {
41 | if ( computed ) {
42 | // We should always get a number back from opacity
43 | var ret = curCSS( elem, "opacity", "opacity" );
44 | return ret === "" ? "1" : ret;
45 |
46 | } else {
47 | return elem.style.opacity;
48 | }
49 | }
50 | }
51 | },
52 |
53 | // Exclude the following css properties to add px
54 | cssNumber: {
55 | "zIndex": true,
56 | "fontWeight": true,
57 | "opacity": true,
58 | "zoom": true,
59 | "lineHeight": true
60 | },
61 |
62 | // Add in properties whose names you wish to fix before
63 | // setting or getting the value
64 | cssProps: {
65 | // normalize float css property
66 | "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
67 | },
68 |
69 | // Get and set the style property on a DOM Node
70 | style: function( elem, name, value, extra ) {
71 | // Don't set styles on text and comment nodes
72 | if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
73 | return;
74 | }
75 |
76 | // Make sure that we're working with the right name
77 | var ret, origName = jQuery.camelCase( name ),
78 | style = elem.style, hooks = jQuery.cssHooks[ origName ];
79 |
80 | name = jQuery.cssProps[ origName ] || origName;
81 |
82 | // Check if we're setting a value
83 | if ( value !== undefined ) {
84 | // Make sure that NaN and null values aren't set. See: #7116
85 | if ( typeof value === "number" && isNaN( value ) || value == null ) {
86 | return;
87 | }
88 |
89 | // If a number was passed in, add 'px' to the (except for certain CSS properties)
90 | if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
91 | value += "px";
92 | }
93 |
94 | // If a hook was provided, use that value, otherwise just set the specified value
95 | if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
96 | // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
97 | // Fixes bug #5509
98 | try {
99 | style[ name ] = value;
100 | } catch(e) {}
101 | }
102 |
103 | } else {
104 | // If a hook was provided get the non-computed value from there
105 | if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
106 | return ret;
107 | }
108 |
109 | // Otherwise just get the value from the style object
110 | return style[ name ];
111 | }
112 | },
113 |
114 | css: function( elem, name, extra ) {
115 | // Make sure that we're working with the right name
116 | var ret, origName = jQuery.camelCase( name ),
117 | hooks = jQuery.cssHooks[ origName ];
118 |
119 | name = jQuery.cssProps[ origName ] || origName;
120 |
121 | // If a hook was provided get the computed value from there
122 | if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
123 | return ret;
124 |
125 | // Otherwise, if a way to get the computed value exists, use that
126 | } else if ( curCSS ) {
127 | return curCSS( elem, name, origName );
128 | }
129 | },
130 |
131 | // A method for quickly swapping in/out CSS properties to get correct calculations
132 | swap: function( elem, options, callback ) {
133 | var old = {};
134 |
135 | // Remember the old values, and insert the new ones
136 | for ( var name in options ) {
137 | old[ name ] = elem.style[ name ];
138 | elem.style[ name ] = options[ name ];
139 | }
140 |
141 | callback.call( elem );
142 |
143 | // Revert the old values
144 | for ( name in options ) {
145 | elem.style[ name ] = old[ name ];
146 | }
147 | },
148 |
149 | camelCase: function( string ) {
150 | return string.replace( rdashAlpha, fcamelCase );
151 | }
152 | });
153 |
154 | // DEPRECATED, Use jQuery.css() instead
155 | jQuery.curCSS = jQuery.css;
156 |
157 | jQuery.each(["height", "width"], function( i, name ) {
158 | jQuery.cssHooks[ name ] = {
159 | get: function( elem, computed, extra ) {
160 | var val;
161 |
162 | if ( computed ) {
163 | if ( elem.offsetWidth !== 0 ) {
164 | val = getWH( elem, name, extra );
165 |
166 | } else {
167 | jQuery.swap( elem, cssShow, function() {
168 | val = getWH( elem, name, extra );
169 | });
170 | }
171 |
172 | if ( val <= 0 ) {
173 | val = curCSS( elem, name, name );
174 |
175 | if ( val === "0px" && currentStyle ) {
176 | val = currentStyle( elem, name, name );
177 | }
178 |
179 | if ( val != null ) {
180 | // Should return "auto" instead of 0, use 0 for
181 | // temporary backwards-compat
182 | return val === "" || val === "auto" ? "0px" : val;
183 | }
184 | }
185 |
186 | if ( val < 0 || val == null ) {
187 | val = elem.style[ name ];
188 |
189 | // Should return "auto" instead of 0, use 0 for
190 | // temporary backwards-compat
191 | return val === "" || val === "auto" ? "0px" : val;
192 | }
193 |
194 | return typeof val === "string" ? val : val + "px";
195 | }
196 | },
197 |
198 | set: function( elem, value ) {
199 | if ( rnumpx.test( value ) ) {
200 | // ignore negative width and height values #1599
201 | value = parseFloat(value);
202 |
203 | if ( value >= 0 ) {
204 | return value + "px";
205 | }
206 |
207 | } else {
208 | return value;
209 | }
210 | }
211 | };
212 | });
213 |
214 | if ( !jQuery.support.opacity ) {
215 | jQuery.cssHooks.opacity = {
216 | get: function( elem, computed ) {
217 | // IE uses filters for opacity
218 | return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
219 | (parseFloat(RegExp.$1) / 100) + "" :
220 | computed ? "1" : "";
221 | },
222 |
223 | set: function( elem, value ) {
224 | var style = elem.style;
225 |
226 | // IE has trouble with opacity if it does not have layout
227 | // Force it by setting the zoom level
228 | style.zoom = 1;
229 |
230 | // Set the alpha filter to set the opacity
231 | var opacity = jQuery.isNaN(value) ?
232 | "" :
233 | "alpha(opacity=" + value * 100 + ")",
234 | filter = style.filter || "";
235 |
236 | style.filter = ralpha.test(filter) ?
237 | filter.replace(ralpha, opacity) :
238 | style.filter + ' ' + opacity;
239 | }
240 | };
241 | }
242 |
243 | if ( document.defaultView && document.defaultView.getComputedStyle ) {
244 | getComputedStyle = function( elem, newName, name ) {
245 | var ret, defaultView, computedStyle;
246 |
247 | name = name.replace( rupper, "-$1" ).toLowerCase();
248 |
249 | if ( !(defaultView = elem.ownerDocument.defaultView) ) {
250 | return undefined;
251 | }
252 |
253 | if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
254 | ret = computedStyle.getPropertyValue( name );
255 | if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
256 | ret = jQuery.style( elem, name );
257 | }
258 | }
259 |
260 | return ret;
261 | };
262 | }
263 |
264 | if ( document.documentElement.currentStyle ) {
265 | currentStyle = function( elem, name ) {
266 | var left,
267 | ret = elem.currentStyle && elem.currentStyle[ name ],
268 | rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
269 | style = elem.style;
270 |
271 | // From the awesome hack by Dean Edwards
272 | // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
273 |
274 | // If we're not dealing with a regular pixel number
275 | // but a number that has a weird ending, we need to convert it to pixels
276 | if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
277 | // Remember the original values
278 | left = style.left;
279 |
280 | // Put in the new values to get a computed value out
281 | if ( rsLeft ) {
282 | elem.runtimeStyle.left = elem.currentStyle.left;
283 | }
284 | style.left = name === "fontSize" ? "1em" : (ret || 0);
285 | ret = style.pixelLeft + "px";
286 |
287 | // Revert the changed values
288 | style.left = left;
289 | if ( rsLeft ) {
290 | elem.runtimeStyle.left = rsLeft;
291 | }
292 | }
293 |
294 | return ret === "" ? "auto" : ret;
295 | };
296 | }
297 |
298 | curCSS = getComputedStyle || currentStyle;
299 |
300 | function getWH( elem, name, extra ) {
301 | var which = name === "width" ? cssWidth : cssHeight,
302 | val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
303 |
304 | if ( extra === "border" ) {
305 | return val;
306 | }
307 |
308 | jQuery.each( which, function() {
309 | if ( !extra ) {
310 | val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
311 | }
312 |
313 | if ( extra === "margin" ) {
314 | val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
315 |
316 | } else {
317 | val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
318 | }
319 | });
320 |
321 | return val;
322 | }
323 |
324 | if ( jQuery.expr && jQuery.expr.filters ) {
325 | jQuery.expr.filters.hidden = function( elem ) {
326 | var width = elem.offsetWidth,
327 | height = elem.offsetHeight;
328 |
329 | return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
330 | };
331 |
332 | jQuery.expr.filters.visible = function( elem ) {
333 | return !jQuery.expr.filters.hidden( elem );
334 | };
335 | }
336 |
337 | })( jQuery );
338 |
--------------------------------------------------------------------------------
/src/offset.js:
--------------------------------------------------------------------------------
1 | (function( jQuery ) {
2 |
3 | var rtable = /^t(?:able|d|h)$/i,
4 | rroot = /^(?:body|html)$/i;
5 |
6 | if ( "getBoundingClientRect" in document.documentElement ) {
7 | jQuery.fn.offset = function( options ) {
8 | var elem = this[0], box;
9 |
10 | if ( options ) {
11 | return this.each(function( i ) {
12 | jQuery.offset.setOffset( this, options, i );
13 | });
14 | }
15 |
16 | if ( !elem || !elem.ownerDocument ) {
17 | return null;
18 | }
19 |
20 | if ( elem === elem.ownerDocument.body ) {
21 | return jQuery.offset.bodyOffset( elem );
22 | }
23 |
24 | try {
25 | box = elem.getBoundingClientRect();
26 | } catch(e) {}
27 |
28 | var doc = elem.ownerDocument,
29 | docElem = doc.documentElement;
30 |
31 | // Make sure we're not dealing with a disconnected DOM node
32 | if ( !box || !jQuery.contains( docElem, elem ) ) {
33 | return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
34 | }
35 |
36 | var body = doc.body,
37 | win = getWindow(doc),
38 | clientTop = docElem.clientTop || body.clientTop || 0,
39 | clientLeft = docElem.clientLeft || body.clientLeft || 0,
40 | scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
41 | scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
42 | top = box.top + scrollTop - clientTop,
43 | left = box.left + scrollLeft - clientLeft;
44 |
45 | return { top: top, left: left };
46 | };
47 |
48 | } else {
49 | jQuery.fn.offset = function( options ) {
50 | var elem = this[0];
51 |
52 | if ( options ) {
53 | return this.each(function( i ) {
54 | jQuery.offset.setOffset( this, options, i );
55 | });
56 | }
57 |
58 | if ( !elem || !elem.ownerDocument ) {
59 | return null;
60 | }
61 |
62 | if ( elem === elem.ownerDocument.body ) {
63 | return jQuery.offset.bodyOffset( elem );
64 | }
65 |
66 | jQuery.offset.initialize();
67 |
68 | var computedStyle,
69 | offsetParent = elem.offsetParent,
70 | prevOffsetParent = elem,
71 | doc = elem.ownerDocument,
72 | docElem = doc.documentElement,
73 | body = doc.body,
74 | defaultView = doc.defaultView,
75 | prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
76 | top = elem.offsetTop,
77 | left = elem.offsetLeft;
78 |
79 | while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
80 | if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
81 | break;
82 | }
83 |
84 | computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
85 | top -= elem.scrollTop;
86 | left -= elem.scrollLeft;
87 |
88 | if ( elem === offsetParent ) {
89 | top += elem.offsetTop;
90 | left += elem.offsetLeft;
91 |
92 | if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
93 | top += parseFloat( computedStyle.borderTopWidth ) || 0;
94 | left += parseFloat( computedStyle.borderLeftWidth ) || 0;
95 | }
96 |
97 | prevOffsetParent = offsetParent;
98 | offsetParent = elem.offsetParent;
99 | }
100 |
101 | if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
102 | top += parseFloat( computedStyle.borderTopWidth ) || 0;
103 | left += parseFloat( computedStyle.borderLeftWidth ) || 0;
104 | }
105 |
106 | prevComputedStyle = computedStyle;
107 | }
108 |
109 | if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
110 | top += body.offsetTop;
111 | left += body.offsetLeft;
112 | }
113 |
114 | if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
115 | top += Math.max( docElem.scrollTop, body.scrollTop );
116 | left += Math.max( docElem.scrollLeft, body.scrollLeft );
117 | }
118 |
119 | return { top: top, left: left };
120 | };
121 | }
122 |
123 | jQuery.offset = {
124 | initialize: function() {
125 | var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
126 | html = "
")
247 | .appendTo("body");
248 |
249 | var index = 0;
250 |
251 | jQuery("#cssFunctionTest div").css({fontSize: function() {
252 | var size = sizes[index];
253 | index++;
254 | return size;
255 | }});
256 |
257 | index = 0;
258 |
259 | jQuery("#cssFunctionTest div").each(function() {
260 | var computedSize = jQuery(this).css("font-size")
261 | var expectedSize = sizes[index]
262 | equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
263 | index++;
264 | });
265 |
266 | jQuery("#cssFunctionTest").remove();
267 | });
268 |
269 | test("css(Object) where values are Functions with incoming values", function() {
270 | expect(3);
271 |
272 | var sizes = ["10px", "20px", "30px"];
273 |
274 | jQuery("
" +
275 | "" +
276 | "
")
277 | .appendTo("body");
278 |
279 | var index = 0;
280 |
281 | jQuery("#cssFunctionTest div").css({fontSize: function() {
282 | var size = sizes[index];
283 | index++;
284 | return size;
285 | }});
286 |
287 | index = 0;
288 |
289 | jQuery("#cssFunctionTest div").css({"font-size": function(i, computedSize) {
290 | var expectedSize = sizes[index]
291 | equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
292 | index++;
293 | return computedSize;
294 | }});
295 |
296 | jQuery("#cssFunctionTest").remove();
297 | });
298 |
299 | test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function () {
300 | expect(4);
301 |
302 | var $checkedtest = jQuery("#checkedtest");
303 | // IE6 was clearing "checked" in jQuery.css(elem, "height");
304 | jQuery.css($checkedtest[0], "height");
305 | ok( !! jQuery(":radio:first", $checkedtest).attr("checked"), "Check first radio still checked." );
306 | ok( ! jQuery(":radio:last", $checkedtest).attr("checked"), "Check last radio still NOT checked." );
307 | ok( !! jQuery(":checkbox:first", $checkedtest).attr("checked"), "Check first checkbox still checked." );
308 | ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." );
309 | });
310 |
311 | test(":visible selector works properly on table elements (bug #4512)", function () {
312 | expect(1);
313 |
314 | jQuery('#table').html('
cell
cell
');
315 | equals(jQuery('#table td:visible').length, 1, "hidden cell is not perceived as visible");
316 | });
317 |
318 | test(":visible selector works properly on children with a hidden parent (bug #4512)", function () {
319 | expect(1);
320 | jQuery('#table').css('display', 'none').html('
cell
cell
');
321 | equals(jQuery('#table td:visible').length, 0, "hidden cell children not perceived as visible");
322 | });
323 |
324 | test("internal ref to elem.runtimeStyle (bug #7608)", function () {
325 | expect(1);
326 | var result = true;
327 |
328 | try {
329 | jQuery("#foo").css( { width: "0%" } ).css("width");
330 | } catch (e) {
331 | result = false;
332 | }
333 |
334 | ok( result, "elem.runtimeStyle does not throw exception" );
335 | });
336 |
--------------------------------------------------------------------------------