AMD-ify jQuery sourcegit s! Woo! Fixes #14113, #14163.

This commit is contained in:
Timmy Willison 2013-08-15 14:15:49 -04:00
parent 7627b8b6d9
commit 6318ae6ab9
77 changed files with 27783 additions and 1580 deletions

2
.gitignore vendored
View File

@ -1,5 +1,3 @@
src/selector-sizzle.js
src/selector.js
dist dist
.project .project
.settings .settings

View File

@ -2,6 +2,9 @@ module.exports = function( grunt ) {
"use strict"; "use strict";
// Integrate build task
require( "./build/build" )( grunt );
var distpaths = [ var distpaths = [
"dist/jquery.js", "dist/jquery.js",
"dist/jquery.min.map", "dist/jquery.min.map",
@ -36,41 +39,19 @@ module.exports = function( grunt ) {
cache: "dist/.sizecache.json" cache: "dist/.sizecache.json"
} }
}, },
selector: {
destFile: "src/selector-sizzle.js",
apiFile: "src/sizzle-jquery.js",
srcFile: "bower_components/sizzle/dist/sizzle.js"
},
build: { build: {
all: { all: {
dest: "dist/jquery.js", dest: "dist/jquery.js",
src: [ minimum: [
"src/intro.js", "core",
"src/core.js", "selector"
{ flag: "sizzle", src: "src/selector-sizzle.js", alt: "src/selector-native.js" }, ],
"src/callbacks.js", // Exclude specified modules if the module matching the key is removed
"src/deferred.js", removeWith: {
"src/support.js", callbacks: [ "deferred" ],
"src/data.js", css: [ "effects", "dimensions", "offset" ],
"src/queue.js", sizzle: [ "css/hidden-visible-selectors", "effects/animated-selector" ]
"src/attributes.js", }
"src/event.js",
"src/traversing.js",
"src/manipulation.js",
{ flag: "wrap", src: "src/wrap.js" },
{ flag: "css", src: "src/css.js" },
"src/serialize.js",
{ flag: "event-alias", src: "src/event-alias.js" },
{ flag: "ajax", src: "src/ajax.js" },
{ flag: "ajax/script", src: "src/ajax/script.js", needs: ["ajax"] },
{ flag: "ajax/jsonp", src: "src/ajax/jsonp.js", needs: [ "ajax", "ajax/script" ] },
{ flag: "ajax/xhr", src: "src/ajax/xhr.js", needs: ["ajax"] },
{ flag: "effects", src: "src/effects.js", needs: ["css"] },
{ flag: "offset", src: "src/offset.js", needs: ["css"] },
{ flag: "dimensions", src: "src/dimensions.js", needs: ["css"] },
{ flag: "deprecated", src: "src/deprecated.js" },
"src/outro.js"
]
} }
}, },
jsonlint: { jsonlint: {
@ -87,7 +68,7 @@ module.exports = function( grunt ) {
options: srcHintOptions options: srcHintOptions
}, },
grunt: { grunt: {
src: [ "Gruntfile.js" ], src: [ "Gruntfile.js", "build/build.js" ],
options: { options: {
jshintrc: ".jshintrc" jshintrc: ".jshintrc"
} }
@ -140,10 +121,6 @@ module.exports = function( grunt ) {
join_vars: false, join_vars: false,
loops: false, loops: false,
unused: false unused: false
},
mangle: {
// saves some bytes when gzipped
except: [ "undefined" ]
} }
} }
} }
@ -208,252 +185,6 @@ module.exports = function( grunt ) {
); );
}); });
grunt.registerTask( "selector", "Build Sizzle-based selector module", function() {
var cfg = grunt.config("selector"),
name = cfg.destFile,
sizzle = {
api: grunt.file.read( cfg.apiFile ),
src: grunt.file.read( cfg.srcFile )
},
compiled, parts;
/**
sizzle-jquery.js -> sizzle between "EXPOSE" blocks,
replace define & window.Sizzle assignment
// EXPOSE
if ( typeof define === "function" && define.amd ) {
define(function() { return Sizzle; });
} else {
window.Sizzle = Sizzle;
}
// EXPOSE
Becomes...
Sizzle.attr = jQuery.attr;
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;
jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
*/
// Break into 3 pieces
parts = sizzle.src.split("// EXPOSE");
// Replace the if/else block with api
parts[1] = sizzle.api;
// Rejoin the pieces
compiled = parts.join("");
grunt.verbose.writeln("Injected " + cfg.apiFile + " into " + cfg.srcFile);
// Write concatenated source to file, and ensure newline-only termination
grunt.file.write( name, compiled.replace( /\x0d\x0a/g, "\x0a" ) );
// Fail task if errors were logged.
if ( this.errorCount ) {
return false;
}
// Otherwise, print a success message.
grunt.log.writeln( "File '" + name + "' created." );
});
// Special "alias" task to make custom build creation less grawlix-y
grunt.registerTask( "custom", function() {
var done = this.async(),
args = [].slice.call(arguments),
modules = args.length ? args[0].replace(/,/g, ":") : "";
// Translation example
//
// grunt custom:+ajax,-dimensions,-effects,-offset
//
// Becomes:
//
// grunt build:*:*:+ajax:-dimensions:-effects:-offset
grunt.log.writeln( "Creating custom build...\n" );
grunt.util.spawn({
grunt: true,
args: [ "build:*:*:" + modules, "pre-uglify", "uglify", "dist" ]
}, function( err, result ) {
if ( err ) {
grunt.verbose.error();
done( err );
return;
}
grunt.log.writeln( result.stdout.replace("Done, without errors.", "") );
done();
});
});
// Special concat/build task to handle various jQuery build requirements
grunt.registerMultiTask(
"build",
"Concatenate source (include/exclude modules with +/- flags), embed date/version",
function() {
// Concat specified files.
var compiled = "",
modules = this.flags,
optIn = !modules["*"],
explicit = optIn || Object.keys(modules).length > 1,
name = this.data.dest,
src = this.data.src,
deps = {},
excluded = {},
version = grunt.config( "pkg.version" ),
excluder = function( flag, needsFlag ) {
// optIn defaults implicit behavior to weak exclusion
if ( optIn && !modules[ flag ] && !modules[ "+" + flag ] ) {
excluded[ flag ] = false;
}
// explicit or inherited strong exclusion
if ( excluded[ needsFlag ] || modules[ "-" + flag ] ) {
excluded[ flag ] = true;
// explicit inclusion overrides weak exclusion
} else if ( excluded[ needsFlag ] === false &&
( modules[ flag ] || modules[ "+" + flag ] ) ) {
delete excluded[ needsFlag ];
// ...all the way down
if ( deps[ needsFlag ] ) {
deps[ needsFlag ].forEach(function( subDep ) {
modules[ needsFlag ] = true;
excluder( needsFlag, subDep );
});
}
}
};
// append commit id to version
if ( process.env.COMMIT ) {
version += " " + process.env.COMMIT;
}
// figure out which files to exclude based on these rules in this order:
// dependency explicit exclude
// > explicit exclude
// > explicit include
// > dependency implicit exclude
// > implicit exclude
// examples:
// * none (implicit exclude)
// *:* all (implicit include)
// *:*:-css all except css and dependents (explicit > implicit)
// *:*:-css:+effects same (excludes effects because explicit include is trumped by explicit exclude of dependency)
// *:+effects none except effects and its dependencies (explicit include trumps implicit exclude of dependency)
src.forEach(function( filepath ) {
var flag = filepath.flag;
if ( flag ) {
excluder(flag);
// check for dependencies
if ( filepath.needs ) {
deps[ flag ] = filepath.needs;
filepath.needs.forEach(function( needsFlag ) {
excluder( flag, needsFlag );
});
}
}
});
// append excluded modules to version
if ( Object.keys( excluded ).length ) {
version += " -" + Object.keys( excluded ).join( ",-" );
// set pkg.version to version with excludes, so minified file picks it up
grunt.config.set( "pkg.version", version );
}
// conditionally concatenate source
src.forEach(function( filepath ) {
var flag = filepath.flag,
specified = false,
omit = false,
messages = [];
if ( flag ) {
if ( excluded[ flag ] !== undefined ) {
messages.push([
( "Excluding " + flag ).red,
( "(" + filepath.src + ")" ).grey
]);
specified = true;
omit = !filepath.alt;
if ( !omit ) {
flag += " alternate";
filepath.src = filepath.alt;
}
}
if ( excluded[ flag ] === undefined ) {
messages.push([
( "Including " + flag ).green,
( "(" + filepath.src + ")" ).grey
]);
// If this module was actually specified by the
// builder, then set the flag to include it in the
// output list
if ( modules[ "+" + flag ] ) {
specified = true;
}
}
filepath = filepath.src;
// Only display the inclusion/exclusion list when handling
// an explicit list.
//
// Additionally, only display modules that have been specified
// by the user
if ( explicit && specified ) {
messages.forEach(function( message ) {
grunt.log.writetableln( [ 27, 30 ], message );
});
}
}
if ( !omit ) {
compiled += grunt.file.read( filepath );
}
});
// Embed Version
// Embed Date
compiled = compiled.replace( /@VERSION/g, version )
// yyyy-mm-ddThh:mmZ
.replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );
// Write concatenated source to file
grunt.file.write( name, compiled );
// Fail task if errors were logged.
if ( this.errorCount ) {
return false;
}
// Otherwise, print a success message.
grunt.log.writeln( "File '" + name + "' created." );
});
// Process files for distribution // Process files for distribution
grunt.registerTask( "dist", function() { grunt.registerTask( "dist", function() {
var stored, flags, paths, nonascii; var stored, flags, paths, nonascii;
@ -545,7 +276,7 @@ module.exports = function( grunt ) {
// Strip banners // Strip banners
return contents return contents
// Remove the main jQuery banner, it'll be replaced by the new banner anyway. // Remove the main jQuery banner, it'll be replaced by the new banner anyway.
.replace( /^\/\*!(?:.|\n)*?\*\/\n?/g, "" ) .replace( /^\/\*![\W\w]*?\*\/\n?/g, "" )
// Strip other banners preserving line count. // Strip other banners preserving line count.
.replace( /^\/\*!(?:.|\n)*?\*\/\n?/gm, function ( match ) { .replace( /^\/\*!(?:.|\n)*?\*\/\n?/gm, function ( match ) {
return match.replace( /[^\n]/gm, "" ); return match.replace( /[^\n]/gm, "" );
@ -590,7 +321,7 @@ module.exports = function( grunt ) {
grunt.loadNpmTasks("grunt-jsonlint"); grunt.loadNpmTasks("grunt-jsonlint");
// Short list as a high frequency watch task // Short list as a high frequency watch task
grunt.registerTask( "dev", [ "selector", "build:*:*", "jshint" ] ); grunt.registerTask( "dev", [ "build:*:*", "jshint" ] );
// Default grunt // Default grunt
grunt.registerTask( "default", [ "jsonlint", "dev", "pre-uglify", "uglify", "post-uglify", "dist:*", "compare_size" ] ); grunt.registerTask( "default", [ "jsonlint", "dev", "pre-uglify", "uglify", "post-uglify", "dist:*", "compare_size" ] );

View File

@ -67,22 +67,36 @@ The built version of jQuery will be put in the `dist/` subdirectory, along with
Special builds can be created that exclude subsets of jQuery functionality. Special builds can be created that exclude subsets of jQuery functionality.
This allows for smaller custom builds when the builder is certain that those parts of jQuery are not being used. This allows for smaller custom builds when the builder is certain that those parts of jQuery are not being used.
For example, an app that only used JSONP for `$.ajax()` and did not need to calculate offsets or positions of elements could exclude the offset and ajax/xhr modules. The current modules that can be excluded are: For example, an app that only used JSONP for `$.ajax()` and did not need to calculate offsets or positions of elements could exclude the offset and ajax/xhr modules.
Any module may be excluded except for `core`, and `selector`. To exclude a module, pass its path relative to the `src` folder (without the `.js` extension).
Some example modules that can be excluded are:
- **ajax**: All AJAX functionality: `$.ajax()`, `$.get()`, `$.post()`, `$.ajaxSetup()`, `.load()`, transports, and ajax event shorthands such as `.ajaxStart()`. - **ajax**: All AJAX functionality: `$.ajax()`, `$.get()`, `$.post()`, `$.ajaxSetup()`, `.load()`, transports, and ajax event shorthands such as `.ajaxStart()`.
- **ajax/xhr**: The XMLHTTPRequest AJAX transport only. - **ajax/xhr**: The XMLHTTPRequest AJAX transport only.
- **ajax/script**: The `<script>` AJAX transport only; used to retrieve scripts. - **ajax/script**: The `<script>` AJAX transport only; used to retrieve scripts.
- **ajax/jsonp**: The JSONP AJAX transport only; depends on the ajax/script transport. - **ajax/jsonp**: The JSONP AJAX transport only; depends on the ajax/script transport.
- **css**: The `.css()` method plus non-animated `.show()`, `.hide()` and `.toggle()`. - **css**: The `.css()` method plus non-animated `.show()`, `.hide()` and `.toggle()`. Also removes **all** modules depending on css (including **effects**, **dimensions**, and **offset**).
- **deprecated**: Methods documented as deprecated but not yet removed; currently only `.andSelf()`. - **deprecated**: Methods documented as deprecated but not yet removed; currently only `.andSelf()`.
- **dimensions**: The `.width()` and `.height()` methods, including `inner-` and `outer-` variations. - **dimensions**: The `.width()` and `.height()` methods, including `inner-` and `outer-` variations.
- **effects**: The `.animate()` method and its shorthands such as `.slideUp()` or `.hide("slow")`. - **effects**: The `.animate()` method and its shorthands such as `.slideUp()` or `.hide("slow")`.
- **event-alias**: All event attaching/triggering shorthands like `.click()` or `.mouseover()`. - **event**: The `.on()` and `.off()` methods and all event functionality. Also removes `event/alias`.
- **event/alias**: All event attaching/triggering shorthands like `.click()` or `.mouseover()`.
- **offset**: The `.offset()`, `.position()`, `.offsetParent()`, `.scrollLeft()`, and `.scrollTop()` methods. - **offset**: The `.offset()`, `.position()`, `.offsetParent()`, `.scrollLeft()`, and `.scrollTop()` methods.
- **wrap**: The `.wrap()`, `.wrapAll()`, `.wrapInner()`, and `.unwrap()` methods. - **wrap**: The `.wrap()`, `.wrapAll()`, `.wrapInner()`, and `.unwrap()` methods.
- **exports/amd**: Exclude the AMD definition.
- **core/ready**: Exclude the ready module if you place your scripts at the end of the body. Any ready callbacks will simply be called immediately.
- **deferred**: Exclude jQuery.Deferred. This also removes jQuery.Callbacks. *Note* that modules that depend on jQuery.Deferred(AJAX, effects, core/ready) will not be removed and will still expect jQuery.Deferred to be there. Include your own jQuery.Deferred implementation or exclude those modules as well (`grunt custom:-deferred,-ajax,-effects,-core/ready`).
- **support**: Excluding the support module is not recommended, but possible. It's your responsibility to either remove modules that use jQuery.support (many of them) or replace the values wherever jQuery.support is used. This is mainly only useful when building a barebones version of jQuery.
As a special case, you may also replace Sizzle by using a special flag `grunt custom:-sizzle`.
- **sizzle**: The Sizzle selector engine. When this module is excluded, it is replaced by a rudimentary selector engine based on the browser's `querySelectorAll` method that does not support jQuery selector extensions or enhanced semantics. See the selector-native.js file for details. - **sizzle**: The Sizzle selector engine. When this module is excluded, it is replaced by a rudimentary selector engine based on the browser's `querySelectorAll` method that does not support jQuery selector extensions or enhanced semantics. See the selector-native.js file for details.
The grunt build process is aware of dependencies across modules. If you explicitly remove a module, its dependent modules will be removed as well. For example, excluding the css module also excludes effects, since the effects module uses `.css()` to animate CSS properties. These dependencies are listed in Gruntfile.js and the build process shows a message for each dependent module it excludes. *Note*: Excluding Sizzle will also exclude all jQuery selector extensions (such as `effects/animated-selector` and `css/hidden-visible-selectors`).
The build process shows a message for each dependent module it excludes or includes.
To create a custom build of the latest stable version, first check out the version: To create a custom build of the latest stable version, first check out the version:
@ -104,16 +118,16 @@ Exclude all **ajax** functionality:
grunt custom:-ajax grunt custom:-ajax
``` ```
Exclude **css**, **effects**, **offset**, **dimensions**, and **position**. Excluding **css** automatically excludes its dependent modules: Excluding **css** removes modules depending on CSS: **effects**, **offset**, **dimensions**.
```bash ```bash
grunt custom:-css,-position grunt custom:-css
``` ```
Exclude **all** optional modules and use the `querySelectorAll`-based selector engine: Exclude a bunch of modules:
```bash ```bash
grunt custom:-ajax,-css,-deprecated,-dimensions,-effects,-event-alias,-offset,-wrap,-sizzle grunt custom:-ajax,-css,-deprecated,-dimensions,-effects,-event/alias,-offset,-wrap
``` ```
For questions or requests regarding custom builds, please start a thread on the [Developing jQuery Core](https://forum.jquery.com/developing-jquery-core) section of the forum. Due to the combinatorics and custom nature of these builds, they are not regularly tested in jQuery's unit test process. The non-Sizzle selector engine currently does not pass unit tests because it is missing too much essential functionality. For questions or requests regarding custom builds, please start a thread on the [Developing jQuery Core](https://forum.jquery.com/developing-jquery-core) section of the forum. Due to the combinatorics and custom nature of these builds, they are not regularly tested in jQuery's unit test process. The non-Sizzle selector engine currently does not pass unit tests because it is missing too much essential functionality.

View File

@ -11,7 +11,8 @@
"bower.json" "bower.json"
], ],
"dependencies": { "dependencies": {
"sizzle": "~1.10.5" "sizzle": "~1.10.5",
"requirejs": "~2.1.8"
}, },
"devDependencies": { "devDependencies": {
"qunit": "~1.12.0" "qunit": "~1.12.0"

238
build/build.js Normal file
View File

@ -0,0 +1,238 @@
/**
* Special concat/build task to handle various jQuery build requirements
* Concats AMD modules, removes their definitions, and includes/excludes specified modules
*/
module.exports = function( grunt ) {
var fs = require("fs"),
srcFolder = __dirname + "/../src/",
rdefineEnd = /\}\);[^}\w]*$/,
// This is temporary until the skipSemiColonInsertion option makes it to NPM
requirejs = require("./r"),
config = {
baseUrl: "src",
name: "jquery",
out: "dist/jquery.js",
// We have multiple minify steps
optimize: "none",
skipSemiColonInsertion: true,
wrap: {
startFile: "src/intro.js",
endFile: "src/outro.js"
},
onBuildWrite: convert
};
/**
* Strip all definitions generated by requirejs
* Convert "var" modules to var declarations
* "var module" means the module only contains a return statement that should be converted to a var declaration
* This is indicated by including the file in any "var" folder
* @param {String} name
* @param {String} path
* @param {String} contents The contents to be written (including their AMD wrappers)
*/
function convert( name, path, contents ) {
// Convert var modules
if ( /\/var\//.test( path ) ) {
contents = contents
.replace( /define\([\w\W]*?return/, "var " + (/var\/([\w-]+)/.exec(name)[1]) + " =" )
.replace( rdefineEnd, "" );
// Sizzle treatment
} else if ( /\/sizzle$/.test( name ) ) {
contents = "var Sizzle =\n" + contents
// Remove EXPOSE lines from Sizzle
.replace( /\/\/\s*EXPOSE[\w\W]*\/\/\s*EXPOSE/, "return Sizzle;" );
} else {
// Ignore jQuery's return statement (the only necessary one)
if ( name !== "jquery" ) {
contents = contents
.replace( /return\s+[^\}]+(\}\);[^\w\}]*)$/, "$1" );
}
// Remove define wrappers, closure ends, and empty declarations
contents = contents
.replace( /define\([^{]*?{/, "" )
.replace( rdefineEnd, "" )
// Remove empty definitions
.replace( /define\(\[[^\]]+\]\)[\W\n]+$/, "" );
}
return contents;
}
grunt.registerMultiTask(
"build",
"Concatenate source, remove sub AMD definitions, (include/exclude modules with +/- flags), embed date/version",
function() {
var flag, index,
done = this.async(),
flags = this.flags,
name = this.data.dest,
minimum = this.data.minimum,
removeWith = this.data.removeWith,
excluded = [],
included = [],
version = grunt.config( "pkg.version" ),
/**
* Recursively calls the excluder to remove on all modules in the list
* @param {Array} list
* @param {String} [prepend] Prepend this to the module name. Indicates we're walking a directory
*/
excludeList = function( list, prepend ) {
if ( list ) {
prepend = prepend ? prepend + "/" : "";
list.forEach(function( module ) {
// Exclude var modules as well
if ( module === "var" ) {
excludeList( fs.readdirSync( srcFolder + prepend + module ), prepend + module );
return;
}
if ( prepend ) {
// Skip if this is not a js file and we're walking files in a dir
if ( !(module = /([\w-\/]+)\.js$/.exec( module )) ) {
return;
}
// Prepend folder name if passed
// Remove .js extension
module = prepend + module[1];
}
// Avoid infinite recursion
if ( excluded.indexOf( module ) === -1 ) {
excluder( "-" + module );
}
});
}
},
/**
* Adds the specified module to the excluded or included list, depending on the flag
* @param {String} flag A module path relative to the src directory starting with + or - to indicate whether it should included or excluded
*/
excluder = function( flag ) {
var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
exclude = m[1] === "-",
module = m[2];
if ( exclude ) {
// Can't exclude certain modules
if ( minimum.indexOf( module ) === -1 ) {
// Add to excluded
if ( excluded.indexOf( module ) === -1 ) {
grunt.log.writeln( flag );
excluded.push( module );
// Exclude all files in the folder of the same name
// These are the removable dependencies
// It's fine if the directory is not there
try {
excludeList( fs.readdirSync( srcFolder + module ), module );
} catch( e ) {
grunt.verbose.writeln( e );
}
}
// Check removeWith list
excludeList( removeWith[ module ] );
} else {
grunt.log.error( "Module \"" + module + "\" is a mimimum requirement.");
if ( module === "selector" ) {
grunt.log.error( "If you meant to replace Sizzle, use -sizzle instead." );
}
}
} else {
grunt.log.writeln( flag );
included.push( module );
}
};
// append commit id to version
if ( process.env.COMMIT ) {
version += " " + process.env.COMMIT;
}
// figure out which files to exclude based on these rules in this order:
// dependency explicit exclude
// > explicit exclude
// > explicit include
// > dependency implicit exclude
// > implicit exclude
// examples:
// * none (implicit exclude)
// *:* all (implicit include)
// *:*:-css all except css and dependents (explicit > implicit)
// *:*:-css:+effects same (excludes effects because explicit include is trumped by explicit exclude of dependency)
// *:+effects none except effects and its dependencies (explicit include trumps implicit exclude of dependency)
for ( flag in flags ) {
if ( flag !== "*" ) {
excluder( flag );
}
}
// Handle Sizzle exclusion
// Replace with selector-native
if ( (index = excluded.indexOf("sizzle")) > -1 ) {
config.rawText = {
selector: "define(['./selector-native']);"
};
excluded.splice( index, 1 );
}
grunt.verbose.writeflags( excluded, "Excluded" );
grunt.verbose.writeflags( included, "Included" );
// append excluded modules to version
if ( excluded.length ) {
version += " -" + excluded.join( ",-" );
// set pkg.version to version with excludes, so minified file picks it up
grunt.config.set( "pkg.version", version );
grunt.verbose.writeln( "Version changed to " + version );
// Have to use shallow or core will get excluded since it is a dependency
config.excludeShallow = excluded;
}
config.include = included;
/**
* Handle Final output from the optimizer
* @param {String} compiled
*/
config.out = function( compiled ) {
compiled = compiled
// Embed Version
.replace( /@VERSION/g, version )
// Embed Date
// yyyy-mm-ddThh:mmZ
.replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );
// Write concatenated source to file
grunt.file.write( name, compiled );
};
// Trace dependencies and concatenate files
requirejs.optimize( config, function( response ) {
grunt.verbose.writeln( response );
grunt.log.ok( "File '" + name + "' created." );
done();
}, function( err ) {
done( err );
});
});
// Special "alias" task to make custom build creation less grawlix-y
// Translation example
//
// grunt custom:+ajax,-dimensions,-effects,-offset
//
// Becomes:
//
// grunt build:*:*:+ajax:-dimensions:-effects:-offset
grunt.registerTask( "custom", function() {
var args = [].slice.call(arguments),
modules = args.length ? args[0].replace(/,/g, ":") : "";
grunt.log.writeln( "Creating custom build...\n" );
grunt.task.run([ "build:*:*:" + modules, "pre-uglify", "uglify", "dist" ]);
});
};

25762
build/r.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,11 @@
"type": "git", "type": "git",
"url": "https://github.com/jquery/jquery.git" "url": "https://github.com/jquery/jquery.git"
}, },
"keywords": [
"jquery",
"javascript",
"library"
],
"bugs": { "bugs": {
"url": "http://bugs.jquery.com" "url": "http://bugs.jquery.com"
}, },
@ -32,12 +37,10 @@
"gzip-js": "0.3.2", "gzip-js": "0.3.2",
"testswarm": "~1.1.0", "testswarm": "~1.1.0",
"archiver": "~0.4.6", "archiver": "~0.4.6",
"grunt-jsonlint": "~1.0.0" "grunt-jsonlint": "~1.0.0",
"requirejs": "~2.1.8"
}, },
"scripts": { "scripts": {
"install": "bower install" "install": "bower install"
}, }
"keywords": []
} }

View File

@ -1,11 +1,16 @@
define([
"./core",
"./var/rnotwhite",
"./ajax/var/nonce",
"./ajax/var/rquery",
"./deferred"
], function( jQuery, rnotwhite, nonce, rquery ) {
var var
// Document location // Document location
ajaxLocParts, ajaxLocParts,
ajaxLocation, ajaxLocation,
ajax_nonce = jQuery.now(),
ajax_rquery = /\?/,
rhash = /#.*$/, rhash = /#.*$/,
rts = /([?&])_=[^&]*/, rts = /([?&])_=[^&]*/,
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
@ -15,9 +20,6 @@ var
rprotocol = /^\/\//, rprotocol = /^\/\//,
rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
// Keep a copy of the old load method
_load = jQuery.fn.load,
/* Prefilters /* Prefilters
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
* 2) These are called: * 2) These are called:
@ -67,7 +69,7 @@ function addToPrefiltersOrTransports( structure ) {
var dataType, var dataType,
i = 0, i = 0,
dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || []; dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
if ( jQuery.isFunction( func ) ) { if ( jQuery.isFunction( func ) ) {
// For each dataType in the dataTypeExpression // For each dataType in the dataTypeExpression
@ -130,63 +132,6 @@ function ajaxExtend( target, src ) {
return target; return target;
} }
jQuery.fn.load = function( url, params, callback ) {
if ( typeof url !== "string" && _load ) {
return _load.apply( this, arguments );
}
var selector, type, response,
self = this,
off = url.indexOf(" ");
if ( off >= 0 ) {
selector = url.slice( off );
url = url.slice( 0, off );
}
// If it's a function
if ( jQuery.isFunction( params ) ) {
// We assume that it's the callback
callback = params;
params = undefined;
// Otherwise, build a param string
} else if ( params && typeof params === "object" ) {
type = "POST";
}
// If we have elements to modify, make the request
if ( self.length > 0 ) {
jQuery.ajax({
url: url,
// if "type" variable is undefined, then "GET" method will be used
type: type,
dataType: "html",
data: params
}).done(function( responseText ) {
// Save response for use in complete callback
response = arguments;
self.html( selector ?
// If a selector was specified, locate the right elements in a dummy div
// Exclude scripts to avoid IE 'Permission Denied' errors
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
// Otherwise use the full result
responseText );
}).complete( callback && function( jqXHR, status ) {
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
});
}
return this;
};
// Attach a bunch of functions for handling common AJAX events // Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){ jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
jQuery.fn[ type ] = function( fn ){ jQuery.fn[ type ] = function( fn ){
@ -418,7 +363,7 @@ jQuery.extend({
s.type = options.method || options.type || s.method || s.type; s.type = options.method || options.type || s.method || s.type;
// Extract dataTypes list // Extract dataTypes list
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""]; s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [""];
// A cross-domain request is in order when we have a protocol:host:port mismatch // A cross-domain request is in order when we have a protocol:host:port mismatch
if ( s.crossDomain == null ) { if ( s.crossDomain == null ) {
@ -466,7 +411,7 @@ jQuery.extend({
// If data is available, append data to url // If data is available, append data to url
if ( s.data ) { if ( s.data ) {
cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
// #9682: remove data so that it's not used in an eventual retry // #9682: remove data so that it's not used in an eventual retry
delete s.data; delete s.data;
} }
@ -476,10 +421,10 @@ jQuery.extend({
s.url = rts.test( cacheURL ) ? s.url = rts.test( cacheURL ) ?
// If there is already a '_' parameter, set its value // If there is already a '_' parameter, set its value
cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) : cacheURL.replace( rts, "$1_=" + nonce++ ) :
// Otherwise add one to the end // Otherwise add one to the end
cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++; cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
} }
} }
@ -853,3 +798,6 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) {
return { state: "success", data: response }; return { state: "success", data: response };
} }
return jQuery;
});

View File

@ -1,3 +1,10 @@
define([
"../core",
"./var/nonce",
"./var/rquery",
"../ajax"
], function( jQuery, nonce, rquery ) {
var oldCallbacks = [], var oldCallbacks = [],
rjsonp = /(=)\?(?=&|$)|\?\?/; rjsonp = /(=)\?(?=&|$)|\?\?/;
@ -5,7 +12,7 @@ var oldCallbacks = [],
jQuery.ajaxSetup({ jQuery.ajaxSetup({
jsonp: "callback", jsonp: "callback",
jsonpCallback: function() { jsonpCallback: function() {
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) ); var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
this[ callback ] = true; this[ callback ] = true;
return callback; return callback;
} }
@ -32,7 +39,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
if ( jsonProp ) { if ( jsonProp ) {
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
} else if ( s.jsonp !== false ) { } else if ( s.jsonp !== false ) {
s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
} }
// Use data converter to retrieve json after script execution // Use data converter to retrieve json after script execution
@ -78,3 +85,5 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
return "script"; return "script";
} }
}); });
});

71
src/ajax/load.js Normal file
View File

@ -0,0 +1,71 @@
define([
"../core",
"../ajax",
"../traversing",
"../selector"
], function( jQuery ) {
// Keep a copy of the old load method
var _load = jQuery.fn.load;
/**
* Load a url into a page
*/
jQuery.fn.load = function( url, params, callback ) {
if ( typeof url !== "string" && _load ) {
return _load.apply( this, arguments );
}
var selector, type, response,
self = this,
off = url.indexOf(" ");
if ( off >= 0 ) {
selector = url.slice( off );
url = url.slice( 0, off );
}
// If it's a function
if ( jQuery.isFunction( params ) ) {
// We assume that it's the callback
callback = params;
params = undefined;
// Otherwise, build a param string
} else if ( params && typeof params === "object" ) {
type = "POST";
}
// If we have elements to modify, make the request
if ( self.length > 0 ) {
jQuery.ajax({
url: url,
// if "type" variable is undefined, then "GET" method will be used
type: type,
dataType: "html",
data: params
}).done(function( responseText ) {
// Save response for use in complete callback
response = arguments;
self.html( selector ?
// If a selector was specified, locate the right elements in a dummy div
// Exclude scripts to avoid IE 'Permission Denied' errors
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
// Otherwise use the full result
responseText );
}).complete( callback && function( jqXHR, status ) {
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
});
}
return this;
};
});

View File

@ -1,3 +1,8 @@
define([
"../core",
"../ajax"
], function( jQuery ) {
// Install script dataType // Install script dataType
jQuery.ajaxSetup({ jQuery.ajaxSetup({
accepts: { accepts: {
@ -55,3 +60,5 @@ jQuery.ajaxTransport( "script", function( s ) {
}; };
} }
}); });
});

5
src/ajax/var/nonce.js Normal file
View File

@ -0,0 +1,5 @@
define([
"../../core"
], function( jQuery ) {
return jQuery.now();
});

3
src/ajax/var/rquery.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return /\?/;
});

View File

@ -1,3 +1,8 @@
define([
"../core",
"../ajax"
], function( jQuery ) {
jQuery.ajaxSettings.xhr = function() { jQuery.ajaxSettings.xhr = function() {
try { try {
return new XMLHttpRequest(); return new XMLHttpRequest();
@ -109,3 +114,5 @@ jQuery.ajaxTransport(function( options ) {
}; };
} }
}); });
});

View File

@ -1,502 +1,6 @@
var nodeHook, boolHook, define([
rclass = /[\t\r\n\f]/g, "./attributes/attr",
rreturn = /\r/g, "./attributes/prop",
rfocusable = /^(?:input|select|textarea|button)$/i; "./attributes/classes",
"./attributes/val"
jQuery.fn.extend({ ]);
attr: function( name, value ) {
return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
},
removeAttr: function( name ) {
return this.each(function() {
jQuery.removeAttr( this, name );
});
},
prop: function( name, value ) {
return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
},
removeProp: function( name ) {
return this.each(function() {
delete this[ jQuery.propFix[ name ] || name ];
});
},
addClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,
proceed = typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).addClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
// The disjunction here is for better compressibility (see removeClass)
classes = ( value || "" ).match( core_rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
cur += clazz + " ";
}
}
elem.className = jQuery.trim( cur );
}
}
}
return this;
},
removeClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,
proceed = arguments.length === 0 || typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).removeClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
classes = ( value || "" ).match( core_rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
// This expression is here for better compressibility (see addClass)
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
""
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
// Remove *all* instances
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
cur = cur.replace( " " + clazz + " ", " " );
}
}
elem.className = value ? jQuery.trim( cur ) : "";
}
}
}
return this;
},
toggleClass: function( value, stateVal ) {
var type = typeof value;
if ( typeof stateVal === "boolean" && type === "string" ) {
return stateVal ? this.addClass( value ) : this.removeClass( value );
}
if ( jQuery.isFunction( value ) ) {
return this.each(function( i ) {
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
});
}
return this.each(function() {
if ( type === "string" ) {
// toggle individual class names
var className,
i = 0,
self = jQuery( this ),
classNames = value.match( core_rnotwhite ) || [];
while ( (className = classNames[ i++ ]) ) {
// check each className given, space separated list
if ( self.hasClass( className ) ) {
self.removeClass( className );
} else {
self.addClass( className );
}
}
// Toggle whole class name
} else if ( type === core_strundefined || type === "boolean" ) {
if ( this.className ) {
// store className if set
data_priv.set( this, "__className__", this.className );
}
// If the element has a class name or if we're passed "false",
// then remove the whole classname (if there was one, the above saved it).
// Otherwise bring back whatever was previously saved (if anything),
// falling back to the empty string if nothing was stored.
this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
}
});
},
hasClass: function( selector ) {
var className = " " + selector + " ",
i = 0,
l = this.length;
for ( ; i < l; i++ ) {
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
return true;
}
}
return false;
},
val: function( value ) {
var hooks, ret, isFunction,
elem = this[0];
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
return ret;
}
ret = elem.value;
return typeof ret === "string" ?
// handle most common string cases
ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
ret == null ? "" : ret;
}
return;
}
isFunction = jQuery.isFunction( value );
return this.each(function( i ) {
var val;
if ( this.nodeType !== 1 ) {
return;
}
if ( isFunction ) {
val = value.call( this, i, jQuery( this ).val() );
} else {
val = value;
}
// Treat null/undefined as ""; convert numbers to string
if ( val == null ) {
val = "";
} else if ( typeof val === "number" ) {
val += "";
} else if ( jQuery.isArray( val ) ) {
val = jQuery.map(val, function ( value ) {
return value == null ? "" : value + "";
});
}
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
// If set returns undefined, fall back to normal setting
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
this.value = val;
}
});
}
});
jQuery.extend({
valHooks: {
option: {
get: function( elem ) {
// attributes.value is undefined in Blackberry 4.7 but
// uses .value. See #6932
var val = elem.attributes.value;
return !val || val.specified ? elem.value : elem.text;
}
},
select: {
get: function( elem ) {
var value, option,
options = elem.options,
index = elem.selectedIndex,
one = elem.type === "select-one" || index < 0,
values = one ? null : [],
max = one ? index + 1 : options.length,
i = index < 0 ?
max :
one ? index : 0;
// Loop through all the selected options
for ( ; i < max; i++ ) {
option = options[ i ];
// IE6-9 doesn't update selected after form reset (#2551)
if ( ( option.selected || i === index ) &&
// Don't return options that are disabled or in a disabled optgroup
( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
// Get the specific value for the option
value = jQuery( option ).val();
// We don't need an array for one selects
if ( one ) {
return value;
}
// Multi-Selects return an array
values.push( value );
}
}
return values;
},
set: function( elem, value ) {
var optionSet, option,
options = elem.options,
values = jQuery.makeArray( value ),
i = options.length;
while ( i-- ) {
option = options[ i ];
if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
optionSet = true;
}
}
// force browsers to behave consistently when non-matching value is set
if ( !optionSet ) {
elem.selectedIndex = -1;
}
return values;
}
}
},
attr: function( elem, name, value ) {
var hooks, ret,
nType = elem.nodeType;
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
// Fallback to prop when attributes are not supported
if ( typeof elem.getAttribute === core_strundefined ) {
return jQuery.prop( elem, name, value );
}
// All attributes are lowercase
// Grab necessary hook if one is defined
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
name = name.toLowerCase();
hooks = jQuery.attrHooks[ name ] ||
( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
}
if ( value !== undefined ) {
if ( value === null ) {
jQuery.removeAttr( elem, name );
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
elem.setAttribute( name, value + "" );
return value;
}
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
return ret;
} else {
ret = jQuery.find.attr( elem, name );
// Non-existent attributes return null, we normalize to undefined
return ret == null ?
undefined :
ret;
}
},
removeAttr: function( elem, value ) {
var name, propName,
i = 0,
attrNames = value && value.match( core_rnotwhite );
if ( attrNames && elem.nodeType === 1 ) {
while ( (name = attrNames[i++]) ) {
propName = jQuery.propFix[ name ] || name;
// Boolean attributes get special treatment (#10870)
if ( jQuery.expr.match.bool.test( name ) ) {
// Set corresponding property to false
elem[ propName ] = false;
}
elem.removeAttribute( name );
}
}
},
attrHooks: {
type: {
set: function( elem, value ) {
if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
// Setting the type on a radio button after the value resets the value in IE6-9
// Reset value to default in case type is set after value during creation
var val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
elem.value = val;
}
return value;
}
}
}
},
propFix: {
"for": "htmlFor",
"class": "className"
},
prop: function( elem, name, value ) {
var ret, hooks, notxml,
nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
if ( notxml ) {
// Fix name and attach hooks
name = jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ];
}
if ( value !== undefined ) {
return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
ret :
( elem[ name ] = value );
} else {
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
ret :
elem[ name ];
}
},
propHooks: {
tabIndex: {
get: function( elem ) {
return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
elem.tabIndex :
-1;
}
}
}
});
// Hooks for boolean attributes
boolHook = {
set: function( elem, value, name ) {
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
} else {
elem.setAttribute( name, name );
}
return name;
}
};
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) {
var fn = jQuery.expr.attrHandle[ name ],
ret = isXML ?
undefined :
/* jshint eqeqeq: false */
// Temporarily disable this handler to check existence
(jQuery.expr.attrHandle[ name ] = undefined) !=
getter( elem, name, isXML ) ?
name.toLowerCase() :
null;
// Restore handler
jQuery.expr.attrHandle[ name ] = fn;
return ret;
};
});
// Support: IE9+
// Selectedness for an option in an optgroup can be inaccurate
if ( !jQuery.support.optSelected ) {
jQuery.propHooks.selected = {
get: function( elem ) {
var parent = elem.parentNode;
if ( parent && parent.parentNode ) {
parent.parentNode.selectedIndex;
}
return null;
}
};
}
jQuery.each([
"tabIndex",
"readOnly",
"maxLength",
"cellSpacing",
"cellPadding",
"rowSpan",
"colSpan",
"useMap",
"frameBorder",
"contentEditable"
], function() {
jQuery.propFix[ this.toLowerCase() ] = this;
});
// Radios and checkboxes getter/setter
jQuery.each([ "radio", "checkbox" ], function() {
jQuery.valHooks[ this ] = {
set: function( elem, value ) {
if ( jQuery.isArray( value ) ) {
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
}
}
};
if ( !jQuery.support.checkOn ) {
jQuery.valHooks[ this ].get = function( elem ) {
// Support: Webkit
// "" is returned instead of "on" if a value isn't specified
return elem.getAttribute("value") === null ? "on" : elem.value;
};
}
});

143
src/attributes/attr.js Normal file
View File

@ -0,0 +1,143 @@
define([
"../core",
"../var/rnotwhite",
"../var/strundefined",
"../selector"
], function( jQuery, rnotwhite, strundefined ) {
var nodeHook, boolHook;
jQuery.fn.extend({
attr: function( name, value ) {
return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
},
removeAttr: function( name ) {
return this.each(function() {
jQuery.removeAttr( this, name );
});
}
});
jQuery.extend({
attr: function( elem, name, value ) {
var hooks, ret,
nType = elem.nodeType;
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
// Fallback to prop when attributes are not supported
if ( typeof elem.getAttribute === strundefined ) {
return jQuery.prop( elem, name, value );
}
// All attributes are lowercase
// Grab necessary hook if one is defined
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
name = name.toLowerCase();
hooks = jQuery.attrHooks[ name ] ||
( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
}
if ( value !== undefined ) {
if ( value === null ) {
jQuery.removeAttr( elem, name );
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
elem.setAttribute( name, value + "" );
return value;
}
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
return ret;
} else {
ret = jQuery.find.attr( elem, name );
// Non-existent attributes return null, we normalize to undefined
return ret == null ?
undefined :
ret;
}
},
removeAttr: function( elem, value ) {
var name, propName,
i = 0,
attrNames = value && value.match( rnotwhite );
if ( attrNames && elem.nodeType === 1 ) {
while ( (name = attrNames[i++]) ) {
propName = jQuery.propFix[ name ] || name;
// Boolean attributes get special treatment (#10870)
if ( jQuery.expr.match.bool.test( name ) ) {
// Set corresponding property to false
elem[ propName ] = false;
}
elem.removeAttribute( name );
}
}
},
attrHooks: {
type: {
set: function( elem, value ) {
if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
// Setting the type on a radio button after the value resets the value in IE6-9
// Reset value to default in case type is set after value during creation
var val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
elem.value = val;
}
return value;
}
}
}
}
});
// Hooks for boolean attributes
boolHook = {
set: function( elem, value, name ) {
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
} else {
elem.setAttribute( name, name );
}
return name;
}
};
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) {
var fn = jQuery.expr.attrHandle[ name ],
ret = isXML ?
undefined :
/* jshint eqeqeq: false */
// Temporarily disable this handler to check existence
(jQuery.expr.attrHandle[ name ] = undefined) !=
getter( elem, name, isXML ) ?
name.toLowerCase() :
null;
// Restore handler
jQuery.expr.attrHandle[ name ] = fn;
return ret;
};
});
});

148
src/attributes/classes.js Normal file
View File

@ -0,0 +1,148 @@
define([
"../core",
"../var/rnotwhite",
"../var/strundefined",
"../data/var/data_priv"
], function( jQuery, rnotwhite, strundefined, data_priv ) {
var rclass = /[\t\r\n\f]/g;
jQuery.fn.extend({
addClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,
proceed = typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).addClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
// The disjunction here is for better compressibility (see removeClass)
classes = ( value || "" ).match( rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
cur += clazz + " ";
}
}
elem.className = jQuery.trim( cur );
}
}
}
return this;
},
removeClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,
proceed = arguments.length === 0 || typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).removeClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
classes = ( value || "" ).match( rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
// This expression is here for better compressibility (see addClass)
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
""
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
// Remove *all* instances
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
cur = cur.replace( " " + clazz + " ", " " );
}
}
elem.className = value ? jQuery.trim( cur ) : "";
}
}
}
return this;
},
toggleClass: function( value, stateVal ) {
var type = typeof value;
if ( typeof stateVal === "boolean" && type === "string" ) {
return stateVal ? this.addClass( value ) : this.removeClass( value );
}
if ( jQuery.isFunction( value ) ) {
return this.each(function( i ) {
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
});
}
return this.each(function() {
if ( type === "string" ) {
// toggle individual class names
var className,
i = 0,
self = jQuery( this ),
classNames = value.match( rnotwhite ) || [];
while ( (className = classNames[ i++ ]) ) {
// check each className given, space separated list
if ( self.hasClass( className ) ) {
self.removeClass( className );
} else {
self.addClass( className );
}
}
// Toggle whole class name
} else if ( type === strundefined || type === "boolean" ) {
if ( this.className ) {
// store className if set
data_priv.set( this, "__className__", this.className );
}
// If the element has a class name or if we're passed "false",
// then remove the whole classname (if there was one, the above saved it).
// Otherwise bring back whatever was previously saved (if anything),
// falling back to the empty string if nothing was stored.
this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
}
});
},
hasClass: function( selector ) {
var className = " " + selector + " ",
i = 0,
l = this.length;
for ( ; i < l; i++ ) {
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
return true;
}
}
return false;
}
});
});

94
src/attributes/prop.js Normal file
View File

@ -0,0 +1,94 @@
define([
"../core"
], function( jQuery ) {
var rfocusable = /^(?:input|select|textarea|button)$/i;
jQuery.fn.extend({
prop: function( name, value ) {
return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
},
removeProp: function( name ) {
return this.each(function() {
delete this[ jQuery.propFix[ name ] || name ];
});
}
});
jQuery.extend({
propFix: {
"for": "htmlFor",
"class": "className"
},
prop: function( elem, name, value ) {
var ret, hooks, notxml,
nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
if ( notxml ) {
// Fix name and attach hooks
name = jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ];
}
if ( value !== undefined ) {
return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
ret :
( elem[ name ] = value );
} else {
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
ret :
elem[ name ];
}
},
propHooks: {
tabIndex: {
get: function( elem ) {
return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
elem.tabIndex :
-1;
}
}
}
});
// Support: IE9+
// Selectedness for an option in an optgroup can be inaccurate
if ( !jQuery.support.optSelected ) {
jQuery.propHooks.selected = {
get: function( elem ) {
var parent = elem.parentNode;
if ( parent && parent.parentNode ) {
parent.parentNode.selectedIndex;
}
return null;
}
};
}
jQuery.each([
"tabIndex",
"readOnly",
"maxLength",
"cellSpacing",
"cellPadding",
"rowSpan",
"colSpan",
"useMap",
"frameBorder",
"contentEditable"
], function() {
jQuery.propFix[ this.toLowerCase() ] = this;
});
});

157
src/attributes/val.js Normal file
View File

@ -0,0 +1,157 @@
define([
"../core"
], function( jQuery ) {
var rreturn = /\r/g;
jQuery.fn.extend({
val: function( value ) {
var hooks, ret, isFunction,
elem = this[0];
if ( !arguments.length ) {
if ( elem ) {
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
return ret;
}
ret = elem.value;
return typeof ret === "string" ?
// handle most common string cases
ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
ret == null ? "" : ret;
}
return;
}
isFunction = jQuery.isFunction( value );
return this.each(function( i ) {
var val;
if ( this.nodeType !== 1 ) {
return;
}
if ( isFunction ) {
val = value.call( this, i, jQuery( this ).val() );
} else {
val = value;
}
// Treat null/undefined as ""; convert numbers to string
if ( val == null ) {
val = "";
} else if ( typeof val === "number" ) {
val += "";
} else if ( jQuery.isArray( val ) ) {
val = jQuery.map(val, function ( value ) {
return value == null ? "" : value + "";
});
}
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
// If set returns undefined, fall back to normal setting
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
this.value = val;
}
});
}
});
jQuery.extend({
valHooks: {
option: {
get: function( elem ) {
// attributes.value is undefined in Blackberry 4.7 but
// uses .value. See #6932
var val = elem.attributes.value;
return !val || val.specified ? elem.value : elem.text;
}
},
select: {
get: function( elem ) {
var value, option,
options = elem.options,
index = elem.selectedIndex,
one = elem.type === "select-one" || index < 0,
values = one ? null : [],
max = one ? index + 1 : options.length,
i = index < 0 ?
max :
one ? index : 0;
// Loop through all the selected options
for ( ; i < max; i++ ) {
option = options[ i ];
// IE6-9 doesn't update selected after form reset (#2551)
if ( ( option.selected || i === index ) &&
// Don't return options that are disabled or in a disabled optgroup
( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
// Get the specific value for the option
value = jQuery( option ).val();
// We don't need an array for one selects
if ( one ) {
return value;
}
// Multi-Selects return an array
values.push( value );
}
}
return values;
},
set: function( elem, value ) {
var optionSet, option,
options = elem.options,
values = jQuery.makeArray( value ),
i = options.length;
while ( i-- ) {
option = options[ i ];
if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
optionSet = true;
}
}
// force browsers to behave consistently when non-matching value is set
if ( !optionSet ) {
elem.selectedIndex = -1;
}
return values;
}
}
}
});
// Radios and checkboxes getter/setter
jQuery.each([ "radio", "checkbox" ], function() {
jQuery.valHooks[ this ] = {
set: function( elem, value ) {
if ( jQuery.isArray( value ) ) {
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
}
}
};
if ( !jQuery.support.checkOn ) {
jQuery.valHooks[ this ].get = function( elem ) {
// Support: Webkit
// "" is returned instead of "on" if a value isn't specified
return elem.getAttribute("value") === null ? "on" : elem.value;
};
}
});
});

View File

@ -1,10 +1,15 @@
define([
"./core",
"./var/rnotwhite"
], function( jQuery, rnotwhite ) {
// String to Object options format cache // String to Object options format cache
var optionsCache = {}; var optionsCache = {};
// Convert String-formatted options into Object-formatted ones and store in cache // Convert String-formatted options into Object-formatted ones and store in cache
function createOptions( options ) { function createOptions( options ) {
var object = optionsCache[ options ] = {}; var object = optionsCache[ options ] = {};
jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
object[ flag ] = true; object[ flag ] = true;
}); });
return object; return object;
@ -195,3 +200,5 @@ jQuery.Callbacks = function( options ) {
return self; return self;
}; };
});

View File

@ -1,18 +1,24 @@
define([
"./var/strundefined",
"./var/arr",
"./var/slice",
"./var/concat",
"./var/push",
"./var/indexOf",
// [[Class]] -> type pairs
"./var/class2type",
"./var/toString",
"./var/hasOwn",
"./var/trim"
], function( strundefined, arr, slice, concat, push, indexOf,
class2type, toString, hasOwn, trim ) {
var var
// A central reference to the root jQuery(document) // A central reference to the root jQuery(document)
rootjQuery, rootjQuery,
// The deferred used on DOM ready
readyList,
// Support: IE9
// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
core_strundefined = typeof undefined,
// Use the correct document accordingly with window argument (sandbox) // Use the correct document accordingly with window argument (sandbox)
location = window.location,
document = window.document, document = window.document,
docElem = document.documentElement,
// Map over jQuery in case of overwrite // Map over jQuery in case of overwrite
_jQuery = window.jQuery, _jQuery = window.jQuery,
@ -20,22 +26,7 @@ var
// Map over the $ in case of overwrite // Map over the $ in case of overwrite
_$ = window.$, _$ = window.$,
// [[Class]] -> type pairs version = "@VERSION",
class2type = {},
// List of deleted data cache ids, so we can reuse them
core_deletedIds = [],
core_version = "@VERSION",
// Save a reference to some core methods
core_concat = core_deletedIds.concat,
core_push = core_deletedIds.push,
core_slice = core_deletedIds.slice,
core_indexOf = core_deletedIds.indexOf,
core_toString = class2type.toString,
core_hasOwn = class2type.hasOwnProperty,
core_trim = core_version.trim,
// Define a local copy of jQuery // Define a local copy of jQuery
jQuery = function( selector, context ) { jQuery = function( selector, context ) {
@ -43,12 +34,6 @@ var
return new jQuery.fn.init( selector, context, rootjQuery ); return new jQuery.fn.init( selector, context, rootjQuery );
}, },
// Used for matching numbers
core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
// Used for splitting on whitespace
core_rnotwhite = /\S+/g,
// A simple way to check for HTML strings // A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <) // Strict HTML recognition (#11290: must start with <)
@ -64,20 +49,14 @@ var
// Used by jQuery.camelCase as callback to replace() // Used by jQuery.camelCase as callback to replace()
fcamelCase = function( all, letter ) { fcamelCase = function( all, letter ) {
return letter.toUpperCase(); return letter.toUpperCase();
},
// The ready event handler and self cleanup method
completed = function() {
document.removeEventListener( "DOMContentLoaded", completed, false );
window.removeEventListener( "load", completed, false );
jQuery.ready();
}; };
jQuery.fn = jQuery.prototype = { jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used // The current version of jQuery being used
jquery: core_version, jquery: version,
constructor: jQuery, constructor: jQuery,
init: function( selector, context, rootjQuery ) { init: function( selector, context, rootjQuery ) {
var match, elem; var match, elem;
@ -162,7 +141,10 @@ jQuery.fn = jQuery.prototype = {
// HANDLE: $(function) // HANDLE: $(function)
// Shortcut for document ready // Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) { } else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector ); return typeof rootjQuery.ready !== "undefined" ?
rootjQuery.ready( selector ) :
// Execute immediately if ready is not present
selector( jQuery );
} }
if ( selector.selector !== undefined ) { if ( selector.selector !== undefined ) {
@ -180,7 +162,7 @@ jQuery.fn = jQuery.prototype = {
length: 0, length: 0,
toArray: function() { toArray: function() {
return core_slice.call( this ); return slice.call( this );
}, },
// Get the Nth element in the matched element set OR // Get the Nth element in the matched element set OR
@ -217,15 +199,8 @@ jQuery.fn = jQuery.prototype = {
return jQuery.each( this, callback, args ); return jQuery.each( this, callback, args );
}, },
ready: function( fn ) {
// Add the callback
jQuery.ready.promise().done( fn );
return this;
},
slice: function() { slice: function() {
return this.pushStack( core_slice.apply( this, arguments ) ); return this.pushStack( slice.apply( this, arguments ) );
}, },
first: function() { first: function() {
@ -254,9 +229,9 @@ jQuery.fn = jQuery.prototype = {
// For internal use only. // For internal use only.
// Behaves like an Array's method, not like a jQuery method. // Behaves like an Array's method, not like a jQuery method.
push: core_push, push: push,
sort: [].sort, sort: arr.sort,
splice: [].splice splice: arr.splice
}; };
// Give the init function the jQuery prototype for later instantiation // Give the init function the jQuery prototype for later instantiation
@ -328,7 +303,10 @@ jQuery.extend = jQuery.fn.extend = function() {
jQuery.extend({ jQuery.extend({
// Unique for each copy of jQuery on the page // Unique for each copy of jQuery on the page
expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
// Assume jQuery is ready without the ready module
isReady: true,
noConflict: function( deep ) { noConflict: function( deep ) {
if ( window.$ === jQuery ) { if ( window.$ === jQuery ) {
@ -342,47 +320,6 @@ jQuery.extend({
return jQuery; return jQuery;
}, },
// Is the DOM ready to be used? Set to true once it occurs.
isReady: false,
// A counter to track how many items to wait for before
// the ready event fires. See #6781
readyWait: 1,
// Hold (or release) the ready event
holdReady: function( hold ) {
if ( hold ) {
jQuery.readyWait++;
} else {
jQuery.ready( true );
}
},
// Handle when the DOM is ready
ready: function( wait ) {
// Abort if there are pending holds or we're already ready
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;
}
// Remember that the DOM is ready
jQuery.isReady = true;
// If a normal DOM Ready event fired, decrement, and wait if need be
if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
// If there are functions bound, to execute
readyList.resolveWith( document, [ jQuery ] );
// Trigger any bound ready events
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
}
},
// See test/unit/core.js for details concerning isFunction. // See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert // Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968). // aren't supported. They return false on IE (#2968).
@ -406,7 +343,7 @@ jQuery.extend({
} }
// Support: Safari <= 5.1 (functionish RegExp) // Support: Safari <= 5.1 (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ? return typeof obj === "object" || typeof obj === "function" ?
class2type[ core_toString.call(obj) ] || "object" : class2type[ toString.call(obj) ] || "object" :
typeof obj; typeof obj;
}, },
@ -425,7 +362,7 @@ jQuery.extend({
// https://bugzilla.mozilla.org/show_bug.cgi?id=814622 // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
try { try {
if ( obj.constructor && if ( obj.constructor &&
!core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
return false; return false;
} }
} catch ( e ) { } catch ( e ) {
@ -452,6 +389,7 @@ jQuery.extend({
// data: string of html // data: string of html
// context (optional): If specified, the fragment will be created in this context, defaults to document // context (optional): If specified, the fragment will be created in this context, defaults to document
// keepScripts (optional): If true, will include scripts passed in the html string // keepScripts (optional): If true, will include scripts passed in the html string
// TODO: Circular reference core -> manipulation -> core
parseHTML: function( data, context, keepScripts ) { parseHTML: function( data, context, keepScripts ) {
if ( !data || typeof data !== "string" ) { if ( !data || typeof data !== "string" ) {
return null; return null;
@ -507,7 +445,7 @@ jQuery.extend({
// Evaluates a script in a global context // Evaluates a script in a global context
globalEval: function( code ) { globalEval: function( code ) {
var script, var script,
indirect = eval; indirect = eval;
code = jQuery.trim( code ); code = jQuery.trim( code );
@ -588,7 +526,7 @@ jQuery.extend({
}, },
trim: function( text ) { trim: function( text ) {
return text == null ? "" : core_trim.call( text ); return text == null ? "" : trim.call( text );
}, },
// results is for internal usage only // results is for internal usage only
@ -602,7 +540,7 @@ jQuery.extend({
[ arr ] : arr [ arr ] : arr
); );
} else { } else {
core_push.call( ret, arr ); push.call( ret, arr );
} }
} }
@ -610,7 +548,7 @@ jQuery.extend({
}, },
inArray: function( elem, arr, i ) { inArray: function( elem, arr, i ) {
return arr == null ? -1 : core_indexOf.call( arr, elem, i ); return arr == null ? -1 : indexOf.call( arr, elem, i );
}, },
merge: function( first, second ) { merge: function( first, second ) {
@ -682,7 +620,7 @@ jQuery.extend({
} }
// Flatten any nested arrays // Flatten any nested arrays
return core_concat.apply( [], ret ); return concat.apply( [], ret );
}, },
// A global GUID counter for objects // A global GUID counter for objects
@ -706,9 +644,9 @@ jQuery.extend({
} }
// Simulated bind // Simulated bind
args = core_slice.call( arguments, 2 ); args = slice.call( arguments, 2 );
proxy = function() { proxy = function() {
return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
}; };
// Set the guid of unique handler to the same of original handler, so it can be removed // Set the guid of unique handler to the same of original handler, so it can be removed
@ -770,56 +708,9 @@ jQuery.extend({
length ? fn( elems[0], key ) : emptyGet; length ? fn( elems[0], key ) : emptyGet;
}, },
now: Date.now, now: Date.now
// A method for quickly swapping in/out CSS properties to get correct calculations.
// Note: this method belongs to the css module but it's needed here for the support module.
// If support gets modularized, this method should be moved back to the css module.
swap: function( elem, options, callback, args ) {
var ret, name,
old = {};
// Remember the old values, and insert the new ones
for ( name in options ) {
old[ name ] = elem.style[ name ];
elem.style[ name ] = options[ name ];
}
ret = callback.apply( elem, args || [] );
// Revert the old values
for ( name in options ) {
elem.style[ name ] = old[ name ];
}
return ret;
}
}); });
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
readyList = jQuery.Deferred();
// Catch cases where $(document).ready() is called after the browser event has already occurred.
// we once tried to use readyState "interactive" here, but it caused issues like the one
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout( jQuery.ready );
} else {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", completed, false );
}
}
return readyList.promise( obj );
};
// Populate the class2type map // Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase(); class2type[ "[object " + name + "]" ] = name.toLowerCase();
@ -843,4 +734,7 @@ function isArraylike( obj ) {
} }
// All jQuery objects should point back to these // All jQuery objects should point back to these
rootjQuery = jQuery(document); rootjQuery = jQuery( document );
return jQuery;
});

92
src/core/ready.js Normal file
View File

@ -0,0 +1,92 @@
define([
"../core",
"../deferred"
], function( jQuery ) {
// The deferred used on DOM ready
var readyList;
jQuery.fn.ready = function( fn ) {
// Add the callback
jQuery.ready.promise().done( fn );
return this;
};
jQuery.extend({
// Is the DOM ready to be used? Set to true once it occurs.
isReady: false,
// A counter to track how many items to wait for before
// the ready event fires. See #6781
readyWait: 1,
// Hold (or release) the ready event
holdReady: function( hold ) {
if ( hold ) {
jQuery.readyWait++;
} else {
jQuery.ready( true );
}
},
// Handle when the DOM is ready
ready: function( wait ) {
// Abort if there are pending holds or we're already ready
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;
}
// Remember that the DOM is ready
jQuery.isReady = true;
// If a normal DOM Ready event fired, decrement, and wait if need be
if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
// If there are functions bound, to execute
readyList.resolveWith( document, [ jQuery ] );
// Trigger any bound ready events
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
}
}
});
/**
* The ready event handler and self cleanup method
*/
function completed() {
document.removeEventListener( "DOMContentLoaded", completed, false );
window.removeEventListener( "load", completed, false );
jQuery.ready();
}
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
readyList = jQuery.Deferred();
// Catch cases where $(document).ready() is called after the browser event has already occurred.
// we once tried to use readyState "interactive" here, but it caused issues like the one
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout( jQuery.ready );
} else {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", completed, false );
}
}
return readyList.promise( obj );
};
});

29
src/core/swap.js Normal file
View File

@ -0,0 +1,29 @@
define([
"../core"
], function( jQuery ) {
// A method for quickly swapping in/out CSS properties to get correct calculations.
// Note: this method belongs to the css module but it's needed here for the support module.
// If support gets modularized, this method should be moved back to the css module.
jQuery.swap = function( elem, options, callback, args ) {
var ret, name,
old = {};
// Remember the old values, and insert the new ones
for ( name in options ) {
old[ name ] = elem.style[ name ];
elem.style[ name ] = options[ name ];
}
ret = callback.apply( elem, args || [] );
// Revert the old values
for ( name in options ) {
elem.style[ name ] = old[ name ];
}
return ret;
};
return jQuery.swap;
});

View File

@ -1,12 +1,21 @@
var curCSS, iframe, define([
"./core",
"./var/pnum",
"./css/var/cssExpand",
"./css/var/isHidden",
"./css/defaultDisplay",
"./data/var/data_priv",
"./core/swap",
"./selector" // contains
], function( jQuery, pnum, cssExpand, isHidden, defaultDisplay, data_priv ) {
var curCSS,
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption" // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
rdisplayswap = /^(none|table(?!-c[ea]).+)/, rdisplayswap = /^(none|table(?!-c[ea]).+)/,
rmargin = /^margin/, rmargin = /^margin/,
rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ),
rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
elemdisplay = { BODY: "block" },
cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssShow = { position: "absolute", visibility: "hidden", display: "block" },
cssNormalTransform = { cssNormalTransform = {
@ -14,7 +23,6 @@ var curCSS, iframe,
fontWeight: 400 fontWeight: 400
}, },
cssExpand = [ "Top", "Right", "Bottom", "Left" ],
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
// return a css property mapped to a potentially vendor prefixed property // return a css property mapped to a potentially vendor prefixed property
@ -40,13 +48,6 @@ function vendorPropName( style, name ) {
return origName; return origName;
} }
function isHidden( elem, el ) {
// isHidden might be called from jQuery#filter function;
// in that case, element will be second argument
elem = el || elem;
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
}
// NOTE: we've included the "window" in window.getComputedStyle // NOTE: we've included the "window" in window.getComputedStyle
// because jsdom on node.js will break without it. // because jsdom on node.js will break without it.
function getStyles( elem ) { function getStyles( elem ) {
@ -78,7 +79,7 @@ function showHide( elements, show ) {
// 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 ( elem.style.display === "" && isHidden( elem ) ) { if ( elem.style.display === "" && isHidden( elem ) ) {
values[ index ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
} }
} else { } else {
@ -414,46 +415,6 @@ function getWidthOrHeight( elem, name, extra ) {
) + "px"; ) + "px";
} }
// Try to determine the default display value of an element
function css_defaultDisplay( nodeName ) {
var doc = document,
display = elemdisplay[ nodeName ];
if ( !display ) {
display = actualDisplay( nodeName, doc );
// If the simple way fails, read from inside an iframe
if ( display === "none" || !display ) {
// Use the already-created iframe if possible
iframe = ( iframe ||
jQuery("<iframe frameborder='0' width='0' height='0'/>")
.css( "cssText", "display:block !important" )
).appendTo( doc.documentElement );
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
doc.write("<!doctype html><html><body>");
doc.close();
display = actualDisplay( nodeName, doc );
iframe.detach();
}
// Store the correct default display
elemdisplay[ nodeName ] = display;
}
return display;
}
// Called ONLY from within css_defaultDisplay
function actualDisplay( name, doc ) {
var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
display = jQuery.css( elem[0], "display" );
elem.remove();
return display;
}
jQuery.each([ "height", "width" ], function( i, name ) { jQuery.each([ "height", "width" ], function( i, name ) {
jQuery.cssHooks[ name ] = { jQuery.cssHooks[ name ] = {
get: function( elem, computed, extra ) { get: function( elem, computed, extra ) {
@ -504,6 +465,7 @@ jQuery(function() {
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// getComputedStyle returns percent when specified for top/left/bottom/right // getComputedStyle returns percent when specified for top/left/bottom/right
// rather than make the css module depend on the offset module, we just check for it here // rather than make the css module depend on the offset module, we just check for it here
// TODO: Optional dependency on offset
if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
jQuery.each( [ "top", "left" ], function( i, prop ) { jQuery.each( [ "top", "left" ], function( i, prop ) {
jQuery.cssHooks[ prop ] = { jQuery.cssHooks[ prop ] = {
@ -519,21 +481,8 @@ jQuery(function() {
}; };
}); });
} }
}); });
if ( jQuery.expr && jQuery.expr.filters ) {
jQuery.expr.filters.hidden = function( elem ) {
// Support: Opera <= 12.12
// Opera reports offsetWidths and offsetHeights less than zero on some elements
return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
};
jQuery.expr.filters.visible = function( elem ) {
return !jQuery.expr.filters.hidden( elem );
};
}
// These hooks are used by animate to expand properties // These hooks are used by animate to expand properties
jQuery.each({ jQuery.each({
margin: "", margin: "",
@ -561,3 +510,5 @@ jQuery.each({
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
} }
}); });
});

58
src/css/defaultDisplay.js Normal file
View File

@ -0,0 +1,58 @@
define([
"../core",
"../manipulation" // appendTo
], function( jQuery ) {
var iframe,
elemdisplay = { BODY: "block" };
/**
* Retrieve the actual display of a element
* @param {String} name nodeName of the element
* @param {Object} doc Document object
*/
function actualDisplay( name, doc ) {
var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
display = jQuery.css( elem[0], "display" );
elem.remove();
return display;
}
/**
* Try to determine the default display value of an element
* @param {String} nodeName
*/
function defaultDisplay( nodeName ) {
var doc = document,
display = elemdisplay[ nodeName ];
if ( !display ) {
display = actualDisplay( nodeName, doc );
// If the simple way fails, read from inside an iframe
if ( display === "none" || !display ) {
// Use the already-created iframe if possible
iframe = ( iframe ||
jQuery("<iframe frameborder='0' width='0' height='0'/>")
.css( "cssText", "display:block !important" )
).appendTo( doc.documentElement );
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
doc.write("<!doctype html><html><body>");
doc.close();
display = actualDisplay( nodeName, doc );
iframe.detach();
}
// Store the correct default display
elemdisplay[ nodeName ] = display;
}
return display;
}
return defaultDisplay;
});

View File

@ -0,0 +1,15 @@
define([
"../core",
"../selector"
], function( jQuery ) {
jQuery.expr.filters.hidden = function( elem ) {
// Support: Opera <= 12.12
// Opera reports offsetWidths and offsetHeights less than zero on some elements
return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
};
jQuery.expr.filters.visible = function( elem ) {
return !jQuery.expr.filters.hidden( elem );
};
});

3
src/css/var/cssExpand.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return [ "Top", "Right", "Bottom", "Left" ];
});

13
src/css/var/isHidden.js Normal file
View File

@ -0,0 +1,13 @@
define([
"../../core",
"../../selector"
// css is assumed
], function( jQuery ) {
return function( elem, el ) {
// isHidden might be called from jQuery#filter function;
// in that case, element will be second argument
elem = el || elem;
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
};
});

View File

@ -1,3 +1,10 @@
define([
"./core",
"./var/rnotwhite",
"./data/var/data_priv",
"./data/var/data_user"
], function( jQuery, rnotwhite, data_priv, data_user ) {
/* /*
Implementation Summary Implementation Summary
@ -9,201 +16,10 @@
5. Avoid exposing implementation details on user objects (eg. expando properties) 5. Avoid exposing implementation details on user objects (eg. expando properties)
6. Provide a clear path for implementation upgrade to WeakMap in 2014 6. Provide a clear path for implementation upgrade to WeakMap in 2014
*/ */
var data_user, data_priv, var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
rmultiDash = /([A-Z])/g; rmultiDash = /([A-Z])/g;
function Data() {
// Support: Android < 4,
// Old WebKit does not have Object.preventExtensions/freeze method,
// return new empty object instead with no [[set]] accessor
Object.defineProperty( this.cache = {}, 0, {
get: function() {
return {};
}
});
this.expando = jQuery.expando + Math.random();
}
Data.uid = 1;
Data.accepts = function( owner ) {
// Accepts only:
// - Node
// - Node.ELEMENT_NODE
// - Node.DOCUMENT_NODE
// - Object
// - Any
return owner.nodeType ?
owner.nodeType === 1 || owner.nodeType === 9 : true;
};
Data.prototype = {
key: function( owner ) {
// We can accept data for non-element nodes in modern browsers,
// but we should not, see #8335.
// Always return the key for a frozen object.
if ( !Data.accepts( owner ) ) {
return 0;
}
var descriptor = {},
// Check if the owner object already has a cache key
unlock = owner[ this.expando ];
// If not, create one
if ( !unlock ) {
unlock = Data.uid++;
// Secure it in a non-enumerable, non-writable property
try {
descriptor[ this.expando ] = { value: unlock };
Object.defineProperties( owner, descriptor );
// Support: Android < 4
// Fallback to a less secure definition
} catch ( e ) {
descriptor[ this.expando ] = unlock;
jQuery.extend( owner, descriptor );
}
}
// Ensure the cache object
if ( !this.cache[ unlock ] ) {
this.cache[ unlock ] = {};
}
return unlock;
},
set: function( owner, data, value ) {
var prop,
// There may be an unlock assigned to this node,
// if there is no entry for this "owner", create one inline
// and set the unlock as though an owner entry had always existed
unlock = this.key( owner ),
cache = this.cache[ unlock ];
// Handle: [ owner, key, value ] args
if ( typeof data === "string" ) {
cache[ data ] = value;
// Handle: [ owner, { properties } ] args
} else {
// Fresh assignments by object are shallow copied
if ( jQuery.isEmptyObject( cache ) ) {
jQuery.extend( this.cache[ unlock ], data );
// Otherwise, copy the properties one-by-one to the cache object
} else {
for ( prop in data ) {
cache[ prop ] = data[ prop ];
}
}
}
return cache;
},
get: function( owner, key ) {
// Either a valid cache is found, or will be created.
// New caches will be created and the unlock returned,
// allowing direct access to the newly created
// empty data object. A valid owner object must be provided.
var cache = this.cache[ this.key( owner ) ];
return key === undefined ?
cache : cache[ key ];
},
access: function( owner, key, value ) {
var stored;
// In cases where either:
//
// 1. No key was specified
// 2. A string key was specified, but no value provided
//
// Take the "read" path and allow the get method to determine
// which value to return, respectively either:
//
// 1. The entire cache object
// 2. The data stored at the key
//
if ( key === undefined ||
((key && typeof key === "string") && value === undefined) ) {
stored = this.get( owner, key );
return stored !== undefined ?
stored : this.get( owner, jQuery.camelCase(key) );
}
// [*]When the key is not a string, or both a key and value
// are specified, set or extend (existing objects) with either:
//
// 1. An object of properties
// 2. A key and value
//
this.set( owner, key, value );
// Since the "set" path can have two possible entry points
// return the expected data based on which path was taken[*]
return value !== undefined ? value : key;
},
remove: function( owner, key ) {
var i, name, camel,
unlock = this.key( owner ),
cache = this.cache[ unlock ];
if ( key === undefined ) {
this.cache[ unlock ] = {};
} else {
// Support array or space separated string of keys
if ( jQuery.isArray( key ) ) {
// If "name" is an array of keys...
// When data is initially created, via ("key", "val") signature,
// keys will be converted to camelCase.
// Since there is no way to tell _how_ a key was added, remove
// both plain key and camelCase key. #12786
// This will only penalize the array argument path.
name = key.concat( key.map( jQuery.camelCase ) );
} else {
camel = jQuery.camelCase( key );
// Try the string as a key before any manipulation
if ( key in cache ) {
name = [ key, camel ];
} else {
// If a key with the spaces exists, use it.
// Otherwise, create an array by matching non-whitespace
name = camel;
name = name in cache ?
[ name ] : ( name.match( core_rnotwhite ) || [] );
}
}
i = name.length;
while ( i-- ) {
delete cache[ name[ i ] ];
}
}
},
hasData: function( owner ) {
return !jQuery.isEmptyObject(
this.cache[ owner[ this.expando ] ] || {}
);
},
discard: function( owner ) {
if ( owner[ this.expando ] ) {
delete this.cache[ owner[ this.expando ] ];
}
}
};
// These may be used throughout the jQuery core codebase
data_user = new Data();
data_priv = new Data();
jQuery.extend({ jQuery.extend({
acceptData: Data.accepts,
hasData: function( elem ) { hasData: function( elem ) {
return data_user.hasData( elem ) || data_priv.hasData( elem ); return data_user.hasData( elem ) || data_priv.hasData( elem );
}, },
@ -354,3 +170,5 @@ function dataAttr( elem, key, data ) {
} }
return data; return data;
} }
});

181
src/data/Data.js Normal file
View File

@ -0,0 +1,181 @@
define([
"../core",
"../var/rnotwhite",
"./accepts"
], function( jQuery, rnotwhite ) {
function Data() {
// Support: Android < 4,
// Old WebKit does not have Object.preventExtensions/freeze method,
// return new empty object instead with no [[set]] accessor
Object.defineProperty( this.cache = {}, 0, {
get: function() {
return {};
}
});
this.expando = jQuery.expando + Math.random();
}
Data.uid = 1;
Data.accepts = jQuery.acceptData;
Data.prototype = {
key: function( owner ) {
// We can accept data for non-element nodes in modern browsers,
// but we should not, see #8335.
// Always return the key for a frozen object.
if ( !Data.accepts( owner ) ) {
return 0;
}
var descriptor = {},
// Check if the owner object already has a cache key
unlock = owner[ this.expando ];
// If not, create one
if ( !unlock ) {
unlock = Data.uid++;
// Secure it in a non-enumerable, non-writable property
try {
descriptor[ this.expando ] = { value: unlock };
Object.defineProperties( owner, descriptor );
// Support: Android < 4
// Fallback to a less secure definition
} catch ( e ) {
descriptor[ this.expando ] = unlock;
jQuery.extend( owner, descriptor );
}
}
// Ensure the cache object
if ( !this.cache[ unlock ] ) {
this.cache[ unlock ] = {};
}
return unlock;
},
set: function( owner, data, value ) {
var prop,
// There may be an unlock assigned to this node,
// if there is no entry for this "owner", create one inline
// and set the unlock as though an owner entry had always existed
unlock = this.key( owner ),
cache = this.cache[ unlock ];
// Handle: [ owner, key, value ] args
if ( typeof data === "string" ) {
cache[ data ] = value;
// Handle: [ owner, { properties } ] args
} else {
// Fresh assignments by object are shallow copied
if ( jQuery.isEmptyObject( cache ) ) {
jQuery.extend( this.cache[ unlock ], data );
// Otherwise, copy the properties one-by-one to the cache object
} else {
for ( prop in data ) {
cache[ prop ] = data[ prop ];
}
}
}
return cache;
},
get: function( owner, key ) {
// Either a valid cache is found, or will be created.
// New caches will be created and the unlock returned,
// allowing direct access to the newly created
// empty data object. A valid owner object must be provided.
var cache = this.cache[ this.key( owner ) ];
return key === undefined ?
cache : cache[ key ];
},
access: function( owner, key, value ) {
var stored;
// In cases where either:
//
// 1. No key was specified
// 2. A string key was specified, but no value provided
//
// Take the "read" path and allow the get method to determine
// which value to return, respectively either:
//
// 1. The entire cache object
// 2. The data stored at the key
//
if ( key === undefined ||
((key && typeof key === "string") && value === undefined) ) {
stored = this.get( owner, key );
return stored !== undefined ?
stored : this.get( owner, jQuery.camelCase(key) );
}
// [*]When the key is not a string, or both a key and value
// are specified, set or extend (existing objects) with either:
//
// 1. An object of properties
// 2. A key and value
//
this.set( owner, key, value );
// Since the "set" path can have two possible entry points
// return the expected data based on which path was taken[*]
return value !== undefined ? value : key;
},
remove: function( owner, key ) {
var i, name, camel,
unlock = this.key( owner ),
cache = this.cache[ unlock ];
if ( key === undefined ) {
this.cache[ unlock ] = {};
} else {
// Support array or space separated string of keys
if ( jQuery.isArray( key ) ) {
// If "name" is an array of keys...
// When data is initially created, via ("key", "val") signature,
// keys will be converted to camelCase.
// Since there is no way to tell _how_ a key was added, remove
// both plain key and camelCase key. #12786
// This will only penalize the array argument path.
name = key.concat( key.map( jQuery.camelCase ) );
} else {
camel = jQuery.camelCase( key );
// Try the string as a key before any manipulation
if ( key in cache ) {
name = [ key, camel ];
} else {
// If a key with the spaces exists, use it.
// Otherwise, create an array by matching non-whitespace
name = camel;
name = name in cache ?
[ name ] : ( name.match( rnotwhite ) || [] );
}
}
i = name.length;
while ( i-- ) {
delete cache[ name[ i ] ];
}
}
},
hasData: function( owner ) {
return !jQuery.isEmptyObject(
this.cache[ owner[ this.expando ] ] || {}
);
},
discard: function( owner ) {
if ( owner[ this.expando ] ) {
delete this.cache[ owner[ this.expando ] ];
}
}
};
return Data;
});

20
src/data/accepts.js Normal file
View File

@ -0,0 +1,20 @@
define([
"../core"
], function( jQuery ) {
/**
* Determines whether an object can have data
*/
jQuery.acceptData = function( owner ) {
// Accepts only:
// - Node
// - Node.ELEMENT_NODE
// - Node.DOCUMENT_NODE
// - Object
// - Any
return owner.nodeType ?
owner.nodeType === 1 || owner.nodeType === 9 : true;
};
return jQuery.acceptData;
});

View File

@ -0,0 +1,5 @@
define([
"../Data"
], function( Data ) {
return new Data();
});

View File

@ -0,0 +1,5 @@
define([
"../Data"
], function( Data ) {
return new Data();
});

View File

@ -1,3 +1,9 @@
define([
"./core",
"./var/slice",
"./callbacks"
], function( jQuery, slice ) {
jQuery.extend({ jQuery.extend({
Deferred: function( func ) { Deferred: function( func ) {
@ -89,7 +95,7 @@ jQuery.extend({
// Deferred helper // Deferred helper
when: function( subordinate /* , ..., subordinateN */ ) { when: function( subordinate /* , ..., subordinateN */ ) {
var i = 0, var i = 0,
resolveValues = core_slice.call( arguments ), resolveValues = slice.call( arguments ),
length = resolveValues.length, length = resolveValues.length,
// the count of uncompleted subordinates // the count of uncompleted subordinates
@ -102,7 +108,7 @@ jQuery.extend({
updateFunc = function( i, contexts, values ) { updateFunc = function( i, contexts, values ) {
return function( value ) { return function( value ) {
contexts[ i ] = this; contexts[ i ] = this;
values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
if( values === progressValues ) { if( values === progressValues ) {
deferred.notifyWith( contexts, values ); deferred.notifyWith( contexts, values );
} else if ( !( --remaining ) ) { } else if ( !( --remaining ) ) {
@ -138,3 +144,4 @@ jQuery.extend({
return deferred.promise(); return deferred.promise();
} }
}); });
});

View File

@ -1,11 +1,11 @@
// Limit scope pollution from any deprecated API define([
// (function() { "./core",
"./traversing"
], function( jQuery ) {
// The number of elements contained in the matched element set // The number of elements contained in the matched element set
jQuery.fn.size = function() { jQuery.fn.size = function() {
return this.length; return this.length;
}; };
jQuery.fn.andSelf = jQuery.fn.addBack; jQuery.fn.andSelf = jQuery.fn.addBack;
});
// })();

View File

@ -1,3 +1,7 @@
define([
"./core",
"./css"
], function( jQuery ) {
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
@ -39,3 +43,4 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
}; };
}); });
}); });
});

129
src/effects.js vendored
View File

@ -1,6 +1,19 @@
define([
"./core",
"./var/pnum",
"./css/var/cssExpand",
"./css/var/isHidden",
"./effects/Tween",
"./data/var/data_priv",
"./queue",
"./css",
"./deferred",
"./traversing"
], function( jQuery, pnum, cssExpand, isHidden, Tween, data_priv ) {
var fxNow, timerId, var fxNow, timerId,
rfxtypes = /^(?:toggle|show|hide)$/, rfxtypes = /^(?:toggle|show|hide)$/,
rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
rrun = /queueHooks$/, rrun = /queueHooks$/,
animationPrefilters = [ defaultPrefilter ], animationPrefilters = [ defaultPrefilter ],
tweeners = { tweeners = {
@ -370,100 +383,6 @@ function defaultPrefilter( elem, props, opts ) {
} }
} }
function Tween( elem, options, prop, end, easing ) {
return new Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = Tween;
Tween.prototype = {
constructor: Tween,
init: function( elem, options, prop, end, easing, unit ) {
this.elem = elem;
this.prop = prop;
this.easing = easing || "swing";
this.options = options;
this.start = this.now = this.cur();
this.end = end;
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
},
cur: function() {
var hooks = Tween.propHooks[ this.prop ];
return hooks && hooks.get ?
hooks.get( this ) :
Tween.propHooks._default.get( this );
},
run: function( percent ) {
var eased,
hooks = Tween.propHooks[ this.prop ];
if ( this.options.duration ) {
this.pos = eased = jQuery.easing[ this.easing ](
percent, this.options.duration * percent, 0, 1, this.options.duration
);
} else {
this.pos = eased = percent;
}
this.now = ( this.end - this.start ) * eased + this.start;
if ( this.options.step ) {
this.options.step.call( this.elem, this.now, this );
}
if ( hooks && hooks.set ) {
hooks.set( this );
} else {
Tween.propHooks._default.set( this );
}
return this;
}
};
Tween.prototype.init.prototype = Tween.prototype;
Tween.propHooks = {
_default: {
get: function( tween ) {
var result;
if ( tween.elem[ tween.prop ] != null &&
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
return tween.elem[ tween.prop ];
}
// passing an empty string as a 3rd parameter to .css will automatically
// attempt a parseFloat and fallback to a string if the parse fails
// so, simple values such as "10px" are parsed to Float.
// complex values such as "rotate(1rad)" are returned as is.
result = jQuery.css( tween.elem, tween.prop, "" );
// Empty strings, null, undefined and "auto" are converted to 0.
return !result || result === "auto" ? 0 : result;
},
set: function( tween ) {
// use step hook for back compat - use cssHook if its there - use .style if its
// available and use plain properties where available
if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
} else {
tween.elem[ tween.prop ] = tween.now;
}
}
}
};
// Support: IE9
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
set: function( tween ) {
if ( tween.elem.nodeType && tween.elem.parentNode ) {
tween.elem[ tween.prop ] = tween.now;
}
}
};
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = jQuery.fn[ name ]; var cssFn = jQuery.fn[ name ];
jQuery.fn[ name ] = function( speed, easing, callback ) { jQuery.fn[ name ] = function( speed, easing, callback ) {
@ -660,17 +579,7 @@ jQuery.speed = function( speed, easing, fn ) {
return opt; return opt;
}; };
jQuery.easing = {
linear: function( p ) {
return p;
},
swing: function( p ) {
return 0.5 - Math.cos( p*Math.PI ) / 2;
}
};
jQuery.timers = []; jQuery.timers = [];
jQuery.fx = Tween.prototype.init;
jQuery.fx.tick = function() { jQuery.fx.tick = function() {
var timer, var timer,
timers = jQuery.timers, timers = jQuery.timers,
@ -718,13 +627,5 @@ jQuery.fx.speeds = {
_default: 400 _default: 400
}; };
// Back Compat <1.8 extension point
jQuery.fx.step = {};
if ( jQuery.expr && jQuery.expr.filters ) { });
jQuery.expr.filters.animated = function( elem ) {
return jQuery.grep(jQuery.timers, function( fn ) {
return elem === fn.elem;
}).length;
};
}

114
src/effects/Tween.js Normal file
View File

@ -0,0 +1,114 @@
define([
"../core",
"../css"
], function( jQuery ) {
function Tween( elem, options, prop, end, easing ) {
return new Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = Tween;
Tween.prototype = {
constructor: Tween,
init: function( elem, options, prop, end, easing, unit ) {
this.elem = elem;
this.prop = prop;
this.easing = easing || "swing";
this.options = options;
this.start = this.now = this.cur();
this.end = end;
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
},
cur: function() {
var hooks = Tween.propHooks[ this.prop ];
return hooks && hooks.get ?
hooks.get( this ) :
Tween.propHooks._default.get( this );
},
run: function( percent ) {
var eased,
hooks = Tween.propHooks[ this.prop ];
if ( this.options.duration ) {
this.pos = eased = jQuery.easing[ this.easing ](
percent, this.options.duration * percent, 0, 1, this.options.duration
);
} else {
this.pos = eased = percent;
}
this.now = ( this.end - this.start ) * eased + this.start;
if ( this.options.step ) {
this.options.step.call( this.elem, this.now, this );
}
if ( hooks && hooks.set ) {
hooks.set( this );
} else {
Tween.propHooks._default.set( this );
}
return this;
}
};
Tween.prototype.init.prototype = Tween.prototype;
Tween.propHooks = {
_default: {
get: function( tween ) {
var result;
if ( tween.elem[ tween.prop ] != null &&
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
return tween.elem[ tween.prop ];
}
// passing an empty string as a 3rd parameter to .css will automatically
// attempt a parseFloat and fallback to a string if the parse fails
// so, simple values such as "10px" are parsed to Float.
// complex values such as "rotate(1rad)" are returned as is.
result = jQuery.css( tween.elem, tween.prop, "" );
// Empty strings, null, undefined and "auto" are converted to 0.
return !result || result === "auto" ? 0 : result;
},
set: function( tween ) {
// use step hook for back compat - use cssHook if its there - use .style if its
// available and use plain properties where available
if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
} else {
tween.elem[ tween.prop ] = tween.now;
}
}
}
};
// Support: IE9
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
set: function( tween ) {
if ( tween.elem.nodeType && tween.elem.parentNode ) {
tween.elem[ tween.prop ] = tween.now;
}
}
};
jQuery.easing = {
linear: function( p ) {
return p;
},
swing: function( p ) {
return 0.5 - Math.cos( p*Math.PI ) / 2;
}
};
jQuery.fx = Tween.prototype.init;
// Back Compat <1.8 extension point
jQuery.fx.step = {};
});

View File

@ -0,0 +1,11 @@
define([
"../core",
"../selector",
"../effects",
], function( jQuery ) {
jQuery.expr.filters.animated = function( elem ) {
return jQuery.grep(jQuery.timers, function( fn ) {
return elem === fn.elem;
}).length;
};
});

View File

@ -1,3 +1,15 @@
define([
"./core",
"./var/strundefined",
"./var/rnotwhite",
"./var/hasOwn",
"./var/slice",
"./data/var/data_priv",
"./data/accepts",
"./selector",
"./support"
], function( jQuery, strundefined, rnotwhite, hasOwn, slice, data_priv ) {
var rkeyEvent = /^key/, var rkeyEvent = /^key/,
rmouseEvent = /^(?:mouse|contextmenu)|click/, rmouseEvent = /^(?:mouse|contextmenu)|click/,
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
@ -57,7 +69,7 @@ jQuery.event = {
eventHandle = elemData.handle = function( e ) { eventHandle = elemData.handle = function( e ) {
// Discard the second event of a jQuery.event.trigger() and // Discard the second event of a jQuery.event.trigger() and
// when an event is called after a page has unloaded // when an event is called after a page has unloaded
return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
undefined; undefined;
}; };
@ -66,7 +78,7 @@ jQuery.event = {
} }
// Handle multiple events separated by a space // Handle multiple events separated by a space
types = ( types || "" ).match( core_rnotwhite ) || [""]; types = ( types || "" ).match( rnotwhite ) || [""];
t = types.length; t = types.length;
while ( t-- ) { while ( t-- ) {
tmp = rtypenamespace.exec( types[t] ) || []; tmp = rtypenamespace.exec( types[t] ) || [];
@ -148,7 +160,7 @@ jQuery.event = {
} }
// Once for each type.namespace in types; type may be omitted // Once for each type.namespace in types; type may be omitted
types = ( types || "" ).match( core_rnotwhite ) || [""]; types = ( types || "" ).match( rnotwhite ) || [""];
t = types.length; t = types.length;
while ( t-- ) { while ( t-- ) {
tmp = rtypenamespace.exec( types[t] ) || []; tmp = rtypenamespace.exec( types[t] ) || [];
@ -210,8 +222,8 @@ jQuery.event = {
var i, cur, tmp, bubbleType, ontype, handle, special, var i, cur, tmp, bubbleType, ontype, handle, special,
eventPath = [ elem || document ], eventPath = [ elem || document ],
type = core_hasOwn.call( event, "type" ) ? event.type : event, type = hasOwn.call( event, "type" ) ? event.type : event,
namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
cur = tmp = elem = elem || document; cur = tmp = elem = elem || document;
@ -342,7 +354,7 @@ jQuery.event = {
var i, j, ret, matched, handleObj, var i, j, ret, matched, handleObj,
handlerQueue = [], handlerQueue = [],
args = core_slice.call( arguments ), args = slice.call( arguments ),
handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {}; special = jQuery.event.special[ event.type ] || {};
@ -827,3 +839,5 @@ jQuery.fn.extend({
} }
} }
}); });
});

View File

@ -1,3 +1,8 @@
define([
"../core",
"../event"
], function( jQuery ) {
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
@ -30,3 +35,5 @@ jQuery.fn.extend({
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
} }
}); });
});

12
src/exports/amd.js Normal file
View File

@ -0,0 +1,12 @@
// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
});
}

View File

@ -27,21 +27,7 @@
return factory( w ); return factory( w );
}; };
} else { } else {
// Execute the factory to produce jQuery factory( window );
var jQuery = factory( window );
// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
});
}
} }
// Pass this, window may not be defined yet // Pass this, window may not be defined yet

38
src/jquery.js vendored Normal file
View File

@ -0,0 +1,38 @@
define([
"./core",
"./selector",
"./callbacks",
"./deferred",
"./core/ready",
"./traversing",
"./data",
"./queue",
"./queue/delay",
"./attributes",
"./event",
"./event/alias",
"./manipulation",
"./manipulation/_evalUrl",
"./wrap",
"./css",
"./css/hidden-visible-selectors",
"./serialize",
"./ajax",
"./ajax/xhr",
"./ajax/script",
"./ajax/jsonp",
"./ajax/load",
"./effects",
"./effects/animated-selector",
"./offset",
"./dimensions",
"./support",
"./deprecated"
], function( jQuery ) {
// Expose jQuery and $ identifiers, even in
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
return (window.jQuery = window.$ = jQuery);
});

View File

@ -1,8 +1,20 @@
define([
"./core",
"./var/concat",
"./var/push",
"./manipulation/var/rcheckableType",
"./data/var/data_priv",
"./data/var/data_user",
"./data/accepts",
"./selector",
"./traversing",
"./event"
], function( jQuery, concat, push, rcheckableType, data_priv, data_user ){
var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
rtagName = /<([\w:]+)/, rtagName = /<([\w:]+)/,
rhtml = /<|&#?\w+;/, rhtml = /<|&#?\w+;/,
rnoInnerhtml = /<(?:script|style|link)/i, rnoInnerhtml = /<(?:script|style|link)/i,
manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
// checked="checked" or checked // checked="checked" or checked
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
rscriptType = /^$|\/(?:java|ecma)script/i, rscriptType = /^$|\/(?:java|ecma)script/i,
@ -72,8 +84,7 @@ jQuery.fn.extend({
}); });
}, },
// keepData is for internal use only--do not document remove: function( selector, keepData /* Internal Use Only */ ) {
remove: function( selector, keepData ) {
var elem, var elem,
elems = selector ? jQuery.filter( selector, this ) : this, elems = selector ? jQuery.filter( selector, this ) : this,
i = 0; i = 0;
@ -195,7 +206,7 @@ jQuery.fn.extend({
domManip: function( args, callback, allowIntersection ) { domManip: function( args, callback, allowIntersection ) {
// Flatten any nested arrays // Flatten any nested arrays
args = core_concat.apply( [], args ); args = concat.apply( [], args );
var fragment, first, scripts, hasScripts, node, doc, var fragment, first, scripts, hasScripts, node, doc,
i = 0, i = 0,
@ -239,7 +250,7 @@ jQuery.fn.extend({
// Keep references to cloned scripts for later restoration // Keep references to cloned scripts for later restoration
if ( hasScripts ) { if ( hasScripts ) {
// Support: QtWebKit // Support: QtWebKit
// jQuery.merge because core_push.apply(_, arraylike) throws // jQuery.merge because push.apply(_, arraylike) throws
jQuery.merge( scripts, getAll( node, "script" ) ); jQuery.merge( scripts, getAll( node, "script" ) );
} }
} }
@ -260,8 +271,10 @@ jQuery.fn.extend({
!data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
if ( node.src ) { if ( node.src ) {
// Hope ajax is available... // Optional AJAX dependency, but won't run scripts if not present
jQuery._evalUrl( node.src ); if ( jQuery._evalUrl ) {
jQuery._evalUrl( node.src );
}
} else { } else {
jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
} }
@ -294,8 +307,8 @@ jQuery.each({
jQuery( insert[ i ] )[ original ]( elems ); jQuery( insert[ i ] )[ original ]( elems );
// Support: QtWebKit // Support: QtWebKit
// .get() because core_push.apply(_, arraylike) throws // .get() because push.apply(_, arraylike) throws
core_push.apply( ret, elems.get() ); push.apply( ret, elems.get() );
} }
return this.pushStack( ret ); return this.pushStack( ret );
@ -360,7 +373,7 @@ jQuery.extend({
// Add nodes directly // Add nodes directly
if ( jQuery.type( elem ) === "object" ) { if ( jQuery.type( elem ) === "object" ) {
// Support: QtWebKit // Support: QtWebKit
// jQuery.merge because core_push.apply(_, arraylike) throws // jQuery.merge because push.apply(_, arraylike) throws
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
// Convert non-html into a text node // Convert non-html into a text node
@ -383,7 +396,7 @@ jQuery.extend({
} }
// Support: QtWebKit // Support: QtWebKit
// jQuery.merge because core_push.apply(_, arraylike) throws // jQuery.merge because push.apply(_, arraylike) throws
jQuery.merge( nodes, tmp.childNodes ); jQuery.merge( nodes, tmp.childNodes );
// Remember the top-level container // Remember the top-level container
@ -438,7 +451,7 @@ jQuery.extend({
i = 0; i = 0;
for ( ; (elem = elems[ i ]) !== undefined; i++ ) { for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
if ( Data.accepts( elem ) ) { if ( jQuery.acceptData( elem ) ) {
key = elem[ data_priv.expando ]; key = elem[ data_priv.expando ];
if ( key && (data = data_priv.cache[ key ]) ) { if ( key && (data = data_priv.cache[ key ]) ) {
@ -463,17 +476,6 @@ jQuery.extend({
// Discard any remaining `user` data // Discard any remaining `user` data
delete data_user.cache[ elem[ data_user.expando ] ]; delete data_user.cache[ elem[ data_user.expando ] ];
} }
},
_evalUrl: function( url ) {
return jQuery.ajax({
url: url,
type: "GET",
dataType: "script",
async: false,
global: false,
"throws": true
});
} }
}); });
@ -567,7 +569,7 @@ function fixInput( src, dest ) {
var nodeName = dest.nodeName.toLowerCase(); var nodeName = dest.nodeName.toLowerCase();
// Fails to persist the checked state of a cloned checkbox or radio button. // Fails to persist the checked state of a cloned checkbox or radio button.
if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
dest.checked = src.checked; dest.checked = src.checked;
// Fails to return the selected option to the default selected state when cloning options // Fails to return the selected option to the default selected state when cloning options
@ -575,3 +577,4 @@ function fixInput( src, dest ) {
dest.defaultValue = src.defaultValue; dest.defaultValue = src.defaultValue;
} }
} }
});

View File

@ -0,0 +1,16 @@
define([
"../ajax"
], function( jQuery ) {
jQuery._evalUrl = function( url ) {
return jQuery.ajax({
url: url,
type: "GET",
dataType: "script",
async: false,
global: false,
"throws": true
});
};
return jQuery._evalUrl;
});

View File

@ -0,0 +1,3 @@
define(function() {
return /^(?:checkbox|radio)$/i;
});

View File

@ -1,3 +1,12 @@
define([
"./core",
"./var/strundefined",
"./css",
"./selector"
], function( jQuery, strundefined ) {
var docElem = window.document.documentElement;
jQuery.fn.offset = function( options ) { jQuery.fn.offset = function( options ) {
if ( arguments.length ) { if ( arguments.length ) {
return options === undefined ? return options === undefined ?
@ -25,7 +34,7 @@ jQuery.fn.offset = function( options ) {
// If we don't have gBCR, just use 0,0 rather than error // If we don't have gBCR, just use 0,0 rather than error
// BlackBerry 5, iOS 3 (original iPhone) // BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== core_strundefined ) { if ( typeof elem.getBoundingClientRect !== strundefined ) {
box = elem.getBoundingClientRect(); box = elem.getBoundingClientRect();
} }
win = getWindow( doc ); win = getWindow( doc );
@ -136,6 +145,12 @@ jQuery.fn.extend({
} }
}); });
/**
* Gets a window from an element
*/
function getWindow( elem ) {
return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}
// Create scrollLeft and scrollTop methods // Create scrollLeft and scrollTop methods
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
@ -162,6 +177,4 @@ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( me
}; };
}); });
function getWindow( elem ) { });
return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}

View File

@ -1,6 +1 @@
// Expose jQuery and $ identifiers, even in }));
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
return (window.jQuery = window.$ = jQuery);
}));

View File

@ -1,3 +1,10 @@
define([
"./core",
"./data/var/data_priv",
"./deferred",
"./callbacks"
], function( jQuery, data_priv ) {
jQuery.extend({ jQuery.extend({
queue: function( elem, type, data ) { queue: function( elem, type, data ) {
var queue; var queue;
@ -96,19 +103,6 @@ jQuery.fn.extend({
jQuery.dequeue( this, type ); jQuery.dequeue( this, type );
}); });
}, },
// Based off of the plugin by Clint Helfers, with permission.
// http://blindsignals.com/index.php/2009/07/jquery-delay/
delay: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
type = type || "fx";
return this.queue( type, function( next, hooks ) {
var timeout = setTimeout( next, time );
hooks.stop = function() {
clearTimeout( timeout );
};
});
},
clearQueue: function( type ) { clearQueue: function( type ) {
return this.queue( type || "fx", [] ); return this.queue( type || "fx", [] );
}, },
@ -143,3 +137,5 @@ jQuery.fn.extend({
return defer.promise( obj ); return defer.promise( obj );
} }
}); });
});

22
src/queue/delay.js Normal file
View File

@ -0,0 +1,22 @@
define([
"../core",
"../queue",
"../effects" // Delay is optional because of this dependency
], function( jQuery ) {
// Based off of the plugin by Clint Helfers, with permission.
// http://blindsignals.com/index.php/2009/07/jquery-delay/
jQuery.fn.delay = function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
type = type || "fx";
return this.queue( type, function( next, hooks ) {
var timeout = setTimeout( next, time );
hooks.stop = function() {
clearTimeout( timeout );
};
});
};
return jQuery.fn.delay;
});

View File

@ -1,3 +1,7 @@
define([
"./core"
], function( jQuery ) {
/* /*
* Optional (non-Sizzle) selector module for custom builds. * Optional (non-Sizzle) selector module for custom builds.
* *
@ -23,7 +27,8 @@
* customize this stub for the project's specific needs. * customize this stub for the project's specific needs.
*/ */
var selector_hasDuplicate, var docElem = window.document.documentElement,
selector_hasDuplicate,
matches = docElem.webkitMatchesSelector || matches = docElem.webkitMatchesSelector ||
docElem.mozMatchesSelector || docElem.mozMatchesSelector ||
docElem.oMatchesSelector || docElem.oMatchesSelector ||
@ -162,3 +167,5 @@ jQuery.extend( jQuery.find, {
return elem.getAttribute( name ); return elem.getAttribute( name );
} }
}); });
});

View File

@ -1,3 +1,8 @@
define([
"./core",
"../bower_components/sizzle/dist/sizzle"
], function ( jQuery, Sizzle ) {
jQuery.find = Sizzle; jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors; jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos; jQuery.expr[":"] = jQuery.expr.pseudos;
@ -5,3 +10,5 @@ jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText; jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML; jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains; jQuery.contains = Sizzle.contains;
});

1
src/selector.js Normal file
View File

@ -0,0 +1 @@
define([ "./selector-sizzle" ]);

View File

@ -1,3 +1,10 @@
define([
"./core",
"./manipulation/var/rcheckableType",
"./traversing", // filter
"./attributes/prop"
], function( jQuery, rcheckableType ) {
var r20 = /%20/g, var r20 = /%20/g,
rbracket = /\[\]$/, rbracket = /\[\]$/,
rCRLF = /\r?\n/g, rCRLF = /\r?\n/g,
@ -19,7 +26,7 @@ jQuery.fn.extend({
// Use .is(":disabled") so that fieldset[disabled] works // Use .is(":disabled") so that fieldset[disabled] works
return this.name && !jQuery( this ).is( ":disabled" ) && return this.name && !jQuery( this ).is( ":disabled" ) &&
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
( this.checked || !manipulation_rcheckableType.test( type ) ); ( this.checked || !rcheckableType.test( type ) );
}) })
.map(function( i, elem ){ .map(function( i, elem ){
var val = jQuery( this ).val(); var val = jQuery( this ).val();
@ -35,8 +42,8 @@ jQuery.fn.extend({
} }
}); });
//Serialize an array of form elements or a set of // Serialize an array of form elements or a set of
//key/values into a query string // key/values into a query string
jQuery.param = function( a, traditional ) { jQuery.param = function( a, traditional ) {
var prefix, var prefix,
s = [], s = [],
@ -97,3 +104,4 @@ function buildParams( prefix, obj, traditional, add ) {
add( prefix, obj ); add( prefix, obj );
} }
} }
});

View File

@ -1,3 +1,8 @@
define([
"./core",
"./core/swap"
], function( jQuery ) {
jQuery.support = (function( support ) { jQuery.support = (function( support ) {
var input = document.createElement("input"), var input = document.createElement("input"),
fragment = document.createDocumentFragment(), fragment = document.createDocumentFragment(),
@ -111,3 +116,4 @@ jQuery.support = (function( support ) {
return support; return support;
})( {} ); })( {} );
});

View File

@ -1,3 +1,8 @@
define([
"./core",
"./var/indexOf",
"./selector"
], function( jQuery, indexOf ) {
var isSimple = /^.[^:#\[\.,]*$/, var isSimple = /^.[^:#\[\.,]*$/,
rparentsprev = /^(?:parents|prev(?:Until|All))/, rparentsprev = /^(?:parents|prev(?:Until|All))/,
rneedsContext = jQuery.expr.match.needsContext, rneedsContext = jQuery.expr.match.needsContext,
@ -110,11 +115,11 @@ jQuery.fn.extend({
// index in selector // index in selector
if ( typeof elem === "string" ) { if ( typeof elem === "string" ) {
return core_indexOf.call( jQuery( elem ), this[ 0 ] ); return indexOf.call( jQuery( elem ), this[ 0 ] );
} }
// Locate the position of the desired element // Locate the position of the desired element
return core_indexOf.call( this, return indexOf.call( this,
// If it receives a jQuery object, the first element is used // If it receives a jQuery object, the first element is used
elem.jquery ? elem[ 0 ] : elem elem.jquery ? elem[ 0 ] : elem
@ -278,6 +283,7 @@ function winnow( elements, qualifier, not ) {
} }
return jQuery.grep( elements, function( elem ) { return jQuery.grep( elements, function( elem ) {
return ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not; return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
}); });
} }
});

3
src/var/arr.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return [];
});

3
src/var/class2type.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return {};
});

5
src/var/concat.js Normal file
View File

@ -0,0 +1,5 @@
define([
"./arr"
], function( arr ) {
return arr.concat;
});

5
src/var/hasOwn.js Normal file
View File

@ -0,0 +1,5 @@
define([
"./class2type"
], function( class2type ) {
return class2type.hasOwnProperty;
});

5
src/var/indexOf.js Normal file
View File

@ -0,0 +1,5 @@
define([
"./arr"
], function( arr ) {
return arr.indexOf;
});

3
src/var/pnum.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
});

5
src/var/push.js Normal file
View File

@ -0,0 +1,5 @@
define([
"./arr"
], function( arr ) {
return arr.push;
});

3
src/var/rnotwhite.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return /\S+/g;
});

5
src/var/slice.js Normal file
View File

@ -0,0 +1,5 @@
define([
"./arr"
], function( arr ) {
return arr.slice;
});

3
src/var/strundefined.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return typeof undefined;
});

5
src/var/toString.js Normal file
View File

@ -0,0 +1,5 @@
define([
"./class2type"
], function( class2type ) {
return class2type.toString;
});

3
src/var/trim.js Normal file
View File

@ -0,0 +1,3 @@
define(function() {
return "".trim;
});

View File

@ -1,3 +1,7 @@
define([
"./core",
"./traversing" // parent, contents
], function( jQuery ) {
jQuery.fn.extend({ jQuery.fn.extend({
wrapAll: function( html ) { wrapAll: function( html ) {
var wrap; var wrap;
@ -67,3 +71,4 @@ jQuery.fn.extend({
}).end(); }).end();
} }
}); });
});

View File

@ -1,6 +1,6 @@
/*jshint multistr:true, quotmark:false */ /*jshint multistr:true, quotmark:false */
var amdDefined, fireNative, var fireNative,
originaljQuery = this.jQuery || "jQuery", originaljQuery = this.jQuery || "jQuery",
original$ = this.$ || "$", original$ = this.$ || "$",
// see RFC 2606 // see RFC 2606
@ -13,15 +13,6 @@ this.isLocal = window.location.protocol === "file:";
this.jQuery = originaljQuery; this.jQuery = originaljQuery;
this.$ = original$; this.$ = original$;
/**
* Set up a mock AMD define function for testing AMD registration.
*/
function define( name, dependencies, callback ) {
amdDefined = callback();
}
define.amd = {};
/** /**
* Returns an array of elements with the given IDs * Returns an array of elements with the given IDs
* @example q("main", "foo", "bar") * @example q("main", "foo", "bar")

View File

@ -248,11 +248,11 @@ this.Globals = (function() {
} }
}; };
QUnit.config.urlConfig.push( { QUnit.config.urlConfig.push({
id: "jqdata", id: "jqdata",
label: "Always check jQuery.data", label: "Always check jQuery.data",
tooltip: "Trigger QUnit.expectJqData detection for all tests instead of just the ones that call it" tooltip: "Trigger QUnit.expectJqData detection for all tests instead of just the ones that call it"
} ); });
/** /**
* Ensures that tests have cleaned up properly after themselves. Should be passed as the * Ensures that tests have cleaned up properly after themselves. Should be passed as the

View File

@ -14,63 +14,33 @@
<script src="data/testinit.js"></script> <script src="data/testinit.js"></script>
<script src="../bower_components/qunit/qunit/qunit.js"></script> <script src="../bower_components/qunit/qunit/qunit.js"></script>
<script> <script src="../bower_components/requirejs/require.js"></script>
(function() { <script>loadTests = [
var src = "../dist/jquery.min.js"; "data/testrunner.js",
"unit/core.js",
// Config parameter to use minified jQuery "unit/callbacks.js",
QUnit.config.urlConfig.push({ "unit/deferred.js",
id: "dev", "unit/support.js",
label: "Load unminified", "unit/data.js",
tooltip: "Load the development (unminified) jQuery file" "unit/queue.js",
}); "unit/attributes.js",
if ( QUnit.urlParams.dev ) { "unit/event.js",
src = "../dist/jquery.js"; "unit/selector.js",
} "unit/traversing.js",
"unit/manipulation.js",
// Config parameter to force basic code paths "unit/wrap.js",
QUnit.config.urlConfig.push({ "unit/css.js",
id: "basic", "unit/serialize.js",
label: "Bypass optimizations", "unit/ajax.js",
tooltip: "Force use of the most basic code by disabling native querySelectorAll; contains; compareDocumentPosition" "unit/effects.js",
}); "unit/offset.js",
if ( QUnit.urlParams.basic ) { "unit/dimensions.js"
document.querySelectorAll = null; ];</script>
document.documentElement.contains = null; <!-- A script that includes jQuery min, dev, or AMD -->
document.documentElement.compareDocumentPosition = null; <!-- Adds "basic" URL option, even to iframes -->
} <!-- iframes will not load AMD as loading needs to be synchronous for some tests -->
<!-- Also loads the tests above synchronously with min or dev and async with AMD -->
// Load jQuery <script src="jquery.js"></script>
document.write( "<script id='jquery-js' src='" + src + "'><\x2Fscript>" );
})();
</script>
<script src="data/testrunner.js"></script>
<script src="unit/core.js"></script>
<script src="unit/callbacks.js"></script>
<script src="unit/deferred.js"></script>
<script src="unit/support.js"></script>
<script src="unit/data.js"></script>
<script src="unit/queue.js"></script>
<script src="unit/attributes.js"></script>
<script src="unit/event.js"></script>
<script src="unit/selector.js"></script>
<script src="unit/traversing.js"></script>
<script src="unit/manipulation.js"></script>
<script src="unit/wrap.js"></script>
<script src="unit/css.js"></script>
<script src="unit/serialize.js"></script>
<script src="unit/ajax.js"></script>
<script src="unit/effects.js"></script>
<script src="unit/offset.js"></script>
<script src="unit/dimensions.js"></script>
<script src="unit/deprecated.js"></script>
<script src="unit/exports.js"></script>
<!-- Subproject tests must be last because they replace our test fixture -->
<script>
testSubproject( "Sizzle", "../bower_components/sizzle/test/", /^unit\/.*\.js$/ );
</script>
<script> <script>
// html5shiv, enabling HTML5 elements to be used with jQuery // html5shiv, enabling HTML5 elements to be used with jQuery

82
test/jquery.js vendored
View File

@ -1,5 +1,77 @@
// Use the right jQuery source in iframe tests // Use the right jQuery source on the test page (and iframes)
document.write( "<script id='jquery-js' src='" + (function() {
parent.document.getElementById("jquery-js").src.replace( /^(?![^\/?#]+:)/, /* global loadTests: true, testSubproject: false */
parent.location.pathname.replace( /[^\/]$/, "$0/" ) ) + /* jshint eqeqeq: false */
"'><\x2Fscript>" );
var i, len,
// Parent is the current window if not an iframe, which is fine
src = /^(.*)test\//.exec( parent.location.pathname )[1],
QUnit = QUnit || parent.QUnit,
require = require || parent.require;
// Config parameter to force basic code paths
QUnit.config.urlConfig.push({
id: "basic",
label: "Bypass optimizations",
tooltip: "Force use of the most basic code by disabling native querySelectorAll; contains; compareDocumentPosition"
});
if ( QUnit.urlParams.basic ) {
document.querySelectorAll = null;
document.documentElement.contains = null;
document.documentElement.compareDocumentPosition = null;
}
// iFrames won't load AMD (the iframe tests synchronously expect jQuery to be there)
QUnit.config.urlConfig.push({
id: "amd",
label: "Load with AMD",
tooltip: "Load the AMD jQuery file (and its dependencies)"
});
if ( QUnit.urlParams.amd && parent == window ) {
require.config({ baseUrl: src });
src = "src/jquery";
// Include tests if specified
if ( typeof loadTests !== "undefined" ) {
QUnit.config.autostart = false;
require( [ src ], function() {
// Ensure load order (to preserve test numbers)
(function loadDep() {
var dep = loadTests.shift();
if ( dep ) {
require( [ dep ], loadDep );
} else {
// Subproject tests must be last because they replace our test fixture
testSubproject( "Sizzle", "../bower_components/sizzle/test/", /^unit\/.*\.js$/ );
QUnit.start();
}
})();
});
} else {
require( [ src ] );
}
return;
}
// Config parameter to use minified jQuery
QUnit.config.urlConfig.push({
id: "dev",
label: "Load unminified",
tooltip: "Load the development (unminified) jQuery file"
});
if ( QUnit.urlParams.dev ) {
src += "dist/jquery.js";
} else {
src += "dist/jquery.min.js";
}
// Load jQuery
document.write( "<script id='jquery-js' src='" + src + "'><\x2Fscript>" );
// Load tests synchronously if available
if ( typeof loadTests !== "undefined" ) {
for ( i = 0, len = loadTests.length; i < len; i++ ) {
document.write( "<script src='" + loadTests.shift() + "'><\x2Fscript>" );
}
}
})();

View File

@ -17,18 +17,6 @@ test("Basic requirements", function() {
ok( $, "$" ); ok( $, "$" );
}); });
testIframeWithCallback( "Conditional compilation compatibility (#13274)", "core/cc_on.html", function( cc_on, errors, $ ) {
expect( 3 );
ok( true, "JScript conditional compilation " + ( cc_on ? "supported" : "not supported" ) );
deepEqual( errors, [], "No errors" );
ok( $(), "jQuery executes" );
});
testIframeWithCallback( "document ready when jQuery loaded asynchronously (#13655)", "core/dynamic_ready.html", function( ready ) {
expect( 1 );
equal( true, ready, "document ready correctly fired when jQuery is loaded after DOMContentLoaded" );
});
test("jQuery()", function() { test("jQuery()", function() {
var elem, i, var elem, i,
@ -1385,3 +1373,15 @@ test("jQuery.camelCase()", function() {
equal( jQuery.camelCase( key ), val, "Converts: " + key + " => " + val ); equal( jQuery.camelCase( key ), val, "Converts: " + key + " => " + val );
}); });
}); });
testIframeWithCallback( "Conditional compilation compatibility (#13274)", "core/cc_on.html", function( cc_on, errors, $ ) {
expect( 3 );
ok( true, "JScript conditional compilation " + ( cc_on ? "supported" : "not supported" ) );
deepEqual( errors, [], "No errors" );
ok( $(), "jQuery executes" );
});
testIframeWithCallback( "document ready when jQuery loaded asynchronously (#13655)", "core/dynamic_ready.html", function( ready ) {
expect( 1 );
equal( true, ready, "document ready correctly fired when jQuery is loaded after DOMContentLoaded" );
});

View File

@ -62,7 +62,7 @@ test( "jQuery.hasData no side effects", function() {
); );
}); });
function dataTests (elem) { function dataTests( elem ) {
var dataObj, internalDataObj; var dataObj, internalDataObj;
equal( jQuery.data(elem, "foo"), undefined, "No data exists initially" ); equal( jQuery.data(elem, "foo"), undefined, "No data exists initially" );
@ -129,30 +129,30 @@ function dataTests (elem) {
test("jQuery.data(div)", 25, function() { test("jQuery.data(div)", 25, function() {
var div = document.createElement("div"); var div = document.createElement("div");
dataTests(div); dataTests( div );
// We stored one key in the private data // We stored one key in the private data
// assert that nothing else was put in there, and that that // assert that nothing else was put in there, and that that
// one stayed there. // one stayed there.
QUnit.expectJqData(div, "foo"); QUnit.expectJqData( div, "foo" );
}); });
test("jQuery.data({})", 25, function() { test("jQuery.data({})", 25, function() {
dataTests({}); dataTests( {} );
}); });
test("jQuery.data(window)", 25, function() { test("jQuery.data(window)", 25, function() {
// remove bound handlers from window object to stop potential false positives caused by fix for #5280 in // remove bound handlers from window object to stop potential false positives caused by fix for #5280 in
// transports/xhr.js // transports/xhr.js
jQuery(window).off("unload"); jQuery( window ).off( "unload" );
dataTests(window); dataTests( window );
}); });
test("jQuery.data(document)", 25, function() { test("jQuery.data(document)", 25, function() {
dataTests(document); dataTests( document );
QUnit.expectJqData(document, "foo"); QUnit.expectJqData( document, "foo" );
}); });
test("jQuery.data(<embed>)", 25, function() { test("jQuery.data(<embed>)", 25, function() {

View File

@ -3,13 +3,18 @@ module("support", { teardown: moduleTeardown });
if ( jQuery.css ) { if ( jQuery.css ) {
testIframeWithCallback( "body background is not lost if set prior to loading jQuery (#9239)", "support/bodyBackground.html", function( color, support ) { testIframeWithCallback( "body background is not lost if set prior to loading jQuery (#9239)", "support/bodyBackground.html", function( color, support ) {
expect( 2 ); expect( 2 );
var okValue = { var okValue = {
"#000000": true, "#000000": true,
"rgb(0, 0, 0)": true "rgb(0, 0, 0)": true
}; };
ok( okValue[ color ], "color was not reset (" + color + ")" ); ok( okValue[ color ], "color was not reset (" + color + ")" );
deepEqual( jQuery.extend( {}, support ), jQuery.support, "Same support properties" ); stop();
// Run doc ready tests as well
jQuery(function() {
deepEqual( jQuery.extend( {}, support ), jQuery.support, "Same support properties" );
start();
});
}); });
} }