Commit 0942b3b3 authored by Xavi's avatar Xavi

Merge branch 'master' of git://github.com/jquery/jquery into bug_7931

parents b78e3fc3 3d0aa196
...@@ -7,11 +7,8 @@ BUILD_DIR = build ...@@ -7,11 +7,8 @@ BUILD_DIR = build
PREFIX = . PREFIX = .
DIST_DIR = ${PREFIX}/dist DIST_DIR = ${PREFIX}/dist
RHINO ?= java -jar ${BUILD_DIR}/js.jar JS_ENGINE ?= `which node nodejs`
COMPILER = ${JS_ENGINE} ${BUILD_DIR}/uglify.js --unsafe
CLOSURE_COMPILER = ${BUILD_DIR}/google-compiler-20100917.jar
MINJAR ?= java -jar ${CLOSURE_COMPILER}
BASE_FILES = ${SRC_DIR}/core.js\ BASE_FILES = ${SRC_DIR}/core.js\
${SRC_DIR}/support.js\ ${SRC_DIR}/support.js\
...@@ -93,17 +90,13 @@ ${SRC_DIR}/selector.js: ${SIZZLE_DIR}/sizzle.js ...@@ -93,17 +90,13 @@ ${SRC_DIR}/selector.js: ${SIZZLE_DIR}/sizzle.js
lint: ${JQ} lint: ${JQ}
@@echo "Checking jQuery against JSLint..." @@echo "Checking jQuery against JSLint..."
@@${RHINO} build/jslint-check.js @@${JS_ENGINE} build/jslint-check.js
min: ${JQ_MIN} min: ${JQ_MIN}
${JQ_MIN}: ${JQ} ${JQ_MIN}: ${JQ}
@@echo "Building" ${JQ_MIN} @@echo "Building" ${JQ_MIN}
@@${COMPILER} ${JQ} > ${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: clean:
@@echo "Removing Distribution directory:" ${DIST_DIR} @@echo "Removing Distribution directory:" ${DIST_DIR}
......
[jQuery](http://jquery.com/) - New Wave Javascript [jQuery](http://jquery.com/) - New Wave Javascript
================================ ==================================================
What you need to build your own jQuery What you need to build your own jQuery
--------------------------------------- --------------------------------------
* Make sure that you have Java installed (if you want to build a minified version of jQuery).
If not, [go to this page](http://java.sun.com/javase/downloads/index.jsp) and download "Java Runtime Environment (JRE) 5.0"
Build Options 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.
-------------- (Earlier versions might work OK, but are not tested.)
You now have **three** options for building jQuery: Windows users have two options:
* **`make`**: If you have access to common UNIX commands (like `make`, `mkdir`, `rm`, `cat`, and `echo`) then simply type `make` to build all the components. 1. Install [msysgit](https://code.google.com/p/msysgit/) (Full installer for official Git),
[GNU make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm), and a
[binary version of Node.js](http://node-js.prcn.co.cc/). Make sure all three packages are installed to the same
location (by default, this is C:\Program Files\Git).
2. Install [Cygwin](http://cygwin.com/) (make sure you install the git, make, and which packages), then either follow
the [Node.js build instructions](https://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29) or install
the [binary version of Node.js](http://node-js.prcn.co.cc/).
* **`rake`**: If you have Ruby Rake installed (on either Windows or UNIX/Linux), you can simply type `rake` to build all the components. Mac OS users should install Xcode (comes on your Mac OS install DVD, or downloadable from
[Apple's Xcode site](http://developer.apple.com/technologies/xcode.html)) and
[http://mxcl.github.com/homebrew/](Homebrew). Once Homebrew is installed, run `brew install git` to install git,
and `brew install node` to install Node.js.
* **`ant`**: If you have Ant installed (or are on Windows and don't have access to make). You can download Ant from here: [http://ant.apache.org/bindownload.cgi]. Linux/BSD users should use their appropriate package managers to install make, git, and node, or build from source
if you swing that way. Easy-peasy.
How to build your own jQuery
-----------------------------
*Note: If you are using either `rake` or `ant`, substitute your chosen method in place of `make` in the examples below. They work identically for all intents and purposes. Quick reference is also available for `rake` by typing `rake -T` in the `jquery` directory.*
In the main directory of the distribution (the one that this file is in), type
the following to make all versions of jQuery:
make
*Here are the individual items that are buildable from the Makefile:*
make init
Pull in all the external dependencies (QUnit, Sizzle) for the project. How to build your own jQuery
----------------------------
make jquery
The standard, uncompressed, jQuery code.
Makes: `./dist/jquery.js`
make min
A compressed version of jQuery (made the Closure Compiler).
Makes: `./dist/jquery.min.js`
make lint First, clone a copy of the main jQuery git repo by running `git clone git://github.com/jquery/jquery.git`.
Tests a build of jQuery against JSLint, looking for potential errors or bits of confusing code. Then, to get a complete, minified, jslinted version of jQuery, simply `cd` to the `jquery` directory and type
`make`. If you don't have Node installed and/or want to make a basic, uncompressed, unlinted version of jQuery, use
`make jquery` instead of `make`.
make selector The built version of jQuery will be put in the `dist/` subdirectory.
Builds the selector library for jQuery from Sizzle. To remove all built files, run `make clean`.
Makes: `./src/selector.js`
Finally, you can remove all the built files using the command:
make clean
Building to a different directory Building to a different directory
---------------------------------- ---------------------------------
If you want to build jQuery to a directory that is different from the default location, you can... If you want to build jQuery to a directory that is different from the default location, you can specify the PREFIX
directory: `make PREFIX=/home/jquery/test/ [command]`
**Make only:** Specify the PREFIX directory, for example: With this example, the output files would end up in `/home/jquery/test/dist/`.
make PREFIX=/home/john/test/ [command]
With this example, the output files would be contained in `/home/john/test/dist/`
**Rake only:** Define the DIST_DIR directory, for example:
rake DIST_DIR=/home/john/test/ [command] Troubleshooting
---------------
With this example, the output files would be contained in `/home/john/test/`
*In both examples, `[command]` is optional.* Sometimes, the various git repositories get into an inconsistent state where builds don't complete properly
(usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then
run `make` again.
**Ant only:** You cannot currently build to another directory when using Ant.
Questions? Questions?
---------- ----------
If you have any questions, please feel free to ask them on the Developing jQuery Core If you have any questions, please feel free to ask on the
forum, which can be found here: [Developing jQuery Core forum](http://forum.jquery.com/developing-jquery-core) or in #jquery on irc.freenode.net.
[http://forum.jquery.com/developing-jquery-core](http://forum.jquery.com/developing-jquery-core)
prefix = File.dirname( __FILE__ )
# Directory variables
src_dir = File.join( prefix, 'src' )
build_dir = File.join( prefix, 'build' )
test_dir = File.join( prefix, 'test' )
# A different destination directory can be set by
# setting DIST_DIR before calling rake
dist_dir = ENV['DIST_DIR'] || File.join( prefix, 'dist' )
base_files = %w{
intro
core
support
data
queue
attributes
event
selector
traversing
manipulation
css
ajax
ajax/jsonp
ajax/script
ajax/xhr
effects
offset
dimensions
outro
}.map { |js| File.join( src_dir, "#{js}.js" ) }
# Sizzle, QUnit and jQuery files/dirs
sizzle_dir = File.join( src_dir, "sizzle" )
sizzle = File.join( sizzle_dir, "sizzle.js" )
selector = File.join( src_dir, "selector.js" )
qunit_dir = File.join( test_dir, "qunit" )
qunit = File.join( qunit_dir, "qunit", "qunit.js" )
jq = File.join( dist_dir, "jquery.js" )
jq_min = File.join( dist_dir, "jquery.min.js" )
# General Variables
date = `git log -1`[/^Date:\s+(.+)$/, 1]
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-20100917.jar"
# Turn off output other than needed from `sh` and file commands
verbose(false)
# Tasks
task :default => "all"
desc "Builds jQuery; Tests with JSLint; Minifies jQuery"
task :all => [:jquery, :lint, :min] do
puts "jQuery build complete."
end
desc "Builds jQuery: jquery.js (Default task)"
task :jquery => [:selector, jq]
desc "Builds a minified version of jQuery: jquery.min.js"
task :min => jq_min
task :init => [sizzle, qunit] do
sizzle_git = File.join(sizzle_dir, '.git')
qunit_git = File.join(qunit_dir, '.git')
puts "Updating SizzleJS with latest..."
sh "git --git-dir=#{sizzle_git} pull -q origin master"
puts "Updating QUnit with latest..."
sh "git --git-dir=#{qunit_git} pull -q origin master"
end
desc "Removes dist folder, selector.js, and Sizzle/QUnit"
task :clean do
puts "Removing Distribution directory: #{dist_dir}..."
rm_rf dist_dir
puts "Removing built copy of Sizzle..."
rm_rf selector
puts "Removing cloned directories..."
rm_rf qunit_dir
rm_rf sizzle_dir
end
desc "Rebuilds selector.js from SizzleJS"
task :selector => [:init, selector]
desc "Tests built jquery.js against JSLint"
task :lint => jq do
puts "Checking jQuery against JSLint..."
sh "#{rhino} " + File.join(build_dir, 'jslint-check.js')
end
# File and Directory Dependencies
directory dist_dir
file jq => [dist_dir, base_files].flatten do
puts "Building jquery.js..."
File.open(jq, 'w') do |f|
f.write cat(base_files).
gsub(/@DATE/, date).
gsub(/@VERSION/, version).
gsub(/.function..jQuery...\{/, '').
gsub(/\}...jQuery..;/, '')
end
end
file jq_min => jq do
puts "Building jquery.min.js..."
sh "#{minfier} --js #{jq} --warning_level QUIET --js_output_file #{jq_min}"
min = File.read( jq_min )
# Equivilent of "head"
File.open(jq_min, 'w') do |f|
f.write File.readlines(jq)[0..14].join()
f.write min
end
end
file selector => [sizzle, :init] do
puts "Building selector code from Sizzle..."
File.open(selector, 'w') do |f|
f.write File.read(sizzle).gsub(
/^.+EXPOSE$\n/,
'\0' + File.read( File.join( src_dir, 'sizzle-jquery.js' ))
).gsub(
/^window.Sizzle.+$\n/, ''
)
end
end
file sizzle do
puts "Retrieving SizzleJS from Github..."
sh "git clone git://github.com/jeresig/sizzle.git #{sizzle_dir}"
end
file qunit do
puts "Retrieving QUnit from Github..."
sh "git clone git://github.com/jquery/qunit.git #{qunit_dir}"
end
def cat( files )
files.map do |file|
File.read(file)
end.join('')
end
<project name="jQuery" default="all" basedir=".">
<loadfile property="version" srcfile="version.txt" />
<property name="PREFIX" value="." />
<property description="Folder for jquery and min target" name="dist" value="${PREFIX}/dist" />
<property name="JQ" value="${dist}/jquery.js" />
<property name="JQ_MIN" value="${dist}/jquery.min.js" />
<loadfile property="sizzle-exports" srcfile="src/sizzle-jquery.js" />
<available property="qunit" file="test/qunit" />
<available property="sizzle" file="src/sizzle" />
<target name="all" depends="jquery,lint,min" />
<target name="qunit-clone" unless="qunit">
<exec executable="git" outputproperty="git-qunit" >
<arg line="clone git://github.com/jquery/qunit.git test/qunit" />
</exec>
<echo message="git clone qunit: ${git-qunit}" />
</target>
<target name="qunit-pull" if="qunit">
<exec executable="git" outputproperty="git-qunit" dir="test/qunit" >
<arg line="pull origin master" />
</exec>
<echo message="git pull sizzle: ${git-qunit}" />
</target>
<target name="sizzle-clone" unless="sizzle">
<exec executable="git" outputproperty="git-sizzle" >
<arg line="clone git://github.com/jeresig/sizzle.git src/sizzle" />
</exec>
<echo message="git clone sizzle: ${git-sizzle}" />
</target>
<target name="sizzle-pull" if="sizzle">
<exec executable="git" outputproperty="git-sizzle" dir="src/sizzle" >
<arg line="pull origin master" />
</exec>
<echo message="git pull sizzle: ${git-sizzle}" />
</target>
<target name="init" depends="qunit-clone,qunit-pull,sizzle-clone,sizzle-pull" />
<target name="selector" depends="init" description="Builds the selector library for jQuery from Sizzle.">
<copy file="src/sizzle/sizzle.js" tofile="src/selector.js" overwrite="true" />
<replaceregexp match="// EXPOSE(.*)&#10;" replace="// EXPOSE\1&#10;${sizzle-exports}" file="src/selector.js" />
<replaceregexp match="window.Sizzle(.*)&#10;" replace="" file="src/selector.js" />
</target>
<target name="jquery" depends="init,selector" description="Main jquery build, concatenates source files and replaces @VERSION">
<echo message="Building ${JQ}" />
<mkdir dir="${dist}" />
<concat destfile="${JQ}">
<fileset file="src/intro.js" />
<fileset file="src/core.js" />
<fileset file="src/support.js" />
<fileset file="src/data.js" />
<fileset file="src/queue.js" />
<fileset file="src/attributes.js" />
<fileset file="src/event.js" />
<fileset file="src/selector.js" />
<fileset file="src/traversing.js" />
<fileset file="src/manipulation.js" />
<fileset file="src/css.js" />
<fileset file="src/ajax.js" />
<fileset file="src/ajax/jsonp.js" />
<fileset file="src/ajax/script.js" />
<fileset file="src/ajax/xhr.js" />
<fileset file="src/effects.js" />
<fileset file="src/offset.js" />
<fileset file="src/dimensions.js" />
<fileset file="src/outro.js" />
</concat>
<replaceregexp match="@VERSION" replace="${version}" flags="g" byline="true" file="${JQ}" />
<exec executable="git" outputproperty="date">
<arg line="log -1 --pretty=format:%ad" />
</exec>
<replaceregexp match="(\(\s*function\s*\(\s*jQuery\s*\)\s*\{)|(\}\s*\)\s*\(\s*jQuery\s*\)\s*;)" flags="g" replace="" file="${JQ}" />
<replaceregexp match="@DATE" replace="${date}" file="${JQ}" />
<echo message="${JQ} built." />
</target>
<target name="lint" depends="jquery" description="Check jQuery against JSLint">
<exec executable="java">
<arg line="-jar build/js.jar build/jslint-check.js" />
</exec>
</target>
<target name="min" depends="jquery" description="Remove all comments and whitespace, no compression, great in combination with GZip">
<echo message="Building ${JQ_MIN}" />
<apply executable="java" parallel="false" verbose="true" dest="${dist}">
<fileset dir="${dist}">
<include name="jquery.js" />
</fileset>
<arg line="-jar" />
<arg path="build/google-compiler-20100917.jar" />
<arg value="--warning_level" />
<arg value="QUIET" />
<arg value="--js_output_file" />
<targetfile />
<arg value="--js" />
<mapper type="glob" from="jquery.js" to="tmpmin" />
</apply>
<concat destfile="${JQ_MIN}">
<filelist files="${JQ}, ${dist}/tmpmin" />
<filterchain>
<headfilter lines="15" />
</filterchain>
</concat>
<concat destfile="${JQ_MIN}" append="yes">
<filelist files="${dist}/tmpmin" />
</concat>
<delete file="${dist}/tmpmin" />
<echo message="${JQ_MIN} built." />
</target>
<target name="clean">
<delete dir="${dist}" />
<delete file="src/selector.js" />
<delete dir="test/qunit" />
<delete dir="src/sizzle" />
</target>
<target name="openAjaxMetadata">
<property name="target" value="openAjaxMetadata-jquery-${version}.xml" />
<delete file="${dist}/jquery-*.xml" />
<get src="http://www.exfer.net/jquery/createjQueryXMLDocs.py?version=1.3" dest="${target}" />
<xslt includes="${target}" excludes="build.xml" destdir="./dist" style="build/style.xsl" extension=".xml" />
<delete file="${target}" />
</target>
</project>
load("build/jslint.js"); var JSLINT = require("./lib/jslint").JSLINT,
print = require("sys").print,
var src = readFile("dist/jquery.js"); src = require("fs").readFileSync("dist/jquery.js", "utf8");
JSLINT(src, { evil: true, forin: true, maxerr: 100 }); JSLINT(src, { evil: true, forin: true, maxerr: 100 });
...@@ -29,8 +29,8 @@ for ( var i = 0; i < e.length; i++ ) { ...@@ -29,8 +29,8 @@ for ( var i = 0; i < e.length; i++ ) {
} }
if ( found > 0 ) { if ( found > 0 ) {
print( "\n" + found + " Error(s) found." ); print( "\n" + found + " Error(s) found.\n" );
} else { } else {
print( "JSLint check passed." ); print( "JSLint check passed.\n" );
} }
...@@ -5495,6 +5495,10 @@ loop: for (;;) { ...@@ -5495,6 +5495,10 @@ loop: for (;;) {
itself.edition = '2010-02-20'; itself.edition = '2010-02-20';
if (typeof exports !== "undefined") {
exports.JSLINT = itself;
}
return itself; return itself;
}()); }());
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
var jsp = require("./parse-js"),
pro = require("./process"),
slice = jsp.slice,
member = jsp.member,
PRECEDENCE = jsp.PRECEDENCE,
OPERATORS = jsp.OPERATORS;
function ast_squeeze_more(ast) {
var w = pro.ast_walker(), walk = w.walk;
return w.with_walkers({
"call": function(expr, args) {
if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
// foo.toString() ==> foo+""
return [ "binary", "+", expr[1], [ "string", "" ]];
}
}
}, function() {
return walk(ast);
});
};
exports.ast_squeeze_more = ast_squeeze_more;
#! /usr/bin/env node
// -*- js2 -*-
global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
var fs = require("fs"),
jsp = require("./lib/parse-js"),
pro = require("./lib/process");
pro.set_logger(function(msg){
sys.debug(msg);
});
var options = {
ast: false,
mangle: true,
mangle_toplevel: false,
squeeze: true,
make_seqs: true,
dead_code: true,
beautify: false,
verbose: false,
show_copyright: true,
out_same_file: false,
extra: false,
unsafe: false, // XXX: extra & unsafe? but maybe we don't want both, so....
beautify_options: {
indent_level: 4,
indent_start: 0,
quote_keys: false,
space_colon: false
},
output: true // stdout
};
var args = jsp.slice(process.argv, 2);
var filename;
out: while (args.length > 0) {
var v = args.shift();
switch (v) {
case "-b":
case "--beautify":
options.beautify = true;
break;
case "-i":
case "--indent":
options.beautify_options.indent_level = args.shift();
break;
case "-q":
case "--quote-keys":
options.beautify_options.quote_keys = true;
break;
case "-mt":
case "--mangle-toplevel":
options.mangle_toplevel = true;
break;
case "--no-mangle":
case "-nm":
options.mangle = false;
break;
case "--no-squeeze":
case "-ns":
options.squeeze = false;
break;
case "--no-seqs":
options.make_seqs = false;
break;
case "--no-dead-code":
options.dead_code = false;
break;
case "--no-copyright":
case "-nc":
options.show_copyright = false;
break;
case "-o":
case "--output":
options.output = args.shift();
break;
case "--overwrite":
options.out_same_file = true;
break;
case "-v":
case "--verbose":
options.verbose = true;
break;
case "--ast":
options.ast = true;
break;
case "--extra":
options.extra = true;
break;
case "--unsafe":
options.unsafe = true;
break;
default:
filename = v;
break out;
}
}
if (filename) {
fs.readFile(filename, "utf8", function(err, text){
if (err) {
throw err;
}
output(squeeze_it(text));
});
} else {
var stdin = process.openStdin();
stdin.setEncoding("utf8");
var text = "";
stdin.on("data", function(chunk){
text += chunk;
});
stdin.on("end", function() {
output(squeeze_it(text));
});
}
function output(text) {
var out;
if (options.out_same_file && filename)
options.output = filename;
if (options.output === true) {
out = process.stdout;
} else {
out = fs.createWriteStream(options.output, {
flags: "w",
encoding: "utf8",
mode: 0644
});
}
out.write(text);
out.end();
};
// --------- main ends here.
function show_copyright(comments) {
var ret = "";
for (var i = 0; i < comments.length; ++i) {
var c = comments[i];
if (c.type == "comment1") {
ret += "//" + c.value + "\n";
} else {
ret += "/*" + c.value + "*/";
}
}
return ret;
};
function squeeze_it(code) {
var result = "";
if (options.show_copyright) {
var initial_comments = [];
// keep first comment
var tok = jsp.tokenizer(code, false), c;
c = tok();
var prev = null;
while (/^comment/.test(c.type) && (!prev || prev == c.type)) {
initial_comments.push(c);
prev = c.type;
c = tok();
}
result += show_copyright(initial_comments);
}
try {
var ast = time_it("parse", function(){ return jsp.parse(code); });
if (options.mangle)
ast = time_it("mangle", function(){ return pro.ast_mangle(ast, options.mangle_toplevel); });
if (options.squeeze)
ast = time_it("squeeze", function(){
ast = pro.ast_squeeze(ast, {
make_seqs : options.make_seqs,
dead_code : options.dead_code,
extra : options.extra
});
if (options.unsafe)
ast = pro.ast_squeeze_more(ast);
return ast;
});
if (options.ast)
return sys.inspect(ast, null, null);
result += time_it("generate", function(){ return pro.gen_code(ast, options.beautify && options.beautify_options) });
return result;
} catch(ex) {
sys.debug(ex.stack);
sys.debug(sys.inspect(ex));
sys.debug(JSON.stringify(ex));
}
};
function time_it(name, cont) {
if (!options.verbose)
return cont();
var t1 = new Date().getTime();
try { return cont(); }
finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
};
This diff is collapsed.
(function( jQuery ) { (function( jQuery ) {
var jsc = jQuery.now(), var jsc = jQuery.now(),
jsre = /\=(?:\?|%3F)(&|$)/i, jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i;
rquery_jsonp = /\?/;
// Default jsonp settings // Default jsonp settings
jQuery.ajaxSetup({ jQuery.ajaxSetup({
...@@ -10,75 +9,78 @@ jQuery.ajaxSetup({ ...@@ -10,75 +9,78 @@ jQuery.ajaxSetup({
jsonpCallback: function() { jsonpCallback: function() {
return "jsonp" + jsc++; return "jsonp" + jsc++;
} }
});
// Normalize jsonp queries // Detect, normalize options and install callbacks for jsonp requests
// 1) put callback parameter in url or data // (dataIsString is used internally)
// 2) sneakily ensure transportDataType is always jsonp for jsonp requests }).ajaxPrefilter("json jsonp", function(s, originalSettings, dataIsString) {
jQuery.ajax.prefilter("json jsonp", function(s, originalSettings) {
dataIsString = ( typeof(s.data) === "string" );
if ( s.dataTypes[ 0 ] === "jsonp" || if ( s.dataTypes[ 0 ] === "jsonp" ||
originalSettings.jsonp ||
originalSettings.jsonpCallback || originalSettings.jsonpCallback ||
jsre.test(s.url) || originalSettings.jsonp != null ||
typeof(s.data) === "string" && jsre.test(s.data) ) { s.jsonp !== false && ( jsre.test( s.url ) ||
dataIsString && jsre.test( s.data ) ) ) {
var jsonpCallback = s.jsonpCallback = var responseContainer,
jsonpCallback = s.jsonpCallback =
jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
url = s.url.replace(jsre, "=" + jsonpCallback + "$1"), previous = window[ jsonpCallback ],
data = s.url === url && typeof(s.data) === "string" ? s.data.replace(jsre, "=" + jsonpCallback + "$1") : s.data; url = s.url,
data = s.data,
if ( url === s.url && data === s.data ) { replace = "$1" + jsonpCallback + "$2";
url += (rquery_jsonp.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
if ( s.jsonp !== false ) {
url = url.replace( jsre, replace );
if ( s.url === url ) {
if ( dataIsString ) {
data = data.replace( jsre, replace );
}
if ( s.data === data ) {
// Add callback manually
url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
}
}
} }
s.url = url; s.url = url;
s.data = data; s.data = data;
s.dataTypes[ 0 ] = "jsonp";
}
// Bind transport to jsonp dataType
}).transport("jsonp", function(s) {
// Put callback in place window [ jsonpCallback ] = function( response ) {
var responseContainer, responseContainer = [response];
jsonpCallback = s.jsonpCallback, };
previous = window[ jsonpCallback ];
window [ jsonpCallback ] = function( response ) { s.complete = [function() {
responseContainer = [response];
};
s.complete = [function() { // Set callback back to previous value
window[ jsonpCallback ] = previous;
// Set callback back to previous value // Call if it was a function and we have a response
window[ jsonpCallback ] = previous; if ( previous) {
if ( responseContainer && jQuery.isFunction ( previous ) ) {
// Call if it was a function and we have a response window[ jsonpCallback ] ( responseContainer[0] );
if ( previous) { }
if ( responseContainer && jQuery.isFunction ( previous ) ) { } else {
window[ jsonpCallback ] ( responseContainer[0] ); // else, more memory leak avoidance
try{ delete window[ jsonpCallback ]; } catch(e){}
} }
} else {
// else, more memory leak avoidance
try{ delete window[ jsonpCallback ]; } catch(e){}
}
}, s.complete ]; }, s.complete ];
// Sneakily ensure this will be handled as json // Use data converter to retrieve json after script execution
s.dataTypes[ 0 ] = "json"; s.converters["script json"] = function() {
if ( ! responseContainer ) {
jQuery.error( jsonpCallback + " was not called" );
}
return responseContainer[ 0 ];
};
// Use data converter to retrieve json after script execution // force json dataType
s.converters["script json"] = function() { s.dataTypes[ 0 ] = "json";
if ( ! responseContainer ) {
jQuery.error( jsonpCallback + " was not called" );
}
return responseContainer[ 0 ];
};
// Delegate to script transport // Delegate to script
return "script"; return "script";
}
}); });
})( jQuery ); })( jQuery );
(function( jQuery ) { (function( jQuery ) {
// Install text to script executor // Install script dataType
jQuery.extend( true, jQuery.ajaxSettings , { jQuery.ajaxSetup({
accepts: { accepts: {
script: "text/javascript, application/javascript" script: "text/javascript, application/javascript"
...@@ -14,20 +14,24 @@ jQuery.extend( true, jQuery.ajaxSettings , { ...@@ -14,20 +14,24 @@ jQuery.extend( true, jQuery.ajaxSettings , {
converters: { converters: {
"text script": jQuery.globalEval "text script": jQuery.globalEval
} }
} );
// Bind script tag hack transport // Handle cache's special case and global
jQuery.ajax.transport("script", function(s) { }).ajaxPrefilter("script", function(s) {
// Handle cache special case
if ( s.cache === undefined ) { if ( s.cache === undefined ) {
s.cache = false; s.cache = false;
} }
// This transport only deals with cross domain get requests if ( s.crossDomain ) {
if ( s.crossDomain && s.async && ( s.type === "GET" || ! s.data ) ) { s.type = "GET";
s.global = false; s.global = false;
}
// Bind script tag hack transport
}).ajaxTransport("script", function(s) {
// This transport only deals with cross domain requests
if ( s.crossDomain ) {
var script, var script,
head = document.getElementsByTagName("head")[0] || document.documentElement; head = document.getElementsByTagName("head")[0] || document.documentElement;
...@@ -47,7 +51,7 @@ jQuery.ajax.transport("script", function(s) { ...@@ -47,7 +51,7 @@ jQuery.ajax.transport("script", function(s) {
script.src = s.url; script.src = s.url;
// Attach handlers for all browsers // Attach handlers for all browsers
script.onload = script.onreadystatechange = function( _ , statusText) { script.onload = script.onreadystatechange = function( _ , isAbort ) {
if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) { if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
...@@ -59,10 +63,13 @@ jQuery.ajax.transport("script", function(s) { ...@@ -59,10 +63,13 @@ jQuery.ajax.transport("script", function(s) {
head.removeChild( script ); head.removeChild( script );
} }
// Dereference the script
script = 0; script = 0;
// Callback // Callback if not abort
callback( statusText ? 0 : 200, statusText || "success" ); if ( ! isAbort ) {
callback( 200, "success" );
}
} }
}; };
// Use insertBefore instead of appendChild to circumvent an IE6 bug. // Use insertBefore instead of appendChild to circumvent an IE6 bug.
...@@ -70,9 +77,9 @@ jQuery.ajax.transport("script", function(s) { ...@@ -70,9 +77,9 @@ jQuery.ajax.transport("script", function(s) {
head.insertBefore( script, head.firstChild ); head.insertBefore( script, head.firstChild );
}, },
abort: function(statusText) { abort: function() {
if ( script ) { if ( script ) {
script.onload( 0 , statusText ); script.onload(0,1);
} }
} }
}; };
......
(function( jQuery ) { (function( jQuery ) {
var // Next fake timer id var // Next active xhr id
xhrPollingId = jQuery.now(), xhrId = jQuery.now(),
// Callbacks hashtable // active xhrs
xhrs = {}, xhrs = {},
// XHR pool // #5280: see below
xhrPool = [], xhrUnloadAbortInstalled;
// #5280: see end of file
xhrUnloadAbortMarker;
jQuery.ajaxTransport( function( s , determineDataType ) {
jQuery.ajax.transport( function( s , determineDataType ) {
// Cross domain only allowed if supported through XMLHttpRequest // Cross domain only allowed if supported through XMLHttpRequest
if ( ! s.crossDomain || jQuery.support.cors ) { if ( ! s.crossDomain || jQuery.support.cors ) {
...@@ -25,26 +22,24 @@ jQuery.ajax.transport( function( s , determineDataType ) { ...@@ -25,26 +22,24 @@ jQuery.ajax.transport( function( s , determineDataType ) {
send: function(headers, complete) { send: function(headers, complete) {
// #5280: we need to abort on unload or IE will keep connections alive // #5280: we need to abort on unload or IE will keep connections alive
if ( ! xhrUnloadAbortMarker ) { if ( ! xhrUnloadAbortInstalled ) {
xhrUnloadAbortMarker = []; xhrUnloadAbortInstalled = 1;
jQuery(window).bind( "unload" , function() { jQuery(window).bind( "unload" , function() {
// Abort all pending requests // Abort all pending requests
jQuery.each(xhrs, function(_, xhr) { jQuery.each(xhrs, function(_, xhr) {
if ( xhr.onreadystatechange ) { if ( xhr.onreadystatechange ) {
xhr.onreadystatechange( xhrUnloadAbortMarker ); xhr.onreadystatechange( 1 );
} }
}); });
// Reset polling structure to be safe
xhrs = {};
}); });
} }
var xhr = xhrPool.pop() || s.xhr(), // Get a new xhr
var xhr = s.xhr(),
handle; handle;
// Open the socket // Open the socket
...@@ -58,7 +53,7 @@ jQuery.ajax.transport( function( s , determineDataType ) { ...@@ -58,7 +53,7 @@ jQuery.ajax.transport( function( s , determineDataType ) {
// Requested-With header // Requested-With header
// Not set for crossDomain requests with no content // Not set for crossDomain requests with no content
// (see why at http://trac.dojotoolkit.org/ticket/9486) // (see why at http://trac.dojotoolkit.org/ticket/9486)
// Won't change header if already provided in beforeSend // Won't change header if already provided
if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) { if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
headers["x-requested-with"] = "XMLHttpRequest"; headers["x-requested-with"] = "XMLHttpRequest";
} }
...@@ -76,49 +71,40 @@ jQuery.ajax.transport( function( s , determineDataType ) { ...@@ -76,49 +71,40 @@ jQuery.ajax.transport( function( s , determineDataType ) {
try { try {
xhr.send( ( s.hasContent && s.data ) || null ); xhr.send( ( s.hasContent && s.data ) || null );
} catch(e) { } catch(e) {
// Store back in pool
xhrPool.push( xhr );
complete(0, "error", "" + e); complete(0, "error", "" + e);
return; return;
} }
// Listener // Listener
callback = function ( abortStatusText ) { callback = function( _ , isAbort ) {
// Was never called and is aborted or complete // Was never called and is aborted or complete
if ( callback && ( abortStatusText || xhr.readyState === 4 ) ) { if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
// Only called once
callback = 0;
// Do not listen anymore // Do not keep as active anymore
// and Store back in pool // and store back into pool
if (handle) { if (handle) {
xhr.onreadystatechange = jQuery.noop; xhr.onreadystatechange = jQuery.noop;
delete xhrs[ handle ]; delete xhrs[ handle ];
handle = undefined;
xhrPool.push( xhr );
} }
callback = 0; // If it's an abort
if ( isAbort ) {
// Get info
var status, statusText, response, responseHeaders;
if ( abortStatusText ) {
// Abort it manually if needed
if ( xhr.readyState !== 4 ) { if ( xhr.readyState !== 4 ) {
xhr.abort(); xhr.abort();
} }
// Stop here if unloadAbort
if ( abortStatusText === xhrUnloadAbortMarker ) {
return;
}
status = 0;
statusText = abortStatusText;
} else { } else {
status = xhr.status; // Get info
var status = xhr.status,
statusText,
response,
responseHeaders = xhr.getAllResponseHeaders();
try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
...@@ -130,8 +116,6 @@ jQuery.ajax.transport( function( s , determineDataType ) { ...@@ -130,8 +116,6 @@ jQuery.ajax.transport( function( s , determineDataType ) {
} }
responseHeaders = xhr.getAllResponseHeaders();
// Filter status for non standard behaviours // Filter status for non standard behaviours
// (so many they seem to be the actual "standard") // (so many they seem to be the actual "standard")
status = status =
...@@ -164,10 +148,10 @@ jQuery.ajax.transport( function( s , determineDataType ) { ...@@ -164,10 +148,10 @@ jQuery.ajax.transport( function( s , determineDataType ) {
xhr.getResponseHeader("content-type"), xhr.getResponseHeader("content-type"),
xhr.responseText, xhr.responseText,
xhr.responseXML ); xhr.responseXML );
}
// Call complete // Call complete
complete(status,statusText,response,responseHeaders); complete(status,statusText,response,responseHeaders);
}
} }
}; };
...@@ -180,18 +164,16 @@ jQuery.ajax.transport( function( s , determineDataType ) { ...@@ -180,18 +164,16 @@ jQuery.ajax.transport( function( s , determineDataType ) {
} else { } else {
// Listener is externalized to handle abort on unload // Add to list of active xhrs
handle = xhrPollingId++; handle = xhrId++;
xhrs[ handle ] = xhr; xhrs[ handle ] = xhr;
xhr.onreadystatechange = function() { xhr.onreadystatechange = callback;
callback();
};
} }
}, },
abort: function(statusText) { abort: function() {
if ( callback ) { if ( callback ) {
callback(statusText); callback(0,1);
} }
} }
}; };
......
...@@ -133,11 +133,11 @@ jQuery.fn.extend({ ...@@ -133,11 +133,11 @@ jQuery.fn.extend({
} else if ( type === "undefined" || type === "boolean" ) { } else if ( type === "undefined" || type === "boolean" ) {
if ( this.className ) { if ( this.className ) {
// store className if set // store className if set
jQuery.data( this, "__className__", this.className ); jQuery._data( this, "__className__", this.className );
} }
// toggle whole className // toggle whole className
this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
} }
}); });
}, },
......
...@@ -3,7 +3,7 @@ var jQuery = (function() { ...@@ -3,7 +3,7 @@ var jQuery = (function() {
// Define a local copy of jQuery // Define a local copy of jQuery
var jQuery = function( selector, context ) { var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced' // The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context ); return new jQuery.fn.init( selector, context, rootjQuery );
}, },
// Map over jQuery in case of overwrite // Map over jQuery in case of overwrite
...@@ -63,6 +63,9 @@ var jQuery = function( selector, context ) { ...@@ -63,6 +63,9 @@ var jQuery = function( selector, context ) {
// The deferred used on DOM ready // The deferred used on DOM ready
readyList, readyList,
// Promise methods
promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
// The ready event handler // The ready event handler
DOMContentLoaded, DOMContentLoaded,
...@@ -78,7 +81,8 @@ var jQuery = function( selector, context ) { ...@@ -78,7 +81,8 @@ var jQuery = function( selector, context ) {
class2type = {}; class2type = {};
jQuery.fn = jQuery.prototype = { jQuery.fn = jQuery.prototype = {
init: function( selector, context ) { constructor: jQuery,
init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc; var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined) // Handle $(""), $(null), or $(undefined)
...@@ -112,6 +116,7 @@ jQuery.fn = jQuery.prototype = { ...@@ -112,6 +116,7 @@ jQuery.fn = jQuery.prototype = {
// HANDLE: $(html) -> $(array) // HANDLE: $(html) -> $(array)
if ( match[1] ) { if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
doc = (context ? context.ownerDocument || context : document); doc = (context ? context.ownerDocument || context : document);
// If a single string is passed in and it's a single tag // If a single string is passed in and it's a single tag
...@@ -129,7 +134,7 @@ jQuery.fn = jQuery.prototype = { ...@@ -129,7 +134,7 @@ jQuery.fn = jQuery.prototype = {
} else { } else {
ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; selector = (ret.cacheable ? jQuery(ret.fragment).clone()[0] : ret.fragment).childNodes;
} }
return jQuery.merge( this, selector ); return jQuery.merge( this, selector );
...@@ -171,7 +176,7 @@ jQuery.fn = jQuery.prototype = { ...@@ -171,7 +176,7 @@ jQuery.fn = jQuery.prototype = {
// HANDLE: $(expr, context) // HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr) // (which is just equivalent to: $(context).find(expr)
} else { } else {
return jQuery( context ).find( selector ); return this.constructor( context ).find( selector );
} }
// HANDLE: $(function) // HANDLE: $(function)
...@@ -222,7 +227,7 @@ jQuery.fn = jQuery.prototype = { ...@@ -222,7 +227,7 @@ jQuery.fn = jQuery.prototype = {
// (returning the new matched element set) // (returning the new matched element set)
pushStack: function( elems, name, selector ) { pushStack: function( elems, name, selector ) {
// Build a new jQuery matched element set // Build a new jQuery matched element set
var ret = jQuery(); var ret = this.constructor();
if ( jQuery.isArray( elems ) ) { if ( jQuery.isArray( elems ) ) {
push.apply( ret, elems ); push.apply( ret, elems );
...@@ -287,7 +292,7 @@ jQuery.fn = jQuery.prototype = { ...@@ -287,7 +292,7 @@ jQuery.fn = jQuery.prototype = {
}, },
end: function() { end: function() {
return this.prevObject || jQuery(null); return this.prevObject || this.constructor(null);
}, },
// For internal use only. // For internal use only.
...@@ -578,7 +583,7 @@ jQuery.extend({ ...@@ -578,7 +583,7 @@ jQuery.extend({
script.type = "text/javascript"; script.type = "text/javascript";
if ( jQuery.support.scriptEval ) { if ( jQuery.support.scriptEval() ) {
script.appendChild( document.createTextNode( data ) ); script.appendChild( document.createTextNode( data ) );
} else { } else {
script.text = data; script.text = data;
...@@ -896,9 +901,10 @@ jQuery.extend({ ...@@ -896,9 +901,10 @@ jQuery.extend({
Deferred: function( func ) { Deferred: function( func ) {
var deferred = jQuery._Deferred(), var deferred = jQuery._Deferred(),
failDeferred = jQuery._Deferred(); failDeferred = jQuery._Deferred(),
promise;
// Add errorDeferred methods and redefine cancel // Add errorDeferred methods, then and promise
jQuery.extend( deferred , { jQuery.extend( deferred , {
then: function( doneCallbacks , failCallbacks ) { then: function( doneCallbacks , failCallbacks ) {
...@@ -911,14 +917,18 @@ jQuery.extend({ ...@@ -911,14 +917,18 @@ jQuery.extend({
isRejected: failDeferred.isResolved, isRejected: failDeferred.isResolved,
// Get a promise for this deferred // Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object // If obj is provided, the promise aspect is added to the object
promise: function( obj ) { // (i is used internally)
obj = obj || {}; promise: function( obj , i ) {
jQuery.each( "then done fail isResolved isRejected".split( " " ) , function( _ , method ) { if ( obj == null ) {
obj[ method ] = deferred[ method ]; if ( promise ) {
}); return promise;
obj.promise = function() { }
return obj; promise = obj = {};
}; }
i = promiseMethods.length;
while( i-- ) {
obj[ promiseMethods[ i ] ] = deferred[ promiseMethods[ i ] ];
}
return obj; return obj;
} }
...@@ -940,10 +950,32 @@ jQuery.extend({ ...@@ -940,10 +950,32 @@ jQuery.extend({
// Deferred helper // Deferred helper
when: function( object ) { when: function( object ) {
object = object && jQuery.isFunction( object.promise ) ? var args = arguments,
object : length = args.length,
jQuery.Deferred().resolve( object ); deferred = length <= 1 && object && jQuery.isFunction( object.promise ) ?
return object.promise(); object :
jQuery.Deferred(),
promise = deferred.promise(),
resolveArray;
if ( length > 1 ) {
resolveArray = new Array( length );
jQuery.each( args, function( index, element, args ) {
jQuery.when( element ).done( function( value ) {
args = arguments;
resolveArray[ index ] = args.length > 1 ? slice.call( args , 0 ) : value;
if( ! --length ) {
deferred.fire( promise, resolveArray );
}
}).fail( function() {
deferred.fireReject( promise, arguments );
});
return !deferred.isRejected();
});
} else if ( deferred !== object ) {
deferred.resolve( object );
}
return promise;
}, },
// Use of jQuery.browser is frowned upon. // Use of jQuery.browser is frowned upon.
...@@ -960,6 +992,25 @@ jQuery.extend({ ...@@ -960,6 +992,25 @@ jQuery.extend({
return { browser: match[1] || "", version: match[2] || "0" }; return { browser: match[1] || "", version: match[2] || "0" };
}, },
subclass: function(){
function jQuerySubclass( selector, context ) {
return new jQuerySubclass.fn.init( selector, context );
}
jQuerySubclass.superclass = this;
jQuerySubclass.fn = jQuerySubclass.prototype = this();
jQuerySubclass.fn.constructor = jQuerySubclass;
jQuerySubclass.subclass = this.subclass;
jQuerySubclass.fn.init = function init( selector, context ) {
if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
context = jQuerySubclass(context);
}
return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
};
jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
var rootjQuerySubclass = jQuerySubclass(document);
return jQuerySubclass;
},
browser: {} browser: {}
}); });
......
...@@ -263,8 +263,9 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) { ...@@ -263,8 +263,9 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) {
if ( document.documentElement.currentStyle ) { if ( document.documentElement.currentStyle ) {
currentStyle = function( elem, name ) { currentStyle = function( elem, name ) {
var left, rsLeft, var left,
ret = elem.currentStyle && elem.currentStyle[ name ], ret = elem.currentStyle && elem.currentStyle[ name ],
rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
style = elem.style; style = elem.style;
// From the awesome hack by Dean Edwards // From the awesome hack by Dean Edwards
...@@ -275,16 +276,19 @@ if ( document.documentElement.currentStyle ) { ...@@ -275,16 +276,19 @@ if ( document.documentElement.currentStyle ) {
if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
// Remember the original values // Remember the original values
left = style.left; left = style.left;
rsLeft = elem.runtimeStyle.left;
// Put in the new values to get a computed value out // Put in the new values to get a computed value out
elem.runtimeStyle.left = elem.currentStyle.left; if ( rsLeft ) {
elem.runtimeStyle.left = elem.currentStyle.left;
}
style.left = name === "fontSize" ? "1em" : (ret || 0); style.left = name === "fontSize" ? "1em" : (ret || 0);
ret = style.pixelLeft + "px"; ret = style.pixelLeft + "px";
// Revert the changed values // Revert the changed values
style.left = left; style.left = left;
elem.runtimeStyle.left = rsLeft; if ( rsLeft ) {
elem.runtimeStyle.left = rsLeft;
}
} }
return ret === "" ? "auto" : ret; return ret === "" ? "auto" : ret;
......
(function( jQuery ) { (function( jQuery ) {
var windowData = {}, var rbrace = /^(?:\{.*\}|\[.*\])$/;
rbrace = /^(?:\{.*\}|\[.*\])$/;
jQuery.extend({ jQuery.extend({
cache: {}, cache: {},
...@@ -23,110 +22,170 @@ jQuery.extend({ ...@@ -23,110 +22,170 @@ jQuery.extend({
}, },
hasData: function( elem ) { hasData: function( elem ) {
if ( elem.nodeType ) { elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
elem = jQuery.cache[ elem[jQuery.expando] ];
}
return !!elem && !jQuery.isEmptyObject(elem); return !!elem && !jQuery.isEmptyObject(elem);
}, },
data: function( elem, name, data ) { data: function( elem, name, data, pvt /* Internal Use Only */ ) {
if ( !jQuery.acceptData( elem ) ) { if ( !jQuery.acceptData( elem ) ) {
return; return;
} }
elem = elem == window ? var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
windowData :
elem; // We have to handle DOM nodes and JS objects differently because IE6-7
// can't GC object references properly across the DOM-JS boundary
isNode = elem.nodeType,
// Only DOM nodes need the global jQuery cache; JS object data is
// attached directly to the object so GC can occur automatically
cache = isNode ? jQuery.cache : elem,
var isNode = elem.nodeType, // Only defining an ID for JS objects if its cache already exists allows
id = isNode ? elem[ jQuery.expando ] : null, // the code to shortcut on the same path as a DOM node with no cache
cache = jQuery.cache, thisCache; id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
if ( isNode && !id && typeof name === "string" && data === undefined ) { // Avoid doing any more work than we need to when trying to get data on an
// object that has no data at all
if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
return; return;
} }
// Get the data from the object directly if ( !id ) {
if ( !isNode ) { // Only DOM nodes need a new unique ID for each element since their data
cache = elem; // ends up in the global cache
if ( isNode ) {
elem[ jQuery.expando ] = id = ++jQuery.uuid;
} else {
id = jQuery.expando;
}
}
// Compute a unique ID for the element if ( !cache[ id ] ) {
} else if ( !id ) { cache[ id ] = {};
elem[ jQuery.expando ] = id = ++jQuery.uuid;
} }
// Avoid generating a new cache unless none exists and we // An object can be passed to jQuery.data instead of a key/value pair; this gets
// want to manipulate it. // shallow copied over onto the existing cache
if ( typeof name === "object" ) { if ( typeof name === "object" ) {
if ( isNode ) { if ( pvt ) {
cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
} else {
cache[ id ] = jQuery.extend(cache[ id ], name); cache[ id ] = jQuery.extend(cache[ id ], name);
}
}
} else { thisCache = cache[ id ];
jQuery.extend( cache, name );
// Internal jQuery data is stored in a separate object inside the object's data
// cache in order to avoid key collisions between internal data and user-defined
// data
if ( pvt ) {
if ( !thisCache[ internalKey ] ) {
thisCache[ internalKey ] = {};
} }
} else if ( isNode && !cache[ id ] ) { thisCache = thisCache[ internalKey ];
cache[ id ] = {};
} }
thisCache = isNode ? cache[ id ] : cache;
// Prevent overriding the named cache with undefined values
if ( data !== undefined ) { if ( data !== undefined ) {
thisCache[ name ] = data; thisCache[ name ] = data;
} }
return typeof name === "string" ? thisCache[ name ] : thisCache; // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
// not attempt to inspect the internal events object using jQuery.data, as this
// internal data object is undocumented and subject to change.
if ( name === "events" && !thisCache[name] ) {
return thisCache[ internalKey ] && thisCache[ internalKey ].events;
}
return getByName ? thisCache[ name ] : thisCache;
}, },
removeData: function( elem, name ) { removeData: function( elem, name, pvt /* Internal Use Only */ ) {
if ( !jQuery.acceptData( elem ) ) { if ( !jQuery.acceptData( elem ) ) {
return; return;
} }
elem = elem == window ? var internalKey = jQuery.expando, isNode = elem.nodeType,
windowData :
elem; // See jQuery.data for more information
cache = isNode ? jQuery.cache : elem,
var isNode = elem.nodeType, // See jQuery.data for more information
id = isNode ? elem[ jQuery.expando ] : elem, id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
cache = jQuery.cache,
thisCache = isNode ? cache[ id ] : id; // If there is already no cache entry for this object, there is no
// purpose in continuing
if ( !cache[ id ] ) {
return;
}
// If we want to remove a specific section of the element's data
if ( name ) { if ( name ) {
var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
if ( thisCache ) { if ( thisCache ) {
// Remove the section of cache data
delete thisCache[ name ]; delete thisCache[ name ];
// If we've removed all the data, remove the element's cache // If there is no data left in the cache, we want to continue
if ( isNode && jQuery.isEmptyObject(thisCache) ) { // and let the cache object itself get destroyed
jQuery.removeData( elem ); if ( !jQuery.isEmptyObject(thisCache) ) {
return;
} }
} }
}
// See jQuery.data for more information
if ( pvt ) {
delete cache[ id ][ internalKey ];
// Don't destroy the parent cache unless the internal data object
// had been the only thing left in it
if ( !jQuery.isEmptyObject(cache[ id ]) ) {
return;
}
}
var internalCache = cache[ id ][ internalKey ];
// Otherwise, we want to remove all of the element's data // Browsers that fail expando deletion also refuse to delete expandos on
// the window, but it will allow it on all other JS objects; other browsers
// don't care
if ( jQuery.support.deleteExpando || cache != window ) {
delete cache[ id ];
} else { } else {
if ( isNode && jQuery.support.deleteExpando ) { cache[ id ] = null;
delete elem[ jQuery.expando ]; }
// We destroyed the entire user cache at once because it's faster than
// iterating through each key, but we need to continue to persist internal
// data if it existed
if ( internalCache ) {
cache[ id ] = {};
cache[ id ][ internalKey ] = internalCache;
// Otherwise, we need to eliminate the expando on the node to avoid
// false lookups in the cache for entries that no longer exist
} else if ( isNode ) {
// IE does not allow us to delete expando properties from nodes,
// nor does it have a removeAttribute function on Document nodes;
// we must handle all of these cases
if ( jQuery.support.deleteExpando ) {
delete elem[ jQuery.expando ];
} else if ( elem.removeAttribute ) { } else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando ); elem.removeAttribute( jQuery.expando );
// Completely remove the data cache
} else if ( isNode ) {
delete cache[ id ];
// Remove all fields from the object
} else { } else {
for ( var n in elem ) { elem[ jQuery.expando ] = null;
delete elem[ n ];
}
} }
} }
}, },
// For internal use only.
_data: function( elem, name, data ) {
return jQuery.data( elem, name, data, true );
},
// A method for determining if a DOM node can handle the data expando // A method for determining if a DOM node can handle the data expando
acceptData: function( elem ) { acceptData: function( elem ) {
if ( elem.nodeName ) { if ( elem.nodeName ) {
......
...@@ -27,7 +27,7 @@ jQuery.fn.extend({ ...@@ -27,7 +27,7 @@ jQuery.fn.extend({
// Reset the inline display of this element to learn if it is // Reset the inline display of this element to learn if it is
// being hidden by cascaded rules or not // being hidden by cascaded rules or not
if ( !jQuery.data(elem, "olddisplay") && display === "none" ) { if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
display = elem.style.display = ""; display = elem.style.display = "";
} }
...@@ -35,7 +35,7 @@ jQuery.fn.extend({ ...@@ -35,7 +35,7 @@ jQuery.fn.extend({
// in a stylesheet to whatever the default browser style is // in a stylesheet to whatever the default browser style is
// for such an element // for such an element
if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName)); jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
} }
} }
...@@ -46,7 +46,7 @@ jQuery.fn.extend({ ...@@ -46,7 +46,7 @@ jQuery.fn.extend({
display = elem.style.display; display = elem.style.display;
if ( display === "" || display === "none" ) { if ( display === "" || display === "none" ) {
elem.style.display = jQuery.data(elem, "olddisplay") || ""; elem.style.display = jQuery._data(elem, "olddisplay") || "";
} }
} }
...@@ -62,8 +62,8 @@ jQuery.fn.extend({ ...@@ -62,8 +62,8 @@ jQuery.fn.extend({
for ( var i = 0, j = this.length; i < j; i++ ) { for ( var i = 0, j = this.length; i < j; i++ ) {
var display = jQuery.css( this[i], "display" ); var display = jQuery.css( this[i], "display" );
if ( display !== "none" && !jQuery.data( this[i], "olddisplay" ) ) { if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
jQuery.data( this[i], "olddisplay", display ); jQuery._data( this[i], "olddisplay", display );
} }
} }
......
This diff is collapsed.
...@@ -346,7 +346,7 @@ jQuery.fn.extend({ ...@@ -346,7 +346,7 @@ jQuery.fn.extend({
table ? table ?
root(this[i], first) : root(this[i], first) :
this[i], this[i],
i > 0 || results.cacheable || this.length > 1 ? i > 0 || results.cacheable || (this.length > 1 && i > 0) ?
jQuery(fragment).clone(true)[0] : jQuery(fragment).clone(true)[0] :
fragment fragment
); );
...@@ -381,17 +381,24 @@ function cloneCopyEvent(orig, ret) { ...@@ -381,17 +381,24 @@ function cloneCopyEvent(orig, ret) {
throw "Cloned data mismatch"; throw "Cloned data mismatch";
} }
var oldData = jQuery.data( orig[nodeIndex] ), var internalKey = jQuery.expando,
curData = jQuery.data( this, oldData ), oldData = jQuery.data( orig[nodeIndex] ),
events = oldData && oldData.events; curData = jQuery.data( this, oldData );
if ( events ) { // Switch to use the internal data object, if it exists, for the next
delete curData.handle; // stage of data copying
curData.events = {}; if ( (oldData = oldData[ internalKey ]) ) {
var events = oldData.events;
curData = curData[ internalKey ] = jQuery.extend({}, oldData);
for ( var type in events ) { if ( events ) {
for ( var i = 0, l = events[ type ].length; i < l; i++ ) { delete curData.handle;
jQuery.event.add( this, type, events[ type ][ i ], events[ type ][ i ].data ); curData.events = {};
for ( var type in events ) {
for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
jQuery.event.add( this, type, events[ type ][ i ], events[ type ][ i ].data );
}
} }
} }
} }
...@@ -420,15 +427,29 @@ function cloneFixAttributes(src, dest) { ...@@ -420,15 +427,29 @@ function cloneFixAttributes(src, dest) {
if ( nodeName === "object" ) { if ( nodeName === "object" ) {
dest.outerHTML = src.outerHTML; dest.outerHTML = src.outerHTML;
// IE6-8 fails to persist the checked state of a cloned checkbox } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
// or radio button // IE6-8 fails to persist the checked state of a cloned checkbox
} else if ( nodeName === "input" && src.checked ) { // or radio button. Worse, IE6-7 fail to give the cloned element
dest.defaultChecked = dest.checked = src.checked; // a checked appearance if the defaultChecked value isn't also set
if ( src.checked ) {
dest.defaultChecked = dest.checked = src.checked;
}
// IE6-7 get confused and end up setting the value of a cloned
// checkbox/radio button to an empty string instead of "on"
if ( dest.value !== src.value ) {
dest.value = src.value;
}
// IE6-8 fails to return the selected option to the default selected // IE6-8 fails to return the selected option to the default selected
// state when cloning options // state when cloning options
} else if ( nodeName === "option" ) { } else if ( nodeName === "option" ) {
dest.selected = src.defaultSelected; dest.selected = src.defaultSelected;
// IE6-8 fails to set the defaultValue to the correct value when
// cloning other types of input fields
} else if ( nodeName === "input" || nodeName === "textarea" ) {
dest.defaultValue = src.defaultValue;
} }
// Event data gets referenced instead of copied if the expando // Event data gets referenced instead of copied if the expando
...@@ -594,8 +615,7 @@ jQuery.extend({ ...@@ -594,8 +615,7 @@ jQuery.extend({
}, },
cleanData: function( elems ) { cleanData: function( elems ) {
var data, id, cache = jQuery.cache, var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
special = jQuery.event.special,
deleteExpando = jQuery.support.deleteExpando; deleteExpando = jQuery.support.deleteExpando;
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
...@@ -606,13 +626,14 @@ jQuery.extend({ ...@@ -606,13 +626,14 @@ jQuery.extend({
id = elem[ jQuery.expando ]; id = elem[ jQuery.expando ];
if ( id ) { if ( id ) {
data = cache[ id ]; data = cache[ id ] && cache[ id ][ internalKey ];
if ( data && data.events ) { if ( data && data.events ) {
for ( var type in data.events ) { for ( var type in data.events ) {
if ( special[ type ] ) { if ( special[ type ] ) {
jQuery.event.remove( elem, type ); jQuery.event.remove( elem, type );
// This is a shortcut to avoid jQuery.event.remove's overhead
} else { } else {
jQuery.removeEvent( elem, type, data.handle ); jQuery.removeEvent( elem, type, data.handle );
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?php <?php
error_reporting(0); error_reporting(0);
$callback = $_REQUEST['callback']; $callback = $_REQUEST['callback'];
if ( ! $callback ) {
$callback = explode("?",end(explode("/",$_SERVER['REQUEST_URI'])));
$callback = $callback[0];
}
$json = $_REQUEST['json']; $json = $_REQUEST['json'];
if($json) { if($json) {
echo $callback . '([ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ])'; echo $callback . '([ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ])';
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
1.4.5pre 1.5pre
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment